go语言程序化交易 go语言gui编程( 二 )


返回的所有日志将是ABI编码,因此它们本身不会非常易读 。为了解码日志,我们需要导入我们智能合约的ABI 。为此,我们导入编译好的智能合约Go包,它将包含名称格式为 ContractABI 的外部属性 。之后,我们使用go-ethereum中的 accounts/abi 包的 abi.JSON 函数返回一个我们可以在Go应用程序中使用的解析过的ABI接口 。
现在我们可以通过日志进行迭代并将它们解码为我么可以使用的类型 。若您回忆起我们的样例合约释放的日志在Solidity中是类型为 bytes32 ,那么Go中的等价物将是 [32]byte。我们可以使用这些类型创建一个匿名结构体,并将指针作为第一个参数传递给解析后的ABI接口的 Unpack 函数,以解码原始的日志数据 。第二个参数是我们尝试解码的事件名称,最后一个参数是编码的日志数据 。
此外 , 日志结构体包含附加信息,例如,区块摘要,区块号和交易摘要 。
若您的solidity事件包含 indexed 事件类型,那么它们将成为 主题 而不是日志的数据属性的一部分 。在solidity中您最多只能有4个主题,但只有3个可索引的事件类型 。第一个主题总是事件的签名 。我们的示例合约不包含可索引的事件,但如果它确实包含,这是如何读取事件主题 。
正如您所见 , 首个主题只是被哈希过的事件签名 。
这就是阅读和解析日志的全部内容 。要学习如何订阅日志 , 阅读上个章节 。
命令
Store.sol
event_read.go
首先,创建ERC-20智能合约的事件日志的interface文件erc20.sol :
然后在给定abi使用 abigen 创建Go包
现在在我们的Go应用程序中,让我们创建与ERC-20事件日志签名类型相匹配的结构类型:
初始化以太坊客户端
按照ERC-20智能合约地址和所需的块范围创建一个“FilterQuery” 。这个例子我们会用 ZRX代币:
用 FilterLogs 来过滤日志:
接下来我们将解析JSON abi,稍后我们将使用解压缩原始日志数据:
为了按某种日志类型进行过滤,我们需要弄清楚每个事件日志函数签名的keccak256哈希值 。事件日志函数签名哈希始终是 topic [0]  , 我们很快就会看到 。以下是使用go-ethereum crypto 包计算keccak256哈希的方法:
现在我们将遍历所有日志并设置switch语句以按事件日志类型进行过滤:
现在要解析 Transfer 事件日志,我们将使用 abi.Unpack 将原始日志数据解析为我们的日志类型结构 。解包不会解析 indexed 事件类型,因为它们存储在 topics 下 , 所以对于那些我们必须单独解析,如下例所示:
Approval日志也是类似的方法:
最后,把所有的步骤放一起:
我们可以把解析的日志与etherscan的数据对比:
Commands
erc20.sol
event_read_erc20.go
solc version used for these examples
要读取 0x Protocol 事件日志,我们必须首先将solidity智能合约编译为一个Go包 。
安装solc版本 0.4.11
为例如 Exchange.sol 的事件日志创建0x Protocol交易所智能合约接口:
Create the 0x protocol exchange smart contract interface for event logs asExchange.sol :
接着给定abi,使用 abigen 来创建Go exchange 包:
Then useabigento create the Goexchangepackage given the abi:
现在在我们的Go应用程序中 , 让我们创建与0xProtocol事件日志签名类型匹配的结构体类型:
初始化以太坊客户端:
创建一个 FilterQuery,并为其传递0x Protocol智能合约地址和所需的区块范围:
用 FilterLogs 查询日志:
接下来我们将解析JSON abi , 我们后续将使用解压缩原始日志数据:
为了按某种日志类型过滤,我们需要知晓每个事件日志函数签名的keccak256摘要 。正如我们很快所见到的那样,事件日志函数签名摘要总是 topic[0] :

推荐阅读