本文写于2019
获取ERC20 Token的余额
https://blog.csdn.net/wypeng2010/article/details/81362562
- 通过REST查询
curl -X POST --data-binary '{"jsonrpc":"2.0","method":"eth_call","params":[{"from": "0x954d1a58c7abd4ac8ebe05f59191Cf718eb0cB89","to": "0xee8e2882e07f89685430c27e2f77636b08df3c81","data": "0x70a08231000000000000000000000000954d1a58c7abd4ac8ebe05f59191Cf718eb0cB89"},"latest"],"id":1}' -H 'content-type: application/json;' http://127.0.0.1:18545
{"jsonrpc":"2.0","id":1,"result":"0x000000000000000000000000000000000000000143127b10e822e2cbd2000000"}
- 在geth console中查询
http://cw.hubwiz.com/card/c/web3.js-1.0/1/2/25/
>
> eth.call({from:"0x954d1a58c7abd4ac8ebe05f59191Cf718eb0cB89", to:"0xee8e2882e07f89685430c27e2f77636b08df3c81", data:"0x70a08231000000000000000000000000954d1a58c7abd4ac8ebe05f59191Cf718eb0cB89"})
"0x000000000000000000000000000000000000000143127b10e822e2cbd2000000"
>
关于ERC20 标准的解析
https://www.jianshu.com/p/a5158fbfaeb9
-
//代币名字 function name() constant returns (string name) //代币简称 function symbol() constant returns (string symbol) //支持几位小数点后几位, balanceOf返回的值除以此值才是真正的余额 function decimals() constant returns (uint8 decimals) //发行代币的总量 function totalSupply() constant returns (uint256 totalSupply) //输入地址,可以获取该地址代币的余额。 function balanceOf(address _owner) constant returns (uint256 balance) //调用transfer函数将自己的token转账给_to地址,_value为转账个数 function transfer(address _to, uint256 _value) returns (bool success) //-------------------------------------------- //批准_spender账户从自己的账户转移_value个token。可以分多次转移。 function approve(address _spender, uint256 _value) returns (bool success) //与approve搭配使用,approve批准之后,调用transferFrom函数来转移token。 function transferFrom(address _from, address _to, uint256 _value) returns (bool success) //返回_spender还能提取token的个数。 function allowance(address _owner, address _spender) constant returns (uint256 remaining) //approve、transferFrom及allowance解释: //账户A有1000个ETH,想允许B账户随意调用100个ETH。 //A账户按照以下形式调用approve函数approve(B,100)。 //当B账户想用这100个ETH中的10个ETH给C账户时, //则调用transferFrom(A, C, 10)。这时调用allowance(A, B) //可以查看B账户还能够调用A账户多少个token。
-
常用函数的 hash
18160ddd -> totalSupply()
70a08231 -> balanceOf(address)
dd62ed3e -> allowance(address,address)
a9059cbb -> transfer(address,uint256)
095ea7b3 -> approve(address,uint256)
23b872dd -> transferFrom(address,address,uint256)
自己计算
>>> from ethereum.utils import *
>>>
>>> sha3('name()').encode('hex')[:4*2]
'06fdde03'
>>>
>>> sha3('symbol()').encode('hex')[:4*2]
'95d89b41'
>>>
>>>
>>> sha3('decimals()').encode('hex')[:4*2]
'313ce567'
>>>
>>>
>>> sha3('totalSupply()').encode('hex')[:4*2]
'18160ddd'
>>>
>>> sha3('balanceOf(address)').encode('hex')[:4*2]
'70a08231'
>>>
>>>
>>> sha3('allowance(address,address)').encode('hex')[:4*2]
'dd62ed3e'
>>>
>>>
>>> sha3('transfer(address,uint256)').encode('hex')[:4*2]
'a9059cbb'
>>>
>>>
>>> sha3('approve(address,uint256)').encode('hex')[:4*2]
'095ea7b3'
>>>
>>>
>>> sha3('transferFrom(address,address,uint256)').encode('hex')[:4*2]
'23b872dd'
>>>
>>>
- 获取 symbol
>
> eth.call({from:"0x954d1a58c7abd4ac8ebe05f59191Cf718eb0cB89", to:"0xee8e2882e07f89685430c27e2f77636b08df3c81", data:"0x95d89b41"})
"0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003424a430000000000000000000000000000000000000000000000000000000000"
-
获取小数位数
> eth.call({from:"0x954d1a58c7abd4ac8ebe05f59191Cf718eb0cB89", to:"0xee8e2882e07f89685430c27e2f77636b08df3c81", data:"0x313ce567"}) "0x0000000000000000000000000000000000000000000000000000000000000012" >
关于字符串的解码
//以下是 python3
from eth_utils import to_bytes
encoded = to_bytes(hexstr="0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000067374617475730000000000000000000000000000000000000000000000000000")
from eth_abi import decode_abi
decoded = decode_abi(['string', 'uint256'], encoded)
assert decoded == (b'status', 12)
//使用python2实现
def my_to_bytes(hexstr='0x234234'):
return hexstr.replace('0x', '').decode('hex')
def decode_abi_string(data):
pass
def ceil32(x: int) -> int:
return x if x % 32 == 0 else x + 32 - (x % 32)
def encode_string(text):
b = text.encode('hex')
padded_value = b.ljust(ceil32(b), '0') #右补0
encode_size = hex(len(b))[2:].replace('L', '').rjust(64, '0')
0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000045553445400000000000000000000000000000000000000000000000000000000