ethereum 0.2.0 → 0.3.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 322a4404d64ad2d1d14328ec0440b6612aaf5867
4
- data.tar.gz: 820552a955aeb11ccb156333758c94eb73eddaae
3
+ metadata.gz: a374154be8bb1dac7fe3073b4ca7e92ace6b8991
4
+ data.tar.gz: 7b21a87aa5d0a754f6abe50ee3eabbdf82dd7c50
5
5
  SHA512:
6
- metadata.gz: b070b6eb2995dc8595a001e584e69fed37b855cbb03a88989fb5bd22fd4d85a57dea48e1d598c2cc990bab21b2162f94f06111acf9b767fa6d583d6d838e3f81
7
- data.tar.gz: 84958a99e16f93a6de3f870398dc085c504582cd590c60570c1701e2802c52e845b22edcd220938c694e31c62321df08a4527c9ff5370a34634e6764d157707b
6
+ metadata.gz: 51e40edef7d4ede819c2ab3e7b3dbce2bc69488ba5b807db0dbcc1b57055611893b5e6c2fb6b782341d67ea22a2216c9287896fa826317faf7c646d8709709ae
7
+ data.tar.gz: 8982b0e349cacf5dc63ff700f73afbc2797da4bf070294c039da744851536ce9c034920b3bd5cff2147ff22f18678f23fbce6a7a022dda50ed06e05673f9311a
data/README.md CHANGED
@@ -4,12 +4,21 @@ A simple library for Ethereum.
4
4
 
5
5
  ## Features
6
6
 
7
+ * Pure Ruby implementation
7
8
  * IPC Client with batch calls support
9
+ * HTTP Client with batch calls support
8
10
  * Compile and deploy Solidity contracts
9
11
  * Expose deployed contracts as Ruby classes
10
12
  * Test solidity contracts with a Ruby testing framework of your choice
11
13
  * Call and wait for the result of Solidity function calls.
12
14
 
15
+ ## Ruby Compatibility
16
+
17
+ * Ruby 2.x
18
+ * Ruby 1.9.x
19
+ * JRuby
20
+ * Rubinius
21
+
13
22
  ## Requirements
14
23
 
15
24
  We currently support UNIX/Linux environments and Windows IPC support on the roadmap.
@@ -53,22 +62,65 @@ simple_name_registry_instance.deploy_and_wait
53
62
 
54
63
  ### Transacting and Calling Solidity Functions
55
64
 
56
- Solidity functions are exposed as transact_<underscore_function_name>(params) (or transact_and_wait_<underscore_function_name>(params)) and call_<underscore_function_name>(params) e.g.:
65
+ Solidity functions are exposed using the following conventions:
66
+
67
+ ```
68
+ transact_[function_name](params)
69
+ transact_and_wait_[function_name](params)
70
+ call_[function_name](params)
71
+ ```
72
+
73
+ **Example Contract in Solidity**
74
+ ```
75
+ contract SimpleNameRegistry {
76
+
77
+ mapping (address => bool) public myMapping;
78
+
79
+ function register(address _a, bytes32 _b) {
80
+ }
81
+
82
+ function getSomeValue(address _x) public constant returns(bool b, address b) {
83
+ }
84
+
85
+ }
86
+ ```
57
87
 
58
88
  ```ruby
59
89
  simple_name_registry_instance.transact_and_wait_register("0x5b6cb65d40b0e27fab87a2180abcab22174a2d45", "minter.contract.dgx")
60
90
  simple_name_registry_instance.transact_register("0x385acafdb80b71ae001f1dbd0d65e62ec2fff055", "anthony@eufemio.dgx")
91
+ simple_name_registry_instance.call_get_some_value("0x385acafdb80b71ae001f1dbd0d65e62ec2fff055")
92
+ simple_name_registry_instance.call_my_mapping("0x385acafdb80b71ae001f1dbd0d65e62ec2fff055")
93
+ ```
94
+
95
+ ### Run contracts using a different address
96
+
97
+ ```ruby
98
+ simple_name_registry_instance.as("0x0c0d99d3608a2d1d38bb1b28025e970d3910b1e1")
99
+ ```
100
+
101
+ ### Point contract instance to a previously deployed contract
102
+
103
+ ```ruby
104
+ simple_name_registry_instance.at("0x734533083b5fc0cd14b7cb8c8eb6ed0c9bd184d3")
61
105
  ```
62
106
 
63
107
  ## Roadmap
64
108
 
65
- * Add JSON RPC Client support
66
109
  * Add Windows IPC Client (named pipes)
110
+ * Add support for creating and sending of raw transactions
111
+ * Offline account creation
67
112
  * Solidity constant function output should be properly formatted according to the ouput data type
