У меня есть файл MyContract.json какого-то контракта (предположим, у меня нет его исходного кода). В файле .json есть abi и байткод. Если я хочу развернуть такой контракт (через web3js), я сталкиваюсь со следующими проблемами. Однако этот вопрос усложняется, когда контрактов тысячи, что является моей последней задачей. Но здесь я просто ограничиваю себя только одним контрактом для понимания цели.
На вопрос №. 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; я совершенно слеп, как вызвать функции контракта, показанные здесь как ??????? (что станет известно через abi файла .json вместе с параметрами!).
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"
}
В приведенном выше примере вы можете видеть, что конструктор имеет два параметра: _ff
и name
типа uint256
и string
соответственно.
На вопрос №. 2 : после создания экземпляра контракта вы можете регистрировать все методы, а также общедоступную переменную состояния, используя console.log(myContractInstance.methods)
.
В противном случае вы можете посмотреть, ABI
где находится type 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);
}
Надеюсь, это поможет.
Амир Али
Яхья
Амир Али
Яхья
setTotalSupply
, просто назовите его какmyContractInstance.methods.setTotalSupply().call()
.Амир Али
Яхья
var methods = myContractInstance.methods
это не только сохранит имена функций, но и сигнатуры функций. такжеvar methods
будет объектом. Таким образом, вы можете получить массив, используяObject.keys(methods)
. Но этот массив будет содержать как имена функций, так и сигнатуры. Когда у вас есть только имена функций, вы можете перебирать массив.Амир Али
Яхья