etherlite 0.2.6 → 0.5.0

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
- SHA1:
3
- metadata.gz: 848bca20f9303df82ddefac854e462dd61838ab0
4
- data.tar.gz: f30e0a8490fdd72badbab0caa190321a397a429b
2
+ SHA256:
3
+ metadata.gz: 3e2219e30428821c5866a33aa415a4ab4217b3b6f66eaa20f4bd701f64070cdc
4
+ data.tar.gz: df7c5c3d51712a08cd3aabc203ebfc4a0daa853610666d0d111f166e1607cf73
5
5
  SHA512:
6
- metadata.gz: 65bec2a78a37311d4adee177678c20c08e933c1163d16a0868fc9c3e7b00db5c7e4ae209c27b9e25cb0b64f931bc443349d9ccf1204ab7ca9347b589ae2edbd0
7
- data.tar.gz: 713b2626113744451c59d535ce5aa7ee72f8040afc3e1dde5f409bd869e4443158ec20f0c135d68ad89d95585cd494750957f1eaaf9eb4b354a69e538263f051
6
+ metadata.gz: ba8e3b442d736af75785838a131a02c02a6075c67fe1126f4ba60bc0ae24df2fb37924bf253fd9bf846f71fb91f6ebff35edb6fa6bc7fd322824bd2ea593122a
7
+ data.tar.gz: 9d6c0edd407d09be73e90a2ad3bd53d323f7297073bfff84fd22f6a0f6a4a844ff3c11080b6a142ccb17d1e2823123d71abaa5f6f91c079fb320fe5b9a9e1fd7
data/etherlite.gemspec CHANGED
@@ -24,11 +24,11 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency "eth", "~> 0.4.4"
25
25
  spec.add_dependency "activesupport"
26
26
 
27
- spec.add_development_dependency "bundler", "~> 1.12"
27
+ spec.add_development_dependency "bundler", "~> 2.1.4"
28
28
  spec.add_development_dependency "rake", "~> 10.0"
29
29
  spec.add_development_dependency "rspec", "~> 3.0"
30
30
  spec.add_development_dependency "guard", "~> 2.14"
31
31
  spec.add_development_dependency "guard-rspec", "~> 4.7"
32
- spec.add_development_dependency "webmock", "~> 3.0.1"
32
+ spec.add_development_dependency "webmock", "~> 3.7.5"
33
33
  spec.add_development_dependency "pry"
34
34
  end
@@ -9,6 +9,15 @@ module Etherlite::Account
9
9
  @normalized_address = _normalized_address
10
10
  end
11
11
 
12
+ def next_nonce
13
+ if @connection.use_parity
14
+ @connection.parity_next_nonce(address)
15
+ else
16
+ # https://github.com/ethereum/go-ethereum/issues/2736
17
+ @connection.eth_get_transaction_count(address, 'pending')
18
+ end
19
+ end
20
+
12
21
  def transfer_to(_target, _options = {})
13
22
  send_transaction _options.merge(to: _target, value: _options.fetch(:amount, 0))
14
23
  end
@@ -30,7 +39,7 @@ module Etherlite::Account
30
39
  end
31
40
 
32
41
  def send_transaction(_options = {})
33
- raise NotSupportedError, 'transactions are not supported by this kind of account'
42
+ raise Etherlite::NotSupportedError, 'transactions are not supported by this kind of account'
34
43
  end
35
44
 
36
45
  def ==(_other)
@@ -41,7 +50,6 @@ module Etherlite::Account
41
50
 
42
51
  def call_constant(_target, _function, _params, _options)
43
52
  params = {
44
- from: json_encoded_address,
45
53
  to: Etherlite::Utils.encode_address_param(_target),
46
54
  data: _function.encode(_params)
47
55
  }
@@ -8,21 +8,27 @@ module Etherlite
8
8
  super _connection, Etherlite::Utils.normalize_address(@key.address)
9
9
  end
10
10
 
11
+ def build_raw_transaction(_options = {})
12
+ nonce = nonce_manager.next_nonce_for(normalized_address, _options.slice(:replace, :nonce))
13
+
14
+ tx = Eth::Tx.new(
15
+ value: _options.fetch(:value, 0),
16
+ data: _options.fetch(:data, ''),
17
+ gas_limit: _options.fetch(:gas, 90_000),
18
+ gas_price: _options.fetch(:gas_price, gas_price),
19
+ to: (Etherlite::Utils.encode_address_param(_options[:to]) if _options.key?(:to)),
20
+ nonce: nonce
21
+ )
22
+
23
+ sign_with_connection_chain tx
24
+
25
+ tx
26
+ end
27
+
11
28
  def send_transaction(_options = {})
