トークンの保有数を追加する
前回の「webページにEtherの残高を表示してみる」に続き、これに独自のトークンの保有数を表示をしたい。
ICOとかのサイトに設置してチェックできる機能というのは、便利なのではないだろうか
JSON-RPCでコントラクトを実行する
トークンの保有数を取得するにはトークンのコントラクトのbalanceOf(address)
のメソッドを実行させる必要がある。
JSON-RPCを使ってコントラクトのFunctionを呼び出すには、eth_call
でコントラクトのメソッドシグネチャとエンコードされたパラメータを送信する。
そのメソッドシグネチャについてはコントラクトのFunctionをSHA3でHASH化してその最初の4byteを使う・・・とのこと
詳しくはEthereum-Contract ABIを参照。
Geth Consoleからweb3.sha3()
で、使いたいFunctionをHASH化、その先頭4byteを取得する。
> web3.sha3('balanceOf(address)').substring(0,10)
"0x70a08231"
取得した結果を32byteデータにする
(残りの桁を0で埋める)
0x70a08231000000000000000000000000
トークンの保有数を表示させたいアドレスをメソッドシグネチャに連結する
(アドレスはデタラメの適当です)
0x70a082310000000000000000000000009876543210FedcBa9876543210FedcBa98765432
出来た結果をeth_call
のdata
パラメータとして送信するのでjson部分を作成する
{
"jsonrpc":"2.0",
"method":"eth_call",
"params":
{
"to":"0x9876543210ffddeea00987654ffdedeEdEdFdFd012",
"data":"0x70a082310000000000000000000000009876543210FedcBa9876543210FedcBa98765432",
"latest",
}
"id":65534
}
出来たJSONをropstenに送る形に整え送信。
JSONが正常であればresponsのように返ってくる。
curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"0x987654321...(contract_address)...","data":"0x70a082310000000000000000000000009876543210FedcBa9876543210FedcBa98765432"},"latest"],"id":65534}' https://ropsten.infura.io/
{"jsonrpc":"2.0","id":65534,"result":"0x00000000000000000000000000000000000000000000000000000000000e57e0"}
コンソールからcurlを使って正しくレスポンスを取得できるようであれば、あとは簡単です。
PHPにトークン保有数の取得を追加する
前回に作ったweb3balance.phpのmain
Function部分を書き換えてトークンの保有数の取得を追加する
function main($address) {
// check
$address = trim($address);
if(!$address) return false;
if(!preg_match('/0x[0-9a-f]+/i',$address)) {
return false;
}
// getBalance
$data = [
"jsonrpc" => "2.0",
"method" => "eth_getBalance",
"params" => [$address,"latest"],
"id" => 65756,
];
//
$response = postJson($data);
$getBalance = json_decode($response);
$ethbalance = decodeHex($getBalance->result);
$cHash = "0x70a08231";
$contractHash = str_pad($cHash,34,"0").substr($address,2);
$contract_address = "0x987654321...(ContractAddress)";
$data = [
"jsonrpc" => "2.0",
"method" => "eth_call",
"params" => [[ "to" => $contract_address, "data" => $contractHash ],"latest"],
"id" => 65757,
];
$response = postJson($data);
$balanceOf = json_decode($response);
$tokenbalance = decodeHex($balanceOf->result) * pow(10,16);
$jsonData = [
"address" => $address,
"ethBalance" => $ethbalance,
"tokenBalance" => $tokenbalance,
"status" => "success"
];
return $jsonData;
}
PHPのトークン保有数取得の追加にあわせて、HTML表示部分にも表示枠とレスポンスの取得・入力を追加する
<form id="myForm">
ETHアドレス<br/>
<input type="text" id="address" name="address" size="64" value="Ethereum Address"><br />
ETH残高<br/>
<input type="text" id="ethbalance" name="ethbalance" size="64"><br />
TOKEN残高<br/>
<input type="text" id="tokenbalance" name="tokenbalance" size="64"><br />
<input type="button" id="btnCheck" value="check">
</form>
<script type="text/javascript">
$(function(){
$("#ethbalance").html("Response Values");
$("#btnCheck").click( function() {
var jsondata = {
address: $("#address").val()
};
console.log(JSON.stringify(jsondata));
$.ajax({
type : 'post',
url : 'web3balance.php',
data : JSON.stringify(jsondata),
contentType : 'application/JSON',
dataType : 'JSON',
scriptCharset : 'utf-8',
success : function(data) {
console.log(JSON.stringify(data));
if(data.status=="success") {
console.log("success");
$("#ethbalance").val(data.ethBalance);
$("#tokenbalance").val(data.tokenBalance);
}
else{
console.log("failer");
}
},
error : function(data) {
console.log("error");
console.log(JSON.stringify(data));
}
});
});
});
</script>
上記のコードは前に作ったものに修正を加えた感じにしております。
私の場合はコントラクトはRopstenにデプロイして置いたminaTokenをコントラクトとして使用しました。
またトークンのDecimalsが2に設定されているので、10進に変換するところは若干異なります。
これでアドレスを入力してCheck!とすると、Etherの残高と、トークンの保有数が表示されます。
最初に調べた際には結構簡単に見えたものですが、メソッドシグネチャを作成するなど部分で詰まったりしました。
この次は、Gasを消費するeth_sendTransaction
を行いたいと思います。
参考
以下の記事を参考にさせて頂きました。ありがとうございます。
https://github.com/ethereum/wiki/wiki/JSON-RPC
https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
JSON-RPC経由でEthereumのContractを作る
EthereumノードにJSON-RPC API経由でアクセスする