2

At the moment I develope dapps that use smart contract as storage for specific data. I use abigen to generate specific go binding to my contract. If someone try change state of the contract I use event for logging this action. But I am stuck, because I do not realy understand how can I view log history of specific event using go ethereum.

How can I use json rpc call of eth_getlogs method and get all the logs that are stored in this contract address with go ?

I will be appreciated for a snippet of code.

Thanks in advance!

1

Typically you would first create a new filter (eth_newFilter + eth_getFilterLogs) and reuse that filter to perform the same query many times as well as listen for changes. However, you can also install an ad-hoc filter with eth_getLogs, referencing the topics you wish to search over.

A topic is a piece of data you are searching. For example, if you have the following event:

Transfer(address to, address from)

The following filter would search for all logs going to 0xb3904758c0d3bfc25746c47caa45b01da8930e19:

[0x000000000000000000000000b3904758c0d3bfc25746c47caa45b01da8930e19, null]

This filter would search for all logs coming from 0xb3904758c0d3bfc25746c47caa45b01da8930e19:

[null, 0x000000000000000000000000b3904758c0d3bfc25746c47caa45b01da8930e19]

And this filter would search for all logs going to 0xb3904758c0d3bfc25746c47caa45b01da8930e19 from 0x8cc19c7b50857abbfbeeed31c302319a075d4a9b:

[0x000000000000000000000000b3904758c0d3bfc25746c47caa45b01da8930e19, 0x0000000000000000000000008cc19c7b50857abbfbeeed31c302319a075d4a9b

A full golang wrapper for RPC requests would look something like this:

// 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
}

The EthereumClient can be instantiated in a different package by something like this:

// Global client connection
var client = EthereumClient{}

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

This client can now be used to start a new filter and get the logs from that filter.

I don't have a specific example for this use case, but please see this for some examples of making RPC requests in Go.

0

You can add contract address as a parameter to eth_getLogs call:

curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"address":["YOUR_CONTRACT_ADDRESS"]}],"id":74}'

If you are interested in constantly polling for events update, you may first create a filter with eth_newFilter and then ask for updates with eth_getFilterChanges.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.