12
- nonce_manager.with_next_nonce_for(normalized_address) do |nonce|
13
- tx = Eth::Tx.new(
14
- value: _options.fetch(:value, 0),
15
- data: _options.fetch(:data, ''),
16
- gas_limit: _options.fetch(:gas, 90_000),
17
- gas_price: _options.fetch(:gas_price, gas_price),
18
- to: (Etherlite::Utils.encode_address_param(_options[:to]) if _options.key?(:to)),
19
- nonce: nonce
20
- )
21
-
22
- # Since eth gem does not allow configuration of chains for every tx, we need
23
- # to globally configure it before signing. This is not thread safe so a mutex is needed.
24
- sign_with_connection_chain tx
29
+ tx = build_raw_transaction(_options)
25
30
 
31
+ nonce_manager.with_next_nonce_for(normalized_address, nonce: tx.nonce) do |nonce|
26
32
  Etherlite::Transaction.new @connection, @connection.eth_send_raw_transaction(tx.hex)
27
33
  end
28
34
  end
@@ -53,7 +53,11 @@ module Etherlite
53
53
  end
54
54
 
55
55
  def default_account
56
- @default_account ||= load_default_account
56
+ @default_account ||= (accounts.first || anonymous_account)
57
+ end
58
+
59
+ def anonymous_account
60
+ @anonymous_account ||= Etherlite::Account::Anonymous.new(connection)
57
61
  end
58
62
 
59
63
  def account_from_pk(_pk)
@@ -66,13 +70,6 @@ use 'load_account' instead"
66
70
  end
67
71
 
68
72
  def_delegators :default_account, :unlock, :lock, :normalized_address, :transfer_to, :call
69
-
70
- private
71
-
72
- def load_default_account
73
- # TODO: consider configuring a global PK and allow the default account to use it
74
- accounts.first || Etherlite::Account::Anonymous.new(connection)
75
- end
76
73
  end
77
74
  end
78
75
  end
@@ -81,9 +81,21 @@ module Etherlite::Abi
81
81
  )
82
82
  end,
83
83
  (_definition['outputs'] || []).map { |input| LoadType.for signature: input['type'] },
84
- _definition.fetch('payable', false),
85
- _definition.fetch('constant', false)
84
+ function_payable?(_definition),
85
+ function_constant?(_definition)
86
86
  )
87
87
  end
88
+
89
+ def function_payable?(_definition)
90
+ return _definition['payable'] if _definition.key? 'payable'
91
+
92
+ _definition['stateMutability'] == 'payable'
93
+ end
94
+
95
+ def function_constant?(_definition)
96
+ return _definition['constant'] if _definition.key? 'constant'
97
+
98
+ _definition['stateMutability'] == 'pure' || _definition['stateMutability'] == 'view'
99
+ end
88
100
  end
89
101
  end
@@ -17,13 +17,22 @@ module Etherlite
17
17
  last_nonce
18
18
  end
19
19
 
20
- def with_next_nonce_for(_normalized_address)
20
+ def next_nonce_for(_normalized_address, replace: false, nonce: nil)
21
+ if nonce.nil?
22
+ nonce = last_nonce_for(_normalized_address)
23
+ nonce += 1 if nonce.negative? || !replace # if first tx, don't replace
24
+ end
25
+
26
+ nonce
27
+ end
28
+
29
+ def with_next_nonce_for(_normalized_address, _options = {})
21
30
  @@nonce_mutex.synchronize do
22
- next_nonce = last_nonce_for(_normalized_address) + 1
31
+ nonce = next_nonce_for(_normalized_address, _options)
23
32
 
24
33
  begin
25
- result = yield next_nonce
26
- @@nonce_cache[_normalized_address] = next_nonce if caching_enabled?
34
+ result = yield nonce
35
+ @@nonce_cache[_normalized_address] = nonce if caching_enabled?
27
36
  return result
28
37
  rescue
29
38
  # if yield fails, cant be sure about transaction status so must rely again on observing.
@@ -1,72 +1,92 @@
1
1
  module Etherlite
2
2
  class Transaction
3
- attr_reader :tx_hash, :receipt
3
+ attr_reader :tx_hash
4
4
 
5
5
  def initialize(_connection, _tx_hash)
6
6
  @connection = _connection
7
7
  @tx_hash = _tx_hash
8
- @receipt = nil
8
+ @loaded = false
9
9
  end
10
10
 
