Ethereumのトークン残高についてノード上から取得できたので記録しておく。
前提と環境:
トークンはERC20標準に準拠するトークンを対象にする。
下記のライブネット接続環境で確認する。
http://qiita.com/umidachi/items/44a50ce86e94ff0df8f2
1. トークンのコントラクトアドレスを取得する。
Ethereumブロックチェーン上のトークンごとのコントラクトアドレスが必要になる。
取得したいトークンのコントラクトアドレスについては、下記URLからでもアドレスを確認できる。
https://ethplorer.io/
これまでにICOなどでブロックチェーン上に排出されたトークンは多いので、ここではターゲットを次の3つに限定する。
例:
SYMBOL | トークン名称 | コントラクトアドレス | URL |
---|---|---|---|
SNT | StatusNetwork | 0x744d70FDBE2Ba4CF95131626614a1763DF805B9E | https://status.im |
MCO | Monaco | 0xB63B606Ac810a52cCa15e44bB630fd42D8d1d83d | https://www.mona.co/ |
VSL | vSlice | 0x5c543e7AE0A1104f78406C340E9C64FD9fCE5170 | http://www.vslice.io |
2.トークンコントラクト上のメソッドの確認
特定のコントラクトアドレスのトークン残高を取得するには、呼び出されたトークンコントラクト上でのメソッドbalanceOf(address)関数を使用する必要がある。(実際のトランザクションとしてEthereumブロックチェーンに送信する必要はない)
ここではjson-apiからeth_callメソッドを用いる。
そのためSHA3 256アルゴリズムでエンコードされたトークンコントラクト上のメソッド、balanceOf(address)'の値を取得する。
> web3.sha3('balanceOf(address)').substring(0,10)
結果:
"0x70a08231"
結果として"0x70a08231"が得られる。
上記結果を16進数32byteデータとするため、残り0埋めする。
eth_callメソッド上では、次のパラメータを指定する
-to: コントラクトアドレス
-data: "0x70a08231000000000000000000000000"+"保管しているトークンのアドレス"
3.APIリクエストの作成
以上から、pythonでjson-rpc api用にリクエストを作成してみる。
import requests
import json
def eth_call(url,to,data):
headers = {'content-type': 'application/json'}
payload = {
"jsonrpc": "2.0",
"method": "eth_call",
"params":[{"to":to,
"data":data},
"latest"],
"id": 0
}
response = requests.post(url, data=json.dumps(payload), headers=headers).json()
i=int(response["result"],16)
return i;
if __name__ == "__main__":
url = "http://localhost:8545"
a="0x○○○○○○○○○○○○○○○○○○○○○○○○○○○○~" #トークンを保管しているアドレス
b="0x70a08231" #コントラクトメソッド(balanceOf(addres)のハッシュ値)
c='000000000000000000000000'
d=a[2:42] #先頭0xの表記を省略
data= b + c + d
contract_address={"SNT":"0x744d70FDBE2Ba4CF95131626614a1763DF805B9E",
"MCO":"0xB63B606Ac810a52cCa15e44bB630fd42D8d1d83d",
"VSL":"0x5c543e7AE0A1104f78406C340E9C64FD9fCE5170"}
SNT_token=eth_call(url,contract_address['SNT'],data)
MCO_token=eth_call(url,contract_address['MCO'],data)
VSL_token=eth_call(url,contract_address['VSL'],data)
print("SNT TokenBalance:",SNT_token/ pow(10,18) ) #下位18桁 少数
print("MCO TokenBalance:",MCO_token/ pow(10,8) ) #下位8桁 少数
print("VSL TokenBalance:",VSL_token/ pow(10,18) ) #下位18桁 少数
SNT TokenBalance: 3232.58036728
MCO TokenBalance: 22.80000912
VSL TokenBalance: 276.44170415
上記結果から、Statu Network ,Monaco ,Vsliceのトークンの保有残高が確認できた。
参考:
-
「ERC: Token standard #20」
https://github.com/ethereum/EIPs/issues/20 -
「How to get balance of a token in 1 line of code on Ubuntu」https://ethereum.stackexchange.com/questions/17607/how-to-get-balance-of-a-token-in-1-line-of-code-on-ubuntu
-
How can I retrieve my account's Augur (REP) token balance via JSON-RPC?
https://ethereum.stackexchange.com/questions/9034/how-can-i-retrieve-my-accounts-augur-rep-token-balance-via-json-rpc?noredirect=1&lq=1 -
Ethereum Contract ABI
https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI -
JSON RPC API
https://github.com/ethereum/wiki/wiki/JSON-RPC