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: PublicKeyThe public key that can unlock this output.
fields: Vec<Vec<u8>>Embedded data fields.
lock_position: LockPositionLock position (before or after data).
Implementations§
Source§impl PushDrop
impl PushDrop
Sourcepub fn new(locking_public_key: PublicKey, fields: Vec<Vec<u8>>) -> Self
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 outputfields- 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();Sourcepub fn with_position(self, position: LockPosition) -> Self
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);Sourcepub fn lock(&self) -> LockingScript
pub fn lock(&self) -> LockingScript
Sourcepub fn decode(script: &LockingScript) -> Result<Self>
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);Sourcepub fn unlock(
private_key: &PrivateKey,
sign_outputs: SignOutputs,
anyone_can_pay: bool,
) -> ScriptTemplateUnlock
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 signanyone_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)?;Sourcepub fn sign_with_sighash(
private_key: &PrivateKey,
sighash: &[u8; 32],
sign_outputs: SignOutputs,
anyone_can_pay: bool,
) -> Result<UnlockingScript>
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 signingsighash- The precomputed sighash to signsign_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,
)?;Sourcepub fn estimate_unlocking_length(&self) -> usize
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.