ABI 在原始交易的“數據”參數中派生 JSON
到目前為止,這是我所擁有的,如果我錯了,請糾正我:
交易的
data
參數是我們告訴已部署的智能合約我們希望如何與之互動的地方。它包含一個十六進制 JSON,其中包含我們要與之互動的合約的所有功能的所有輸入。這個 JSON 是使用合約的 ABI 編碼的,這是一份關於合約可以採用和返回的格式的手冊。為了適合data
參數,我們要發送的 JSON 必須轉換為十六進制。假設這一切都是正確的,我正在尋找非
data
十六進制 JSON 的範例,以了解我應該使用 ABI 編寫的內容。
數據不是 JSON 數據的十六進製表示。Solidity 有一個自定義格式,在Contract ABI Specification中有描述。本質上,有兩種不同類型的類型,靜態和動態。靜態類型是始終適合 32 字節(= 256 位)數據的類型,例如
uint256
、address
等。動態類型是不適合這 32 字節數據的類型,例如bytes
和string
數組(包括類似的東西uint256[]
)。靜態類型的編碼順序與您的 Solidity 函式相同。所以假設我們有一個這樣的函式:
function foo(uint256 bar, address baz) external
事務
data
欄位以函式選擇器開頭,指定要呼叫的函式。在這種情況下,是a68b44f8
(Keccak 雜湊的前四個字節foo(uint256,address)
。之後,我們將 的值按bar
順序baz
排列,其中每個值的長度為 32 個字節。如果我們想對12345
forbar
和0x4bbeeb066ed09b7aed07bf39eee0460dfa261520
for進行編碼baz
,則數據變為:0xa68b44f8 (function selector) 0000000000000000000000000000000000000000000000000000000000003039 (bar) 0000000000000000000000004bbeeb066ed09b7aed07bf39eee0460dfa261520 (baz)
在動態類型的情況下,我們編碼一個指向動態值的指針。該值附加到數據的末尾,從值的長度(32 字節)開始。所以如果我們有這樣的函式:
function foo(uint256[] bar, address baz) external
並且我們要對 和 相同的地址進行編碼
[12345, 67890]
,bar
數據baz
變為:0xd22ec959 0000000000000000000000000000000000000000000000000000000000000040 (pointer to bar) 0000000000000000000000004bbeeb066ed09b7aed07bf39eee0460dfa261520 (baz) 0000000000000000000000000000000000000000000000000000000000000002 (length of bar) 0000000000000000000000000000000000000000000000000000000000003039 (bar[0]) 0000000000000000000000000000000000000000000000000000000000010932 (bar[1])
合約 ABI 規範描述了 Solidity 中不同類型的編碼方式。我寫了一個更詳細的交易數據解釋,你可以在這裡找到。