Skip to content

Commit 54e1bbf

Browse files
committed
feat: Implement contract upgrade function and refactor the upgrade script to source .env files and output status to stderr.
1 parent 9a46bc4 commit 54e1bbf

2 files changed

Lines changed: 75 additions & 46 deletions

File tree

contracts/governance_voting/src/contract.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,22 @@ impl GovernanceVoting {
467467
Ok(session.threshold_reached)
468468
}
469469

470+
// ========================================================================
471+
// ADMIN
472+
// ========================================================================
473+
474+
pub fn upgrade(env: Env, new_wasm_hash: BytesN<32>) -> Result<(), GovernanceError> {
475+
let admin: Address = env
476+
.storage()
477+
.instance()
478+
.get(&GovernanceDataKey::Admin)
479+
.ok_or(GovernanceError::NotInitialized)?;
480+
admin.require_auth();
481+
env.deployer().update_current_contract_wasm(new_wasm_hash);
482+
Self::extend_instance_ttl(&env);
483+
Ok(())
484+
}
485+
470486
// ========================================================================
471487
// INTERNAL HELPERS
472488
// ========================================================================

scripts/upgrade.sh

Lines changed: 59 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,30 @@
88
#
99
# Prerequisites:
1010
# - stellar CLI installed
11-
# - ADMIN_SECRET env var set
12-
# - NETWORK env var set (testnet | mainnet)
13-
# - Contract ID env vars set (CORE_ESCROW_ID, BOUNTY_REGISTRY_ID, etc.)
11+
# - .env file with ADMIN_SECRET and contract IDs (or set them as env vars)
1412
# - WASM files built via `stellar contract build`
1513

1614
set -euo pipefail
1715

18-
WASM_DIR="${WASM_DIR:-target/wasm32v1-none/release}"
16+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
17+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
18+
19+
# Source .env if present
20+
if [[ -f "$PROJECT_ROOT/.env" ]]; then
21+
set -a
22+
# shellcheck disable=SC1091
23+
source "$PROJECT_ROOT/.env"
24+
set +a
25+
fi
26+
27+
WASM_DIR="${WASM_DIR:-$PROJECT_ROOT/target/wasm32v1-none/release}"
1928
NETWORK="${NETWORK:-testnet}"
2029

2130
if [[ -z "${ADMIN_SECRET:-}" ]]; then
22-
echo "ERROR: ADMIN_SECRET environment variable required"
31+
>&2 echo "ERROR: ADMIN_SECRET not set (add to .env or export it)"
2332
exit 1
2433
fi
2534

