The Transaction Script

Learn transaction scripts that are used by Bitcoin in this lesson.

Script language

Bitcoin uses a stack-based script language, called Script, that supports Reverse Polish NotationRPN is a mathematical notation in which operators follow their operands. For instance, the expression 5+7 is written as 57+, or 3 . 5-2 is written as 35. 2-. (RPN)(\mathrm{RPN}) for its transaction system. During execution, the parameters <><\ldots> are pushed on top of the stack, whereas the operands OP_opcode perform their instructions to the most recently added parameters, removing the processed parameters from the stack and pushing the result of the operation on top of the stack.

The language is very limited, e.g., it doesn’t allow more complex structures, such as loops, in order to avoid attacks on the transaction validation mechanism. Thus, there are only a few primitive operators in use.

Transaction validation: locking and unlocking script

The transaction validation process of Bitcoin relies on two different types of scripts, which Antonopoulos (2014)Andreas M. Antonopoulos. Mastering Bitcoin: Unlocking Digital Cryptocurrencies. Sebastopol, CA, 2014. O’Reilly Media. refers to as locking script and unlocking script. Every transaction output contains a number of cryptocurrencies and a conditional locking script scriptPubKey that specifies a spending condition placed on the output, under which the UTXO is to be spent. Any user who can satisfy the condition of scriptPubKey gains the coins paid to it. Roughly speaking, this script creates a cryptographic puzzle that must be solved in order to release the spending process. On the contrary, every transaction input contains an unlocking script scriptSig. If this protocol solves the puzzle, then it satisfies the condition placed on the UTXO such that the UTXO is unlocked and hence is allowed to be spent.

In summary, an output is locked by a script and can only be unlocked by an appropriate unlocking script of an input. The input is then allowed to spend an output if the unlocking script scriptSig satisfies the conditions that have been placed on the output by the locking script scriptPubKey.

Standard transaction script pay-to-public-key-hash

The Bitcoin protocol provides certain standard scripts for transactions. The most natural is:

  1. Pay-to-public-key (P2PK): The original Bitcoin 0.10.1 release provided transactions directly to a public key. The locking script scriptPubkey of the output specifies the condition for unlocking by the knowledge of the private key that corresponds to the public key. In order to do so, the recipient creates an unlocking script sigScript with only a signature created with the private key.

  2. Pay-to-public-key-hash (P2PKH): This kind of transaction allows the spender to pay directly to an address. This is currently the most common transaction type in Bitcoin.

In this section, we explain how Alice can transfer cryptocurrencies to Bob by using the standard Pay-To-Public-Key-Hash (P2PKH) transaction type, which allows Alice to send a fund to a typical user address that is under Bob’s control, who is able to further transfer it to any other user of the Bitcoin network.

The most common transaction type in Bitcoin is pay-to-address. In this case, the outputs to be spent are locked with a Pay-To-Public-Key-Hash (P2PKH) script, i.e., the script that locks the outputs to a Bitcoin address (or to the public key hash). This output can then be unlocked by presenting a public key QQ and an associated signature (created by dd ) in order to spend the funds. We assume that Alice wants to send currency units to a typical Bitcoin address that is under Bob’s control, which is later used to spend this transaction, as shown in this figure :Transactions_fig_5 .

According to the official Bitcoin Developer GuideBitcoin Developer Guide. Transactions. https://bitcoin.org/en/developer-guide. Accessed: 2019-01-07., a transaction involves the following steps:

  1. Creation of the locking script: At the beginning, Alice holds an output that’s under the control of her private key dAd_{A}. Before Alice can create the transaction in order to release the output, Bob must first generate a corresponding ECC private and public key pair dBd_{B} and QBQ_{B} according to Algorithm 1 :Algorithm_1 , which uses the secp256k1 curve. Q B_{B} is then cryptographically hashed to QˉB\bar{Q}_{B} and subsequently encoded to the Bitcoin address ABA_{B} by Algorithm 8:Algorithm_8. Bob then provides his address ABA_{B} to Alice, who decodes ABA_{B} back into the standard hash QˉB\bar{Q}_{B}. She now creates a P2PKH transaction output with a corresponding locking script scriptPubKey, which contains a spending condition that allows anyone to redeem that output who can prove he is in possession of the private key that corresponds to Bob’s hashed public key QˉB.\bar{Q}_{B}.

    The locking script scriptPubKey of the transaction output is of the form

    OP_DUP OP_HASH160 PubKeyHash\text{OP}\_\text{DUP} \ \text{OP}\_\text{HASH160} \ \langle \text{PubKeyHash} \rangle

