Skip to content

Commit 2201526

Browse files
authored
Merge pull request #13533 from ethereum/evmhost-create
EVMHost: Calculate address for CREATE properly
2 parents 5f8b487 + 0357ced commit 2201526

File tree

15 files changed

+114
-21
lines changed

15 files changed

+114
-21
lines changed

test/EVMHost.cpp

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,23 +250,48 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
250250

251251
if (message.kind == EVMC_CREATE)
252252
{
253-
// TODO this is not the right formula
254253
// 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+
255274
h160 createAddress(keccak256(
275+
bytes{static_cast<uint8_t>(0xc0 + 21 + encodedNonce.size())} +
276+
bytes{0x94} +
256277
bytes(begin(message.sender.bytes), end(message.sender.bytes)) +
257-
asBytes(to_string(sender.nonce++))
258-
), h160::AlignLeft);
278+
encodedNonce
279+
), h160::AlignRight);
280+
259281
message.destination = convertToEVMC(createAddress);
282+
assertThrow(accounts.count(message.destination) == 0, Exception, "Account cannot exist");
283+
260284
code = evmc::bytes(message.input_data, message.input_data + message.input_size);
261285
}
262286
else if (message.kind == EVMC_CREATE2)
263287
{
264288
h160 createAddress(keccak256(
265-
bytes(1, 0xff) +
289+
bytes{0xff} +
266290
bytes(begin(message.sender.bytes), end(message.sender.bytes)) +
267291
bytes(begin(message.create2_salt.bytes), end(message.create2_salt.bytes)) +
268292
keccak256(bytes(message.input_data, message.input_data + message.input_size)).asBytes()
269-
), h160::AlignLeft);
293+
), h160::AlignRight);
294+
270295
message.destination = convertToEVMC(createAddress);
271296
if (accounts.count(message.destination) && (
272297
accounts[message.destination].nonce > 0 ||

test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ contract C {
1919
// gas legacy: 250376
2020
// gas legacyOptimized: 174522
2121
// deposit(bytes32), 18 wei: 0x1234 ->
22-
// ~ emit Deposit(address,bytes32,uint256) from 0xf01f7809444bd9a93a854361c6fae3f23d9e23db: #0x0fdd67305928fcac8d213d1e47bfa6165cd0b87b, #0x1234, 0x00
22+
// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00

test/libsolidity/semanticTests/events/event_indexed_function.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ contract C {
66
}
77
// ----
88
// f() ->
9-
// ~ emit Test(function): #0x0fdd67305928fcac8d213d1e47bfa6165cd0b87b26121ff00000000000000000
9+
// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000

test/libsolidity/semanticTests/events/event_indexed_function2.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ contract C {
1010
}
1111
// ----
1212
// f1() ->
13-
// ~ emit TestA(function): #0x0fdd67305928fcac8d213d1e47bfa6165cd0b87bc27fc3050000000000000000
13+
// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000
1414
// f2(uint256): 1 ->
15-
// ~ emit TestB(function): #0x0fdd67305928fcac8d213d1e47bfa6165cd0b87bbf3724af0000000000000000
15+
// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000

test/libsolidity/semanticTests/functionCall/failed_create.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ contract C {
2020
// gas irOptimized: 184005
2121
// gas legacy: 294335
2222
// gas legacyOptimized: 173427
23-
// f(uint256): 20 -> 1370859564726510389319704988634906228201275401179
23+
// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a
2424
// x() -> 1
2525
// f(uint256): 20 -> FAILURE
2626
// x() -> 1
@@ -29,5 +29,5 @@ contract C {
2929
// gas legacy: 483942
3030
// gas legacyOptimized: 302349
3131
// x() -> 1
32-
// stack(uint256): 10 -> 693016686122178122849713379390321835634789309880
32+
// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908
3333
// x() -> 2

test/libsolidity/semanticTests/functionTypes/address_member.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ contract C {
99
// ====
1010
// compileToEwasm: also
1111
// ----
12-
// f() -> 90572315268751552425567948436632610904688605307, 90572315268751552425567948436632610904688605307
12+
// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e

test/libsolidity/semanticTests/functionTypes/function_external_delete_storage.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ contract C {
2525
// increment() ->
2626
// y() -> 1
2727
// set() ->
28-
// x() -> 0xfdd67305928fcac8d213d1e47bfa6165cd0b87bd09de08a0000000000000000
28+
// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000
2929
// increment() ->
3030
// y() -> 2
3131
// incrementIndirectly() ->

test/libsolidity/semanticTests/inlineAssembly/external_function_pointer_address.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ contract C {
1313
}
1414
}
1515
// ----
16-
// testYul() -> 0x0fdd67305928fcac8d213d1e47bfa6165cd0b87b
17-
// testSol() -> 0x0fdd67305928fcac8d213d1e47bfa6165cd0b87b
16+
// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e
17+
// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e

test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ contract ClientReceipt {
2323
// gas irOptimized: 191881
2424
// gas legacy: 235167
2525
// gas legacyOptimized: 180756
26-
// getAddress() -> 0xf01f7809444bd9a93a854361c6fae3f23d9e23db
27-
// balance: 0xf01f7809444bd9a93a854361c6fae3f23d9e23db -> 500
26+
// getAddress() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a
27+
// balance: 0x137aa4dfc0911524504fcd4d98501f179bc13b4a -> 500
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
contract D {
2+
uint public x;
3+
constructor(uint a) {
4+
x = a;
5+
}
6+
}
7+
8+
contract C {
9+
function createDSalted(bytes32 salt, uint arg) public {
10+
address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(
11+
bytes1(0xff),
12+
address(this),
13+
salt,
14+
keccak256(abi.encodePacked(
15+
type(D).creationCode,
16+
arg
17+
))
18+
)))));
19+
20+
D d = new D{salt: salt}(arg);
21+
require(address(d) == predictedAddress, "Address mismatch.");
22+
}
23+
}
24+
// ====
25+
// EVMVersion: >=constantinople
26+
// compileViaYul: also
27+
// ----
28+
// createDSalted(bytes32,uint256): 42, 64 ->
29+
// gas legacy: 104365

0 commit comments

Comments
 (0)