Search code examples
c#.net-coreethereumsoliditynethereum

Cannot get readable integer from nethereum decoded input data


I'm having trouble with converting solidity's uint256 to readable c# object.

public Transaction DecodeInputData(Transaction tx)
    {

        EthApiContractService ethApi = new EthApiContractService(null);
        var contract = ethApi.GetContract(Abi.Replace(@"\", string.Empty), Address);

        var transfer = contract.GetFunction("transfer");
        var decodedTx = transfer.DecodeInput(tx.input);

        tx.to = (string)decodedTx[0].Result;
        tx.value = "0x" + ((BigInteger)decodedTx[1].Result).ToString("x");

        return tx;
    }

Example Tx: https://etherscan.io/tx/0x622760ad1a0ead8d16641d5888b8c36cb67be5369556f8887499f4ad3e3d1c3d

We must able to convert decodedTx[1].Result variable ( its: {53809663494440740791636285293469688360281260987263635605451211260198698423701}) to 83218945020000000000.

We converting this value to hex to compatibility. But the hex i get is; "0x76f730b400000000000000000000000000000000000000000000000482e51595"

I am using Nethereum library with .net core 2.1


Solution

  • You are trying to decode the smart contract function parameters of a transaction. The smart contract is an ERC20 smart contract, and the function is the Transfer method.

    To do so you need to do the following.

    • Create your Function message in this is scenario the Transfer Function.
    • Retrieve the transaction
    • Using the FunctionMessage extension method DecodeTransaction, decode the values of the original Transaction input.
    using Nethereum.Web3;
    using Nethereum.ABI.FunctionEncoding.Attributes;
    using Nethereum.Contracts.CQS;
    using Nethereum.Util;
    using Nethereum.Web3.Accounts;
    using Nethereum.Hex.HexConvertors.Extensions;
    using Nethereum.Contracts;
    using Nethereum.Contracts.Extensions;
    using System;
    using System.Numerics;
    using System.Threading;
    using System.Threading.Tasks;
    
    
    public class GetStartedSmartContracts
    {
    
        [Function("transfer", "bool")]
        public class TransferFunction : FunctionMessage
        {
            [Parameter("address", "_to", 1)]
            public string To { get; set; }
    
            [Parameter("uint256", "_value", 2)]
            public BigInteger TokenAmount { get; set; }
        }
    
        public static async Task Main()
        {
    
            var url = "https://mainnet.infura.io";
            var web3 = new Web3(url);
                    var txn = await web3.Eth.Transactions.GetTransactionByHash.SendRequestAsync("0x622760ad1a0ead8d16641d5888b8c36cb67be5369556f8887499f4ad3e3d1c3d");
    
            var transfer = new TransferFunction().DecodeTransaction(txn);
                    Console.WriteLine(transfer.TokenAmount);
                    //BAT has 18 decimal places the same as Wei
                    Console.WriteLine(Web3.Convert.FromWei(transfer.TokenAmount));
        }
    }
    

    You can test this in the http://playground.nethereum.com

    Or you can also do, if want to check what function is:

    var functionCallDecoder = new FunctionCallDecoder();
    
            if(functionCallDecoder.IsDataForFunction(ABITypedRegistry.GetFunctionABI<TransferFunction>().Sha3Signature, txn.Input)) {
                
                    var transfer = new TransferFunction().DecodeInput(txn.Input);
                    Console.WriteLine(Web3.Convert.FromWei(transfer.TokenAmount));
                    Console.WriteLine(transfer.To);
            }