Go-Ethereum

如何通過知道合約地址(golang)來訪問事件日誌?

  • July 3, 2017

目前,我開發了使用智能合約作為特定數據儲存的 dapp。我使用 abigen 為我的契約生成特定的 go 綁定。如果有人嘗試更改契約狀態,我會使用事件來記錄此操作。但是我被卡住了,因為我真的不明白如何使用 go ethereum 查看特定事件的日誌歷史記錄。

如何使用 json rpceth_getlogs方法呼叫並使用 go 獲取儲存在此合約地址中的所有日誌?

我將不勝感激一段程式碼。

提前致謝!

通常,您將首先創建一個新過濾器 ( eth_newFilter+ eth_getFilterLogs) 並重用該過濾器以多次執行相同的查詢並偵聽更改。但是,您也可以使用 安裝一個臨時過濾器eth_getLogs,引用您希望搜尋的主題。

主題是您正在搜尋的一段數據。例如,如果您有以下事件:

Transfer(address to, address from)

以下過濾器將搜尋所有日誌0xb3904758c0d3bfc25746c47caa45b01da8930e19

[0x000000000000000000000000b3904758c0d3bfc25746c47caa45b01da8930e19, null]

此過濾器將搜尋來自以下的所有日誌0xb3904758c0d3bfc25746c47caa45b01da8930e19

[null, 0x000000000000000000000000b3904758c0d3bfc25746c47caa45b01da8930e19]

此過濾器將搜尋來自的所有0xb3904758c0d3bfc25746c47caa45b01da8930e19日誌0x8cc19c7b50857abbfbeeed31c302319a075d4a9b

[0x000000000000000000000000b3904758c0d3bfc25746c47caa45b01da8930e19, 0x0000000000000000000000008cc19c7b50857abbfbeeed31c302319a075d4a9b

用於 RPC 請求的完整 golang 包裝器看起來像這樣:

// This needs to be instantiated
type EthereumClient struct {
 URL string
}

// Basic RPC repsonse format
type JSONRPCRequest struct {
 JSONRPC string        `json:"jsonrpc"`
 Method  string        `json:"method"`
 ID      int64         `json:"id"`
 Params  []interface{} `json:"params"`
}

// Base struct
type ResponseBase struct {
 JSONRPC string `json:"jsonrpc"`
 ID      int64  `json:"id"`
}

// Response struct based on below RPC methods
type Response struct {
 ResponseBase
 Result string `json:"result"`
}

// ToJSON marshals a JSONRPCRequest into JSON
func (req *JSONRPCRequest) ToJSON() ([]byte, error) {
 s, err := json.Marshal(req)
 if err != nil {
   return nil, err
 }
 return s, nil
}

// Get logs given an array of topics
func (client *EthereumClient) Eth_getLogs(topics string[]) (string, error) {
 reqBody := JSONRPCRequest{
   JSONRPC: "2.0",
   ID:      1,
   Method:  "eth_sendRawTransaction",
   Params:  []interface{}{topics},
 }
 res, err := client.issueRequest(&reqBody)
 if err != nil {
   return "", err
 }

 var clientResp Response
 err = json.Unmarshal(res, &clientResp)
 if err != nil {
   return "", err
 }
 return clientResp.Result, nil
}

可以通過以下EthereumClient方式在不同的包中實例化:

// Global client connection
var client = EthereumClient{}

// provider = e.g. 'localhost:8545'
func ConnectToRPC(provider string) {
 client = EthereumClient{provider}
}

現在client可以使用它來啟動一個新的過濾器並從該過濾器獲取日誌。

我沒有這個案例的具體範例,但請參閱這個以獲取在 Go 中發出 RPC 請求的一些範例。

引用自:https://ethereum.stackexchange.com/questions/19261