做法
新增 .env
檔。
1
| PROVIDER_URL=https://eth-goerli.alchemyapi.io/v2/your-api-key
|
新增 ethereum/ethereum.go
檔。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package ethereum
import ( "context" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" "log" "math/big" "os" )
var ( client *ethclient.Client )
func init() { var err error if client, err = ethclient.Dial(os.Getenv("PROVIDER_URL")); err != nil { log.Fatal(err) } }
func FetchTransactionReceipt(txHash common.Hash) (*types.Receipt, error) { receipt, err := client.TransactionReceipt(context.Background(), txHash) if err != nil { return nil, err } log.Printf("Fetching transaction receipt: %s", txHash) return receipt, nil }
|
解析
解析 Receipt
交易回條中的 Log
資料,可以使用 abi.ABI
的 UnpackIntoMap
或 UnpackIntoInterface
方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| func decodeTransactionLogs(receipt *types.Receipt, contractABI *abi.ABI) error { for _, receiptLog := range receipt.Logs { for _, topic := range receiptLog.Topics { event, err := contractABI.EventByID(topic) if err != nil { continue } if event.Name == "StakeCreated" { e := StakeEvent{} if err = contractABI.UnpackIntoInterface(&e, event.Name, receiptLog.Data); err != nil { log.Fatal(err) } break } if event.Name == "StakeRemoved" { e := StakeEvent{} if err = contractABI.UnpackIntoInterface(&e, event.Name, receiptLog.Data); err != nil { log.Fatal(err) } } } } return nil }
type StakeEvent struct { Stake struct { Index *big.Int Amount *big.Int RewardPlanIndex *big.Int CreatedAt *big.Int } }
|
如果 Log
中的參數是一個物件,可以使用以下方法查看其結構體的定義。
1 2 3 4 5
| v := make(map[string]interface{}) if err = contractABI.UnpackIntoMap(v, event.Name, receiptLog.Data); err != nil { log.Fatal(err) } log.Print(reflect.TypeOf(v["stake"]))
|
參考資料