$ ./miniscript 

X    110.0000000000    37 and_v(v:pk(A),older(10)) and(older(10),pk(A))

      1 scriptlen=37 maxops=2 type=B safe=yes nonmal=yes dissat=no input=1n output=nonzero miniscript=and_v(v:pk(A),older(10))

(the last line shows the compiled script because I added printf("%s", Disassemble(ret->ToScript(COMPILER_CTX)).c_str()); to the command line-based tool output)

AFAICT nothing says that this cannot be top-level (but I may be missing something). It also says nonmal=yes, that this is not malleable.

The witness that is needed for this script to be successfully executed in the spending check is [<A_signature>, <any-nonzero>], and of course the CHECKSEQUENCEVERIFY condition must pass. The CHECKSIGVERIFY will consume <A_signature>, and then <any-nonzero> will be checked as the sole item on the stack, that indicates success (after CastToBool())

But <any-nonzero> can be just that, anything, and thus malleable.

What am I missing ?


OP_CHECKSEQUENCEVERIFY is a redefined OP_NOP code, so it cannot manipulate the stack - only abort or continue. In your script, that means it leaves the 10 on the stack, and no <any-nonzero> is necessary in the witness (and adding one would be a violation of the CLEANSTACK standardness rule).

  • Oh right, my mistake. It seems that I was looking at CHECKSIGVERIFY code that pops the arg, and thought that I was looking at CHECKSEQUENCEVERIFY. – Dmitry Petukhov Nov 4 '20 at 8:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.