Skip to content

Commit 621f6df

Browse files
committed
Add extra tests for intended behaviour with P2PKH-only transactions & with old artifacts
1 parent a931383 commit 621f6df

File tree

2 files changed

+97
-4
lines changed

2 files changed

+97
-4
lines changed

packages/cashscript/test/TransactionBuilder.test.ts

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,18 +296,54 @@ describe('Transaction Builder', () => {
296296
});
297297
});
298298

299-
it('should not fail when spending from only P2PKH inputs', async () => {
299+
it('should not fail when validly spending from only P2PKH inputs', async () => {
300300
const aliceUtxos = (await provider.getUtxos(aliceAddress)).filter(isNonTokenUtxo);
301301
const sigTemplate = new SignatureTemplate(alicePriv);
302302

303303
expect(aliceUtxos.length).toBeGreaterThan(2);
304304

305305
const change = aliceUtxos[0].satoshis + aliceUtxos[1].satoshis - 1000n;
306306

307-
await expect(new TransactionBuilder({ provider })
307+
const transaction = new TransactionBuilder({ provider })
308308
.addInput(aliceUtxos[0], sigTemplate.unlockP2PKH())
309309
.addInput(aliceUtxos[1], sigTemplate.unlockP2PKH())
310-
.addOutput({ to: aliceAddress, amount: change })
311-
.send()).resolves.not.toThrow();
310+
.addOutput({ to: aliceAddress, amount: change });
311+
312+
await expect(transaction.send()).resolves.not.toThrow();
313+
});
314+
315+
// TODO: Currently, P2PKH inputs are not evaluated at all
316+
it.skip('should fail when invalidly spending from only P2PKH inputs', async () => {
317+
const aliceUtxos = (await provider.getUtxos(aliceAddress)).filter(isNonTokenUtxo);
318+
const incorrectSigTemplate = new SignatureTemplate(bobPriv);
319+
320+
expect(aliceUtxos.length).toBeGreaterThan(2);
321+
322+
const change = aliceUtxos[0].satoshis + aliceUtxos[1].satoshis - 1000n;
323+
324+
const transaction = new TransactionBuilder({ provider })
325+
.addInput(aliceUtxos[0], incorrectSigTemplate.unlockP2PKH())
326+
.addInput(aliceUtxos[1], incorrectSigTemplate.unlockP2PKH())
327+
.addOutput({ to: aliceAddress, amount: change });
328+
329+
await expect(transaction.send()).rejects.toThrow();
330+
});
331+
332+
// TODO: Currently, P2PKH inputs are not evaluated at all
333+
it.skip('should fail when invalidly spending from P2PKH and correctly from contract inputs', async () => {
334+
const aliceUtxos = (await provider.getUtxos(aliceAddress)).filter(isNonTokenUtxo);
335+
const p2pkhUtxos = (await p2pkhInstance.getUtxos()).filter(isNonTokenUtxo).sort(utxoComparator).reverse();
336+
const incorrectSigTemplate = new SignatureTemplate(bobPriv);
337+
338+
expect(aliceUtxos.length).toBeGreaterThan(2);
339+
340+
const change = aliceUtxos[0].satoshis + aliceUtxos[1].satoshis - 1000n;
341+
342+
const transaction = new TransactionBuilder({ provider })
343+
.addInput(aliceUtxos[0], incorrectSigTemplate.unlockP2PKH())
344+
.addInput(p2pkhUtxos[0], p2pkhInstance.unlock.spend(carolPub, new SignatureTemplate(carolPriv)))
345+
.addOutput({ to: aliceAddress, amount: change });
346+
347+
await expect(transaction.send()).rejects.toThrow();
312348
});
313349
});
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { Contract, MockNetworkProvider, randomUtxo, SignatureTemplate, TransactionBuilder } from '../src/index.js';
2+
import { alicePkh, alicePriv, alicePub, bobPriv } from './fixture/vars.js';
3+
4+
const artifact = {
5+
contractName: 'P2PKH',
6+
constructorInputs: [
7+
{ name: 'pkh', type: 'bytes20' },
8+
],
9+
abi: [
10+
{
11+
name: 'spend',
12+
inputs: [
13+
{ name: 'pk', type: 'pubkey' },
14+
{ name: 's', type: 'sig' },
15+
],
16+
},
17+
],
18+
bytecode: 'OP_OVER OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG',
19+
source: 'pragma cashscript ^0.7.0;\n\ncontract P2PKH(bytes20 pkh) {\n // Require pk to match stored pkh and signature to match\n function spend(pubkey pk, sig s) {\n require(hash160(pk) == pkh);\n require(checkSig(s, pk));\n }\n}\n',
20+
compiler: {
21+
name: 'cashc',
22+
version: '0.7.0',
23+
},
24+
updatedAt: '2025-08-05T09:04:50.388Z',
25+
};
26+
27+
describe('Debugging tests - old artifacts', () => {
28+
it('should succeed when passing the correct parameters', () => {
29+
const provider = new MockNetworkProvider();
30+
const contractTestLogs = new Contract(artifact, [alicePkh], { provider });
31+
const contractUtxo = randomUtxo();
32+
provider.addUtxo(contractTestLogs.address, contractUtxo);
33+
34+
const transaction = new TransactionBuilder({ provider })
35+
.addInput(contractUtxo, contractTestLogs.unlock.spend(alicePub, new SignatureTemplate(alicePriv)))
36+
.addOutput({ to: contractTestLogs.address, amount: 10000n });
37+
38+
console.warn(transaction.bitauthUri());
39+
40+
expect(() => transaction.debug()).not.toThrow();
41+
});
42+
43+
it('should fail when passing the wrong parameters', () => {
44+
const provider = new MockNetworkProvider();
45+
const contractTestLogs = new Contract(artifact, [alicePkh], { provider });
46+
const contractUtxo = randomUtxo();
47+
provider.addUtxo(contractTestLogs.address, contractUtxo);
48+
49+
const transaction = new TransactionBuilder({ provider })
50+
.addInput(contractUtxo, contractTestLogs.unlock.spend(alicePub, new SignatureTemplate(bobPriv)))
51+
.addOutput({ to: contractTestLogs.address, amount: 10000n });
52+
53+
console.warn(transaction.bitauthUri());
54+
55+
expect(() => transaction.debug()).toThrow();
56+
});
57+
});

0 commit comments

Comments
 (0)