From 3b0f25653b1ec68d5061a582f4f70a144efd06fe Mon Sep 17 00:00:00 2001 From: Alysia Huggins Date: Tue, 9 Sep 2025 12:39:39 -0400 Subject: [PATCH 1/4] Port EspressoSystems/timeboost#482 into timeboost-contracts --- README.md | 142 ++++++++++++++++++++++++++++++++++ env.example | 31 ++++++++ script/DeployKeyManager.s.sol | 41 ++++++++++ script/README.md | 76 ++++++++++++++++++ script/deploy.sh | 78 +++++++++++++++++++ src/KeyManager.sol | 9 ++- 6 files changed, 376 insertions(+), 1 deletion(-) create mode 100644 README.md create mode 100644 env.example create mode 100644 script/DeployKeyManager.s.sol create mode 100644 script/README.md create mode 100755 script/deploy.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..e6e5999 --- /dev/null +++ b/README.md @@ -0,0 +1,142 @@ +# Timeboost Smart Contracts + +This directory contains the smart contracts that power the decentralized Timeboost protocol. These contracts run on Ethereum-compatible blockchains and provide the foundation for secure, decentralized time synchronization. + +## Background +Smart contracts are executable code, deployed on blockchains that +can be read from / written to anyone with an internet connection. +Transaction data and smart contract storage is public and can be +accessed in blockchain explorers. In decentralized Timeboost, +smart contracts are used to allow anyone to interact with various +of the protocol. This readme is directed at developers who are +contributing to or making use of this decentralized timeboost +implementation. + +## What Are These Contracts For? + +Timeboost needs a way to coordinate cryptographic keys and committee members across a decentralized network. These smart contracts provide: + +- **Key Management**: Store and manage public keys for the protocol +- **Committee Coordination**: Track which nodes are part of the consensus committee +- **Access Control**: Ensure only authorized parties can update critical protocol parameters +- **Transparency**: All changes are recorded on-chain for public verification + +These contracts act as the "coordination layer" that allows the Timeboost network to operate without a central authority. + +## Handling Upgradeability + +### The Upgrade Problem +Once deployed, smart contracts can't be changed. To solve this, we use a proxy solution that performs functionally as upgradeable contracts. + +### The Proxy Solution +We use a "proxy pattern" that works like this: + +1. **Users always interact with the proxy** - This address never changes +2. **The proxy points to an implementation** - This can be updated +3. **When you upgrade** - Just point the proxy to a new implementation +4. **All data stays safe** - Storage is preserved across upgrades + +Think of it like changing the engine in a car - the car (proxy) stays the same, but you can swap out the engine (implementation) for a better one. + +### Our Architecture +``` +User → Proxy Contract → Implementation Contract + ↓ + Storage (persistent) +``` + +## The Contracts + +### KeyManager - The Main Contract + +**What it stores:** +- **Encryption keys** - The cryptographic keys used by the protocol +- **Committee members** - Who's currently in the consensus committee +- **Manager address** - Who can update the contract + +**What it does:** +- **Sets committees** - Updates which nodes are part of the network +- **Manages keys** - Stores the threshold encryption key +- **Controls access** - Only the manager can make changes +- **Logs everything** - All changes are recorded as events + +**Key functions:** +- `setNextCommittee()` - Add a new committee with future members +- `currentCommitteeId()` - Find which committee is active right now +- `getCommitteeById()` - Get details about a specific committee +- `setThresholdEncryptionKey()` - Set the encryption key for the protocol + +### ERC1967Proxy - The Upgrade Mechanism +This is the "shell" that makes upgrades possible: + +- **Never changes** - Users always interact with this address +- **Delegates calls** - Forwards requests to the current implementation +- **Preserves data** - All storage survives upgrades +- **SecOps Precautions** - it's important to call the initialize methods during deploys and upgrades so that those transactions aren't front-run + +## Getting Started + +### Prerequisites +- **Foundry** - For building and testing contracts + +### Building the Contracts +```bash +# Build all contracts +just build-contracts + +# Or use forge directly +forge build +``` + +### Testing +```bash +# Run all tests +just test-contracts + +# Run with detailed output +forge test -vvv + +# Run specific test +forge test --match-test test_setThresholdEncryptionKey +``` + +### Integration Testing +For testing contract interactions from Rust code, see the [timeboost-contract README](../timeboost-contract/README.md). + +## Deployment +You can deploy a local anvil network (as done in the test), a fork of a real network, a testnet network (e.g. Ethereum Sepolia) or a mainnet (e.g. Ethereum Mainnet). + +### Quick Start (Local Testing) +```bash +# 1. Start a local blockchain +anvil + +# 2. Deploy the contracts +cp env.example .env +# Edit .env with your values +./script/deploy.sh +``` + +**📋 For detailed deployment instructions, see the [deployment script README](script/README.md)** + +## Security + +### Current Status +- **ERC1967Proxy** - Audited by OpenZeppelin, widely used +- **KeyManager** - Not yet audited (audit planned) + +### Security Considerations +- **Manager privileges** - The manager can update committees and keys +- **Upgrade authority** - Only the contract owner can upgrade +- **Committee validation** - Contracts validate committee transitions +- **Event logging** - All changes are logged onchain for transparency + +### Best Practices +- **Use multisig wallets** - Don't use single-key wallets for manager/owner +- **Test thoroughly** - Always test on testnets first +- **Monitor events** - Watch for unexpected contract changes +- **Keep keys secure** - Store private keys and mnemonics safely + +## Getting Help +- Check the [deployment script README](script/README.md) for deployment issues +- Review the [timeboost-contract README](../timeboost-contract/README.md) for integration questions \ No newline at end of file diff --git a/env.example b/env.example new file mode 100644 index 0000000..62c1a98 --- /dev/null +++ b/env.example @@ -0,0 +1,31 @@ +# Timeboost Contract Deployment Configuration +# Copy this file to .env and fill in your actual values +# DO NOT commit .env files to version control + +# Manager address for the KeyManager contract +# This should be the address that will manage the KeyManager contract +# Typically a multisig wallet or governance contract address +# Example: MANAGER_ADDRESS=0x1234567890123456789012345678901234567890 +MANAGER_ADDRESS= + +# RPC endpoint for the target network +# For local development: http://localhost:8545 (Anvil) +# For testnets: https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY +# For mainnet: https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY +RPC_URL= + +# Deployment Account Mnemonic and account index +# Your 12 or 24 word BIP39 mnemonic phrase for the deployment account +# This account must have enough ETH to pay for gas fees +# Example: MNEMONIC="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" +MNEMONIC= + +# Which account to use from the mnemonic (0 = first account, 1 = second, etc.) +# Example: ACCOUNT_INDEX=0 +ACCOUNT_INDEX= + +# Etherscan API key for contract verification (optional) +# Get one at: https://etherscan.io/apis +# This is used to verify your contracts on Etherscan after deployment +# Example: ETHERSCAN_API_KEY=YourApiKeyToken +ETHERSCAN_API_KEY= diff --git a/script/DeployKeyManager.s.sol b/script/DeployKeyManager.s.sol new file mode 100644 index 0000000..f4bf4c1 --- /dev/null +++ b/script/DeployKeyManager.s.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Script, console} from "forge-std/Script.sol"; +import {KeyManager} from "../src/KeyManager.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; + +/// @title DeployKeyManager +/// @notice Simple script to deploy KeyManager implementation and proxy, then initialize +contract DeployKeyManager is Script { + function run() external returns (address, address) { + // Get the manager address from environment variable or use sender as fallback + address manager = vm.envOr("MANAGER_ADDRESS", msg.sender); + + vm.startBroadcast(); + + // Deploy the KeyManager implementation + KeyManager implementation = new KeyManager(); + console.log("KeyManager implementation deployed at:", address(implementation)); + + // Prepare initialization data + bytes memory initData = abi.encodeWithSelector(KeyManager.initialize.selector, manager); + + // Deploy the proxy and initialize it + ERC1967Proxy proxy = new ERC1967Proxy(address(implementation), initData); + console.log("ERC1967Proxy deployed at:", address(proxy)); + + // Verify initialization + KeyManager proxyContract = KeyManager(address(proxy)); + require(proxyContract.manager() == manager, "Manager not set correctly"); + + console.log("Deployment successful!"); + console.log("Implementation:", address(implementation)); + console.log("Proxy:", address(proxy)); + console.log("Manager:", manager); + + vm.stopBroadcast(); + + return (address(proxy), address(implementation)); + } +} diff --git a/script/README.md b/script/README.md new file mode 100644 index 0000000..2b4b52b --- /dev/null +++ b/script/README.md @@ -0,0 +1,76 @@ +# Deploy KeyManager Contract + +This script deploys the KeyManager contract to any Ethereum network. + +## Quick Start + +1. **Set up your environment:** + ```bash + cp env.example .env + # Edit .env with your values + ``` + +2. **Start a local blockchain (if testing locally):** + ```bash + anvil + ``` + +3. **Deploy:** + ```bash + ./script/deploy.sh + ``` + +That's it! The script will deploy your contract and show you the addresses. + +## What You Need + +- **Manager Address**: Who will manage the contract (usually a multisig wallet) +- **RPC URL**: Where to deploy (localhost for testing, or a real network) +- **Mnemonic**: Your wallet phrase (optional for local testing) + +## How It Works + +The script deploys two contracts: +1. **KeyManager** - The actual contract with your business logic +2. **Proxy** - Points to the KeyManager, so you can upgrade it later + +The proxy gets initialized with your manager address, and that's it! + +## Configuration + +All settings go in your `.env` file: + +```bash +# Required: Who manages the contract +MANAGER_ADDRESS=0x1234567890123456789012345678901234567890 + +# Optional: Where to deploy (defaults to localhost) +RPC_URL=http://localhost:8545 + +# Optional: Your wallet phrase (defaults to Anvil's test account) +MNEMONIC="your twelve word mnemonic phrase here" +ACCOUNT_INDEX=0 +``` + +## How it works +The deployment script: +1. **Deploys** the KeyManager implementation contract +2. **Creates** an ERC1967 proxy pointing to the implementation +3. **Initializes** the proxy with your manager address +4. **Verifies** the deployment was successful +5. **Returns** both proxy and implementation addresses + + +## Troubleshooting + +**"Manager address not set"** +- Make sure you have `MANAGER_ADDRESS=0x...` in your `.env` file + +**"Deployment failed"** +- Check your RPC URL works +- Make sure your wallet has enough ETH for gas +- Verify your mnemonic is correct + +**Need help?** +- Make sure Foundry is installed: `forge --version` +- Check your `.env` file has all required values diff --git a/script/deploy.sh b/script/deploy.sh new file mode 100755 index 0000000..43699d3 --- /dev/null +++ b/script/deploy.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# Simple deployment script for KeyManager contract + +set -e + +# Load environment variables if .env file exists +if [ -f ".env" ]; then + echo "Loading environment from .env file..." + # Use source to properly handle quoted values + set -a + source .env + set +a +fi + +# Check if required environment variables are set +if [ -z "$MANAGER_ADDRESS" ]; then + echo "Error: MANAGER_ADDRESS is required" + echo "Please set MANAGER_ADDRESS in your .env file" + echo "" + echo "Example .env file:" + echo "MANAGER_ADDRESS=0x1234567890123456789012345678901234567890" + echo "RPC_URL=http://localhost:8545" + echo "MNEMONIC=\"your twelve word mnemonic phrase here\"" + echo "ACCOUNT_INDEX=0" + exit 1 +fi + +# Use environment variables with defaults +RPC_URL=${RPC_URL:-"http://localhost:8545"} +ACCOUNT_INDEX=${ACCOUNT_INDEX:-0} +MNEMONIC=${MNEMONIC:-"test test test test test test test test test test test junk"} + +echo "Deploying KeyManager contract..." +echo "Manager address: $MANAGER_ADDRESS" +echo "RPC URL: $RPC_URL" +echo "Account index: $ACCOUNT_INDEX" +echo + +# Set environment variable for the script +export MANAGER_ADDRESS=$MANAGER_ADDRESS + +# Build forge command +FORGE_CMD="forge script script/DeployKeyManager.s.sol:DeployKeyManager --rpc-url $RPC_URL --broadcast --mnemonics \"$MNEMONIC\" --mnemonic-indexes $ACCOUNT_INDEX" + + +echo "Executing Forge command" +echo + +# Deploy the contract and capture output +DEPLOYMENT_OUTPUT=$(eval $FORGE_CMD 2>&1) +DEPLOYMENT_EXIT_CODE=$? + +if [ $? -eq 124 ]; then + echo "Forge command timed out - likely invalid flags or connection issue" + exit 1 +fi + +echo "Forge command completed with exit code: $DEPLOYMENT_EXIT_CODE" + +# Display the deployment output +echo "$DEPLOYMENT_OUTPUT" + +# Check if deployment was successful +if [ $DEPLOYMENT_EXIT_CODE -eq 0 ]; then + echo + echo "Deployment complete!" + echo "Check the output above for contract addresses." + + # Try to extract addresses from the output (optional enhancement) + echo + echo "Extracted contract addresses:" + echo "$DEPLOYMENT_OUTPUT" | grep -E "(KeyManager implementation deployed at:|ERC1967Proxy deployed at:)" || echo "Could not extract addresses from output" +else + echo + echo "Deployment failed with exit code $DEPLOYMENT_EXIT_CODE" + exit $DEPLOYMENT_EXIT_CODE +fi diff --git a/src/KeyManager.sol b/src/KeyManager.sol index ca2f506..a8e18b6 100644 --- a/src/KeyManager.sol +++ b/src/KeyManager.sol @@ -5,6 +5,13 @@ import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Own import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +/// @title KeyManager +/// @notice The KeyManager contract is responsible for managing the keys for the Timeboost protocol. +/// @notice It is used to set the threshold encryption key, create committees, and prune old committees. +/// @notice It is also used to get the current committee id and the committee by id. +/// @notice Only the admin can set the manager. +/// @notice The manager can set the threshold encryption key, create committees, and prune old committees. +/// @notice The contract is upgradeable and can be upgraded by the admin. contract KeyManager is Initializable, OwnableUpgradeable, UUPSUpgradeable { struct CommitteeMember { /// @notice public key for consensus votes, also used as the primary label for a node @@ -106,7 +113,7 @@ contract KeyManager is Initializable, OwnableUpgradeable, UUPSUpgradeable { * @notice This function is used to initialize the contract. * @dev Reverts if the manager is the zero address. * @dev Assumes that the manager is valid. - * @dev This must be called once when the contract is first deployed. + * @dev This must be called once when the contract is first deployed, in the same transaction as the proxy deployment. * @param initialManager The initial manager. */ function initialize(address initialManager) external initializer { From d4326d6557720d181e4d1c3f658e986da289ca82 Mon Sep 17 00:00:00 2001 From: Alysia Huggins Date: Tue, 9 Sep 2025 12:48:07 -0400 Subject: [PATCH 2/4] remove redudunct readme and linked to the correct readme location for the timeboost repo --- README.md | 83 +++++++++++++++++++++++++++++++++++++++++------- script/README.md | 76 -------------------------------------------- 2 files changed, 72 insertions(+), 87 deletions(-) delete mode 100644 script/README.md diff --git a/README.md b/README.md index e6e5999..407987e 100644 --- a/README.md +++ b/README.md @@ -104,20 +104,81 @@ forge test --match-test test_setThresholdEncryptionKey For testing contract interactions from Rust code, see the [timeboost-contract README](../timeboost-contract/README.md). ## Deployment -You can deploy a local anvil network (as done in the test), a fork of a real network, a testnet network (e.g. Ethereum Sepolia) or a mainnet (e.g. Ethereum Mainnet). -### Quick Start (Local Testing) +You can deploy to a local anvil network (as done in the test), a fork of a real network, a testnet network (e.g. Ethereum Sepolia) or a mainnet (e.g. Ethereum Mainnet). + +### Quick Start + +1. **Set up your environment:** + ```bash + cp env.example .env + # Edit .env with your values + ``` + +2. **Start a local blockchain (if testing locally):** + ```bash + anvil + ``` + +3. **Deploy:** + ```bash + ./script/deploy.sh + ``` + +That's it! The script will deploy your contract and show you the addresses. + +### What You Need + +- **Manager Address**: Who will manage the contract (usually a multisig wallet) +- **RPC URL**: Where to deploy (localhost for testing, or a real network) +- **Mnemonic**: Your wallet phrase (optional for local testing) + +### How It Works + +The script deploys two contracts: +1. **KeyManager** - The actual contract with your business logic +2. **Proxy** - Points to the KeyManager, so you can upgrade it later + +The proxy gets initialized with your manager address, and that's it! + +### Configuration + +All settings go in your `.env` file: + ```bash -# 1. Start a local blockchain -anvil +# Required: Who manages the contract +MANAGER_ADDRESS=0x1234567890123456789012345678901234567890 -# 2. Deploy the contracts -cp env.example .env -# Edit .env with your values -./script/deploy.sh +# Optional: Where to deploy (defaults to localhost) +RPC_URL=http://localhost:8545 + +# Optional: Your wallet phrase (defaults to Anvil's test account) +MNEMONIC="your twelve word mnemonic phrase here" +ACCOUNT_INDEX=0 ``` -**📋 For detailed deployment instructions, see the [deployment script README](script/README.md)** +### Deployment Process + +The deployment script: +1. **Deploys** the KeyManager implementation contract +2. **Creates** an ERC1967 proxy pointing to the implementation +3. **Initializes** the proxy with your manager address +4. **Verifies** the deployment was successful +5. **Returns** both proxy and implementation addresses + +### Troubleshooting + +**"Manager address not set"** +- Make sure you have `MANAGER_ADDRESS=0x...` in your `.env` file + +**"Deployment failed"** +- Check your RPC URL works +- Make sure your wallet has enough ETH for gas +- Verify your mnemonic is correct + +**Need help?** +- Make sure Foundry is installed: `forge --version` +- Check your `.env` file has all required values ## Security @@ -138,5 +199,5 @@ cp env.example .env - **Keep keys secure** - Store private keys and mnemonics safely ## Getting Help -- Check the [deployment script README](script/README.md) for deployment issues -- Review the [timeboost-contract README](../timeboost-contract/README.md) for integration questions \ No newline at end of file +- Review the [timeboost-contract README](https://github.com/EspressoSystems/timeboost/tree/main/timeboost-contract/README.md) in the rust repo for integration questions +- Check the troubleshooting section above for deployment issues \ No newline at end of file diff --git a/script/README.md b/script/README.md deleted file mode 100644 index 2b4b52b..0000000 --- a/script/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# Deploy KeyManager Contract - -This script deploys the KeyManager contract to any Ethereum network. - -## Quick Start - -1. **Set up your environment:** - ```bash - cp env.example .env - # Edit .env with your values - ``` - -2. **Start a local blockchain (if testing locally):** - ```bash - anvil - ``` - -3. **Deploy:** - ```bash - ./script/deploy.sh - ``` - -That's it! The script will deploy your contract and show you the addresses. - -## What You Need - -- **Manager Address**: Who will manage the contract (usually a multisig wallet) -- **RPC URL**: Where to deploy (localhost for testing, or a real network) -- **Mnemonic**: Your wallet phrase (optional for local testing) - -## How It Works - -The script deploys two contracts: -1. **KeyManager** - The actual contract with your business logic -2. **Proxy** - Points to the KeyManager, so you can upgrade it later - -The proxy gets initialized with your manager address, and that's it! - -## Configuration - -All settings go in your `.env` file: - -```bash -# Required: Who manages the contract -MANAGER_ADDRESS=0x1234567890123456789012345678901234567890 - -# Optional: Where to deploy (defaults to localhost) -RPC_URL=http://localhost:8545 - -# Optional: Your wallet phrase (defaults to Anvil's test account) -MNEMONIC="your twelve word mnemonic phrase here" -ACCOUNT_INDEX=0 -``` - -## How it works -The deployment script: -1. **Deploys** the KeyManager implementation contract -2. **Creates** an ERC1967 proxy pointing to the implementation -3. **Initializes** the proxy with your manager address -4. **Verifies** the deployment was successful -5. **Returns** both proxy and implementation addresses - - -## Troubleshooting - -**"Manager address not set"** -- Make sure you have `MANAGER_ADDRESS=0x...` in your `.env` file - -**"Deployment failed"** -- Check your RPC URL works -- Make sure your wallet has enough ETH for gas -- Verify your mnemonic is correct - -**Need help?** -- Make sure Foundry is installed: `forge --version` -- Check your `.env` file has all required values From a0d0cf5207654c3e749281db23c84ba72f75301a Mon Sep 17 00:00:00 2001 From: Alysia Huggins Date: Tue, 9 Sep 2025 13:04:32 -0400 Subject: [PATCH 3/4] remove lock files in gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 85198aa..7cd957e 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ docs/ # Dotenv file .env + +# Lock files +foundry.lock From 67e16632e0e01b65bcaf40643d1acd72203f1644 Mon Sep 17 00:00:00 2001 From: Alysia Huggins Date: Tue, 9 Sep 2025 13:08:34 -0400 Subject: [PATCH 4/4] improves readme --- README.md | 79 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 407987e..7c966d4 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,24 @@ This directory contains the smart contracts that power the decentralized Timeboost protocol. These contracts run on Ethereum-compatible blockchains and provide the foundation for secure, decentralized time synchronization. +## Table of Contents + +- [Background](#background) +- [What Are These Contracts For?](#what-are-these-contracts-for) +- [Handling Upgradeability](#handling-upgradeability) +- [The Contracts](#the-contracts) +- [Getting Started](#getting-started) +- [Deployment](#deployment) +- [Security](#security) +- [Getting Help](#getting-help) + ## Background Smart contracts are executable code, deployed on blockchains that can be read from / written to anyone with an internet connection. Transaction data and smart contract storage is public and can be accessed in blockchain explorers. In decentralized Timeboost, smart contracts are used to allow anyone to interact with various -of the protocol. This readme is directed at developers who are +parts of the protocol. This readme is directed at developers who are contributing to or making use of this decentralized timeboost implementation. @@ -26,7 +37,7 @@ These contracts act as the "coordination layer" that allows the Timeboost networ ## Handling Upgradeability ### The Upgrade Problem -Once deployed, smart contracts can't be changed. To solve this, we use a proxy solution that performs functionally as upgradeable contracts. +Once deployed, smart contracts can't be changed. To solve this, we use a proxy solution that functions as upgradeable contracts. ### The Proxy Solution We use a "proxy pattern" that works like this: @@ -77,7 +88,15 @@ This is the "shell" that makes upgrades possible: ## Getting Started ### Prerequisites -- **Foundry** - For building and testing contracts + +Before you begin, make sure you have: + +- **Foundry** - For building, testing, and deploying contracts + ```bash + # Install Foundry + curl -L https://foundry.paradigm.xyz | bash + foundryup + ``` ### Building the Contracts ```bash @@ -101,13 +120,13 @@ forge test --match-test test_setThresholdEncryptionKey ``` ### Integration Testing -For testing contract interactions from Rust code, see the [timeboost-contract README](../timeboost-contract/README.md). +For testing contract interactions from Rust code, see the [timeboost-contract README](https://github.com/EspressoSystems/timeboost/tree/main/timeboost-contract/README.md) in the Rust repository. ## Deployment You can deploy to a local anvil network (as done in the test), a fork of a real network, a testnet network (e.g. Ethereum Sepolia) or a mainnet (e.g. Ethereum Mainnet). -### Quick Start +### Quick Start (Local Testing) 1. **Set up your environment:** ```bash @@ -115,17 +134,26 @@ You can deploy to a local anvil network (as done in the test), a fork of a real # Edit .env with your values ``` -2. **Start a local blockchain (if testing locally):** +2. **Start a local blockchain (not needed if using remote rpc):** ```bash anvil ``` -3. **Deploy:** +3. **Deploy the contracts:** ```bash ./script/deploy.sh ``` -That's it! The script will deploy your contract and show you the addresses. +That's it! The script will deploy your contracts and show you the addresses. + +### Production Deployment + +For production deployments, ensure you have: + +1. **A secure wallet** with sufficient ETH for gas fees +2. **A valid manager address** (preferably a multisig wallet) +3. **The correct RPC URL** for your target network +4. **Tested thoroughly** on testnets first ### What You Need @@ -143,10 +171,10 @@ The proxy gets initialized with your manager address, and that's it! ### Configuration -All settings go in your `.env` file: +All settings go in your `.env` file. Copy `env.example` to `.env` and customize: ```bash -# Required: Who manages the contract +# Required: Who manages the contract (use a multisig for production) MANAGER_ADDRESS=0x1234567890123456789012345678901234567890 # Optional: Where to deploy (defaults to localhost) @@ -157,6 +185,12 @@ MNEMONIC="your twelve word mnemonic phrase here" ACCOUNT_INDEX=0 ``` +**Example configurations:** + +- **Local testing**: Use Anvil's default account (no mnemonic needed) +- **Testnet**: Use a test wallet with testnet ETH +- **Mainnet**: Use a secure multisig wallet + ### Deployment Process The deployment script: @@ -198,6 +232,29 @@ The deployment script: - **Monitor events** - Watch for unexpected contract changes - **Keep keys secure** - Store private keys and mnemonics safely +## Quick Reference + +### Common Commands +```bash +# Build contracts +forge build + +# Run tests +forge test + +# Deploy locally +anvil +./script/deploy.sh + +# Run specific test +forge test --match-test test_setThresholdEncryptionKey +``` + +### Important Addresses +- **Proxy Contract**: The address users interact with (never changes) +- **Implementation Contract**: The actual contract logic (can be upgraded) +- **Manager**: The address that can update committees and keys + ## Getting Help -- Review the [timeboost-contract README](https://github.com/EspressoSystems/timeboost/tree/main/timeboost-contract/README.md) in the rust repo for integration questions +- Review the [timeboost-contract README](https://github.com/EspressoSystems/timeboost/tree/main/timeboost-contract/README.md) in the Rust repo for integration questions - Check the troubleshooting section above for deployment issues \ No newline at end of file