Help us understand the problem. What is going on with this article?

Ethereumベース(ERC20標準)のトークン残高を取得する

More than 1 year has passed since last update.

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)'の値を取得する。

gethコンソール
> web3.sha3('balanceOf(address)').substring(0,10)

結果:
"0x70a08231"

結果として"0x70a08231"が得られる。
上記結果を16進数32byteデータとするため、残り0埋めする。

eth_callメソッド上では、次のパラメータを指定する
-to: コントラクトアドレス
-data: "0x70a08231000000000000000000000000"+"保管しているトークンのアドレス"

3.APIリクエストの作成

以上から、pythonでjson-rpc api用にリクエストを作成してみる。

get_token.py
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のトークンの保有残高が確認できた。

参考:

umidachi
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away