Solidity

如何通過 JSON-RPC 返回數組的契約呼叫獲取 JavaScript 中的數組元素?

  • February 13, 2022

我的 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

引用自:https://ethereum.stackexchange.com/questions/66343