mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
EVMHost: Calculate address for CREATE properly
This commit is contained in:
parent
5f8b48793c
commit
9aa304d43a
@ -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 ||
|
||||||
|
Loading…
Reference in New Issue
Block a user