diff --git a/package-lock.json b/package-lock.json index 948f5032..2c69033e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,7 @@ "mocha": "^10.1.0", "prettier": "^2.8.2", "rimraf": "^3.0.2", - "scrypt-cli": "^0.1.72", + "scrypt-cli": "^0.1.73", "ts-node": "^10.9.1", "typescript": "^5.3.3" } @@ -4534,9 +4534,9 @@ ] }, "node_modules/scrypt-cli": { - "version": "0.1.72", - "resolved": "https://registry.npmjs.org/scrypt-cli/-/scrypt-cli-0.1.72.tgz", - "integrity": "sha512-jLfewoDSnmKWeoliQ7GjP9VeCbfkUjIaxBDalGabpzwb2BA4QVvVVbQIlHBz+bh2jK8NlK1/Gi7RjQJqPPpGsw==", + "version": "0.1.73", + "resolved": "https://registry.npmjs.org/scrypt-cli/-/scrypt-cli-0.1.73.tgz", + "integrity": "sha512-tH0dm/d+WuOd5gQ+jk+e6m2BXboNVolHVCgIjsLqdWhybKlmKKZ+QCqcpVFLGCnFy6UAOIG4NEZLAaKvREe0sg==", "dev": true, "dependencies": { "axios": "^1.3.6", @@ -4552,7 +4552,7 @@ "json5": "^2.2.2", "lodash": "^4.17.21", "ora": "^5.4.1", - "scrypt-ts-transpiler": "^1.2.20", + "scrypt-ts-transpiler": "^1.2.21", "scryptlib": "^2.1.41", "semver": "^7.3.8", "shelljs": "^0.8.5", @@ -4761,15 +4761,15 @@ } }, "node_modules/scrypt-ts-transpiler": { - "version": "1.2.20", - "resolved": "https://registry.npmjs.org/scrypt-ts-transpiler/-/scrypt-ts-transpiler-1.2.20.tgz", - "integrity": "sha512-fYS11B9W8NOzGoCeQ/ORFrmRPuZEo1NZEGt0HXpgivPsQB873q+p/bcBXCBrfWzN7cesfMYU9IoNYPHcNGcvlA==", + "version": "1.2.21", + "resolved": "https://registry.npmjs.org/scrypt-ts-transpiler/-/scrypt-ts-transpiler-1.2.21.tgz", + "integrity": "sha512-jGUiYwvRnDT9+7yV+v/L4NeUKpXTC0jkMabFpX/Cio0U0nuFHn0dJlbSaSbhKDmt2LcInQgwEjeu2t2lxlOy/A==", "dev": true, "hasInstallScript": true, "dependencies": { "@phenomnomnominal/tsquery": "^6.1.2", "reflect-metadata": "^0.1.13", - "scryptlib": "^2.1.25", + "scryptlib": "^2.1.41", "ts-patch": "^3.0.1", "typescript": "^5.3.3" }, @@ -9203,9 +9203,9 @@ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "scrypt-cli": { - "version": "0.1.72", - "resolved": "https://registry.npmjs.org/scrypt-cli/-/scrypt-cli-0.1.72.tgz", - "integrity": "sha512-jLfewoDSnmKWeoliQ7GjP9VeCbfkUjIaxBDalGabpzwb2BA4QVvVVbQIlHBz+bh2jK8NlK1/Gi7RjQJqPPpGsw==", + "version": "0.1.73", + "resolved": "https://registry.npmjs.org/scrypt-cli/-/scrypt-cli-0.1.73.tgz", + "integrity": "sha512-tH0dm/d+WuOd5gQ+jk+e6m2BXboNVolHVCgIjsLqdWhybKlmKKZ+QCqcpVFLGCnFy6UAOIG4NEZLAaKvREe0sg==", "dev": true, "requires": { "axios": "^1.3.6", @@ -9221,7 +9221,7 @@ "json5": "^2.2.2", "lodash": "^4.17.21", "ora": "^5.4.1", - "scrypt-ts-transpiler": "^1.2.20", + "scrypt-ts-transpiler": "^1.2.21", "scryptlib": "^2.1.41", "semver": "^7.3.8", "shelljs": "^0.8.5", @@ -9380,14 +9380,14 @@ } }, "scrypt-ts-transpiler": { - "version": "1.2.20", - "resolved": "https://registry.npmjs.org/scrypt-ts-transpiler/-/scrypt-ts-transpiler-1.2.20.tgz", - "integrity": "sha512-fYS11B9W8NOzGoCeQ/ORFrmRPuZEo1NZEGt0HXpgivPsQB873q+p/bcBXCBrfWzN7cesfMYU9IoNYPHcNGcvlA==", + "version": "1.2.21", + "resolved": "https://registry.npmjs.org/scrypt-ts-transpiler/-/scrypt-ts-transpiler-1.2.21.tgz", + "integrity": "sha512-jGUiYwvRnDT9+7yV+v/L4NeUKpXTC0jkMabFpX/Cio0U0nuFHn0dJlbSaSbhKDmt2LcInQgwEjeu2t2lxlOy/A==", "dev": true, "requires": { "@phenomnomnominal/tsquery": "^6.1.2", "reflect-metadata": "^0.1.13", - "scryptlib": "^2.1.25", + "scryptlib": "^2.1.41", "ts-patch": "^3.0.1", "typescript": "^5.3.3" } diff --git a/package.json b/package.json index 9d619550..b554829b 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "mocha": "^10.1.0", "prettier": "^2.8.2", "rimraf": "^3.0.2", - "scrypt-cli": "^0.1.72", + "scrypt-cli": "^0.1.73", "ts-node": "^10.9.1", "typescript": "^5.3.3" } diff --git a/src/contracts/enum.ts b/src/contracts/enum.ts new file mode 100644 index 00000000..264a6473 --- /dev/null +++ b/src/contracts/enum.ts @@ -0,0 +1,61 @@ +import { + method, + prop, + SmartContract, + assert, + hash256, + SigHash, +} from 'scrypt-ts' + +// Enum representing shipping status +// Pending - 0 +// Shipped - 1 +// Accepted - 2 +// Rejected - 3 +// Canceled - 4 +export enum Status { + Pending, + Shipped, + Accepted, + Rejected, + Canceled, +} + +export class Enum extends SmartContract { + @prop(true) + status: Status + + constructor() { + super(...arguments) + this.status = Status.Pending + } + + @method() + get(): Status { + return this.status + } + + // Update status by passing uint into input + @method() + set(status: Status): void { + this.status = status + } + + @method(SigHash.ANYONECANPAY_SINGLE) + public unlock() { + let s = this.get() + assert(s == Status.Pending, 'invalid stauts') + + this.set(Status.Accepted) + + s = this.get() + + assert(s == Status.Accepted, 'invalid stauts') + + assert( + this.ctx.hashOutputs == + hash256(this.buildStateOutput(this.ctx.utxo.value)), + 'hashOutputs check failed' + ) + } +} diff --git a/tests/counter.test.ts b/tests/counter.test.ts index 22a92996..00055764 100644 --- a/tests/counter.test.ts +++ b/tests/counter.test.ts @@ -1,8 +1,11 @@ -import { expect } from 'chai' +import { expect, use } from 'chai' import { Counter } from '../src/contracts/counter' import { getDefaultSigner } from './utils/helper' import { MethodCallOptions } from 'scrypt-ts' +import chaiAsPromised from 'chai-as-promised' +use(chaiAsPromised) + describe('Test SmartContract `Counter`', () => { before(() => { Counter.loadArtifact() diff --git a/tests/enum.test.ts b/tests/enum.test.ts new file mode 100644 index 00000000..7ba43411 --- /dev/null +++ b/tests/enum.test.ts @@ -0,0 +1,37 @@ +import { expect, use } from 'chai' +import { Enum, Status } from '../src/contracts/enum' +import { getDefaultSigner } from './utils/helper' +import { MethodCallOptions } from 'scrypt-ts' +import chaiAsPromised from 'chai-as-promised' +use(chaiAsPromised) + +describe('Test SmartContract `Enum`', () => { + before(() => { + Enum.loadArtifact() + }) + + it('should pass the public method unit test successfully.', async () => { + const balance = 1 + + const instance = new Enum() + await instance.connect(getDefaultSigner()) + + await instance.deploy(1) + + // create the next instance from the current + const nextInstance = instance.next() + + // apply updates on the next instance off chain + nextInstance.set(Status.Accepted) + + // call the method of current instance to apply the updates on chain + const callContract = async () => + instance.methods.unlock({ + next: { + instance: nextInstance, + balance, + }, + } as MethodCallOptions) + await expect(callContract()).not.rejected + }) +})