@opcat-labs/scrypt-ts-opcat 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/assets/.templates/smart-contract/builtin-libs/backtrace.scrypt.map +1 -1
  2. package/assets/.templates/smart-contract/builtin-libs/backtrace.scrypt.tpl +4 -0
  3. package/assets/.templates/smart-contract/builtin-libs/genesis.scrypt.map +1 -0
  4. package/assets/.templates/smart-contract/builtin-libs/genesis.scrypt.tpl +42 -0
  5. package/assets/.templates/smart-contract/builtin-libs/genesis.transformer.json +9 -0
  6. package/assets/.templates/smart-contract/builtin-libs/p2pk.scrypt.map +1 -1
  7. package/assets/.templates/smart-contract/builtin-libs/p2pk.scrypt.tpl +3 -0
  8. package/assets/.templates/smart-contract/builtin-libs/p2pkh.scrypt.map +1 -1
  9. package/assets/.templates/smart-contract/builtin-libs/p2pkh.scrypt.tpl +3 -0
  10. package/assets/smart-contract/builtin-libs/backtrace.scrypt +16 -12
  11. package/assets/smart-contract/builtin-libs/byteStringReader.scrypt +5 -5
  12. package/assets/smart-contract/builtin-libs/byteStringWriter.scrypt +6 -6
  13. package/assets/smart-contract/builtin-libs/contextUtils.scrypt +16 -16
  14. package/assets/smart-contract/builtin-libs/genesis.scrypt +44 -0
  15. package/assets/smart-contract/builtin-libs/p2pk.scrypt +4 -1
  16. package/assets/smart-contract/builtin-libs/p2pkh.scrypt +4 -1
  17. package/assets/smart-contract/builtin-libs/stateLib.scrypt +1 -1
  18. package/assets/smart-contract/builtin-libs/stateUtils.scrypt +1 -1
  19. package/assets/smart-contract/builtin-libs/stdUtils.scrypt +12 -12
  20. package/assets/smart-contract/builtin-libs/txHashPreimageUtils.scrypt +7 -7
  21. package/assets/smart-contract/builtin-libs/txUtils.scrypt +12 -12
  22. package/assets/smart-contract/types/structs.scrypt +8 -8
  23. package/dist/cjs/features/deployGenesis.cjs +84 -31
  24. package/dist/cjs/features/deployGenesis.js.map +1 -1
  25. package/dist/cjs/providers/dryRunProvider.cjs +57 -0
  26. package/dist/cjs/providers/dryRunProvider.js.map +1 -0
  27. package/dist/cjs/providers/dummyProvider.cjs +10 -0
  28. package/dist/cjs/providers/dummyProvider.js.map +1 -1
  29. package/dist/cjs/providers/index.cjs +4 -1
  30. package/dist/cjs/providers/index.js.map +1 -1
  31. package/dist/cjs/providers/mempoolProvider.cjs +44 -0
  32. package/dist/cjs/providers/mempoolProvider.js.map +1 -1
  33. package/dist/cjs/providers/rpcProvider.cjs +46 -3
  34. package/dist/cjs/providers/rpcProvider.js.map +1 -1
  35. package/dist/cjs/providers/utxoProvider.cjs +9 -1
  36. package/dist/cjs/providers/utxoProvider.js.map +1 -1
  37. package/dist/cjs/psbt/extPsbt.cjs +8 -1
  38. package/dist/cjs/psbt/extPsbt.js.map +1 -1
  39. package/dist/cjs/psbt/psbt.cjs +3 -1
  40. package/dist/cjs/psbt/psbt.js.map +1 -1
  41. package/dist/cjs/smart-contract/builtin-libs/backtrace.cjs +59 -2
  42. package/dist/cjs/smart-contract/builtin-libs/backtrace.js.map +1 -1
  43. package/dist/cjs/smart-contract/builtin-libs/genesis.cjs +553 -0
  44. package/dist/cjs/smart-contract/builtin-libs/genesis.js.map +1 -0
  45. package/dist/cjs/smart-contract/builtin-libs/index.cjs +5 -1
  46. package/dist/cjs/smart-contract/builtin-libs/index.js.map +1 -1
  47. package/dist/cjs/smart-contract/smartContract.cjs +22 -0
  48. package/dist/cjs/smart-contract/smartContract.js.map +1 -1
  49. package/dist/esm/features/deployGenesis.js +84 -31
  50. package/dist/esm/features/deployGenesis.js.map +1 -1
  51. package/dist/esm/providers/dryRunProvider.js +53 -0
  52. package/dist/esm/providers/dryRunProvider.js.map +1 -0
  53. package/dist/esm/providers/dummyProvider.js +10 -0
  54. package/dist/esm/providers/dummyProvider.js.map +1 -1
  55. package/dist/esm/providers/index.js +2 -1
  56. package/dist/esm/providers/index.js.map +1 -1
  57. package/dist/esm/providers/mempoolProvider.js +44 -0
  58. package/dist/esm/providers/mempoolProvider.js.map +1 -1
  59. package/dist/esm/providers/rpcProvider.js +45 -2
  60. package/dist/esm/providers/rpcProvider.js.map +1 -1
  61. package/dist/esm/providers/utxoProvider.js +7 -0
  62. package/dist/esm/providers/utxoProvider.js.map +1 -1
  63. package/dist/esm/psbt/extPsbt.js +8 -1
  64. package/dist/esm/psbt/extPsbt.js.map +1 -1
  65. package/dist/esm/psbt/psbt.js +3 -1
  66. package/dist/esm/psbt/psbt.js.map +1 -1
  67. package/dist/esm/smart-contract/builtin-libs/backtrace.js +61 -4
  68. package/dist/esm/smart-contract/builtin-libs/backtrace.js.map +1 -1
  69. package/dist/esm/smart-contract/builtin-libs/genesis.js +549 -0
  70. package/dist/esm/smart-contract/builtin-libs/genesis.js.map +1 -0
  71. package/dist/esm/smart-contract/builtin-libs/index.js +1 -0
  72. package/dist/esm/smart-contract/builtin-libs/index.js.map +1 -1
  73. package/dist/esm/smart-contract/smartContract.js +23 -1
  74. package/dist/esm/smart-contract/smartContract.js.map +1 -1
  75. package/dist/types/features/deployGenesis.d.ts +39 -12
  76. package/dist/types/features/deployGenesis.d.ts.map +1 -1
  77. package/dist/types/providers/chainProvider.d.ts +12 -0
  78. package/dist/types/providers/chainProvider.d.ts.map +1 -1
  79. package/dist/types/providers/dryRunProvider.d.ts +4 -0
  80. package/dist/types/providers/dryRunProvider.d.ts.map +1 -0
  81. package/dist/types/providers/dummyProvider.d.ts +4 -2
  82. package/dist/types/providers/dummyProvider.d.ts.map +1 -1
  83. package/dist/types/providers/index.d.ts +2 -1
  84. package/dist/types/providers/index.d.ts.map +1 -1
  85. package/dist/types/providers/mempoolProvider.d.ts +4 -2
  86. package/dist/types/providers/mempoolProvider.d.ts.map +1 -1
  87. package/dist/types/providers/rpcProvider.d.ts +4 -2
  88. package/dist/types/providers/rpcProvider.d.ts.map +1 -1
  89. package/dist/types/providers/utxoProvider.d.ts +3 -0
  90. package/dist/types/providers/utxoProvider.d.ts.map +1 -1
  91. package/dist/types/psbt/extPsbt.d.ts.map +1 -1
  92. package/dist/types/psbt/psbt.d.ts.map +1 -1
  93. package/dist/types/smart-contract/builtin-libs/backtrace.d.ts +49 -0
  94. package/dist/types/smart-contract/builtin-libs/backtrace.d.ts.map +1 -1
  95. package/dist/types/smart-contract/builtin-libs/genesis.d.ts +252 -0
  96. package/dist/types/smart-contract/builtin-libs/genesis.d.ts.map +1 -0
  97. package/dist/types/smart-contract/builtin-libs/index.d.ts +1 -0
  98. package/dist/types/smart-contract/builtin-libs/index.d.ts.map +1 -1
  99. package/dist/types/smart-contract/smartContract.d.ts +20 -0
  100. package/dist/types/smart-contract/smartContract.d.ts.map +1 -1
  101. package/package.json +5 -3
  102. package/scrypt.index.json +4 -0
  103. package/src/smart-contract/builtin-libs/backtrace.ts +62 -3
  104. package/src/smart-contract/builtin-libs/genesis.ts +569 -0
  105. package/src/smart-contract/builtin-libs/index.ts +2 -1
