深入Ethereum Raw Transaction
每次看完raw transaction的組法,都會忘記,所以紀錄一下
使用Web3元件呼叫smart contract的function,就我所知有兩個方法 ,一個是自己組成raw transaction,另一個是用web3j產生的 java wrapper呼叫(不過最終還是組成raw transaction)。在這邊就是要介紹raw transaction到底是怎麼組成的
首先,會先對function做encoding的動作,encoding完會長得下面這樣,一堆hex字串
以上圖來說,我對addMember(address, bytes, bytes...)(參數太多,所以做省略)這個function做encoding,最前面是function的symbol,作sha3然後取前四個bytes
keccak256("addMember(address,bytes,bytes,...)") //0x9400062b56b462ed4e31c3f26b13ce3523a3881b5c19480da8856142e9b687d0
後面緊接著的就是參數了,這個很容易理解。更詳細的解釋可以參考Inside an Ethereum transaction,解釋得很清楚
接下來,就是把encoded function組成raw transaction了
組完的結果會像這樣
接下來,就是把encoded function組成raw transaction了
組完的結果會像這樣
在原本的hex字串,頭尾加上一堆不知道幹嘛的字串,本篇的重點就是在解釋這個字串。
如果,讀者有看完上面那篇Inside an Ethereum transaction,就可以知道,其實transaction的組成是由
var rawTx = { nonce, gasPrice, gasLimit, to, value, data, signature };
這裡的data就是encoded function,所以前面還有nonce, gas price, gas limit跟送給誰的地址,最後是加上signature。不過,如果你直接看,一定會納悶,感覺對但好像又不對,中間似乎穿插了莫名的值,這是因為Ethereum在做serialize的時候,選用RLP做encoding,這裡不對RLP做解釋,有興趣的可以參考這裡,還滿好懂的。
所以把上面那串raw transaction做分解,可以得到下面的圖
舉例來說,"85 04a817c800"
85就是0x80加5,以RLP的規格,資料是0-55 bytes的是以0x80開頭,然後再加上資料長度,也就是5個bytes ( len(“04a817c800”)/2,兩個hex字是一個byte ),所以開頭就是85。"f9 03ab" 這個就複雜一點,以0x80開頭,如果資料長度過長勒?! 所以在RLP定義裡,超過55 bytes長度的就以f7做base,後面接著是資料長度的數字,有點難解釋,直接用例子。
開頭"f9 03ab","03ab"代表資料長度-939 bytes,而“f9”就是0xf7 + 0x02,而0x02就是"03ab"的長度。RLP的encoding大概就是這樣。
最後的signature就是直接放rsv(把rawTx作RLP encoding然後hash再sign,然後取rsv值)
今天廢話比較少,如果有跳太快不懂的地方,請歡迎指教喔!
留言
張貼留言