ERC721
ERC721标准
(此处用的是OpenZeppelin中的版本):
contract ERC721 {
event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);
event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);
function balanceOf(address _owner) public view returns (uint256 _balance);
function ownerOf(uint256 _tokenId) public view returns (address _owner);
function transfer(address _to, uint256 _tokenId) public;
function approve(address _to, uint256 _tokenId) public;
function takeOwnership(uint256 _tokenId) public;
}
ERC721规范有两种不同的办法来转移代币:
function transfer(address _to, uint256 _tokenId) public;
function approve(address _to, uint256 _tokenId) public;
function takeOwnership(uint256 _tokenId) public;
1. 第一种方法是代币的拥有者调用transfer 方法,传入他想转移到的 address 和他想转移的代币的 _tokenId。
2. 第二种方法是代币拥有者首先调用 approve,然后传入与以上相同的参数。接着,该合约会存储谁被允许提取代币,通常存储到一个 mapping (uint256 => address) 里。然后,当有人调用 takeOwnership 时,合约会检查 msg.sender 是否得到拥有者的批准来提取代币,如果是,则将代币转移给他。
体会: 对于一个机制或者协议最简单的理解方式就是你自己来实现它。
合约安全增强: 溢出和下溢——使用SafeMath
- 溢出(overflow):一个uint8只能存储8bit即255个的数据,当255+1时自动变为0,这就是溢出。 - 下溢(underflow):类似,当一个等于0的uint8类型的减去1,它将变成255。uint无符号,因此不会变成负数。
SafeMath
OpenZeppelin为了防止一些情况例如上述的溢出下溢问题,建立了一个叫做SafeMath的库(library)。一个库是Solidaty中一种特殊的合约,其中一个有用的功能是给原始数据类型增加一些方法。
使用 SafeMath 库的时候,我们将使用 using SafeMath for uint256 这样的语法。 SafeMath 库有四个方法——add,sub,mul,以及 div。现在我们可以这样来让 uint256 调用这些方法:
using SafeMath for uint256;
uint256 a = 5;
uint256 b = a.add(3); // 5 + 3 = 8
uint256 c = a.mul(2); // 5 * 2 = 10
SafeMath.sol的代码: pragma solidity ^0.4.18;
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
/**
* @dev Multiplies two numbers, throws on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
assert(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers, truncating the quotient.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
使用SafeMath
为了防止溢出和下溢,可以把代码里面的+,-,*,/都换为SafeMath里面的方法。
例如:
myUint++;
//替换为:
myUint = myUint.add(1);
声明uint32和uint16使用的safemath。
using SafeMath32 for uint32;
using SafeMath16 for uint16;
注释
solidaty社区所使用的一个标准是使用一种被称作natspec
的格式,例如@anthor
,@dev
,@title
。
web3.js
web3.js是一组使用HTTP或IPC来连接本地或远程以太坊节点来进行交互的库,是以太坊基金发布的JavaScript库。