На данный момент я разрабатываю dapps, которые используют смарт-контракты в качестве хранилища для конкретных данных. Я использую abigen для создания конкретной привязки к моему контракту. Если кто-то попытается изменить состояние контракта, я использую событие для регистрации этого действия. Но я застрял, потому что я действительно не понимаю, как я могу просмотреть историю журнала определенного события, используя go ethereum.
Как я могу использовать вызов eth_getlogs
метода json rpc и получить все журналы, которые хранятся на этом адресе контракта, с помощью go?
Я буду признателен за фрагмент кода.
Заранее спасибо!
Обычно вы сначала создаете новый фильтр ( eth_newFilter
+ eth_getFilterLogs
) и повторно используете этот фильтр для многократного выполнения одного и того же запроса, а также для прослушивания изменений. Однако вы также можете установить специальный фильтр с помощью eth_getLogs
ссылки на темы, по которым вы хотите выполнить поиск.
Тема — это фрагмент данных, который вы ищете. Например, если у вас есть следующее событие:
Transfer(address to, address from)
Следующий фильтр будет искать все журналы, идущие в 0xb3904758c0d3bfc25746c47caa45b01da8930e19
:
[0x000000000000000000000000b3904758c0d3bfc25746c47caa45b01da8930e19, null]
Этот фильтр будет искать все журналы, поступающие из 0xb3904758c0d3bfc25746c47caa45b01da8930e19
:
[null, 0x000000000000000000000000b3904758c0d3bfc25746c47caa45b01da8930e19]
И этот фильтр будет искать все журналы, идущие 0xb3904758c0d3bfc25746c47caa45b01da8930e19
от 0x8cc19c7b50857abbfbeeed31c302319a075d4a9b
:
[0x000000000000000000000000b3904758c0d3bfc25746c47caa45b01da8930e19, 0x0000000000000000000000008cc19c7b50857abbfbeeed31c302319a075d4a9b
Полная оболочка golang для RPC-запросов будет выглядеть примерно так:
// 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
можно использовать для запуска нового фильтра и получения журналов из этого фильтра.
У меня нет конкретного примера для этого варианта использования, но, пожалуйста, посмотрите здесь несколько примеров выполнения запросов RPC в Go.
Вы можете добавить адрес контракта в качестве параметра вызова eth_getLogs:
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"address":["YOUR_CONTRACT_ADDRESS"]}],"id":74}'
Если вы заинтересованы в постоянном опросе обновлений событий, вы можете сначала создать фильтр с помощью eth_newFilter, а затем запрашивать обновления с помощью eth_getFilterChanges .