Een introductie van de Bitcoin Script
Een introductie van de Bitcoin Script
StartpaginaArtikelen

Een introductie van de Bitcoin Script

Geavanceerd
1w ago
13m

Introductie

Bitcoin  wordt ook wel  programmeerbaar geld  genoemd. Vanwege het digitale karakter biedt het gebruikers een grote mate van flexibiliteit als het gaat om het stellen van voorwaarden bij de besteding van geld. 
We spreken van  wallets  en  coins  wanneer we het hebben over Bitcoin. Maar we kunnen ook wallets zien als keys, coins als cheques en de  blockchain  als een rij met vergrendelde kluizen. Elke kluis heeft een dunne sleuf, zodat iedereen cheques kan storten of kan kijken om te zien hoeveel waarde de kluis heeft. Alleen de key-houder heeft echter toegang tot de binnenkant.

Als een key-houder geld aan iemand anders wil geven, ontgrendelen ze hun box. Ze schrijven een nieuwe cheque die verwijst naar de oudere (die vervolgens wordt vernietigd) en vergrendelen deze in een vak dat de ontvanger kan openen. Om dat uit te geven, herhaalt de nieuwe ontvanger het proces.

In dit artikel bekijken we Script, de programmeertaal die wordt geïnterpreteerd door  nodes  op het Bitcoin-netwerk. Script is wat het vergrendelings- / ontgrendelingsmechanisme voor de kluizen regelt.


Hoe werkt Bitcoin?

In lijn met onze analogie van hierboven, zou je kunnen zeggen dat elke transactie uit twee delen bestaat: een  key  (om je box te ontgrendelen) en een  lock . U gebruikt uw key om de doos te openen die de cheque bevat die u wilt verzenden, en vervolgens voegt u een nieuwe toe aan een nieuwe doos met een ander lock. Om uit de nieuwe doos te kunnen besteden, heb je een andere key nodig.
Simpel genoeg. Je kunt ook een beetje variatie krijgen op de soorten sloten in het systeem. Misschien vereisen sommige kluizen dat u  meerdere keys  opgeeft, en misschien moeten anderen u bewijzen dat u een geheim kent. Er zijn een aantal voorwaarden die mensen kunnen stellen. 
Onze key is wat we een  scriptSig  noemen. Het slot is ons  scriptPubKey . Als we die componenten wat gedetailleerder bekijken, zullen we ontdekken dat ze eigenlijk bestaan uit stukjes gegevens en codeblokken. Gecombineerd creëren ze een klein programma.

Wanneer u een transactie doet, zendt u die combinatie uit naar het netwerk. Elk node dat het ontvangt, controleert het programma, dat aangeeft of de transactie geldig is. Zo niet, dan wordt het gewoon weggegooid en kunt u het vergrendelde geld niet uitgeven.

