# 事件(Events)
事件是使用EVM日志内置功能的方便工具,在DAPP的接口中,它可以反过来调用Javascript的监听事件的回调。
事件在合约中可被继承。当被调用时,会触发参数存储到交易的日志中(一种区块链上的特殊数据结构)。这些日志与合约的地址关联,并合并到区块链中,只要区块可以访问就一直存在(至少Frontier,Homestead是这样,但Serenity也许也是这样)。日志和事件在合约内不可直接被访问,即使是创建日志的合约。
日志的SPV(简单支付验证)是可能的,如果一个外部的实体提供了一个这样证明的合约,它可以证明日志在区块链是否存在。但需要留意的是,由于合约中仅能访问最近的256个区块哈希,所以还需要提供区块头信息。
可以最多有三个参数被设置为`indexed`,来设置是否被索引。设置为索引后,可以允许通过这个参数来查找日志,甚至可以按特定的值过滤。
如果数组(包括`string`和`bytes`)类型被标记为索引项,会用它对应的`Keccak-256`哈希值做为`topic`。
除非是匿名事件,否则事件签名(比如:`Deposit(address,hash256,uint256)`)是其中一个`topic`,同时也意味着对于匿名事件无法通过名字来过滤。
所有未被索引的参数将被做为日志的一部分被保存起来。
被索引的参数将不会保存它们自己,你可以搜索他们的值,但不能检索值本身。
下面是一个简单的例子:
```
pragma solidity ^0.4.0;
contract ClientReceipt {
event Deposit(
address indexed _from,
bytes32 indexed _id,
uint _value
);
function deposit(bytes32 _id) {
// Any call to this function (even deeply nested) can
// be detected from the JavaScript API by filtering
// for `Deposit` to be called.
Deposit(msg.sender, _id, msg.value);
}
}
```
下述是使用javascript来获取日志的例子。
```
var abi = /* abi as generated by the compiler */;
var ClientReceipt = web3.eth.contract(abi);
var clientReceipt = ClientReceipt.at(0x123 /* address */);
var event = clientReceipt.Deposit();
// watch for changes
event.watch(function(error, result){
// result will contain various information
// including the argumets given to the Deposit
// call.
if (!error)
console.log(result);
});
// Or pass a callback to start watching immediately
var event = clientReceipt.Deposit(function(error, result) {
if (!error)
console.log(result);
});
```
### 底层的日志接口(Low-level Interface to Logs)
通过函数`log0`,`log1`,`log2`,`log3`,`log4`,可以直接访问底层的日志组件。`logi`表示总共有带`i + 1`个参数(`i`表示的就是可带参数的数目,只是是从0开始计数的)。其中第一个参数会被用来做为日志的数据部分,其它的会做为主题(topics)。前面例子中的事件可改为如下:
```
log3(
msg.value,
0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20,
msg.sender,
_id
);
```
其中的长16进制串是事件的签名,计算方式是`keccak256("Deposit(address,hash256,uint256)")`
更多的理解事件的资源
- [Javascript documentation](https://github.com/ethereum/wiki/wiki/JavaScript-API#contract-events)
- [Example usage of events](https://github.com/debris/smart-exchange/blob/master/lib/contracts/SmartExchange.sol)
- [How to access them in js](https://github.com/debris/smart-exchange/blob/master/lib/exchange_transactions.js)
- Solidity语言
- 入门说明
- Solidity智能合约文件结构
- 智能合约源文件的基本要素概览
- 值类型
- 类型
- 布尔
- 整型
- 地址
- 字节数组
- 小数
- 字符串
- 十六进制字面量
- 枚举
- 函数
- 引用类型
- 引用类型
- 数据位置
- 数组
- 数据结构
- 杂项
- 映射
- 左值运算符
- 类型间的转换
- 类型推断
- 单位
- 货币单位
- 时间单位
- 语言内置特性
- 特殊变量及函数
- 数学和加密函数
- 地址相关
- 进阶
- 入参和出参
- 控制结构
- 函数调用
- 创建合约实例
- 表达式的执行顺序
- 赋值
- 作用范围和声明
- 异常
- 内联汇编
- 合约详解
- 合约
- 可见性或权限控制
- 访问函数
- 函数修改器
- 常状态变量
- 回退函数
- 事件
- 继承
- 接口
- 其它
- 库
- 状态变量的存储模型
- 内存变量的存局
- 调用数据的布局