Skip to content

Commit

Permalink
♻️ PR feedback
Browse files Browse the repository at this point in the history
Signed-off-by: Pascal Marco Caversaccio <[email protected]>
  • Loading branch information
pcaversaccio committed Dec 14, 2023
1 parent e72bbce commit d4b6172
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 21 deletions.
10 changes: 2 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2077,7 +2077,7 @@ interface ICreateX {
We offer two options for deploying [`CreateX`](./src/CreateX.sol) to your desired chain:

1. Deploy it yourself by using one of the pre-signed transactions. Details can be found in the subsequent paragraph.
2. Request a deployment by opening an [issue](https://github.com/pcaversaccio/createx/issues/new?assignees=pcaversaccio&labels=new+deployment+%E2%9E%95&projects=&template=deployment_request.yml&title=%5BNew-Deployment-Request%5D%3A+). You can significantly reduce the time to deployment by sending funds to cover the deployment cost (a reliable amount with a small tip 😏 would be ~0.1 ETH) to the deployer account: `0xeD456e05CaAb11d66C4c797dD6c1D6f9A7F352b5`.
2. Request a deployment by opening an [issue](https://github.com/pcaversaccio/createx/issues/new?assignees=pcaversaccio&labels=new+deployment+%E2%9E%95&projects=&template=deployment_request.yml&title=%5BNew-Deployment-Request%5D%3A+). You can significantly reduce the time to deployment by sending funds to cover the deployment cost (a reliable amount with a small tip 😏 would be ~0.3 ETH) to the deployer account: `0xeD456e05CaAb11d66C4c797dD6c1D6f9A7F352b5`.

> [!CAUTION]
> Prior to using a pre-signed transaction, you **MUST** ensure that the gas metering of the target chain is **EQUIVALENT** to that of Ethereum's EVM version!
Expand All @@ -2086,7 +2086,7 @@ We offer two options for deploying [`CreateX`](./src/CreateX.sol) to your desire
>
> If you are not sure how to validate this, you can either use the [`eth_estimateGas`](https://ethereum.github.io/execution-apis/api-documentation/) JSON-RPC method or simply deploy the [`CreateX`](./src/CreateX.sol) contract from another account and see how much gas is needed for the deployment. Standard EVM chains should require exactly 2,580,902 gas to deploy [`CreateX`](./src/CreateX.sol).
We repeat: PLEASE DO NOT BROADCAST ANY PRE-SIGNED TRANSACTION WITHOUT LOCAL TESTING! Also, before deploying, you MUST send at least 0.1 ETH to the deployer address `0xeD456e05CaAb11d66C4c797dD6c1D6f9A7F352b5`. We offer three pre-signed, pre-[`EIP-155`](https://eips.ethereum.org/EIPS/eip-155) transactions with the same gas price of 100 gwei, but different `gasLimit` levels:
We repeat: PLEASE DO NOT BROADCAST ANY PRE-SIGNED TRANSACTION WITHOUT LOCAL TESTING! Also, before deploying, you MUST send at least 0.3 ETH to the deployer address `0xeD456e05CaAb11d66C4c797dD6c1D6f9A7F352b5`. We offer three pre-signed, pre-[`EIP-155`](https://eips.ethereum.org/EIPS/eip-155) transactions with the same gas price of 100 gwei, but different `gasLimit` levels:

- _Default Case:_ `gasLimit = 3_000_000`; [`signed_serialised_transaction_gaslimit_3000000_.json`](./scripts/presigned-createx-deployment-transactions/signed_serialised_transaction_gaslimit_3000000_.json),
- _Medium Case:_ `gasLimit = 25_000_000`; [`signed_serialised_transaction_gaslimit_25000000_.json`](./scripts/presigned-createx-deployment-transactions/signed_serialised_transaction_gaslimit_25000000_.json),
Expand Down Expand Up @@ -2129,12 +2129,6 @@ curl -L https://foundry.paradigm.xyz | bash
foundryup
```

If you want or need to build [Foundry](https://github.com/foundry-rs/foundry) from source code, you can simply invoke the following command to install the full toolkit:

```console
cargo install --git https://github.com/foundry-rs/foundry --profile local --force --locked forge cast chisel anvil
```

To broadcast a pre-signed transaction, you can invoke:

```console
Expand Down
67 changes: 56 additions & 11 deletions scripts/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ const GREEN = "\x1b[32m";
const RED = "\x1b[31m";

// The `keccak256` hashes of the pre-signed transactions:
// - 0xb6274b80bc7cda162df89894c7748a5cb7ba2eaa6004183c41a1837c3b072f1e (3m gasLimit)
// - 0xc8354e4112f3c78ecfb985f7d1935cb4a8a625cb0b000a4cf0aff327c0708d4c (25m gasLimit)
// - 0x891a2cf734349124752970c4b5666b5b71e9db38c40cb8aab493a11e5c85d6fd (45m gasLimit)
// - 0xb6274b80bc7cda162df89894c7748a5cb7ba2eaa6004183c41a1837c3b072f1e (3m gasLimit),
// - 0xc8354e4112f3c78ecfb985f7d1935cb4a8a625cb0b000a4cf0aff327c0708d4c (25m gasLimit),
// - 0x891a2cf734349124752970c4b5666b5b71e9db38c40cb8aab493a11e5c85d6fd (45m gasLimit).
const signedTxHashes = [
"0xb6274b80bc7cda162df89894c7748a5cb7ba2eaa6004183c41a1837c3b072f1e",
"0xc8354e4112f3c78ecfb985f7d1935cb4a8a625cb0b000a4cf0aff327c0708d4c",
Expand All @@ -27,11 +27,37 @@ function delay(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

// This function deploys the `CreateX` contract using the private key of the deployer
// account: `0xeD456e05CaAb11d66C4c797dD6c1D6f9A7F352b5` (or any other preconfigured
// private key), and the hardcoded contract creation bytecode.
// IMPORTANT: This function must be enabled in the main entry point of the script by
// replacing the current logic at the end of this file with:
// ```ts
// deployUsingPrivateKey().catch((error) => {
// console.error(error);
// process.exitCode = 1;
// });
// ```
// Subsequently, every `npx hardhat run --no-compile --network <NETWORK_NAME> scripts/deploy.ts`
// invocation will use the `deployUsingPrivateKey` function.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async function deployNormal() {
async function deployUsingPrivateKey() {
// Ensure the correct contract creation bytecode is used
if (
hre.ethers.keccak256(initCode) !=
// This following hash can be retrieved via Solidity and using the compiler settings in `./verification/CreateX.json`:
// ```sol
// // SPDX-License-Identifier: AGPL-3.0-only
// pragma solidity 0.8.23;
//
// import {CreateX} from "./src/CreateX.sol";
//
// contract CreationCodeHashCreateX {
// function creationCodeHashCreateX() external pure returns (bytes32) {
// return keccak256(type(CreateX).creationCode);
// }
// }
// ```
"0x12ec861579b63a3ab9db3b5a23c57d56402ad3061475b088f17054e2f2daf22f"
) {
throw new Error("Incorrect contract creation bytecode.");
Expand All @@ -43,16 +69,30 @@ async function deployNormal() {
await createx.waitForDeployment();
const createxAddress = await createx.getAddress();

console.log("CreateX deployed to:", createxAddress);
console.log("CreateX deployed to: " + `${GREEN}${createxAddress}${RESET}\n`);

if (createxAddress != "0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed") {
console.log(
`${RED}The CreateX address does not correspond to the expected address 0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed!${RESET}\n`,
);
}

console.log(
"Waiting 30 seconds before beginning the contract verification to allow the block explorer to index the contract...\n",
);
await delay(30000); // Wait for 30 seconds before verifying `CreateX`

await hre.run("verify:verify", {
address: createxAddress,
});
}

async function deployRaw() {
// This function deploys the `CreateX` contract using a pre-signed transaction.
// The preconfigured pre-signed transaction is the default version using 3 million gas.
// IMPORTANT: This function is enabled in the main entry point of the script! Thus, every
// `npx hardhat run --no-compile --network <NETWORK_NAME> scripts/deploy.ts` invocation
// will use the `deployUsingPrivateKey` function.
async function deployUsingPresignedTransaction() {
// Ensure a correct pre-signed transaction is used
if (!signedTxHashes.includes(hre.ethers.keccak256(signedTx))) {
throw new Error("Incorrect pre-signed transaction.");
Expand All @@ -61,10 +101,12 @@ async function deployRaw() {
try {
// Send the transaction
const tx = await hre.ethers.provider.broadcastTransaction(signedTx);
console.log("Transaction hash: " + `${GREEN}${tx.hash}${RESET}`);
console.log("Transaction hash: " + `${GREEN}${tx.hash}${RESET}\n`);
const transactionReceipt = await tx.wait();
const createxAddress = transactionReceipt?.contractAddress;
console.log("Contract address: " + `${GREEN}${createxAddress}${RESET}`);
console.log(
"CreateX deployed to: " + `${GREEN}${createxAddress}${RESET}\n`,
);

// Save the transaction receipt in a JSON file
if (!fs.existsSync(dir)) {
Expand All @@ -76,10 +118,13 @@ async function deployRaw() {
fs.writeFileSync(saveDir, JSON.stringify(transactionReceipt));

console.log(
`\n${GREEN}Transaction has been successfully broadcasted!${RESET}`,
`${GREEN}Transaction has been successfully broadcasted!${RESET}\n`,
);
console.log(`Transaction details written to: ${GREEN}${saveDir}${RESET}\n`);

console.log(
"Waiting 30 seconds before beginning the contract verification to allow the block explorer to index the contract...\n",
);
await delay(30000); // Wait for 30 seconds before verifying `CreateX`

await hre.run("verify:verify", {
Expand All @@ -93,12 +138,12 @@ async function deployRaw() {
const saveDir = path.normalize(path.join(dir, "transaction_error.json"));
fs.writeFileSync(saveDir, JSON.stringify(err));

console.log(`\n${RED}Transaction broadcasting failed!${RESET}`);
console.log(`${RED}Transaction broadcasting failed!${RESET}\n`);
console.log(`Error details written to: ${RED}${saveDir}${RESET}\n`);
}
}

deployRaw().catch((error) => {
deployUsingPresignedTransaction().catch((error) => {
console.error(error);
process.exitCode = 1;
});
17 changes: 15 additions & 2 deletions scripts/presign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ export async function presign() {
// Ensure the correct contract creation bytecode is used
if (
hre.ethers.keccak256(initCode) !=
// This following hash can be retrieved via Solidity and using the compiler settings in `./verification/CreateX.json`:
// ```sol
// // SPDX-License-Identifier: AGPL-3.0-only
// pragma solidity 0.8.23;
//
// import {CreateX} from "./src/CreateX.sol";
//
// contract CreationCodeHashCreateX {
// function creationCodeHashCreateX() external pure returns (bytes32) {
// return keccak256(type(CreateX).creationCode);
// }
// }
// ```
"0x12ec861579b63a3ab9db3b5a23c57d56402ad3061475b088f17054e2f2daf22f"
) {
throw new Error("Incorrect contract creation bytecode.");
Expand Down Expand Up @@ -72,7 +85,7 @@ export async function presign() {
);
fs.writeFileSync(saveDir, JSON.stringify(signedTx.serialized));

console.log(`${GREEN}Signing attempt has been successful!${RESET}`);
console.log(`${GREEN}Signing attempt has been successful!${RESET}\n`);
console.log(
`Serialised signed transaction written to: ${GREEN}${saveDir}${RESET}\n`,
);
Expand Down Expand Up @@ -101,7 +114,7 @@ export async function presign() {
);
fs.writeFileSync(saveDir, JSON.stringify(err));

console.log(`${RED}Signing attempt failed!${RESET}`);
console.log(`${RED}Signing attempt failed!${RESET}\n`);
console.log(`Error details written to: ${RED}${saveDir}${RESET}\n`);
}
}
Expand Down

0 comments on commit d4b6172

Please sign in to comment.