@btc-vision/btc-runtime 1.2.5 → 1.2.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@btc-vision/btc-runtime",
3
- "version": "1.2.5",
3
+ "version": "1.2.6",
4
4
  "description": "Bitcoin Smart Contract Runtime",
5
5
  "main": "btc/index.ts",
6
6
  "scripts": {
@@ -3,7 +3,6 @@ import { MemorySlotPointer } from '../memory/MemorySlotPointer';
3
3
  import { MemorySlotData } from '../memory/MemorySlot';
4
4
  import { u256 } from 'as-bignum/assembly';
5
5
  import { BytesReader } from '../buffer/BytesReader';
6
- import { encodePointerHash } from '../math/abi';
7
6
  import { BytesWriter } from '../buffer/BytesWriter';
8
7
  import { NetEvent } from '../events/NetEvent';
9
8
  import { Potential } from '../lang/Definitions';
@@ -210,11 +209,9 @@ export class BlockchainEnvironment {
210
209
  }
211
210
 
212
211
  public getStorageAt(
213
- pointer: u16,
214
- subPointer: MemorySlotPointer,
212
+ pointerHash: MemorySlotPointer,
215
213
  defaultValue: MemorySlotData<u256>,
216
214
  ): MemorySlotData<u256> {
217
- const pointerHash: MemorySlotPointer = encodePointerHash(pointer, subPointer);
218
215
  this.ensureStorageAtPointer(pointerHash, defaultValue);
219
216
 
220
217
  if (this.storage.has(pointerHash)) {
@@ -224,20 +221,14 @@ export class BlockchainEnvironment {
224
221
  return defaultValue;
225
222
  }
226
223
 
227
- public hasStorageAt(pointer: u16, subPointer: MemorySlotPointer): bool {
224
+ public hasStorageAt(pointerHash: MemorySlotPointer): bool {
228
225
  // We mark zero as the default value for the storage, if something is 0, the storage slot get deleted or is non-existent
229
- const val: u256 = this.getStorageAt(pointer, subPointer, u256.Zero);
226
+ const val: u256 = this.getStorageAt(pointerHash, u256.Zero);
230
227
 
231
228
  return u256.ne(val, u256.Zero);
232
229
  }
233
230
 
234
- public setStorageAt(
235
- pointer: u16,
236
- keyPointer: MemorySlotPointer,
237
- value: MemorySlotData<u256>,
238
- ): void {
239
- const pointerHash: u256 = encodePointerHash(pointer, keyPointer);
240
-
231
+ public setStorageAt(pointerHash: MemorySlotPointer, value: MemorySlotData<u256>): void {
241
232
  this._internalSetStorageAt(pointerHash, value);
242
233
  }
243
234
 
@@ -1,7 +1,6 @@
1
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
2
  import { bytes32, bytes4 } from './bytes';
3
3
  import { MemorySlotPointer } from '../memory/MemorySlotPointer';
4
- import { u256 } from 'as-bignum/assembly';
5
4
  import { Sha256 } from './sha256';
6
5
 
7
6
  export type Selector = u32;
@@ -13,25 +12,8 @@ export function encodeSelector(name: string): Selector {
13
12
  return bytes4(hash);
14
13
  }
15
14
 
16
- export function encodePointer(str: string): MemorySlotPointer {
17
- const typed = Uint8Array.wrap(String.UTF8.encode(str));
15
+ export function encodePointer(typed: Uint8Array): MemorySlotPointer {
18
16
  const hash = Sha256.hash(typed);
19
17
 
20
18
  return bytes32(hash);
21
19
  }
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
- }
@@ -3,6 +3,7 @@ import { Blockchain } from '../env';
3
3
  import { encodePointer } from '../math/abi';
4
4
  import { MemorySlotData } from './MemorySlot';
5
5
  import { u256 } from 'as-bignum/assembly';
6
+ import { BytesWriter } from '../buffer/BytesWriter';
6
7
 
7
8
  @final
8
9
  export class AddressMemoryMap<K extends string, V extends MemorySlotData<u256>> {
@@ -16,18 +17,22 @@ export class AddressMemoryMap<K extends string, V extends MemorySlotData<u256>>
16
17
  }
17
18
 
18
19
  public set(key: K, value: V): this {
19
- const keyHash: MemorySlotPointer = encodePointer(key);
20
- Blockchain.setStorageAt(this.pointer, keyHash, value);
20
+ const keyHash: MemorySlotPointer = this.encodePointer(key);
21
+ Blockchain.setStorageAt(keyHash, value);
21
22
 
22
23
  return this;
23
24
  }
24
25
 
25
26
  public get(key: K): MemorySlotData<u256> {
26
- return Blockchain.getStorageAt(this.pointer, encodePointer(key), this.defaultValue);
27
+ const keyHash: MemorySlotPointer = this.encodePointer(key);
28
+
29
+ return Blockchain.getStorageAt(keyHash, this.defaultValue);
27
30
  }
28
31
 
29
32
  public has(key: K): bool {
30
- return Blockchain.hasStorageAt(this.pointer, encodePointer(key));
33
+ const keyHash: MemorySlotPointer = this.encodePointer(key);
34
+
35
+ return Blockchain.hasStorageAt(keyHash);
31
36
  }
32
37
 
33
38
  @unsafe
@@ -41,4 +46,12 @@ export class AddressMemoryMap<K extends string, V extends MemorySlotData<u256>>
41
46
  public clear(): void {
42
47
  throw new Error('Method not implemented.');
43
48
  }
49
+
50
+ private encodePointer(key: K): MemorySlotPointer {
51
+ const writer = new BytesWriter(key.length + 2);
52
+ writer.writeU16(this.pointer);
53
+ writer.writeString(key);
54
+
55
+ return encodePointer(writer.getBuffer());
56
+ }
44
57
  }
@@ -3,6 +3,7 @@ import { u256 } from 'as-bignum/assembly';
3
3
  import { Blockchain } from '../env';
4
4
  import { MemorySlotPointer } from './MemorySlotPointer';
5
5
  import { encodePointer } from '../math/abi';
6
+ import { BytesWriter } from '../buffer/BytesWriter';
6
7
 
7
8
  @final
8
9
  export class KeyMerger<K extends string, K2 extends string, V extends MemorySlotData<u256>> {
@@ -22,9 +23,9 @@ export class KeyMerger<K extends string, K2 extends string, V extends MemorySlot
22
23
 
23
24
  public set(key2: K2, value: V): this {
24
25
  const mergedKey: string = `${this.parentKey}${key2}`;
25
- const keyHash: MemorySlotPointer = encodePointer(mergedKey);
26
+ const keyHash: MemorySlotPointer = this.encodePointer(mergedKey);
26
27
 
27
- Blockchain.setStorageAt(this.pointer, keyHash, value);
28
+ Blockchain.setStorageAt(keyHash, value);
28
29
 
29
30
  return this;
30
31
  }
@@ -32,13 +33,13 @@ export class KeyMerger<K extends string, K2 extends string, V extends MemorySlot
32
33
  public get(key: K): MemorySlotData<u256> {
33
34
  const mergedKey: string = `${this.parentKey}${key}`;
34
35
 
35
- return Blockchain.getStorageAt(this.pointer, encodePointer(mergedKey), this.defaultValue);
36
+ return Blockchain.getStorageAt(this.encodePointer(mergedKey), this.defaultValue);
36
37
  }
37
38
 
38
39
  public has(key: K): bool {
39
40
  const mergedKey: string = `${this.parentKey}${key}`;
40
41
 
41
- return Blockchain.hasStorageAt(this.pointer, encodePointer(mergedKey));
42
+ return Blockchain.hasStorageAt(this.encodePointer(mergedKey));
42
43
  }
43
44
 
44
45
  @unsafe
@@ -50,4 +51,12 @@ export class KeyMerger<K extends string, K2 extends string, V extends MemorySlot
50
51
  public clear(): void {
51
52
  throw new Error('Clear method not implemented.');
52
53
  }
54
+
55
+ private encodePointer(key: string): MemorySlotPointer {
56
+ const writer = new BytesWriter(key.length + 2);
57
+ writer.writeU16(this.pointer);
58
+ writer.writeString(key);
59
+
60
+ return encodePointer(writer.getBuffer());
61
+ }
53
62
  }
@@ -4,26 +4,29 @@ import { MemorySlotPointer } from '../memory/MemorySlotPointer';
4
4
  import { BytesWriter } from '../buffer/BytesWriter';
5
5
  import { BytesReader } from '../buffer/BytesReader';
6
6
  import { Revert } from '../types/Revert';
7
+ import { encodePointer } from '../math/abi';
7
8
 
8
9
  export abstract class Serializable {
9
10
  protected pointer: u16;
10
- protected subPointer:MemorySlotPointer;
11
+ protected subPointer: MemorySlotPointer;
11
12
 
12
- protected constructor(pointer: u16,
13
- subPointer:MemorySlotPointer) {
13
+ protected constructor(pointer: u16, subPointer: MemorySlotPointer) {
14
14
  this.pointer = pointer;
15
15
  this.subPointer = subPointer;
16
16
  }
17
17
 
18
18
  public abstract get chunkCount(): i32;
19
+
19
20
  public abstract writeToBuffer(): BytesWriter;
21
+
20
22
  public abstract readFromBuffer(reader: BytesReader): void;
21
23
 
22
- public load() :void {
24
+ public load(): void {
23
25
  const chunks: u256[] = [];
24
26
 
25
- for(let index:i32 = 0; index < this.chunkCount; index++){
26
- const chunk: u256 = Blockchain.getStorageAt(this.pointer, u256.add(this.subPointer, u256.fromU32(index)), u256.Zero);
27
+ for (let index: i32 = 0; index < this.chunkCount; index++) {
28
+ const pointer = this.getPointer(u256.add(this.subPointer, u256.fromU32(index)));
29
+ const chunk: u256 = Blockchain.getStorageAt(pointer, u256.Zero);
27
30
  chunks.push(chunk);
28
31
  }
29
32
 
@@ -41,8 +44,7 @@ export abstract class Serializable {
41
44
 
42
45
  for (let index: i32 = 0; index < chunks.length; index++) {
43
46
  Blockchain.setStorageAt(
44
- this.pointer,
45
- u256.add(this.subPointer, u256.fromU32(index)),
47
+ this.getPointer(u256.add(this.subPointer, u256.fromU32(index))),
46
48
  chunks[index],
47
49
  );
48
50
  }
@@ -60,7 +62,7 @@ export abstract class Serializable {
60
62
  }
61
63
 
62
64
  protected chunksToBytes(chunks: u256[]): BytesReader {
63
- if(this.chunkCount >= 67108863) {
65
+ if (this.chunkCount >= 67108863) {
64
66
  throw new Revert('Too many chunks received');
65
67
  }
66
68
 
@@ -76,4 +78,12 @@ export abstract class Serializable {
76
78
 
77
79
  return new BytesReader(buffer);
78
80
  }
81
+
82
+ private getPointer(subPointer: u256): u256 {
83
+ const writer = new BytesWriter(34);
84
+ writer.writeU16(this.pointer);
85
+ writer.writeU256(subPointer);
86
+
87
+ return encodePointer(writer.getBuffer());
88
+ }
79
89
  }
@@ -3,10 +3,14 @@ import { Blockchain } from '../env';
3
3
 
4
4
  @final
5
5
  export class StoredBoolean {
6
+ private readonly u256Pointer: u256;
7
+
6
8
  constructor(
7
9
  public pointer: u16,
8
10
  private defaultValue: bool,
9
- ) {}
11
+ ) {
12
+ this.u256Pointer = u256.from(this.pointer);
13
+ }
10
14
 
11
15
  private _value: u256 = u256.Zero;
12
16
 
@@ -21,14 +25,14 @@ export class StoredBoolean {
21
25
  public set value(value: bool) {
22
26
  this._value = value ? u256.One : u256.Zero;
23
27
 
24
- Blockchain.setStorageAt(this.pointer, u256.Zero, this._value);
28
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
25
29
  }
26
30
 
27
31
  @inline
28
32
  public set(value: u256): this {
29
33
  this._value = value;
30
34
 
31
- Blockchain.setStorageAt(this.pointer, u256.Zero, this._value);
35
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
32
36
 
33
37
  return this;
34
38
  }
@@ -40,8 +44,7 @@ export class StoredBoolean {
40
44
 
41
45
  private ensureValue(): void {
42
46
  this._value = Blockchain.getStorageAt(
43
- this.pointer,
44
- u256.Zero,
47
+ this.u256Pointer,
45
48
  this.defaultValue ? u256.One : u256.Zero,
46
49
  );
47
50
  }
@@ -1,6 +1,8 @@
1
1
  import { u256 } from 'as-bignum/assembly';
2
2
  import { Blockchain } from '../env';
3
3
  import { SafeMath } from '../types/SafeMath';
4
+ import { encodePointer } from '../math/abi';
5
+ import { BytesWriter } from '../buffer/BytesWriter';
4
6
 
5
7
  @final
6
8
  export class StoredString {
@@ -30,8 +32,12 @@ export class StoredString {
30
32
  return a < b ? a : b;
31
33
  }
32
34
 
33
- private max(a: u32, b: u32): u32 {
34
- return a > b ? a : b;
35
+ private getPointer(key: u256): u256 {
36
+ const buf = new BytesWriter(34);
37
+ buf.writeU16(this.pointer);
38
+ buf.writeU256(key);
39
+
40
+ return encodePointer(buf.getBuffer());
35
41
  }
36
42
 
37
43
  private save(): void {
@@ -55,7 +61,7 @@ export class StoredString {
55
61
  // Save the initial chunk (first 28 bytes) in the header
56
62
  let bytesToWrite: u32 = this.min(remainingLength, 28);
57
63
  header = this.saveChunk(header, this._value, offset, bytesToWrite, 4);
58
- Blockchain.setStorageAt(this.pointer, currentPointer, header);
64
+ Blockchain.setStorageAt(this.getPointer(currentPointer), header);
59
65
 
60
66
  remainingLength -= bytesToWrite;
61
67
  offset += bytesToWrite;
@@ -71,7 +77,7 @@ export class StoredString {
71
77
  0,
72
78
  );
73
79
  currentPointer = u256.add(currentPointer, u256.One);
74
- Blockchain.setStorageAt(this.pointer, currentPointer, storageValue);
80
+ Blockchain.setStorageAt(this.getPointer(currentPointer), storageValue);
75
81
 
76
82
  remainingLength -= bytesToWrite;
77
83
  offset += bytesToWrite;
@@ -95,7 +101,7 @@ export class StoredString {
95
101
  }
96
102
 
97
103
  private load(): void {
98
- const header: u256 = Blockchain.getStorageAt(this.pointer, u256.Zero, u256.Zero);
104
+ const header: u256 = Blockchain.getStorageAt(this.getPointer(u256.Zero), u256.Zero);
99
105
  if (u256.eq(header, u256.Zero)) {
100
106
  if (this.defaultValue) {
101
107
  this.value = this.defaultValue;
@@ -120,7 +126,7 @@ export class StoredString {
120
126
  while (remainingLength > 0) {
121
127
  // Move to the next storage slot
122
128
  currentPointer = u256.add(currentPointer, u256.One);
123
- currentStorage = Blockchain.getStorageAt(this.pointer, currentPointer, u256.Zero);
129
+ currentStorage = Blockchain.getStorageAt(this.getPointer(currentPointer), u256.Zero);
124
130
 
125
131
  // Extract the relevant portion of the string from the current storage slot
126
132
  const bytesToRead: u32 = this.min(remainingLength, 32);
@@ -2,14 +2,24 @@ import { u256 } from 'as-bignum/assembly';
2
2
  import { SafeMath } from '../types/SafeMath';
3
3
  import { MemorySlotPointer } from '../memory/MemorySlotPointer';
4
4
  import { Blockchain } from '../env';
5
+ import { encodePointer } from '../math/abi';
6
+ import { BytesWriter } from '../buffer/BytesWriter';
5
7
 
6
8
  @final
7
9
  export class StoredU256 {
10
+ private readonly u256Pointer: u256;
11
+
8
12
  constructor(
9
13
  public pointer: u16,
10
14
  public subPointer: MemorySlotPointer,
11
15
  private defaultValue: u256,
12
- ) {}
16
+ ) {
17
+ const writer = new BytesWriter(34);
18
+ writer.writeU16(pointer);
19
+ writer.writeU256(subPointer);
20
+
21
+ this.u256Pointer = encodePointer(writer.getBuffer());
22
+ }
13
23
 
14
24
  private _value: u256 = u256.Zero;
15
25
 
@@ -28,7 +38,7 @@ export class StoredU256 {
28
38
 
29
39
  this._value = value;
30
40
 
31
- Blockchain.setStorageAt(this.pointer, this.subPointer, this._value);
41
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
32
42
  }
33
43
 
34
44
  @inline
@@ -42,7 +52,28 @@ export class StoredU256 {
42
52
  this.ensureValue();
43
53
 
44
54
  this._value = SafeMath.add(this._value, value);
45
- Blockchain.setStorageAt(this.pointer, this.subPointer, this._value);
55
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
56
+
57
+ return this;
58
+ }
59
+
60
+ @inline
61
+ public addNoCommit(value: u256): this {
62
+ this._value = SafeMath.add(this._value, value);
63
+
64
+ return this;
65
+ }
66
+
67
+ @inline
68
+ public subNoCommit(value: u256): this {
69
+ this._value = SafeMath.sub(this._value, value);
70
+
71
+ return this;
72
+ }
73
+
74
+ @inline
75
+ public commit(): this {
76
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
46
77
 
47
78
  return this;
48
79
  }
@@ -53,7 +84,7 @@ export class StoredU256 {
53
84
  this.ensureValue();
54
85
 
55
86
  this._value = SafeMath.sub(this._value, value);
56
- Blockchain.setStorageAt(this.pointer, this.subPointer, this._value);
87
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
57
88
 
58
89
  return this;
59
90
  }
@@ -64,7 +95,7 @@ export class StoredU256 {
64
95
  this.ensureValue();
65
96
 
66
97
  this._value = SafeMath.mul(this._value, value);
67
- Blockchain.setStorageAt(this.pointer, this.subPointer, this._value);
98
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
68
99
 
69
100
  return this;
70
101
  }
@@ -123,7 +154,7 @@ export class StoredU256 {
123
154
  this.ensureValue();
124
155
 
125
156
  this._value = u256.shr(this._value, value);
126
- Blockchain.setStorageAt(this.pointer, this.subPointer, this._value);
157
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
127
158
 
128
159
  return this;
129
160
  }
@@ -134,7 +165,7 @@ export class StoredU256 {
134
165
  this.ensureValue();
135
166
 
136
167
  this._value = u256.and(this._value, value);
137
- Blockchain.setStorageAt(this.pointer, this.subPointer, this._value);
168
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
138
169
 
139
170
  return this;
140
171
  }
@@ -145,7 +176,7 @@ export class StoredU256 {
145
176
  this.ensureValue();
146
177
 
147
178
  this._value = u256.or(this._value, value);
148
- Blockchain.setStorageAt(this.pointer, this.subPointer, this._value);
179
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
149
180
 
150
181
  return this;
151
182
  }
@@ -156,7 +187,7 @@ export class StoredU256 {
156
187
  this.ensureValue();
157
188
 
158
189
  this._value = u256.xor(this._value, value);
159
- Blockchain.setStorageAt(this.pointer, this.subPointer, this._value);
190
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
160
191
 
161
192
  return this;
162
193
  }
@@ -167,7 +198,7 @@ export class StoredU256 {
167
198
  this.ensureValue();
168
199
 
169
200
  this._value = SafeMath.pow(this._value, exponent);
170
- Blockchain.setStorageAt(this.pointer, this.subPointer, this._value);
201
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
171
202
 
172
203
  return this;
173
204
  }
@@ -178,7 +209,7 @@ export class StoredU256 {
178
209
  this.ensureValue();
179
210
 
180
211
  this._value = SafeMath.mod(this._value, value);
181
- Blockchain.setStorageAt(this.pointer, this.subPointer, this._value);
212
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
182
213
 
183
214
  return this;
184
215
  }
@@ -189,7 +220,7 @@ export class StoredU256 {
189
220
  this.ensureValue();
190
221
 
191
222
  this._value = SafeMath.add(this._value, u256.One);
192
- Blockchain.setStorageAt(this.pointer, this.subPointer, this._value);
223
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
193
224
 
194
225
  return this;
195
226
  }
@@ -200,7 +231,7 @@ export class StoredU256 {
200
231
  this.ensureValue();
201
232
 
202
233
  this._value = SafeMath.sub(this._value, u256.One);
203
- Blockchain.setStorageAt(this.pointer, this.subPointer, this._value);
234
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
204
235
 
205
236
  return this;
206
237
  }
@@ -209,7 +240,7 @@ export class StoredU256 {
209
240
  public set(value: u256): this {
210
241
  this._value = value;
211
242
 
212
- Blockchain.setStorageAt(this.pointer, this.subPointer, this._value);
243
+ Blockchain.setStorageAt(this.u256Pointer, this._value);
213
244
 
214
245
  return this;
215
246
  }
@@ -220,6 +251,6 @@ export class StoredU256 {
220
251
  }
221
252
 
222
253
  private ensureValue(): void {
223
- this._value = Blockchain.getStorageAt(this.pointer, this.subPointer, this.defaultValue);
254
+ this._value = Blockchain.getStorageAt(this.u256Pointer, this.defaultValue);
224
255
  }
225
256
  }