<p>What is signed is a simplified version of the transaction (replacing the scriptSig, since that is what we are creating). There is a lot here so hopefully I covered it all:</p>

<pre><code> * `version` (4 Bytes) - Transaction format version
 * `flag` (2 Byte Array) - Optional flag, if present, must be 0001, which indicates there is witness data in this transaction
 * `input counter` (Variable Length) - Number of inputs in the transaction represented by a Variable Length Integer.
 * `inputs` (based on Input Counter) - List of all transaction inputs which will be spent and which reference unspent transaction outputs from previous transactions.
 * `output counter` (Variable Length) - Number of outputs in the transaction represented by a Variable Length Integer.
 * `outputs` (based on Output Counter) - List of all transaction outputs where the coins will be sent and which will become unspent transaction outputs to be spent in future transactions.
 * `scriptsig` (variable) - First, a one-byte varint which denotes the length of the scriptSig, then it is temporarily filled with the scriptPubKey of the output we want to redeem.
 * sequence number (4 Bytes) - Used as a relative lock time if transaction version is &gt;= 2. See BIP68.
 * one-byte varint containing the number of outputs in our new transaction
 * 8-byte field (64 bit integer) containing the amount we want to redeem from the specified output (in satoshis)
 * one-byte varint denoting the length of the output script
 * output script
 * `locktime` (4 Bytes) - If non-zero and sequence numbers are &lt; `ffffffff`: it represents either the block height or timestamp when transaction is final.
 * four-byte "hash code type" (1 in our case): 01000000 see [Sighash types][1]
</code></pre>

<p>Then, double-SHA256 hash this entire structure and the hash is what is signed. For an example, see <a href="https://bitcoin.stackexchange.com/a/5241/60443">https://bitcoin.stackexchange.com/a/5241/60443</a></p>

CC BY-SA 4.0
2019-08-30T06:50:09.323Z
Thanks that was great! @JBaczuk Also is the way the signature is created differs for different sighash type? Is there a documentation where I can find where and how these transactions are signed?
Or if you know could you explain say something like a SIGHASH_ALL|SIGHASH_ANYONECANPAY. How the Unlocking Script signs the inputs?
Shubham Saxena
CC BY-SA 4.0
2019-08-30T20:25:26.770Z
Yes, see https://bitcoin.org/en/transactions-guide#signature-hash-types
JBaczuk
CC BY-SA 4.0
2019-09-09T10:25:38.080Z
So from what I have read. The input contains the previous transaction hash, the index and the ScriptPubkey of this input that we are consuming? But is this ScriptPubkey a temporary value which is replaced by some other script? @JBaczuk
Shubham Saxena
CC BY-SA 4.0
2019-09-09T12:10:57.853Z
No, the input does not contain the scriptpubkey, the scriptsig does while you are signing it, then it is replaced with the actual scriptsig which is a script that satisfies the scriptpubkey. The scriptsig will contain the transaction signature, this is why it is temporarily filled with the scriptpubkey
JBaczuk
CC BY-SA 4.0
2019-09-09T12:19:09.137Z
So that means, I have to replace the scriptPubKey of the input with the actual signature appended with the hash code type and then consequently remove the last 4 bytes? This will be the input that is hashed twice and signed over by the private key? @JBaczuk
Shubham Saxena
CC BY-SA 4.0
2019-09-09T12:38:53.950Z
Sorry I might have been confusing, I'd recommend following the link in my answer for how to sign a tx
JBaczuk
CC BY-SA 4.0
2019-09-09T12:40:17.560Z
So I did go through the link. My question is more towards verifying a transaction signature rather than how to sign a tx. @JBaczuk
Shubham Saxena
CC BY-SA 4.0
2019-09-09T12:44:55.290Z
Gotcha, see https://bitcoin.stackexchange.com/a/32308/60443
JBaczuk
CC BY-SA 4.0
2019-09-10T10:14:33.320Z
Okay So i found the bug, It was related to storing the data in little Endian format!
Shubham Saxena
CC BY-SA 4.0
2019-09-10T11:57:07.147Z
That will bite you while you're learning for sure
JBaczuk
CC BY-SA 4.0
2019-08-29T13:14:47.650Z
2019-08-29T13:14:47.650Z
JBaczuk
<p>Hi I am learning bitcoin and learning how scripting works and how to use P2PKH. I was wondering how does OP_CHECKSIG work. I want to understand what is the data that the private key signs to create the digital signature itself? </p>

