Skip to content

Conversation

@IzioDev
Copy link
Collaborator

@IzioDev IzioDev commented Oct 16, 2025

Usage:

let mut s = ScriptBuilder::new();

// given that `script_vec` is &[u8]
s.script_mut().extend_from_slice(&script_vec);

// print the human readable form
println!("{}", s.string_view::<ValidatedTransaction, SigHashReusedValuesSync>());

Input:

4130ef124590e4e6627078a658e2eb0b89fe4733f40d8cbfe0d077ae16bb90afb0a5f10e5693352e4b9d19d77a98fe75e395ce60988a0750ab8603a252c9c7290401412294d292317d03d1a5f49a8204c35486da84bbbea604209637e2bbfb5bbfabb36bcb37fc90aeb9836ed950a42b87382880fbd926b362cdbca16e9db9891918850141c2d76d4c64c9b8a8a64fa34a69f7cea953c4f0e564463226d931481ee1fbccafd7c20500a699fc8a10d01d03219d25944081750cdbba89e6a5a64b3224f58a5a014c875320b0a2f302b97271d6d1f20f2168e8b86b037d42a52aaf7ca959bea8a8bbf859a220e040996f44024491881ad4d2f59d4397a5a1f2e169c55624cb9509693fbb7a14204e518f0ecb51eef7db45042e441bb4d99f2c68277359bea369fcb7c80bee5b0120924013135715c9a8076141a33d6528a13fa2e816d3f006897b6d6c8b1da90fd754ae

Output:

OP_PUSHBYTES_65 30ef124590e4e6627078a658e2eb0b89fe4733f40d8cbfe0d077ae16bb90afb0a5f10e5693352e4b9d19d77a98fe75e395ce60988a0750ab8603a252c9c7290401
OP_PUSHBYTES_65 2294d292317d03d1a5f49a8204c35486da84bbbea604209637e2bbfb5bbfabb36bcb37fc90aeb9836ed950a42b87382880fbd926b362cdbca16e9db98919188501
OP_PUSHBYTES_65 c2d76d4c64c9b8a8a64fa34a69f7cea953c4f0e564463226d931481ee1fbccafd7c20500a699fc8a10d01d03219d25944081750cdbba89e6a5a64b3224f58a5a01
OP_PUSHDATA1 135 5320b0a2f302b97271d6d1f20f2168e8b86b037d42a52aaf7ca959bea8a8bbf859a220e040996f44024491881ad4d2f59d4397a5a1f2e169c55624cb9509693fbb7a14204e518f0ecb51eef7db45042e441bb4d99f2c68277359bea369fcb7c80bee5b0120924013135715c9a8076141a33d6528a13fa2e816d3f006897b6d6c8b1da90fd754ae
    -- Begin Redeem Script --
OP_3
OP_PUSHBYTES_32 b0a2f302b97271d6d1f20f2168e8b86b037d42a52aaf7ca959bea8a8bbf859a2
OP_PUSHBYTES_32 e040996f44024491881ad4d2f59d4397a5a1f2e169c55624cb9509693fbb7a14
OP_PUSHBYTES_32 4e518f0ecb51eef7db45042e441bb4d99f2c68277359bea369fcb7c80bee5b01
OP_PUSHBYTES_32 924013135715c9a8076141a33d6528a13fa2e816d3f006897b6d6c8b1da90fd7
OP_4
OP_CHECKMULTISIG
// 3 of 4
// CtWsLozeKzacL3SrheKo1aWxN7tT9eNv2KRwL7f5PxoB
// G6PTTyaAgFfzBg8DsDUjtdC4rs5qsZCV4yoHZ43TxgQj
// 6Giw2Rnf1tcauJ3ejSKD4AdJbKrqZF1WdhjfLU2KWAFA
// AquC7saqDzzuqCnP4jUPxJLiwHFcxYUUUDwL8L6mvsBc
    -- End Redeem Script --

An early review has been made by @biryukovmaxim here for the record. Thanks Maxim 🙏


macro_rules! opcode_list {
( $( opcode $(|$alias:ident|)? $name:ident<$num:literal, $length:tt>($self:ident, $vm:ident) $code: expr ) *) => {
( $( opcode $(|$alias:ident|)? $name:ident<$str_rep:literal, $num:literal, $length:tt>($self:ident, $vm:ident) $code: expr ) *) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think $name:ident can be used instead on str_rep directly and it will be consistent with enum

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, let's try this 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with macros, but compiler complains on introduced $name:ident with error duplicate matcher binding

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name:ident already there. You can reuse it

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I tried re-using this "variable" (not sure the proper term for macros)

Image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No
You are trying to introduce new one with the same name. Reusing it means remove the newly added variable and use the first "name"

Comment on lines 7 to 12
#[derive(Debug)]
pub struct MultiSigScriptParameters {
pub required_signatures_count: u8,
pub signers_count: u8,
pub signers_pubkey: Vec<secp256k1::XOnlyPublicKey>,
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that is only correct for schnorr based multisigs. so either add enum or suffix to make it cleat that it can only work with schnorr based mulisigs

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in review: make it clear it only support schnorr multiscript, precised naming to restraint to schnorr.

It seems to be standard, as the opcode OpCheckMultiSig is for Schnorr, while this one: OpCheckMultiSigECDSA is specifically for ECDSA

s.push(' ');
s.push_str(&hex::encode(data));

// try to disassemble the data as a script
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it needs explicit param to try disassemble. also output is not clearly specifies that redeem script and last push data are the same. maybe it makes sense to wrap it into : (redeem script) or something like that

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it makes sense to wrap it into : (redeem script)

Could you please describe a bit more what you mean by that?
I'm not sure to get it properly. Thanks :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant formatting.currently it looks like

OpCode, OpCodeData data
Redeem script 

There's no direct link between data and redeem script. I suggest adding some extra delimiters to make it look like OpData hex: (redeem script)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, on it

borsh.workspace = true
bs58.workspace = true
cfg-if.workspace = true
hex.workspace = true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use faster hex. i think we should use the library everywhere instead of mixing them

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@IzioDev
Copy link
Collaborator Author

IzioDev commented Nov 9, 2025

As per requested by @someone235 and @biryukovmaxim, added a parameter to enable sub script disassembling. If false, it will not attempt disassembling redeem script: review: add parameters to enable subscript disassembling

@IzioDev IzioDev marked this pull request as draft December 22, 2025 15:59
@IzioDev
Copy link
Collaborator Author

IzioDev commented Dec 22, 2025

Converted to draft in the meantime of a cleaner implementation. (cf. review by Maxim)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants