Ethereum ERC20 Transaction(二)
上一篇我們介紹瞭如何建立ERC20代幣的過程,本文我們將介紹利用JSON-API介面對ERC20代幣進行的一些開發過程中的相關操作。
1. 傳送代幣。
ETH的Transaction
有幾個重要欄位,from
, to
, value
, data
(input
)。
from
: Transaction是由誰發起的。
to
: Transaction傳送到哪個地址。
value
: Transaction傳送的ETH數量。
data
: 某些api中欄位名字叫做input
,含義都一樣,代表這個Transaction附帶的資料,通常是執行某些智慧合約的命令。
代幣的傳送,也是通過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
.
2. 檢視某地址代幣餘額。
檢視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餘額。