-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcreate-testnet-tx.js
More file actions
122 lines (102 loc) · 4.35 KB
/
create-testnet-tx.js
File metadata and controls
122 lines (102 loc) · 4.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Create a real Zcash testnet transaction
const { proposeTransaction, getSighash, appendSignature, finalizeAndExtract } = require('./dist/index.js');
const secp256k1 = require('secp256k1');
const crypto = require('crypto');
// CONFIGURATION - UPDATE THESE WITH YOUR TESTNET VALUES
const CONFIG = {
// Input UTXO (from testnet faucet)
utxo: {
txid: 'YOUR_TXID_HERE', // Get from zcash-cli listunspent
vout: 0,
value: 10000000n, // Amount in zatoshis (0.1 ZEC = 10000000)
scriptPubKey: Buffer.from('YOUR_SCRIPTPUBKEY_HEX', 'hex'), // From listunspent
},
// Private key for signing (32 bytes hex)
privateKey: 'YOUR_PRIVATE_KEY_HEX', // DO NOT COMMIT THIS!
// Destination address
destination: {
address: 'tmYOUR_DESTINATION_ADDRESS', // Testnet transparent address
amount: 9990000n, // Send 0.0999 ZEC (leaving 10000 for fee)
}
};
async function createTestnetTransaction() {
console.log('🔧 Creating Zcash Testnet Transaction\n');
// Validate configuration
if (CONFIG.utxo.txid === 'YOUR_TXID_HERE') {
console.error('❌ ERROR: Please update CONFIG in create-testnet-tx.js with your testnet values');
console.log('\n📝 Steps:');
console.log('1. Get testnet ZEC from faucet: https://faucet.zecpages.com/');
console.log('2. Run: zcash-cli -testnet listunspent');
console.log('3. Update CONFIG.utxo with your UTXO details');
console.log('4. Update CONFIG.privateKey with your private key');
console.log('5. Update CONFIG.destination.address');
process.exit(1);
}
try {
// Prepare inputs
const inputs = [[
{
txid: CONFIG.utxo.txid,
vout: CONFIG.utxo.vout,
sequence: 0xFFFFFFFE, // Enable RBF
},
{
value: CONFIG.utxo.value,
scriptPubKey: CONFIG.utxo.scriptPubKey,
}
]];
// Prepare payment request
const request = {
payments: [{
address: CONFIG.destination.address,
amount: CONFIG.destination.amount,
}]
};
console.log('📋 Transaction Details:');
console.log(' Input:', CONFIG.utxo.txid.slice(0, 16) + '...', 'vout:', CONFIG.utxo.vout);
console.log(' Amount:', CONFIG.utxo.value.toString(), 'zatoshis');
console.log(' Send to:', CONFIG.destination.address);
console.log(' Send amount:', CONFIG.destination.amount.toString(), 'zatoshis');
console.log(' Fee: ~10000 zatoshis\n');
// Step 1: Create PCZT
console.log('1️⃣ Creating PCZT...');
const pczt = await proposeTransaction(inputs, request);
console.log('✅ PCZT created');
// Step 2: Get sighash
console.log('\n2️⃣ Computing sighash...');
const sighash = await getSighash(pczt, 0);
console.log('✅ Sighash:', Buffer.from(sighash.hash).toString('hex'));
// Step 3: Sign with private key
console.log('\n3️⃣ Signing transaction...');
const privateKeyBuffer = Buffer.from(CONFIG.privateKey, 'hex');
const messageHash = Buffer.from(sighash.hash);
const sigObj = secp256k1.ecdsaSign(messageHash, privateKeyBuffer);
// Encode to DER format + SIGHASH_ALL
const derSig = secp256k1.signatureExport(sigObj.signature);
const signature = Buffer.concat([derSig, Buffer.from([0x01])]); // Add SIGHASH_ALL
console.log('✅ Signature created:', signature.toString('hex').slice(0, 32) + '...');
// Step 4: Append signature
console.log('\n4️⃣ Appending signature to PCZT...');
const signedPczt = await appendSignature(pczt, 0, signature);
console.log('✅ Signature appended');
// Step 5: Finalize
console.log('\n5️⃣ Finalizing transaction...');
const txBytes = await finalizeAndExtract(signedPczt);
const txHex = Buffer.from(txBytes).toString('hex');
console.log('✅ Transaction finalized!');
console.log(' Size:', txBytes.length, 'bytes');
console.log('\n📤 Raw Transaction (hex):');
console.log(txHex);
console.log('\n🚀 Next Steps:');
console.log('1. Broadcast with: zcash-cli -testnet sendrawtransaction', txHex.slice(0, 32) + '...');
console.log('2. Or use block explorer to broadcast');
console.log('3. Wait for confirmation and note the TXID');
console.log('\n💡 Save this TXID for bounty submission!');
} catch (error) {
console.error('\n❌ Error:', error.message);
console.error(error.stack);
process.exit(1);
}
}
// Run
createTestnetTransaction().catch(console.error);