diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..a2d398f --- /dev/null +++ b/.env.example @@ -0,0 +1,8 @@ +# Path to your keystore file (JSON) +KEYSTORE=/absolute/path/to/keystore.json + +# Password for your keystore +PASSWORD=your_keystore_password + +# Optionally override the RPC URL (defaults set by network in deploy script) +# RPC_URL=https://api.calibration.node.glif.io/rpc/v1 \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b73142d --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +.PHONY: build deploy-mupay deploy-multisig deploy-all clean chmod-deploy + +chmod-deploy: + chmod +x ./tools/deploy.sh + +build: + @echo "Building contracts..." + forge build + forge test + +deploy-mupay: chmod-deploy + @echo "Deploying MuPay contract..." + ./tools/deploy.sh mupay 314159 + +deploy-multisig: chmod-deploy + @echo "Deploying Multisig contract..." + ./tools/deploy.sh multisig 314159 + +deploy-all: deploy-mupay deploy-multisig + +clean: + forge clean \ No newline at end of file diff --git a/README.md b/README.md index 522a8b2..03eb71f 100644 --- a/README.md +++ b/README.md @@ -17,3 +17,55 @@ The process flow of interactions between the client, server, and smart contract Hash Chain-Based Scheme This contract ensures secure, efficient, and trustless micro transactions for decentralized applications. + +## Local Development & Deployment + +### Prerequisites + +- [Foundry](https://book.getfoundry.sh/getting-started/installation) (`forge`, `cast`) +- A valid Ethereum/FEVM keystore file and password +- RPC endpoint (e.g. Filecoin Calibration, Mainnet, etc.) + +### Build and test + +```sh +make build +``` + +## Deployment + +### Deploy MuPay contract + +```sh +make deploy-mupay +``` + +### Deploy Multisig contract + +```sh +make deploy-multisig +``` + +### Deploy both + +```sh +make deploy-all +``` + +By default, deployment targets the Filecoin Calibration (calibnet) network (`chain_id: 314159`). +You can adjust the `chain_id` or RPC endpoint in the Makefile or deployment script for other networks. + +## Environment Setup + +Copy `.env.example` to `.env` and fill in your values before deploying: +```sh +cp .env.example .env +``` + +Then edit `.env` as needed. + +You can generate a keystore file from a private key using: +```sh +cast wallet import --private-key $PRIVATE_KEY keystoreName +# File will be saved to ~/.foundry/keystores/ +``` \ No newline at end of file diff --git a/tools/deploy.sh b/tools/deploy.sh new file mode 100755 index 0000000..703a568 --- /dev/null +++ b/tools/deploy.sh @@ -0,0 +1,90 @@ +#!/bin/bash +# deploy.sh - Deploys MuPay or Multisig contracts to a specified network +# Usage: ./tools/deploy.sh +# : mupay | multisig | both (default: both) +# : 314159 (calibnet), 314 (mainnet), etc. (default: 314159) +# +# Example: +# ./tools/deploy.sh mupay 314159 +# ./tools/deploy.sh multisig 314159 +# ./tools/deploy.sh both 314159 + +set -euo pipefail + +CONTRACT="${1}" +CHAIN_ID="${2:-314159}" # Default to calibnet + +if [ $# -lt 1 ]; then + echo "Usage: $0 [chain_id]" + exit 1 +fi + +# Load environment variables from .env if present +if [ -f ".env" ]; then + export $(grep -v '^#' .env | xargs) +fi + +# Set default RPC_URL if not set +if [ -z "${RPC_URL:-}" ]; then + if [ "$CHAIN_ID" = "314159" ]; then + export RPC_URL="https://api.calibration.node.glif.io/rpc/v1" + elif [ "$CHAIN_ID" = "314" ]; then + export RPC_URL="https://api.node.glif.io/rpc/v1" + else + echo "Error: RPC_URL must be set for CHAIN_ID $CHAIN_ID" + exit 1 + fi +fi + +if [ -z "${KEYSTORE:-}" ]; then + echo "Error: KEYSTORE is not set" + exit 1 +fi +if [ -z "${PASSWORD:-}" ]; then + echo "Error: PASSWORD is not set" + exit 1 +fi + +ADDR=$(cast wallet address --keystore "$KEYSTORE" --password "$PASSWORD") +echo "Deploying from address $ADDR to chain $CHAIN_ID" +NONCE="$(cast nonce --rpc-url "$RPC_URL" "$ADDR")" + +deploy_contract() { + local contract_path="$1" + local contract_name="$2" + + echo "Deploying $contract_name ($contract_path)" + DEPLOYED_ADDRESS=$( + forge create --rpc-url "$RPC_URL" \ + --keystore "$KEYSTORE" \ + --password "$PASSWORD" \ + --broadcast \ + --nonce $NONCE \ + --chain-id $CHAIN_ID \ + "$contract_path" \ + | grep "Deployed to" | awk '{print $3}' + ) + + if [ -z "$DEPLOYED_ADDRESS" ]; then + echo "Error: Failed to extract $contract_name contract address" + exit 1 + fi + + echo "$contract_name deployed at: $DEPLOYED_ADDRESS" + NONCE=$((NONCE + 1)) # Increment nonce for next contract, if any +} + +case "$CONTRACT" in + mupay) + deploy_contract "src/MuPay.sol:MuPay" "MuPay" + ;; + multisig) + deploy_contract "src/Multisig_2of2.sol:Multisig" "Multisig" + ;; + *) + echo "Invalid contract option: $CONTRACT" + echo "Usage: $0 [chain_id]" + exit 1 + ;; +esac +echo "Deployment complete." \ No newline at end of file