8
8
from ethereum import bloom
9
9
from ethereum import vm as vm
10
10
from ethereum .exceptions import *
11
- from ethereum .utils import safe_ord , normalize_address , mk_contract_address
11
+ from ethereum .utils import safe_ord , normalize_address , mk_contract_address , \
12
+ mk_metropolis_contract_address , int_to_addr , big_endian_to_int
12
13
from ethereum import transactions
13
14
import ethereum .config as config
14
15
@@ -80,7 +81,10 @@ def rp(what, actual, target):
80
81
81
82
# (1) The transaction signature is valid;
82
83
if not tx .sender : # sender is set and validated on Transaction initialization
83
- raise UnsignedTransaction (tx )
84
+ if block .number >= config .default_config ["METROPOLIS_FORK_BLKNUM" ]:
85
+ tx ._sender = normalize_address (config .default_config ["METROPOLIS_ENTRY_POINT" ])
86
+ else :
87
+ raise UnsignedTransaction (tx )
84
88
if block .number >= config .default_config ["HOMESTEAD_FORK_BLKNUM" ]:
85
89
tx .check_low_s ()
86
90
@@ -197,6 +201,8 @@ def __init__(self, block, tx):
197
201
self .get_code = block .get_code
198
202
self .get_balance = block .get_balance
199
203
self .set_balance = block .set_balance
204
+ self .get_nonce = block .get_nonce
205
+ self .set_nonce = block .set_nonce
200
206
self .set_storage_data = block .set_storage_data
201
207
self .get_storage_data = block .get_storage_data
202
208
self .log_storage = lambda x : block .account_to_dict (x )['storage' ]
@@ -274,10 +280,21 @@ def create_contract(ext, msg):
274
280
log_msg .debug ('CONTRACT CREATION' )
275
281
#print('CREATING WITH GAS', msg.gas)
276
282
sender = decode_hex (msg .sender ) if len (msg .sender ) == 40 else msg .sender
277
- if ext .tx_origin != msg .sender :
278
- ext ._block .increment_nonce (msg .sender )
279
- nonce = utils .encode_int (ext ._block .get_nonce (msg .sender ) - 1 )
280
- msg .to = mk_contract_address (sender , nonce )
283
+ code = msg .data .extract_all ()
284
+ if ext ._block .number >= ext ._block .METROPOLIS_FORK_BLKNUM :
285
+ msg .to = mk_metropolis_contract_address (msg .sender , code )
286
+ if ext .get_code (msg .to ):
287
+ if ext .get_nonce (msg .to ) >= 2 ** 40 :
288
+ ext .set_nonce (msg .to , (ext .get_nonce (msg .to ) + 1 ) % 2 ** 160 )
289
+ msg .to = normalize_address ((ext .get_nonce (msg .to ) - 1 ) % 2 ** 160 )
290
+ else :
291
+ ext .set_nonce (msg .to , (big_endian_to_int (msg .to ) + 2 ) % 2 ** 160 )
292
+ msg .to = normalize_address ((ext .get_nonce (msg .to ) - 1 ) % 2 ** 160 )
293
+ else :
294
+ if ext .tx_origin != msg .sender :
295
+ ext ._block .increment_nonce (msg .sender )
296
+ nonce = utils .encode_int (ext ._block .get_nonce (msg .sender ) - 1 )
297
+ msg .to = mk_contract_address (sender , nonce )
281
298
b = ext .get_balance (msg .to )
282
299
if b > 0 :
283
300
ext .set_balance (msg .to , b )
@@ -286,7 +303,6 @@ def create_contract(ext, msg):
286
303
ext ._block .reset_storage (msg .to )
287
304
msg .is_create = True
288
305
# assert not ext.get_code(msg.to)
289
- code = msg .data .extract_all ()
290
306
msg .data = vm .CallData ([], 0 , 0 )
291
307
snapshot = ext ._block .snapshot ()
292
308
res , gas , dat = _apply_msg (ext , msg , code )
0 commit comments