Skip to content

Commit

Permalink
fix(EVM): Make contract creation consistent with Geth implementation (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
0xVolosnikov authored Oct 26, 2024
1 parent e9819ec commit 7b8cecc
Show file tree
Hide file tree
Showing 6 changed files with 417 additions and 459 deletions.
8 changes: 4 additions & 4 deletions system-contracts/SystemContractsHashes.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
"contractName": "ContractDeployer",
"bytecodePath": "artifacts-zk/contracts-preprocessed/ContractDeployer.sol/ContractDeployer.json",
"sourceCodePath": "contracts-preprocessed/ContractDeployer.sol",
"bytecodeHash": "0x010006893b07703146f0b1c9b4cd9d481e206eef99147d13fea699be2fdc8ad9",
"sourceCodeHash": "0xa4c2c1f55f5ef1281e18fd016865d9b83b71ad7facb2fd5130940b3b0b7de621"
"bytecodeHash": "0x01000697c616ad2f70268eedf874c28c7396a868e5a13f3b3401ed7693a9ec4d",
"sourceCodeHash": "0xa6ce082f01fa320322b961928086128e4f3dbd35928b8754f74e49c07c1db456"
},
{
"contractName": "Create2Factory",
Expand Down Expand Up @@ -122,8 +122,8 @@
"contractName": "EvmEmulator",
"bytecodePath": "contracts-preprocessed/artifacts/EvmEmulator.yul/EvmEmulator.yul.zbin",
"sourceCodePath": "contracts-preprocessed/EvmEmulator.yul",
"bytecodeHash": "0x01000cf74eb8015735f39ee5568f6025c9e789d2d73c9b5510614e6296c87341",
"sourceCodeHash": "0xf5d31991d176ac5beca9190ae39fae9e17f32bfe78d4359d6c564959b5478868"
"bytecodeHash": "0x01000cd3259c135498bea6fabbd58c67187ff2effbbc8c3aa2e9a9358e79defc",
"sourceCodeHash": "0xe607a7ec66e349868419f82ffeb32063b46cb9bde7e85612c44ffd79a318ec08"
},
{
"contractName": "EvmGasManager",
Expand Down
39 changes: 15 additions & 24 deletions system-contracts/contracts/ContractDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -200,60 +200,51 @@ contract ContractDeployer is IContractDeployer, SystemContractBase {
return newAddress;
}

function prepareForEvmCreateFromEmulator() public onlySystemCallFromEvmEmulator returns (address) {
function precreateEvmAccountFromEmulator(
bytes32 _salt,
bytes32 evmBytecodeHash
) public onlySystemCallFromEvmEmulator returns (address newAddress) {
if (_getAllowedBytecodeTypesMode() != AllowedBytecodeTypes.EraVmAndEVM) {
revert EVMEmulationNotSupported();
}

return address(0); // TODO solidity semantic tests are invalid, remove it later

// TODO uncomment
/*
uint256 senderNonce = NONCE_HOLDER_SYSTEM_CONTRACT.incrementDeploymentNonce(msg.sender);

address newAddress = Utils.getNewAddressCreateEVM(msg.sender, senderNonce);
if (evmBytecodeHash != bytes32(0)) {
// Create2 case
newAddress = Utils.getNewAddressCreate2EVM(msg.sender, _salt, evmBytecodeHash);
} else {
// Create case
newAddress = Utils.getNewAddressCreateEVM(msg.sender, senderNonce);
}

// Unfortunately we can not provide revert reason as it would break EVM compatibility
// we should not increase nonce in case of collision
require(NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(newAddress) == 0x0);
require(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getCodeHash(uint256(uint160(newAddress))) == 0x0);

return newAddress;
*/
}

/// Note: only possible revert case should be due to revert in the called constructor
function createEvmFromEmulator(
address newAddress,
bytes calldata _initCode
) external payable onlySystemCallFromEvmEmulator returns (address) {
// ##### TODO solidity semantic tests are invalid, remove it later
{
uint256 senderNonce = NONCE_HOLDER_SYSTEM_CONTRACT.incrementDeploymentNonce(msg.sender);

newAddress = Utils.getNewAddressCreateEVM(msg.sender, senderNonce);

// Unfortunately we can not provide revert reason as it would break EVM compatibility
require(NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(newAddress) == 0x0);
require(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getCodeHash(uint256(uint160(newAddress))) == 0x0);
}
// ##### END TODO

_evmDeployOnAddress(msg.sender, newAddress, _initCode);

return newAddress;
}

/// @notice Deploys an EVM contract using address derivation of EVM's `CREATE2` opcode
/// @param _salt The CREATE2 salt
/// @param _initCode The init code for the contract
/// Note: this method may be callable only in system mode,
/// that is checked in the `createAccount` by `onlySystemCall` modifier.
/// Note: this method may be callable only in system mode
function create2EVM(
bytes32 _salt,
bytes calldata _initCode
) external payable override onlySystemCall returns (address) {
// No collision is possible with the zksync's non-EVM CREATE2, since
// the prefixes are different
NONCE_HOLDER_SYSTEM_CONTRACT.incrementDeploymentNonce(msg.sender);
// No collision is possible with the zksync's non-EVM CREATE2, since the prefixes are different
bytes32 bytecodeHash = EfficientCall.keccak(_initCode);
address newAddress = Utils.getNewAddressCreate2EVM(msg.sender, _salt, bytecodeHash);

Expand Down
Loading

0 comments on commit 7b8cecc

Please sign in to comment.