Bitcoin is sometimes called programmable currency. Its digital nature gives users a lot of flexibility in setting conditions for how their funds are used
When discussing Bitcoin, we will mention wallets and tokens. But we can also think of wallets as keys, tokens as checks, and blockchains as rows and rows of locked safes. Each safe has a tiny slot so anyone can deposit a check or see how much value is in the safe. However, only the key holder can unlock the safe.
If the key holder wants to give the money to someone else, the safe will be opened. They would write a new check referencing the old check (which would then be destroyed) and relock it in a box that the payee could open. In order to spend the money, the new recipient needs to repeat the process.
In this article, we will take a closer look at scripting, a programming language that is interpreted by nodes on the Bitcoin network. The script manages the locking/unlocking mechanism of the safe mentioned earlier.
Using the above analogy, we can say that every transaction has two parts - the key (used to unlock the safe) and the lock. You need a key to open the box containing the check you want to send, and then add the new check to a new box with a different lock. To spend the money inside the new chest, you need another key.
It’s that simple. There may be some variation in the types of locks in the system. Some safes require you to provide multiple keys, others require you to prove you know a combination, and there are many conditions you can set.
Our key is what we call scriptSig, and the lock is what we call scriptPubKey. If we look at these components in more detail, we see that they are actually made up of bits of data and blocks of code. When they are combined, they form a small program.
When you place a trade, you are broadcasting that combination to the network. Each node that receives this transaction will check this program, which will tell the node whether this transaction is valid. If invalid, the transaction will be scrapped and you will not be able to use the locked funds.
The checks (tokens) you hold are called Unspent Transaction Outputs (UTXO). Anyone can access the funds as long as they provide a key that matches the lock. Specifically, the key is scriptSig and the lock is scriptPubKey.
If UTXOs are in your wallet, they may have a condition that only someone who can prove ownership of that public key can unlock the funds. To unlock funds, you need to provide a scriptSig that contains a digital signature, using the private key mapped to the public key specified in scriptPubKey. Everything will become clear soon.
Script is a stack-based language. This means that when we read a set of instructions, we place them in columns that are considered vertical. For example, the list A, B, C will produce a stack with A at the bottom and C at the top. When an instruction tells us to do something, we operate on one or more elements starting at the top of the stack.
Elements A, B and C are added and removed from the stack "Pop up".
We can distinguish between data (such as signatures, hashes, and public keys) and instructions (or opcodes). Instructions to delete data and process it. Here is a very simple script example:
<xyz> ; <md5 hasher> <d16fb36f0911f878998c136191af705e> <check if equal>
The red part represents the data, and the blue part represents the operation code. We read from left to right, so we first put the string <xyz> on the stack superior. Next is the <md5 hasher> opcode. This opcode does not exist in Bitcoin, but we assume that it removes the element at the top of the stack (<xyz>) and hashed using the MD5 algorithm. The output is then added back to the stack. The output here happens to be d16fb36f0911f878998c136191af705e.
What a coincidence! The next element we want to add is <d16fb36f0911f878998c136191af705e>, so now our stack has two identical elements. Finally, <check if equal> pops two elements on top and checks if they are equal. If equal, add <1> to the stack. If not equal, add <0> to the stack.
We have reached the end of the command list. Our script can fail in two ways - if the remaining elements are zero, or if some condition is not met, one of the operators will cause it to fail. In this example, we don't have any such operator and end up with a non-zero element (<1>), so our script is valid. These rules also apply to real Bitcoin transactions.
The above example is just a fictitious program. Now let's look at some practical examples.
Payment to Public Key (P2PK) is very simple. It is designed to lock funds to a specific public key. If you want to receive funds this way, you need to provide the sender with your public key, not your Bitcoin address.
The first transaction between Satoshi Nakamoto and Hal Finney in 2009 was a P2PK transaction. This structure was heavily used in the early days of Bitcoin, but today, Payment-to-Public-Key Hash (P2PKH) has largely replaced it.
The locking script for P2PK transactions follows <public key> OP_CHECKSIG format. It's that simple. As you may have guessed, OP_CHECKSIG checks the signature against the provided public key. Therefore, our scriptSig will be a simple <signature>. Remember, scriptSig is the key that unlocks the lock.
It doesn't get any simpler than this. The signature is added to the stack, followed by the public key.OP_CHECKSIGPop up the signature and public key at the same time, and verify the signature based on the public key. If they match, send Add<1> to the stack. Otherwise add<0>.
P2PK is actually no longer used for reasons we will detail in the next section.
Payment to Public Key Hash (P2PKH) is The most common type of transaction now. Unless you go out of your way to download outdated software, your wallet will most likely default to this transaction.
P2PKH’s scriptPubKey is as follows:
OP_DUP OP_HASH160 <public key hash> OP_EQUALVERIFY OP_CHECKSIG
In our Before introducing scriptSig, let's first analyze the function of the new opcode:
OP_DUP pops up the first element and Copiesthe element. It then adds both back to the stack. Typically this is done to operate on the copy without affecting the original element.
This will pop the first element and hash it twice. The first round will be hashed using the SHA-256 algorithm. The SHA-256 output is then hashed using the RIPEMD-160 algorithm. The resulting output is added back to the stack.
OP_EQUALVERIFY is composed of two other operators, OP_EQUAL and OP_VERIFY. OP_EQUAL pops two elements and checks if they are the same. If they are the same, add 1 to the stack. If they are not the same, add 0. OP_VERIFY pops the top element and checks if it is True (that is, not 0). If not, the transaction fails. Taken together, OP_EQUALVERIFY will cause the transaction to fail if the top two elements do not match.
This time, the scriptSig looks like this:
<signature> <public key>
You A signature along with the corresponding public key is required to unlock the P2PKH output.
You can learn more about it through the GIF above. It's not that different from P2PK scripts. We just added an extra step to check if the public key matches the hash in the script.
However, there is one thing to note. In the P2PKH locking script, the public key is invisible – we can only see its hash. If we go to the blockchain explorer and look at the output of P2PKH that has not been spent yet, we will not be able to determine its public key. It is only disclosed when the recipient decides to transfer the funds.
This has several benefits. The first is that public key hashes are easier to transmit than the full public key. It was for this reason that Satoshi Nakamoto introduced public key hashing in 2009. The public key hash is what we now know as a Bitcoin address.
The second benefit is that public key hashing can provide an additional layer of security for quantum computing. Because our public key is only known after we spend the funds, it is harder for others to calculate the private key. They had to reverse two rounds of hashes (RIPEMD-160 and SHA-256) to get the private key.
➟ Want to start your cryptocurrency journey? Go to Binance and buy Bitcoin now!
Pay to Script Hash (P2SH) ) is a very interesting development for Bitcoin. It allows the sender to lock funds to a script’s hash – without knowing what the script actually does. Take the following SHA-256 hash as an example:
e145fe9ed5c23aa71fdb443de00c7d9b4a69f8a27a2e4fbb1fe1d0dbfb6583f1
You don’t need to know the hash Enter to lock funds. However, the person spending the funds needs to provide the script used to hash it, and the conditions of that script need to be met.
The above hash is created by the following script:
<multiply by 2> <4> <check if equal>
If you want to spend the tokens bound to this scriptPubKey, you must not only provide these commands . You also need a scriptSig so that the value of the completed script is True. In this example, you<multiply by 2> to get<4>Elements of the result. Of course, this means that our script is just<2>.
In actual situations, the scriptPubKey output by P2SH is:
OP_HASH160 <redeemScript hash> OP_EQUAL
There are no new operators here. However, we do have <redeemScript hash> as a new element. As the name suggests, this is the script hash we need to provide for the amount of funds to be redeemed (call it redeemScript). scriptSig will change based on what is in redeemScript. Typically, though, you'll find it's some combination of a signature and an appended public key, followed by (mandatory) redeemScript:
<signature> <public key> <redeemScript>
Our calculations and the stack we see so far The execution is slightly different. It is divided into two parts. The first part just checks that you provided the correct hash.
You will notice that we did not perform any operations on the elements preceding the redeemScript . They will not be used at this time. We have reached the end of this little program and the top element is non-zero. That is, it works.
But we're not done yet. Network nodes recognize this structure as P2SH, so they actually have elements of scriptSig waiting on another stack. This is where signatures and public keys are used.
So far, we have treated redeemScript as an element. But now, it will be interpreted as a command, which can be anything. Let's take the P2PKH lock script as an example. We must provide it with the same strong><public key hash>Matching<signature> and<public key>.
Once your redeemScript is extended, you can see that our situation looks the same as regular P2PKH The transaction is exactly the same. After that, you just need to run it like a normal program.
We have demonstrated so-called P2SH (P2PKH) scripts, but you are unlikely to find such scripts in the wild. There's nothing stopping you from making one, but it won't do you any good and will end up taking up more block space (and therefore costing more).
P2SH is generally suitable for situations like multi-signature or SegWit compatible transactions. Multisignature transactions can be very large because they require multiple keys. Before implementing pay-to-script hashing, senders must list all possible public keys in their locking script.
But for P2SH, no matter how complex the consumption conditions are, it will not have an impact. redeemScript's hash is always a fixed size. Therefore, the cost is passed on to the user who wants to unlock the locked script.
SegWit compatibility is another example where P2SH can come in handy (we will discuss the differences in transaction structures in detail in the next section). SegWit is a soft fork that results in changes to the block/transaction format. Since it is an optional upgrade, not all wallet software will recognize these changes.
This does not matter if the client wraps the SegWit script hash in P2SH. As with all transactions of this type, they do not need to know what the unlocked redeemScript is.
For a more comprehensive introduction to SegWit, please refer to"A Beginner's Guide to SegWit".
To understand the transaction format in SegWit, all you need to know is that we no longer only have scriptSig and scriptPubKey. Now, we have a new area called "witnessing". The data we previously saved in scriptSig was moved to the witness, so scriptSig is empty.
If you have ever encountered addresses starting with "bc1", then these are what we call SegWit native (rather than SegWit compatible, as they are P2SH addresses, so they start with "3" ;beginning).
Payment To-Witness Public Key Hash (P2PKH) is the SegWit version of P2PKH. Our testimony is as follows:
<signature> <public key>
You will notice that this is the same as scriptSig in P2PKH. Here, scriptSig is empty. At the same time, scriptPubKey is similar to the following:
<OP_0> span> <public key hash>
This looks weird, right? Where is the opcode that lets us compare signatures, public keys, and their hashes?
We do not show additional operators here because the node receiving the transaction is based on the <public key hash> ;'s length knows how to handle it. They calculate the length and understand that it must function the same way as a traditional P2PKH transaction.
Non-upgraded nodes don't know how to interpret transactions this way, but that doesn't matter. Under the old rules there were no witnesses, so they read an empty scriptSig and some data. They evaluate it and mark it as valid - in their opinion, anyone can use the output. This is why SegWit is considered a backwards compatible soft fork.
Pay to Public Key Hash (P2PKH) is the new P2SH. If you've gotten this far, you can probably figure out how it works, but we'll go over it anyway. Our witness is what we normally put in scriptSig. For example, in P2WSH wrapping a P2PKH transaction, it might look like this:
<signature> <public key>
Here is our scriptPubKey:
<OP_0> ; <public key hash>
The same rules apply here. The SegWit node reads the length of the script hash and determines it is a P2WSH output, which is evaluated similarly to P2SH. Meanwhile, old nodes see it as nothing more than an output that anyone can spend.
In this article, we have a certain understanding of the building blocks of Bitcoin . Let's quickly summarize:
Script Type | Description |
---|---|
Pay to Public Key (P2PK) | Lock funds to a specific Public Key |
Pay to Public Key Hash (P2PKH) | Lock funds to Specific public key hash (i.e. address) |
Payment to script hash (P2SH) | Lock funds to a hash of a script that the payee can provide |
Pay to a witness public key hash (P2PKH) | SegWit version of P2PK |
Payment to Public Key Hash (P2PKH) | SegWit version of P2SH |
Once you delve deeper into Bitcoin, you'll begin to understand why it has so much potential. A transaction may have several different components. By manipulating these building blocks, users can set conditions for how and when their funds can be used with extreme flexibility.