This is a read note of Programming Bitcoin Ch07 and Ch08: Transaction and Pay-to-Script Hash.

1 Validating Transactions

The main things of transaction validation are:

  • The inputs of the transactions are unspent: no double-spending.
  • The sum of the inputs is greater than or equal to the sum of the outputs: no new bitcoin created.
  • The ScriptSig successfully unlocks the previous ScriptPubKey: spending is authorized.

The signature hashing algorithm is inefficient and wasteful. The quadratic hashing problem states that time required to calculate the signature hashes increases quadratically with the number of inputs in a transaction. Segwit fixies this issue with a different way of calculating signature hash, which is specified in BIP0143.

2 Pay-to-Script Hash

multisig was built into Bitcoin from the begining but it has an off-by-one bug that has had to stay in the protocol because fixing it would require a hard fork.

In bare m-of-n multisig, OP_CHECKMULTISIG will consume m + n + 3 elements. The bare multsig is too big and can be abused. Pay-to-Script-Hash (p2sh) is a general solution to the long address/ScriptPubKey problem. The solution that p2sh implements is to take the hash of some Script commands and then reveal the preimage Script commands later. Pay-to-script-hash was introduced in 2011 to a lot of controversy.

In p2sh, a rule gets executed only when the hash of some script (called RedeemScript) is equal to the hash value defined in ScriptPubKey. The RedeemScript contains the m-of-n multisig scripts: m, n public keys, n, followed by OP_CHECKMULTISIG. The RedeemScript is at the end of the ScriptSig that has the requird m signatures.

The nice thing about p2sh is that the RedeemScript can be as long as the largest single element from OP_PUSHDATA2, which is 520 bytes. Multisig is just one possibility. You can have scripts that define more complicated logic, like “2 of 3 of these keys or 5 of 7 of these other keys.” The main feature of p2sh is that it’s flexible and at the same time reduces the UTXO set size by pushing the burden of storing part of the script back to the user.