script: add `to_p2wsh()` and `is_p2swsh()` functions to allow easy segwit output computation
This commit is contained in:
parent
c341e21dc6
commit
e5f109221e
|
@ -1,7 +1,7 @@
|
|||
|
||||
[package]
|
||||
name = "bitcoin"
|
||||
version = "0.10.1"
|
||||
version = "0.10.2"
|
||||
authors = ["Andrew Poelstra <apoelstra@wpsoftware.net>"]
|
||||
license = "CC0-1.0"
|
||||
homepage = "https://github.com/apoelstra/rust-bitcoin/"
|
||||
|
|
|
@ -27,11 +27,14 @@
|
|||
use std::default::Default;
|
||||
use std::{error, fmt};
|
||||
|
||||
use crypto::digest::Digest;
|
||||
use crypto::sha2::Sha256;
|
||||
use serde;
|
||||
|
||||
use blockdata::opcodes;
|
||||
use network::encodable::{ConsensusDecodable, ConsensusEncodable};
|
||||
use network::serialize::{SimpleDecoder, SimpleEncoder};
|
||||
use util::hash::Hash160;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
/// A Bitcoin script
|
||||
|
@ -255,6 +258,25 @@ impl Script {
|
|||
/// Convert the script into a byte vector
|
||||
pub fn into_vec(self) -> Vec<u8> { self.0.into_vec() }
|
||||
|
||||
/// Compute the P2SH output corresponding to this redeem script
|
||||
pub fn to_p2sh(&self) -> Script {
|
||||
Builder::new().push_opcode(opcodes::All::OP_HASH160)
|
||||
.push_slice(&Hash160::from_data(&self.0)[..])
|
||||
.push_opcode(opcodes::All::OP_EQUAL)
|
||||
.into_script()
|
||||
}
|
||||
|
||||
/// Compute the P2WSH output corresponding to this redeem script
|
||||
pub fn to_v0_p2wsh(&self) -> Script {
|
||||
let mut tmp = [0; 32];
|
||||
let mut sha2 = Sha256::new();
|
||||
sha2.input(&self.0);
|
||||
sha2.result(&mut tmp);
|
||||
Builder::new().push_int(0)
|
||||
.push_slice(&tmp)
|
||||
.into_script()
|
||||
}
|
||||
|
||||
/// Checks whether a script pubkey is a p2sh output
|
||||
#[inline]
|
||||
pub fn is_p2sh(&self) -> bool {
|
||||
|
@ -275,6 +297,14 @@ impl Script {
|
|||
self.0[24] == opcodes::All::OP_CHECKSIG as u8
|
||||
}
|
||||
|
||||
/// Checks whether a script pubkey is a p2wsh output
|
||||
#[inline]
|
||||
pub fn is_v0_p2wsh(&self) -> bool {
|
||||
self.0.len() == 34 &&
|
||||
self.0[0] == opcodes::All::OP_PUSHBYTES_0 as u8 &&
|
||||
self.0[1] == opcodes::All::OP_PUSHBYTES_32 as u8
|
||||
}
|
||||
|
||||
/// Whether a script can be proven to have no satisfying input
|
||||
pub fn is_provably_unspendable(&self) -> bool {
|
||||
!self.0.is_empty() && (opcodes::All::from(self.0[0]).classify() == opcodes::Class::ReturnOp ||
|
||||
|
@ -637,5 +667,30 @@ mod test {
|
|||
assert!(!hex_script!("a914acc91e6fef5c7f24e5c8b3f11a664aa8f1352ffd87").is_p2pkh());
|
||||
assert!(!hex_script!("a314acc91e6fef5c7f24e5c8b3f11a664aa8f1352ffd87").is_p2sh());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn p2sh_p2wsh_conversion() {
|
||||
// Test vectors taken from Core tests/data/script_tests.json
|
||||
// bare p2wsh
|
||||
let redeem_script = hex_script!("410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac");
|
||||
let expected_witout = hex_script!("0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64");
|
||||
assert!(redeem_script.to_v0_p2wsh().is_v0_p2wsh());
|
||||
assert_eq!(redeem_script.to_v0_p2wsh(), expected_witout);
|
||||
|
||||
// p2sh
|
||||
let redeem_script = hex_script!("0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8");
|
||||
let expected_p2shout = hex_script!("a91491b24bf9f5288532960ac687abb035127b1d28a587");
|
||||
assert!(redeem_script.to_p2sh().is_p2sh());
|
||||
assert_eq!(redeem_script.to_p2sh(), expected_p2shout);
|
||||
|
||||
// p2sh-p2wsh
|
||||
let redeem_script = hex_script!("410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac");
|
||||
let expected_witout = hex_script!("0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64");
|
||||
let expected_out = hex_script!("a914f386c2ba255cc56d20cfa6ea8b062f8b5994551887");
|
||||
assert!(redeem_script.to_p2sh().is_p2sh());
|
||||
assert!(redeem_script.to_p2sh().to_v0_p2wsh().is_v0_p2wsh());
|
||||
assert_eq!(redeem_script.to_v0_p2wsh(), expected_witout);
|
||||
assert_eq!(redeem_script.to_v0_p2wsh().to_p2sh(), expected_out);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue