簡介
在本教程中,我們將逐步介紹如何使用測試來確保 Go 應用程式中以太坊資料提取的完整性。我們將使用 Go-Ethereum 用戶端檢索區塊和交易數據,並使用 testify 套件進行測試。
先決條件
項目設定
mkdir ethereum-data-extraction cd ethereum-data-extraction go mod init ethereum-data-extraction
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中文網其他相關文章!