3

How can I decode a raw transaction using Go / go-ethereum ? There is no method/function to read the raw bytes or the hex into a transaction https://godoc.org/github.com/ethereum/go-ethereum/core/types . Basically I just want to extract the destination address and the amount sent.

4
  • Possible duplicate of How can I easily parse a raw transaction? Commented Jan 24, 2018 at 17:05
  • I voted to close this as a duplicate of ethereum.stackexchange.com/questions/4196/…. If you think it is not a duplicate or are for some reason not satisfied with the answers to that question, please edit question explaining why it should be reopened. Commented Jan 24, 2018 at 17:07
  • @AjoyBhatia This question seems to specifically be about how to do this using go-ethereum. Commented Jan 24, 2018 at 19:20
  • @smarx - That is correct. I retracted my Close vote Commented Jan 24, 2018 at 19:48

4 Answers 4

4

Using the official go-ethereum package:

import ( "encoding/hex" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" ) func GetToAddressFromRawTransaction(rawTxHex string) (*common.Address, error) { rawTxData, err := hex.DecodeString(rawTxHex[2:]) // Remove hex prefix "0x..." if err != nil { return nil, err } var tx types.Transaction err = rlp.DecodeBytes(rawTxData, &tx) if err != nil { return nil, err } return tx.To(), nil } 

Look at the methods of the Transaction type to access data in the tx object.

Here's a working code on github

2
  • may I ask what are you doing in that loop to decode the public key ??? What are the sig1 and sig2 and why do you need a public key at all? Commented Jun 21, 2018 at 2:32
  • @Nulik For normal using of blockchain you don't need a public key. But if you want to research or to know deeper about EC cryptography you might be eager to find a public key. In my code sig1 and sig2 is a signature of the message. It consists of R+S+V (learn more about elliptic curves). R and S are known. V can be 00 or 01, so we just check both options. Commented Jun 22, 2018 at 10:47
1

With introduction of EIP-1559, rlp.DecodeBytes(..) no longer works and you'd have to use tx.UnmarshalBinary(..) instead. Here's an example:

package main import ( "github.com/davecgh/go-spew/spew" ) func deraw() { // eip-1559 tx: 0xc2163f50770bd4bfd3c13848b405a56a451ae2a39cfa5a236ea2738ce44aa9df rawTx := "02f8740181bf8459682f00851191460ee38252089497e542ec6b81dea28f212775ce8ac436ab77a7df880de0b6b3a764000080c080a02bc11202cee115fe22558ce2edb25c621266ce75f75e9b10da9a2ae72460ad4ea07d573eef31fdebf0f5f93eb7721924a082907419eb97a8dda0dd20a4a5b954a1" // legacy tx //rawTx := "f86d8202b28477359400825208944592d8f8d7b001e72cb26a73e4fa1806a51ac79d880de0b6b3a7640000802ca05924bde7ef10aa88db9c66dd4f5fb16b46dff2319b9968be983118b57bb50562a001b24b31010004f13d9a26b320845257a6cfc2bf819a3d55e3fc86263c5f0772" tx := &types.Transaction{} rawTxBytes, err := hex.DecodeString(rawTx) if err != nil { fmt.Println("err:", err) return 1 } err = tx.UnmarshalBinary(rawTxBytes) if err != nil { fmt.Println("err:", err) return 1 } spew.Dump(tx) } 

Alternatively, you can extract what you want using rlpdump.

1
  • This should be the top answer! huge thx, been bugging me for days Commented Jan 25, 2024 at 15:56
0

Here is a package I found out about from this answer:

https://github.com/ConsenSys/abi-decoder

See the code block titled Decode Tx data. I think this should do what you want.

2
  • Can you understand the difference between javascript and Go ? Commented Jan 24, 2018 at 20:17
  • Ok. Ok. I should read questions more carefully. go-ethereum also has a Javascript API to communicate with the node using IPC or RPC. That is what I have always used because I programmed in Javascript. Perhaps, when you said Go / go-ethereum, you meant an application in Go (i.e. not Javascript) interacting with the go-ethereum client? Commented Jan 24, 2018 at 20:32
0

Here's a full example of how to read transaction values (ie, from address, eth value, etc..) in Go.

package main import ( "context" "fmt" "log" "math/big" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" ) func main() { client, err := ethclient.Dial("https://mainnet.infura.io") if err != nil { log.Fatal(err) } blockNumber := big.NewInt(5671744) block, err := client.BlockByNumber(context.Background(), blockNumber) if err != nil { log.Fatal(err) } for _, tx := range block.Transactions() { fmt.Println(tx.Hash().Hex()) // 0x5d49fcaa394c97ec8a9c3e7bd9e8388d420fb050a52083ca52ff24b3b65bc9c2 fmt.Println(tx.Value().String()) // 10000000000000000 fmt.Println(tx.Gas()) // 105000 fmt.Println(tx.GasPrice().Uint64()) // 102000000000 fmt.Println(tx.Nonce()) // 110644 fmt.Println(tx.Data()) // [] fmt.Println(tx.To().Hex()) // 0x55fE59D8Ad77035154dDd0AD0388D09Dd4047A8e if msg, err := tx.AsMessage(types.HomesteadSigner{}); err != nil { fmt.Println(msg.From().Hex()) // 0x0fD081e3Bb178dc45c0cb23202069ddA57064258 } receipt, err := client.TransactionReceipt(context.Background(), tx.Hash()) if err != nil { log.Fatal(err) } fmt.Println(receipt.Status) // 1 } } 

If you have the raw tx hex, here's how you can decode it into a tx type:

package main import ( "encoding/hex" "log" "github.com/c3systems/vendor.bak/github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/rlp" ) func main() { client, err := ethclient.Dial("https://rinkeby.infura.io") if err != nil { log.Fatal(err) } rawTx := "f86d8202b28477359400825208944592d8f8d7b001e72cb26a73e4fa1806a51ac79d880de0b6b3a7640000802ca05924bde7ef10aa88db9c66dd4f5fb16b46dff2319b9968be983118b57bb50562a001b24b31010004f13d9a26b320845257a6cfc2bf819a3d55e3fc86263c5f0772" var tx *types.Transaction rawTxBytes, err := hex.DecodeString(rawTx) rlp.DecodeBytes(rawTxBytes, &tx) spew.Dump(tx) } 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.