Implement tokensByIndex extension
- Remove restrictions from mock mint and burn calls
This commit is contained in:
@ -7,7 +7,7 @@ import "./ERC721Basic.sol";
|
||||
contract ERC721Enumerable is ERC721Basic {
|
||||
function totalSupply() public view returns (uint256);
|
||||
function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint256 _tokenId);
|
||||
// function tokenByIndex(uint256 _index) public view returns (uint256);
|
||||
function tokenByIndex(uint256 _index) public view returns (uint256);
|
||||
}
|
||||
|
||||
/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
|
||||
|
||||
@ -19,9 +19,6 @@ contract ERC721BasicToken is ERC721Basic {
|
||||
// Equals to bytes4(keccak256("onERC721Received(address,uint256,bytes)"))
|
||||
bytes4 ERC721_RECEIVED = 0xf0b9e5ba;
|
||||
|
||||
// Total amount of tokens
|
||||
uint256 internal totalTokens;
|
||||
|
||||
// Mapping from token ID to owner
|
||||
mapping (uint256 => address) internal tokenOwner;
|
||||
|
||||
@ -194,7 +191,6 @@ contract ERC721BasicToken is ERC721Basic {
|
||||
function doMint(address _to, uint256 _tokenId) internal {
|
||||
require(_to != address(0));
|
||||
addToken(_to, _tokenId);
|
||||
totalTokens = totalTokens.add(1);
|
||||
Transfer(0x0, _to, _tokenId);
|
||||
}
|
||||
|
||||
@ -203,11 +199,10 @@ contract ERC721BasicToken is ERC721Basic {
|
||||
* @dev Reverts if the token does not exist
|
||||
* @param _tokenId uint256 ID of the token being burned by the msg.sender
|
||||
*/
|
||||
function doBurn(uint256 _tokenId) onlyOwnerOf(_tokenId) internal {
|
||||
clearApproval(msg.sender, _tokenId);
|
||||
removeToken(msg.sender, _tokenId);
|
||||
totalTokens = totalTokens.sub(1);
|
||||
Transfer(msg.sender, 0x0, _tokenId);
|
||||
function doBurn(address _owner, uint256 _tokenId) internal {
|
||||
clearApproval(_owner, _tokenId);
|
||||
removeToken(_owner, _tokenId);
|
||||
Transfer(_owner, 0x0, _tokenId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -24,6 +24,12 @@ contract ERC721Token is ERC721, ERC721BasicToken {
|
||||
// Mapping from token ID to index of the owner tokens list
|
||||
mapping(uint256 => uint256) internal ownedTokensIndex;
|
||||
|
||||
// Array with all token ids, used for enumeration
|
||||
uint256[] internal allTokens;
|
||||
|
||||
// Mapping from token id to position in the allTokens array
|
||||
mapping(uint256 => uint256) internal allTokensIndex;
|
||||
|
||||
/**
|
||||
* @dev Constructor function
|
||||
*/
|
||||
@ -73,7 +79,18 @@ contract ERC721Token is ERC721, ERC721BasicToken {
|
||||
* @return uint256 representing the total amount of tokens
|
||||
*/
|
||||
function totalSupply() public view returns (uint256) {
|
||||
return totalTokens;
|
||||
return allTokens.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Gets the token ID at a given index of all the tokens in this contract
|
||||
* @dev Reverts if the index is greater or equal to the total number of tokens
|
||||
* @param _index uint256 representing the index to be accessed of the tokens list
|
||||
* @return uint256 token ID at the given index of the tokens list
|
||||
*/
|
||||
function tokenByIndex(uint256 _index) public view returns (uint256) {
|
||||
require(_index < totalSupply());
|
||||
return allTokens[_index];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,4 +130,38 @@ contract ERC721Token is ERC721, ERC721BasicToken {
|
||||
ownedTokensIndex[lastToken] = tokenIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Internal function to mint a new token
|
||||
* @dev Reverts if the given token ID already exists
|
||||
* @param _to address the beneficiary that will own the minted token
|
||||
* @param _tokenId uint256 ID of the token to be minted by the msg.sender
|
||||
*/
|
||||
function doMint(address _to, uint256 _tokenId) internal {
|
||||
super.doMint(_to, _tokenId);
|
||||
|
||||
allTokensIndex[_tokenId] = allTokens.length;
|
||||
allTokens.push(_tokenId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Internal function to burn a specific token
|
||||
* @dev Reverts if the token does not exist
|
||||
* @param _owner owner of the token to burn
|
||||
* @param _tokenId uint256 ID of the token being burned by the msg.sender
|
||||
*/
|
||||
function doBurn(address _owner, uint256 _tokenId) internal {
|
||||
super.doBurn(_owner, _tokenId);
|
||||
|
||||
uint256 tokenIndex = allTokensIndex[_tokenId];
|
||||
uint256 lastTokenIndex = allTokens.length.sub(1);
|
||||
uint256 lastToken = allTokens[lastTokenIndex];
|
||||
|
||||
allTokens[tokenIndex] = lastToken;
|
||||
allTokens[lastTokenIndex] = 0;
|
||||
|
||||
allTokens.length--;
|
||||
allTokensIndex[_tokenId] = 0;
|
||||
allTokensIndex[lastToken] = tokenIndex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user