#!/bin/sh # deploy_contracts.sh — деплой всех 4 production-контрактов из genesis-кошелька. # # Запуск: # docker compose --profile deploy run --rm deploy # # После деплоя contract_id'ы выводятся в stdout и сохраняются в /tmp/contracts.env. # Контракты видны в Explorer: http://localhost:8081/contracts set -e # ── Конфигурация нод (через backbone IP, без DNS) ───────────────────────────── NODE1_URL="${NODE1_URL:-http://172.30.0.11:8080}" NODE2_URL="${NODE2_URL:-http://172.30.0.12:8080}" NODE3_URL="${NODE3_URL:-http://172.30.0.13:8080}" # Основная нода для деплоя (genesis-кошелёк на node1) NODE="$NODE1_URL" GENESIS_KEY="/keys/node1.json" BOLD='\033[1m' CYAN='\033[1;36m' GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' RESET='\033[0m' step() { printf "\n${CYAN}▶ %s${RESET}\n" "$*"; } ok() { printf " ${GREEN}✓${RESET} %s\n" "$*"; } fail() { printf " ${RED}✗${RESET} %s\n" "$*"; exit 1; } info() { printf " %s\n" "$*"; } # ── Ожидание готовности ноды ────────────────────────────────────────────────── wait_node() { local name="$1" url="$2" step "Ожидание готовности $name ($url)..." i=0 while [ $i -lt 90 ]; do if wget -qO /dev/null "$url/api/netstats" 2>/dev/null; then ok "$name доступен"; break fi printf "."; sleep 1; i=$((i+1)) done [ $i -lt 90 ] || fail "$name недоступен после 90 секунд" } wait_node "node1" "$NODE1_URL" wait_node "node2" "$NODE2_URL" wait_node "node3" "$NODE3_URL" printf " Ждём genesis block на node1" i=0 while [ $i -lt 60 ]; do if wget -qO- "$NODE/api/netstats" 2>/dev/null | grep -q '"total_blocks": *[1-9]'; then printf " — готово.\n"; break fi printf "."; sleep 1; i=$((i+1)) done [ $i -lt 60 ] || fail "Genesis block не появился" # ── Хелпер: деплой одного контракта ────────────────────────────────────────── deploy_contract() { local name="$1" wasm="$2" abi="$3" step "Деплой $name" OUT=$(client deploy-contract \ --key "$GENESIS_KEY" \ --wasm "$wasm" \ --abi "$abi" \ --node "$NODE" 2>&1) printf '%s\n' "$OUT" CID=$(printf '%s' "$OUT" | grep 'contract_id:' | awk '{print $NF}') [ -n "$CID" ] || fail "Не удалось получить contract_id для $name" # Ждём подтверждения on-chain printf " Ждём подтверждения" i=0 while [ $i -lt 40 ]; do if wget -qO- "$NODE/api/contracts/$CID" 2>/dev/null | grep -q '"contract_id"'; then printf " — задеплоен.\n"; break fi printf "."; sleep 1; i=$((i+1)) done [ $i -lt 40 ] || fail "Timeout ожидания контракта $name" ok "$name contract_id: $CID" echo "$CID" } # ── Инициализация контракта (вызов init) ────────────────────────────────────── init_contract() { local name="$1" cid="$2" step "Инициализация $name (вызов init)" client call-contract \ --key "$GENESIS_KEY" \ --contract "$cid" \ --method init \ --gas 50000 \ --node "$NODE" 2>&1 | grep -v '^$' || true sleep 2 ok "$name инициализирован" } # ── Деплой всех контрактов ──────────────────────────────────────────────────── printf "\n${YELLOW}══════════════════════════════════════════════════${RESET}\n" printf "${BOLD} DChain — деплой production-контрактов${RESET}\n" printf "${YELLOW}══════════════════════════════════════════════════${RESET}\n" UR_ID=$(deploy_contract "username_registry" \ "/keys/username_registry.wasm" \ "/keys/username_registry_abi.json") GOV_ID=$(deploy_contract "governance" \ "/keys/governance.wasm" \ "/keys/governance_abi.json") AUC_ID=$(deploy_contract "auction" \ "/keys/auction.wasm" \ "/keys/auction_abi.json") ESC_ID=$(deploy_contract "escrow" \ "/keys/escrow.wasm" \ "/keys/escrow_abi.json") # Инициализируем контракты с admin-ролью init_contract "governance" "$GOV_ID" init_contract "escrow" "$ESC_ID" # ── Линковка governance со всеми нодами (runtime, без перезапуска) ──────────── link_governance() { local name="$1" url="$2" step "Линковка governance с $name ($url)" RESP=$(wget -qO- --post-data="{\"governance\":\"$GOV_ID\"}" \ --header="Content-Type: application/json" \ "$url/api/governance/link" 2>/dev/null || true) if printf '%s' "$RESP" | grep -q '"ok"'; then ok "governance привязан — gas_price управляется on-chain" else info "нода недоступна или уже настроена: $RESP" fi } link_governance "node1" "$NODE1_URL" link_governance "node2" "$NODE2_URL" link_governance "node3" "$NODE3_URL" # ── Итоговый вывод ──────────────────────────────────────────────────────────── printf "\n${YELLOW}══════════════════════════════════════════════════${RESET}\n" printf "${BOLD} Все контракты задеплоены!${RESET}\n" printf "${YELLOW}══════════════════════════════════════════════════${RESET}\n\n" ok "username_registry : $UR_ID" ok "governance : $GOV_ID" ok "auction : $AUC_ID" ok "escrow : $ESC_ID" printf "\n${BOLD}Explorer:${RESET}\n" info "node1 → http://localhost:8081/contracts" info "node2 → http://localhost:8082/contracts" info "node3 → http://localhost:8083/contracts" printf "\n" info "http://localhost:8081/contract?id=$UR_ID (username_registry)" info "http://localhost:8081/contract?id=$GOV_ID (governance)" info "http://localhost:8081/contract?id=$AUC_ID (auction)" info "http://localhost:8081/contract?id=$ESC_ID (escrow)" # Сохраняем ID для последующего использования cat > /tmp/contracts.env << EOF USERNAME_REGISTRY=$UR_ID GOVERNANCE=$GOV_ID AUCTION=$AUC_ID ESCROW=$ESC_ID EOF printf "\n" ok "ID сохранены в /tmp/contracts.env" echo