以太坊ABI生成を理解する

3814 ワード

以太坊公式ABI紹介住所:https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
いずれも英語で何度も見てから分かるように、ABI符号化ルールをまとめ、特にその複数の入力パラメータのメソッド体に動的パラメータを含むメソッドは、要求呼び出し時のABI符号化生成ルールを以下のようにまとめた.
公式文書の例を見てみましょう
function sam(bytes name, bool z, uint[] data)

samという関数メソッドを呼び出し、"dave"true and [1,2,3]のような3つの要求パラメータを入力したい場合.ABI符号化を生成する方法は、以下のようにいくつかのステップに分けられる.
1.関数メソッドの符号化.パラメータ名を削除し、パラメータタイプ:sam(bytes,bool,uint 256[])のみを保持してから行います(Keccakハッシュ値は4バイト前).符号化後の結果は0 xa 5643 bf 2である
2.最初の要求パラメータbytesが動的タイプに属することを分析し、動的タイプの要求パラメータ符号化には、まず要求パラメータの配置位置のパラメータを符号化する必要がある(少し拗ねている.つまり、「dave」を伝えるという意味である.では、この「dave」が最終的なABI要求体に置かれているどの受信者かを確認してください).分析の開始:
a.最初の32ビットは最初のパラメータに属するが、ダイナミックタイプであるため、ここでは「dave」を符号化するパラメータの配置位置の値(入力パラメータの符号化ではない)が必要であり、位置がどこにあるかを特定せず、一時的に32ビット立っている
b.第2の32ビットは第2の要求パラメータに属し、boolタイプであり、静的タイプに属する.入力値を直接変換できます.ここではtrue、符号化後の値は0 x 00000000000000000000000000000000000000000000001(2番目の32ビット)です.
c.3番目の32ビットは3番目の要求パラメータに属し、動的タイプでもあるため、ここでは[1,2,3]のパラメータ配置位置の値(入力パラメータの符号化ではない)を置く必要があり、この場合もどれだけなのか分からないので、次に下ります.
d.4番目の32ビット.静的タイプで計算するとsam法では3つの要求パラメータがあり,32ビット毎に上にはすでに3つの32ビットの符号化があり,符号化が完了しているが,ここでは2つの動的タイプがあり,1つ目の32ビットと3つ目の32ビットがパラメータの置かれた位置の値に占められ,1つ目と3つ目の動的タイプの値はまだ符号化されていないので,4つ目の32ビットはこの「dave」パラメータを置く符号化情報を用い,なお、ここでは「dave」の符号化位置を32*3=96とし、96を16進数符号化して32ビットを足した結果、0 x 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060(第1 32位)となった.最初の32ビットの値を決定した後、4番目のビットが「dave」パラメータを伝える値を見てみましょう.ダイナミックタイプであることに注意して、「dave」の符号化値を直接伝えることはできません.ここではダイナミックタイプの長さを伝えています.「dave」の長さは4なので、16進数符号化して32ビットを足した結果、0 x 00000000000000000000000000000000000000000000000000004(4番目の32ビット)
e.5番目の32位.上から4番目に「dave」のパラメータ長値が伝わっているので、5番目が「dave」の符号化値、utf 8符号化「dave」のHex値で、右から32桁を足した結果、0 x 6461766500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000(5番目の32位)
f.6番目の32ビット.上記の手順で1番目と2番目の入力パラメータの両方の符号化が完了し、ここでは3番目のパラメータ[1,2,3]の長さ値を置くべきである.注意:この時点で3番目の32ビットの値は5*32=160で、16進数に換算して32ビットを足した値は、0 x 00000000000000000000000000000000000000000000000000000000000000000000000 a 0(3番目の32ビット)です.続いて6番目の32ビットの値の長さを3にし、16進符号化に変換して32ビットを足した結果、0 x 00000000000000000000000000000000000000000000000000000000003(6番目の32ビット)
g.7番目の32ビット.[1,2,3]は3つのパラメータであるため、ここでは3つのuint 256に分けなければならない.7位はパラメータ1の16進符号化で32位を足した結果:0 x 00000000000000000000000000000000000000000000000000001(7位32位)
h.8番目の32ビット.パラメータ2の16進符号化および32ビット補正の結果は、0 x 00000000000000000000000000000000000000000000002(8番目の32ビット)
i.9番目の32ビット.パラメータ3の16進符号化および32ビット補正の結果は、0 x 00000000000000000000000000000000000000000000000000003(9番目の32ビット)
最終的な変換結果は次のとおりです.
0xa5643bf2
0000000000000000000000000000000000000000000000000000000000000060
0000000000000000000000000000000000000000000000000000000000000001
00000000000000000000000000000000000000000000000000000000000000a0
0000000000000000000000000000000000000000000000000000000000000004
6461766500000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000003
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000003