68
- * Unit testing and contract testing examples
113
+ * Unit testing and contract testing examples. Use [web3.js](https://github.com/ethereum/web3.js) tests as a baseline.
114
+ * ContractTransaction class
69
115
  * Add more examples
70
116
  * API documentation
71
117
 
118
+ ## Support
119
+
120
+ Please join our Gitter chat room or open a new issue in this repository
121
+
122
+ [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/DigixGlobal/ethereum-ruby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
123
+
72
124
  ## Development
73
125
 
74
126
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -6,7 +6,7 @@ require 'ethereum/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "ethereum"
8
8
  spec.version = Ethereum::VERSION
9
- spec.authors = ["Digix"]
9
+ spec.authors = ["DigixGlobal Pte Ltd (https://dgx.io)"]
10
10
  spec.email = ["ace@dgx.io"]
11
11
 
12
12
  spec.summary = %q{Ethereum libraries for Ruby}
@@ -32,5 +32,5 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency "rspec"
33
33
  spec.add_development_dependency "pry"
34
34
  spec.add_dependency "activesupport"
35
- spec.add_dependency "digest-sha3"
35
+ spec.add_dependency "sha3-pure-ruby"
36
36
  end
@@ -1,9 +1,12 @@
1
1
  require "ethereum/version"
2
2
  require 'active_support'
3
3
  require 'active_support/core_ext'
4
+ require 'sha3-pure-ruby'
4
5
 
5
6
  module Ethereum
7
+ require 'ethereum/client'
6
8
  require 'ethereum/ipc_client'
9
+ require 'ethereum/http_client'
7
10
  require 'ethereum/initializer'
8
11
  require 'ethereum/contract'
9
12
  require 'ethereum/function'
@@ -0,0 +1,18 @@
1
+ module Ethereum
2
+ class Client
3
+
4
+ RPC_COMMANDS = %w(eth_accounts eth_blockNumber eth_getBalance eth_protocolVersion eth_coinbase eth_mining eth_gasPrice eth_getStorage eth_storageAt eth_getStorageAt eth_getTransactionCount eth_getBlockTransactionCountByHash eth_getBlockTransactionCountByNumber eth_getUncleCountByBlockHash eth_getUncleCountByBlockNumber eth_getData eth_getCode eth_sign eth_sendRawTransaction eth_sendTransaction eth_transact eth_estimateGas eth_call eth_flush eth_getBlockByHash eth_getBlockByNumber eth_getTransactionByHash eth_getTransactionByBlockNumberAndIndex eth_getTransactionByBlockHashAndIndex eth_getUncleByBlockHashAndIndex eth_getUncleByBlockNumberAndIndex eth_getCompilers eth_compileSolidity eth_newFilter eth_newBlockFilter eth_newPendingTransactionFilter eth_uninstallFilter eth_getFilterChanges eth_getFilterLogs eth_getLogs eth_hashrate eth_getWork eth_submitWork eth_resend eth_pendingTransactions eth_getTransactionReceipt)
5
+
6
+ def get_id
7
+ @id = @id + 1
8
+ return @id
9
+ end
10
+
11
+ def clear_batch
12
+ @batch = []
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+
@@ -71,41 +71,44 @@ module Ethereum
71
71
  end
72
72
 
73
73
  functions.each do |fun|
74
- if fun.constant
75
- define_method "call_#{fun.name.underscore}".to_sym do |*args|
76
- formatter = Ethereum::Formatter.new
77
- arg_types = fun.inputs.collect(&:type)
78
- #out_types = fun.outputs.collect(&:type)
79
- connection = self.connection
80
- return {result: :error, message: "missing parameters for #{fun.function_string}" } if arg_types.length != args.length
81
- payload = []
82
- payload << fun.signature
83
- arg_types.zip(args).each do |arg|
84
- payload << formatter.to_payload(arg)
85
- end
86
- return {result: connection.call({to: self.address, from: self.sender, data: payload.join()})["result"].gsub(/^0x/,'').scan(/.{64}/)}
87
- end
88
- else
89
- define_method "transact_#{fun.name.underscore}".to_sym do |*args|
90
- formatter = Ethereum::Formatter.new
91
- arg_types = fun.inputs.collect(&:type)
92
- connection = self.connection
93
- return {result: :error, message: "missing parameters for #{fun.function_string}" } if arg_types.length != args.length
94
- payload = []
95
- payload << fun.signature
96
- arg_types.zip(args).each do |arg|
97
- payload << formatter.to_payload(arg)
98
- end
99
- txid = connection.send_transaction({to: self.address, from: self.sender, data: payload.join(), gas: self.gas, gasPrice: self.gas_price})["result"]
100
- return Ethereum::Transaction.new(txid, self.connection)
74
+
75
+ define_method "call_#{fun.name.underscore}".to_sym do |*args|
76
+ formatter = Ethereum::Formatter.new
77
+ arg_types = fun.inputs.collect(&:type)
78
+ #out_types = fun.outputs.collect(&:type)
79
+ connection = self.connection
80
+ return {result: :error, message: "missing parameters for #{fun.function_string}" } if arg_types.length != args.length
81
+ payload = []
82
+ payload << fun.signature
83
+ arg_types.zip(args).each do |arg|
84
+ payload << formatter.to_payload(arg)
101
85
  end
102
- define_method "transact_and_wait_#{fun.name.underscore}".to_sym do |*args|
103
- function_name = "transact_#{fun.name.underscore}".to_sym
104
- tx = self.send(function_name, *args)
105
- tx.wait_for_miner
106
- return tx
86
+ raw_result = connection.call({to: self.address, from: self.sender, data: payload.join()})["result"]
87
+ formatted_result = raw_result.gsub(/^0x/,'').scan(/.{64}/)
88
+ return {data: payload.join(), raw: raw_result, formatted: formatted_result}
89
+ end
90
+
91
+ define_method "transact_#{fun.name.underscore}".to_sym do |*args|
92
+ formatter = Ethereum::Formatter.new
93
+ arg_types = fun.inputs.collect(&:type)
94
+ connection = self.connection
95
+ return {result: :error, message: "missing parameters for #{fun.function_string}" } if arg_types.length != args.length
96
+ payload = []
97
+ payload << fun.signature
98
+ arg_types.zip(args).each do |arg|
99
+ payload << formatter.to_payload(arg)
107
100
  end
101
+ txid = connection.send_transaction({to: self.address, from: self.sender, data: payload.join(), gas: self.gas, gasPrice: self.gas_price})["result"]
102
+ return Ethereum::Transaction.new(txid, self.connection, payload.join(), args)
108
103
  end
104
+
105
+ define_method "transact_and_wait_#{fun.name.underscore}".to_sym do |*args|
106
+ function_name = "transact_#{fun.name.underscore}".to_sym
107
+ tx = self.send(function_name, *args)
108
+ tx.wait_for_miner
109
+ return tx
110
+ end
111
+
109
112
  end
110
113
  end
111
114
  Object.const_set(class_name, class_methods)
@@ -31,10 +31,10 @@ module Ethereum
31
31
  @valid_deployment = @connection.get_code(@contract_address)["result"] != "0x"
32
32
  end
33
33
 
34
- def wait_for_deployment(timeout = 60.seconds)
34
+ def wait_for_deployment(timeout = 1500.seconds)
35
35
  start_time = Time.now
36
36
  while self.deployed? == false
37
- raise Timeout::Error if ((Time.now - start_time) > timeout)
37
+ raise "Transaction #{@id} timed out." if ((Time.now - start_time) > timeout)
38
38
  sleep 5
39
39
  return true if self.deployed?
40
40
  end
@@ -54,11 +54,11 @@ module Ethereum
54
54
  end
55
55
 
56
56
  def uint_to_payload(uint)
57
- self.to_twos_complement(uint)
57
+ self.to_twos_complement(uint).rjust(64, '0')
58
58
  end
59
59
 
60
60
  def int_to_payload(int)
61
- self.to_twos_complement(uint)
61
+ self.to_twos_complement(uint).rjust(64, '0')
62
62
  end
63
63
 
64
64
  def bytes_to_payload(bytes)
@@ -0,0 +1,40 @@
1
+ require 'pry'
2
+ module Ethereum
3
+ class HttpClient < Client
4
+ attr_accessor :command, :id, :host, :port, :batch, :converted_transactions, :uri
5
+
6
+ def initialize(host, port)
7
+ @host = host
8
+ @port = port
9
+ @id = 1
10
+ @uri = URI("http://#{@host}:#{@port}")
11
+ @batch = []
12
+ end
13
+
14
+ RPC_COMMANDS.each do |rpc_command|
15
+ method_name = "#{rpc_command.split("_")[1].underscore}"
16
+ define_method method_name do |*args|
17
+ command = rpc_command
18
+ payload = {jsonrpc: "2.0", method: command, params: args, id: get_id}
19
+ http = Net::HTTP.new(@host, @port)
20
+ header = {'Content-Type' => 'application/json'}
21
+ request = Net::HTTP::Post.new(uri, header)
22
+ request.body = payload.to_json
23
+ response = http.request(request)
24
+ return JSON.parse(response.body)
25
+ end
26
+
27
+ define_method "#{method_name}_batch" do |*args|
28
+ command = rpc_command
29
+ payload = {jsonrpc: "2.0", method: command, params: args, id: get_id}
30
+ @batch << payload.to_json
31
+ end
32
+ end
33
+
34
+ def send_batch
35
+
36
+ end
37
+
38
+ end
39
+
40
+ end
@@ -1,6 +1,6 @@
1
1
  require 'socket'
2
2
  module Ethereum
3
- class IpcClient
3
+ class IpcClient < Client
4
4
  attr_accessor :command, :id, :ipcpath, :batch, :converted_transactions
5
5
 
6
6
  def initialize(ipcpath = "#{ENV['HOME']}/.ethereum/geth.ipc")
@@ -9,13 +9,6 @@ module Ethereum
9
9
  @batch = []
10
10
  end
11
11
 
12
- def get_id
13
- @id = @id + 1
14
- return @id
15
- end
16
-
17
- RPC_COMMANDS = %w(eth_accounts eth_blockNumber eth_getBalance eth_protocolVersion eth_coinbase eth_mining eth_gasPrice eth_getStorage eth_storageAt eth_getStorageAt eth_getTransactionCount eth_getBlockTransactionCountByHash eth_getBlockTransactionCountByNumber eth_getUncleCountByBlockHash eth_getUncleCountByBlockNumber eth_getData eth_getCode eth_sign eth_sendRawTransaction eth_sendTransaction eth_transact eth_estimateGas eth_call eth_flush eth_getBlockByHash eth_getBlockByNumber eth_getTransactionByHash eth_getTransactionByBlockNumberAndIndex eth_getTransactionByBlockHashAndIndex eth_getUncleByBlockHashAndIndex eth_getUncleByBlockNumberAndIndex eth_getCompilers eth_compileSolidity eth_newFilter eth_newBlockFilter eth_newPendingTransactionFilter eth_uninstallFilter eth_getFilterChanges eth_getFilterLogs eth_getLogs eth_hashrate eth_getWork eth_submitWork eth_resend eth_pendingTransactions eth_getTransactionReceipt)
18
-
19
12
  RPC_COMMANDS.each do |rpc_command|
20
13
  method_name = "#{rpc_command.split("_")[1].underscore}"
21
14
  define_method method_name do |*args|
@@ -52,10 +45,6 @@ module Ethereum
52
45
  return collection
53
46
  end
54
47
 
55
- def clear_batch
56
- @batch = []
57
- end
58
-
59
48
  end
60
49
  end
61
50
 
@@ -1,12 +1,14 @@
1
1
  module Ethereum
2
2
 
3
3
  class Transaction
4
- attr_accessor :id, :mined, :connection
4
+ attr_accessor :id, :mined, :connection, :input, :input_parameters
5
5
 
6
- def initialize(id, connection)
6
+ def initialize(id, connection, data, input_parameters = [])
7
7
  @mined = false
8
8
  @connection = connection
9
9
  @id = id
10
+ @input = data
11
+ @input_parameters = input_parameters
10
12
  end
11
13
 
12
14
  def mined?
@@ -14,7 +16,7 @@ module Ethereum
14
16
  @mined = @connection.get_transaction_by_hash(@id)["result"]["blockNumber"].present?
15
17
  end
16
18
 
17
- def wait_for_miner(timeout = 60.seconds)
19
+ def wait_for_miner(timeout = 1500.seconds)
18
20
  start_time = Time.now
19
21
  while self.mined? == false
20
22
  raise Timeout::Error if ((Time.now - start_time) > timeout)
@@ -1,3 +1,3 @@
1
1
  module Ethereum
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.8"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ethereum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.8
5
5
  platform: ruby
6
6
  authors:
7
- - Digix
7
+ - DigixGlobal Pte Ltd (https://dgx.io)
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-10-08 00:00:00.000000000 Z
11
+ date: 2015-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: digest-sha3
84
+ name: sha3-pure-ruby
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -116,12 +116,14 @@ files:
116
116
  - bin/setup
117
117
  - ethereum.gemspec
118
118
  - lib/ethereum.rb
119
+ - lib/ethereum/client.rb
119
120
  - lib/ethereum/contract.rb
120
121
  - lib/ethereum/deployment.rb
121
122
  - lib/ethereum/formatter.rb
122
123
  - lib/ethereum/function.rb
123
124
  - lib/ethereum/function_input.rb
124
125
  - lib/ethereum/function_output.rb
126
+ - lib/ethereum/http_client.rb
125
127
  - lib/ethereum/initializer.rb
126
128
  - lib/ethereum/ipc_client.rb
127
129
  - lib/ethereum/transaction.rb