Implementing (W)Pubkey/ScriptHash and BlockHash
This commit is contained in:
parent
ec92a05682
commit
5ef39e34fa
|
@ -26,6 +26,7 @@ use util;
|
||||||
use util::Error::{BlockBadTarget, BlockBadProofOfWork};
|
use util::Error::{BlockBadTarget, BlockBadProofOfWork};
|
||||||
use util::hash::{BitcoinHash, MerkleRoot, bitcoin_merkle_root};
|
use util::hash::{BitcoinHash, MerkleRoot, bitcoin_merkle_root};
|
||||||
use util::uint::Uint256;
|
use util::uint::Uint256;
|
||||||
|
use hash_types::BlockHash;
|
||||||
use consensus::encode::Encodable;
|
use consensus::encode::Encodable;
|
||||||
use network::constants::Network;
|
use network::constants::Network;
|
||||||
use blockdata::transaction::Transaction;
|
use blockdata::transaction::Transaction;
|
||||||
|
@ -39,7 +40,7 @@ pub struct BlockHeader {
|
||||||
/// The protocol version. Should always be 1.
|
/// The protocol version. Should always be 1.
|
||||||
pub version: u32,
|
pub version: u32,
|
||||||
/// Reference to the previous block in the chain
|
/// Reference to the previous block in the chain
|
||||||
pub prev_blockhash: sha256d::Hash,
|
pub prev_blockhash: BlockHash,
|
||||||
/// The root hash of the merkle tree of transactions in the block
|
/// The root hash of the merkle tree of transactions in the block
|
||||||
pub merkle_root: sha256d::Hash,
|
pub merkle_root: sha256d::Hash,
|
||||||
/// The timestamp of the block, as claimed by the miner
|
/// The timestamp of the block, as claimed by the miner
|
||||||
|
|
|
@ -49,3 +49,5 @@ hash_newtype!(WScriptHash, sha256::Hash, 32, doc="SegWit version of a Bitcoin Sc
|
||||||
hash_newtype!(XpubIdentifier, hash160::Hash, 20, doc="XpubIdentifier as defined in BIP-32.");
|
hash_newtype!(XpubIdentifier, hash160::Hash, 20, doc="XpubIdentifier as defined in BIP-32.");
|
||||||
|
|
||||||
impl_hashencode!(Txid);
|
impl_hashencode!(Txid);
|
||||||
|
impl_hashencode!(Wtxid);
|
||||||
|
impl_hashencode!(BlockHash);
|
||||||
|
|
|
@ -46,6 +46,7 @@ use std::str::FromStr;
|
||||||
use bech32;
|
use bech32;
|
||||||
use hashes::{hash160, sha256, Hash};
|
use hashes::{hash160, sha256, Hash};
|
||||||
|
|
||||||
|
use hash_types::{PubkeyHash, ScriptHash, WScriptHash};
|
||||||
use blockdata::opcodes;
|
use blockdata::opcodes;
|
||||||
use blockdata::script;
|
use blockdata::script;
|
||||||
use network::constants::Network;
|
use network::constants::Network;
|
||||||
|
@ -159,9 +160,9 @@ impl FromStr for AddressType {
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub enum Payload {
|
pub enum Payload {
|
||||||
/// pay-to-pkhash address
|
/// pay-to-pkhash address
|
||||||
PubkeyHash(hash160::Hash),
|
PubkeyHash(PubkeyHash),
|
||||||
/// P2SH address
|
/// P2SH address
|
||||||
ScriptHash(hash160::Hash),
|
ScriptHash(ScriptHash),
|
||||||
/// Segwit address
|
/// Segwit address
|
||||||
WitnessProgram {
|
WitnessProgram {
|
||||||
/// The witness program version
|
/// The witness program version
|
||||||
|
@ -175,9 +176,9 @@ impl Payload {
|
||||||
/// Get a [Payload] from an output script (scriptPubkey).
|
/// Get a [Payload] from an output script (scriptPubkey).
|
||||||
pub fn from_script(script: &script::Script) -> Option<Payload> {
|
pub fn from_script(script: &script::Script) -> Option<Payload> {
|
||||||
Some(if script.is_p2pkh() {
|
Some(if script.is_p2pkh() {
|
||||||
Payload::PubkeyHash(Hash::from_slice(&script.as_bytes()[3..23]).unwrap())
|
Payload::PubkeyHash(PubkeyHash::from_slice(&script.as_bytes()[3..23]).unwrap())
|
||||||
} else if script.is_p2sh() {
|
} else if script.is_p2sh() {
|
||||||
Payload::ScriptHash(Hash::from_slice(&script.as_bytes()[2..22]).unwrap())
|
Payload::ScriptHash(ScriptHash::from_slice(&script.as_bytes()[2..22]).unwrap())
|
||||||
} else if script.is_witness_program() {
|
} else if script.is_witness_program() {
|
||||||
// We can unwrap the u5 check and assume script length
|
// We can unwrap the u5 check and assume script length
|
||||||
// because [Script::is_witness_program] makes sure of this.
|
// because [Script::is_witness_program] makes sure of this.
|
||||||
|
@ -247,7 +248,7 @@ impl Address {
|
||||||
|
|
||||||
Address {
|
Address {
|
||||||
network: network,
|
network: network,
|
||||||
payload: Payload::PubkeyHash(hash160::Hash::from_engine(hash_engine)),
|
payload: Payload::PubkeyHash(PubkeyHash::from_engine(hash_engine)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +258,7 @@ impl Address {
|
||||||
pub fn p2sh(script: &script::Script, network: Network) -> Address {
|
pub fn p2sh(script: &script::Script, network: Network) -> Address {
|
||||||
Address {
|
Address {
|
||||||
network: network,
|
network: network,
|
||||||
payload: Payload::ScriptHash(hash160::Hash::hash(&script[..])),
|
payload: Payload::ScriptHash(ScriptHash::hash(&script[..])),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +289,7 @@ impl Address {
|
||||||
|
|
||||||
Address {
|
Address {
|
||||||
network: network,
|
network: network,
|
||||||
payload: Payload::ScriptHash(hash160::Hash::hash(builder.into_script().as_bytes())),
|
payload: Payload::ScriptHash(ScriptHash::hash(builder.into_script().as_bytes())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +299,7 @@ impl Address {
|
||||||
network: network,
|
network: network,
|
||||||
payload: Payload::WitnessProgram {
|
payload: Payload::WitnessProgram {
|
||||||
version: bech32::u5::try_from_u8(0).expect("0<32"),
|
version: bech32::u5::try_from_u8(0).expect("0<32"),
|
||||||
program: sha256::Hash::hash(&script[..])[..].to_vec(),
|
program: WScriptHash::hash(&script[..])[..].to_vec(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,7 +314,7 @@ impl Address {
|
||||||
|
|
||||||
Address {
|
Address {
|
||||||
network: network,
|
network: network,
|
||||||
payload: Payload::ScriptHash(hash160::Hash::hash(&ws[..])),
|
payload: Payload::ScriptHash(ScriptHash::hash(&ws[..])),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,19 +471,19 @@ impl FromStr for Address {
|
||||||
let (network, payload) = match data[0] {
|
let (network, payload) = match data[0] {
|
||||||
0 => (
|
0 => (
|
||||||
Network::Bitcoin,
|
Network::Bitcoin,
|
||||||
Payload::PubkeyHash(hash160::Hash::from_slice(&data[1..]).unwrap()),
|
Payload::PubkeyHash(PubkeyHash::from_slice(&data[1..]).unwrap()),
|
||||||
),
|
),
|
||||||
5 => (
|
5 => (
|
||||||
Network::Bitcoin,
|
Network::Bitcoin,
|
||||||
Payload::ScriptHash(hash160::Hash::from_slice(&data[1..]).unwrap()),
|
Payload::ScriptHash(ScriptHash::from_slice(&data[1..]).unwrap()),
|
||||||
),
|
),
|
||||||
111 => (
|
111 => (
|
||||||
Network::Testnet,
|
Network::Testnet,
|
||||||
Payload::PubkeyHash(hash160::Hash::from_slice(&data[1..]).unwrap()),
|
Payload::PubkeyHash(PubkeyHash::from_slice(&data[1..]).unwrap()),
|
||||||
),
|
),
|
||||||
196 => (
|
196 => (
|
||||||
Network::Testnet,
|
Network::Testnet,
|
||||||
Payload::ScriptHash(hash160::Hash::from_slice(&data[1..]).unwrap()),
|
Payload::ScriptHash(ScriptHash::from_slice(&data[1..]).unwrap()),
|
||||||
),
|
),
|
||||||
x => return Err(Error::Base58(base58::Error::InvalidVersion(vec![x]))),
|
x => return Err(Error::Base58(base58::Error::InvalidVersion(vec![x]))),
|
||||||
};
|
};
|
||||||
|
@ -505,7 +506,7 @@ mod tests {
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::string::ToString;
|
use std::string::ToString;
|
||||||
|
|
||||||
use hashes::{hash160, Hash};
|
use hashes::Hash;
|
||||||
use hex::{decode as hex_decode, encode as hex_encode};
|
use hex::{decode as hex_decode, encode as hex_encode};
|
||||||
|
|
||||||
use blockdata::script::Script;
|
use blockdata::script::Script;
|
||||||
|
@ -517,7 +518,8 @@ mod tests {
|
||||||
macro_rules! hex (($hex:expr) => (hex_decode($hex).unwrap()));
|
macro_rules! hex (($hex:expr) => (hex_decode($hex).unwrap()));
|
||||||
macro_rules! hex_key (($hex:expr) => (PublicKey::from_slice(&hex!($hex)).unwrap()));
|
macro_rules! hex_key (($hex:expr) => (PublicKey::from_slice(&hex!($hex)).unwrap()));
|
||||||
macro_rules! hex_script (($hex:expr) => (Script::from(hex!($hex))));
|
macro_rules! hex_script (($hex:expr) => (Script::from(hex!($hex))));
|
||||||
macro_rules! hex_hash160 (($hex:expr) => (hash160::Hash::from_slice(&hex!($hex)).unwrap()));
|
macro_rules! hex_pubkeyhash (($hex:expr) => (PubkeyHash::from_slice(&hex!($hex)).unwrap()));
|
||||||
|
macro_rules! hex_scripthash (($hex:expr) => (ScriptHash::from_slice(&hex!($hex)).unwrap()));
|
||||||
|
|
||||||
fn roundtrips(addr: &Address) {
|
fn roundtrips(addr: &Address) {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -539,7 +541,7 @@ mod tests {
|
||||||
fn test_p2pkh_address_58() {
|
fn test_p2pkh_address_58() {
|
||||||
let addr = Address {
|
let addr = Address {
|
||||||
network: Bitcoin,
|
network: Bitcoin,
|
||||||
payload: Payload::PubkeyHash(hex_hash160!("162c5ea71c0b23f5b9022ef047c4a86470a5b070")),
|
payload: Payload::PubkeyHash(hex_pubkeyhash!("162c5ea71c0b23f5b9022ef047c4a86470a5b070")),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -568,7 +570,7 @@ mod tests {
|
||||||
fn test_p2sh_address_58() {
|
fn test_p2sh_address_58() {
|
||||||
let addr = Address {
|
let addr = Address {
|
||||||
network: Bitcoin,
|
network: Bitcoin,
|
||||||
payload: Payload::ScriptHash(hex_hash160!("162c5ea71c0b23f5b9022ef047c4a86470a5b070")),
|
payload: Payload::ScriptHash(hex_scripthash!("162c5ea71c0b23f5b9022ef047c4a86470a5b070")),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -21,11 +21,12 @@
|
||||||
use secp256k1::{self, Secp256k1};
|
use secp256k1::{self, Secp256k1};
|
||||||
use PrivateKey;
|
use PrivateKey;
|
||||||
use PublicKey;
|
use PublicKey;
|
||||||
use hashes::{hash160, sha256, Hash, HashEngine, Hmac, HmacEngine};
|
use hashes::{sha256, Hash, HashEngine, Hmac, HmacEngine};
|
||||||
use blockdata::{opcodes, script};
|
use blockdata::{opcodes, script};
|
||||||
|
|
||||||
use std::{error, fmt};
|
use std::{error, fmt};
|
||||||
|
|
||||||
|
use hash_types::ScriptHash;
|
||||||
use network::constants::Network;
|
use network::constants::Network;
|
||||||
use util::address;
|
use util::address;
|
||||||
|
|
||||||
|
@ -208,7 +209,7 @@ pub fn create_address<C: secp256k1::Verification>(secp: &Secp256k1<C>,
|
||||||
Ok(address::Address {
|
Ok(address::Address {
|
||||||
network: network,
|
network: network,
|
||||||
payload: address::Payload::ScriptHash(
|
payload: address::Payload::ScriptHash(
|
||||||
hash160::Hash::hash(&script[..])
|
ScriptHash::hash(&script[..])
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue