Web3js

僅使用 ABI 呼叫合約函式,無需原始碼

  • November 15, 2019

我有一些契約的 MyContract.json 文件(假設我沒有它的原始碼)。在 .json 文件中,有 abi 和字節碼。如果我想部署這樣的契約(通過 web3js),我將面臨以下問題。但是,當有數千份契約時,這個問題變得更加複雜,這是我的最終任務。但在這裡,我只是為了理解目的而將自己限制在一份契約中。

  1. 如果這樣的合約在其建構子中需要一些參數,那麼我如何知道它的參數具有有效值,以便可以成功部署它。
  2. 如何呼叫它的不同功能(getter、setter)?

**對於問題沒有。1個;**我在這里分享我的部署程式碼。如果合約具有在其參數中採用所有者地址的建構子,則它是有效且有效的。這段程式碼在一些已知的帶有原始碼的合約上進行了測試。但是,如果建構子不帶參數或不同的參數或許多其他參數,則此程式碼將無法部署,因為我必須傳遞有效數量的參數和有效值。

var compiledContract = require('./build/MyContract.json');

async function deployCon() {

const contract = new web3.eth.Contract(compiledContract.abi);
const params = {
   data: '0x' + compiledContract.bytecode,
   arguments: [account1]
};
const transaction = contract.deploy(params); 
const options = {
   data: transaction.encodeABI(),
   gas: await transaction.estimateGas({from: account1})
};
// console.log(options)
const signed = await web3.eth.accounts.signTransaction(options, privateKey1);
receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction);
console.log(`Contract deployed at address: ${receipt.contractAddress}`);
return receipt;

}

對於問題沒有。2;我完全失明如何呼叫此處顯示的契約功能??????? (這將通過 .json 文件的 abi 以及參數來了解!)。

var  myContAddr = receipt.contractAddress;
   var myContractAbiDefenition = compiledContract.abi;
   var myContractInstance = new web3.eth.Contract(myContractAbiDefenition, myContAddr);
   await myContractInstance.methods.???????.send({from: account1, value: web3.utils.toWei(amount, 'ether')})

對於你的問題沒有。1:"type": "constructor"您的ABI. 從此對像中,您可以看到inputs具有參數數組及其名稱和類型的 。例子:

 {
   "inputs": [
     {
       "internalType": "uint256",
       "name": "_ff",
       "type": "uint256"
     },
     {
       "internalType": "string",
       "name": "_name",
       "type": "string"
     }
   ],
   "payable": false,
   "stateMutability": "nonpayable",
   "type": "constructor"
 }

在上面的例子中,可以看到建構子有兩個參數:_ffname類型分別為uint256string

對於問題沒有。2:一旦合約被實例化,你可以使用 .log 記錄所有方法以及公共狀態變數console.log(myContractInstance.methods)

否則,您可以查看ABItype 在哪裡function。但這可能是一種更複雜的方式。

更新:

let abi = JSON ABI;

for (let item of abi) {
   // this will return an array of constructor parameters along with their name and type
   if (item.type === "constructor") console.log(item.inputs);
   // result [{internalType: "uint256", name: "_ff", type: "uint256"}, {internalType: "string", name: "_name", type: "string"}]

   // this will return only the names
   // you can push the names into array
   // then iterate over the array to call them
   if (item.type === "function") console.log(item.name);
}

希望它會有所幫助。

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