@btc-vision/btc-runtime 1.11.0-rc.9 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +7 -7
  2. package/docs/README.md +39 -39
  3. package/docs/advanced/bitcoin-scripts.md +17 -17
  4. package/docs/advanced/{contract-upgrades.md → contract-updates.md} +90 -98
  5. package/docs/advanced/cross-contract-calls.md +4 -4
  6. package/docs/advanced/plugins.md +21 -21
  7. package/docs/advanced/quantum-resistance.md +32 -32
  8. package/docs/advanced/signature-verification.md +22 -22
  9. package/docs/api-reference/blockchain.md +14 -14
  10. package/docs/api-reference/events.md +2 -2
  11. package/docs/api-reference/op20.md +7 -7
  12. package/docs/api-reference/op721.md +7 -7
  13. package/docs/api-reference/storage.md +2 -2
  14. package/docs/contracts/op-net-base.md +15 -15
  15. package/docs/contracts/op20-token.md +3 -3
  16. package/docs/contracts/op20s-signatures.md +2 -2
  17. package/docs/contracts/op721-nft.md +3 -3
  18. package/docs/contracts/reentrancy-guard.md +5 -7
  19. package/docs/contracts/updatable.md +384 -0
  20. package/docs/core-concepts/blockchain-environment.md +10 -10
  21. package/docs/core-concepts/decorators.md +5 -5
  22. package/docs/core-concepts/events.md +6 -6
  23. package/docs/core-concepts/pointers.md +5 -5
  24. package/docs/core-concepts/security.md +5 -5
  25. package/docs/core-concepts/storage-system.md +24 -24
  26. package/docs/examples/basic-token.md +8 -8
  27. package/docs/examples/nft-with-reservations.md +9 -9
  28. package/docs/examples/oracle-integration.md +13 -13
  29. package/docs/examples/stablecoin.md +10 -10
  30. package/docs/getting-started/first-contract.md +8 -8
  31. package/docs/getting-started/installation.md +2 -2
  32. package/docs/getting-started/project-structure.md +6 -6
  33. package/docs/storage/memory-maps.md +8 -8
  34. package/docs/storage/stored-arrays.md +6 -6
  35. package/docs/storage/stored-maps.md +8 -8
  36. package/docs/storage/stored-primitives.md +6 -6
  37. package/docs/types/address.md +13 -13
  38. package/docs/types/bytes-writer-reader.md +18 -18
  39. package/docs/types/calldata.md +12 -12
  40. package/package.json +10 -10
  41. package/runtime/constants/Exports.ts +0 -30
  42. package/runtime/contracts/OP20.ts +7 -7
  43. package/runtime/contracts/OP721.ts +60 -74
  44. package/runtime/contracts/OP_NET.ts +2 -2
  45. package/runtime/contracts/ReentrancyGuard.ts +1 -5
  46. package/runtime/contracts/Updatable.ts +241 -0
  47. package/runtime/contracts/interfaces/OP721InitParameters.ts +8 -8
  48. package/runtime/env/BlockchainEnvironment.ts +5 -5
  49. package/runtime/env/global.ts +7 -6
  50. package/runtime/events/predefined/{ApprovedEvent.ts → OP20ApprovedEvent.ts} +1 -1
  51. package/runtime/events/predefined/{BurnedEvent.ts → OP20BurnedEvent.ts} +1 -1
  52. package/runtime/events/predefined/{MintedEvent.ts → OP20MintedEvent.ts} +1 -1
  53. package/runtime/events/predefined/{TransferredEvent.ts → OP20TransferredEvent.ts} +1 -1
  54. package/runtime/events/predefined/OP721ApprovedEvent.ts +17 -0
  55. package/runtime/events/predefined/{ApprovedForAll.ts → OP721ApprovedForAllEvent.ts} +1 -1
  56. package/runtime/events/predefined/OP721BurnedEvent.ts +16 -0
  57. package/runtime/events/predefined/OP721MintedEvent.ts +16 -0
  58. package/runtime/events/predefined/OP721TransferredEvent.ts +18 -0
  59. package/runtime/events/predefined/index.ts +5 -5
  60. package/runtime/events/{upgradeable/UpgradeableEvents.ts → updatable/UpdatableEvents.ts} +9 -9
  61. package/runtime/hashing/keccak256.ts +1 -1
  62. package/runtime/index.ts +3 -5
  63. package/runtime/plugins/UpdatablePlugin.ts +276 -0
  64. package/runtime/script/Networks.ts +1 -1
  65. package/runtime/storage/StoredBoolean.ts +23 -12
  66. package/runtime/types/Address.ts +1 -1
  67. package/runtime/types/ExtendedAddress.ts +1 -1
  68. package/docs/contracts/upgradeable.md +0 -396
  69. package/runtime/contracts/Upgradeable.ts +0 -242
  70. package/runtime/contracts/interfaces/IOP1155.ts +0 -33
  71. package/runtime/contracts/interfaces/OP1155InitParameters.ts +0 -11
  72. package/runtime/plugins/UpgradeablePlugin.ts +0 -279
