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.
- Possible duplicate of How can I easily parse a raw transaction?Ajoy Bhatia– Ajoy Bhatia2018-01-24 17:05:59 +00:00Commented 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.Ajoy Bhatia– Ajoy Bhatia2018-01-24 17:07:16 +00:00Commented Jan 24, 2018 at 17:07
- @AjoyBhatia This question seems to specifically be about how to do this using go-ethereum.user19510– user195102018-01-24 19:20:35 +00:00Commented Jan 24, 2018 at 19:20
- @smarx - That is correct. I retracted my Close voteAjoy Bhatia– Ajoy Bhatia2018-01-24 19:48:24 +00:00Commented Jan 24, 2018 at 19:48
4 Answers
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
- 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?Nulik– Nulik2018-06-21 02:32:56 +00:00Commented 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.Tarik– Tarik2018-06-22 10:47:24 +00:00Commented Jun 22, 2018 at 10:47
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.
- This should be the top answer! huge thx, been bugging me for daysgabkov– gabkov2024-01-25 15:56:22 +00:00Commented Jan 25, 2024 at 15:56
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.
- Can you understand the difference between javascript and Go ?Books– Books2018-01-24 20:17:03 +00:00Commented 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?Ajoy Bhatia– Ajoy Bhatia2018-01-24 20:32:31 +00:00Commented Jan 24, 2018 at 20:32
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) }