Skip to content

Commit

Permalink
Suggestions for PR #119 (#122)
Browse files Browse the repository at this point in the history
* refactor to make defaults based on the chainId and support deployment with ledger

* add note about the lack of support for hardware wallets

* run forge fmt
  • Loading branch information
nategraf authored Jun 25, 2024
1 parent 6656f6b commit 5fd5f3c
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 23 deletions.
16 changes: 12 additions & 4 deletions deployment-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ You can deploy your contracts on the `Sepolia` testnet and run an end-to-end tes
3. Deploy your contract by running:

```bash
CONFIG_PROFILE=sepolia forge script script/Deploy.s.sol --rpc-url https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY:?} --broadcast
forge script script/Deploy.s.sol --rpc-url https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY:?} --broadcast
```

This command uses the `sepolia` profile defined in the [config][config] file, and should output something similar to:
Expand Down Expand Up @@ -179,7 +179,7 @@ You can deploy your contract on Ethereum Mainnet as follows:
export BONSAI_API_KEY="YOUR_API_KEY" # see form linked in the previous section
export BONSAI_API_URL="BONSAI_API_URL" # provided with your api key
export ALCHEMY_API_KEY="YOUR_ALCHEMY_API_KEY" # the API_KEY provided with an alchemy account
export ETH_WALLET_PRIVATE_KEY="YOUR_WALLET_PRIVATE_KEY" # the private hex-encoded key of your Mainnet wallet
export ETH_WALLET_ADDRESS="YOUR_WALLET_ADDRESS" # the account address you want to use for deployment
```

2. Build your project:
Expand All @@ -190,8 +190,11 @@ You can deploy your contract on Ethereum Mainnet as follows:

3. Deploy your contract by running:

You'll need to pass options to forge script to connect to your deployer wallet. See the [Foundry documentation][forge-script-wallet-docs].
The example command below configures Forge to use a Ledger hardware wallet.
```bash
CONFIG_PROFILE=mainnet forge script script/MainnetDeploy.s.sol --rpc-url https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY:?} --broadcast
forge script script/Deploy.s.sol --rpc-url https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY:?} --broadcast --ledger
```
This command uses the `mainnet` profile defined in the [config][config] file, and should output something similar to:
Expand Down Expand Up @@ -228,6 +231,10 @@ You can deploy your contract on Ethereum Mainnet as follows:
2. Publish a new state
> [!WARNING]
> Currently only a local wallet, provided by the `ETH_WALLET_PRIVATE_KEY` env var is implemented in the example publisher app.
> Please see https://github.com/risc0/risc0-foundry-template/issues/121 for more details.
```bash
cargo run --bin publisher -- \
--chain-id=1 \
Expand All @@ -243,11 +250,12 @@ You can deploy your contract on Ethereum Mainnet as follows:
```
[Deploy to Ethereum Mainnet]: #deploy-your-project-on-ethereum-mainnet
[Deploy to a testnet]: #deploy-your-project-on-a-testnet
[Deploy your project to a local network]: #deploy-your-project-on-a-local-network
[RISC Zero]: https://www.risczero.com/
[Docker]: https://docs.docker.com/engine/install/
[contracts]: ./contracts/
[jq]: https://jqlang.github.io/jq/
[methods]: ./methods/
[tested]: ./README.md#run-the-tests
[config]: ./script/config.toml
[forge-script-wallet-docs]: https://book.getfoundry.sh/reference/forge/forge-script#wallet-options---raw
68 changes: 52 additions & 16 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,39 +26,75 @@ import {EvenNumber} from "../contracts/EvenNumber.sol";

/// @notice Deployment script for the RISC Zero starter project.
/// @dev Use the following environment variable to control the deployment:
/// * ETH_WALLET_PRIVATE_KEY private key of the wallet to be used for deployment.
/// * Set one of these two environment variables to control the deployment wallet:
/// * ETH_WALLET_PRIVATE_KEY private key of the wallet account.
/// * ETH_WALLET_ADDRESS address of the wallet account.
///
/// See the Foundry documentation for more information about Solidity scripts,
/// including information about wallet options.
///
/// See the Foundry documentation for more information about Solidity scripts.
/// https://book.getfoundry.sh/tutorials/solidity-scripting
/// https://book.getfoundry.sh/reference/forge/forge-script
contract EvenNumberDeploy is Script {
using stdToml for string;

// Path to deployment config file, relative to the project root.
string constant CONFIG_FILE = "script/config.toml";
string constant DEFAULT_PROFILE = "DEFAULT_PROFILE";

IRiscZeroVerifier verifier;

function run() external {
// read and log the chainID
// Read and log the chainID
uint256 chainId = block.chainid;
console2.log("You are deploying on ChainID %d", chainId);

uint256 deployerKey = uint256(vm.envBytes32("ETH_WALLET_PRIVATE_KEY"));

vm.startBroadcast(deployerKey);
// Read the config profile from the environment variable, or use the default for the chainId.
// Default is the first profile with a matching chainId field.
string memory config = vm.readFile(string.concat(vm.projectRoot(), "/", CONFIG_FILE));
string memory configProfile = vm.envOr("CONFIG_PROFILE", string(""));
if (bytes(configProfile).length == 0) {
string[] memory profileKeys = vm.parseTomlKeys(config, ".profile");
for (uint256 i = 0; i < profileKeys.length; i++) {
if (stdToml.readUint(config, string.concat(".profile.", profileKeys[i], ".chainId")) == chainId) {
configProfile = profileKeys[i];
break;
}
}
}

string memory configProfile = vm.envOr("CONFIG_PROFILE", DEFAULT_PROFILE);
if (keccak256(abi.encodePacked(configProfile)) != keccak256(abi.encodePacked(DEFAULT_PROFILE))) {
string memory config = vm.readFile(CONFIG_FILE);
string memory profile = string.concat(".profile.", configProfile);
if (bytes(configProfile).length != 0) {
console2.log("Deploying using config profile:", configProfile);
address riscZeroVerifierAddress = config.readAddress(string.concat(profile, ".riscZeroVerifierAddress"));
string memory configProfileKey = string.concat(".profile.", configProfile);
address riscZeroVerifierAddress =
stdToml.readAddress(config, string.concat(configProfileKey, ".riscZeroVerifierAddress"));
// If set, use the predeployed verifier address found in the config.
verifier = IRiscZeroVerifier(riscZeroVerifierAddress);
console2.log("Using IRiscZeroVerifier contract deployed at", riscZeroVerifierAddress);
}

// Determine the wallet to send transactions from.
uint256 deployerKey = uint256(vm.envOr("ETH_WALLET_PRIVATE_KEY", bytes32(0)));
address deployerAddr = address(0);
if (deployerKey != 0) {
// Check for conflicts in how the two environment variables are set.
address envAddr = vm.envOr("ETH_WALLET_ADDRESS", address(0));
require(
envAddr == address(0) || envAddr == vm.addr(deployerKey),
"conflicting settings from ETH_WALLET_PRIVATE_KEY and ETH_WALLET_ADDRESS"
);

vm.startBroadcast(deployerKey);
} else {
deployerAddr = vm.envAddress("ETH_WALLET_ADDRESS");
vm.startBroadcast(deployerAddr);
}

// Deploy the verifier, if not already deployed.
if (address(verifier) == address(0)) {
verifier = new RiscZeroGroth16Verifier(ControlID.CONTROL_ROOT, ControlID.BN254_CONTROL_ID);
console2.log("Deployed IRiscZeroVerifier to", address(verifier));
console2.log("Deployed RiscZeroGroth16Verifier to", address(verifier));
} else {
console2.log("Using IRiscZeroVerifier contract deployed at", address(verifier));
}

// Deploy the application contract.
EvenNumber evenNumber = new EvenNumber(verifier);
console2.log("Deployed EvenNumber to", address(evenNumber));

Expand Down
9 changes: 6 additions & 3 deletions script/config.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
[profile.mainnet]
# RISC Zero Verifier contract deployed on mainnet (see https://dev.risczero.com/api/blockchain-integration/contracts/verifier#deployed-verifiers)
chainId = 1
riscZeroVerifierAddress = "0x8EaB2D97Dfce405A1692a21b3ff3A172d593D319"

[profile.sepolia]
# RISC Zero Verifier contract deployed on sepolia (see https://dev.risczero.com/api/blockchain-integration/contracts/verifier#deployed-verifiers)
chainId = 11155111
riscZeroVerifierAddress = "0x925d8331ddc0a1F0d96E68CF073DFE1d92b69187"

[profile.custom]
# You can define a pre-deployed IRiscZeroVerifier contract here
# riscZeroVerifierAddress =
# You can add additional profiles here
# [profile.custom]
# chainId = 11155111
# riscZeroVerifierAddress =

0 comments on commit 5fd5f3c

Please sign in to comment.