-
Notifications
You must be signed in to change notification settings - Fork 11.8k
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 Create2 library #1744
Add Create2 library #1744
Conversation
@spalladino I followed the same nomeclature used in https://github.com/zeppelinos/zos/blob/master/packages/lib/contracts/upgradeability/ProxyFactory.sol I dont know if you plan to allow CREATE2 to be used in the proxy factory, but I guess thats something that should be discussed in zeppelinos repo. ping to @nventuro @cwhinfrey who discussed the implementation in #1644 I Think this PR should be focused on a simple implementation of a CREATE2 factory. And once accepted we can extend this to two more factories, one that support Ownable contracts and another that deploys contracts with a fixed bytecode, where the fixed bytecode version can be used for metatxs contracts. |
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.
Hello @AugustoL, thank you for working on this!
I only made a couple comments on the contract code so far. What do you think about turning it into a library
with internal
functions? Otherwise, with the current API we'd be forcing any contract that wants to use the factory to either deploy one itself, or extend it and provide public
methods that it doesn't need.
After having looked at this PR, I would like to suggest to split CREATE2Factory into two contracts. a BasicFactory Contract without public functions and then a standard factory Contract which contains public functions such as deploy and computeAddress. so that if someone wants to create a Factory that takes different arguments in deploy and computeAddress we can still make it inherit from BasicFactory without completely rewriting the contract. an example of this kind of scenario has been provided by @marekkirejczyk in #1651. |
@AugustoL this is awesome! Great to see this coming along. I think one thing to think about is whether people will want to use the regular constructor or the Using the regular constructor will mean appending any constructor parameters to the end of the init code before passing it in as the Using the After thinking through all of this, I really like @nventuro's idea of having a Create2 library rather than a factory (or having a library and a factory that uses it). It would give people the most flexibility in how they calculate the salt, initialize the contracts, ect. while still encapsulating the Create2 assembly code and address calculation. |
@cwhinfrey a flexible library that simply makes the opcode easier to use and then building on top of that with common patterns sounds like the way to go :) |
@nventuro I changed the contract for a library. Next:
|
I like this, since a user may either use this to be a factory itself, or to compute addresses of contracts deployed by other factories. I worry that the names being the same may make this confusing, but am unsure as to what a better name would be ( The Note that the |
@nventuro what about having only the Also, what about having an anotrher example of a create2 factory for meta txs? that can be useful. |
I was also thinking that having just the more flexible one sounds like the way to go, but now I wonder, in which scenario would you need to compute the address where another factory would deploy a contract? @spalladino thoughts? Regarding the extra example, meta transactions does seem like a useful case. However, I'm not particularly sold on the idea of standalone example contracts, I think they're not very useful by themselves without an accompanying guide. We'll be updating the current guides and docsite in the following days: I'd wait until then to see how we make make this better fit that new format. |
Hi all! |
Hi folks! |
We'd really like to have support for |
A couple of comments after working with @JustynaBroniszewska on CREATE2 based functionality in Universal Login:
const computeAddress = (deployer, salt, code) => {
const codeHash = keccak256(['bytes'], [code]);
const hashedData = keccak256(['bytes1', 'address', 'bytes32', 'bytes32'], ['0xff', deployer, salt, codeHash]);
return `0x${hashedData.slice(26)}`;
}; Looking forward to your opinions. |
Hi, The two firsts point seems ok, but the third, I think the lib should maintain a method to calculate the address by itself. (is kinda a syntax sugar) We can build some smart contract logic by calculating the address without the need of external source (feed by the user). Cheers |
I found this PR because i was looking for that specific method 💯 |
Sounds fair. |
Hi everybody, It looks like the is a code duplication in two methods, why not encapsulate as : function computeAddress(bytes32 salt, bytes memory codeInit) internal returns(address) {
return computeAddress(address(this), salt, codeInit);
} The deploy function should return an address instead of emitting an event as: function deploy(bytes32 salt, bytes memory codeInit) internal returns(address) {
return _deploy(salt, codeInit);
} Cheers |
contracts/utils/Create2.sol
Outdated
* @param code The bytecode of of the contract to be deployed | ||
*/ | ||
function deploy(bytes32 salt, bytes memory code) internal { | ||
address addr = _deploy(salt, code); |
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.
Maybe you can use deployAddress
to replace addr
, it is shorter, but it will be more difficult to understand.
Not really, just like the function name, one is to deploy, and the other is to calculate. you can use |
At first, I think we can keep both, more than one approach, more than one choice. But when I decide to compute a special address, I find it is more convenient by js function. |
import "../ownership/Ownable.sol"; | ||
|
||
contract Create2OwnableFactory { | ||
function deploy(bytes32 salt, bytes memory code) public { |
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.
If I use uint256
rather than bytes32
, is it OK?
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.
@Skyge I believe it will be fairly common to calculate the salt with a keccak256
hash. Is there a case where the salt would be calculated as an integer?
I was thinking in maintaining the two methods, just make one call the other if you dont pass the first param (deployer address). The code inside the two function are same. |
Hi all! |
It looks like the latest version of |
@frangio I've upgraded |
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.
Thanks everyone involved! This is a great addition to the library.
* See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more | ||
* information. | ||
*/ | ||
library Create2 { |
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 a fan of this name. Do we have other options?
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.
Usage will be Create2.deploy()
. I also dislike the name, but I'm not sure how we can more succinctly convey the underlying idea.
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.
Yep, I think we wont came up with a better name.
Hi all! |
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 @AugustoL!
I'm merging temporarily into a feature branch. I want us to think a bit more about alternative names. I also want to add a revert reason for when the deploy fails, but this PR has been open for too long.
* Add Create2 library (#1744) * feat(contracts): Add Create2 library to use create2 evm opcode * Upgrade sol-coverage * Add changelog entry * Update comments and code style * Remove create2 helper * Fix linter error * Fix truffle dependency * Fix linter error * refactor(Create2): Remove _deploy internal function * test(Create2): test Create2 with inline assembly code * fix(Create2): Check address returned form create2 instead of codesize of created contract * refactor(Create2):Add revert reason when Create2 deploy fails (#2062) * fix merge with master * fix test Co-authored-by: Augusto Lemble <me@augustol.com>
* Add Create2 library (OpenZeppelin#1744) * feat(contracts): Add Create2 library to use create2 evm opcode * Upgrade sol-coverage * Add changelog entry * Update comments and code style * Remove create2 helper * Fix linter error * Fix truffle dependency * Fix linter error * refactor(Create2): Remove _deploy internal function * test(Create2): test Create2 with inline assembly code * fix(Create2): Check address returned form create2 instead of codesize of created contract * refactor(Create2):Add revert reason when Create2 deploy fails (OpenZeppelin#2062) * fix merge with master * fix test Co-authored-by: Augusto Lemble <me@augustol.com>
Fixes #1644
This PR adds a simple CREATE2Factory based on different implementations I saw around.
The goal is to have the minimum and necessary contract factory to deploy contracts using CREATE2 evm opcode. This I why I didnt added any extra methods to deploy smart contracts with a fixed bytecode, nevertheless this contract can be extended into metatxs or ownable create2 factories.