首頁 > 後端開發 > Golang > 主體

透過測試來確保以太坊資料提取的完整性

王林
發布: 2024-07-18 07:48:19
原創
534 人瀏覽過

Asserting Integrity in Ethereum Data Extraction with Go through tests

簡介

在本教程中,我們將逐步介紹如何使用測試來確保 Go 應用程式中以太坊資料提取的完整性。我們將使用 Go-Ethereum 用戶端檢索區塊和交易數據,並使用 testify 套件進行測試。

先決條件

  1. 對 Go 程式語言有基本了解。
  2. 安裝到您的系統上。
  3. geth (Go-Ethereum) 用戶端已安裝。
  4. 已安裝 testify 軟體包(前往 github.com/stretchr/testify)。

項目設定

  1. 建立一個 Go 專案:
mkdir ethereum-data-extraction
cd ethereum-data-extraction
go mod init ethereum-data-extraction
登入後複製
  1. 安裝依賴項:
go get github.com/ethereum/go-ethereum
go get github.com/stretchr/testify
登入後複製

資料擷取代碼

區塊資料擷取
我們先從提取區塊資料的函數開始。

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
}

登入後複製

交易資料擷取

接下來,我們定義提取交易資料的函數。

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
}

登入後複製

寫測驗

現在,讓我們寫測試來斷言資料提取函數的完整性。

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")
    }
}
登入後複製

使用以下命令執行測試:

go test -v

登入後複製

輸出:

--- 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)
登入後複製

結論

在本教程中,我們示範如何使用 Go 和 Go-Ethereum 用戶端從以太坊區塊鏈中提取區塊和交易資料。我們也介紹如何編寫和執行測試以確保資料提取過程的完整性。透過執行以下步驟,您可以在 Go 應用程式中可靠地檢索和驗證區塊鏈資料。

以上是透過測試來確保以太坊資料提取的完整性的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!