1

I need to confirm that I understand how transactions work in the Bitcoin network. Ok, so:

  1. Alice is a network node. Alice wants to send bitcoins to someone in the network. Alice is creating a transaction using her wallet.
  2. Every transaction has inputs and outputs. The inputs of every transaction are just references to some previous outputs of some other, older transactions that previously sent funds to Alice addresses.
  3. To send bitcoins Alice needs to resolve the puzzle given in the scriptPubKey of a previous transaction's output by using her scriptSig which her wallet generates upon making a transaction. Basically Alice just needs to prove that she is in control of private key (related to address previous bitcoins were sent to) by signing the new transaction.

Did I get these steps right?
My confusion started when I was exploring the hash type because I saw many sentences that said the Output of a transaction is signed correctly. With my understanding (from above) I assume that the previous output is signed correctly? And therefor, an input of a new transaction is considered valid. But I couldn't find confirmation for this. Am I missing something? Thank you!

2

When creating a Bitcoin transaction, each input explicitly states which unspent transaction output (UTXO) is consumed (via an outpoint consisting of txid:vout) and then proves the spender's authority to use this unspent. For the standard output format such a proof is a signature created by the private key corresponding to the public key the funds were previously locked to. I think what's actually unclear is what exactly the signature is signing.

Imagine yourself signing a contract. Putting your signature on a contract signals that you have understood and agreed exactly to that contract. The signature is not meant to be taken out of the context of the contract and certainly not supposed to get stuck onto another contract.

Similarly, the signature on a Bitcoin transaction commits to the specific context of the transaction! If the signature was simply signing for the input without context, an attacker could grab a number of inputs from unconfirmed transactions and reassemble them into a transaction paying the attacker themselves.

Luckily, in Bitcoin we can actually enforce that a signature is invalid when taken out of context. Each signature commits to the complete set of the transaction's instructions, i.e. which UTXOs get spent in the inputs and which UXTOs get created in the outputs as well as the transaction's meta information. (Obviously, a signature cannot commit to the other inputs' signatures as that would be cause an unresolveable recursion.) This commitment to the transaction's structure is called the sigHash. By default a sigHash will be built from the whole transaction using the signature type (or "sigHash flag") SIGHASH_ALL. @darosior touches briefly on other sighash flags, but you can read more about that in (Raghav Sood's article about all types of sighash flags).

| improve this answer | |
  • First, thank you for your editing support for given question. Second of all, thank you for clearing it out. I was doing just that, taking the signature out of the context and binding it only to transaction input. Thank you @Murch and @darosior! – ddavi031 Jul 9 at 19:34
3

The sighash type conditions what is part of the digest which is eventually signed for the transaction to be valid.

Some sighash types allow to either include (commit to) part --or none-- of the outputs of the transaction in the digest. Using these far less common sighash types introduce some malleability for a transaction, which usually allow more flexibility when different parties create a single transaction.
You almost always want to use SIGHASH_ALL and you anyway should append a SIGHASH_ALL signature to an input before broadcasting a transaction.

Regarding your question and to sum up, you always sign the current transaction and append this signature to the witness or the scriptSig. This signature can be conditioned using different sighash types.

For reference, you can see the wiki page on OP_CHECKSIG (it only covers the legacy transaction format, though).

| improve this answer | |
  • Thank you for your answer. However, it still bugs me because, ok, i sign the transaction inputs, but those inputs are just outputs of some previous transaction? So I'm signing outputs of previous transaction. So hash type has nothing to do with output of current transaction? It's more like : which of the outputs of previous transactions are signed inputs inside of new transaction? Sorry if i don't follow correctly. – ddavi031 Jul 9 at 16:52

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.