Three levels of abstractification.
The are three level to understand the way the Bitcoin block chain works.
In the first level, we got those who just heard about Bitcoin for the first time. People usually thinks that the coins are just associated with the Bitcoin address. Whenever Alice sends Bob coins, she just place a statement (or transaction) in the block chain specifying that the X coins that were associated with Alice address, should now be associated with Bob address. This is of course wrong since this representation contains only 3 thing: the sender address, the receiver address and the amount of coins to be transferred. But this level of abstraction is usually the first thought most people have when first presented with the idea of the block chain.
In the second level, people starts to understand that each transaction also contains the origin of each coin. So if Alice wants to send 5 BTC to bob, she first needs to show where she got these 5 BTC from, That is, she also needs to provide a way to point to older translations on the block chain, transactions which proves that Alice is indeed the rightful owner of these five BTC. So now what we have starts to look more like a chain. It’s no longer just a table containing the address and the current BTC balance, rather the block chain needs to contain a list of all previous transactions. This depiction is more accurate, but still it isn’t complete – introducing the third level.
In the third level, people learns that a transaction is more then just a simple statement in the block chain. Transaction contains more then just information about the origin of the coins (the input), the address of the receivers (the outputs) and the amount of coins to be transferred. Rather, the transaction also contains a riddle in it, and only by solving this riddle, can the coins be claimed and transferred. So when Alice send 5 BTC to Bob, she doesn’t only pointing at the transaction from which Alice got the coins, it also solves the riddle specified in that transaction to prove that Alice is allowed to claim those coins, but that’s not the end of it, in the transaction that Alice publish on the block chain she’s also inserting another riddle, a riddle that only Bob can answer. So if Bob would like to use this coins in the future, he’ll have to solve that riddle which was provided to him by Alice. And the process goes on and on and on.
I love riddles! Or, how to solve the riddle and prove that I’m allowed to claim the coins?
A quick reminder. Signing messages and key pair.
In the previous post we’ve talked about mathematical trapdoors and hashing functions. We’ve saw how we can use these types of function so sign a message with a
private key and how these signed message can be verified with the corresponding
F("My name is Alice", Alice's_private_key) = signed message.
Verify(signed message, "My name is Alice", Alice's_public key) = true.
Change any component in the
Verify statement, and we’ll receive
false. This way we can easily prove that the message “My name is Alice” was indeed signed by Alice and that no one tempered with that message.
Pay attention! We cannot sign a message with the public key, it simply wont work! the public key can only be used to verify a message, not to sign it!
So, Alice can now publish a message in the block chain that contains the input (origin of the coins) and the output (the address of the receiver). This is the original message, public for anyone to see and check as he or she pleases. Alice can also now specify the following rules in that public message:
- This message is the original message.
- Within this message I’ve included Bob’s_public_key (In hashed format – We’ll get there in a second).
- Take your public key and hash it. If your hashed public key matches the hashed public key from step 2, you may move to the next step.
- Take this original message, and sign it with your own private key.
F(This message, Bob’s_private_key) = signed message.
- The signed message should be verified only against the public key that is specified in this message.
Verify(signed message, This message, Bob’s_public_key) = true.
- If the verification indeed yield true, you may claim the coins in this transaction
Getting Bob’s public key
When Alice specify Bob as the recipient of a transaction, she does so by inserting Bob’s
hashed public key. The
hashed public key (as we already saw in the post dealing with keys) can be deducted from Bob’s Bitcoin address.
So basically, knowing Bob’s Bitcoin address is equal to knowing Bob’s
hashed public key. All we need to do is to convert the address back from base 58, and remember that out of the 25 bytes of the binary address, we need to omit the first byte and the last 4 bytes.
Scrips – the beginning
As we’ve already saw many times in the past, Bitcoin message is no more then a string of bytes that follow a predefined order. That means that in order to specify conditions and rules like the one Alice is using in her transaction message, we also need all parties to agree on a predefined field that will contain the conditions, and we also need to agree on a way to translate the bytes in that field into a set of rules, or instructions. For this purpose, a scripting language was created for Bitcoin, this langue allocate predefined operation to a predefined byte. For example, the byte
0x8b means “plus 1”, the byte
0x8c means “minus 1”, the byte
0xa9 means “hash the public key. First with SHA-256 and then with RIPEMD-160”, and so on. There’re many more of these operators (also called OP-codes) and these OP-codes helps us to specify the rules that needs to be fulfilled. These rules are transparent and are publicly visible on the block chain. Whenever a node verify a transaction, the nodes follows these rules and make sure that they eventually do yield a true statement.
We’ll talk more about these OP-codes and scrips in the next sections, when we’ll also see a real example of valid transaction script.