OP_EQUALVERIFY OP_CHECKSIG\text{OP}\_\text{EQUALVERIFY} \ \text{OP}\_\text{CHECKSIG}

where PubKeyHash is Bob’s hashed public key QˉB\bar{Q}_{B}.

  1. Broadcasting: Now, Alice broadcasts the transaction to the network, which categorizes the output as UTXO, and its corresponding amount appears in Bob’s wallet. So Bob’s wallet software displays that he is in possession of these funds. The transaction is later included by a miner into a new block of transactions and subsequently added to the blockchain.

  2. Creation of the unlocking script: In order to spend the UTXO to Carol in a subsequent transaction, Bob must create an input that references the transaction Alice created by Bob’s hashed public key QˉB\bar{Q}_{B}. Furthermore, Bob has to create the unlocking script scriptSig, which must meet the conditions Alice placed in the previous scriptPubKey. Bob’s scriptSig contains the following parts:

    1. His full unhashed public key QBQ_{B}, which is needed for the scriptPubKey to check if QBQ_{B} hashes to the same value QˉB\bar{Q}_{B} which Alice defined in her spending conditions.

    2. An ECDSA signature according to this figure :transactions_fig_1 , which combines the hash of the previous transaction and Carol’s hashed public key QˉC\bar{Q}_{C}, signed with Bob’s private key dBd_{B}. This allows scriptPubKey to verify that Bob really controls the private key dBd_{B} which created QB.Q_{B}.

    So, the transaction input has an unlocking script scriptSig, which looks as follows:

    sigPubKey\langle\mathrm{sig}\rangle\langle\mathrm{PubKey}\rangle

    where sig is Bob’s signature and PubKey is his public key QBQ_{B}, respectively.

  3. Validation process: The validation process in Bitcoin requires both locking and unlocking the script in order to verify if scriptSig now satisfies all the conditions which Alice placed in her previous scriptPubKey. So, any P2PKH output that is locked by a scriptPubKey only can be unlocked by an appropriate scriptSig. Since Alice’s locking script doesn’t include Bob’s full public key but only a hash of it, Bob has to provide both his public key and a valid signature in his scriptSig in order to redeem the output. The validation process now concatenates both the scriptSig and scriptPubKey in order to evaluate the validity of the transaction such that the script now looks as

    sig PubKey OP_DUP OP_HASH160\langle \text{sig} \rangle \ \langle \text{PubKey} \rangle \ \text{OP}\_\text{DUP} \ \text{OP}\_\text{HASH160}

PubKeyHash OP_EQUALVERIFY OP_CHECKSIG\langle \text{PubKeyHash} \rangle \ \text{OP}\_\text{EQUALVERIFY} \ \text{OP}\_\text{CHECKSIG}

The stepwise script evaluation is shown in this Figure. In the first two steps, the two constants \langle sig \rangle and \langle PubKey \rangle which are provided by Bob’s unlocking script are pushed to the stack. Then OPDUPOP_DUP duplicates the top item of the stack, which is actually \langle PubKey \rangle, and adds it to the top of the stack. In the fourth step, OPHASH160OP_HASH160 hashes the top stack constant, Bob’s provided public key \langlePubKey\rangle, twice with SHA256 and then with RIPEMD160RIPEMD160 and pushes the resulting value \langle PubKeyHashB \rangle to the top of the stack. The script now pushes the value \langle PubKeyHash \rangle of the locking script to the top of the stack, which is subsequently compared with \langlePubKeyHashB\rangle by the operator OP_EQUALVERIFY. If Bob has provided an address to Alice for the transaction that’s really diverted from his public key, the two top stack values match, and thus, both are removed from the stack and the script continues with the command OP_CHECKSIG, which checks Bob’s signature against his provided public key \langlePubKey\rangle. If the signature is valid, the script pushes TRUE to the top of the stack, and the transaction finishes successfully.

In summary, the script verifies if Bob’s provided public key QBQ_{B} really hashes to QˉB\bar{Q}_{B}, which is placed by Alice in her scriptPubKey, and subsequently checks the provided signature against QBQ_{B}. In doing so, Alice can verify that Bob really is in possession of the private key dBd_{B} from which the public key QBQ_{B} and hence its hash QˉB\bar{Q}_{B} was derived, which proves Bob’s control over dBd_{B}. If the validation process finishes successfully, the unlocking script matches the conditions of the locking script, and therefore the input is considered a valid authorization to spend the UTXO. Otherwise, the input is invalid.

  1. Broadcasting: Now, Bob broadcasts the transaction to the Bitcoin network, where the transaction is independently validated by each Bitcoin node by executing the locking and unlocking scripts before broadcasting it further to other nodes.

Figure 1

Get hands-on with 1200+ tech skills courses.