@@ -0,0 +1,252 @@
1
+ import { SmartContract } from '../smartContract.js';
2
+ import { FixedArray, TxOut } from '../types/index.js';
3
+ import { ContractCall } from '../../psbt/types.js';
4
+ /**
5
+ * Maximum number of inputs allowed during genesis deployment.
6
+ *
7
+ * ## Purpose
8
+ * Limits the number of inputs validated to prevent script size bloat while
9
+ * maintaining sufficient security coverage.
10
+ *
11
+ * ## Why 6?
12
+ * - **Typical deployments**: 1-3 inputs (Genesis UTXO + fee UTXOs)
13
+ * - **Edge case coverage**: Handles multi-input deployment scenarios
14
+ * - **Script size**: Each input check adds ~50 bytes; 6 is optimal balance
15
+ * - **Security**: Validates all inputs in normal cases
16
+ * - **sCrypt constraint**: Bitcoin Script loops must be unrolled at compile time
17
+ *
18
+ * ## Security Implications
19
+ * Transactions with more than 6 inputs will be **rejected by the contract**.
20
+ * This prevents attackers from hiding duplicate scriptHashes in unchecked input
21
+ * indices beyond the validation limit.
22
+ *
23
+ * @constant
24
+ * @see {@link Genesis.checkDeploy} - Uses this constant for input validation
25
+ * @category Genesis
26
+ */
27
+ export declare const MAX_GENESIS_CHECK_INPUT = 6;
28
+ /**
29
+ * Maximum number of outputs to check during genesis deployment.
30
+ *
31
+ * ## Purpose
32
+ * Limits the number of outputs validated during deployment to match input
33
+ * validation coverage and support typical deployment patterns.
34
+ *
35
+ * ## Usage Scenarios
36
+ * - **1 output**: Deploy single contract
37
+ * - **2-3 outputs**: Deploy contract + change outputs
38
+ * - **4-6 outputs**: Multi-contract deployment or complex output structures
39
+ *
40
+ * ## Validation Scope
41
+ * Only `output[0]` must be unique. Other outputs (1-5) can have duplicate
42
+ * scriptHashes as long as they differ from `output[0]`.
43
+ *
44
+ * @constant
45
+ * @see {@link Genesis.checkDeploy} - Uses this constant for output validation
46
+ * @see {@link MAX_GENESIS_CHECK_INPUT} - Corresponding input limit
47
+ * @category Genesis
48
+ */
49
+ export declare const MAX_GENESIS_CHECK_OUTPUT = 6;
50
+ /**
51
+ * Genesis contract for validating initial deployment outputs.
52
+ *
53
+ * ## Purpose
54
+ * The Genesis contract ensures that deployed contracts have unique scriptHashes,
55
+ * preventing duplicate deployments and establishing a verifiable deployment origin.
56
+ * It acts as a "genesis UTXO" that validates the first deployment of a contract.
57
+ *
58
+ * ## Deployment Validation Rules
59
+ * 1. **Genesis position**: Genesis must be unlocked at input index 0
60
+ * 2. **Output uniqueness**: Contract at `output[0]` must have unique scriptHash among all outputs
61
+ * 3. **Input differentiation**: Contract at `output[0]` must differ from all input scriptHashes
62
+ * 4. **Input limit**: Transaction must have ≤ {@link MAX_GENESIS_CHECK_INPUT} inputs
63
+ * 5. **Output limit**: Transaction must specify ≤ {@link MAX_GENESIS_CHECK_OUTPUT} outputs
64
+ *
65
+ * ## Why output[0]?
66
+ * Only `output[0]` requires uniqueness validation. This design allows:
67
+ * - Deploying the **primary contract** at output[0] with guaranteed uniqueness
68
+ * - Including **auxiliary contracts** or **change outputs** at indices 1-5
69
+ * - **Multi-output deployments** where only the main contract needs uniqueness
70
+ *
71
+ * ## Empty Placeholders
72
+ * When fewer than {@link MAX_GENESIS_CHECK_OUTPUT} outputs exist, use empty
73
+ * placeholders (scriptHash = empty ByteString) for unused slots. These are
74
+ * ignored during validation.
75
+ *
76
+ * @example
77
+ * **Basic single contract deployment:**
78
+ * ```typescript
79
+ * import { Genesis, genesisCheckDeploy } from '@opcat-labs/scrypt-ts-opcat';
80
+ * import { ExtPsbt } from '@opcat-labs/scrypt-ts-opcat';
81
+ *
82
+ * // 1. Create and bind Genesis contract
83
+ * const genesis = new Genesis();
84
+ * genesis.bindToUtxo(genesisUtxo);
85
+ *
86
+ * // 2. Create the contract to deploy
87
+ * const minter = new CAT20Minter(...);
88
+ *
89
+ * // 3. Build deployment transaction
90
+ * const psbt = new ExtPsbt({ network })
91
+ * .addContractInput(genesis, genesisCheckDeploy()) // Genesis validates deployment
92
+ * .addContractOutput(minter, 1000n) // Deploy at output[0]
93
+ * .change(changeAddress, feeRate)
94
+ * .seal();
95
+ *
96
+ * // 4. Finalize and broadcast
97
+ * await psbt.finalizeAllInputs();
98
+ * const txid = await psbt.broadcast();
99
+ * console.log(`Contract deployed at ${txid}:0`);
100
+ * ```
101
+ *
102
+ * @category Contract
103
+ * @category Genesis
104
+ * @see {@link genesisCheckDeploy} - Helper function for easier deployment
105
+ * @see {@link MAX_GENESIS_CHECK_INPUT} - Maximum inputs validated
106
+ * @see {@link MAX_GENESIS_CHECK_OUTPUT} - Maximum outputs validated
107
+ * @onchain
108
+ */
109
+ export declare class Genesis extends SmartContract {
110
+ constructor();
111
+ /**
112
+ * Validates the deployment transaction outputs.
113
+ *
114
+ * ## Validation Process
115
+ * This method performs a **two-phase validation**:
116
+ *
117
+ * **Phase 1: Output Serialization & Uniqueness** (lines 168-183)
118
+ * - Iterates through all outputs up to MAX_GENESIS_CHECK_OUTPUT
119
+ * - Serializes valid outputs (index < outputCount) for context matching
120
+ * - Validates `output[0]` scriptHash is unique among all outputs
121
+ * - Ensures no duplicate contracts are deployed in a single transaction
122
+ *
123
+ * **Phase 2: Input Differentiation** (lines 185-195)
124
+ * - Checks `output[0]` differs from all input scriptHashes
125
+ * - Prevents redeployment attacks using existing contract UTXOs
126
+ * - Validates only inputs within MAX_GENESIS_CHECK_INPUT limit
127
+ *
128
+ * ## Why Two Separate Loops?
129
+ * 1. **Output loop**: Dual-purpose (serialize + validate uniqueness)
130
+ * 2. **Input loop**: Independent validation after outputs are processed
131
+ * 3. **sCrypt constraint**: Loops must be unrolled at compile time
132
+ *
133
+ * @param outputs - Fixed array of 6 outputs; fill unused slots with empty placeholders
134
+ * @param outputCount - Number of actual outputs (1-6); outputs beyond this are ignored
135
+ *
136
+ * @throws {Error} 'Genesis must be unlocked at input index 0' - Genesis not at input 0
137
+ * @throws {Error} 'Too many inputs to validate' - More than MAX_GENESIS_CHECK_INPUT inputs
138
+ * @throws {Error} 'Invalid outputCount' - outputCount out of range [1, 6]
139
+ * @throws {Error} 'Output scriptHash must be non-empty' - Empty scriptHash in valid output
140
+ * @throws {Error} 'output[0] must be unique among all outputs' - Duplicate scriptHash in outputs
141
+ * @throws {Error} 'output[0] must differ from all input scriptHashes' - Matches an input
142
+ * @throws {Error} 'Outputs mismatch with the transaction context' - Serialization mismatch
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * // Advanced: Direct method call (most users should use genesisCheckDeploy helper)
147
+ * const genesis = new Genesis();
148
+ * genesis.bindToUtxo(genesisUtxo);
149
+ *
150
+ * // Create output array with empty placeholders
151
+ * const outputs: TxOut[] = [
152
+ * { scriptHash: sha256(contractScript), satoshis: 1000n, dataHash: sha256('') },
153
+ * ...fill({ scriptHash: toByteString(''), satoshis: 0n, dataHash: sha256('') }, 5)
154
+ * ];
155
+ *
156
+ * await genesis.methods.checkDeploy(
157
+ * outputs as FixedArray<TxOut, 6>,
158
+ * 1n // Only 1 real output, rest are placeholders
159
+ * );
160
+ * ```
161
+ *
162
+ * @see {@link genesisCheckDeploy} - Helper function for easier usage
163
+ * @see {@link MAX_GENESIS_CHECK_INPUT} - Maximum inputs validated
164
+ * @see {@link MAX_GENESIS_CHECK_OUTPUT} - Maximum outputs validated
165
+ * @onchain
166
+ */
167
+ checkDeploy(outputs: FixedArray<TxOut, typeof MAX_GENESIS_CHECK_OUTPUT>, outputCount: bigint): void;
168
+ }
169
+ /**
170
+ * Creates a contract call function for Genesis.checkDeploy that automatically
171
+ * builds the TxOut array from transaction outputs.
172
+ *
173
+ * ## What it does
174
+ * This helper function simplifies Genesis deployment by:
175
+ * 1. **Extracting outputs** from the PSBT transaction
176
+ * 2. **Computing hashes** (scriptHash and dataHash) for each output
177
+ * 3. **Creating placeholders** for unused output slots (up to 6 total)
178
+ * 4. **Invoking checkDeploy** with properly formatted parameters
179
+ *
180
+ * ## When to use
181
+ * - **Recommended**: Use this helper when building deployment transactions with ExtPsbt
182
+ * - **Advanced**: Call {@link Genesis.checkDeploy} directly for manual control
183
+ *
184
+ * ## Output Handling
185
+ * - Processes up to {@link MAX_GENESIS_CHECK_OUTPUT} (6) outputs
186
+ * - Automatically limits `outputCount` via `Math.min(txOutputs.length, 6)`
187
+ * - Fills unused slots with empty placeholders (scriptHash = empty ByteString)
188
+ *
189
+ * @returns A ContractCall function compatible with ExtPsbt.addContractInput
190
+ *
191
+ * @example
192
+ * **Basic single contract deployment:**
193
+ * ```typescript
194
+ * import { Genesis, genesisCheckDeploy } from '@opcat-labs/scrypt-ts-opcat';
195
+ * import { ExtPsbt } from '@opcat-labs/scrypt-ts-opcat';
196
+ *
197
+ * // 1. Setup Genesis contract
198
+ * const genesis = new Genesis();
199
+ * genesis.bindToUtxo(genesisUtxo);
200
+ *
201
+ * // 2. Create contract to deploy
202
+ * const minter = new CAT20Minter(...);
203
+ *
204
+ * // 3. Build deployment transaction
205
+ * const psbt = new ExtPsbt({ network })
206
+ * .addContractInput(genesis, genesisCheckDeploy()) // Genesis validates
207
+ * .addContractOutput(minter, 1000n) // Deploy at output[0]
208
+ * .change(changeAddress, feeRate) // Change output
209
+ * .seal();
210
+ *
211
+ * // 4. Finalize and broadcast
212
+ * await psbt.finalizeAllInputs();
213
+ * const txid = await psbt.broadcast();
214
+ * console.log(`Contract deployed at ${txid}:0`);
215
+ * ```
216
+ *
217
+ * @example
218
+ * **Multi-output deployment:**
219
+ * ```typescript
220
+ * // Deploy primary contract + auxiliary contracts
221
+ * const psbt = new ExtPsbt({ network })
222
+ * .addContractInput(genesis, genesisCheckDeploy())
223
+ * .addContractOutput(primaryContract, 2000n) // output[0] - must be unique
224
+ * .addContractOutput(helperContract, 1000n) // output[1] - can match output[2+]
225
+ * .addContractOutput(anotherHelper, 1000n) // output[2] - can match output[1]
226
+ * .change(changeAddress, feeRate)
227
+ * .seal();
228
+ * ```
229
+ *
230
+ * @example
231
+ * **Error handling:**
232
+ * ```typescript
233
+ * try {
234
+ * const psbt = new ExtPsbt({ network })
235
+ * .addContractInput(genesis, genesisCheckDeploy())
236
+ * .addContractOutput(contract1, 1000n) // output[0]
237
+ * .addContractOutput(contract1, 1000n) // ❌ Same as output[0] - will fail!
238
+ * .seal();
239
+ * await psbt.finalizeAllInputs();
240
+ * await psbt.broadcast();
241
+ * } catch (error) {
242
+ * // Error: output[0] must be unique among all outputs
243
+ * console.error('Deployment failed:', error.message);
244
+ * }
245
+ * ```
246
+ *
247
+ * @category Genesis
248
+ * @see {@link Genesis.checkDeploy} - The underlying contract method
249
+ * @see {@link MAX_GENESIS_CHECK_OUTPUT} - Maximum outputs validated
250
+ */
251
+ export declare function genesisCheckDeploy(): ContractCall<Genesis>;
252
+ //# sourceMappingURL=genesis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"genesis.d.ts","sourceRoot":"","sources":["../../../../src/smart-contract/builtin-libs/genesis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAGtD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,qBACa,OAAQ,SAAQ,aAAa;;IAMxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuDG;IAEI,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,KAAK,EAAE,OAAO,wBAAwB,CAAC,EAAE,WAAW,EAAE,MAAM;CAyEpG;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiFG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAAC,OAAO,CAAC,CAwC1D"}
@@ -5,4 +5,5 @@ export { StdUtils } from './stdUtils.js';
5
5
  export { Backtrace, type ChainTxVerifyResponse } from './backtrace.js';
