@cashscript/utils 0.8.0-next.0 → 0.8.0-next.2

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.
@@ -1,3 +1,5 @@
1
+ /// <reference types="node" />
2
+ import { PathLike } from 'fs';
1
3
  export interface AbiInput {
2
4
  name: string;
3
5
  type: string;
@@ -19,5 +21,5 @@ export interface Artifact {
19
21
  };
20
22
  updatedAt: string;
21
23
  }
22
- export declare function importArtifact(artifactFile: string): Artifact;
24
+ export declare function importArtifact(artifactFile: PathLike): Artifact;
23
25
  export declare function exportArtifact(artifact: Artifact, targetFile: string): void;
@@ -1,7 +1,7 @@
1
1
  export declare function encodeBool(bool: boolean): Uint8Array;
2
2
  export declare function decodeBool(encodedBool: Uint8Array): boolean;
3
- export declare function encodeInt(int: number | bigint): Uint8Array;
4
- export declare function decodeInt(encodedInt: Uint8Array, maxLength?: number): number;
3
+ export declare function encodeInt(int: bigint): Uint8Array;
4
+ export declare function decodeInt(encodedInt: Uint8Array, maxLength?: number): bigint;
5
5
  export declare function encodeString(str: string): Uint8Array;
6
6
  export declare function decodeString(encodedString: Uint8Array): string;
7
7
  export declare function placeholder(size: number): Uint8Array;
@@ -1,6 +1,6 @@
1
- import { bigIntToScriptNumber, parseBytesAsScriptNumber, isScriptNumberError, utf8ToBin, binToUtf8, } from '@bitauth/libauth';
1
+ import { bigIntToVmNumber, utf8ToBin, binToUtf8, vmNumberToBigInt, isVmNumberError, } from '@bitauth/libauth';
2
2
  export function encodeBool(bool) {
3
- return bool ? encodeInt(1) : encodeInt(0);
3
+ return bool ? encodeInt(1n) : encodeInt(0n);
4
4
  }
