Skip to main content

PushDrop

Struct PushDrop 

Source
pub struct PushDrop {
    pub locking_public_key: PublicKey,
    pub fields: Vec<Vec<u8>>,
    pub lock_position: LockPosition,
}
Expand description

PushDrop locking script template.

This template creates scripts that embed arbitrary data fields alongside a P2PK (Pay-to-Public-Key) lock. The data fields are pushed onto the stack and then dropped, leaving only the signature verification.

§Example

use bsv_rs::script::templates::PushDrop;
use bsv_rs::primitives::ec::PrivateKey;

let privkey = PrivateKey::random();
let pubkey = privkey.public_key();

// Create with embedded token data
let fields = vec![
    b"BSV20".to_vec(),
    b"transfer".to_vec(),
    b"1000".to_vec(),
];

let pushdrop = PushDrop::new(pubkey, fields);
let locking_script = pushdrop.lock();

Fields§

§locking_public_key: PublicKey

The public key that can unlock this output.

§fields: Vec<Vec<u8>>

Embedded data fields.

§lock_position: LockPosition

Lock position (before or after data).

Implementations§

Source§

impl PushDrop

Source

pub fn new(locking_public_key: PublicKey, fields: Vec<Vec<u8>>) -> Self

Creates a new PushDrop template with lock-before pattern.

§Arguments
  • locking_public_key - Public key that can spend this output
  • fields - Data fields to embed
§Example
use bsv_rs::script::templates::PushDrop;
use bsv_rs::primitives::ec::PrivateKey;

let privkey = PrivateKey::random();
let pubkey = privkey.public_key();
let fields = vec![b"hello".to_vec(), b"world".to_vec()];

let pushdrop = PushDrop::new(pubkey, fields);
let script = pushdrop.lock();
Source

pub fn with_position(self, position: LockPosition) -> Self

Sets the lock position and returns self for chaining.

§Arguments
  • position - The lock position (Before or After)
§Example
use bsv_rs::script::templates::{PushDrop, LockPosition};
use bsv_rs::primitives::ec::PrivateKey;

let privkey = PrivateKey::random();
let pubkey = privkey.public_key();

let pushdrop = PushDrop::new(pubkey, vec![b"data".to_vec()])
    .with_position(LockPosition::After);
Source

pub fn lock(&self) -> LockingScript

Creates the locking script.

§Returns

The locking script containing the embedded data and P2PK lock.

Source

pub fn decode(script: &LockingScript) -> Result<Self>

Decodes a PushDrop locking script.

Extracts the public key and embedded fields from a locking script.

§Arguments
  • script - The locking script to decode
§Returns

The decoded PushDrop template, or an error if the script format is invalid.

§Example
use bsv_rs::script::templates::PushDrop;
use bsv_rs::script::LockingScript;

let script = LockingScript::from_hex("...")?;
let pushdrop = PushDrop::decode(&script)?;
println!("Fields: {:?}", pushdrop.fields);
Source

pub fn unlock( private_key: &PrivateKey, sign_outputs: SignOutputs, anyone_can_pay: bool, ) -> ScriptTemplateUnlock

Creates an unlock template for spending a PushDrop output.

PushDrop uses a P2PK (Pay-to-Public-Key) lock, so the unlocking script is just a signature. Unlike P2PKH, the public key is already in the locking script, so it doesn’t need to be repeated in the unlock.

§Arguments
  • private_key - The private key for signing (must match the public key in the lock)
  • sign_outputs - Which outputs to sign
  • anyone_can_pay - Whether to allow other inputs to be added
§Returns

A ScriptTemplateUnlock that can sign transaction inputs.

§Example
use bsv_rs::script::templates::PushDrop;
use bsv_rs::script::template::{SignOutputs, SigningContext};
use bsv_rs::primitives::ec::PrivateKey;

let private_key = PrivateKey::random();
let public_key = private_key.public_key();
let fields = vec![b"token_data".to_vec()];

// Create locking script
let pushdrop = PushDrop::new(public_key, fields);
let locking_script = pushdrop.lock();

// Create unlock template
let unlock = PushDrop::unlock(&private_key, SignOutputs::All, false);

// Estimate length for fee calculation (73 bytes)
let estimated_size = unlock.estimate_length();

// Sign with a transaction context
let context = SigningContext::new(&raw_tx, input_index, satoshis, locking_script.as_script());
let unlocking_script = unlock.sign(&context)?;
Source

pub fn sign_with_sighash( private_key: &PrivateKey, sighash: &[u8; 32], sign_outputs: SignOutputs, anyone_can_pay: bool, ) -> Result<UnlockingScript>

Creates an unlocking script with a precomputed sighash.

This is useful when you already have the sighash computed and don’t need to parse the transaction.

§Arguments
  • private_key - The private key for signing
  • sighash - The precomputed sighash to sign
  • sign_outputs - Which outputs to sign (for the scope byte)
  • anyone_can_pay - Whether to allow other inputs to be added
§Returns

The unlocking script, or an error if signing fails.

§Example
use bsv_rs::script::templates::PushDrop;
use bsv_rs::script::template::SignOutputs;
use bsv_rs::primitives::ec::PrivateKey;

let private_key = PrivateKey::random();
let sighash: [u8; 32] = compute_sighash_externally();

let unlocking = PushDrop::sign_with_sighash(
    &private_key,
    &sighash,
    SignOutputs::All,
    false,
)?;
Source

pub fn estimate_unlocking_length(&self) -> usize

Estimates the unlocking script length.

For a PushDrop output (P2PK lock), the unlocking script is just a signature. Unlike P2PKH, the public key is already in the locking script.

§Returns

The estimated length in bytes (73 bytes for signature only). This matches the TypeScript SDK’s estimate.

Trait Implementations§

Source§

impl Clone for PushDrop

Source§

fn clone(&self) -> PushDrop

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PushDrop

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for PushDrop

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V