@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
@@ -0,0 +1,45 @@
1
+ /** Environment */
2
+ export * from './env';
3
+
4
+ /** Contracts */
5
+ export * from './contracts/interfaces/IOP_20';
6
+ export * from './contracts/OP_20';
7
+ export * from './contracts/OP_NET';
8
+
9
+ /** Buffer */
10
+ export * from './buffer/BytesReader';
11
+ export * from './buffer/BytesWriter';
12
+
13
+ /** Events */
14
+ export * from './events/NetEvent';
15
+ export * from './events/predefined';
16
+
17
+ /** Types */
18
+ export * from './generic/Map';
19
+ export * from './interfaces/IBTC';
20
+
21
+ /** Definitions */
22
+ export * from './lang/Definitions';
23
+ export * from './types/Address';
24
+ export * from './types/Revert';
25
+ export * from './types/SafeMath';
26
+
27
+ /** Math */
28
+ export * from './math/abi';
29
+ export * from './math/bytes';
30
+ export * from './math/cyrb53';
31
+ export * from './math/sha256';
32
+ export * from './math/rnd';
33
+
34
+ /** Memory */
35
+ export * from './memory/AddressMemoryMap';
36
+ export * from './memory/MemorySlot';
37
+ export * from './memory/MemorySlotPointer';
38
+ export * from './memory/KeyMerger';
39
+ export * from './memory/MultiAddressMemoryMap';
40
+
41
+ /** Storage */
42
+ export * from './storage/StoredU256';
43
+
44
+ /** Universal */
45
+ export * from './universal/ABIRegistry';
@@ -0,0 +1,6 @@
1
+ import { Address } from '../types/Address';
2
+
3
+ export interface IBTC {
4
+ readonly owner: Address;
5
+ readonly address: Address;
6
+ }
@@ -0,0 +1 @@
1
+ export type Potential<T> = T | null;
@@ -0,0 +1,37 @@
1
+ // SO IN TYPESCRIPT, WE CAN NOT USE TWO METHOD WITH THE SAME NAME. SO NOT ADDING THE TYPE TO THE HASH IS A DESIGN CHOICE.
2
+ import { bytes32, bytes4 } from './bytes';
3
+ import { Sha256 } from './sha256';
4
+ import { MemorySlotPointer } from '../memory/MemorySlotPointer';
5
+ import { u256 } from 'as-bignum/assembly';
6
+
7
+ export type Selector = u32;
8
+
9
+ export function encodeSelector(name: string): Selector {
10
+ const typed = Uint8Array.wrap(String.UTF8.encode(name));
11
+ const hash = Sha256.hash(typed);
12
+
13
+ return bytes4(hash);
14
+ }
15
+
16
+ export function encodePointer(str: string): MemorySlotPointer {
17
+ const typed = Uint8Array.wrap(String.UTF8.encode(str));
18
+ const hash = Sha256.hash(typed);
19
+
20
+ return bytes32(hash);
21
+ }
22
+
23
+ export function encodePointerHash(pointer: u16, sub: u256): MemorySlotPointer {
24
+ const finalBuffer: Uint8Array = new Uint8Array(34);
25
+ const mergedKey: u8[] = [u8(pointer & u16(0xff)), u8((pointer >> u16(8)) & u16(0xff))];
26
+
27
+ for (let i: i32 = 0; i < mergedKey.length; i++) {
28
+ finalBuffer[i] = mergedKey[i];
29
+ }
30
+
31
+ const subKey = sub.toUint8Array();
32
+ for (let i: i32 = 0; i < subKey.length; i++) {
33
+ finalBuffer[mergedKey.length + i] = subKey[i];
34
+ }
35
+
36
+ return bytes32(Sha256.hash(finalBuffer));
37
+ }
@@ -0,0 +1,34 @@
1
+ import { u256 } from 'as-bignum/assembly';
2
+
3
+ export function bytes(number: u256[]): Uint8Array {
4
+ const result = new Uint8Array(32 * number.length);
5
+ for (let i: u8 = 0; i < 32; i++) {
6
+ const num: Uint8Array = number[31 - i].toUint8Array();
7
+ for (let j: u8 = 0; j < u8(number.length); j++) {
8
+ result[i + j * 32] = num[i];
9
+ }
10
+ }
11
+
12
+ return result;
13
+ }
14
+
15
+ export function bytes4(number: Uint8Array): u32 {
16
+ return (u32(number[0]) << 24) | (u32(number[1]) << 16) | (u32(number[2]) << 8) | u32(number[3]);
17
+ }
18
+
19
+ export function bytes8(number: Uint8Array): u64 {
20
+ return (
21
+ (u64(number[0]) << u64(56)) |
22
+ (u64(number[1]) << u64(48)) |
23
+ (u64(number[2]) << u64(40)) |
24
+ (u64(number[3]) << u64(32)) |
25
+ (u64(number[4]) << 24) |
26
+ (u64(number[5]) << 16) |
27
+ (u64(number[6]) << 8) |
28
+ u64(number[7])
29
+ );
30
+ }
31
+
32
+ export function bytes32(number: Uint8Array): u256 {
33
+ return u256.fromBytes(number);
34
+ }
@@ -0,0 +1,46 @@
1
+ export function cyrb53(str: string, seed: i32 = 0): i64 {
2
+ let h1: i32 = 0xdeadbeef ^ seed;
3
+ let h2: i32 = 0x41c6ce57 ^ seed;
4
+ for (let i: i32 = 0; i < str.length; i++) {
5
+ let ch: i32 = str.charCodeAt(i);
6
+ h1 = (h1 ^ ch) * 2654435761;
7
+ h2 = (h2 ^ ch) * 1597334677;
8
+ }
9
+
10
+ h1 = ((h1 ^ (h1 >>> 16)) * 2246822507) ^ ((h2 ^ (h2 >>> 13)) * 3266489909);
11
+ h2 = ((h2 ^ (h2 >>> 16)) * 2246822507) ^ ((h1 ^ (h1 >>> 13)) * 3266489909);
12
+
13
+ return 4294967296 * i64((2097151 & h2) >>> 0) + i64(h1 >>> 0);
14
+ }
15
+
16
+ export function imul64(a: u64, b: u64): u64 {
17
+ const aLow: u64 = a & 0xffffffff;
18
+ const aHigh: u64 = a >> 32;
19
+ const bLow: u64 = b & 0xffffffff;
20
+ const bHigh: u64 = b >> 32;
21
+
22
+ const low: u64 = aLow * bLow;
23
+ const middle1: u64 = (aHigh * bLow) << 32;
24
+ const middle2: u64 = (aLow * bHigh) << 32;
25
+ const high: u64 = (aHigh * bHigh) << 64;
26
+
27
+ return low + middle1 + middle2 + high;
28
+ }
29
+
30
+ export function cyrb53a(str: u8[], seed: i32 = 0): u64 {
31
+ let h1: u64 = u64(0xdeadbeef ^ seed);
32
+ let h2: u64 = u64(0x41c6ce57 ^ seed);
33
+
34
+ for (let i: i32 = 0; i < str.length; i++) {
35
+ let ch: u64 = u64(str[i]);
36
+ h1 = imul64(h1 ^ ch, 0x85ebca77);
37
+ h2 = imul64(h2 ^ ch, 0xc2b2ae3d);
38
+ }
39
+
40
+ h1 ^= imul64(h1 ^ (h2 >> 15), 0x735a2d97);
41
+ h2 ^= imul64(h2 ^ (h1 >> 15), 0xcaf649a9);
42
+ h1 ^= h2 >> 16;
43
+ h2 ^= h1 >> 16;
44
+
45
+ return (2097152 * (h2 & 0xffffffffffffffff) + (h1 >> 11)) & 0xffffffffffffffff;
46
+ }
@@ -0,0 +1,51 @@
1
+ let random_state0_64: u64;
2
+ let random_state1_64: u64;
3
+ let random_state0_32: u32;
4
+ let random_state1_32: u32;
5
+ let random_seeded = false;
6
+
7
+ function murmurHash3(h: u64): u64 {
8
+ // Force all bits of a hash block to avalanche
9
+ h ^= h >> 33; // see: https://github.com/aappleby/smhasher
10
+ h *= 0xff51afd7ed558ccd;
11
+ h ^= h >> 33;
12
+ h *= 0xc4ceb9fe1a85ec53;
13
+ h ^= h >> 33;
14
+ return h;
15
+ }
16
+
17
+ function splitMix32(h: u32): u32 {
18
+ h += 0x6d2b79f5;
19
+ h = (h ^ (h >> 15)) * (h | 1);
20
+ h ^= h + (h ^ (h >> 7)) * (h | 61);
21
+ return h ^ (h >> 14);
22
+ }
23
+
24
+ function seedRandom(value: i64): void {
25
+ // Instead zero seed use golden ratio:
26
+ // phi = (1 + sqrt(5)) / 2
27
+ // trunc(2^64 / phi) = 0x9e3779b97f4a7c15
28
+ if (value == 0) value = 0x9e3779b97f4a7c15;
29
+ random_state0_64 = murmurHash3(value);
30
+ random_state1_64 = murmurHash3(~random_state0_64);
31
+ random_state0_32 = splitMix32(<u32>value);
32
+ random_state1_32 = splitMix32(random_state0_32);
33
+ random_seeded = true;
34
+ }
35
+
36
+ /**
37
+ * Safe deterministic random number generator
38
+ * @param {u64} seed - The seed to use
39
+ */
40
+ export function randomU64(seed: i64): u64 {
41
+ if (!random_seeded) seedRandom(seed);
42
+ let s1 = random_state0_64;
43
+ let s0 = random_state1_64;
44
+ random_state0_64 = s0;
45
+ s1 ^= s1 << 23;
46
+ s1 ^= s1 >> 17;
47
+ s1 ^= s0;
48
+ s1 ^= s0 >> 26;
49
+ random_state1_64 = s1;
50
+ return s0;
51
+ }
@@ -0,0 +1,270 @@
1
+ type aisize = i32;
2
+
3
+ function setU8(t: Uint8Array, s: Uint8Array, o: isize = 0): void {
4
+ memory.copy(t.dataStart + o, s.dataStart, s.length);
5
+ }
6
+
7
+ function store64_be(x: Uint8Array, offset: isize, u: u64): void {
8
+ store<u64>(changetype<usize>(x.buffer) + offset, bswap(u));
9
+ }
10
+
11
+ function load32_be(x: Uint8Array, offset: isize): u32 {
12
+ return bswap(load<u32>(changetype<usize>(x.buffer) + offset));
13
+ }
14
+
15
+ function store32_be(x: Uint8Array, offset: isize, u: u32): void {
16
+ store<u32>(changetype<usize>(x.buffer) + offset, bswap(u));
17
+ }
18
+
19
+ class Internal {
20
+ static K: u32[] = [
21
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4,
22
+ 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe,
23
+ 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f,
24
+ 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
25
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
26
+ 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
27
+ 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116,
28
+ 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
29
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
30
+ 0xc67178f2,
31
+ ];
32
+ static iv: u8[] = [
33
+ 0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae, 0x85, 0x3c, 0x6e, 0xf3, 0x72, 0xa5, 0x4f, 0xf5,
34
+ 0x3a, 0x51, 0x0e, 0x52, 0x7f, 0x9b, 0x05, 0x68, 0x8c, 0x1f, 0x83, 0xd9, 0xab, 0x5b, 0xe0,
35
+ 0xcd, 0x19,
36
+ ];
37
+
38
+ @inline
39
+ static Sigma0(x: u32): u32 {
40
+ return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22);
41
+ }
42
+
43
+ @inline
44
+ static Sigma1(x: u32): u32 {
45
+ return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25);
46
+ }
47
+
48
+ @inline
49
+ static sigma0(x: u32): u32 {
50
+ return rotr(x, 7) ^ rotr(x, 18) ^ (x >> 3);
51
+ }
52
+
53
+ @inline
54
+ static sigma1(x: u32): u32 {
55
+ return rotr(x, 17) ^ rotr(x, 19) ^ (x >> 10);
56
+ }
57
+
58
+ @inline
59
+ static Ch(x: u32, y: u32, z: u32): u32 {
60
+ return z ^ (x & (y ^ z));
61
+ }
62
+
63
+ @inline
64
+ static Maj(x: u32, y: u32, z: u32): u32 {
65
+ return (x & (y ^ z)) ^ (y & z);
66
+ }
67
+
68
+ static expand(w: StaticArray<u32>): void {
69
+ for (let i = 0; i < 16; i++) {
70
+ unchecked(
71
+ (w[i] +=
72
+ w[(i + 9) & 15] +
73
+ Internal.sigma1(w[(i + 14) & 15]) +
74
+ Internal.sigma0(w[(i + 1) & 15])),
75
+ );
76
+ }
77
+ }
78
+
79
+ static handle(r: StaticArray<u32>, w: StaticArray<u32>, c: u32[]): void {
80
+ for (let i = 0; i < 16; i++) {
81
+ var x = r[7 & (7 - i)] + w[i] + c[i];
82
+ x += unchecked(Internal.Sigma1(r[7 & (4 - i)]));
83
+ x += unchecked(Internal.Ch(r[7 & (4 - i)], r[7 & (5 - i)], r[7 & (6 - i)]));
84
+ unchecked((r[7 & (3 - i)] += x));
85
+ x += unchecked(Internal.Sigma0(r[7 & (0 - i)]));
86
+ x += unchecked(Internal.Maj(r[7 & (0 - i)], r[7 & (1 - i)], r[7 & (2 - i)]));
87
+ unchecked((r[7 & (7 - i)] = x));
88
+ }
89
+ }
90
+
91
+ static _hashblocks(st: Uint8Array, m: Uint8Array, n_: isize): isize {
92
+ let z = new StaticArray<u32>(8),
93
+ r = new StaticArray<u32>(8),
94
+ w = new StaticArray<u32>(16);
95
+ for (let i = 0; i < 8; ++i) {
96
+ unchecked((z[i] = r[i] = load32_be(st, i << 2)));
97
+ }
98
+ let pos = 0,
99
+ n = n_;
100
+ while (n >= 64) {
101
+ for (let i = 0; i < 16; ++i) {
102
+ w[i] = load32_be(m, (i << 2) + pos);
103
+ }
104
+ Internal.handle(r, w, Internal.K.slice(0));
105
+ Internal.expand(w);
106
+ Internal.handle(r, w, Internal.K.slice(16));
107
+ Internal.expand(w);
108
+ Internal.handle(r, w, Internal.K.slice(32));
109
+ Internal.expand(w);
110
+ Internal.handle(r, w, Internal.K.slice(48));
111
+ for (let i = 0; i < 8; ++i) {
112
+ let x = unchecked(r[i] + z[i]);
113
+ unchecked((z[i] = x));
114
+ unchecked((r[i] = x));
115
+ }
116
+ pos += 64;
117
+ n -= 64;
118
+ }
119
+ for (let i = 0; i < 8; ++i) {
120
+ store32_be(st, i << 2, unchecked(z[i]));
121
+ }
122
+ return n;
123
+ }
124
+
125
+ static _hashInit(): Uint8Array {
126
+ let st = new Uint8Array(32 + 64);
127
+
128
+ for (let i = 0; i < 32; ++i) {
129
+ st[i] = Internal.iv[i];
130
+ }
131
+ return st;
132
+ }
133
+
134
+ static _hashUpdate(st: Uint8Array, m: Uint8Array, n: isize, r: isize): isize {
135
+ let obuffered = st.subarray(32);
136
+ let buffered = new Uint8Array(64);
137
+ setU8(buffered, obuffered.subarray(0, 64));
138
+
139
+ let still_available_in_buffer = <isize>64 - r;
140
+ let copiable_to_buffer = min(n, still_available_in_buffer);
141
+ setU8(buffered, m.subarray(0, <aisize>copiable_to_buffer), r);
142
+ r += copiable_to_buffer;
143
+ n -= copiable_to_buffer;
144
+ let pos: isize = 0;
145
+ if (r === 64) {
146
+ Internal._hashblocks(st, buffered, 64);
147
+ r = 0;
148
+ pos = copiable_to_buffer;
149
+ }
150
+ if (n == 0) {
151
+ setU8(obuffered, buffered);
152
+ return r;
153
+ }
154
+ let left = m.subarray(<aisize>pos);
155
+ r = Internal._hashblocks(st, left, left.length);
156
+ if (r > 0) {
157
+ setU8(obuffered, left.subarray(left.length - <aisize>r));
158
+ }
159
+ return r;
160
+ }
161
+
162
+ static _hashFinal(st: Uint8Array, out: Uint8Array, t: isize, r: isize): void {
163
+ let buffered = st.subarray(32);
164
+ let padded = new Uint8Array(128);
165
+ setU8(padded, buffered.subarray(0, <aisize>r));
166
+ padded[<aisize>r] = 0x80;
167
+ if (r < 56) {
168
+ store64_be(padded, 64 - 8, t << 3);
169
+ Internal._hashblocks(st, padded, 64);
170
+ } else {
171
+ store64_be(padded, 128 - 8, t << 3);
172
+ Internal._hashblocks(st, padded, 128);
173
+ }
174
+ for (let i = 0; i < 32; ++i) {
175
+ out[i] = st[i];
176
+ }
177
+ }
178
+
179
+ static _hash(out: Uint8Array, m: Uint8Array, n: isize): void {
180
+ let st = Internal._hashInit();
181
+ let r = Internal._hashUpdate(st, m, n, 0);
182
+
183
+ Internal._hashFinal(st, out, n, r);
184
+ }
185
+
186
+ static _hmac(m: Uint8Array, k: Uint8Array): Uint8Array {
187
+ if (k.length > 64) {
188
+ k = Sha256.hash(k);
189
+ }
190
+ let b = new Uint8Array(64);
191
+ setU8(b, k);
192
+ for (let i = 0; i < b.length; ++i) {
193
+ b[i] ^= 0x36;
194
+ }
195
+ let out = new Uint8Array(32);
196
+ let st = Internal._hashInit();
197
+ let r = Internal._hashUpdate(st, b, b.length, 0);
198
+ r = Internal._hashUpdate(st, m, m.length, r);
199
+ Internal._hashFinal(st, out, b.length + m.length, r);
200
+ for (let i = 0; i < b.length; ++i) {
201
+ b[i] ^= 0x6a;
202
+ }
203
+ st = Internal._hashInit();
204
+ r = Internal._hashUpdate(st, b, b.length, 0);
205
+ r = Internal._hashUpdate(st, out, out.length, r);
206
+ Internal._hashFinal(st, out, b.length + out.length, r);
207
+ return out;
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Hash function output size, in bytes
213
+ */
214
+ export const SHA256_HASH_BYTES: isize = 32;
215
+
216
+ export class Sha256 {
217
+ r: u64 = 0;
218
+ t: u64 = 0;
219
+ st: Uint8Array;
220
+
221
+ /**
222
+ * Initialize a multipart hash computation
223
+ * @returns A hash function state
224
+ */
225
+ constructor() {
226
+ let st = Internal._hashInit();
227
+ this.st = st;
228
+ }
229
+
230
+ /**
231
+ * Compute a hash for a single-part message
232
+ * @param m Message
233
+ * @returns Hash
234
+ */
235
+ static hash(m: Uint8Array): Uint8Array {
236
+ let h = new Uint8Array(<aisize>SHA256_HASH_BYTES);
237
+ Internal._hash(h, m, m.length);
238
+ return h;
239
+ }
240
+
241
+ /**
242
+ * HMAC-SHA-256
243
+ * @param m Message
244
+ * @param k Key
245
+ * @returns `HMAC-SHA-256(m, k)`
246
+ */
247
+ static hmac(m: Uint8Array, k: Uint8Array): Uint8Array {
248
+ return Internal._hmac(m, k);
249
+ }
250
+
251
+ /**
252
+ * Absorb data to be hashed
253
+ * @param m (partial) message
254
+ */
255
+ update(m: Uint8Array): void {
256
+ let n = m.length;
257
+ this.t += n;
258
+ this.r = Internal._hashUpdate(this.st, m, n, this.r as isize);
259
+ }
260
+
261
+ /**
262
+ * Finalize a hash computation
263
+ * @returns Hash
264
+ */
265
+ final(): Uint8Array {
266
+ let h = new Uint8Array(<aisize>SHA256_HASH_BYTES);
267
+ Internal._hashFinal(this.st, h, this.t as isize, this.r as isize);
268
+ return h;
269
+ }
270
+ }
@@ -0,0 +1,64 @@
1
+ import { MemorySlotPointer } from './MemorySlotPointer';
2
+ import { Blockchain } from '../env';
3
+ import { Address } from '../types/Address';
4
+ import { encodePointer } from '../math/abi';
5
+ import { MemorySlotData } from './MemorySlot';
6
+ import { u256 } from 'as-bignum/assembly';
7
+
8
+ @final
9
+ export class AddressMemoryMap<K extends string, V extends MemorySlotData<u256>> {
10
+ public pointer: u16;
11
+
12
+ private readonly memoryAllocatorAddress: Address;
13
+
14
+ constructor(
15
+ pointer: u16,
16
+ self: Address,
17
+ private readonly defaultValue: V,
18
+ ) {
19
+ this.pointer = pointer;
20
+ this.memoryAllocatorAddress = self;
21
+ }
22
+
23
+ public set(key: K, value: V): this {
24
+ const keyHash: MemorySlotPointer = encodePointer(key);
25
+ Blockchain.setStorageAt(
26
+ this.memoryAllocatorAddress,
27
+ this.pointer,
28
+ keyHash,
29
+ value,
30
+ this.defaultValue,
31
+ );
32
+
33
+ return this;
34
+ }
35
+
36
+ public get(key: K): MemorySlotData<u256> {
37
+ return Blockchain.getStorageAt(
38
+ this.memoryAllocatorAddress,
39
+ this.pointer,
40
+ encodePointer(key),
41
+ this.defaultValue,
42
+ );
43
+ }
44
+
45
+ public has(key: K): bool {
46
+ return Blockchain.hasStorageAt(
47
+ this.memoryAllocatorAddress,
48
+ this.pointer,
49
+ encodePointer(key),
50
+ );
51
+ }
52
+
53
+ @unsafe
54
+ public delete(key: K): bool {
55
+ this.set(key, this.defaultValue);
56
+
57
+ return true;
58
+ }
59
+
60
+ @unsafe
61
+ public clear(): void {
62
+ throw new Error('Method not implemented.');
63
+ }
64
+ }
@@ -0,0 +1,72 @@
1
+ import { MemorySlotData } from './MemorySlot';
2
+ import { u256 } from 'as-bignum/assembly';
3
+ import { Blockchain } from '../env';
4
+ import { Address } from '../types/Address';
5
+ import { MemorySlotPointer } from './MemorySlotPointer';
6
+ import { encodePointer } from '../math/abi';
7
+
8
+ @final
9
+ export class KeyMerger<K extends string, K2 extends string, V extends MemorySlotData<u256>> {
10
+ public parentKey: K;
11
+
12
+ public pointer: u16;
13
+ private readonly memoryAllocatorAddress: Address;
14
+
15
+ constructor(
16
+ parent: K,
17
+ pointer: u16,
18
+ self: Address,
19
+ private readonly defaultValue: V,
20
+ ) {
21
+ this.pointer = pointer;
22
+ this.memoryAllocatorAddress = self;
23
+
24
+ this.parentKey = parent;
25
+ }
26
+
27
+ public set(key2: K2, value: V): this {
28
+ const mergedKey: string = `${this.parentKey}${key2}`;
29
+ const keyHash: MemorySlotPointer = encodePointer(mergedKey);
30
+
31
+ Blockchain.setStorageAt(
32
+ this.memoryAllocatorAddress,
33
+ this.pointer,
34
+ keyHash,
35
+ value,
36
+ this.defaultValue,
37
+ );
38
+
39
+ return this;
40
+ }
41
+
42
+ public get(key: K): MemorySlotData<u256> {
43
+ const mergedKey: string = `${this.parentKey}${key}`;
44
+
45
+ return Blockchain.getStorageAt(
46
+ this.memoryAllocatorAddress,
47
+ this.pointer,
48
+ encodePointer(mergedKey),
49
+ this.defaultValue,
50
+ );
51
+ }
52
+
53
+ public has(key: K): bool {
54
+ const mergedKey: string = `${this.parentKey}${key}`;
55
+
56
+ return Blockchain.hasStorageAt(
57
+ this.memoryAllocatorAddress,
58
+ this.pointer,
59
+ encodePointer(mergedKey),
60
+ );
61
+ }
62
+
63
+ @unsafe
64
+ public delete(_key: K): bool {
65
+ throw new Error('Method not implemented.');
66
+ }
67
+
68
+ @unsafe
69
+ public clear(): void {
70
+ throw new Error('Clear method not implemented.');
71
+ }
72
+ }
@@ -0,0 +1 @@
1
+ export type MemorySlotData<T> = T;
@@ -0,0 +1,3 @@
1
+ import { u256 } from 'as-bignum/assembly';
2
+
3
+ export type MemorySlotPointer = u256;