Go-Ethereum
如何通過知道合約地址(golang)來訪問事件日誌?
目前,我開發了使用智能合約作為特定數據儲存的 dapp。我使用 abigen 為我的契約生成特定的 go 綁定。如果有人嘗試更改契約狀態,我會使用事件來記錄此操作。但是我被卡住了,因為我真的不明白如何使用 go ethereum 查看特定事件的日誌歷史記錄。
如何使用 json rpc
eth_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 請求的一些範例。