My notes on bitcoin transactions — Part 2

Ismail Akkila
5 min readJul 24, 2017

In part 1, I went in to details about transaction inputs and outputs, as well as how the locking and unlocking scripts are executed by the stack-based execution language ‘Script’. In part 2, I will mention the different types of bitcoin transaction scripts in use today and how they operate.

A few notes about ‘Script’ though:

It is Turing Incomplete, meaning that it has no loops or complex flow control capabilities. This limitation is intentional in order for scripts to have limited complexity with predictable execution times.

It is Stateless, in that there is no state prior to the execution of the script or any state saved post execution.

Transaction Types

The book mentions that there are 5 types of transactions that could be processed by a bitcoin node. However, this may not be the case now.

Pay-to-Public-Key-Hash (P2PKH)

This is the most common type of transactions on the bitcoin network. The locking script is in the form:

OP_DUP OP_HASH160 <Public Key Hash> OP_EQUAL OP_CHECKSIG

The corresponding unlocking script:

<Signature> <Public Key>

If Alice wants to pay Bob, she would need to reference a corresponding UTXO (which contains the locking script) and execute the following script:

Format: <Unlocking Script (Derived from Private Key and Bitcoin Address> <Locking Script (Obtained from UTXO)><Alice's Signature> <Alice's Public Key> OP_DUP OP_HASH160 <Alice's Public Key Hash> OP_EQUAL OP_CHECKSIG

If the above script results in TRUE, this indicates a valid transaction indicating a valid signature from Alice that correponds to her public key hash (bitcoin address). The resulting transaction would create a UTXO that will have the following locking script:

OP_DUP OP_HASH160 <Bob's Public Key Hash> OP_EQUAL OP_CHECKSIG

And now Bob can reference this UTXO and provide his unlocking script to spend this output…Very nice!

Here is a step by step diagram illustrating the execution of the different operations in the script:

Pay-to-Public-Key (P2PK)

This transaction type uses a simpler script and uses the public key instead of the hash.

It has the following locking script:

<Public Key> OP_CHECKSIG

And locking script:

<Signature>

Pay-to-Public-Key-Hash (P2PKH) is favoured over this transaction type.

Multi-signature

This is a special script where you have N public keys and you need M signatures to release the encumbrance. Therefore, a UTXO can be spent if M signatures are presented in the unlocking script out of the N public keys in the locking script.

Locking script:

M <Public Key 1> <Public Key 2> <Public Key 3> N OP_CHECKMULTISIG

Unlocking script:

OP_0 <Signature 1> <Signature 2>

In the above, 2 signatures are presented in the unlocking script. If M = 2 and N = 3, this means that the locking script requires 2 out 0f the 3 signatures (derived from private keys) that correspond to the 3 public keys to validate the transaction.

Data Output (OP_RETURN)

Bitcoin has potential uses beyond payments. This transaction type allows for using the blockchain to store data unrelated to bitcoin payments. This is achieved though the OP_RETURN operator. OP_RETURN outputs are recorded on the blockchain and are provably unspendable. For example, it can be used to store a digital fingerprint of a file to establish proof-of-existence of that file on a particular date.

Scripts look like this:

OP_RETURN <data>

The data portion is limited to 80 bytes and most often represents a hash, such as the output of a SHA256 hashing algorithm (32 bytes). Some applications also use an 8 byte prefix to help identify the application. It is important to note that there is no “unlocking script” here as OP_RETURN outputs are unspendable.

Pay-to-Script-Hash (P2SH)

This type of transaction was introduced to simplify the use of complex transaction scripts. For example, if we take a look at a locking script of a Multi-signature transaction involving 5 public keys:

M <Public Key 1> <Public Key 2> <Public Key 3> <Public Key 4> <Public Key 5> N OP_CHECKMULTISIG

If I were to make a payment using this script, my bitcoin wallet application would need to have the ability to create custom transaction scripts. This introduces a barrier to payment. Moreover, due to the large size of the script, this would increase the transaction fees required to process the transaction. Remember, transaction fees are calculated based on the size of the transaction in kilobytes (not the value of BTC!). This also unfairly puts the burden of transaction fees on the payer and not the payee who requires this script.

In a P2SH transaction, the locking script above is referred to as a ‘redeem script’ and is replaced by a hash (20 byte hash produced by applying SHA256 and then the RIPEMD160 algorithm on the result). Here is the comparison:

Without P2SH:

Locking Script: M <Public Key 1> <Public Key 2> <Public Key 3> <Public Key 4> <Public Key 5> N OP_CHECKMULTISIGUnlocking Script: <Signature 1> <Signature 2>

With P2SH:

Redeem Script: M <Public Key 1> <Public Key 2> <Public Key 3> <Public Key 4> <Public Key 5> N OP_CHECKMULTISIGLocking Script: OP_HASH160 <20 Byte Hash of Redeem Script> OP_EQUALUnlocking Script <Signature 1> <Signature 2> <Redeem Script>

In a P2SH transaction, the payer would just need to use a special bitcoin address which are essentially Base58Check encodings of the 20 byte hash of the redeem script. Therefore, this address would correspond to a script instead of a public key. There is no need to support a custom transaction script in the bitcoin wallet application.

Spending this type of transaction is a 2 step process:

1- Check if hash of redeem script from the unlocking script matches the script hash in the locking script:

<Redeem Script> OP_HASH160 <20 Byte Hash of Redeem Script> OP_EQUAL

2- Evaluate the redeem script using the signatures from the unlocking script:

<Signature 1> <Signature 2> <Redeem Script>

Note that this is similar to the execution of this script (Assuming the script is a multi-signature script):

<Signature 1> <Signature 2> M <Public Key 1> <Public Key 2> <Public Key 3> <Public Key 4> <Public Key 5> N OP_CHECKMULTISIG

Notice now that the unlocking script requires the redeem script (unhashed) which shifts the burden of transaction fees to the payee. The payer just needs to send BTC to the ‘special bitcoin address’. Overall, here are the main advantages:

1- No support required for custom transaction scripts. Scripts can be coded as a bitcoin address.

2- Smaller transaction size for the sender (meaning less transaction fees). Burden is shifted to the recipient.

This concludes the topic of bitcoin transactions! I will have more on other areas of bitcoin.

--

--

Ismail Akkila

I live and breathe technology. Curious about programming, bitcoin and cybersecurity.