27
27
CREATE_CONTRACT_ADDRESS = b''
28
28
29
29
30
+ def mk_contract_address (sender , nonce ):
31
+ return utils .sha3 (rlp .encode ([sender , nonce ]))[12 :]
32
+
33
+
30
34
def verify (block , parent ):
31
35
from ethereum import blocks
32
36
try :
@@ -71,41 +75,49 @@ def __repr__(self):
71
75
(encode_hex (self .address ), self .topics , self .data )
72
76
73
77
74
- def apply_transaction (block , tx ):
78
+ def intrinsic_gas_used (tx ):
79
+ num_zero_bytes = str_to_bytes (tx .data ).count (ascii_chr (0 ))
80
+ num_non_zero_bytes = len (tx .data ) - num_zero_bytes
81
+ return (opcodes .GTXCOST
82
+ + opcodes .GTXDATAZERO * num_zero_bytes
83
+ + opcodes .GTXDATANONZERO * num_non_zero_bytes )
84
+
85
+
86
+ def validate_transaction (block , tx ):
75
87
76
- def rp (actual , target ):
77
- return '%r, actual:%r target:%r' % (tx , actual , target )
88
+ def rp (what , actual , target ):
89
+ return '%r: %r actual:%r target:%r' % (tx , what , actual , target )
78
90
79
91
# (1) The transaction signature is valid;
80
- if not tx .sender :
92
+ if not tx .sender : # sender is set and validated on Transaction initialization
81
93
raise UnsignedTransaction (tx )
82
94
83
95
# (2) the transaction nonce is valid (equivalent to the
84
96
# sender account's current nonce);
85
97
acctnonce = block .get_nonce (tx .sender )
86
98
if acctnonce != tx .nonce :
87
- raise InvalidNonce (rp (tx .nonce , acctnonce ))
99
+ raise InvalidNonce (rp ('nonce' , tx .nonce , acctnonce ))
88
100
89
101
# (3) the gas limit is no smaller than the intrinsic gas,
90
102
# g0, used by the transaction;
91
- num_zero_bytes = str_to_bytes (tx .data ).count (ascii_chr (0 ))
92
- num_non_zero_bytes = len (tx .data ) - num_zero_bytes
93
- intrinsic_gas_used = (opcodes .GTXCOST
94
- + opcodes .GTXDATAZERO * num_zero_bytes
95
- + opcodes .GTXDATANONZERO * num_non_zero_bytes )
96
- if tx .startgas < intrinsic_gas_used :
97
- raise InsufficientStartGas (rp (tx .startgas , intrinsic_gas_used ))
103
+ if tx .startgas < intrinsic_gas_used (tx ):
104
+ raise InsufficientStartGas (rp ('startgas' , tx .startgas , intrinsic_gas_used ))
98
105
99
106
# (4) the sender account balance contains at least the
100
107
# cost, v0, required in up-front payment.
101
108
total_cost = tx .value + tx .gasprice * tx .startgas
102
109
if block .get_balance (tx .sender ) < total_cost :
103
- raise InsufficientBalance (
104
- rp (block .get_balance (tx .sender ), total_cost ))
110
+ raise InsufficientBalance (rp ('balance' , block .get_balance (tx .sender ), total_cost ))
105
111
106
112
# check block gas limit
107
113
if block .gas_used + tx .startgas > block .gas_limit :
108
- raise BlockGasLimitReached (rp (block .gas_used + tx .startgas , block .gas_limit ))
114
+ raise BlockGasLimitReached (rp ('gaslimit' , block .gas_used + tx .startgas , block .gas_limit ))
115
+
116
+ return True
117
+
118
+
119
+ def apply_transaction (block , tx ):
120
+ validate_transaction (block , tx )
109
121
110
122
log_tx .debug ('TX NEW' , tx = encode_hex (tx .hash ), tx_dict = tx .to_dict ())
111
123
# start transacting #################
@@ -115,11 +127,9 @@ def rp(actual, target):
115
127
# buy startgas
116
128
assert block .get_balance (tx .sender ) >= tx .startgas * tx .gasprice
117
129
block .delta_balance (tx .sender , - tx .startgas * tx .gasprice )
118
-
119
- message_gas = tx .startgas - intrinsic_gas_used
130
+ message_gas = tx .startgas - intrinsic_gas_used (tx )
120
131
message_data = vm .CallData ([safe_ord (x ) for x in tx .data ], 0 , len (tx .data ))
121
- message = vm .Message (tx .sender , tx .to , tx .value , message_gas , message_data ,
122
- code_address = tx .to )
132
+ message = vm .Message (tx .sender , tx .to , tx .value , message_gas , message_data , code_address = tx .to )
123
133
124
134
# MESSAGE
125
135
ext = VMExt (block , tx )
@@ -250,7 +260,7 @@ def create_contract(ext, msg):
250
260
if ext .tx_origin != msg .sender :
251
261
ext ._block .increment_nonce (msg .sender )
252
262
nonce = utils .encode_int (ext ._block .get_nonce (msg .sender ) - 1 )
253
- msg .to = utils . sha3 ( rlp . encode ([ sender , nonce ]))[ 12 :]
263
+ msg .to = mk_contract_address ( sender , nonce )
254
264
b = ext .get_balance (msg .to )
255
265
if b > 0 :
256
266
ext .set_balance (msg .to , b )
0 commit comments