@btc-vision/btc-runtime 1.10.10 → 1.10.11

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 (44) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +258 -137
  3. package/SECURITY.md +226 -0
  4. package/docs/README.md +614 -0
  5. package/docs/advanced/bitcoin-scripts.md +939 -0
  6. package/docs/advanced/cross-contract-calls.md +579 -0
  7. package/docs/advanced/plugins.md +1006 -0
  8. package/docs/advanced/quantum-resistance.md +660 -0
  9. package/docs/advanced/signature-verification.md +715 -0
  10. package/docs/api-reference/blockchain.md +729 -0
  11. package/docs/api-reference/events.md +642 -0
  12. package/docs/api-reference/op20.md +902 -0
  13. package/docs/api-reference/op721.md +819 -0
  14. package/docs/api-reference/safe-math.md +510 -0
  15. package/docs/api-reference/storage.md +840 -0
  16. package/docs/contracts/op-net-base.md +786 -0
  17. package/docs/contracts/op20-token.md +687 -0
  18. package/docs/contracts/op20s-signatures.md +614 -0
  19. package/docs/contracts/op721-nft.md +785 -0
  20. package/docs/contracts/reentrancy-guard.md +787 -0
  21. package/docs/core-concepts/blockchain-environment.md +724 -0
  22. package/docs/core-concepts/decorators.md +466 -0
  23. package/docs/core-concepts/events.md +652 -0
  24. package/docs/core-concepts/pointers.md +391 -0
  25. package/docs/core-concepts/security.md +473 -0
  26. package/docs/core-concepts/storage-system.md +969 -0
  27. package/docs/examples/basic-token.md +745 -0
  28. package/docs/examples/nft-with-reservations.md +1440 -0
  29. package/docs/examples/oracle-integration.md +1212 -0
  30. package/docs/examples/stablecoin.md +1180 -0
  31. package/docs/getting-started/first-contract.md +575 -0
  32. package/docs/getting-started/installation.md +384 -0
  33. package/docs/getting-started/project-structure.md +630 -0
  34. package/docs/storage/memory-maps.md +764 -0
  35. package/docs/storage/stored-arrays.md +778 -0
  36. package/docs/storage/stored-maps.md +758 -0
  37. package/docs/storage/stored-primitives.md +655 -0
  38. package/docs/types/address.md +773 -0
  39. package/docs/types/bytes-writer-reader.md +938 -0
  40. package/docs/types/calldata.md +744 -0
  41. package/docs/types/safe-math.md +446 -0
  42. package/package.json +51 -26
  43. package/runtime/memory/MapOfMap.ts +1 -0
  44. package/LICENSE.md +0 -21
