上一篇我们介绍了如何创建ERC20代币的过程,本文我们将介绍利用JSON-API接口对ERC20代币进行的一些开发过程中的相关操作。
ETH的Transaction有几个重要字段,from, to, value, data(input)。
from: Transaction是由谁发起的。 to: Transaction发送到哪个地址。 value: Transaction发送的ETH数量。 data: 某些api中字段名字叫做input,含义都一样,代表这个Transaction附带的数据,通常是执行某些智能合约的命令。
在Ethereum JSON-Api 的使用 一文中,我们介绍了JSON-API的一些基本使用,可以先行阅读,便于理解本文一些概念。
代币的发送,也是通过Transaction进行,不同于发送ETH的是,from是token发送方地址,to是token的合约地址,value通常为0,如果不需要ETH随同token一起发送的话。data是根据不同的token和接收地址,以及数量进行编码得到的,编码格式遵循Ethereum Contract ABI格式。详细的信息可以阅读链接中以太坊的官方文章介绍,此处介绍一下实现的重要细节即可。
通常的token发送,data部分包括三个部分, 1. 指令的hash;2. 接收账户;3. 数量,由这三个部分拼接而成。
1.指令hash。
回到ERC20的代码中,发送的函数如下,根据ABI编码的规则,我们要通过web3.sha3("transfer(address,uint256)")方法计算得到值,取前4个字节(8个16进制数)得到Transaction中的指令hash。ERC20标准的transfer函数的指令hash前8字节为a9059cbb。
/** * Transfer tokens * * Send `_value` tokens to `_to` from your account * * @param _to The address of the recipient * @param _value the amount to send */ function transfer(address _to, uint256 _value) public { _transfer(msg.sender, _to, _value); }2.接收账户。 通常的以太坊账户为20字节(40个16进制数),前面加上0x。在data部分,需要将40个16进制数前面填充24个0,总共64个16进制数。
3.数量。 将数量转化成16进制(以1e-18为单位),同样填充若干个0,填充为64个16进制数。
然后将三个部分拼接而成Transaction的data。例如,向0x299432642dcc4c2f33ff0f5d41b8f4154b82ae2a地址发送1000个token。data部分凭接如下:
0x + a9059cbb + 000000000000000000000000299432642dcc4c2f33ff0f5d41b8f4154b82ae2a (接收地址)+00000000000000000000000000000000000000000000021e19e0c9bab2400000(接收数量16进制表示,以1e-18为单位)。所以发送的Transaction参数为: from: 0x发送地址; to:0x合约地址; value:0x; data:0xa9059cbb000000000000000000000000299432642dcc4c2f33ff0f5d41b8f4154b82ae2a00000000000000000000000000000000000000000000021e19e0c9bab2400000.
查看token余额,相当于是查看区块链某个位置上的数据变量值,需要通过JSON-API发送eth.getStorageAt获得。
contract TokenERC20 { // Public variables of the token string public name; string public symbol; uint8 public decimals = 18; // 18 decimals is the strongly suggested default, avoid changing it uint256 public totalSupply; // This creates an array with all balances mapping (address => uint256) public balanceOf; mapping (address => mapping (address => uint256)) public allowance;上述ERC20代码中的变量,其中mapping(address => uint256) public balanceOf;是用于存放每个账户余额的变量。获取的规则是,balanceOf是第4个参数(name是第0个),将4补充成64个16进制数,即0000000000000000000000000000000000000000000000000000000000000004.然后按照发送token的规则,将要获取余额的地址补充成64个16进制数。获得input = "64位地址"+"64位变量位置"的字符串,然后计算得到hash = web3.sha3(input)。最后通过eth.getStorageAt(contract address, hash, 'latest')得到这个地址的token余额。