6
6
  export { StateLib } from './stateLib.js';
7
7
  export { TxHashPreimageUtils } from './txHashPreimageUtils.js';
8
+ export { Genesis, MAX_GENESIS_CHECK_OUTPUT, genesisCheckDeploy } from './genesis.js';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/smart-contract/builtin-libs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,KAAK,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/smart-contract/builtin-libs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,KAAK,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC"}
@@ -43,12 +43,32 @@ export declare class SmartContract<StateT extends OpcatState = undefined> extend
43
43
  * @ignore
44
44
  */
45
45
  getStateType(): string | undefined;
46
+ /**
47
+ * Get the data of the contract.
48
+ * @returns the data of the contract
49
+ */
50
+ get data(): ByteString;
51
+ /**
52
+ * Set the data of the contract.
53
+ * Only stateless contracts (without stateType) can set data.
54
+ * Stateful contracts should use the state property instead.
55
+ * @param value the data to set
56
+ */
57
+ set data(value: ByteString);
46
58
  utxo?: ExtUtxo;
47
59
  /**
48
60
  * The state of the contract UTXO, usually committed to the first OP_RETURN output, is revealed when spending.
49
61
  * @onchain
50
62
  */
51
63
  state: StateT;
64
+ /**
65
+ * Raw data for stateless contracts (contracts without stateType).
66
+ * For stateful contracts, use the `state` property instead.
67
+ * Access this field through the `data` getter/setter.
68
+ * @private
69
+ * @onchain
70
+ */
71
+ private _data;
52
72
  private contractHeader;
