Ben Beecher
Sample examples:
Physical property — houses, unique artwork
Virtual collectables — unique pictures of kittens, collectable cards
"Negative value" assets — loans, burdens and other responsibilities
In general, all houses are distinct and no two kittens are alike. NFTs are distinguishable and you must track the ownership of each one separately.
Property is unique and differentiated
Token id is integer, and unique token location is defined as contractID + TokenID
So not a direct extension
checks ownership of the sender and is supposed to throw if not an allowed operator
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
Wallets must implement
function onERC721Received(address _from, uint256 _tokenId, bytes data) external returns(bytes4);
To handle incoming assets and can throw to reject transfer
This allows your smart contract to be interrogated for its name and for details about the assets which your NFT represent
interface ERC721Metadata {
function name() external pure returns (string _name);
function symbol() external pure returns (string _symbol);
function tokenURI(uint256 _tokenId) external view returns (string);
}
{ "title": "Asset Metadata", "type": "object", "properties": { "name": { "type": "string", "description": "Identifies the asset to which this NFT represents", }, "description": { "type": "string", "description": "Describes the asset to which this NFT represents", }, "image": { "type": "string", "description": "A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.", } } }
Is only accessible via web3 - no usecase for on chain querying of metadata
Allows your contract to publish its full list of NFTs and make them discoverable.
interface ERC721Enumerable { function totalSupply() external view returns (uint256); /// (sort order not specified) function tokenByIndex(uint256 _index) external view returns (uint256); /// (sort order not specified) function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256); }
Ownership of a token is _public_ and that is unchangeable. No such thing as private holder if your wallet id is leaked!