implementing script singing in progress
This commit is contained in:
parent
2ac5ee73d3
commit
93ef222a25
|
@ -19,6 +19,7 @@ pub mod hash;
|
|||
pub mod merkle_root;
|
||||
pub mod network;
|
||||
pub mod reader;
|
||||
pub mod sign;
|
||||
pub mod stream;
|
||||
pub mod transaction;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ impl Builder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn push_num(mut self, num: Num) -> Self {
|
||||
pub fn push_num(self, num: Num) -> Self {
|
||||
self.push_data(&num.to_vec())
|
||||
}
|
||||
|
||||
|
|
|
@ -7,11 +7,47 @@ use script::{script, Script, Num, VerificationFlags, Opcode, Error, read_usize};
|
|||
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
pub enum SignatureHash {
|
||||
pub enum SighashBase {
|
||||
All = 1,
|
||||
None = 2,
|
||||
Single = 3,
|
||||
AnyoneCanPay = 0x80,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
pub struct Sighash {
|
||||
base: SighashBase,
|
||||
anyone_can_pay: bool,
|
||||
}
|
||||
|
||||
impl From<Sighash> for u8 {
|
||||
fn from(s: Sighash) -> Self {
|
||||
let base = s.base as u8;
|
||||
match s.anyone_can_pay {
|
||||
true => base | 0x80,
|
||||
false => base,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Sighash {
|
||||
fn from_u8(u: u8) -> Option<Self> {
|
||||
let (base, anyone_can_pay) = match u {
|
||||
1 => (SighashBase::All, false),
|
||||
2 => (SighashBase::None, false),
|
||||
3 => (SighashBase::Single, false),
|
||||
0x81 => (SighashBase::All, true),
|
||||
0x82 => (SighashBase::None, true),
|
||||
0x83 => (SighashBase::Single, true),
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
let sighash = Sighash {
|
||||
base: base,
|
||||
anyone_can_pay: anyone_can_pay
|
||||
};
|
||||
|
||||
Some(sighash)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
|
@ -79,10 +115,7 @@ impl SignatureChecker for TransactionSignatureChecker {
|
|||
return false;
|
||||
}
|
||||
|
||||
let hash_type = script_signature.last().unwrap();
|
||||
|
||||
|
||||
|
||||
let _hash_type = script_signature.last().unwrap();
|
||||
|
||||
unimplemented!();
|
||||
}
|
||||
|
@ -98,18 +131,18 @@ impl SignatureChecker for TransactionSignatureChecker {
|
|||
}
|
||||
|
||||
fn signature_hash(
|
||||
script_code: &Script,
|
||||
_script_code: &Script,
|
||||
tx: &Transaction,
|
||||
i: usize,
|
||||
hash_type: i32,
|
||||
amount: u32,
|
||||
version: SignatureVersion
|
||||
_amount: u32,
|
||||
_version: SignatureVersion
|
||||
) -> H256 {
|
||||
if i >= tx.transaction_inputs().len() {
|
||||
return h256_from_u8(1);
|
||||
}
|
||||
|
||||
if (hash_type & 0x1f) == SignatureHash::Single as i32 {
|
||||
if (hash_type & 0x1f) == SighashBase::Single as i32 {
|
||||
if i >= tx.transaction_outputs().len() {
|
||||
return h256_from_u8(1);
|
||||
}
|
||||
|
@ -241,11 +274,7 @@ fn is_defined_hashtype_signature(sig: &[u8]) -> bool {
|
|||
return false;
|
||||
}
|
||||
|
||||
let n_hashtype = sig[sig.len() -1] & !(SignatureHash::AnyoneCanPay as u8);
|
||||
if n_hashtype < SignatureHash::All as u8 && n_hashtype > SignatureHash::Single as u8 {
|
||||
return false
|
||||
}
|
||||
true
|
||||
Sighash::from_u8(sig[sig.len() -1]).is_some()
|
||||
}
|
||||
|
||||
fn check_signature_encoding(sig: &[u8], flags: &VerificationFlags) -> Result<(), Error> {
|
||||
|
|
|
@ -11,7 +11,7 @@ mod standard;
|
|||
pub use self::builder::Builder;
|
||||
pub use self::error::Error;
|
||||
pub use self::flags::VerificationFlags;
|
||||
pub use self::interpreter::eval_script;
|
||||
pub use self::interpreter::{eval_script, Sighash};
|
||||
pub use self::opcode::Opcode;
|
||||
pub use self::num::Num;
|
||||
pub use self::script::{Script, ScriptWitness, read_usize};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::fmt;
|
||||
use hex::ToHex;
|
||||
use script::{Opcode, Error, Num};
|
||||
use script::{Opcode, Error};
|
||||
|
||||
/// Maximum number of bytes pushable to the stack
|
||||
const MAX_SCRIPT_ELEMENT_SIZE: usize = 520;
|
||||
|
@ -172,7 +172,7 @@ impl fmt::Display for Script {
|
|||
}
|
||||
|
||||
pub struct ScriptWitness {
|
||||
script: Vec<Vec<u8>>,
|
||||
_script: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -225,4 +225,16 @@ OP_ADD
|
|||
"#;
|
||||
assert_eq!(script.to_string(), s.to_string());
|
||||
}
|
||||
|
||||
//#[test]
|
||||
//#[ignore]
|
||||
//fn playpen() {
|
||||
//let hex = "47304402202cb265bf10707bf49346c3515dd3d16fc454618c58ec0a0ff448a676c54ff71302206c6624d762a1fcef4618284ead8f08678ac05b13c84235f1654e6ad168233e8201410414e301b2328f17442c0b8310d787bf3d8a404cfbd0704f135b6ad4b2d3ee751310f981926e53a6e8c39bd7d3fefd576c543cce493cbac06388f2651d1aacbfcd".from_hex().unwrap();
|
||||
//let script = Script::new(hex);
|
||||
//let hex2 = "76a914c8e90996c7c6080ee06284600c684ed904d14c5c88ac".from_hex().unwrap();
|
||||
//let script2 = Script::new(hex2);
|
||||
//println!("1:\n{}", script);
|
||||
//println!("2:\n{}", script2);
|
||||
//assert!(false);
|
||||
//}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use script::{Script, ScriptWitness};
|
||||
|
||||
pub struct SignatureData {
|
||||
script: Script,
|
||||
witness: ScriptWitness,
|
||||
_script: Script,
|
||||
_witness: ScriptWitness,
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
use script::Sighash;
|
||||
use keys::KeyPair;
|
||||
use transaction::{Transaction, TransactionOutput, MutableTransaction};
|
||||
|
||||
pub enum Error {
|
||||
InvalidIndex,
|
||||
InvalidPreviousOutputIndex,
|
||||
}
|
||||
|
||||
pub fn sign_signature(
|
||||
key: &KeyPair,
|
||||
tx_from: &Transaction,
|
||||
tx_to: &MutableTransaction,
|
||||
index: usize,
|
||||
hashtype: Sighash
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
if index >= tx_to.transaction_inputs.len() {
|
||||
return Err(Error::InvalidIndex);
|
||||
}
|
||||
|
||||
let input = &tx_to.transaction_inputs[index];
|
||||
let n = input.previous_output().index() as usize;
|
||||
if n >= tx_from.transaction_outputs().len() {
|
||||
return Err(Error::InvalidPreviousOutputIndex);
|
||||
}
|
||||
|
||||
let output = &tx_from.transaction_outputs()[n];
|
||||
sign_signature_with_output(key, output, tx_to, index, hashtype)
|
||||
}
|
||||
|
||||
pub fn sign_signature_with_output(
|
||||
_key: &KeyPair,
|
||||
_output: &TransactionOutput,
|
||||
tx: &MutableTransaction,
|
||||
index: usize,
|
||||
_hashtype: Sighash
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
if index >= tx.transaction_inputs.len() {
|
||||
return Err(Error::InvalidIndex);
|
||||
}
|
||||
|
||||
unimplemented!();
|
||||
}
|
|
@ -41,6 +41,16 @@ impl Deserializable for OutPoint {
|
|||
}
|
||||
}
|
||||
|
||||
impl OutPoint {
|
||||
pub fn hash(&self) -> &H256 {
|
||||
&self.hash
|
||||
}
|
||||
|
||||
pub fn index(&self) -> u32 {
|
||||
self.index
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TransactionInput {
|
||||
previous_output: OutPoint,
|
||||
|
@ -75,6 +85,20 @@ impl Deserializable for TransactionInput {
|
|||
}
|
||||
}
|
||||
|
||||
impl TransactionInput {
|
||||
pub fn previous_output(&self) -> &OutPoint {
|
||||
&self.previous_output
|
||||
}
|
||||
|
||||
pub fn script_sig(&self) -> &[u8] {
|
||||
&self.script_sig
|
||||
}
|
||||
|
||||
pub fn sequence(&self) -> u32 {
|
||||
self.sequence
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TransactionOutput {
|
||||
value: u64,
|
||||
|
@ -159,6 +183,13 @@ impl Transaction {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct MutableTransaction {
|
||||
pub version: i32,
|
||||
pub transaction_inputs: Vec<TransactionInput>,
|
||||
pub transaction_outputs: Vec<TransactionOutput>,
|
||||
pub lock_time: u32,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use hex::FromHex;
|
||||
|
|
Loading…
Reference in New Issue