Вызов контрактных функций с использованием только ABI без исходного кода

У меня есть файл MyContract.json какого-то контракта (предположим, у меня нет его исходного кода). В файле .json есть abi и байткод. Если я хочу развернуть такой контракт (через web3js), я сталкиваюсь со следующими проблемами. Однако этот вопрос усложняется, когда контрактов тысячи, что является моей последней задачей. Но здесь я просто ограничиваю себя только одним контрактом для понимания цели.

  1. Если такому контракту нужны какие-то аргументы в его конструкторе, то как я могу узнать его параметры с допустимыми значениями, чтобы его можно было успешно развернуть.
  2. Как я могу вызвать его различные функции (геттеры, сеттеры)?

На вопрос №. 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)

На ваш вопрос нет. 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);
}

Надеюсь, это поможет.

спасибо за Ваш ответ. Хорошо, но как извлечь конструктор и его параметр из такого сложного abi с помощью web3 ?? ... это должно быть более осуществимо для меня, если вы окажете услугу, чтобы дать пример кода (поскольку я новичок)... Для 2-го вопроса я могу получить имя метода и распечатать их... но как вызывать их по отдельности как myContractInstance.methods.MY_RETRIEVED_FUNCTION_NAME().send()
пожалуйста, посмотрите на этот пример для вызова методов: web3js.readthedocs.io/en/v1.2.2/web3-eth-contract.html#id28
я думаю, что не мог объяснить... я знаю, как вызвать функцию... но как добавить различные имена функций (извлеченные из методов = myContractInstance.methods)... например, это (myContractInstance.methods) даст нам метод имя, то есть setTotalSupply, которое хранится в методах [0], а getTotalSupply хранится в методах [1]. затем как вызвать (или добавить эти извлеченные имена в myContractInstance.methods. ------. send()
Я не понимаю, что вы имеете в виду под добавлением. если вы знаете имя метода, скажем setTotalSupply, просто назовите его как myContractInstance.methods.setTotalSupply().call().
я имею в виду, что когда я вызываю, скажем, var методы = myContractInstance.methods, поэтому все имена методов будут сохранены в переменной методов. затем, как получить имена методов из переменной «методы», а затем я вызываю, например, myContractInstance.methods.methods[0].send () // я знаю, что это не сработает, но я хочу вызвать метод динамически (во время выполнения) [ 0] следует заменить реальными именами...
var methods = myContractInstance.methodsэто не только сохранит имена функций, но и сигнатуры функций. также var methodsбудет объектом. Таким образом, вы можете получить массив, используя Object.keys(methods). Но этот массив будет содержать как имена функций, так и сигнатуры. Когда у вас есть только имена функций, вы можете перебирать массив.
спасибо, я попробую... однако, мой предыдущий вопрос "как извлечь конструктор и его параметр из такого сложного abi с помощью web3, javascript? все еще ожидается, если у вас есть какие-либо идеи, я буду вам благодарен...
см. обновленный ответ.