Skip to content

Commit 882d837

Browse files
committed
Fix small bug and update libauth template property naming
- Fix bug where P2PKH inputs were not correctly detected using the new transaction builder - Update libauth template generation to always include input index in names - Update fixtures accordingly
1 parent 8ffe2ae commit 882d837

File tree

5 files changed

+154
-127
lines changed

5 files changed

+154
-127
lines changed

packages/cashscript/src/LibauthTemplate.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
AddressType,
3434
SignatureAlgorithm,
3535
HashType,
36+
isUnlockableUtxo,
3637
} from './interfaces.js';
3738
import SignatureTemplate from './SignatureTemplate.js';
3839
import { Transaction } from './Transaction.js';
@@ -354,6 +355,7 @@ const generateTemplateScenarioSourceOutputs = (
354355
export const generateTemplateScenarioBytecode = (
355356
input: Utxo, p2pkhScriptName: string, placeholderKeyName: string, insertSlot?: boolean,
356357
): WalletTemplateScenarioBytecode | ['slot'] => {
358+
// This is for P2PKH inputs in the old transaction builder (TODO: remove when we remove old transaction builder)
357359
if (isUtxoP2PKH(input)) {
358360
return {
359361
script: p2pkhScriptName,
@@ -367,6 +369,22 @@ export const generateTemplateScenarioBytecode = (
367369
};
368370
}
369371

372+
// This is for P2PKH inputs in the new transaction builder
373+
if (isUnlockableUtxo(input) && input.unlocker.template) {
374+
return {
375+
script: p2pkhScriptName,
376+
overrides: {
377+
keys: {
378+
privateKeys: {
379+
[placeholderKeyName]: binToHex(input.unlocker.template.privateKey),
380+
},
381+
},
382+
},
383+
};
384+
}
385+
386+
// 'slot' means that we are currently evaluating this specific input,
387+
// {} means that it is the same script type, but not being evaluated
370388
return insertSlot ? ['slot'] : {};
371389
};
372390

packages/cashscript/src/advanced/LibauthTemplate.ts

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export const generateTemplateEntitiesP2SH = (
108108
);
109109

110110
const entities = {
111-
[artifact.contractName + '_parameters' + '_input' + inputIndex]: {
111+
[artifact.contractName + '_input' + inputIndex + '_parameters']: {
112112
description: 'Contract creation and function parameters',
113113
name: `${artifact.contractName} (input #${inputIndex})`,
114114
scripts: [
@@ -124,7 +124,7 @@ export const generateTemplateEntitiesP2SH = (
124124

125125
// function_index is a special variable that indicates the function to execute
126126
if (artifact.abi.length > 1) {
127-
entities[artifact.contractName + '_parameters' + '_input' + inputIndex].variables.function_index = {
127+
entities[artifact.contractName + '_input' + inputIndex + '_parameters'].variables.function_index = {
128128
description: 'Script function index to execute',
129129
name: 'function_index',
130130
type: 'WalletData',
@@ -184,15 +184,14 @@ export const generateTemplateScriptsP2SH = (
184184
abiFunction: AbiFunction,
185185
encodedFunctionArgs: EncodedFunctionArgument[],
186186
encodedConstructorArgs: EncodedConstructorArgument[],
187-
scenarioId: string,
188187
inputIndex: number,
189188
): WalletTemplate['scripts'] => {
190189
// definition of locking scripts and unlocking scripts with their respective bytecode
191190
const unlockingScriptName = artifact.contractName + '_' + abiFunction.name + '_input' + inputIndex + '_unlock';
192191
const lockingScriptName = artifact.contractName + '_lock';
193192

194193
return {
195-
[unlockingScriptName]: generateTemplateUnlockScript(artifact, abiFunction, encodedFunctionArgs, scenarioId, inputIndex),
194+
[unlockingScriptName]: generateTemplateUnlockScript(artifact, abiFunction, encodedFunctionArgs, inputIndex),
196195
[lockingScriptName]: generateTemplateLockScript(artifact, addressType, encodedConstructorArgs),
197196
};
198197
};
@@ -233,9 +232,9 @@ const generateTemplateUnlockScript = (
233232
artifact: Artifact,
234233
abiFunction: AbiFunction,
235234
encodedFunctionArgs: EncodedFunctionArgument[],
236-
scenarioId: string,
237235
inputIndex: number,
238236
): WalletTemplateScriptUnlocking => {
237+
const scenarioIdentifier = `${artifact.contractName}_${abiFunction.name}_input${inputIndex}_evaluate`;
239238
const functionIndex = artifact.abi.findIndex((func) => func.name === abiFunction.name);
240239

241240
const functionIndexString = artifact.abi.length > 1
@@ -244,7 +243,7 @@ const generateTemplateUnlockScript = (
244243

245244
return {
246245
// this unlocking script must pass our only scenario
247-
passes: [scenarioId],
246+
passes: [scenarioIdentifier],
248247
name: `${abiFunction.name} (input #${inputIndex})`,
249248
script: [
250249
`// "${abiFunction.name}" function parameters`,
@@ -257,21 +256,21 @@ const generateTemplateUnlockScript = (
257256
};
258257

259258
export const generateTemplateScenarios = (
260-
scenarioIdentifier: string,
261259
contract: Contract,
262260
libauthTransaction: TransactionBch,
263261
csTransaction: Transaction,
264262
abiFunction: AbiFunction,
265263
encodedFunctionArgs: EncodedFunctionArgument[],
266-
slotIndex: number,
264+
inputIndex: number,
267265
): WalletTemplate['scenarios'] => {
268266
const artifact = contract.artifact;
269267
const encodedConstructorArgs = contract.encodedConstructorArgs;
268+
const scenarioIdentifier = `${artifact.contractName}_${abiFunction.name}_input${inputIndex}_evaluate`;
270269

271270
const scenarios = {
272271
// single scenario to spend out transaction under test given the CashScript parameters provided
273272
[scenarioIdentifier]: {
274-
name: artifact.contractName + '_' + abiFunction.name + '_evaluate',
273+
name: `Evaluate ${artifact.contractName} ${abiFunction.name} (input #${inputIndex})`,
275274
description: 'An example evaluation where this script execution passes.',
276275
data: {
277276
// encode values for the variables defined above in `entities` property
@@ -285,8 +284,8 @@ export const generateTemplateScenarios = (
285284
privateKeys: generateTemplateScenarioKeys(abiFunction.inputs, encodedFunctionArgs),
286285
},
287286
},
288-
transaction: generateTemplateScenarioTransaction(contract, libauthTransaction, csTransaction, slotIndex),
289-
sourceOutputs: generateTemplateScenarioSourceOutputs(csTransaction, slotIndex),
287+
transaction: generateTemplateScenarioTransaction(contract, libauthTransaction, csTransaction, inputIndex),
288+
sourceOutputs: generateTemplateScenarioSourceOutputs(csTransaction, inputIndex),
290289
},
291290
};
292291

@@ -415,21 +414,6 @@ export const getLibauthTemplates = (
415414
throw new Error('No ABI function found in unlocker');
416415
}
417416

418-
// Find matching function and index from contract.unlock Object, this uses Function Reference Comparison.
419-
// Generate unique scenario identifier by combining contract name, function name and counter
420-
const baseIdentifier = `${contract.artifact.contractName}_${abiFunction.name}_evaluate`;
421-
let scenarioIdentifier = baseIdentifier;
422-
let counter = 0;
423-
424-
const scenarioIds = [scenarioIdentifier];
425-
426-
// Find first available unique identifier by incrementing counter
427-
while (scenarios[scenarioIdentifier]) {
428-
counter++;
429-
scenarioIdentifier = `${baseIdentifier}${counter}`;
430-
scenarioIds.push(scenarioIdentifier);
431-
}
432-
433417
// Encode the function arguments for this contract input
434418
const encodedArgs = encodeFunctionArguments(
435419
abiFunction,
@@ -439,7 +423,6 @@ export const getLibauthTemplates = (
439423
// Generate a scenario object for this contract input
440424
Object.assign(scenarios,
441425
generateTemplateScenarios(
442-
scenarioIdentifier,
443426
contract,
444427
libauthTransaction,
445428
csTransaction as any,
@@ -464,7 +447,6 @@ export const getLibauthTemplates = (
464447
abiFunction,
465448
encodedArgs,
466449
contract.encodedConstructorArgs,
467-
scenarioIdentifier,
468450
inputIndex,
469451
);
470452

0 commit comments

Comments
 (0)