以太坊智能合约ERC721代码⽰例pragma solidity ^0.4.24;
/**
* Utility library of inline functions on address
*/
library Address {
}
/**
* @title SafeMath
* @dev Math operations with safety checks that revert on error
*/
library SafeMath {
uint256 c = a * b;
require(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0); // Solidity only automatically asrts when dividing by 0
uint256 c = a / b;
// asrt(a == b * c + a % b); // There is no ca in which this doesn't hold
return c;
}
/**
* @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). */
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
uint256 c = a - b;
return c;
}
/**
* @dev Adds two numbers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;外文翻译
require(c >= a);
return c;
}
/**
* @notice Query if a contract implements an interface
* @param interfaceId The interface identifier, as specified in ERC-165 * @dev Interface identification is specified in ERC-165. This function * us less than 30,000 gas.
*/
function supportsInterface(bytes4 interfaceId)
external
view
returns (bool);
}
/**
* @title ERC165
* @author Matt Condon (@shrugs)
* @dev Implements ERC165 using a lookup table.
*/
contract ERC165 is IERC165 {
bytes4 private constant _InterfaceId_ERC165 = 0x01ffc9a7;
life is like a dream/效益英文
**
* 0x01ffc9a7 ===
* bytes4(keccak256('supportsInterface(bytes4)'))
*/
/**
* @dev a mapping of interface id to whether or not it's supported
*/
mapping(bytes4 => bool) private _supportedInterfaces;
/**
* @dev A contract implementing SupportsInterfaceWithLookup
* implement ERC165 itlf
*/
constructor()
a m
public
{
_registerInterface(_InterfaceId_ERC165);
}
/**
* @dev implement supportsInterface(bytes4) using a lookup table
*/
function supportsInterface(bytes4 interfaceId)
external
view
returns (bool)
{
return _supportedInterfaces[interfaceId];
}
event Transfer(
address indexed from,
address indexed to,
uint256 indexed tokenId
);
event Approval(
address indexed owner,
address indexed approved,
uint256 indexed tokenId
);
event ApprovalForAll(
address indexed owner,
address indexed operator,
bool approved
);
function balanceOf(address owner) public view returns (uint256 balance); function ownerOf(uint256 tokenId) public view returns (address owner);
function approve(address to, uint256 tokenId) public;
function getApproved(uint256 tokenId)
public view returns (address operator);
function tApprovalForAll(address operator, bool _approved) public;
广州动漫学院
function isApprovedForAll(address owner, address operator)
public view returns (bool);
function transferFrom(address from, address to, uint256 tokenId) public; function safeTransferFrom(address from, address to, uint256 tokenId)
public;
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
engage
bytes data
)
public;
}
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransferstimev
* from ERC721 ast contracts.
*/
contract IERC721Receiver {
/**
上海话翻译
* @notice Handle the receipt of an NFT
* @dev The ERC721 smart contract calls this function on the recipient
* after a `safeTransfer`. This function MUST return the function lector,
* otherwi the caller will revert the transaction. The lector to be
南京蛋糕培训学校
* returned can be obtained as `ERC721Received.lector`. This
* function MAY throw to revert and reject the transfer.
* Note: the ERC721 contract address is always the message nder.
* @param operator The address which called `safeTransferFrom` function
* @param from The address which previously owned the token
* @param tokenId The NFT identifier which is being transferred
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` */
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes data
)
public
returns(bytes4);
}
using SafeMath for uint256;
using Address for address;
// Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.lector`
bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
// Mapping from token ID to owner
mapping (uint256 => address) private _tokenOwner;
// Mapping from token ID to approved address
mapping (uint256 => address) private _tokenApprovals;
// Mapping from owner to number of owned token
mapping (address => uint256) private _ownedTokensCount;
// Mapping from owner to operator approvals
mapping (address => mapping (address => bool)) private _operatorApprovals;
bytes4 private constant _InterfaceId_ERC721 = 0x80ac58cd;
/*
* 0x80ac58cd ===
* bytes4(keccak256('balanceOf(address)')) ^
* bytes4(keccak256('ownerOf(uint256)')) ^
* bytes4(keccak256('approve(address,uint256)')) ^
* bytes4(keccak256('getApproved(uint256)')) ^
* bytes4(keccak256('tApprovalForAll(address,bool)')) ^
* bytes4(keccak256('isApprovedForAll(address,address)')) ^
* bytes4(keccak256('transferFrom(address,address,uint256)')) ^
* bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^
* bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)'))
*/
constructor()
public
{
// register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(_InterfaceId_ERC721);
}
/**
* @dev Gets the balance of the specified address
* @param owner address to query the balance of
* @return uint256 reprenting the amount owned by the pasd address
*/
function balanceOf(address owner) public view returns (uint256) {
require(owner != address(0));
return _ownedTokensCount[owner];
}
/**
* @dev Gets the owner of the specified token ID
* @param tokenId uint256 ID of the token to query the owner of
* @return owner address currently marked as the owner of the given token ID */
function ownerOf(uint256 tokenId) public view returns (address) {
address owner = _tokenOwner[tokenId];
require(owner != address(0));
return owner;
}
/**
* @dev Approves another address to transfer the given token ID
* The zero address indicates there is no approved address.
* There can only be one approved address per token at a given time.
* Can only be called by the token owner or an approved operator.
* @param to address to be approved for the given token ID
* @param tokenId uint256 ID of the token to be approved
母语英语
*/
function approve(address to, uint256 tokenId) public {
address owner = ownerOf(tokenId);
require(to != owner);
require(msg.nder == owner || isApprovedForAll(owner, msg.nder));