-
-
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); | |
} |
i see a logic bug here
The function removeFromTokenList has two parameters, but it is only given one argument on line 58. The contract does not compile for this reason.
What argument did you add as the second one?
@vlugansky
It looks like the call should be removeFromTokenList(currentOwner, _tokenId);
. That said, it looks like removeFromTokenList
does the wrong thing, clearing the record of owner->token up to but not including the token passed in, corrupting the results of tokenOfOwnerByIndex
.
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.
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?
Has anybody implemented an ERC-721 compliant contract in production use-cases yet? I'm looking at doing something with it, in a prod-like setting.
Edit: Crypto Kitties...duh