<p>Is there a simple explanation which illustrates how the digital signature is constructed for verification in OP_CHECKSIG? I understand that the Opcode uses the ECDSA algorithm for verifying the signature but I want to understand how the signature is generated for verification?</p>

<p>Pardon me if this is a basic question. Thanks</p>

<signature><transaction-verification><opcodes>
How does OP_CHECKSIG work
Shubham Saxena
# How does OP_CHECKSIG work

(Asked by: username_0 on 2019-08-29)

Hi I am learning bitcoin and learning how scripting works and how to use P2PKH. I was wondering how does OP\_CHECKSIG work. I want to understand what is the data that the private key signs to create the digital signature itself?

Is there a simple explanation which illustrates how the digital signature is constructed for verification in OP\_CHECKSIG? I understand that the Opcode uses the ECDSA algorithm for verifying the signature but I want to understand how the signature is generated for verification?

Pardon me if this is a basic question. Thanks

**Tags:** signature, transaction-verification, opcodes


---

## 1 answers

### Answer by username_1 on 2019-08-29. Score: 5 | Accepted answer

What is signed is a simplified version of the transaction (replacing the scriptSig, since that is what we are creating). There is a lot here so hopefully I covered it all:

```
 * `version` (4 Bytes) - Transaction format version
 * `flag` (2 Byte Array) - Optional flag, if present, must be 0001, which indicates there is witness data in this transaction
 * `input counter` (Variable Length) - Number of inputs in the transaction represented by a Variable Length Integer.
 * `inputs` (based on Input Counter) - List of all transaction inputs which will be spent and which reference unspent transaction outputs from previous transactions.
 * `output counter` (Variable Length) - Number of outputs in the transaction represented by a Variable Length Integer.
 * `outputs` (based on Output Counter) - List of all transaction outputs where the coins will be sent and which will become unspent transaction outputs to be spent in future transactions.
 * `scriptsig` (variable) - First, a one-byte varint which denotes the length of the scriptSig, then it is temporarily filled with the scriptPubKey of the output we want to redeem.
 * sequence number (4 Bytes) - Used as a relative lock time if transaction version is >= 2. See BIP68.
 * one-byte varint containing the number of outputs in our new transaction
 * 8-byte field (64 bit integer) containing the amount we want to redeem from the specified output (in satoshis)
 * one-byte varint denoting the length of the output script
 * output script
 * `locktime` (4 Bytes) - If non-zero and sequence numbers are < `ffffffff`: it represents either the block height or timestamp when transaction is final.
 * four-byte "hash code type" (1 in our case): 01000000 see [Sighash types][1]

```

Then, double-SHA256 hash this entire structure and the hash is what is signed. For an example, see <https://bitcoin.stackexchange.com/a/5241/60443>

> **Comments:**
> **username_0**: Thanks that was great! @username_1 Also is the way the signature is created differs for different sighash type? Is there a documentation where I can find where and how these transactions are signed? Or if you know could you explain say something like a SIGHASH_ALL|SIGHASH_ANYONECANPAY. How the Unlocking Script signs the inputs?  
> **username_1**: Yes, see https://bitcoin.org/en/transactions-guide#signature-hash-types  
> **username_0**: So from what I have read. The input contains the previous transaction hash, the index and the ScriptPubkey of this input that we are consuming? But is this ScriptPubkey a temporary value which is replaced by some other script? @username_1  
> **username_1**: No, the input does not contain the scriptpubkey, the scriptsig does while you are signing it, then it is replaced with the actual scriptsig which is a script that satisfies the scriptpubkey. The scriptsig will contain the transaction signature, this is why it is temporarily filled with the scriptpubkey  
> **username_0**: So that means, I have to replace the scriptPubKey of the input with the actual signature appended with the hash code type and then consequently remove the last 4 bytes? This will be the input that is hashed twice and signed over by the private key? @username_1  
> **username_1**: Sorry I might have been confusing, I'd recommend following the link in my answer for how to sign a tx  
> **username_0**: So I did go through the link. My question is more towards verifying a transaction signature rather than how to sign a tx. @username_1  
> **username_1**: Gotcha, see https://bitcoin.stackexchange.com/a/32308/60443  
> **username_0**: Okay So i found the bug, It was related to storing the data in little Endian format!  
> **username_1**: That will bite you while you're learning for sure  

---

