Who looks after the shared list?
Imagine a class keeps one shared page of who paid whom. How would you stop somebody quietly rubbing out a line and writing a different amount? A blockchain answers with maths instead of a person in charge. This lab is a toy: a few short files of Python that show the ideas, with no coin, no network and no value.
By the end of this lesson
Note
I can explain how blocks linked by hashes make a change to an old record show up.
Key words
- Hash: a fixed-length fingerprint worked out from some data. Change one letter and the fingerprint is completely different.
- Block: a group of records, with the hash of the block before it.
- Chain: blocks in order, each holding the hash of the one before.
- Nonce: a number that is changed again and again until the hash looks the way the rules ask.
- Mining: trying nonces until a block's hash starts with enough zeros.
- Signature: proof that a message came from the holder of a secret key.
Starter: what you already know
Note
Answer in your head. 1. Why might you compare a downloaded file with its checksum? 2. If you change one letter of a long message, should its fingerprint change a little or a lot? 3. What does a loop do? Answers: to check nothing has changed; a lot; it repeats a step.
Before you start
Note
Press Start the lab on the bar at the top of this lesson and wait until it says it is running. There is one container, jupyter, and the terminal reaches its Python with docker exec jupyter, which runs one command inside it. The JupyterLab link opens its web page, port 8888. Each Run button below types its command into your lab's terminal, one after another in the same session. To watch them, or to type your own, press Open terminal on the bar.
A chain is blocks that hold each other's fingerprints
ls lists the work folder: three short Python files, the notebook and the folder steps. The first script builds three blocks. Each line shows a block's number, the hash of the block before it and its own hash, cut short. Block 0 has nothing before it, so its previous hash is all zeros. Every other block's previous hash is the line above it. Every hash starts with 000, which is what mining made it do.
docker exec jupyter lsShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
docker exec jupyter python3 steps/link.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Change one amount and the chain notices
The script checks the chain, changes one amount inside block 1, and checks again. The first answer is (True, None): valid, no bad block. After the change it is (False, 1): not valid, and block 1 is where. Block 1's fingerprint no longer matches its contents. Faking the fingerprint does not help. Mining block 1 again makes block 1 right, but now the answer is (False, 2), because block 2 still holds the old hash of block 1.
docker exec jupyter python3 steps/tamper.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Mining is trying numbers until the hash looks right
To add a block, the rules ask for a hash that starts with some zeros. The only way to find one is to try a nonce, then the next, and the next. The script mines the same block at four difficulties. It took 15 tries for one zero, 835 for two, 7992 for three and 109028 for four. Each extra zero costs far more work, and the answer is the same every time because the block and the start are fixed.
docker exec jupyter python3 steps/mine.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Check
Tip
Why is changing an old block harder than changing a new one? Answer: every block after it holds the old hash, so each one has to be mined again, and every one costs tries.
A ledger is worked out from the payments
Nobody stores a balance. The script starts Asha with 10, Ben with 5 and Cara with 0, then replays four payments in order. The last line says the payment of 8 from Cara to Asha was refused, because Cara had only 6 at that point. The balances are Asha 6, Ben 0 and Cara 9.
docker exec jupyter python3 steps/balances.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A signature shows who sent a message
Anybody can write "Asha pays Ben 5". A signature shows Asha wrote it. This one is made only of hashes: a secret key of 256 pairs, a public key that is the hash of each, and a signature that reveals one secret of each pair. The signed message checks out as True. Change one letter of the message, keep the same signature, and it checks out as False. A key like this signs one message only, so it is a lesson and not something to use.
docker exec jupyter python3 steps/sign.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
When two chains disagree, work decides
Two people can add different blocks to the same chain at the same moment, and then there are two chains. The script builds both from the same first two blocks. Chain A has 3 blocks and chain B has 4. Both are valid. The rule is to follow the chain with more work, here 768 against 1024, so B wins and A's extra block is dropped.
docker exec jupyter python3 steps/fork.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A common mistake
Warning
Many people think a valid chain means every payment in it is true. It means only that nobody has changed the record since it was written. Whether a payment should be in it at all is a different job: the ledger refuses an overspend and a signature shows who sent it. Keep the three questions apart: was it changed, is it allowed, who sent it.
The same work in a notebook
Open JupyterLab from the bar and double-click start.ipynb. It builds a chain, checks it, changes a block and checks again. Click a cell and press Shift and Enter to run it. The last cell is where your own question goes, and chain.py is short enough to read in full.
Exit check
Tip
Answer without looking back. 1. What does a block hold that links it to the one before? 2. What does mining try again and again? 3. Why did the check fail at block 2 after block 1 was mined again? 4. Does a valid chain show that every payment is true? Answers: the previous block's hash; nonces; block 2 still held the old hash of block 1; no, only that it has not been changed.
For teachers
Tip
This lesson is a small example of a lesson worked in a lab: the steps and the Run buttons are the lesson, and the lab is each student's own copy. The lab is one service, JupyterLab with a toy chain written in the Python standard library, and nothing here marks itself: the student hands in a notebook of their own, downloaded from JupyterLab, and a sentence on what it showed. Key learning points: 1. A hash links blocks, so a change shows. 2. Mining is trial and error whose cost grows with the difficulty. 3. A valid chain, an allowed payment and a signature are three different checks. Common mistake: reading a valid chain as every payment being true. The lab is a toy for the ideas and talks about no coin, market or price. Equipment: the lab and a browser. Tip: ask students to guess how many tries the next difficulty needs before they run it. Copy it into your own module and change it, or build one from scratch with the Lab menu in the lesson builder.