-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathupgrade_contract.ts
More file actions
100 lines (87 loc) · 3.7 KB
/
Copy pathupgrade_contract.ts
File metadata and controls
100 lines (87 loc) · 3.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import {
Contract,
Keypair,
Networks,
TransactionBuilder,
Operation,
SorobanRpc,
xdr,
} from 'soroban-client';
import { config } from 'dotenv';
import * as fs from 'fs';
import * as path from 'path';
config({ path: '../../.env' });
const networkPassphrase = Networks.TESTNET; // Or Networks.PUBLIC for mainnet
const rpcUrl = process.env.STELLAR_RPC_URL || 'https://soroban-testnet.stellar.org';
const server = new SorobanRpc.Server(rpcUrl, { allowHttp: true });
async function upgradeContract(
contractId: string,
newWasmPath: string,
adminSecret: string
) {
const adminKeypair = Keypair.fromSecret(adminSecret);
const adminPublicKey = adminKeypair.publicKey();
console.log(`Attempting to upgrade contract ${contractId} with admin ${adminPublicKey}`);
console.log(`New Wasm file: ${newWasmPath}`);
// 1. Read the new WASM file
const wasm = fs.readFileSync(path.resolve(__dirname, newWasmPath));
// 2. Upload the new WASM to the network to get its hash
console.log('Uploading new WASM to the network...');
const uploadTx = await server.prepareTransaction(
TransactionBuilder.forAccount(adminPublicKey, await server.getAccount(adminPublicKey).then(a => a.sequence))
.addOperation(Operation.uploadContractCode({ code: wasm }))
.setTimeout(30)
.build(),
networkPassphrase
);
uploadTx.sign(adminKeypair);
const uploadResult = await server.sendTransaction(uploadTx);
if (uploadResult.status === 'PENDING') {
console.log('WASM upload transaction submitted. Waiting for confirmation...');
const uploadStatus = await server.getTransaction(uploadResult.hash);
if (uploadStatus.status === 'SUCCESS') {
const newWasmHash = (uploadStatus.resultXdr as xdr.TransactionResult).result().results()[0].tr().uploadContractCodeResult().hash();
console.log(`New WASM uploaded successfully. Hash: ${newWasmHash.toString('hex')}`);
// 3. Call the contract's 'upgrade' function
const contract = new Contract(contractId);
const tx = await server.prepareTransaction(
TransactionBuilder.forAccount(adminPublicKey, await server.getAccount(adminPublicKey).then(a => a.sequence))
.addOperation(contract.call('upgrade', ...[newWasmHash]))
.setTimeout(30)
.build(),
networkPassphrase
);
tx.sign(adminKeypair);
console.log('Submitting contract upgrade transaction...');
const result = await server.sendTransaction(tx);
if (result.status === 'PENDING') {
console.log(`Upgrade transaction submitted. Hash: ${result.hash}. Waiting for confirmation...`);
const status = await server.getTransaction(result.hash);
console.log(`Upgrade transaction status: ${status.status}`);
if (status.status === 'SUCCESS') {
console.log('Contract upgraded successfully!');
} else {
console.error('Contract upgrade failed:', status.error);
}
} else {
console.error('Failed to submit upgrade transaction:', result.error);
}
} else {
console.error('WASM upload failed:', uploadStatus.error);
}
} else {
console.error('Failed to submit WASM upload transaction:', uploadResult.error);
}
}
const contractId = process.argv[2];
const newWasmPath = process.argv[3];
const adminSecret = process.env.ADMIN_SECRET_KEY; // Ensure this is set in your .env
if (!contractId || !newWasmPath || !adminSecret) {
console.error('Usage: ts-node upgrade_contract.ts <contract-id> <path-to-new-wasm>');
console.error('Ensure ADMIN_SECRET_KEY is set in your .env file.');
process.exit(1);
}
upgradeContract(contractId, newWasmPath, adminSecret).catch(e => {
console.error('An error occurred during contract upgrade:', e);
process.exit(1);
});