@@ -250,23 +250,48 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
250
250
251
251
if (message.kind == EVMC_CREATE)
252
252
{
253
- // TODO this is not the right formula
254
253
// TODO is the nonce incremented on failure, too?
254
+ // NOTE: nonce for creation from contracts starts at 1
255
+ // TODO: check if sender is an EOA and do not pre-increment
256
+ sender.nonce ++;
257
+
258
+ auto encodeRlpInteger = [](int value) -> bytes {
259
+ if (value == 0 ) {
260
+ return bytes{128 };
261
+ } else if (value <= 127 ) {
262
+ return bytes{static_cast <uint8_t >(value)};
263
+ } else if (value <= 0xff ) {
264
+ return bytes{128 + 1 , static_cast <uint8_t >(value)};
265
+ } else if (value <= 0xffff ) {
266
+ return bytes{128 + 55 + 2 , static_cast <uint8_t >(value >> 8 ), static_cast <uint8_t >(value)};
267
+ } else {
268
+ assertThrow (false , Exception, " Can only encode RLP numbers <= 0xffff" );
269
+ }
270
+ };
271
+
272
+ bytes encodedNonce = encodeRlpInteger (sender.nonce );
273
+
255
274
h160 createAddress (keccak256 (
275
+ bytes{static_cast <uint8_t >(0xc0 + 21 + encodedNonce.size ())} +
276
+ bytes{0x94 } +
256
277
bytes (begin (message.sender .bytes ), end (message.sender .bytes )) +
257
- asBytes (to_string (sender.nonce ++))
258
- ), h160::AlignLeft);
278
+ encodedNonce
279
+ ), h160::AlignRight);
280
+
259
281
message.destination = convertToEVMC (createAddress);
282
+ assertThrow (accounts.count (message.destination ) == 0 , Exception, " Account cannot exist" );
283
+
260
284
code = evmc::bytes (message.input_data , message.input_data + message.input_size );
261
285
}
262
286
else if (message.kind == EVMC_CREATE2)
263
287
{
264
288
h160 createAddress (keccak256 (
265
- bytes ( 1 , 0xff ) +
289
+ bytes{ 0xff } +
266
290
bytes (begin (message.sender .bytes ), end (message.sender .bytes )) +
267
291
bytes (begin (message.create2_salt .bytes ), end (message.create2_salt .bytes )) +
268
292
keccak256 (bytes (message.input_data , message.input_data + message.input_size )).asBytes ()
269
- ), h160::AlignLeft);
293
+ ), h160::AlignRight);
294
+
270
295
message.destination = convertToEVMC (createAddress);
271
296
if (accounts.count (message.destination ) && (
272
297
accounts[message.destination ].nonce > 0 ||
0 commit comments