mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-12 01:55:48 +00:00
Script opcode and data support
Overrides the shift-left operator for pushing opcodes onto the Script, matching the notation used in zcashd.
This commit is contained in:
parent
1862354ea6
commit
dab3c002b7
105
zcash_primitives/src/legacy.rs
Normal file
105
zcash_primitives/src/legacy.rs
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
//! Support for legacy transparent addresses and scripts.
|
||||||
|
|
||||||
|
use byteorder::{ReadBytesExt, WriteBytesExt};
|
||||||
|
use std::io::{self, Read, Write};
|
||||||
|
use std::ops::Shl;
|
||||||
|
|
||||||
|
use crate::serialize::Vector;
|
||||||
|
|
||||||
|
/// Script opcodes.
|
||||||
|
enum OpCode {
|
||||||
|
// push value
|
||||||
|
PushData1 = 0x4c,
|
||||||
|
PushData2 = 0x4d,
|
||||||
|
PushData4 = 0x4e,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A serialized script, used inside transparent inputs and outputs of a transaction.
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Script(pub Vec<u8>);
|
||||||
|
|
||||||
|
impl Script {
|
||||||
|
pub fn read<R: Read>(mut reader: R) -> io::Result<Self> {
|
||||||
|
let script = Vector::read(&mut reader, |r| r.read_u8())?;
|
||||||
|
Ok(Script(script))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
||||||
|
Vector::write(&mut writer, &self.0, |w, e| w.write_u8(*e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Shl<OpCode> for Script {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn shl(mut self, rhs: OpCode) -> Self {
|
||||||
|
self.0.push(rhs as u8);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Shl<&[u8]> for Script {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn shl(mut self, data: &[u8]) -> Self {
|
||||||
|
if data.len() < OpCode::PushData1 as usize {
|
||||||
|
self.0.push(data.len() as u8);
|
||||||
|
} else if data.len() <= 0xff {
|
||||||
|
self.0.push(OpCode::PushData1 as u8);
|
||||||
|
self.0.push(data.len() as u8);
|
||||||
|
} else if data.len() <= 0xffff {
|
||||||
|
self.0.push(OpCode::PushData2 as u8);
|
||||||
|
self.0.extend(&(data.len() as u16).to_le_bytes());
|
||||||
|
} else {
|
||||||
|
self.0.push(OpCode::PushData4 as u8);
|
||||||
|
self.0.extend(&(data.len() as u32).to_le_bytes());
|
||||||
|
}
|
||||||
|
self.0.extend(data);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::{OpCode, Script};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn script_opcode() {
|
||||||
|
{
|
||||||
|
let script = Script::default() << OpCode::PushData1;
|
||||||
|
assert_eq!(&script.0, &[OpCode::PushData1 as u8]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn script_pushdata() {
|
||||||
|
{
|
||||||
|
let script = Script::default() << &[1, 2, 3, 4][..];
|
||||||
|
assert_eq!(&script.0, &[4, 1, 2, 3, 4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let short_data = vec![2; 100];
|
||||||
|
let script = Script::default() << &short_data[..];
|
||||||
|
assert_eq!(script.0[0], OpCode::PushData1 as u8);
|
||||||
|
assert_eq!(script.0[1] as usize, 100);
|
||||||
|
assert_eq!(&script.0[2..], &short_data[..]);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let medium_data = vec![7; 1024];
|
||||||
|
let script = Script::default() << &medium_data[..];
|
||||||
|
assert_eq!(script.0[0], OpCode::PushData2 as u8);
|
||||||
|
assert_eq!(&script.0[1..3], &[0x00, 0x04][..]);
|
||||||
|
assert_eq!(&script.0[3..], &medium_data[..]);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let long_data = vec![42; 1_000_000];
|
||||||
|
let script = Script::default() << &long_data[..];
|
||||||
|
assert_eq!(script.0[0], OpCode::PushData4 as u8);
|
||||||
|
assert_eq!(&script.0[1..5], &[0x40, 0x42, 0x0f, 0x00][..]);
|
||||||
|
assert_eq!(&script.0[5..], &long_data[..]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,7 @@ use sapling_crypto::jubjub::JubjubBls12;
|
|||||||
|
|
||||||
pub mod block;
|
pub mod block;
|
||||||
pub mod keys;
|
pub mod keys;
|
||||||
|
pub mod legacy;
|
||||||
pub mod merkle_tree;
|
pub mod merkle_tree;
|
||||||
pub mod note_encryption;
|
pub mod note_encryption;
|
||||||
pub mod prover;
|
pub mod prover;
|
||||||
|
@ -7,7 +7,7 @@ use sapling_crypto::{
|
|||||||
};
|
};
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
|
|
||||||
use serialize::Vector;
|
use legacy::Script;
|
||||||
use JUBJUB;
|
use JUBJUB;
|
||||||
|
|
||||||
// π_A + π_B + π_C
|
// π_A + π_B + π_C
|
||||||
@ -58,20 +58,6 @@ impl Amount {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Script(pub Vec<u8>);
|
|
||||||
|
|
||||||
impl Script {
|
|
||||||
pub fn read<R: Read>(mut reader: R) -> io::Result<Self> {
|
|
||||||
let script = Vector::read(&mut reader, |r| r.read_u8())?;
|
|
||||||
Ok(Script(script))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
|
||||||
Vector::write(&mut writer, &self.0, |w, e| w.write_u8(*e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct OutPoint {
|
pub struct OutPoint {
|
||||||
hash: [u8; 32],
|
hash: [u8; 32],
|
||||||
|
@ -3,10 +3,11 @@ use byteorder::{LittleEndian, WriteBytesExt};
|
|||||||
use ff::{PrimeField, PrimeFieldRepr};
|
use ff::{PrimeField, PrimeFieldRepr};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
components::{Amount, Script, TxOut},
|
components::{Amount, TxOut},
|
||||||
Transaction, TransactionData, OVERWINTER_VERSION_GROUP_ID, SAPLING_TX_VERSION,
|
Transaction, TransactionData, OVERWINTER_VERSION_GROUP_ID, SAPLING_TX_VERSION,
|
||||||
SAPLING_VERSION_GROUP_ID,
|
SAPLING_VERSION_GROUP_ID,
|
||||||
};
|
};
|
||||||
|
use legacy::Script;
|
||||||
|
|
||||||
const ZCASH_SIGHASH_PERSONALIZATION_PREFIX: &'static [u8; 12] = b"ZcashSigHash";
|
const ZCASH_SIGHASH_PERSONALIZATION_PREFIX: &'static [u8; 12] = b"ZcashSigHash";
|
||||||
const ZCASH_PREVOUTS_HASH_PERSONALIZATION: &'static [u8; 16] = b"ZcashPrevoutHash";
|
const ZCASH_PREVOUTS_HASH_PERSONALIZATION: &'static [u8; 16] = b"ZcashPrevoutHash";
|
||||||
|
@ -6,11 +6,8 @@ use sapling_crypto::{
|
|||||||
redjubjub::PrivateKey,
|
redjubjub::PrivateKey,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{components::Amount, sighash::signature_hash, Transaction, TransactionData};
|
||||||
components::{Amount, Script},
|
use legacy::Script;
|
||||||
sighash::signature_hash,
|
|
||||||
Transaction, TransactionData,
|
|
||||||
};
|
|
||||||
use JUBJUB;
|
use JUBJUB;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user