@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,446 @@
1
+ # SafeMath
2
+
3
+ SafeMath provides overflow-safe arithmetic operations for `u256` and other numeric types. It's essential for all smart contract arithmetic to prevent silent overflow/underflow bugs.
4
+
5
+ ## Overview
6
+
7
+ ```typescript
8
+ import { SafeMath } from '@btc-vision/btc-runtime/runtime';
9
+ import { u256 } from '@btc-vision/as-bignum/assembly';
10
+
11
+ const a = u256.fromU64(100);
12
+ const b = u256.fromU64(50);
13
+
14
+ // Safe operations
15
+ const sum = SafeMath.add(a, b); // 150
16
+ const diff = SafeMath.sub(a, b); // 50
17
+ const product = SafeMath.mul(a, b); // 5000
18
+ const quotient = SafeMath.div(a, b); // 2
19
+ ```
20
+
21
+ ## Why SafeMath?
22
+
23
+ ### The Problem
24
+
25
+ Native arithmetic can overflow silently:
26
+
27
+ ```typescript
28
+ // DANGEROUS: Silent overflow
29
+ const max = u256.Max;
30
+ const result = max + u256.One; // Wraps to 0!
31
+
32
+ // DANGEROUS: Silent underflow
33
+ const zero = u256.Zero;
34
+ const result = zero - u256.One; // Wraps to u256.Max!
35
+ ```
36
+
37
+ ### The Solution
38
+
39
+ SafeMath reverts on overflow/underflow:
40
+
41
+ ```typescript
42
+ // SAFE: Reverts on overflow
43
+ const max = u256.Max;
44
+ const result = SafeMath.add(max, u256.One); // Reverts!
45
+
46
+ // SAFE: Reverts on underflow
47
+ const zero = u256.Zero;
48
+ const result = SafeMath.sub(zero, u256.One); // Reverts!
49
+ ```
50
+
51
+ ## Basic Operations
52
+
53
+ ### Addition
54
+
55
+ ```typescript
56
+ const sum = SafeMath.add(a, b);
57
+
58
+ // Reverts if a + b > u256.Max
59
+ // Equivalent to Solidity: a + b (with checked arithmetic)
60
+ ```
61
+
62
+ ### Subtraction
63
+
64
+ ```typescript
65
+ const diff = SafeMath.sub(a, b);
66
+
67
+ // Reverts if b > a (would underflow)
68
+ // Equivalent to Solidity: a - b (with checked arithmetic)
69
+ ```
70
+
71
+ ### Multiplication
72
+
73
+ ```typescript
74
+ const product = SafeMath.mul(a, b);
75
+
76
+ // Reverts if a * b > u256.Max
77
+ // Equivalent to Solidity: a * b (with checked arithmetic)
78
+ ```
79
+
80
+ ### Division
81
+
82
+ ```typescript
83
+ const quotient = SafeMath.div(a, b);
84
+
85
+ // Reverts if b == 0
86
+ // Equivalent to Solidity: a / b
87
+ ```
88
+
89
+ ### Modulo
90
+
91
+ ```typescript
92
+ const remainder = SafeMath.mod(a, b);
93
+
94
+ // Reverts if b == 0
95
+ // Equivalent to Solidity: a % b
96
+ ```
97
+
98
+ ## Advanced Operations
99
+
100
+ ### Power (Exponentiation)
101
+
102
+ ```typescript
103
+ const base = u256.fromU64(2);
104
+ const exp = u256.fromU64(10);
105
+
106
+ const result = SafeMath.pow(base, exp); // 2^10 = 1024
107
+
108
+ // Reverts on overflow
109
+ // Uses efficient exponentiation by squaring (binary exponentiation)
110
+ ```
111
+
112
+ ### Power of 10
113
+
114
+ ```typescript
115
+ // Optimized function for 10^n
116
+ const million = SafeMath.pow10(6); // 10^6 = 1,000,000
117
+ const ether = SafeMath.pow10(18); // 10^18
118
+
119
+ // Maximum safe exponent is 77 (10^78 > u256.Max)
120
+ // Reverts if exponent > 77
121
+ ```
122
+
123
+ ### Square Root
124
+
125
+ ```typescript
126
+ const value = u256.fromU64(144);
127
+ const sqrt = SafeMath.sqrt(value); // 12
128
+
129
+ // Uses Newton-Raphson method
130
+ // Returns floor of square root
131
+ ```
132
+
133
+ ### Increment and Decrement
134
+
135
+ ```typescript
136
+ const value = u256.fromU64(100);
137
+
138
+ // Safe increment (reverts at u256.Max)
139
+ const incremented = SafeMath.inc(value); // 101
140
+
141
+ // Safe decrement (reverts at 0)
142
+ const decremented = SafeMath.dec(value); // 99
143
+ ```
144
+
145
+ ## Shift Operations
146
+
147
+ ### Left Shift
148
+
149
+ ```typescript
150
+ const shifted = SafeMath.shl(value, 10); // value << 10
151
+
152
+ // WARNING: Unlike other SafeMath operations, bit shifts do NOT throw on overflow!
153
+ // Bits shifted beyond the type width are SILENTLY LOST
154
+ // Shifts >= 256 return 0
155
+ // Negative shifts return 0 (defensive behavior)
156
+ ```
157
+
158
+ ### Right Shift
159
+
160
+ ```typescript
161
+ const shifted = SafeMath.shr(value, 5); // value >> 5
162
+
163
+ // Right shift is always safe (can't overflow)
164
+ // Equivalent to division by 2^bits
165
+ ```
166
+
167
+ ### Bitwise Operations
168
+
169
+ ```typescript
170
+ // AND operation
171
+ const result1 = SafeMath.and(a, b); // a & b
172
+
173
+ // OR operation
174
+ const result2 = SafeMath.or(a, b); // a | b
175
+
176
+ // XOR operation
177
+ const result3 = SafeMath.xor(a, b); // a ^ b
178
+
179
+ // Check if even
180
+ const isEven = SafeMath.isEven(value); // (value & 1) == 0
181
+ ```
182
+
183
+ ## Comparison Operations
184
+
185
+ ```typescript
186
+ // Use u256 built-in comparison methods (not SafeMath)
187
+ if (u256.lt(a, b)) { } // Less than
188
+ if (u256.le(a, b)) { } // Less than or equal
189
+ if (u256.gt(a, b)) { } // Greater than
190
+ if (u256.ge(a, b)) { } // Greater than or equal
191
+ if (u256.eq(a, b)) { } // Equal
192
+ if (u256.ne(a, b)) { } // Not equal
193
+
194
+ // SafeMath provides min/max operations
195
+ const smaller = SafeMath.min(a, b);
196
+ const larger = SafeMath.max(a, b);
197
+ ```
198
+
199
+ ## Specialized Functions
200
+
201
+ ### Modular Multiplication
202
+
203
+ ```typescript
204
+ // (a * b) % n without intermediate overflow
205
+ const result = SafeMath.mulmod(a, b, n);
206
+
207
+ // Useful for cryptographic operations
208
+ ```
209
+
210
+ ### Modular Inverse
211
+
212
+ ```typescript
213
+ // Find x such that (a * x) % n == 1
214
+ const inverse = SafeMath.modInverse(a, n);
215
+
216
+ // Used in elliptic curve operations
217
+ // Reverts if inverse doesn't exist
218
+ ```
219
+
220
+ ### Logarithm Operations
221
+
222
+ ```typescript
223
+ // Approximate log2 (returns floor of log2(x))
224
+ // Fast O(1) using bit length calculation
225
+ const log2 = SafeMath.approximateLog2(value); // Returns u256
226
+
227
+ // Precise natural log (ln) scaled by 10^6 for fixed-point precision
228
+ // Higher accuracy but more gas intensive
229
+ const lnScaled = SafeMath.preciseLog(value); // ln(x) * 1e6
230
+
231
+ // Approximate natural log scaled by 10^6
232
+ // Uses bit length * ln(2) approximation
233
+ const approxLn = SafeMath.approxLog(value); // Approximate ln(x) * 1e6
234
+
235
+ // Bit length (number of bits needed to represent value)
236
+ const bits = SafeMath.bitLength256(value); // Returns u32
237
+ ```
238
+
239
+ ## Operations for Other Integer Sizes
240
+
241
+ SafeMath provides variants for u128 and u64 for more efficient operations when u256 is not needed:
242
+
243
+ ### u128 Operations
244
+
245
+ ```typescript
246
+ import { u128 } from '@btc-vision/as-bignum/assembly';
247
+
248
+ const a = u128.fromU64(100);
249
+ const b = u128.fromU64(50);
250
+
251
+ SafeMath.add128(a, b); // Addition
252
+ SafeMath.sub128(a, b); // Subtraction
253
+ SafeMath.mul128(a, b); // Multiplication
254
+ SafeMath.div128(a, b); // Division
255
+ SafeMath.min128(a, b); // Minimum
256
+ SafeMath.max128(a, b); // Maximum
257
+ SafeMath.shl128(a, 10); // Left shift
258
+ ```
259
+
260
+ ### u64 Operations
261
+
262
+ ```typescript
263
+ const x: u64 = 100;
264
+ const y: u64 = 50;
265
+
266
+ SafeMath.add64(x, y); // Addition
267
+ SafeMath.sub64(x, y); // Subtraction
268
+ SafeMath.mul64(x, y); // Multiplication
269
+ SafeMath.div64(x, y); // Division
270
+ SafeMath.min64(x, y); // Minimum
271
+ SafeMath.max64(x, y); // Maximum
272
+ ```
273
+
274
+ ## Solidity Comparison
275
+
276
+ | Solidity | SafeMath |
277
+ |----------|----------|
278
+ | `a + b` (checked) | `SafeMath.add(a, b)` |
279
+ | `a - b` (checked) | `SafeMath.sub(a, b)` |
280
+ | `a * b` (checked) | `SafeMath.mul(a, b)` |
281
+ | `a / b` | `SafeMath.div(a, b)` |
282
+ | `a % b` | `SafeMath.mod(a, b)` |
283
+ | `a ** b` | `SafeMath.pow(a, b)` |
284
+ | `mulmod(a, b, n)` | `SafeMath.mulmod(a, b, n)` |
285
+
286
+ ## SafeMathI128
287
+
288
+ For signed 128-bit arithmetic:
289
+
290
+ ```typescript
291
+ import { SafeMathI128 } from '@btc-vision/btc-runtime/runtime';
292
+ import { i128 } from '@btc-vision/as-bignum/assembly';
293
+
294
+ const a = i128.from(-100);
295
+ const b = i128.from(50);
296
+
297
+ const sum = SafeMathI128.add(a, b); // -50
298
+ const diff = SafeMathI128.sub(a, b); // -150
299
+
300
+ // Handles signed overflow correctly
301
+ ```
302
+
303
+ ## Common Patterns
304
+
305
+ ### Percentage Calculation
306
+
307
+ ```typescript
308
+ // Calculate percentage: (amount * percentage) / 100
309
+ public calculatePercentage(amount: u256, percentage: u256): u256 {
310
+ const numerator = SafeMath.mul(amount, percentage);
311
+ return SafeMath.div(numerator, u256.fromU64(100));
312
+ }
313
+
314
+ // Example: 10% of 1000
315
+ const result = calculatePercentage(u256.fromU64(1000), u256.fromU64(10)); // 100
316
+ ```
317
+
318
+ ### Fee Deduction
319
+
320
+ ```typescript
321
+ // Deduct fee and return remaining
322
+ public deductFee(amount: u256, feePercent: u256): u256 {
323
+ const fee = SafeMath.div(SafeMath.mul(amount, feePercent), u256.fromU64(100));
324
+ return SafeMath.sub(amount, fee);
325
+ }
326
+ ```
327
+
328
+ ### Balance Updates
329
+
330
+ ```typescript
331
+ // Safe balance increase
332
+ private addToBalance(addr: Address, amount: u256): void {
333
+ const current = this.balances.get(addr);
334
+ const newBalance = SafeMath.add(current, amount);
335
+ this.balances.set(addr, newBalance);
336
+ }
337
+
338
+ // Safe balance decrease
339
+ private subFromBalance(addr: Address, amount: u256): void {
340
+ const current = this.balances.get(addr);
341
+ if (current < amount) {
342
+ throw new Revert('Insufficient balance');
343
+ }
344
+ const newBalance = SafeMath.sub(current, amount);
345
+ this.balances.set(addr, newBalance);
346
+ }
347
+ ```
348
+
349
+ ### Supply Cap Enforcement
350
+
351
+ ```typescript
352
+ public mint(to: Address, amount: u256): void {
353
+ const currentSupply = this.totalSupply.value;
354
+ const maxSupply = this.maxSupply.value;
355
+
356
+ // Check supply cap
357
+ const newSupply = SafeMath.add(currentSupply, amount);
358
+ if (newSupply > maxSupply) {
359
+ throw new Revert('Exceeds max supply');
360
+ }
361
+
362
+ this.totalSupply.value = newSupply;
363
+ this.addToBalance(to, amount);
364
+ }
365
+ ```
366
+
367
+ ## Edge Cases
368
+
369
+ ### Division by Zero
370
+
371
+ ```typescript
372
+ // Always reverts
373
+ SafeMath.div(u256.fromU64(100), u256.Zero); // Reverts!
374
+ SafeMath.mod(u256.fromU64(100), u256.Zero); // Reverts!
375
+ ```
376
+
377
+ ### Power Edge Cases
378
+
379
+ ```typescript
380
+ // 0^0 = 1 (mathematical convention)
381
+ SafeMath.pow(u256.Zero, u256.Zero); // Returns 1
382
+
383
+ // n^0 = 1
384
+ SafeMath.pow(u256.fromU64(5), u256.Zero); // Returns 1
385
+
386
+ // 0^n = 0 (for n > 0)
387
+ SafeMath.pow(u256.Zero, u256.fromU64(5)); // Returns 0
388
+
389
+ // 1^n = 1
390
+ SafeMath.pow(u256.One, u256.fromU64(1000)); // Returns 1
391
+ ```
392
+
393
+ ### Maximum Values
394
+
395
+ ```typescript
396
+ // Near max value operations
397
+ const nearMax = SafeMath.sub(u256.Max, u256.fromU64(10));
398
+
399
+ SafeMath.add(nearMax, u256.fromU64(5)); // OK: 5 from max
400
+ SafeMath.add(nearMax, u256.fromU64(15)); // Reverts: would overflow
401
+ ```
402
+
403
+ ## Best Practices
404
+
405
+ ### 1. Always Use SafeMath
406
+
407
+ ```typescript
408
+ // WRONG
409
+ const sum = a + b;
410
+ const diff = a - b;
411
+
412
+ // CORRECT
413
+ const sum = SafeMath.add(a, b);
414
+ const diff = SafeMath.sub(a, b);
415
+ ```
416
+
417
+ ### 2. Validate Before Division
418
+
419
+ ```typescript
420
+ // Explicit zero check for better error messages
421
+ public divide(a: u256, b: u256): u256 {
422
+ if (b.isZero()) {
423
+ throw new Revert('Division by zero');
424
+ }
425
+ return SafeMath.div(a, b);
426
+ }
427
+ ```
428
+
429
+ ### 3. Order Operations to Minimize Overflow
430
+
431
+ ```typescript
432
+ // RISKY: Large intermediate value
433
+ const result = SafeMath.div(SafeMath.mul(largeA, largeB), c);
434
+
435
+ // BETTER: Divide first if possible
436
+ const result = SafeMath.mul(SafeMath.div(largeA, c), largeB);
437
+
438
+ // BEST: Use muldiv for multiplication then division
439
+ const result = u128.muldiv(largeA, largeB, c);
440
+ ```
441
+
442
+ ---
443
+
444
+ **Navigation:**
445
+ - Previous: [Address](./address.md)
446
+ - Next: [Calldata](./calldata.md)
package/package.json CHANGED
@@ -1,36 +1,46 @@
1
1
  {
2
2
  "name": "@btc-vision/btc-runtime",
3
- "version": "1.10.10",
4
- "description": "Bitcoin Smart Contract Runtime",
3
+ "version": "1.10.11",
4
+ "description": "Bitcoin L1 Smart Contract Runtime for OPNet. Build decentralized applications on Bitcoin using AssemblyScript and WebAssembly. Fully audited.",
5
5
  "main": "btc/index.ts",
6
- "scripts": {
7
- "test": "asp --config as-pect.config.js --verbose --no-logo",
8
- "test:ci": "asp --config as-pect.config.js --summary --no-logo"
9
- },
10
6
  "types": "btc/index.ts",
7
+ "author": "OPNet <support@opnet.org>",
8
+ "license": "Apache-2.0",
9
+ "homepage": "https://opnet.org",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/btc-vision/btc-runtime.git"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/btc-vision/btc-runtime/issues"
16
+ },
17
+ "funding": {
18
+ "type": "github",
19
+ "url": "https://github.com/sponsors/btc-vision"
20
+ },
11
21
  "keywords": [
12
22
  "bitcoin",
13
- "smart",
14
- "contract",
23
+ "smart-contracts",
24
+ "blockchain",
15
25
  "runtime",
16
26
  "opnet",
17
- "OP_NET"
27
+ "OP_NET",
28
+ "OP20",
29
+ "OP721",
30
+ "wasm",
31
+ "webassembly",
32
+ "assemblyscript",
33
+ "defi",
34
+ "tokens",
35
+ "nft",
36
+ "l1",
37
+ "layer1",
38
+ "deterministic",
39
+ "quantum-resistant"
18
40
  ],
19
- "homepage": "https://opnet.org",
20
- "author": "BlobMaster41",
21
- "license": "MIT",
22
- "devDependencies": {
23
- "@btc-vision/as-covers-assembly": "^0.4.4",
24
- "@btc-vision/as-covers-transform": "^0.4.4",
25
- "@btc-vision/as-pect-assembly": "^8.2.0",
26
- "@btc-vision/as-pect-cli": "^8.2.0",
27
- "@btc-vision/as-pect-transform": "^8.2.0",
28
- "@types/node": "^24.10.1",
29
- "assemblyscript": "^0.28.9"
30
- },
31
- "repository": {
32
- "type": "git",
33
- "url": "https://github.com/btc-vision/btc-runtime"
41
+ "scripts": {
42
+ "test": "asp --config as-pect.config.js --verbose --no-logo",
43
+ "test:ci": "asp --config as-pect.config.js --summary --no-logo"
34
44
  },
35
45
  "type": "module",
36
46
  "files": [
@@ -40,16 +50,31 @@
40
50
  "runtime/**/*.ts",
41
51
  "!**/*.js.map",
42
52
  "!**/*.tsbuildinfo",
43
- "test/*.ts"
53
+ "README.md",
54
+ "SECURITY.md",
55
+ "LICENSE",
56
+ "docs"
44
57
  ],
58
+ "engines": {
59
+ "node": ">=22.0.0"
60
+ },
45
61
  "dependencies": {
46
62
  "@assemblyscript/loader": "^0.28.9",
47
- "@btc-vision/as-bignum": "^0.0.6",
63
+ "@btc-vision/as-bignum": "^0.0.7",
48
64
  "@btc-vision/opnet-transform": "^0.2.1",
49
65
  "@eslint/js": "9.39.1",
50
66
  "gulplog": "^2.2.0",
51
67
  "ts-node": "^10.9.2",
52
68
  "typescript": "^5.9.3",
53
69
  "typescript-eslint": "^8.46.3"
70
+ },
71
+ "devDependencies": {
72
+ "@btc-vision/as-covers-assembly": "^0.4.4",
73
+ "@btc-vision/as-covers-transform": "^0.4.4",
74
+ "@btc-vision/as-pect-assembly": "^8.2.0",
75
+ "@btc-vision/as-pect-cli": "^8.2.0",
76
+ "@btc-vision/as-pect-transform": "^8.2.0",
77
+ "@types/node": "^24.10.1",
78
+ "assemblyscript": "^0.28.9"
54
79
  }
55
80
  }
@@ -1,5 +1,6 @@
1
1
  import { Address } from '../types/Address';
2
2
  import { Nested } from './Nested';
3
+ import { Map } from '../generic/Map';
3
4
 
4
5
  @final
5
6
  export class MapOfMap<T> extends Map<Address, Nested<T>> {
package/LICENSE.md DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 [Orange Pill Labs Holding Ltd.]
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.