event事件
Event
事件是EVM上日志的抽象,具有两大特点:
emit
触发事件,可以直接过滤、订阅事件- 经济友好,通过
Event
存储数据,每次存储大概花销2000gas
event Transfer(address indexed from, address indexed to, uint256 value);
事件Transfer内部参数表示需要记录在链上的变量类型和参数名称
- 通过
indexed
关键字,单独将事件参数作为一个topic
进行存储和索引 - 一个
Event
最多拥有三个indexed
数据 - 没有
indexed
关键字修饰的参数作为data
变量存储在data
域中,作为参数解析
Golang 解析 event事件
func ParseLogFromReceipet(contract, txhash string) {
receipet, err := client.TransactionReceipt(context.Background(), common.HexToHash(txhash))
if err != nil {
log.Fatalf("Error in get TransactionReceipt: %s", err)
}
if receipet.Status == 0 {
fmt.Printf("Tx has failed\n")
return
}
logs := receipet.Logs
ParseLogs(logs, contract)
}
func ParseLogs(logs []*types.Log, contract string) bool {
for _, logData := range logs {
if logData.Address != common.HexToAddress(contract) {
continue
}
Sender := common.HexToAddress(logData.Topics[1].Hex())
types, _ := strconv.ParseInt(hexutil.Encode(logData.Topics[2].Bytes())[2:], 16, 64)
uuid, _ := strconv.ParseInt(hexutil.Encode(logData.Topics[3].Bytes())[2:], 16, 64)
fmt.Printf("Contract: %s, Sender: %s, types: %d, uuid: %d\n", contract, Sender, types, uuid)
return true
}
return false
}
event topic过滤
同时过滤topic1 + topic2 的 logs
for startBlockHeight < latestblockNum {
toblock := startBlockHeight + 10000
if toblock > latestblockNum {
toblock = latestblockNum
}
query := ethereum.FilterQuery{
FromBlock: big.NewInt(startBlockHeight),
ToBlock: big.NewInt(toblock),
Addresses: []common.Address{common.HexToAddress(contract)},
Topics: [][]common.Hash{{common.HexToHash("topic1"), common.HexToHash("topic2")}},
}
logs, err := mainnetLPClient.FilterLogs(context.Background(), query)
if err != nil {
fmt.Printf("Error in filter logs: error:%v", err)
return
}
}