These are chat archives for DigixGlobal/ethereum-ruby

4th
Feb 2016
Jikku Jose
@JikkuJose
Feb 04 2016 05:18
Is it possible to have a transpiller be made for Ruby to Solidity?
Anthony C. Eufemio
@tymat
Feb 04 2016 12:54
@JikkuJose on the first question there's no documentation yet... I'm planning on refactoring everything at some point but for now the README has some examples
Oleg Aldekein
@Aldekein
Feb 04 2016 12:55
Hello, everybody! Is it possible to read contract events from ruby library?
Anthony C. Eufemio
@tymat
Feb 04 2016 12:55
as far as a transpiler it's probably going to take a lot more work... we're going to wait until we hear more about the WebAssembly stuff that the Ethereum folks are planning
@Aldekein yes.. this is exactly what the library was made for so that you can interact with contract events
the latest branch actually allows you to create a filter and read the filter events from it
Oleg Aldekein
@Aldekein
Feb 04 2016 12:56
I've got an instance of Ethereum::ContractEvent after I called .at on contract instance.
Anthony C. Eufemio
@tymat
Feb 04 2016 12:56
and eventually once go-ethereum 1.4.0 is released I'm planning on adding the pub-sub support
Oleg Aldekein
@Aldekein
Feb 04 2016 12:57
But I'm not sure how to apply filters now.
Anthony C. Eufemio
@tymat
Feb 04 2016 12:57
so if you initialized your contract
let's say you have a solidity contract that has event Transfer
my_contract.nf_transfer (which will return a filter ID)
and you can do my_contract.gfl(filter_id)
my_contract.gfl_transfer(filter_id)
and my_contract.gfc_transfer(filter_id)
(this will change in version 2.0)
Oleg Aldekein
@Aldekein
Feb 04 2016 13:00
ok, I've got a filter ID.
Anthony C. Eufemio
@tymat
Feb 04 2016 13:01
there's a gfl_<event name>(filter_id) method
gfl = get filter logs which will show you all of the events
gfc = get filter changes (only get the changes since you created the filter)
Oleg Aldekein
@Aldekein
Feb 04 2016 13:01
can I pass arguments to filter?
Anthony C. Eufemio
@tymat
Feb 04 2016 13:01
when you create the filter you can
same as what you would use from web3.js
Oleg Aldekein
@Aldekein
Feb 04 2016 13:02
#<Ethereum::ContractEvent:0x007f9814188c98 @name="Transaction", @input_types=["bytes32", "address", "address", "uint256", "uint256"], @inputs=["hash", "from", "to", "time", "amount"], @event_string="Transaction(bytes32,address,address,uint256,uint256)", @signature="ea0f544916910bb1ff33390cbe54a3f5d36d298328578399311cde3c9a750686", @address="0x276c5c6ca8507ed7bac085fc9b9521f4f54b58d3", @client=#<Ethereum::HttpClient:0x007f981261ab28 @host="127.0.0.1", @port="10043", @id=2, @uri=#<URI::HTTP http://127.0.0.1:10043>, @batch=[]>>
so, should I pass arguments when I call db.nf_transaction to get filter ID?
Oleg Aldekein
@Aldekein
Feb 04 2016 13:09
I've looked into source code and tried this:
>> db.nf_transaction({:from_block => "0x#{697172.to_s(16)}", :to_block => "0x#{697173.to_s(16)}"})
"0x60d77f369d72b1a2c96a6c0929006184"

