@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.
- package/LICENSE.md +62 -0
- package/README.md +34 -0
- package/package.json +46 -0
- package/runtime/buffer/BytesReader.ts +193 -0
- package/runtime/buffer/BytesWriter.ts +322 -0
- package/runtime/contracts/OP_20.ts +377 -0
- package/runtime/contracts/OP_NET.ts +77 -0
- package/runtime/contracts/interfaces/IOP_20.ts +25 -0
- package/runtime/env/BTCEnvironment.ts +372 -0
- package/runtime/env/global.ts +18 -0
- package/runtime/env/index.ts +3 -0
- package/runtime/events/NetEvent.ts +27 -0
- package/runtime/events/predefined/ApproveEvent.ts +16 -0
- package/runtime/events/predefined/BurnEvent.ts +13 -0
- package/runtime/events/predefined/ClaimEvent.ts +13 -0
- package/runtime/events/predefined/MintEvent.ts +15 -0
- package/runtime/events/predefined/StakeEvent.ts +13 -0
- package/runtime/events/predefined/TransferEvent.ts +16 -0
- package/runtime/events/predefined/UnstakeEvent.ts +13 -0
- package/runtime/events/predefined/index.ts +7 -0
- package/runtime/exports/index.ts +57 -0
- package/runtime/generic/Map.ts +55 -0
- package/runtime/index.ts +45 -0
- package/runtime/interfaces/IBTC.ts +6 -0
- package/runtime/lang/Definitions.ts +1 -0
- package/runtime/math/abi.ts +37 -0
- package/runtime/math/bytes.ts +34 -0
- package/runtime/math/cyrb53.ts +46 -0
- package/runtime/math/rnd.ts +51 -0
- package/runtime/math/sha256.ts +270 -0
- package/runtime/memory/AddressMemoryMap.ts +64 -0
- package/runtime/memory/KeyMerger.ts +72 -0
- package/runtime/memory/MemorySlot.ts +1 -0
- package/runtime/memory/MemorySlotPointer.ts +3 -0
- package/runtime/memory/MultiAddressMemoryMap.ts +76 -0
- package/runtime/storage/StoredU256.ts +320 -0
- package/runtime/types/Address.ts +5 -0
- package/runtime/types/Revert.ts +5 -0
- package/runtime/types/SafeMath.ts +137 -0
- package/runtime/types/index.ts +8 -0
- package/runtime/universal/ABIRegistry.ts +72 -0
package/runtime/index.ts
ADDED
|
@@ -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 @@
|
|
|
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;
|