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
use crate::{ Address, AddressType, ByteArray, Opcode::*, Pubkey, Script, SigHashFlags, Signatory, TxBuilder, TxOutput, TxPreimage, MAX_SIGNATURE_SIZE, }; #[derive(Clone)] pub struct P2PKHSignatory { pub pubkey: Pubkey, pub sig_hash_flags: SigHashFlags, } #[crate::script(P2PKHInputs, crate = "crate")] pub fn p2pkh_script(address: &Address, sig: ByteArray, pubkey: ByteArray) { OP_DUP(pubkey); let pk_hashed = OP_HASH160(pubkey); let pk_hash = address.hash(); OP_EQUALVERIFY(pk_hashed, pk_hash); let success = OP_CHECKSIG(sig, pubkey); } #[crate::script(P2SHInputs, crate = "crate")] pub fn p2sh_script(address: &Address, redeem_script: ByteArray) { let script_hashed = OP_HASH160(redeem_script); let script_hash = address.hash(); let success = OP_EQUAL(script_hashed, script_hash); } impl Into<Script> for &'_ Address<'_> { fn into(self) -> Script { match self.addr_type() { AddressType::P2SH => p2sh_script(self).into(), AddressType::P2PKH => p2pkh_script(self).into(), } } } impl Into<Script> for Address<'_> { fn into(self) -> Script { match self.addr_type() { AddressType::P2SH => p2sh_script(&self).into(), AddressType::P2PKH => p2pkh_script(&self).into(), } } } impl<'b> Signatory for P2PKHSignatory { type Script = P2PKHInputs; type Signatures = ByteArray; fn sig_hash_flags(&self) -> Vec<SigHashFlags> { vec![self.sig_hash_flags] } fn placeholder_signatures(&self) -> Self::Signatures { ByteArray::new_unnamed(vec![0; MAX_SIGNATURE_SIZE]) } fn build_script( &self, _tx_preimage: &[TxPreimage], _unsigned_tx: &TxBuilder, sigs: Self::Signatures, _lock_script: &Script, _tx_outputs: &[TxOutput], ) -> Self::Script { P2PKHInputs { pubkey: self.pubkey.as_slice().into(), sig: sigs.concat(ByteArray::new( "sig_hash", [self.sig_hash_flags.bits() as u8].as_ref(), )), } } fn is_p2sh(&self) -> bool { false } }