Llamar a funciones de contrato usando solo ABI sin código fuente

Tengo el archivo MyContract.json de algún contrato (supongamos que no tengo su código fuente). En el archivo .json, hay abi y bytecode. Si quiero implementar dicho contrato (a través de web3js), me enfrento a los siguientes problemas. Sin embargo, esta pregunta se vuelve más compleja, cuando hay miles de contratos, que es mi tarea final. Pero aquí estoy, solo me limito a un solo contrato para comprender el propósito.

  1. Si dicho contrato necesita algunos argumentos en su constructor, entonces, ¿cómo puedo saber sus parámetros con valores válidos, para que pueda implementarse con éxito?
  2. ¿Cómo puedo llamar a sus diferentes funciones (getters, setters)?

Para la pregunta No. 1; Estoy compartiendo aquí mi código para su implementación. Es válido y funciona si el contrato tiene un constructor que toma la dirección del propietario en su parámetro. Este código se prueba en algún contrato conocido con código fuente. Sin embargo, si el constructor no toma parámetros o diferentes parámetros o muchos otros parámetros, este código no se implementará , porque debo pasar una cantidad válida de parámetros y valores válidos.

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;

}

Para la pregunta No. 2; Estoy totalmente ciego sobre cómo llamar a las funciones del contrato que se muestran aquí como ??????? (que llegará a saber a través de abi del archivo .json junto con los parámetros).

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')})

Respuestas (1)

Para su pregunta No. 1: Busca "type": "constructor"en tu ABI. Desde este objeto, puede ver el inputsque tiene una matriz de parámetros junto con su nombre y tipo. Ejemplo:

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

En el ejemplo anterior, puede ver que el constructor tiene dos parámetros: _ffy namede tipo uint256y stringrespectivamente.

Para la pregunta No. 2 : una vez que se instancia el contrato, puede registrar todos los métodos, así como la variable de estado público, utilizando console.log(myContractInstance.methods).

De lo contrario, puede buscar ABIdónde está type function. Pero esta puede ser una forma más compleja.

Actualizado:

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);
}

Espero que ayude

gracias por tu respuesta. Está bien, pero ¿cómo extraer el constructor y su parámetro de un abi tan complejo usando web3? ... debería ser más factible para mí, si prefiere dar un código de muestra (ya que soy novato) ... Para la segunda pregunta, puedo obtener el nombre de los métodos e imprimirlos ... pero cómo llamarlos individualmente como myContractInstance.methods.MY_RETRIEVED_FUNCTION_NAME().send()
mire este ejemplo para llamar a los métodos: web3js.readthedocs.io/en/v1.2.2/web3-eth-contract.html#id28
Creo que no pude explicarlo... Sé cómo llamar a la función... pero cómo agregar los diferentes nombres de función (extraídos de métodos = myContractInstance.methods)... por ejemplo, esto (myContractInstance.methods) nos dará el método nombre, es decir, setTotalSupply que se almacena en los métodos [0], y getTotalSupply se almacena en los métodos [1]. luego cómo llamar (o agregar estos nombres extraídos a myContractInstance.methods. ------. enviar()
No entiendo a qué te refieres con añadir. si conoce el nombre del método, digamos setTotalSupply, simplemente llámelo como myContractInstance.methods.setTotalSupply().call().
Quiero decir que cuando llamo digamos var métodos = myContractInstance.methods, por lo que todos los nombres de los métodos se guardarán en la variable de métodos. luego, cómo recuperar nombres de métodos de la variable 'métodos' y luego llamo, es decir, myContractInstance.methods.methods[0].send () // Sé que esto no funcionará, pero quiero llamar dinámicamente (tiempo de ejecución) al método[ 0] debe ser reemplazado con nombres reales...
var methods = myContractInstance.methodsesto no solo guardará los nombres de las funciones, sino también las firmas de las funciones. también var methodsserá un objeto. Entonces puede obtener una matriz usando Object.keys(methods). Pero esta matriz contendrá nombres de funciones y firmas. Una vez que solo tenga nombres de funciones, puede iterar sobre la matriz.
gracias, lo intentaré... sin embargo, mi pregunta anterior "¿cómo extraer el constructor y su parámetro de un abi tan complejo usando web3, javascript? aún está pendiente, si tiene alguna idea, se lo agradeceré...
por favor vea la respuesta actualizada.