1

I am trying to create a timelock transaction, but I am unable to use a UNIX timestamp on testnet. However, if I use a block height the transaction works.

When I use a block height that is in the future and broadcast the transaction, I get:

sendrawtransaction RPC error: {"code":-26,"message":"non-final"}

When the block height is reached, the transaction goes through as expected.

When I make the locktime above 500,000,000 I get a different message:

"non-mandatory-script-verify-flag (Locktime requirement not satisfied)"

I have tried several different random timestamps from various years (2013, 2020) and I get the same error message. If I make the transaction with a large locktime like 400,000,000 I get the expected "non-final" message. It only happens when I go over the 500,000,000 minimum.

I have decoded both transactions, and the only noticable difference is the locktime.

Here is the raw transaction with the UNIX timestamp from 2013:

0200000001ab306f83a06f006f76695f0911fbe095d2443798f232e91e7a78e8bbf2050ec40000000088483045022100c381bfb9de6930ecb45cf2cc13581aca8c42e9f570615cabf1a631fbf137270b022026636856bbf250d169f7608abe1ab4fcba13c495ffa27ee4e821d38d626365ab012103803a5bbbe00dad7dbb29dd5f4d7883ac049bad52d78b456cda12591e26ae70241c00b17576a91450840658811828e04f5501bf3fe87f012d297bdd88acfeffffff01e4250000000000001976a914f005b469eb92525da0294247b5d0ae169efd78f588ac2e377452

Here is the raw transaction with block height:

0200000001ab306f83a06f006f76695f0911fbe095d2443798f232e91e7a78e8bbf2050ec40000000087473044022011704ab11cf526e656aaf681c9ab2c3002fd8a3982383afcad8ec46af68f099d022061c06671dcc7cf6e192c541b4692a809ea97711ed2866c004780054028cc5237012103803a5bbbe00dad7dbb29dd5f4d7883ac049bad52d78b456cda12591e26ae70241c00b17576a91450840658811828e04f5501bf3fe87f012d297bdd88acfeffffff01e4250000000000001976a914f005b469eb92525da0294247b5d0ae169efd78f588acfbb22400

1 Answer 1

3

The input to your transaction has a script that uses OP_CHECKLOCKTIMEVERIFY. This opcode takes the item at the top of the stack and compares its value to the locktime given in the transaction. However, because the locktime can be either a height or a timestamp, it also checks that the comparison is comparing two heights or two timestamps, not both. So it applies the same height and timestamp mode switching rules.

If you we look at the redeemScript in more detail, we find that it pushes a 0 before the OP_CHECKLOCKTIMEVERIFY, so 0 is the locktime to compare against. Since 0 is less than 500,000,000, this value is interpreted as a height locktime of 0. However your transactions locktime is greater than the threshold, so it is interpreted as a timestamp. Since height and timestamp cannot be compared, the script interpreter throws an error here and causes the transaction to be invalid. Thus the only way to use this script is to use exclusively height based locktimes.

1
  • Thank you so much! I’ve been hacking at this for days. I found the problem in my code.
    – Cannabijoy
    Nov 7, 2022 at 18:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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