>  기사  >  백엔드 개발  >  Go through 테스트를 통해 이더리움 데이터 추출의 무결성 보장

Go through 테스트를 통해 이더리움 데이터 추출의 무결성 보장

王林
王林원래의
2024-07-18 07:48:19534검색

Asserting Integrity in Ethereum Data Extraction with Go through tests

소개

이 튜토리얼에서는 테스트를 사용하여 Go 애플리케이션에서 Ethereum 데이터 추출의 무결성을 확인하는 방법을 살펴보겠습니다. 우리는 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 애플리케이션에서 블록체인 데이터를 안정적으로 검색하고 확인할 수 있습니다.

위 내용은 Go through 테스트를 통해 이더리움 데이터 추출의 무결성 보장의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.