Merge pull request #4726 from ethereum/add_factory_template

add create2 factory
runscript
yann300 7 months ago committed by GitHub
commit 890d631def
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 11
      apps/remix-ide-e2e/src/tests/workspace.test.ts
  2. 2
      apps/remix-ide/src/app/tabs/locales/en/filePanel.json
  3. 10
      libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx
  4. 1
      libs/remix-ws-templates/src/index.ts
  5. 98
      libs/remix-ws-templates/src/script-templates/create2-solidity-factory/create2-factory.sol
  6. 8
      libs/remix-ws-templates/src/script-templates/create2-solidity-factory/index.ts

@ -569,6 +569,17 @@ module.exports = {
.waitForElementVisible('*[data-id="treeViewLitreeViewItemsrc/MULTI_SIG/MultiSigSwapHook.sol"]')
},
'Should add Create2 solidity factory #group4': !function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('filePanel')
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspaceaddcreate2solidityfactory"]')
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`contract Create2FactoryAssembly {`) !== -1,
'current displayed content is not Create2FactoryAssembly')
})
},
tearDown: sauce
}

@ -36,6 +36,8 @@
"filePanel.addscriptetherscan": "Add Etherscan scripts",
"filePanel.workspace.addscriptsindri": "Adds scripts for interacting with Sindri, a zk proof generation remote service",
"filePanel.addscriptsindri": "Add Sindri ZK scripts",
"filePanel.workspace.addcreate2solidityfactory": "A contract which allows you to deploy a contract using CREATE2.",
"filePanel.addcreate2solidityfactory": "Add Create2 Solidity factory",
"filePanel.workspace.addscriptdeployer": "Adds scripts which can be used to deploy contracts",
"filePanel.addscriptdeployer": "Add contract deployer scripts",
"filePanel.workspace.slitherghaction": "Adds a preset yml file to run slither analysis on github actions CI",

@ -194,6 +194,16 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
}}
platforms={[appPlatformTypes.web, appPlatformTypes.desktop]}
></HamburgerMenuItem>
<HamburgerMenuItem
kind="addcreate2solidityfactory"
fa="fa-kit fa-ts-logo"
hideOption={hideWorkspaceOptions || hideFileOperations}
actionOnClick={() => {
props.addHelperScripts('contractCreate2Factory')
props.hideIconsMenu(!showIconsMenu)
}}
platforms={[appPlatformTypes.web, appPlatformTypes.desktop]}
></HamburgerMenuItem>
</>
)
}

@ -13,4 +13,5 @@ export { default as rln } from './templates/rln'
export { contractDeployerScripts } from './script-templates/contract-deployer'
export { etherscanScripts } from './script-templates/etherscan'
export { sindriScripts } from './script-templates/sindri'
export { contractCreate2Factory } from './script-templates/create2-solidity-factory'

@ -0,0 +1,98 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
// credits to https://solidity-by-example.org/app/create2/
contract Create2Factory {
// Returns the address of the newly deployed contract
function deploy(address _owner, uint256 _foo, bytes32 _salt)
public
payable
returns (address)
{
// This syntax is a newer way to invoke create2 without assembly, you just need to pass salt
// https://docs.soliditylang.org/en/latest/control-structures.html#salted-contract-creations-create2
return address(new TestContract{salt: _salt}(_owner, _foo));
}
}
// This is the older way of doing it using assembly
contract Create2FactoryAssembly {
event Deployed(address addr, uint256 salt);
// 1. Get bytecode of contract to be deployed
// NOTE: _owner and _foo are arguments of the TestContract's constructor
function getBytecode(address _owner, uint256 _foo)
public
pure
returns (bytes memory)
{
bytes memory bytecode = type(TestContract).creationCode;
return abi.encodePacked(bytecode, abi.encode(_owner, _foo));
}
// 2. Compute the address of the contract to be deployed
// NOTE: _salt is a random number used to create an address
function getAddress(bytes memory bytecode, uint256 _salt)
public
view
returns (address)
{
bytes32 hash = keccak256(
abi.encodePacked(
bytes1(0xff), address(this), _salt, keccak256(bytecode)
)
);
// NOTE: cast last 20 bytes of hash to address
return address(uint160(uint256(hash)));
}
// 3. Deploy the contract
// NOTE:
// Check the event log Deployed which contains the address of the deployed TestContract.
// The address in the log should equal the address computed from above.
function deploy(bytes memory bytecode, uint256 _salt) public payable {
address addr;
/*
NOTE: How to call create2
create2(v, p, n, s)
create new contract with code at memory p to p + n
and send v wei
and return the new address
where new address = first 20 bytes of keccak256(0xff + address(this) + s + keccak256(mem[€¦(p+n)))
s = big-endian 256-bit value
*/
assembly {
addr :=
create2(
callvalue(), // wei sent with current call
// Actual code starts after skipping the first 32 bytes
add(bytecode, 0x20),
mload(bytecode), // Load the size of code contained in the first 32 bytes
_salt // Salt from function arguments
)
if iszero(extcodesize(addr)) { revert(0, 0) }
}
emit Deployed(addr, _salt);
}
}
contract TestContract {
address public owner;
uint256 public foo;
constructor(address _owner, uint256 _foo) payable {
owner = _owner;
foo = _foo;
}
function getBalance() public view returns (uint256) {
return address(this).balance;
}
}

@ -0,0 +1,8 @@
export const contractCreate2Factory = async (plugin) => {
await plugin.call('fileManager', 'writeFile',
'contracts/libs/create2-factory.sol' ,
// @ts-ignore
(await import('!!raw-loader!./create2-factory.sol')).default)
await plugin.call('fileManager', 'open', 'contracts/libs/create2-factory.sol')
}
Loading…
Cancel
Save