-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add CREATE3 opcode - no init_code hash #3171
Conversation
status: Draft | ||
created: 2020-12-22 | ||
--- | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where should discussions for this EIP go?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@moodysalem please update with a discussions-to
section.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@moodysalem still missing a discussions-to
section. Merging is blocked until this is resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a few recommendations on the eip. The only things blocking a merge are updating the author field with your github handle and creating a discussions-to
field.
status: Draft | ||
created: 2020-12-22 | ||
--- | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@moodysalem please update with a discussions-to
section.
|
||
## Simple Summary | ||
|
||
This EIP is a fork of [EIP-1014](./eip-1014.md) (`CREATE2`) which adds an account creation opcode (`CREATE3`) that does |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this sentence makes more sense in the abstract, and the simple summary can just be sentence below.
This EIP is a fork of [EIP-1014](./eip-1014.md) (`CREATE2`) which adds an account creation opcode (`CREATE3`) that does | ||
not involve the init code hash. It is otherwise identical to `CREATE2` opcode. | ||
|
||
This opcode allows users to create accounts at an address independent of the bytecode deployed to the address. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This opcode allows users to create accounts at an address independent of the bytecode deployed to the address. | |
`CREATE3 (0xf6)` allows users to create accounts at an address independent of the bytecode deployed to the address. |
|
||
## Security Considerations | ||
|
||
This new opcode allows the deterministic contract address to be independent of the bytecode. Users may not depend on the deterministic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure it's fair to say this opcode "allows" this behaviour as it's possible to deploy arbitrary contracts to deterministic addresses with CREATE2
.
Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com>
This is feasible only because the Uniswap V2 Pair does not have any constructor arguments, which means the init code hash | ||
can be hard coded in the library. However, the init code hash cannot be hard coded when the deployed smart contract has | ||
constructor arguments. In order to compute the init code hash, one must append the constructor arguments to the init code | ||
before computing the init code hash. Thus, in order to compute the address of an account created via `CREATE2`, it is | ||
necessary to include the entire init code without the constructor arguments, and hash | ||
`ceil(len(init_code_base + constructor_arguments) / 32)` words on-chain. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not particularly pretty, but I believe another workaround to this problem is to have the init code pull the arguments from the creator:
interface F {
function provideX() external returns (uint) {
}
contract A {
uint x;
constructor() {
x = F(msg.sender).provideX();
}
}
contract Factory {
uint x;
function provideX() public returns (uint) {
return x;
}
function deployA(uint initArg) public {
x = initArg;
new A();
x = 0;
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, I heard about this in the #allcoredevs channel of Discord and I will add it as a workaround
status: Draft | ||
created: 2020-12-22 | ||
--- | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@moodysalem still missing a discussions-to
section. Merging is blocked until this is resolved.
Since there is a great workaround I don't see a reason for this EIP any longer. Closing this PR so as not to reserve the name CREATE3 for only an incremental improvement over CREATE2. Would prefer a CREATE3 or other opcode that does something to improve the cost of deploying many contracts with identical init code and near identical runtime bytecode (without any runtime overhead like minimal proxy) |
@moodysalem the work around being the delegatecall trampoline in the init code? |
There's no delegatecall involved (it just does a staticcall to get the constructor arguments from another address, with 0 real constructor arguments) |
@moodysalem ah okay, and that is fine because you're always deploying the same code - just with different constructor arguments? |
I believe there is still a strong reason for removing init code hash from the address generation, which is the controlling the same address on multiple networks but with different code. With layer 2s, different code may need to be deployed at the same address for each network. |
Hi! I'm a bot, and I wanted to automerge your PR, but couldn't because of the following issue(s): eip-3171.md
|
With some effort, you can have different deployed bytecode on each network without a new opcode. You just need to fetch your deployment bytes (or parameters) from storage as part of the constructor, rather than deploying static bytes. While the current tooling doesn't support this, I think changing the tooling is superior to changing the EVM when possible. The gas cost of deploying like this is a bit higher, but usually deployments are cheap. Separately, this PR still needs the adjustments mentioned above, plus the Simple Summary is no longer a section and it is replaced with a |
The reason to add a new opcode is that the original rationale for init code hash being included is incorrect (guarantee that the code at that address is the same) because it can be circumvented as you describe. I will work on updates to the PR to make it mergeable. |
This seems like an argument for removing/fixing/altering CREATE2, rather than an argument for adding CREATE3? |
Wouldn't altering it require recomputing all the addresses previously created by |
I just meant to say that the argument you made is essentially that "CREATE2 doesn't achieve its stated goals", but it wasn't an argument that "CREATE3 is necessary". |
Strongly supporting this EIP. Let's also remove CREATE/CREATE2/CREATE3 32k gas payment in case of 0 bytecode deployment size, this would allow to have cheaper pure proxy factories. |
There has been no activity on this pull request for two months. It will be closed in a week if no further activity occurs. If you would like to move this EIP forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review. |
CREATE3 is very useful for |
This pull request was closed due to inactivity. If you are still pursuing it, feel free to reopen it and respond to any feedback or request a review in a comment. |
Pull request was closed
Dealing with this right now and CREATE3 would really make a lot of things simpler, voicing support for it too :) |
Please reopen this. |
Hi, thanks I love to follow the discussion about Create3. Where do I follow the latest discussion? Is this pull request the canonical discussion place? I saw it was put on AllCoreDevs #102 for a decision but checked the agenda and notes |
@k06a I created an solution that allow you to initialize immutables using Source code: Essentially it is a Create2Factory contract, but with some advanced features:
|
Adds a CREATE3 opcode that does not include the init code hash, which is difficult to use on-chain to compute addresses in combination with constructor arguments.
The rationale for including the init code hash in the CREATE2 implementation is that it forces the address to contain specific bytecode. However it is not useful for cases where you only care that the contract was deployed by a specific factory account, with certain arguments (encoded in the salt), which is sufficient proof that the contract bytecode is as expected in many use cases.
I.e., if you want to compute the address of a contract with constructor arguments created via CREATE2 on-chain, you have to include the entire bytecode of the contract for which you are computing the address (instead of just the hash) to get the preimage of the contract bytecode.