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

Use keystores in Scaffold-Eth #878

Merged
merged 35 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
5a59463
feat : use keystore as account
jrcarlos2000 Jul 1, 2024
47a74b5
fix: add setup on yarn chain
jrcarlos2000 Jul 2, 2024
552001a
fix : remove redundant space
jrcarlos2000 Jul 3, 2024
b84a7cf
fix : warning on deploy helper
jrcarlos2000 Jul 3, 2024
e2d4a58
fix : add scaffold-eth-custom keystore on yarn:generate | import
jrcarlos2000 Jul 3, 2024
5735429
fix : update scripts
jrcarlos2000 Jul 3, 2024
fc459aa
feat : allows for custom nmaes through --name on account:import and a…
jrcarlos2000 Jul 3, 2024
aa91883
feat: list accounts using keystore and cast wallet address
jrcarlos2000 Jul 3, 2024
43cd3da
fix : script for account
jrcarlos2000 Jul 3, 2024
24da39d
fix : simplify logic
jrcarlos2000 Jul 3, 2024
996a761
commit package.json changes on yarn install
technophile-04 Jul 9, 2024
960d592
fix verify script
technophile-04 Jul 9, 2024
0949365
chor : reset anvil account to previous balance
jrcarlos2000 Jul 10, 2024
5381eaa
chor : simple logic on script
jrcarlos2000 Jul 10, 2024
243d1b4
fix : typo
jrcarlos2000 Jul 11, 2024
9930073
fix : ether balance
jrcarlos2000 Jul 11, 2024
4c8c6da
chor : dont revert on anvil call fail
jrcarlos2000 Jul 11, 2024
e5c741a
fix : fund deployer at once
jrcarlos2000 Jul 11, 2024
7e90c13
chore : update scripts
jrcarlos2000 Jul 28, 2024
b6cfa29
chore: update scripts
jrcarlos2000 Jul 28, 2024
01fed55
chore: update scripts
jrcarlos2000 Jul 28, 2024
cf8cbd9
enh : update branch and cleanup
jrcarlos2000 Aug 19, 2024
8195dff
fix: double broadcast
jrcarlos2000 Aug 19, 2024
aee94c4
chor: remove unused file
jrcarlos2000 Aug 19, 2024
7337861
fix: remove unused variable
jrcarlos2000 Aug 19, 2024
c90e80c
enh: improve scripts:
jrcarlos2000 Aug 19, 2024
d30c085
format foundry/package.json on yarn install
technophile-04 Aug 20, 2024
23b283e
foundry keystore makefile (#912)
technophile-04 Aug 26, 2024
b90fab5
update verify-keystore and account script, require password for both …
technophile-04 Aug 27, 2024
19b2a54
use flag while passing address to ListAccoutn
technophile-04 Aug 29, 2024
3e82a45
crawl through args to find address in ListAccount.json
technophile-04 Aug 29, 2024
f0ab123
use process.argsv
technophile-04 Aug 29, 2024
aa5e957
Dont require password on localhost
carletex Aug 30, 2024
cbc3ac9
fix forking command
technophile-04 Sep 4, 2024
d9ffad2
setup anvil wallet for fork too(same as yarn chain)
technophile-04 Sep 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"verify": "yarn workspace @se-2/foundry verify",
"deploy:verify": "yarn workspace @se-2/foundry deploy:verify",
"compile": "yarn workspace @se-2/foundry compile",
"generate": "yarn workspace @se-2/foundry generate",
"account:generate": "yarn workspace @se-2/foundry account:generate",
"account:import": "yarn workspace @se-2/foundry account:import",
"flatten": "yarn workspace @se-2/foundry flatten",
"foundry:format": "yarn workspace @se-2/foundry format",
"foundry:lint": "yarn workspace @se-2/foundry lint",
Expand Down
4 changes: 2 additions & 2 deletions packages/foundry/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
# be auto filled when run `yarn generate`.
# Although `.env` is ignored by git, it's still important that you don't paste your
# actual account private key and use the generated one.
DEPLOYER_PRIVATE_KEY=

# Alchemy rpc URL is used while deploying the contracts to some testnets/mainnets, checkout `foundry.toml` for it's use.
ALCHEMY_API_KEY=oKxs-03sij-U_N0iOlrSsZFr29-IqbuF

# Etherscan API key is used to verify the contract on etherscan.
ETHERSCAN_API_KEY=DNXJA8RX2Q3VZ4URQIWP7Z68CJXQZSC6AW
# Default account for localhost / use "scaffold-eth-custom" if you wish to use a generated account or imported account
ETH_KEYSTORE_ACCOUNT=scaffold-eth-default
12 changes: 7 additions & 5 deletions packages/foundry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
"version": "0.0.1",
"type": "module",
"scripts": {
"account": "node scripts-js/ListAccount.js",
"chain": "anvil --config-out localhost.json",
"verify-keystore": "cast wallet address 2>/dev/null || exit 1",
"account": "node scripts-js/ListAccount.js $(yarn verify-keystore)",
"chain": "shx rm ~/.foundry/keystores/scaffold-eth-default 2>/dev/null; cast wallet import --private-key 0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6 --unsafe-password '' scaffold-eth-default && anvil",
"compile": "forge compile",
"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 scripts-js/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 scripts-js/generateTsAbis.js",
"deploy": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --legacy --ffi && node scripts-js/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 --ffi --verify ; node scripts-js/generateTsAbis.js",
"flatten": "forge flatten",
"fork": "anvil --fork-url ${0:-mainnet} --chain-id 31337 --config-out localhost.json",
"format": "forge fmt && prettier --write ./script/**/*.js",
"generate": "node scripts-js/generateAccount.js",
"account:generate": "shx rm ~/.foundry/keystores/scaffold-eth-custom 2>/dev/null ; cast wallet import ${1:-scaffold-eth-custom} --private-key $(cast wallet new | grep 'Private key:' | awk '{print $3}')",
"account:import": "shx rm ~/.foundry/keystores/scaffold-eth-custom 2>/dev/null ; cast wallet import ${1:-scaffold-eth-custom} --interactive",
"lint": "forge fmt --check && prettier --check ./script/**/*.js",
"postinstall": "shx cp -n .env.example .env",
"test": "forge test",
Expand Down
18 changes: 5 additions & 13 deletions packages/foundry/script/Deploy.s.sol
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "../contracts/YourContract.sol";
import "./DeployHelpers.s.sol";
import { YourContract } from "../contracts/YourContract.sol";
import { ScaffoldETHDeploy, console } from "./DeployHelpers.s.sol";

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 deployer = _startBroadcast();
YourContract yourContract = new YourContract(deployer);
console.logString(
string.concat(
"YourContract deployed at: ", vm.toString(address(yourContract))
)
);

vm.stopBroadcast();
_stopBroadcast();

/**
* This function generates the file containing the contracts Abi definitions.
Expand Down
74 changes: 62 additions & 12 deletions packages/foundry/script/DeployHelpers.s.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "forge-std/Script.sol";
import "forge-std/Vm.sol";
import { Script, console } from "forge-std/Script.sol";
import { Vm } from "forge-std/Vm.sol";

contract ScaffoldETHDeploy is Script {
error InvalidChain();
error FailedAnvilRequest();
error DeployerHasNoBalance();

event AnvilSetBalance(address account, uint256 amount);

struct Deployment {
string name;
Expand All @@ -15,20 +19,42 @@ contract ScaffoldETHDeploy is Script {
string root;
string path;
Deployment[] public deployments;
uint256 constant ANVIL_LAST_PK =
0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6;
address constant ANVIL_LAST_ACCOUNT =
0xa0Ee7A142d267C1f36714E4a8F75612F20a79720;
uint256 constant ANVIL_BASE_BALANCE = 1000 ether;

function _startBroadcast() internal returns (address deployer) {
vm.startBroadcast();
(, deployer,) = vm.readCallers();

if (block.chainid == 31337 && deployer.balance) {
technophile-04 marked this conversation as resolved.
Show resolved Hide resolved
vm.stopBroadcast();

// ------------- FUND DEPLOYER ACCOUNT -------------
vm.startBroadcast(ANVIL_LAST_PK);
(bool success,) = deployer.call{ value: ANVIL_BASE_BALANCE / 2 }("");
if (!success) {
revert DeployerHasNoBalance();
} else {
try this.anvil_setBalance(ANVIL_LAST_ACCOUNT, ANVIL_BASE_BALANCE) {
emit AnvilSetBalance(ANVIL_LAST_ACCOUNT, ANVIL_BASE_BALANCE);
} catch {
revert FailedAnvilRequest();
}
jrcarlos2000 marked this conversation as resolved.
Show resolved Hide resolved
}
vm.stopBroadcast();
// ------------------------------------------------

function setupLocalhostEnv() internal returns (uint256 localhostPrivateKey) {
if (block.chainid == 31337) {
root = vm.projectRoot();
path = string.concat(root, "/localhost.json");
string memory json = vm.readFile(path);
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");
vm.startBroadcast(deployer);
}
}

function _stopBroadcast() internal {
vm.stopBroadcast();
}

function exportDeployments() internal {
// fetch already existing contracts
root = vm.projectRoot();
Expand Down Expand Up @@ -61,6 +87,30 @@ contract ScaffoldETHDeploy is Script {
return getChain(block.chainid);
}

function anvil_setBalance(address addr, uint256 amount) public {
string memory addressString = vm.toString(addr);
string memory amountString = vm.toString(amount);
string memory requestPayload = string.concat(
'{"method":"anvil_setBalance","params":["',
addressString,
'", ',
amountString,
'"],"id":1,"jsonrpc":"2.0"}'
);

string[] memory inputs = new string[](8);
inputs[0] = "curl";
inputs[1] = "-X";
inputs[2] = "POST";
inputs[3] = "http://localhost:8545";
inputs[4] = "-H";
inputs[5] = "Content-Type: application/json";
inputs[6] = "--data";
inputs[7] = requestPayload;

vm.ffi(inputs);
}

technophile-04 marked this conversation as resolved.
Show resolved Hide resolved
function findChainName() public returns (string memory) {
uint256 thisChainId = block.chainid;
string[2][] memory allRpcUrls = vm.rpcUrls();
Expand Down
2 changes: 1 addition & 1 deletion packages/foundry/script/VerifyAll.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ contract VerifyAll is Script {
(address)
);
bytes memory deployedBytecode = abi.decode(
vm.parseJson(content, searchStr(currTransactionIdx, "transaction.data")),
vm.parseJson(content, searchStr(currTransactionIdx, "transaction.input")),
(bytes)
);
bytes memory compiledBytecode = abi.decode(
Expand Down
19 changes: 13 additions & 6 deletions packages/foundry/scripts-js/ListAccount.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,26 @@ async function getBalanceForEachNetwork(address) {
console.error("Error reading foundry.toml:", error);
}
}

function verifyAddressFormat(address) {
try {
ethers.utils.getAddress(address);
return true;
} catch (e) {
return false;
}
}

async function main() {
const privateKey = process.env.DEPLOYER_PRIVATE_KEY;
const address = process.argv[2];

if (!privateKey) {
if (!verifyAddressFormat(address)) {
console.log(
"🚫️ You don't have a deployer account. Run `yarn generate` first"
"🚫️ Invalid account or password, please run `yarn account:generate` or `yarn account:import`"
);
return;
}

// Get account from private key.
const wallet = new Wallet(privateKey);
const address = wallet.address;
console.log(await toString(address, { type: "terminal", small: true }));
console.log("Public address:", address, "\n");

Expand Down
48 changes: 0 additions & 48 deletions packages/foundry/scripts-js/generateAccount.js

This file was deleted.