以太坊中的事件(Events)和日志(Logs)是个特别让人困惑的概念,本文帮大家梳理。
因为上篇文章,我们讨论过以太坊go-ethereum客户端查询交易列表的一些办法,这篇文章,我们具体实现一种filter的探讨。让我们明白这种方法具体如何使用。重点在最后一部分。希望对开发起到一定的帮助作用。我们从基本的概念说起,来整体理解这个过程。
首先,以太坊中的Events和Logs基本上算是同一个概念。Solidity和web3.js中称为Events,以太坊黄皮书中称为Logs。你可以理解为:以太坊通过Logs实现Events(事件)功能。智能合约代码通过LOG 将日志写入区块链中。
(如果用Truffle框架开发也是一样的,因为Truffle框架本身就包装的Web3.js)
日志内容位于区块链的什么地方?
日志内容是交易收据(Transaction Receipts)的一部分,整个日志内容,包括Receipts的其它内容会生成一个ReceiptsRoot存储在区块的头部。而完整数据则是链下存储。
事件和日志的主要用途有四种:
1.帮助用户客户端(web3.js)读取智能合约的返回值;
2.智能合约异步通知用户客户端(web3.js);
3.用于智能合约的存储(比Storage便宜得多);
4.我认为有第四种,可以帮助我们通过filter过滤出历史交易数据,具体实现看下面文章解析。

下面我们逐个解释
1.帮助用户客户端(web3.js)读取智能合约的返回值:
假设下面的智能合约:

contract ExampleContract {// some state variables ...function foo(int256 _value) returns (int256) {// manipulate state ...return _value;}
}

我们可以通过web3.js的message call功能模拟调用智能合约:

var returnValue = exampleContract.foo.call(2);
console.log(returnValue) // 2

但是在真实的环境中我们需要发送交易(Transaction)来调用某个智能合约。这时我们将无法获得智能合约的返回值。因为该交易当前只是被发送、打包、执行还有一段时间(需要矿工的工作量证明来实现)。此时调用的返回值只是该交易的txid或称为tx hash值。

var returnValue = exampleContract.foo.sendTransaction(2, {from: web3.eth.coinbase});
console.log(returnValue) // transaction hash

这时事件(Events)就登场了:我们往往将写入链上方法,或者叫让链上数据改变的方法。我们在方法前面加上Event来实现。

//以下是solidity智能合约代码
contract ExampleContract {event ReturnValue(address indexed _from, int256 _value);unction foo(int256 _value) returns (int256) {ReturnValue(msg.sender, _value);return _value;}
}

//以下是web3.js用户客户端代码

var exampleEvent = exampleContract.ReturnValue({_from: web3.eth.coinbase});
exampleEvent.watch(function(err, result) {if (err) {console.log(err)return;}console.log(result.args._value)// check that result.args._from is web3.eth.coinbase then// display result.args._value in the UI and call    // exampleEvent.stopWatching()
})
exampleContract.foo.sendTransaction(2, {from: web3.eth.coinbase})

当交易被打包时,web3.js中的callback就会被调用,这时web3.js就可以得到交易中的智能合约调用的返回值了。
至于为什么交易打包,web3.js中的callback就被调用那是另一个问题了,简单解释如下。web3.js会和以太坊某个节点相连,当该节点得知某个交易写进block后,会通知相连的节点相关信息。
2.智能合约异步通知用户客户端(web3.js):
上面例子是智能合约通知用户客户端的典型例子,但还有更多的异步调用可以通过类似的方式实现,从而实现了智能合约异步调用用户客户端的能力。
注:智能合约通常用solidity编写,运行在以太坊节点上(EVM)。
注:用户客户端通常用web3.js编写,运行在web服务器上,web3.js跟某个以太坊节点相连。
3.用于智能合约的存储(比Storage便宜得多):
相比智能合约账户的Storage,用日志的方式存储一些信息会便宜很多。Storage中大致的价格是:每32字节(256位)存储需要消耗20,000气(Gas)。而日志大致是每字节8气(Gas)。
下面看一个例子:

