@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.
- package/README.md +7 -7
- package/docs/README.md +39 -39
- package/docs/advanced/bitcoin-scripts.md +17 -17
- package/docs/advanced/{contract-upgrades.md → contract-updates.md} +90 -98
- package/docs/advanced/cross-contract-calls.md +4 -4
- package/docs/advanced/plugins.md +21 -21
- package/docs/advanced/quantum-resistance.md +32 -32
- package/docs/advanced/signature-verification.md +22 -22
- package/docs/api-reference/blockchain.md +14 -14
- package/docs/api-reference/events.md +2 -2
- package/docs/api-reference/op20.md +7 -7
- package/docs/api-reference/op721.md +7 -7
- package/docs/api-reference/storage.md +2 -2
- package/docs/contracts/op-net-base.md +15 -15
- package/docs/contracts/op20-token.md +3 -3
- package/docs/contracts/op20s-signatures.md +2 -2
- package/docs/contracts/op721-nft.md +3 -3
- package/docs/contracts/reentrancy-guard.md +5 -7
- package/docs/contracts/updatable.md +384 -0
- package/docs/core-concepts/blockchain-environment.md +10 -10
- package/docs/core-concepts/decorators.md +5 -5
- package/docs/core-concepts/events.md +6 -6
- package/docs/core-concepts/pointers.md +5 -5
- package/docs/core-concepts/security.md +5 -5
- package/docs/core-concepts/storage-system.md +24 -24
- package/docs/examples/basic-token.md +8 -8
- package/docs/examples/nft-with-reservations.md +9 -9
- package/docs/examples/oracle-integration.md +13 -13
- package/docs/examples/stablecoin.md +10 -10
- package/docs/getting-started/first-contract.md +8 -8
- package/docs/getting-started/installation.md +2 -2
- package/docs/getting-started/project-structure.md +6 -6
- package/docs/storage/memory-maps.md +8 -8
- package/docs/storage/stored-arrays.md +6 -6
- package/docs/storage/stored-maps.md +8 -8
- package/docs/storage/stored-primitives.md +6 -6
- package/docs/types/address.md +13 -13
- package/docs/types/bytes-writer-reader.md +18 -18
- package/docs/types/calldata.md +12 -12
- package/package.json +10 -10
- package/runtime/constants/Exports.ts +0 -30
- package/runtime/contracts/OP20.ts +7 -7
- package/runtime/contracts/OP721.ts +60 -74
- package/runtime/contracts/OP_NET.ts +2 -2
- package/runtime/contracts/ReentrancyGuard.ts +1 -5
- package/runtime/contracts/Updatable.ts +241 -0
- package/runtime/contracts/interfaces/OP721InitParameters.ts +8 -8
- package/runtime/env/BlockchainEnvironment.ts +5 -5
- package/runtime/env/global.ts +7 -6
- package/runtime/events/predefined/{ApprovedEvent.ts → OP20ApprovedEvent.ts} +1 -1
- package/runtime/events/predefined/{BurnedEvent.ts → OP20BurnedEvent.ts} +1 -1
- package/runtime/events/predefined/{MintedEvent.ts → OP20MintedEvent.ts} +1 -1
- package/runtime/events/predefined/{TransferredEvent.ts → OP20TransferredEvent.ts} +1 -1
- package/runtime/events/predefined/OP721ApprovedEvent.ts +17 -0
- package/runtime/events/predefined/{ApprovedForAll.ts → OP721ApprovedForAllEvent.ts} +1 -1
- package/runtime/events/predefined/OP721BurnedEvent.ts +16 -0
- package/runtime/events/predefined/OP721MintedEvent.ts +16 -0
- package/runtime/events/predefined/OP721TransferredEvent.ts +18 -0
- package/runtime/events/predefined/index.ts +5 -5
- package/runtime/events/{upgradeable/UpgradeableEvents.ts → updatable/UpdatableEvents.ts} +9 -9
- package/runtime/hashing/keccak256.ts +1 -1
- package/runtime/index.ts +3 -5
- package/runtime/plugins/UpdatablePlugin.ts +276 -0
- package/runtime/script/Networks.ts +1 -1
- package/runtime/storage/StoredBoolean.ts +23 -12
- package/runtime/types/Address.ts +1 -1
- package/runtime/types/ExtendedAddress.ts +1 -1
- package/docs/contracts/upgradeable.md +0 -396
- package/runtime/contracts/Upgradeable.ts +0 -242
- package/runtime/contracts/interfaces/IOP1155.ts +0 -33
- package/runtime/contracts/interfaces/OP1155InitParameters.ts +0 -11
- package/runtime/plugins/UpgradeablePlugin.ts +0 -279
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Blockchain Environment
|
|
2
2
|
|
|
3
|
-
The `Blockchain` object is the primary interface for interacting with the
|
|
3
|
+
The `Blockchain` object is the primary interface for interacting with the OP_NET runtime. It provides access to block information, transaction context, storage operations, cryptographic functions, and cross-contract calls.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
@@ -55,15 +55,15 @@ flowchart LR
|
|
|
55
55
|
|
|
56
56
|
### Solidity Comparison
|
|
57
57
|
|
|
58
|
-
| Solidity |
|
|
58
|
+
| Solidity | OP_NET | Notes |
|
|
59
59
|
|----------|-------|-------|
|
|
60
60
|
| `block.number` | `Blockchain.block.number` | Current block height |
|
|
61
|
-
| `block.timestamp` | `Blockchain.block.medianTimestamp` |
|
|
61
|
+
| `block.timestamp` | `Blockchain.block.medianTimestamp` | OP_NET uses Median Time Past |
|
|
62
62
|
| `blockhash(n)` | `Blockchain.getBlockHash(n)` | Historical block hash |
|
|
63
63
|
|
|
64
64
|
### Median Time Past
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
OP_NET 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
67
|
|
|
68
68
|
```typescript
|
|
69
69
|
// Get current timestamp (median time past)
|
|
@@ -140,7 +140,7 @@ This distinction is critical for security:
|
|
|
140
140
|
|
|
141
141
|
### Solidity Comparison
|
|
142
142
|
|
|
143
|
-
| Solidity |
|
|
143
|
+
| Solidity | OP_NET | Notes |
|
|
144
144
|
|----------|-------|-------|
|
|
145
145
|
| `msg.sender` | `Blockchain.tx.sender` | Immediate caller |
|
|
146
146
|
| `tx.origin` | `Blockchain.tx.origin` | Original signer (ExtendedAddress) |
|
|
@@ -157,7 +157,7 @@ config:
|
|
|
157
157
|
sequenceDiagram
|
|
158
158
|
participant User as User/EOA
|
|
159
159
|
participant TX as Transaction Broadcast
|
|
160
|
-
participant VM as
|
|
160
|
+
participant VM as OP_NET VM
|
|
161
161
|
participant ContractA as Target Contract
|
|
162
162
|
participant ContractB as External Contract
|
|
163
163
|
participant Storage as Storage
|
|
@@ -166,7 +166,7 @@ sequenceDiagram
|
|
|
166
166
|
User->>TX: Sign transaction
|
|
167
167
|
TX->>VM: Broadcast transaction
|
|
168
168
|
|
|
169
|
-
Note over User,Storage:
|
|
169
|
+
Note over User,Storage: OP_NET Runtime Initialization
|
|
170
170
|
VM->>VM: Initialize Blockchain Context
|
|
171
171
|
VM->>VM: Set tx.origin = User Address
|
|
172
172
|
VM->>VM: Set tx.sender = User Address
|
|
@@ -401,7 +401,7 @@ sequenceDiagram
|
|
|
401
401
|
// Solidity
|
|
402
402
|
(bool success, bytes memory data) = target.call(calldata);
|
|
403
403
|
|
|
404
|
-
//
|
|
404
|
+
// OP_NET
|
|
405
405
|
const result = Blockchain.call(target, calldata, true);
|
|
406
406
|
// result.success: boolean
|
|
407
407
|
// result.data: BytesReader
|
|
@@ -438,7 +438,7 @@ const doubleHash: Uint8Array = Blockchain.hash256(data);
|
|
|
438
438
|
|
|
439
439
|
### Signature Verification
|
|
440
440
|
|
|
441
|
-
|
|
441
|
+
OP_NET supports Schnorr, ECDSA (secp256k1), and quantum-resistant ML-DSA signatures:
|
|
442
442
|
|
|
443
443
|
```typescript
|
|
444
444
|
import { SignaturesMethods } from '@btc-vision/btc-runtime/runtime';
|
|
@@ -525,7 +525,7 @@ ML-DSA Security Levels:
|
|
|
525
525
|
|
|
526
526
|
### Keccak-256 Hashing
|
|
527
527
|
|
|
528
|
-
|
|
528
|
+
OP_NET includes an Ethereum-compatible Keccak-256 implementation (original Keccak, not NIST SHA-3):
|
|
529
529
|
|
|
530
530
|
```typescript
|
|
531
531
|
import { keccak256, keccak256Concat, functionSelector, ethAddressFromPubKey } from '@btc-vision/btc-runtime/runtime';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Decorators
|
|
2
2
|
|
|
3
|
-
Decorators are essential for
|
|
3
|
+
Decorators are essential for OP_NET smart contracts. They define the ABI (Application Binary Interface) that allows external callers to interact with your contract methods.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
OP_NET uses three main decorators:
|
|
8
8
|
|
|
9
9
|
| Decorator | Purpose |
|
|
10
10
|
|-----------|---------|
|
|
@@ -51,9 +51,9 @@ flowchart LR
|
|
|
51
51
|
|
|
52
52
|
## Solidity Comparison
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
OP_NET decorators serve the same purpose as Solidity's function signatures but are more explicit:
|
|
55
55
|
|
|
56
|
-
| Solidity |
|
|
56
|
+
| Solidity | OP_NET |
|
|
57
57
|
|----------|-------|
|
|
58
58
|
| `function name() public view returns (string)` | `@method() @returns({ name: 'name', type: ABIDataTypes.STRING })` |
|
|
59
59
|
| `function balanceOf(address owner) public view returns (uint256)` | `@method({ name: 'owner', type: ABIDataTypes.ADDRESS }) @returns({ name: 'balance', type: ABIDataTypes.UINT256 })` |
|
|
@@ -79,7 +79,7 @@ The `ABIDataTypes` enum defines all supported parameter and return types:
|
|
|
79
79
|
|
|
80
80
|
| Type | Description | Size |
|
|
81
81
|
|------|-------------|------|
|
|
82
|
-
| `ABIDataTypes.ADDRESS` |
|
|
82
|
+
| `ABIDataTypes.ADDRESS` | OP_NET address | 32 bytes |
|
|
83
83
|
| `ABIDataTypes.BYTES` | Variable-length bytes | Variable |
|
|
84
84
|
| `ABIDataTypes.BYTES32` | Fixed 32-byte value | 32 bytes |
|
|
85
85
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Events
|
|
2
2
|
|
|
3
|
-
Events in
|
|
3
|
+
Events in OP_NET allow contracts to emit signals that can be observed by off-chain systems. They're essential for tracking state changes, building user interfaces, and indexing blockchain data.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
@@ -81,7 +81,7 @@ classDiagram
|
|
|
81
81
|
|
|
82
82
|
### Using Predefined Events
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
OP_NET provides common events out of the box:
|
|
85
85
|
|
|
86
86
|
```typescript
|
|
87
87
|
import {
|
|
@@ -162,7 +162,7 @@ event Stake(address indexed staker, uint256 amount, uint64 duration);
|
|
|
162
162
|
```
|
|
163
163
|
|
|
164
164
|
```typescript
|
|
165
|
-
//
|
|
165
|
+
// OP_NET
|
|
166
166
|
@final
|
|
167
167
|
export class StakeEvent extends NetEvent {
|
|
168
168
|
public constructor(staker: Address, amount: u256, duration: u64) {
|
|
@@ -469,7 +469,7 @@ event Transfer(address indexed from, address indexed to, uint256 value);
|
|
|
469
469
|
```
|
|
470
470
|
|
|
471
471
|
```typescript
|
|
472
|
-
//
|
|
472
|
+
// OP_NET - uses predefined TransferredEvent with operator field
|
|
473
473
|
// Event type: 'Transferred'
|
|
474
474
|
import { TransferredEvent } from '@btc-vision/btc-runtime/runtime';
|
|
475
475
|
|
|
@@ -494,7 +494,7 @@ emit Transfer(from, to, amount);
|
|
|
494
494
|
```
|
|
495
495
|
|
|
496
496
|
```typescript
|
|
497
|
-
//
|
|
497
|
+
// OP_NET - using predefined TransferredEvent (includes operator)
|
|
498
498
|
this.emitEvent(new TransferredEvent(Blockchain.tx.sender, from, to, amount));
|
|
499
499
|
|
|
500
500
|
// Or using custom TransferEvent (without operator)
|
|
@@ -507,7 +507,7 @@ this.emitEvent(new TransferEvent(from, to, amount));
|
|
|
507
507
|
// Solidity: indexed parameters for filtering
|
|
508
508
|
event Transfer(address indexed from, address indexed to, uint256 value);
|
|
509
509
|
|
|
510
|
-
//
|
|
510
|
+
// OP_NET: All parameters can be filtered by off-chain indexers
|
|
511
511
|
// (no explicit "indexed" keyword needed)
|
|
512
512
|
```
|
|
513
513
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Pointers
|
|
2
2
|
|
|
3
|
-
Pointers are the foundation of
|
|
3
|
+
Pointers are the foundation of OP_NET's storage system. Understanding how they work is essential for building efficient and secure smart contracts.
|
|
4
4
|
|
|
5
5
|
## What Are Pointers?
|
|
6
6
|
|
|
@@ -52,7 +52,7 @@ flowchart LR
|
|
|
52
52
|
|
|
53
53
|
## Why Pointers?
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
OP_NET's pointer system provides:
|
|
56
56
|
|
|
57
57
|
| Benefit | Description |
|
|
58
58
|
|---------|-------------|
|
|
@@ -63,7 +63,7 @@ OPNet's pointer system provides:
|
|
|
63
63
|
|
|
64
64
|
## Solidity Comparison
|
|
65
65
|
|
|
66
|
-
In Solidity, storage slots are assigned implicitly by the compiler. In
|
|
66
|
+
In Solidity, storage slots are assigned implicitly by the compiler. In OP_NET, you explicitly allocate pointers at runtime:
|
|
67
67
|
|
|
68
68
|
```solidity
|
|
69
69
|
// Solidity - Implicit slot assignment
|
|
@@ -75,7 +75,7 @@ contract Token {
|
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
```typescript
|
|
78
|
-
//
|
|
78
|
+
// OP_NET - Explicit pointer allocation
|
|
79
79
|
export class Token extends OP_NET {
|
|
80
80
|
private totalSupplyPointer: u16 = Blockchain.nextPointer; // ~0 (allocated at runtime)
|
|
81
81
|
private namePointer: u16 = Blockchain.nextPointer; // ~1 (allocated at runtime)
|
|
@@ -85,7 +85,7 @@ export class Token extends OP_NET {
|
|
|
85
85
|
|
|
86
86
|
### Storage Key Hashing Comparison
|
|
87
87
|
|
|
88
|
-
| Solidity |
|
|
88
|
+
| Solidity | OP_NET |
|
|
89
89
|
|----------|-------|
|
|
90
90
|
| Automatic slot assignment | Explicit pointer allocation |
|
|
91
91
|
| Slot 0, 1, 2, ... | `Blockchain.nextPointer` |
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Security
|
|
2
2
|
|
|
3
|
-
Security is paramount in smart contract development. This guide covers
|
|
3
|
+
Security is paramount in smart contract development. This guide covers OP_NET's security mechanisms and best practices for writing secure contracts.
|
|
4
4
|
|
|
5
5
|
## Security Mechanisms
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
OP_NET provides several built-in security features:
|
|
8
8
|
|
|
9
9
|
| Feature | Description |
|
|
10
10
|
|---------|-------------|
|
|
@@ -48,7 +48,7 @@ const remainder = SafeMath.mod(a, b); // Reverts on division by zero
|
|
|
48
48
|
|
|
49
49
|
### Solidity Comparison
|
|
50
50
|
|
|
51
|
-
In Solidity 0.8+, arithmetic operations revert on overflow/underflow by default.
|
|
51
|
+
In Solidity 0.8+, arithmetic operations revert on overflow/underflow by default. OP_NET achieves the same behavior through SafeMath:
|
|
52
52
|
|
|
53
53
|
```solidity
|
|
54
54
|
// Solidity 0.8+ - automatic overflow protection
|
|
@@ -56,7 +56,7 @@ uint256 result = a + b; // Reverts on overflow
|
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
```typescript
|
|
59
|
-
//
|
|
59
|
+
// OP_NET - explicit SafeMath usage
|
|
60
60
|
const result = SafeMath.add(a, b); // Reverts on overflow
|
|
61
61
|
```
|
|
62
62
|
|
|
@@ -138,7 +138,7 @@ modifier onlyOwner() {
|
|
|
138
138
|
```
|
|
139
139
|
|
|
140
140
|
```typescript
|
|
141
|
-
//
|
|
141
|
+
// OP_NET
|
|
142
142
|
protected onlyOwner(): void {
|
|
143
143
|
if (!Blockchain.tx.sender.equals(this.owner.value)) {
|
|
144
144
|
throw new Revert('Not owner');
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Storage System
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
OP_NET uses a pointer-based storage system that provides deterministic, secure, and efficient data persistence on Bitcoin L1. This guide explains how storage works and how to use it effectively.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
Unlike Solidity where storage is implicitly managed,
|
|
7
|
+
Unlike Solidity where storage is implicitly managed, OP_NET requires explicit pointer allocation for all persistent data. This design provides:
|
|
8
8
|
|
|
9
9
|
- **Deterministic storage locations** via SHA256 hashing
|
|
10
10
|
- **Collision-free addressing** through unique pointer combinations
|
|
@@ -88,13 +88,13 @@ flowchart LR
|
|
|
88
88
|
P4 --> N1["owner+spender hash -> allowance"]
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
## Solidity vs
|
|
91
|
+
## Solidity vs OP_NET Storage Model
|
|
92
92
|
|
|
93
|
-
In Solidity, storage slots are assigned implicitly by the compiler. In
|
|
93
|
+
In Solidity, storage slots are assigned implicitly by the compiler. In OP_NET, you explicitly allocate pointers at runtime.
|
|
94
94
|
|
|
95
95
|
### Quick Reference Table
|
|
96
96
|
|
|
97
|
-
| Feature | Solidity |
|
|
97
|
+
| Feature | Solidity | OP_NET |
|
|
98
98
|
|---------|----------|-------|
|
|
99
99
|
| Storage slot assignment | Implicit (compiler) | Explicit (`Blockchain.nextPointer`) |
|
|
100
100
|
| Hash function | keccak256 | SHA256 |
|
|
@@ -110,7 +110,7 @@ In Solidity, storage slots are assigned implicitly by the compiler. In OPNet, yo
|
|
|
110
110
|
|
|
111
111
|
### Type Mapping Reference
|
|
112
112
|
|
|
113
|
-
| Solidity Type |
|
|
113
|
+
| Solidity Type | OP_NET Equivalent | Notes |
|
|
114
114
|
|---------------|------------------|-------|
|
|
115
115
|
| `uint256` | `StoredU256` | 32 bytes |
|
|
116
116
|
| `uint64` (packed) | `StoredU64` | Stores up to 4 u64 values in one slot |
|
|
@@ -136,7 +136,7 @@ contract Token {
|
|
|
136
136
|
```
|
|
137
137
|
|
|
138
138
|
```typescript
|
|
139
|
-
//
|
|
139
|
+
// OP_NET - Explicit pointer allocation
|
|
140
140
|
export class Token extends OP_NET {
|
|
141
141
|
private readonly totalSupplyPointer: u16 = Blockchain.nextPointer; // ~0 (allocated at runtime)
|
|
142
142
|
private readonly namePointer: u16 = Blockchain.nextPointer; // ~1 (allocated at runtime)
|
|
@@ -168,7 +168,7 @@ flowchart LR
|
|
|
168
168
|
S_CONTRACT -->|"CAN hold ETH"| S_CUSTODY["Contract Custody<br/>address(this).balance"]
|
|
169
169
|
end
|
|
170
170
|
|
|
171
|
-
subgraph OPNetFlow["
|
|
171
|
+
subgraph OPNetFlow["OP_NET (Bitcoin L1)"]
|
|
172
172
|
O_USER[("👤 User")] -->|"Signs Bitcoin TX"| O_TX["Bitcoin Transaction"]
|
|
173
173
|
O_TX -->|"WASM executes"| O_CONTRACT["Smart Contract"]
|
|
174
174
|
|
|
@@ -188,10 +188,10 @@ flowchart LR
|
|
|
188
188
|
end
|
|
189
189
|
|
|
190
190
|
subgraph KeyDiff["Critical Differences"]
|
|
191
|
-
DIFF1["Custody: Solidity holds funds,<br/>
|
|
192
|
-
DIFF2["Storage: Solidity implicit slots,<br/>
|
|
193
|
-
DIFF3["Hash: Solidity keccak256,<br/>
|
|
194
|
-
DIFF4["Execution: Solidity EVM,<br/>
|
|
191
|
+
DIFF1["Custody: Solidity holds funds,<br/>OP_NET verifies outputs"]
|
|
192
|
+
DIFF2["Storage: Solidity implicit slots,<br/>OP_NET explicit pointers"]
|
|
193
|
+
DIFF3["Hash: Solidity keccak256,<br/>OP_NET SHA256"]
|
|
194
|
+
DIFF4["Execution: Solidity EVM,<br/>OP_NET WASM"]
|
|
195
195
|
end
|
|
196
196
|
```
|
|
197
197
|
|
|
@@ -226,15 +226,15 @@ config:
|
|
|
226
226
|
sequenceDiagram
|
|
227
227
|
participant User
|
|
228
228
|
participant Bitcoin as Bitcoin L1
|
|
229
|
-
participant
|
|
229
|
+
participant OP_NET as OP_NET Node
|
|
230
230
|
participant WASM as WASM Runtime
|
|
231
231
|
participant Contract
|
|
232
232
|
participant Blockchain as Blockchain API
|
|
233
233
|
participant Storage as Storage System
|
|
234
234
|
|
|
235
235
|
User->>Bitcoin: Broadcast Transaction
|
|
236
|
-
Bitcoin->>
|
|
237
|
-
|
|
236
|
+
Bitcoin->>OP_NET: New Block with TX
|
|
237
|
+
OP_NET->>WASM: Execute Contract
|
|
238
238
|
WASM->>Contract: Instantiate
|
|
239
239
|
Contract->>Blockchain: nextPointer
|
|
240
240
|
Blockchain-->>Contract: 0 (totalSupply)
|
|
@@ -247,13 +247,13 @@ sequenceDiagram
|
|
|
247
247
|
Contract->>Storage: Read/Write with pointers
|
|
248
248
|
Storage-->>Contract: Data
|
|
249
249
|
Contract-->>WASM: Execution Result
|
|
250
|
-
WASM-->>
|
|
251
|
-
|
|
250
|
+
WASM-->>OP_NET: State Changes
|
|
251
|
+
OP_NET->>OP_NET: Update State Root
|
|
252
252
|
```
|
|
253
253
|
|
|
254
254
|
## System Architecture
|
|
255
255
|
|
|
256
|
-
The following diagram shows how storage fits into the overall
|
|
256
|
+
The following diagram shows how storage fits into the overall OP_NET architecture:
|
|
257
257
|
|
|
258
258
|
```mermaid
|
|
259
259
|
---
|
|
@@ -271,8 +271,8 @@ flowchart TD
|
|
|
271
271
|
UTXO["UTXOs"]
|
|
272
272
|
end
|
|
273
273
|
|
|
274
|
-
subgraph OPNetConsensus["
|
|
275
|
-
INDEXER["
|
|
274
|
+
subgraph OPNetConsensus["OP_NET Consensus Layer"]
|
|
275
|
+
INDEXER["OP_NET Nodes"]
|
|
276
276
|
WASM["WASM Runtime"]
|
|
277
277
|
EPOCH["Epoch Mining<br/>SHA1 PoW"]
|
|
278
278
|
CHECKPOINT["State Checksum<br/>Root Hash"]
|
|
@@ -317,7 +317,7 @@ flowchart TD
|
|
|
317
317
|
|
|
318
318
|
## Storage Types
|
|
319
319
|
|
|
320
|
-
|
|
320
|
+
OP_NET provides typed storage classes for common data types:
|
|
321
321
|
|
|
322
322
|
### Primitive Storage
|
|
323
323
|
|
|
@@ -405,7 +405,7 @@ public constructor() {
|
|
|
405
405
|
|
|
406
406
|
### Common Patterns Comparison
|
|
407
407
|
|
|
408
|
-
| Pattern | Solidity |
|
|
408
|
+
| Pattern | Solidity | OP_NET |
|
|
409
409
|
|---------|----------|-------|
|
|
410
410
|
| Increment counter | `counter++;` | `counter.value = SafeMath.add(counter.value, u256.One);` |
|
|
411
411
|
| Read balance | `balances[addr]` | `balanceOf.get(addr)` |
|
|
@@ -524,7 +524,7 @@ protected setAllowance(owner: Address, spender: Address, amount: u256): void {
|
|
|
524
524
|
// struct User { address addr; uint256 balance; bool active; }
|
|
525
525
|
// mapping(uint256 => User) public users;
|
|
526
526
|
|
|
527
|
-
//
|
|
527
|
+
// OP_NET: Use multiple pointers or encode into u256
|
|
528
528
|
private readonly userAddressPointer: u16 = Blockchain.nextPointer;
|
|
529
529
|
private readonly userBalancePointer: u16 = Blockchain.nextPointer;
|
|
530
530
|
private readonly userActivePointer: u16 = Blockchain.nextPointer;
|
|
@@ -588,7 +588,7 @@ contract SimpleToken {
|
|
|
588
588
|
}
|
|
589
589
|
```
|
|
590
590
|
|
|
591
|
-
**
|
|
591
|
+
**OP_NET:**
|
|
592
592
|
```typescript
|
|
593
593
|
import { u256 } from '@btc-vision/as-bignum/assembly';
|
|
594
594
|
import {
|
|
@@ -376,7 +376,7 @@ function mint(address to, uint256 amount) external onlyOwner {
|
|
|
376
376
|
emit Minted(to, amount);
|
|
377
377
|
}
|
|
378
378
|
|
|
379
|
-
//
|
|
379
|
+
// OP_NET
|
|
380
380
|
@method(
|
|
381
381
|
{ name: 'to', type: ABIDataTypes.ADDRESS },
|
|
382
382
|
{ name: 'amount', type: ABIDataTypes.UINT256 },
|
|
@@ -508,7 +508,7 @@ modifier onlyOwner() {
|
|
|
508
508
|
|
|
509
509
|
function mint(address to, uint256 amount) external onlyOwner { }
|
|
510
510
|
|
|
511
|
-
//
|
|
511
|
+
// OP_NET uses inline checks
|
|
512
512
|
public mint(calldata: Calldata): BytesWriter {
|
|
513
513
|
this.onlyDeployer(Blockchain.tx.sender); // Throws if not deployer
|
|
514
514
|
// ...
|
|
@@ -627,11 +627,11 @@ contract BasicToken is ERC20, Ownable {
|
|
|
627
627
|
}
|
|
628
628
|
```
|
|
629
629
|
|
|
630
|
-
## Solidity vs
|
|
630
|
+
## Solidity vs OP_NET Comparison
|
|
631
631
|
|
|
632
632
|
### Key Differences Table
|
|
633
633
|
|
|
634
|
-
| Aspect | Solidity (ERC20) |
|
|
634
|
+
| Aspect | Solidity (ERC20) | OP_NET (OP20) |
|
|
635
635
|
|--------|------------------|--------------|
|
|
636
636
|
| **Inheritance** | `contract MyToken is ERC20, Ownable` | `class MyToken extends OP20` |
|
|
637
637
|
| **Constructor** | `constructor() ERC20("Name", "SYM")` | `onDeployment()` + `this.instantiate(new OP20InitParameters(...))` |
|
|
@@ -658,7 +658,7 @@ function mint(address to, uint256 amount) external onlyOwner {
|
|
|
658
658
|
}
|
|
659
659
|
```
|
|
660
660
|
|
|
661
|
-
**
|
|
661
|
+
**OP_NET:**
|
|
662
662
|
```typescript
|
|
663
663
|
// Method with decorators
|
|
664
664
|
@method(
|
|
@@ -682,7 +682,7 @@ public mint(calldata: Calldata): BytesWriter {
|
|
|
682
682
|
}
|
|
683
683
|
```
|
|
684
684
|
|
|
685
|
-
### Advantages of
|
|
685
|
+
### Advantages of OP_NET Approach
|
|
686
686
|
|
|
687
687
|
| Feature | Benefit |
|
|
688
688
|
|---------|---------|
|
|
@@ -703,7 +703,7 @@ constructor(string memory name, string memory symbol) ERC20(name, symbol) {
|
|
|
703
703
|
}
|
|
704
704
|
```
|
|
705
705
|
|
|
706
|
-
**
|
|
706
|
+
**OP_NET (onDeployment called during contract deployment):**
|
|
707
707
|
```typescript
|
|
708
708
|
public override onDeployment(calldata: Calldata): void {
|
|
709
709
|
const name = calldata.readString();
|
|
@@ -721,7 +721,7 @@ event Minted(address indexed to, uint256 amount);
|
|
|
721
721
|
emit Minted(to, amount);
|
|
722
722
|
```
|
|
723
723
|
|
|
724
|
-
**
|
|
724
|
+
**OP_NET:**
|
|
725
725
|
```typescript
|
|
726
726
|
// Event class definition
|
|
727
727
|
class MintEvent extends NetEvent {
|
|
@@ -287,7 +287,7 @@ function whitelistMint(uint256 quantity, bytes32[] calldata proof) external {
|
|
|
287
287
|
_mintInternal(msg.sender, quantity);
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
-
//
|
|
290
|
+
// OP_NET - Using on-chain mapping (simpler approach)
|
|
291
291
|
@method({ name: 'quantity', type: ABIDataTypes.UINT256 })
|
|
292
292
|
@returns({ name: 'success', type: ABIDataTypes.BOOL })
|
|
293
293
|
@emit('Minted')
|
|
@@ -908,7 +908,7 @@ public getSaleInfo(_calldata: Calldata): BytesWriter { }
|
|
|
908
908
|
|
|
909
909
|
## Solidity Comparison
|
|
910
910
|
|
|
911
|
-
| Aspect | Solidity (ERC721) |
|
|
911
|
+
| Aspect | Solidity (ERC721) | OP_NET (OP721) |
|
|
912
912
|
|--------|-------------------|---------------|
|
|
913
913
|
| Inheritance | `contract NFT is ERC721, Ownable` | `class NFT extends OP721` |
|
|
914
914
|
| Constructor | `constructor() ERC721("Name", "SYM")` | `onDeployment()` + `this.instantiate(...)` |
|
|
@@ -936,7 +936,7 @@ function whitelistMint(uint256 quantity, bytes32[] calldata proof) external paya
|
|
|
936
936
|
}
|
|
937
937
|
```
|
|
938
938
|
|
|
939
|
-
**
|
|
939
|
+
**OP_NET (On-chain mapping):**
|
|
940
940
|
```typescript
|
|
941
941
|
private _whitelist: AddressMemoryMap;
|
|
942
942
|
|
|
@@ -985,7 +985,7 @@ function reveal(string calldata _baseURI) external onlyOwner {
|
|
|
985
985
|
}
|
|
986
986
|
```
|
|
987
987
|
|
|
988
|
-
**
|
|
988
|
+
**OP_NET:**
|
|
989
989
|
```typescript
|
|
990
990
|
private _baseURI: StoredString;
|
|
991
991
|
private _hiddenURI: StoredString;
|
|
@@ -1032,7 +1032,7 @@ function setSalePhase(SalePhase phase) external onlyOwner {
|
|
|
1032
1032
|
require(salePhase == SalePhase.WHITELIST, "Whitelist sale not active");
|
|
1033
1033
|
```
|
|
1034
1034
|
|
|
1035
|
-
**
|
|
1035
|
+
**OP_NET:**
|
|
1036
1036
|
```typescript
|
|
1037
1037
|
const PHASE_INACTIVE: u8 = 0;
|
|
1038
1038
|
const PHASE_WHITELIST: u8 = 1;
|
|
@@ -1061,7 +1061,7 @@ if (this._salePhase.value != PHASE_WHITELIST) {
|
|
|
1061
1061
|
}
|
|
1062
1062
|
```
|
|
1063
1063
|
|
|
1064
|
-
### Advantages of
|
|
1064
|
+
### Advantages of OP_NET Approach
|
|
1065
1065
|
|
|
1066
1066
|
| Feature | Benefit |
|
|
1067
1067
|
|---------|---------|
|
|
@@ -1088,7 +1088,7 @@ function _mintInternal(address to, uint256 quantity) internal {
|
|
|
1088
1088
|
}
|
|
1089
1089
|
```
|
|
1090
1090
|
|
|
1091
|
-
**
|
|
1091
|
+
**OP_NET:**
|
|
1092
1092
|
```typescript
|
|
1093
1093
|
private _mintInternal(to: Address, quantity: u256): void {
|
|
1094
1094
|
const currentSupply = this.totalSupply();
|
|
@@ -1137,7 +1137,7 @@ function cancelReservation() external {
|
|
|
1137
1137
|
}
|
|
1138
1138
|
```
|
|
1139
1139
|
|
|
1140
|
-
**
|
|
1140
|
+
**OP_NET (Bitcoin UTXO model):**
|
|
1141
1141
|
```typescript
|
|
1142
1142
|
// Payment handled at Bitcoin transaction level
|
|
1143
1143
|
// Refund logic would involve different mechanisms
|
|
@@ -1180,7 +1180,7 @@ function getSaleInfo() external view returns (
|
|
|
1180
1180
|
}
|
|
1181
1181
|
```
|
|
1182
1182
|
|
|
1183
|
-
**
|
|
1183
|
+
**OP_NET:**
|
|
1184
1184
|
```typescript
|
|
1185
1185
|
@method()
|
|
1186
1186
|
@returns(
|
|
@@ -112,7 +112,7 @@ function latestRoundData() external view returns (
|
|
|
112
112
|
uint80 answeredInRound
|
|
113
113
|
);
|
|
114
114
|
|
|
115
|
-
//
|
|
115
|
+
// OP_NET - Custom multi-oracle aggregation
|
|
116
116
|
@method({ name: 'asset', type: ABIDataTypes.ADDRESS })
|
|
117
117
|
@returns(
|
|
118
118
|
{ name: 'price', type: ABIDataTypes.UINT256 },
|
|
@@ -977,11 +977,11 @@ contract MultiOracle is Ownable {
|
|
|
977
977
|
}
|
|
978
978
|
```
|
|
979
979
|
|
|
980
|
-
## Solidity vs
|
|
980
|
+
## Solidity vs OP_NET Comparison
|
|
981
981
|
|
|
982
982
|
### Key Differences Table
|
|
983
983
|
|
|
984
|
-
| Aspect | Solidity (Chainlink-style) |
|
|
984
|
+
| Aspect | Solidity (Chainlink-style) | OP_NET |
|
|
985
985
|
|--------|---------------------------|-------|
|
|
986
986
|
| **Oracle Interface** | `AggregatorV3Interface` with rounds | Custom multi-oracle aggregation |
|
|
987
987
|
| **Price Storage** | `mapping(address => PriceData)` | `AddressMemoryMap` |
|
|
@@ -992,7 +992,7 @@ contract MultiOracle is Ownable {
|
|
|
992
992
|
| **Staleness Check** | `block.timestamp - data.timestamp` | `now - timestamp > maxStaleness` |
|
|
993
993
|
| **Return Format** | Multiple return values | `BytesWriter` serialization |
|
|
994
994
|
|
|
995
|
-
### Chainlink vs
|
|
995
|
+
### Chainlink vs OP_NET Oracle Pattern
|
|
996
996
|
|
|
997
997
|
**Chainlink (Solidity) - Consumer Pattern:**
|
|
998
998
|
```solidity
|
|
@@ -1021,7 +1021,7 @@ contract PriceConsumer {
|
|
|
1021
1021
|
}
|
|
1022
1022
|
```
|
|
1023
1023
|
|
|
1024
|
-
**
|
|
1024
|
+
**OP_NET - Self-Contained Oracle:**
|
|
1025
1025
|
```typescript
|
|
1026
1026
|
@method({ name: 'asset', type: ABIDataTypes.ADDRESS })
|
|
1027
1027
|
@returns(
|
|
@@ -1068,7 +1068,7 @@ function _calculateMedian(uint256[] memory arr, uint256 len) internal pure retur
|
|
|
1068
1068
|
}
|
|
1069
1069
|
```
|
|
1070
1070
|
|
|
1071
|
-
**
|
|
1071
|
+
**OP_NET:**
|
|
1072
1072
|
```typescript
|
|
1073
1073
|
private calculateMedian(prices: u256[]): u256 {
|
|
1074
1074
|
const len = prices.length;
|
|
@@ -1104,7 +1104,7 @@ bytes32 key = keccak256(abi.encodePacked(oracle, asset));
|
|
|
1104
1104
|
oracleSubmissions[key] = PriceData(price, timestamp);
|
|
1105
1105
|
```
|
|
1106
1106
|
|
|
1107
|
-
**
|
|
1107
|
+
**OP_NET:**
|
|
1108
1108
|
```typescript
|
|
1109
1109
|
// Uses sha256 for storage key
|
|
1110
1110
|
private oracleAssetKey(oracle: Address, asset: Address): u256 {
|
|
@@ -1122,7 +1122,7 @@ private setOraclePrice(key: u256, price: u256): void {
|
|
|
1122
1122
|
}
|
|
1123
1123
|
```
|
|
1124
1124
|
|
|
1125
|
-
### Advantages of
|
|
1125
|
+
### Advantages of OP_NET Approach
|
|
1126
1126
|
|
|
1127
1127
|
| Feature | Benefit |
|
|
1128
1128
|
|---------|---------|
|
|
@@ -1146,7 +1146,7 @@ function _withinDeviation(uint256 oldPrice, uint256 newPrice) internal view retu
|
|
|
1146
1146
|
}
|
|
1147
1147
|
```
|
|
1148
1148
|
|
|
1149
|
-
**
|
|
1149
|
+
**OP_NET:**
|
|
1150
1150
|
```typescript
|
|
1151
1151
|
private withinDeviation(oldPrice: u256, newPrice: u256): bool {
|
|
1152
1152
|
const maxDev = this._maxDeviation.value;
|
|
@@ -1173,7 +1173,7 @@ function submitPrice(address asset, uint256 price) external {
|
|
|
1173
1173
|
}
|
|
1174
1174
|
```
|
|
1175
1175
|
|
|
1176
|
-
**
|
|
1176
|
+
**OP_NET:**
|
|
1177
1177
|
```typescript
|
|
1178
1178
|
private oracles: StoredAddressArray;
|
|
1179
1179
|
|
|
@@ -1200,10 +1200,10 @@ public submitPrice(calldata: Calldata): BytesWriter {
|
|
|
1200
1200
|
| Use Case | Recommended Approach |
|
|
1201
1201
|
|----------|---------------------|
|
|
1202
1202
|
| **Need Chainlink feeds** | Solidity with AggregatorV3Interface |
|
|
1203
|
-
| **Custom oracle network** |
|
|
1204
|
-
| **Bitcoin-native DeFi** |
|
|
1203
|
+
| **Custom oracle network** | OP_NET multi-oracle aggregation |
|
|
1204
|
+
| **Bitcoin-native DeFi** | OP_NET with Bitcoin timestamp |
|
|
1205
1205
|
| **Existing EVM infrastructure** | Solidity |
|
|
1206
|
-
| **New protocol on Bitcoin** |
|
|
1206
|
+
| **New protocol on Bitcoin** | OP_NET |
|
|
1207
1207
|
|
|
1208
1208
|
---
|
|
1209
1209
|
|