Heim  >  Artikel  >  Backend-Entwicklung  >  Gewährleistung der Integrität bei der Ethereum-Datenextraktion mit Durchlauftests

Gewährleistung der Integrität bei der Ethereum-Datenextraktion mit Durchlauftests

王林
王林Original
2024-07-18 07:48:19534Durchsuche

Asserting Integrity in Ethereum Data Extraction with Go through tests

Einführung

In diesem Tutorial erfahren Sie, wie Sie mithilfe von Tests die Integrität der Ethereum-Datenextraktion in einer Go-Anwendung sicherstellen. Wir werden den Go-Ethereum-Client verwenden, um Block- und Transaktionsdaten abzurufen, und das Testify-Paket für unsere Tests verwenden.

Voraussetzungen

  1. Grundlegendes Verständnis der Programmiersprache Go.
  2. Go wird auf Ihrem System installiert.
  3. geth (Go-Ethereum)-Client installiert.
  4. testify-Paket installiert (holen Sie sich github.com/stretchr/testify).

Projekteinrichtung

  1. Erstellen Sie ein Go-Projekt:
mkdir ethereum-data-extraction
cd ethereum-data-extraction
go mod init ethereum-data-extraction
  1. Abhängigkeiten installieren:
go get github.com/ethereum/go-ethereum
go get github.com/stretchr/testify

Code zur Datenextraktion

Datenextraktion blockieren
Beginnen wir mit der Funktion zum Extrahieren von Blockdaten.

package blockchain

import (
    "context"
    "log"
    "math/big"

    "github.com/ethereum/go-ethereum"
    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/core/types"
    "github.com/ethereum/go-ethereum/ethclient"
    "github.com/ethereum/go-ethereum/rpc"
)

type BlockData struct {
    Number       *big.Int
    Hash         string
    ParentHash   string
    Nonce        uint64
    Sha3Uncles   string
    Miner        string
    Difficulty   *big.Int
    ExtraData    string
    Size         uint64
    GasLimit     uint64
    GasUsed      uint64
    Timestamp    uint64
    Transactions []string
}

func getClient() (*ethclient.Client, error) {
    client, err := ethclient.Dial("https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID")
    if err != nil {
        return nil, err
    }
    return client, nil
}

func GetBlockData(blockNumber *big.Int) (*BlockData, error) {
    client, err := getClient()
    if err != nil {
        log.Fatal("Failed to get client:", err)
    }

    block, err := client.BlockByNumber(context.Background(), blockNumber)
    if err != nil {
        log.Fatalf("Failed to retrieve the block: %v", err)
        return nil, err
    }

    transactionHashes := make([]string, len(block.Body().Transactions))
    for i, tx := range block.Body().Transactions {
        transactionHashes[i] = tx.Hash().Hex()
    }

    blockData := &BlockData{
        Number:       block.Number(),
        Hash:         block.Hash().Hex(),
        ParentHash:   block.ParentHash().Hex(),
        Nonce:        block.Nonce(),
        Sha3Uncles:   block.UncleHash().Hex(),
        Miner:        block.Coinbase().Hex(),
        Difficulty:   block.Difficulty(),
        ExtraData:    string(block.Extra()),
        Size:         block.Size(),
        GasLimit:     block.GasLimit(),
        GasUsed:      block.GasUsed(),
        Timestamp:    block.Time(),
        Transactions: transactionHashes,
    }

    return blockData, nil
}

Transaktionsdatenextraktion

Als nächstes definieren wir die Funktion zum Extrahieren von Transaktionsdaten.

package blockchain

import (
    "context"
    "log"
    "math/big"

    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/core/types"
    "github.com/ethereum/go-ethereum/ethclient"
)

type TransactionData struct {
    Hash     string
    Nonce    uint64
    From     string
    To       string
    Value    *big.Int
    Gas      uint64
    GasPrice *big.Int
    Data     string
}

func GetTxData(txHash string) (*TransactionData, error) {
    client, err := getClient()
    if err != nil {
        log.Fatal("Failed to get client:", err)
        return nil, err
    }

    tx, _, err := client.TransactionByHash(context.Background(), common.HexToHash(txHash))
    if err != nil {
        log.Fatal("Failed to retrieve transaction:", err)
        return nil, err
    }

    sender, err := getTxSender(tx)
    if err != nil {
        log.Fatalf("Failed to get sender: %v", err)
        return nil, err
    }

    decodedData := decodeTxData(tx.Data())

    return &TransactionData{
        Hash:     tx.Hash().Hex(),
        Nonce:    tx.Nonce(),
        From:     sender,
        To:       tx.To().Hex(),
        Value:    tx.Value(),
        Gas:      tx.Gas(),
        GasPrice: tx.GasPrice(),
        Data:     decodedData,
    }, nil
}

