diff --git a/ethereum.gemspec b/ethereum.gemspec index f5dacbe..7c3ec6f 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 "digest-sha3", "~> 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 d6236b6..11abeff 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 'digest/sha3' +require 'sha3' +# require 'sha3-pure-ruby' module Ethereum require 'ethereum/client' diff --git a/lib/ethereum/client.rb b/lib/ethereum/client.rb index c94323d..e07eeeb 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, 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 + def batch @batch = [] @@ -38,6 +44,21 @@ def reset_id @id = 0 end + def int_to_hex(n) + return "0x#{n.to_s(16)}" + 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) + 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/lib/ethereum/contract_event.rb b/lib/ethereum/contract_event.rb index 2ffce39..18e542e 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 = 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 079c768..a579c67 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 = 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 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 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')