Skip to content
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

Migrate to Foundry Keystore for Deployer Account implementation. #813

Closed
wants to merge 11 commits into from
Closed
3 changes: 2 additions & 1 deletion templates/extensions/foundry/packages/foundry/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
DEPLOYER_PRIVATE_KEY=
ETHERSCAN_API_KEY=
ALCHEMY_API_KEY=
ALCHEMY_API_KEY=
DEPLOYER_PUBLIC_KEY=
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const contents = () =>
`DEPLOYER_PRIVATE_KEY=
ALCHEMY_API_KEY=oKxs-03sij-U_N0iOlrSsZFr29-IqbuF
ETHERSCAN_API_KEY=DNXJA8RX2Q3VZ4URQIWP7Z68CJXQZSC6AW
DEPLOYER_PUBLIC_KEY=
`

export default contents
4 changes: 2 additions & 2 deletions templates/extensions/foundry/packages/foundry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"compile": "forge compile",
"generate": "node script/generateAccount.js",
"flatten": "forge flatten",
"deploy": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --legacy && node script/generateTsAbis.js",
"deploy:verify": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --legacy --verify ; node script/generateTsAbis.js",
"deploy": "node script/deploy.js",
"deploy:verify": "node script/deploy.js --verify",
"verify": "forge build --build-info --build-info-path out/build-info/ && forge script script/VerifyAll.s.sol --ffi --rpc-url ${1:-default_network}",
"lint": "forge fmt --check && prettier --check ./script/**/*.js",
"format": "forge fmt && prettier --write ./script/**/*.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,9 @@ contract DeployScript is ScaffoldETHDeploy {
error InvalidPrivateKey(string);

function run() external {
uint256 deployerPrivateKey = setupLocalhostEnv();
if (deployerPrivateKey == 0) {
revert InvalidPrivateKey(
"You don't have a deployer account. Make sure you have set DEPLOYER_PRIVATE_KEY in .env or use `yarn generate` to generate a new random account"
);
}
vm.startBroadcast(deployerPrivateKey);
YourContract yourContract =
new YourContract(vm.addr(deployerPrivateKey));
address owner = setupAndStartBroadcast();

YourContract yourContract = new YourContract(owner);
console.logString(
string.concat(
"YourContract deployed at: ", vm.toString(address(yourContract))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,23 @@ contract ScaffoldETHDeploy is Script {
string path;
Deployment[] public deployments;

function setupAndStartBroadcast() internal returns (address memory owner) {
if (msg.sender == 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38) {
uint256 deployerPrivateKey = setupLocalhostEnv();
if (deployerPrivateKey == 0) {
revert InvalidPrivateKey(
"You don't have a deployer account. Make sure you have set DEPLOYER_PRIVATE_KEY in .env or use `yarn generate` to generate a new random account"
);
}

owner = vm.addr(deployerPrivateKey);
vm.startBroadcast(deployerPrivateKey);
} else {
owner = msg.sender;
vm.startBroadcast();
}
}

function setupLocalhostEnv()
internal
returns (uint256 localhostPrivateKey)
Expand All @@ -27,8 +44,6 @@ contract ScaffoldETHDeploy is Script {
bytes memory mnemonicBytes = vm.parseJson(json, ".wallet.mnemonic");
string memory mnemonic = abi.decode(mnemonicBytes, (string));
return vm.deriveKey(mnemonic, 0);
} else {
return vm.envUint("DEPLOYER_PRIVATE_KEY");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,15 @@ async function getBalanceForEachNetwork(address) {
}
}
async function main() {
const privateKey = process.env.DEPLOYER_PRIVATE_KEY;
const address = process.env.DEPLOYER_PUBLIC_KEY;

if (!privateKey) {
if (!address) {
console.log(
"🚫️ You don't have a deployer account. Run `yarn generate` first"
);
return;
}

// Get account from private key.
const wallet = new Wallet(privateKey);
const address = wallet.address;
console.log(
await QRCode.toString(address, { type: "terminal", small: true })
);
Expand Down
53 changes: 53 additions & 0 deletions templates/extensions/foundry/packages/foundry/script/deploy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
const { execSync } = require("node:child_process");
require("dotenv").config();

const accountAndSender = process.env.DEPLOYER_PUBLIC_KEY;

async function main() {
let deploymentAddendum = "";

let slicedArgs = process.argv.slice(2);

if (process.argv.length > 2) {
deploymentAddendum = " ";
for (let i = 0; i < slicedArgs.length; i++) {
deploymentAddendum +=
i !== slicedArgs.length - 1 ? slicedArgs[i] + " " : slicedArgs[i];
}
}

let commands = [
"forge build --build-info --build-info-path out/build-info/",

"forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --legacy" +
deploymentAddendum,
"node script/generateTsAbis.js",
];

for (let i = 0; i < slicedArgs.length; i++) {
if (slicedArgs[i] === "--network") {
commands[1] =
"forge script script/Deploy.s.sol --rpc-url " +
slicedArgs[i + 1] +
` --account ${accountAndSender} --sender ${accountAndSender} --broadcast --legacy`;
}

if (slicedArgs[i] === "--verify") {
commands[1] += "--verify";
}
}

console.log("Deploying contracts...");

for (let i = 0; i < commands.length; i++) {
console.log("Executing " + commands[i]);
let output = execSync(`${commands[i]}`);
console.log(output.toString());
console.log("Finished executing " + commands[i]);
}
}

main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const ethers = require("ethers");
const { parse, stringify } = require("envfile");
const fs = require("fs");
const { execSync } = require("node:child_process");

const envFilePath = "./.env";

Expand All @@ -12,20 +13,24 @@ const setNewEnvConfig = (existingEnvConfig = {}) => {
console.log("👛 Generating new Wallet");
const randomWallet = ethers.Wallet.createRandom();

const output = execSync(
`cast wallet import ${randomWallet.address} --private-key ${randomWallet.privateKey}`
);

const newEnvConfig = {
...existingEnvConfig,
DEPLOYER_PRIVATE_KEY: randomWallet.privateKey,
DEPLOYER_PUBLIC_KEY: randomWallet.address,
};

console.log("Output: \n", output.toString());

// Store in .env
fs.writeFileSync(envFilePath, stringify(newEnvConfig));
console.log("📄 Private Key saved to packages/foundry/.env file");
console.log("🪄 Generated wallet address:", randomWallet.address);
console.log("📄 Public key saved to packages/foundry/.env file");
};

async function main() {
if (!fs.existsSync(envFilePath)) {
console.log("entered here");
// No .env file yet.
setNewEnvConfig();
return;
Expand Down