ciri 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/Gemfile.lock +6 -6
- data/README.md +68 -48
- data/Rakefile +16 -11
- data/ciri-crypto/lib/ciri/crypto/signature.rb +7 -5
- data/ciri-rlp/ciri-rlp.gemspec +1 -1
- data/ciri-rlp/lib/ciri/rlp.rb +1 -1
- data/ciri-rlp/lib/ciri/rlp/decode.rb +23 -7
- data/ciri-rlp/lib/ciri/rlp/encode.rb +8 -2
- data/ciri-rlp/lib/ciri/rlp/serializable.rb +14 -4
- data/ciri-rlp/lib/ciri/rlp/version.rb +1 -1
- data/ciri-rlp/spec/ciri/fixture_spec.rb +2 -2
- data/ciri-utils/Gemfile.lock +1 -1
- data/ciri-utils/lib/ciri/utils/version.rb +1 -1
- data/ciri.gemspec +4 -4
- data/lib/ciri/chain/header.rb +13 -11
- data/lib/ciri/chain/header_chain.rb +1 -10
- data/lib/ciri/chain/transaction.rb +5 -23
- data/lib/ciri/db/account_db.rb +0 -4
- data/lib/ciri/db/backend/errors.rb +27 -0
- data/lib/ciri/db/backend/memory.rb +10 -12
- data/lib/ciri/db/backend/rocks.rb +13 -6
- data/lib/ciri/db/backend/rocks_db.rb +4 -0
- data/lib/ciri/evm.rb +6 -1
- data/lib/ciri/evm/execution_context.rb +6 -2
- data/lib/ciri/evm/instruction.rb +0 -1
- data/lib/ciri/evm/op.rb +11 -5
- data/lib/ciri/evm/op/errors.rb +37 -0
- data/lib/ciri/evm/state.rb +1 -1
- data/lib/ciri/evm/sub_state.rb +6 -6
- data/lib/ciri/evm/vm.rb +53 -33
- data/lib/ciri/forks.rb +4 -0
- data/lib/ciri/forks/base.rb +28 -0
- data/lib/ciri/forks/byzantium.rb +45 -11
- data/lib/ciri/forks/byzantium/opcodes.rb +37 -0
- data/lib/ciri/forks/constantinople.rb +29 -0
- data/lib/ciri/forks/frontier.rb +49 -29
- data/lib/ciri/forks/frontier/cost.rb +91 -95
- data/lib/ciri/forks/frontier/opcodes.rb +99 -0
- data/lib/ciri/forks/frontier/transaction.rb +62 -0
- data/lib/ciri/forks/homestead.rb +31 -7
- data/lib/ciri/forks/homestead/opcodes.rb +37 -0
- data/lib/ciri/forks/homestead/transaction.rb +43 -0
- data/lib/ciri/forks/spurious_dragon.rb +55 -0
- data/lib/ciri/forks/spurious_dragon/cost.rb +91 -0
- data/lib/ciri/forks/spurious_dragon/transaction.rb +44 -0
- data/lib/ciri/forks/tangerine_whistle.rb +37 -0
- data/lib/ciri/forks/tangerine_whistle/cost.rb +98 -0
- data/lib/ciri/rlp/decode.rb +4 -4
- data/lib/ciri/rlp/encode.rb +2 -2
- data/lib/ciri/version.rb +1 -1
- metadata +22 -10
- data/lib/ciri/forks/homestead/cost.rb +0 -195
data/lib/ciri/evm/state.rb
CHANGED
@@ -24,7 +24,7 @@ module Ciri
|
|
24
24
|
|
25
25
|
extend Forwardable
|
26
26
|
|
27
|
-
def_delegators :@account_db, :set_nonce, :increment_nonce, :set_balance, :add_balance,
|
27
|
+
def_delegators :@account_db, :set_nonce, :increment_nonce, :set_balance, :add_balance,
|
28
28
|
:find_account, :delete_account, :account_dead?, :store, :fetch,
|
29
29
|
:set_account_code, :get_account_code, :account_exist?
|
30
30
|
|
data/lib/ciri/evm/sub_state.rb
CHANGED
@@ -41,16 +41,16 @@ module Ciri
|
|
41
41
|
@refunds = orig.refunds.dup
|
42
42
|
end
|
43
43
|
|
44
|
-
def add_refund_account(
|
45
|
-
@refunds <<
|
44
|
+
def add_refund_account(address)
|
45
|
+
@refunds << address
|
46
46
|
end
|
47
47
|
|
48
|
-
def add_touched_account(
|
49
|
-
@touched_accounts <<
|
48
|
+
def add_touched_account(address)
|
49
|
+
@touched_accounts << address
|
50
50
|
end
|
51
51
|
|
52
|
-
def add_suicide_account(
|
53
|
-
@suicide_accounts <<
|
52
|
+
def add_suicide_account(address)
|
53
|
+
@suicide_accounts << address
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
data/lib/ciri/evm/vm.rb
CHANGED
@@ -24,6 +24,7 @@ require_relative 'instruction'
|
|
24
24
|
require_relative 'sub_state'
|
25
25
|
require_relative 'block_info'
|
26
26
|
require_relative 'log_entry'
|
27
|
+
require_relative 'op/errors'
|
27
28
|
|
28
29
|
using Ciri::CoreExt
|
29
30
|
module Ciri
|
@@ -101,26 +102,34 @@ module Ciri
|
|
101
102
|
end
|
102
103
|
|
103
104
|
deposit_code_gas = fork_schema.calculate_deposit_code_gas(output)
|
105
|
+
gas_is_not_enough = deposit_code_gas > remain_gas
|
106
|
+
deposit_code_reach_limit = output.size > fork_schema.contract_code_size_limit
|
104
107
|
|
105
|
-
|
106
|
-
|
108
|
+
# check deposit_code_gas
|
109
|
+
if gas_is_not_enough || deposit_code_reach_limit
|
107
110
|
contract_address = 0
|
111
|
+
if fork_schema.exception_on_deposit_code_gas_not_enough
|
112
|
+
if deposit_code_reach_limit
|
113
|
+
set_exception GasNotEnoughError.new("deposit_code size reach limit, code size: #{output.size}, limit size: #{fork_schema.contract_code_size_limit}")
|
114
|
+
else
|
115
|
+
set_exception GasNotEnoughError.new("deposit_code_gas not enough, deposit_code_gas: #{deposit_code_gas}, remain_gas: #{remain_gas}")
|
116
|
+
end
|
117
|
+
else
|
118
|
+
set_output ''.b
|
119
|
+
end
|
108
120
|
elsif exception
|
109
|
-
# state.touch_account(contract_address)
|
110
121
|
contract_address = 0
|
111
|
-
if burn_gas_on_exception
|
112
|
-
debug("exception: #{exception}, burn gas #{remain_gas} to zero... op code: 0x#{get_op(pc).to_s(16)}")
|
113
|
-
consume_gas remain_gas
|
114
|
-
end
|
115
|
-
execution_context.revert
|
116
|
-
state.revert(snapshot)
|
117
122
|
else
|
118
123
|
# set contract code
|
119
124
|
set_account_code(contract_address, output)
|
125
|
+
if fork_schema.contract_init_nonce != 0
|
126
|
+
state.set_nonce(contract_address, fork_schema.contract_init_nonce)
|
127
|
+
end
|
120
128
|
# minus deposit_code_fee
|
121
129
|
consume_gas deposit_code_gas
|
122
|
-
state.commit(snapshot)
|
123
130
|
end
|
131
|
+
|
132
|
+
finalize_message(snapshot)
|
124
133
|
[contract_address, exception]
|
125
134
|
end
|
126
135
|
end
|
@@ -148,18 +157,7 @@ module Ciri
|
|
148
157
|
set_exception(e)
|
149
158
|
end
|
150
159
|
|
151
|
-
|
152
|
-
if burn_gas_on_exception
|
153
|
-
debug("exception: #{exception}, burn gas #{remain_gas} to zero... op code: 0x#{get_op(pc).to_s(16)}")
|
154
|
-
consume_gas remain_gas
|
155
|
-
end
|
156
|
-
execution_context.revert
|
157
|
-
|
158
|
-
state.revert(snapshot)
|
159
|
-
else
|
160
|
-
state.commit(snapshot)
|
161
|
-
end
|
162
|
-
|
160
|
+
finalize_message(snapshot)
|
163
161
|
[status, output || ''.b, exception]
|
164
162
|
end
|
165
163
|
end
|
@@ -172,6 +170,8 @@ module Ciri
|
|
172
170
|
def transact(sender:, value:, to:)
|
173
171
|
sender_account = find_account(sender)
|
174
172
|
raise VMError.new("balance not enough") if sender_account.balance < value
|
173
|
+
add_touched_account(sender)
|
174
|
+
add_touched_account(to)
|
175
175
|
state.add_balance(sender, -value)
|
176
176
|
state.add_balance(to, value)
|
177
177
|
end
|
@@ -207,12 +207,21 @@ module Ciri
|
|
207
207
|
machine_state.extend_memory(execution_context, pos, size)
|
208
208
|
end
|
209
209
|
|
210
|
+
def delete_empty_accounts
|
211
|
+
return unless fork_schema.clean_empty_accounts?
|
212
|
+
sub_state.touched_accounts.to_set.select do |address|
|
213
|
+
account_dead?(address)
|
214
|
+
end.each do |address|
|
215
|
+
state.delete_account(address)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
210
219
|
private
|
211
220
|
|
212
221
|
# O(σ, μ, A, I) ≡ (σ′, μ′, A′, I)
|
213
222
|
def operate
|
214
223
|
w = get_op(pc)
|
215
|
-
operation =
|
224
|
+
operation = fork_schema.get_operation(w)
|
216
225
|
|
217
226
|
raise "can't find operation #{w}, pc #{pc}" unless operation
|
218
227
|
|
@@ -230,12 +239,6 @@ module Ciri
|
|
230
239
|
set_exception(e)
|
231
240
|
end
|
232
241
|
|
233
|
-
# revert sub_state and return if exception occur
|
234
|
-
if exception
|
235
|
-
execution_context.revert
|
236
|
-
return
|
237
|
-
end
|
238
|
-
|
239
242
|
set_pc case
|
240
243
|
when w == OP::JUMP
|
241
244
|
jump_pc
|
@@ -254,8 +257,6 @@ module Ciri
|
|
254
257
|
output
|
255
258
|
elsif w == OP::STOP || w == OP::SELFDESTRUCT
|
256
259
|
operate
|
257
|
-
# return empty sequence: nil
|
258
|
-
# debug("#{pc} #{OP.get(w).name} gas: 0 stack: #{stack.size}")
|
259
260
|
nil
|
260
261
|
else
|
261
262
|
EMPTY_SET
|
@@ -266,7 +267,7 @@ module Ciri
|
|
266
267
|
def check_exception(state, ms, instruction)
|
267
268
|
w = instruction.get_op(pc)
|
268
269
|
case
|
269
|
-
when w == OP::INVALID ||
|
270
|
+
when w == OP::INVALID || fork_schema.get_operation(w).nil?
|
270
271
|
InvalidOpCodeError.new "can't find op code 0x#{w.to_s(16)} pc: #{pc}"
|
271
272
|
when ms.stack.size < (consume = OP.input_count(w))
|
272
273
|
StackError.new "stack not enough: stack:#{ms.stack.size} next consume: #{consume}"
|
@@ -280,7 +281,6 @@ module Ciri
|
|
280
281
|
ReturnError.new "return data copy error"
|
281
282
|
when stack.size - OP.input_count(w) + OP.output_count(w) > stack_size
|
282
283
|
StackError.new "stack size reach #{stack_size} limit"
|
283
|
-
# A condition in yellow paper but I can't understand..: (¬Iw ∧W(w,μ))
|
284
284
|
when depth > max_depth
|
285
285
|
StackError.new "call depth reach #{max_depth} limit"
|
286
286
|
else
|
@@ -288,6 +288,26 @@ module Ciri
|
|
288
288
|
end
|
289
289
|
end
|
290
290
|
|
291
|
+
def finalize_message(snapshot)
|
292
|
+
# check exception and commit/revert state
|
293
|
+
if exception.is_a?(OP::RevertError)
|
294
|
+
execution_context.revert_sub_state
|
295
|
+
state.revert(snapshot)
|
296
|
+
# cleanup exception
|
297
|
+
set_exception(nil)
|
298
|
+
elsif exception
|
299
|
+
if burn_gas_on_exception
|
300
|
+
debug("exception: #{exception}, burn gas #{remain_gas} to zero... op code: 0x#{get_op(pc).to_s(16)}")
|
301
|
+
consume_gas remain_gas
|
302
|
+
end
|
303
|
+
execution_context.revert_sub_state
|
304
|
+
state.revert(snapshot)
|
305
|
+
else
|
306
|
+
delete_empty_accounts
|
307
|
+
state.commit(snapshot)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
291
311
|
end
|
292
312
|
end
|
293
313
|
end
|
data/lib/ciri/forks.rb
CHANGED
@@ -18,6 +18,10 @@
|
|
18
18
|
require_relative 'forks/config'
|
19
19
|
require_relative 'forks/frontier'
|
20
20
|
require_relative 'forks/homestead'
|
21
|
+
require_relative 'forks/tangerine_whistle'
|
22
|
+
require_relative 'forks/spurious_dragon'
|
23
|
+
require_relative 'forks/byzantium'
|
24
|
+
require_relative 'forks/constantinople'
|
21
25
|
|
22
26
|
module Ciri
|
23
27
|
module Forks
|
data/lib/ciri/forks/base.rb
CHANGED
@@ -61,6 +61,34 @@ module Ciri
|
|
61
61
|
def find_precompile_contract(address)
|
62
62
|
raise NotImplementedError
|
63
63
|
end
|
64
|
+
|
65
|
+
def transaction_class
|
66
|
+
raise NotImplementedError
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_operation(op_code)
|
70
|
+
raise NotImplementedError
|
71
|
+
end
|
72
|
+
|
73
|
+
def exception_on_deposit_code_gas_not_enough
|
74
|
+
raise NotImplementedError
|
75
|
+
end
|
76
|
+
|
77
|
+
def contract_code_size_limit
|
78
|
+
raise NotImplementedError
|
79
|
+
end
|
80
|
+
|
81
|
+
def contract_init_nonce
|
82
|
+
raise NotImplementedError
|
83
|
+
end
|
84
|
+
|
85
|
+
def clean_empty_accounts?
|
86
|
+
raise NotImplementedError
|
87
|
+
end
|
88
|
+
|
89
|
+
def make_receipt(execution_result:, gas_used:)
|
90
|
+
raise NotImplementedError
|
91
|
+
end
|
64
92
|
end
|
65
93
|
|
66
94
|
end
|
data/lib/ciri/forks/byzantium.rb
CHANGED
@@ -16,25 +16,59 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
require_relative 'base'
|
19
|
-
require_relative '
|
19
|
+
require_relative 'spurious_dragon'
|
20
|
+
require_relative 'byzantium/opcodes'
|
21
|
+
require 'ciri/types/receipt'
|
22
|
+
require 'ciri/utils'
|
23
|
+
require 'ciri/rlp'
|
20
24
|
|
21
25
|
module Ciri
|
22
26
|
module Forks
|
27
|
+
# https://github.com/ethereum/EIPs/blob/181867ae830df5419eb9982d2a24797b2dcad28f/EIPS/eip-609.md
|
23
28
|
module Byzantium
|
24
|
-
class Schema < Forks::
|
29
|
+
class Schema < Forks::SpuriousDragon::Schema
|
25
30
|
|
26
|
-
|
31
|
+
BLOCK_REWARD = 3 * 10.pow(18) # 3 ether
|
27
32
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
33
|
+
TRANSACTION_STATUS_FAILURE = ''.b
|
34
|
+
TRANSACTION_STATUS_SUCCESS = "\x01".b
|
35
|
+
|
36
|
+
BLANK_OMMERS_HASH = Utils.keccak(RLP.encode([])).freeze
|
37
|
+
|
38
|
+
def calculate_difficulty(header, parent_header)
|
39
|
+
# https://github.com/ethereum/EIPs/blob/984cf5de90bbf5fbe7e49be227b0c2f9567e661e/EIPS/eip-100.md
|
40
|
+
y = parent_header.ommers_hash == BLANK_OMMERS_HASH ? 1 : 2
|
41
|
+
difficulty_time_factor = [y - (header.timestamp - parent_header.timestamp) / 9, -99].max
|
42
|
+
x = parent_header.difficulty / 2048
|
43
|
+
|
44
|
+
# difficulty bomb
|
45
|
+
height = [(header.number - 3000000), 0].max
|
46
|
+
height_factor = 2 ** (height / 100000 - 2)
|
47
|
+
|
48
|
+
difficulty = (parent_header.difficulty + x * difficulty_time_factor + height_factor).to_i
|
49
|
+
[header.difficulty, difficulty].max
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_operation(op)
|
53
|
+
OPCODES[op]
|
54
|
+
end
|
55
|
+
|
56
|
+
def mining_rewards_of_block(block)
|
57
|
+
rewards = Hash.new(0)
|
58
|
+
# reward miner
|
59
|
+
rewards[block.header.beneficiary] += ((1 + block.ommers.count.to_f / 32) * BLOCK_REWARD).to_i
|
60
|
+
|
61
|
+
# reward ommer(uncle) block miners
|
62
|
+
block.ommers.each do |ommer|
|
63
|
+
rewards[ommer.beneficiary] += ((1 + (ommer.number - block.header.number).to_f / 8) * BLOCK_REWARD).to_i
|
64
|
+
end
|
65
|
+
rewards
|
34
66
|
end
|
35
67
|
|
36
|
-
|
37
|
-
|
68
|
+
# https://github.com/ethereum/EIPs/blob/181867ae830df5419eb9982d2a24797b2dcad28f/EIPS/eip-658.md
|
69
|
+
def make_receipt(execution_result:, gas_used:)
|
70
|
+
status = execution_result.status == 1 ? TRANSACTION_STATUS_SUCCESS : TRANSACTION_STATUS_FAILURE
|
71
|
+
Types::Receipt.new(state_root: status, gas_used: gas_used, logs: execution_result.logs)
|
38
72
|
end
|
39
73
|
|
40
74
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2018 Jiang Jinyang <https://justjjy.com>
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
|
18
|
+
require 'ciri/evm/op'
|
19
|
+
require 'ciri/forks/homestead/opcodes'
|
20
|
+
|
21
|
+
module Ciri
|
22
|
+
module Forks
|
23
|
+
module Byzantium
|
24
|
+
|
25
|
+
include Ciri::EVM::OP
|
26
|
+
|
27
|
+
UPDATE_OPCODES = [
|
28
|
+
REVERT,
|
29
|
+
].map do |op|
|
30
|
+
[op, Ciri::EVM::OP.get(op)]
|
31
|
+
end.to_h.freeze
|
32
|
+
|
33
|
+
OPCODES = Homestead::OPCODES.merge(UPDATE_OPCODES).freeze
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2018 Jiang Jinyang <https://justjjy.com>
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
|
18
|
+
require_relative 'base'
|
19
|
+
require_relative 'byzantium'
|
20
|
+
|
21
|
+
module Ciri
|
22
|
+
module Forks
|
23
|
+
module Constantinople
|
24
|
+
class Schema < Forks::Byzantium::Schema
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/ciri/forks/frontier.rb
CHANGED
@@ -17,8 +17,12 @@
|
|
17
17
|
|
18
18
|
require_relative 'base'
|
19
19
|
require_relative 'frontier/cost'
|
20
|
+
require_relative 'frontier/transaction'
|
21
|
+
require_relative 'frontier/opcodes'
|
22
|
+
require 'ciri/types/receipt'
|
20
23
|
require 'ciri/core_ext'
|
21
24
|
require 'ciri/evm/precompile_contract'
|
25
|
+
require 'forwardable'
|
22
26
|
|
23
27
|
using Ciri::CoreExt
|
24
28
|
|
@@ -27,24 +31,15 @@ module Ciri
|
|
27
31
|
module Frontier
|
28
32
|
class Schema < Base
|
29
33
|
|
30
|
-
|
31
|
-
|
32
|
-
# gas methods
|
33
|
-
def gas_of_operation(vm)
|
34
|
-
Cost.cost_of_operation vm
|
35
|
-
end
|
34
|
+
extend Forwardable
|
36
35
|
|
37
|
-
|
38
|
-
Cost.cost_of_memory word_count
|
39
|
-
end
|
36
|
+
BLOCK_REWARD = 5 * 10.pow(18) # 5 ether
|
40
37
|
|
41
|
-
def
|
42
|
-
Cost.
|
38
|
+
def initialize
|
39
|
+
@cost = Cost.new
|
43
40
|
end
|
44
41
|
|
45
|
-
|
46
|
-
Cost.intrinsic_gas_of_transaction transaction
|
47
|
-
end
|
42
|
+
def_delegators :@cost, :gas_of_operation, :gas_of_memory, :gas_of_call, :intrinsic_gas_of_transaction
|
48
43
|
|
49
44
|
def calculate_deposit_code_gas(code_bytes)
|
50
45
|
Cost::G_CODEDEPOSIT * (code_bytes || ''.b).size
|
@@ -66,26 +61,23 @@ module Ciri
|
|
66
61
|
rewards
|
67
62
|
end
|
68
63
|
|
69
|
-
def
|
70
|
-
|
71
|
-
|
72
|
-
end
|
73
|
-
end
|
64
|
+
def calculate_difficulty(header, parent_header)
|
65
|
+
difficulty_time_factor = (header.timestamp - parent_header.timestamp) < 13 ? 1 : -1
|
66
|
+
x = parent_header.difficulty / 2048
|
74
67
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
68
|
+
# difficulty bomb
|
69
|
+
height = header.number
|
70
|
+
height_factor = 2 ** (height / 100000 - 2)
|
79
71
|
|
80
|
-
|
81
|
-
|
72
|
+
difficulty = (parent_header.difficulty + x * difficulty_time_factor + height_factor).to_i
|
73
|
+
[header.difficulty, difficulty].max
|
82
74
|
end
|
83
75
|
|
84
76
|
PRECOMPILE_CONTRACTS = {
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
77
|
+
"\x01".pad_zero(20).b => EVM::PrecompileContract::ECRecover.new,
|
78
|
+
"\x02".pad_zero(20).b => EVM::PrecompileContract::SHA256.new,
|
79
|
+
"\x03".pad_zero(20).b => EVM::PrecompileContract::RIPEMD160.new,
|
80
|
+
"\x04".pad_zero(20).b => EVM::PrecompileContract::Identity.new,
|
89
81
|
}.freeze
|
90
82
|
|
91
83
|
# EVM op code and contract
|
@@ -93,6 +85,34 @@ module Ciri
|
|
93
85
|
PRECOMPILE_CONTRACTS[address.to_s]
|
94
86
|
end
|
95
87
|
|
88
|
+
def transaction_class
|
89
|
+
Transaction
|
90
|
+
end
|
91
|
+
|
92
|
+
def get_operation(op)
|
93
|
+
OPCODES[op]
|
94
|
+
end
|
95
|
+
|
96
|
+
def exception_on_deposit_code_gas_not_enough
|
97
|
+
false
|
98
|
+
end
|
99
|
+
|
100
|
+
def contract_code_size_limit
|
101
|
+
Float::INFINITY
|
102
|
+
end
|
103
|
+
|
104
|
+
def contract_init_nonce
|
105
|
+
0
|
106
|
+
end
|
107
|
+
|
108
|
+
def clean_empty_accounts?
|
109
|
+
false
|
110
|
+
end
|
111
|
+
|
112
|
+
def make_receipt(execution_result:, gas_used:)
|
113
|
+
Types::Receipt.new(state_root: execution_result.state_root, gas_used: gas_used, logs: execution_result.logs)
|
114
|
+
end
|
115
|
+
|
96
116
|
end
|
97
117
|
end
|
98
118
|
end
|