@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.
- package/LICENSE +190 -0
- package/README.md +258 -137
- package/SECURITY.md +226 -0
- package/docs/README.md +614 -0
- package/docs/advanced/bitcoin-scripts.md +939 -0
- package/docs/advanced/cross-contract-calls.md +579 -0
- package/docs/advanced/plugins.md +1006 -0
- package/docs/advanced/quantum-resistance.md +660 -0
- package/docs/advanced/signature-verification.md +715 -0
- package/docs/api-reference/blockchain.md +729 -0
- package/docs/api-reference/events.md +642 -0
- package/docs/api-reference/op20.md +902 -0
- package/docs/api-reference/op721.md +819 -0
- package/docs/api-reference/safe-math.md +510 -0
- package/docs/api-reference/storage.md +840 -0
- package/docs/contracts/op-net-base.md +786 -0
- package/docs/contracts/op20-token.md +687 -0
- package/docs/contracts/op20s-signatures.md +614 -0
- package/docs/contracts/op721-nft.md +785 -0
- package/docs/contracts/reentrancy-guard.md +787 -0
- package/docs/core-concepts/blockchain-environment.md +724 -0
- package/docs/core-concepts/decorators.md +466 -0
- package/docs/core-concepts/events.md +652 -0
- package/docs/core-concepts/pointers.md +391 -0
- package/docs/core-concepts/security.md +473 -0
- package/docs/core-concepts/storage-system.md +969 -0
- package/docs/examples/basic-token.md +745 -0
- package/docs/examples/nft-with-reservations.md +1440 -0
- package/docs/examples/oracle-integration.md +1212 -0
- package/docs/examples/stablecoin.md +1180 -0
- package/docs/getting-started/first-contract.md +575 -0
- package/docs/getting-started/installation.md +384 -0
- package/docs/getting-started/project-structure.md +630 -0
- package/docs/storage/memory-maps.md +764 -0
- package/docs/storage/stored-arrays.md +778 -0
- package/docs/storage/stored-maps.md +758 -0
- package/docs/storage/stored-primitives.md +655 -0
- package/docs/types/address.md +773 -0
- package/docs/types/bytes-writer-reader.md +938 -0
- package/docs/types/calldata.md +744 -0
- package/docs/types/safe-math.md +446 -0
- package/package.json +51 -26
- package/runtime/memory/MapOfMap.ts +1 -0
- package/LICENSE.md +0 -21
|
@@ -0,0 +1,630 @@
|
|
|
1
|
+
# Project Structure
|
|
2
|
+
|
|
3
|
+
This guide explains the standard project structure for OPNet smart contract development and how the btc-runtime library is organized.
|
|
4
|
+
|
|
5
|
+
## Your Project Structure
|
|
6
|
+
|
|
7
|
+
### Project Directory Layout
|
|
8
|
+
|
|
9
|
+
This diagram visualizes the complete project structure and file relationships:
|
|
10
|
+
|
|
11
|
+
```mermaid
|
|
12
|
+
---
|
|
13
|
+
config:
|
|
14
|
+
theme: dark
|
|
15
|
+
---
|
|
16
|
+
graph LR
|
|
17
|
+
subgraph root["Project Root"]
|
|
18
|
+
ROOT["my-opnet-project/"]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
subgraph source["Source Code - src/"]
|
|
22
|
+
SRC["src/"]
|
|
23
|
+
TOKEN_DIR["token/"]
|
|
24
|
+
NFT_DIR["nft/"]
|
|
25
|
+
|
|
26
|
+
TOKEN["MyToken.ts"]
|
|
27
|
+
TOKEN_INDEX["index.ts"]
|
|
28
|
+
NFT["MyNFT.ts"]
|
|
29
|
+
NFT_INDEX["index.ts"]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
subgraph build["Build Output - build/"]
|
|
33
|
+
BUILD["build/"]
|
|
34
|
+
TOKEN_WASM["MyToken.wasm"]
|
|
35
|
+
NFT_WASM["MyNFT.wasm"]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
subgraph tests["Tests - tests/"]
|
|
39
|
+
TESTS["tests/"]
|
|
40
|
+
SPEC["MyToken.spec.ts"]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
subgraph config["Configuration"]
|
|
44
|
+
ASCONFIG["asconfig.json"]
|
|
45
|
+
PKG["package.json"]
|
|
46
|
+
TSCONFIG["tsconfig.json"]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
ROOT --> SRC
|
|
50
|
+
ROOT --> BUILD
|
|
51
|
+
ROOT --> TESTS
|
|
52
|
+
ROOT --> ASCONFIG
|
|
53
|
+
ROOT --> PKG
|
|
54
|
+
ROOT --> TSCONFIG
|
|
55
|
+
|
|
56
|
+
SRC --> TOKEN_DIR
|
|
57
|
+
SRC --> NFT_DIR
|
|
58
|
+
|
|
59
|
+
TOKEN_DIR --> TOKEN
|
|
60
|
+
TOKEN_DIR --> TOKEN_INDEX
|
|
61
|
+
NFT_DIR --> NFT
|
|
62
|
+
NFT_DIR --> NFT_INDEX
|
|
63
|
+
|
|
64
|
+
TOKEN -.->|"imported by"| TOKEN_INDEX
|
|
65
|
+
NFT -.->|"imported by"| NFT_INDEX
|
|
66
|
+
|
|
67
|
+
TOKEN_INDEX -.->|"compiled by"| ASCONFIG
|
|
68
|
+
NFT_INDEX -.->|"compiled by"| ASCONFIG
|
|
69
|
+
ASCONFIG -.->|"produces"| TOKEN_WASM
|
|
70
|
+
ASCONFIG -.->|"produces"| NFT_WASM
|
|
71
|
+
|
|
72
|
+
TOKEN -.->|"tested by"| SPEC
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
A typical OPNet contract project looks like this:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
my-opnet-project/
|
|
79
|
+
├── src/ # AssemblyScript source code
|
|
80
|
+
│ ├── token/ # Token contract
|
|
81
|
+
│ │ ├── MyToken.ts # Contract implementation
|
|
82
|
+
│ │ └── index.ts # Entry point with Blockchain.contract
|
|
83
|
+
│ ├── nft/ # NFT contract (optional)
|
|
84
|
+
│ │ ├── MyNFT.ts
|
|
85
|
+
│ │ └── index.ts
|
|
86
|
+
│ └── tsconfig.json # AssemblyScript config for src/
|
|
87
|
+
├── build/ # Compiled output
|
|
88
|
+
│ ├── MyToken.wasm # Token contract build
|
|
89
|
+
│ └── MyNFT.wasm # NFT contract build
|
|
90
|
+
├── tests/ # Test files
|
|
91
|
+
│ └── MyToken.spec.ts
|
|
92
|
+
├── asconfig.json # AssemblyScript configuration
|
|
93
|
+
├── package.json # Node.js configuration
|
|
94
|
+
└── tsconfig.json # TypeScript configuration
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Key Files
|
|
98
|
+
|
|
99
|
+
### src/token/index.ts
|
|
100
|
+
|
|
101
|
+
The entry point for each contract that sets up the contract instance:
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { Blockchain } from '@btc-vision/btc-runtime/runtime';
|
|
105
|
+
import { revertOnError } from '@btc-vision/btc-runtime/runtime/abort/abort';
|
|
106
|
+
import { MyToken } from './MyToken';
|
|
107
|
+
|
|
108
|
+
// DO NOT TOUCH TO THIS.
|
|
109
|
+
Blockchain.contract = () => {
|
|
110
|
+
// ONLY CHANGE THE CONTRACT CLASS NAME.
|
|
111
|
+
// DO NOT ADD CUSTOM LOGIC HERE.
|
|
112
|
+
|
|
113
|
+
return new MyToken();
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// VERY IMPORTANT
|
|
117
|
+
export * from '@btc-vision/btc-runtime/runtime/exports';
|
|
118
|
+
|
|
119
|
+
// VERY IMPORTANT
|
|
120
|
+
export function abort(message: string, fileName: string, line: u32, column: u32): void {
|
|
121
|
+
revertOnError(message, fileName, line, column);
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### asconfig.json
|
|
126
|
+
|
|
127
|
+
AssemblyScript compiler configuration with per-contract targets:
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"targets": {
|
|
132
|
+
"token": {
|
|
133
|
+
"outFile": "build/MyToken.wasm",
|
|
134
|
+
"use": ["abort=src/token/index/abort"]
|
|
135
|
+
},
|
|
136
|
+
"nft": {
|
|
137
|
+
"outFile": "build/MyNFT.wasm",
|
|
138
|
+
"use": ["abort=src/nft/index/abort"]
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"options": {
|
|
142
|
+
"sourceMap": false,
|
|
143
|
+
"optimizeLevel": 3,
|
|
144
|
+
"shrinkLevel": 1,
|
|
145
|
+
"converge": true,
|
|
146
|
+
"noAssert": false,
|
|
147
|
+
"enable": [
|
|
148
|
+
"sign-extension",
|
|
149
|
+
"mutable-globals",
|
|
150
|
+
"nontrapping-f2i",
|
|
151
|
+
"bulk-memory",
|
|
152
|
+
"simd",
|
|
153
|
+
"reference-types",
|
|
154
|
+
"multi-value"
|
|
155
|
+
],
|
|
156
|
+
"runtime": "stub",
|
|
157
|
+
"memoryBase": 0,
|
|
158
|
+
"initialMemory": 1,
|
|
159
|
+
"exportStart": "start",
|
|
160
|
+
"transform": "@btc-vision/opnet-transform"
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
| Option | Description |
|
|
166
|
+
|--------|-------------|
|
|
167
|
+
| `targets` | Per-contract build targets with output paths |
|
|
168
|
+
| `use` | Links custom abort function for error handling |
|
|
169
|
+
| `optimizeLevel` | Optimization level (0-3), higher = faster but larger |
|
|
170
|
+
| `shrinkLevel` | Code size reduction (0-2) |
|
|
171
|
+
| `transform` | OPNet transform for decorator processing |
|
|
172
|
+
| `runtime: "stub"` | Minimal runtime (OPNet provides its own) |
|
|
173
|
+
|
|
174
|
+
### package.json Scripts
|
|
175
|
+
|
|
176
|
+
Recommended scripts for your `package.json`:
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"scripts": {
|
|
181
|
+
"build:token": "asc src/token/index.ts --target token --measure --uncheckedBehavior never",
|
|
182
|
+
"build:nft": "asc src/nft/index.ts --target nft --measure --uncheckedBehavior never"
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## btc-runtime Library Structure
|
|
188
|
+
|
|
189
|
+
### Runtime Library Architecture
|
|
190
|
+
|
|
191
|
+
This diagram shows the internal organization of the @btc-vision/btc-runtime package:
|
|
192
|
+
|
|
193
|
+
```mermaid
|
|
194
|
+
---
|
|
195
|
+
config:
|
|
196
|
+
theme: dark
|
|
197
|
+
---
|
|
198
|
+
graph LR
|
|
199
|
+
subgraph runtime["btc-runtime Package"]
|
|
200
|
+
RUNTIME["runtime/"]
|
|
201
|
+
INDEX["index.ts<br/>Main Exports"]
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
subgraph contracts["Contract Base Classes"]
|
|
205
|
+
OPNET["OP_NET.ts<br/>Base Contract"]
|
|
206
|
+
OP20["OP20.ts<br/>Fungible Token"]
|
|
207
|
+
OP721["OP721.ts<br/>NFT Standard"]
|
|
208
|
+
GUARD["ReentrancyGuard.ts<br/>Security"]
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
subgraph storage["Storage System"]
|
|
212
|
+
STORED["StoredU256.ts<br/>Persistent Values"]
|
|
213
|
+
STOREDSTR["StoredString.ts<br/>String Storage"]
|
|
214
|
+
STOREDMAP["StoredMapU256.ts<br/>Key-Value Maps"]
|
|
215
|
+
STOREDARRAY["StoredU256Array.ts<br/>Dynamic Arrays"]
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
subgraph memory["Memory Management"]
|
|
219
|
+
ADDRMAP["AddressMemoryMap.ts<br/>Address Mappings"]
|
|
220
|
+
MAPOFMAP["MapOfMap.ts<br/>Nested Maps"]
|
|
221
|
+
KEYMERGE["KeyMerger.ts<br/>Key Utilities"]
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
subgraph types["Types & Utilities"]
|
|
225
|
+
ADDR["Address.ts<br/>32-byte Addresses"]
|
|
226
|
+
CALLDATA["Calldata.ts<br/>Input Parsing"]
|
|
227
|
+
BYTESW["BytesWriter.ts<br/>Output Builder"]
|
|
228
|
+
BYTESR["BytesReader.ts<br/>Data Reader"]
|
|
229
|
+
SAFE["SafeMath.ts<br/>Overflow Protection"]
|
|
230
|
+
REV["Revert.ts<br/>Error Handling"]
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
subgraph blockchain["Blockchain Environment"]
|
|
234
|
+
BLOCKCHAIN["BlockchainEnvironment.ts<br/>Runtime Context"]
|
|
235
|
+
TX["Transaction.ts<br/>TX Data"]
|
|
236
|
+
BLOCK["Block.ts<br/>Block Info"]
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
subgraph events["Event System"]
|
|
240
|
+
EVENT["NetEvent.ts<br/>Event Base"]
|
|
241
|
+
TRANSFER["TransferredEvent.ts"]
|
|
242
|
+
APPROVAL["ApprovedEvent.ts"]
|
|
243
|
+
MINT["MintedEvent.ts"]
|
|
244
|
+
BURN["BurnedEvent.ts"]
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
RUNTIME --> INDEX
|
|
248
|
+
|
|
249
|
+
INDEX --> OPNET
|
|
250
|
+
INDEX --> OP20
|
|
251
|
+
INDEX --> OP721
|
|
252
|
+
INDEX --> GUARD
|
|
253
|
+
|
|
254
|
+
INDEX --> STORED
|
|
255
|
+
INDEX --> STOREDSTR
|
|
256
|
+
INDEX --> STOREDMAP
|
|
257
|
+
INDEX --> STOREDARRAY
|
|
258
|
+
|
|
259
|
+
INDEX --> ADDRMAP
|
|
260
|
+
INDEX --> MAPOFMAP
|
|
261
|
+
|
|
262
|
+
INDEX --> ADDR
|
|
263
|
+
INDEX --> CALLDATA
|
|
264
|
+
INDEX --> BYTESW
|
|
265
|
+
INDEX --> BYTESR
|
|
266
|
+
INDEX --> SAFE
|
|
267
|
+
INDEX --> REV
|
|
268
|
+
|
|
269
|
+
INDEX --> BLOCKCHAIN
|
|
270
|
+
INDEX --> EVENT
|
|
271
|
+
|
|
272
|
+
OPNET -.->|"uses"| BLOCKCHAIN
|
|
273
|
+
OPNET -.->|"uses"| EVENT
|
|
274
|
+
OP20 -.->|"extends"| GUARD
|
|
275
|
+
GUARD -.->|"extends"| OPNET
|
|
276
|
+
|
|
277
|
+
OP20 -.->|"uses"| STORED
|
|
278
|
+
OP20 -.->|"uses"| ADDRMAP
|
|
279
|
+
OP20 -.->|"uses"| SAFE
|
|
280
|
+
|
|
281
|
+
BLOCKCHAIN --> TX
|
|
282
|
+
BLOCKCHAIN --> BLOCK
|
|
283
|
+
|
|
284
|
+
EVENT --> TRANSFER
|
|
285
|
+
EVENT --> APPROVAL
|
|
286
|
+
EVENT --> MINT
|
|
287
|
+
EVENT --> BURN
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Understanding the btc-runtime structure helps you find the right imports:
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
@btc-vision/btc-runtime/
|
|
294
|
+
├── runtime/ # Main runtime directory
|
|
295
|
+
│ ├── index.ts # Main exports
|
|
296
|
+
│ ├── contracts/ # Contract base classes
|
|
297
|
+
│ │ ├── OP_NET.ts # Base contract class
|
|
298
|
+
│ │ ├── OP20.ts # Fungible token standard
|
|
299
|
+
│ │ ├── OP20S.ts # Token with signatures
|
|
300
|
+
│ │ ├── OP721.ts # NFT standard
|
|
301
|
+
│ │ └── ReentrancyGuard.ts # Reentrancy protection
|
|
302
|
+
│ ├── storage/ # Storage types
|
|
303
|
+
│ │ ├── StoredU256.ts
|
|
304
|
+
│ │ ├── StoredString.ts
|
|
305
|
+
│ │ ├── StoredArray.ts
|
|
306
|
+
│ │ ├── StoredMap.ts
|
|
307
|
+
│ │ └── ...
|
|
308
|
+
│ ├── math/ # Math utilities
|
|
309
|
+
│ │ ├── SafeMath.ts
|
|
310
|
+
│ │ └── SafeMathI128.ts
|
|
311
|
+
│ ├── types/ # Core types
|
|
312
|
+
│ │ ├── Address.ts
|
|
313
|
+
│ │ ├── Calldata.ts
|
|
314
|
+
│ │ ├── BytesWriter.ts
|
|
315
|
+
│ │ ├── BytesReader.ts
|
|
316
|
+
│ │ └── Selector.ts
|
|
317
|
+
│ ├── events/ # Event system
|
|
318
|
+
│ │ ├── NetEvent.ts
|
|
319
|
+
│ │ ├── predefined/
|
|
320
|
+
│ │ └── ...
|
|
321
|
+
│ ├── env/ # Blockchain environment
|
|
322
|
+
│ │ └── BlockchainEnvironment.ts
|
|
323
|
+
│ └── interfaces/ # TypeScript interfaces
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Import Patterns
|
|
327
|
+
|
|
328
|
+
### Basic Imports
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
// Core runtime - contracts and utilities
|
|
332
|
+
import {
|
|
333
|
+
OP_NET,
|
|
334
|
+
OP20,
|
|
335
|
+
OP721,
|
|
336
|
+
Blockchain,
|
|
337
|
+
Address,
|
|
338
|
+
Calldata,
|
|
339
|
+
BytesWriter,
|
|
340
|
+
BytesReader,
|
|
341
|
+
SafeMath,
|
|
342
|
+
Revert,
|
|
343
|
+
} from '@btc-vision/btc-runtime/runtime';
|
|
344
|
+
|
|
345
|
+
// Big numbers
|
|
346
|
+
import { u128, u256 } from '@btc-vision/as-bignum/assembly';
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Storage Types
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
import {
|
|
353
|
+
StoredU256,
|
|
354
|
+
StoredString,
|
|
355
|
+
StoredBoolean,
|
|
356
|
+
StoredAddress,
|
|
357
|
+
StoredU256Array,
|
|
358
|
+
StoredAddressArray,
|
|
359
|
+
StoredMapU256,
|
|
360
|
+
AddressMemoryMap,
|
|
361
|
+
} from '@btc-vision/btc-runtime/runtime';
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Events
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
import {
|
|
368
|
+
NetEvent,
|
|
369
|
+
TransferEvent,
|
|
370
|
+
ApprovalEvent,
|
|
371
|
+
MintEvent,
|
|
372
|
+
BurnEvent,
|
|
373
|
+
} from '@btc-vision/btc-runtime/runtime';
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### Contract Initialization
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
import {
|
|
380
|
+
OP20InitParameters,
|
|
381
|
+
OP721InitParameters,
|
|
382
|
+
} from '@btc-vision/btc-runtime/runtime';
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Storage Pointer System
|
|
386
|
+
|
|
387
|
+
This diagram illustrates how OPNet manages persistent storage using pointers:
|
|
388
|
+
|
|
389
|
+
```mermaid
|
|
390
|
+
---
|
|
391
|
+
config:
|
|
392
|
+
theme: dark
|
|
393
|
+
---
|
|
394
|
+
flowchart LR
|
|
395
|
+
subgraph contract["Contract Storage Model"]
|
|
396
|
+
CONTRACT["MyToken Contract"]
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
subgraph pointers["Storage Pointers"]
|
|
400
|
+
P1["Pointer 0<br/>Total Supply"]
|
|
401
|
+
P2["Pointer 1<br/>Token Name"]
|
|
402
|
+
P3["Pointer 2<br/>Token Symbol"]
|
|
403
|
+
P4["Pointer 3<br/>Decimals"]
|
|
404
|
+
P5["Pointer 4<br/>Balance Map"]
|
|
405
|
+
P6["Pointer 5<br/>Allowance Map"]
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
subgraph state["Blockchain State"]
|
|
409
|
+
STATE[("Persistent Storage")]
|
|
410
|
+
|
|
411
|
+
subgraph values["Stored Values"]
|
|
412
|
+
V1["0x00...01<br/>1000000 tokens"]
|
|
413
|
+
V2["0x00...02<br/>MyToken"]
|
|
414
|
+
V3["0x00...03<br/>MTK"]
|
|
415
|
+
V4["0x00...04<br/>18"]
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
subgraph balances["Balance Mapping"]
|
|
419
|
+
B1["SHA256(pointer 4 + address1)<br/>→ 1000 tokens"]
|
|
420
|
+
B2["SHA256(pointer 4 + address2)<br/>→ 500 tokens"]
|
|
421
|
+
B3["SHA256(pointer 4 + address3)<br/>→ 250 tokens"]
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
subgraph allowances["Allowance Nested Map"]
|
|
425
|
+
A1["SHA256(pointer 5 + owner + spender)<br/>→ 100 tokens"]
|
|
426
|
+
end
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
CONTRACT --> P1
|
|
430
|
+
CONTRACT --> P2
|
|
431
|
+
CONTRACT --> P3
|
|
432
|
+
CONTRACT --> P4
|
|
433
|
+
CONTRACT --> P5
|
|
434
|
+
CONTRACT --> P6
|
|
435
|
+
|
|
436
|
+
P1 -.->|"reads/writes"| V1
|
|
437
|
+
P2 -.->|"reads/writes"| V2
|
|
438
|
+
P3 -.->|"reads/writes"| V3
|
|
439
|
+
P4 -.->|"reads/writes"| V4
|
|
440
|
+
|
|
441
|
+
P5 -.->|"with address key"| B1
|
|
442
|
+
P5 -.->|"with address key"| B2
|
|
443
|
+
P5 -.->|"with address key"| B3
|
|
444
|
+
|
|
445
|
+
P6 -.->|"with owner+spender"| A1
|
|
446
|
+
|
|
447
|
+
V1 --> STATE
|
|
448
|
+
V2 --> STATE
|
|
449
|
+
V3 --> STATE
|
|
450
|
+
V4 --> STATE
|
|
451
|
+
B1 --> STATE
|
|
452
|
+
B2 --> STATE
|
|
453
|
+
B3 --> STATE
|
|
454
|
+
A1 --> STATE
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
## Contract Organization
|
|
458
|
+
|
|
459
|
+
### Single Contract Project
|
|
460
|
+
|
|
461
|
+
For simple projects with one contract:
|
|
462
|
+
|
|
463
|
+
```
|
|
464
|
+
src/
|
|
465
|
+
├── token/
|
|
466
|
+
│ ├── MyToken.ts
|
|
467
|
+
│ └── index.ts
|
|
468
|
+
└── tsconfig.json
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Multi-Contract Project
|
|
472
|
+
|
|
473
|
+
For larger projects with multiple contracts:
|
|
474
|
+
|
|
475
|
+
```
|
|
476
|
+
src/
|
|
477
|
+
├── token/
|
|
478
|
+
│ ├── MyToken.ts
|
|
479
|
+
│ └── index.ts
|
|
480
|
+
├── stablecoin/
|
|
481
|
+
│ ├── MyStablecoin.ts
|
|
482
|
+
│ └── index.ts
|
|
483
|
+
├── nft/
|
|
484
|
+
│ ├── MyNFT.ts
|
|
485
|
+
│ └── index.ts
|
|
486
|
+
├── shared/
|
|
487
|
+
│ ├── CustomTypes.ts
|
|
488
|
+
│ └── Helpers.ts
|
|
489
|
+
└── tsconfig.json
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### Shared Logic
|
|
493
|
+
|
|
494
|
+
For contracts sharing common functionality:
|
|
495
|
+
|
|
496
|
+
```typescript
|
|
497
|
+
// src/shared/Pausable.ts
|
|
498
|
+
import { Blockchain, OP_NET, Revert, StoredBoolean } from '@btc-vision/btc-runtime/runtime';
|
|
499
|
+
|
|
500
|
+
const pausedPointer: u16 = Blockchain.nextPointer;
|
|
501
|
+
|
|
502
|
+
export abstract class Pausable extends OP_NET {
|
|
503
|
+
private _paused: StoredBoolean = new StoredBoolean(pausedPointer, false);
|
|
504
|
+
|
|
505
|
+
protected whenNotPaused(): void {
|
|
506
|
+
if (this._paused.value) {
|
|
507
|
+
throw new Revert('Contract is paused');
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
protected pause(): void {
|
|
512
|
+
this.onlyDeployer(Blockchain.tx.sender);
|
|
513
|
+
this._paused.value = true;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
protected unpause(): void {
|
|
517
|
+
this.onlyDeployer(Blockchain.tx.sender);
|
|
518
|
+
this._paused.value = false;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// src/token/MyToken.ts
|
|
523
|
+
import { Pausable } from '../shared/Pausable';
|
|
524
|
+
|
|
525
|
+
export class MyToken extends Pausable {
|
|
526
|
+
// Now has pause functionality
|
|
527
|
+
}
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
## Comparison with Solidity Projects
|
|
531
|
+
|
|
532
|
+
| Solidity | OPNet | Notes |
|
|
533
|
+
|----------|-------|-------|
|
|
534
|
+
| `contracts/` | `src/token/`, `src/nft/` | Contract source files (one folder per contract) |
|
|
535
|
+
| `interfaces/` | `src/shared/` | Type definitions and shared logic |
|
|
536
|
+
| `libraries/` | `src/shared/` | Shared utilities |
|
|
537
|
+
| `test/` | `tests/` | Test files |
|
|
538
|
+
| `artifacts/` | `build/` | Compiled output |
|
|
539
|
+
| `hardhat.config.js` | `asconfig.json` | Build configuration |
|
|
540
|
+
|
|
541
|
+
## Best Practices
|
|
542
|
+
|
|
543
|
+
### 1. Organize by Feature
|
|
544
|
+
|
|
545
|
+
```
|
|
546
|
+
src/
|
|
547
|
+
├── token/ # Token contract
|
|
548
|
+
├── stablecoin/ # Stablecoin contract
|
|
549
|
+
├── nft/ # NFT contract
|
|
550
|
+
├── governance/ # Governance contract
|
|
551
|
+
└── shared/ # Shared utilities and types
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
### 2. Use Consistent Naming
|
|
555
|
+
|
|
556
|
+
```typescript
|
|
557
|
+
// Contract files: PascalCase.ts
|
|
558
|
+
MyToken.ts
|
|
559
|
+
MyStablecoin.ts
|
|
560
|
+
|
|
561
|
+
// Type files: PascalCase.ts
|
|
562
|
+
CustomTypes.ts
|
|
563
|
+
|
|
564
|
+
// Utility files: camelCase.ts
|
|
565
|
+
mathHelpers.ts
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
### 3. Entry Point Pattern
|
|
569
|
+
|
|
570
|
+
Each contract should have its own index.ts with the proper pattern:
|
|
571
|
+
|
|
572
|
+
```typescript
|
|
573
|
+
// src/token/index.ts
|
|
574
|
+
import { Blockchain } from '@btc-vision/btc-runtime/runtime';
|
|
575
|
+
import { revertOnError } from '@btc-vision/btc-runtime/runtime/abort/abort';
|
|
576
|
+
import { MyToken } from './MyToken';
|
|
577
|
+
|
|
578
|
+
Blockchain.contract = () => {
|
|
579
|
+
return new MyToken();
|
|
580
|
+
};
|
|
581
|
+
|
|
582
|
+
export * from '@btc-vision/btc-runtime/runtime/exports';
|
|
583
|
+
|
|
584
|
+
export function abort(message: string, fileName: string, line: u32, column: u32): void {
|
|
585
|
+
revertOnError(message, fileName, line, column);
|
|
586
|
+
}
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
### 4. Separate Concerns
|
|
590
|
+
|
|
591
|
+
```typescript
|
|
592
|
+
// Good: Each contract has a single responsibility
|
|
593
|
+
export class TokenContract extends OP20 { /* token logic */ }
|
|
594
|
+
export class GovernanceContract extends OP_NET { /* governance logic */ }
|
|
595
|
+
|
|
596
|
+
// Bad: One contract doing too much
|
|
597
|
+
export class EverythingContract extends OP_NET {
|
|
598
|
+
// token logic
|
|
599
|
+
// governance logic
|
|
600
|
+
// oracle logic
|
|
601
|
+
// etc.
|
|
602
|
+
}
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
## Testing Structure
|
|
606
|
+
|
|
607
|
+
```
|
|
608
|
+
tests/
|
|
609
|
+
├── unit/ # Unit tests
|
|
610
|
+
│ ├── MyToken.spec.ts
|
|
611
|
+
│ └── SafeMath.spec.ts
|
|
612
|
+
├── integration/ # Integration tests
|
|
613
|
+
│ └── TokenTransfer.spec.ts
|
|
614
|
+
└── fixtures/ # Test fixtures
|
|
615
|
+
└── testData.ts
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
## Next Steps
|
|
619
|
+
|
|
620
|
+
Now that you understand the project structure:
|
|
621
|
+
|
|
622
|
+
1. [Learn about the blockchain environment](../core-concepts/blockchain-environment.md)
|
|
623
|
+
2. [Understand the storage system](../core-concepts/storage-system.md)
|
|
624
|
+
3. [See complete examples](../examples/basic-token.md)
|
|
625
|
+
|
|
626
|
+
---
|
|
627
|
+
|
|
628
|
+
**Navigation:**
|
|
629
|
+
- Previous: [First Contract](./first-contract.md)
|
|
630
|
+
- Next: [Blockchain Environment](../core-concepts/blockchain-environment.md)
|