We hebben eerder geschreven over de rol van proof-of-work in bitcoin en hoe het digitale schaarste creëert door energie om te zetten in hashes. Maar waar werkt al die rekenkracht precies aan?

Het doel van proof-of-work is het genereren van een stukje data dat moeilijk is om na te maken maar makkelijk voor anderen om te verifiëren. Het produceren van een geldig stukje proof-of-work, een geldige hash, is een willekeurig proces. Hierdoor valt er geen algoritme te bedenken dat sneller of slimmer de oplossing kan vinden. Een geldig proof-of-work is een waarde die lager is dan het huidige target. In dit artikel leggen we uit hoe dit in elkaar steekt.

We hashen erop los

Het zijn termen die al vaker zijn langsgekomen: hashen, een hash, hashes en hashfuncties. Een hashfunctie is een algoritme dat, gegeven een bepaalde input, een unieke output genereert. Vanuit de gegenereerde output kan niet terug berekend worden wat de input was, maar het is wel mogelijk om, gegeven de input, te controleren dat de eerder getoonde output klopt door het algoritme nogmaals uit te voeren met de input. In dit geval is de unieke output een hash.

Het hashen van data is een veelgebruikt principe dat overal in de computerwetenschap terug te vinden is. Je gebruikt het, op de achtergrond, ook dagelijks bij het browsen op het internet. Wanneer je bijvoorbeeld een nieuw wachtwoord aanmaakt, dan wordt deze gehashed opgeslagen; geheel onherkenbaar. Hierdoor kan de partij waarbij jij jouw wachtwoord opslaat jouw wachtwoord niet zien en kan een potentiële hacker er niet zomaar met jouw wachtwoord vandoor gaan.

De gecombineerde rekenkracht van het bitcoinnetwerk (hierboven en hier) is geheel bezig met het uitvoeren van een enorme hoeveelheid aan hashes. Dit wordt gedaan door gespecialiseerde hardware, hier te zien. Dit doen zij teneinde het vinden van een geldige hash van een block, waardoor zij de beloning van vers aangemaakte bitcoins kunnen claimen. Een geldige hash is er een die voldoet aan een aantal voorwaarden.

Doelwit?

De belangrijkste van deze voorwaarden is het vinden van een waarde die lager is dan het huidige target. Het huidige target is een indicatie van de huidige moeilijkheidsgraad. We kunnen dit het beste uitleggen aan de hand van een simpel voorbeeld.

We gaan een simpel stukje data hashen met het SHA-256 algoritme, een veelgebruikt algoritme en tevens het algoritme dat de bitcoinminers gebruiken. De data die we gaan hashen is de zin "Hello, world!" en het beoogde target dat we onszelf stellen is het vinden van een hash die begint met vier nullen. Je zou dus kunnen zeggen dat de moelijkheidsgraad "4" is. Wanneer we de zin simpelweg een keer hashen komt er de volgende reeks uit:

315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3

Helaas, deze begint niet met vier nullen. Maar wat kunnen we nog doen om deze hash te veranderen? Elke input heeft echter maar één unieke output. Bitcoin gebruikt hiervoor een nonce, dit is een gewoon getal dat toegevoegd wordt aan de originele data. Bijvoorbeeld: "Hello, world!1". Door een willekeurig getal toe te voegen verandert de hash volledig:

e9afc424b79e4f6ab42d99c81156d3a17228d6e1eef4139be78e948a9332a7d8

Helaas levert dit wederom geen hash die begint met vier nullen op. We zullen het getal moeten veranderen en het nogmaals moeten proberen, dit doen we door systematisch het getal op te hogen; "Hello, world!2", "Hello, world!3", … , "Hello, world!500", enzovoorts. Dit doen we totdat we de gewenste hash tegenkomen. In dit geval moeten we het getal ophogen tot en met 4250. De data "Hello, world!4250" geeft de hash:

0000c3af42fc31103f1fdc0151fa747ff87349a4714df7cc52ea464e12dcd4e9

Nu hebben we ons doel bereikt. Het vinden van een geldig proof-of-work in bitcoin werkt vrijwel hetzelfde, alleen is de ingegeven data anders en verandert het target regelmatig.

Eens per 10 minuten

De data die bij het minen gebruikt wordt om de geldige hash te berekenen is de data die in het huidige block gaat en dus uniek. Onderdeel van deze data is de hash van het vorige block. Hierdoor is het dus niet mogelijk om vast een voorsprong te nemen en vast vooruit te rekenen aan het volgende block. Er moet gewacht worden tot de oplossing van het laatste block bekend is voordat de miners kunnen beginnen met het volgende block. Dit helpt om de boel eerlijk te houden.

De moeilijkheidsgraad van het vinden van een geldige hash is zodanig dat het gemiddeld 10 minuten duurt voor de volgende oplossing gevonden wordt. Maar wat nu als een miner heel veel extra rekenkracht toevoegt aan het netwerk, dan wordt de oplossing toch veel sneller gevonden? Dit zou inderdaad het geval zijn. Als oplossing hiervoor is de moeilijkheidsgraad zo ontworpen dat deze zichzelf automatisch aanpast aan de hoeveelheid rekenkracht in het netwerk.

Is er veel rekenkracht in het netwerk waardoor de oplossingen gemiddeld sneller dan eens per 10 minuten gevonden worden, dan wordt de moeilijkheidsgraad verhoogd. Dit gebeurt eens per 2016 blocks, ongeveer elke twee weken. Bij het verhogen van de moeilijkheidsgraad wordt het target verlaagd. Dit wil zeggen dat de waarde van de hash die gevonden moet worden kleiner wordt gemaakt. Waar dit voorheen in ons voorbeeld vier nullen was, wordt het target nu een hash die begint met vijf nullen. Hierdoor moeten er weer een stuk meer pogingen gedaan worden voordat de geldige oplossing gevonden wordt. Op dezelfde manier kan de moeilijkheidsgraad verlaagd worden. Wanneer er minder rekenkracht in het netwerk is dan voorheen, dan wordt het target verhoogd van bijvoorbeeld een hash die begint met vijf nullen terug naar een hash die begint met vier nullen.

Op deze manier wordt het vinden van een nieuwe block beperkt tot gemiddeld eens per 10 minuten. Dit is van belang om onder andere mining eerlijk te houden voor alle deelnemers, maar ook om te zorgen dat de rest van het netwerk de tijd heeft om de meeste recente blocks te ontvangen en te verwerken. Er wordt zo voorkomen dat sommige deelnemers in het netwerk op achterstand komen en deze wellicht niet meer in kunnen halen.

Eitje, toch?

Nogmaals in het kort: men neemt de data voor het volgende block, de hash van het laatste block en begint deze te hashen in combinatie met een extra getal dat bij elke poging stapsgewijs ophoogt. Wanneer de hash gevonden is met het juiste aantal nullen, op dit moment 18 nullen, is het recht om verse bitcoins te claimen gewonnen en gaan alle miners aan de slag met het volgende block. Doordat de hash van het laatste block steeds wordt opgenomen in het volgende block ontstaat er een ketting van hashes: de blockchain.

Dat minen? Simpel gokwerk dus, gebaseerd op willekeur en een geheel zelfregulerend systeem waar geen mens invloed op heeft. Misschien niet het interessantste onderdeel van bitcoin, met al die hashes en andere technische termen, maar tegelijkertijd van grote impact op bitcoin als geheel.