4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Ethereum】Geth APIにおけるContract functionへの引数の渡し方

Posted at

はじめに

一年前ぐらいに投稿するつもりだったものを供養する。
gethのバージョンは古いが、現在でもここの仕様はおそらく変わっていない。

GethにはJSON-RPC APIがあり、基本的にほとんどの機能がAPI経由で実行することができる。そこでコントラクトをBlockchainにデプロイしようと思った時、コントラクトに値を渡す方法がわからなかったので、忘備録として記録しておく。

以下に詳しくは書いてある。
Ethereum Contract ABI - Github Ethereum wiki

基本的なEthereum APIの使い方は以下
JSON RPC - Github Ethereum wiki

環境

  • geth 1.6.5-stable

やり方

基本的には

0x(Keccak(関数名)の先頭4byte)(渡す 引数パラメータ群)

をdataとしてContract Account宛に送ることでコントラクトの関数実行が可能である。
デプロイ時にはコントラクトをコンパイルしたソースコードの末尾に渡すパラメータ群を記述する。コンストラクタの関数名は入れる必要はないので、パラメーター群をそのまま以下のような形式で書けば良い。

引数パラメータの記述方法

基本的に32byte毎に引数一つとして記述する。例えば以下のような関数を考える。

foo.solidity
function fuga(uint256 hoge,address user,string fuga) {
    _hoge = hoge;
    _user = user;
    _fuga = fuga;
}

この場合、uint256型とaddress型、string型のパラメータを渡したい。

Uint256の場合

先頭はuint256型なので、渡したい値を16進数にし、パラメータ一つの全体が32byteの長さになるように左を0埋めする。

1234
-> 00000000000000000000000000000000000000000000000000000000000004d2

addressの場合

次にaddress型だが、これも左0埋めして32byteにする。

0xb8bac7b269f97350e1df5b57a45302ded9b177d3
-> 000000000000000000000000b8bac7b269f97350e1df5b57a45302ded9b177d3

Stringの場合

stringの場合は、パラメータ全体の末尾にその長さとともに記述し、正規の記述するべき順序の場所の32byteには、先頭から何byte後の部分からその順序にあるべきStringのデータが記述されているかを記述する。つまり、この場合はパラメータが3つあり、その末尾になるので、正規の記述するべき順序の場所の32byteには先頭から96byte後あることを示す。その後、末尾には、先頭32byteにそのString長の数値を左0埋め、その後ASCIIでStringを記述する。

つまり、3番目のパラメータとして、

先頭から96byte後にStringの記述開始
-> 0000000000000000000000000000000000000000000000000000000000000060

そして末尾に

hogehoge
-> 0000000000000000000000000000000000000000000000000000000000000008
686f6765686f6765000000000000000000000000000000000000000000000000

を記述する。

関数名

関数名は引数を含んだものをKeccakするので、

keccak("fuga(uint256 hoge,address user,string fuga)")
-> 5e03f4b96ab58326c1381d7b3218d9318f3b013f7d044e6d039e67f8cae2ed4d

これの先頭4byteを持つ。

送信データ

上の3つをパラメータとして、実際に送信するdataは以下である。わかりやすく32byte毎に改行している。

0x5e03f4b9
00000000000000000000000000000000000000000000000000000000000004d2
000000000000000000000000b8bac7b269f97350e1df5b57a45302ded9b177d3
0000000000000000000000000000000000000000000000000000000000000060
0000000000000000000000000000000000000000000000000000000000000008
686f6765686f6765000000000000000000000000000000000000000000000000

eth_sendTransactionのメソッドを使ってContract Account向けにトランザクションを発行することで実行できる。

# おわりに
他にも配列や、渡す型によって記述方法がそれぞれ違うのだが、全てを網羅するのは諦めた。ドキュメント読め。正直この辺の話は上に挙げたABIのページに書いてあるのだが、非常にわかりづらく英語もわからないのでMistでコンパイルし、トランザクションデータを作らせて、というのを繰り返して諸行無常をした。ちゃんとドキュメントには書いてあるので読もう。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?