In the process of validating transactions by hand with a new library in elixir. I am starting with f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16, which is one of the first P2PK transactions ever made.

I am struggling to manually validate that transaction with the secp256k1 library included with the language.

It probably has something to do with my code. Most probably is when I strip the signature, creating the message to be signed with the public key, in the process of verifying the signature, or how I encode things, I don't know.

In the process of solving that mystery, I've spent countless hours in vain trying to find a super detailed step-by-step validation of an early transaction.

Might be enough to just know a txid and the exact bytes being sent to a secp256k1 verifying function, so I make sure my code does the same.

In the event that such a document exists somewhere I'd be grateful to be pointed towards it.

  • Hey, the “message” input, i.e. the digest of the transaction that is being committed to by the signature in Bitcoin transactions is called “signature hash” or sighash. I think this might be useful: bitcoin.stackexchange.com/a/95750/5406
    – Murch
    Commented Nov 29, 2022 at 16:49
  • I got to know exactly what "delete all the script signatures in the raw transaction" means... I am replacing it with 0100 which means one byte that equals to zero. Not 100% it's what's needed.
    – RooSoft
    Commented Nov 29, 2022 at 16:59
  • I was mistaken, it's 00.
    – RooSoft
    Commented Nov 29, 2022 at 19:13

1 Answer 1


There are a lot of things to keep track of when verifying.

  1. Did you encode your data according to the proper sighash byte?
  2. Are you using the correct key to verify?
  3. Did you hash the data you are verifying?
  4. Did you add the four bytes representing the sighash byte to your data?

So, for the transaction you mentioned, there is only one input that contains a signature that ends with sighash byte 01. Sighash byte 01 means we basically use the raw transaction as our data. If there had been multiple inputs, we would use zero-length scripts for the inputs we are not verifying, but in this case we only have one. But we do have to put a 4-byte little endian value at the end of the data to represent the sighash byte.

So this is the data that I believe needs to be verified.








Notice the 01000000 at the end. That represents the sighash byte which has to be signed along with the rest of the data.

I'm not familiar with the library you mentioned, but many of them will work. Typically, you need to pass the data and its length, the signature and the public key being verified. Since the signatures in bitcoin transactions usually have a sighash byte stuck on the end of them, you'll need to remove that byte before passing it to the function you use to verify.

If you serialize all of the bytes above into one message, convert it to binary and apply a double sha256 to it, I bet you can verify it with the public key included in the previous output's script.

  • Got the same, except for the script sig at line 5, which I tought had to be replaced by 0...
    – RooSoft
    Commented Nov 29, 2022 at 18:59
  • reference, point 7 here: en.bitcoin.it/wiki/OP_CHECKSIG#How_it_works
    – RooSoft
    Commented Nov 29, 2022 at 19:04
  • 1
    Usually, you would set them all to length zero as explained in step 7, and then in step 8 it says to include just the script for the input you are verifying. However, with the transaction we're looking at there is only one input, so we can just use it as is.
    – Zephyrus
    Commented Nov 29, 2022 at 21:39

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.