![](https://cdn.nodeguardians.io/backend-production/solidity_bg_fc76a87eed/solidity_bg_fc76a87eed.webp)
Standalone
Self-Hosted EVM
![](https://cdn.nodeguardians.io/backend-production/Self_Hosted_EVM_Part7_fa595654c8/Self_Hosted_EVM_Part7_fa595654c8.webp)
Part VII
Create & Create2
With the CALL
family of instructions implemented, we are only left with the CREATE and CREATE2
instructions. We are almost finished!
Create
CREATE
is used by a contract to deploy a new contract on-chain. The deployer might attach some value to the deploying call. This instruction will consume the following stack:
![selfhosted_EVM_12.webp](https://cdn.nodeguardians.io/backend-production/selfhosted_EVM_12_b421070e04/selfhosted_EVM_12_b421070e04.webp)
The deployment bytecode is given by mem[ARGS OFFSET: ARGS OFFSET + ARGS LENGTH]
, which consists of the contract bytecode and any constructor parameters.
The new contract's construction might revert. In this case, opCreate
should safely handle the reversion and push address(0)
onto the stack. This can be handled by using ICrossTx
and a try
/catch
block, similar to what we did with our call instructions.
function opCreate(Scope memory scope) internal {
...
try ICrossTx(address(this)).create(...) {
// SUCCESS ...
} catch (bytes memory revertData) {
// FAILURE ...
}
}
![selfhosted_EVM_13.webp](https://cdn.nodeguardians.io/backend-production/selfhosted_EVM_13_443473a1bf/selfhosted_EVM_13_443473a1bf.webp)
CREATE
also has several other nuances you have to consider to get the implementation right:
Each new contract's address is determined by the deployer's address and the deployer's nonce. A pre-defined function,
State.getNextDeploymentAddress(address)
, is provided to help you perform this computation.Upon each deployment, the deployer's nonce should be incremented by 1, while the new contract's nonce should be set to 1.
Although unlikely, it is possible that the address to deploy to is already occupied. In this case, deployment should fail.
Error | Expected Message |
|
|
|
|
|
|
Create2
CREATE2
deploys a contract as well, except that the new address is deterministically computed, independent from the deployer's nonce. Instead, it is computed from the deployer's address, initialization bytecode, and a salt. This instruction consumes the following stack:
![selfhosted_EVM_14.webp](https://cdn.nodeguardians.io/backend-production/selfhosted_EVM_14_034e4c18e4/selfhosted_EVM_14_034e4c18e4.webp)
Similar to how opCreate
is implemented, opCreate2
will need to make an external call to the sEVM.create2
function.
![selfhosted_EVM_15.webp](https://cdn.nodeguardians.io/backend-production/selfhosted_EVM_15_c317344b2f/selfhosted_EVM_15_c317344b2f.webp)
Unlike in CREATE
, you will need to define the address computation logic yourself.|
Error | Expected Message |
|
|
|
|
|
|
Your Task
Implement CREATE
by defining:
opCreate
incontracts/libraries/Instructions.sol
create
incontracts/sEVM.sol
Then, implement CREATE2
by defining:
opCreate2
incontracts/libraries/Instructions.sol
create2
incontracts/sEVM.sol
Run tests in Questplay
Submit work in Questplay
![](https://cdn.nodeguardians.io/backend-production/Self_Hosted_EVM_Part7_fa595654c8/Self_Hosted_EVM_Part7_fa595654c8.webp)
As more and more came to learn, the Order of the Node Guardians was founded, sworn to follow the Tenets and use Cryptomancy to strive for a better world for all...