Contract#logs should support filtering by indexed parameters
Opened this issue · 2 comments
right now it's able to filter by raw ABI encoded hexadecimals.
would be nice to filter like:
Event(uint indexed a, uint indexed b)
{
matches: ["Event", [1,2,3], 2]
}
Modify waitLogs
@hayeah Could you please more details for the issue? Thank you
The RPC call to get contract logs is:
searchlogs <fromBlock> <toBlock> (address) (topics)
requires -logevents to be enabled
Argument:
1. "fromBlock" (numeric, required) The number of the earliest block (latest may be given to mean the most recent block).
2. "toBlock" (string, required) The number of the latest block (-1 may be given to mean the most recent block).
3. "address" (string, optional) An address or a list of addresses to only get logs from particular account(s).
4. "topics" (string, optional) An array of values from which at least one must appear in the log entries. The order is important, if you want to leave topics out use null, e.g. ["null", "0x00..."].
5. "minconf" (uint, optional, default=0) Minimal number of confirmations before a log is returned
Examples:
> qtum-cli searchlogs 0 100 '{"addresses": ["12ae42729af478ca92c8c66773a3e32115717be4"]}' '{"topics": ["null","b436c2bf863ccd7b8f63171201efd4792066b4ce8e543dde9c3e9e9ab98e216c"]}'
> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "searchlogs", "params": [0 100 {"addresses": ["12ae42729af478ca92c8c66773a3e32115717be4"]} {"topics": ["null","b436c2bf863ccd7b8f63171201efd4792066b4ce8e543dde9c3e9e9ab98e216c"]}] }' -H 'content-type: text/plain;' http://127.0.0.1:3889/
You can filter the logs by matching which topics you want. In the example, the topics
array is a list of hexadecimals:
{"topics": ["null","b436c2bf863ccd7b8f63171201efd4792066b4ce8e543dde9c3e9e9ab98e216c"]}
This is the lower EVM mechanism.
Check the help message for the waitforlogs
, which is similar, but does long-polling to wait for new logs to arrive.
Solidity Event Logs
Suppose we have a solidity event looking like this:
event Foo(uint256 indexed a, uint256 indexed b);
This event type would emit three topics: Foo
, a
, and b
, but ABI-encoded. For details about this, see How Solidity Events Are Implemented.
To filter by topics, the underlying RPC call expects the log parameter values to be ABI-encoded hexadecimal string.
In the Contract
class, we should handle the ABI-encoding automatically for user, filtering waitforlogs like this:
contract.waitLogs({
matches: ["Foo", 1, 2],
})
And the library should convert that to a instance of ILogFilter.
To do the ABI-conversion, you'll need to read the contract's ABI info (generated by the solidity compiler), which for an event looks something like this:
{
"name": "emitFooEvent",
"type": "function",
"payable": false,
"inputs": [
{
"name": "a",
"type": "string",
"indexed": false
}
],
"outputs": [
{
"name": "",
"type": "string",
"indexed": false
}
],
"constant": false,
"anonymous": false
},