@@ -1,396 +0,0 @@
1
- # Upgradeable
2
-
3
- The `Upgradeable` base class provides a secure upgrade mechanism with configurable timelock protection. Contracts extending `Upgradeable` can replace their bytecode while giving users time to assess pending changes.
4
-
5
- > **Alternative**: If you're already extending another base class (like `OP20` or `OP721`), use the [`UpgradeablePlugin`](../advanced/contract-upgrades.md#using-the-upgradeableplugin) instead. Just call `this.registerPlugin(new UpgradeablePlugin(144))` in your constructor - no other code changes needed!
6
-
7
- ## Overview
8
-
9
- ```typescript
10
- import {
11
- Upgradeable,
12
- Calldata,
13
- BytesWriter,
14
- encodeSelector,
15
- Selector,
16
- ADDRESS_BYTE_LENGTH,
17
- } from '@btc-vision/btc-runtime/runtime';
18
-
19
- @final
20
- export class MyContract extends Upgradeable {
21
- // Set delay: 144 blocks = ~24 hours
22
- protected readonly upgradeDelay: u64 = 144;
23
-
24
- public override execute(method: Selector, calldata: Calldata): BytesWriter {
25
- switch (method) {
26
- case encodeSelector('submitUpgrade'):
27
- return this.submitUpgrade(calldata.readAddress());
28
- case encodeSelector('applyUpgrade'): {
29
- const sourceAddress = calldata.readAddress();
30
- const remainingLength = calldata.byteLength - ADDRESS_BYTE_LENGTH;
31
- const updateCalldata = new BytesWriter(remainingLength);
32
- if (remainingLength > 0) {
33
- updateCalldata.writeBytes(calldata.readBytes(remainingLength));
34
- }
35
- return this.applyUpgrade(sourceAddress, updateCalldata);
36
- }
37
- case encodeSelector('cancelUpgrade'):
38
- return this.cancelUpgrade();
39
- default:
40
- return super.execute(method, calldata);
41
- }
42
- }
43
- }
44
- ```
45
-
46
- ## Class Reference
47
-
48
- ### Properties
49
-
50
- | Property | Type | Description |
51
- |----------|------|-------------|
52
- | `upgradeDelay` | `u64` | Blocks to wait before upgrade can be applied (default: 144 = ~24h) |
53
- | `pendingUpgradeAddress` | `Address` | Source address of pending upgrade (zero if none) |
54
- | `pendingUpgradeBlock` | `u64` | Block when upgrade was submitted (0 if none) |
55
- | `upgradeEffectiveBlock` | `u64` | Block when upgrade can be applied (0 if none) |
56
- | `hasPendingUpgrade` | `bool` | Whether an upgrade is pending |
57
- | `canApplyUpgrade` | `bool` | Whether the delay has elapsed |
58
-
59
- ### Methods
60
-
61
- #### submitUpgrade
62
-
63
- Submits an upgrade for timelock. Only callable by deployer.
64
-
65
- ```typescript
66
- protected submitUpgrade(sourceAddress: Address): BytesWriter
67
- ```
68
-
69
- **Parameters:**
70
- - `sourceAddress`: The address of the contract containing the new bytecode
71
-
72
- **Reverts if:**
73
- - Caller is not the deployer
74
- - Source is not a deployed contract
75
- - An upgrade is already pending
76
-
77
- **Emits:** `UpgradeSubmitted(sourceAddress, submitBlock, effectiveBlock)`
78
-
79
- #### applyUpgrade
80
-
81
- Applies a pending upgrade after the delay has passed. Only callable by deployer.
82
-
83
- ```typescript
84
- protected applyUpgrade(sourceAddress: Address, calldata: BytesWriter): BytesWriter
85
- ```
86
-
87
- **Parameters:**
88
- - `sourceAddress`: The source contract address (must match pending)
89
- - `calldata`: Data passed to the `onUpdate` hook of the new contract
90
-
91
- **Reverts if:**
92
- - Caller is not the deployer
93
- - No upgrade is pending
94
- - Delay has not elapsed
95
- - Address does not match pending upgrade
96
-
97
- **Emits:** `UpgradeApplied(sourceAddress, appliedAtBlock)`
98
-
99
- #### cancelUpgrade
100
-
101
- Cancels a pending upgrade. Only callable by deployer.
102
-
103
- ```typescript
104
- protected cancelUpgrade(): BytesWriter
105
- ```
106
-
107
- **Reverts if:**
108
- - Caller is not the deployer
109
- - No upgrade is pending
110
-
111
- **Emits:** `UpgradeCancelled(sourceAddress, cancelledAtBlock)`
112
-
113
- ## Events
114
-
115
- ### UpgradeSubmittedEvent
116
-
117
- Emitted when an upgrade is submitted.
118
-
119
- ```typescript
120
- class UpgradeSubmittedEvent extends NetEvent {
121
- constructor(
122
- sourceAddress: Address, // Contract with new bytecode
123
- submitBlock: u64, // Block when submitted
124
- effectiveBlock: u64 // Block when can be applied
125
- )
126
- }
127
- ```
128
-
129
- ### UpgradeAppliedEvent
130
-
131
- Emitted when an upgrade is applied.
132
-
133
- ```typescript
134
- class UpgradeAppliedEvent extends NetEvent {
135
- constructor(
136
- sourceAddress: Address, // Contract with new bytecode
137
- appliedAtBlock: u64 // Block when applied
138
- )
139
- }
140
- ```
141
-
142
- ### UpgradeCancelledEvent
143
-
144
- Emitted when a pending upgrade is cancelled.
145
-
146
- ```typescript
147
- class UpgradeCancelledEvent extends NetEvent {
148
- constructor(
149
- sourceAddress: Address, // Cancelled source contract
150
- cancelledAtBlock: u64 // Block when cancelled
151
- )
152
- }
153
- ```
154
-
155
- ## Usage Patterns
156
-
157
- ### Basic Upgradeable Contract
158
-
159
- ```typescript
160
- @final
161
- export class SimpleUpgradeable extends Upgradeable {
162
- protected readonly upgradeDelay: u64 = 144; // ~1 day
163
-
164
- public override execute(method: Selector, calldata: Calldata): BytesWriter {
165
- switch (method) {
166
- case encodeSelector('submitUpgrade'):
167
- return this.submitUpgrade(calldata.readAddress());
168
- case encodeSelector('applyUpgrade'): {
169
- const sourceAddress = calldata.readAddress();
170
- const remainingLength = calldata.byteLength - ADDRESS_BYTE_LENGTH;
171
- const updateCalldata = new BytesWriter(remainingLength);
172
- if (remainingLength > 0) {
173
- updateCalldata.writeBytes(calldata.readBytes(remainingLength));
174
- }
175
- return this.applyUpgrade(sourceAddress, updateCalldata);
176
- }
177
- case encodeSelector('cancelUpgrade'):
178
- return this.cancelUpgrade();
179
- default:
180
- return super.execute(method, calldata);
181
- }
182
- }
183
- }
184
- ```
185
-
186
- ### With Upgrade Status Views
187
-
188
- ```typescript
189
- @final
190
- export class UpgradeableWithViews extends Upgradeable {
191
- protected readonly upgradeDelay: u64 = 1008; // ~1 week
192
-
193
- public override execute(method: Selector, calldata: Calldata): BytesWriter {
194
- switch (method) {
195
- // Upgrade actions
196
- case encodeSelector('submitUpgrade'):
197
- return this.submitUpgrade(calldata.readAddress());
198
- case encodeSelector('applyUpgrade'): {
199
- const sourceAddress = calldata.readAddress();
200
- const remainingLength = calldata.byteLength - ADDRESS_BYTE_LENGTH;
201
- const updateCalldata = new BytesWriter(remainingLength);
202
- if (remainingLength > 0) {
203
- updateCalldata.writeBytes(calldata.readBytes(remainingLength));
204
- }
205
- return this.applyUpgrade(sourceAddress, updateCalldata);
206
- }
207
- case encodeSelector('cancelUpgrade'):
208
- return this.cancelUpgrade();
209
-
210
- // View methods
211
- case encodeSelector('getPendingUpgrade'):
212
- return this.getPendingUpgrade();
213
- case encodeSelector('getUpgradeStatus'):
214
- return this.getUpgradeStatus();
215
-
216
- default:
217
- return super.execute(method, calldata);
218
- }
219
- }
220
-
221
- private getPendingUpgrade(): BytesWriter {
222
- const response = new BytesWriter(32);
223
- response.writeAddress(this.pendingUpgradeAddress);
224
- return response;
225
- }
226
-
227
- private getUpgradeStatus(): BytesWriter {
228
- const response = new BytesWriter(17);
229
- response.writeBoolean(this.hasPendingUpgrade);
230
- response.writeU64(this.pendingUpgradeBlock);
231
- response.writeU64(this.upgradeEffectiveBlock);
232
- return response;
233
- }
234
- }
235
- ```
236
-
237
- ### Emergency Upgrades (Not Recommended)
238
-
239
- For contracts that need faster upgrades (use with caution):
240
-
241
- ```typescript
242
- @final
243
- export class QuickUpgradeable extends Upgradeable {
244
- // Only 6 blocks (~1 hour) - use only for emergencies
245
- protected readonly upgradeDelay: u64 = 6;
246
-
247
- // ... rest of implementation
248
- }
249
- ```
250
-
251
- ## Security Considerations
252
-
253
- ### 1. Delay Selection
254
-
255
- Choose an appropriate delay based on your contract's risk profile:
256
-
257
- | Contract Type | Recommended Delay |
258
- |---------------|-------------------|
259
- | Test/Development | 1-6 blocks |
260
- | Standard DeFi | 144 blocks (~24 hours) |
261
- | High-value vaults | 1008 blocks (~1 week) |
262
- | Governance contracts | 4320 blocks (~1 month) |
263
-
264
- ### 2. Source Validation
265
-
266
- The `submitUpgrade` function validates that the source is a deployed contract. This prevents:
267
- - Submitting non-existent addresses
268
- - Last-minute malicious deployments
269
-
270
- ### 3. Address Match Verification
271
-
272
- The `applyUpgrade` function requires the address to match the pending upgrade. This prevents:
273
- - Front-running attacks
274
- - Address substitution attacks
275
-
276
- ### 4. Storage Compatibility
277
-
278
- When upgrading, ensure storage layout compatibility:
279
-
280
- ```typescript
281
- // V1 - Original
282
- class ContractV1 extends Upgradeable {
283
- private ptr1: u16 = Blockchain.nextPointer; // Pointer 1
284
- private ptr2: u16 = Blockchain.nextPointer; // Pointer 2
285
- }
286
-
287
- // V2 - Add new pointers at the END
288
- class ContractV2 extends Upgradeable {
289
- private ptr1: u16 = Blockchain.nextPointer; // Pointer 1 (same)
290
- private ptr2: u16 = Blockchain.nextPointer; // Pointer 2 (same)
291
- private ptr3: u16 = Blockchain.nextPointer; // Pointer 3 (NEW)
292
- }
293
- ```
294
-
295
- ## Upgrade Workflow
296
-
297
- ```
298
- 1. Deploy new bytecode contract
299
- └─> Returns: newContractAddress
300
-
301
- 2. Submit upgrade
302
- └─> submitUpgrade(newContractAddress)
303
- └─> Emits: UpgradeSubmitted
304
-
305
- 3. Wait for delay
306
- └─> Users can monitor and exit
307
-
308
- 4. Apply upgrade
309
- └─> applyUpgrade(newContractAddress)
310
- └─> Emits: UpgradeApplied
311
- └─> VM calls onUpdate() on new bytecode
312
- └─> New bytecode active next block
313
-
314
- 5. (Optional) Discard source contract
315
- └─> Source contract can be abandoned
316
- ```
317
-
318
- ### The onUpdate Hook
319
-
320
- Override `onUpdate` in your new contract version to perform migrations:
321
-
322
- ```typescript
323
- @final
324
- export class MyContractV2 extends Upgradeable {
325
- protected readonly upgradeDelay: u64 = 144;
326
-
327
- // New storage added in V2
328
- private newFeaturePointer: u16 = Blockchain.nextPointer;
329
- private _newFeature: StoredU256;
330
-
331
- public constructor() {
332
- super();
333
- this._newFeature = new StoredU256(this.newFeaturePointer, EMPTY_POINTER);
334
- }
335
-
336
- public override onUpdate(calldata: Calldata): void {
337
- super.onUpdate(calldata);
338
- // Initialize new storage
339
- this._newFeature.value = u256.fromU64(100);
340
- }
341
-
342
- // ... execute() and other methods
343
- }
344
- ```
345
-
346
- See [The onUpdate Lifecycle Hook](../advanced/contract-upgrades.md#the-onupdate-lifecycle-hook) for more details.
347
-
348
- ## Combining with Other Base Classes
349
-
350
- ### Upgradeable + ReentrancyGuard
351
-
352
- ```typescript
353
- // Create a combined base class
354
- class UpgradeableWithReentrancy extends Upgradeable {
355
- protected readonly reentrancyLevel: ReentrancyLevel = ReentrancyLevel.STANDARD;
356
- private _locked: StoredBoolean;
357
-
358
- protected constructor() {
359
- super();
360
- this._locked = new StoredBoolean(Blockchain.nextPointer, false);
361
- }
362
-
363
- protected nonReentrant(): void {
364
- if (this._locked.value) {
365
- throw new Revert('ReentrancyGuard: LOCKED');
366
- }
367
- this._locked.value = true;
368
- }
369
-
370
- protected releaseGuard(): void {
371
- this._locked.value = false;
372
- }
373
- }
374
-
375
- @final
376
- export class SecureUpgradeableVault extends UpgradeableWithReentrancy {
377
- // Implementation with both upgrade and reentrancy protection
378
- }
379
- ```
380
-
381
- ## Solidity Comparison
382
-
383
- | Feature | OpenZeppelin UUPS | OPNet Upgradeable |
384
- |---------|-------------------|-------------------|
385
- | Upgrade mechanism | delegatecall | Native bytecode replacement |
386
- | Storage location | Implementation contract | Same contract |
387
- | Proxy overhead | Yes | No |
388
- | Timelock | Separate contract (optional) | Built-in |
389
- | Events | Custom | Built-in |
390
- | Cancel upgrade | Custom implementation | Built-in |
391
-
392
- ---
393
-
394
- **Navigation:**
395
- - Previous: [ReentrancyGuard](./reentrancy-guard.md)
396
- - Next: [Address Type](../types/address.md)
@@ -1,242 +0,0 @@
1
- import { u256 } from '@btc-vision/as-bignum/assembly';
2
- import { Blockchain } from '../env';
3
- import { OP_NET } from './OP_NET';
4
- import { StoredAddress } from '../storage/StoredAddress';
5
- import { StoredU256 } from '../storage/StoredU256';
6
- import { Address } from '../types/Address';
7
- import { Revert } from '../types/Revert';
8
- import { BytesWriter } from '../buffer/BytesWriter';
9
- import { EMPTY_POINTER } from '../math/bytes';
10
- import {
11
- UpgradeAppliedEvent,
12
- UpgradeCancelledEvent,
13
- UpgradeSubmittedEvent,
14
- } from '../events/upgradeable/UpgradeableEvents';
15
-
16
- const pendingUpgradeAddressPointer: u16 = Blockchain.nextPointer;
17
- const pendingUpgradeBlockPointer: u16 = Blockchain.nextPointer;
18
-
19
- /**
20
- * Upgradeable - Base contract for upgradeable contracts with timelock protection.
21
- *
22
- * This contract provides a secure upgrade mechanism with a configurable delay period.
23
- * The pattern prevents instant malicious upgrades by requiring:
24
- * 1. submitUpgrade() - Submit the source contract address, starts the timelock
25
- * 2. Wait for the delay period to pass
26
- * 3. applyUpgrade() - Apply the upgrade after the delay
27
- *
28
- * Users can monitor for UpgradeSubmitted events and exit if they distrust pending changes.
29
- *
30
- * @example
31
- * ```typescript
32
- * @final
33
- * export class MyUpgradeableContract extends Upgradeable {
34
- * // Set a 24-hour delay (144 blocks at 10 min/block)
35
- * protected readonly upgradeDelay: u64 = 144;
36
- *
37
- * public override execute(method: Selector, calldata: Calldata): BytesWriter {
38
- * switch (method) {
39
- * case encodeSelector('submitUpgrade'):
40
- * return this.submitUpgrade(calldata.readAddress());
41
- * case encodeSelector('applyUpgrade'):
42
- * const sourceAddress = calldata.readAddress();
43
- * const updateCalldata = new BytesWriter(calldata.byteLength - ADDRESS_BYTE_LENGTH);
44
- * // Copy remaining calldata for onUpdate
45
- * return this.applyUpgrade(sourceAddress, updateCalldata);
46
- * case encodeSelector('cancelUpgrade'):
47
- * return this.cancelUpgrade();
48
- * default:
49
- * return super.execute(method, calldata);
50
- * }
51
- * }
52
- * }
53
- * ```
54
- */
55
- export class Upgradeable extends OP_NET {
56
- /**
57
- * The pending upgrade source address.
58
- * Zero address means no pending upgrade.
59
- */
60
- protected readonly _pendingUpgradeAddress: StoredAddress;
61
-
62
- /**
63
- * The block number when the upgrade was submitted.
64
- * Stored as u256, used as u64.
65
- */
66
- protected readonly _pendingUpgradeBlock: StoredU256;
67
-
68
- /**
69
- * The number of blocks to wait before an upgrade can be applied.
70
- * Override this in derived contracts to set the delay.
71
- *
72
- * Common values:
73
- * - 6 blocks = ~1 hour
74
- * - 144 blocks = ~24 hours
75
- * - 1008 blocks = ~1 week
76
- */
77
- protected readonly upgradeDelay: u64 = 144; // ~24 hours default
78
-
79
- protected constructor() {
80
- super();
81
- this._pendingUpgradeAddress = new StoredAddress(pendingUpgradeAddressPointer);
82
- this._pendingUpgradeBlock = new StoredU256(pendingUpgradeBlockPointer, EMPTY_POINTER);
83
- }
84
-
85
- /**
86
- * Returns the pending upgrade source address.
87
- * Returns zero address if no upgrade is pending.
88
- */
89
- public get pendingUpgradeAddress(): Address {
90
- return this._pendingUpgradeAddress.value;
91
- }
92
-
93
- /**
94
- * Returns the block number when the pending upgrade was submitted.
95
- * Returns 0 if no upgrade is pending.
96
- */
97
- public get pendingUpgradeBlock(): u64 {
98
- return this._pendingUpgradeBlock.value.lo1;
99
- }
100
-
101
- /**
102
- * Returns the block number when the pending upgrade can be applied.
103
- * Returns 0 if no upgrade is pending.
104
- */
105
- public get upgradeEffectiveBlock(): u64 {
106
- const submitBlock = this.pendingUpgradeBlock;
107
- if (submitBlock === 0) return 0;
108
- return submitBlock + this.upgradeDelay;
109
- }
110
-
111
- /**
112
- * Returns true if there is a pending upgrade.
113
- */
114
- public get hasPendingUpgrade(): bool {
115
- return this.pendingUpgradeBlock !== 0;
116
- }
117
-
118
- /**
119
- * Returns true if the pending upgrade can be applied (delay has passed).
120
- */
121
- public get canApplyUpgrade(): bool {
122
- if (!this.hasPendingUpgrade) return false;
123
- return Blockchain.block.number >= this.upgradeEffectiveBlock;
124
- }
125
-
126
- /**
127
- * Submits an upgrade for timelock.
128
- *
129
- * The source address must be a deployed contract containing the new bytecode.
130
- * After submission, the upgrade can only be applied after upgradeDelay blocks.
131
- *
132
- * Emits UpgradeSubmitted event.
133
- *
134
- * @param sourceAddress - The source contract address containing new bytecode
135
- * @returns Empty response
136
- * @throws If caller is not deployer
137
- * @throws If source is not a deployed contract
138
- * @throws If an upgrade is already pending
139
- */
140
- protected submitUpgrade(sourceAddress: Address): BytesWriter {
141
- this.onlyDeployer(Blockchain.tx.sender);
142
-
143
- // Check no pending upgrade
144
- if (this.hasPendingUpgrade) {
145
- throw new Revert('Upgrade already pending. Cancel first.');
146
- }
147
-
148
- // Validate source is a deployed contract
149
- if (!Blockchain.isContract(sourceAddress)) {
150
- throw new Revert('Source must be a deployed contract');
151
- }
152
-
153
- // Store pending upgrade
154
- const currentBlock = Blockchain.block.number;
155
- this._pendingUpgradeAddress.value = sourceAddress;
156
- this._pendingUpgradeBlock.value = u256.fromU64(currentBlock);
157
-
158
- // Emit event
159
- const effectiveBlock = currentBlock + this.upgradeDelay;
160
- Blockchain.emit(new UpgradeSubmittedEvent(sourceAddress, currentBlock, effectiveBlock));
161
-
162
- return new BytesWriter(0);
163
- }
164
-
165
- /**
166
- * Applies a pending upgrade after the timelock period has passed.
167
- *
168
- * The provided address must match the pending upgrade address as an
169
- * additional security measure against front-running attacks.
170
- *
171
- * Emits UpgradeApplied event before the upgrade (new bytecode takes effect next block).
172
- *
173
- * @param sourceAddress - The source contract address (must match pending)
174
- * @param calldata - The calldata to pass to onUpdate method of the new contract
175
- * @returns Empty response
176
- * @throws If caller is not deployer
177
- * @throws If no upgrade is pending
178
- * @throws If delay has not passed
179
- * @throws If provided address does not match pending
180
- */
181
- protected applyUpgrade(sourceAddress: Address, calldata: BytesWriter): BytesWriter {
182
- this.onlyDeployer(Blockchain.tx.sender);
183
-
184
- // Check pending upgrade exists
185
- if (!this.hasPendingUpgrade) {
186
- throw new Revert('No pending upgrade');
187
- }
188
-
189
- // Check delay has passed
190
- if (!this.canApplyUpgrade) {
191
- throw new Revert('Upgrade delay not elapsed');
192
- }
193
-
194
- // Verify address matches pending
195
- if (!sourceAddress.equals(this._pendingUpgradeAddress.value)) {
196
- throw new Revert('Address does not match pending upgrade');
197
- }
198
-
199
- // Clear pending state before upgrade
200
- this._pendingUpgradeAddress.value = Address.zero();
201
- this._pendingUpgradeBlock.value = u256.Zero;
202
-
203
- // Emit event
204
- Blockchain.emit(new UpgradeAppliedEvent(sourceAddress, Blockchain.block.number));
205
-
206
- // Perform upgrade - new bytecode takes effect next block
207
- Blockchain.updateContractFromExisting(sourceAddress, calldata);
208
-
209
- return new BytesWriter(0);
210
- }
211
-
212
- /**
213
- * Cancels a pending upgrade.
214
- *
215
- * Can only be called by the deployer. Clears the pending upgrade state.
216
- *
217
- * Emits UpgradeCancelled event.
218
- *
219
- * @returns Empty response
220
- * @throws If caller is not deployer
221
- * @throws If no upgrade is pending
222
- */
223
- protected cancelUpgrade(): BytesWriter {
224
- this.onlyDeployer(Blockchain.tx.sender);
225
-
226
- // Check pending upgrade exists
227
- if (!this.hasPendingUpgrade) {
228
- throw new Revert('No pending upgrade');
229
- }
230
-
231
- const pendingAddress = this._pendingUpgradeAddress.value;
232
-
233
- // Clear pending state
234
- this._pendingUpgradeAddress.value = Address.zero();
235
- this._pendingUpgradeBlock.value = u256.Zero;
236
-
237
- // Emit event
238
- Blockchain.emit(new UpgradeCancelledEvent(pendingAddress, Blockchain.block.number));
239
-
240
- return new BytesWriter(0);
241
- }
242
- }
@@ -1,33 +0,0 @@
1
- import { BytesWriter } from '../../buffer/BytesWriter';
2
- import { Calldata } from '../../types';
3
-
4
- export interface IOP1155 {
5
- // Core properties
6
- fn_name(calldata: Calldata): BytesWriter;
7
- fn_symbol(calldata: Calldata): BytesWriter;
8
- uri(calldata: Calldata): BytesWriter;
9
-
10
- // Balance and supply
11
- balanceOf(calldata: Calldata): BytesWriter;
12
- balanceOfBatch(calldata: Calldata): BytesWriter;
13
- totalSupply(calldata: Calldata): BytesWriter;
14
- exists(calldata: Calldata): BytesWriter;
15
-
16
- // Transfer functions
17
- safeTransferFrom(calldata: Calldata): BytesWriter;
18
- safeBatchTransferFrom(calldata: Calldata): BytesWriter;
19
-
20
- // Approval functions
21
- setApprovalForAll(calldata: Calldata): BytesWriter;
22
- isApprovedForAll(calldata: Calldata): BytesWriter;
23
-
24
- // Advanced functions
25
- burn(calldata: Calldata): BytesWriter;
26
- burnBatch(calldata: Calldata): BytesWriter;
27
- transferBySignature(calldata: Calldata): BytesWriter;
28
- batchTransferBySignature(calldata: Calldata): BytesWriter;
29
- domainSeparator(calldata: Calldata): BytesWriter;
30
-
31
- // Interface support
32
- supportsInterface(calldata: Calldata): BytesWriter;
33
- }
@@ -1,11 +0,0 @@
1
- export class OP1155InitParameters {
2
- public name: string;
3
- public symbol: string;
4
- public baseUri: string;
5
-
6
- constructor(name: string, symbol: string, baseUri: string) {
7
- this.name = name;
8
- this.symbol = symbol;
9
- this.baseUri = baseUri;
10
- }
11
- }