>> res = db.gfl_transaction("0x60d77f369d72b1a2c96a6c0929006184")
NoMethodError: undefined method `gsub' for nil:NilClass
I'm filtering by blocks cause there are about 150000 of events.
Oleg Aldekein
@Aldekein
Feb 04 2016 13:18

Probably it's a bug. When I do

$ethereum.get_filter_logs("0x5cc803fa48eeb2735b7f4adbb320c5a1")

I get a valid response. But if I do gfl_transaction with the same filter ID I get a following stacktrace:

NoMethodError: undefined method `gsub' for nil:NilClass
    from /usr/local/lib/ruby/gems/2.3.0/gems/ethereum-0.4.95/lib/ethereum/formatter.rb:92:in `to_int'
    from /usr/local/lib/ruby/gems/2.3.0/gems/ethereum-0.4.95/lib/ethereum/formatter.rb:134:in `output_to_uint'
    from /usr/local/lib/ruby/gems/2.3.0/gems/ethereum-0.4.95/lib/ethereum/formatter.rb:122:in `from_payload'
    from /usr/local/lib/ruby/gems/2.3.0/gems/ethereum-0.4.95/lib/ethereum/contract.rb:124:in `block (5 levels) in build'
    from /usr/local/lib/ruby/gems/2.3.0/gems/ethereum-0.4.95/lib/ethereum/contract.rb:123:in `each'
    from /usr/local/lib/ruby/gems/2.3.0/gems/ethereum-0.4.95/lib/ethereum/contract.rb:123:in `block (4 levels) in build'
    from /usr/local/lib/ruby/gems/2.3.0/gems/ethereum-0.4.95/lib/ethereum/contract.rb:119:in `each'
    from /usr/local/lib/ruby/gems/2.3.0/gems/ethereum-0.4.95/lib/ethereum/contract.rb:119:in `block (3 levels) in build'
    from (irb):33
    from /usr/local/lib/ruby/gems/2.3.0/gems/railties-4.2.4/lib/rails/commands/console.rb:110:in `start'

The problem is in:

    def to_int(hexstring)
      (hexstring.gsub(/^0x/,'')[0..1] == "ff") ? (hexstring.hex - (2 ** 256)) : hexstring.hex
    end

maybe the whole function contents could be replaced by

    def to_int(hexstring)
      hexstring.to_i(16)
    end
Oleg Aldekein
@Aldekein
Feb 04 2016 13:23
Though it will fail on nil anyway :D
Oleg Aldekein
@Aldekein
Feb 04 2016 13:51

The problem tends to be deeper than I thought.
Here's one of log entries I get from get_filter_logs in ruby:

        [0] {
                     "address" => "0x276c5c6ca8507ed7bac085fc9b9521f4f54b58d3",
                   "blockHash" => "0xb30067417539a2f7c2b913d308909bc9aa4aa2c7c3cf03e11fa189740505820f",
                 "blockNumber" => "0xaa439",
                        "data" => "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f42400",
                    "logIndex" => "0x0",
                      "topics" => [
                [0] "0xea0f544916910bb1ff33390cbe54a3f5d36d298328578399311cde3c9a750686",
                [1] "0x0000000000000000000000000000000000000000000000000000000000000000",
                [2] "0x00000000000000000000000048175da4c20313bcb6b62d74937d3ff985885701",
                [3] "0x0000000000000000000000000000000000000000000000000000000000000000"
            ],
             "transactionHash" => "0x9c2060107102e5fe72c3e9b2c9d978a0c794ffd18cc28d706e9390e0ecd7a365",
            "transactionIndex" => "0xa"
        },

Here's the same I get from web3 console in JS:

{
    "address": "0x276c5c6ca8507ed7bac085fc9b9521f4f54b58d3",
    "args": {
        "amount": "16000000",
        "from": "0x48175da4c20313bcb6b62d74937d3ff985885701",
        "hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "time": "0",
        "to": "0x0000000000000000000000000000000000000000"
    },
    "blockHash": "0xb30067417539a2f7c2b913d308909bc9aa4aa2c7c3cf03e11fa189740505820f",
    "blockNumber": 697401,
    "event": "Transaction",
    "logIndex": 0,
    "transactionHash": "0x9c2060107102e5fe72c3e9b2c9d978a0c794ffd18cc28d706e9390e0ecd7a365",
    "transactionIndex": 10
}

I don't see in topics anything like f42400 which is "amount": "16000000" converted to HEX.

I've checked the place where topics are calculated from event signature:
Transaction(bytes32,address,address,uint256,uint256)
Oleg Aldekein
@Aldekein
Feb 04 2016 14:00
I've manually constructed the payload, created a filter, got results and they have only 4 topics :(
            payload = {topics: ['ea0f544916910bb1ff33390cbe54a3f5d36d298328578399311cde3c9a750686'], fromBlock: "0xaa439", toBlock: "0xaa439", address: "0x276c5c6ca8507ed7bac085fc9b9521f4f54b58d3"}
            filter_id = connection.new_filter(payload)
Looks like a bug in RPC itself.
Oleg Aldekein
@Aldekein
Feb 04 2016 15:29
Oh. Look like I am lame and didn't read the docs :( https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#events explains it.
Oleg Aldekein
@Aldekein
Feb 04 2016 15:45

So in

outputs = inputs.zip(result["topics"][1..-1])

There's a problem that it doesn't parse and return EVENT_NON_INDEXED_ARGS at all.

Anthony C. Eufemio
@tymat
Feb 04 2016 16:19
if you see any bugs please feel free to submit a PR