接上篇,这篇将详解介绍ERC721
代币标准
balanceOf
function balanceOf(address _owner) public view returns (uint256 _balance);
这个函数只需要一个传入 address
参数,然后返回这个 address
拥有多少代币。
ownerOf
function ownerOf(uint256 _tokenId) public view returns (address _owner);
这个函数需要传入一个代币ID
作为参数,然后返回该代币拥有者的 address
。
ERC721: 转移标准
注意 ERC721
规范有两种不同的方法来转移代币:
// 第一种方法
function transfer(address _to, uint256 _tokenId) public;
// 第二种方法
function approve(address _to, uint256 _tokenId) public;
function takeOwnership(uint256 _tokenId) public;
第一种方法是代币的拥有者调用
transfer
方法,传入他想转移到的address
和他想转移的代币的_tokenId
。第二种方法是代币拥有者首先调用
approve
,然后传入与以上相同的参数。接着,该合约会存储谁被允许提取代币,通常存储到一个mapping (uint256 => address)
里。然后,当有人调用takeOwnership
时,合约会检查msg.sender
是否得到拥有者的批准来提取代币,如果是,则将代币转移给他。
注:第一种方法是发送者调用了转移逻辑,第二张方法是接受者调用了转移逻辑。
批准approve
使用 approve
或者 takeOwnership
的时候,转移有2
个步骤:
你,作为所有者,用新主人的
address
和你希望他获取的_tokenId
来调用approve
新主人用
_tokenId
来调用takeOwnership
,合约会检查确保他获得了批准,然后把代币转移给他。
takeOwnership
记得加上权限:
require(zombieApprovals[_tokenId] == msg.sender);
以下是ERC721
代币标准完整的例子
pragma solidity ^0.4.19;
import "./zombieattack.sol";
import "./erc721.sol";
contract ZombieOwnership is ZombieAttack, ERC721 {
mapping (uint => address) zombieApprovals;
function balanceOf(address _owner) public view returns (uint256 _balance) {
return ownerZombieCount[_owner];
}
function ownerOf(uint256 _tokenId) public view returns (address _owner) {
return zombieToOwner[_tokenId];
}
function _transfer(address _from, address _to, uint256 _tokenId) private {
ownerZombieCount[_to]++;
ownerZombieCount[_from]--;
zombieToOwner[_tokenId] = _to;
Transfer(_from, _to, _tokenId);
}
function transfer(address _to, uint256 _tokenId) public onlyOwnerOf(_tokenId) {
_transfer(msg.sender, _to, _tokenId);
}
function approve(address _to, uint256 _tokenId) public onlyOwnerOf(_tokenId) {
zombieApprovals[_tokenId] = _to;
Approval(msg.sender, _to, _tokenId);
}
function takeOwnership(uint256 _tokenId) public {
require(zombieApprovals[_tokenId] == msg.sender);
address owner = ownerOf(_tokenId);
_transfer(owner, msg.sender, _tokenId);
}
}