@btc-vision/btc-runtime 1.3.4 → 1.3.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 +2 -2
- package/runtime/contracts/DeployableOP_20.ts +6 -2
- package/runtime/contracts/OP_NET.ts +0 -4
- package/runtime/env/BlockchainEnvironment.ts +26 -0
- package/runtime/env/global.ts +8 -0
- package/runtime/math/abi.ts +11 -2
- package/runtime/memory/AddressMemoryMap.ts +2 -3
- package/runtime/memory/KeyMerger.ts +2 -3
- package/runtime/memory/MultiAddressMemoryMap.ts +0 -11
- package/runtime/memory/StringMemoryMap.ts +2 -3
- package/runtime/memory/Uint8ArrayMerger.ts +2 -4
- package/runtime/storage/Serializable.ts +2 -3
- package/runtime/storage/StoredAddress.ts +1 -2
- package/runtime/storage/StoredString.ts +2 -3
- package/runtime/storage/StoredU256.ts +2 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btc-vision/btc-runtime",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.6",
|
|
4
4
|
"description": "Bitcoin Smart Contract Runtime",
|
|
5
5
|
"main": "btc/index.ts",
|
|
6
6
|
"scripts": {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@assemblyscript/loader": "^0.27.30",
|
|
46
46
|
"@eslint/js": "^9.10.0",
|
|
47
|
-
"as-bignum": "^0.3.
|
|
47
|
+
"as-bignum": "^0.3.1",
|
|
48
48
|
"gulplog": "^2.2.0",
|
|
49
49
|
"mocha": "^10.7.3",
|
|
50
50
|
"ts-node": "^10.9.2",
|
|
@@ -216,8 +216,12 @@ export abstract class DeployableOP_20 extends OP_NET implements IOP_20 {
|
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
protected _approve(owner: Address, spender: Address, value: u256): boolean {
|
|
219
|
-
if (owner === Blockchain.DEAD_ADDRESS
|
|
220
|
-
throw new Revert('
|
|
219
|
+
if (owner === Blockchain.DEAD_ADDRESS) {
|
|
220
|
+
throw new Revert('Address can not be dead address');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (spender === Blockchain.DEAD_ADDRESS) {
|
|
224
|
+
throw new Revert('Spender cannot be dead address');
|
|
221
225
|
}
|
|
222
226
|
|
|
223
227
|
const senderMap = this.allowanceMap.get(owner);
|
|
@@ -22,10 +22,6 @@ export class OP_NET implements IBTC {
|
|
|
22
22
|
let response: BytesWriter;
|
|
23
23
|
|
|
24
24
|
switch (method) {
|
|
25
|
-
case encodeSelector('address'):
|
|
26
|
-
response = new BytesWriter(ADDRESS_BYTE_LENGTH);
|
|
27
|
-
response.writeAddress(this.address);
|
|
28
|
-
break;
|
|
29
25
|
case encodeSelector('owner'):
|
|
30
26
|
response = new BytesWriter(ADDRESS_BYTE_LENGTH);
|
|
31
27
|
response.writeAddress(this.owner);
|
|
@@ -16,7 +16,9 @@ import {
|
|
|
16
16
|
encodeAddress,
|
|
17
17
|
loadPointer,
|
|
18
18
|
log,
|
|
19
|
+
nextPointerGreaterThan,
|
|
19
20
|
storePointer,
|
|
21
|
+
validateBitcoinAddress,
|
|
20
22
|
} from './global';
|
|
21
23
|
import { DeployContractResponse } from '../interfaces/DeployContractResponse';
|
|
22
24
|
import { MapU256 } from '../generic/MapU256';
|
|
@@ -162,6 +164,14 @@ export class BlockchainEnvironment {
|
|
|
162
164
|
emit(buffer.getBuffer());
|
|
163
165
|
}
|
|
164
166
|
|
|
167
|
+
public validateBitcoinAddress(address: string): bool {
|
|
168
|
+
const writer = new BytesWriter(address.length);
|
|
169
|
+
writer.writeString(address);
|
|
170
|
+
|
|
171
|
+
const reader = new BytesReader(validateBitcoinAddress(writer.getBuffer()));
|
|
172
|
+
return reader.readBoolean();
|
|
173
|
+
}
|
|
174
|
+
|
|
165
175
|
public encodeVirtualAddress(virtualAddress: u8[]): Address {
|
|
166
176
|
const writer: BytesWriter = new BytesWriter(virtualAddress.length + 4);
|
|
167
177
|
writer.writeU32(virtualAddress.length);
|
|
@@ -222,6 +232,22 @@ export class BlockchainEnvironment {
|
|
|
222
232
|
return defaultValue;
|
|
223
233
|
}
|
|
224
234
|
|
|
235
|
+
public getNextPointerGreaterThan(
|
|
236
|
+
targetPointer: MemorySlotPointer,
|
|
237
|
+
valueAtLeast: u256,
|
|
238
|
+
lte: boolean = true,
|
|
239
|
+
): MemorySlotData<u256> {
|
|
240
|
+
const writer = new BytesWriter(65);
|
|
241
|
+
writer.writeU256(targetPointer);
|
|
242
|
+
writer.writeU256(valueAtLeast);
|
|
243
|
+
writer.writeBoolean(lte);
|
|
244
|
+
|
|
245
|
+
const result: Uint8Array = nextPointerGreaterThan(writer.getBuffer());
|
|
246
|
+
const reader: BytesReader = new BytesReader(result);
|
|
247
|
+
|
|
248
|
+
return reader.readU256();
|
|
249
|
+
}
|
|
250
|
+
|
|
225
251
|
public hasStorageAt(pointerHash: MemorySlotPointer): bool {
|
|
226
252
|
// We mark zero as the default value for the storage, if something is 0, the storage slot get deleted or is non-existent
|
|
227
253
|
const val: u256 = this.getStorageAt(pointerHash, u256.Zero);
|
package/runtime/env/global.ts
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
@external('env', 'load')
|
|
3
3
|
export declare function loadPointer(data: Uint8Array): Uint8Array;
|
|
4
4
|
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
@external('env', 'nextPointerGreaterThan')
|
|
7
|
+
export declare function nextPointerGreaterThan(data: Uint8Array): Uint8Array;
|
|
8
|
+
|
|
5
9
|
// @ts-ignore
|
|
6
10
|
@external('env', 'store')
|
|
7
11
|
export declare function storePointer(data: Uint8Array): Uint8Array;
|
|
@@ -38,6 +42,10 @@ export declare function sha256(data: Uint8Array): Uint8Array;
|
|
|
38
42
|
@external('env', 'ripemd160')
|
|
39
43
|
export declare function ripemd160(data: Uint8Array): Uint8Array;
|
|
40
44
|
|
|
45
|
+
// @ts-ignore
|
|
46
|
+
@external('env', 'validateBitcoinAddress')
|
|
47
|
+
export declare function validateBitcoinAddress(data: Uint8Array): Uint8Array;
|
|
48
|
+
|
|
41
49
|
// @ts-ignore
|
|
42
50
|
@external('env', 'inputs')
|
|
43
51
|
export declare function inputs(): Uint8Array;
|
package/runtime/math/abi.ts
CHANGED
|
@@ -12,8 +12,17 @@ export function encodeSelector(name: string): Selector {
|
|
|
12
12
|
return bytes4(hash);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export function encodePointer(typed: Uint8Array): MemorySlotPointer {
|
|
15
|
+
export function encodePointer(uniqueIdentifier: u16, typed: Uint8Array): MemorySlotPointer {
|
|
16
16
|
const hash = Sha256.hash(typed);
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
const finalPointer = new Uint8Array(32);
|
|
19
|
+
finalPointer[0] = uniqueIdentifier & 0xff;
|
|
20
|
+
finalPointer[1] = (uniqueIdentifier >> 8) & 0xff;
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < 30; i++) {
|
|
23
|
+
// drop the last two bytes
|
|
24
|
+
finalPointer[i + 2] = hash[i];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return bytes32(finalPointer);
|
|
19
28
|
}
|
|
@@ -49,10 +49,9 @@ export class AddressMemoryMap<V extends MemorySlotData<u256>> {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
private encodePointer(key: Address): MemorySlotPointer {
|
|
52
|
-
const writer = new BytesWriter(key.length
|
|
53
|
-
writer.writeU16(this.pointer);
|
|
52
|
+
const writer = new BytesWriter(key.length);
|
|
54
53
|
writer.writeBytes(key);
|
|
55
54
|
|
|
56
|
-
return encodePointer(writer.getBuffer());
|
|
55
|
+
return encodePointer(this.pointer, writer.getBuffer());
|
|
57
56
|
}
|
|
58
57
|
}
|
|
@@ -53,10 +53,9 @@ export class KeyMerger<K extends string, K2 extends string, V extends MemorySlot
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
private encodePointer(key: string): MemorySlotPointer {
|
|
56
|
-
const writer = new BytesWriter(key.length
|
|
57
|
-
writer.writeU16(this.pointer);
|
|
56
|
+
const writer = new BytesWriter(key.length);
|
|
58
57
|
writer.writeString(key);
|
|
59
58
|
|
|
60
|
-
return encodePointer(writer.getBuffer());
|
|
59
|
+
return encodePointer(this.pointer, writer.getBuffer());
|
|
61
60
|
}
|
|
62
61
|
}
|
|
@@ -25,17 +25,6 @@ export class MultiAddressMemoryMap<V extends MemorySlotData<u256>> extends Map<
|
|
|
25
25
|
return super.get(key);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
public setUpperKey(key: Address, key2: Address, value: V): this {
|
|
29
|
-
this.createKeyMerger(key);
|
|
30
|
-
|
|
31
|
-
const subMap = super.get(key);
|
|
32
|
-
if (subMap) {
|
|
33
|
-
subMap.set(key2, value);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return this;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
28
|
public set(key: Address, value: Uint8ArrayMerger<V>): this {
|
|
40
29
|
this.createKeyMerger(key);
|
|
41
30
|
|
|
@@ -48,10 +48,9 @@ export class StringMemoryMap<K extends string, V extends MemorySlotData<u256>> {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
private encodePointer(key: K): MemorySlotPointer {
|
|
51
|
-
const writer = new BytesWriter(key.length
|
|
52
|
-
writer.writeU16(this.pointer);
|
|
51
|
+
const writer = new BytesWriter(key.length);
|
|
53
52
|
writer.writeString(key);
|
|
54
53
|
|
|
55
|
-
return encodePointer(writer.getBuffer());
|
|
54
|
+
return encodePointer(this.pointer, writer.getBuffer());
|
|
56
55
|
}
|
|
57
56
|
}
|
|
@@ -51,7 +51,7 @@ export class Uint8ArrayMerger<V extends MemorySlotData<u256>> {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
private getKeyHash(key: Uint8Array): MemorySlotPointer {
|
|
54
|
-
const writer: BytesWriter = new BytesWriter(key.byteLength +
|
|
54
|
+
const writer: BytesWriter = new BytesWriter(key.byteLength + this.parentKey.byteLength);
|
|
55
55
|
|
|
56
56
|
writer.writeBytes(this.parentKey);
|
|
57
57
|
writer.writeBytes(key);
|
|
@@ -60,8 +60,6 @@ export class Uint8ArrayMerger<V extends MemorySlotData<u256>> {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
private encodePointer(writer: BytesWriter): MemorySlotPointer {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return encodePointer(writer.getBuffer());
|
|
63
|
+
return encodePointer(this.pointer, writer.getBuffer());
|
|
66
64
|
}
|
|
67
65
|
}
|
|
@@ -80,10 +80,9 @@ export abstract class Serializable {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
private getPointer(subPointer: u256): u256 {
|
|
83
|
-
const writer = new BytesWriter(
|
|
84
|
-
writer.writeU16(this.pointer);
|
|
83
|
+
const writer = new BytesWriter(32);
|
|
85
84
|
writer.writeU256(subPointer);
|
|
86
85
|
|
|
87
|
-
return encodePointer(writer.getBuffer());
|
|
86
|
+
return encodePointer(this.pointer, writer.getBuffer());
|
|
88
87
|
}
|
|
89
88
|
}
|
|
@@ -14,10 +14,9 @@ export class StoredAddress {
|
|
|
14
14
|
defaultValue: Address,
|
|
15
15
|
) {
|
|
16
16
|
const writer = new BytesWriter(32);
|
|
17
|
-
writer.writeU16(pointer);
|
|
18
17
|
|
|
19
18
|
this.defaultValue = u256.fromBytes(defaultValue);
|
|
20
|
-
this.addressPointer = encodePointer(writer.getBuffer());
|
|
19
|
+
this.addressPointer = encodePointer(pointer, writer.getBuffer());
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
private _value: Address = new Address();
|
|
@@ -33,11 +33,10 @@ export class StoredString {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
private getPointer(key: u256): u256 {
|
|
36
|
-
const buf = new BytesWriter(
|
|
37
|
-
buf.writeU16(this.pointer);
|
|
36
|
+
const buf = new BytesWriter(32);
|
|
38
37
|
buf.writeU256(key);
|
|
39
38
|
|
|
40
|
-
return encodePointer(buf.getBuffer());
|
|
39
|
+
return encodePointer(this.pointer, buf.getBuffer());
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
private save(): void {
|
|
@@ -14,11 +14,10 @@ export class StoredU256 {
|
|
|
14
14
|
public subPointer: MemorySlotPointer,
|
|
15
15
|
private defaultValue: u256,
|
|
16
16
|
) {
|
|
17
|
-
const writer = new BytesWriter(
|
|
18
|
-
writer.writeU16(pointer);
|
|
17
|
+
const writer = new BytesWriter(32);
|
|
19
18
|
writer.writeU256(subPointer);
|
|
20
19
|
|
|
21
|
-
this.u256Pointer = encodePointer(writer.getBuffer());
|
|
20
|
+
this.u256Pointer = encodePointer(pointer, writer.getBuffer());
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
private _value: u256 = u256.Zero;
|