11
11
  def refresh
12
- @receipt = @connection.eth_get_transaction_receipt(@tx_hash) || {}
12
+ @original = @connection.eth_get_transaction_by_hash(@tx_hash)
13
+ @loaded = true
13
14
  self
14
15
  end
15
16
 
17
+ def original
18
+ refresh unless @loaded
19
+ @original
20
+ end
21
+
16
22
  def removed?
17
- @receipt.empty?
23
+ original.nil?
18
24
  end
19
25
 
20
- def succeeded?
21
- status == 1
26
+ def mined?
27
+ original.present? && !original['blockNumber'].nil?
22
28
  end
23
29
 
24
- def status
25
- return nil if removed?
26
- status = @receipt['status']
27
- status.is_a?(String) ? Utils.hex_to_uint(status) : status
30
+ def gas
31
+ original && Utils.hex_to_uint(original['gas'])
28
32
  end
29
33
 
30
- def mined?
31
- !removed? && @receipt.key?('blockNumber')
34
+ def gas_price
35
+ original && Utils.hex_to_uint(original['gasPrice'])
36
+ end
37
+
38
+ def value
39
+ original && Utils.hex_to_uint(original['value'])
40
+ end
41
+
42
+ def block_number
43
+ return nil unless mined?
44
+
45
+ Utils.hex_to_uint(original['blockNumber'])
32
46
  end
33
47
 
34
48
  def confirmations
35
49
  return 0 unless mined?
36
50
 
37
- @connection.eth_block_number - block_number
51
+ (@connection.eth_block_number - block_number) + 1
38
52
  end
39
53
 
40
- def gas
41
- Utils.hex_to_uint original['gas']
54
+ # receipt attributes
55
+
56
+ def receipt
57
+ return nil unless mined?
58
+
59
+ @receipt ||= @connection.eth_get_transaction_receipt(@tx_hash)
42
60
  end
43
61
 
44
- def gas_used
45
- Utils.hex_to_uint @receipt['gasUsed']
62
+ def status
63
+ return nil if receipt.nil?
64
+
65
+ receipt['status'].is_a?(String) ? Utils.hex_to_uint(receipt['status']) : receipt['status']
46
66
  end
47
67
 
48
- def gas_price
49
- Utils.hex_to_uint original['gasPrice']
68
+ def succeeded?
69
+ status == 1
50
70
  end
51
71
 
52
- def value
53
- Utils.hex_to_uint original['value']
72
+ def failed?
73
+ status == 0
54
74
  end
55
75
 
56
- def logs
57
- @receipt['logs'] || []
76
+ def gas_used
77
+ receipt && Utils.hex_to_uint(receipt['gasUsed'])
58
78
  end
59
79
 
60
- def events
61
- ::Etherlite::EventProvider.parse_raw_logs(@connection, logs)
80
+ def logs
81
+ receipt && (receipt['logs'] || [])
62
82
  end
63
83
 
64
- def block_number
65
- Utils.hex_to_uint @receipt['blockNumber']
84
+ def events
85
+ receipt && ::Etherlite::EventProvider.parse_raw_logs(@connection, logs)
66
86
  end
67
87
 
68
88
  def contract_address
69
- @receipt['contractAddress']
89
+ receipt && receipt['contractAddress']
70
90
  end
71
91
 
72
92
  def wait_for_block(timeout: 120)
@@ -79,11 +99,5 @@ module Etherlite
79
99
 
80
100
  true
81
101
  end
82
-
83
- private
84
-
85
- def original
86
- @original ||= @connection.eth_get_transaction_by_hash(@tx_hash)
87
- end
88
102
  end
89
103
  end
@@ -1,3 +1,3 @@
1
1
  module Etherlite
2
- VERSION = "0.2.6"
2
+ VERSION = "0.5.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: etherlite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ignacio Baixas
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-22 00:00:00.000000000 Z
11
+ date: 2021-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: digest-sha3
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '1.12'
75
+ version: 2.1.4
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '1.12'
82
+ version: 2.1.4
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -142,14 +142,14 @@ dependencies:
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: 3.0.1
145
+ version: 3.7.5
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: 3.0.1
152
+ version: 3.7.5
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: pry
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -248,8 +248,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
248
248
  - !ruby/object:Gem::Version
249
249
  version: '0'
250
250
  requirements: []
251
- rubyforge_project:
252
- rubygems_version: 2.6.14.1
251
+ rubygems_version: 3.0.3
253
252
  signing_key:
254
253
  specification_version: 4
255
254
  summary: Ethereum integration for ruby on rails