Solodity知识点集 — ERC721代币标准详解(十)
2018-04-27 本文已影响14人
童蒙vlog
接上篇,这篇将详解介绍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);
}
}