mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-01 08:12:14 +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 keys;
|
||||
pub mod legacy;
|
||||
pub mod merkle_tree;
|
||||
pub mod note_encryption;
|
||||
pub mod prover;
|
||||
|
@ -7,7 +7,7 @@ use sapling_crypto::{
|
||||
};
|
||||
use std::io::{self, Read, Write};
|
||||
|
||||
use serialize::Vector;
|
||||
use legacy::Script;
|
||||
use JUBJUB;
|
||||
|
||||
// π_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)]
|
||||
pub struct OutPoint {
|
||||
hash: [u8; 32],
|
||||
|
@ -3,10 +3,11 @@ use byteorder::{LittleEndian, WriteBytesExt};
|
||||
use ff::{PrimeField, PrimeFieldRepr};
|
||||
|
||||
use super::{
|
||||
components::{Amount, Script, TxOut},
|
||||
components::{Amount, TxOut},
|
||||
Transaction, TransactionData, OVERWINTER_VERSION_GROUP_ID, SAPLING_TX_VERSION,
|
||||
SAPLING_VERSION_GROUP_ID,
|
||||
};
|
||||
use legacy::Script;
|
||||
|
||||
const ZCASH_SIGHASH_PERSONALIZATION_PREFIX: &'static [u8; 12] = b"ZcashSigHash";
|
||||
const ZCASH_PREVOUTS_HASH_PERSONALIZATION: &'static [u8; 16] = b"ZcashPrevoutHash";
|
||||
|
@ -6,11 +6,8 @@ use sapling_crypto::{
|
||||
redjubjub::PrivateKey,
|
||||
};
|
||||
|
||||
use super::{
|
||||
components::{Amount, Script},
|
||||
sighash::signature_hash,
|
||||
Transaction, TransactionData,
|
||||
};
|
||||
use super::{components::Amount, sighash::signature_hash, Transaction, TransactionData};
|
||||
use legacy::Script;
|
||||
use JUBJUB;
|
||||
|
||||
#[test]
|
||||
|
Loading…
Reference in New Issue
Block a user