26-
# ── Contract name → env var mapping ──────────────────────
27-
declare -A CONTRACT_IDS=(
28-
[core_escrow]="${CORE_ESCROW_ID:-}"
29-
[reputation_registry]="${REPUTATION_REGISTRY_ID:-}"
30-
[governance_voting]="${GOVERNANCE_VOTING_ID:-}"
31-
[project_registry]="${PROJECT_REGISTRY_ID:-}"
32-
[bounty_registry]="${BOUNTY_REGISTRY_ID:-}"
33-
[crowdfund_registry]="${CROWDFUND_REGISTRY_ID:-}"
34-
[grant_hub]="${GRANT_HUB_ID:-}"
35-
[hackathon_registry]="${HACKATHON_REGISTRY_ID:-}"
36-
)
37-
3835
# Upgrade order: infrastructure first, then modules
3936
UPGRADE_ORDER=(
4037
core_escrow
@@ -49,9 +46,25 @@ UPGRADE_ORDER=(
4946

5047
# ── Helpers ──────────────────────────────────────────────
5148

49+
# Map contract name → contract ID env var value
50+
get_contract_id() {
51+
local name="$1"
52+
case "$name" in
53+
core_escrow) echo "${CORE_ESCROW_ID:-}" ;;
54+
reputation_registry) echo "${REPUTATION_REGISTRY_ID:-}" ;;
55+
governance_voting) echo "${GOVERNANCE_VOTING_ID:-}" ;;
56+
project_registry) echo "${PROJECT_REGISTRY_ID:-}" ;;
57+
bounty_registry) echo "${BOUNTY_REGISTRY_ID:-}" ;;
58+
crowdfund_registry) echo "${CROWDFUND_REGISTRY_ID:-}" ;;
59+
grant_hub) echo "${GRANT_HUB_ID:-}" ;;
60+
hackathon_registry) echo "${HACKATHON_REGISTRY_ID:-}" ;;
61+
*) return 1 ;;
62+
esac
63+
}
64+
5265
install_wasm() {
5366
local wasm="$1"
54-
echo " Installing WASM on-chain..."
67+
>&2 echo " Installing WASM on-chain..."
5568
stellar contract install \
5669
--wasm "$wasm" \
5770
--source "$ADMIN_SECRET" \
@@ -60,51 +73,52 @@ install_wasm() {
6073

6174
upgrade_contract() {
6275
local name="$1"
63-
local contract_id="${CONTRACT_IDS[$name]:-}"
76+
local contract_id
77+
contract_id="$(get_contract_id "$name")"
6478
local wasm="$WASM_DIR/${name}.wasm"
6579

6680
if [[ -z "$contract_id" ]]; then
67-
echo "SKIP: $name — no contract ID set (${name^^}_ID)"
81+
>&2 echo "SKIP: $name — no contract ID set"
6882
return 1
6983
fi
7084

7185
if [[ ! -f "$wasm" ]]; then
72-
echo "ERROR: WASM not found: $wasm"
86+
>&2 echo "ERROR: WASM not found: $wasm"
7387
return 1
7488
fi
7589

76-
echo ""
77-
echo "────────────────────────────────────────"
78-
echo "Upgrading: $name"
79-
echo " Contract: $contract_id"
80-
echo " WASM: $wasm"
81-
echo "────────────────────────────────────────"
90+
>&2 echo ""
91+
>&2 echo "────────────────────────────────────────"
92+
>&2 echo "Upgrading: $name"
93+
>&2 echo " Contract: $contract_id"
94+
>&2 echo " WASM: $wasm"
95+
>&2 echo "────────────────────────────────────────"
8296

8397
# Install the new WASM and get the hash
8498
local wasm_hash
8599
wasm_hash=$(install_wasm "$wasm")
86-
echo " WASM hash: $wasm_hash"
100+
>&2 echo " WASM hash: $wasm_hash"
87101

88102
# Call the contract's upgrade function
89-
echo " Calling upgrade..."
103+
>&2 echo " Calling upgrade..."
90104
stellar contract invoke \
91105
--id "$contract_id" \
92106
--source "$ADMIN_SECRET" \
93107
--network "$NETWORK" \
94108
-- upgrade \
95109
--new_wasm_hash "$wasm_hash"
96110

97-
echo " Done: $name upgraded successfully"
111+
>&2 echo " Done: $name upgraded successfully"
98112
}
99113

100114
# ── Main ─────────────────────────────────────────────────
101115

102116
TARGETS=("$@")
103117

104118
if [[ ${#TARGETS[@]} -eq 0 ]]; then
105-
echo "Usage: $0 <all | contract_name [contract_name ...]>"
106-
echo ""
107-
echo "Contracts: ${UPGRADE_ORDER[*]}"
119+
>&2 echo "Usage: $0 <all | contract_name [contract_name ...]>"
120+
>&2 echo ""
121+
>&2 echo "Contracts: ${UPGRADE_ORDER[*]}"
108122
exit 1
109123
fi
110124

@@ -113,20 +127,19 @@ if [[ "${TARGETS[0]}" == "all" ]]; then
113127
TARGETS=("${UPGRADE_ORDER[@]}")
114128
fi
115129

116-
echo "=== Boundless Platform — Contract Upgrade ==="
117-
echo "Network: $NETWORK"
118-
echo "Targets: ${TARGETS[*]}"
119-
echo ""
130+
>&2 echo "=== Boundless Platform — Contract Upgrade ==="
131+
>&2 echo "Network: $NETWORK"
132+
>&2 echo "Targets: ${TARGETS[*]}"
133+
>&2 echo ""
120134

121135
SUCCEEDED=0
122136
FAILED=0
123-
SKIPPED=0
124137

125138
for name in "${TARGETS[@]}"; do
126139
# Validate contract name
127-
if [[ -z "${CONTRACT_IDS[$name]+exists}" ]]; then
128-
echo "ERROR: Unknown contract '$name'"
129-
echo "Valid contracts: ${!CONTRACT_IDS[*]}"
140+
if ! get_contract_id "$name" > /dev/null 2>&1; then
141+
>&2 echo "ERROR: Unknown contract '$name'"
142+
>&2 echo "Valid contracts: ${UPGRADE_ORDER[*]}"
130143
exit 1
131144
fi
132145

@@ -137,11 +150,11 @@ for name in "${TARGETS[@]}"; do
137150
fi
138151
done
139152

140-
echo ""
141-
echo "=== Upgrade Summary ==="
142-
echo " Succeeded: $SUCCEEDED"
143-
echo " Failed: $FAILED"
144-
echo ""
153+
>&2 echo ""
154+
>&2 echo "=== Upgrade Summary ==="
155+
>&2 echo " Succeeded: $SUCCEEDED"
156+
>&2 echo " Failed: $FAILED"
157+
>&2 echo ""
145158

146159
if [[ $FAILED -gt 0 ]]; then
147160
exit 1

0 commit comments

Comments
 (0)