@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
|
@@ -615,11 +615,11 @@ protected override encodeData(writer: BytesWriter): void {
|
|
|
615
615
|
}
|
|
616
616
|
```
|
|
617
617
|
|
|
618
|
-
## Solidity vs
|
|
618
|
+
## Solidity vs OP_NET Comparison
|
|
619
619
|
|
|
620
620
|
### Encoding/Decoding Comparison Table
|
|
621
621
|
|
|
622
|
-
| Feature | Solidity |
|
|
622
|
+
| Feature | Solidity | OP_NET |
|
|
623
623
|
|---------|----------|-------|
|
|
624
624
|
| **Encode function** | `abi.encode(...)` | `BytesWriter` methods |
|
|
625
625
|
| **Decode function** | `abi.decode(data, (types))` | `BytesReader` methods |
|
|
@@ -632,7 +632,7 @@ protected override encodeData(writer: BytesWriter): void {
|
|
|
632
632
|
|
|
633
633
|
### Type Encoding Comparison
|
|
634
634
|
|
|
635
|
-
| Solidity Encoding |
|
|
635
|
+
| Solidity Encoding | OP_NET Encoding |
|
|
636
636
|
|-------------------|----------------|
|
|
637
637
|
| `abi.encode(uint256)` | `writer.writeU256(value)` |
|
|
638
638
|
| `abi.encode(uint128)` | `writer.writeU128(value)` |
|
|
@@ -659,12 +659,12 @@ bytes memory packed = abi.encodePacked(recipient, amount);
|
|
|
659
659
|
```
|
|
660
660
|
|
|
661
661
|
```typescript
|
|
662
|
-
//
|
|
662
|
+
// OP_NET
|
|
663
663
|
const writer = new BytesWriter(64); // 32 + 32 bytes
|
|
664
664
|
writer.writeAddress(recipient);
|
|
665
665
|
writer.writeU256(amount);
|
|
666
666
|
const data: Uint8Array = writer.getBuffer();
|
|
667
|
-
//
|
|
667
|
+
// OP_NET encoding is similar to encodePacked (no padding)
|
|
668
668
|
```
|
|
669
669
|
|
|
670
670
|
#### Basic Decoding
|
|
@@ -675,7 +675,7 @@ const data: Uint8Array = writer.getBuffer();
|
|
|
675
675
|
```
|
|
676
676
|
|
|
677
677
|
```typescript
|
|
678
|
-
//
|
|
678
|
+
// OP_NET
|
|
679
679
|
const reader = new BytesReader(data);
|
|
680
680
|
const to: Address = reader.readAddress();
|
|
681
681
|
const amount: u256 = reader.readU256();
|
|
@@ -696,7 +696,7 @@ function encodeTransferData(
|
|
|
696
696
|
```
|
|
697
697
|
|
|
698
698
|
```typescript
|
|
699
|
-
//
|
|
699
|
+
// OP_NET
|
|
700
700
|
function encodeTransferData(
|
|
701
701
|
from: Address,
|
|
702
702
|
to: Address,
|
|
@@ -724,7 +724,7 @@ bytes memory callData = abi.encodeWithSignature("transfer(address,uint256)", to,
|
|
|
724
724
|
```
|
|
725
725
|
|
|
726
726
|
```typescript
|
|
727
|
-
//
|
|
727
|
+
// OP_NET
|
|
728
728
|
const TRANSFER_SELECTOR: Selector = Selector.from("transfer(address,uint256)");
|
|
729
729
|
const writer = new BytesWriter(68); // 4 + 32 + 32
|
|
730
730
|
writer.writeSelector(TRANSFER_SELECTOR);
|
|
@@ -745,7 +745,7 @@ function getInfo() public view returns (address, uint256, bool) {
|
|
|
745
745
|
```
|
|
746
746
|
|
|
747
747
|
```typescript
|
|
748
|
-
//
|
|
748
|
+
// OP_NET - Manual return encoding
|
|
749
749
|
public getInfo(_calldata: Calldata): BytesWriter {
|
|
750
750
|
const writer = new BytesWriter(65); // 32 + 32 + 1
|
|
751
751
|
writer.writeAddress(this._owner.value);
|
|
@@ -766,7 +766,7 @@ if (success) {
|
|
|
766
766
|
```
|
|
767
767
|
|
|
768
768
|
```typescript
|
|
769
|
-
//
|
|
769
|
+
// OP_NET
|
|
770
770
|
const result = Blockchain.call(target, callData, true);
|
|
771
771
|
if (result.success) {
|
|
772
772
|
const reader = new BytesReader(result.data);
|
|
@@ -793,7 +793,7 @@ function encodeOrder(Order memory order) public pure returns (bytes memory) {
|
|
|
793
793
|
```
|
|
794
794
|
|
|
795
795
|
```typescript
|
|
796
|
-
//
|
|
796
|
+
// OP_NET
|
|
797
797
|
class Order {
|
|
798
798
|
maker: Address;
|
|
799
799
|
taker: Address;
|
|
@@ -826,7 +826,7 @@ function _transfer(address from, address to, uint256 amount) internal {
|
|
|
826
826
|
```
|
|
827
827
|
|
|
828
828
|
```typescript
|
|
829
|
-
//
|
|
829
|
+
// OP_NET - Custom event class with manual encoding
|
|
830
830
|
export class TransferEvent extends NetEvent {
|
|
831
831
|
constructor(
|
|
832
832
|
public readonly from: Address,
|
|
@@ -861,7 +861,7 @@ function extractAddress(bytes calldata data, uint offset) public pure returns (a
|
|
|
861
861
|
```
|
|
862
862
|
|
|
863
863
|
```typescript
|
|
864
|
-
//
|
|
864
|
+
// OP_NET
|
|
865
865
|
function extractSelector(data: Uint8Array): Selector {
|
|
866
866
|
const reader = new BytesReader(data);
|
|
867
867
|
return reader.readSelector();
|
|
@@ -879,7 +879,7 @@ function extractAddress(data: Uint8Array, offset: u32): Address {
|
|
|
879
879
|
|
|
880
880
|
### Size Comparison (Encoding Overhead)
|
|
881
881
|
|
|
882
|
-
| Data | Solidity abi.encode | Solidity encodePacked |
|
|
882
|
+
| Data | Solidity abi.encode | Solidity encodePacked | OP_NET |
|
|
883
883
|
|------|---------------------|----------------------|-------|
|
|
884
884
|
| `bool` | 32 bytes | 1 byte | 1 byte |
|
|
885
885
|
| `uint8` | 32 bytes | 1 byte | 1 byte |
|
|
@@ -893,7 +893,7 @@ function extractAddress(data: Uint8Array, offset: u32): Address {
|
|
|
893
893
|
|
|
894
894
|
### Key Differences Summary
|
|
895
895
|
|
|
896
|
-
| Aspect | Solidity |
|
|
896
|
+
| Aspect | Solidity | OP_NET |
|
|
897
897
|
|--------|----------|-------|
|
|
898
898
|
| **Encoding approach** | `abi.encode()` function | BytesWriter object methods |
|
|
899
899
|
| **Decoding approach** | `abi.decode()` with type tuple | BytesReader sequential reads |
|
|
@@ -914,7 +914,7 @@ bytes memory encoded = abi.encode(addr, amount, flag);
|
|
|
914
914
|
```
|
|
915
915
|
|
|
916
916
|
```typescript
|
|
917
|
-
//
|
|
917
|
+
// OP_NET equivalent
|
|
918
918
|
const writer = new BytesWriter(65); // 32 + 32 + 1
|
|
919
919
|
writer.writeAddress(addr);
|
|
920
920
|
writer.writeU256(amount);
|
|
@@ -930,7 +930,7 @@ const encoded = writer.getBuffer();
|
|
|
930
930
|
```
|
|
931
931
|
|
|
932
932
|
```typescript
|
|
933
|
-
//
|
|
933
|
+
// OP_NET equivalent
|
|
934
934
|
const reader = new BytesReader(data);
|
|
935
935
|
const addr = reader.readAddress();
|
|
936
936
|
const amount = reader.readU256();
|
|
@@ -949,7 +949,7 @@ bytes memory data = abi.encodeWithSelector(
|
|
|
949
949
|
```
|
|
950
950
|
|
|
951
951
|
```typescript
|
|
952
|
-
//
|
|
952
|
+
// OP_NET equivalent
|
|
953
953
|
const TRANSFER_SELECTOR: Selector = Selector.from("transfer(address,uint256)");
|
|
954
954
|
const writer = new BytesWriter(68);
|
|
955
955
|
writer.writeSelector(TRANSFER_SELECTOR);
|
package/docs/types/calldata.md
CHANGED
|
@@ -235,11 +235,11 @@ Arrays use a u16 length prefix (max 65535 elements):
|
|
|
235
235
|
|----------------------|-----------|-----------|-----|
|
|
236
236
|
```
|
|
237
237
|
|
|
238
|
-
## Solidity vs
|
|
238
|
+
## Solidity vs OP_NET Comparison
|
|
239
239
|
|
|
240
240
|
### Calldata Decoding Comparison Table
|
|
241
241
|
|
|
242
|
-
| Feature | Solidity |
|
|
242
|
+
| Feature | Solidity | OP_NET |
|
|
243
243
|
|---------|----------|-------|
|
|
244
244
|
| **Parameter access** | Automatic (named parameters) | Manual sequential reading |
|
|
245
245
|
| **Decode function** | `abi.decode(data, (T1, T2))` | `calldata.readT1(); calldata.readT2();` |
|
|
@@ -251,7 +251,7 @@ Arrays use a u16 length prefix (max 65535 elements):
|
|
|
251
251
|
|
|
252
252
|
### Type-by-Type Decoding Comparison
|
|
253
253
|
|
|
254
|
-
| Solidity Decoding |
|
|
254
|
+
| Solidity Decoding | OP_NET Decoding |
|
|
255
255
|
|-------------------|----------------|
|
|
256
256
|
| `abi.decode(data, (uint256))` | `calldata.readU256()` |
|
|
257
257
|
| `abi.decode(data, (uint128))` | `calldata.readU128()` |
|
|
@@ -282,7 +282,7 @@ function transfer(address to, uint256 amount) public returns (bool) {
|
|
|
282
282
|
```
|
|
283
283
|
|
|
284
284
|
```typescript
|
|
285
|
-
//
|
|
285
|
+
// OP_NET - Parameters read sequentially
|
|
286
286
|
public transfer(calldata: Calldata): BytesWriter {
|
|
287
287
|
// Must read in exact order they were encoded
|
|
288
288
|
const to: Address = calldata.readAddress();
|
|
@@ -312,7 +312,7 @@ function transferFrom(
|
|
|
312
312
|
```
|
|
313
313
|
|
|
314
314
|
```typescript
|
|
315
|
-
//
|
|
315
|
+
// OP_NET
|
|
316
316
|
public transferFrom(calldata: Calldata): BytesWriter {
|
|
317
317
|
const from: Address = calldata.readAddress();
|
|
318
318
|
const to: Address = calldata.readAddress();
|
|
@@ -344,7 +344,7 @@ function decodeWithOffset(bytes calldata data) public pure {
|
|
|
344
344
|
```
|
|
345
345
|
|
|
346
346
|
```typescript
|
|
347
|
-
//
|
|
347
|
+
// OP_NET - Sequential reading handles offset automatically
|
|
348
348
|
public decodeTransfer(calldata: Calldata): BytesWriter {
|
|
349
349
|
const to: Address = calldata.readAddress(); // Reads bytes 0-31
|
|
350
350
|
const amount: u256 = calldata.readU256(); // Reads bytes 32-63
|
|
@@ -372,7 +372,7 @@ function processData(bytes calldata data) public {
|
|
|
372
372
|
```
|
|
373
373
|
|
|
374
374
|
```typescript
|
|
375
|
-
//
|
|
375
|
+
// OP_NET
|
|
376
376
|
public setName(calldata: Calldata): BytesWriter {
|
|
377
377
|
const name: string = calldata.readString(); // Length-prefixed
|
|
378
378
|
if (name.length == 0) {
|
|
@@ -408,7 +408,7 @@ function batchTransfer(
|
|
|
408
408
|
```
|
|
409
409
|
|
|
410
410
|
```typescript
|
|
411
|
-
//
|
|
411
|
+
// OP_NET
|
|
412
412
|
public batchTransfer(calldata: Calldata): BytesWriter {
|
|
413
413
|
const recipients: Address[] = calldata.readAddressArray();
|
|
414
414
|
const amounts: u256[] = calldata.readU256Array();
|
|
@@ -443,7 +443,7 @@ function safeTransferFrom(
|
|
|
443
443
|
```
|
|
444
444
|
|
|
445
445
|
```typescript
|
|
446
|
-
//
|
|
446
|
+
// OP_NET - Check for remaining data
|
|
447
447
|
public safeTransferFrom(calldata: Calldata): BytesWriter {
|
|
448
448
|
const from: Address = calldata.readAddress();
|
|
449
449
|
const to: Address = calldata.readAddress();
|
|
@@ -466,7 +466,7 @@ public safeTransferFrom(calldata: Calldata): BytesWriter {
|
|
|
466
466
|
|
|
467
467
|
### Encoding Format Differences
|
|
468
468
|
|
|
469
|
-
| Aspect | Solidity ABI |
|
|
469
|
+
| Aspect | Solidity ABI | OP_NET |
|
|
470
470
|
|--------|--------------|-------|
|
|
471
471
|
| **Byte order** | Big-endian | Big-endian (default) |
|
|
472
472
|
| **Address padding** | Left-padded to 32 bytes | 32 bytes (native size) |
|
|
@@ -478,7 +478,7 @@ public safeTransferFrom(calldata: Calldata): BytesWriter {
|
|
|
478
478
|
|
|
479
479
|
### Encoding Size Comparison
|
|
480
480
|
|
|
481
|
-
| Type | Solidity ABI Size |
|
|
481
|
+
| Type | Solidity ABI Size | OP_NET Size |
|
|
482
482
|
|------|-------------------|------------|
|
|
483
483
|
| `bool` | 32 bytes | 1 byte |
|
|
484
484
|
| `uint8` | 32 bytes | 1 byte |
|
|
@@ -492,7 +492,7 @@ public safeTransferFrom(calldata: Calldata): BytesWriter {
|
|
|
492
492
|
|
|
493
493
|
### Key Differences Summary
|
|
494
494
|
|
|
495
|
-
| Solidity |
|
|
495
|
+
| Solidity | OP_NET |
|
|
496
496
|
|----------|-------|
|
|
497
497
|
| Named parameters in function signature | Single `Calldata` parameter |
|
|
498
498
|
| Automatic ABI decoding | Manual `read*()` methods |
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btc-vision/btc-runtime",
|
|
3
|
-
"version": "1.11.0
|
|
4
|
-
"description": "Bitcoin L1 Smart Contract Runtime for
|
|
3
|
+
"version": "1.11.0",
|
|
4
|
+
"description": "Bitcoin L1 Smart Contract Runtime for OP_NET. Build decentralized applications on Bitcoin using AssemblyScript and WebAssembly. Fully audited.",
|
|
5
5
|
"main": "btc/index.ts",
|
|
6
6
|
"types": "btc/index.ts",
|
|
7
|
-
"author": "
|
|
7
|
+
"author": "OP_NET <support@opnet.org>",
|
|
8
8
|
"license": "Apache-2.0",
|
|
9
9
|
"homepage": "https://opnet.org",
|
|
10
10
|
"repository": {
|
|
@@ -59,16 +59,16 @@
|
|
|
59
59
|
"node": ">=24.0.0"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@
|
|
63
|
-
"@btc-vision/as-
|
|
64
|
-
"@btc-vision/assemblyscript": "^0.29.
|
|
65
|
-
"@btc-vision/opnet-transform": "^1.2.
|
|
62
|
+
"@btc-vision/as-bignum": "^1.0.0",
|
|
63
|
+
"@btc-vision/as-loader": "^0.0.0",
|
|
64
|
+
"@btc-vision/assemblyscript": "^0.29.3",
|
|
65
|
+
"@btc-vision/opnet-transform": "^1.2.2",
|
|
66
66
|
"@eslint/js": "^10.0.1",
|
|
67
|
-
"eslint": "^10.0.
|
|
67
|
+
"eslint": "^10.0.3",
|
|
68
68
|
"gulplog": "^2.2.0",
|
|
69
69
|
"ts-node": "^10.9.2",
|
|
70
70
|
"typescript": "^5.9.3",
|
|
71
|
-
"typescript-eslint": "^8.
|
|
71
|
+
"typescript-eslint": "^8.57.1"
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
74
|
"@btc-vision/as-covers-assembly": "^0.4.4",
|
|
@@ -76,6 +76,6 @@
|
|
|
76
76
|
"@btc-vision/as-pect-assembly": "^8.2.0",
|
|
77
77
|
"@btc-vision/as-pect-cli": "^8.2.0",
|
|
78
78
|
"@btc-vision/as-pect-transform": "^8.2.0",
|
|
79
|
-
"@types/node": "^25.
|
|
79
|
+
"@types/node": "^25.5.0"
|
|
80
80
|
}
|
|
81
81
|
}
|
|
@@ -16,39 +16,9 @@ export const ALLOWANCE_DECREASE_TYPE_HASH: u8[] = [
|
|
|
16
16
|
// onOP721Received(address,address,uint256,bytes)
|
|
17
17
|
export const ON_OP721_RECEIVED_SELECTOR: u32 = 0x5349f6de;
|
|
18
18
|
|
|
19
|
-
// onOP1155Received(address,address,uint256,uint256,bytes)
|
|
20
|
-
export const ON_OP1155_RECEIVED_MAGIC: u32 = 0xcedc9fdf;
|
|
21
|
-
|
|
22
|
-
// onOP1155BatchReceived(address,address,uint256[],uint256[],bytes)
|
|
23
|
-
export const ON_OP1155_BATCH_RECEIVED_MAGIC: u32 = 0x5d95545f;
|
|
24
|
-
|
|
25
|
-
// Interface IDs
|
|
26
|
-
// balanceOf(address,uint256) -> 0x7ab6c0bc
|
|
27
|
-
// balanceOfBatch(address[],uint256[]) -> 0xed4db4b0
|
|
28
|
-
// safeTransferFrom(address,address,uint256,uint256,bytes) -> 0x0875aead
|
|
29
|
-
// safeBatchTransferFrom(address,address,uint256[],uint256[],bytes) -> 0x1917c486
|
|
30
|
-
// setApprovalForAll(address,bool) -> 0xd97fb4c0
|
|
31
|
-
// isApprovedForAll(address,address) -> 0x67da1fb2
|
|
32
|
-
export const INTERFACE_ID_OP1155: u32 = 0x383cb555;
|
|
33
|
-
|
|
34
|
-
// sha256("uri(uint256)")
|
|
35
|
-
export const INTERFACE_ID_OP1155_METADATA_URI: u32 = 0x31473f54;
|
|
36
|
-
|
|
37
19
|
// sha256("supportsInterface(bytes4)")
|
|
38
20
|
export const INTERFACE_ID_ERC165: u32 = 0x0e2b7fe2;
|
|
39
21
|
|
|
40
|
-
// OP1155Transfer(address from,address to,uint256 id,uint256 amount,uint256 nonce,uint64 deadline)
|
|
41
|
-
export const OP1155_TRANSFER_TYPE_HASH: u8[] = [
|
|
42
|
-
0x5a, 0x64, 0x2c, 0xa2, 0xd8, 0xfd, 0xe9, 0xe1, 0x28, 0x87, 0x7c, 0xf5, 0x5d, 0x71, 0x96, 0xe3,
|
|
43
|
-
0x3a, 0xd4, 0x4b, 0xb3, 0x4b, 0x0a, 0x8d, 0x85, 0x8d, 0xa8, 0x04, 0xbd, 0x3b, 0x86, 0x21, 0x0e,
|
|
44
|
-
];
|
|
45
|
-
|
|
46
|
-
// OP1155BatchTransfer(address from,address to,uint256[] ids,uint256[] amounts,uint256 nonce,uint64 deadline)
|
|
47
|
-
export const OP1155_BATCH_TRANSFER_TYPE_HASH: u8[] = [
|
|
48
|
-
0x7b, 0xf8, 0xb6, 0x39, 0x5f, 0xea, 0xcc, 0x15, 0x97, 0x12, 0x38, 0x00, 0x91, 0xb9, 0x2b, 0x96,
|
|
49
|
-
0x67, 0x6b, 0x2b, 0x73, 0x46, 0xff, 0x29, 0x27, 0xbf, 0x1a, 0x54, 0xf8, 0xfc, 0xef, 0x9c, 0x0b,
|
|
50
|
-
];
|
|
51
|
-
|
|
52
22
|
// sha256("OP712Domain(string name,string version,bytes32 chainId,bytes32 protocolId,address verifyingContract)")
|
|
53
23
|
export const OP712_DOMAIN_TYPE_HASH: u8[] = [
|
|
54
24
|
0xfe, 0xe8, 0x22, 0x92, 0x35, 0x1d, 0x1a, 0x8b, 0xab, 0x21, 0xc4, 0xef, 0xdd, 0x15, 0x7e, 0x31,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
} from '../constants/Exports';
|
|
22
22
|
import { Blockchain } from '../env';
|
|
23
23
|
import { sha256, sha256String } from '../env/global';
|
|
24
|
-
import {
|
|
24
|
+
import { OP20ApprovedEvent, OP20BurnedEvent, OP20MintedEvent, OP20TransferredEvent } from '../events/predefined';
|
|
25
25
|
import { Selector } from '../math/abi';
|
|
26
26
|
import { EMPTY_POINTER } from '../math/bytes';
|
|
27
27
|
import { AddressMemoryMap } from '../memory/AddressMemoryMap';
|
|
@@ -56,7 +56,7 @@ const allowanceMapPointer: u16 = Blockchain.nextPointer;
|
|
|
56
56
|
const nonceMapPointer: u16 = Blockchain.nextPointer;
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
|
-
* OP20 Token Standard Implementation for
|
|
59
|
+
* OP20 Token Standard Implementation for OP_NET.
|
|
60
60
|
*
|
|
61
61
|
* This abstract class implements the OP20 token standard, providing a complete
|
|
62
62
|
* fungible token implementation with advanced features including:
|
|
@@ -67,7 +67,7 @@ const nonceMapPointer: u16 = Blockchain.nextPointer;
|
|
|
67
67
|
* - Unlimited approval optimization (u256.Max)
|
|
68
68
|
*
|
|
69
69
|
* @remarks
|
|
70
|
-
* OP20 is
|
|
70
|
+
* OP20 is OP_NET's equivalent of ERC20, adapted for Bitcoin's UTXO model with
|
|
71
71
|
* additional security features. All storage uses persistent pointers for
|
|
72
72
|
* cross-transaction state management. The contract includes built-in protection
|
|
73
73
|
* against common attack vectors including reentrancy and integer overflow.
|
|
@@ -949,15 +949,15 @@ export abstract class OP20 extends ReentrancyGuard implements IOP20 {
|
|
|
949
949
|
|
|
950
950
|
/** Event creation helpers */
|
|
951
951
|
protected createBurnedEvent(from: Address, amount: u256): void {
|
|
952
|
-
this.emitEvent(new
|
|
952
|
+
this.emitEvent(new OP20BurnedEvent(from, amount));
|
|
953
953
|
}
|
|
954
954
|
|
|
955
955
|
protected createApprovedEvent(owner: Address, spender: Address, amount: u256): void {
|
|
956
|
-
this.emitEvent(new
|
|
956
|
+
this.emitEvent(new OP20ApprovedEvent(owner, spender, amount));
|
|
957
957
|
}
|
|
958
958
|
|
|
959
959
|
protected createMintedEvent(to: Address, amount: u256): void {
|
|
960
|
-
this.emitEvent(new
|
|
960
|
+
this.emitEvent(new OP20MintedEvent(to, amount));
|
|
961
961
|
}
|
|
962
962
|
|
|
963
963
|
protected createTransferredEvent(
|
|
@@ -966,6 +966,6 @@ export abstract class OP20 extends ReentrancyGuard implements IOP20 {
|
|
|
966
966
|
to: Address,
|
|
967
967
|
amount: u256,
|
|
968
968
|
): void {
|
|
969
|
-
this.emitEvent(new
|
|
969
|
+
this.emitEvent(new OP20TransferredEvent(operator, from, to, amount));
|
|
970
970
|
}
|
|
971
971
|
}
|
|
@@ -28,13 +28,7 @@ import { IOP721 } from './interfaces/IOP721';
|
|
|
28
28
|
import { OP721InitParameters } from './interfaces/OP721InitParameters';
|
|
29
29
|
import { ReentrancyGuard } from './ReentrancyGuard';
|
|
30
30
|
import { StoredMapU256 } from '../storage/maps/StoredMapU256';
|
|
31
|
-
import {
|
|
32
|
-
ApprovedEvent,
|
|
33
|
-
ApprovedForAllEvent,
|
|
34
|
-
MAX_URI_LENGTH,
|
|
35
|
-
TransferredEvent,
|
|
36
|
-
URIEvent,
|
|
37
|
-
} from '../events/predefined';
|
|
31
|
+
import { MAX_URI_LENGTH, OP721ApprovedForAllEvent, URIEvent } from '../events/predefined';
|
|
38
32
|
import {
|
|
39
33
|
ON_OP721_RECEIVED_SELECTOR,
|
|
40
34
|
OP712_DOMAIN_TYPE_HASH,
|
|
@@ -43,6 +37,10 @@ import {
|
|
|
43
37
|
OP721_APPROVAL_TYPE_HASH,
|
|
44
38
|
} from '../constants/Exports';
|
|
45
39
|
import { ExtendedAddress } from '../types/ExtendedAddress';
|
|
40
|
+
import { OP721TransferredEvent } from '../events/predefined/OP721TransferredEvent';
|
|
41
|
+
import { OP721ApprovedEvent } from '../events/predefined/OP721ApprovedEvent';
|
|
42
|
+
import { OP721MintedEvent } from '../events/predefined/OP721MintedEvent';
|
|
43
|
+
import { OP721BurnedEvent } from '../events/predefined/OP721BurnedEvent';
|
|
46
44
|
|
|
47
45
|
const stringPointer: u16 = Blockchain.nextPointer;
|
|
48
46
|
const totalSupplyPointer: u16 = Blockchain.nextPointer;
|
|
@@ -63,10 +61,10 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
|
|
|
63
61
|
protected readonly _name: StoredString;
|
|
64
62
|
protected readonly _symbol: StoredString;
|
|
65
63
|
protected readonly _baseURI: StoredString;
|
|
66
|
-
protected readonly
|
|
67
|
-
protected readonly
|
|
68
|
-
protected readonly
|
|
69
|
-
protected readonly
|
|
64
|
+
protected readonly _banner: StoredString;
|
|
65
|
+
protected readonly _icon: StoredString;
|
|
66
|
+
protected readonly _description: StoredString;
|
|
67
|
+
protected readonly _website: StoredString;
|
|
70
68
|
|
|
71
69
|
protected readonly _totalSupply: StoredU256;
|
|
72
70
|
protected readonly _maxSupply: StoredU256;
|
|
@@ -97,10 +95,10 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
|
|
|
97
95
|
this._name = new StoredString(stringPointer, 0);
|
|
98
96
|
this._symbol = new StoredString(stringPointer, 2);
|
|
99
97
|
this._baseURI = new StoredString(stringPointer, 3);
|
|
100
|
-
this.
|
|
101
|
-
this.
|
|
102
|
-
this.
|
|
103
|
-
this.
|
|
98
|
+
this._banner = new StoredString(stringPointer, 4);
|
|
99
|
+
this._icon = new StoredString(stringPointer, 5);
|
|
100
|
+
this._description = new StoredString(stringPointer, 6);
|
|
101
|
+
this._website = new StoredString(stringPointer, 7);
|
|
104
102
|
|
|
105
103
|
this._totalSupply = new StoredU256(totalSupplyPointer, EMPTY_POINTER);
|
|
106
104
|
this._maxSupply = new StoredU256(maxSupplyPointer, EMPTY_POINTER);
|
|
@@ -128,6 +126,10 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
|
|
|
128
126
|
return this._symbol.value;
|
|
129
127
|
}
|
|
130
128
|
|
|
129
|
+
public get icon(): string {
|
|
130
|
+
return this._icon.value;
|
|
131
|
+
}
|
|
132
|
+
|
|
131
133
|
public get baseURI(): string {
|
|
132
134
|
return this._baseURI.value;
|
|
133
135
|
}
|
|
@@ -140,20 +142,16 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
|
|
|
140
142
|
return this._maxSupply.value;
|
|
141
143
|
}
|
|
142
144
|
|
|
143
|
-
public get
|
|
144
|
-
return this.
|
|
145
|
+
public get banner(): string {
|
|
146
|
+
return this._banner.value;
|
|
145
147
|
}
|
|
146
148
|
|
|
147
|
-
public get
|
|
148
|
-
return this.
|
|
149
|
+
public get description(): string {
|
|
150
|
+
return this._description.value;
|
|
149
151
|
}
|
|
150
152
|
|
|
151
|
-
public get
|
|
152
|
-
return this.
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
public get collectionWebsite(): string {
|
|
156
|
-
return this._collectionWebsite.value;
|
|
153
|
+
public get website(): string {
|
|
154
|
+
return this._website.value;
|
|
157
155
|
}
|
|
158
156
|
|
|
159
157
|
public instantiate(
|
|
@@ -175,10 +173,10 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
|
|
|
175
173
|
this._initialized.value = u256.One;
|
|
176
174
|
this._tokenURICounter.value = u256.Zero;
|
|
177
175
|
|
|
178
|
-
this.
|
|
179
|
-
this.
|
|
180
|
-
this.
|
|
181
|
-
this.
|
|
176
|
+
this._banner.value = params.banner;
|
|
177
|
+
this._icon.value = params.icon;
|
|
178
|
+
this._description.value = params.description;
|
|
179
|
+
this._website.value = params.website;
|
|
182
180
|
}
|
|
183
181
|
|
|
184
182
|
@method('name')
|
|
@@ -207,28 +205,6 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
|
|
|
207
205
|
return w;
|
|
208
206
|
}
|
|
209
207
|
|
|
210
|
-
@method('collectionInfo')
|
|
211
|
-
@returns(
|
|
212
|
-
{ name: 'icon', type: ABIDataTypes.STRING },
|
|
213
|
-
{ name: 'banner', type: ABIDataTypes.STRING },
|
|
214
|
-
{ name: 'description', type: ABIDataTypes.STRING },
|
|
215
|
-
{ name: 'website', type: ABIDataTypes.STRING },
|
|
216
|
-
)
|
|
217
|
-
public collectionInfo(_: Calldata): BytesWriter {
|
|
218
|
-
const length =
|
|
219
|
-
String.UTF8.byteLength(this.collectionIcon) +
|
|
220
|
-
String.UTF8.byteLength(this.collectionDescription) +
|
|
221
|
-
String.UTF8.byteLength(this.collectionWebsite) +
|
|
222
|
-
String.UTF8.byteLength(this.collectionBanner);
|
|
223
|
-
|
|
224
|
-
const w = new BytesWriter(U32_BYTE_LENGTH * 4 + length);
|
|
225
|
-
w.writeStringWithLength(this.collectionIcon);
|
|
226
|
-
w.writeStringWithLength(this.collectionBanner);
|
|
227
|
-
w.writeStringWithLength(this.collectionDescription);
|
|
228
|
-
w.writeStringWithLength(this.collectionWebsite);
|
|
229
|
-
return w;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
208
|
@method({ name: 'tokenId', type: ABIDataTypes.UINT256 })
|
|
233
209
|
@returns({ name: 'uri', type: ABIDataTypes.STRING })
|
|
234
210
|
public tokenURI(calldata: Calldata): BytesWriter {
|
|
@@ -272,10 +248,10 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
|
|
|
272
248
|
if (description.length == 0) throw new Revert('Description cannot be empty');
|
|
273
249
|
if (website.length == 0) throw new Revert('Website cannot be empty');
|
|
274
250
|
|
|
275
|
-
this.
|
|
276
|
-
this.
|
|
277
|
-
this.
|
|
278
|
-
this.
|
|
251
|
+
this._icon.value = icon;
|
|
252
|
+
this._banner.value = banner;
|
|
253
|
+
this._description.value = description;
|
|
254
|
+
this._website.value = website;
|
|
279
255
|
|
|
280
256
|
return new BytesWriter(0);
|
|
281
257
|
}
|
|
@@ -489,7 +465,7 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
|
|
|
489
465
|
}
|
|
490
466
|
|
|
491
467
|
@method({ name: 'tokenId', type: ABIDataTypes.UINT256 })
|
|
492
|
-
@emit('
|
|
468
|
+
@emit('Burned')
|
|
493
469
|
public burn(calldata: Calldata): BytesWriter {
|
|
494
470
|
const tokenId = calldata.readU256();
|
|
495
471
|
this._burn(tokenId);
|
|
@@ -526,7 +502,7 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
|
|
|
526
502
|
|
|
527
503
|
@method({ name: 'owner', type: ABIDataTypes.ADDRESS })
|
|
528
504
|
@returns({ name: 'nonce', type: ABIDataTypes.UINT256 })
|
|
529
|
-
public
|
|
505
|
+
public nonceOf(calldata: Calldata): BytesWriter {
|
|
530
506
|
const owner = calldata.readAddress();
|
|
531
507
|
const nonce = this._approveNonceMap.get(owner);
|
|
532
508
|
const w = new BytesWriter(U256_BYTE_LENGTH);
|
|
@@ -565,10 +541,10 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
|
|
|
565
541
|
public metadata(_: Calldata): BytesWriter {
|
|
566
542
|
const name = this.name;
|
|
567
543
|
const symbol = this.symbol;
|
|
568
|
-
const icon = this.
|
|
569
|
-
const banner = this.
|
|
570
|
-
const description = this.
|
|
571
|
-
const website = this.
|
|
544
|
+
const icon = this.icon;
|
|
545
|
+
const banner = this.banner;
|
|
546
|
+
const description = this.description;
|
|
547
|
+
const website = this.website;
|
|
572
548
|
const domainSeparator = this._buildDomainSeparator();
|
|
573
549
|
|
|
574
550
|
const nameLength = String.UTF8.byteLength(name);
|
|
@@ -628,7 +604,7 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
|
|
|
628
604
|
// Update total supply
|
|
629
605
|
this._totalSupply.value = SafeMath.add(this._totalSupply.value, u256.One);
|
|
630
606
|
|
|
631
|
-
this.
|
|
607
|
+
this.createMintedEvent(to, tokenId);
|
|
632
608
|
}
|
|
633
609
|
|
|
634
610
|
protected _burn(tokenId: u256): void {
|
|
@@ -667,12 +643,17 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
|
|
|
667
643
|
// Update total supply
|
|
668
644
|
this._totalSupply.value = SafeMath.sub(this._totalSupply.value, u256.One);
|
|
669
645
|
|
|
670
|
-
this.
|
|
646
|
+
this.createBurnedEvent(owner, tokenId);
|
|
671
647
|
}
|
|
672
648
|
|
|
673
649
|
protected _transfer(from: Address, to: Address, tokenId: u256): void {
|
|
674
|
-
|
|
675
|
-
|
|
650
|
+
if (from === Address.zero()) {
|
|
651
|
+
throw new Revert('Invalid sender');
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
if (to === Address.zero()) {
|
|
655
|
+
throw new Revert('Invalid receiver');
|
|
656
|
+
}
|
|
676
657
|
|
|
677
658
|
const owner = this._ownerOf(tokenId);
|
|
678
659
|
|
|
@@ -680,10 +661,6 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
|
|
|
680
661
|
throw new Revert('Transfer from incorrect owner');
|
|
681
662
|
}
|
|
682
663
|
|
|
683
|
-
if (to === Address.zero()) {
|
|
684
|
-
throw new Revert('Transfer to zero address');
|
|
685
|
-
}
|
|
686
|
-
|
|
687
664
|
// Check authorization
|
|
688
665
|
const sender = Blockchain.tx.sender;
|
|
689
666
|
if (sender !== from && !this._isApprovedForAll(from, sender)) {
|
|
@@ -712,7 +689,7 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
|
|
|
712
689
|
// Transfer ownership
|
|
713
690
|
this.ownerOfMap.set(tokenId, this._u256FromAddress(to));
|
|
714
691
|
|
|
715
|
-
this.
|
|
692
|
+
this.createTransferredEvent(from, to, tokenId);
|
|
716
693
|
}
|
|
717
694
|
|
|
718
695
|
protected _safeTransfer(from: Address, to: Address, tokenId: u256, data: Uint8Array): void {
|
|
@@ -1019,19 +996,28 @@ export abstract class OP721 extends ReentrancyGuard implements IOP721 {
|
|
|
1019
996
|
}
|
|
1020
997
|
|
|
1021
998
|
// Event creation helpers
|
|
1022
|
-
protected
|
|
1023
|
-
this.emitEvent(new
|
|
999
|
+
protected createTransferredEvent(from: Address, to: Address, tokenId: u256): void {
|
|
1000
|
+
this.emitEvent(new OP721TransferredEvent(Blockchain.tx.sender, from, to, tokenId));
|
|
1024
1001
|
}
|
|
1025
1002
|
|
|
1026
1003
|
protected createApprovedEvent(owner: Address, approved: Address, tokenId: u256): void {
|
|
1027
|
-
this.emitEvent(new
|
|
1004
|
+
this.emitEvent(new OP721ApprovedEvent(owner, approved, tokenId));
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
protected createMintedEvent(to: Address, tokenId: u256): void {
|
|
1008
|
+
this.emitEvent(new OP721MintedEvent(to, tokenId));
|
|
1028
1009
|
}
|
|
1029
1010
|
|
|
1011
|
+
protected createBurnedEvent(from: Address, tokenId: u256): void {
|
|
1012
|
+
this.emitEvent(new OP721BurnedEvent(from, tokenId));
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
|
|
1030
1016
|
protected createApprovedForAllEvent(
|
|
1031
1017
|
owner: Address,
|
|
1032
1018
|
operator: Address,
|
|
1033
1019
|
approved: boolean,
|
|
1034
1020
|
): void {
|
|
1035
|
-
this.emitEvent(new
|
|
1021
|
+
this.emitEvent(new OP721ApprovedForAllEvent(owner, operator, approved));
|
|
1036
1022
|
}
|
|
1037
1023
|
}
|
|
@@ -33,7 +33,7 @@ export class OP_NET implements IBTC {
|
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* Called when the contract's bytecode is updated via updateContractFromExisting.
|
|
36
|
-
* Override this method to perform migration logic when the contract is
|
|
36
|
+
* Override this method to perform migration logic when the contract is updated.
|
|
37
37
|
*
|
|
38
38
|
* @param calldata - The calldata passed to updateContractFromExisting
|
|
39
39
|
*
|
|
@@ -100,7 +100,7 @@ export class OP_NET implements IBTC {
|
|
|
100
100
|
* ```typescript
|
|
101
101
|
* public constructor() {
|
|
102
102
|
* super();
|
|
103
|
-
* this.registerPlugin(new
|
|
103
|
+
* this.registerPlugin(new UpdatablePlugin(144));
|
|
104
104
|
* }
|
|
105
105
|
* ```
|
|
106
106
|
*
|