10

There is a tool on npm ethereum-input-data-decoder. And yes, i can read input data as hex.

And i hope that i can decode transaction's inputdata using golang. For example 0xa9059cbb00000000000000000000000067f883a42031215622e0b84c96d0e4dca7a3ce810000000000000000000000000000000000000000000000000000000005f5e100

thx.

3

6 Answers 6

9

took me a bit of time to figure out that myAbi.Unpack(...) unpacks output of a method or event. In your case (and mine) we want to unpack the inputs. Here is a working code sample

// example of transaction input data
txInput := "0xa5142faa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003"

// load contract ABI
abi, err := abi.JSON(strings.NewReader(myContractAbi))
if err != nil {
    log.Fatal(err)
}

// decode txInput method signature
decodedSig, err := hex.DecodeString(txInput[2:10])
if err != nil {
    log.Fatal(err)
}

// recover Method from signature and ABI
method, err := abi.MethodById(decodedSig)
if err != nil {
    log.Fatal(err)
}

// decode txInput Payload
decodedData, err := hex.DecodeString(txInput[10:])
if err != nil {
    log.Fatal(err)
}

// create strut that matches input names to unpack
// for example my function takes 2 inputs, with names "Name1" and "Name2" and of type uint256 (solidity)
type FunctionInputs struct {
    Name1 *big.Int // *big.Int for uint256 for example
    Name2 *big.Int
}

var data FunctionInputs

// unpack method inputs
err = method.Inputs.Unpack(&data, decodedData)
if err != nil {
    log.Fatal(err)
}

fmt.Println(data)
3
  • Can someone guide me what imports I need for this code? 2019's libraries look very different from 2021 ... what is "abi" in this context?
    – nicocesar
    Sep 22, 2021 at 0:06
  • 2
    @nicocesar "github.com/ethereum/go-ethereum/accounts/abi"
    – DiveInto
    Nov 4, 2021 at 16:18
  • 404 Grr.... help us out please May 24 at 13:38
3

This is isn't tested, but it'd be sort of like this:

myAbi, err := abi.JSON(strings.NewReader(abiJsonString))
if err != nil {
    log.Fatal(err)
}

var ifc map[string]interface{}
encodedData := "0x00123..."
err := myApi.Unpack(&ifc, "someMethod", encodedData)
if err != nil {
     log.Fatal(err)
}

You'd also have to iterate through all the ABI methods and plug it into the second argument to the abi.Unpack method to find which method the data belongs to.

3
3
    if reader, err := os.Open("token.abi"); err != nil {
        log.Fatal(err)
    } else {
        if tokenAbi, err := abi.JSON(reader); err != nil {
            log.Fatal(err)
        } else {
            encodedData := "a9059cbb00000000000000000000000067f883a42031215622e0b84c96d0e4dca7a3ce810000000000000000000000000000000000000000000000000000000005f5e100"
            decodeData, err := hex.DecodeString(encodedData)
            if err != nil {
                log.Fatal(err)
            }
            // a9059cbb == transfer
            if method, ok := tokenAbi.Methods["transfer"]; ok {
                params, err := method.Inputs.Unpack(decodeData[4:])
                if err != nil {
                    log.Fatal(err)
                }
                log.Println(params)
            }
        }
    }

2
  • Hello. Avoid code only answer and provide an explanation on how this solves the problem. Jun 10, 2021 at 6:18
  • decodeData[4:] works like a magic
    – DiveInto
    Nov 4, 2021 at 16:18
1

Since geth is written in go, it makes some sense there's probably an official package for this. Looking into the official go-ethereum library, there's a package called abi there, you might be able to use that.

1
  • sorry, I know this package .But i dont't know how to use it. Nov 3, 2017 at 3:33
1

I think you can try with the solution:

myAbi, err := abi.JSON(strings.NewReader(abiJsonString))
if err != nil {
    log.Fatal(err)
}

var ifc map[string]interface{}
encodedData := "0xa9059cbb00000000000000000000000067f883a42031215622e0b84c96d0e4dca7a3ce810000000000000000000000000000000000000000000000000000000005f5e100"
decodeData, _ := hex.DecodeString(encodedData)
err := myApi.Unpack(&ifc, "someMethod", decodeData[4:])
if err != nil {
     log.Fatal(err)
}
1
1

Here is an example about decode input data and output data

https://gist.github.com/crazygit/9279a3b26461d7cb03e807a6362ec855

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.