ark/vtxo/policy/
clause.rs

1
2use bitcoin::absolute::LockTime;
3use bitcoin::hashes::sha256;
4use bitcoin::key::constants::SCHNORR_SIGNATURE_SIZE;
5use bitcoin::secp256k1::schnorr;
6use bitcoin::taproot::{self, ControlBlock};
7use bitcoin::{Sequence, VarInt, Witness};
8use bitcoin::{secp256k1::PublicKey, ScriptBuf};
9
10use bitcoin_ext::{BlockDelta, BlockHeight};
11
12use crate::vtxo::policy::Policy;
13use crate::Vtxo;
14use crate::scripts;
15
16/// A trait describing a VTXO policy clause.
17///
18/// It can be used when creating the VTXO, specifying the script pubkey,
19/// and check the satisfaction weight when spending it.
20pub trait TapScriptClause: Sized + Clone {
21	/// The type of witness data required to sign the clause.
22	type WitnessData;
23
24	/// Returns the tapscript for the clause.
25	fn tapscript(&self) -> ScriptBuf;
26
27	/// Construct the taproot control block for spending the VTXO using this clause
28	fn control_block<G, P: Policy>(&self, vtxo: &Vtxo<G, P>) -> ControlBlock {
29		vtxo.output_taproot()
30			.control_block(&(self.tapscript(), taproot::LeafVersion::TapScript))
31			.expect("clause is not in taproot tree")
32	}
33
34	/// Computes the total witness size in bytes for spending via this clause.
35	fn witness_size<G, P: Policy>(&self, vtxo: &Vtxo<G, P>) -> usize;
36
37	/// Constructs the witness for the clause.
38	fn witness(
39		&self,
40		data: &Self::WitnessData,
41		control_block: &ControlBlock,
42	) -> Witness;
43}
44
45/// A clause that allows to sign and spend the UTXO after a relative
46/// timelock.
47#[derive(Debug, Clone)]
48pub struct DelayedSignClause {
49	pub pubkey: PublicKey,
50	pub block_delta: BlockDelta,
51}
52
53impl DelayedSignClause {
54	/// Returns the input sequence value for this clause.
55	pub fn sequence(&self) -> Sequence {
56		Sequence::from_height(self.block_delta)
57	}
58}
59
60impl TapScriptClause for DelayedSignClause {
61	type WitnessData = schnorr::Signature;
62
63	fn tapscript(&self) -> ScriptBuf {
64		scripts::delayed_sign(self.block_delta, self.pubkey.x_only_public_key().0)
65	}
66
67	fn witness(
68		&self,
69		signature: &Self::WitnessData,
70		control_block: &ControlBlock,
71	) -> Witness {
72		Witness::from_slice(&[
73			&signature[..],
74			self.tapscript().as_bytes(),
75			&control_block.serialize()[..],
76		])
77	}
78
79
80	fn witness_size<G, P: Policy>(&self, vtxo: &Vtxo<G, P>) -> usize {
81		let cb_size = self.control_block(vtxo).size();
82		let tapscript_size = self.tapscript().as_bytes().len();
83
84		1 // byte for the number of witness elements
85		+ 1  // schnorr signature size byte
86		+ SCHNORR_SIGNATURE_SIZE // schnorr sig bytes
87		+ VarInt::from(tapscript_size).size()  // tapscript size bytes
88		+ tapscript_size // tapscript bytes
89		+ VarInt::from(cb_size).size()  // control block size bytes
90		+ cb_size // control block bytes
91	}
92}
93
94impl Into<VtxoClause> for DelayedSignClause {
95	fn into(self) -> VtxoClause {
96		VtxoClause::DelayedSign(self)
97	}
98}
99
100/// A clause that allows to sign and spend the UTXO after an absolute
101/// timelock.
102#[derive(Debug, Clone)]
103pub struct TimelockSignClause {
104	pub pubkey: PublicKey,
105	pub timelock_height: BlockHeight,
106}
107
108impl TimelockSignClause {
109	/// Returns the absolute locktime for this clause.
110	pub fn locktime(&self) -> LockTime {
111		LockTime::from_height(self.timelock_height).expect("timelock height is valid")
112	}
113}
114
115impl TapScriptClause for TimelockSignClause {
116	type WitnessData = schnorr::Signature;
117
118	fn tapscript(&self) -> ScriptBuf {
119		scripts::timelock_sign(self.timelock_height, self.pubkey.x_only_public_key().0)
120	}
121
122	fn witness(
123		&self,
124		signature: &Self::WitnessData,
125		control_block: &ControlBlock,
126	) -> Witness {
127		Witness::from_slice(&[
128			&signature[..],
129			self.tapscript().as_bytes(),
130			&control_block.serialize()[..],
131		])
132	}
133
134	fn witness_size<G, P: Policy>(&self, vtxo: &Vtxo<G, P>) -> usize {
135		let cb_size = self.control_block(vtxo).size();
136		let tapscript_size = self.tapscript().as_bytes().len();
137
138		1 // byte for the number of witness elements
139		+ 1  // schnorr signature size byte
140		+ SCHNORR_SIGNATURE_SIZE // schnorr sig bytes
141		+ VarInt::from(tapscript_size).size()  // tapscript size bytes
142		+ tapscript_size // tapscript bytes
143		+ VarInt::from(cb_size).size()  // control block size bytes
144		+ cb_size // control block bytes
145	}
146}
147
148impl Into<VtxoClause> for TimelockSignClause {
149	fn into(self) -> VtxoClause {
150		VtxoClause::TimelockSign(self)
151	}
152}
153
154/// A clause that allows to sign and spend the UTXO after a relative
155/// timelock, with an additional absolute one.
156#[derive(Debug, Clone)]
157pub struct DelayedTimelockSignClause {
158	pub pubkey: PublicKey,
159	pub timelock_height: BlockHeight,
160	pub block_delta: BlockDelta,
161}
162
163impl DelayedTimelockSignClause {
164	/// Returns the input sequence for this clause.
165	pub fn sequence(&self) -> Sequence {
166		Sequence::from_height(self.block_delta)
167	}
168
169	/// Returns the absolute locktime for this clause.
170	pub fn locktime(&self) -> LockTime {
171		LockTime::from_height(self.timelock_height).expect("timelock height is valid")
172	}
173}
174
175impl TapScriptClause for DelayedTimelockSignClause {
176	type WitnessData = schnorr::Signature;
177
178	fn tapscript(&self) -> ScriptBuf {
179		scripts::delay_timelock_sign(
180			self.block_delta,
181			self.timelock_height,
182			self.pubkey.x_only_public_key().0,
183		)
184	}
185
186	fn witness(
187		&self,
188		signature: &Self::WitnessData,
189		control_block: &ControlBlock,
190	) -> Witness {
191		Witness::from_slice(&[
192			&signature[..],
193			self.tapscript().as_bytes(),
194			&control_block.serialize()[..],
195		])
196	}
197
198	fn witness_size<G, P: Policy>(&self, vtxo: &Vtxo<G, P>) -> usize {
199		let cb_size = self.control_block(vtxo).size();
200		let tapscript_size = self.tapscript().as_bytes().len();
201
202		1 // byte for the number of witness elements
203		+ 1  // schnorr signature size byte
204		+ SCHNORR_SIGNATURE_SIZE // schnorr sig bytes
205		+ VarInt::from(tapscript_size).size()  // tapscript size bytes
206		+ tapscript_size // tapscript bytes
207		+ VarInt::from(cb_size).size()  // control block size bytes
208		+ cb_size // control block bytes
209	}
210}
211
212impl Into<VtxoClause> for DelayedTimelockSignClause {
213	fn into(self) -> VtxoClause {
214		VtxoClause::DelayedTimelockSign(self)
215	}
216}
217
218/// A clause that allows to sign and spend the UTXO after a relative
219/// timelock, if preimage matching the hash is provided.
220#[derive(Debug, Clone)]
221pub struct HashDelaySignClause {
222	pub pubkey: PublicKey,
223	pub hash: sha256::Hash,
224	pub block_delta: BlockDelta,
225}
226
227impl HashDelaySignClause {
228	/// Returns the input sequence for this clause.
229	pub fn sequence(&self) -> Sequence {
230		Sequence::from_height(self.block_delta)
231	}
232}
233
234impl TapScriptClause for HashDelaySignClause {
235	type WitnessData = (schnorr::Signature, [u8; 32]);
236
237	fn tapscript(&self) -> ScriptBuf {
238		scripts::hash_delay_sign(
239			self.hash,
240			self.block_delta,
241			self.pubkey.x_only_public_key().0,
242		)
243	}
244
245	fn witness(
246		&self,
247		data: &Self::WitnessData,
248		control_block: &ControlBlock,
249	) -> Witness {
250		let (signature, preimage) = data;
251		Witness::from_slice(&[
252			&signature[..],
253			&preimage[..],
254			self.tapscript().as_bytes(),
255			&control_block.serialize()[..],
256		])
257	}
258
259	fn witness_size<G, P: Policy>(&self, vtxo: &Vtxo<G, P>) -> usize {
260		let cb_size = self.control_block(vtxo).size();
261		let tapscript_size = self.tapscript().as_bytes().len();
262
263		1 // byte for the number of witness elements
264		+ 1  // schnorr signature size byte
265		+ SCHNORR_SIGNATURE_SIZE // schnorr sig bytes
266		+ 1  // preimage size byte
267		+ 32 // preimage bytes
268		+ VarInt::from(tapscript_size).size()  // tapscript size bytes
269		+ tapscript_size // tapscript bytes
270		+ VarInt::from(cb_size).size()  // control block size bytes
271		+ cb_size // control block bytes
272	}
273}
274
275impl Into<VtxoClause> for HashDelaySignClause {
276	fn into(self) -> VtxoClause {
277		VtxoClause::HashDelaySign(self)
278	}
279}
280
281/// A clause that allows spending by revealing a preimage and providing a signature.
282///
283/// This is used for the unlock clause in hArk leaf outputs, where the aggregate
284/// pubkey of user+server must sign, and a preimage must be revealed.
285#[derive(Debug, Clone)]
286pub struct HashSignClause {
287	pub pubkey: PublicKey,
288	pub hash: sha256::Hash,
289}
290
291impl TapScriptClause for HashSignClause {
292	type WitnessData = (schnorr::Signature, [u8; 32]);
293
294	fn tapscript(&self) -> ScriptBuf {
295		scripts::hash_and_sign(self.hash, self.pubkey.x_only_public_key().0)
296	}
297
298	fn witness(
299		&self,
300		data: &Self::WitnessData,
301		control_block: &ControlBlock,
302	) -> Witness {
303		let (signature, preimage) = data;
304		Witness::from_slice(&[
305			&signature[..],
306			&preimage[..],
307			self.tapscript().as_bytes(),
308			&control_block.serialize()[..],
309		])
310	}
311
312	fn witness_size<G, P: Policy>(&self, vtxo: &Vtxo<G, P>) -> usize {
313		let cb_size = self.control_block(vtxo).size();
314		let tapscript_size = 57;
315
316		debug_assert_eq!(tapscript_size, self.tapscript().as_bytes().len());
317
318		1 // byte for the number of witness elements
319		+ 1  // schnorr signature size byte
320		+ SCHNORR_SIGNATURE_SIZE // schnorr sig bytes
321		+ 1  // preimage size byte
322		+ 32 // preimage bytes
323		+ VarInt::from(tapscript_size).size()  // tapscript size bytes
324		+ tapscript_size // tapscript bytes
325		+ VarInt::from(cb_size).size()  // control block size bytes
326		+ cb_size // control block bytes
327	}
328}
329
330impl Into<VtxoClause> for HashSignClause {
331	fn into(self) -> VtxoClause {
332		VtxoClause::HashSign(self)
333	}
334}
335
336#[derive(Debug, Clone)]
337pub enum VtxoClause {
338	DelayedSign(DelayedSignClause),
339	TimelockSign(TimelockSignClause),
340	DelayedTimelockSign(DelayedTimelockSignClause),
341	HashDelaySign(HashDelaySignClause),
342	HashSign(HashSignClause),
343}
344
345impl VtxoClause {
346	/// Returns the public key associated with this clause.
347	pub fn pubkey(&self) -> PublicKey {
348		match self {
349			Self::DelayedSign(c) => c.pubkey,
350			Self::TimelockSign(c) => c.pubkey,
351			Self::DelayedTimelockSign(c) => c.pubkey,
352			Self::HashDelaySign(c) => c.pubkey,
353			Self::HashSign(c) => c.pubkey,
354		}
355	}
356
357
358	/// Returns the tapscript for this clause.
359	pub fn tapscript(&self) -> ScriptBuf {
360		match self {
361			Self::DelayedSign(c) => c.tapscript(),
362			Self::TimelockSign(c) => c.tapscript(),
363			Self::DelayedTimelockSign(c) => c.tapscript(),
364			Self::HashDelaySign(c) => c.tapscript(),
365			Self::HashSign(c) => c.tapscript(),
366		}
367	}
368
369	/// Returns the input sequence for this clause, if applicable.
370	pub fn sequence(&self) -> Option<Sequence> {
371		match self {
372			Self::DelayedSign(c) => Some(c.sequence()),
373			Self::TimelockSign(_) => None,
374			Self::DelayedTimelockSign(c) => Some(c.sequence()),
375			Self::HashDelaySign(c) => Some(c.sequence()),
376			Self::HashSign(_) => None,
377		}
378	}
379
380	/// Computes the total witness size in bytes for spending the VTXO via this clause.
381	pub fn control_block<G, P: Policy>(&self, vtxo: &Vtxo<G, P>) -> ControlBlock {
382		match self {
383			Self::DelayedSign(c) => c.control_block(vtxo),
384			Self::TimelockSign(c) => c.control_block(vtxo),
385			Self::DelayedTimelockSign(c) => c.control_block(vtxo),
386			Self::HashDelaySign(c) => c.control_block(vtxo),
387			Self::HashSign(c) => c.control_block(vtxo),
388		}
389	}
390
391	/// Computes the total witness size in bytes for spending the VTXO via this clause.
392	pub fn witness_size<G, P: Policy>(&self, vtxo: &Vtxo<G, P>) -> usize {
393		match self {
394			Self::DelayedSign(c) => c.witness_size(vtxo),
395			Self::TimelockSign(c) => c.witness_size(vtxo),
396			Self::DelayedTimelockSign(c) => c.witness_size(vtxo),
397			Self::HashDelaySign(c) => c.witness_size(vtxo),
398			Self::HashSign(c) => c.witness_size(vtxo),
399		}
400	}
401}
402
403#[cfg(test)]
404mod tests {
405	use std::str::FromStr;
406
407	use bitcoin::taproot::TaprootSpendInfo;
408	use bitcoin::{Amount, OutPoint, Transaction, TxIn, TxOut, Txid, sighash};
409	use bitcoin::hashes::Hash;
410	use bitcoin::key::Keypair;
411	use bitcoin_ext::{TaprootSpendInfoExt, fee};
412
413	use crate::{SECP, musig};
414	use crate::test_util::verify_tx;
415
416	use super::*;
417
418	lazy_static! {
419		static ref USER_KEYPAIR: Keypair = Keypair::from_str("5255d132d6ec7d4fc2a41c8f0018bb14343489ddd0344025cc60c7aa2b3fda6a").unwrap();
420		static ref SERVER_KEYPAIR: Keypair = Keypair::from_str("1fb316e653eec61de11c6b794636d230379509389215df1ceb520b65313e5426").unwrap();
421	}
422
423	#[allow(unused)]
424	fn all_clause_tested(clause: VtxoClause) -> bool {
425		// NB: matcher to ensure all clauses are tested
426		match clause {
427			VtxoClause::DelayedSign(_) => true,
428			VtxoClause::TimelockSign(_) => true,
429			VtxoClause::DelayedTimelockSign(_) => true,
430			VtxoClause::HashDelaySign(_) => true,
431			VtxoClause::HashSign(_) => true,
432		}
433	}
434
435	fn transaction() -> Transaction {
436		let address = bitcoin::Address::from_str("tb1q00h5delzqxl7xae8ufmsegghcl4jwfvdnd8530")
437			.unwrap().assume_checked();
438
439		Transaction {
440			version: bitcoin::transaction::Version(3),
441			lock_time: bitcoin::absolute::LockTime::ZERO,
442			input: vec![],
443			output: vec![TxOut {
444				script_pubkey: address.script_pubkey(),
445				value: Amount::from_sat(900_000),
446			}, fee::fee_anchor()]
447		}
448	}
449
450	fn taproot_material(clause_spk: ScriptBuf) -> (TaprootSpendInfo, ControlBlock) {
451		let user_pubkey = USER_KEYPAIR.public_key();
452		let server_pubkey = SERVER_KEYPAIR.public_key();
453
454		let combined_pk = musig::combine_keys([user_pubkey, server_pubkey])
455			.x_only_public_key().0;
456		let taproot = taproot::TaprootBuilder::new()
457			.add_leaf(0, clause_spk.clone()).unwrap()
458			.finalize(&SECP, combined_pk).unwrap();
459
460		let cb = taproot
461			.control_block(&(clause_spk.clone(), taproot::LeafVersion::TapScript))
462			.expect("script is in taproot");
463
464		(taproot, cb)
465	}
466
467	fn signature(tx: &Transaction, input: &TxOut, clause_spk: ScriptBuf) -> schnorr::Signature {
468		let leaf_hash = taproot::TapLeafHash::from_script(
469			&clause_spk,
470			taproot::LeafVersion::TapScript,
471		);
472
473		let mut shc = sighash::SighashCache::new(tx);
474		let sighash = shc.taproot_script_spend_signature_hash(
475			0, &sighash::Prevouts::All(&[input.clone()]), leaf_hash, sighash::TapSighashType::Default,
476		).expect("all prevouts provided");
477
478		SECP.sign_schnorr(&sighash.into(), &*USER_KEYPAIR)
479	}
480
481	#[test]
482	fn test_delayed_sign_clause() {
483		let clause = DelayedSignClause {
484			pubkey: USER_KEYPAIR.public_key(),
485			block_delta: 100,
486		};
487
488		// We compute taproot material for the clause
489		let (taproot, cb) = taproot_material(clause.tapscript());
490		let tx_in = TxOut {
491			script_pubkey: taproot.script_pubkey(),
492			value: Amount::from_sat(1_000_000),
493		};
494
495		// We build transaction spending input containing clause
496		let mut tx = transaction();
497		tx.input.push(TxIn {
498			previous_output: OutPoint::new(Txid::all_zeros(), 0),
499			script_sig: ScriptBuf::default(),
500			sequence: clause.sequence(),
501			witness: Witness::new(),
502		});
503
504		// We compute the signature for the transaction
505		let signature = signature(&tx, &tx_in, clause.tapscript());
506		tx.input[0].witness = clause.witness(&signature, &cb);
507
508		// We verify the transaction
509		verify_tx(&[tx_in], 0, &tx).expect("transaction is invalid");
510	}
511
512	#[test]
513	fn test_timelock_sign_clause() {
514		let clause = TimelockSignClause {
515			pubkey: USER_KEYPAIR.public_key(),
516			timelock_height: 100,
517		};
518
519		// We compute taproot material for the clause
520		let (taproot, cb) = taproot_material(clause.tapscript());
521		let tx_in = TxOut {
522			script_pubkey: taproot.script_pubkey(),
523			value: Amount::from_sat(1_000_000),
524		};
525
526		// We build transaction spending input containing clause
527		let mut tx = transaction();
528		tx.lock_time = clause.locktime();
529		tx.input.push(TxIn {
530			previous_output: OutPoint::new(Txid::all_zeros(), 0),
531			script_sig: ScriptBuf::default(),
532			sequence: Sequence::ZERO,
533			witness: Witness::new(),
534		});
535
536		// We compute the signature for the transaction
537		let signature = signature(&tx, &tx_in, clause.tapscript());
538		tx.input[0].witness = clause.witness(&signature, &cb);
539
540		// We verify the transaction
541		verify_tx(&[tx_in], 0, &tx).expect("transaction is invalid");
542	}
543
544	#[test]
545	fn test_delayed_timelock_clause() {
546		let clause = DelayedTimelockSignClause {
547			pubkey: USER_KEYPAIR.public_key(),
548			timelock_height: 100,
549			block_delta: 24,
550		};
551
552		// We compute taproot material for the clause
553		let (taproot, cb) = taproot_material(clause.tapscript());
554		let tx_in = TxOut {
555			script_pubkey: taproot.script_pubkey(),
556			value: Amount::from_sat(1_000_000),
557		};
558
559		// We build transaction spending input containing clause
560		let mut tx = transaction();
561		tx.lock_time = clause.locktime();
562		tx.input.push(TxIn {
563			previous_output: OutPoint::new(Txid::all_zeros(), 0),
564			script_sig: ScriptBuf::default(),
565			sequence: clause.sequence(),
566			witness: Witness::new(),
567		});
568
569		// We compute the signature for the transaction
570		let signature = signature(&tx, &tx_in, clause.tapscript());
571		tx.input[0].witness = clause.witness(&signature, &cb);
572
573		// We verify the transaction
574		verify_tx(&[tx_in], 0, &tx).expect("transaction is invalid");
575	}
576
577	#[test]
578	fn test_hash_delay_clause() {
579		let preimage = [0; 32];
580
581		let clause = HashDelaySignClause {
582			pubkey: USER_KEYPAIR.public_key(),
583			hash: sha256::Hash::hash(&preimage),
584			block_delta: 24,
585		};
586
587		// We compute taproot material for the clause
588		let (taproot, cb) = taproot_material(clause.tapscript());
589		let tx_in = TxOut {
590			script_pubkey: taproot.script_pubkey(),
591			value: Amount::from_sat(1_000_000),
592		};
593
594		// We build transaction spending input containing clause
595		let mut tx = transaction();
596		tx.input.push(TxIn {
597			previous_output: OutPoint::new(Txid::all_zeros(), 0),
598			script_sig: ScriptBuf::default(),
599			sequence: clause.sequence(),
600			witness: Witness::new(),
601		});
602
603		// We compute the signature for the transaction
604		let signature = signature(&tx, &tx_in, clause.tapscript());
605		tx.input[0].witness = clause.witness(&(signature, preimage), &cb);
606
607		// We verify the transaction
608		verify_tx(&[tx_in], 0, &tx).expect("transaction is invalid");
609	}
610
611	#[test]
612	fn test_hash_sign_clause() {
613		let preimage = [0u8; 32];
614		let hash = sha256::Hash::hash(&preimage);
615
616		// HashSignClause uses an x-only aggregate public key
617		let agg_pk = musig::combine_keys([USER_KEYPAIR.public_key(), SERVER_KEYPAIR.public_key()]);
618
619		let clause = HashSignClause {
620			pubkey: agg_pk,
621			hash,
622		};
623
624		// We compute taproot material for the clause
625		let (taproot, cb) = taproot_material(clause.tapscript());
626		let tx_in = TxOut {
627			script_pubkey: taproot.script_pubkey(),
628			value: Amount::from_sat(1_000_000),
629		};
630
631		// We build transaction spending input containing clause
632		let mut tx = transaction();
633		tx.input.push(TxIn {
634			previous_output: OutPoint::new(Txid::all_zeros(), 0),
635			script_sig: ScriptBuf::default(),
636			sequence: Sequence::ZERO, // HashSignClause has no relative timelock
637			witness: Witness::new(),
638		});
639
640		// For HashSignClause, we need a MuSig signature from both parties
641		let leaf_hash = taproot::TapLeafHash::from_script(
642			&clause.tapscript(),
643			taproot::LeafVersion::TapScript,
644		);
645
646		let mut shc = sighash::SighashCache::new(&tx);
647		let sighash = shc.taproot_script_spend_signature_hash(
648			0, &sighash::Prevouts::All(&[tx_in.clone()]), leaf_hash, sighash::TapSighashType::Default,
649		).expect("all prevouts provided");
650
651		// Create MuSig signature
652		let (user_sec_nonce, user_pub_nonce) = musig::nonce_pair(&*USER_KEYPAIR);
653		let (server_pub_nonce, server_part_sig) = musig::deterministic_partial_sign(
654			&*SERVER_KEYPAIR,
655			[USER_KEYPAIR.public_key()],
656			&[&user_pub_nonce],
657			sighash.to_byte_array(),
658			None,
659		);
660		let agg_nonce = musig::nonce_agg(&[&user_pub_nonce, &server_pub_nonce]);
661
662		let (_user_part_sig, final_sig) = musig::partial_sign(
663			[USER_KEYPAIR.public_key(), SERVER_KEYPAIR.public_key()],
664			agg_nonce,
665			&*USER_KEYPAIR,
666			user_sec_nonce,
667			sighash.to_byte_array(),
668			None,
669			Some(&[&server_part_sig]),
670		);
671		let final_sig = final_sig.expect("should have final signature");
672
673		tx.input[0].witness = clause.witness(&(final_sig, preimage), &cb);
674
675		// We verify the transaction
676		verify_tx(&[tx_in], 0, &tx).expect("transaction is invalid");
677	}
678}