De cheques (coins) die u bezit, worden  niet-uitgegeven transactie-uitgangen  (UTXO's) genoemd. Het geld kan worden gebruikt door iedereen die de key kan leveren die in het slot past. De key is met name de scriptSig en het slot is de scriptPubKey.
Als de UTXO's in je wallet zitten, hebben ze waarschijnlijk een aandoening die zegt dat  alleen de persoon die het eigendom van deze openbare key kan bewijzen, deze fondsen kan ontgrendelen . Om het te ontgrendelen, levert u een scriptSig met een  digitale handtekening , met behulp van de  private key  die wordt toegewezen aan de openbare sleutel die is opgegeven in de scriptPubKey. Dit wordt straks allemaal duidelijk.


De Bitcoin stack

Script is wat bekend staat als een  op stack gebaseerde  taal. Dit alles betekent dat wanneer we een reeks instructies lezen, we ze plaatsen in wat kan worden beschouwd als een verticale kolom. De lijst A, B, C zou bijvoorbeeld resulteren in een stapel met A onderaan en C bovenaan. Wanneer de instructies ons vertellen iets te doen, werken we met een of meer elementen die bovenaan de stapel beginnen.


Elementen A, B en C worden toegevoegd en uit de stapel gehaald.


We kunnen onderscheid maken tussen de gegevens (zaken als  handtekeningen ,  hashes  en openbare keys) en de instructies (of  opcodes ). De instructies verwijderen gegevens en doen er iets mee. Hier is een heel eenvoudig voorbeeld van hoe een script eruit zou kunnen zien:
<xyz> <md5 hasher> <d16fb36f0911f878998c136191af705e> <check if equal>
In het rood hebben we gegevens en in het blauw hebben we de opcodes. We lezen van links naar rechts, dus we zetten eerst de string <xyz> op de stapel. De volgende is de <md5 hasher> opcode. Deze bestaat niet in Bitcoin, maar laten we zeggen dat het het bovenste element van de stapel (<xyz>) verwijdert en het hasht met behulp van het MD5-algoritme. Vervolgens wordt de uitvoer weer toegevoegd aan de stapel. De uitvoer is hier toevallig d16fb36f0911f878998c136191af705e.
Wat een toeval! Ons volgende toe te voegen element is <d16fb36f0911f878998c136191af705e>, dus nu heeft onze stapel twee identieke elementen. Ten slotte zet <check if equal> twee elementen bovenaan en controleert of ze gelijk zijn. Als dat zo is, wordt <1> aan de stapel toegevoegd. Zo niet, dan wordt <0> toegevoegd. 
We zijn aan het einde van onze lijst met instructies gekomen. Ons script had op twee manieren kunnen mislukken als het resterende element een nul was, of als een van de operatoren ervoor zorgde dat het mislukte als niet aan bepaalde voorwaarden was voldaan. We hadden dergelijke operators niet in dit voorbeeld en we eindigen met een niet-nul element (<1>), dus ons script was geldig. Deze regels gelden ook voor echte Bitcoin-transacties.

Dat was maar een verzonnen programma. Laten we nu eens kijken naar enkele echte.


Pay-to-Pubkey (P2PK)

Pay-to-Pubkey (P2PK) is ongelooflijk eenvoudig. Het gaat om het vergrendelen van geld op een bepaalde openbare sleutel. Als u op deze manier geld wilde ontvangen, zou u de afzender uw openbare sleutel verstrekken, in plaats van een Bitcoin-adres.

De  allereerste transactie  tussen  Satoshi Nakamoto  en Hal Finney in 2009 was een P2PK-transactie. De structuur werd veel gebruikt in de begindagen van Bitcoin, maar tegenwoordig heeft Pay-to-Pubkey-Hash (P2PKH) deze grotendeels vervangen. 
Het vergrendelingsscript voor een P2PK-transactie volgt de indeling <public key>    OP_CHECKSIG . Simpel genoeg. Je hebt misschien geraden dat  OP_CHECKSIG  controleert op een handtekening met de verstrekte openbare sleutel. Als zodanig wordt ons scriptSig een eenvoudige <signature>. Onthoud dat de scriptSig de sleutel is tot het slot.



Het wordt niet veel eenvoudiger dan dit. Er wordt een handtekening aan de stapel toegevoegd, gevolgd door een openbare sleutel.  OP_CHECKSIG  plaatst ze allebei en verifieert de handtekening met de openbare sleutel. Als ze overeenkomen, wordt er een <1> aan de stapel toegevoegd. Anders voegt het een <0> toe.

Om redenen die we in de volgende sectie zullen toelichten, wordt P2PK niet echt meer gebruikt.


Pay-to-Pubkey-Hash (P2PKH)

Pay-to-Pubkey-Hash (P2PKH) is nu het meest voorkomende type transactie. Tenzij u besluit om archaïsche software te downloaden, doet uw portemonnee dit waarschijnlijk standaard.

Het scriptPubKey in P2PKH is het volgende:

OP_DUP OP_HASH160 <public key hash> OP_EQUALVERIFY OP_CHECKSIG

Voordat we het scriptSig introduceren, laten we eens uitsplitsen wat de nieuwe opcodes zullen doen:


OP_DUP

OP_DUP springt het eerste element en  dupliceert  het. Vervolgens worden beide weer aan de stapel toegevoegd. Meestal wordt dit gedaan zodat we een bewerking op het duplicaat kunnen uitvoeren zonder het origineel te beïnvloeden.


OP_HASH160

Hierdoor springt het eerste element en hashes het tweemaal. De eerste ronde hash met het SHA-256-algoritme. De SHA-256-uitvoer wordt vervolgens gehasht met het RIPEMD-160-algoritme. De resulterende output wordt terug toegevoegd aan de stapel.


OP_EQUALVERIFY

OP_EQUALVERIFY combineert twee andere operators OP_EQUAL en OP_VERIFY. OP_EQUAL plaatst twee elementen en controleert of ze identiek zijn. Als dat zo is, voegt het een 1 toe aan de stapel. Zo niet, dan wordt er een 0 toegevoegd. OP_VERIFY laat het bovenste element verschijnen en controleert of het waar is (d.w.z. niet-nul). Als dat niet het geval is, mislukt de transactie. Gecombineerd zorgt OP_EQUALVERIFY ervoor dat de transactie mislukt als de twee bovenste elementen niet overeenkomen.

Deze keer ziet het scriptSig er als volgt uit:

<signature> <public key>

U moet een handtekening en de bijbehorende openbare sleutel opgeven om P2PKH-uitgangen te ontgrendelen.



Je kunt zien wat er aan de hand is in de bovenstaande GIF. Het verschilt niet veel van een P2PK-script. We voegen gewoon een extra stap toe om te controleren of de openbare sleutel overeenkomt met de hash in het script.

Er is echter iets op te merken. In een P2PKH-vergrendelingsscript is de openbare sleutel niet zichtbaar, we kunnen alleen de hash zien. Als we naar een  blockchain-verkenner  gaan en kijken naar een P2PKH-uitvoer die niet is uitgegeven, kunnen we de openbare sleutel niet bepalen. Het wordt pas onthuld wanneer de ontvanger besluit het geld over te maken.
Dit heeft een aantal voordelen. De eerste is dat de hash van de openbare sleutel eenvoudigweg gemakkelijker kan worden doorgegeven dan een volledige openbare sleutel. Om deze reden lanceerde Satoshi het in 2009.  De hash van de openbare sleutel is wat we tegenwoordig kennen als een Bitcoin-adres .
Het tweede voordeel is dat hashes met openbare sleutels een extra beveiligingslaag kunnen bieden tegen  quantum computing. Omdat onze openbare sleutel pas bekend is wanneer we het geld uitgeven, is het voor anderen nog moeilijker om de privésleutel te berekenen. Ze zouden de twee rondes van hashing (RIPEMD-160 en SHA-256) moeten omkeren om het te krijgen.



Pay-to-Script-Hash (P2SH)

Pay-to-Script-Hash (P2SH) was een zeer interessante ontwikkeling voor  Bitcoin . Hiermee kan de afzender geld vergrendelen voor de hash van een script, ze hoeven niet te weten wat het script eigenlijk doet. Neem de volgende SHA-256-hash:

e145fe9ed5c23aa71fdb443de00c7d9b4a69f8a27a2e4fbb1fe1d0dbfb6583f1

U hoeft de invoer van de hash niet te kennen om er geld aan vast te maken. De spender moet echter het script opgeven dat is gebruikt om het te hashen en moet voldoen aan de voorwaarden van dat script.

De bovenstaande hash is gemaakt op basis van het volgende script:

<multiply by 2> <4> <check if equal>

Als u de coins die aan dat scriptPubKey zijn gebonden wilt uitgeven, geeft u niet alleen die opdrachten op. U hebt ook een scriptSig nodig waarmee het voltooide script naar True wordt geëvalueerd. In dit voorbeeld is dat een element dat u <multiply by 2> geeft om een resultaat van <4> te geven. Dat betekent natuurlijk dat ons scriptSig slechts <2> is.

In het echte leven is de scriptPubKey voor een P2SH-uitvoer:

OP_HASH160 <redeemScript hash> OP_EQUAL

Geen nieuwe operators hier. Maar we hebben <redeemScript hash> als een nieuw element. Zoals de naam al doet vermoeden, is het een hash van het script dat we moeten verstrekken om het geld in te wisselen (het  redeemScript  genoemd). Het scriptSig verandert afhankelijk van wat er in het redeemScript staat. Over het algemeen zul je echter merken dat het een combinatie is van handtekeningen en de bijgevoegde openbare sleutels, gevolgd door het (verplichte) redeemScript:

<signature> <public key> <redeemScript>

Onze evaluatie wijkt een beetje af van de stack-uitvoering die we tot nu toe hebben gezien. Het gebeurt in twee delen. De eerste controleert eenvoudig of je de juiste hash hebt opgegeven



U zult merken dat we niets doen met de elementen die aan het redeemScript voorafgaan. Ze worden op dit moment niet gebruikt. We zijn aan het einde van dit miniprogramma gekomen en het bovenste element is niet nul. Dat betekent dat het geldig is.

We zijn echter nog niet klaar. Netwerk  knooppunten  herkennen deze structuur als P2SH, dus ze hebben de elementen van scriptSig eigenlijk in een andere stapel laten wachten. Dat is waar de handtekening en openbare sleutel zullen worden gebruikt.
Tot dusver hebben we het redeemScript als een element behandeld. Maar nu zal het worden geïnterpreteerd als instructies, wat van alles kan zijn. Laten we het voorbeeld nemen van een P2PKH-vergrendelingsscript, waaraan we de <signature> en <public key> moeten geven die overeenkomen met een <public key hash> binnen de <redeemScript>.



Zodra uw redeemScript is uitgebreid, kunt u zien dat we een situatie hebben die precies lijkt op een gewone P2PKH-transactie. Vanaf daar voer je het gewoon uit zoals je normaal zou doen.

We hebben hier gedemonstreerd wat een P2SH (P2PKH) -script wordt genoemd, maar het is onwaarschijnlijk dat u een van die in het wild zult vinden. Niets weerhoudt je ervan er een te maken, maar het geeft je geen extra voordelen en neemt uiteindelijk meer ruimte in beslag in een blok (en kost daarom meer).

P2SH is over het algemeen handig voor zaken als  multisignature  of  SegWit  -compatibele transacties. Multisig-transacties kunnen erg groot zijn omdat er meerdere sleutels nodig zijn. Voorafgaand aan de implementatie van Pay-to-Script-Hash, zou een afzender alle mogelijke openbare sleutels moeten vermelden in zijn vergrendelingsscript. 

Maar met P2SH maakt het niet uit hoe complex de bestedingsvoorwaarden zijn. De hash van de redeemScript heeft altijd een vaste grootte. De kosten worden daarom doorberekend aan de gebruiker (s) die het vergrendelingsscript willen ontgrendelen.

SegWit-compatibiliteit is een ander geval waarin P2SH van pas komt (we zullen in de volgende sectie ingaan op de details van hoe de transactiestructuur verschilt). SegWit was een zachte vork die resulteerde in een wijziging in blok- / transactieformaten. Omdat het een opt-in upgrade is, herkent niet alle wallet software de wijzigingen.

Dat maakt niet uit of clients de SegWit-scripthash in P2SH verpakken. Zoals bij alle transacties van dit type, hoeven ze niet te weten wat de ontgrendelingsredeemScript zal zijn


SegWit Transactions (P2WPKH and P2WSH)

Voor een uitgebreidere inleiding tot SegWit, bekijk  A Beginner's Guide to Segregated Witness .
Om het transactieformaat in SegWit te begrijpen, moet je gewoon weten dat we niet langer alleen een scriptSig en een scriptPubKey hebben. Nu hebben we ook een nieuw veld genaamd de  getuige . De gegevens die we gebruikten in de scriptSig worden verplaatst naar de getuige, dus de scriptSig is leeg.

Als u adressen tegenkomt die beginnen met '' bc1 '', zijn dat wat we '' SegWit-native '' noemen (in tegenstelling tot alleen SegWit-compatibel, die beginnen met een '' 3 '' omdat ze P2SH zijn) adressen).


Pay-to-Witness-Pubkey-Hash (P2WPKH)

Pay-to-Witness-Pubkey-Hash (P2WPKH) is de SegWit-versie van P2PKH. Onze getuige ziet er zo uit:

<signature> <public key>

Je zult merken dat dit hetzelfde is als de scriptSig van P2PKH. Hier is het scriptSig leeg. Ondertussen lijkt het scriptPubKey op het volgende:

<OP_0> <public key hash>

Dat ziet er een beetje vreemd uit, nietwaar? Waar zijn de opcodes waarmee we de handtekening, openbare sleutel en de hash kunnen vergelijken?

We laten hier geen extra operators zien, omdat nodes die de transactie ontvangen, weten wat ze ermee moeten doen op basis van de lengte van <public key hash>. Ze berekenen de lengte en begrijpen dat deze in dezelfde stijl moet worden uitgevoerd als een ouderwetse P2PKH-transactie.
Niet-geüpgradede nodes weten niet hoe ze de transactie op die manier moeten interpreteren, maar dat maakt niet uit. Onder de oude regels is er geen getuige, dus lezen ze een leeg script Sig en wat gegevens. Ze evalueren dit en markeren het wat hen betreft geldig, iedereen zou de output kunnen uitgeven. Daarom wordt SegWit beschouwd als een achterwaarts compatibele  zachte vork .


