Unable to push script bytes into a Script builder

Unable to push script bytes into a Script builder

Manage alerts

Loading saved threads...

jiamijiang · External communityPost link
External question — Bitcoin Stack Exchange Author: jiamijiang Original post: https://bitcoin.stackexchange.com/questions/130649 License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/ Adaptation: HTML converted to plain text; contact email addresses removed. I am using rust-bitcoin to spend a P2SH. I want to construct the scriptSig by pushing a signature and the redeem script. The redeem script is just a 1-of-1 P2MS script. let redeem_script = Script::builder() .push_opcode(OP_PUSHNUM_1) .push_key(&pubkey1) .push_opcode(OP_PUSHNUM_1) .push_opcode(OP_CHECKMULTISIG) .into_script(); ... let mut scriptSig = ScriptBuf::builder(); scriptSig.push_opcode(OP_0); scriptSig.push_slice(&signature1.serialize()); scriptSig.push_slice(&redeem_script.as_bytes()); // type error here There is a type error that i get on the .push_slice(&redeem_script.as_bytes()) segment because the push_slice method expects a type that implements AsRef<PushBytes> , but the provided type &[u8] does not satisfy this trait bound. How would I convert the redeem_script to satisfy the AsRef<PushBytes> param type?
Quote
Report
vincenzopalazzo · External communityPost link
External answer — Bitcoin Stack Exchange Author: vincenzopalazzo Original post: https://bitcoin.stackexchange.com/a/130650 License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/ Adaptation: HTML converted to plain text; contact email addresses removed. The issue is with the push_slice API in recent versions of rust-bitcoin (≥ 0.30). ScriptBuf::builder().push_slice (and Builder::push_slice ) now requires T: AsRef<PushBytes> for safety—it enforces Bitcoin’s push-data limits at compile time where possible and prevents oversized pushes. &[u8] (what redeem_script.as_bytes() returns) no longer satisfies that bound directly. Fix Convert the redeem script bytes to PushBytesBuf (the owned version) using TryFrom : use bitcoin::script::{Builder, PushBytesBuf, ScriptBuf}; // or the full path: bitcoin::blockdata::script::* // ... your redeem_script construction (this part is already correct) ... let redeem_script = Script::builder() .push_opcode(OP_PUSHNUM_1) .push_key(&pubkey1) .push_opcode(OP_PUSHNUM_1) .push_opcode(OP_CHECKMULTISIG) .into_script(); // Build the scriptSig for the P2SH spend (1-of-1 multisig redeem script) let mut script_sig = Builder::new() .push_opcode(OP_0) // dummy 0 for CHECKMULTISIG .push_slice(&signature1.serialize()) // signature (already a valid push) .push_slice( PushBytesBuf::try_from(redeem_script.as_bytes()) .expect("redeem script too large to push") // will never fail for normal multisig ) .into_script(); tx.input[0].script_sig = script_sig; // or however you're attaching it Why this works PushBytesBuf::try_from(&[u8]) (or &PushBytes::try_from(&[u8]) if you prefer a reference) validates the length and gives you a type that implements AsRef<PushBytes> . For a 1-of-1 P2MS redeem script the size is tiny (~36 bytes), so the expect / unwrap is safe. In production you can handle the PushBytesError if you want to be extra defensive. The resulting script_sig will be a valid P2SH unlocking script: <0> <sig> <redeemScript> (all pushes). Alternative one-liners (if you prefer) .push_slice(PushBytesBuf::from(redeem_script.as_bytes())) // panics on >4 GiB (impossible) or .push_slice(redeem_script.as_bytes().try_into().unwrap()) (using the TryInto impl that PushBytesBuf provides). This is the idiomatic way in current rust-bitcoin . Your redeem script builder and overall P2SH flow look correct—only the final push needed the type adjustment.
Quote
Report

Post Reply

Quoted from Forex.com.bd-Editorial External answer — Bitcoin Stack Exchange Author: vincenzopalazzo Source score (net votes, not local likes): 0 Original post: https://bitcoin.stackexchange.com/a/130650 License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/ Adaptation: HTML converted to plain text; contact email addresses removed. The issue is with the push_slice API in recent versions of rust-bitcoin (≥ 0.30). ScriptBuf::builder().push_slice (and Builder::push_slice ) now requires T: AsRef<PushBytes> for safety—it enforces Bitcoin’s push-data limits at compile time where possible and prevents oversized pushes. &[u8] (what redeem_script.as_bytes() returns) no longer satisfies that bound directly. Fix Convert the redeem script bytes to PushBytesBuf (the owned version) using TryFrom : use bitcoin::script::{Builder, PushBytesBuf, ScriptBuf}; // or the full path: bitcoin::blockdata::script::* // ... your redeem_script construction (this part is already correct) ... let redeem_script = Script::builder() .push_opcode(OP_PUSHNUM_1) .push_key(&pubkey1) .push_opcode(OP_PUSHNUM_1) .push_opcode(OP_CHECKMULTISIG) .into_script(); // Build the scriptSig for the P2SH spend (1-of-1 multisig redeem script) let mut script_sig = Builder::new() .push_opcode(OP_0) // dummy 0 for CHECKMULTISIG .push_slice(&signature1.serialize()) // signature (already a valid push) .push_slice( PushBytesBuf::try_from(redeem_script.as_bytes()) .expect("redeem script too large to push") // will never fail for normal multisig ) .into_script(); tx.input[0].script_sig = script_sig; // or however you're attaching it Why this works PushBytesBuf::try_from(&[u8]) (or &PushBytes::try_from(&[u8]) if you prefer a reference) validates the length and gives you a type that implements AsRef<PushBytes> . For a 1-of-1 P2MS redeem script the size is tiny (~36 bytes), so the expect / unwrap is safe. In production you can handle the PushBytesError if you want to be extra defensive. The resulting script_sig will be a valid P2SH unlocking script: <0> <sig> <redeemScript> (all pushes). Alternative one-liners (if you prefer) .push_slice(PushBytesBuf::from(redeem_script.as_bytes())) // panics on >4 GiB (impossible) or .push_slice(redeem_script.as_bytes().try_into().unwrap()) (using the TryInto impl that PushBytesBuf provides). This is the idiomatic way in current rust-bitcoin . Your redeem script builder and overall P2SH flow look correct—only the final push needed the type adjustment.

Cancel quote

Checking account access…