From 964ac9047747e5d648fda47b3e76e14ea188e832 Mon Sep 17 00:00:00 2001 From: Alexander Hanhikoski Date: Tue, 28 Jun 2016 14:59:14 +0300 Subject: [PATCH 1/7] encode params --- lib/ethereum/client.rb | 24 +++++++++++++++++++++++- spec/client_spec.rb | 9 +++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/ethereum/client.rb b/lib/ethereum/client.rb index c94323d..b673f60 100644 --- a/lib/ethereum/client.rb +++ b/lib/ethereum/client.rb @@ -38,6 +38,27 @@ def reset_id @id = 0 end + def int_to_hex(n) + return "0x#{n.to_s(16)}" + end + + def add_hex_prefix(s) + s.start_with?('0x') ? s : "0x#{s}" + end + + # https://github.com/ethereum/wiki/wiki/JSON-RPC#output-hex-values + def encode_params(params) + return params.map do |p| + if p.is_a?(Integer) + int_to_hex(p) + elsif p.is_a?(String) + add_hex_prefix(p) + else + p + end + end + end + (RPC_COMMANDS + RPC_MANAGEMENT_COMMANDS).each do |rpc_command| method_name = "#{rpc_command.underscore}" define_method method_name do |*args| @@ -45,7 +66,8 @@ def reset_id if command == "eth_call" args << "latest" end - payload = {jsonrpc: "2.0", method: command, params: args, id: get_id} + payload = {jsonrpc: "2.0", method: command, params: encode_params(args), id: get_id} + if @log == true @logger.info("Sending #{payload.to_json}") end diff --git a/spec/client_spec.rb b/spec/client_spec.rb index 728a1db..ea4c2a2 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -1,6 +1,15 @@ require 'spec_helper' describe Ethereum do + describe 'Client' do + it 'should encode parameters' do + params = [true, false, 0, 12345, '0x7d84abf0f241b10927b567bd636d95fa9f66ae34', '0x4d5e07d4057dd0c3849c2295d20ee1778fc29d69150e8d75a07207347dce17fa', '7d84abf0f241b10927b567bd636d95fa9f66ae34'] + client = Ethereum::Client.new + encoded_params = client.encode_params(params) + expect(encoded_params).to eq([true, false, '0x0', '0x3039', '0x7d84abf0f241b10927b567bd636d95fa9f66ae34', '0x4d5e07d4057dd0c3849c2295d20ee1778fc29d69150e8d75a07207347dce17fa', '0x7d84abf0f241b10927b567bd636d95fa9f66ae34']) + end + end + describe 'HttpClient' do it 'should work' do client = Ethereum::HttpClient.new('localhost', '8545') From 227663220e7040fc1e7de2f3d49e93d0b9118bd0 Mon Sep 17 00:00:00 2001 From: Alexander Hanhikoski Date: Thu, 30 Jun 2016 21:25:05 +0300 Subject: [PATCH 2/7] lets not fiddle with string params --- lib/ethereum/client.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/ethereum/client.rb b/lib/ethereum/client.rb index b673f60..004fac3 100644 --- a/lib/ethereum/client.rb +++ b/lib/ethereum/client.rb @@ -42,17 +42,11 @@ def int_to_hex(n) return "0x#{n.to_s(16)}" end - def add_hex_prefix(s) - s.start_with?('0x') ? s : "0x#{s}" - end - # https://github.com/ethereum/wiki/wiki/JSON-RPC#output-hex-values def encode_params(params) return params.map do |p| if p.is_a?(Integer) int_to_hex(p) - elsif p.is_a?(String) - add_hex_prefix(p) else p end From 63e8784a93eb7a24d0a85ef2fa5693c82b7fc551 Mon Sep 17 00:00:00 2001 From: Alexander Hanhikoski Date: Tue, 5 Jul 2016 12:46:22 +0300 Subject: [PATCH 3/7] change to sha3 gem --- ethereum.gemspec | 2 +- lib/ethereum.rb | 2 +- lib/ethereum/contract_event.rb | 2 +- lib/ethereum/function.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ethereum.gemspec b/ethereum.gemspec index f5dacbe..5d77e7d 100644 --- a/ethereum.gemspec +++ b/ethereum.gemspec @@ -31,5 +31,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "pry" spec.add_dependency "activesupport" - spec.add_dependency "digest-sha3", "~> 1.1" + spec.add_dependency "sha3", "~> 0.2.6" end diff --git a/lib/ethereum.rb b/lib/ethereum.rb index d6236b6..f8fe15b 100644 --- a/lib/ethereum.rb +++ b/lib/ethereum.rb @@ -1,7 +1,7 @@ require "ethereum/version" require 'active_support' require 'active_support/core_ext' -require 'digest/sha3' +require 'sha3' module Ethereum require 'ethereum/client' diff --git a/lib/ethereum/contract_event.rb b/lib/ethereum/contract_event.rb index 2ffce39..949fca9 100644 --- a/lib/ethereum/contract_event.rb +++ b/lib/ethereum/contract_event.rb @@ -8,7 +8,7 @@ def initialize(data) @input_types = data["inputs"].collect {|x| x["type"]} @inputs = data["inputs"].collect {|x| x["name"]} @event_string = "#{@name}(#{@input_types.join(",")})" - @signature = Digest::SHA3.hexdigest(@event_string, 256) + @signature = SHA3::Digest::SHA256.hexdigest(@event_string) end def set_address(address) diff --git a/lib/ethereum/function.rb b/lib/ethereum/function.rb index 079c768..0fab116 100644 --- a/lib/ethereum/function.rb +++ b/lib/ethereum/function.rb @@ -13,7 +13,7 @@ def initialize(data) Ethereum::FunctionOutput.new(output) end @function_string = "#{@name}(#{@inputs.collect {|x| x.type }.join(",")})" - @signature = Digest::SHA3.hexdigest(@function_string, 256)[0..7] + @signature = SHA3::Digest::SHA256.hexdigest(@function_string)[0..7] end end From 65b76760913995171b0cb1bc886fc71185b49a53 Mon Sep 17 00:00:00 2001 From: Alexander Hanhikoski Date: Tue, 5 Jul 2016 13:13:01 +0300 Subject: [PATCH 4/7] revert to sha256 pure ruby again... --- ethereum.gemspec | 3 ++- lib/ethereum.rb | 3 ++- lib/ethereum/contract_event.rb | 3 ++- lib/ethereum/function.rb | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ethereum.gemspec b/ethereum.gemspec index 5d77e7d..7bb0126 100644 --- a/ethereum.gemspec +++ b/ethereum.gemspec @@ -31,5 +31,6 @@ Gem::Specification.new do |spec| spec.add_development_dependency "pry" spec.add_dependency "activesupport" - spec.add_dependency "sha3", "~> 0.2.6" + # spec.add_dependency "sha3", "~> 0.2.6" + spec.add_dependency "sha3-pure-ruby", "~>0.1.1" end diff --git a/lib/ethereum.rb b/lib/ethereum.rb index f8fe15b..7efbbb9 100644 --- a/lib/ethereum.rb +++ b/lib/ethereum.rb @@ -1,7 +1,8 @@ require "ethereum/version" require 'active_support' require 'active_support/core_ext' -require 'sha3' +# require 'sha3' +require 'sha3-pure-ruby' module Ethereum require 'ethereum/client' diff --git a/lib/ethereum/contract_event.rb b/lib/ethereum/contract_event.rb index 949fca9..c003d29 100644 --- a/lib/ethereum/contract_event.rb +++ b/lib/ethereum/contract_event.rb @@ -8,7 +8,8 @@ def initialize(data) @input_types = data["inputs"].collect {|x| x["type"]} @inputs = data["inputs"].collect {|x| x["name"]} @event_string = "#{@name}(#{@input_types.join(",")})" - @signature = SHA3::Digest::SHA256.hexdigest(@event_string) + # @signature = SHA3::Digest::SHA256.hexdigest(@event_string) + @signature = Digest::SHA3.hexdigest @event_string, 256 end def set_address(address) diff --git a/lib/ethereum/function.rb b/lib/ethereum/function.rb index 0fab116..6a3fd5d 100644 --- a/lib/ethereum/function.rb +++ b/lib/ethereum/function.rb @@ -13,7 +13,8 @@ def initialize(data) Ethereum::FunctionOutput.new(output) end @function_string = "#{@name}(#{@inputs.collect {|x| x.type }.join(",")})" - @signature = SHA3::Digest::SHA256.hexdigest(@function_string)[0..7] + # @signature = SHA3::Digest::SHA256.hexdigest(@function_string)[0..7] + @signature = Digest::SHA3.hexdigest(@function_string, 256)[0..7] end end From da700048083e2745a272085d2a30e73d769ee953 Mon Sep 17 00:00:00 2001 From: Alexander Hanhikoski Date: Tue, 5 Jul 2016 15:27:10 +0300 Subject: [PATCH 5/7] switch to sha3 again --- ethereum.gemspec | 4 ++-- lib/ethereum.rb | 4 ++-- lib/ethereum/contract_event.rb | 4 ++-- lib/ethereum/function.rb | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ethereum.gemspec b/ethereum.gemspec index 7bb0126..7c3ec6f 100644 --- a/ethereum.gemspec +++ b/ethereum.gemspec @@ -31,6 +31,6 @@ Gem::Specification.new do |spec| spec.add_development_dependency "pry" spec.add_dependency "activesupport" - # spec.add_dependency "sha3", "~> 0.2.6" - spec.add_dependency "sha3-pure-ruby", "~>0.1.1" + spec.add_dependency "sha3", "~> 0.2.6" + # spec.add_dependency "sha3-pure-ruby", "~>0.1.1" end diff --git a/lib/ethereum.rb b/lib/ethereum.rb index 7efbbb9..11abeff 100644 --- a/lib/ethereum.rb +++ b/lib/ethereum.rb @@ -1,8 +1,8 @@ require "ethereum/version" require 'active_support' require 'active_support/core_ext' -# require 'sha3' -require 'sha3-pure-ruby' +require 'sha3' +# require 'sha3-pure-ruby' module Ethereum require 'ethereum/client' diff --git a/lib/ethereum/contract_event.rb b/lib/ethereum/contract_event.rb index c003d29..18e542e 100644 --- a/lib/ethereum/contract_event.rb +++ b/lib/ethereum/contract_event.rb @@ -8,8 +8,8 @@ def initialize(data) @input_types = data["inputs"].collect {|x| x["type"]} @inputs = data["inputs"].collect {|x| x["name"]} @event_string = "#{@name}(#{@input_types.join(",")})" - # @signature = SHA3::Digest::SHA256.hexdigest(@event_string) - @signature = Digest::SHA3.hexdigest @event_string, 256 + @signature = SHA3::Digest::SHA256.hexdigest(@event_string) + # @signature = Digest::SHA3.hexdigest @event_string, 256 end def set_address(address) diff --git a/lib/ethereum/function.rb b/lib/ethereum/function.rb index 6a3fd5d..a579c67 100644 --- a/lib/ethereum/function.rb +++ b/lib/ethereum/function.rb @@ -13,8 +13,8 @@ def initialize(data) Ethereum::FunctionOutput.new(output) end @function_string = "#{@name}(#{@inputs.collect {|x| x.type }.join(",")})" - # @signature = SHA3::Digest::SHA256.hexdigest(@function_string)[0..7] - @signature = Digest::SHA3.hexdigest(@function_string, 256)[0..7] + @signature = SHA3::Digest::SHA256.hexdigest(@function_string)[0..7] + # @signature = Digest::SHA3.hexdigest(@function_string, 256)[0..7] end end From 11d743107a645c5d16eb0e66f7553ba0b44a3583 Mon Sep 17 00:00:00 2001 From: Alexander Hanhikoski Date: Tue, 5 Jul 2016 20:51:12 +0300 Subject: [PATCH 6/7] implement generic factory method to create rpc clients --- lib/ethereum/client.rb | 6 ++++++ lib/ethereum/http_client.rb | 11 +++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/ethereum/client.rb b/lib/ethereum/client.rb index 004fac3..4f09cbb 100644 --- a/lib/ethereum/client.rb +++ b/lib/ethereum/client.rb @@ -17,6 +17,12 @@ def initialize(log = false) end end + def self.create(host_or_ipcpath, log = false) + return IpcClient.new(host_or_ipcpath) if host_or_ipcpath.include? '.ipc' + return HttpClient.new(host_or_ipcpath) if host_or_ipcpath.include? 'http' + raise ArgumentError.new('Unable to detect client type') + end + def batch @batch = [] diff --git a/lib/ethereum/http_client.rb b/lib/ethereum/http_client.rb index b8a214d..8c9315c 100644 --- a/lib/ethereum/http_client.rb +++ b/lib/ethereum/http_client.rb @@ -3,11 +3,14 @@ module Ethereum class HttpClient < Client attr_accessor :host, :port, :uri, :ssl - def initialize(host, port, ssl = false, log = false) + def initialize(host, log = false) super(log) - @host = host - @port = port - @ssl = ssl + uri = URI.parse(host) + raise ArgumentError unless ['http', 'https'].include? uri.scheme + @host = uri.host + @port = uri.port + + @ssl = uri.scheme == 'https' if ssl @uri = URI("https://#{@host}:#{@port}") else From 36c78cefda5f0f3102295e0fcee5213dd14f3a73 Mon Sep 17 00:00:00 2001 From: Alexander Hanhikoski Date: Sat, 9 Jul 2016 12:06:53 +0300 Subject: [PATCH 7/7] improve Client.create --- lib/ethereum/client.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ethereum/client.rb b/lib/ethereum/client.rb index 4f09cbb..e07eeeb 100644 --- a/lib/ethereum/client.rb +++ b/lib/ethereum/client.rb @@ -18,8 +18,8 @@ def initialize(log = false) end def self.create(host_or_ipcpath, log = false) - return IpcClient.new(host_or_ipcpath) if host_or_ipcpath.include? '.ipc' - return HttpClient.new(host_or_ipcpath) if host_or_ipcpath.include? 'http' + return IpcClient.new(host_or_ipcpath, log) if host_or_ipcpath.end_with? '.ipc' + return HttpClient.new(host_or_ipcpath, log) if host_or_ipcpath.start_with? 'http' raise ArgumentError.new('Unable to detect client type') end