Pay-to-Witness-Script-Hash (P2WSH)

Pay-to-Witness-Script Hash (P2WSH) is de nieuwe P2SH. Als je zover bent gekomen, kun je er waarschijnlijk achter komen hoe dit eruit zal zien, maar we zullen het hoe dan ook doornemen. Onze getuige is wat we normaal in het script Sig zouden zetten. In een P2WSH die bijvoorbeeld een P2PKH-transactie afrondt, zou het er ongeveer zo uit kunnen zien:

<signature 1> <public key>

Hier is ons scriptPubKey:

<OP_0> <script hash>

Dezelfde regels gelden. SegWit-nodes lezen de lengte van de script-hash en bepalen dat het een P2WSH-uitvoer is, die op dezelfde manier wordt geëvalueerd als P2SH. Ondertussen zien oude knooppunten het gewoon als een output die iedereen kan uitgeven.


Tot Slot

In dit artikel hebben we iets geleerd over de bouwstenen van Bitcoin. Laten we ze samenvatten:


Script typeOmschrijving

Pay-to-Pubkey (P2PK)

Vergrendelt fondsen voor een bepaalde openbare sleutel

Pay-to-Pubkey-Hash (P2PKH)

Vergrendelt geld voor een bepaalde hash met openbare sleutel

Pay-to-Script-Hash (P2SH)

Vergrendelt geld aan de hash van een script dat de ontvanger kan verstrekken

Pay-to-Witness-Pubkey-Hash (P2WPKH)

De SegWit-versie van P2PK

Pay-to-Witness-Script-Hash (P2WSH)

De SegWit-versie van P2SH


Zodra je dieper in Bitcoin graaft, begin je te begrijpen waarom het zoveel potentieel heeft. Transacties kunnen uit veel verschillende componenten bestaan. Door deze bouwstenen te manipuleren, hebben gebruikers veel flexibiliteit als het gaat om het stellen van voorwaarden aan hoe en wanneer geld kan worden besteed.