Entschlüsseln Sie die Rohtransaktion

Wie kann ich eine Rohtransaktion mit Go / go-ethereum entschlüsseln? Es gibt keine Methode/Funktion, um die rohen Bytes oder das Hex in eine Transaktion einzulesen https://godoc.org/github.com/ethereum/go-ethereum/core/types . Im Grunde möchte ich nur die Zieladresse und den gesendeten Betrag extrahieren.

Ich habe dafür gestimmt, dies als Duplikat von ethereum.stackexchange.com/questions/4196/… zu schließen . Wenn Sie der Meinung sind, dass es sich nicht um ein Duplikat handelt, oder aus irgendeinem Grund mit den Antworten auf diese Frage nicht zufrieden sind, bearbeiten Sie bitte die Frage und erklären Sie, warum sie erneut geöffnet werden sollte.
@AjoyBhatia Bei dieser Frage scheint es speziell darum zu gehen, wie dies mit Go-Ethereum zu tun ist.
@smart - Das ist richtig. Ich habe meine Abstimmung zurückgezogen

Antworten (4)

Verwenden des offiziellen go-ethereum-Pakets:

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
}

Sehen Sie sich die Methoden des TransactionTyps an, um auf Daten im tx-Objekt zuzugreifen.

Hier ist ein funktionierender Code auf github

Darf ich fragen, was Sie in dieser Schleife tun, um den öffentlichen Schlüssel zu entschlüsseln? Was sind sig1 und sig2 und warum braucht man überhaupt einen öffentlichen Schlüssel?
@Nulik Für die normale Verwendung von Blockchain benötigen Sie keinen öffentlichen Schlüssel. Aber wenn Sie etwas über die EC-Kryptographie recherchieren oder tiefer wissen möchten, sind Sie vielleicht begierig darauf, einen öffentlichen Schlüssel zu finden. In meinem Code sig1 und sig2 ist eine Signatur der Nachricht. Es besteht aus R+S+V (erfahren Sie mehr über elliptische Kurven). R und S sind bekannt. V kann 00 oder 01 sein, also prüfen wir einfach beide Optionen.

Hier ist ein Paket, von dem ich aus dieser Antwort erfahren habe :

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

Siehe den Codeblock mit dem Titel Decode Tx data . Ich denke, das sollte tun, was Sie wollen.

Können Sie den Unterschied zwischen Javascript und Go verstehen?
OK. OK. Ich sollte die Fragen genauer lesen. go-ethereum verfügt auch über eine Javascript-API, um mit dem Knoten über IPC oder RPC zu kommunizieren. Das habe ich immer verwendet, weil ich in Javascript programmiert habe. Vielleicht meinten Sie, als Sie Go / go-ethereum sagten , eine Anwendung in Go (dh nicht Javascript), die mit dem Go-ethereum-Client interagiert?

Hier ist ein vollständiges Beispiel dafür, wie Transaktionswerte (dh von Adresse, eth-Wert usw.) in Go gelesen werden.

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
    }
}

Wenn Sie das rohe TX-Hex haben, können Sie es folgendermaßen in einen TX-Typ dekodieren:

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)
}

Mit der Einführung von EIP-1559 rlp.DecodeBytes(..)funktioniert es nicht mehr und Sie müssten es tx.UnmarshalBinary(..)stattdessen verwenden. Hier ist ein Beispiel :

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)
}

Alternativ können Sie mit extrahieren, was Sie wollen rlpdump.