简明介绍ethereum中events和logs

Events和logs在ethereum中十分重要,因为他们租金了智能合约和其用户接口之间的沟通。在常规的web开发中,在前端的回调中提供服务器相应。在ethereum中,当一个交易被矿工添加,智能合约可以激活事件events并将日志log写入前端可以处理的区块链。有不同的方法可以处理events和logs。这篇简要介绍会解释有关events的一些概念和与他们一起使用的一些实例代码。

Events可能会令人困惑,因为它们可以用不同的方式使用。一个event可能和另一个event完全不同。可以归纳为有三种主要的events和logs的实例:

  1. 智能合约对用户接口返回值;
  2. 异步触发和数据相关的事件;
  3. 更廉价的存储形式。

为用户接口提供智能合约返回值

最简单的event的使用是将contract中的返回值传递给应用程序的前端。为了说明以下为一个例子:

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

假设exampleContract是ExampleContract的一个实例(instance),前端交互使用web3.js,可以使用以下代码获取函数返回值:

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

但是,如果web3.js将这个函数提交为一笔交易(transaction),它就不能获得返回值:

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

sendTransaction的返回值永远都是交易的hash值。交易不会将函数的返回值发送给前端因为交易不是立即被矿工加入到区块中(有一定延迟)。

这是我们建议用event来实现得到函数返回值的功能,这也是使用events的一个目的之一。

contract ExampleContract {
  event ReturnValue(address indexed _from, int256 _value);
function foo(int256 _value) returns (int256) {
    ReturnValue(msg.sender, _value);
    return _value;
  }
}

前端可以使用如下代码获得返回值:

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})

当调用foo的transaction被miner挖矿时,watch当中的回调函数将会被触发,这允许前端来从foo获得返回值。

异步数据触发器

event通常可以被认为是数据的异步触发器。当一个智能合约想要触发前端时,合约会发出一个event。前端正在使用watch函数观察时间,他可以采取行动,显示消息等。

更廉价的数据存储

第三个用例和上面提到的不同,使用events作为一个更便宜的存储方式。在Ethereum Virtual Machine he Ethereum 黄皮书中,events对应于logs(LOG 字节码)。logs被设计成一个存储方式,比contract storage存储成本低很多。Logs消耗8 gas 每byte,而contract storage消耗20000 gas 每 32 bytes。虽然logs消耗更少,但logs不可以被任何contract所访问。

尽管如此,还是有使用logs作为廉价存储的用例,而不是前端的触发器。一个更合适的logs示例是存储前端可以呈现的历史数据。一笔加密货币交易可能想要显示一个用户的所有交易存款。不是将这些存款的详细信息存储在智能合约中,而是将它们存储为logs,这样会便宜很多。

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, etc
    Deposit(_market, msg.sender, _amount, now);
}

假设我们想在用户进行存款的时候更新用户界面。下面是一个使用event作为数据的异步触发器的示例,假设cryptoExchange是一CryptoExchange的一个示例:

var depositEvent = cryptoExContract.Deposit({_sender: userAddress});
depositEvent.watch(function(err, result) {
  if (err) {
    console.log(err)
    return;
  }
  // append details of result.args to UI
})

提高为用户获得所有event的效率是event的_sender参数被索引(indexed)的原因

event Deposit(uint256 indexed _market, address indexed _sender, uint256 _amount, uint256 _time)

默认情况下,监听event仅在event实例化时开始。当用户界面第一次加载时,没有追加的存款。所以我们希望从block 0 开始检索事件,这是通过在事件中添加一个'fromBlock'参数完成的。

var depositEventAll = cryptoExContract.Deposit({_sender: userAddress}, {fromBlock: 0, toBlock: 'latest'});
depositEventAll.watch(function(err, result) {
  if (err) {
    console.log(err)
    return;
  }
  // append details of result.args to UI
})

当呈现UI时,应调用depositEventAll.stopWatching()

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351