-
-
Save aunyks/b25cffd4f4250a3fbf26e3a626441e33 to your computer and use it in GitHub Desktop.
pragma solidity ^0.4.19; | |
contract ERC721 { | |
string constant private tokenName = "My ERC721 Token"; | |
string constant private tokenSymbol = "MET"; | |
uint256 constant private totalTokens = 1000000; | |
mapping(address => uint) private balances; | |
mapping(uint256 => address) private tokenOwners; | |
mapping(uint256 => bool) private tokenExists; | |
mapping(address => mapping (address => uint256)) private allowed; | |
mapping(address => mapping(uint256 => uint256)) private ownerTokens; | |
mapping(uint256 => string) tokenLinks; | |
function removeFromTokenList(address owner, uint256 _tokenId) private { | |
for(uint256 i = 0;ownerTokens[owner][i] != _tokenId;i++){ | |
ownerTokens[owner][i] = 0; | |
} | |
} | |
function name() public constant returns (string){ | |
return tokenName; | |
} | |
function symbol() public constant returns (string) { | |
return tokenSymbol; | |
} | |
function totalSupply() public constant returns (uint256){ | |
return totalTokens; | |
} | |
function balanceOf(address _owner) constant returns (uint){ | |
return balances[_owner]; | |
} | |
function ownerOf(uint256 _tokenId) constant returns (address){ | |
require(tokenExists[_tokenId]); | |
return tokenOwners[_tokenId]; | |
} | |
function approve(address _to, uint256 _tokenId){ | |
require(msg.sender == ownerOf(_tokenId)); | |
require(msg.sender != _to); | |
allowed[msg.sender][_to] = _tokenId; | |
Approval(msg.sender, _to, _tokenId); | |
} | |
function takeOwnership(uint256 _tokenId){ | |
require(tokenExists[_tokenId]); | |
address oldOwner = ownerOf(_tokenId); | |
address newOwner = msg.sender; | |
require(newOwner != oldOwner); | |
require(allowed[oldOwner][newOwner] == _tokenId); | |
balances[oldOwner] -= 1; | |
tokenOwners[_tokenId] = newOwner; | |
balances[oldOwner] += 1; | |
Transfer(oldOwner, newOwner, _tokenId); | |
} | |
function transfer(address _to, uint256 _tokenId){ | |
address currentOwner = msg.sender; | |
address newOwner = _to; | |
require(tokenExists[_tokenId]); | |
require(currentOwner == ownerOf(_tokenId)); | |
require(currentOwner != newOwner); | |
require(newOwner != address(0)); | |
removeFromTokenList(_tokenId); | |
balances[currentOwner] -= 1; | |
tokenOwners[_tokenId] = newOwner; | |
balances[newOwner] += 1; | |
Transfer(currentOwner, newOwner, _tokenId); | |
} | |
function tokenOfOwnerByIndex(address _owner, uint256 _index) constant returns (uint tokenId){ | |
return ownerTokens[_owner][_index]; | |
} | |
function tokenMetadata(uint256 _tokenId) constant returns (string infoUrl){ | |
return tokenLinks[_tokenId]; | |
} | |
event Transfer(address indexed _from, address indexed _to, uint256 _tokenId); | |
event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId); | |
} |
Hey @aunyks, I think this also needs a way to add meta-data to a token, e.g.:
function setTokenMetadata(uint256 _tokenId, string infoUrl) {
require(msg.sender == ownerOf(_tokenId));
tokenLinks[_tokenId] = infoUrl;
}
The check require(tokenExists[_tokenId])
in L54 seems redundant, given that the existance check is also done in ownerOf()
.
Shouldn't line 48 be:
balances[newOwner] += 1;
(newOwner
instead of oldOwner
)
Thanks a lot!
i have a suspicion this is what you want
function removeFromTokenList(address owner, uint256 _tokenId) private {
for(uint256 i = 0;ownerTokens[owner][i] == _tokenId;i++){
//not
//for(uint256 i = 0;ownerTokens[owner][i] != _tokenId;i++){
ownerTokens[owner][i] = 0;
}
}
also add addToTokenList under line 48 after turning
balances[oldOwner] += 1;
into
balances[newOwner] += 1;
addToTokenList(newOwner,_tokenId);
function addToTokenList(address owner, uint256 _tokenId) private {
ownerTokens[owner][i] = _tokenId;
}
[
Why not?
ownerTokens[owner][_tokenId] = 0
So many bugs !!! improvements above all should add into it !
i have a suspicion this is what you want
function removeFromTokenList(address owner, uint256 _tokenId) private { for(uint256 i = 0;ownerTokens[owner][i] == _tokenId;i++){ //not //for(uint256 i = 0;ownerTokens[owner][i] != _tokenId;i++){ ownerTokens[owner][i] = 0; } }
also add addToTokenList under line 48 after turning
balances[oldOwner] += 1;
intobalances[newOwner] += 1; addToTokenList(newOwner,_tokenId);
function addToTokenList(address owner, uint256 _tokenId) private { ownerTokens[owner][i] = _tokenId; }
it supppose to be like this....
function removeFromTokenList(address owner, uint256 _tokenId) private {
for(uint256 i = 0;ownerTokens[owner][i] != _tokenId;i++){}
ownerTokens[owner][i] = 0;
}
How to mint NFT?
@vlugansky
It looks like the call should be
removeFromTokenList(currentOwner, _tokenId);
. That said, it looks likeremoveFromTokenList
does the wrong thing, clearing the record of owner->token up to but not including the token passed in, corrupting the results oftokenOfOwnerByIndex
.There's a reason there's a note at the top saying DO NOT DEPLOY TO THE NETWORK. It's way off-spec in the handling of approval events, as well.