Contrary to popular belief, Bitcoin comes with full smart contracting capability since its inception. We introduce the basics of Bitcoin smart contract and demonstrate it through an example.
Each bitcoin transaction consists of multiple inputs and outputs. An output contains:
- The amount of bitcoins it contains.
- Bytecodes (the locking script).
while an input contains:
- A reference to the previous transaction output.
- Bytecodes (the unlocking script).
When A sends B a bitcoin, there is a transaction TX_1 recorded on chain. In its first output TX_1_OUT_1, there is a bitcoin that can only be moved by B’s private key. Since only B knows it, nobody else can spend the bitcoin.
When B sends the bitcoin to C, he constructs a new transaction TX_2. Its input includes a reference to the previous transaction’s output TX_1_OUT_1 and a “key” signed with his private key (i.e., unlocking script). Its output includes the bitcoin and a new “lock” that only C can open (i.e., a new locking script). TX_2 is sent to the Bitcoin network and will only be recorded on chain if miners validate the included scripts. This is how bitcoin transfers work in general.
Output TX_1_OUT_1 is marked as spent by the network since it was consumed in TX_2. If any other transaction references it again, it will be regarded as double spending and rejected by the network. TX_2_OUT_1 is thus called an Unspent Transaction Output (UTXO) since it is not consumed in any transaction yet.
In summary, an input points to a previous transaction output and spends bitcoins within it. A transaction moves bitcoins from output(s) to output(s). Only when an input contains the “key” matching previous output’s “lock”, it can move bitcoins contained in the output to new output(s).
Bitcoin Virtual Machine (BVM) and Script
At the core of understanding these bytecodes lies the Bitcoin Virtual Machine. Each bitcoin node has a virtual machine (VM), which we call BVM. BVM executes instructions to conduct computations in a stack. Each instruction consists of an operator/opcode and its operands. (Opcode is also called bytecode since it is one byte in size.) Each opcode is followed by zero to two operands.
Here are some opcode examples. The full list of BVM opcodes can be found here.
In Bitcoin, these instructions are called Script. The bytecodes discussed in the previous section are scripts. When validating a transaction, the script in the output (called locking script since it locks up bitcoins) is appended to the script in the input referencing it (called unlocking script). The joint script is fed into the BVM and evaluated. If the top of the stack is a true value (i.e., non-zero) upon completion, the script succeeds and the bitcoin spending is authorized. Otherwise, it is rejected.
A Working Example
In one transaction, some bitcoins are locked up in an output with the following script
OP_1 OP_2 OP_ADD OP_EQUAL.
Another transaction spends the output using the following script
To see how the spending is authorized, let us walk through the script evaluation.
First, two scripts are joined.
OP_3 OP_1 OP_2 OP_ADD OP_EQUAL
Next, BVM starts evaluating the script from the beginning. We list each step below:
Upon completion, true is on top of the stack and thus the script succeeds. Had any single number other than 3 been pushed in the unlocking script, the script would have evaluated to false.
Smart Contracts on Bitcoin
As seen from the example, for a given locking script, only a certain unlocking script can make the joint script evaluate to true. In this sense, any bitcoin spending forms a contract: one party offers funds in bitcoin and stipulates terms of agreement; the other party can only redeem the funds if he fulfills the terms of the contract. It is smart in the sense that it is automatically enforced by miners in the Bitcoin network, unlike a conventional contract.
Smart contracts on Bitcoin are simply computer codes in Script executed by the BVM. Thanks to the versatility and expressiveness of bitcoin Script, we can run arbitrarily complex smart contracts on Bitcoin, which we will demonstrate further in a series of articles.
Chinese version translated by Yiqiang Wang
Japanese version translated by Ken Shishido
Vietnamese version translated by Bao Bui