@btc-vision/btc-runtime 1.5.8 → 1.6.1

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.5.8",
3
+ "version": "1.6.1",
4
4
  "description": "Bitcoin Smart Contract Runtime",
5
5
  "main": "btc/index.ts",
6
6
  "scripts": {},
@@ -279,13 +279,14 @@ export abstract class DeployableOP_20 extends OP_NET implements IOP_20 {
279
279
 
280
280
  // Build the hash to match exactly what the user signed, including the nonce
281
281
  const writer = new BytesWriter(
282
- ADDRESS_BYTE_LENGTH * 2 + U256_BYTE_LENGTH + U256_BYTE_LENGTH,
282
+ ADDRESS_BYTE_LENGTH * 3 + U256_BYTE_LENGTH + U256_BYTE_LENGTH,
283
283
  );
284
284
 
285
285
  writer.writeAddress(owner);
286
286
  writer.writeAddress(spender);
287
287
  writer.writeU256(value);
288
288
  writer.writeU256(nonce);
289
+ writer.writeAddress(this.address);
289
290
 
290
291
  const hash = sha256(writer.getBuffer());
291
292
  if (!Blockchain.verifySchnorrSignature(owner, signature, hash)) {
@@ -13,11 +13,15 @@ import {
13
13
  deployFromAddress,
14
14
  emit,
15
15
  env_exit,
16
+ getAccountType,
17
+ getBlockHash,
16
18
  getCallResult,
17
19
  loadPointer,
18
20
  log,
19
21
  sha256,
20
22
  storePointer,
23
+ tLoadPointer,
24
+ tStorePointer,
21
25
  validateBitcoinAddress,
22
26
  verifySchnorrSignature,
23
27
  } from './global';
@@ -36,6 +40,7 @@ export class BlockchainEnvironment {
36
40
  public readonly DEAD_ADDRESS: Address = Address.dead();
37
41
 
38
42
  private storage: MapUint8Array = new MapUint8Array();
43
+ private transientStorage: MapUint8Array = new MapUint8Array();
39
44
  private _selfContract: Potential<OP_NET> = null;
40
45
  private _plugins: Plugin[] = [];
41
46
 
@@ -230,6 +235,7 @@ export class BlockchainEnvironment {
230
235
  resultAddressBuffer,
231
236
  );
232
237
 
238
+ // TODO: Decode revert data if status is not 0
233
239
  if (status !== 0) {
234
240
  throw new Revert('Failed to deploy contract');
235
241
  }
@@ -249,6 +255,16 @@ export class BlockchainEnvironment {
249
255
  return new Uint8Array(32);
250
256
  }
251
257
 
258
+ public getTransientStorageAt(
259
+ pointerHash: Uint8Array,
260
+ ): Uint8Array {
261
+ if (this.hasPointerTransientStorageHash(pointerHash)) {
262
+ return this.transientStorage.get(pointerHash);
263
+ }
264
+
265
+ return new Uint8Array(32);
266
+ }
267
+
252
268
  public sha256(buffer: Uint8Array): Uint8Array {
253
269
  return sha256(buffer);
254
270
  }
@@ -274,10 +290,31 @@ export class BlockchainEnvironment {
274
290
  return !eqUint(val, EMPTY_BUFFER);
275
291
  }
276
292
 
293
+ public hasTransientStorageAt(pointerHash: Uint8Array): bool {
294
+ // We mark zero as the default value for the storage, if something is 0, the storage slot get deleted or is non-existent
295
+ const val: Uint8Array = this.getTransientStorageAt(pointerHash);
296
+
297
+ return !eqUint(val, EMPTY_BUFFER);
298
+ }
299
+
277
300
  public setStorageAt(pointerHash: Uint8Array, value: Uint8Array): void {
278
301
  this._internalSetStorageAt(pointerHash, value);
279
302
  }
280
303
 
304
+ public setTransientStorageAt(pointerHash: Uint8Array, value: Uint8Array): void {
305
+ this._internalSetTransientStorageAt(pointerHash, value);
306
+ }
307
+
308
+ public getAccountType(address: Address): u32 {
309
+ return getAccountType(address.buffer);
310
+ }
311
+
312
+ public getBlockHash(blockNumber: u64): Uint8Array {
313
+ const hash = new ArrayBuffer(32);
314
+ getBlockHash(blockNumber, hash);
315
+ return Uint8Array.wrap(hash);
316
+ }
317
+
281
318
  private createContractIfNotExists(): void {
282
319
  if (!this._contract) {
283
320
  throw new Revert('Contract is required');
@@ -294,6 +331,12 @@ export class BlockchainEnvironment {
294
331
  storePointer(pointerHash.buffer, value.buffer);
295
332
  }
296
333
 
334
+ private _internalSetTransientStorageAt(pointerHash: Uint8Array, value: Uint8Array): void {
335
+ this.transientStorage.set(pointerHash, value);
336
+
337
+ tStorePointer(pointerHash.buffer, value.buffer);
338
+ }
339
+
297
340
  private hasPointerStorageHash(pointer: Uint8Array): bool {
298
341
  if (this.storage.has(pointer)) {
299
342
  return true;
@@ -308,4 +351,19 @@ export class BlockchainEnvironment {
308
351
 
309
352
  return !eqUint(value, EMPTY_BUFFER);
310
353
  }
354
+
355
+ private hasPointerTransientStorageHash(pointer: Uint8Array): bool {
356
+ if (this.transientStorage.has(pointer)) {
357
+ return true;
358
+ }
359
+
360
+ // we attempt to load the requested pointer.
361
+ const resultBuffer = new ArrayBuffer(32);
362
+ tLoadPointer(pointer.buffer, resultBuffer);
363
+
364
+ const value: Uint8Array = Uint8Array.wrap(resultBuffer);
365
+ this.transientStorage.set(pointer, value); // cache the value
366
+
367
+ return !eqUint(value, EMPTY_BUFFER);
368
+ }
311
369
  }
@@ -10,14 +10,18 @@ export declare function getCalldata(offset: u32, length: u32, result: ArrayBuffe
10
10
  @external('env', 'load')
11
11
  export declare function loadPointer(key: ArrayBuffer, result: ArrayBuffer): void;
12
12
 
13
- // @ts-ignore
14
- @external('env', 'nextPointerGreaterThan')
15
- export declare function nextPointerGreaterThan(data: Uint8Array): Uint8Array;
16
-
17
13
  // @ts-ignore
18
14
  @external('env', 'store')
19
15
  export declare function storePointer(key: ArrayBuffer, value: ArrayBuffer): void;
20
16
 
17
+ // @ts-ignore
18
+ @external('env', 'tload')
19
+ export declare function tLoadPointer(key: ArrayBuffer, result: ArrayBuffer): void;
20
+
21
+ // @ts-ignore
22
+ @external('env', 'tstore')
23
+ export declare function tStorePointer(key: ArrayBuffer, value: ArrayBuffer): void;
24
+
21
25
  // @ts-ignore
22
26
  @external('env', 'deployFromAddress')
23
27
  export declare function deployFromAddress(originAddress: ArrayBuffer, salt: ArrayBuffer, calldata: ArrayBuffer, calldataLength: u32, resultAddress: ArrayBuffer): u32;
@@ -83,6 +87,14 @@ export declare function getOutputsSize(): u32;
83
87
  @external('env', 'verifySchnorrSignature')
84
88
  export declare function verifySchnorrSignature(publicKey: ArrayBuffer, signature: ArrayBuffer, message: ArrayBuffer): u32;
85
89
 
90
+ // @ts-ignore
91
+ @external('env', 'blockHash')
92
+ export declare function getBlockHash(block_number: u64, result: ArrayBuffer): void;
93
+
94
+ // @ts-ignore
95
+ @external('env', 'accountType')
96
+ export declare function getAccountType(address: ArrayBuffer): u32;
97
+
86
98
  // @ts-ignore
87
99
  @external('env', 'exit')
88
100
  export declare function env_exit(status: u32, data: ArrayBuffer, dataLength: u32): void;