53
73
  /**
54
74
  * Locking script corresponding to the SmartContract
@@ -1 +1 @@
1
- {"version":3,"file":"smartContract.d.ts","sourceRoot":"","sources":["../../../src/smart-contract/smartContract.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"smartContract.d.ts","sourceRoot":"","sources":["../../../src/smart-contract/smartContract.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@opcat-labs/scrypt-ts-opcat",
3
3
  "description": "A TypeScript library for building OPCAT smart contracts with sCrypt.",
4
- "version": "2.0.2",
4
+ "version": "2.1.0",
5
5
  "author": "OP_CAT Labs",
6
6
  "main": "./dist/cjs/index.cjs",
7
7
  "module": "./dist/esm/index.js",
@@ -31,8 +31,9 @@
31
31
  "node": ">=20.0.0"
32
32
  },
33
33
  "scripts": {
34
- "test": "npm run test:local",
34
+ "test": "npm run test:local && npm run test:dist",
35
35
  "test:local": "cross-env DUMMY_PROVIDER=1 mocha",
36
+ "test:dist": "node test-esm/test.mjs && node test-cjs/test.cjs",
36
37
  "test:testnet": "cross-env NETWORK=opcat-testnet mocha --timeout=0 --jobs=1",
37
38
  "test:mainnet": "cross-env NETWORK=opcat-mainnet mocha --timeout=0 --jobs=1",
38
39
  "build:cjs": "tsc -p tsconfig.cjs.json",
@@ -40,6 +41,7 @@
40
41
  "build:esm": "tsc -p tsconfig.esm.json",
41
42
  "build": "yarn run build:cjs && yarn run build:esm",
42
43
  "gen:assets": "tspc -p tsconfig.assets.json && node injectAsm.cjs",
44
+ "gen:contract": "tsx scripts/genContract.ts",
43
45
  "prebuild": "yarn run clean",
44
46
  "beta": "yarn publish --tag beta --access public",
45
47
  "genkey": "tsx test/utils/privateKey.ts",
@@ -66,7 +68,7 @@
66
68
  },
67
69
  "dependencies": {
68
70
  "@noble/curves": "^1.8.1",
69
- "@opcat-labs/opcat": "2.0.2",
71
+ "@opcat-labs/opcat": "2.1.0",
70
72
  "bip174": "^3.0.0-rc.1",
71
73
  "cbor2": "^2.0.1",
72
74
  "cross-fetch": "^4.1.0",
package/scrypt.index.json CHANGED
@@ -69,6 +69,10 @@
69
69
  "symbol": "StateLib",
70
70
  "path": "smart-contract/builtin-libs/stateLib.scrypt.tpl"
71
71
  },
72
+ {
73
+ "symbol": "Genesis",
74
+ "path": "smart-contract/builtin-libs/genesis.scrypt.tpl"
75
+ },
72
76
  {
73
77
  "symbol": "P2PK",
74
78
  "path": "smart-contract/builtin-libs/p2pk.scrypt.tpl"
@@ -1,11 +1,11 @@
1
- import { method } from '../decorators.js';
1
+ import { method, prop } from '../decorators.js';
2
2
  import { assert } from '../fns/assert.js';
3
3
  import { SmartContractLib } from '../smartContractLib.js';
4
4
  import { ByteString } from '../types/index.js';
5
5
  import { BacktraceInfo, Prevouts, TxHashPreimage } from '../types/structs.js';
6
6
  import { TxUtils } from './txUtils.js';
7
7
  import { TX_INPUT_BYTE_LEN, TX_OUTPUT_BYTE_LEN, TX_OUTPUT_SATOSHI_BYTE_LEN, TX_OUTPUT_SCRIPT_HASH_LEN } from '../consts.js';
8
- import { slice } from '../fns/byteString.js';
8
+ import { slice, toByteString } from '../fns/byteString.js';
9
9
  import { StdUtils } from './stdUtils.js';
10
10
  import { TxHashPreimageUtils } from './txHashPreimageUtils.js';
11
11
 
@@ -25,6 +25,25 @@ export type ChainTxVerifyResponse = {
25
25
  * @onchain
26
26
  */
27
27
  export class Backtrace extends SmartContractLib {
28
+ /**
29
+ * SHA256 hash of the Genesis contract script (including header).
30
+ * Used to validate that prevPrevScript is the Genesis contract when tracing back to genesis outpoint.
31
+ *
32
+ * ## How this hash is generated
33
+ * This is the SHA256 hash of the Genesis contract's full locking script, including:
34
+ * - Contract header (name, version metadata)
35
+ * - Compiled bytecode
36
+ *
37
+ * To verify or regenerate: `sha256(toByteString(new Genesis().lockingScript.toHex()))`
38
+ *
39
+ * ## Important
40
+ * If the Genesis contract is updated, this hash MUST be updated accordingly.
41
+ * Use the test in genesis.test.ts to verify this hash remains correct.
42
+ *
43
+ * @see packages/scrypt-ts-opcat/test/local-test/genesis.test.ts - GENESIS_SCRIPT_HASH validation tests
44
+ */
45
+ @prop()
46
+ static readonly GENESIS_SCRIPT_HASH: ByteString = toByteString('8f6157664f8f7cd43e6bba7f3209bb803d4d0fb2fb6e59fdc548989ed3901f15');
28
47
 
29
48
  /**
30
49
  * Verifies that the transaction hash preimage matches the previous transaction hash
@@ -47,6 +66,37 @@ export class Backtrace extends SmartContractLib {
47
66
  /**
48
67
  * Back-to-genesis backtrace verification for a contract which can be backtraced to the genesis outpoint.
49
68
  * It will be a valid backtraceInfo if the prevPrevOutpoint is the genesis outpoint or the prevPrevScript is the selfScript.
69
+ *
70
+ * ## Multiple Genesis Support
71
+ * A single transaction can create multiple Genesis outputs at different indices (output[0], output[1], etc.).
72
+ * Each Genesis output can be spent separately to deploy a different contract, with each contract having
73
+ * its own unique genesisOutpoint. This allows batch creation of Genesis contracts in one transaction
74
+ * while maintaining independent contract lineages.
75
+ *
76
+ * ```
77
+ * Genesis Creation Tx
78
+ * +-------------------+
79
+ * | output[0] |---> Genesis_0 (outpoint: txid:0)
80
+ * UTXOs -------------->| output[1] |---> Genesis_1 (outpoint: txid:1)
81
+ * | output[2] |---> Genesis_2 (outpoint: txid:2)
82
+ * +-------------------+
83
+ * |
84
+ * +----------------------+----------------------+
85
+ * | | |
86
+ * v v v
87
+ * +-------------+ +-------------+ +-------------+
88
+ * | Deploy Tx A | | Deploy Tx B | | Deploy Tx C |
89
+ * +-------------+ +-------------+ +-------------+
90
+ * | spend Gen_0 | | spend Gen_1 | | spend Gen_2 |
91
+ * | output[0]: | | output[0]: | | output[0]: |
92
+ * | Contract_A | | Contract_B | | Contract_C |
93
+ * +-------------+ +-------------+ +-------------+
94
+ * | | |
95
+ * v v v
96
+ * genesisOutpoint: genesisOutpoint: genesisOutpoint:
97
+ * txid:0 txid:1 txid:2
98
+ * ```
99
+ *
50
100
  * @param backtraceInfo backtrace info to verify, including prevTx and prevPrevTx informations
51
101
  * @param t_genesisOutpoint expected genesis outpoint of the contract which usually is a contract property and trustable
52
102
  * @param t_selfScript expected self locking script, i.e. this.ctx.spentScript, of the currect spending UTXO context which is trustable
@@ -60,6 +110,13 @@ export class Backtrace extends SmartContractLib {
60
110
  t_prevTxInputList: ByteString,
61
111
  ): void {
62
112
  const res = Backtrace.verifyChainTxs(backtraceInfo, t_prevTxInputList);
113
+ // When at genesis outpoint, verify the prevPrevScript (scriptHash) matches the Genesis contract
114
+ if (res.prevPrevOutpoint === t_genesisOutpoint) {
115
+ assert(
116
+ res.prevPrevScript == Backtrace.GENESIS_SCRIPT_HASH,
117
+ `prevPrevScript does not match Genesis contract script`,
118
+ );
119
+ }
63
120
  assert(
64
121
  res.prevPrevOutpoint === t_genesisOutpoint || res.prevPrevScript == t_selfScript,
65
122
  `can not backtrace to the genesis outpoint`,
@@ -104,17 +161,19 @@ export class Backtrace extends SmartContractLib {
104
161
  // check if the passed prevTxInput and prevTxInputIndexVal are matched
105
162
  assert(
106
163
  slice(
107
- t_prevTxInputList,
164
+ t_prevTxInputList,
108
165
  backtraceInfo.prevTxInputIndex * TX_INPUT_BYTE_LEN,
109
166
  (backtraceInfo.prevTxInputIndex + 1n) * TX_INPUT_BYTE_LEN
110
167
  ) ==
111
168
  TxUtils.mergeInput(backtraceInfo.prevTxInput),
169
+ 'prevTxInput does not match prevTxInputList at specified index',
112
170
  );
113
171
  // check if prevTxHash of passed prevTxInput and prevPrevTx are matched
114
172
  const prevPrevTxHash = backtraceInfo.prevTxInput.prevTxHash;
115
173
  assert(
116
174
  prevPrevTxHash ==
117
175
  TxHashPreimageUtils.getTxHashFromTxHashPreimage(backtraceInfo.prevPrevTxPreimage),
176
+ 'prevPrevTxHash mismatch: prevTxInput.prevTxHash does not match prevPrevTxPreimage hash',
118
177
  );
119
178
  // all fields in backtraceInfo have been verified
120
179
  const prevPrevScript =