es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

decodeFunctionResult: obtener la salida de un recibo de transacción utilizando ethers (js). puede que haya un error en ethers v5.

El desafío consiste en extraer la salida uint256 de una transacción de recibo de un contrato inteligente público utilizando ethers en un script de JavaScript que interactúa con un contrato inteligente.

Consideremos el siguiente contrato muy simple contract1.sol. Vamos a jugar con la variable _val_1 y la función fun_sum256.

pragma solidity ^0.8.0;
// SPDX-License-Identifier: MIT
contract Contract1  {

string public _str_1;
  uint256 public _val_1;

constructor(string memory str_in1, uint256 in_val1 ) {
    _str_1 = str_in1;
    _val_1 = in_val1;
  } //endconstructor

function get_str() external view returns (string memory) {
    return _str_1;
  } //endfun get_str

function set_str(string memory str_in1) external returns (string memory) {
    _str_1 = str_in1;
    return _str_1;
  } //endfun set_str

function fun_sum256(uint256 inval_2) public returns (uint256) {
    _val_1 += inval_2;
    return _val_1;
  } //endfun sum256

} //endcon

Como se observa en ethers, el procedimiento para decodificar tx_receipt.data requiere el uso de una interfaz,

let value = contract.interface.decodeFunctionResult(fragment, result);

donde fragment es el fragmento de la función correspondiente a fun_sum256, y result es los datos del recibo de la transacción (adecuadamente extraídos y esperados). El fragmento de la función también se puede llamar directamente de la siguiente manera, <tucontratodesplegado>.interface.functions["fun_sum256(uint256)"].

Simplemente no funciona, al menos para mí. Puedo extraer el otro argumento de cadena _str_1, pero no los tipos uint. Pero, por el contrario, en remix-ide sí funciona. Si inicio _val_1 con el valor 1 en el constructor y luego invoco la función pública fun_uint256 con una entrada de 2, funciona correctamente en remix, realizando 1+2=3, para ver la salida decodificada 0: uint256: 3. Y de hecho, desde mi script de JavaScript que interactúa con el contrato, puedo prever el valor en los datos de la transacción, el último cifrado:

0x78081f400000000000000000000000000000000000000000000000000000000000000003

Pero ethers v5 simplemente parece incapaz de extraer ese “3”.

¿Alguien puede proporcionar un ejemplo muy simple con un simple.sol y el correspondiente simple.js para interactuar con, que funcione con la biblioteca ethers en js?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para extraer la salida uint256 de una transacción de recibo de un contrato inteligente público utilizando ethers en un script de JavaScript, puedes usar el método decodeFunctionResult() de la interfaz del contrato. Aquí tienes un contrato simple.sol simple que contiene una función sum() que suma dos números y devuelve el resultado:

    pragma solidity ^0.8.0;
    
    contract Simple {
        function sum(uint256 x, uint256 y) public pure returns (uint256) {
            return x + y;
        }
    }
    

    Aquí tienes un ejemplo de script simple.js que interactúa con el contrato Simple y extrae la salida de la función sum() de un recibo de transacción:

    const ethers = require('ethers');
    
    const ABI = [
        'function sum(uint256 x, uint256 y) public pure returns (uint256)',
    ];
    const contractAddress = '0x...'; // reemplaza con la dirección de tu contrato
    const privateKey = '0x...'; // reemplaza con tu clave privada
    
    async function main() {
        const provider = new ethers.providers.JsonRpcProvider('https://ropsten.infura.io');
        const wallet = new ethers.Wallet(privateKey, provider);
        const contract = new ethers.Contract(contractAddress, ABI, wallet);
    
        const x = 123;
        const y = 456;
    
        const tx = await contract.sum(x, y);
        const receipt = await tx.wait();
    
        const output = contract.interface.decodeFunctionResult('sum(uint256,uint256)', receipt.logs[0].data);
        console.log(output[0].toString());
    }
    
    main().catch(console.error);
    

    En este script, primero definimos el ABI del contrato y la dirección del contrato, y creamos una instancia de la clase ethers.Contract. Luego llamamos a la función sum() con algunos argumentos y esperamos a que la transacción se mine y se incluya en un bloque. Una vez que tenemos el recibo de la transacción, podemos usar el método decodeFunctionResult() para extraer la salida de la función sum() del primer registro en el recibo. Imprimimos la salida en la consola, que debería ser la suma de x e y.

Comments are closed.