@btc-vision/btc-runtime 1.0.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.
Files changed (41) hide show
  1. package/LICENSE.md +62 -0
  2. package/README.md +34 -0
  3. package/package.json +46 -0
  4. package/runtime/buffer/BytesReader.ts +193 -0
  5. package/runtime/buffer/BytesWriter.ts +322 -0
  6. package/runtime/contracts/OP_20.ts +377 -0
  7. package/runtime/contracts/OP_NET.ts +77 -0
  8. package/runtime/contracts/interfaces/IOP_20.ts +25 -0
  9. package/runtime/env/BTCEnvironment.ts +372 -0
  10. package/runtime/env/global.ts +18 -0
  11. package/runtime/env/index.ts +3 -0
  12. package/runtime/events/NetEvent.ts +27 -0
  13. package/runtime/events/predefined/ApproveEvent.ts +16 -0
  14. package/runtime/events/predefined/BurnEvent.ts +13 -0
  15. package/runtime/events/predefined/ClaimEvent.ts +13 -0
  16. package/runtime/events/predefined/MintEvent.ts +15 -0
  17. package/runtime/events/predefined/StakeEvent.ts +13 -0
  18. package/runtime/events/predefined/TransferEvent.ts +16 -0
  19. package/runtime/events/predefined/UnstakeEvent.ts +13 -0
  20. package/runtime/events/predefined/index.ts +7 -0
  21. package/runtime/exports/index.ts +57 -0
  22. package/runtime/generic/Map.ts +55 -0
  23. package/runtime/index.ts +45 -0
  24. package/runtime/interfaces/IBTC.ts +6 -0
  25. package/runtime/lang/Definitions.ts +1 -0
  26. package/runtime/math/abi.ts +37 -0
  27. package/runtime/math/bytes.ts +34 -0
  28. package/runtime/math/cyrb53.ts +46 -0
  29. package/runtime/math/rnd.ts +51 -0
  30. package/runtime/math/sha256.ts +270 -0
  31. package/runtime/memory/AddressMemoryMap.ts +64 -0
  32. package/runtime/memory/KeyMerger.ts +72 -0
  33. package/runtime/memory/MemorySlot.ts +1 -0
  34. package/runtime/memory/MemorySlotPointer.ts +3 -0
  35. package/runtime/memory/MultiAddressMemoryMap.ts +76 -0
  36. package/runtime/storage/StoredU256.ts +320 -0
  37. package/runtime/types/Address.ts +5 -0
  38. package/runtime/types/Revert.ts +5 -0
  39. package/runtime/types/SafeMath.ts +137 -0
  40. package/runtime/types/index.ts +8 -0
  41. package/runtime/universal/ABIRegistry.ts +72 -0
