當一個參數沒有 indexed
屬性時, 他們會被 ABI-encoded
成 log
的 data
部分。
如果一個參數有 indexed
屬性,他們會被包含在 topics
裡面。
var options = {
fromBlock: 0,
address: web3.eth.defaultAccount,
topics: ["0x0000000000000000000000000000000000000000000000000000000000000000", null, null]
};
web3.eth.subscribe('logs', options, function (error, result) {
if (!error)
console.log(result);
})
.on("data", function (log) {
console.log(log);
})
.on("changed", function (log) {
});
Topics
Topics 是一個包含 event
裡的 indexed
參數們的物件。
topic[0]
代表的是一個事件它自己的 hash 的 hash。可以擁有最多三個的 indexed
參數,每一個會有相對應的 topics
元素。
以下的範例是使用 web3.js
subscribe("logs")
這個方法去過濾 logs 中符合特定 address
的 topics
:
var options = {
fromBlock: 0,
address: web3.eth.defaultAccount,
topics: ["0x0000000000000000000000000000000000000000000000000000000000000000", null, null]
};
web3.eth.subscribe('logs', options, function (error, result) {
if (!error)
console.log(result);
})
.on("data", function (log) {
console.log(log);
})
.on("changed", function (log) {
});
EVM 使用低階原始語言去呼叫 logs 並且 map
他們成高階的 Solidity 結構,也就是 Event
。Logs 裡面可能儲存 indexed arguments
於不同的 topics
。
舉例來說:
contract SimpleAuction {
event PersonCreated(uint indexed age, uint height);
}
function foobar() {
emit PersonCreated(26, 176);
}
當我們觸發了這個事件,將會製造一個擁有 topics
的低階的以太坊虛擬機日誌接口(low-level EVM log entry):
0x6be15e8568869b1e100750dd5079151b32637268ec08d199b318b793181b8a7d
Keccak-256 hash of PersonCreated(uint256,uint256)
0x36383cc9cfbf1dc87c78c2529ae2fcd4e3fc4e575e154b357ae3a8b2739113cf
Keccak-256 hash of age
, 反得到 value
為 26
我們會發現 height
並不存在於 topics
裡面,因為它屬於 event
裡面 data
的部分。
如果我們在 web3 的客戶端想要聆聽所有 persons
的事件,其中每個人都是 age == 26
,我們可以做以下動作:
var createdEvent = myContract.PersonCreated({age: 26});
createdEvent.watch(function(err, result) {
if (err) {
console.log(err)
return;
}
console.log("Found ", result);
})