@@ -0,0 +1,391 @@
1
+ # Pointers
2
+
3
+ Pointers are the foundation of OPNet's storage system. Understanding how they work is essential for building efficient and secure smart contracts.
4
+
5
+ ## What Are Pointers?
6
+
7
+ A pointer is a `u16` value (0-65535) that identifies a storage slot in your contract. Combined with an optional `u256` sub-pointer, it creates a unique storage key through SHA256 hashing.
8
+
9
+ ```
10
+ Storage Key = SHA256(pointer || subPointer)
11
+ ```
12
+
13
+ ### Pointer Structure Visualization
14
+
15
+ ```mermaid
16
+ flowchart LR
17
+ subgraph Construction["32-Byte Storage Key Construction"]
18
+ A["Pointer<br/>(u16, 2 bytes)<br/>0x0003"]
19
+ B["SubPointer<br/>(u256, 30 bytes)<br/>0x00...ABC123"]
20
+ Concat["Concatenation (||)"]
21
+ Hash["SHA256 Hash"]
22
+ Key["Storage Key<br/>(32 bytes)<br/>0x7F3E...9A2D"]
23
+
24
+ A --> Concat
25
+ B --> Concat
26
+ Concat --> Hash
27
+ Hash --> Key
28
+ end
29
+ ```
30
+
31
+ ### Pointer Byte Layout
32
+
33
+ ```mermaid
34
+ flowchart LR
35
+ subgraph Input["Input to SHA256 (32 bytes total)"]
36
+ P["Pointer<br/>2 bytes<br/>[0-1]"]
37
+ S["SubPointer<br/>30 bytes<br/>[2-31]"]
38
+ P --> S
39
+ end
40
+
41
+ subgraph Process["Hashing Process"]
42
+ Arrow["SHA256 Hash"]
43
+ end
44
+
45
+ subgraph Result["Output"]
46
+ Output["Storage Key<br/>32 bytes"]
47
+ end
48
+
49
+ S --> Arrow
50
+ Arrow --> Output
51
+ ```
52
+
53
+ ## Why Pointers?
54
+
55
+ OPNet's pointer system provides:
56
+
57
+ | Benefit | Description |
58
+ |---------|-------------|
59
+ | **Determinism** | Same inputs always produce same storage keys |
60
+ | **Collision Resistance** | SHA256 ensures unique keys |
61
+ | **Verifiability** | Storage proofs can be validated off-chain |
62
+ | **Explicitness** | Storage layout is explicit and auditable |
63
+
64
+ ## Solidity Comparison
65
+
66
+ In Solidity, storage slots are assigned implicitly by the compiler. In OPNet, you explicitly allocate pointers at runtime:
67
+
68
+ ```solidity
69
+ // Solidity - Implicit slot assignment
70
+ contract Token {
71
+ uint256 public totalSupply; // slot 0 (assigned by compiler)
72
+ string public name; // slot 1 (assigned by compiler)
73
+ mapping(address => uint256) balances; // slot 2 (assigned by compiler)
74
+ }
75
+ ```
76
+
77
+ ```typescript
78
+ // OPNet - Explicit pointer allocation
79
+ export class Token extends OP_NET {
80
+ private totalSupplyPointer: u16 = Blockchain.nextPointer; // ~0 (allocated at runtime)
81
+ private namePointer: u16 = Blockchain.nextPointer; // ~1 (allocated at runtime)
82
+ private balancesPointer: u16 = Blockchain.nextPointer; // ~2 (allocated at runtime)
83
+ }
84
+ ```
85
+
86
+ ### Storage Key Hashing Comparison
87
+
88
+ | Solidity | OPNet |
89
+ |----------|-------|
90
+ | Automatic slot assignment | Explicit pointer allocation |
91
+ | Slot 0, 1, 2, ... | `Blockchain.nextPointer` |
92
+ | `keccak256(key . slot)` | `SHA256(pointer \|\| subPointer)` |
93
+
94
+ ## Allocating Pointers
95
+
96
+ ### Basic Allocation
97
+
98
+ Use `Blockchain.nextPointer` to get unique pointers:
99
+
100
+ ```typescript
101
+ import { Blockchain } from '@btc-vision/btc-runtime/runtime';
102
+
103
+ @final
104
+ export class MyContract extends OP_NET {
105
+ // Each call returns a unique, sequential u16
106
+ private counterPointer: u16 = Blockchain.nextPointer; // e.g., 0
107
+ private ownerPointer: u16 = Blockchain.nextPointer; // e.g., 1
108
+ private balancesPointer: u16 = Blockchain.nextPointer; // e.g., 2
109
+ }
110
+ ```
111
+
112
+ ### Pointer Range
113
+
114
+ ```
115
+ u16 range: 0 to 65,535
116
+
117
+ Your contract can have up to 65,536 unique pointer slots.
118
+ ```
119
+
120
+ ### Important Rules
121
+
122
+ 1. **Call `nextPointer` once per storage slot** - Don't reuse pointers
123
+ 2. **Allocate at class level** - Pointers should be class properties
124
+ 3. **Order matters** - Pointers are assigned sequentially
125
+ 4. **Never hardcode** - Always use `Blockchain.nextPointer`
126
+
127
+ ## Pointer vs Sub-Pointer
128
+
129
+ ### Primary Pointer (u16)
130
+
131
+ The primary pointer identifies the **type** of storage:
132
+
133
+ ```typescript
134
+ private balancesPointer: u16 = Blockchain.nextPointer; // "balances mapping"
135
+ private allowancesPointer: u16 = Blockchain.nextPointer; // "allowances mapping"
136
+ ```
137
+
138
+ ### Sub-Pointer (u256)
139
+
140
+ The sub-pointer identifies a **specific entry** within that storage type:
141
+
142
+ ```typescript
143
+ // balances[address] = amount
144
+ // pointer = balancesPointer
145
+ // subPointer = address (converted to u256)
146
+
147
+ const key = SHA256(balancesPointer || addressAsU256);
148
+ ```
149
+
150
+ ### Visual Example
151
+
152
+ ```
153
+ Contract Storage
154
+ |
155
+ +-- Pointer 0 (totalSupply)
156
+ | +-- SubPointer 0 -> u256 value
157
+ |
158
+ +-- Pointer 1 (name)
159
+ | +-- SubPointer 0 -> string value
160
+ |
161
+ +-- Pointer 2 (balances mapping)
162
+ | +-- SubPointer 0xAAA... -> balance of 0xAAA
163
+ | +-- SubPointer 0xBBB... -> balance of 0xBBB
164
+ | +-- SubPointer 0xCCC... -> balance of 0xCCC
165
+ |
166
+ +-- Pointer 3 (allowances nested mapping)
167
+ +-- SubPointer hash(0xAAA, 0xBBB) -> allowance[AAA][BBB]
168
+ +-- SubPointer hash(0xAAA, 0xCCC) -> allowance[AAA][CCC]
169
+ ```
170
+
171
+ ### Multiple Storage Variables Example
172
+
173
+ ```mermaid
174
+ flowchart LR
175
+ subgraph Contract["Token Contract"]
176
+ Root["Contract Root"]
177
+ end
178
+
179
+ subgraph SimpleValues["Simple Storage (Single Values)"]
180
+ P0["Pointer 0: totalSupply<br/>StoredU256"]
181
+ P1["Pointer 1: name<br/>StoredString"]
182
+ P2["Pointer 2: symbol<br/>StoredString"]
183
+
184
+ K0["Key: SHA256(0 || 0)<br/>Value: u256"]
185
+ K1["Key: SHA256(1 || 0)<br/>Value: 'MyToken'"]
186
+ K2["Key: SHA256(2 || 0)<br/>Value: 'MTK'"]
187
+
188
+ P0 --> K0
189
+ P1 --> K1
190
+ P2 --> K2
191
+ end
192
+
193
+ subgraph Mappings["Mappings (Multiple Values)"]
194
+ P3["Pointer 3: balances<br/>AddressMemoryMap"]
195
+ P4["Pointer 4: allowances<br/>MapOfMap"]
196
+
197
+ K3A["Key: SHA256(3 || 0xAAA...)<br/>Value: 1000"]
198
+ K3B["Key: SHA256(3 || 0xBBB...)<br/>Value: 500"]
199
+ K3C["Key: SHA256(3 || 0xCCC...)<br/>Value: 250"]
200
+
201
+ K4A["Key: SHA256(4 || hash(owner,spender1))<br/>Value: 100"]
202
+ K4B["Key: SHA256(4 || hash(owner,spender2))<br/>Value: 200"]
203
+
204
+ P3 --> K3A
205
+ P3 --> K3B
206
+ P3 --> K3C
207
+
208
+ P4 --> K4A
209
+ P4 --> K4B
210
+ end
211
+
212
+ Root --> P0
213
+ Root --> P1
214
+ Root --> P2
215
+ Root --> P3
216
+ Root --> P4
217
+ ```
218
+
219
+ ## Pointer Patterns
220
+
221
+ ### Simple Value
222
+
223
+ ```typescript
224
+ import { EMPTY_POINTER } from '@btc-vision/btc-runtime/runtime';
225
+
226
+ // Single value storage
227
+ private totalSupplyPointer: u16 = Blockchain.nextPointer;
228
+ private _totalSupply: StoredU256 = new StoredU256(
229
+ this.totalSupplyPointer,
230
+ EMPTY_POINTER
231
+ );
232
+
233
+ // Storage key: SHA256(totalSupplyPointer || 0)
234
+ ```
235
+
236
+ ### Mapping
237
+
238
+ ```typescript
239
+ // mapping(address => uint256)
240
+ private balancesPointer: u16 = Blockchain.nextPointer;
241
+ private balances: AddressMemoryMap = new AddressMemoryMap(this.balancesPointer);
242
+
243
+ // For balances[0xABC]:
244
+ // Storage key: SHA256(balancesPointer || 0xABC)
245
+ ```
246
+
247
+ ### Nested Mapping
248
+
249
+ ```typescript
250
+ // mapping(address => mapping(address => uint256))
251
+ private allowancesPointer: u16 = Blockchain.nextPointer;
252
+
253
+ // For allowances[owner][spender]:
254
+ // SubPointer = SHA256(owner || spender)
255
+ // Storage key: SHA256(allowancesPointer || SubPointer)
256
+ ```
257
+
258
+ ### Array
259
+
260
+ ```typescript
261
+ // uint256[] holders
262
+ private holdersPointer: u16 = Blockchain.nextPointer;
263
+ private holders: StoredU256Array = new StoredU256Array(this.holdersPointer);
264
+
265
+ // For holders[i]:
266
+ // Storage key: SHA256(holdersPointer || i)
267
+
268
+ // For holders.length:
269
+ // Storage key: SHA256(holdersPointer || MAX_U256) // Special length slot
270
+ ```
271
+
272
+ ## Advanced: Manual Key Calculation
273
+
274
+ For advanced use cases, you can calculate storage keys manually:
275
+
276
+ ```typescript
277
+ import { Blockchain, encodePointer } from '@btc-vision/btc-runtime/runtime';
278
+
279
+ // Generate storage key (32-byte hash)
280
+ const pointerHash = encodePointer(pointer, subPointer);
281
+
282
+ // Direct storage access
283
+ const stored = Blockchain.getStorageAt(pointerHash);
284
+ const value = u256.fromUint8ArrayBE(stored);
285
+
286
+ // Write to storage
287
+ Blockchain.setStorageAt(pointerHash, value.toUint8Array(true));
288
+ ```
289
+
290
+ ### encodePointer() Function Flow
291
+
292
+ ```mermaid
293
+ flowchart LR
294
+ A["pointer: u16<br/>subPointer: u256"] --> B["32-byte buffer<br/>[0-1] = pointer<br/>[2-31] = subPointer"]
295
+ B --> C["SHA256"]
296
+ C --> D["Storage Key<br/>(32 bytes)"]
297
+ ```
298
+
299
+ ## Collision Prevention
300
+
301
+ The SHA256 hashing ensures collision resistance:
302
+
303
+ ```typescript
304
+ // Different pointers = different keys
305
+ SHA256(0 || 0xABC) != SHA256(1 || 0xABC)
306
+
307
+ // Different sub-pointers = different keys
308
+ SHA256(0 || 0xABC) != SHA256(0 || 0xDEF)
309
+
310
+ // Even with same total bits
311
+ SHA256(0x0001 || 0x00...00) != SHA256(0x0000 || 0x00...01)
312
+ ```
313
+
314
+ ## Best Practices
315
+
316
+ ### 1. Document Your Pointer Layout
317
+
318
+ ```typescript
319
+ /**
320
+ * Storage Layout:
321
+ * Pointer 0: totalSupply (u256)
322
+ * Pointer 1: name (string)
323
+ * Pointer 2: symbol (string)
324
+ * Pointer 3: decimals (u8)
325
+ * Pointer 4: balances (address => u256)
326
+ * Pointer 5: allowances (address => address => u256)
327
+ * Pointer 6: paused (bool)
328
+ */
329
+ export class MyToken extends OP20 {
330
+ // ... pointers allocated in this order
331
+ }
332
+ ```
333
+
334
+ ### 2. Group Related Pointers
335
+
336
+ ```typescript
337
+ // Token metadata pointers
338
+ private namePointer: u16 = Blockchain.nextPointer;
339
+ private symbolPointer: u16 = Blockchain.nextPointer;
340
+ private decimalsPointer: u16 = Blockchain.nextPointer;
341
+
342
+ // Balance pointers
343
+ private balancesPointer: u16 = Blockchain.nextPointer;
344
+ private totalSupplyPointer: u16 = Blockchain.nextPointer;
345
+
346
+ // Approval pointers
347
+ private allowancesPointer: u16 = Blockchain.nextPointer;
348
+ ```
349
+
350
+ ### 3. Never Reuse Pointers
351
+
352
+ ```typescript
353
+ // WRONG: Reusing pointer for different data
354
+ private myPointer: u16 = Blockchain.nextPointer;
355
+ private valueA: StoredU256 = new StoredU256(this.myPointer, EMPTY_POINTER);
356
+ private valueB: StoredU256 = new StoredU256(this.myPointer, EMPTY_POINTER); // BUG!
357
+
358
+ // CORRECT: Unique pointer for each
359
+ private pointerA: u16 = Blockchain.nextPointer;
360
+ private pointerB: u16 = Blockchain.nextPointer;
361
+ private valueA: StoredU256 = new StoredU256(this.pointerA, EMPTY_POINTER);
362
+ private valueB: StoredU256 = new StoredU256(this.pointerB, EMPTY_POINTER);
363
+ ```
364
+
365
+ ### 4. Understand Inheritance
366
+
367
+ When extending contracts, parent pointers are allocated first:
368
+
369
+ ```typescript
370
+ // OP20 allocates pointers 0-6 internally
371
+ export class MyToken extends OP20 {
372
+ // Your pointers start after OP20's
373
+ private customPointer: u16 = Blockchain.nextPointer; // ~7
374
+ }
375
+ ```
376
+
377
+ ## Debugging Pointers
378
+
379
+ To debug storage issues:
380
+
381
+ ```typescript
382
+ // Log pointer values during development
383
+ console.log(`Balance pointer: ${this.balancesPointer}`);
384
+ console.log(`Expected key: ${encodePointer(this.balancesPointer, addressAsU256)}`);
385
+ ```
386
+
387
+ ---
388
+
389
+ **Navigation:**
390
+ - Previous: [Storage System](./storage-system.md)
391
+ - Next: [Events](./events.md)