# 事件(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智能合約文件結構
- 智能合約源文件的基本要素概覽
- 值類型
- 類型
- 布爾
- 整型
- 地址
- 字節數組
- 小數
- 字符串
- 十六進制字面量
- 枚舉
- 函數
- 引用類型
- 引用類型
- 數據位置
- 數組
- 數據結構
- 雜項
- 映射
- 左值運算符
- 類型間的轉換
- 類型推斷
- 單位
- 貨幣單位
- 時間單位
- 語言內置特性
- 特殊變量及函數
- 數學和加密函數
- 地址相關
- 進階
- 入參和出參
- 控制結構
- 函數調用
- 創建合約實例
- 表達式的執行順序
- 賦值
- 作用范圍和聲明
- 異常
- 內聯匯編
- 合約詳解
- 合約
- 可見性或權限控制
- 訪問函數
- 函數修改器
- 常狀態變量
- 回退函數
- 事件
- 繼承
- 接口
- 其它
- 庫
- 狀態變量的存儲模型
- 內存變量的存局
- 調用數據的布局