首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

80%开发者都不知道的以太坊骚操作:事件和日志 还可以这么玩!

4月6日,Daniel Larimer发布了一篇文章《EOSIO Dawn 3.0 Now Available》(译:EOSIO Dawn 3.0来啦),在章节「Simplified Contract Development」(译:更简单的合约开发)中,举了个「Hello,World」的智能合约的例子来说明合约开发的简单。

https://gist.githubusercontent.com/bytemaster/

58d45d13dbf8732c8d467b6415a44df9/raw/ba460c2aff29c7f60ecdef7dc082a0190b5af418/

hello.cpp

然而值得注意的是,示例的合约就执行了一条语句:print( "Hello, ", user);

那么问题来了:在智能合约中print的内容会出现在哪里呢?

我没实际运行过这段代码,但我知道,print的内容只会出现在每个区块链节点的日志文件或终端(Console)上。 实际上,传统的print日志打印对智能合约的开发和跟踪不存在任何意义。

那么,以太坊怎么解决这个问题的呢?以太坊引入了事件(Events)和日志(Logs)。

这里说的「事件」和「日志」这两个术语可能会引起混淆,本质上来说,智能合约通过「事件」来产生「日志」。本文会介绍以太坊的「事件」和「日志」系统常用的3种场景,供以太坊开发者参考。

事件和日志的用途

「事件」和「日志」对于以太坊是非常重要的,因为它们使智能合约与用户界面之间的通信变得容易。在传统的Web开发中,一个服务器响应会提供回调给前端。在以太坊中,当一个交易被打包,智能合约能发送事件以及写日志到区块链上以便前端处理。有三种情况需要使用事件和日志。

1. 智能合约给用户界面返回值

我们还是以EOS的例子来看,鉴于Solidity拼接字符串比较麻烦,我就直接返回一个字符串。

如果你用Web3.JS来调用HelloWorld这个智能合约的函数「hi()」,你可能会认为是这样:

那么,这句调用的result会是「hello, World」呢? 其实不是,不管函数返回什么值,Web3.JS都会返回一个Transaction Hash(交易哈希)。

那要怎么做呢?现在就轮到事件上场了。

修改后的智能合约代码如下:

而Web3.JS则需要这样写:

当交易被打包时,回调函数将被触发, 前端将获得智能合约函数的返回值。

2. 异步数据通知

使用返回值返回给用户界面其实很少用到。大部分时间,我们是使用事件给用户界面发送数据。当智能合约想把某些数据通知用户界面时,可以发送事件,用户界面对这些时间进行监听,就可以进行不同的操作。

3. 相对便宜的数据存储

还有这一种使用方式是把日志作为数据存储。在EVM规范和黄皮书中说明,事件将产生日志,而日志是会被存储都区块链的。日志存储的Gas费用要比合约的存储便宜很多(日志每个字节花费8个Gas,而合约存储是每32个字节20,000个Gas)。因此,当你有存证等应用的时候,可以考虑使用日志来存储,而不是在合约中使用Mapping来存储。

日志的存储结构

上面说了时间和日志的三种用法,最后我们来看看日志的大致结构。

你可以通过「remix」查看日志的接口。Topic指向特定的事件,但值是16进制的,这是个什么呢?其实这是事件的签名。图中的288d740d3b11a36c8526119855345e3ba2aee438370d264289ea6dfb76294fd0其实是sha3(Hi(string))的执行结果。下面的「event」和「args」是「remix」从区块链的「收据」(Receipt)数据的Logs项中解码出来的。

实际数据为:

那是怎么解码的呢?

前文中提到过,Topics实际上是事件的「sha3」签名,示例合约中只有一个事件,可以直接对应,如果合约中有多个事件,需要通过ABI找出对应的event,逐一签名,最后与Topics中的签名进行对应即可找到对应的事件。

事件的名称找到了,对应的参数就相对简单,示例合约的ABI如下:

可以看到,type为event的事件,「输入」(inputs)只有一个,那就是「say」,类型是「string」。

我们使用eth-abi工具(https://github.com/ethereum/eth-abi)可以进行解码。(eth-abi是一个用Python编写的Ethereum ABI工具)。命令如下:

在web3.js 1.0-beta版本中,可以直接通过以下函数进行日志解码:

结束语

「事件」(Events)是以太坊中很有意思的设计,对智能合约运行时与外部交互,特别是DApp的设计具有重要意义。大家在开发DApp和智能合约时可以根据实际情况灵活应用以上所介绍的3种方式,进行与前端的交互和日志的调试。也欢迎大家发掘更多的应用场景。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180504A1OV2N00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券