func getChainId() (*big.Int, error) {
    client, err := getClient()
    if err != nil {
        log.Fatal("Failed to get client:", err)
        return big.NewInt(0), err
    }

    chainId, err := client.NetworkID(context.Background())
    if err != nil {
        log.Fatal("Failed to get chainId:", err)
        return big.NewInt(0), err
    }

    return chainId, nil
}

func getTxSender(tx *types.Transaction) (string, error) {
    chainId, err := getChainId()

    if err != nil {
        log.Fatal("Failed to get chainId:", err)
        return "", err
    }

    sender, err := types.Sender(types.NewLondonSigner(chainId), tx)
    if err != nil {
        log.Fatal("Not able to retrieve sender:", err)
        return "", err
    }

    return sender.Hex(), nil
}

func decodeTxData(data []byte) string {
    dataHex := common.Bytes2Hex(data)
    return dataHex
}

Schreibtests

Jetzt schreiben wir Tests, um die Integrität der Datenextraktionsfunktionen sicherzustellen.

package blockchain

import (
    "fmt"
    "math/big"
    "testing"

    "github.com/stretchr/testify/assert"
)

func TestGetBlockData(t *testing.T) {
    blockNumber := big.NewInt(20076728)
    blockData, err := GetBlockData(blockNumber)

    // Use fmt.Sprintf to format the log message
    t.Log(fmt.Sprintf("Block Data: \n%+v\nError: \n%v", blockData, err))

    assert.Nil(t, err)
    assert.NotNil(t, blockData)
}

func TestGetTransactionData(t *testing.T) {
    blockNumber := big.NewInt(20076728)
    blockData, err := GetBlockData(blockNumber)
    assert.Nil(t, err)
    assert.NotNil(t, blockData)

    if len(blockData.Transactions) > 0 {
        tx := blockData.Transactions[0]
        txData, err := GetTxData(tx)

        // Use fmt.Sprintf to format the log message
        t.Log(fmt.Sprintf("Transaction Data: \n%+v\nError: \n%v", txData, err))

        assert.Nil(t, err)
        assert.NotNil(t, txData)
    } else {
        t.Skip("No transactions found in the block")
    }
}

Führen Sie die Tests mit dem folgenden Befehl aus:

go test -v

Die Ausgabe:

--- PASS: TestGetBlockData (0.95s)
=== RUN   TestGetTransactionData
Current working directory: /mnt/c/github/dfbeat-v2/pkg/blockchain
Current working directory: /mnt/c/github/dfbeat-v2/pkg/blockchain
Current working directory: /mnt/c/github/dfbeat-v2/pkg/blockchain
    blockchain_test.go:33: Transaction Data:
        &{Hash:0x47e80ad8fa5f3bc94160f7eb1a3357f87b2756190007ab815b1a1890ddb65949 Nonce:249 BlockHash: BlockNumber:0 TransactionIndex:0 From:0x71B8CF59230bb295ade15506efd258eb458056A1 To:0x80a64c6D7f12C47B7c66c5B4E20E72bc1FCd5d9e Value:+50000000000000000 Gas:297438 GasPrice:+81175867687 Data:088890dc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000071b8cf59230bb295ade15506efd258eb458056a1000000000000000000000000000000000000000000000000000000006669c2ac0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000f3fd27ffb4712278e6d51d7d526a0ce431d454c5}
        Error:
        <nil>
--- PASS: TestGetTransactionData (0.56s)

Fazit

In diesem Tutorial haben wir gezeigt, wie man mit Go und dem Go-Ethereum-Client Block- und Transaktionsdaten aus der Ethereum-Blockchain extrahiert. Wir haben auch erläutert, wie Tests geschrieben und ausgeführt werden, um die Integrität des Datenextraktionsprozesses sicherzustellen. Wenn Sie diese Schritte befolgen, können Sie Blockchain-Daten in Ihren Go-Anwendungen zuverlässig abrufen und überprüfen.

Das obige ist der detaillierte Inhalt vonGewährleistung der Integrität bei der Ethereum-Datenextraktion mit Durchlauftests. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn