@btc-vision/btc-runtime 1.10.10 → 1.10.12

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 (45) 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 +731 -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 +370 -0
  26. package/docs/core-concepts/storage-system.md +938 -0
  27. package/docs/examples/basic-token.md +745 -0
  28. package/docs/examples/nft-with-reservations.md +1210 -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 +721 -0
  35. package/docs/storage/stored-arrays.md +714 -0
  36. package/docs/storage/stored-maps.md +686 -0
  37. package/docs/storage/stored-primitives.md +608 -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 +403 -0
  42. package/package.json +51 -26
  43. package/runtime/memory/MapOfMap.ts +1 -0
  44. package/runtime/types/SafeMath.ts +121 -1
  45. package/LICENSE.md +0 -21
@@ -0,0 +1,724 @@
1
+ # Blockchain Environment
2
+
3
+ The `Blockchain` object is the primary interface for interacting with the OPNet runtime. It provides access to block information, transaction context, storage operations, cryptographic functions, and cross-contract calls.
4
+
5
+ ## Overview
6
+
7
+ ```typescript
8
+ import { Blockchain } from '@btc-vision/btc-runtime/runtime';
9
+ ```
10
+
11
+ The `Blockchain` object is globally available in all contracts and provides:
12
+
13
+ | Category | Description |
14
+ |----------|-------------|
15
+ | **Block Context** | Current block information (height, hash, timestamp) |
16
+ | **Transaction Context** | Sender, origin, inputs, outputs |
17
+ | **Contract Context** | Contract address, deployer, identity |
18
+ | **Storage** | Read/write persistent and transient storage |
19
+ | **Pointers** | Allocate storage slots |
20
+ | **Cross-Contract Calls** | Call other contracts |
21
+ | **Cryptography** | Hashing and signature verification |
22
+ | **Events** | Emit events |
23
+
24
+ ## Block Context
25
+
26
+ Access information about the current block:
27
+
28
+ ```typescript
29
+ // Current block number (height)
30
+ const blockNumber: u64 = Blockchain.block.number;
31
+
32
+ // Block number as u256
33
+ const blockNumberU256: u256 = Blockchain.block.numberU256;
34
+
35
+ // Block hash
36
+ const blockHash: Uint8Array = Blockchain.block.hash;
37
+
38
+ // Median time past (consensus timestamp)
39
+ const timestamp: u64 = Blockchain.block.medianTimestamp;
40
+ ```
41
+
42
+ ```mermaid
43
+ ---
44
+ config:
45
+ theme: dark
46
+ ---
47
+ flowchart LR
48
+ subgraph Block["Block Context"]
49
+ B1["Blockchain.block.number"] --> V1["u64"]
50
+ B2["Blockchain.block.numberU256"] --> V2["u256"]
51
+ B3["Blockchain.block.hash"] --> V3["Uint8Array (32 bytes)"]
52
+ B4["Blockchain.block.medianTimestamp"] --> V4["u64"]
53
+ end
54
+ ```
55
+
56
+ ### Solidity Comparison
57
+
58
+ | Solidity | OPNet | Notes |
59
+ |----------|-------|-------|
60
+ | `block.number` | `Blockchain.block.number` | Current block height |
61
+ | `block.timestamp` | `Blockchain.block.medianTimestamp` | OPNet uses Median Time Past |
62
+ | `blockhash(n)` | `Blockchain.getBlockHash(n)` | Historical block hash |
63
+
64
+ ### Median Time Past
65
+
66
+ OPNet uses **Median Time Past (MTP)** instead of raw block timestamps. MTP is the median of the last 11 block timestamps, providing more reliable time measurements that are resistant to miner manipulation.
67
+
68
+ ```typescript
69
+ // Get current timestamp (median time past)
70
+ const currentTime: u64 = Blockchain.block.medianTimestamp;
71
+
72
+ // Time-based logic
73
+ const ONE_HOUR: u64 = 3600;
74
+ if (currentTime > this.deadline.value) {
75
+ throw new Revert('Deadline passed');
76
+ }
77
+ ```
78
+
79
+ ## Transaction Context
80
+
81
+ Access information about the current transaction:
82
+
83
+ ```typescript
84
+ // Immediate caller (the address that called this contract)
85
+ const sender: Address = Blockchain.tx.sender;
86
+
87
+ // Original transaction signer (EOA that initiated the transaction)
88
+ // Note: origin is ExtendedAddress for quantum-resistant key support
89
+ const origin: ExtendedAddress = Blockchain.tx.origin;
90
+
91
+ // Transaction ID and hash
92
+ const txId: Uint8Array = Blockchain.tx.txId;
93
+ const txHash: Uint8Array = Blockchain.tx.hash;
94
+
95
+ // Transaction inputs and outputs (UTXOs)
96
+ const inputs: TransactionInput[] = Blockchain.tx.inputs;
97
+ const outputs: TransactionOutput[] = Blockchain.tx.outputs;
98
+
99
+ // Consensus rules for current transaction
100
+ const consensus: ConsensusRules = Blockchain.tx.consensus;
101
+ ```
102
+
103
+ ```mermaid
104
+ ---
105
+ config:
106
+ theme: dark
107
+ ---
108
+ flowchart LR
109
+ subgraph TX["Transaction Context"]
110
+ T1["Blockchain.tx.sender"] --> A1["Address"]
111
+ T2["Blockchain.tx.origin"] --> A2["ExtendedAddress"]
112
+ T3["Blockchain.tx.txId"] --> A3["Uint8Array"]
113
+ T4["Blockchain.tx.hash"] --> A4["Uint8Array"]
114
+ T5["Blockchain.tx.inputs"] --> A5["TransactionInput[]"]
115
+ T6["Blockchain.tx.outputs"] --> A6["TransactionOutput[]"]
116
+ end
117
+ ```
118
+
119
+ ### sender vs origin
120
+
121
+ This distinction is critical for security:
122
+
123
+ ```
124
+ 👤 User (EOA) --> Contract A --> Contract B
125
+ origin=User origin=User
126
+ sender=User sender=ContractA
127
+ ```
128
+
129
+ ```typescript
130
+ // sender: The immediate caller (Address type)
131
+ // - Use for most authorization checks
132
+ // - Changes with each contract call
133
+
134
+ // origin: The original transaction signer (ExtendedAddress type)
135
+ // - Always the EOA that signed the transaction
136
+ // - Stays constant through the call chain
137
+ // - Supports quantum-resistant keys (ML-DSA)
138
+ // - Be careful: using origin can enable phishing attacks!
139
+ ```
140
+
141
+ ### Solidity Comparison
142
+
143
+ | Solidity | OPNet | Notes |
144
+ |----------|-------|-------|
145
+ | `msg.sender` | `Blockchain.tx.sender` | Immediate caller |
146
+ | `tx.origin` | `Blockchain.tx.origin` | Original signer (ExtendedAddress) |
147
+ | `address(this)` | `Blockchain.contractAddress` | This contract's address |
148
+ | N/A | `Blockchain.contractDeployer` | Who deployed the contract |
149
+
150
+ ### Contract Execution Context Flow
151
+
152
+ ```mermaid
153
+ ---
154
+ config:
155
+ theme: dark
156
+ ---
157
+ sequenceDiagram
158
+ participant User as User/EOA
159
+ participant TX as Transaction Broadcast
160
+ participant VM as OPNet VM
161
+ participant ContractA as Target Contract
162
+ participant ContractB as External Contract
163
+ participant Storage as Storage
164
+
165
+ Note over User,Storage: Transaction Initiation
166
+ User->>TX: Sign transaction
167
+ TX->>VM: Broadcast transaction
168
+
169
+ Note over User,Storage: OPNet Runtime Initialization
170
+ VM->>VM: Initialize Blockchain Context
171
+ VM->>VM: Set tx.origin = User Address
172
+ VM->>VM: Set tx.sender = User Address
173
+
174
+ Note over User,Storage: Contract Loading
175
+ VM->>ContractA: Load Target Contract
176
+ VM->>VM: Set contractAddress
177
+ VM->>VM: Set contractDeployer
178
+ VM->>ContractA: Execute Contract Method
179
+
180
+ Note over User,Storage: Cross-Contract Calls (if any)
181
+ alt Makes Cross-Contract Call
182
+ ContractA->>VM: Request external call
183
+ VM->>VM: Update tx.sender to ContractA
184
+ VM->>ContractB: Call External Contract
185
+ ContractB->>VM: Return result
186
+ VM->>VM: Restore tx.sender
187
+ VM->>ContractA: Return result
188
+ end
189
+
190
+ Note over User,Storage: Transaction Finalization
191
+ ContractA->>VM: Complete Execution
192
+ VM->>Storage: Commit Storage Changes
193
+ VM->>VM: Emit Events
194
+ VM->>User: Transaction Complete
195
+ ```
196
+
197
+ ### Security Warning
198
+
199
+ ```typescript
200
+ // DANGEROUS: Using origin for authorization
201
+ @method()
202
+ public withdraw(calldata: Calldata): BytesWriter {
203
+ // BAD: Allows phishing attacks through malicious contracts
204
+ if (Blockchain.tx.origin.equals(this.owner)) {
205
+ // ...
206
+ }
207
+ }
208
+
209
+ // SAFE: Using sender for authorization
210
+ @method()
211
+ public withdraw(calldata: Calldata): BytesWriter {
212
+ // GOOD: Only direct caller can access
213
+ if (Blockchain.tx.sender.equals(this.owner)) {
214
+ // ...
215
+ }
216
+ }
217
+ ```
218
+
219
+ ## Contract Context
220
+
221
+ Access contract metadata:
222
+
223
+ ```typescript
224
+ // This contract's address
225
+ const address: Address = Blockchain.contractAddress;
226
+
227
+ // Contract deployer address
228
+ const deployer: Address = Blockchain.contractDeployer;
229
+
230
+ // Current contract instance
231
+ const contract: OP_NET = Blockchain.contract;
232
+
233
+ // Chain ID (for replay protection)
234
+ const chainId: Uint8Array = Blockchain.chainId;
235
+
236
+ // Protocol ID
237
+ const protocolId: Uint8Array = Blockchain.protocolId;
238
+
239
+ // Current network
240
+ const network: Networks = Blockchain.network;
241
+
242
+ // Dead address for burns
243
+ const deadAddress: ExtendedAddress = Blockchain.DEAD_ADDRESS;
244
+ ```
245
+
246
+ ```mermaid
247
+ ---
248
+ config:
249
+ theme: dark
250
+ ---
251
+ flowchart LR
252
+ subgraph Contract["Contract Context"]
253
+ C1["Blockchain.contractAddress"] --> V1["Address"]
254
+ C2["Blockchain.contractDeployer"] --> V2["Address"]
255
+ C3["Blockchain.contract"] --> V3["OP_NET"]
256
+ C4["Blockchain.chainId"] --> V4["Uint8Array"]
257
+ C5["Blockchain.network"] --> V5["Networks"]
258
+ C6["Blockchain.DEAD_ADDRESS"] --> V6["ExtendedAddress"]
259
+ end
260
+ ```
261
+
262
+ ## Storage Operations
263
+
264
+ ### Persistent Storage
265
+
266
+ Direct storage access (low-level):
267
+
268
+ ```typescript
269
+ import { encodePointer } from '@btc-vision/btc-runtime/runtime';
270
+
271
+ // Create storage key from pointer and subPointer
272
+ const pointerHash = encodePointer(pointer, subPointer);
273
+
274
+ // Write to storage
275
+ Blockchain.setStorageAt(pointerHash, value.toUint8Array(true));
276
+
277
+ // Read from storage
278
+ const stored = Blockchain.getStorageAt(pointerHash);
279
+ const value = u256.fromUint8ArrayBE(stored);
280
+
281
+ // Check if storage slot has value
282
+ const hasValue: bool = Blockchain.hasStorageAt(pointerHash);
283
+ ```
284
+
285
+ ### Transient Storage
286
+
287
+ Transient storage is cleared after each transaction (useful for reentrancy guards):
288
+
289
+ ```typescript
290
+ // Write to transient storage
291
+ Blockchain.setTransientStorageAt(pointerHash, value);
292
+
293
+ // Read from transient storage
294
+ const transientValue = Blockchain.getTransientStorageAt(pointerHash);
295
+
296
+ // Check if transient storage slot has value
297
+ const hasTransient: bool = Blockchain.hasTransientStorageAt(pointerHash);
298
+ ```
299
+
300
+ **Warning:** Transient storage is NOT CURRENTLY ENABLED IN PRODUCTION. It is experimental and only available in the testing framework.
301
+
302
+ **Note:** For most use cases, use the typed storage classes like `StoredU256`, `StoredString`, etc. Direct storage access is for advanced scenarios.
303
+
304
+ See [Storage System](./storage-system.md) for detailed information.
305
+
306
+ ## Pointer Allocation
307
+
308
+ Allocate storage pointers for your contract:
309
+
310
+ ```typescript
311
+ // Get the next available pointer
312
+ const myPointer: u16 = Blockchain.nextPointer;
313
+
314
+ // Use it for storage
315
+ private balancePointer: u16 = Blockchain.nextPointer;
316
+ private allowancePointer: u16 = Blockchain.nextPointer;
317
+ ```
318
+
319
+ Each `nextPointer` call returns a unique `u16` value. Pointers are allocated sequentially starting from 1. Limited to 65,535 storage slots per contract.
320
+
321
+ See [Pointers](./pointers.md) for more details.
322
+
323
+ ## Cross-Contract Calls
324
+
325
+ Call other contracts:
326
+
327
+ ```typescript
328
+ import { Blockchain, Address, BytesWriter, CallResult } from '@btc-vision/btc-runtime/runtime';
329
+
330
+ // Prepare the call
331
+ const targetContract: Address = /* ... */;
332
+ const calldata: BytesWriter = /* encoded call data */;
333
+ const stopOnFailure: bool = true;
334
+
335
+ // Make the call
336
+ const result: CallResult = Blockchain.call(targetContract, calldata, stopOnFailure);
337
+
338
+ // Handle the result
339
+ if (result.success) {
340
+ const returnData = result.data; // BytesReader
341
+ // Process return data...
342
+ } else {
343
+ throw new Revert('External call failed');
344
+ }
345
+ ```
346
+
347
+ ### Call Parameters
348
+
349
+ | Parameter | Type | Description |
350
+ |-----------|------|-------------|
351
+ | `destinationContract` | `Address` | Contract to call |
352
+ | `calldata` | `BytesWriter` | Encoded function call |
353
+ | `stopExecutionOnFailure` | `boolean` | If true (default), revert entire transaction on failure |
354
+
355
+ ### Cross-Contract Call Sequence
356
+
357
+ ```mermaid
358
+ ---
359
+ config:
360
+ theme: dark
361
+ ---
362
+ sequenceDiagram
363
+ participant UserEOA as 👤 User (EOA)
364
+ participant ContractA as Contract A
365
+ participant Blockchain as Blockchain Singleton
366
+ participant ContractB as Contract B
367
+ participant Storage as Bitcoin L1 Storage
368
+
369
+ UserEOA->>ContractA: Call methodA()
370
+ Note over ContractA: tx.sender = UserEOA<br/>tx.origin = UserEOA
371
+
372
+ ContractA->>ContractA: Prepare calldata for Contract B
373
+ ContractA->>Blockchain: call(ContractB, calldata, stopOnFailure)
374
+
375
+ Blockchain->>Blockchain: Save current context
376
+ Blockchain->>Blockchain: Update tx.sender = ContractA
377
+ Note over Blockchain: tx.origin remains UserEOA
378
+
379
+ Blockchain->>ContractB: Execute methodB(calldata)
380
+ Note over ContractB: tx.sender = ContractA<br/>tx.origin = UserEOA
381
+
382
+ ContractB->>Storage: Read/Write State
383
+ Storage-->>ContractB: State Data
384
+
385
+ ContractB-->>Blockchain: Return CallResult{success, data}
386
+ Blockchain->>Blockchain: Restore previous context
387
+ Blockchain-->>ContractA: Return CallResult
388
+
389
+ ContractA->>ContractA: Process return data
390
+ alt stopOnFailure = true AND success = false
391
+ ContractA->>UserEOA: Revert entire transaction
392
+ else success = true
393
+ ContractA->>Storage: Commit changes
394
+ ContractA-->>UserEOA: Return success
395
+ end
396
+ ```
397
+
398
+ ### Solidity Comparison
399
+
400
+ ```solidity
401
+ // Solidity
402
+ (bool success, bytes memory data) = target.call(calldata);
403
+
404
+ // OPNet
405
+ const result = Blockchain.call(target, calldata, true);
406
+ // result.success: boolean
407
+ // result.data: BytesReader
408
+ ```
409
+
410
+ See [Cross-Contract Calls](../advanced/cross-contract-calls.md) for advanced usage.
411
+
412
+ ## Contract Deployment
413
+
414
+ Deploy new contracts from existing templates:
415
+
416
+ ```typescript
417
+ // Deploy a new contract using an existing contract as template
418
+ const newContractAddress: Address = Blockchain.deployContractFromExisting(
419
+ templateAddress, // Address of existing contract to clone
420
+ salt, // u256 salt for deterministic address
421
+ constructorData // BytesWriter with constructor parameters
422
+ );
423
+ ```
424
+
425
+ This uses CREATE2-style deterministic addressing: same salt + template = same address.
426
+
427
+ ## Cryptographic Operations
428
+
429
+ ### SHA256 Hashing
430
+
431
+ ```typescript
432
+ // Single SHA256
433
+ const hash: Uint8Array = Blockchain.sha256(data);
434
+
435
+ // Double SHA256 (hash256 - common in Bitcoin)
436
+ const doubleHash: Uint8Array = Blockchain.hash256(data);
437
+ ```
438
+
439
+ ### Signature Verification
440
+
441
+ OPNet supports both classical Schnorr signatures and quantum-resistant ML-DSA signatures:
442
+
443
+ ```typescript
444
+ // Recommended: Use consensus-aware verification
445
+ // Automatically selects Schnorr or ML-DSA based on consensus rules
446
+ const isValid: bool = Blockchain.verifySignature(
447
+ address, // ExtendedAddress
448
+ signature, // Uint8Array
449
+ hash // Uint8Array (32 bytes)
450
+ );
451
+
452
+ // Force ML-DSA verification even if Schnorr is allowed
453
+ const isValidMLDSA: bool = Blockchain.verifySignature(
454
+ address,
455
+ signature,
456
+ hash,
457
+ true // forceMLDSA
458
+ );
459
+ ```
460
+
461
+ ```mermaid
462
+ ---
463
+ config:
464
+ theme: dark
465
+ ---
466
+ flowchart LR
467
+ subgraph Verify["Blockchain.verifySignature()"]
468
+ Check{"unsafeSignaturesAllowed()<br/>AND !forceMLDSA?"}
469
+ Check -->|Yes| Schnorr["Schnorr Verification<br/>(64-byte signature)"]
470
+ Check -->|No| MLDSA["ML-DSA Verification<br/>(ML-DSA-44, Level2)"]
471
+ end
472
+ Input["address, signature, hash, forceMLDSA?"] --> Check
473
+ Schnorr --> Result["boolean"]
474
+ MLDSA --> Result
475
+ ```
476
+
477
+ #### Legacy Methods (Deprecated)
478
+
479
+ ```typescript
480
+ // Verify Schnorr signature directly (deprecated)
481
+ const isValid: bool = Blockchain.verifySchnorrSignature(
482
+ publicKey, // ExtendedAddress
483
+ signature, // Uint8Array (64 bytes)
484
+ hash // Uint8Array (32 bytes)
485
+ );
486
+
487
+ // Verify ML-DSA signature with specific security level
488
+ const isValidQuantum: bool = Blockchain.verifyMLDSASignature(
489
+ MLDSASecurityLevel.Level2, // Level2, Level3, or Level5
490
+ publicKey, // Uint8Array (size depends on level)
491
+ signature, // Uint8Array (size depends on level)
492
+ hash // Uint8Array (32 bytes)
493
+ );
494
+ ```
495
+
496
+ ML-DSA Security Levels:
497
+ - **Level2 (ML-DSA-44)**: 1312-byte public key, 2420-byte signature
498
+ - **Level3 (ML-DSA-65)**: 1952-byte public key, 3309-byte signature
499
+ - **Level5 (ML-DSA-87)**: 2592-byte public key, 4627-byte signature
500
+
501
+ See [Signature Verification](../advanced/signature-verification.md) for details.
502
+
503
+ ## Utility Methods
504
+
505
+ ### Account Type Check
506
+
507
+ ```typescript
508
+ // Check if an address is a contract
509
+ const isContract: bool = Blockchain.isContract(address);
510
+
511
+ // Get account type code (0 = EOA, >0 = contract type)
512
+ const accountType: u32 = Blockchain.getAccountType(address);
513
+ ```
514
+
515
+ ### Bitcoin Address Validation
516
+
517
+ ```typescript
518
+ // Validate a Bitcoin address for the current network
519
+ const isValid: bool = Blockchain.validateBitcoinAddress(addressString);
520
+ ```
521
+
522
+ ### Block Hash Lookup
523
+
524
+ ```typescript
525
+ // Get historical block hash (limited to ~256 recent blocks)
526
+ const oldBlockHash: Uint8Array = Blockchain.getBlockHash(blockNumber);
527
+ ```
528
+
529
+ ### Logging (Testing Only)
530
+
531
+ ```typescript
532
+ // Log debug messages (only works in unit testing framework)
533
+ Blockchain.log("Debug message");
534
+ ```
535
+
536
+ **Warning:** `log()` is ONLY available in the unit testing framework. It will fail in production or testnet environments.
537
+
538
+ ## Event Emission
539
+
540
+ Emit events for off-chain indexing:
541
+
542
+ ```typescript
543
+ import { NetEvent } from '@btc-vision/btc-runtime/runtime';
544
+
545
+ // Emit an event
546
+ Blockchain.emit(new TransferEvent(from, to, amount));
547
+ ```
548
+
549
+ See [Events](./events.md) for complete event documentation.
550
+
551
+ ## Blockchain Singleton Architecture
552
+
553
+ ```mermaid
554
+ ---
555
+ config:
556
+ theme: dark
557
+ ---
558
+ classDiagram
559
+ class BlockchainEnvironment {
560
+ <<singleton>>
561
+ +DEAD_ADDRESS: ExtendedAddress
562
+ +network: Networks
563
+ +block: Block
564
+ +tx: Transaction
565
+ +contract: OP_NET
566
+ +nextPointer: u16
567
+ +contractDeployer: Address
568
+ +contractAddress: Address
569
+ +chainId: Uint8Array
570
+ +protocolId: Uint8Array
571
+ +call(destination, calldata, stopOnFailure) CallResult
572
+ +deployContractFromExisting(address, salt, calldata) Address
573
+ +getStorageAt(pointerHash) Uint8Array
574
+ +setStorageAt(pointerHash, value) void
575
+ +hasStorageAt(pointerHash) bool
576
+ +getTransientStorageAt(pointerHash) Uint8Array
577
+ +setTransientStorageAt(pointerHash, value) void
578
+ +hasTransientStorageAt(pointerHash) bool
579
+ +sha256(buffer) Uint8Array
580
+ +hash256(buffer) Uint8Array
581
+ +verifySignature(address, sig, hash, forceMLDSA?) bool
582
+ +verifySchnorrSignature(pubKey, sig, hash) bool
583
+ +verifyMLDSASignature(level, pubKey, sig, hash) bool
584
+ +isContract(address) bool
585
+ +getAccountType(address) u32
586
+ +validateBitcoinAddress(address) bool
587
+ +getBlockHash(blockNumber) Uint8Array
588
+ +emit(event) void
589
+ +log(data) void
590
+ +registerPlugin(plugin) void
591
+ }
592
+
593
+ class Block {
594
+ +hash: Uint8Array
595
+ +number: u64
596
+ +numberU256: u256
597
+ +medianTimestamp: u64
598
+ }
599
+
600
+ class Transaction {
601
+ +sender: Address
602
+ +origin: ExtendedAddress
603
+ +txId: Uint8Array
604
+ +hash: Uint8Array
605
+ +inputs: TransactionInput[]
606
+ +outputs: TransactionOutput[]
607
+ +consensus: ConsensusRules
608
+ }
609
+
610
+ class CallResult {
611
+ +success: boolean
612
+ +data: BytesReader
613
+ }
614
+
615
+ BlockchainEnvironment --> Block: block
616
+ BlockchainEnvironment --> Transaction: tx
617
+ BlockchainEnvironment ..> CallResult: returns
618
+ ```
619
+
620
+ ## Example: Using Blockchain in a Contract
621
+
622
+ ```typescript
623
+ import { u256 } from '@btc-vision/as-bignum/assembly';
624
+ import {
625
+ OP_NET,
626
+ Blockchain,
627
+ Calldata,
628
+ BytesWriter,
629
+ StoredU256,
630
+ Revert,
631
+ EMPTY_POINTER,
632
+ ABIDataTypes,
633
+ } from '@btc-vision/btc-runtime/runtime';
634
+
635
+ @final
636
+ export class MyContract extends OP_NET {
637
+ // Storage pointer declaration
638
+ private readonly lastUpdatePointer: u16 = Blockchain.nextPointer;
639
+ private readonly lastUpdate: StoredU256 = new StoredU256(
640
+ this.lastUpdatePointer,
641
+ EMPTY_POINTER
642
+ );
643
+
644
+ public constructor() {
645
+ super();
646
+ }
647
+
648
+ public override onDeployment(_calldata: Calldata): void {
649
+ // Store deployment block
650
+ this.lastUpdate.value = u256.fromU64(Blockchain.block.number);
651
+ }
652
+
653
+ @method()
654
+ public doSomething(calldata: Calldata): BytesWriter {
655
+ // Access control
656
+ this.onlyDeployer(Blockchain.tx.sender);
657
+
658
+ // Time check
659
+ const now = Blockchain.block.medianTimestamp;
660
+ const lastBlock = this.lastUpdate.value.toU64();
661
+ const currentBlock = Blockchain.block.number;
662
+
663
+ // Must wait at least 10 blocks
664
+ if (currentBlock - lastBlock < 10) {
665
+ throw new Revert('Must wait 10 blocks');
666
+ }
667
+
668
+ // Update timestamp
669
+ this.lastUpdate.value = u256.fromU64(currentBlock);
670
+
671
+ return new BytesWriter(0);
672
+ }
673
+ }
674
+ ```
675
+
676
+ ## Summary
677
+
678
+ | Property/Method | Returns | Description |
679
+ |-----------------|---------|-------------|
680
+ | `Blockchain.block.number` | `u64` | Current block height |
681
+ | `Blockchain.block.numberU256` | `u256` | Current block height as u256 |
682
+ | `Blockchain.block.hash` | `Uint8Array` | Current block hash |
683
+ | `Blockchain.block.medianTimestamp` | `u64` | Median time past |
684
+ | `Blockchain.tx.sender` | `Address` | Immediate caller |
685
+ | `Blockchain.tx.origin` | `ExtendedAddress` | Original signer |
686
+ | `Blockchain.tx.txId` | `Uint8Array` | Transaction ID |
687
+ | `Blockchain.tx.hash` | `Uint8Array` | Transaction hash |
688
+ | `Blockchain.tx.inputs` | `TransactionInput[]` | Transaction inputs |
689
+ | `Blockchain.tx.outputs` | `TransactionOutput[]` | Transaction outputs |
690
+ | `Blockchain.tx.consensus` | `ConsensusRules` | Consensus rules |
691
+ | `Blockchain.contract` | `OP_NET` | Current contract instance |
692
+ | `Blockchain.contractAddress` | `Address` | This contract's address |
693
+ | `Blockchain.contractDeployer` | `Address` | Contract deployer |
694
+ | `Blockchain.chainId` | `Uint8Array` | Chain identifier |
695
+ | `Blockchain.protocolId` | `Uint8Array` | Protocol identifier |
696
+ | `Blockchain.network` | `Networks` | Current network |
697
+ | `Blockchain.DEAD_ADDRESS` | `ExtendedAddress` | Burn address |
698
+ | `Blockchain.nextPointer` | `u16` | Next storage pointer |
699
+ | `Blockchain.call()` | `CallResult` | Cross-contract call |
700
+ | `Blockchain.deployContractFromExisting()` | `Address` | Deploy new contract |
701
+ | `Blockchain.getStorageAt()` | `Uint8Array` | Read persistent storage |
702
+ | `Blockchain.setStorageAt()` | `void` | Write persistent storage |
703
+ | `Blockchain.hasStorageAt()` | `bool` | Check storage existence |
704
+ | `Blockchain.getTransientStorageAt()` | `Uint8Array` | Read transient storage |
705
+ | `Blockchain.setTransientStorageAt()` | `void` | Write transient storage |
706
+ | `Blockchain.hasTransientStorageAt()` | `bool` | Check transient storage existence |
707
+ | `Blockchain.sha256()` | `Uint8Array` | SHA256 hash |
708
+ | `Blockchain.hash256()` | `Uint8Array` | Double SHA256 |
709
+ | `Blockchain.verifySignature()` | `bool` | Consensus-aware signature verification |
710
+ | `Blockchain.verifySchnorrSignature()` | `bool` | Schnorr verification (deprecated) |
711
+ | `Blockchain.verifyMLDSASignature()` | `bool` | ML-DSA verification |
712
+ | `Blockchain.isContract()` | `bool` | Check if address is contract |
713
+ | `Blockchain.getAccountType()` | `u32` | Get account type code |
714
+ | `Blockchain.validateBitcoinAddress()` | `bool` | Validate Bitcoin address |
715
+ | `Blockchain.getBlockHash()` | `Uint8Array` | Historical block hash |
716
+ | `Blockchain.emit()` | `void` | Emit event |
717
+ | `Blockchain.log()` | `void` | Debug logging (testing only) |
718
+ | `Blockchain.registerPlugin()` | `void` | Register a plugin |
719
+
720
+ ---
721
+
722
+ **Navigation:**
723
+ - Previous: [Project Structure](../getting-started/project-structure.md)
724
+ - Next: [Storage System](./storage-system.md)