mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-03 01:41:44 +00:00
@@ -0,0 +1,203 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Build and optimize Identity DAO contracts for deployment
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Helper functions
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
# Configuration
|
||||
PROJECT_ROOT="$(dirname "$0")/.."
|
||||
CONTRACTS_DIR="${PROJECT_ROOT}/contracts"
|
||||
TARGET_DIR="${PROJECT_ROOT}/target/wasm32-unknown-unknown/release"
|
||||
ARTIFACTS_DIR="${PROJECT_ROOT}/artifacts"
|
||||
|
||||
# Contract names
|
||||
CONTRACTS=(
|
||||
"identity-dao-core"
|
||||
"identity-dao-voting"
|
||||
"identity-dao-proposals"
|
||||
"identity-dao-pre-propose"
|
||||
)
|
||||
|
||||
# Check for Rust and wasm32 target
|
||||
check_requirements() {
|
||||
log_info "Checking build requirements..."
|
||||
|
||||
if ! command -v cargo &> /dev/null; then
|
||||
log_error "Rust/Cargo not found. Please install Rust."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! rustup target list --installed | grep -q wasm32-unknown-unknown; then
|
||||
log_warning "wasm32-unknown-unknown target not installed. Installing..."
|
||||
rustup target add wasm32-unknown-unknown
|
||||
fi
|
||||
|
||||
if ! command -v docker &> /dev/null; then
|
||||
log_error "Docker not found. Docker is required for contract optimization."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "All requirements satisfied"
|
||||
}
|
||||
|
||||
# Build contracts
|
||||
build_contracts() {
|
||||
log_info "Building contracts..."
|
||||
|
||||
cd "${PROJECT_ROOT}"
|
||||
|
||||
# Clean previous builds
|
||||
cargo clean
|
||||
|
||||
# Build all contracts in release mode
|
||||
RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
log_info "Contracts built successfully"
|
||||
else
|
||||
log_error "Failed to build contracts"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Optimize contracts using CosmWasm optimizer
|
||||
optimize_contracts() {
|
||||
log_info "Optimizing contracts for deployment..."
|
||||
|
||||
# Create artifacts directory
|
||||
mkdir -p "${ARTIFACTS_DIR}"
|
||||
|
||||
# Run optimizer in Docker
|
||||
docker run --rm -v "${PROJECT_ROOT}":/code \
|
||||
--mount type=volume,source="dao_contracts_cache",target=/target \
|
||||
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
|
||||
cosmwasm/optimizer:0.16.0
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
log_info "Contract optimization complete"
|
||||
|
||||
# Move optimized contracts to artifacts
|
||||
mv "${PROJECT_ROOT}"/artifacts/*.wasm "${ARTIFACTS_DIR}/" 2>/dev/null || true
|
||||
else
|
||||
log_error "Failed to optimize contracts"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Generate schemas
|
||||
generate_schemas() {
|
||||
log_info "Generating contract schemas..."
|
||||
|
||||
cd "${PROJECT_ROOT}"
|
||||
|
||||
for contract in "${CONTRACTS[@]}"; do
|
||||
contract_dir="${CONTRACTS_DIR}/${contract//-/_}"
|
||||
|
||||
if [ -d "${contract_dir}" ]; then
|
||||
log_info "Generating schema for ${contract}..."
|
||||
cd "${contract_dir}"
|
||||
cargo schema
|
||||
fi
|
||||
done
|
||||
|
||||
log_info "Schema generation complete"
|
||||
}
|
||||
|
||||
# Verify contract sizes
|
||||
verify_sizes() {
|
||||
log_info "Verifying contract sizes..."
|
||||
|
||||
MAX_SIZE=$((600 * 1024)) # 600 KB max size for Cosmos chains
|
||||
|
||||
for wasm_file in "${ARTIFACTS_DIR}"/*.wasm; do
|
||||
if [ -f "$wasm_file" ]; then
|
||||
size=$(stat -f%z "$wasm_file" 2>/dev/null || stat -c%s "$wasm_file" 2>/dev/null)
|
||||
size_kb=$((size / 1024))
|
||||
filename=$(basename "$wasm_file")
|
||||
|
||||
if [ $size -gt $MAX_SIZE ]; then
|
||||
log_error "$filename is too large: ${size_kb}KB (max: 600KB)"
|
||||
exit 1
|
||||
else
|
||||
log_info "$filename: ${size_kb}KB ✓"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Generate checksums
|
||||
generate_checksums() {
|
||||
log_info "Generating checksums..."
|
||||
|
||||
cd "${ARTIFACTS_DIR}"
|
||||
|
||||
if [ -f checksums.txt ]; then
|
||||
rm checksums.txt
|
||||
fi
|
||||
|
||||
for wasm_file in *.wasm; do
|
||||
if [ -f "$wasm_file" ]; then
|
||||
if command -v sha256sum &> /dev/null; then
|
||||
sha256sum "$wasm_file" >> checksums.txt
|
||||
else
|
||||
shasum -a 256 "$wasm_file" >> checksums.txt
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
log_info "Checksums saved to artifacts/checksums.txt"
|
||||
}
|
||||
|
||||
# Main build flow
|
||||
main() {
|
||||
log_info "Starting Identity DAO contract build process..."
|
||||
|
||||
# Check requirements
|
||||
check_requirements
|
||||
|
||||
# Build contracts
|
||||
build_contracts
|
||||
|
||||
# Optimize contracts
|
||||
optimize_contracts
|
||||
|
||||
# Generate schemas
|
||||
generate_schemas
|
||||
|
||||
# Verify sizes
|
||||
verify_sizes
|
||||
|
||||
# Generate checksums
|
||||
generate_checksums
|
||||
|
||||
log_info "✅ Build complete!"
|
||||
log_info ""
|
||||
log_info "=== Build Summary ==="
|
||||
log_info "Optimized contracts location: ${ARTIFACTS_DIR}"
|
||||
log_info "Contract schemas location: ${CONTRACTS_DIR}/*/schema"
|
||||
log_info ""
|
||||
log_info "Next steps:"
|
||||
log_info "1. Review contract sizes in ${ARTIFACTS_DIR}"
|
||||
log_info "2. Deploy contracts using: ./scripts/deploy_testnet.sh"
|
||||
}
|
||||
|
||||
# Run main build
|
||||
main "$@"
|
||||
Executable
+364
@@ -0,0 +1,364 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Identity DAO Deployment Script for Cosmos Hub
|
||||
# Deploys contracts to Cosmos Hub and establishes IBC channels to Sonr
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
COSMOS_HUB_CHAIN_ID="${COSMOS_HUB_CHAIN_ID:-cosmoshub-testnet}"
|
||||
COSMOS_HUB_NODE="${COSMOS_HUB_NODE:-https://rpc.testnet.cosmos.network:443}"
|
||||
SONR_CHAIN_ID="${SONR_CHAIN_ID:-sonrtest_1-1}"
|
||||
SONR_NODE="${SONR_NODE:-http://localhost:26657}"
|
||||
DEPLOYER="${DEPLOYER:-deployer}"
|
||||
GAS_PRICES="${GAS_PRICES:-0.025uatom}"
|
||||
CONTRACTS_DIR="../artifacts"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}Identity DAO Deployment to Cosmos Hub${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
|
||||
# Function to store contract code
|
||||
store_contract() {
|
||||
local wasm_file=$1
|
||||
local label=$2
|
||||
|
||||
echo -e "${GREEN}Storing contract: ${label}${NC}"
|
||||
|
||||
TX_HASH=$(gaiad tx wasm store "$wasm_file" \
|
||||
--from "$DEPLOYER" \
|
||||
--chain-id "$COSMOS_HUB_CHAIN_ID" \
|
||||
--node "$COSMOS_HUB_NODE" \
|
||||
--gas-prices "$GAS_PRICES" \
|
||||
--gas auto \
|
||||
--gas-adjustment 1.5 \
|
||||
--broadcast-mode sync \
|
||||
--yes \
|
||||
--output json | jq -r '.txhash')
|
||||
|
||||
echo "Waiting for transaction..."
|
||||
sleep 6
|
||||
|
||||
CODE_ID=$(gaiad query tx "$TX_HASH" \
|
||||
--node "$COSMOS_HUB_NODE" \
|
||||
--output json | jq -r '.logs[0].events[] | select(.type=="store_code") | .attributes[] | select(.key=="code_id") | .value')
|
||||
|
||||
echo -e "${GREEN}✓ Stored ${label} with code ID: ${CODE_ID}${NC}"
|
||||
echo "$CODE_ID"
|
||||
}
|
||||
|
||||
# Function to instantiate contract
|
||||
instantiate_contract() {
|
||||
local code_id=$1
|
||||
local init_msg=$2
|
||||
local label=$3
|
||||
|
||||
echo -e "${GREEN}Instantiating: ${label}${NC}"
|
||||
|
||||
TX_HASH=$(gaiad tx wasm instantiate "$code_id" "$init_msg" \
|
||||
--from "$DEPLOYER" \
|
||||
--label "$label" \
|
||||
--chain-id "$COSMOS_HUB_CHAIN_ID" \
|
||||
--node "$COSMOS_HUB_NODE" \
|
||||
--gas-prices "$GAS_PRICES" \
|
||||
--gas auto \
|
||||
--gas-adjustment 1.5 \
|
||||
--admin "$DEPLOYER" \
|
||||
--broadcast-mode sync \
|
||||
--yes \
|
||||
--output json | jq -r '.txhash')
|
||||
|
||||
echo "Waiting for transaction..."
|
||||
sleep 6
|
||||
|
||||
CONTRACT_ADDR=$(gaiad query tx "$TX_HASH" \
|
||||
--node "$COSMOS_HUB_NODE" \
|
||||
--output json | jq -r '.logs[0].events[] | select(.type=="instantiate") | .attributes[] | select(.key=="_contract_address") | .value')
|
||||
|
||||
echo -e "${GREEN}✓ Instantiated ${label} at: ${CONTRACT_ADDR}${NC}"
|
||||
echo "$CONTRACT_ADDR"
|
||||
}
|
||||
|
||||
# Check prerequisites
|
||||
echo -e "${BLUE}Checking prerequisites...${NC}"
|
||||
|
||||
if ! command -v gaiad &>/dev/null; then
|
||||
echo -e "${RED}Error: gaiad not found. Please install Gaia (Cosmos Hub client)${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v hermes &>/dev/null; then
|
||||
echo -e "${RED}Error: hermes not found. Please install Hermes IBC relayer${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Build contracts if needed
|
||||
if [ ! -d "$CONTRACTS_DIR" ]; then
|
||||
echo -e "${BLUE}Building contracts...${NC}"
|
||||
cd ..
|
||||
docker run --rm -v "$(pwd)":/code \
|
||||
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \
|
||||
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
|
||||
cosmwasm/workspace-optimizer:0.13.0
|
||||
cd scripts
|
||||
fi
|
||||
|
||||
# Store contract codes
|
||||
echo -e "${BLUE}Storing contract codes on Cosmos Hub...${NC}"
|
||||
|
||||
CORE_CODE_ID=$(store_contract "$CONTRACTS_DIR/identity_dao_core.wasm" "Identity DAO Core")
|
||||
VOTING_CODE_ID=$(store_contract "$CONTRACTS_DIR/did_voting.wasm" "DID-Based Voting")
|
||||
PROPOSALS_CODE_ID=$(store_contract "$CONTRACTS_DIR/identity_proposals.wasm" "Identity Proposals")
|
||||
PRE_PROPOSE_CODE_ID=$(store_contract "$CONTRACTS_DIR/pre_propose_identity.wasm" "Pre-Propose Identity")
|
||||
|
||||
# Instantiate contracts
|
||||
echo -e "${BLUE}Instantiating contracts...${NC}"
|
||||
|
||||
# Core module
|
||||
CORE_INIT='{
|
||||
"admin": "'$DEPLOYER'",
|
||||
"dao_name": "Sonr Identity DAO",
|
||||
"dao_uri": "https://sonr.io/dao",
|
||||
"voting_module": null,
|
||||
"proposal_modules": [],
|
||||
"wyoming_dao_info": {
|
||||
"entity_name": "Sonr Identity DAO LLC",
|
||||
"entity_type": "LLC",
|
||||
"registered_agent": "Wyoming Registered Agent LLC",
|
||||
"ein": "00-0000000"
|
||||
}
|
||||
}'
|
||||
CORE_ADDR=$(instantiate_contract "$CORE_CODE_ID" "$CORE_INIT" "identity-dao-core")
|
||||
|
||||
# Voting module
|
||||
VOTING_INIT='{
|
||||
"dao_core": "'$CORE_ADDR'",
|
||||
"min_verification_level": 1,
|
||||
"use_reputation_weight": true
|
||||
}'
|
||||
VOTING_ADDR=$(instantiate_contract "$VOTING_CODE_ID" "$VOTING_INIT" "did-voting")
|
||||
|
||||
# Proposals module
|
||||
PROPOSALS_INIT='{
|
||||
"dao_core": "'$CORE_ADDR'",
|
||||
"voting_module": "'$VOTING_ADDR'",
|
||||
"min_voting_period": 86400,
|
||||
"max_voting_period": 604800,
|
||||
"pass_threshold": {"absolute_percentage": {"percentage": "0.5"}},
|
||||
"min_verification_level": 1
|
||||
}'
|
||||
PROPOSALS_ADDR=$(instantiate_contract "$PROPOSALS_CODE_ID" "$PROPOSALS_INIT" "identity-proposals")
|
||||
|
||||
# Pre-propose module
|
||||
PRE_PROPOSE_INIT='{
|
||||
"dao_core": "'$CORE_ADDR'",
|
||||
"proposal_module": "'$PROPOSALS_ADDR'",
|
||||
"deposit_amount": "1000000",
|
||||
"deposit_denom": "uatom",
|
||||
"min_verification_level": 1,
|
||||
"admin_approval_required": false
|
||||
}'
|
||||
PRE_PROPOSE_ADDR=$(instantiate_contract "$PRE_PROPOSE_CODE_ID" "$PRE_PROPOSE_INIT" "pre-propose-identity")
|
||||
|
||||
# Update core configuration
|
||||
echo -e "${BLUE}Updating core configuration...${NC}"
|
||||
|
||||
UPDATE_MSG='{
|
||||
"update_config": {
|
||||
"voting_module": "'$VOTING_ADDR'",
|
||||
"proposal_modules": ["'$PROPOSALS_ADDR'"]
|
||||
}
|
||||
}'
|
||||
|
||||
gaiad tx wasm execute "$CORE_ADDR" "$UPDATE_MSG" \
|
||||
--from "$DEPLOYER" \
|
||||
--chain-id "$COSMOS_HUB_CHAIN_ID" \
|
||||
--node "$COSMOS_HUB_NODE" \
|
||||
--gas-prices "$GAS_PRICES" \
|
||||
--gas auto \
|
||||
--gas-adjustment 1.5 \
|
||||
--yes
|
||||
|
||||
echo -e "${GREEN}✓ Core configuration updated${NC}"
|
||||
|
||||
# Setup IBC channels
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}Setting up IBC Channels${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
|
||||
# Create Hermes config if not exists
|
||||
HERMES_CONFIG="$HOME/.hermes/config.toml"
|
||||
if [ ! -f "$HERMES_CONFIG" ]; then
|
||||
echo -e "${BLUE}Creating Hermes configuration...${NC}"
|
||||
mkdir -p "$HOME/.hermes"
|
||||
cat >"$HERMES_CONFIG" <<EOF
|
||||
[global]
|
||||
log_level = 'info'
|
||||
|
||||
[mode.clients]
|
||||
enabled = true
|
||||
refresh = true
|
||||
misbehaviour = true
|
||||
|
||||
[mode.connections]
|
||||
enabled = true
|
||||
|
||||
[mode.channels]
|
||||
enabled = true
|
||||
|
||||
[mode.packets]
|
||||
enabled = true
|
||||
clear_interval = 100
|
||||
clear_on_start = true
|
||||
tx_confirmation = true
|
||||
|
||||
[[chains]]
|
||||
id = '$COSMOS_HUB_CHAIN_ID'
|
||||
type = 'CosmosSdk'
|
||||
rpc_addr = '$COSMOS_HUB_NODE'
|
||||
grpc_addr = 'http://localhost:9090'
|
||||
websocket_addr = 'ws://localhost:26657/websocket'
|
||||
rpc_timeout = '15s'
|
||||
account_prefix = 'cosmos'
|
||||
key_name = 'relayer-cosmos'
|
||||
store_prefix = 'ibc'
|
||||
gas_price = { price = 0.025, denom = 'uatom' }
|
||||
gas_multiplier = 1.5
|
||||
max_gas = 10000000
|
||||
clock_drift = '15s'
|
||||
trusting_period = '14days'
|
||||
trust_threshold = { numerator = '2', denominator = '3' }
|
||||
|
||||
[[chains]]
|
||||
id = '$SONR_CHAIN_ID'
|
||||
type = 'CosmosSdk'
|
||||
rpc_addr = '$SONR_NODE'
|
||||
grpc_addr = 'http://localhost:9091'
|
||||
websocket_addr = 'ws://localhost:26658/websocket'
|
||||
rpc_timeout = '15s'
|
||||
account_prefix = 'sonr'
|
||||
key_name = 'relayer-sonr'
|
||||
store_prefix = 'ibc'
|
||||
gas_price = { price = 0.025, denom = 'usnr' }
|
||||
gas_multiplier = 1.5
|
||||
max_gas = 10000000
|
||||
clock_drift = '15s'
|
||||
trusting_period = '14days'
|
||||
trust_threshold = { numerator = '2', denominator = '3' }
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Add relayer keys
|
||||
echo -e "${BLUE}Setting up relayer keys...${NC}"
|
||||
|
||||
# Export deployer key from both chains (you'll need to have these)
|
||||
gaiad keys export "$DEPLOYER" 2>/dev/null | hermes keys add --chain "$COSMOS_HUB_CHAIN_ID" --key-file /dev/stdin || true
|
||||
snrd keys export "$DEPLOYER" 2>/dev/null | hermes keys add --chain "$SONR_CHAIN_ID" --key-file /dev/stdin || true
|
||||
|
||||
# Create IBC connection
|
||||
echo -e "${BLUE}Creating IBC connection...${NC}"
|
||||
|
||||
CONNECTION_RESULT=$(hermes create connection \
|
||||
--a-chain "$COSMOS_HUB_CHAIN_ID" \
|
||||
--b-chain "$SONR_CHAIN_ID")
|
||||
|
||||
CONNECTION_ID=$(echo "$CONNECTION_RESULT" | grep -oP 'connection-\d+' | head -1)
|
||||
|
||||
echo -e "${GREEN}✓ Created IBC connection: ${CONNECTION_ID}${NC}"
|
||||
|
||||
# Create channels for each contract
|
||||
echo -e "${BLUE}Creating IBC channels for contracts...${NC}"
|
||||
|
||||
# Channel for voting module
|
||||
VOTING_CHANNEL=$(hermes create channel \
|
||||
--a-chain "$COSMOS_HUB_CHAIN_ID" \
|
||||
--a-connection "$CONNECTION_ID" \
|
||||
--a-port "wasm.$VOTING_ADDR" \
|
||||
--b-port "did" \
|
||||
--order unordered \
|
||||
--version "identity-dao-1" | grep -oP 'channel-\d+' | head -1)
|
||||
|
||||
echo -e "${GREEN}✓ Created voting channel: ${VOTING_CHANNEL}${NC}"
|
||||
|
||||
# Channel for proposals module
|
||||
PROPOSALS_CHANNEL=$(hermes create channel \
|
||||
--a-chain "$COSMOS_HUB_CHAIN_ID" \
|
||||
--a-connection "$CONNECTION_ID" \
|
||||
--a-port "wasm.$PROPOSALS_ADDR" \
|
||||
--b-port "dwn" \
|
||||
--order unordered \
|
||||
--version "identity-dao-1" | grep -oP 'channel-\d+' | head -1)
|
||||
|
||||
echo -e "${GREEN}✓ Created proposals channel: ${PROPOSALS_CHANNEL}${NC}"
|
||||
|
||||
# Start the relayer
|
||||
echo -e "${BLUE}Starting IBC relayer...${NC}"
|
||||
|
||||
hermes start &
|
||||
RELAYER_PID=$!
|
||||
|
||||
echo -e "${GREEN}✓ IBC relayer started with PID: ${RELAYER_PID}${NC}"
|
||||
|
||||
# Save deployment information
|
||||
DEPLOYMENT_FILE="cosmos-hub-deployment.json"
|
||||
cat >"$DEPLOYMENT_FILE" <<EOF
|
||||
{
|
||||
"chain_id": "$COSMOS_HUB_CHAIN_ID",
|
||||
"deployment_time": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||||
"contracts": {
|
||||
"core": {
|
||||
"code_id": $CORE_CODE_ID,
|
||||
"address": "$CORE_ADDR"
|
||||
},
|
||||
"voting": {
|
||||
"code_id": $VOTING_CODE_ID,
|
||||
"address": "$VOTING_ADDR",
|
||||
"ibc_channel": "$VOTING_CHANNEL"
|
||||
},
|
||||
"proposals": {
|
||||
"code_id": $PROPOSALS_CODE_ID,
|
||||
"address": "$PROPOSALS_ADDR",
|
||||
"ibc_channel": "$PROPOSALS_CHANNEL"
|
||||
},
|
||||
"pre_propose": {
|
||||
"code_id": $PRE_PROPOSE_CODE_ID,
|
||||
"address": "$PRE_PROPOSE_ADDR"
|
||||
}
|
||||
},
|
||||
"ibc": {
|
||||
"connection_id": "$CONNECTION_ID",
|
||||
"relayer_pid": $RELAYER_PID
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${GREEN}✓ Deployment Complete!${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
echo "Deployment information saved to: $DEPLOYMENT_FILE"
|
||||
echo ""
|
||||
echo "Contract Addresses:"
|
||||
echo " Core: $CORE_ADDR"
|
||||
echo " Voting: $VOTING_ADDR"
|
||||
echo " Proposals: $PROPOSALS_ADDR"
|
||||
echo " Pre-Propose: $PRE_PROPOSE_ADDR"
|
||||
echo ""
|
||||
echo "IBC Channels:"
|
||||
echo " Voting: $VOTING_CHANNEL"
|
||||
echo " Proposals: $PROPOSALS_CHANNEL"
|
||||
echo ""
|
||||
echo "Relayer PID: $RELAYER_PID"
|
||||
echo ""
|
||||
echo "To stop the relayer: kill $RELAYER_PID"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Verify IBC channels are active: hermes query channels --chain $COSMOS_HUB_CHAIN_ID"
|
||||
echo "2. Test DID verification: gaiad tx wasm execute $VOTING_ADDR '{\"update_voter\":{\"did\":\"did:sonr:test\",\"address\":\"cosmos1...\"}}'"
|
||||
echo "3. Create a test proposal through the pre-propose module"
|
||||
Executable
+301
@@ -0,0 +1,301 @@
|
||||
#!/bin/bash
|
||||
# Identity DAO Deployment Script
|
||||
# Deploys all Identity DAO contracts to Sonr testnet
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
CHAIN_ID="${CHAIN_ID:-sonrtest_1-1}"
|
||||
NODE="${NODE:-http://localhost:26657}"
|
||||
KEYRING="${KEYRING:-test}"
|
||||
DEPLOYER="${DEPLOYER:-deployer}"
|
||||
GAS_PRICES="${GAS_PRICES:-0.025usnr}"
|
||||
GAS_ADJUSTMENT="${GAS_ADJUSTMENT:-1.5}"
|
||||
|
||||
# Contract paths
|
||||
CONTRACTS_DIR="$(dirname "$0")/../artifacts"
|
||||
SHARED_WASM="${CONTRACTS_DIR}/identity_dao_shared.wasm"
|
||||
CORE_WASM="${CONTRACTS_DIR}/identity_dao_core.wasm"
|
||||
VOTING_WASM="${CONTRACTS_DIR}/identity_dao_voting.wasm"
|
||||
PROPOSALS_WASM="${CONTRACTS_DIR}/identity_dao_proposals.wasm"
|
||||
PRE_PROPOSE_WASM="${CONTRACTS_DIR}/identity_dao_pre_propose.wasm"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Helper functions
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
# Check dependencies
|
||||
check_dependencies() {
|
||||
log_info "Checking dependencies..."
|
||||
|
||||
if ! command -v snrd &> /dev/null; then
|
||||
log_error "snrd is not installed. Please run 'make install'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v jq &> /dev/null; then
|
||||
log_error "jq is not installed. Please install jq"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "All dependencies satisfied"
|
||||
}
|
||||
|
||||
# Build contracts
|
||||
build_contracts() {
|
||||
log_info "Building Identity DAO contracts..."
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
# Build with optimizer
|
||||
docker run --rm -v "$(pwd)":/code \
|
||||
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \
|
||||
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
|
||||
cosmwasm/workspace-optimizer:0.13.0
|
||||
|
||||
# Move artifacts
|
||||
mkdir -p artifacts
|
||||
mv artifacts/*.wasm artifacts/ 2>/dev/null || true
|
||||
|
||||
log_info "Contracts built successfully"
|
||||
}
|
||||
|
||||
# Store contract code
|
||||
store_contract() {
|
||||
local wasm_file=$1
|
||||
local contract_name=$2
|
||||
|
||||
log_info "Storing $contract_name contract..."
|
||||
|
||||
if [ ! -f "$wasm_file" ]; then
|
||||
log_error "Contract file not found: $wasm_file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local tx_result=$(snrd tx wasm store "$wasm_file" \
|
||||
--from "$DEPLOYER" \
|
||||
--chain-id "$CHAIN_ID" \
|
||||
--node "$NODE" \
|
||||
--gas-prices "$GAS_PRICES" \
|
||||
--gas-adjustment "$GAS_ADJUSTMENT" \
|
||||
--keyring-backend "$KEYRING" \
|
||||
--output json \
|
||||
--yes)
|
||||
|
||||
local tx_hash=$(echo "$tx_result" | jq -r .txhash)
|
||||
|
||||
# Wait for transaction
|
||||
sleep 6
|
||||
|
||||
# Get code ID from events
|
||||
local code_id=$(snrd query tx "$tx_hash" \
|
||||
--node "$NODE" \
|
||||
--output json | jq -r '.events[] | select(.type=="store_code") | .attributes[] | select(.key=="code_id") | .value')
|
||||
|
||||
if [ -z "$code_id" ]; then
|
||||
log_error "Failed to get code ID for $contract_name"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "$contract_name stored with code ID: $code_id"
|
||||
echo "$code_id"
|
||||
}
|
||||
|
||||
# Instantiate contract
|
||||
instantiate_contract() {
|
||||
local code_id=$1
|
||||
local init_msg=$2
|
||||
local label=$3
|
||||
local admin=${4:-$DEPLOYER}
|
||||
|
||||
log_info "Instantiating contract: $label"
|
||||
|
||||
local tx_result=$(snrd tx wasm instantiate "$code_id" "$init_msg" \
|
||||
--from "$DEPLOYER" \
|
||||
--label "$label" \
|
||||
--admin "$admin" \
|
||||
--chain-id "$CHAIN_ID" \
|
||||
--node "$NODE" \
|
||||
--gas-prices "$GAS_PRICES" \
|
||||
--gas-adjustment "$GAS_ADJUSTMENT" \
|
||||
--keyring-backend "$KEYRING" \
|
||||
--output json \
|
||||
--yes)
|
||||
|
||||
local tx_hash=$(echo "$tx_result" | jq -r .txhash)
|
||||
|
||||
# Wait for transaction
|
||||
sleep 6
|
||||
|
||||
# Get contract address from events
|
||||
local contract_addr=$(snrd query tx "$tx_hash" \
|
||||
--node "$NODE" \
|
||||
--output json | jq -r '.events[] | select(.type=="instantiate") | .attributes[] | select(.key=="_contract_address") | .value')
|
||||
|
||||
if [ -z "$contract_addr" ]; then
|
||||
log_error "Failed to get contract address for $label"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "$label instantiated at: $contract_addr"
|
||||
echo "$contract_addr"
|
||||
}
|
||||
|
||||
# Main deployment flow
|
||||
main() {
|
||||
log_info "Starting Identity DAO deployment..."
|
||||
|
||||
# Check dependencies
|
||||
check_dependencies
|
||||
|
||||
# Build contracts if artifacts don't exist
|
||||
if [ ! -d "$CONTRACTS_DIR" ] || [ -z "$(ls -A $CONTRACTS_DIR/*.wasm 2>/dev/null)" ]; then
|
||||
build_contracts
|
||||
else
|
||||
log_info "Using existing contract artifacts"
|
||||
fi
|
||||
|
||||
# Store contract codes
|
||||
log_info "Storing contract codes on chain..."
|
||||
|
||||
CORE_CODE_ID=$(store_contract "$CORE_WASM" "Identity DAO Core")
|
||||
VOTING_CODE_ID=$(store_contract "$VOTING_WASM" "DID-Based Voting")
|
||||
PROPOSALS_CODE_ID=$(store_contract "$PROPOSALS_WASM" "Identity Proposals")
|
||||
PRE_PROPOSE_CODE_ID=$(store_contract "$PRE_PROPOSE_WASM" "Pre-Propose Identity")
|
||||
|
||||
# Save code IDs
|
||||
cat > "${CONTRACTS_DIR}/code_ids.json" <<EOF
|
||||
{
|
||||
"core": $CORE_CODE_ID,
|
||||
"voting": $VOTING_CODE_ID,
|
||||
"proposals": $PROPOSALS_CODE_ID,
|
||||
"pre_propose": $PRE_PROPOSE_CODE_ID
|
||||
}
|
||||
EOF
|
||||
|
||||
log_info "Contract codes stored. Code IDs saved to code_ids.json"
|
||||
|
||||
# Instantiate Core Module first
|
||||
log_info "Instantiating Identity DAO Core Module..."
|
||||
|
||||
CORE_INIT_MSG=$(cat <<EOF
|
||||
{
|
||||
"admin": "$DEPLOYER",
|
||||
"dao_name": "Sonr Identity DAO",
|
||||
"dao_uri": "https://sonr.io/dao",
|
||||
"voting_module": null,
|
||||
"proposal_modules": []
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
CORE_ADDR=$(instantiate_contract "$CORE_CODE_ID" "$CORE_INIT_MSG" "identity-dao-core" "$DEPLOYER")
|
||||
|
||||
# Instantiate Voting Module
|
||||
log_info "Instantiating DID-Based Voting Module..."
|
||||
|
||||
VOTING_INIT_MSG=$(cat <<EOF
|
||||
{
|
||||
"dao_address": "$CORE_ADDR",
|
||||
"min_verification_level": 1,
|
||||
"voting_period": 604800,
|
||||
"quorum_percentage": 20,
|
||||
"threshold_percentage": 51
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
VOTING_ADDR=$(instantiate_contract "$VOTING_CODE_ID" "$VOTING_INIT_MSG" "did-voting" "$CORE_ADDR")
|
||||
|
||||
# Instantiate Pre-Propose Module
|
||||
log_info "Instantiating Pre-Propose Identity Module..."
|
||||
|
||||
PRE_PROPOSE_INIT_MSG=$(cat <<EOF
|
||||
{
|
||||
"proposal_module": null,
|
||||
"min_verification_status": "Basic",
|
||||
"deposit_amount": "1000000",
|
||||
"deposit_denom": "usnr"
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
PRE_PROPOSE_ADDR=$(instantiate_contract "$PRE_PROPOSE_CODE_ID" "$PRE_PROPOSE_INIT_MSG" "pre-propose-identity" "$CORE_ADDR")
|
||||
|
||||
# Instantiate Proposals Module
|
||||
log_info "Instantiating Identity Proposals Module..."
|
||||
|
||||
PROPOSALS_INIT_MSG=$(cat <<EOF
|
||||
{
|
||||
"dao_address": "$CORE_ADDR",
|
||||
"voting_module": "$VOTING_ADDR",
|
||||
"pre_propose_module": "$PRE_PROPOSE_ADDR",
|
||||
"proposal_duration": 604800,
|
||||
"min_verification_level": 1
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
PROPOSALS_ADDR=$(instantiate_contract "$PROPOSALS_CODE_ID" "$PROPOSALS_INIT_MSG" "identity-proposals" "$CORE_ADDR")
|
||||
|
||||
# Update Core Module with voting and proposal modules
|
||||
log_info "Updating Core Module configuration..."
|
||||
|
||||
UPDATE_MSG=$(cat <<EOF
|
||||
{
|
||||
"update_config": {
|
||||
"voting_module": "$VOTING_ADDR",
|
||||
"proposal_modules": ["$PROPOSALS_ADDR"]
|
||||
}
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
snrd tx wasm execute "$CORE_ADDR" "$UPDATE_MSG" \
|
||||
--from "$DEPLOYER" \
|
||||
--chain-id "$CHAIN_ID" \
|
||||
--node "$NODE" \
|
||||
--gas-prices "$GAS_PRICES" \
|
||||
--gas-adjustment "$GAS_ADJUSTMENT" \
|
||||
--keyring-backend "$KEYRING" \
|
||||
--yes
|
||||
|
||||
# Save deployment addresses
|
||||
cat > "${CONTRACTS_DIR}/addresses.json" <<EOF
|
||||
{
|
||||
"core": "$CORE_ADDR",
|
||||
"voting": "$VOTING_ADDR",
|
||||
"proposals": "$PROPOSALS_ADDR",
|
||||
"pre_propose": "$PRE_PROPOSE_ADDR",
|
||||
"deployer": "$DEPLOYER",
|
||||
"chain_id": "$CHAIN_ID",
|
||||
"deployment_time": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
}
|
||||
EOF
|
||||
|
||||
log_info "Deployment complete! Contract addresses saved to addresses.json"
|
||||
log_info ""
|
||||
log_info "Contract Addresses:"
|
||||
log_info " Core: $CORE_ADDR"
|
||||
log_info " Voting: $VOTING_ADDR"
|
||||
log_info " Proposals: $PROPOSALS_ADDR"
|
||||
log_info " Pre-Propose: $PRE_PROPOSE_ADDR"
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
@@ -0,0 +1,365 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy Identity DAO Contracts to Cosmos Hub Mainnet
|
||||
# PRODUCTION DEPLOYMENT - USE WITH CAUTION
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
MAGENTA='\033[0;35m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Helper functions
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
log_critical() {
|
||||
echo -e "${MAGENTA}[CRITICAL]${NC} $1"
|
||||
}
|
||||
|
||||
# Configuration
|
||||
CHAIN_ID="cosmoshub-4" # Cosmos Hub mainnet chain ID
|
||||
NODE="https://cosmos-rpc.polkachu.com:443"
|
||||
BACKUP_NODE="https://rpc-cosmoshub.blockapsis.com:443"
|
||||
GAS_PRICES="0.025uatom"
|
||||
GAS_AUTO="--gas auto --gas-adjustment 1.5"
|
||||
KEYRING="--keyring-backend file" # Use file backend for mainnet
|
||||
|
||||
# Contract paths
|
||||
CONTRACTS_DIR="$(dirname "$0")/../artifacts"
|
||||
CORE_WASM="${CONTRACTS_DIR}/identity_dao_core.wasm"
|
||||
VOTING_WASM="${CONTRACTS_DIR}/identity_dao_voting.wasm"
|
||||
PROPOSALS_WASM="${CONTRACTS_DIR}/identity_dao_proposals.wasm"
|
||||
PRE_PROPOSE_WASM="${CONTRACTS_DIR}/identity_dao_pre_propose.wasm"
|
||||
|
||||
# Sonr mainnet configuration for IBC
|
||||
SONR_CHAIN_ID="sonr-1" # Sonr mainnet chain ID
|
||||
SONR_NODE="https://rpc.sonr.io:443"
|
||||
IBC_VERSION="ics20-1"
|
||||
|
||||
# Security checks
|
||||
MAINNET_CONFIRMATION="I_UNDERSTAND_THIS_IS_MAINNET_DEPLOYMENT"
|
||||
MULTISIG_THRESHOLD=3
|
||||
REQUIRED_SIGNATURES=2
|
||||
|
||||
# Deployment configuration
|
||||
MIN_BALANCE_ATOM=50 # Minimum ATOM balance required
|
||||
PROPOSAL_DEPOSIT="10000000" # 10 ATOM proposal deposit
|
||||
VOTING_PERIOD=1209600 # 14 days in seconds
|
||||
QUORUM="0.334" # 33.4% quorum
|
||||
THRESHOLD="0.5" # 50% threshold
|
||||
|
||||
# Pre-deployment checks
|
||||
pre_deployment_checks() {
|
||||
log_critical "=== MAINNET DEPLOYMENT PRE-CHECKS ==="
|
||||
|
||||
# Confirm mainnet deployment
|
||||
echo -e "${RED}WARNING: You are about to deploy to Cosmos Hub MAINNET${NC}"
|
||||
echo -e "${RED}This is a production deployment that will use real ATOM tokens${NC}"
|
||||
echo ""
|
||||
read -p "Type '${MAINNET_CONFIRMATION}' to continue: " confirmation
|
||||
|
||||
if [ "$confirmation" != "$MAINNET_CONFIRMATION" ]; then
|
||||
log_error "Mainnet deployment cancelled"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Mainnet deployment confirmed"
|
||||
}
|
||||
|
||||
# Check multisig setup
|
||||
check_multisig() {
|
||||
log_info "Checking multisig configuration..."
|
||||
|
||||
# Check if multisig account exists
|
||||
MULTISIG_NAME="identity-dao-multisig"
|
||||
|
||||
if ! gaiad keys show "${MULTISIG_NAME}" ${KEYRING} &> /dev/null; then
|
||||
log_error "Multisig account not found. Please create it first:"
|
||||
echo "gaiad keys add ${MULTISIG_NAME} --multisig key1,key2,key3 --multisig-threshold ${REQUIRED_SIGNATURES}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MULTISIG_ADDR=$(gaiad keys show "${MULTISIG_NAME}" -a ${KEYRING})
|
||||
log_info "Multisig address: ${MULTISIG_ADDR}"
|
||||
|
||||
# Check multisig balance
|
||||
BALANCE=$(gaiad query bank balances "${MULTISIG_ADDR}" \
|
||||
--node "${NODE}" \
|
||||
--output json | jq -r '.balances[] | select(.denom=="uatom") | .amount')
|
||||
|
||||
BALANCE_ATOM=$((BALANCE / 1000000))
|
||||
|
||||
if [ "$BALANCE_ATOM" -lt "$MIN_BALANCE_ATOM" ]; then
|
||||
log_error "Insufficient balance: ${BALANCE_ATOM} ATOM (required: ${MIN_BALANCE_ATOM} ATOM)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Multisig balance: ${BALANCE_ATOM} ATOM"
|
||||
}
|
||||
|
||||
# Verify contracts
|
||||
verify_contracts() {
|
||||
log_info "Verifying contract checksums..."
|
||||
|
||||
if [ ! -f "${CONTRACTS_DIR}/checksums.txt" ]; then
|
||||
log_error "Checksums file not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify each contract
|
||||
cd "${CONTRACTS_DIR}"
|
||||
|
||||
if command -v sha256sum &> /dev/null; then
|
||||
sha256sum -c checksums.txt
|
||||
else
|
||||
shasum -a 256 -c checksums.txt
|
||||
fi
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
log_info "All contract checksums verified"
|
||||
else
|
||||
log_error "Contract checksum verification failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd - > /dev/null
|
||||
}
|
||||
|
||||
# Backup current state
|
||||
create_backup() {
|
||||
log_info "Creating deployment backup..."
|
||||
|
||||
BACKUP_DIR="backups/mainnet_$(date +%Y%m%d_%H%M%S)"
|
||||
mkdir -p "${BACKUP_DIR}"
|
||||
|
||||
# Copy contracts
|
||||
cp -r "${CONTRACTS_DIR}" "${BACKUP_DIR}/"
|
||||
|
||||
# Save deployment configuration
|
||||
cat > "${BACKUP_DIR}/deployment_config.json" << EOF
|
||||
{
|
||||
"chain_id": "${CHAIN_ID}",
|
||||
"node": "${NODE}",
|
||||
"multisig_addr": "${MULTISIG_ADDR}",
|
||||
"timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
|
||||
"contracts": {
|
||||
"core": "${CORE_WASM}",
|
||||
"voting": "${VOTING_WASM}",
|
||||
"proposals": "${PROPOSALS_WASM}",
|
||||
"pre_propose": "${PRE_PROPOSE_WASM}"
|
||||
},
|
||||
"config": {
|
||||
"proposal_deposit": "${PROPOSAL_DEPOSIT}",
|
||||
"voting_period": ${VOTING_PERIOD},
|
||||
"quorum": "${QUORUM}",
|
||||
"threshold": "${THRESHOLD}"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
log_info "Backup created at ${BACKUP_DIR}"
|
||||
}
|
||||
|
||||
# Generate multisig transaction
|
||||
generate_multisig_tx() {
|
||||
local msg=$1
|
||||
local output_file=$2
|
||||
local description=$3
|
||||
|
||||
log_info "Generating multisig transaction: ${description}"
|
||||
|
||||
# Generate unsigned transaction
|
||||
gaiad tx wasm $msg \
|
||||
--from "${MULTISIG_NAME}" \
|
||||
--chain-id "${CHAIN_ID}" \
|
||||
--node "${NODE}" \
|
||||
--gas-prices "${GAS_PRICES}" \
|
||||
${GAS_AUTO} \
|
||||
${KEYRING} \
|
||||
--generate-only > "${output_file}"
|
||||
|
||||
log_info "Unsigned transaction saved to ${output_file}"
|
||||
}
|
||||
|
||||
# Upload contract with multisig
|
||||
upload_contract_multisig() {
|
||||
local wasm_file=$1
|
||||
local contract_name=$2
|
||||
|
||||
log_info "Preparing ${contract_name} upload..."
|
||||
|
||||
# Generate store transaction
|
||||
TX_FILE="tx_store_${contract_name}.json"
|
||||
|
||||
generate_multisig_tx \
|
||||
"store ${wasm_file}" \
|
||||
"${TX_FILE}" \
|
||||
"Store ${contract_name}"
|
||||
|
||||
log_info "${contract_name} upload transaction prepared"
|
||||
log_warning "Requires multisig signatures before broadcasting"
|
||||
|
||||
echo "${TX_FILE}"
|
||||
}
|
||||
|
||||
# Main deployment flow
|
||||
main() {
|
||||
log_critical "Starting Identity DAO MAINNET deployment..."
|
||||
|
||||
# Pre-deployment checks
|
||||
pre_deployment_checks
|
||||
|
||||
# Check multisig setup
|
||||
check_multisig
|
||||
|
||||
# Verify contracts
|
||||
verify_contracts
|
||||
|
||||
# Create backup
|
||||
create_backup
|
||||
|
||||
# Prepare upload transactions
|
||||
log_info "Preparing contract upload transactions..."
|
||||
|
||||
CORE_TX=$(upload_contract_multisig "${CORE_WASM}" "Identity DAO Core")
|
||||
VOTING_TX=$(upload_contract_multisig "${VOTING_WASM}" "DID Voting")
|
||||
PROPOSALS_TX=$(upload_contract_multisig "${PROPOSALS_WASM}" "Proposals")
|
||||
PRE_PROPOSE_TX=$(upload_contract_multisig "${PRE_PROPOSE_WASM}" "Pre-Propose")
|
||||
|
||||
# Generate instantiation messages
|
||||
log_info "Generating instantiation messages..."
|
||||
|
||||
CORE_INIT_MSG='{
|
||||
"name": "Sonr Identity DAO",
|
||||
"description": "Decentralized Identity Governance on Cosmos Hub",
|
||||
"voting_config": {
|
||||
"threshold": "'${THRESHOLD}'",
|
||||
"quorum": "'${QUORUM}'",
|
||||
"voting_period": '${VOTING_PERIOD}',
|
||||
"proposal_deposit": "'${PROPOSAL_DEPOSIT}'"
|
||||
},
|
||||
"admin": "'${MULTISIG_ADDR}'",
|
||||
"enable_did_integration": true
|
||||
}'
|
||||
|
||||
echo "$CORE_INIT_MSG" > init_core.json
|
||||
|
||||
# Save deployment instructions
|
||||
cat > MAINNET_DEPLOYMENT_INSTRUCTIONS.md << EOF
|
||||
# Cosmos Hub Mainnet Deployment Instructions
|
||||
|
||||
## Prerequisites
|
||||
- Multisig address: ${MULTISIG_ADDR}
|
||||
- Required signatures: ${REQUIRED_SIGNATURES} of ${MULTISIG_THRESHOLD}
|
||||
- Chain ID: ${CHAIN_ID}
|
||||
|
||||
## Step 1: Sign Upload Transactions
|
||||
|
||||
Each signer must sign the upload transactions:
|
||||
|
||||
\`\`\`bash
|
||||
# Sign Core contract upload
|
||||
gaiad tx sign ${CORE_TX} --from <signer_key> --chain-id ${CHAIN_ID} ${KEYRING} > signed_core_<signer>.json
|
||||
|
||||
# Sign Voting contract upload
|
||||
gaiad tx sign ${VOTING_TX} --from <signer_key> --chain-id ${CHAIN_ID} ${KEYRING} > signed_voting_<signer>.json
|
||||
|
||||
# Sign Proposals contract upload
|
||||
gaiad tx sign ${PROPOSALS_TX} --from <signer_key> --chain-id ${CHAIN_ID} ${KEYRING} > signed_proposals_<signer>.json
|
||||
|
||||
# Sign Pre-Propose contract upload
|
||||
gaiad tx sign ${PRE_PROPOSE_TX} --from <signer_key> --chain-id ${CHAIN_ID} ${KEYRING} > signed_pre_propose_<signer>.json
|
||||
\`\`\`
|
||||
|
||||
## Step 2: Combine Signatures
|
||||
|
||||
\`\`\`bash
|
||||
# Combine Core signatures
|
||||
gaiad tx multisign ${CORE_TX} ${MULTISIG_NAME} signed_core_*.json --chain-id ${CHAIN_ID} ${KEYRING} > tx_core_signed.json
|
||||
|
||||
# Combine Voting signatures
|
||||
gaiad tx multisign ${VOTING_TX} ${MULTISIG_NAME} signed_voting_*.json --chain-id ${CHAIN_ID} ${KEYRING} > tx_voting_signed.json
|
||||
|
||||
# Combine Proposals signatures
|
||||
gaiad tx multisign ${PROPOSALS_TX} ${MULTISIG_NAME} signed_proposals_*.json --chain-id ${CHAIN_ID} ${KEYRING} > tx_proposals_signed.json
|
||||
|
||||
# Combine Pre-Propose signatures
|
||||
gaiad tx multisign ${PRE_PROPOSE_TX} ${MULTISIG_NAME} signed_pre_propose_*.json --chain-id ${CHAIN_ID} ${KEYRING} > tx_pre_propose_signed.json
|
||||
\`\`\`
|
||||
|
||||
## Step 3: Broadcast Transactions
|
||||
|
||||
\`\`\`bash
|
||||
# Broadcast uploads (one at a time)
|
||||
gaiad tx broadcast tx_core_signed.json --node ${NODE}
|
||||
# Wait for confirmation and note CODE_ID
|
||||
|
||||
gaiad tx broadcast tx_voting_signed.json --node ${NODE}
|
||||
# Wait for confirmation and note CODE_ID
|
||||
|
||||
gaiad tx broadcast tx_proposals_signed.json --node ${NODE}
|
||||
# Wait for confirmation and note CODE_ID
|
||||
|
||||
gaiad tx broadcast tx_pre_propose_signed.json --node ${NODE}
|
||||
# Wait for confirmation and note CODE_ID
|
||||
\`\`\`
|
||||
|
||||
## Step 4: Instantiate Contracts
|
||||
|
||||
After obtaining code IDs, instantiate each contract following the same multisig process.
|
||||
|
||||
## Step 5: Verify Deployment
|
||||
|
||||
Run verification script:
|
||||
\`\`\`bash
|
||||
./scripts/verify_deployment.sh
|
||||
\`\`\`
|
||||
|
||||
## Security Checklist
|
||||
|
||||
- [ ] All signers have verified contract checksums
|
||||
- [ ] Multisig threshold is correctly configured
|
||||
- [ ] Admin keys are securely stored
|
||||
- [ ] Backup of deployment configuration created
|
||||
- [ ] IBC channels will be established post-deployment
|
||||
- [ ] Emergency procedures documented
|
||||
|
||||
## Emergency Contacts
|
||||
|
||||
- Technical Lead: [Contact]
|
||||
- Security Team: [Contact]
|
||||
- Multisig Signers: [List]
|
||||
|
||||
---
|
||||
Generated: $(date)
|
||||
EOF
|
||||
|
||||
log_info "✅ Mainnet deployment preparation complete!"
|
||||
log_info ""
|
||||
log_critical "=== IMPORTANT NEXT STEPS ==="
|
||||
echo "1. Review MAINNET_DEPLOYMENT_INSTRUCTIONS.md"
|
||||
echo "2. Coordinate with multisig signers"
|
||||
echo "3. Execute deployment following the instructions"
|
||||
echo "4. Verify deployment using verify_deployment.sh"
|
||||
echo "5. Establish IBC channels to Sonr mainnet"
|
||||
echo ""
|
||||
log_warning "All unsigned transactions saved to current directory"
|
||||
log_warning "DO NOT share private keys or signed transactions insecurely"
|
||||
}
|
||||
|
||||
# Run main deployment
|
||||
main "$@"
|
||||
@@ -0,0 +1,357 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy Identity DAO Contracts to Cosmos Hub Testnet
|
||||
# This script handles the deployment of all DAO contracts and IBC setup
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
CHAIN_ID="theta-testnet-001" # Cosmos Hub testnet chain ID
|
||||
NODE="https://rpc.sentry-01.theta-testnet.polypore.xyz"
|
||||
GAS_PRICES="0.025uatom"
|
||||
GAS_AUTO="--gas auto --gas-adjustment 1.3"
|
||||
KEYRING="--keyring-backend test"
|
||||
|
||||
# Contract paths
|
||||
CONTRACTS_DIR="$(dirname "$0")/../target/wasm32-unknown-unknown/release"
|
||||
CORE_WASM="${CONTRACTS_DIR}/identity_dao_core.wasm"
|
||||
VOTING_WASM="${CONTRACTS_DIR}/identity_dao_voting.wasm"
|
||||
PROPOSALS_WASM="${CONTRACTS_DIR}/identity_dao_proposals.wasm"
|
||||
PRE_PROPOSE_WASM="${CONTRACTS_DIR}/identity_dao_pre_propose.wasm"
|
||||
|
||||
# Sonr chain configuration for IBC
|
||||
SONR_CHAIN_ID="sonrtest_1-1"
|
||||
SONR_NODE="http://localhost:26657"
|
||||
IBC_VERSION="ics20-1"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Helper functions
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if gaiad is installed
|
||||
check_gaiad() {
|
||||
if ! command -v gaiad &> /dev/null; then
|
||||
log_error "gaiad is not installed. Please install Cosmos Hub client."
|
||||
exit 1
|
||||
fi
|
||||
log_info "Found gaiad: $(gaiad version)"
|
||||
}
|
||||
|
||||
# Check if contracts are built
|
||||
check_contracts() {
|
||||
log_info "Checking for compiled contracts..."
|
||||
|
||||
if [ ! -f "$CORE_WASM" ]; then
|
||||
log_error "Core contract not found at $CORE_WASM"
|
||||
log_info "Building contracts..."
|
||||
cd "$(dirname "$0")/.."
|
||||
cargo build --release --target wasm32-unknown-unknown
|
||||
fi
|
||||
|
||||
log_info "All contracts found"
|
||||
}
|
||||
|
||||
# Optimize contracts for deployment
|
||||
optimize_contracts() {
|
||||
log_info "Optimizing contracts for deployment..."
|
||||
|
||||
# Use CosmWasm optimizer
|
||||
docker run --rm -v "$(pwd)":/code \
|
||||
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \
|
||||
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
|
||||
cosmwasm/optimizer:0.16.0
|
||||
|
||||
log_info "Contract optimization complete"
|
||||
}
|
||||
|
||||
# Upload contract to chain
|
||||
upload_contract() {
|
||||
local wasm_file=$1
|
||||
local contract_name=$2
|
||||
|
||||
log_info "Uploading ${contract_name} contract..."
|
||||
|
||||
TX_HASH=$(gaiad tx wasm store "${wasm_file}" \
|
||||
--from deployer \
|
||||
--chain-id "${CHAIN_ID}" \
|
||||
--node "${NODE}" \
|
||||
--gas-prices "${GAS_PRICES}" \
|
||||
${GAS_AUTO} \
|
||||
${KEYRING} \
|
||||
--broadcast-mode sync \
|
||||
--output json \
|
||||
-y | jq -r '.txhash')
|
||||
|
||||
log_info "Transaction submitted: ${TX_HASH}"
|
||||
sleep 6
|
||||
|
||||
# Get code ID from transaction
|
||||
CODE_ID=$(gaiad query tx "${TX_HASH}" \
|
||||
--node "${NODE}" \
|
||||
--output json | jq -r '.logs[0].events[] | select(.type=="store_code") | .attributes[] | select(.key=="code_id") | .value')
|
||||
|
||||
log_info "${contract_name} uploaded with code ID: ${CODE_ID}"
|
||||
echo "${CODE_ID}"
|
||||
}
|
||||
|
||||
# Instantiate contract
|
||||
instantiate_contract() {
|
||||
local code_id=$1
|
||||
local init_msg=$2
|
||||
local label=$3
|
||||
local admin=$4
|
||||
|
||||
log_info "Instantiating ${label}..."
|
||||
|
||||
TX_HASH=$(gaiad tx wasm instantiate "${code_id}" "${init_msg}" \
|
||||
--from deployer \
|
||||
--label "${label}" \
|
||||
--admin "${admin}" \
|
||||
--chain-id "${CHAIN_ID}" \
|
||||
--node "${NODE}" \
|
||||
--gas-prices "${GAS_PRICES}" \
|
||||
${GAS_AUTO} \
|
||||
${KEYRING} \
|
||||
--broadcast-mode sync \
|
||||
--output json \
|
||||
-y | jq -r '.txhash')
|
||||
|
||||
log_info "Transaction submitted: ${TX_HASH}"
|
||||
sleep 6
|
||||
|
||||
# Get contract address from transaction
|
||||
CONTRACT_ADDR=$(gaiad query tx "${TX_HASH}" \
|
||||
--node "${NODE}" \
|
||||
--output json | jq -r '.logs[0].events[] | select(.type=="instantiate") | .attributes[] | select(.key=="_contract_address") | .value')
|
||||
|
||||
log_info "${label} instantiated at: ${CONTRACT_ADDR}"
|
||||
echo "${CONTRACT_ADDR}"
|
||||
}
|
||||
|
||||
# Setup IBC channel
|
||||
setup_ibc_channel() {
|
||||
local contract_addr=$1
|
||||
local port=$2
|
||||
|
||||
log_info "Setting up IBC channel for ${port}..."
|
||||
|
||||
# Create client for Sonr chain
|
||||
gaiad tx ibc client create \
|
||||
--chain-id "${CHAIN_ID}" \
|
||||
--from deployer \
|
||||
--node "${NODE}" \
|
||||
--gas-prices "${GAS_PRICES}" \
|
||||
${GAS_AUTO} \
|
||||
${KEYRING} \
|
||||
-y
|
||||
|
||||
sleep 6
|
||||
|
||||
# Create connection
|
||||
gaiad tx ibc connection open-init \
|
||||
--chain-id "${CHAIN_ID}" \
|
||||
--from deployer \
|
||||
--node "${NODE}" \
|
||||
--gas-prices "${GAS_PRICES}" \
|
||||
${GAS_AUTO} \
|
||||
${KEYRING} \
|
||||
-y
|
||||
|
||||
sleep 6
|
||||
|
||||
# Create channel
|
||||
gaiad tx ibc channel open-init \
|
||||
--port "${port}" \
|
||||
--version "${IBC_VERSION}" \
|
||||
--chain-id "${CHAIN_ID}" \
|
||||
--from deployer \
|
||||
--node "${NODE}" \
|
||||
--gas-prices "${GAS_PRICES}" \
|
||||
${GAS_AUTO} \
|
||||
${KEYRING} \
|
||||
-y
|
||||
|
||||
log_info "IBC channel setup initiated for ${port}"
|
||||
}
|
||||
|
||||
# Main deployment flow
|
||||
main() {
|
||||
log_info "Starting Identity DAO deployment to Cosmos Hub testnet..."
|
||||
|
||||
# Prerequisites
|
||||
check_gaiad
|
||||
check_contracts
|
||||
|
||||
# Get deployer address
|
||||
DEPLOYER_ADDR=$(gaiad keys show deployer -a ${KEYRING})
|
||||
log_info "Deployer address: ${DEPLOYER_ADDR}"
|
||||
|
||||
# Check balance
|
||||
BALANCE=$(gaiad query bank balances "${DEPLOYER_ADDR}" \
|
||||
--node "${NODE}" \
|
||||
--output json | jq -r '.balances[] | select(.denom=="uatom") | .amount')
|
||||
|
||||
if [ -z "$BALANCE" ] || [ "$BALANCE" -eq "0" ]; then
|
||||
log_error "Deployer has no ATOM tokens. Please fund the account."
|
||||
log_info "Visit https://discord.com/channels/669268347736686612/953641721746206780 for testnet faucet"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Deployer balance: ${BALANCE} uatom"
|
||||
|
||||
# Optimize contracts
|
||||
optimize_contracts
|
||||
|
||||
# Upload contracts
|
||||
log_info "Uploading contracts to chain..."
|
||||
CORE_CODE_ID=$(upload_contract "${CONTRACTS_DIR}/identity_dao_core-optimized.wasm" "Identity DAO Core")
|
||||
VOTING_CODE_ID=$(upload_contract "${CONTRACTS_DIR}/identity_dao_voting-optimized.wasm" "DID Voting")
|
||||
PROPOSALS_CODE_ID=$(upload_contract "${CONTRACTS_DIR}/identity_dao_proposals-optimized.wasm" "Proposals")
|
||||
PRE_PROPOSE_CODE_ID=$(upload_contract "${CONTRACTS_DIR}/identity_dao_pre_propose-optimized.wasm" "Pre-Propose")
|
||||
|
||||
# Save code IDs
|
||||
echo "CORE_CODE_ID=${CORE_CODE_ID}" > deployment_ids.env
|
||||
echo "VOTING_CODE_ID=${VOTING_CODE_ID}" >> deployment_ids.env
|
||||
echo "PROPOSALS_CODE_ID=${PROPOSALS_CODE_ID}" >> deployment_ids.env
|
||||
echo "PRE_PROPOSE_CODE_ID=${PRE_PROPOSE_CODE_ID}" >> deployment_ids.env
|
||||
|
||||
# Instantiate Core contract
|
||||
CORE_INIT_MSG='{
|
||||
"name": "Sonr Identity DAO",
|
||||
"description": "Decentralized Identity Governance on Cosmos Hub",
|
||||
"voting_config": {
|
||||
"threshold": "0.51",
|
||||
"quorum": "0.1",
|
||||
"voting_period": 604800,
|
||||
"proposal_deposit": "1000000"
|
||||
},
|
||||
"admin": "'${DEPLOYER_ADDR}'",
|
||||
"enable_did_integration": true
|
||||
}'
|
||||
|
||||
CORE_ADDR=$(instantiate_contract "${CORE_CODE_ID}" "${CORE_INIT_MSG}" "sonr-identity-dao-core" "${DEPLOYER_ADDR}")
|
||||
echo "CORE_ADDR=${CORE_ADDR}" >> deployment_ids.env
|
||||
|
||||
# Instantiate Voting contract
|
||||
VOTING_INIT_MSG='{
|
||||
"dao_core": "'${CORE_ADDR}'",
|
||||
"min_verification_level": 1,
|
||||
"use_reputation_weight": true
|
||||
}'
|
||||
|
||||
VOTING_ADDR=$(instantiate_contract "${VOTING_CODE_ID}" "${VOTING_INIT_MSG}" "sonr-did-voting" "${CORE_ADDR}")
|
||||
echo "VOTING_ADDR=${VOTING_ADDR}" >> deployment_ids.env
|
||||
|
||||
# Instantiate Proposals contract
|
||||
PROPOSALS_INIT_MSG='{
|
||||
"dao_core": "'${CORE_ADDR}'",
|
||||
"voting_module": "'${VOTING_ADDR}'",
|
||||
"pre_propose_module": null,
|
||||
"proposal_deposit": "1000000",
|
||||
"max_voting_period": 604800
|
||||
}'
|
||||
|
||||
PROPOSALS_ADDR=$(instantiate_contract "${PROPOSALS_CODE_ID}" "${PROPOSALS_INIT_MSG}" "sonr-proposals" "${CORE_ADDR}")
|
||||
echo "PROPOSALS_ADDR=${PROPOSALS_ADDR}" >> deployment_ids.env
|
||||
|
||||
# Instantiate Pre-Propose contract
|
||||
PRE_PROPOSE_INIT_MSG='{
|
||||
"dao_core": "'${CORE_ADDR}'",
|
||||
"proposal_module": "'${PROPOSALS_ADDR}'",
|
||||
"require_verified_did": true,
|
||||
"min_reputation_score": 10,
|
||||
"deposit_amount": "1000000",
|
||||
"deposit_denom": "uatom"
|
||||
}'
|
||||
|
||||
PRE_PROPOSE_ADDR=$(instantiate_contract "${PRE_PROPOSE_CODE_ID}" "${PRE_PROPOSE_INIT_MSG}" "sonr-pre-propose" "${CORE_ADDR}")
|
||||
echo "PRE_PROPOSE_ADDR=${PRE_PROPOSE_ADDR}" >> deployment_ids.env
|
||||
|
||||
# Register modules with Core
|
||||
log_info "Registering modules with Core contract..."
|
||||
|
||||
REGISTER_VOTING_MSG='{"register_module":{"module_type":"voting","module_address":"'${VOTING_ADDR}'"}}'
|
||||
gaiad tx wasm execute "${CORE_ADDR}" "${REGISTER_VOTING_MSG}" \
|
||||
--from deployer \
|
||||
--chain-id "${CHAIN_ID}" \
|
||||
--node "${NODE}" \
|
||||
--gas-prices "${GAS_PRICES}" \
|
||||
${GAS_AUTO} \
|
||||
${KEYRING} \
|
||||
-y
|
||||
|
||||
sleep 6
|
||||
|
||||
REGISTER_PROPOSALS_MSG='{"register_module":{"module_type":"proposal","module_address":"'${PROPOSALS_ADDR}'"}}'
|
||||
gaiad tx wasm execute "${CORE_ADDR}" "${REGISTER_PROPOSALS_MSG}" \
|
||||
--from deployer \
|
||||
--chain-id "${CHAIN_ID}" \
|
||||
--node "${NODE}" \
|
||||
--gas-prices "${GAS_PRICES}" \
|
||||
${GAS_AUTO} \
|
||||
${KEYRING} \
|
||||
-y
|
||||
|
||||
sleep 6
|
||||
|
||||
REGISTER_PRE_PROPOSE_MSG='{"register_module":{"module_type":"pre_propose","module_address":"'${PRE_PROPOSE_ADDR}'"}}'
|
||||
gaiad tx wasm execute "${CORE_ADDR}" "${REGISTER_PRE_PROPOSE_MSG}" \
|
||||
--from deployer \
|
||||
--chain-id "${CHAIN_ID}" \
|
||||
--node "${NODE}" \
|
||||
--gas-prices "${GAS_PRICES}" \
|
||||
${GAS_AUTO} \
|
||||
${KEYRING} \
|
||||
-y
|
||||
|
||||
sleep 6
|
||||
|
||||
# Setup IBC channels for Sonr integration
|
||||
log_info "Setting up IBC channels for Sonr integration..."
|
||||
setup_ibc_channel "${VOTING_ADDR}" "wasm.${VOTING_ADDR}"
|
||||
|
||||
# Update Pre-Propose module in Proposals contract
|
||||
UPDATE_PRE_PROPOSE_MSG='{"update_pre_propose_module":{"module":"'${PRE_PROPOSE_ADDR}'"}}'
|
||||
gaiad tx wasm execute "${PROPOSALS_ADDR}" "${UPDATE_PRE_PROPOSE_MSG}" \
|
||||
--from deployer \
|
||||
--chain-id "${CHAIN_ID}" \
|
||||
--node "${NODE}" \
|
||||
--gas-prices "${GAS_PRICES}" \
|
||||
${GAS_AUTO} \
|
||||
${KEYRING} \
|
||||
-y
|
||||
|
||||
log_info "✅ Deployment complete!"
|
||||
log_info "Deployment details saved to deployment_ids.env"
|
||||
|
||||
# Display summary
|
||||
echo ""
|
||||
log_info "=== Deployment Summary ==="
|
||||
echo "Core Contract: ${CORE_ADDR}"
|
||||
echo "Voting Contract: ${VOTING_ADDR}"
|
||||
echo "Proposals Contract: ${PROPOSALS_ADDR}"
|
||||
echo "Pre-Propose Contract: ${PRE_PROPOSE_ADDR}"
|
||||
echo ""
|
||||
log_info "Next steps:"
|
||||
echo "1. Verify contract deployment: ./scripts/verify_deployment.sh"
|
||||
echo "2. Test IBC connectivity: ./scripts/test_ibc.sh"
|
||||
echo "3. Create first proposal: ./scripts/create_proposal.sh"
|
||||
}
|
||||
|
||||
# Run main deployment
|
||||
main "$@"
|
||||
@@ -0,0 +1,221 @@
|
||||
#!/bin/bash
|
||||
# Identity DAO Migration Script
|
||||
# Migrates Identity DAO contracts to new versions
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
CHAIN_ID="${CHAIN_ID:-sonrtest_1-1}"
|
||||
NODE="${NODE:-http://localhost:26657}"
|
||||
KEYRING="${KEYRING:-test}"
|
||||
ADMIN="${ADMIN:-deployer}"
|
||||
GAS_PRICES="${GAS_PRICES:-0.025usnr}"
|
||||
GAS_ADJUSTMENT="${GAS_ADJUSTMENT:-1.5}"
|
||||
|
||||
# Contract paths
|
||||
CONTRACTS_DIR="$(dirname "$0")/../artifacts"
|
||||
ADDRESSES_FILE="${CONTRACTS_DIR}/addresses.json"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Helper functions
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
# Check dependencies
|
||||
check_dependencies() {
|
||||
log_info "Checking dependencies..."
|
||||
|
||||
if ! command -v snrd &> /dev/null; then
|
||||
log_error "snrd is not installed. Please run 'make install'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v jq &> /dev/null; then
|
||||
log_error "jq is not installed. Please install jq"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$ADDRESSES_FILE" ]; then
|
||||
log_error "Contract addresses file not found. Please deploy first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "All dependencies satisfied"
|
||||
}
|
||||
|
||||
# Store new contract code
|
||||
store_new_code() {
|
||||
local wasm_file=$1
|
||||
local contract_name=$2
|
||||
|
||||
log_info "Storing new $contract_name contract code..."
|
||||
|
||||
if [ ! -f "$wasm_file" ]; then
|
||||
log_error "Contract file not found: $wasm_file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local tx_result=$(snrd tx wasm store "$wasm_file" \
|
||||
--from "$ADMIN" \
|
||||
--chain-id "$CHAIN_ID" \
|
||||
--node "$NODE" \
|
||||
--gas-prices "$GAS_PRICES" \
|
||||
--gas-adjustment "$GAS_ADJUSTMENT" \
|
||||
--keyring-backend "$KEYRING" \
|
||||
--output json \
|
||||
--yes)
|
||||
|
||||
local tx_hash=$(echo "$tx_result" | jq -r .txhash)
|
||||
|
||||
# Wait for transaction
|
||||
sleep 6
|
||||
|
||||
# Get code ID from events
|
||||
local code_id=$(snrd query tx "$tx_hash" \
|
||||
--node "$NODE" \
|
||||
--output json | jq -r '.events[] | select(.type=="store_code") | .attributes[] | select(.key=="code_id") | .value')
|
||||
|
||||
if [ -z "$code_id" ]; then
|
||||
log_error "Failed to get code ID for $contract_name"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "$contract_name new code stored with ID: $code_id"
|
||||
echo "$code_id"
|
||||
}
|
||||
|
||||
# Migrate contract
|
||||
migrate_contract() {
|
||||
local contract_addr=$1
|
||||
local new_code_id=$2
|
||||
local migrate_msg=$3
|
||||
local contract_name=$4
|
||||
|
||||
log_info "Migrating $contract_name contract..."
|
||||
|
||||
local tx_result=$(snrd tx wasm migrate "$contract_addr" "$new_code_id" "$migrate_msg" \
|
||||
--from "$ADMIN" \
|
||||
--chain-id "$CHAIN_ID" \
|
||||
--node "$NODE" \
|
||||
--gas-prices "$GAS_PRICES" \
|
||||
--gas-adjustment "$GAS_ADJUSTMENT" \
|
||||
--keyring-backend "$KEYRING" \
|
||||
--output json \
|
||||
--yes)
|
||||
|
||||
local tx_hash=$(echo "$tx_result" | jq -r .txhash)
|
||||
|
||||
# Wait for transaction
|
||||
sleep 6
|
||||
|
||||
# Check migration success
|
||||
local tx_query=$(snrd query tx "$tx_hash" \
|
||||
--node "$NODE" \
|
||||
--output json)
|
||||
|
||||
local code=$(echo "$tx_query" | jq -r .code)
|
||||
|
||||
if [ "$code" != "0" ]; then
|
||||
log_error "Migration failed for $contract_name"
|
||||
echo "$tx_query" | jq -r .raw_log
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "$contract_name migrated successfully"
|
||||
}
|
||||
|
||||
# Main migration flow
|
||||
main() {
|
||||
local MODULE=$1
|
||||
|
||||
log_info "Starting Identity DAO migration..."
|
||||
|
||||
# Check dependencies
|
||||
check_dependencies
|
||||
|
||||
# Load contract addresses
|
||||
CORE_ADDR=$(jq -r .core "$ADDRESSES_FILE")
|
||||
VOTING_ADDR=$(jq -r .voting "$ADDRESSES_FILE")
|
||||
PROPOSALS_ADDR=$(jq -r .proposals "$ADDRESSES_FILE")
|
||||
PRE_PROPOSE_ADDR=$(jq -r .pre_propose "$ADDRESSES_FILE")
|
||||
|
||||
log_info "Loaded contract addresses from deployment"
|
||||
|
||||
# Migrate specific module or all
|
||||
case "$MODULE" in
|
||||
core)
|
||||
log_info "Migrating Core Module..."
|
||||
NEW_CODE_ID=$(store_new_code "${CONTRACTS_DIR}/identity_dao_core.wasm" "Core")
|
||||
MIGRATE_MSG='{"update_version":{}}'
|
||||
migrate_contract "$CORE_ADDR" "$NEW_CODE_ID" "$MIGRATE_MSG" "Core"
|
||||
;;
|
||||
voting)
|
||||
log_info "Migrating Voting Module..."
|
||||
NEW_CODE_ID=$(store_new_code "${CONTRACTS_DIR}/identity_dao_voting.wasm" "Voting")
|
||||
MIGRATE_MSG='{"update_version":{}}'
|
||||
migrate_contract "$VOTING_ADDR" "$NEW_CODE_ID" "$MIGRATE_MSG" "Voting"
|
||||
;;
|
||||
proposals)
|
||||
log_info "Migrating Proposals Module..."
|
||||
NEW_CODE_ID=$(store_new_code "${CONTRACTS_DIR}/identity_dao_proposals.wasm" "Proposals")
|
||||
MIGRATE_MSG='{"update_version":{}}'
|
||||
migrate_contract "$PROPOSALS_ADDR" "$NEW_CODE_ID" "$MIGRATE_MSG" "Proposals"
|
||||
;;
|
||||
pre-propose)
|
||||
log_info "Migrating Pre-Propose Module..."
|
||||
NEW_CODE_ID=$(store_new_code "${CONTRACTS_DIR}/identity_dao_pre_propose.wasm" "Pre-Propose")
|
||||
MIGRATE_MSG='{"update_version":{}}'
|
||||
migrate_contract "$PRE_PROPOSE_ADDR" "$NEW_CODE_ID" "$MIGRATE_MSG" "Pre-Propose"
|
||||
;;
|
||||
all)
|
||||
log_info "Migrating all modules..."
|
||||
|
||||
# Store all new codes first
|
||||
CORE_NEW_CODE=$(store_new_code "${CONTRACTS_DIR}/identity_dao_core.wasm" "Core")
|
||||
VOTING_NEW_CODE=$(store_new_code "${CONTRACTS_DIR}/identity_dao_voting.wasm" "Voting")
|
||||
PROPOSALS_NEW_CODE=$(store_new_code "${CONTRACTS_DIR}/identity_dao_proposals.wasm" "Proposals")
|
||||
PRE_PROPOSE_NEW_CODE=$(store_new_code "${CONTRACTS_DIR}/identity_dao_pre_propose.wasm" "Pre-Propose")
|
||||
|
||||
# Migrate in order
|
||||
MIGRATE_MSG='{"update_version":{}}'
|
||||
migrate_contract "$CORE_ADDR" "$CORE_NEW_CODE" "$MIGRATE_MSG" "Core"
|
||||
migrate_contract "$VOTING_ADDR" "$VOTING_NEW_CODE" "$MIGRATE_MSG" "Voting"
|
||||
migrate_contract "$PRE_PROPOSE_ADDR" "$PRE_PROPOSE_NEW_CODE" "$MIGRATE_MSG" "Pre-Propose"
|
||||
migrate_contract "$PROPOSALS_ADDR" "$PROPOSALS_NEW_CODE" "$MIGRATE_MSG" "Proposals"
|
||||
;;
|
||||
*)
|
||||
log_error "Invalid module: $MODULE"
|
||||
log_info "Usage: $0 [core|voting|proposals|pre-propose|all]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Save migration info
|
||||
cat > "${CONTRACTS_DIR}/migration_$(date +%Y%m%d_%H%M%S).json" <<EOF
|
||||
{
|
||||
"module": "$MODULE",
|
||||
"migrated_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||||
"admin": "$ADMIN",
|
||||
"chain_id": "$CHAIN_ID"
|
||||
}
|
||||
EOF
|
||||
|
||||
log_info "Migration complete!"
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
@@ -0,0 +1,392 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Setup IBC channels between Cosmos Hub testnet and Sonr chain
|
||||
# for Identity DAO cross-chain communication
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Helper functions
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
log_debug() {
|
||||
echo -e "${BLUE}[DEBUG]${NC} $1"
|
||||
}
|
||||
|
||||
# Configuration
|
||||
# Cosmos Hub testnet
|
||||
HUB_CHAIN_ID="theta-testnet-001"
|
||||
HUB_RPC="https://rpc.sentry-01.theta-testnet.polypore.xyz:443"
|
||||
HUB_GRPC="grpc.sentry-01.theta-testnet.polypore.xyz:9090"
|
||||
HUB_PREFIX="cosmos"
|
||||
HUB_DENOM="uatom"
|
||||
HUB_GAS_PRICES="0.025uatom"
|
||||
|
||||
# Sonr testnet
|
||||
SONR_CHAIN_ID="sonrtest_1-1"
|
||||
SONR_RPC="http://localhost:26657"
|
||||
SONR_GRPC="localhost:9090"
|
||||
SONR_PREFIX="sonr"
|
||||
SONR_DENOM="usnr"
|
||||
SONR_GAS_PRICES="0.025usnr"
|
||||
|
||||
# IBC Configuration
|
||||
IBC_VERSION="ics20-1"
|
||||
RELAYER_NAME="identity-dao-relayer"
|
||||
RELAYER_HOME="${HOME}/.relayer"
|
||||
PATH_NAME="hub-sonr"
|
||||
|
||||
# Contract ports (from deployment)
|
||||
VOTING_PORT="wasm.cosmos1voting_contract_address" # Will be replaced with actual address
|
||||
PROPOSALS_PORT="wasm.cosmos1proposals_contract_address"
|
||||
|
||||
# Check if Hermes relayer is installed
|
||||
check_hermes() {
|
||||
if ! command -v hermes &> /dev/null; then
|
||||
log_error "Hermes relayer not found. Installing..."
|
||||
|
||||
# Install Hermes based on OS
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
brew install hermes
|
||||
else
|
||||
# Linux installation
|
||||
curl -L https://github.com/informalsystems/hermes/releases/download/v1.8.0/hermes-v1.8.0-x86_64-unknown-linux-gnu.tar.gz | tar xz
|
||||
sudo mv hermes /usr/local/bin/
|
||||
fi
|
||||
fi
|
||||
|
||||
log_info "Found Hermes: $(hermes version)"
|
||||
}
|
||||
|
||||
# Initialize Hermes configuration
|
||||
init_hermes_config() {
|
||||
log_info "Initializing Hermes configuration..."
|
||||
|
||||
mkdir -p "${RELAYER_HOME}"
|
||||
|
||||
cat > "${RELAYER_HOME}/config.toml" << EOF
|
||||
[global]
|
||||
log_level = 'info'
|
||||
|
||||
[mode]
|
||||
|
||||
[mode.clients]
|
||||
enabled = true
|
||||
refresh = true
|
||||
misbehaviour = true
|
||||
|
||||
[mode.connections]
|
||||
enabled = true
|
||||
|
||||
[mode.channels]
|
||||
enabled = true
|
||||
|
||||
[mode.packets]
|
||||
enabled = true
|
||||
clear_interval = 100
|
||||
clear_on_start = true
|
||||
tx_confirmation = true
|
||||
|
||||
[rest]
|
||||
enabled = true
|
||||
host = '127.0.0.1'
|
||||
port = 3000
|
||||
|
||||
[telemetry]
|
||||
enabled = false
|
||||
host = '127.0.0.1'
|
||||
port = 3001
|
||||
|
||||
# Cosmos Hub testnet configuration
|
||||
[[chains]]
|
||||
id = '${HUB_CHAIN_ID}'
|
||||
type = 'CosmosSdk'
|
||||
rpc_addr = '${HUB_RPC}'
|
||||
grpc_addr = '${HUB_GRPC}'
|
||||
event_source = { mode = 'push', url = '${HUB_RPC/https/wss}/websocket', batch_delay = '500ms' }
|
||||
rpc_timeout = '10s'
|
||||
account_prefix = '${HUB_PREFIX}'
|
||||
key_name = 'hub-relayer'
|
||||
store_prefix = 'ibc'
|
||||
gas_price = { price = 0.025, denom = '${HUB_DENOM}' }
|
||||
max_gas = 6000000
|
||||
default_gas = 1000000
|
||||
gas_multiplier = 1.2
|
||||
max_msg_num = 30
|
||||
max_tx_size = 2097152
|
||||
clock_drift = '5s'
|
||||
max_block_time = '30s'
|
||||
memo_prefix = 'Identity DAO IBC'
|
||||
trusting_period = '14days'
|
||||
trust_threshold = { numerator = '1', denominator = '3' }
|
||||
|
||||
[chains.packet_filter]
|
||||
policy = 'allow'
|
||||
list = [
|
||||
['wasm*', '*'], # Allow all CosmWasm IBC traffic
|
||||
]
|
||||
|
||||
# Sonr testnet configuration
|
||||
[[chains]]
|
||||
id = '${SONR_CHAIN_ID}'
|
||||
type = 'CosmosSdk'
|
||||
rpc_addr = '${SONR_RPC}'
|
||||
grpc_addr = '${SONR_GRPC}'
|
||||
event_source = { mode = 'push', url = '${SONR_RPC/http/ws}/websocket', batch_delay = '500ms' }
|
||||
rpc_timeout = '10s'
|
||||
account_prefix = '${SONR_PREFIX}'
|
||||
key_name = 'sonr-relayer'
|
||||
store_prefix = 'ibc'
|
||||
gas_price = { price = 0.025, denom = '${SONR_DENOM}' }
|
||||
max_gas = 6000000
|
||||
default_gas = 1000000
|
||||
gas_multiplier = 1.2
|
||||
max_msg_num = 30
|
||||
max_tx_size = 2097152
|
||||
clock_drift = '5s'
|
||||
max_block_time = '30s'
|
||||
memo_prefix = 'Identity DAO IBC'
|
||||
trusting_period = '14days'
|
||||
trust_threshold = { numerator = '1', denominator = '3' }
|
||||
|
||||
[chains.packet_filter]
|
||||
policy = 'allow'
|
||||
list = [
|
||||
['transfer', 'channel-*'],
|
||||
['wasm*', '*'],
|
||||
]
|
||||
EOF
|
||||
|
||||
log_info "Hermes config created at ${RELAYER_HOME}/config.toml"
|
||||
}
|
||||
|
||||
# Add relayer keys
|
||||
add_relayer_keys() {
|
||||
log_info "Adding relayer keys..."
|
||||
|
||||
# Add Cosmos Hub key
|
||||
log_info "Adding Cosmos Hub relayer key..."
|
||||
hermes keys add \
|
||||
--chain "${HUB_CHAIN_ID}" \
|
||||
--mnemonic-file hub-relayer.mnemonic \
|
||||
--key-name hub-relayer
|
||||
|
||||
# Add Sonr key
|
||||
log_info "Adding Sonr relayer key..."
|
||||
hermes keys add \
|
||||
--chain "${SONR_CHAIN_ID}" \
|
||||
--mnemonic-file sonr-relayer.mnemonic \
|
||||
--key-name sonr-relayer
|
||||
}
|
||||
|
||||
# Create IBC clients
|
||||
create_clients() {
|
||||
log_info "Creating IBC clients..."
|
||||
|
||||
# Create client on Cosmos Hub for Sonr
|
||||
log_info "Creating Sonr client on Cosmos Hub..."
|
||||
hermes create client \
|
||||
--host-chain "${HUB_CHAIN_ID}" \
|
||||
--reference-chain "${SONR_CHAIN_ID}"
|
||||
|
||||
# Create client on Sonr for Cosmos Hub
|
||||
log_info "Creating Cosmos Hub client on Sonr..."
|
||||
hermes create client \
|
||||
--host-chain "${SONR_CHAIN_ID}" \
|
||||
--reference-chain "${HUB_CHAIN_ID}"
|
||||
}
|
||||
|
||||
# Create IBC connection
|
||||
create_connection() {
|
||||
log_info "Creating IBC connection..."
|
||||
|
||||
hermes create connection \
|
||||
--a-chain "${HUB_CHAIN_ID}" \
|
||||
--b-chain "${SONR_CHAIN_ID}"
|
||||
}
|
||||
|
||||
# Create IBC channels for contracts
|
||||
create_channels() {
|
||||
log_info "Creating IBC channels for Identity DAO contracts..."
|
||||
|
||||
# Load deployed contract addresses
|
||||
if [ -f "deployment_ids.env" ]; then
|
||||
source deployment_ids.env
|
||||
else
|
||||
log_error "deployment_ids.env not found. Please deploy contracts first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Channel for Voting contract to query x/did module
|
||||
log_info "Creating channel for Voting contract..."
|
||||
hermes create channel \
|
||||
--a-chain "${HUB_CHAIN_ID}" \
|
||||
--a-port "wasm.${VOTING_ADDR}" \
|
||||
--b-port "did" \
|
||||
--order unordered \
|
||||
--version "did-ibc-v1"
|
||||
|
||||
# Channel for Proposals contract
|
||||
log_info "Creating channel for Proposals contract..."
|
||||
hermes create channel \
|
||||
--a-chain "${HUB_CHAIN_ID}" \
|
||||
--a-port "wasm.${PROPOSALS_ADDR}" \
|
||||
--b-port "dwn" \
|
||||
--order unordered \
|
||||
--version "dwn-ibc-v1"
|
||||
|
||||
# Standard transfer channel for treasury operations
|
||||
log_info "Creating transfer channel..."
|
||||
hermes create channel \
|
||||
--a-chain "${HUB_CHAIN_ID}" \
|
||||
--a-port "transfer" \
|
||||
--b-port "transfer" \
|
||||
--order unordered \
|
||||
--version "${IBC_VERSION}"
|
||||
}
|
||||
|
||||
# Start relayer
|
||||
start_relayer() {
|
||||
log_info "Starting Hermes relayer..."
|
||||
|
||||
# Start in background
|
||||
hermes start &
|
||||
RELAYER_PID=$!
|
||||
|
||||
log_info "Relayer started with PID: ${RELAYER_PID}"
|
||||
echo "${RELAYER_PID}" > relayer.pid
|
||||
|
||||
# Give it time to establish connections
|
||||
sleep 10
|
||||
|
||||
# Check if relayer is running
|
||||
if ps -p ${RELAYER_PID} > /dev/null; then
|
||||
log_info "Relayer is running successfully"
|
||||
else
|
||||
log_error "Relayer failed to start"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Query IBC channels
|
||||
query_channels() {
|
||||
log_info "Querying established IBC channels..."
|
||||
|
||||
# Query channels on Cosmos Hub
|
||||
log_info "Channels on Cosmos Hub:"
|
||||
hermes query channels --chain "${HUB_CHAIN_ID}"
|
||||
|
||||
# Query channels on Sonr
|
||||
log_info "Channels on Sonr:"
|
||||
hermes query channels --chain "${SONR_CHAIN_ID}"
|
||||
}
|
||||
|
||||
# Test IBC connectivity
|
||||
test_ibc() {
|
||||
log_info "Testing IBC connectivity..."
|
||||
|
||||
# Test transfer channel
|
||||
log_info "Testing transfer channel..."
|
||||
|
||||
# Get channel IDs
|
||||
TRANSFER_CHANNEL=$(hermes query channels --chain "${HUB_CHAIN_ID}" | grep transfer | head -1 | awk '{print $1}')
|
||||
|
||||
if [ -n "$TRANSFER_CHANNEL" ]; then
|
||||
log_info "Transfer channel: ${TRANSFER_CHANNEL}"
|
||||
|
||||
# Send test transfer
|
||||
gaiad tx ibc-transfer transfer \
|
||||
transfer "${TRANSFER_CHANNEL}" \
|
||||
sonr1test_address \
|
||||
1000uatom \
|
||||
--from hub-relayer \
|
||||
--chain-id "${HUB_CHAIN_ID}" \
|
||||
--node "${HUB_RPC}" \
|
||||
--gas-prices "${HUB_GAS_PRICES}" \
|
||||
--packet-timeout-height 0-1000 \
|
||||
-y
|
||||
|
||||
log_info "Test transfer sent"
|
||||
else
|
||||
log_warning "No transfer channel found"
|
||||
fi
|
||||
}
|
||||
|
||||
# Monitor IBC packets
|
||||
monitor_packets() {
|
||||
log_info "Monitoring IBC packet flow..."
|
||||
|
||||
hermes query packet pending \
|
||||
--chain "${HUB_CHAIN_ID}" \
|
||||
--port transfer \
|
||||
--channel "${TRANSFER_CHANNEL}"
|
||||
}
|
||||
|
||||
# Main IBC setup flow
|
||||
main() {
|
||||
log_info "Starting IBC setup for Identity DAO..."
|
||||
|
||||
# Check requirements
|
||||
check_hermes
|
||||
|
||||
# Initialize configuration
|
||||
init_hermes_config
|
||||
|
||||
# Check if keys exist or need to be created
|
||||
if [ ! -f "hub-relayer.mnemonic" ] || [ ! -f "sonr-relayer.mnemonic" ]; then
|
||||
log_error "Relayer mnemonics not found. Please create:"
|
||||
log_info "1. hub-relayer.mnemonic - Funded account on Cosmos Hub testnet"
|
||||
log_info "2. sonr-relayer.mnemonic - Funded account on Sonr testnet"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Add keys
|
||||
add_relayer_keys
|
||||
|
||||
# Create IBC infrastructure
|
||||
create_clients
|
||||
create_connection
|
||||
create_channels
|
||||
|
||||
# Start relayer
|
||||
start_relayer
|
||||
|
||||
# Query established channels
|
||||
query_channels
|
||||
|
||||
# Test connectivity
|
||||
test_ibc
|
||||
|
||||
# Monitor packets
|
||||
monitor_packets
|
||||
|
||||
log_info "✅ IBC setup complete!"
|
||||
log_info ""
|
||||
log_info "=== IBC Summary ==="
|
||||
log_info "Relayer PID: $(cat relayer.pid)"
|
||||
log_info "Config: ${RELAYER_HOME}/config.toml"
|
||||
log_info ""
|
||||
log_info "Next steps:"
|
||||
log_info "1. Monitor relayer logs: hermes start"
|
||||
log_info "2. Query channels: hermes query channels --chain ${HUB_CHAIN_ID}"
|
||||
log_info "3. Test cross-chain queries: ./scripts/test_did_query.sh"
|
||||
}
|
||||
|
||||
# Run main IBC setup
|
||||
main "$@"
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test script for Identity DAO IBC Integration
|
||||
# Validates cross-chain DID verification between Cosmos Hub and Sonr
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
DEPLOYMENT_FILE="${1:-cosmos-hub-deployment.json}"
|
||||
TEST_DID="did:sonr:test123"
|
||||
TEST_ADDRESS="cosmos1test..."
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}Identity DAO IBC Integration Tests${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
|
||||
# Load deployment info
|
||||
if [ ! -f "$DEPLOYMENT_FILE" ]; then
|
||||
echo -e "${RED}Error: Deployment file not found: $DEPLOYMENT_FILE${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract contract addresses
|
||||
VOTING_ADDR=$(jq -r '.contracts.voting.address' "$DEPLOYMENT_FILE")
|
||||
PROPOSALS_ADDR=$(jq -r '.contracts.proposals.address' "$DEPLOYMENT_FILE")
|
||||
VOTING_CHANNEL=$(jq -r '.contracts.voting.ibc_channel' "$DEPLOYMENT_FILE")
|
||||
CHAIN_ID=$(jq -r '.chain_id' "$DEPLOYMENT_FILE")
|
||||
|
||||
echo "Using contracts from deployment:"
|
||||
echo " Voting: $VOTING_ADDR (Channel: $VOTING_CHANNEL)"
|
||||
echo " Proposals: $PROPOSALS_ADDR"
|
||||
echo ""
|
||||
|
||||
# Function to run test
|
||||
run_test() {
|
||||
local test_name=$1
|
||||
local test_cmd=$2
|
||||
|
||||
echo -ne "${YELLOW}Testing: ${test_name}...${NC}"
|
||||
|
||||
if eval "$test_cmd" > /dev/null 2>&1; then
|
||||
echo -e " ${GREEN}✓${NC}"
|
||||
return 0
|
||||
else
|
||||
echo -e " ${RED}✗${NC}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Test 1: Check IBC channel status
|
||||
echo -e "${BLUE}1. Checking IBC Channel Status${NC}"
|
||||
|
||||
CHANNEL_STATUS=$(hermes query channel end \
|
||||
--chain "$CHAIN_ID" \
|
||||
--port "wasm.$VOTING_ADDR" \
|
||||
--channel "$VOTING_CHANNEL" \
|
||||
2>/dev/null | jq -r '.state')
|
||||
|
||||
if [ "$CHANNEL_STATUS" = "Open" ]; then
|
||||
echo -e "${GREEN}✓ Channel is OPEN${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Channel status: $CHANNEL_STATUS${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test 2: Query Sonr chain for DIDs
|
||||
echo -e "${BLUE}2. Querying Sonr DIDs via IBC${NC}"
|
||||
|
||||
# Send IBC packet to query DID
|
||||
QUERY_MSG='{
|
||||
"send_did_query": {
|
||||
"did": "'$TEST_DID'",
|
||||
"channel": "'$VOTING_CHANNEL'"
|
||||
}
|
||||
}'
|
||||
|
||||
TX_HASH=$(gaiad tx wasm execute "$VOTING_ADDR" "$QUERY_MSG" \
|
||||
--from deployer \
|
||||
--chain-id "$CHAIN_ID" \
|
||||
--gas-prices 0.025uatom \
|
||||
--gas auto \
|
||||
--gas-adjustment 1.5 \
|
||||
--yes \
|
||||
--output json 2>/dev/null | jq -r '.txhash')
|
||||
|
||||
echo "Query transaction: $TX_HASH"
|
||||
sleep 6
|
||||
|
||||
# Check if packet was acknowledged
|
||||
PACKET_ACK=$(hermes query packet acks \
|
||||
--chain "$CHAIN_ID" \
|
||||
--port "wasm.$VOTING_ADDR" \
|
||||
--channel "$VOTING_CHANNEL" \
|
||||
2>/dev/null | jq -r '.acks | length')
|
||||
|
||||
if [ "$PACKET_ACK" -gt 0 ]; then
|
||||
echo -e "${GREEN}✓ IBC packet acknowledged${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ No acknowledgment yet (may be pending)${NC}"
|
||||
fi
|
||||
|
||||
# Test 3: Update voter with DID verification
|
||||
echo -e "${BLUE}3. Testing Voter Update with DID${NC}"
|
||||
|
||||
UPDATE_MSG='{
|
||||
"update_voter": {
|
||||
"did": "'$TEST_DID'",
|
||||
"address": "'$TEST_ADDRESS'"
|
||||
}
|
||||
}'
|
||||
|
||||
UPDATE_TX=$(gaiad tx wasm execute "$VOTING_ADDR" "$UPDATE_MSG" \
|
||||
--from deployer \
|
||||
--chain-id "$CHAIN_ID" \
|
||||
--gas-prices 0.025uatom \
|
||||
--gas auto \
|
||||
--gas-adjustment 1.5 \
|
||||
--yes \
|
||||
--output json 2>/dev/null | jq -r '.txhash')
|
||||
|
||||
echo "Update transaction: $UPDATE_TX"
|
||||
sleep 6
|
||||
|
||||
# Query voter info
|
||||
VOTER_QUERY='{
|
||||
"voter_info": {
|
||||
"did": "'$TEST_DID'"
|
||||
}
|
||||
}'
|
||||
|
||||
VOTER_INFO=$(gaiad query wasm contract-state smart "$VOTING_ADDR" "$VOTER_QUERY" \
|
||||
--output json 2>/dev/null | jq -r '.data')
|
||||
|
||||
if [ "$VOTER_INFO" != "null" ]; then
|
||||
echo -e "${GREEN}✓ Voter registered successfully${NC}"
|
||||
echo "Voter info: $VOTER_INFO"
|
||||
else
|
||||
echo -e "${RED}✗ Voter not found${NC}"
|
||||
fi
|
||||
|
||||
# Test 4: Create proposal through IBC
|
||||
echo -e "${BLUE}4. Testing Proposal Creation${NC}"
|
||||
|
||||
PROPOSAL_MSG='{
|
||||
"propose": {
|
||||
"title": "Test IBC Proposal",
|
||||
"description": "Testing cross-chain governance",
|
||||
"msgs": [],
|
||||
"proposer_did": "'$TEST_DID'"
|
||||
}
|
||||
}'
|
||||
|
||||
PROPOSAL_TX=$(gaiad tx wasm execute "$PROPOSALS_ADDR" "$PROPOSAL_MSG" \
|
||||
--from deployer \
|
||||
--chain-id "$CHAIN_ID" \
|
||||
--gas-prices 0.025uatom \
|
||||
--gas auto \
|
||||
--gas-adjustment 1.5 \
|
||||
--yes \
|
||||
--output json 2>/dev/null | jq -r '.txhash')
|
||||
|
||||
echo "Proposal transaction: $PROPOSAL_TX"
|
||||
sleep 6
|
||||
|
||||
# Query proposals
|
||||
PROPOSALS_QUERY='{"list_proposals": {"limit": 10}}'
|
||||
|
||||
PROPOSALS=$(gaiad query wasm contract-state smart "$PROPOSALS_ADDR" "$PROPOSALS_QUERY" \
|
||||
--output json 2>/dev/null | jq -r '.data.proposals | length')
|
||||
|
||||
if [ "$PROPOSALS" -gt 0 ]; then
|
||||
echo -e "${GREEN}✓ Proposal created successfully${NC}"
|
||||
echo "Total proposals: $PROPOSALS"
|
||||
else
|
||||
echo -e "${RED}✗ No proposals found${NC}"
|
||||
fi
|
||||
|
||||
# Test 5: Check relayer metrics
|
||||
echo -e "${BLUE}5. Checking Relayer Health${NC}"
|
||||
|
||||
RELAYER_STATUS=$(hermes health-check 2>/dev/null | grep -c "OK" || true)
|
||||
|
||||
if [ "$RELAYER_STATUS" -gt 0 ]; then
|
||||
echo -e "${GREEN}✓ Relayer is healthy${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ Relayer may need attention${NC}"
|
||||
fi
|
||||
|
||||
# Test 6: Packet flow statistics
|
||||
echo -e "${BLUE}6. IBC Packet Statistics${NC}"
|
||||
|
||||
echo "Channel: $VOTING_CHANNEL"
|
||||
|
||||
# Get packet commitments
|
||||
PENDING_PACKETS=$(hermes query packet commitments \
|
||||
--chain "$CHAIN_ID" \
|
||||
--port "wasm.$VOTING_ADDR" \
|
||||
--channel "$VOTING_CHANNEL" \
|
||||
2>/dev/null | jq -r '.commitments | length')
|
||||
|
||||
echo "Pending packets: $PENDING_PACKETS"
|
||||
|
||||
# Get packet acknowledgments
|
||||
TOTAL_ACKS=$(hermes query packet acks \
|
||||
--chain "$CHAIN_ID" \
|
||||
--port "wasm.$VOTING_ADDR" \
|
||||
--channel "$VOTING_CHANNEL" \
|
||||
2>/dev/null | jq -r '.acks | length')
|
||||
|
||||
echo "Total acknowledgments: $TOTAL_ACKS"
|
||||
|
||||
# Summary
|
||||
echo ""
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}Test Summary${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
|
||||
TESTS_PASSED=0
|
||||
TESTS_TOTAL=6
|
||||
|
||||
[ "$CHANNEL_STATUS" = "Open" ] && ((TESTS_PASSED++))
|
||||
[ "$PACKET_ACK" -gt 0 ] && ((TESTS_PASSED++))
|
||||
[ "$VOTER_INFO" != "null" ] && ((TESTS_PASSED++))
|
||||
[ "$PROPOSALS" -gt 0 ] && ((TESTS_PASSED++))
|
||||
[ "$RELAYER_STATUS" -gt 0 ] && ((TESTS_PASSED++))
|
||||
[ "$PENDING_PACKETS" -eq 0 ] && ((TESTS_PASSED++))
|
||||
|
||||
if [ "$TESTS_PASSED" -eq "$TESTS_TOTAL" ]; then
|
||||
echo -e "${GREEN}✓ All tests passed! ($TESTS_PASSED/$TESTS_TOTAL)${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ Some tests failed ($TESTS_PASSED/$TESTS_TOTAL)${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Monitor packet relay: hermes query packet pending --chain $CHAIN_ID"
|
||||
echo "2. Check channel balance: hermes query channel balance --chain $CHAIN_ID"
|
||||
echo "3. View relayer logs: hermes start --log-level debug"
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"cosmos_hub_testnet": {
|
||||
"chain_id": "theta-testnet-001",
|
||||
"rpc_endpoints": [
|
||||
"https://rpc.sentry-01.theta-testnet.polypore.xyz",
|
||||
"https://rpc.sentry-02.theta-testnet.polypore.xyz"
|
||||
],
|
||||
"grpc_endpoints": [
|
||||
"grpc.sentry-01.theta-testnet.polypore.xyz:9090",
|
||||
"grpc.sentry-02.theta-testnet.polypore.xyz:9090"
|
||||
],
|
||||
"explorer": "https://explorer.theta-testnet.polypore.xyz",
|
||||
"faucet": "https://discord.com/channels/669268347736686612/953697793476821092"
|
||||
},
|
||||
"sonr_testnet": {
|
||||
"chain_id": "sonrtest_1-1",
|
||||
"rpc_endpoints": [
|
||||
"http://localhost:26657",
|
||||
"https://testnet-rpc.sonr.io"
|
||||
],
|
||||
"grpc_endpoints": [
|
||||
"localhost:9090",
|
||||
"testnet-grpc.sonr.io:443"
|
||||
]
|
||||
},
|
||||
"ibc_config": {
|
||||
"connection_version": "1",
|
||||
"channel_version": "identity-dao-1",
|
||||
"packet_timeout": "10m",
|
||||
"ports": {
|
||||
"voting": "wasm.identity_dao_voting",
|
||||
"proposals": "wasm.identity_dao_proposals",
|
||||
"core": "wasm.identity_dao_core"
|
||||
},
|
||||
"sonr_ports": {
|
||||
"did": "did",
|
||||
"dwn": "dwn",
|
||||
"svc": "svc"
|
||||
}
|
||||
},
|
||||
"deployment_params": {
|
||||
"gas_prices": {
|
||||
"cosmos_hub": "0.025uatom",
|
||||
"sonr": "0.025usnr"
|
||||
},
|
||||
"gas_adjustment": 1.5,
|
||||
"deposit_amount": "1000000",
|
||||
"min_verification_level": 1,
|
||||
"voting_periods": {
|
||||
"min_seconds": 86400,
|
||||
"max_seconds": 604800
|
||||
},
|
||||
"pass_threshold": {
|
||||
"percentage": "0.5"
|
||||
}
|
||||
},
|
||||
"relayer_config": {
|
||||
"type": "hermes",
|
||||
"version": "1.7.0",
|
||||
"clear_interval": 100,
|
||||
"packet_timeout": "10m",
|
||||
"trusting_period": "14days",
|
||||
"trust_threshold": {
|
||||
"numerator": 2,
|
||||
"denominator": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,356 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Verify Identity DAO deployment and IBC connectivity
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Helper functions
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[✓]${NC} $1"
|
||||
}
|
||||
|
||||
log_fail() {
|
||||
echo -e "${RED}[✗]${NC} $1"
|
||||
}
|
||||
|
||||
# Configuration
|
||||
CHAIN_ID="theta-testnet-001"
|
||||
NODE="https://rpc.sentry-01.theta-testnet.polypore.xyz"
|
||||
|
||||
# Load deployment addresses
|
||||
load_deployment() {
|
||||
if [ -f "deployment_ids.env" ]; then
|
||||
source deployment_ids.env
|
||||
log_info "Loaded deployment configuration"
|
||||
else
|
||||
log_error "deployment_ids.env not found. Please deploy contracts first."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Verify contract deployment
|
||||
verify_contract() {
|
||||
local addr=$1
|
||||
local name=$2
|
||||
|
||||
log_info "Verifying ${name}..."
|
||||
|
||||
# Query contract info
|
||||
CONTRACT_INFO=$(gaiad query wasm contract "${addr}" \
|
||||
--node "${NODE}" \
|
||||
--output json 2>/dev/null || echo "{}")
|
||||
|
||||
if [ "$CONTRACT_INFO" != "{}" ]; then
|
||||
CODE_ID=$(echo "$CONTRACT_INFO" | jq -r '.contract_info.code_id')
|
||||
CREATOR=$(echo "$CONTRACT_INFO" | jq -r '.contract_info.creator')
|
||||
ADMIN=$(echo "$CONTRACT_INFO" | jq -r '.contract_info.admin')
|
||||
|
||||
log_success "${name} deployed at ${addr}"
|
||||
echo " Code ID: ${CODE_ID}"
|
||||
echo " Creator: ${CREATOR}"
|
||||
echo " Admin: ${ADMIN}"
|
||||
return 0
|
||||
else
|
||||
log_fail "${name} not found at ${addr}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Query contract state
|
||||
query_contract_state() {
|
||||
local addr=$1
|
||||
local query=$2
|
||||
local name=$3
|
||||
|
||||
log_info "Querying ${name} state..."
|
||||
|
||||
RESULT=$(gaiad query wasm contract-state smart "${addr}" "${query}" \
|
||||
--node "${NODE}" \
|
||||
--output json 2>/dev/null || echo "{}")
|
||||
|
||||
if [ "$RESULT" != "{}" ]; then
|
||||
echo "$RESULT" | jq '.'
|
||||
return 0
|
||||
else
|
||||
log_error "Failed to query ${name}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Test Core contract
|
||||
test_core_contract() {
|
||||
log_info "Testing Core contract functionality..."
|
||||
|
||||
# Query config
|
||||
CONFIG_QUERY='{"get_config":{}}'
|
||||
if query_contract_state "${CORE_ADDR}" "${CONFIG_QUERY}" "Core Config"; then
|
||||
log_success "Core config query successful"
|
||||
fi
|
||||
|
||||
# Query modules
|
||||
MODULES_QUERY='{"get_modules":{}}'
|
||||
if query_contract_state "${CORE_ADDR}" "${MODULES_QUERY}" "Core Modules"; then
|
||||
log_success "Core modules query successful"
|
||||
fi
|
||||
|
||||
# Query treasury
|
||||
TREASURY_QUERY='{"get_treasury":{}}'
|
||||
if query_contract_state "${CORE_ADDR}" "${TREASURY_QUERY}" "Core Treasury"; then
|
||||
log_success "Core treasury query successful"
|
||||
fi
|
||||
}
|
||||
|
||||
# Test Voting contract
|
||||
test_voting_contract() {
|
||||
log_info "Testing Voting contract functionality..."
|
||||
|
||||
# Query total voting power
|
||||
POWER_QUERY='{"get_total_power":{}}'
|
||||
if query_contract_state "${VOTING_ADDR}" "${POWER_QUERY}" "Total Voting Power"; then
|
||||
log_success "Voting power query successful"
|
||||
fi
|
||||
|
||||
# Query voters list
|
||||
VOTERS_QUERY='{"list_voters":{"limit":10}}'
|
||||
if query_contract_state "${VOTING_ADDR}" "${VOTERS_QUERY}" "Voters List"; then
|
||||
log_success "Voters list query successful"
|
||||
fi
|
||||
}
|
||||
|
||||
# Test Proposals contract
|
||||
test_proposals_contract() {
|
||||
log_info "Testing Proposals contract functionality..."
|
||||
|
||||
# Query proposal count
|
||||
COUNT_QUERY='{"get_proposal_count":{}}'
|
||||
if query_contract_state "${PROPOSALS_ADDR}" "${COUNT_QUERY}" "Proposal Count"; then
|
||||
log_success "Proposal count query successful"
|
||||
fi
|
||||
|
||||
# Query proposals list
|
||||
LIST_QUERY='{"list_proposals":{"limit":10}}'
|
||||
if query_contract_state "${PROPOSALS_ADDR}" "${LIST_QUERY}" "Proposals List"; then
|
||||
log_success "Proposals list query successful"
|
||||
fi
|
||||
}
|
||||
|
||||
# Test Pre-Propose contract
|
||||
test_pre_propose_contract() {
|
||||
log_info "Testing Pre-Propose contract functionality..."
|
||||
|
||||
# Query config
|
||||
CONFIG_QUERY='{"get_config":{}}'
|
||||
if query_contract_state "${PRE_PROPOSE_ADDR}" "${CONFIG_QUERY}" "Pre-Propose Config"; then
|
||||
log_success "Pre-propose config query successful"
|
||||
fi
|
||||
|
||||
# Query deposit info
|
||||
DEPOSIT_QUERY='{"get_deposit_info":{}}'
|
||||
if query_contract_state "${PRE_PROPOSE_ADDR}" "${DEPOSIT_QUERY}" "Deposit Info"; then
|
||||
log_success "Deposit info query successful"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check IBC channels
|
||||
check_ibc_channels() {
|
||||
log_info "Checking IBC channels..."
|
||||
|
||||
# Query all channels
|
||||
CHANNELS=$(gaiad query ibc channel channels \
|
||||
--node "${NODE}" \
|
||||
--output json 2>/dev/null || echo '{"channels":[]}')
|
||||
|
||||
CHANNEL_COUNT=$(echo "$CHANNELS" | jq '.channels | length')
|
||||
|
||||
if [ "$CHANNEL_COUNT" -gt 0 ]; then
|
||||
log_success "Found ${CHANNEL_COUNT} IBC channel(s)"
|
||||
|
||||
# Display channel details
|
||||
echo "$CHANNELS" | jq -r '.channels[] | " Channel \(.channel_id): \(.state) (\(.port_id))"'
|
||||
else
|
||||
log_fail "No IBC channels found"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check IBC clients
|
||||
check_ibc_clients() {
|
||||
log_info "Checking IBC clients..."
|
||||
|
||||
# Query all clients
|
||||
CLIENTS=$(gaiad query ibc client states \
|
||||
--node "${NODE}" \
|
||||
--output json 2>/dev/null || echo '{"client_states":[]}')
|
||||
|
||||
CLIENT_COUNT=$(echo "$CLIENTS" | jq '.client_states | length')
|
||||
|
||||
if [ "$CLIENT_COUNT" -gt 0 ]; then
|
||||
log_success "Found ${CLIENT_COUNT} IBC client(s)"
|
||||
|
||||
# Display client details
|
||||
echo "$CLIENTS" | jq -r '.client_states[] | " Client \(.client_id): \(.client_state.chain_id)"'
|
||||
else
|
||||
log_fail "No IBC clients found"
|
||||
fi
|
||||
}
|
||||
|
||||
# Test cross-chain query
|
||||
test_cross_chain_query() {
|
||||
log_info "Testing cross-chain DID query..."
|
||||
|
||||
# Prepare IBC query for x/did module
|
||||
DID_QUERY='{"query_did_via_ibc":{"did":"did:sonr:test123"}}'
|
||||
|
||||
# Execute query through Voting contract
|
||||
RESULT=$(gaiad query wasm contract-state smart "${VOTING_ADDR}" "${DID_QUERY}" \
|
||||
--node "${NODE}" \
|
||||
--output json 2>/dev/null || echo '{"error":"IBC query failed"}')
|
||||
|
||||
if echo "$RESULT" | jq -e '.error' > /dev/null; then
|
||||
log_fail "Cross-chain query failed"
|
||||
echo "$RESULT" | jq '.'
|
||||
else
|
||||
log_success "Cross-chain query successful"
|
||||
echo "$RESULT" | jq '.'
|
||||
fi
|
||||
}
|
||||
|
||||
# Generate deployment report
|
||||
generate_report() {
|
||||
log_info "Generating deployment report..."
|
||||
|
||||
REPORT_FILE="deployment_report_$(date +%Y%m%d_%H%M%S).md"
|
||||
|
||||
cat > "$REPORT_FILE" << EOF
|
||||
# Identity DAO Deployment Report
|
||||
|
||||
**Date:** $(date)
|
||||
**Chain:** Cosmos Hub Testnet (${CHAIN_ID})
|
||||
**Node:** ${NODE}
|
||||
|
||||
## Deployed Contracts
|
||||
|
||||
| Contract | Address | Code ID | Status |
|
||||
|----------|---------|---------|--------|
|
||||
| Core | ${CORE_ADDR} | ${CORE_CODE_ID} | ✓ |
|
||||
| Voting | ${VOTING_ADDR} | ${VOTING_CODE_ID} | ✓ |
|
||||
| Proposals | ${PROPOSALS_ADDR} | ${PROPOSALS_CODE_ID} | ✓ |
|
||||
| Pre-Propose | ${PRE_PROPOSE_ADDR} | ${PRE_PROPOSE_CODE_ID} | ✓ |
|
||||
|
||||
## IBC Configuration
|
||||
|
||||
- Clients: ${CLIENT_COUNT}
|
||||
- Channels: ${CHANNEL_COUNT}
|
||||
- Relayer Status: $([ -f "relayer.pid" ] && echo "Running (PID: $(cat relayer.pid))" || echo "Not running")
|
||||
|
||||
## Test Results
|
||||
|
||||
- Core Contract: ✓
|
||||
- Voting Contract: ✓
|
||||
- Proposals Contract: ✓
|
||||
- Pre-Propose Contract: ✓
|
||||
- IBC Connectivity: $([ "$CHANNEL_COUNT" -gt 0 ] && echo "✓" || echo "✗")
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Fund DAO treasury
|
||||
2. Register initial DID voters
|
||||
3. Create first governance proposal
|
||||
4. Monitor IBC packet flow
|
||||
|
||||
## Commands
|
||||
|
||||
\`\`\`bash
|
||||
# Query DAO config
|
||||
gaiad query wasm contract-state smart ${CORE_ADDR} '{"get_config":{}}' --node ${NODE}
|
||||
|
||||
# Query voting power
|
||||
gaiad query wasm contract-state smart ${VOTING_ADDR} '{"get_total_power":{}}' --node ${NODE}
|
||||
|
||||
# List proposals
|
||||
gaiad query wasm contract-state smart ${PROPOSALS_ADDR} '{"list_proposals":{"limit":10}}' --node ${NODE}
|
||||
\`\`\`
|
||||
|
||||
---
|
||||
Generated by verify_deployment.sh
|
||||
EOF
|
||||
|
||||
log_success "Report saved to ${REPORT_FILE}"
|
||||
}
|
||||
|
||||
# Main verification flow
|
||||
main() {
|
||||
log_info "Starting Identity DAO deployment verification..."
|
||||
|
||||
# Load deployment configuration
|
||||
load_deployment
|
||||
|
||||
# Verify all contracts
|
||||
CONTRACTS_OK=true
|
||||
verify_contract "${CORE_ADDR}" "Core Contract" || CONTRACTS_OK=false
|
||||
verify_contract "${VOTING_ADDR}" "Voting Contract" || CONTRACTS_OK=false
|
||||
verify_contract "${PROPOSALS_ADDR}" "Proposals Contract" || CONTRACTS_OK=false
|
||||
verify_contract "${PRE_PROPOSE_ADDR}" "Pre-Propose Contract" || CONTRACTS_OK=false
|
||||
|
||||
if [ "$CONTRACTS_OK" = false ]; then
|
||||
log_error "Some contracts are not deployed correctly"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Test contract functionality
|
||||
test_core_contract
|
||||
echo ""
|
||||
test_voting_contract
|
||||
echo ""
|
||||
test_proposals_contract
|
||||
echo ""
|
||||
test_pre_propose_contract
|
||||
echo ""
|
||||
|
||||
# Check IBC setup
|
||||
check_ibc_clients
|
||||
echo ""
|
||||
check_ibc_channels
|
||||
echo ""
|
||||
|
||||
# Test cross-chain functionality
|
||||
test_cross_chain_query
|
||||
echo ""
|
||||
|
||||
# Generate report
|
||||
generate_report
|
||||
|
||||
log_info "✅ Verification complete!"
|
||||
log_info ""
|
||||
log_info "=== Summary ==="
|
||||
if [ "$CONTRACTS_OK" = true ]; then
|
||||
log_success "All contracts deployed successfully"
|
||||
fi
|
||||
|
||||
if [ "$CHANNEL_COUNT" -gt 0 ]; then
|
||||
log_success "IBC channels established"
|
||||
else
|
||||
log_fail "IBC channels not yet established"
|
||||
fi
|
||||
|
||||
log_info ""
|
||||
log_info "View detailed report: cat ${REPORT_FILE}"
|
||||
}
|
||||
|
||||
# Run main verification
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user