¿Cómo puedo decodificar una transacción sin procesar usando Go/go-ethereum? No existe un método/función para leer los bytes sin formato o el hexadecimal en una transacción https://godoc.org/github.com/ethereum/go-ethereum/core/types . Básicamente, solo quiero extraer la dirección de destino y la cantidad enviada.
Usando el paquete oficial de go-ethereum:
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
}
Mire los métodos del Transaction
tipo para acceder a los datos en el objeto tx.
Aquí hay un código de trabajo en github
Aquí hay un paquete que descubrí de esta respuesta :
https://github.com/ConsenSys/abi-decodificador
Consulte el bloque de código titulado Decodificar datos Tx . Creo que esto debería hacer lo que quieres.
Aquí hay un ejemplo completo de cómo leer los valores de transacción (es decir, desde la dirección, el valor ético, etc.) en 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
}
}
Si tiene el hexadecimal tx sin procesar, así es como puede decodificarlo en un tipo tx:
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)
}
Con la introducción de EIP-1559, rlp.DecodeBytes(..)
ya no funciona y tendrá que usarlo en su tx.UnmarshalBinary(..)
lugar. Aquí hay un ejemplo :
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)
}
Alternativamente, puede extraer lo que quiera usando rlpdump
.
Ajoy Bhatia
Ajoy Bhatia
usuario19510
Ajoy Bhatia