Solidity

如何通過 uint32, uint8web3.js 中智能合約的參數

  • July 7, 2021

我正在做估算氣體。這是我的程式碼。

var sdate = new Date('2021-07-01 00:00:00');
var edate = new Date('2021-07-31 00:00:00');
var arrDate = [];
arrDate.push(sdate/1000);
arrDate.push(edate/1000);

var arrCategory = [1,12,14];

var param1 = web3.eth.abi.encodeParameter('uint32[]',arrDate);
var param2 = web3.eth.abi.encodeParameter('uint8[]',arrCategory);

let Contract = new web3.eth.Contract(myPack.abi, myPack.ca);
Contract.methods.createTicket(param1, param2).estimateGas({from: accounts[0]})
 .then(console.log);

我遇到了錯誤

Uncaught TypeError: t.map is not a function
   at h.formatParam (index.js:218)
   at index.js:100
   at Array.map (<anonymous>)
   at h.encodeParameters (index.js:94)
   at index.js:439
   at Array.map (<anonymous>)
   at Object.d._encodeMethodABI (index.js:438)
   at Object.d._processExecuteArguments (index.js:701)
   at Object.d._executeMethod (index.js:720)
   at estimateGas (issuecfm:257)

我在 encodeParameter 之前嘗試了一些東西

大數

var BN =  web3.utils.BN;
arrDate = arrDate.map(item => {return new BN(item)});
arrCategory = arrCategory.map(item => {return new BN(item)});

和字元串

arrDate = arrDate.map(item => {return item.toString()});
arrCategory = arrCategory.map(item => {return item.toString()});

經過大量搜尋,我盡我所能。但我仍然得到同樣的錯誤。如果您能教我如何修改我的程式碼,我將不勝感激。



添加

我像這樣修改了我的程式碼。

var parameters = web3.eth.abi.encodeParameters(['uint32[]', 'uint8[]'],[arrDate, arrCategory]);
console.log(parameters);
console.log(web3.eth.abi.decodeParameters(['uint32[]', 'uint8[]'],parameters));

let Contract = new web3.eth.Contract(myPack.abi, myPack.ca);
Contract.methods.createTicket(parameters).estimateGas({from: accounts[0]})
.then(console.log);


0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000060e31e7000000000000000000000000000000000000000000000000000000000615b16ef0000000000000000000000000000000000000000000000000000000060e31e7000000000000000000000000000000000000000000000000000000000615b16ef000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000011
c {0: Array(4), 1: Array(3), __length__: 2}

我在控制台中檢查了參數的值是否正確編碼和解碼。&-一世

並遇到下一個錯誤

errors.js:33 Uncaught Error: Invalid number of parameters for "createTicket". Got 1 expected 2!
   at Object.InvalidNumberOfParams (errors.js:33)
   at Object.d._createTxObject (index.js:670)
   at estimateGas (issuecfm:261)
   at HTMLDocument.<anonymous> (issuecfm:130)
   at j (jquery-latest.min.js:2)
   at Object.fireWith [as resolveWith] (jquery-latest.min.js:2)
   at Function.ready (jquery-latest.min.js:2)
   at HTMLDocument.J (jquery-latest.min.js:2)

web.eth.abi.encodeParameters() 我相信您必須使用以下函式在數組中編碼兩個參數:

您傳入一個類型數組和一個帶有參數值的數組,如下所示:

web3.eth.abi.encodeParameters(['uint32[]','uint8[]'], [arrDate, arrCategory]);

在你的solidity合約中,你像這樣解碼數據:

function createTicket(bytes calldata params) external ... {
   (uint32[] arrDate, uint8[] arrCategory) = abi.decode(params, (uint32[], uint8[]));

我從堆棧溢出中得到了一個簡單的解決方案。

使用 web3 合約助手函式,您需要傳遞“原始”JS 參數,而不是 ABI 編碼的數據。

所以我修改了我的程式碼

let contract = new web3.eth.Contract(myPack.abi, myPack.ca);

// mind the `arrDate` and `arrCategory` instead of `param1` and `param2`
contract.methods.createTicket(arrDate, arrCategory)
   .estimateGas({from: accounts[0]})
   .then(console.log);

有用!!

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