package/LICENSE.md ADDED
@@ -0,0 +1,62 @@
1
+ # Custom Software License Agreement
2
+
3
+ ## 1. Definitions
4
+
5
+ - **"Licensor"** refers to the owner(s) and creator(s) of the software. The owner of the github organization "
6
+ btc-vision", "BlobMaster41".
7
+ - **"User"** refers to any person or entity that accesses or uses the software.
8
+ - **"Software"** refers to the source code, binaries, and documentation, whether in electronic or printed format, made
9
+ available by Licensor.
10
+
11
+ ## 2. Grant of License
12
+
13
+ This License permits User to view the Software via the repository hosting the Software ("Hosting Service"). Except as
14
+ provided in this Section, no other use of the Software is permitted. The User may not modify, copy, reproduce,
15
+ republish, upload, post, transmit, or distribute the Software in any way.
16
+
17
+ ## 3. Restrictions
18
+
19
+ - **Modification and Distribution**: User is prohibited from modifying, merging, distributing, sublicensing, and/or
20
+ selling copies of the Software.
21
+ - **Commercial Use**: User is prohibited from using the Software for any commercial purposes.
22
+ - **Reverse Engineering**: User is prohibited from reverse engineering, decompiling, or disassembling the Software.
23
+
24
+ ## 4. Termination
25
+
26
+ This License is effective until terminated by the Licensor. It will terminate immediately without notice from the
27
+ Licensor if User fails to comply with any provision of this License. Upon termination, User must destroy all copies of
28
+ the Software.
29
+
30
+ ## 5. Copyright Notice
31
+
32
+ The Software is © 2024 by the Licensor. All rights reserved.
33
+
34
+ ## 6. Governing Law
35
+
36
+ This License shall be governed by and construed in accordance with the laws of [Toronto, Canada]. Any legal action or
37
+ proceeding arising under this License will be brought exclusively in the courts located in [Toronto], and the parties
38
+ hereby consent to personal jurisdiction and venue therein.
39
+
40
+ ## 7. Limitation of Liability
41
+
42
+ In no event will the Licensor be liable for any damages, including, without limitation, indirect, incidental, special,
43
+ consequential, or punitive damages arising out of the use of or inability to use the Software.
44
+
45
+ ## 8. Indemnification
46
+
47
+ User agrees to indemnify, defend, and hold harmless the Licensor and its affiliates, officers, agents, employees, and
48
+ partners from any claim or demand, including reasonable attorneys' fees, made by any third party due to or arising out
49
+ of User's use of the Software, User's violation of this License, or User's violation of any rights of another.
50
+
51
+ ## 9. Breach of License
52
+
53
+ Any breach of this License will result in immediate termination of User's rights under this License. Additionally, the
54
+ Licensor reserves the right to pursue any legal action against the User in the event of a breach of this License.
55
+
56
+ ## 10. Acknowledgment
57
+
58
+ User acknowledges that they have read this License, understand it, and agree to be bound by its terms and conditions.
59
+ User also agrees that this License is the complete and exclusive statement of the agreement between the Licensor and the
60
+ User and supersedes all proposals or prior agreements, oral or written, and any other communications between the
61
+ Licensor and the User relating to the subject matter of this License.
62
+
package/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # OPNet Smart Contract Runtime
2
+
3
+ ![Bitcoin](https://img.shields.io/badge/Bitcoin-000?style=for-the-badge&logo=bitcoin&logoColor=white)
4
+ ![AssemblyScript](https://img.shields.io/badge/assembly%20script-%23000000.svg?style=for-the-badge&logo=assemblyscript&logoColor=white)
5
+ ![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white)
6
+ ![NodeJS](https://img.shields.io/badge/Node%20js-339933?style=for-the-badge&logo=nodedotjs&logoColor=white)
7
+ ![WebAssembly](https://img.shields.io/badge/WebAssembly-654FF0?style=for-the-badge&logo=webassembly&logoColor=white)
8
+ ![NPM](https://img.shields.io/badge/npm-CB3837?style=for-the-badge&logo=npm&logoColor=white)
9
+
10
+ [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
11
+
12
+ ## Introduction
13
+
14
+ The OPNet Smart Contract Runtime is a WebAssembly runtime that is designed to help developers write smart contracts for the OPNet blockchain.
15
+ The runtime is written in AssemblyScript, a subset of TypeScript that compiles to WebAssembly.
16
+
17
+ ### Installation
18
+
19
+ 1. Clone the repository:
20
+ ```bash
21
+ git clone https://github.com/btc-vision/btc-runtime.git
22
+ ```
23
+ 2. Navigate to the repository directory:
24
+ ```bash
25
+ cd btc-runtime
26
+ ```
27
+ 3. Install the necessary dependencies:
28
+ ```bash
29
+ npm i
30
+ ```
31
+
32
+ ## License
33
+
34
+ View the license by clicking [here](https://github.com/btc-vision/wbtc/blob/main/LICENSE.md).
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@btc-vision/btc-runtime",
3
+ "version": "1.0.0",
4
+ "description": "Bitcoin Smart Contract Runtime",
5
+ "main": "btc/index.ts",
6
+ "types": "btc/index.ts",
7
+ "scripts": {
8
+ "test": "jest",
9
+ "build": "asc runtime/index.ts --target release --measure -Ospeed --noAssert --optimizeLevel 3 --shrinkLevel 2 --converge --disable mutable-globals,sign-extension,nontrapping-f2i,bulk-memory --runtime stub --memoryBase 0 --lowMemoryLimit --uncheckedBehavior never --initialMemory 16 --maximumMemory 16 --exportRuntime"
10
+ },
11
+ "keywords": [
12
+ "bitcoin",
13
+ "smart",
14
+ "contract",
15
+ "runtime",
16
+ "opnet",
17
+ "OP_NET"
18
+ ],
19
+ "homepage": "https://opnet.org",
20
+ "author": "BlobMaster41",
21
+ "license": "LICENSE.MD",
22
+ "devDependencies": {
23
+ "@types/node": "^20.11.30",
24
+ "assemblyscript": "^0.27.25",
25
+ "prettier": "^3.2.5"
26
+ },
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/BlobMaster41/btc-runtime.git"
30
+ },
31
+ "type": "module",
32
+ "files": [
33
+ "package.json",
34
+ "runtime",
35
+ "runtime/*.ts",
36
+ "runtime/**/*.ts",
37
+ "!**/*.js.map",
38
+ "!**/*.tsbuildinfo"
39
+ ],
40
+ "dependencies": {
41
+ "@assemblyscript/loader": "^0.27.25",
42
+ "as-bignum": "^0.3.0",
43
+ "gulplog": "^2.2.0",
44
+ "ts-node": "^10.9.2"
45
+ }
46
+ }
@@ -0,0 +1,193 @@
1
+ import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
2
+ import { Selector } from '../math/abi';
3
+ import { u256 } from 'as-bignum/assembly';
4
+ import { Revert } from '../types/Revert';
5
+ import { Map } from '../generic/Map';
6
+
7
+ @final
8
+ export class BytesReader {
9
+ private readonly buffer: DataView;
10
+
11
+ private currentOffset: i32 = 0;
12
+
13
+ constructor(bytes: Uint8Array) {
14
+ this.buffer = new DataView(bytes.buffer);
15
+ }
16
+
17
+ public readU8(): u8 {
18
+ this.verifyEnd(this.currentOffset + 1);
19
+
20
+ return this.buffer.getUint8(this.currentOffset++);
21
+ }
22
+
23
+ public readU16(): u16 {
24
+ this.verifyEnd(this.currentOffset + 2);
25
+
26
+ const value = this.buffer.getUint16(this.currentOffset, true);
27
+ this.currentOffset += 2;
28
+
29
+ return value;
30
+ }
31
+
32
+ public readU32(le: boolean = true): u32 {
33
+ this.verifyEnd(this.currentOffset + 4);
34
+
35
+ const value = this.buffer.getUint32(this.currentOffset, le);
36
+ this.currentOffset += 4;
37
+ return value;
38
+ }
39
+
40
+ public readU64(): u64 {
41
+ this.verifyEnd(this.currentOffset + 8);
42
+
43
+ const value = this.buffer.getUint64(this.currentOffset, true);
44
+ this.currentOffset += 8;
45
+
46
+ return value;
47
+ }
48
+
49
+ public readU256(): u256 {
50
+ const next32Bytes: u8[] = [];
51
+ for (let i = 0; i < 32; i++) {
52
+ next32Bytes[i] = this.readU8();
53
+ }
54
+
55
+ return u256.fromBytesBE(next32Bytes);
56
+ }
57
+
58
+ public readBytes(length: u32, zeroStop: boolean = false): Uint8Array {
59
+ this.verifyEnd(this.currentOffset + length);
60
+
61
+ let bytes: Uint8Array = new Uint8Array(length);
62
+ for (let i: u32 = 0; i < length; i++) {
63
+ const byte: u8 = this.readU8();
64
+ if (zeroStop && byte === 0) {
65
+ bytes = bytes.slice(0, i);
66
+
67
+ this.currentOffset += length - (i + 1);
68
+ break;
69
+ }
70
+
71
+ bytes[i] = byte;
72
+ }
73
+
74
+ return bytes;
75
+ }
76
+
77
+ public readMultiBytesAddressMap(): Map<Address, Uint8Array[]> {
78
+ const map: Map<Address, Uint8Array[]> = new Map<Address, Uint8Array[]>();
79
+ const size: u8 = this.readU8();
80
+
81
+ if (size > 8) throw new Revert('Too many contract called.');
82
+
83
+ for (let i: u8 = 0; i < size; i++) {
84
+ const address: Address = this.readAddress();
85
+ const responseSize: u8 = this.readU8();
86
+
87
+ if (responseSize > 10) throw new Revert('Too many calls.');
88
+
89
+ const calls: Uint8Array[] = [];
90
+ for (let j: u8 = 0; j < responseSize; j++) {
91
+ const response: Uint8Array = this.readBytesWithLength();
92
+ calls.push(response);
93
+ }
94
+
95
+ map.set(address, calls);
96
+ }
97
+
98
+ return map;
99
+ }
100
+
101
+ public readBytesWithLength(): Uint8Array {
102
+ const length = this.readU32();
103
+
104
+ return this.readBytes(length);
105
+ }
106
+
107
+ public readString(length: u16): string {
108
+ const bytes = this.readBytes(length, true);
109
+
110
+ return String.UTF8.decode(bytes.buffer);
111
+ }
112
+
113
+ public readTuple(): u256[] {
114
+ const length = this.readU32();
115
+ const result: u256[] = new Array<u256>(length);
116
+
117
+ for (let i = 0; i < length; i++) {
118
+ result[i] = this.readU256();
119
+ }
120
+
121
+ return result;
122
+ }
123
+
124
+ public readAddressValueTuple(): Map<Address, u256> {
125
+ const length: u16 = this.readU16();
126
+ const result = new Map<Address, u256>();
127
+
128
+ for (let i: u16 = 0; i < length; i++) {
129
+ const address = this.readAddress();
130
+ const value = this.readU256();
131
+
132
+ if (result.has(address)) throw new Revert('Duplicate address found in map');
133
+
134
+ result.set(address, value);
135
+ }
136
+
137
+ return result;
138
+ }
139
+
140
+ public readSelector(): Selector {
141
+ return this.readU32(false);
142
+ }
143
+
144
+ public readStringWithLength(): string {
145
+ const length = this.readU16();
146
+
147
+ return this.readString(length);
148
+ }
149
+
150
+ public readBoolean(): boolean {
151
+ return this.readU8() !== 0;
152
+ }
153
+
154
+ public readFloat(): f32 {
155
+ const value = this.buffer.getFloat32(this.currentOffset, true);
156
+ this.currentOffset += 4;
157
+
158
+ return value;
159
+ }
160
+
161
+ public readAddress(): Address {
162
+ return this.readString(ADDRESS_BYTE_LENGTH);
163
+ }
164
+
165
+ public getOffset(): i32 {
166
+ return this.currentOffset;
167
+ }
168
+
169
+ public setOffset(offset: i32): void {
170
+ this.currentOffset = offset;
171
+ }
172
+
173
+ public verifyEnd(size: i32): void {
174
+ if (this.currentOffset > this.buffer.byteLength) {
175
+ throw new Error(`Expected to read ${size} bytes but read ${this.currentOffset} bytes`);
176
+ }
177
+ }
178
+
179
+ private verifyChecksum(): void {
180
+ const writtenChecksum = this.readU32();
181
+
182
+ let checksum: u32 = 0;
183
+ for (let i = 0; i < this.buffer.byteLength; i++) {
184
+ checksum += this.buffer.getUint8(i);
185
+ }
186
+
187
+ checksum = checksum % 2 ** 32;
188
+
189
+ if (checksum !== writtenChecksum) {
190
+ throw new Error('Invalid checksum for buffer');
191
+ }
192
+ }
193
+ }
@@ -0,0 +1,322 @@
1
+ import { u256 } from 'as-bignum/assembly';
2
+ import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
3
+ import { Selector } from '../math/abi';
4
+ import { BytesReader } from './BytesReader';
5
+ import { SelectorsMap } from '../universal/ABIRegistry';
6
+ import { MemorySlotPointer } from '../memory/MemorySlotPointer';
7
+ import { MemorySlotData } from '../memory/MemorySlot';
8
+ import { cyrb53a } from '../math/cyrb53';
9
+ import { Revert } from '../types/Revert';
10
+ import { Map } from '../generic/Map';
11
+ import { BlockchainStorage, PointerStorage } from '../types';
12
+
13
+ export enum BufferDataType {
14
+ U8 = 0,
15
+ U16 = 1,
16
+ U32 = 2,
17
+ U64 = 3,
18
+ U256 = 4,
19
+ ADDRESS = 5,
20
+ STRING = 6,
21
+ BOOLEAN = 7,
22
+ }
23
+
24
+ @final
25
+ export class BytesWriter {
26
+ private currentOffset: u32 = 0;
27
+ private buffer: DataView;
28
+
29
+ private selectorDatatype: u8[] = [];
30
+
31
+ constructor(
32
+ length: i32 = 1,
33
+ private readonly trackDataTypes: boolean = false,
34
+ ) {
35
+ this.buffer = new DataView(new ArrayBuffer(length));
36
+ }
37
+
38
+ public bufferLength(): u32 {
39
+ return this.buffer.byteLength;
40
+ }
41
+
42
+ public writeU8(value: u8): void {
43
+ if (this.trackDataTypes) this.selectorDatatype.push(u8(BufferDataType.U8));
44
+
45
+ this.allocSafe(1);
46
+ this.buffer.setUint8(this.currentOffset++, value);
47
+ }
48
+
49
+ public writeU16(value: u16): void {
50
+ if (this.trackDataTypes) this.selectorDatatype.push(u8(BufferDataType.U16));
51
+
52
+ this.allocSafe(2);
53
+ this.buffer.setUint16(this.currentOffset, value, true);
54
+ this.currentOffset += 2;
55
+ }
56
+
57
+ public writeU32(value: u32, le: boolean = true): void {
58
+ if (this.trackDataTypes) this.selectorDatatype.push(u8(BufferDataType.U32));
59
+
60
+ this.allocSafe(4);
61
+ this.buffer.setUint32(this.currentOffset, value, le);
62
+ this.currentOffset += 4;
63
+ }
64
+
65
+ public writeU64(value: u64): void {
66
+ if (this.trackDataTypes) this.selectorDatatype.push(u8(BufferDataType.U64));
67
+
68
+ this.allocSafe(8);
69
+ this.buffer.setUint64(this.currentOffset, value || 0, true);
70
+ this.currentOffset += 8;
71
+ }
72
+
73
+ public writeStorage(storage: BlockchainStorage): void {
74
+ this.writeU32(storage.size);
75
+
76
+ const keys: Address[] = storage.keys();
77
+ const values: PointerStorage[] = storage.values();
78
+
79
+ for (let i: i32 = 0; i < keys.length; i++) {
80
+ const address: Address = keys[i];
81
+ const storage: PointerStorage = values[i];
82
+
83
+ this.writeAddress(address);
84
+
85
+ const subKeys: MemorySlotPointer[] = storage.keys();
86
+ const subValues: MemorySlotData<u256>[] = storage.values();
87
+
88
+ this.writeU32(subKeys.length);
89
+
90
+ for (let j: i32 = 0; j < subKeys.length; j++) {
91
+ const pointer: MemorySlotPointer = subKeys[j];
92
+ const value: MemorySlotData<u256> = subValues[j];
93
+
94
+ this.writeU256(pointer);
95
+ this.writeU256(value);
96
+ }
97
+ }
98
+ }
99
+
100
+ public writeSelector(value: Selector): void {
101
+ this.writeU32(value, false);
102
+ }
103
+
104
+ public writeBoolean(value: boolean): void {
105
+ if (this.trackDataTypes) this.selectorDatatype.push(u8(BufferDataType.BOOLEAN));
106
+
107
+ this.writeU8(value ? 1 : 0);
108
+ }
109
+
110
+ public writeU256(value: u256): void {
111
+ if (this.trackDataTypes) this.selectorDatatype.push(u8(BufferDataType.U256));
112
+ this.allocSafe(32);
113
+
114
+ const bytes = value.toUint8Array(true);
115
+ for (let i: i32 = 0; i < 32; i++) {
116
+ this.writeU8(bytes[i] || 0);
117
+ }
118
+ }
119
+
120
+ public writeTuple(value: u256[]): void {
121
+ this.allocSafe(4 + value.length * 32);
122
+ this.writeU32(u32(value.length));
123
+
124
+ for (let i = 0; i < value.length; i++) {
125
+ this.writeU256(value[i]);
126
+ }
127
+ }
128
+
129
+ public writeBytes(value: Uint8Array): void {
130
+ this.allocSafe(value.length);
131
+
132
+ for (let i = 0; i < value.length; i++) {
133
+ this.writeU8(value[i]);
134
+ }
135
+ }
136
+
137
+ public writeBytesWithLength(value: Uint8Array): void {
138
+ const length: u32 = u32(value.byteLength);
139
+ this.allocSafe(length + 4);
140
+ this.writeU32(length);
141
+
142
+ for (let i: u32 = 0; i < length; i++) {
143
+ this.writeU8(value[i]);
144
+ }
145
+ }
146
+
147
+ public writeString(value: string): void {
148
+ if (this.trackDataTypes) this.selectorDatatype.push(u8(BufferDataType.STRING));
149
+
150
+ for (let i: i32 = 0; i < value.length; i++) {
151
+ this.writeU8(u8(value.charCodeAt(i)));
152
+ }
153
+ }
154
+
155
+ public writeAddress(value: Address): void {
156
+ if (this.trackDataTypes) this.selectorDatatype.push(u8(BufferDataType.ADDRESS));
157
+
158
+ const bytes = this.fromAddress(value);
159
+ this.writeBytes(bytes);
160
+ }
161
+
162
+ public writeStringWithLength(value: string): void {
163
+ this.writeU16(u16(value.length));
164
+
165
+ this.writeString(value);
166
+ }
167
+
168
+ public writeViewSelectorMap(map: SelectorsMap): void {
169
+ this.writeU16(u16(map.size));
170
+
171
+ const keys = map.keys();
172
+ for (let i = 0; i < keys.length; i++) {
173
+ const key: u32 = keys[i] as u32;
174
+ const value = map.get(key);
175
+
176
+ this.writeBytes(value);
177
+ }
178
+ }
179
+
180
+ public writeAddressValueTupleMap(map: Map<Address, u256>): void {
181
+ if (map.size > 65535) throw new Revert('Map size is too large');
182
+ this.writeU16(u16(map.size));
183
+
184
+ const keys = map.keys();
185
+ for (let i = 0; i < keys.length; i++) {
186
+ const key: Address = keys[i];
187
+ const value: u256 = map.get(key) || u256.Zero;
188
+
189
+ this.writeAddress(key);
190
+ this.writeU256(value);
191
+ }
192
+ }
193
+
194
+ public writeLimitedAddressBytesMap(map: Map<Address, Uint8Array[]>): void {
195
+ if (map.size > 8) throw new Revert('Too many contract called.'); // no more than 8 different contracts.
196
+
197
+ this.writeU8(u8(map.size));
198
+
199
+ const keys: Address[] = map.keys();
200
+ for (let i: i32 = 0; i < keys.length; i++) {
201
+ const address: Address = keys[i];
202
+ const calls: Uint8Array[] = map.get(address) || [];
203
+
204
+ if (calls.length > 10) throw new Revert('Too many calls.'); // no more than 16 different calls.
205
+
206
+ this.writeAddress(address);
207
+ this.writeU8(u8(calls.length));
208
+
209
+ for (let j: i32 = 0; j < calls.length; j++) {
210
+ this.writeBytesWithLength(calls[j]);
211
+ }
212
+ }
213
+ }
214
+
215
+ public writeMethodSelectorsMap(map: Selector[]): void {
216
+ this.writeU16(u16(map.length));
217
+
218
+ for (let i = 0; i < map.length; i++) {
219
+ this.writeSelector(map[i]);
220
+ }
221
+ }
222
+
223
+ public getBuffer(clear: boolean = true): Uint8Array {
224
+ const buf = new Uint8Array(this.buffer.byteLength);
225
+ for (let i: u32 = 0; i < u32(this.buffer.byteLength); i++) {
226
+ buf[i] = this.buffer.getUint8(i);
227
+ }
228
+
229
+ if (clear) this.clear();
230
+
231
+ return buf;
232
+ }
233
+
234
+ public toBytesReader(): BytesReader {
235
+ return new BytesReader(this.getBuffer());
236
+ }
237
+
238
+ public getOffset(): u32 {
239
+ return this.currentOffset;
240
+ }
241
+
242
+ public setOffset(offset: u32): void {
243
+ this.currentOffset = offset;
244
+ }
245
+
246
+ public clear(): void {
247
+ this.currentOffset = 0;
248
+ this.buffer = this.getDefaultBuffer();
249
+ this.selectorDatatype = [];
250
+ }
251
+
252
+ public allocSafe(size: u32): void {
253
+ if (this.currentOffset + size > u32(this.buffer.byteLength)) {
254
+ const sizeDiff: u32 = size - (u32(this.buffer.byteLength) - this.currentOffset);
255
+
256
+ this.resize(sizeDiff);
257
+ }
258
+ }
259
+
260
+ public writeABISelector(name: string, selector: Selector): void {
261
+ this.writeStringWithLength(name);
262
+ this.writeSelector(selector);
263
+ }
264
+
265
+ public getSelectorDataType(): u64 {
266
+ let hash: u64 = 0;
267
+ if (this.selectorDatatype.length === 0) return hash;
268
+
269
+ return cyrb53a(this.selectorDatatype);
270
+ }
271
+
272
+ private getChecksum(): u32 {
273
+ let checksum: u32 = 0;
274
+ for (let i = 0; i < this.buffer.byteLength; i++) {
275
+ checksum += this.buffer.getUint8(i);
276
+ }
277
+
278
+ return checksum % 2 ** 32;
279
+ }
280
+
281
+ private writeMethodSelectorMap(value: Set<Selector>): void {
282
+ this.writeU16(u16(value.size));
283
+
284
+ const keys = value.values();
285
+ for (let i = 0; i < keys.length; i++) {
286
+ const key = keys[i];
287
+
288
+ this.writeSelector(key);
289
+ }
290
+ }
291
+
292
+ private fromAddress(value: Address): Uint8Array {
293
+ if (value.length > i32(ADDRESS_BYTE_LENGTH)) {
294
+ throw new Revert('Address is too long');
295
+ }
296
+
297
+ const bytes: Uint8Array = new Uint8Array(ADDRESS_BYTE_LENGTH);
298
+ for (let i: i32 = 0; i < value.length; i++) {
299
+ bytes[i] = value.charCodeAt(i);
300
+ }
301
+
302
+ for (let i: u8 = u8(value.length); i < ADDRESS_BYTE_LENGTH; i++) {
303
+ bytes[i] = 0;
304
+ }
305
+
306
+ return bytes;
307
+ }
308
+
309
+ private resize(size: u32): void {
310
+ const buf: Uint8Array = new Uint8Array(u32(this.buffer.byteLength) + size);
311
+
312
+ for (let i: i32 = 0; i < this.buffer.byteLength; i++) {
313
+ buf[i] = this.buffer.getUint8(i);
314
+ }
315
+
316
+ this.buffer = new DataView(buf.buffer);
317
+ }
318
+
319
+ private getDefaultBuffer(length: i32 = 1): DataView {
320
+ return new DataView(new ArrayBuffer(length));
321
+ }
322
+ }