5
5
  export function decodeBool(encodedBool) {
6
6
  // Any encoding of 0 is false, else true
@@ -15,15 +15,15 @@ export function decodeBool(encodedBool) {
15
15
  return false;
16
16
  }
17
17
  export function encodeInt(int) {
18
- return bigIntToScriptNumber(BigInt(int));
18
+ return bigIntToVmNumber(int);
19
19
  }
20
20
  export function decodeInt(encodedInt, maxLength = 8) {
21
- const options = { maximumScriptNumberByteLength: maxLength };
22
- const result = parseBytesAsScriptNumber(encodedInt, options);
23
- if (isScriptNumberError(result)) {
21
+ const options = { maximumVmNumberByteLength: maxLength };
22
+ const result = vmNumberToBigInt(encodedInt, options);
23
+ if (isVmNumberError(result)) {
24
24
  throw new Error(result);
25
25
  }
26
- return Number(result);
26
+ return result;
27
27
  }
28
28
  export function encodeString(str) {
29
29
  return utf8ToBin(str);
@@ -1,3 +1,4 @@
1
+ // TODO: Replace with libauth
1
2
  import hash from 'hash.js';
2
3
  export function sha512(payload) {
3
4
  return Uint8Array.from(hash.sha512().update(payload).digest());
@@ -1,32 +1,7 @@
1
- import { OpcodesBCH } from '@bitauth/libauth';
2
- export declare const Op: typeof OpcodesBCH;
1
+ export declare const Op: typeof import("@bitauth/libauth").OpcodesBCH2023;
3
2
  export declare type Op = number;
4
3
  export declare type OpOrData = Op | Uint8Array;
5
4
  export declare type Script = OpOrData[];
6
- export declare enum IntrospectionOp {
7
- OP_INPUTINDEX = 192,
8
- OP_ACTIVEBYTECODE = 193,
9
- OP_TXVERSION = 194,
10
- OP_TXINPUTCOUNT = 195,
11
- OP_TXOUTPUTCOUNT = 196,
12
- OP_TXLOCKTIME = 197,
13
- OP_UTXOVALUE = 198,
14
- OP_UTXOBYTECODE = 199,
15
- OP_OUTPOINTTXHASH = 200,
16
- OP_OUTPOINTINDEX = 201,
17
- OP_INPUTBYTECODE = 202,
18
- OP_INPUTSEQUENCENUMBER = 203,
19
- OP_OUTPUTVALUE = 204,
20
- OP_OUTPUTBYTECODE = 205,
21
- OP_UTXOTOKENCATEGORY = 206,
22
- OP_UTXOTOKENCOMMITMENT = 207,
23
- OP_UTXOTOKENAMOUNT = 208,
24
- OP_OUTPUTTOKENCATEGORY = 209,
25
- OP_OUTPUTTOKENCOMMITMENT = 210,
26
- OP_OUTPUTTOKENAMOUNT = 211
27
- }
28
- export declare const introspectionOpMapping: any;
29
- export declare const reverseIntrospectionOpMapping: any;
30
5
  export declare function scriptToAsm(script: Script): string;
31
6
  export declare function asmToScript(asm: string): Script;
32
7
  export declare function scriptToBytecode(script: Script): Uint8Array;
@@ -1,54 +1,7 @@
1
- import { OpcodesBCH, encodeDataPush, parseBytecode, serializeAuthenticationInstructions, hexToBin, disassembleBytecodeBCH, flattenBinArray, } from '@bitauth/libauth';
1
+ import { OpcodesBCH, encodeDataPush, hexToBin, disassembleBytecodeBCH, flattenBinArray, encodeAuthenticationInstructions, decodeAuthenticationInstructions, } from '@bitauth/libauth';
2
2
  import { decodeInt, encodeInt } from './data.js';
3
3
  import OptimisationsEquivFile from './cashproof-optimisations.js';
4
4
  export const Op = OpcodesBCH;
5
- // TODO: Replace this when these opcodes are in Libauth
6
- export var IntrospectionOp;
7
- (function (IntrospectionOp) {
8
- IntrospectionOp[IntrospectionOp["OP_INPUTINDEX"] = 192] = "OP_INPUTINDEX";
9
- IntrospectionOp[IntrospectionOp["OP_ACTIVEBYTECODE"] = 193] = "OP_ACTIVEBYTECODE";
10
- IntrospectionOp[IntrospectionOp["OP_TXVERSION"] = 194] = "OP_TXVERSION";
11
- IntrospectionOp[IntrospectionOp["OP_TXINPUTCOUNT"] = 195] = "OP_TXINPUTCOUNT";
12
- IntrospectionOp[IntrospectionOp["OP_TXOUTPUTCOUNT"] = 196] = "OP_TXOUTPUTCOUNT";
13
- IntrospectionOp[IntrospectionOp["OP_TXLOCKTIME"] = 197] = "OP_TXLOCKTIME";
14
- IntrospectionOp[IntrospectionOp["OP_UTXOVALUE"] = 198] = "OP_UTXOVALUE";
15
- IntrospectionOp[IntrospectionOp["OP_UTXOBYTECODE"] = 199] = "OP_UTXOBYTECODE";
16
- IntrospectionOp[IntrospectionOp["OP_OUTPOINTTXHASH"] = 200] = "OP_OUTPOINTTXHASH";
17
- IntrospectionOp[IntrospectionOp["OP_OUTPOINTINDEX"] = 201] = "OP_OUTPOINTINDEX";
18
- IntrospectionOp[IntrospectionOp["OP_INPUTBYTECODE"] = 202] = "OP_INPUTBYTECODE";
19
- IntrospectionOp[IntrospectionOp["OP_INPUTSEQUENCENUMBER"] = 203] = "OP_INPUTSEQUENCENUMBER";
20
- IntrospectionOp[IntrospectionOp["OP_OUTPUTVALUE"] = 204] = "OP_OUTPUTVALUE";
21
- IntrospectionOp[IntrospectionOp["OP_OUTPUTBYTECODE"] = 205] = "OP_OUTPUTBYTECODE";
22
- IntrospectionOp[IntrospectionOp["OP_UTXOTOKENCATEGORY"] = 206] = "OP_UTXOTOKENCATEGORY";
23
- IntrospectionOp[IntrospectionOp["OP_UTXOTOKENCOMMITMENT"] = 207] = "OP_UTXOTOKENCOMMITMENT";
24
- IntrospectionOp[IntrospectionOp["OP_UTXOTOKENAMOUNT"] = 208] = "OP_UTXOTOKENAMOUNT";
25
- IntrospectionOp[IntrospectionOp["OP_OUTPUTTOKENCATEGORY"] = 209] = "OP_OUTPUTTOKENCATEGORY";
26
- IntrospectionOp[IntrospectionOp["OP_OUTPUTTOKENCOMMITMENT"] = 210] = "OP_OUTPUTTOKENCOMMITMENT";
27
- IntrospectionOp[IntrospectionOp["OP_OUTPUTTOKENAMOUNT"] = 211] = "OP_OUTPUTTOKENAMOUNT";
28
- })(IntrospectionOp || (IntrospectionOp = {}));
29
- export const introspectionOpMapping = {
30
- OP_INPUTINDEX: 'OP_UNKNOWN192',
31
- OP_ACTIVEBYTECODE: 'OP_UNKNOWN193',
32
- OP_TXVERSION: 'OP_UNKNOWN194',
33
- OP_TXINPUTCOUNT: 'OP_UNKNOWN195',
34
- OP_TXOUTPUTCOUNT: 'OP_UNKNOWN196',
35
- OP_TXLOCKTIME: 'OP_UNKNOWN197',
36
- OP_UTXOVALUE: 'OP_UNKNOWN198',
37
- OP_UTXOBYTECODE: 'OP_UNKNOWN199',
38
- OP_OUTPOINTTXHASH: 'OP_UNKNOWN200',
39
- OP_OUTPOINTINDEX: 'OP_UNKNOWN201',
40
- OP_INPUTBYTECODE: 'OP_UNKNOWN202',
41
- OP_INPUTSEQUENCENUMBER: 'OP_UNKNOWN203',
42
- OP_OUTPUTVALUE: 'OP_UNKNOWN204',
43
- OP_OUTPUTBYTECODE: 'OP_UNKNOWN205',
44
- OP_UTXOTOKENCATEGORY: 'OP_UNKNOWN206',
45
- OP_UTXOTOKENCOMMITMENT: 'OP_UNKNOWN207',
46
- OP_UTXOTOKENAMOUNT: 'OP_UNKNOWN208',
47
- OP_OUTPUTTOKENCATEGORY: 'OP_UNKNOWN209',
48
- OP_OUTPUTTOKENCOMMITMENT: 'OP_UNKNOWN210',
49
- OP_OUTPUTTOKENAMOUNT: 'OP_UNKNOWN211',
50
- };
51
- export const reverseIntrospectionOpMapping = Object.fromEntries(Object.entries(introspectionOpMapping).map(([k, v]) => ([v, k])));
52
5
  export function scriptToAsm(script) {
53
6
  return bytecodeToAsm(scriptToBytecode(script));
54
7
  }
@@ -61,14 +14,14 @@ export function scriptToBytecode(script) {
61
14
  if (typeof opOrData === 'number') {
62
15
  return { opcode: opOrData };
63
16
  }
64
- return parseBytecode(encodeDataPush(opOrData))[0];
17
+ return decodeAuthenticationInstructions(encodeDataPush(opOrData))[0];
65
18
  });
66
19
  // Convert the AuthenticationInstructions to bytecode
67
- return serializeAuthenticationInstructions(instructions);
20
+ return encodeAuthenticationInstructions(instructions);
68
21
  }
69
22
  export function bytecodeToScript(bytecode) {
70
23
  // Convert the bytecode to AuthenticationInstructions
71
- const instructions = parseBytecode(bytecode);
24
+ const instructions = decodeAuthenticationInstructions(bytecode);
72
25
  // Convert the AuthenticationInstructions to script elements
73
26
  const script = instructions.map((instruction) => ('data' in instruction ? instruction.data : instruction.opcode));
74
27
  return script;
@@ -76,17 +29,15 @@ export function bytecodeToScript(bytecode) {
76
29
  export function asmToBytecode(asm) {
77
30
  // Remove any duplicate whitespace
78
31
  asm = asm.replace(/\s+/g, ' ').trim();
79
- // Replace introspection ops with OP_UNKNOWN... so Libauth gets it
80
- asm = asm.split(' ').map((token) => { var _a; return (_a = introspectionOpMapping[token]) !== null && _a !== void 0 ? _a : token; }).join(' ');
81
32
  // Convert the ASM tokens to AuthenticationInstructions
82
33
  const instructions = asm.split(' ').map((token) => {
83
34
  if (token.startsWith('OP_')) {
84
35
  return { opcode: Op[token] };
85
36
  }
86
- return parseBytecode(encodeDataPush(hexToBin(token)))[0];
37
+ return decodeAuthenticationInstructions(encodeDataPush(hexToBin(token)))[0];
87
38
  });
88
39
  // Convert the AuthenticationInstructions to bytecode
89
- return serializeAuthenticationInstructions(instructions);
40
+ return encodeAuthenticationInstructions(instructions);
90
41
  }
91
42
  export function bytecodeToAsm(bytecode) {
92
43
  // Convert the bytecode to libauth's ASM format
@@ -95,8 +46,6 @@ export function bytecodeToAsm(bytecode) {
95
46
  asm = asm.replace(/OP_PUSHBYTES_[^\s]+/g, '');
96
47
  asm = asm.replace(/OP_PUSHDATA[^\s]+ [^\s]+/g, '');
97
48
  asm = asm.replace(/(^|\s)0x/g, ' ');
98
- // Replace OP_UNKNOWN... with the correct ops
99
- asm = asm.split(' ').map((token) => { var _a; return (_a = reverseIntrospectionOpMapping[token]) !== null && _a !== void 0 ? _a : token; }).join(' ');
100
49
  // Remove any duplicate whitespace
101
50
  asm = asm.replace(/\s+/g, ' ').trim();
102
51
  return asm;
@@ -150,7 +99,7 @@ export function replaceBytecodeNop(script) {
150
99
  // Retrieve size of current OP_SPLIT
151
100
  let oldCut = script[index];
152
101
  if (oldCut instanceof Uint8Array) {
153
- oldCut = decodeInt(oldCut);
102
+ oldCut = Number(decodeInt(oldCut));
154
103
  }
155
104
  else if (oldCut === Op.OP_0) {
156
105
  oldCut = 0;
@@ -162,10 +111,10 @@ export function replaceBytecodeNop(script) {
162
111
  return script;
163
112
  }
164
113
  // Update the old OP_SPLIT by adding either 1 or 3 to it
165
- script[index] = encodeInt(oldCut + 1);
114
+ script[index] = encodeInt(BigInt(oldCut + 1));
166
115
  const bytecodeSize = calculateBytesize(script);
167
116
  if (bytecodeSize > 252) {
168
- script[index] = encodeInt(oldCut + 3);
117
+ script[index] = encodeInt(BigInt(oldCut + 3));
169
118
  }
170
119
  // Minimally encode
171
120
  return asmToScript(scriptToAsm(script));
@@ -4,8 +4,7 @@ export class ArrayType {
4
4
  this.bound = bound;
5
5
  }
6
6
  toString() {
7
- var _a;
8
- return `${this.elementType}[${(_a = this.bound) !== null && _a !== void 0 ? _a : ''}]`;
7
+ return `${this.elementType}[${this.bound ?? ''}]`;
9
8
  }
10
9
  }
11
10
  export class BytesType {
@@ -17,8 +16,7 @@ export class BytesType {
17
16
  return new BytesType(bound);
18
17
  }
19
18
  toString() {
20
- var _a;
21
- return `bytes${(_a = this.bound) !== null && _a !== void 0 ? _a : ''}`;
19
+ return `bytes${this.bound ?? ''}`;
22
20
  }
23
21
  }
24
22
  export class TupleType {
@@ -41,9 +39,7 @@ export var PrimitiveType;
41
39
  PrimitiveType["ANY"] = "any";
42
40
  })(PrimitiveType || (PrimitiveType = {}));
43
41
  const ExplicitlyCastableTo = {
44
- [PrimitiveType.INT]: [
45
- PrimitiveType.INT, PrimitiveType.BOOL,
46
- ],
42
+ [PrimitiveType.INT]: [PrimitiveType.INT, PrimitiveType.BOOL],
47
43
  [PrimitiveType.BOOL]: [PrimitiveType.BOOL, PrimitiveType.INT],
48
44
  [PrimitiveType.STRING]: [PrimitiveType.STRING],
49
45
  [PrimitiveType.PUBKEY]: [PrimitiveType.PUBKEY],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cashscript/utils",
3
- "version": "0.8.0-next.0",
3
+ "version": "0.8.0-next.2",
4
4
  "description": "CashScript utilities and types",
5
5
  "keywords": [
6
6
  "bitcoin cash",
@@ -18,34 +18,36 @@
18
18
  },
19
19
  "license": "MIT",
20
20
  "author": "Rosco Kalis <roscokalis@gmail.com>",
21
- "main": "dist/main/index",
22
- "module": "dist/module/index",
23
- "types": "dist/module/index",
21
+ "main": "dist/index.js",
22
+ "types": "dist/index.d.ts",
23
+ "type": "module",
24
24
  "sideEffects": false,
25
25
  "directories": {
26
26
  "lib": "src",
27
27
  "test": "test"
28
28
  },
29
29
  "scripts": {
30
- "build": "npm run clean && npm run compile",
30
+ "build": "yarn clean && yarn compile",
31
+ "build:test": "yarn clean:test && yarn compile:test",
31
32
  "clean": "rm -rf ./dist",
32
- "compile": "npm run compile:main && npm run compile:module",
33
- "compile:main": "tsc -p tsconfig.build.main.json",
34
- "compile:module": "tsc -p tsconfig.build.module.json",
33
+ "clean:test": "rm -rf ./dist-test",
34
+ "compile": "tsc -p tsconfig.build.json",
35
+ "compile:test": "tsc -p tsconfig.test.json",
35
36
  "lint": "eslint . --ext .ts --ignore-path ../../.eslintignore",
36
- "prepare": "npm run build",
37
- "prepublishOnly": "npm test && npm run lint",
38
- "test": "jest --config=../../jest.config.js packages/utils"
37
+ "prepare": "yarn build",
38
+ "prepublishOnly": "yarn test && yarn lint",
39
+ "pretest": "yarn build:test",
40
+ "test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest"
39
41
  },
40
42
  "dependencies": {
41
- "@bitauth/libauth": "^1.18.1",
43
+ "@bitauth/libauth": "^2.0.0-alpha.8",
42
44
  "hash.js": "^1.1.7"
43
45
  },
44
46
  "devDependencies": {
47
+ "@jest/globals": "^29.4.1",
45
48
  "eslint": "^7.20.0",
46
- "jest": "^26.6.3",
47
- "ts-jest": "^26.5.1",
49
+ "jest": "^29.4.1",
48
50
  "typescript": "^4.1.5"
49
51
  },
50
- "gitHead": "18d793bbb5aa4aef1a07587cd1565ae2a63b0728"
52
+ "gitHead": "37bcb8e924fc56ef8da2cb2a2640eb5478de39b2"
51
53
  }
@@ -1,17 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.exportArtifact = exports.importArtifact = void 0;
7
- const fs_1 = __importDefault(require("fs"));
8
- function importArtifact(artifactFile) {
9
- return JSON.parse(fs_1.default.readFileSync(artifactFile, { encoding: 'utf-8' }));
10
- }
11
- exports.importArtifact = importArtifact;
12
- function exportArtifact(artifact, targetFile) {
13
- const jsonString = JSON.stringify(artifact, null, 2);
14
- fs_1.default.writeFileSync(targetFile, jsonString);
15
- }
16
- exports.exportArtifact = exportArtifact;
17
- //# sourceMappingURL=artifact.js.map
@@ -1,127 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = `
4
- # This file can be run with CashProof to prove that the optimisations preserve exact functionality
5
- # This includes most of CashScript's bytecode optimisations, although some are incompatible with CashProof
6
-
7
- # Hardcoded arithmetic
8
- # OP_NOT OP_IF <=> OP_NOTIF;
9
- OP_1 OP_ADD <=> OP_1ADD;
10
- OP_1 OP_SUB <=> OP_1SUB;
11
- OP_1 OP_NEGATE <=> OP_1NEGATE;
12
- OP_0 OP_EQUAL OP_NOT <=> OP_0NOTEQUAL;
13
- OP_NUMEQUAL OP_NOT <=> OP_NUMNOTEQUAL;
14
- OP_SHA256 OP_SHA256 <=> OP_HASH256;
15
- OP_SHA256 OP_RIPEMD160 <=> OP_HASH160;
16
-
17
- # Hardcoded stack ops
18
- OP_2 OP_PICK OP_1 OP_PICK OP_3 OP_PICK <=> OP_3DUP OP_SWAP;
19
- OP_2 OP_PICK OP_2 OP_PICK OP_2 OP_PICK <=> OP_3DUP;
20
-
21
- OP_0 OP_PICK OP_2 OP_PICK <=> OP_2DUP OP_SWAP;
22
- OP_2 OP_PICK OP_4 OP_PICK <=> OP_2OVER OP_SWAP;
23
- OP_3 OP_PICK OP_3 OP_PICK <=> OP_2OVER;
24
-
25
- OP_2 OP_ROLL OP_3 OP_ROLL <=> OP_2SWAP OP_SWAP;
26
- OP_3 OP_ROLL OP_3 OP_ROLL <=> OP_2SWAP;
27
- OP_4 OP_ROLL OP_5 OP_ROLL <=> OP_2ROT OP_SWAP;
28
- OP_5 OP_ROLL OP_5 OP_ROLL <=> OP_2ROT;
29
-
30
- OP_0 OP_PICK <=> OP_DUP;
31
- OP_1 OP_PICK <=> OP_OVER;
32
- OP_0 OP_ROLL <=> ;
33
- OP_1 OP_ROLL <=> OP_SWAP;
34
- OP_2 OP_ROLL <=> OP_ROT;
35
- OP_DROP OP_DROP <=> OP_2DROP;
36
-
37
- # Secondary effects
38
- OP_DUP OP_SWAP <=> OP_DUP;
39
- OP_SWAP OP_SWAP <=> ;
40
- OP_2SWAP OP_2SWAP <=> ;
41
- OP_ROT OP_ROT OP_ROT <=> ;
42
- OP_2ROT OP_2ROT OP_2ROT <=> ;
43
- OP_OVER OP_OVER <=> OP_2DUP;
44
- OP_DUP OP_DROP <=> ;
45
- OP_DUP OP_NIP <=> ;
46
-
47
- # Enabling secondary effects
48
- OP_DUP OP_OVER <=> OP_DUP OP_DUP;
49
-
50
- # Merge OP_VERIFY
51
- OP_EQUAL OP_VERIFY <=> OP_EQUALVERIFY;
52
- OP_NUMEQUAL OP_VERIFY <=> OP_NUMEQUALVERIFY;
53
- OP_CHECKSIG OP_VERIFY <=> OP_CHECKSIGVERIFY;
54
- # OP_CHECKMULTISIG OP_VERIFY <=> OP_CHECKMULTISIGVERIFY;
55
- OP_CHECKDATASIG OP_VERIFY <=> OP_CHECKDATASIGVERIFY;
56
-
57
- # Remove/replace extraneous OP_SWAP
58
- # OP_SWAP OP_AND <=> OP_AND;
59
- # OP_SWAP OP_OR <=> OP_OR;
60
- # OP_SWAP OP_XOR <=> OP_XOR;
61
- OP_SWAP OP_ADD <=> OP_ADD;
62
- OP_SWAP OP_EQUAL <=> OP_EQUAL;
63
- OP_SWAP OP_NUMEQUAL <=> OP_NUMEQUAL;
64
- OP_SWAP OP_NUMNOTEQUAL <=> OP_NUMNOTEQUAL;
65
- OP_SWAP OP_GREATERTHANOREQUAL <=> OP_LESSTHANOREQUAL;
66
- OP_SWAP OP_LESSTHANOREQUAL <=> OP_GREATERTHANOREQUAL;
67
- OP_SWAP OP_GREATERTHAN <=> OP_LESSTHAN;
68
- OP_SWAP OP_LESSTHAN <=> OP_GREATERTHAN;
69
- OP_SWAP OP_DROP <=> OP_NIP;
70
- OP_SWAP OP_NIP <=> OP_DROP;
71
-
72
- # Remove/replace extraneous OP_DUP
73
- # OP_DUP OP_AND <=> ;
74
- # OP_DUP OP_OR <=> ;
75
- OP_DUP OP_DROP <=> ;
76
- OP_DUP OP_NIP <=> ;
77
-
78
- # Random optimisations (don't know what I'm targeting with this)
79
- OP_2DUP OP_DROP <=> OP_OVER;
80
- OP_2DUP OP_NIP <=> OP_DUP;
81
- OP_CAT OP_DROP <=> OP_2DROP;
82
- OP_NIP OP_DROP <=> OP_2DROP;
83
-
84
- # Far-fetched stuff
85
- OP_DUP OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
86
- OP_OVER OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
87
- OP_2 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
88
- OP_3 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
89
- OP_4 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
90
- OP_5 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
91
- OP_6 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
92
- OP_7 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
93
- OP_8 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
94
- OP_9 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
95
- OP_10 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
96
- OP_11 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
97
- OP_12 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
98
- OP_13 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
99
- OP_14 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
100
- OP_15 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
101
- OP_16 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;
102
-
103
- OP_DUP OP_ROT OP_DROP <=> OP_NIP OP_DUP;
104
- OP_OVER OP_ROT OP_DROP <=> OP_SWAP;
105
- OP_2 OP_PICK OP_ROT OP_DROP <=> OP_NIP OP_OVER;
106
-
107
- OP_0 OP_NIP <=> OP_DROP OP_0;
108
- OP_1 OP_NIP <=> OP_DROP OP_1;
109
- OP_2 OP_NIP <=> OP_DROP OP_2;
110
- OP_3 OP_NIP <=> OP_DROP OP_3;
111
- OP_4 OP_NIP <=> OP_DROP OP_4;
112
- OP_5 OP_NIP <=> OP_DROP OP_5;
113
- OP_6 OP_NIP <=> OP_DROP OP_6;
114
- OP_7 OP_NIP <=> OP_DROP OP_7;
115
- OP_8 OP_NIP <=> OP_DROP OP_8;
116
- OP_9 OP_NIP <=> OP_DROP OP_9;
117
- OP_10 OP_NIP <=> OP_DROP OP_10;
118
- OP_11 OP_NIP <=> OP_DROP OP_11;
119
- OP_12 OP_NIP <=> OP_DROP OP_12;
120
- OP_13 OP_NIP <=> OP_DROP OP_13;
121
- OP_14 OP_NIP <=> OP_DROP OP_14;
122
- OP_15 OP_NIP <=> OP_DROP OP_15;
123
- OP_16 OP_NIP <=> OP_DROP OP_16;
124
-
125
- OP_2 OP_PICK OP_SWAP OP_2 OP_PICK OP_NIP <=> OP_DROP OP_2DUP;
126
- `;
127
- //# sourceMappingURL=cashproof-optimisations.js.map
package/dist/main/data.js DELETED
@@ -1,47 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.placeholder = exports.decodeString = exports.encodeString = exports.decodeInt = exports.encodeInt = exports.decodeBool = exports.encodeBool = void 0;
4
- const libauth_1 = require("@bitauth/libauth");
5
- function encodeBool(bool) {
6
- return bool ? encodeInt(1) : encodeInt(0);
7
- }
8
- exports.encodeBool = encodeBool;
9
- function decodeBool(encodedBool) {
10
- // Any encoding of 0 is false, else true
11
- for (let i = 0; i < encodedBool.byteLength; i += 1) {
12
- if (encodedBool[i] !== 0) {
13
- // Can be negative zero
14
- if (i === encodedBool.byteLength - 1 && encodedBool[i] === 0x80)
15
- return false;
16
- return true;
17
- }
18
- }
19
- return false;
20
- }
21
- exports.decodeBool = decodeBool;
22
- function encodeInt(int) {
23
- return (0, libauth_1.bigIntToScriptNumber)(BigInt(int));
24
- }
25
- exports.encodeInt = encodeInt;
26
- function decodeInt(encodedInt, maxLength = 8) {
27
- const options = { maximumScriptNumberByteLength: maxLength };
28
- const result = (0, libauth_1.parseBytesAsScriptNumber)(encodedInt, options);
29
- if ((0, libauth_1.isScriptNumberError)(result)) {
30
- throw new Error(result);
31
- }
32
- return Number(result);
33
- }
34
- exports.decodeInt = decodeInt;
35
- function encodeString(str) {
36
- return (0, libauth_1.utf8ToBin)(str);
37
- }
38
- exports.encodeString = encodeString;
39
- function decodeString(encodedString) {
40
- return (0, libauth_1.binToUtf8)(encodedString);
41
- }
42
- exports.decodeString = decodeString;
43
- function placeholder(size) {
44
- return new Uint8Array(size).fill(0);
45
- }
46
- exports.placeholder = placeholder;
47
- //# sourceMappingURL=data.js.map
package/dist/main/hash.js DELETED
@@ -1,28 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.hash256 = exports.hash160 = exports.ripemd160 = exports.sha256 = exports.sha512 = void 0;
7
- const hash_js_1 = __importDefault(require("hash.js"));
8
- function sha512(payload) {
9
- return Uint8Array.from(hash_js_1.default.sha512().update(payload).digest());
10
- }
11
- exports.sha512 = sha512;
12
- function sha256(payload) {
13
- return Uint8Array.from(hash_js_1.default.sha256().update(payload).digest());
14
- }
15
- exports.sha256 = sha256;
16
- function ripemd160(payload) {
17
- return Uint8Array.from(hash_js_1.default.ripemd160().update(payload).digest());
18
- }
19
- exports.ripemd160 = ripemd160;
20
- function hash160(payload) {
21
- return ripemd160(sha256(payload));
22
- }
23
- exports.hash160 = hash160;
24
- function hash256(payload) {
25
- return sha256(sha256(payload));
26
- }
27
- exports.hash256 = hash256;
28
- //# sourceMappingURL=hash.js.map
@@ -1,22 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./artifact.js"), exports);
18
- __exportStar(require("./data.js"), exports);
19
- __exportStar(require("./hash.js"), exports);
20
- __exportStar(require("./script.js"), exports);
21
- __exportStar(require("./types.js"), exports);
22
- //# sourceMappingURL=index.js.map
@@ -1,237 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.optimiseBytecode = exports.generateRedeemScript = exports.replaceBytecodeNop = exports.encodeNullDataScript = exports.calculateBytesize = exports.countOpcodes = exports.bytecodeToAsm = exports.asmToBytecode = exports.bytecodeToScript = exports.scriptToBytecode = exports.asmToScript = exports.scriptToAsm = exports.reverseIntrospectionOpMapping = exports.introspectionOpMapping = exports.IntrospectionOp = exports.Op = void 0;
7
- const libauth_1 = require("@bitauth/libauth");
8
- const data_js_1 = require("./data.js");
9
- const cashproof_optimisations_js_1 = __importDefault(require("./cashproof-optimisations.js"));
10
- exports.Op = libauth_1.OpcodesBCH;
11
- // TODO: Replace this when these opcodes are in Libauth
12
- var IntrospectionOp;
13
- (function (IntrospectionOp) {
14
- IntrospectionOp[IntrospectionOp["OP_INPUTINDEX"] = 192] = "OP_INPUTINDEX";
15
- IntrospectionOp[IntrospectionOp["OP_ACTIVEBYTECODE"] = 193] = "OP_ACTIVEBYTECODE";
16
- IntrospectionOp[IntrospectionOp["OP_TXVERSION"] = 194] = "OP_TXVERSION";
17
- IntrospectionOp[IntrospectionOp["OP_TXINPUTCOUNT"] = 195] = "OP_TXINPUTCOUNT";
18
- IntrospectionOp[IntrospectionOp["OP_TXOUTPUTCOUNT"] = 196] = "OP_TXOUTPUTCOUNT";
19
- IntrospectionOp[IntrospectionOp["OP_TXLOCKTIME"] = 197] = "OP_TXLOCKTIME";
20
- IntrospectionOp[IntrospectionOp["OP_UTXOVALUE"] = 198] = "OP_UTXOVALUE";
21
- IntrospectionOp[IntrospectionOp["OP_UTXOBYTECODE"] = 199] = "OP_UTXOBYTECODE";
22
- IntrospectionOp[IntrospectionOp["OP_OUTPOINTTXHASH"] = 200] = "OP_OUTPOINTTXHASH";
23
- IntrospectionOp[IntrospectionOp["OP_OUTPOINTINDEX"] = 201] = "OP_OUTPOINTINDEX";
24
- IntrospectionOp[IntrospectionOp["OP_INPUTBYTECODE"] = 202] = "OP_INPUTBYTECODE";
25
- IntrospectionOp[IntrospectionOp["OP_INPUTSEQUENCENUMBER"] = 203] = "OP_INPUTSEQUENCENUMBER";
26
- IntrospectionOp[IntrospectionOp["OP_OUTPUTVALUE"] = 204] = "OP_OUTPUTVALUE";
27
- IntrospectionOp[IntrospectionOp["OP_OUTPUTBYTECODE"] = 205] = "OP_OUTPUTBYTECODE";
28
- IntrospectionOp[IntrospectionOp["OP_UTXOTOKENCATEGORY"] = 206] = "OP_UTXOTOKENCATEGORY";
29
- IntrospectionOp[IntrospectionOp["OP_UTXOTOKENCOMMITMENT"] = 207] = "OP_UTXOTOKENCOMMITMENT";
30
- IntrospectionOp[IntrospectionOp["OP_UTXOTOKENAMOUNT"] = 208] = "OP_UTXOTOKENAMOUNT";
31
- IntrospectionOp[IntrospectionOp["OP_OUTPUTTOKENCATEGORY"] = 209] = "OP_OUTPUTTOKENCATEGORY";
32
- IntrospectionOp[IntrospectionOp["OP_OUTPUTTOKENCOMMITMENT"] = 210] = "OP_OUTPUTTOKENCOMMITMENT";
33
- IntrospectionOp[IntrospectionOp["OP_OUTPUTTOKENAMOUNT"] = 211] = "OP_OUTPUTTOKENAMOUNT";
34
- })(IntrospectionOp = exports.IntrospectionOp || (exports.IntrospectionOp = {}));
35
- exports.introspectionOpMapping = {
36
- OP_INPUTINDEX: 'OP_UNKNOWN192',
37
- OP_ACTIVEBYTECODE: 'OP_UNKNOWN193',
38
- OP_TXVERSION: 'OP_UNKNOWN194',
39
- OP_TXINPUTCOUNT: 'OP_UNKNOWN195',
40
- OP_TXOUTPUTCOUNT: 'OP_UNKNOWN196',
41
- OP_TXLOCKTIME: 'OP_UNKNOWN197',
42
- OP_UTXOVALUE: 'OP_UNKNOWN198',
43
- OP_UTXOBYTECODE: 'OP_UNKNOWN199',
44
- OP_OUTPOINTTXHASH: 'OP_UNKNOWN200',
45
- OP_OUTPOINTINDEX: 'OP_UNKNOWN201',
46
- OP_INPUTBYTECODE: 'OP_UNKNOWN202',
47
- OP_INPUTSEQUENCENUMBER: 'OP_UNKNOWN203',
48
- OP_OUTPUTVALUE: 'OP_UNKNOWN204',
49
- OP_OUTPUTBYTECODE: 'OP_UNKNOWN205',
50
- OP_UTXOTOKENCATEGORY: 'OP_UNKNOWN206',
51
- OP_UTXOTOKENCOMMITMENT: 'OP_UNKNOWN207',
52
- OP_UTXOTOKENAMOUNT: 'OP_UNKNOWN208',
53
- OP_OUTPUTTOKENCATEGORY: 'OP_UNKNOWN209',
54
- OP_OUTPUTTOKENCOMMITMENT: 'OP_UNKNOWN210',
55
- OP_OUTPUTTOKENAMOUNT: 'OP_UNKNOWN211',
56
- };
57
- exports.reverseIntrospectionOpMapping = Object.fromEntries(Object.entries(exports.introspectionOpMapping).map(([k, v]) => ([v, k])));
58
- function scriptToAsm(script) {
59
- return bytecodeToAsm(scriptToBytecode(script));
60
- }
61
- exports.scriptToAsm = scriptToAsm;
62
- function asmToScript(asm) {
63
- return bytecodeToScript(asmToBytecode(asm));
64
- }
65
- exports.asmToScript = asmToScript;
66
- function scriptToBytecode(script) {
67
- // Convert the script elements to AuthenticationInstructions
68
- const instructions = script.map((opOrData) => {
69
- if (typeof opOrData === 'number') {
70
- return { opcode: opOrData };
71
- }
72
- return (0, libauth_1.parseBytecode)((0, libauth_1.encodeDataPush)(opOrData))[0];
73
- });
74
- // Convert the AuthenticationInstructions to bytecode
75
- return (0, libauth_1.serializeAuthenticationInstructions)(instructions);
76
- }
77
- exports.scriptToBytecode = scriptToBytecode;
78
- function bytecodeToScript(bytecode) {
79
- // Convert the bytecode to AuthenticationInstructions
80
- const instructions = (0, libauth_1.parseBytecode)(bytecode);
81
- // Convert the AuthenticationInstructions to script elements
82
- const script = instructions.map((instruction) => ('data' in instruction ? instruction.data : instruction.opcode));
83
- return script;
84
- }
85
- exports.bytecodeToScript = bytecodeToScript;
86
- function asmToBytecode(asm) {
87
- // Remove any duplicate whitespace
88
- asm = asm.replace(/\s+/g, ' ').trim();
89
- // Replace introspection ops with OP_UNKNOWN... so Libauth gets it
90
- asm = asm.split(' ').map((token) => { var _a; return (_a = exports.introspectionOpMapping[token]) !== null && _a !== void 0 ? _a : token; }).join(' ');
91
- // Convert the ASM tokens to AuthenticationInstructions
92
- const instructions = asm.split(' ').map((token) => {
93
- if (token.startsWith('OP_')) {
94
- return { opcode: exports.Op[token] };
95
- }
96
- return (0, libauth_1.parseBytecode)((0, libauth_1.encodeDataPush)((0, libauth_1.hexToBin)(token)))[0];
97
- });
98
- // Convert the AuthenticationInstructions to bytecode
99
- return (0, libauth_1.serializeAuthenticationInstructions)(instructions);
100
- }
101
- exports.asmToBytecode = asmToBytecode;
102
- function bytecodeToAsm(bytecode) {
103
- // Convert the bytecode to libauth's ASM format
104
- let asm = (0, libauth_1.disassembleBytecodeBCH)(bytecode);
105
- // COnvert libauth's ASM format to BITBOX's
106
- asm = asm.replace(/OP_PUSHBYTES_[^\s]+/g, '');
107
- asm = asm.replace(/OP_PUSHDATA[^\s]+ [^\s]+/g, '');
108
- asm = asm.replace(/(^|\s)0x/g, ' ');
109
- // Replace OP_UNKNOWN... with the correct ops
110
- asm = asm.split(' ').map((token) => { var _a; return (_a = exports.reverseIntrospectionOpMapping[token]) !== null && _a !== void 0 ? _a : token; }).join(' ');
111
- // Remove any duplicate whitespace
112
- asm = asm.replace(/\s+/g, ' ').trim();
113
- return asm;
114
- }
115
- exports.bytecodeToAsm = bytecodeToAsm;
116
- function countOpcodes(script) {
117
- return script
118
- .filter((opOrData) => typeof opOrData === 'number')
119
- .filter((op) => op > exports.Op.OP_16)
120
- .length;
121
- }
122
- exports.countOpcodes = countOpcodes;
123
- function calculateBytesize(script) {
124
- return scriptToBytecode(script).byteLength;
125
- }
126
- exports.calculateBytesize = calculateBytesize;
127
- // For encoding OP_RETURN data (doesn't require BIP62.3 / MINIMALDATA)
128
- function encodeNullDataScript(chunks) {
129
- return (0, libauth_1.flattenBinArray)(chunks.map((chunk) => {
130
- if (typeof chunk === 'number') {
131
- return new Uint8Array([chunk]);
132
- }
133
- const pushdataOpcode = getPushDataOpcode(chunk);
134
- return new Uint8Array([...pushdataOpcode, ...chunk]);
135
- }));
136
- }
137
- exports.encodeNullDataScript = encodeNullDataScript;
138
- function getPushDataOpcode(data) {
139
- const { byteLength } = data;
140
- if (byteLength === 0)
141
- return Uint8Array.from([0x4c, 0x00]);
142
- if (byteLength < 76)
143
- return Uint8Array.from([byteLength]);
144
- if (byteLength < 256)
145
- return Uint8Array.from([0x4c, byteLength]);
146
- throw Error('Pushdata too large');
147
- }
148
- /**
149
- * When cutting out the tx.bytecode preimage variable, the compiler does not know
150
- * the size of the final redeem scrip yet, because the constructor parameters still
151
- * need to get added. Because of this it does not know whether the VarInt is 1 or 3
152
- * bytes. During compilation, an OP_NOP is added at the spot where the bytecode is
153
- * cut out. This function replaces that OP_NOP and adds either 1 or 3 to the cut to
154
- * additionally cut off the VarInt.
155
- *
156
- * @param script incomplete redeem script
157
- * @returns completed redeem script
158
- */
159
- function replaceBytecodeNop(script) {
160
- const index = script.findIndex((op) => op === exports.Op.OP_NOP);
161
- if (index < 0)
162
- return script;
163
- // Remove the OP_NOP
164
- script.splice(index, 1);
165
- // Retrieve size of current OP_SPLIT
166
- let oldCut = script[index];
167
- if (oldCut instanceof Uint8Array) {
168
- oldCut = (0, data_js_1.decodeInt)(oldCut);
169
- }
170
- else if (oldCut === exports.Op.OP_0) {
171
- oldCut = 0;
172
- }
173
- else if (oldCut >= exports.Op.OP_1 && oldCut <= exports.Op.OP_16) {
174
- oldCut -= 80;
175
- }
176
- else {
177
- return script;
178
- }
179
- // Update the old OP_SPLIT by adding either 1 or 3 to it
180
- script[index] = (0, data_js_1.encodeInt)(oldCut + 1);
181
- const bytecodeSize = calculateBytesize(script);
182
- if (bytecodeSize > 252) {
183
- script[index] = (0, data_js_1.encodeInt)(oldCut + 3);
184
- }
185
- // Minimally encode
186
- return asmToScript(scriptToAsm(script));
187
- }
188
- exports.replaceBytecodeNop = replaceBytecodeNop;
189
- function generateRedeemScript(baseScript, encodedArgs) {
190
- return replaceBytecodeNop([...encodedArgs, ...baseScript]);
191
- }
192
- exports.generateRedeemScript = generateRedeemScript;
193
- function optimiseBytecode(script, runs = 1000) {
194
- const optimisations = cashproof_optimisations_js_1.default
195
- // Split by line and filter all line comments (#)
196
- .split('\n')
197
- .map((equiv) => equiv.trim())
198
- .filter((equiv) => !equiv.startsWith('#'))
199
- // Join back the lines, and split on semicolon
200
- .join('')
201
- .split(';')
202
- // Parse all optimisations in .equiv file
203
- .map((equiv) => equiv.trim())
204
- .map((equiv) => equiv.split('<=>').map((part) => part.trim()))
205
- .filter((equiv) => equiv.length === 2);
206
- for (let i = 0; i < runs; i += 1) {
207
- const oldScript = script;
208
- script = replaceOps(script, optimisations);
209
- // Break on fixed point
210
- if (scriptToAsm(oldScript) === scriptToAsm(script))
211
- break;
212
- }
213
- return script;
214
- }
215
- exports.optimiseBytecode = optimiseBytecode;
216
- function replaceOps(script, optimisations) {
217
- let asm = scriptToAsm(script);
218
- // Apply all optimisations in the cashproof file
219
- optimisations.forEach(([pattern, replacement]) => {
220
- asm = asm.replace(new RegExp(pattern, 'g'), replacement);
221
- });
222
- // Add optimisations that are not compatible with CashProof
223
- // CashProof can't prove OP_IF without parameters
224
- asm = asm.replace(/OP_NOT OP_IF/g, 'OP_NOTIF');
225
- // CashProof can't prove OP_CHECKMULTISIG without specifying N
226
- asm = asm.replace(/OP_CHECKMULTISIG OP_VERIFY/g, 'OP_CHECKMULTISIGVERIFY');
227
- // CashProof can't prove bitwise operators
228
- asm = asm.replace(/OP_SWAP OP_AND/g, 'OP_AND');
229
- asm = asm.replace(/OP_SWAP OP_OR/g, 'OP_OR');
230
- asm = asm.replace(/OP_SWAP OP_XOR/g, 'OP_XOR');
231
- asm = asm.replace(/OP_DUP OP_AND/g, '');
232
- asm = asm.replace(/OP_DUP OP_OR/g, '');
233
- // Remove any double spaces as a result of opcode removal
234
- asm = asm.replace(/\s+/g, ' ').trim();
235
- return asmToScript(asm);
236
- }
237
- //# sourceMappingURL=script.js.map
@@ -1,192 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isPrimitive = exports.parseType = exports.implicitlyCastableSignature = exports.arrayType = exports.resultingType = exports.implicitlyCastable = exports.explicitlyCastable = exports.PrimitiveType = exports.TupleType = exports.BytesType = exports.ArrayType = void 0;
4
- class ArrayType {
5
- constructor(elementType, bound) {
6
- this.elementType = elementType;
7
- this.bound = bound;
8
- }
9
- toString() {
10
- var _a;
11
- return `${this.elementType}[${(_a = this.bound) !== null && _a !== void 0 ? _a : ''}]`;
12
- }
13
- }
14
- exports.ArrayType = ArrayType;
15
- class BytesType {
16
- constructor(bound) {
17
- this.bound = bound;
18
- }
19
- static fromString(str) {
20
- const bound = str === 'byte' ? 1 : Number.parseInt(str.substring(5), 10) || undefined;
21
- return new BytesType(bound);
22
- }
23
- toString() {
24
- var _a;
25
- return `bytes${(_a = this.bound) !== null && _a !== void 0 ? _a : ''}`;
26
- }
27
- }
28
- exports.BytesType = BytesType;
29
- class TupleType {
30
- constructor(elementType) {
31
- this.elementType = elementType;
32
- }
33
- toString() {
34
- return `(${this.elementType}, ${this.elementType})`;
35
- }
36
- }
37
- exports.TupleType = TupleType;
38
- var PrimitiveType;
39
- (function (PrimitiveType) {
40
- PrimitiveType["INT"] = "int";
41
- PrimitiveType["BOOL"] = "bool";
42
- PrimitiveType["STRING"] = "string";
43
- // ADDRESS = 'address',
44
- PrimitiveType["PUBKEY"] = "pubkey";
45
- PrimitiveType["SIG"] = "sig";
46
- PrimitiveType["DATASIG"] = "datasig";
47
- PrimitiveType["ANY"] = "any";
48
- })(PrimitiveType = exports.PrimitiveType || (exports.PrimitiveType = {}));
49
- const ExplicitlyCastableTo = {
50
- [PrimitiveType.INT]: [
51
- PrimitiveType.INT, PrimitiveType.BOOL,
52
- ],
53
- [PrimitiveType.BOOL]: [PrimitiveType.BOOL, PrimitiveType.INT],
54
- [PrimitiveType.STRING]: [PrimitiveType.STRING],
55
- [PrimitiveType.PUBKEY]: [PrimitiveType.PUBKEY],
56
- [PrimitiveType.SIG]: [PrimitiveType.SIG],
57
- [PrimitiveType.DATASIG]: [PrimitiveType.DATASIG],
58
- [PrimitiveType.ANY]: [],
59
- };
60
- function explicitlyCastable(from, to) {
61
- if (!from || !to)
62
- return false;
63
- // Tuples can't be cast
64
- if (from instanceof TupleType || to instanceof TupleType)
65
- return false;
66
- // Arrays can be cast if their elements can be cast (don't think this is actually used ever)
67
- if (from instanceof ArrayType && to instanceof ArrayType) {
68
- return explicitlyCastable(from.elementType, to.elementType);
69
- }
70
- // Can't cast between Array and non-Array
71
- if (from instanceof ArrayType || to instanceof ArrayType)
72
- return false;
73
- if (to instanceof BytesType) {
74
- // Can't cast bool to bytes
75
- if (from === PrimitiveType.BOOL)
76
- return false;
77
- // Can cast int to any size bytes
78
- if (from === PrimitiveType.INT)
79
- return true;
80
- // Can freely cast to unbounded bytes
81
- if (!to.bound)
82
- return true;
83
- if (from instanceof BytesType) {
84
- // Can freely cast from unbounded bytes
85
- if (!from.bound)
86
- return true;
87
- // Can only cast bounded bytes to bounded bytes if bounds are equal
88
- return from.bound === to.bound;
89
- }
90
- // Cannot cast other primitive types directly to bounded bytes types
91
- return false;
92
- }
93
- if (from instanceof BytesType) {
94
- // Can cast unbounded bytes or <=4 bytes to int
95
- if (to === PrimitiveType.INT)
96
- return !from.bound || from.bound <= 8;
97
- // Can't cast bytes to bool or string
98
- if (to === PrimitiveType.BOOL)
99
- return false;
100
- if (to === PrimitiveType.STRING)
101
- return false;
102
- // Can cast any bytes to pubkey, sig, datasig
103
- if (to === PrimitiveType.PUBKEY)
104
- return true;
105
- if (to === PrimitiveType.SIG)
106
- return true;
107
- if (to === PrimitiveType.DATASIG)
108
- return true;
109
- return true;
110
- }
111
- return ExplicitlyCastableTo[from].includes(to);
112
- }
113
- exports.explicitlyCastable = explicitlyCastable;
114
- function implicitlyCastable(actual, expected) {
115
- if (!actual || !expected)
116
- return false;
117
- // Tuples can't be cast
118
- if (actual instanceof TupleType || expected instanceof TupleType)
119
- return false;
120
- // Arrays can be cast if their elements can be cast (don't think this is actually used ever)
121
- if (actual instanceof ArrayType && expected instanceof ArrayType) {
122
- return implicitlyCastable(actual.elementType, expected.elementType);
123
- }
124
- // Can't cast between Array and non-Array
125
- if (actual instanceof ArrayType || expected instanceof ArrayType)
126
- return false;
127
- // Anything can be implicitly cast to ANY
128
- if (expected === PrimitiveType.ANY)
129
- return true;
130
- if (expected instanceof BytesType) {
131
- // Can't implicitly cast bool, int, string to bytes
132
- if (actual === PrimitiveType.BOOL)
133
- return false;
134
- if (actual === PrimitiveType.INT)
135
- return false;
136
- if (actual === PrimitiveType.STRING)
137
- return false;
138
- // Can freely cast to unbounded bytes
139
- if (!expected.bound)
140
- return true;
141
- if (actual instanceof BytesType) {
142
- // Cannot implicitly cast from unbounded bytes
143
- if (!actual.bound)
144
- return false;
145
- // Can only cast bounded bytes to bounded bytes if bounds are equal
146
- return actual.bound === expected.bound;
147
- }
148
- // Cannot cast other primitive types directly to bounded bytes types
149
- return false;
150
- }
151
- // Other primitive types can only be implicitly cast to themselves
152
- return actual === expected;
153
- }
154
- exports.implicitlyCastable = implicitlyCastable;
155
- function resultingType(left, right) {
156
- if (implicitlyCastable(left, right))
157
- return right;
158
- if (implicitlyCastable(right, left))
159
- return left;
160
- if (left instanceof BytesType && right instanceof BytesType) {
161
- return new BytesType();
162
- }
163
- return undefined;
164
- }
165
- exports.resultingType = resultingType;
166
- function arrayType(types) {
167
- if (types.length === 0)
168
- return undefined;
169
- let resType = types[0];
170
- types.forEach((t) => {
171
- resType = resultingType(resType, t);
172
- });
173
- return resType;
174
- }
175
- exports.arrayType = arrayType;
176
- function implicitlyCastableSignature(actual, expected) {
177
- if (actual.length !== expected.length)
178
- return false;
179
- return expected.every((t, i) => implicitlyCastable(actual[i], t));
180
- }
181
- exports.implicitlyCastableSignature = implicitlyCastableSignature;
182
- function parseType(str) {
183
- if (str.startsWith('byte'))
184
- return BytesType.fromString(str);
185
- return PrimitiveType[str.toUpperCase()];
186
- }
187
- exports.parseType = parseType;
188
- function isPrimitive(type) {
189
- return !!PrimitiveType[type.toString().toUpperCase()];
190
- }
191
- exports.isPrimitive = isPrimitive;
192
- //# sourceMappingURL=types.js.map
@@ -1,23 +0,0 @@
1
- export interface AbiInput {
2
- name: string;
3
- type: string;
4
- }
5
- export interface AbiFunction {
6
- name: string;
7
- covenant?: boolean;
8
- inputs: AbiInput[];
9
- }
10
- export interface Artifact {
11
- contractName: string;
12
- constructorInputs: AbiInput[];
13
- abi: AbiFunction[];
14
- bytecode: string;
15
- source: string;
16
- compiler: {
17
- name: string;
18
- version: string;
19
- };
20
- updatedAt: string;
21
- }
22
- export declare function importArtifact(artifactFile: string): Artifact;
23
- export declare function exportArtifact(artifact: Artifact, targetFile: string): void;
@@ -1,2 +0,0 @@
1
- declare const _default: "\n# This file can be run with CashProof to prove that the optimisations preserve exact functionality\n# This includes most of CashScript's bytecode optimisations, although some are incompatible with CashProof\n\n# Hardcoded arithmetic\n# OP_NOT OP_IF <=> OP_NOTIF;\nOP_1 OP_ADD <=> OP_1ADD;\nOP_1 OP_SUB <=> OP_1SUB;\nOP_1 OP_NEGATE <=> OP_1NEGATE;\nOP_0 OP_EQUAL OP_NOT <=> OP_0NOTEQUAL;\nOP_NUMEQUAL OP_NOT <=> OP_NUMNOTEQUAL;\nOP_SHA256 OP_SHA256 <=> OP_HASH256;\nOP_SHA256 OP_RIPEMD160 <=> OP_HASH160;\n\n# Hardcoded stack ops\nOP_2 OP_PICK OP_1 OP_PICK OP_3 OP_PICK <=> OP_3DUP OP_SWAP;\nOP_2 OP_PICK OP_2 OP_PICK OP_2 OP_PICK <=> OP_3DUP;\n\nOP_0 OP_PICK OP_2 OP_PICK <=> OP_2DUP OP_SWAP;\nOP_2 OP_PICK OP_4 OP_PICK <=> OP_2OVER OP_SWAP;\nOP_3 OP_PICK OP_3 OP_PICK <=> OP_2OVER;\n\nOP_2 OP_ROLL OP_3 OP_ROLL <=> OP_2SWAP OP_SWAP;\nOP_3 OP_ROLL OP_3 OP_ROLL <=> OP_2SWAP;\nOP_4 OP_ROLL OP_5 OP_ROLL <=> OP_2ROT OP_SWAP;\nOP_5 OP_ROLL OP_5 OP_ROLL <=> OP_2ROT;\n\nOP_0 OP_PICK <=> OP_DUP;\nOP_1 OP_PICK <=> OP_OVER;\nOP_0 OP_ROLL <=> ;\nOP_1 OP_ROLL <=> OP_SWAP;\nOP_2 OP_ROLL <=> OP_ROT;\nOP_DROP OP_DROP <=> OP_2DROP;\n\n# Secondary effects\nOP_DUP OP_SWAP <=> OP_DUP;\nOP_SWAP OP_SWAP <=> ;\nOP_2SWAP OP_2SWAP <=> ;\nOP_ROT OP_ROT OP_ROT <=> ;\nOP_2ROT OP_2ROT OP_2ROT <=> ;\nOP_OVER OP_OVER <=> OP_2DUP;\nOP_DUP OP_DROP <=> ;\nOP_DUP OP_NIP <=> ;\n\n# Enabling secondary effects\nOP_DUP OP_OVER <=> OP_DUP OP_DUP;\n\n# Merge OP_VERIFY\nOP_EQUAL OP_VERIFY <=> OP_EQUALVERIFY;\nOP_NUMEQUAL OP_VERIFY <=> OP_NUMEQUALVERIFY;\nOP_CHECKSIG OP_VERIFY <=> OP_CHECKSIGVERIFY;\n# OP_CHECKMULTISIG OP_VERIFY <=> OP_CHECKMULTISIGVERIFY;\nOP_CHECKDATASIG OP_VERIFY <=> OP_CHECKDATASIGVERIFY;\n\n# Remove/replace extraneous OP_SWAP\n# OP_SWAP OP_AND <=> OP_AND;\n# OP_SWAP OP_OR <=> OP_OR;\n# OP_SWAP OP_XOR <=> OP_XOR;\nOP_SWAP OP_ADD <=> OP_ADD;\nOP_SWAP OP_EQUAL <=> OP_EQUAL;\nOP_SWAP OP_NUMEQUAL <=> OP_NUMEQUAL;\nOP_SWAP OP_NUMNOTEQUAL <=> OP_NUMNOTEQUAL;\nOP_SWAP OP_GREATERTHANOREQUAL <=> OP_LESSTHANOREQUAL;\nOP_SWAP OP_LESSTHANOREQUAL <=> OP_GREATERTHANOREQUAL;\nOP_SWAP OP_GREATERTHAN <=> OP_LESSTHAN;\nOP_SWAP OP_LESSTHAN <=> OP_GREATERTHAN;\nOP_SWAP OP_DROP <=> OP_NIP;\nOP_SWAP OP_NIP <=> OP_DROP;\n\n# Remove/replace extraneous OP_DUP\n# OP_DUP OP_AND <=> ;\n# OP_DUP OP_OR <=> ;\nOP_DUP OP_DROP <=> ;\nOP_DUP OP_NIP <=> ;\n\n# Random optimisations (don't know what I'm targeting with this)\nOP_2DUP OP_DROP <=> OP_OVER;\nOP_2DUP OP_NIP <=> OP_DUP;\nOP_CAT OP_DROP <=> OP_2DROP;\nOP_NIP OP_DROP <=> OP_2DROP;\n\n# Far-fetched stuff\nOP_DUP OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_OVER OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_2 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_3 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_4 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_5 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_6 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_7 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_8 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_9 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_10 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_11 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_12 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_13 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_14 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_15 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\nOP_16 OP_PICK OP_ROT OP_SWAP OP_DROP <=> OP_SWAP;\n\nOP_DUP OP_ROT OP_DROP <=> OP_NIP OP_DUP;\nOP_OVER OP_ROT OP_DROP <=> OP_SWAP;\nOP_2 OP_PICK OP_ROT OP_DROP <=> OP_NIP OP_OVER;\n\nOP_0 OP_NIP <=> OP_DROP OP_0;\nOP_1 OP_NIP <=> OP_DROP OP_1;\nOP_2 OP_NIP <=> OP_DROP OP_2;\nOP_3 OP_NIP <=> OP_DROP OP_3;\nOP_4 OP_NIP <=> OP_DROP OP_4;\nOP_5 OP_NIP <=> OP_DROP OP_5;\nOP_6 OP_NIP <=> OP_DROP OP_6;\nOP_7 OP_NIP <=> OP_DROP OP_7;\nOP_8 OP_NIP <=> OP_DROP OP_8;\nOP_9 OP_NIP <=> OP_DROP OP_9;\nOP_10 OP_NIP <=> OP_DROP OP_10;\nOP_11 OP_NIP <=> OP_DROP OP_11;\nOP_12 OP_NIP <=> OP_DROP OP_12;\nOP_13 OP_NIP <=> OP_DROP OP_13;\nOP_14 OP_NIP <=> OP_DROP OP_14;\nOP_15 OP_NIP <=> OP_DROP OP_15;\nOP_16 OP_NIP <=> OP_DROP OP_16;\n\nOP_2 OP_PICK OP_SWAP OP_2 OP_PICK OP_NIP <=> OP_DROP OP_2DUP;\n";
2
- export default _default;
@@ -1,7 +0,0 @@
1
- export declare function encodeBool(bool: boolean): Uint8Array;
2
- export declare function decodeBool(encodedBool: Uint8Array): boolean;
3
- export declare function encodeInt(int: number | bigint): Uint8Array;
4
- export declare function decodeInt(encodedInt: Uint8Array, maxLength?: number): number;
5
- export declare function encodeString(str: string): Uint8Array;
6
- export declare function decodeString(encodedString: Uint8Array): string;
7
- export declare function placeholder(size: number): Uint8Array;
@@ -1,5 +0,0 @@
1
- export declare function sha512(payload: Uint8Array): Uint8Array;
2
- export declare function sha256(payload: Uint8Array): Uint8Array;
3
- export declare function ripemd160(payload: Uint8Array): Uint8Array;
4
- export declare function hash160(payload: Uint8Array): Uint8Array;
5
- export declare function hash256(payload: Uint8Array): Uint8Array;
@@ -1,5 +0,0 @@
1
- export * from './artifact.js';
2
- export * from './data.js';
3
- export * from './hash.js';
4
- export * from './script.js';
5
- export * from './types.js';
@@ -1,52 +0,0 @@
1
- import { OpcodesBCH } from '@bitauth/libauth';
2
- export declare const Op: typeof OpcodesBCH;
3
- export declare type Op = number;
4
- export declare type OpOrData = Op | Uint8Array;
5
- export declare type Script = OpOrData[];
6
- export declare enum IntrospectionOp {
7
- OP_INPUTINDEX = 192,
8
- OP_ACTIVEBYTECODE = 193,
9
- OP_TXVERSION = 194,
10
- OP_TXINPUTCOUNT = 195,
11
- OP_TXOUTPUTCOUNT = 196,
12
- OP_TXLOCKTIME = 197,
13
- OP_UTXOVALUE = 198,
14
- OP_UTXOBYTECODE = 199,
15
- OP_OUTPOINTTXHASH = 200,
16
- OP_OUTPOINTINDEX = 201,
17
- OP_INPUTBYTECODE = 202,
18
- OP_INPUTSEQUENCENUMBER = 203,
19
- OP_OUTPUTVALUE = 204,
20
- OP_OUTPUTBYTECODE = 205,
21
- OP_UTXOTOKENCATEGORY = 206,
22
- OP_UTXOTOKENCOMMITMENT = 207,
23
- OP_UTXOTOKENAMOUNT = 208,
24
- OP_OUTPUTTOKENCATEGORY = 209,
25
- OP_OUTPUTTOKENCOMMITMENT = 210,
26
- OP_OUTPUTTOKENAMOUNT = 211
27
- }
28
- export declare const introspectionOpMapping: any;
29
- export declare const reverseIntrospectionOpMapping: any;
30
- export declare function scriptToAsm(script: Script): string;
31
- export declare function asmToScript(asm: string): Script;
32
- export declare function scriptToBytecode(script: Script): Uint8Array;
33
- export declare function bytecodeToScript(bytecode: Uint8Array): Script;
34
- export declare function asmToBytecode(asm: string): Uint8Array;
35
- export declare function bytecodeToAsm(bytecode: Uint8Array): string;
36
- export declare function countOpcodes(script: Script): number;
37
- export declare function calculateBytesize(script: Script): number;
38
- export declare function encodeNullDataScript(chunks: OpOrData[]): Uint8Array;
39
- /**
40
- * When cutting out the tx.bytecode preimage variable, the compiler does not know
41
- * the size of the final redeem scrip yet, because the constructor parameters still
42
- * need to get added. Because of this it does not know whether the VarInt is 1 or 3
43
- * bytes. During compilation, an OP_NOP is added at the spot where the bytecode is
44
- * cut out. This function replaces that OP_NOP and adds either 1 or 3 to the cut to
45
- * additionally cut off the VarInt.
46
- *
47
- * @param script incomplete redeem script
48
- * @returns completed redeem script
49
- */
50
- export declare function replaceBytecodeNop(script: Script): Script;
51
- export declare function generateRedeemScript(baseScript: Script, encodedArgs: Script): Script;
52
- export declare function optimiseBytecode(script: Script, runs?: number): Script;
@@ -1,34 +0,0 @@
1
- export declare type Type = PrimitiveType | ArrayType | TupleType | BytesType;
2
- export declare class ArrayType {
3
- elementType: Type;
4
- bound?: number | undefined;
5
- constructor(elementType: Type, bound?: number | undefined);
6
- toString(): string;
7
- }
8
- export declare class BytesType {
9
- bound?: number | undefined;
10
- constructor(bound?: number | undefined);
11
- static fromString(str: string): BytesType;
12
- toString(): string;
13
- }
14
- export declare class TupleType {
15
- elementType?: Type | undefined;
16
- constructor(elementType?: Type | undefined);
17
- toString(): string;
18
- }
19
- export declare enum PrimitiveType {
20
- INT = "int",
21
- BOOL = "bool",
22
- STRING = "string",
23
- PUBKEY = "pubkey",
24
- SIG = "sig",
25
- DATASIG = "datasig",
26
- ANY = "any"
27
- }
28
- export declare function explicitlyCastable(from?: Type, to?: Type): boolean;
29
- export declare function implicitlyCastable(actual?: Type, expected?: Type): boolean;
30
- export declare function resultingType(left?: Type, right?: Type): Type | undefined;
31
- export declare function arrayType(types: Type[]): Type | undefined;
32
- export declare function implicitlyCastableSignature(actual: Type[], expected: Type[]): boolean;
33
- export declare function parseType(str: string): Type;
34
- export declare function isPrimitive(type: Type): type is PrimitiveType;
File without changes
File without changes
File without changes
File without changes
File without changes