Git Product home page Git Product logo

ethereum.rb's Introduction

Ethereum for Ruby

GitHub Workflow Status GitHub release (latest by date) Gem Gem Visitors codecov Maintainability Top Language Yard Doc API Usage Wiki Open-Source License Contributions Welcome

A straightforward library to build, sign, and broadcast Ethereum transactions. It allows the separation of key and node management. Sign transactions and handle keys anywhere you can run Ruby and broadcast transactions through any local or remote node. Sign messages and recover signatures for authentication.

Note, this repository is just a public archive of the no longer maintained ethereum gem. For the partial rewrite and merge with the eth gem see q9f/eth.rb.

Highlights

  • Simple syntax, programmer friendly
  • Deploy and interact with contracts on the blockchain
  • Contract - ruby object mapping to solidity contract
  • Signing transactions with ruby-eth gem.
  • Compile Solidity contracts with solc compiler from ruby
  • Receive events from contract
  • Make direct json rpc calls to node from ruby application
  • Connect to node via IPC or HTTP
  • Helpful rake tasks for common actions

Installation

Before installing the gem make sure you meet all prerequisites, especially that you have:

  • compatible ethereum node installed
  • compatible solidity compiler installed
  • wallet with some ethereum on it

Before you run a program check that the node is running and accounts you want to spend from are unlocked.

To install gem simply add this line to your application's Gemfile:

gem 'ethereum.rb'

And then execute:

$ bundle

Or install it yourself as:

$ gem install ethereum.rb

Basic Usage

You can create a contract from solidity source and deploy it to the blockchain, with the following code:

contract = Ethereum::Contract.create(file: "greeter.sol")
address = contract.deploy_and_wait("Hello from ethereum.rb!")

Deployment may take up to a couple of minutes. Once deployed you can start interacting with the contract, e.g. calling it's methods:

contract.call.greet # => "Hello from ethereum.rb!"

You can see example contract greeter here.

If contract method name uses camel case you must convert it to snake case when use call: call.your_method.

Smart contracts

Compile multiple contracts at once

If you want to complie multiple contracts at once, you can create new instances using newly declared ruby clasess:

Ethereum::Contract.create(file: "mycontracts.sol", client: client)
contract = MyContract1.new
contract = contract.deploy_and_wait
contract2 = MyContract2.new
contract2 = contract.deploy_and_wait

All names used to name contract in solidity source will translate to name of classes in ruby (camelized).

Note: If class of given name exist it will be undefined first to avoid name collision.

Get contract from blockchain

The other way to obtain a contract instance is to get one that already exists on the blockchain. To do so you need a contract name, contract address and ABI definition.

contract = Ethereum::Contract.create(name: "MyContract", address: "0x01a4d1A62F01ED966646acBfA8BB0b59960D06dd ", abi: abi)

Note that you need to specify a contract name, that will be used to define new class in ruby, as it is not a part of the ABI definition.

Alternatively you can obtain the abi definition and name from a contract source file:

contract = Ethereum::Contract.create(file: "MyContract.sol", address: "0x01a4d1A62F01ED966646acBfA8BB0b59960D06dd ")

If you want to create a new contract, that is not yet deployed from ABI definition you will need also to supply binary code:

contract = Ethereum::Contract.create(name: "MyContract", abi: abi, code: "...")

Simple Truffle integration

If you use Truffle to build and deploy contracts, you can pick up the Truffle artifacts to initialize a contract. For example, if you have a MyContract in the Truffle directory at /my/truffle/project:

contract = Ethereum::Contract.create(name: "MyContract", truffle: { paths: [ '/my/truffle/project' ] }, client: client, address: '0x01a4d1A62F01ED966646acBfA8BB0b59960D06dd')

The contract factory will attempt to load the deployed address from the Truffle artifacts if the client's network is present:

contract = Ethereum::Contract.create(name: "MyContract", truffle: { paths: [ '/my/truffle/project' ] }, client: client)

Interacting with contract

Functions defined in a contract are exposed using the following conventions:

contract.transact.[function_name](params)
contract.transact_and_wait.[function_name](params)
contract.call.[function_name](params)

Example Contract in Solidity

contract SimpleRegistry {
  event LogRegister(bytes32 key, string value);
  mapping (bytes32 => string) public registry;

  function register(bytes32 key, string value) {
    registry[key] = value;
    LogRegister(key, value);
  }

  function get(bytes32 key) public constant returns(string) {
    return registry[key];
  }

}

For contract above here is how to access it's methods:

contract.transact_and_wait.register("performer", "Beastie Boys")

Will send transaction to the blockchain and wait for it to be mined.

contract.transact.register("performer", "Black Eyed Peas")

Will send transaction to the blockchain return instantly.

contract.call.get("performer") # => "Black Eyed Peas"

Will call method of the contract and return result. Note that no transaction need to be send to the network as method is read-only. On the other hand register method will change contract state, so you need to use transact or transact_and_wait to call it.

Receiving Contract Events

Using the example smart contract described above, one can listen for LogRegister events by using filters.

You can get a list of events from a certain block number to the latest:

require 'ostruct'

event_abi = contract.abi.find {|a| a['name'] == 'LogRegister'}
event_inputs = event_abi['inputs'].map {|i| OpenStruct.new(i)}
decoder = Ethereum::Decoder.new

filter_id = contract.new_filter.log_register(
  {
    from_block: '0x0',
    to_block: 'latest',
    address: '0x....',
    topics: []
  }
)

events = contract.get_filter_logs.log_register(filter_id)

events.each do |event|
  transaction_id = event[:transactionHash]
  transaction = ethereum.eth_get_transaction_receipt(transaction_id)
  args = decoder.decode_arguments(event_inputs, entry['data'])
  puts "#{transaction.inspect} with args: #{args}"
