やったこと
自分の保有しているトークン価格が
市場ベースでいくらほどなのか知りたいときがある。
これまでドルベースではethplorerのサービスから把握できていたが、最近のICOの人気のせいか、レスポンスが遅い。
そこで、せっかくEthereumの自ノードも立てているため、
自前で日本円に換算してみるスクリプトを書いてみた。
↓こんな感じでプロンプト上からトークンの保有残高と日本円を標準出力する。
前提
Ethereumの自ノードを構築し、json-rpcでブロックチェーンの情報を取得できる環境 で確認する。
「スクレイピング: 仮想通貨の時価総額推移について」でも紹介したCryptoCurrency MarketCapitalizationsのAPIを利用する。
CryptoCurrency MarketCapitalizations
Step0.全体のイメージ
やっていることは、 自身のトークン残高を取得する方法からそんなに変わらない。
海外サービスからAPIでトークン市場取引価格を取得し、自身のトークン残高と掛け算をするだけ。
Step1. APIを利用してトークンあたりの市場取引価格を取得する。
CryptoCurrency MarketCapitalizationsのAPIの説明でもわかるように
下記URLのようにトークンあたりの市場取引価格をJPYベースでgetする。
https://api.coinmarketcap.com/v1/ticker/?convert=JPY
[
{
"id": "bitcoin",
"name": "Bitcoin",
"symbol": "BTC",
"rank": "1",
"price_usd": "4551.16",
"price_btc": "1.0",
"24h_volume_usd": "1980450000.0",
"market_cap_usd": "75247855429.0",
"available_supply": "16533775.0",
"total_supply": "16533775.0",
"percent_change_1h": "0.29",
"percent_change_24h": "-0.99",
"percent_change_7d": "9.22",
"last_updated": "1504128263",
"price_jpy": "501968.371736",
"24h_volume_jpy": "218432940570.0000000000",
"market_cap_jpy": "8299432115399"
},
{
"id": "ethereum",
"name": "Ethereum",
"symbol": "ETH",
"rank": "2",
"price_usd": "380.237",
"price_btc": "0.0830763",
"24h_volume_usd": "1374760000.0",
"market_cap_usd": "35870045070.0",
"available_supply": "94336020.0",
"total_supply": "94336020.0",
"percent_change_1h": "-0.27",
"percent_change_24h": "2.48",
"percent_change_7d": "19.33",
"last_updated": "1504128261",
"price_jpy": "41938.0878202",
"24h_volume_jpy": "151628604296.0000000000",
"market_cap_jpy": "3956272272978"
},....
]
上記APIのレスポンスで
- "symbol":トークン名称
- "price_jpy":取引価格(日本円)
となっていることがわかる。
Step2 pythonで記述する。
上記APIでアクセスする際に、抽出したいのが
トークン名称"symbol"ごとの取引価格"price_jpy"なので
その全ての関係を返す関数を作っておく。
import json
import requests as rs
def get_market_cap(url):
res=rs.get(url)
data=json.loads(res.text)
dict_price = {}
for i in data:
d=i['symbol']
n=i['price_jpy']
dict_price.update({d:n})
return dict_price;
また、自身が持っているトークン種別と、トークンのコントラクトアドレス、
トークンの桁数(decimals)の関係を仕込んでおく。
token_symboles=["SNT","MCO","VSL","BAT","BNT","GNT","MGO","REP","SNM","TKN","BET"]
dict_address={"SNT":"0x744d70FDBE2Ba4CF95131626614a1763DF805B9E",
"MCO":"0xB63B606Ac810a52cCa15e44bB630fd42D8d1d83d",
"VSL":"0x5c543e7AE0A1104f78406C340E9C64FD9fCE5170",
"BAT":"0x0d8775f648430679a709e98d2b0cb6250d2887ef",
"BNT":"0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c",
"GNT":"0xa74476443119A942dE498590Fe1f2454d7D4aC0d",
"MGO":"0x40395044Ac3c0C57051906dA938B54BD6557F212",
"SNM":"0x983f6d60db79ea8ca4eb9968c6aff8cfa04b3c63",
"TKN":"0xaaaf91d9b90df800df4f55c205fd6989c977e73a",
"BET":"0x8aa33a7899fcc8ea5fbe6a608a109c3893a1b8b2",
"REP":"0xe94327d07fc17907b4db788e5adf2ed424addff6",
}
dict_decimals={"SNT":18,"MCO":8,"VSL":18,"BAT":18,"BNT":18,"GNT":18,
"MGO":8,"SNM":18,"TKN":8,"BET":18,"REP":18}
スクリプト全体
import json
import requests as rs
def get_market_cap(url):
res=rs.get(url)
data=json.loads(res.text)
dict_price = {}
for i in data:
d=i['symbol']
n=i['price_jpy']
dict_price.update({d:n})
return dict_price;
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 = rs.post(url, data=json.dumps(payload), headers=headers).json()
i=int(response["result"],16)
return i;
def get_tokenBalance(contract_address):
url = "http://localhost:8545"
a="0x○○○○○○○○○○○○○○○○○○○○○○○○○○○○○" #トークンを保管しているアドレス
b="0x70a08231" #コントラクトメソッド(balanceOf(addres)のハッシュ値)
c='000000000000000000000000'
d=a[2:42] #先頭0xの表記を省略
data= b + c + d
balance=eth_call(url,contract_address,data)
return balance;
if __name__ == "__main__":
url_market_cap="https://api.coinmarketcap.com/v1/ticker/?convert=JPY&limit=500"
token_symboles=["SNT","MCO","VSL","BAT","BNT","GNT","MGO","REP","SNM","TKN","BET"]
dict_address={"SNT":"0x744d70FDBE2Ba4CF95131626614a1763DF805B9E",
"MCO":"0xB63B606Ac810a52cCa15e44bB630fd42D8d1d83d",
"VSL":"0x5c543e7AE0A1104f78406C340E9C64FD9fCE5170",
"BAT":"0x0d8775f648430679a709e98d2b0cb6250d2887ef",
"BNT":"0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c",
"GNT":"0xa74476443119A942dE498590Fe1f2454d7D4aC0d",
"MGO":"0x40395044Ac3c0C57051906dA938B54BD6557F212",
"SNM":"0x983f6d60db79ea8ca4eb9968c6aff8cfa04b3c63",
"TKN":"0xaaaf91d9b90df800df4f55c205fd6989c977e73a",
"BET":"0x8aa33a7899fcc8ea5fbe6a608a109c3893a1b8b2",
"REP":"0xe94327d07fc17907b4db788e5adf2ed424addff6",
}
dict_decimals={"SNT":18,"MCO":8,"VSL":18,"BAT":18,"BNT":18,"GNT":18,
"MGO":8,"SNM":18,"TKN":8,"BET":18,"REP":18}
dict_price=get_market_cap(url_market_cap)
Total_asset=0;
for token in token_symboles:
token_decimal=dict_decimals[token]
token_balance=get_tokenBalance(dict_address[token]) / pow(10,token_decimal)
token_yen=token_balance*float(dict_price[token])
Total_asset+=token_yen
print("トークン:",token)
print("保有トークン数:",token_balance)
print("日本円換算:",token_yen,"円")
print("(1トークンあたり):",dict_price[token],"円")
print("--------------")
print("総額:",Total_asset)
出力結果
トークン: SNT
保有トークン数: 3232.58036728
日本円換算: 16960.2763496179 円
(1トークンあたり): 5.2466681173 円
--------------
トークン: MCO
保有トークン数: 22.80000912
日本円換算: 47004.36136561702 円
(1トークンあたり): 2061.5939721 円
--------------
トークン: VSL
保有トークン数: 276.44170415
日本円換算: 31065.573047326245 円
(1トークンあたり): 112.376579152 円
--------------
トークン: BAT
保有トークン数: 621.84391775
日本円換算: 16295.043185794791 円
(1トークンあたり): 26.204394255 円
--------------
トークン: BNT
保有トークン数: 36.22750590057683
日本円換算: 12385.770558238028 円
(1トークンあたり): 341.888580247 円
--------------
トークン: GNT
保有トークン数: 99.66515485
日本円換算: 3434.502622963604 円
(1トークンあたり): 34.4604152588 円
--------------
トークン: MGO
保有トークン数: 62.98742702
日本円換算: 6127.409746267665 円
(1トークンあたり): 97.279886418 円
--------------
トークン: REP
保有トークン数: 5.6
日本円換算: 15007.39522464 円
(1トークンあたり): 2679.8920044 円
--------------
トークン: SNM
保有トークン数: 871.36448801
日本円換算: 7955.87581581428 円
(1トークンあたり): 9.1303649911 円
--------------
トークン: TKN
保有トークン数: 142.77681278
日本円換算: 43070.72642552058 円
(1トークンあたり): 301.664714227 円
--------------
トークン: BET
保有トークン数: 504.0
日本円換算: 6400.203260724 円
(1トークンあたり): 12.6988159935 円
--------------
総額: 205707.13760252408
自身の保有するトークン残高が日本円ベースで確認できる。