如何通過 JSON-RPC 返回數組的契約呼叫獲取 JavaScript 中的數組元素?
我的 Solidity 合約中有一個函式,其原型是:
function checkLastCustomerInvoices() public view returns (bytes32 [] memory)
當我從 Truffle 控制台呼叫它時,它返回一個元素數組,即:
松露(開發)> myContractInstance.checkLastCustomerInvoices();
$$ ‘0x0000000000000000000000000000000000000000000000000000657567656f74’, ‘0x0000000000000000000000000000000000000000000000000000656e61756c74’, ‘0x0000000000000000000000000000000000000000000000000065726365646573’ $$ 當我使用 JSON-RPC 從瀏覽器呼叫它時,使用 JavaScript 程式碼:
function checkLastCustomerInvoices() { myContractInstance.checkLastCustomerInvoices(function(err,res){ if (err) console.log(err); else { console.log(res); } } ); return false; }
它在我的瀏覽器控制台中返回:
函式 checkLastCustomerInvoices() 數組 [“0x000000000000000000000000000000000000000000000000000000000000000000020”] {“ID”:1,“jsonrpc”:“2.0”,“結果”:“0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000657567656f740000000000000000000000000000000000000000000000000000656e61756c740000000000000000000000000000000000000000000000000065726365646573”}
所以 JSON-RPC 返回的結果似乎是一個以某種方式連接的字元串:
0x 0000000000000000000000000000000000000000000000000000000000000020 0000000000000000000000000000000000000000000000000000000000000003 000000000000000000000000000000000000000000000000000000657567656f74 000000000000000000000000000000000000000000000000000000656e61756c74 0000000000000000000000000000000000000000000000000065726365646573
除了 0x,第一行是 32(有什麼用?)第二行是元素的數量,其他 3 行是我的數組元素。
這種編碼在哪裡描述?是否有用於將此字元串解析為 JavaScript 數組的標準 JavaScript 方法?
謝謝
不確定如何從瀏覽器執行此操作,但從(客戶端)節點腳本,您可以執行以下操作:
const web3_eth_abi = require("web3-eth-abi"); const array = web3_eth_abi.decodeParameter("uint256[]", yourReturnedObject.result);
數組用 32 個字節編碼,表示距數據開頭的位置(偏移量)。然後在那個偏移處,你會發現另外 32 個字節顯示長度。之後,您將擁有所有數組元素。
在您的情況下,前 32 個字節顯示偏移量為 0x20 = 32,然後在位置 32 我們有另外 32 個字節顯示長度為 1,然後 1 個 32 字節的記錄對實際元素進行編碼。
在下面找到一個詳細的範例以更好地理解這一點。
以下文章更詳細地解釋了這一點: https ://medium.com/@hayeah/how-to-decipher-a-smart-contract-method-call-8ee980311603
> encode_abi( ["uint256[]", "uint256[]", "uint256[]"], [[0xa1, 0xa2, 0xa3], [0xb1, 0xb2, 0xb3], [0xc1, 0xc2, 0xc3]] ).hex() /************* HEAD (32*3 bytes) *************/ // arg1: look at position 0x60 for array data 0000000000000000000000000000000000000000000000000000000000000060 // arg2: look at position 0xe0 for array data 00000000000000000000000000000000000000000000000000000000000000e0 // arg3: look at position 0x160 for array data 0000000000000000000000000000000000000000000000000000000000000160 /************* TAIL (128**3 bytes) *************/ // position 0x60. Data for arg1. // Length followed by elements. 0000000000000000000000000000000000000000000000000000000000000003 00000000000000000000000000000000000000000000000000000000000000a1 00000000000000000000000000000000000000000000000000000000000000a2 00000000000000000000000000000000000000000000000000000000000000a3 // position 0xe0. Data for arg2. 0000000000000000000000000000000000000000000000000000000000000003 00000000000000000000000000000000000000000000000000000000000000b1 00000000000000000000000000000000000000000000000000000000000000b2 00000000000000000000000000000000000000000000000000000000000000b3 // position 0x160. Data for arg3. 0000000000000000000000000000000000000000000000000000000000000003 00000000000000000000000000000000000000000000000000000000000000c1 00000000000000000000000000000000000000000000000000000000000000c2 00000000000000000000000000000000000000000000000000000000000000c3