scrypt-ts
Advanced tools
Comparing version 0.1.5-beta.4 to 0.1.5-beta.5
import { SigHashType } from "scryptlib"; | ||
import { PubKey, Sig, PubKeyHash, OpCodeType, SigHashPreimage, PrivKey, ByteString } from "./types"; | ||
export { and, xor, or, invert } from "scryptlib/dist/builtins"; | ||
export { getSortedItem } from "scryptlib/dist"; | ||
/** | ||
@@ -5,0 +6,0 @@ * bigint can be converted to string with pack |
"use strict"; | ||
// build-in function | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Constants = exports.Tx = exports.VarIntWriter = exports.VarIntReader = exports.SigHash = exports.Utils = exports.OpCode = exports.asm = exports.rshift = exports.lshift = exports.pow2 = exports.assert = exports.flattenSha256 = exports.hash256 = exports.hash160 = exports.sha256 = exports.sha1 = exports.ripemd160 = exports.within = exports.max = exports.min = exports.abs = exports.exit = exports.checkMultiSig = exports.reverseBytes = exports.len = exports.int2str = exports.unpack = exports.pack = exports.invert = exports.or = exports.xor = exports.and = void 0; | ||
exports.Constants = exports.Tx = exports.VarIntWriter = exports.VarIntReader = exports.SigHash = exports.Utils = exports.OpCode = exports.asm = exports.rshift = exports.lshift = exports.pow2 = exports.assert = exports.flattenSha256 = exports.hash256 = exports.hash160 = exports.sha256 = exports.sha1 = exports.ripemd160 = exports.within = exports.max = exports.min = exports.abs = exports.exit = exports.checkMultiSig = exports.reverseBytes = exports.len = exports.int2str = exports.unpack = exports.pack = exports.getSortedItem = exports.invert = exports.or = exports.xor = exports.and = void 0; | ||
const scryptlib_1 = require("scryptlib"); | ||
@@ -12,2 +12,4 @@ const types_1 = require("./types"); | ||
Object.defineProperty(exports, "invert", { enumerable: true, get: function () { return builtins_1.invert; } }); | ||
var dist_1 = require("scryptlib/dist"); | ||
Object.defineProperty(exports, "getSortedItem", { enumerable: true, get: function () { return dist_1.getSortedItem; } }); | ||
/** | ||
@@ -14,0 +16,0 @@ * bigint can be converted to string with pack |
@@ -1,4 +0,5 @@ | ||
import { Bytes, SigHashPreimage } from "scryptlib"; | ||
import { SubBytes } from "scryptlib/dist/scryptTypes"; | ||
import { Bytes, SigHashPreimage, AbstractContract } from "scryptlib"; | ||
import { SubBytes, SupportedParamType } from "scryptlib/dist/scryptTypes"; | ||
export { PubKey, Sig, SigHashPreimage, PrivKey, Ripemd160, PubKeyHash, Sha256, Sha1, OpCodeType, SigHashType } from "scryptlib"; | ||
export { SubBytes } from "scryptlib/dist/scryptTypes"; | ||
/** | ||
@@ -54,1 +55,51 @@ * @ignore | ||
export declare function equals<T>(a: T, b: T): boolean; | ||
export declare class HashedMap<K extends SupportedParamType, V extends SupportedParamType> { | ||
static readonly H_SIZE = 32n; | ||
static readonly ITEM_SIZE = 64n; | ||
private innerMap; | ||
private _keyType?; | ||
private _valueType?; | ||
private _type?; | ||
private DelegateClazz?; | ||
init(type: string, clazz: typeof AbstractContract): void; | ||
constructor(map: Map<K, V>); | ||
private _checkInOrder; | ||
private _set; | ||
private _canGet; | ||
private _delete; | ||
private _has; | ||
clear(): boolean; | ||
size(): bigint; | ||
data(): ByteString; | ||
set(key: SortedItem<K>, value: V): boolean; | ||
has(key: SortedItem<K>): boolean; | ||
delete(key: SortedItem<K>): boolean; | ||
canGet(key: SortedItem<K>, val: V): boolean; | ||
toMap(): Map<K, V>; | ||
attach(map: Map<K, V>): void; | ||
} | ||
export declare class HashedSet<E extends SupportedParamType> { | ||
innerSet: Set<E>; | ||
static readonly H_SIZE = 32n; | ||
private _elemType?; | ||
private _type?; | ||
private DelegateClazz?; | ||
constructor(set: Set<E>); | ||
init(type: string, clazz: typeof AbstractContract): void; | ||
private _checkInOrder; | ||
private _add; | ||
private _delete; | ||
private _has; | ||
add(key: SortedItem<E>): boolean; | ||
has(key: SortedItem<E>): boolean; | ||
delete(key: SortedItem<E>): boolean; | ||
clear(): boolean; | ||
size(): bigint; | ||
data(): ByteString; | ||
toSet(): Set<E>; | ||
attach(set: Set<E>): void; | ||
} | ||
export declare type SortedItem<T> = { | ||
idx: bigint; | ||
item: T; | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.equals = exports.utf8ToByteString = exports.toByteString = exports.SigHashType = exports.OpCodeType = exports.Sha1 = exports.Sha256 = exports.PubKeyHash = exports.Ripemd160 = exports.PrivKey = exports.SigHashPreimage = exports.Sig = exports.PubKey = void 0; | ||
exports.HashedSet = exports.HashedMap = exports.equals = exports.utf8ToByteString = exports.toByteString = exports.SigHashType = exports.OpCodeType = exports.Sha1 = exports.Sha256 = exports.PubKeyHash = exports.Ripemd160 = exports.PrivKey = exports.SigHashPreimage = exports.Sig = exports.PubKey = void 0; | ||
const scryptlib_1 = require("scryptlib"); | ||
const functions_1 = require("./functions"); | ||
var scryptlib_2 = require("scryptlib"); | ||
@@ -85,2 +86,251 @@ Object.defineProperty(exports, "PubKey", { enumerable: true, get: function () { return scryptlib_2.PubKey; } }); | ||
; | ||
class HashedMap { | ||
constructor(map) { | ||
this.innerMap = map; | ||
} | ||
init(type, clazz) { | ||
const [name, genericTypes] = (0, scryptlib_1.parseGenericType)(type); | ||
this._keyType = genericTypes[0]; | ||
this._valueType = genericTypes[1]; | ||
this.DelegateClazz = clazz; | ||
this._type = type; | ||
} | ||
// compare two bytes' order | ||
_checkInOrder(low, high) { | ||
// Note: low & high are both 256 bits, so they can not be converted to the same number unless they are the same. | ||
// Not working if their size are not equal due to non-minimal number format, ex. unpack('7180') == unpack('710080') | ||
return (0, functions_1.unpack)(low) < (0, functions_1.unpack)(high); | ||
} | ||
// insert / update (`key`, `val`) at `idx`, return false if `idx` is invalid or hash256ed' `key` is not in ascending order | ||
_set(key, val) { | ||
let r = false; | ||
let size = this.size(); | ||
let newKeyHash = this.DelegateClazz?.flattenSha256(key.item, this._keyType); | ||
let newElem = newKeyHash + this.DelegateClazz?.flattenSha256(val, this._valueType); | ||
if (key.idx >= 0n && key.idx <= size) { | ||
let isFirst = key.idx == 0n; | ||
let isLast = key.idx >= size - 1n; // idx == size if appending | ||
let before = isFirst ? toByteString("") : this.data().slice(0, Number(key.idx * HashedMap.ITEM_SIZE) * 2); | ||
let curElem = key.idx == size ? toByteString("") : this.data().slice(Number(key.idx * HashedMap.ITEM_SIZE) * 2, Number(key.idx * HashedMap.ITEM_SIZE + HashedMap.ITEM_SIZE) * 2); | ||
let curKeyHash = curElem == toByteString("") ? toByteString("") : curElem.slice(0, Number(HashedMap.H_SIZE) * 2); | ||
let after = isLast ? toByteString("") : this.data().slice(Number((key.idx + 1n) * HashedMap.ITEM_SIZE) * 2); | ||
// check prevKeyHash < newKeyHash && newKeyHash < afterKeyHash | ||
if ((isFirst || this._checkInOrder(before.slice(Number((key.idx - 1n) * HashedMap.ITEM_SIZE) * 2, Number((key.idx - 1n) * HashedMap.ITEM_SIZE + HashedMap.H_SIZE) * 2), newKeyHash)) && | ||
(isLast || this._checkInOrder(newKeyHash, after.slice(0, Number(HashedMap.H_SIZE) * 2)))) { | ||
if (curKeyHash == newKeyHash) { | ||
// update current element if key hashes matches | ||
r = true; | ||
} | ||
else if (curKeyHash == toByteString("") || this._checkInOrder(newKeyHash, curKeyHash)) { | ||
// insert new element before current if newKeyHash < curKeyHash or curKeyHash not exists | ||
r = true; | ||
} | ||
} | ||
} | ||
return r; | ||
} | ||
// check whether if (`key`,`val`) exists at `idx` | ||
_canGet(key, val) { | ||
let r = false; | ||
if (key.idx >= 0n && key.idx < this.size()) { | ||
let startPos = key.idx * HashedMap.ITEM_SIZE; | ||
let k = this.data().slice(Number(startPos) * 2, Number(startPos + HashedMap.H_SIZE) * 2); | ||
let v = this.data().slice(Number(startPos + HashedMap.H_SIZE) * 2, Number(startPos + HashedMap.ITEM_SIZE) * 2); | ||
r = this.DelegateClazz?.flattenSha256(key.item, this._keyType) == k && this.DelegateClazz.flattenSha256(val, this._valueType) == v; | ||
} | ||
return r; | ||
} | ||
// delete `key` which at `idx` from map | ||
_delete(key) { | ||
let r = false; | ||
if (key.idx >= 0 && key.idx < this.size()) { | ||
let startPos = key.idx * HashedMap.ITEM_SIZE; | ||
let k = this.data().slice(Number(startPos) * 2, Number(startPos + HashedMap.H_SIZE) * 2); | ||
if (this.DelegateClazz?.flattenSha256(key.item, this._keyType) == k) { | ||
r = true; | ||
} | ||
} | ||
return r; | ||
} | ||
// check whether has `key` at `idx` | ||
_has(key) { | ||
let r = false; | ||
if (key.idx >= 0 && key.idx < this.size()) { | ||
let startPos = key.idx * HashedMap.ITEM_SIZE; | ||
let k = this.data().slice(Number(startPos) * 2, Number(startPos + HashedMap.H_SIZE) * 2); | ||
r = this.DelegateClazz?.flattenSha256(key.item, this._keyType) == k; | ||
} | ||
return r; | ||
} | ||
// delete all | ||
clear() { | ||
this.innerMap = new Map(); | ||
return true; | ||
} | ||
// return map size | ||
size() { | ||
return BigInt((0, functions_1.len)(this.data())) / HashedMap.ITEM_SIZE; | ||
} | ||
// return the underlaying data storage | ||
data() { | ||
return this.DelegateClazz?.toData(this.innerMap, this._type); | ||
} | ||
set(key, value) { | ||
if (this.DelegateClazz && this._keyType && this._valueType) { | ||
if (this._set(key, value)) { | ||
this.innerMap.set(key.item, value); | ||
return true; | ||
} | ||
return false; | ||
} | ||
this.innerMap.set(key.item, value); | ||
return true; | ||
} | ||
has(key) { | ||
if (this.DelegateClazz && this._keyType && this._valueType) { | ||
return this._has(key); | ||
} | ||
return this.innerMap.has(key.item); | ||
} | ||
delete(key) { | ||
if (this.DelegateClazz && this._keyType && this._valueType) { | ||
if (this._delete(key)) { | ||
return this.innerMap.delete(key.item); | ||
} | ||
else { | ||
return false; | ||
} | ||
} | ||
return this.innerMap.delete(key.item); | ||
} | ||
canGet(key, val) { | ||
if (this.DelegateClazz && this._keyType && this._valueType) { | ||
return this._canGet(key, val); | ||
} | ||
return (this.innerMap.get(key.item) === val); | ||
} | ||
toMap() { | ||
return this.innerMap; | ||
} | ||
attach(map) { | ||
this.innerMap = new Map(map); | ||
} | ||
} | ||
exports.HashedMap = HashedMap; | ||
HashedMap.H_SIZE = 32n; // hash256'ed key/value size, 32 bytes | ||
HashedMap.ITEM_SIZE = 64n; // 2 * H_SIZE | ||
class HashedSet { | ||
constructor(set) { | ||
this.innerSet = set; | ||
} | ||
init(type, clazz) { | ||
const [name, genericTypes] = (0, scryptlib_1.parseGenericType)(type); | ||
this._type = type; | ||
this._elemType = genericTypes[0]; | ||
this.DelegateClazz = clazz; | ||
} | ||
// compare two bytes' order | ||
_checkInOrder(low, high) { | ||
// Note: low & high are both 256 bits, so they can not be converted to the same number unless they are the same. | ||
// Not working if their size are not equal due to non-minimal number format, ex. unpack('7180') == unpack('710080') | ||
return (0, functions_1.unpack)(low) < (0, functions_1.unpack)(high); | ||
} | ||
// add / update element `elem` at `idx`, return false if `idx` is invalid or hash256ed' `elem` is not in ascending order | ||
_add(elem) { | ||
let r = false; | ||
let size = this.size(); | ||
let newHash = this.DelegateClazz?.flattenSha256(elem.item, this._elemType); | ||
if (elem.idx >= 0 && elem.idx <= size) { | ||
let isFirst = elem.idx == 0n; | ||
let isLast = elem.idx >= size - 1n; // idx == size if appending | ||
let before = isFirst ? toByteString("") : this.data().slice(0, Number(elem.idx * HashedSet.H_SIZE) * 2); | ||
let curHash = elem.idx == size ? toByteString("") : this.data().slice(Number(elem.idx * HashedSet.H_SIZE) * 2, Number(elem.idx * HashedSet.H_SIZE + HashedSet.H_SIZE) * 2); | ||
let after = isLast ? toByteString("") : this.data().slice(Number((elem.idx + 1n) * HashedSet.H_SIZE) * 2); | ||
// check prevHash < newHash && newHash < afterHash | ||
if ((isFirst || this._checkInOrder(before.slice(Number((elem.idx - 1n) * HashedSet.H_SIZE) * 2, Number((elem.idx - 1n) * HashedSet.H_SIZE + HashedSet.H_SIZE) * 2), newHash)) && | ||
(isLast || this._checkInOrder(newHash, after.slice(0, Number(HashedSet.H_SIZE) * 2)))) { | ||
if (curHash == newHash) { | ||
// duplicated adding | ||
r = true; | ||
} | ||
else if (curHash == toByteString("") || this._checkInOrder(newHash, curHash)) { | ||
// insert new element before current if newHash < curHash or curHash not exists | ||
r = true; | ||
} | ||
} | ||
} | ||
return r; | ||
} | ||
// delete `elem` which at `idx` from set | ||
_delete(elem) { | ||
let r = false; | ||
if (elem.idx >= 0 && elem.idx < this.size()) { | ||
let startPos = elem.idx * HashedSet.H_SIZE; | ||
let v = this.data().slice(Number(startPos) * 2, Number(startPos + HashedSet.H_SIZE) * 2); | ||
if (this.DelegateClazz?.flattenSha256(elem.item, this._elemType) == v) { | ||
r = true; | ||
} | ||
} | ||
return r; | ||
} | ||
// check whether has `elem` at `idx` | ||
_has(elem) { | ||
let r = false; | ||
if (elem.idx >= 0 && elem.idx < this.size()) { | ||
let startPos = elem.idx * HashedSet.H_SIZE; | ||
let v = this.data().slice(Number(startPos) * 2, Number(startPos + HashedSet.H_SIZE) * 2); | ||
r = this.DelegateClazz?.flattenSha256(elem.item, this._elemType) == v; | ||
} | ||
return r; | ||
} | ||
add(key) { | ||
if (this.DelegateClazz && this._elemType) { | ||
if (this._add(key)) { | ||
this.innerSet.add(key.item); | ||
return true; | ||
} | ||
return false; | ||
} | ||
this.innerSet.add(key.item); | ||
return true; | ||
} | ||
has(key) { | ||
if (this.DelegateClazz && this._elemType) { | ||
return this._has(key); | ||
} | ||
return this.innerSet.has(key.item); | ||
} | ||
delete(key) { | ||
if (this.DelegateClazz && this._elemType) { | ||
if (this._delete(key)) { | ||
return this.innerSet.delete(key.item); | ||
} | ||
else { | ||
return false; | ||
} | ||
} | ||
return this.innerSet.delete(key.item); | ||
} | ||
// delete all | ||
clear() { | ||
this.innerSet = new Set(); | ||
return true; | ||
} | ||
// return set size | ||
size() { | ||
return BigInt((0, functions_1.len)(this.data())) / HashedSet.H_SIZE; | ||
} | ||
// return the underlaying data storage | ||
data() { | ||
return this.DelegateClazz?.toData(this.innerSet, this._type); | ||
} | ||
toSet() { | ||
return this.innerSet; | ||
} | ||
attach(set) { | ||
this.innerSet = new Set(set); | ||
} | ||
} | ||
exports.HashedSet = HashedSet; | ||
HashedSet.H_SIZE = 32n; // hash256'ed elem size, 32 bytes | ||
//# sourceMappingURL=types.js.map |
import "reflect-metadata"; | ||
import { VerifyResult, bsv, ContractDescription } from "scryptlib"; | ||
import { VerifyResult, bsv, ContractArtifact, SupportedParamType } from "scryptlib"; | ||
import { SigHashPreimage, SigHashType, Sig, PubKey, PrivKey, ByteString } from "./builtins/types"; | ||
import { TranspileError } from "./transpiler"; | ||
/** | ||
@@ -63,2 +64,13 @@ * A reference to an input of a transaction | ||
/** | ||
* DebugFunctions contains a set of functions for debugging contracts at runtime. | ||
* All debugging functions will not affect the execution results of the contract. | ||
*/ | ||
interface DebugFunctions { | ||
/** | ||
* Compare the difference between the outputs argument and all the outputs of the transaction bound by `this.unlockFrom`, | ||
* which are serialized and hashed to produce `this.ctx.hashOutputs`. | ||
*/ | ||
diffOutputs: (outputs: ByteString) => void; | ||
} | ||
/** | ||
* The main contract class. To write a contract, extend this class as such: | ||
@@ -79,7 +91,8 @@ * @example | ||
private delegateInstance; | ||
static compile(): Promise<void>; | ||
static loadDesc(desc: ContractDescription): void; | ||
static compile(): Promise<TranspileError[] | undefined>; | ||
static loadArtifact(artifact: ContractArtifact): void; | ||
private static _getTransform; | ||
private static _getScryptFile; | ||
private static _getCtxMethods; | ||
getCtxMethods(): string; | ||
getCtxMethods(): string[]; | ||
private getDelegateClazz; | ||
@@ -128,2 +141,6 @@ constructor(...args: any[]); | ||
set lockTo(ref: TxOutputRef); | ||
static findKeyIndex(collection: Map<SupportedParamType, SupportedParamType> | Set<SupportedParamType>, key: SupportedParamType, keyType?: string): bigint; | ||
private diffOutputs; | ||
get debug(): DebugFunctions; | ||
} | ||
export {}; |
@@ -41,2 +41,3 @@ "use strict"; | ||
const typeCheck_1 = require("scryptlib/dist/typeCheck"); | ||
const diffUtils_1 = require("./diffUtils"); | ||
/** | ||
@@ -57,8 +58,20 @@ * The main contract class. To write a contract, extend this class as such: | ||
if (!DelegateClazz) { | ||
throw new Error(`'${this.constructor.name}.compile' or '${this.constructor.name}.loadDesc' should be called before initializing any instance!`); | ||
throw new Error(`'${this.constructor.name}.compile' or '${this.constructor.name}.loadArtifact' should be called before initializing any instance!`); | ||
} | ||
const args_ = args.map(arg => { | ||
const args_ = args.map((arg, index) => { | ||
if (arg instanceof library_1.SmartContractLib) { | ||
return arg.getArgs(); | ||
} | ||
else if (arg instanceof types_1.HashedMap) { | ||
const ctorAbi = DelegateClazz.abi.find(abi => abi.type === scryptlib_1.ABIEntityType.CONSTRUCTOR); | ||
const type = ctorAbi.params[index].type; | ||
arg.init(type, DelegateClazz); | ||
return arg.toMap(); | ||
} | ||
else if (arg instanceof types_1.HashedSet) { | ||
const ctorAbi = DelegateClazz.abi.find(abi => abi.type === scryptlib_1.ABIEntityType.CONSTRUCTOR); | ||
const type = ctorAbi.params[index].type; | ||
arg.init(type, DelegateClazz); | ||
return arg.toSet(); | ||
} | ||
return arg; | ||
@@ -70,2 +83,6 @@ }); | ||
static async compile() { | ||
const transform = this._getTransform(); | ||
if (!transform.success) { | ||
return transform.errors; | ||
} | ||
const tmpDir = fs.mkdtempSync((0, path_1.join)((0, os_1.tmpdir)(), "scrypt-ts-")); | ||
@@ -75,3 +92,3 @@ let filePath = this._getScryptFile(); | ||
sourceMap: true, | ||
desc: true, | ||
artifact: true, | ||
out: tmpDir | ||
@@ -83,5 +100,6 @@ }); | ||
else { | ||
const descFile = fs.readdirSync(tmpDir).filter(fn => fn.endsWith('_desc.json'))[0]; | ||
if (descFile) { | ||
fs.copyFileSync((0, path_1.join)(tmpDir, descFile), (0, path_1.join)((0, path_1.dirname)(filePath), descFile)); | ||
const artifactFileName = (0, path_1.basename)(filePath).replace('.scrypt', '.json'); | ||
const artifactFile = fs.readdirSync(tmpDir).filter(fn => fn == artifactFileName)[0]; | ||
if (artifactFile) { | ||
fs.copyFileSync((0, path_1.join)(tmpDir, artifactFile), (0, path_1.join)((0, path_1.dirname)(filePath), artifactFile)); | ||
} | ||
@@ -91,13 +109,28 @@ } | ||
} | ||
static loadDesc(desc) { | ||
static loadArtifact(artifact) { | ||
let filePath = this._getScryptFile(); | ||
const sourceContent = fs.readFileSync(filePath, 'utf8'); | ||
const md5Hash = (0, scryptlib_1.md5)(sourceContent); | ||
if (this.name !== desc.contract || desc.md5 !== md5Hash) { | ||
throw new Error(`Contract description file cannot match contract \`${this.name}\`!`); | ||
if (this.name !== artifact.contract || artifact.md5 !== md5Hash) { | ||
throw new Error(`Contract artifact file cannot match contract \`${this.name}\`!`); | ||
} | ||
this.DelegateClazz = (0, scryptlib_1.buildContractClass)(desc); | ||
this.DelegateClazz = (0, scryptlib_1.buildContractClass)(artifact); | ||
} | ||
static _getTransform() { | ||
let transformFile = Reflect.getMetadata("scrypt:transform", this); | ||
if (!transformFile) { | ||
throw new Error('the ts-scrypt transformer plugin may not be activated for the project, check your `tsconfig` file!'); | ||
} | ||
let srcFile = Reflect.getMetadata("__filename", this); | ||
let indexFile = indexer_1.Indexer.queryIndexFile(srcFile, process.cwd()); | ||
if (!indexFile) { | ||
throw new Error(`can not find \`scrypt.index.json\` file for contract \`${this.name}\`, search path from ${srcFile} to ${process.cwd()}`); | ||
} | ||
let indexer = new indexer_1.Indexer(indexFile); | ||
let filePath = indexer.getFullPath(transformFile); | ||
return JSON.parse(fs.readFileSync(filePath).toString()); | ||
} | ||
static _getScryptFile() { | ||
let scryptFile = Reflect.getMetadata("scrypt:file", this); | ||
let transform = this._getTransform(); | ||
let scryptFile = transform.scryptfile; | ||
if (!scryptFile) { | ||
@@ -119,3 +152,4 @@ throw new Error('the ts-scrypt transformer plugin may not be activated for the project, check your `tsconfig` file!'); | ||
static _getCtxMethods() { | ||
return Reflect.getMetadata("scrypt:ctxMethods", this); | ||
let transform = this._getTransform(); | ||
return transform.ctxMethods; | ||
} | ||
@@ -177,2 +211,8 @@ getCtxMethods() { | ||
} | ||
else if (this[statePropKey] instanceof types_1.HashedMap) { | ||
this.delegateInstance[statePropKey] = this[statePropKey].toMap(); | ||
} | ||
else if (this[statePropKey] instanceof types_1.HashedSet) { | ||
this.delegateInstance[statePropKey] = this[statePropKey].toSet(); | ||
} | ||
else { | ||
@@ -218,4 +258,10 @@ this.delegateInstance[statePropKey] = this[statePropKey]; | ||
.forEach(p => { | ||
let value = this[p.name]; | ||
if (value instanceof types_1.HashedMap || value instanceof types_1.HashedSet) { | ||
value = { | ||
_data: value.data() | ||
}; | ||
} | ||
(0, typeCheck_1.flatternArg)(Object.assign({}, p, { | ||
value: this[p.name] | ||
value: value | ||
}), this.delegateInstance.resolver, { | ||
@@ -337,3 +383,6 @@ state: true, | ||
&& abi.params[abi.params.length - 1].type === "SigHashPreimage") { | ||
const txPreimage = (0, types_1.SigHashPreimage)(this._unlockFrom.tx.getPreimage(this._unlockFrom.inputIndex)); | ||
if (!this.unlockFrom) { | ||
throw new Error('unlockFrom should be set'); | ||
} | ||
const txPreimage = (0, types_1.SigHashPreimage)(this.unlockFrom.tx.getPreimage(this._unlockFrom.inputIndex)); | ||
args.push(txPreimage); | ||
@@ -400,4 +449,43 @@ } | ||
} | ||
static findKeyIndex(collection, key, keyType) { | ||
if (!keyType) { | ||
switch (typeof key) { | ||
case 'bigint': | ||
keyType = 'int'; | ||
break; | ||
case 'string': | ||
keyType = 'bytes'; | ||
break; | ||
case 'boolean': | ||
keyType = 'bool'; | ||
break; | ||
default: | ||
throw new Error('Struct or Array need to explicitly specify the type.'); | ||
} | ||
} | ||
return this.DelegateClazz.findKeyIndex(collection, key, keyType); | ||
} | ||
diffOutputs(outputs) { | ||
if (!this.unlockFrom) { | ||
throw new Error('unlockFrom should be set'); | ||
} | ||
try { | ||
const info = (0, diffUtils_1.diffOutputs)(this.delegateInstance, outputs, this.unlockFrom.tx); | ||
console.info(info); | ||
} | ||
catch (e) { | ||
console.log(e); | ||
throw new Error('diffOutputs error'); | ||
} | ||
} | ||
get debug() { | ||
const self = this; | ||
return { | ||
diffOutputs: (outputs) => { | ||
self.diffOutputs(outputs); | ||
} | ||
}; | ||
} | ||
} | ||
exports.SmartContract = SmartContract; | ||
//# sourceMappingURL=contract.js.map |
@@ -47,2 +47,5 @@ "use strict"; | ||
} | ||
if (this.entryMethodCall) { | ||
args = this.entryMethodCall.args.map(a => a.value); | ||
} | ||
} | ||
@@ -49,0 +52,0 @@ return originalMethod.apply(this, args); |
@@ -10,2 +10,2 @@ import { prop, method } from './decorators'; | ||
export declare type UTXO = bsv.Transaction.IUnspentOutput; | ||
export { bsv, toHex, buildPublicKeyHashScript, buildOpreturnScript, ContractDescription, TxContext, VerifyResult, FunctionCall } from 'scryptlib'; | ||
export { bsv, toHex, buildPublicKeyHashScript, buildOpreturnScript, ContractArtifact, TxContext, VerifyResult, FunctionCall } from 'scryptlib'; |
@@ -115,3 +115,4 @@ "use strict"; | ||
const scryptFile = root2srcRelativePath.replace(/\.ts$/, '.scrypt').replaceAll('\\', '/'); | ||
let transpiler = new transpiler_1.Transpiler(sourceFile, checker, scryptOutDir, scryptFile, indexer); | ||
const transformFile = root2srcRelativePath.replace(/\.ts$/, '.transformer.json').replaceAll('\\', '/'); | ||
let transpiler = new transpiler_1.Transpiler(sourceFile, checker, scryptOutDir, scryptFile, transformFile, indexer); | ||
if (!transpiler.isTransformable()) { | ||
@@ -129,3 +130,3 @@ return sourceFile; | ||
pos: classNode.end + 1, | ||
code: `Reflect.defineMetadata("scrypt:file", "${scryptFile}", ${className});Reflect.defineMetadata("__filename", __filename, ${className});Reflect.defineMetadata("scrypt:ctxMethods", "${transpiler.ctxMethods.join(',')}", ${className});` | ||
code: `Reflect.defineMetadata("scrypt:transform", "${transformFile}", ${className});Reflect.defineMetadata("__filename", __filename, ${className});` | ||
}); | ||
@@ -132,0 +133,0 @@ } |
@@ -30,2 +30,9 @@ import * as ts from 'typescript'; | ||
} | ||
export declare type TransformInfo = { | ||
success: boolean; | ||
errors: TranspileError[]; | ||
scryptfile: string; | ||
sourceMapFile: string; | ||
ctxMethods: string[]; | ||
}; | ||
export declare class Transpiler { | ||
@@ -39,12 +46,15 @@ scComponents: ts.ClassDeclaration[]; | ||
_outFilePath: string; | ||
_transformFile: string; | ||
_outTransformFilePath: string; | ||
_indexer: Indexer; | ||
_existsStateProp: boolean; | ||
_ctxMethods: Array<string>; | ||
_localTypeSymbols: Map<string, ts.Symbol>; | ||
_importedTypeSymbols: Map<string, ts.Symbol>; | ||
constructor(sourceFile: ts.SourceFile, checker: ts.TypeChecker, scryptOutDir: string, scryptOutFile: string, indexer: Indexer); | ||
constructor(sourceFile: ts.SourceFile, checker: ts.TypeChecker, scryptOutDir: string, scryptOutFile: string, transformFile: string, indexer: Indexer); | ||
get ctxMethods(): string[]; | ||
get _sourceMapFile(): string; | ||
transform(): EmittedSection; | ||
isTransformable(): boolean; | ||
private outputScrypt; | ||
private outputTransform; | ||
private diagnose; | ||
@@ -57,2 +67,3 @@ private outputDiagnostic; | ||
private isExtendsSCComponent; | ||
private isHashedMapOrHashedSet; | ||
private searchSmartContractComponents; | ||
@@ -68,2 +79,6 @@ private getCoordinates; | ||
private transformMethodDeclaration; | ||
private isAssertStatement; | ||
private hasAccessCtx; | ||
private hasAccessStateProperty; | ||
private shouldAutoAppendSighashPreimage; | ||
private transformParameter; | ||
@@ -75,4 +90,17 @@ private transformStatement; | ||
private transformModifiers; | ||
isCTCProperty(node: ts.HasModifiers): boolean; | ||
isPublic(node: ts.HasModifiers): boolean; | ||
private findDecorator; | ||
private isProperty; | ||
private isNonProp; | ||
private isStateProperty; | ||
private isStatePropertyReferences; | ||
private getClassDeclaration; | ||
private isNonPropReferences; | ||
private existsStatePropertyDeclaration; | ||
private allPropertyDeclaration; | ||
private isCTC; | ||
private transformCTC; | ||
private queryPropertyInitializedInStmt; | ||
private hasProperties; | ||
private hasConstructor; | ||
private checkConstructor; | ||
private transformImports; | ||
@@ -79,0 +107,0 @@ private transformTypeLiteralAndInterfaces; |
@@ -10,1 +10,3 @@ import * as ts from 'typescript'; | ||
export declare function number2hex(val: number | bigint): string; | ||
export declare function hasModifier(node: ts.Node, ...kinds: Array<ts.Modifier['kind']>): boolean; | ||
export declare function isNumberLiteralExpr(expr: ts.Node | undefined): boolean; |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.number2hex = exports.getBuildInType = exports.getPreimage = exports.signTx = void 0; | ||
exports.isNumberLiteralExpr = exports.hasModifier = exports.number2hex = exports.getBuildInType = exports.getPreimage = exports.signTx = void 0; | ||
const ts = __importStar(require("typescript")); | ||
var scryptlib_1 = require("scryptlib"); | ||
@@ -42,2 +66,24 @@ Object.defineProperty(exports, "signTx", { enumerable: true, get: function () { return scryptlib_1.signTx; } }); | ||
exports.number2hex = number2hex; | ||
function hasModifier(node, ...kinds) { | ||
if (ts.canHaveModifiers(node)) { | ||
let modifiers = ts.getModifiers(node); | ||
if (typeof modifiers === 'undefined') { | ||
return false; | ||
} | ||
for (const modifier of modifiers) | ||
if (kinds.includes(modifier.kind)) | ||
return true; | ||
} | ||
return false; | ||
} | ||
exports.hasModifier = hasModifier; | ||
function isNumberLiteralExpr(expr) { | ||
if (expr === undefined) | ||
return false; | ||
if (ts.isNumericLiteral(expr) || ts.isBigIntLiteral(expr)) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
exports.isNumberLiteralExpr = isNumberLiteralExpr; | ||
//# sourceMappingURL=utils.js.map |
{ | ||
"name": "scrypt-ts", | ||
"version": "0.1.5-beta.4", | ||
"version": "0.1.5-beta.5", | ||
"description": "A toolset for building sCrypt smart contract applications on Bitcoin SV network written in typescript.", | ||
@@ -11,3 +11,3 @@ "main": "dist/index.js", | ||
"gendocs": "typedoc --readme none --plugin typedoc-plugin-markdown --out scryptTS-docs src/index.ts", | ||
"clean-test-out": "rimraf test/scrypt.index.json && rimraf test/out && rimraf test/scrypts", | ||
"clean-test-out": "rimraf test/scrypt.index.json && rimraf test/out && rimraf test/artifacts", | ||
"pretest": "npm run build && npm run clean-test-out && cross-env TS_NODE_PROJECT=test/tsconfig.json NODE_ENV=test tsc -p test", | ||
@@ -36,2 +36,3 @@ "test": "cd test && mocha 'out/test/local/**/*.test.js' --timeout 1200000", | ||
"chai": "^4.3.6", | ||
"chai-exclude": "^2.1.0", | ||
"cross-env": "^7.0.3", | ||
@@ -50,5 +51,6 @@ "dotenv": "^16.0.3", | ||
"@phenomnomnominal/tsquery": "^5.0.0", | ||
"fast-diff": "^1.2.0", | ||
"lodash.clonedeep": "^4.5.0", | ||
"reflect-metadata": "^0.1.13", | ||
"scryptlib": "=2.0.0-beta.3", | ||
"scryptlib": "=2.0.3", | ||
"sourcemap-codec": "^1.4.8", | ||
@@ -55,0 +57,0 @@ "ts-patch": "^2.0.2", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
226711
33
4870
8
18
+ Addedfast-diff@^1.2.0
+ Addedfast-diff@1.3.0(transitive)
Updatedscryptlib@=2.0.3