end

IPC Client Connection

By default methods interacting with contracts will use default Json RPC Client that will handle connection to ethereum node. Default client communicate via IPC. If you want to create custom client or use multiple clients you can create them yourself.

To create IPC client instance of simply create Ethereum::IpcClient:

client = Ethereum::IpcClient.new

You can also customize it with path to ipc file path and logging flag:

client = Ethereum::IpcClient.new("~/.parity/mycustom.ipc", false)

If no ipc file path given, IpcClient looks for ipc file in default locations for parity and geth. The second argument is optional. If it is true then logging is on.

By default logging is on and logs are saved in "/tmp/ethereum_ruby_http.log".

To create Http client use following:

client = Ethereum::HttpClient.new('http://localhost:8545')

You can supply client when creating a contract:

contract = Ethereum::Contract.create(client: client, ...)

You can also obtain default client:

client = Ethereum::Singleton.instance

Calling json rpc methods

Ethereum.rb allows you to interact directly with Ethereum node using json rpc api calls. Api calls translates directly to client methods. E.g. to call eth_gasPrice method:

client.eth_gas_price # => {"jsonrpc"=>"2.0", "result"=>"0x4a817c800", "id"=>1}

Note: methods are translated to underscore notation using metaprogramming (See client.rb for more information).

Full list of json rpc methods is available here

Signed transactions

Ethereum.rb supports signing transactions with key using ruby-eth gem.

To create a new key simply do the following:

key = Eth::Key.new

Then you can use the key to deploy contracts and send transactions, i.e.:

contract = Ethereum::Contract.create(file: "...")
contract.key = key
contract.deploy_and_wait("Allo Allo!")
contract.transact_and_wait.set("greeting", "Aloha!")

You can also transfer ether transfer using custom keys:

client.transfer(key, "0x342bcf27DCB234FAb8190e53E2d949d7b2C37411", amount)
client.transfer_and_wait(key, "0x949d7b2C37411eFB763fcDCB234FAb8190e53E2d", amount)

Custom gas price and gas limit

You can change gas price or gas limit in the client:

client.gas_limit = 2_000_000_
client.gas_price = 24_000_000_000

or per contract:

contract.gas_limit = 2_000_000_
contract.gas_price = 24_000_000_000

Utils

Url helpers for rails applications

Often in the application you want to link to blockchain explorer. This can be problematic if you want links to work with different networks (ropsten, mainnet, kovan) depending on environment you're working on. Following helpers will generate link according to network connected:

link_to_tx("See the transaction", "0x3a4e53b01274b0ca9087750d96d8ba7f5b6b27bf93ac65f3174f48174469846d")
link_to_address("See the wallet", "0xE08cdFD4a1b2Ef5c0FC193877EC6A2Bb8f8Eb373")

They use etherscan.io as a blockexplorer.

Note: Helpers work in rails environment only, works with rails 5.0+.

Utils rake tasks

There are couple of rake tasks to help in wallet maintenance, i.e.:

rake ethereum:contract:deploy[path]             # Compile and deploy contract
rake ethereum:contract:compile[path]            # Compile a contract
rake ethereum:transaction:byhash[id]            # Get info about transaction
rake ethereum:transaction:send[address,amount]  # Send [amount of] ether to an account

Debbuging

Logs from communication between ruby app and node are available under following path:

/tmp/ethereum_ruby_http.log

Roadmap

  • Rubydoc documentation

Development

Run bin/console for an interactive prompt that will allow you to experiment.

Make sure rake ethereum:test:setup passes before running tests.

Then, run rake spec to run the tests.

Test that do send transactions to blockchain are marked with blockchain tag. Good practice is to run first fast tests that use no ether and only if they pass, run slow tests that do spend ether. To do that use the following line:

$ bundle exec rspec --tag ~blockchain && bundle exec rspec --tag blockchain

You need ethereum node up and running for tests to pass and it needs to be working on testnet (Ropsten).

Acknowledgements and license

