EVMHost: Calculate address for CREATE properly

This commit is contained in:
Alex Beregszaszi 2022-09-16 15:38:50 +02:00
parent 5f8b48793c
commit 9aa304d43a

View File

@ -250,23 +250,48 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
if (message.kind == EVMC_CREATE) if (message.kind == EVMC_CREATE)
{ {
// TODO this is not the right formula
// TODO is the nonce incremented on failure, too? // TODO is the nonce incremented on failure, too?
// NOTE: nonce for creation from contracts starts at 1
// TODO: check if sender is an EOA and do not pre-increment
sender.nonce++;
auto encodeRlpInteger = [](int value) -> bytes {
if (value == 0) {
return bytes{128};
} else if (value <= 127) {
return bytes{static_cast<uint8_t>(value)};
} else if (value <= 0xff) {
return bytes{128 + 1, static_cast<uint8_t>(value)};
} else if (value <= 0xffff) {
return bytes{128 + 55 + 2, static_cast<uint8_t>(value >> 8), static_cast<uint8_t>(value)};
} else {
assertThrow(false, Exception, "Can only encode RLP numbers <= 0xffff");
}
};
bytes encodedNonce = encodeRlpInteger(sender.nonce);
h160 createAddress(keccak256( h160 createAddress(keccak256(
bytes{static_cast<uint8_t>(0xc0 + 21 + encodedNonce.size())} +
bytes{0x94} +
bytes(begin(message.sender.bytes), end(message.sender.bytes)) + bytes(begin(message.sender.bytes), end(message.sender.bytes)) +
asBytes(to_string(sender.nonce++)) encodedNonce
), h160::AlignLeft); ), h160::AlignRight);
message.destination = convertToEVMC(createAddress); message.destination = convertToEVMC(createAddress);
assertThrow(accounts.count(message.destination) == 0, Exception, "Account cannot exist");
code = evmc::bytes(message.input_data, message.input_data + message.input_size); code = evmc::bytes(message.input_data, message.input_data + message.input_size);
} }
else if (message.kind == EVMC_CREATE2) else if (message.kind == EVMC_CREATE2)
{ {
h160 createAddress(keccak256( h160 createAddress(keccak256(
bytes(1, 0xff) + bytes{0xff} +
bytes(begin(message.sender.bytes), end(message.sender.bytes)) + bytes(begin(message.sender.bytes), end(message.sender.bytes)) +
bytes(begin(message.create2_salt.bytes), end(message.create2_salt.bytes)) + bytes(begin(message.create2_salt.bytes), end(message.create2_salt.bytes)) +
keccak256(bytes(message.input_data, message.input_data + message.input_size)).asBytes() keccak256(bytes(message.input_data, message.input_data + message.input_size)).asBytes()
), h160::AlignLeft); ), h160::AlignRight);
message.destination = convertToEVMC(createAddress); message.destination = convertToEVMC(createAddress);
if (accounts.count(message.destination) && ( if (accounts.count(message.destination) && (
accounts[message.destination].nonce > 0 || accounts[message.destination].nonce > 0 ||