@btc-vision/btc-runtime 1.5.8 → 1.6.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/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.0",
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)) {
@@ -15,11 +15,15 @@ import {
15
15
  env_exit,
16
16
  getCallResult,
17
17
  loadPointer,
18
+ tLoadPointer,
18
19
  log,
19
20
  sha256,
20
21
  storePointer,
22
+ tStorePointer,
21
23
  validateBitcoinAddress,
22
24
  verifySchnorrSignature,
25
+ getAccountType,
26
+ getBlockHash,
23
27
  } from './global';
24
28
  import { eqUint, MapUint8Array } from '../generic/MapUint8Array';
25
29
  import { EMPTY_BUFFER } from '../math/bytes';
@@ -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,17 @@ export class BlockchainEnvironment {
249
255
  return new Uint8Array(32);
250
256
  }
251
257
 
258
+ public getTransientStorageAt(
259
+ pointerHash: Uint8Array,
260
+ ): Uint8Array {
261
+ this.hasPointerTransientStorageHash(pointerHash);
262
+ if (this.transientStorage.has(pointerHash)) {
263
+ return this.transientStorage.get(pointerHash);
264
+ }
265
+
266
+ return new Uint8Array(32);
267
+ }
268
+
252
269
  public sha256(buffer: Uint8Array): Uint8Array {
253
270
  return sha256(buffer);
254
271
  }
@@ -274,10 +291,21 @@ export class BlockchainEnvironment {
274
291
  return !eqUint(val, EMPTY_BUFFER);
275
292
  }
276
293
 
294
+ public hasTransientStorageAt(pointerHash: Uint8Array): bool {
295
+ // We mark zero as the default value for the storage, if something is 0, the storage slot get deleted or is non-existent
296
+ const val: Uint8Array = this.getTransientStorageAt(pointerHash);
297
+
298
+ return !eqUint(val, EMPTY_BUFFER);
299
+ }
300
+
277
301
  public setStorageAt(pointerHash: Uint8Array, value: Uint8Array): void {
278
302
  this._internalSetStorageAt(pointerHash, value);
279
303
  }
280
304
 
305
+ public setTransientStorageAt(pointerHash: Uint8Array, value: Uint8Array): void {
306
+ this._internalSetTransientStorageAt(pointerHash, value);
307
+ }
308
+
281
309
  private createContractIfNotExists(): void {
282
310
  if (!this._contract) {
283
311
  throw new Revert('Contract is required');
@@ -294,6 +322,12 @@ export class BlockchainEnvironment {
294
322
  storePointer(pointerHash.buffer, value.buffer);
295
323
  }
296
324
 
325
+ private _internalSetTransientStorageAt(pointerHash: Uint8Array, value: Uint8Array): void {
326
+ this.transientStorage.set(pointerHash, value);
327
+
328
+ tStorePointer(pointerHash.buffer, value.buffer);
329
+ }
330
+
297
331
  private hasPointerStorageHash(pointer: Uint8Array): bool {
298
332
  if (this.storage.has(pointer)) {
299
333
  return true;
@@ -308,4 +342,29 @@ export class BlockchainEnvironment {
308
342
 
309
343
  return !eqUint(value, EMPTY_BUFFER);
310
344
  }
345
+
346
+ private hasPointerTransientStorageHash(pointer: Uint8Array): bool {
347
+ if (this.storage.has(pointer)) {
348
+ return true;
349
+ }
350
+
351
+ // we attempt to load the requested pointer.
352
+ const resultBuffer = new ArrayBuffer(32);
353
+ tLoadPointer(pointer.buffer, resultBuffer);
354
+
355
+ const value: Uint8Array = Uint8Array.wrap(resultBuffer);
356
+ this.storage.set(pointer, value); // cache the value
357
+
358
+ return !eqUint(value, EMPTY_BUFFER);
359
+ }
360
+
361
+ public getAccountType(address: Address): u32 {
362
+ return getAccountType(address.buffer)
363
+ }
364
+
365
+ public getBlockHash(blockNumber: u64): Uint8Array {
366
+ const hash = new ArrayBuffer(32);
367
+ getBlockHash(blockNumber, hash);
368
+ return Uint8Array.wrap(hash);
369
+ }
311
370
  }
@@ -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;