This library has been forked from ethereum-ruby by DigixGlobal Pte Ltd (https://dgx.io).

The gem is available as open source under the terms of the MIT License.

ethereum.rb's People

Contributors

ackintosh avatar alexhanh avatar benjii avatar briansoule avatar comike011 avatar designium avatar dfherr avatar empeje avatar escoffon avatar eugenpaul avatar gmile avatar iberianpig avatar ignition42 avatar jasonadkison avatar jeiwan avatar kulerskim avatar kurotaky avatar kwikiel avatar longhoangwkm avatar luong-komorebi avatar marekkirejczyk avatar michiels avatar nicolasleger avatar polyglot0027 avatar q9f avatar rjurado01 avatar thelucasmoore avatar therevoltingx avatar tymat avatar zernie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ethereum.rb's Issues

No such file or directory @ rb_sysopen - /tmp/ethereum_ruby_http.log

I am trying to use this gem in windows, I installed ethereum node (Parity) and solidity compiler and both are running. But when I am querying

contract = Ethereum::Contract.create(file: "greeter.sol")

I am getting below error:
No such file or directory @ rb_sysopen - /tmp/ethereum_ruby_http.log

created the file ethereum_ruby_http.log inside tmp folder in my application but still getting the same error.

can someone please let me know how to fix this issue.

Get token contract on Kovan

I took all data from: https://kovan.etherscan.io/address/0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570#code
and i want to get contract and do some transactions, but i can't do anything:
contract_name = "ZRXToken"
contract_address = '0x6Ff6C0Ff1d68b964901F986d4C9FA3ac68346570'
abi = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"}]

Ethereum::Contract.create(name: contract_name, address: contract_address, abi: abi).call.total_supply
I run parity like this: parity --chain kovan

I have always undefined method 'total_supply'

Operations on my smartcontract on eth work.
What am i doing wrong?

ArgumentError: unknown keyword: truffle

Hi,

I'm using Truffle and the project is located inside /Users/zulh/hg/hg_blockchain inside my machine.

$ pwd
/Users/zulh/hg/hg_blockchain

$ ls
README.md          migrations         package.json       truffle.js
build              migrations_staging test               yarn.lock
contracts          node_modules       truffle-config.js

When I try create the contract variable, I got into this error:

> contract = Ethereum::Contract.create(name: "GoldToken", truffle: { paths: [ '/Users/zulh/hg/hg_blockchain' ] }, client: client, address: '0xf90bbfee4f57f05af68b9695ea430730a2b50e1d')
ArgumentError: unknown keyword: truffle
	from /Users/zulh/.rvm/gems/ruby-2.4.1/gems/ethereum.rb-2.1.8/lib/ethereum/contract.rb:28:in `create'
	from (irb):5
	from /Users/zulh/.rvm/rubies/ruby-2.4.1/bin/irb:11:in `<main>'

Any idea what's wrong here?

Path to geth.ipc not set for linux

Hi
When running geth on Ubuntu my paths to .ipc file are ~/.ethereum/geth.ipc and ~/.ethereum/testnet/geth.ipc. As I can see IpcClient doesn't have those paths in its list. It causes an error when trying to open a contract. The same error can be seen if I run rake ethereum:test:setup:

>rake ethereum:test:setup
rake aborted!
Errno::EINVAL: Invalid argument - connect(2) for 
<...>/ethereum.rb/lib/ethereum/ipc_client.rb:27:in `initialize'
<...>/ethereum.rb/lib/ethereum/ipc_client.rb:27:in `new'
<...>/ethereum.rb/lib/ethereum/ipc_client.rb:27:in `send_single'
<...>/ethereum.rb/lib/ethereum/client.rb:126:in `send_command'
<...>ethereum.rb/lib/ethereum/client.rb:137:in `block (2 levels) in <class:Client>'
<...>/ethereum.rb/lib/tasks/ethereum_test.rake:8:in `block (3 levels) in <top (required)>'
/var/lib/gems/2.3.0/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'
Tasks: TOP => ethereum:test:setup

For some reason it affects HttpClient as well. My workaround now is to create a simlink from one of the existing paths. The solution would probably be to hardcode two more paths: "#{ENV['HOME']}/.ethereum/geth.ipc" and ""#{ENV['HOME']}/.ethereum/testnet/geth.ipc", - but I'm not sure. Is there a way to set the path with HttpClient?

Trying to deploy contract with Docker container node

I am having a docker container which runs ethereum/client-go. And it's working fine with block synchronisation.

From the container I forwarded the ports 8545 & 30303 as well.
Here is my lsof -i :8545 output

COMMAND  PID  USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
parity  6198 Admin   44u  IPv4 0xfdda6e6d4d9bbb97      0t0  TCP localhost:8545 (LISTEN)
vpnkit  6208 Admin   24u  IPv4 0xfdda6e6d4d65db97      0t0  TCP *:8545 (LISTEN)
vpnkit  6208 Admin   25u  IPv6 0xfdda6e6d4509106f      0t0  TCP localhost:8545 (LISTEN)

But when I'm trying to deploy a contract using ethereum.rb it just stuck in that step. Even though I haven't unlock any account it doesn't throw me an error saying there are no unlock account.

So do you have any idea why ethereum.rb can not connect with my docker container client?

Setting a default account in client

Hi EthWorks!

The package works really great, but I had a little problem with the default_account in the client. It is the main sender for every transaction (which is great), but it's impossible to set it to the desired value. For example, when using Infura, eth_accounts returns an empty array. The default_account is always nil, which complicates things as from: nil when sending transactions creates bugs.

Is it possible to have a version where we can access and modify the default_account?

Problem with digest-sha3 gem on Ubuntu 16.04

Hello
It seems that you have a dependency, that causes this error at least on Ubuntu 16.04:

Building native extensions.  This could take a while...
ERROR:  Error installing digest-sha3:
        ERROR: Failed to build gem native extension.

    current directory: /var/lib/gems/2.3.0/gems/digest-sha3-1.1.0/ext/digest
/usr/bin/ruby2.3 -r ./siteconf20170706-6882-10kgp7b.rb extconf.rb
checking for ruby/digest.h... yes
checking for rb_str_set_len()... yes
creating Makefile

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /var/lib/gems/2.3.0/extensions/x86_64-linux/2.3.0/digest-sha3-1.1.0/mkmf.log

current directory: /var/lib/gems/2.3.0/gems/digest-sha3-1.1.0/ext/digest
make "DESTDIR=" clean

current directory: /var/lib/gems/2.3.0/gems/digest-sha3-1.1.0/ext/digest
make "DESTDIR="
compiling KeccakF-1600-reference.c
compiling KeccakNISTInterface.c
compiling KeccakSponge.c
compiling displayIntermediateValues.c
displayIntermediateValues.c: In function โ€˜displayTextโ€™:
displayIntermediateValues.c:113:9: error: format not a string literal and no format arguments [-Werror=format-security]
         fprintf(intermediateValueFile, text);
         ^
cc1: some warnings being treated as errors
Makefile:239: recipe for target 'displayIntermediateValues.o' failed
make: *** [displayIntermediateValues.o] Error 1

make failed, exit code 2

The gem is no longer maintained. But looks like solution proposed here by lmX2015 works: phusion/digest-sha3-ruby#7

Cannot send ERC20 token

It can't seem to successfully transfer ERC20 token from one account to another. I've published a question with details on Ethereum StackExchange, "Cannot transfer ERC20 token, โ€œBad instructionโ€ error".

Whenever I try to send tokens between account, for some reason my transaction is qualified as Contract Creation (why?). And the transaction fails. Example of failed transaction is here:
0xe7e09fb3692fae3cf52ba58a7b52967300b83c783c0cd758a60ee6a79b1eb40c.

Here's the code to reproduce the problem in question:

require 'ethereum'

value = 14

account_a_address = "0xd8e05701eFf33acfDA0A8e24C04070347703c72C"
account_b_address = "0x3A70Ceac36c8111a95b573d76aD75B7ba898662b"
contract_address = "0x1caf5380b7adc2e4e93c2828f895693ff38c3947"

Ethereum::Singleton.setup do |c|
  c.default_account = account_a_address
end

Ethereum::Contract.create(
  file: "/Users/gmile/projects/ico-scripts/contracts/02-14-2018-1518620826/contract_text.sol",
  address: contract_address
)

contract = EugeneToken.new
tx = contract.transact.transfer(account_b_address, value * 1_000_000_00)

puts tx.id

It looks as if my ruby code tries to create a new contract instead of using existing one from the network, which is wrong. But this is how it is per Readme, e.g. Get contract from blockchain:

Alternatively you can obtain abi definition and name from contract source file:

  contract = Ethereum::Contract.create(file: "MyContract.sol", address: 
  "0x01a4d1A62F01ED966646acBfA8BB0b59960D06dd ")

Sending signed transaction fails with `IOError: missing value for required argument 1`

I tried to use signed transactions instead of personal_unlock_account and got
/var/lib/gems/2.3.0/gems/ethereum.rb-2.1.7/lib/ethereum/client.rb:129:in 'send_command': missing value for required argument 1 (IOError)
Looks like it's related to #18
I run geth on testnet and to illustrate this case wrote a simple ruby script (the contract is real, you can use it):

require "ethereum.rb"
require "eth"

address = "0x65cA73D13a2cc1dB6B92fd04eb4EBE4cEB70c5eC"
abi = '[ { "constant": false, "inputs": [ { "name": "newString", "type": "string" } ], "name": "setString", "outputs": [], "payable": false, "type": "function" }, { "constant": true, "inputs": [], "name": "getString", "outputs": [ { "name": "", "type": "string", "value": "Hello World!" } ], "payable": false, "type": "function" } ]'

stringHolder = Ethereum::Contract.create(name: "StringHolder", address: address, abi: abi)

key = Eth::Key.new
stringHolder.key = key

stringHolder.transact_and_wait.set_string("test")

This returns

/var/lib/gems/2.3.0/gems/ethereum.rb-2.1.7/lib/ethereum/client.rb:129:in `send_command': missing value for required argument 1 (IOError)
        from /var/lib/gems/2.3.0/gems/ethereum.rb-2.1.7/lib/ethereum/client.rb:137:in `block (2 levels) in <class:Client>'
        from /var/lib/gems/2.3.0/gems/ethereum.rb-2.1.7/lib/ethereum/client.rb:76:in `get_nonce'
        from /var/lib/gems/2.3.0/gems/ethereum.rb-2.1.7/lib/ethereum/contract.rb:70:in `send_raw_transaction'
        from /var/lib/gems/2.3.0/gems/ethereum.rb-2.1.7/lib/ethereum/contract.rb:137:in `transact'
        from /var/lib/gems/2.3.0/gems/ethereum.rb-2.1.7/lib/ethereum/contract.rb:145:in `transact_and_wait'
        from /var/lib/gems/2.3.0/gems/ethereum.rb-2.1.7/lib/ethereum/contract.rb:232:in `block (2 levels) in create_function_proxies'
        from example_not_working.rb:12:in `<main>'

On the other hand, this example with unlock_account works (just put valid account and password):

require "ethereum.rb"
require "eth"

address = "0x65cA73D13a2cc1dB6B92fd04eb4EBE4cEB70c5eC"
abi = '[ { "constant": false, "inputs": [ { "name": "newString", "type": "string" } ], "name": "setString", "outputs": [], "payable": false, "type": "function" }, { "constant": true, "inputs": [], "name": "getString", "outputs": [ { "name": "", "type": "string", "value": "Hello World!" } ], "payable": false, "type": "function" } ]'

stringHolder = Ethereum::Contract.create(name: "StringHolder", address: address, abi: abi)

account = "0x<address>"
password = "<password>"
stringHolder.sender = account
Ethereum::IpcClient.new.personal_unlock_account(account, password)

stringHolder.transact_and_wait.set_string("test")
puts stringHolder.call.get_string()

How to call contract's public variable?

In my contract, I have some public variables i.e. name, symbol and decimals like the following:

string public constant name    = "Cat Token";
string public constant symbol  = "CAT";
uint8 public constant decimals = 18;

But I'm not able to call it. I got into this error:

> contract.call.name()
NoMethodError: undefined method `name' for #<#<Class:0x007ff6811e7268>:0x007ff6811e7150>
	from (irb):261
	from /Users/zulh/.rvm/rubies/ruby-2.4.1/bin/irb:11:in `<main>'

Am I missing something here?

"replacement transaction underpriced" error when calling two transactions in a row from different contract instances

There seems to be a problem with getting a valid nonce if I call the same contract from different instances. The log looks like this:

replacement transaction underpriced
<...>/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/bundler/gems/ethereum.rb-6a921f96dfc1/lib/ethereum/client.rb:129:in `send_command'
<...>/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/bundler/gems/ethereum.rb-6a921f96dfc1/lib/ethereum/client.rb:137:in `block (2 levels) in <class:Client>'
<...>/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/bundler/gems/ethereum.rb-6a921f96dfc1/lib/ethereum/contract.rb:87:in `send_raw_transaction'
<...>/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/bundler/gems/ethereum.rb-6a921f96dfc1/lib/ethereum/contract.rb:141:in `transact'
<...>/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/bundler/gems/ethereum.rb-6a921f96dfc1/lib/ethereum/contract.rb:235:in `block (2 levels) in create_function_proxies'

When I tried to fix get_nonce by adding the missing argument to eth_get_transaction_count, I added "latest" as it was the default, and it looked like it worked. But "latest" doesn't take into account pending transactions. When I use the same contract instance - global nonce in send_raw_transaction gets increased and the issue goes away. But when I use different contract instances - nonce turns out to be the same, because "latest" transaction_count doesn't change until the next block.
So should I refix this by making a PR with "pending" instead of "latest" in eth_get_transaction_count? At least for me it works, and I don't see anything that could be broken by this change.

Required dependencies

Bundle install:

   ethereum.rb was resolved to 2.0.2, which depends on
      activesupport (~> 5.0.1)

I can't update my rails application because of stack reasons to version 5.x.x. Are you sure that you need version of activesupport not lower than 5.0.

Can you reduce the requirements for the version of activesupport?

activesupport ~> 5.0

Hi,

does ethereum.rb specifically require activesupport >5.0?

why is it locked to this version?

Thank you for clarifying.

IOError: unknown transaction

I got an error, IOError: unknown transaction when deploying to private network.

irb> client = Ethereum::IpcClient.new('/Users/cohki0305/private_geth/geth.ipc')
irb> contract = Ethereum::Contract.create(file: '/Users/cohki0305/sample.sol', client: client)
irb> contract.deploy_and_wait()

IOError: unknown transaction
	from /Users/cohki0305/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/ethereum.rb-2.2/lib/ethereum/client.rb:129:in `send_command'
	from /Users/cohki0305/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/ethereum.rb-2.2/lib/ethereum/client.rb:137:in `block (2 levels) in <class:Client>'
	from /Users/cohki0305/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/ethereum.rb-2.2/lib/ethereum/deployment.rb:27:in `check_deployed'
	from /Users/cohki0305/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/ethereum.rb-2.2/lib/ethereum/deployment.rb:35:in `deployed?'
	from /Users/cohki0305/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/ethereum.rb-2.2/lib/ethereum/deployment.rb:43:in `block in wait_for_deployment'
	from /Users/cohki0305/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/ethereum.rb-2.2/lib/ethereum/deployment.rb:40:in `loop'
	from /Users/cohki0305/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/ethereum.rb-2.2/lib/ethereum/deployment.rb:40:in `wait_for_deployment'
	from /Users/cohki0305/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/ethereum.rb-2.2/lib/ethereum/contract.rb:152:in `deploy_and_wait'
	from (irb):18
	from /Users/cohki0305/.rbenv/versions/2.4.3/bin/irb:11:in `<main>'

geth console

$ geth --networkid "10" --nodiscover --datadir "~/private_geth" --rpc --rpcapi="db,eth,net,web3,personal,web3" console 2>> ~/private_geth/geth_err.log

contract

pragma solidity ^0.4.2;

contract SingleNumRegister {
    uint storedData;
    function set(uint x) public {
        storedData = x;
    }
    function get() public constant returns (uint retVal) {
       return storedData;
    }
}

version

$ geth versions

Geth
Version: 1.8.1-stable
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.10
Operating System: darwin
GOPATH=
GOROOT=/usr/local/opt/go/libexec

$ ruby -v
ruby 2.4.3p205 (2017-12-14 revision 61247) [x86_64-darwin17]

$ gem list | grep ethereum
ethereum.rb (2.2)

Error: cannot unmarshal string into Go value of type uint64 in personal_unlock_account

There is an error when I try to use personal_unlock_account from Client.

irb> client = Ethereum::HttpClient.new('http://localhost:8545')
=> #<Ethereum::HttpClient:0x000000040a2ae0 @id=0, @log=false, @batch=nil, @formatter=#<Ethereum::Formatter:0x000000040a2ab8>, @gas_price=22000000000, @gas_limit=4000000, @host="localhost", @port=8545, @ssl=false, @uri=#<URI::HTTP http://localhost:8545>>

irb> client.personal_unlock_account("0x<address>", "<password>", 30)
IOError: invalid argument 2: json: cannot unmarshal string into Go value of type uint64
        from (irb):3

It seems that the problem is in conversion of integer to hex string, which is not needed in this case. I resolved it by adding an exception for this particular function - not to call encode_params on its args . Should I prepare a pull request?

Weird issue with encoder?

I have the following contract:

pragma solidity ^0.4.4;

contract TestRecover {
  function isValidAddress(bytes32 hash, uint8 v, bytes32 r, bytes32 s) constant returns(bool) {
    return (ecrecover(hash, v, r, s) == 0x0b1A5F722A111B1903D493420Adb85c15a848CB0);
  }
}

When I run it from the truffle console, it returns true:

TestRecover.at('0x068a489399c0488cdf14670b1ad9efff0d7f83af').isValidAddress(
'0xa1de988600a42c4b4ab089b619297c17d53cffae5d5120d82d8a92d0bb3b78f2', 
27, 
'0xf79d2e19fb416715f7b142fd2f3cbe14e6d348d068d24d4ff7ea3aec53593bae', 
'0x4cf71703542e9a966ce01b2833e695f60d6d7fad7e7bf171df74cc3c0969acc4')

When I run through the gem, it returns false:

client = Ethereum::HttpClient.new('http://localhost:8545')
contract = Ethereum::Contract.create(name: "TestRecover", address: "0x068a489399c0488cdf14670b1ad9efff0d7f83af", client: client, abi: JSON.parse(open('/contracts/TestRecover.json').read)['abi'])
contract.call.is_valid_address(
'0xa1de988600a42c4b4ab089b619297c17d53cffae5d5120d82d8a92d0bb3b78f2', 
27, 
'0xf79d2e19fb416715f7b142fd2f3cbe14e6d348d068d24d4ff7ea3aec53593bae', 
'0x4cf71703542e9a966ce01b2833e695f60d6d7fad7e7bf171df74cc3c0969acc4')
# false

I set log to true to see what params are getting sent to eth_call by the gem, and then used them in truffle console:

web3.eth.call({"to":"0x068a489399c0488cdf14670b1ad9efff0d7f83af","from":"0x0b1A5F722A111B1903D493420Adb85c15a848CB0","data":"0x48b8e303307861316465393838363030613432633462346162303839623631393239376331376435336366666165356435313230643832643861393264306262336237386632000000000000000000000000000000000000000000000000000000000000001b307866373964326531396662343136373135663762313432666432663363626531346536643334386430363864323464346666376561336165633533353933626165307834636637313730333534326539613936366365303162323833336536393566363064366437666164376537626631373164663734636333633039363961636334"})

This also returns false, so obviously the problem is in encoding the data field.
What might be the issue here?

uninitialized constant Ethereum::Contract::Forwardable (NameError)

Hi there, thanks for keeping up the work on a working ruby implementation.

The following code:

require 'ethereum.rb'
greeter = Ethereum::Contract.create file: 'greeter.sol'
address = greeter.deploy_and_wait 'Hello Afri'

Throws the following issue:

/home/user/.gem/ruby/2.4.0/gems/ethereum.rb-2.1.3/lib/ethereum/contract.rb:193:in `block in build': uninitialized constant Ethereum::Contract::Forwardable (NameError)
  from /home/user/.gem/ruby/2.4.0/gems/ethereum.rb-2.1.3/lib/ethereum/contract.rb:192:in `initialize'
  from /home/user/.gem/ruby/2.4.0/gems/ethereum.rb-2.1.3/lib/ethereum/contract.rb:192:in `new'
  from /home/user/.gem/ruby/2.4.0/gems/ethereum.rb-2.1.3/lib/ethereum/contract.rb:192:in `build'
  from /home/user/.gem/ruby/2.4.0/gems/ethereum.rb-2.1.3/lib/ethereum/initializer.rb:22:in `block in build_all'
  from /home/user/.gem/ruby/2.4.0/gems/ethereum.rb-2.1.3/lib/ethereum/initializer.rb:21:in `each'
  from /home/user/.gem/ruby/2.4.0/gems/ethereum.rb-2.1.3/lib/ethereum/initializer.rb:21:in `build_all'
  from /home/user/.gem/ruby/2.4.0/gems/ethereum.rb-2.1.3/lib/ethereum/contract.rb:29:in `create'
  from myscript.rb:1337:in `<main>'

I'm using the greeter.sol you linked in the Readme. Ethereum.rb 2.1.3 from rubygems, Ruby 2.4.0p0 on Archlinux 4.10.10.

testrpc

Hi!

Thanks for creating and sharing this gem. I am trying to make use of it so I compiled parity, and installed solc.

invalid argument connect(2)

line 21 of the controller.
on Etherem::contract.create

It seems to be compiling the contract sol file but I am not sure what I am missing. Wondering if this is possible to use just bypass and use testrpc with you gem for testing?

Thanks in advance!
Mark

Documentation outdated?

I tried pretty much all i can at this point. I cant get any of the examples on how to interact with a contract to work. There simply never are any methods on call or transact.

Invalid Sender

Hi, I'm getting "invalid sender" error when trying to send signed transactions using ethereum.rb + ruby-eth in a local node. Can't figure out which is the problem. Here's the code, which calls transfer method in a contract.

key = Eth::Key.new priv: "xxxxx"
contract = Ethereum::Contract.create(client: eth_ipc_client, file: route_to_contract, address: contract_address)
contract.key = key
contract.transact.transfer(to, qty)

Of course private key is correct, variables to instantiate contract are correct, params "to" and "qty" are variables with a correct ETH address and a quantity lower than sender's total balance of token. Also, sender has enough ETH to send transaction. I also tried playing with gas_limit and gas_price values with no luck (as expected, because I'm working in a local node).

Every time I run the code, I get the "Invalid Sender" error. Not sure if this is an error in ruby-eth or if it is an error in ethereum.rb, but calling contract methods that don't require to be signed, run without problem.

ethereum.rb version: 2.1.8
ruby-eth version : 0.4.6

Any ideas?. Thanks!

100% cpu

Sometimes when I run a rails console and have required ethereum to interact with a contract, the cpu goes to 100%

add class_name option to Contract.create

Hey! first of all thx for great work on this gem.

So i think Ethereum::Contract.create should accept class_name additionally to just name because if i have contract in my truffle project with same name as my model it will simple replace it.

For example i have AmazingCoin it my truffle project and AmazingCoin in my rails app when i will call Ethereum::Contract.create(name: "AmazingCoin", truffle: { paths: [ './coin' ]} ...) it will replace my Rails model and make it inaccessible.

So it think good solution here is to add additional parameter to create, such as class_name. If class_name passed, we obviously create class with class_name instead of just name, otherwise use name as class name . Will u accept pr if i make one?

Documentation missing on getting transaction data

I'm able to get data from a transaction like this

client = Ethereum::HttpClient.new(BACK_END_ETH_NODE_URL)
transaction_data = client.eth_get_transaction_by_hash(transaction_hash)

I am trying to find the "value" of this transaction -- that is, how much ETH was sent with it.

This code returns

...
 "transactionIndex"=>"0x4b",
 "v"=>"0x25",
 "value"=>"0x3a110e53a3f94c0"

So the value is encoded as 0x3a110e53a3f94c0. Does anyone know how I can transform this data into something like Wei or Eth or some float or integer value that could be useful?
thanks

Problems sending erc20 token

client = Ethereum::HttpClient.new(endpoint_url)
# => #<Ethereum::HttpClient:0x0055cd7de0da80 @id=0, @log=false, @batch=nil, @formatter=#<Ethereum::Formatter:0x0055cd7de0da58>, @gas_price=1000000000, @gas_limit=4000000, @host="172.16.0.16", @port=8545, @ssl=false, @uri=#<URI::HTTP http://172.16.0.16:8545>, @default_account="0x0fe7cec4eb814b884fb708ab182671af5653ad95">
client.personal_unlock_account(source_address, source_secret)
# => {"jsonrpc"=>"2.0", "id"=>1, "result"=>true}
erc20 = Ethereum::Contract.create(client: client, name: 'MyToken', address: contract_address, abi: contract_abi_json_string)
# => #<MyToken:0x0055cd7dea5808>
erc20.transact.transfer_from(source_address, target_address, formatter.to_wei(amount))
### IOError: authentication needed: password or unlock

It sends ether without problem but I'm stuck with any ERC20 token.
source_address is already unlocked. What else I should unlock then?

Class overwriting

Hi all,

I am writing Rails application, using Ethereum blockchain and local DB.
I have payment_order.sol contract and also have PaymentOrder ActiveRecord model.
When the contract is built and application tries to access PaymentOrder ActiveRecord model, it crushes, because its class is overwritten by contract class in build method, and no longer have ActiveRecord methods.
Changed

    def build
      class_name = @name.camelize

with

    def build
      class_name = @name.camelize + 'EthereumRb'

And it works again. But probably you can suggest better solution.

Client#transfer chain_id problems with ganache-cli

In my test/development environments, I run ganache-cli with a specific --networkId (1) since I need a constancy for connecting multiple blockchain components. Unfortunately, this breaks Client#transfer: https://github.com/EthWorks/ethereum.rb/blob/master/lib/ethereum/client.rb#L89

The problem seems to be that this method sets chain_id to the net_version, which, confusingly, seems to bear no relation to the network id I initialized ganache-cli with.

I was able to get things working by hardcoding my network id of 1:

def transfer(...)
  Eth.configure { |c| c.chain_id = 1  }
   ...
end

I confess I don't yet fully grok the difference between chain id and network id, but I do know that this problem would be solved for me if the signature of transfer was modified to accept an optional chain_id param.

Ipc file not found

This is my code:
contract = Ethereum::Contract.create(file: './src/MyToken.sol')
And this is my error:
RuntimeError: Ipc file not found. Please pass in the file path explicitly to IpcClient initializer
Can anyone explain and help me to solve this issue?

How to decode event data for events with indexed arguments

Firstly - thanks for this repository! It's been a real help for me getting started with Ethereum, coming from the ruby world.

I have question regarding decoding events, specificallly events with indexed arguments.

parsing the data for an event such as:

Transfer(address from, address to, uint256 amount)

works find, but as soon as any arguments are indexed, it barfs out an Argument error (in the below case from 'decode_address')

Transfer(address indexed from, address indexed to, uint256 amount)

I see that the repository has some example contracts which also have indexed arguments in the events, so I presume I must be doing something wrong here. Any pointers most welcome!

deployed not-expected Contract

I wanted to deploy B contract like following code.

contract = Ethereum::Contract.create(file: './B.sol', client: client)
contract.deploy_and_wait
puts contract
# => #<A:0x00007f95fd1fdb88> 

But the deployed contract was A. I expected B.

solidity

// 'B.sol'

import './A.sol';

contract B is A {}
// 'A.sol'

contract A {}

IOError: Method not found for personal methods

How to call to personal methods from IPC client to Parity?

Example:

  client = Ethereum::IpcClient.new(partiy_ipc_path)
  client.personal_list_accounts
  => IOError: Method not found from client.rb:129:in `send_command'
Another methods works fine

When I'm working with IpcClient and geth, all methods works fine

Soory
In my case I just add ipc settings for config.toml and all works great

Making API calls on behalf of different senders

TL;DR. Would ethereum.rb team consider to accept a change to make it possible to pass (override) sender during a transaction?


Right now it looks like the ethereum.rb was designed to make API calls from a certain single address aka @sender aka default_address. I suspect this was done to support a case, where the library user only has one address, and would like to issue all transactions using that address.

Once initialized, there seems to be no way to override sender on demand. Hence the singleton. In the case of our application, we need to use different senders all the time: we operate multiple addresses and often need to send tokens from these addresses to contract. However looks like is it not possible to do, by design.

To work around this, I have to "manually" write something like this:

require 'ethereum'

account_a_address = "0xd8e05701eFf33acfDA0A8e24C04070347703c72C"
account_b_address = "0xad9c9b5085bec8e8013296dc12bd9cecad102356"
contract_address  = "0x5928ead021bd523e6d3531de920d78b7a02efa60"

client = Ethereum::IpcClient.new
encoder = Ethereum::Encoder.new
contract = Ethereum::Contract.create(file: "/path/to/contract_text.sol", address: contract_address)

fun = Ethereum::Abi.parse_abi(contract.abi)[1].find { |fun| fun.name == "transferFrom" }

args = [
  account_a_address,
  account_b_address,
  value_to_transfer = Time.now.to_i
]

contract.client.eth_send_transaction({
  to: contract_address,
  from: account_a_address,
  data: ("0x" + fun.signature + (encoder.encode_arguments(fun.inputs, args).presence || "0"*64)),
  gas_limit: client.int_to_hex(client.gas_limit),
  gas_price: client.int_to_hex(client.gas_price)
})["result"]

question re call_payload

I'm looking for someone who could add a feature to the library, specifically just implementing the call_payload function without having to be connected to a client. The goal is to easily get the hex data necessary to prepare a sendRawTransaction call. Please contact me if interested to help. Skype = alex.kampa.

Examples on Listening for Events

Hi,

Currently using this project but having difficulty implementing event logs.
I need to be able to listen for events and decode its data, but there is no documentation on how to do it.

Thank you.

Cannot unmarshal non-string into Go struct

Trying to access an already deployed contract on Ropsten network using an Infura Http client.

At first I was getting this error

irb(main):1621:0> contract = Ethereum::Contract.create(client: client, name: 'BlipCompetition', address: '0xd3dcb2493c6c35213042cb7d95cb5baa2d2430eb', abi: abi_json)
=> #<Ethereum::Contract::BlipCompetition:0x00007faa2ca81d98>
irb(main):1622:0> contract.call.owner
Traceback (most recent call last):
        7: from bin/console:14:in `<main>'
        6: from (irb):1622
        5: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/contract.rb:344:in `block (2 levels) in create_function_proxies'
        4: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/contract.rb:188:in `call'
        3: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/contract.rb:182:in `call_raw'
        2: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/client.rb:137:in `block (2 levels) in <class:Client>'
        1: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/client.rb:129:in `send_command'
IOError (invalid argument 0: json: cannot unmarshal non-string into Go struct field CallArgs.from of type common.Address)

And then I followed the suggestion here
And now I have this error (running from console in this gem's directory to get full stack trace):

irb(main):1627:0> contract = Ethereum::Contract.create(client: client, name: 'BlipCompetition', address: '0xd3dcb2493c6c35213042cb7d95cb5baa2d2430eb', abi: abi_json)
=> #<Ethereum::Contract::BlipCompetition:0x00007faa2da93a38>
irb(main):1628:0> contract.call.owner
Traceback (most recent call last):
       13: from bin/console:14:in `<main>'
       12: from (irb):1628
       11: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/contract.rb:344:in `block (2 levels) in create_function_proxies'
       10: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/contract.rb:188:in `call'
        9: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/contract.rb:183:in `call_raw'
        8: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/decoder.rb:76:in `decode_arguments'
        7: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/decoder.rb:76:in `map'
        6: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/decoder.rb:76:in `each'
        5: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/decoder.rb:76:in `with_index'
        4: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/decoder.rb:76:in `each'
        3: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/decoder.rb:76:in `block in decode_arguments'
        2: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/decoder.rb:14:in `decode'
        1: from /Users/carlos/Desktop/imthatcarlos/ethereum.rb/lib/ethereum/decoder.rb:51:in `decode_address'
ArgumentError (ArgumentError)

Not sure which of the two is a valid bug... anyone running into the same issues?

unrecognised option '--add-std'

Hi. I'm getting the error

unrecognised option '--add-std'

when trying to create a contract using Ethereum::Contract.create. After some research it looks that solc was updated in my system from version 0.4.19 to version 0.4.21, and the new version has removed that option. I found this thread in solidity's github:

ethereum/solidity#3695

Are you aware of it? any workaround until you fix it?

Thanks.

When connected to Parity, the IPC client connection sometimes returns a JSON parse error

The below doesn't happen for every call. Sometimes the block number is returned correctly. I suspect it happens when the Parity returns an empty string.

client.block_number
JSON::ParserError: A JSON text must at least contain two octets!
	from /home/tfj/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/json/common.rb:156:in `initialize'
	from /home/tfj/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/json/common.rb:156:in `new'
	from /home/tfj/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/json/common.rb:156:in `parse'
	from /home/tfj/.rvm/gems/ruby-2.3.1/gems/ethereum-0.5.2/lib/ethereum/ipc_client.rb:32:in `block (2 levels) in <class:IpcClient>'
	from (irb):2
	from /home/tfj/.rvm/rubies/ruby-2.3.1/bin/irb:11:in `<main>'

JSON::ParserError: 765: unexpected token at ''

Hello,

I'm trying to load a contract's method in the following manner:

client = Ethereum::HttpClient.new('https://rinkeby.infura.io/<API_KEY>')
contract = Ethereum::Contract.create(name: 'MyToken', address: '0x000', abi: Abi.to_json, client: client)

Apparently the above is ok because it gives me the proper contract methods (ERC20):

> contract.transact.methods
=> [:name, :symbol, :transfer, :set_prices, :approve, :total_supply, :transfer_from, :decimals, :sell_price, :standard, :balance_of, :buy_price, :buy, :allowance, :sell, :admin .... ]

But when I try to call any of the contract methods, the following happens:

> contract.transact.name
JSON::ParserError: 765: unexpected token at ''
	from (irb):9

Any ideas about what I could be doing wrong? @ToJen Maybe you could give me a hand here?

Thank in advance!

Question regarding best practices

It looks like every time you call Ethereum::Contract.create, it creates a new dynamic class. We have many places in the app where we need the instances of different contracts to interact with them. Most of the time we're calling Ethereum::Contract.create when needed, but I'm thinking that this would result in a "memory leak" of sorts that will slowly grow the app's memory footprint.

  1. I'm curious as to why there needs to be meta classes getting created for each contract? Why not just use method missing?

  2. Is there a best practice to always only have 1 instance of the contract for the entire lifetime of the app and pass that around?

entry is not defined in events part of README

args = decoder.decode_arguments(event_inputs, entry['data'])

What is entry? I tried with decoder.decode_arguments(event_inputs,transaction["result"]["logs"][0]["data"]) but that didn't work

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.