//solidity智能合约代码,模拟用户存款功能
contract CryptoExchange {event Deposit(uint256 indexed _market, address indexed _sender, uint256 _amount, uint256 _time);function deposit(uint256 _amount, uint256 _market) returns (int256) {// perform deposit, update user’s balance, etcDeposit(_market, msg.sender, _amount, now);
}

//当某户调用智能合约存了某笔款后, 智能合约需要主动通知用户客户端更新相应信息。
4.帮助我们通过filter过滤出历史交易数据.
下面的方法具体实现我们开始讲的通过filter办法,从链上扒出历史交易数据的办法。
//以下是web3.js代码:

var depositEvent = cryptoExContract.Deposit({_sender: userAddress});
depositEvent.watch(function(err, result) {if (err) {console.log(err)return;}else{// append details of result.args to UI//将这笔交易写入客户端资料库中,方便以后查询历史交易数据。}
})
//通过增加fromBlock参数指定关注的区块范围,来查询所有的交易数据。(获取链上存储的历史交易数据,我们用扒链的办法来获取,因为eth目前没有提供获取历史数据的API。)
var depositEventAll = cryptoExContract.Deposit({_sender: userAddress}, {fromBlock: 0, toBlock: 'latest'});
depositEventAll.watch(function(err, result) {if (err) {console.log(err)return;}else{// append details of result.args to UI//如果不想再被通知可以调用://depositEventAll.stopWatching();}
})

//注:indexed关键字表示按该字段索引日志,以提高查询效率。
2017年12月24日整理于 深圳

区块链开发(十五)以太坊中的Events和Logs解析及用途相关推荐

  1. 从零开发区块链应用(十五)--以太坊交易匹配查询

    文章目录 一.获取区块内交易 1.1 获取最新区块中的交易详情 1.2 获取指定区块中的交易详情 二. 获取匹配交易回执主要信息 三.获取区块内交易数量 一.获取区块内交易 1.1 获取最新区块中的交 ...

  2. 区块链开发之搭建以太坊私有链

    (一)区块链开发之搭建以太坊私有链 本文链接:https://blog.csdn.net/rwdxll/article/details/82929417 1.安装ethereum/Go client( ...

  3. 区块链开发教程 # 2 以太坊公链

    科普向介绍请参考 tutorial.技术开发教程请参考本文.本系列文章更偏向技术入门.参考网上资料根据个人理解整理而成.本文主要参考廖雪峰博客. 前一篇文章地址:区块链开发教程 # 1 比特币公链 本 ...

  4. 04.区块链的那些事儿-以太坊中的 Patricia Tree

    本节主要讨论以太坊中存储的 Patricia Tree 比特币只有1棵Merkle树,而以太坊的每一个区块头,并非只包含1棵Merkle Tree,而是包含了3棵Merkle Tree,分别对应了三种 ...

  5. 区块链学习笔记16——以太坊中的交易树和收据树

    十六.以太坊中的交易树和收据树 每次发布一个交易的时候,那些交易会组织成一个交易树,也是一颗Merkle tree跟比特币中的情况是类似的,同时以太坊还增加了一个收据树,每个交易执行完之后会形成一个收 ...

  6. 从零开发区块链应用(十二)--以太坊余额查询

    文章目录 一.账户状态stateTrie 1.2 查询余额代码思路 1.3 余额查询流程 二.获取账户余额 2.1 代码解析 2.2 完整代码 三.获取账户代币余额 一.账户状态stateTrie B ...

  7. 视频教程-区块链项目:基于以太坊开发拍卖系统DApp教程(含资料)-区块链

    区块链项目:基于以太坊开发拍卖系统DApp教程(含资料) 张长志技术全才.擅长领域:区块链.大数据.Java等.10余年软件研发及企业培训经验,曾为多家大型企业提供企业内训如中石化,中国联通,中国移动 ...

  8. 区块链开发(五)区块链ICO:互联网进化的驱动力

    区块链开发(五)区块链ICO:互联网进化的驱动力 李赫 2016年10月8日 由于区块链不可篡改的特性,在众多区块链组织和公司的共同努力下,互联网将逐步从中心化的信任进化到由算法.数据为核心的去中心化 ...

  9. 区块链技术--Ethereum(以太坊)

    以太坊项目进一步扩展了区块链网络的能力,从交易延伸为智能合约(Smart Contract) 其官网首页为 ethereum.org. 简介 根据以太坊官方的宣称,以太坊(Ethereum)目标是打造 ...

最新文章

  1. golang defer简介 goland 警告提示 possible resource leak,difer is called in a for loop 原因
  2. Linux C编程中的段错误
  3. NOV. 2nd, 减肥第三天
  4. 周志华《机器学习》西瓜书出全新视频课啦!
  5. centos mysql pid_centos7 mysql The server quit without updating PID file(错误解决)
  6. windows中mysql添加环境变量_windows 下添加mysql到系统环境变量
  7. java 多线程的一种实现方式
  8. atitit.架构设计---方法调用结果使用异常还是返回值
  9. [网络安全自学篇] 九十四.《Windows黑客编程技术详解》之提权技术(令牌权限提升和Bypass UAC)
  10. 品优购项目——黑马程序员pink老师/完整源代码/项目讲解
  11. 解析常见网络钓鱼攻击方法
  12. 【wps表格】重点标识折线图上的某个数据点
  13. 等比缩放公式_等比缩放算法
  14. 小福利,通过python利用百度ai实现图片识别
  15. 给PPT插入页码和总页码
  16. 原来java有这么多把锁,图解java中的17把锁
  17. 从“受精卵”到“独角兽”,有多大概率?
  18. request to https://registry.npm.taobao.org/jsprim failed, reason: connect ETIMEDOUT 错误解决方案
  19. 因为 QUERY_ALL_PACKAGES 权限,我们上不了 Google Play 了
  20. plc 梯形图 转c语言,电路与PLC之间的梯形图转化,电气人必备技能!

热门文章

  1. String为什么无法在方法中修改原有string变量的值
  2. ansible系列5-开启加速 Ansible 执行速度的功能
  3. 设置软件有效许可期(设置截止时间)
  4. scrapy爬虫之爬取汽车之家奥迪Q7高清图片
  5. potplayer重置设置_potplayer 设置更清晰 - 卡饭网
  6. 面试:线程安全的恶汉单例
  7. 鸿蒙系统可以几年不卡顿,鸿蒙系统会不会越用越卡?鸿蒙系统会影响王者荣耀吗?...
  8. 遭遇公司裁员,如何赔偿?
  9. 当年准备去的那家公司,如今裁员了
  10. Android 增量更新实现