10. Segregated Witness

Dieses Kapitel behandelt

  • Bitcoins Probleme begreifen

  • Entfernung von Signaturen aus Transaktionen

Bitcoin ist bei weitem nicht perfekt. Es hat einige Schwächen, die wir angehen sollten. Der erste Abschnitt dieses Kapitels wird einige dieser Defizite erklären. Unter den kritischsten sind Transaktions-Umformbarkeit oder transaction malleability und Ineffizienzen in der Verifikation von Signaturen. Wir haben transaction malleability bereits in [time-locked-transactions] erwähnt–jemand könnte eine Transaktion auf eine subtile, aber gültige, Weise verändern, während diese gesendet wird, was zu einer Änderung der txid führen würde.

Eine Lösung für dieses Problem wurde 2015 bei einer Konferenz über die Skalierung von Bitcoin präsentiert. Die Lösung wird segregated witness (SegWit) genannt, was ein merkwürdiger Name dafür ist, dass man Signaturdaten aus den Transaktionen herausnimmt. Ich werde die Lösung im Detail beschreiben: es beinhaltet Änderungen in so ziemlich allen Teilen von Bitcoin, einschliesslich Bitcoin Adressen, Transaktionsformat, Blockformat, lokalem Speicher und Netzwerkprotokoll.

Weil SegWit eine ziemlich grosse Änderung an Bitcoin war, war es nicht einfach auszurollen, ohne das Netzwerk zu erschüttern. Es wurde sorgfältig so gestaltet, dass alte Software weiterhin funktionieren und SegWit Transaktionen und Blocks akzeptieren würde, auch wenn sie einige Teile davon nicht verifizieren würde.

10.1. Durch SegWit gelöste Probleme

In diesem Abschnitt besprechen wir die Probleme, die SegWit löst.

10.1.1. Transaktions-Umformbarkeit, Transaction Malleability

Um Transaktions-Umformbarkeit zu erklären, gehen wir zurück zu dem Beispiel in [ch09], in dem du deiner Tochter eine time-locked Transaktion gegeben hast. Wenn knapp ein Jahr vergangen ist, seitdem du deine time-locked Transaktion erzeugt hast, musst du die Transaktion ungültig machen und eine neue time-locked Transaktion generieren, wie in Abbildung 1 dargestellt.

10 01
Abbildung 1. Du gibst einen der Outputs aus, den die vorige zeitgesperrte Transaktion ausgibt, und erzeugst eine neue zeitgesperrte Transaktion, die du deiner Tochter gibst.

Es ist wichtig, deiner Tochter die neue zeitgesperrte Transaktion Tx3 zu geben, bevor du Tx2 sendest, die die vorhergehende zeitgesperrte Transaktion Tx1 ungültig macht. Ansonsten kann deine Tochter, wenn du es andersherum machst und zwischen den beiden Schritten von einem Bus überfahren wirst, ihren Anspruch auf das Geld nicht anmelden.

Angenommen du machst das korrekt und gibst zunächst Tx3 deiner Tochter und sendest dann Tx2. Tx3 gibt den Output von Tx2 aus, was bedeutet, Tx3 enthält die txid von Tx2 in einer ihrer Inputs. Schauen wir mal, was passiert, wenn du Tx2 sendest (Abbildung 2).

10 02
Abbildung 2. Deine Transaktion wird auf ihrem Weg durch das Netzwerk von Qi abgeändert.
Malleability

Das Wort malleate bedeutet umformen–zum Beispiel Metall mit einem Hammer. Dieser Term wird in der Kryptografie benutzt, wenn eine Signatur geändert wird, ohne ungültig zu werden, oder eine verschlüsselte Nachricht geändert wird, ohne völlig unleserlich zu werden.

Qi will Ärger machen. Wenn sie deine Transaktion Tx2 bekommt, ändert sie sie auf eine bestimmte Weise zu Tx2M ab, sodass Tx2M zwar immer noch gültig ist und denselben Effekt hat wie die originale Transaktion Tx2. (Du siehst gleich ein paar verschiedene Wege, wie sie das erreichen kann.) Das Ergebnis ist, dass jetzt zwei verschiedene Transaktionen durch das Netzwerk laufen, die dieselben Outputs ausgeben und dasselbe Geld in derselben Höhe an die selben Empfänger schicken–aber sie haben unterschiedliche txids.

Weil Tx2 und Tx2M dieselben Outputs ausgeben, stehen sie im Konflikt miteinander, und höchstens einer von beiden wird bestätigt. Nehmen wir an, Tx2M gewinnt und findet Eingang in den nächsten Block. Was passiert mit der Erbschaft deiner Tochter? Siehe Abbildung 3.

10 03
Abbildung 3. Die Erbschaft schlägt fehl, weil die zeitgesperrte Transaktion deiner Tochter auf ewig ungültig ist, wegen der Transaktionsumformbarkeit.

Die umgeformte Transaktion, Tx2M, wird in der Blockchain gespeichert. Dadurch wird Tx2 ungültig, weil die denselben Output wie Tx2M ausgibt. Der erste Input der zeitgesperrten Transaktion, Tx3, referenziert Tx2 mittels txid, wenn also der 30. April 2020 vorbei ist, wird deine Tochter nicht in der Lage sein, ihr Erbe anzutreten: Sie würde versuchen, einen Output einer ungültigen Transaktion auszugeben.

Wie kann Qi die txid ädern?

Qi hat mehrere Möglichkeiten, die Transaktion zu ändern, ohne sie ungültig zu machen. Alle haben damit zu tun, dass auf die eine oder andere Art das Signatur Script verändert wird. Abbildung 4 zeigt drei Klassen von Transaktionsumformung.

10 04
Abbildung 4. Drei Klassen von Transaktions-Umformbarkeit
BIP66

BIP66 behebt die erste Klasse von Umformbarkeitsproblemen.

Die erste modifiziert das Signatur Container Format, was verändert, wie die Signatur im Signatur Script codiert wird. Man kann die Signatur auf ein paar verschiedene Weisen codieren, die alle gültig sind. Dieses Problem wurde bei einem Systemupgrade durch BIP66 behoben, was die Codierung von Signaturen in einer ganz bestimmten Art festschreibt. Der Fix wurde in Block 363724 aktiviert.

Die zweite Art, eine Transaktion umzuformen, ist mittels kryptografischer Tricks. Ich gehe hier nicht in die Details, aber die Signatur kann unabhängig von ihrem Containerformat auf ein paar Weisen verändert werden, ohne dass sie ungültig wird. Nur ein solcher Trick ist bekannt, aber wir können nicht ausschliessen, dass es weitere gibt.

Beim letzten Ansatz geht es darum, das Script Programm selbst zu ändern. Das kann man auf verschiedenen Wegen erledigen. Der in Bild Abbildung 4 dargestellte dupliziert (OP_DUP) zunächst das oberste Element auf dem Stack und entfernt (OP_DROP) anschliessend das duplizierte Element sofort wieder. Im Ergebnis ändert das nichts, und das ganze Programm läuft einwandfrei ab.

Die zweite und dritte Form von Transaktionsumformung werden durch die relay Policies ein wenig eingeschränkt. Das bedeutet, Nodes werden verlangen, dass Signaturen bestimmten Regeln unterliegen und dass sich keine Script Operatoren ausser dem Ablegen von Daten im Signatur Script befinden. Andernfalls würde der Node die Transaktion nicht relayen. Aber nichts hält einen Miner davon ab, umgeformte Transaktionen zu minen. Relay Policies wurden implementiert, um Transaktionsumformung zu erschweren, aber sie können sie nicht verhindern.

10.1.2. Unzureichende Signatur Verifikation

Wenn ein Transaktions Script signiert wird, hasht der Signatur Algorithmus die Transaktion auf eine bestimmte Weise.

Erinnere dich an [sign-transaction] und wie du alle Signatur Scripts vor dem Signieren bereinigt hast. Wenn du aber nur das tätest, dann würden alle Signaturen genau denselben Hash benutzen. Wenn die Transaktion zwei verschiedene Outputs ausgibt, die an dieselbe Adresse zahlen, könnte die Signatur von einem der Inputs in dem anderen Input wiederverwendet werden. Diese Eigenschaft könnte von einem Bösewicht ausgenutzt werden.

Warum benutzt man kein Dummy Byte?

Das Pubkey Script in das Signatur Script einzufügen scheint überflüssig. Es wäre einfacher, ein einzelnes Dummy Byte in das Signatur Script zu legen, um eine Wiederverwendung der Signatur auszuschliessen. Niemand weiss so richtig, weshalb das Pubkey Script dafür benutzt wird.

Um dieses Problem zu vermeiden, lässt Bitcoin jede Signatur sich an eine leicht veränderte Version der Transaktion binden, indem es das ausgegebene Pubkey Script in das Signatur Script des Inputs kopiert, der gerade signiert wird.

Zoomen wir ein bisschen in das hinein, was da vor sich geht. Nimm an, du willst eine Transaktion mit zwei Inputs signieren. Der erste Input wird signiert wie in Abbildung 5 dargestellt.

10 05
Abbildung 5. Signieren des ersten Inputs. Du bereitest es durch Kopieren des Pubkey Scripts in das Signatur Script vor.

Die Signatur Scripts aller Inputs sind leer, aber du kopierst das Pubkey Script des ausgegebenen Outputs und fügst es in das Signatur Script des ausgebenden Inputs ein. Dann erzeugst du die Signatur für den ersten Input und machst mit dem zweiten Input weiter (Abbildung 6).

10 06
Abbildung 6. Signieren des zweiten Inputs

Hier sind alle Signatur Scripts ausser dem zweiten leer. Das zweite Signatur Script wird mit dem Pubkey Script des ausgegebenen Outputs gefüllt. Dann wird die Signatur erstellt.

Indem man diese Übung für alle Inputs durchführt, stellt man sicher, dass Signaturen nicht für andere Inputs wiederverwendbar sind, auch wenn sie vom selben private Key signiert wurden. Aber das führt auch ein neues Problem ein: Signaturverifikation wird ineffizient.

Angenommen du willst die Signaturen der oben genannten Transaktion verifizieren. Dann musst du im Grunde für jeden Input dasselbe Vorgehen abarbeiten wie als die Transaktion signiert wurde: alle Signatur Scripts aus der Transaktion bereinigen und dann, eins nach dem anderen, die Pubkey Scripts in das Signatur Script des Inputs, den du verifizieren willst, einfügen. Und danach die Signatur für diesen Input verifizieren.

Das mag harmlos erscheinen, aber wenn die Anzahl Inputs zunimmt, wächst die Menge an Daten, die für jede Signatur gehasht werden müssen. Wenn du die Anzahl Inputs verdoppelst wirst du grob

  • Die Anzahl an Signaturen verdoppeln

  • Die Grösse der Transaktion verdoppeln

Warum 1 ms?

Die Zeit von 1 ms ist nur ein Beispiel. Die eigentliche Zeit zur Verifikation einer Transaktion variiert von Node zu Node.

Wenn die Zeit zur Verifikation der Transaktion mit zwei Inputs in Abbildung 7 1 ms beträgt, dann dauert es 4 ms um eine Transaktion mit vier Inputs zu verifizieren. Verdopple die Anzahl Inputs erneut, und du bekommst 16 ms. Eine Transaktion mit 1.024 Inputs würde über 4 Minuten brauchen!

10 07
Abbildung 7. Gesamtdauer zum Hashen während der Signaturverifikation. Die Zeit vervierfacht sich etwa, wenn sich die Anzahl Inputs verdoppelt.

Diese Schwäche kann ausgenutzt werden, indem eine grosse Transaktion mit einer Menge Inputs erzeugt wird. Alle Nodes, die verifizieren, werden minutenlang blockiert, wodurch sie während dieser Zeit nicht mehr in der Lage sind, andere Transaktionen und Blocks zu verifizieren. Das Bitcoin Netzwerk als Ganzes verlangsamt sich dadurch.

Es wäre viel besser, wenn die Transaktions-Verifikationszeit linear wachsen würde statt quadratisch.: die Zeit zur Verifikation einer Transaktion würde sich verdoppeln, wenn sich die Anzahl Inputs verdoppelt. Dann würde es nur ungefähr 512 ms dauern, die 1024 Inputs zu verifizieren, anstatt 4 Minuten.

10.1.3. Bandbreitenverschwendung

Wenn ein Full Node eine Transaktion an ein Lightweight Wallet sendet, schickt er die komplette Transaktion, die alle Signaturdaten enthält. Aber ein Lightweight Wallet kann die Signaturen nicht verifizieren, weil es die ausgegebenen Outputs nicht kennt.

Die Signatur Scripts machen einen erheblichen Teil der Transaktionsgrösse aus. Ein typisches Signatur Script, das einen p2pkh ausgibt, belegt 107 Bytes. Betrachten wir ein par verschiedene Transaktionen mit zwei Outputs, wie in Tabelle 1 gezeigt.

Tabelle 1. Durch Signatur Script Daten belegter Platz verschiedener typischer Transaktionen
Inputs Gesamte Signatur Script Grösse (Bytes) Tx Grösse (Bytes) Relativer Signatur Script Anteil

1

107

224

47%

2

214

373

57%

3

321

521

61%

8

856

1255

68%

u10 01

Wäre es nicht schön, wenn ein Full Node nicht die Signatur Script Daten an das Lightweight Wallet schicken müsste? Du würdest vermutlich über 50% an Datenvolumen einsparen. Es gibt nur ein Problem: diese Daten werden benötigt, um die txids zu berechnen. Wenn du das Senden von Signatur Scripts von Transaktionen überspringst, kann das Lightweight Wallet nicht mehr verifizieren, dass die Transaktion im Block enthalten ist, weil sie den Merkle Proof nicht verifizieren kann (Abbildung 8).

10 08
Abbildung 8. Ohne die Signatur Scripts könnte das Lightweight Wallet nicht verifizieren, dass sich die Transaktion im Block befindet.

Wir würden das wirklich gerne irgendwie lösen.

10.1.4. Script Upgrades sind schwer

Gelegentlich wollen wir die Script Sprache mit neuen Operationen erweitern. Zum Beispiel wurden OP_CHECKSEQUENCEVERIFY (OP_CSV) und OP_CHECKLOCKTIMEVERIFY (OP_CLTV) der Sprache 2015 and 2016 hinzugefügt. Schauen wir uns an, wie OP_CLTV eingeführt wurde.

Wir beginnen damit, was OP_ Codes sind. Sie sind nichts als ein einzelnes Byte. OP_EQUAL wird zum Beispiel durch den Hex Code 87 repräsentiert. Jeder Node weiss, dass er, wenn er Byte 87 im Script Programm sieht, die beiden obersten Elemente auf dem Stack vergleichen und das Ergebnis auf dem Stack ablegen muss. OP_CHECKMULTISIG ist auch nur ein einzelnes Byte, ae. Alle Operatoren werden durch verschiedene Bytes repräsentiert.

Als Bitcoin erfunden wurde, wurden mehrere NOP Operatoren spezifiziert, OP_NOP1OP_NOP10. Diese werden durch die Bytes b0b9 repräsentiert. Sie sind dafür gemacht, nichts zu tun. Der Name NOP kommt von No OPeration, was im Grunde bedeutet “Wenn diese Instruktion auftaucht, ignoriere sie und mach weiter.”

Diese NOPs können zur Erweiterung der Script Sprache verwendet werden. Der OP_CLTV Operator ist eigentlich OP_NOP2, oder Byte b1. OP_CLTV wurde durch Freigabe einer neuen Bitcoin Core Version eingeführt, die neu definiert, wie OP_NOP2 funktioniert. Aber es musste auf eine kompatible Art geschehen, damit wir nicht die Kompatibilität mit alten, nicht aktualisierten Nodes kaputtmachen.

Gehen wir zurück zum Beispiel von [absolute-time-locked-outputs], wo wir deiner Tochter im voraus ein Taschengeld gegeben haben, das sie ab dem 1. Mai einlösen konnte (siehe Abbildung 9).

10 09
Abbildung 9. Benutzung von OP_CLTV, um einen Output bis zum 1. Mai zu verriegeln.

Das Pubkey Script für diesen Output ist

<may 1 2019 00:00:00> OP_CHECKLOCKTIMEVERIFY OP_DROP
OP_DUP OP_HASH160 <PKHD> OP_EQUALVERIFY OP_CHECKSIG

So interpretiert ein neuer Node–der die neue Bedeutung des Byte b1 kennt–das Script. Er macht folgendes:

  1. Legt die Zeit <1 may 2019 00:00:00> auf den Stack.

  2. Prüft, dass die Lock Time der ausgebenden Transaktion mindestens den Wert hat, der oben auf dem Stack liegt, oder bricht sonst sofort ab.

  3. Nimmt den Zeitwert wieder vom Stack herunter.

  4. Macht mit der normalen Signatur Verifikation weiter.

Ein alter Node andererseits wird das Script wie folgt interpretieren:

<may 1 2019 00:00:00> OP_NOP2 OP_DROP
OP_DUP OP_HASH160 <PKHD> OP_EQUALVERIFY OP_CHECKSIG

Er wird

  1. Legt die Zeit <1 may 2019 00:00:00> auf den Stack.

  2. Nichts tun.

  3. Nimmt den Zeitwert wieder vom Stack herunter.

  4. Macht mit der normalen Signatur Verifikation weiter.

ALte Nodes behandeln OP_NOP2 wie bisher–indem sie nichts tun und weitermachen. Die wissen nichts von den neuen Regeln, die mit dem Byte b1 assoziiert sind.

Die alten und neuen Nodes werden sich gleich verhalten, wenn der OP_CLTV auf dem neuen Node gelingt. Aber wenn er auf dem neuen Node fehlschlägt, wird er das auf dem alten Node nicht tun, da "tu nichts" nie fehlschlägt. Die neuen Nodes schlagen häufiger fehl als die alten Nodes, weil die neuen Nodes strengeren Regeln folgen. Die alten Nodes beenden das Script immer erfolgreich, wenn die neuen Nodes das Script erfolgreich beenden. Dies wird als Soft Fork bezeichnet_ein System Upgrade, das nicht von allen Nodes verlangt wird. Wir sprechen mehr über Forks, System Upgrades und alternative Währungen, die von Bitcoins Blockchain abstammen, in [ch11].

Du fragst dich vielleicht, wozu die OP_DROP Instruktion da ist. OP_DROP nimmt das oberste Element vom Stack und wirft es weg. OP_CTLV ist so gemacht, dass es sich genau wie OP_NOP2 benimmt, wenn es erfolgreich ist. Wenn OP_CTLV ohne Rücksicht auf alte Nodes entworfen worden wäre, dann würde es vermutlich das oberste Element vom Stack nehmen. Aber weil wir an die anderen Nodes denken müssen, tut OP_CTLV dies nicht. Wir brauchen den zusätzlichen OP_DROP hinter OP_CTLV, um das oberste Element auf dem Stack loszuwerden.

Dies war ein Beispiel dafür, wie alte Script Operatoren so umfunktioniert werden können, dass sie etwas Eingeschränkteres tun, ohne das ganze Netzwerk zu stören.

Diese Methode für Script Upgrades wurde bis jetzt für zwei Operatoren verwendet:

Byte Alter Code Neuer Code Neue Bedeutung

b1

OP_NOP2

OP_CLTV

Verifiziere, dass die ausgebende Transaktion eine ausreichend hohe absolute Lock Time hat.

b2

OP_NOP3

OP_CSV

Verifiziere, dass die ausgebende Transaktion eine ausreichend hohe relative Lock Time hat.

Nur 10 OP_NOP Operatoren sind für Script Upgrades verfügbar, und solche Upgrades sind darauf beschränkt, im Erfolgsfalle genau das Verhalten von OP_NOP nachzubilden.

Früher oder später werden wir einen weiteren Script Upgrade Mechanismus benötigen, sowohl weil wir irgendwann keine OP_NOPs mehr haben als auch weil wir wollen, dass die neuen Script Operatoren sich anders benehmen als OP_NOP, wenn sie erfolgreich sind.

10.2. Lösungen

Eine Lösung für all diese Probleme wurde 2015 auf einer Konferenz präsentiert. Die Lösung war, die Signatur Scripts komplett aus den Transaktionen herauszunehmen.

Schauen wir uns nochmal die Anatomie einer normalen Transaktion an, wie in Abbildung 10 gezeigt.

10 10
Abbildung 10. Die txid wird aus der gesamten Transaktion berechnet, einschliesslich der Signatur Scripts.

Wenn wir das System so ändern könnten, dass die txid nicht das Signatur Script beinhaltet, würden wir alle bekannten Möglichkeiten von unbeabsichtigter Transaktionsumformung eliminieren. Unglücklicherweise würden wir damit auch alte Software inkompatibel machen, weil diese die txid auf die herkömmliche Art berechnet.

BIP141

Die von Segregated Witness definierten neuen Regeln sind spezifiziert in BIP141, “Segregated Witness (Consensus layer).”

SegWit löst dieses Problem und alle vorher genannten Probleme auf vorwärts- und rückwärtskompatible Weise:

  • Vorwärtskompatibel, weil Blocks, die von der neuen Software erzeugt wurden, mit der alten Software funktionieren.

  • Rückwärtskompatibel, weil Blocks, die durch die alte Software erzeugt wurden, auf der neuen funktionieren.

Im Kryptojargon heisst Witness, also Zeuge, im Grunde so viel wie Signatur. Etwas, das die Authentizität von irgendetwas bezeugt. Für eine Bitcoin Transaktion ist der Witness der Inhalt der Signatur Scripts, denn das ist das, was bezeugt, dass die Transaktion authentifiziert wurde. Segregated heisst abgetrennt, weil wir den Inhalt der Signatur Scripts von der Transaktion abtrennen und im Effekt die Signatur Scripts leer lassen, wie Abbildung 11 zeigt.

10 11
Abbildung 11. Eine SegWit Transaktion enthält keine Signaturdaten. Die Signaturen werden stattdessen angehängt. Die txid bindet sich nicht an die Signaturen.

Segregated Witness bedeutet also, der Inhalt der Signatur Scripts wurde aus der Transaktion entfernt und in eine externe Struktur namens Witness eingebracht.

Wir folgen ein paar SegWit Transaktionen, um zu sehen, wie diese verschiedene Teile des Bitcoin Systems tangieren. Aber zuerst tun wir ein wenig bitcoin in unser SegWit Wallet.

10.2.1. Segwit Adressen

Angenommen, dein Wallet benutzt SegWit und du verkaufst einen Laptop an Amy. Dein Wallet muss eine Adresse erzeugen, die du Amy geben kannst. So weit nichts Neues.

BIP173

Dieser BIP definiert das mit Checksum versehene Codierungsschema Bech32 und wie SegWit Adressen mit Hilfe von Bech32 zusammengesetzt und codiert werden.

Aber SegWit definiert einen neuen Adresstyp, der mittels Bech32 statt base58check codiert wird. Nimm an, dein Wallet erzeugt die folgende SegWit Adresse:

bc1qeqzjk7vume5wmrdgz5xyehh54cchdjag6jdmkj

Dieses Adressformat bietet im Vergleich zu den bereits geläufigen base58check Adressen mehrere Verbesserungen:

  • Alle Zeichen sind im gleichen case, also gross oder klein, was bedeutet

    • QR Codes können kleiner dargestellt werden.

    • Adressen lassen sich leichter vorlesen.

  • Die von Bech32 verwendete Checksumme stellt bis zu 4 Zeichenfehler mit 100% Wahrscheinlichkeit fest. Wenn es mehr Zeichenfehler gibt, beträgt die Wahrscheinlichkeit, das nicht festzustellen, weniger als eins zu einer Milliarde. Das ist eine erhebliche Verbesserung zu der 4 Byte Checksumme in base58check, die keinerlei Garantien bietet.

Deine SegWit Adresse besteht aus zwei Teilen. Die ersten beiden Zeichen, bc (kurz für bitcoin) sind der menschenlesbare Teil. Die 1 ist ein begrenzer zwischen dem menschenlesbaren Teil und dem Datenteil, der die eigentliche Information codiert, die Amy benuzten wird, um den Transaktionsoutput zu erzeugen.

  • Eine Version, 0 in diesem Falle.

  • Ein Witness Programm. In diesem Fall ist das Witness Programm ein PKH, c8052b79…3176cba8.

Wir klären ein bisschen später, was das Witness Programm ist. Stell es dir im Moment einfach als PKH vor. Die Version und das Witness Programm lassen sich aus der Adresse nicht direkt herausziehen, denn sie sind mittels bech32 codiert. Du gibst die Adresse bc1qeqzj…ag6jdmkj Amy, indem du ihr einen QR Code zeigst. Sie hat ein modernes Wallet, das dieses Adressformat versteht, also scannt sie deine Adresse und extrahiert Version und Witness Programm, wie Abbildung 12 illustriert.

10 12
Abbildung 12. Amy decodiert die SegWit Adresse, um die Witness Version und das Witness Programm zu erhalten.
Checksumme

Ich gehe nicht in Details auf die Checksumme ein. Dafür ermuntere ich die Leser, sich BIP173 anzuschauen.

Dies geschieht in mehreren Schritten:

  1. Der menschenlesbare Teil und der Datenteil werden getrennt.

  2. Der Datenteil der Adresse wird mit Hilfe der bech32 Nachschlagetabelle Zeichen für Zeichen in Zahlen konvertiert. Die erste dieser Zahlen ist die Witness Version, 0. Die folgenden Zahlen, bis auf die letzten sechs, sind das Witness Programm. Die letzten sechs Zahlen sind die Checksumme.

  3. Die Checksumme wird verifiziert; in diesem Beispiel werden keine Fehler festgestellt.

  4. Das Witness Programm wird neu geschrieben, indem jede zahl als 5 Bit Zahl geschrieen wird.

  5. Die Bits werden in Gruppen von 8 Bits neu angeordnet. Jede solche Gruppe repräsentiert ein Byte des Witness Programms.

  6. Amy extrahiert das Witness Programm als c8052b7…3176cba8.

Amy erzeugt eine Transaktion mit einer neuen Art von Pubkey Script, das du noch nicht gewöhnt bist (Abbildung 13).

10 13
Abbildung 13. Amy schickt 0,1 BTC an deine SegWit Adresse. Das Pubkey Script enthält keine Script Operatoren, nur Daten.

Sie sendet diese Transaktion an das Bitcoin Netzwerk. Das Netzwerk wird die Transaktion akzeptieren, weil sie auf die herkömmliche Weise korrekt signiert ist. Irgendwann wird sie in einen Block eingebaut. Dein Wallet wird bestätigen, dass du das Geld bekommen hast, und du gibst Amy den Laptop.

10.2.2. Ausgeben des Segwit outputs

Jetzt wo du das Geld bekommen hast, möchtest du es für eine gebrauchte Popcorn Maschine ausgeben. Sie kostet nur 0,09 BTC. Es ist ein Schnäppchen! Nehmen wir an, der Besitzer der Popcorn Maschine hat die SegWit Adresse bc1qlk34…ul0qwrqp.

Deine Transaktion schickt das Geld an die SegWit Adresse des Besitzers der Popcorn Maschine und zahlt eine 0,01 BTC Transaktionsgebühr (Abbildung 14). Der Input hat ein leeres Signatur Script; die Signaturdaten sind stattdessen als Witness Feld im angehängten Witness eingetragen.

10 14
Abbildung 14. Du erzeugst und sendest eine Zahlung an den Popcornmaschinenbesitzer.

Wären mehrere Inputs in dieser Transaktion gewesen, gäbe es mehrere Witness Felder im Witness, eines für jeden Input. Du kannst SegWit Inputs und herkömmliche Inputs mischen, in diesem Fall sind die Witness Felder für die herkömmlichen Inputs leer, weil deren Signaturen im jeweiligen Signatur Script liegen, so wie sie das immer taten.

10.2.3. Verifizieren der SegWit Transaktion

Du hast deine Transaktion für die Popcorn Maschine an das Bitcoin Peer-to-Peer Netzwerk zur Verarbeitung geschickt. Schauen wir, wie ein aktueller Full Node diese Transaktion verifiziert, bevor er sie an andere Nodes weiterleitet (Abbildung 15). Weil er die letzte und tollste Softwareversion benutzt, weiss er, wie man mit SegWit Transaktionen umgehen muss.

10 15
Abbildung 15. Ein Full Node verifiziert den Witness deiner Transaktion, Das Muster 00 gefolgt von genau 20 Bytes erfährt eine Sonderbehandlung.
Kennst du noch p2sh

Ein SegWit Output wird durch Mustererkennung festgestellt, genau so wie ein p2sh Output in [ch05].

Der Full Node, der SegWit kennt, sucht nach einem Muster im Pubkey Script, das mit einem einzelnen Versionsbyte beginnt und von einem 2- bis 40-Byte Witness Programm gefolgt wird. In diesem Fall passt das Muster, was bedeutet, es ist ein SegWit Output.

Der nächste Schritt für den Full Node ist, zu verstehen, welche Art von SegWit Output es ist. Zum Zeitpunkt des Schreibens gibt es nur eine Version von SegWit Output: Version 00. Diese Version kommt in zwei verschiedenen Geschmacksrichtungen:

  • Pay-to-witness-public-key-hash (p2wpkh), gekennzeichnet durch ein 20 Byte Witness Programm, wie in diesem Beispiel

  • Pay-to-witness-script-hash (p2wsh), gekennzeichnet durch ein 32 Byte Witness Programm. p2wsh wird später in diesem Kapitel erklärt.

Wieso “Witness Programm”?

Es wird als Witness Programm bezeichnet, da es als Programm einer seltsamen Sprache angesehen werden kann. In der Version "00" ist das Witness Programm ein einzelner Operator, dessen Länge sein Verhalten definiert.

In diesem Fall haben wir das Versionsbyte 00, gefolgt von genau 20 Bytes, was bedeutet, dies ist eine p2wpkh Zahlung. Wenn dem Node das Versionsbyte unbekannt ist, akzeptiert er diesen Input sofort, ohne weitere Bearbeitung. Diese Akzeptanz unbekannter Versionen wird bei späteren, vorwärtskompatiblen Upgrades der Script Sprache nützlich sein. Alle SegWit Nodes erkennen Version 00.

Das p2wpkh ist der einfachste der beiden Typen, weil es ähnlich dem bekannten p2pkh ist. Schauen wir uns an, wie die beiden funktionieren:

  • p2pkh—Das Pubkey Script enthält das eigentliche Script, welches die Signatur im Signatur Script überprüft.

  • p2wpkh—Das eigentliche Script ist eine vordefinierte Schablone, ein Template, und das Witness Programm ist der PKH, der in die Schablone eingetragen wird. Die Signatur und der public Key werden dem Witness entnommen.

Am Ende ist es augenscheinlich genau dasselbe Programm, das für beide Typen abläuft. Der Unterschied liegt darin, woher die Komponenten kommen. Aber es gibt andere Unterschiede zwischen SegWit Scripts und herkömmlichen Scripts–zum Beispiel hat sich die Bedeutung von OP_CHECKSIG geändert, wie wir in Abschnitt 10.2.6 sehen.

Warum überhaupt p2wpkh benutzen, wenn wir sowieso dasselbe Programm laufen lassen wie bei p2pkh? Denk daran, dass wir Transaction Malleability reparieren wollen. Wir tun dies, indem wir die Signaturdaten aus den Transaktion Inputs herausnehmen, sodass niemand die txid durch subtile Änderungen am Signatur Script verändern kann.

Der Full Node hat diese Transaktion verifiziert und schickt sie an seine Peers. Es gibt nur ein Problem: einer der Peers hat keine Ahnung, was SegWit ist. Es ist ein alter Node, der schon eine ganze Weile nicht aktualisiert wurde.

“Verifizieren” auf alten Nodes

Ein alter Node hat gerade deine Transaktion bekommen, und möchte sie verifizieren. Alte Nodes wissen nichts von SegWit, oder dass Witnesses an Transaktionen dranhängen. Der alte Node lädt die Transaktion so wie immer, also ohne den Witness-Anhang. Abbildung 16 zeigt, was der Node sieht.

10 16
Abbildung 16. Ein alter Node sieht nur zwei Datenobjekte im Pubkey Script und ein leeres Signatur Script.

Weil der Node es nicht besser weiss, erzeugt er das Script Programm indem er das leere Signatur Script nimmt und das Pubkey Script daranhängt. Das resultierende Programm sieht so aus:

00 c8052b799cde68ed8da8150c4cdef4ae3176cba8

Der Node startet dieses Programm. Das Programm legt zwei Datenobjekte auf den Stack–zuerst 00 und dann c805…cba8. Wenn das fertig ist, ist nichts mehr zu tun als zu prüfen, ob das oberste Element des Stacks, c805…cba8, true ist. Bitcoin definiert alles, was nicht null ist, als true, also läuft dieses Script durch und die Transaktion ist autorisiert.

Das wirkt nicht besonders sicher. Es ist bekannt als anyone-can-spend, was bedeutet, dass jeder eine Transaktion erzeugen kann, die den Output ausgibt. Es bedarf keiner Signatur. Man muss nur einen Input mit einem leeren Signatur Script erzeugen, um sich das Geld zu holen.

Nonstandard Transaktionen

Ein Node, der den ausgebenden Script Typ nicht kennt, leitet die Transaktion normalerweise nicht weiter. Sie wird als nicht standardkonforme Transaktion betrachtet. Diese Relay Policy verringert das Risiko, dass eine Transaktion, die den SegWit Output als anyone-can-spend verwendet, in einem Block landet.

In [ch11] besprechen wir, auf welche Weise Upgrades wie SegWit sicher ausgerollt werden können. Für den Moment kannst du annehmen, dass 95% der Hashrate (Miner) mit SegWit laufen. Wenn eine Transaktion deinen Output als anyone-can-spend verwendet und ein non-SegWit Miner sie in einen Block einbaut, dann wird dieser Block von 95% der Hashrate abgelehnt und daher aus der stärksten Chain ausgeschlossen. Der Miner verliert seinen Block Reward.

10.2.4. Einbindung der SegWit Transaktion in einen Block

Deine SegWit Transaktion hat sich über das Netzwerk verbreitet und alle Nodes haben sie auf dem Weg verifiziert. Jetzt will ein Miner die Transaktion in einen neuen Block einfügen. Angenommen, der Miner benutzt moderne Software und weiss daher von SegWit. Schauen wir, wie die Transaktion in den Block eingetragen wird (Abbildung 17).

10 17
Abbildung 17. Deine SegWit Transaktion wird in einen Block integriert. Der Block bindet sich an den Witness, indem er das Witness Commitment in einen Output der Coinbase Transaktion legt.

Der Block ist wie zuvor gebaut, aber mit einem wichtigen Unterschied. Eine neue Blockregel wird mit SegWit eingeführt: wenn es SegWit Transaktionen in dem Block gibt, dann muss die Coinbase Transaktion einen Output mit einem Witness Commitment enthalten. Dieses Witness Commitment ist der kombinierte Hash vom Witness Root Hash und einem Reservierten Witness Wert. Der Witness Root Hash ist der Merkle Root der Witness txids (wtxids) aller Transaktionen in dem Block. Die wtxid ist der Hash der Transaktion einschliesslich Witness, wenn es einen gibt. Es gibt eine Ausnahme für die Coinbase, deren wtxid immer als 32 Nullbytes definiert ist. Der reservierte Witness Wert ist für zukünftige Systemerweiterungen vorgesehen.

Das Witness Commitment wird in einen OP_RETURN Output geschrieben (Abbildung 18).

10 18
Abbildung 18. Der Witness der Coinbase Transaktion enthält den reservierten Witness Wert, und ein OP_RETURN Output enthält das Witness Commitment.

Der reservierte Witness Wert kann ein beliebiger Wert sein. Aber ein Full Node, der den Block verifiziert, muss eine Methode haben, diesen Wert herauszufinden. Wenn der Node den reservierten Witness Wert nicht kennen würde, dann könnte er das Witness Commitment nicht rekonstruieren, um es mit dem OP_RETURN Output des Witness Commitments zu vergleichen. Der Witness der Coinbase Transaktion enthält den reservierten Witness Wert, damit Full Nodes das Witness Commitment verifizieren können.

Alte Nodes verifizieren den Block

Der Block in Abbildung 17 ist für neue, SegWit-fähige Full Nodes gültig, also muss er auch für alte Nodes gültig sein, die nicht wissen, was SegWit ist. Ein alter Node wird keine Witnesses von seinen Peers laden, weil er nicht weiss, dass es so etwas gibt (Abbildung 19).

10 19
Abbildung 19. Ein alter Node verifiziert den Block mit deiner Transaktion. Er wird weder die Signatur noch das Witness Commitment verifizieren.

Dieser Node macht das, was er immer gemacht hat–die Scripts der Transaktion ausführen, die genau so aussehen wie anyone-can-spend Outputs. Das ist in Ordnung, mach weiter. Wenn einige der Transaktionen in dem Block non-SegWit sind, werden diese Transaktionen vollständig verifiziert.

Wir haben jetzt den Kreis mit deiner Transaktion an den Besitzer der Popcorn Maschine geschlossen, der die Maschine an dich übergibt.

10.2.5. Pay-to-witness-script-hash

Erinnerst du dich daran, wie wir p2sh in [pay-to-script-hash] eingeführt haben? p2sh schiebt den Pubkey Script Teil des Programms in den ausgebenden Output. Schauen wir uns nochmal das Wohlfahrts-Wallet an, das John, Ellen und Faiza eingerichtet haben (Abbildung 20).

10 20
Abbildung 20. John und Faiza verbrauchen einen Output aus ihrem Multisig Wallet.

Ihre Idee war, dass der Zahler–in diesem Falle der Spender–keine höhere Gebühr für ein grosses, komplexes Script zahlen sollte. Stattdessen sollte der Empfänger, der dieses extravagante Modell benutzen will, für die Komplexität bezahlen.

Mit SegWit kannst du ungefähr dasselbe mittels pay-to-witness-script-hash erledigen, was die SegWit Version von p2sh ist. Ist die Namensvergabe in Bitcoin nicht fantastisch?

Angenommen, John, Ellen und Faiza benutzen SegWit für ihr Wohlfahrts-Wallet, und dass der vorherige Popcornmaschinenbesitzer das Geld, das er für die Popcornmaschine bekommen hat, der Wohlfahrt spenden möchte.

John, Ellen und Faiza müssen dem Popcorntypen eine p2wsh Adresse geben. Ihr Witness Script ist dasselbe wie das p2sh Redeem Script war als sie p2sh verwendet haben (Abbildung 21).

10 21
Abbildung 21. Das Witness Script wird zu einem Witness Script Hash gehasht.

Sie verwenden diesen Witness Script Hash zur Erzeugung einer p2wsh Adresse auf die gleiche Weise, wie du deine p2wpkh Adresse generiert hast. Sie codieren

00 983b977f86b9bce124692e68904935f5e562c88226befb8575b4a51e29db9062

mittels bech32 und bekommen die p2wsh Adresse:

bc1qnqaewluxhx7wzfrf9e5fqjf47hjk9jyzy6l0hpt4kjj3u2wmjp3qr3lft8

Diese Adresse wird dem Popcorntypen übergeben, der eine Transaktion erzeugt und sendet, so wie sie in Abbildung 22 steht.

10 22
Abbildung 22. Der Popcorntyp schickt das Geld an die p2wsh Adresse der Wohlfahrt.

An der Transaktion hängt der Witness dran, genau wie bei deiner Transaktion mit dem Popcorn Typen. Der einzige Unterschied zwischen deiner Transaktion und der des Popcorn Typen ist, dass deren Outputs eine unterschiedliche Witness Programm Länge haben. Deine Transaktion hatte ein 20 Byte Witness Programm, weil es der SHA256+RIPEMD160 Hash eines public Keys war, und die Transaktion des Popcorn Typen hat ein 32 Byte Witness Programm, weil es der SHA256 eines Witness Scripts ist.

Diese Transaktion wird verifiziert und eventuell in einen Block integriert.

Ausgeben der p2wsh Transaktion

Angenommen, John und Faiza wollen die 0,08 BTC, die sie vom Popcorntypen bekommen haben, ausgeben, indem sie sie an eine Obdachlosen-Unterkunft der Wohlfahrt schicken. Die Unterkunft hat zufälligerweise auch schon eine p2wsh Adresse. John und Faiza arbeiten zusammen, um die neue Transaktion zu erzeugen, die Abbildung 23 zeigt.

10 23
Abbildung 23. Die Wohlfahrt bezahlt 0,07 BTC an die Adresse der Unterkunft. Der Witness sind die Signaturen, gefolgt von einem Datenobjekt, das das eigentliche Witness Script enthält.

Beachte, dass im Signatur Script nichts steht. Als wir p2sh in [pay-to-script-hash] benutzt haben, wurde das Signatur Script wirklich gross, weil es zwei Signaturen und das Redeem Script enthielt, welches wiederum drei public Keys enthielt. Bei SegWit werden stattdessen alle Daten im Witness zusammengefasst.

Verifizieren des p2wsh Inputs

Ein Full Node, der die Transaktion verifizieren will, muss den Typ des ausgegebenen Outputs feststellen (Abbildung 24). Er schaut sich den Output an, findet das Muster <version byte> <2 to 40 bytes data>, und schliesst daraus, dass dies ein SegWit Output ist. Als nächstes muss er den Wert des Versionsbytes prüfen.

Das Versionsbyte ist 00. Ein Version 00 SegWit Output kann zwei verschiedene Längen des Witness Programms haben, 20 oder 32 Bytes. Wir haben den ersten Fall im vorangegangenen Abschnitt über p2wpkh betrachtet. Das Witness Programm in diesem Beispiel ist 32 Bytes, was bedeutet, es ist ein p2wsh Output.

10 24
Abbildung 24. Vorbereitung zur Verifikation des p2wsh Inputs

Für das Ausgeben eines p2wsh Outputs gelten besondere Regeln. Zuerst werden die Datenobjekte im Witness Feld des ausgebenden Inputs auf den Programm Stack gelegt. Dann wird das oberste Stack-Element, das Witness Script, anhand des Witness Programms im Output geprüft (Abbildung 25).

10 25
Abbildung 25. Verifizieren des Witness einer p2wsh Zahlung

Das Witness Script wird gehasht und mit dem Witness Programm im ausgegebenen Output verglichen, bevor es mit den drei Elementen auf dem Stack ausgeführt wird. Dieser Prozess ist ähnlich wie der der Verifikation einer p2sh Zahlung.

Miner und Blockverifizierer behandeln alle SegWit Transaktionen auf dieselbe Art, es gibt also keinen Unterschied darin, wie eine Transaktion in einen Block integriert wird gegenüber p2wpkh Transaktionen.

10.2.6. Neues Hashverfahren für Signaturen.

BIP143

Diese Lösung wird in BIP143, “Transaction Signature Verification for Version 0 Witness Program,” spezifiziert.

Ein Problem, das mit SegWit gelöst wird, ist das ineffiziente Hashing von Signaturen. Wie in Abschnitt 10.1.2 erklärt, führt eine Verdopplung der Inputs zu einer runden Vervierfachung der Verifikationszeit der Transaktion. Das liegt daran, dass man

  • Die Anzahl an Signaturen verdoppeln

  • Die Transaktionsgrösse verdoppelt

Dieser Algorithmus ist vereinfacht

In Wirklichkeit werden drei verschiedene Zwischenhashes erzeugt: einer für alle Outpoints, einer für alle Sequenznummern und einer für alle Outputs. Der Effekt ist aber derselbe. Lies BIP143 für Näheres.

Wenn du die Anzahl berechneter Hashes und die Datenmenge verdoppelst, die jeder Hash verarbeiten muss, vervierfacht man effektiv die Gesamtzeit, die für das Hashen gebraucht wird.

Die Lösung ist, die Signaturen schrittweise zu machen. Nimm an, du willst alle vier Inputs einer Transaktion signieren, wie in Abbildung 26 gezeigt.

10 26
Abbildung 26. Hashen wird in zwei Schritten erledigt. Der Zwischenhash wird für jeden Input wiederverwendet.

Zuerst generierst du einen Zwischenhash der kompletten Transaktion. Wenn die Transaktion non-SegWit Inputs enthält, werden diese Signatur Scripts vor dem Hashen bereinigt. Der Zwischenhash bindet sich an alle Inputs und Outputs dieser Transaktion. Dann fügst du für jeden Input den Zwischenhash zu bestimmten Input-spezifischen Daten hinzu:

  • Spent Outpoint—Die txid und der Index des Outputs, den dieser Input ausgibt

  • Spent Script—Das Witness Script oder p2wpkh Script, das zu dem ausgegebenen Output gehört

  • Spent Amount—Der Wert an BTC des ausgegebenen Outputs

Altes Hashing
u10 02

Der Grossteil der Transaktion wird nur einmal gehasht, um einen Zwischenhash zu erzeugen. Das reduziert den für das Hashen benötigten Aufwand drastisch. Wenn die Anzahl Inputs sich verdoppelt, verdoppelt sich lediglich der benötigte Aufwand für das Hashen. Das lässt den den Aufwand des Hash-Algorithmus linear mit der Anzahl Inputs wachsen anstatt quadratisch. Die Zeit, eine Transaktion mit 1.024 Inputs zu verifizieren, wie es in Abbildung 7 besprochen wurde, wird von 262.144 ms auf 512 ms verringert.

Die Signatur bindet sich an den Betrag

Warum nehmen wir den ausgegebenen Betrag mit dazu? Das haben wir im alten Signatur-Hashverfahren nicht getan. Das hat nichts mit der Hash-Effizienz zu tun, sondern behebt ein weiteres Problem, mit dem offline Wallets und einige Lightweight Wallets konfrontiert sind.

Hardware Wallets

Ein Hardware Wallet ist ein elektronisches Gerät, das zum gesicherten Aufheben von private Keys entworfen wurde. Unsignierte Transaktionen werden zur Signatur an das Gerät geschickt. Das Gerät benötigt normalerweise einen PIN Code zum Signieren.

Ein offline Wallet–zum Beispiel ein Hardware Wallet–kann nicht wissen, wie viel Geld ausgegeben wird. Wenn das offline Wallet eine Transaktion signieren soll, kann es dem Benutzer die Gebührenhöhe der Transaktion nicht anzeigen, da es die Werte der Outputs, die die Transaktion ausgibt, nicht sehen kann (Abbildung 27). Es hat keinen Zugang zur Blockchain.

10 27
Abbildung 27. Ein offline Wallet kann die Transaktionsgebühr nicht kennen.

Das gilt sowohl für SegWit als auch für non-SegWit Transaktionen. Da sich bei SegWit Transaktionen die Signaturen aber an die ausgegebenen Beträge binden, muss das Wallet die Beträge von irgendwoher bekommen, um signieren zu können. Angenommen, die Inputbeträge werden dem offline Wallet irgendwie übermittelt, zusammen mit der zu signierenden Transaktion. Dann kann das Wallet die Transaktion mit Hilfe dieser Beträge signieren, und sogar dem Benutzer anzeigen, welche Fee bezahlt wird, bevor es signiert.

Wenn das offline Wallet den falschen Betrag übermittelt bekommt, kann es das nicht feststellen. Es kann ja die Inputwerte nicht überprüfen. Aber weil die Signaturen sich jetzt an die Beträge binden, wäre dann die Transaktion ungültig. Denn ein verifizierender Node kennt die korrekten Beträge und benutzt diese beim Verifizieren der Signaturen. Der Signaturcheck wird scheitern. Der neue Signaturhashing-Algorithmus macht es also unmöglich, ein Wallet dazu zu bringen, eine gültige Transaktion mit einer Gebühr zu signieren, die der Benutzer nicht wollte.

10.2.7. Bandbreitenersparnisse

SegWit entfernt die Signaturdaten aus der Transaktion, sodass immer dann, wenn ein Lightweight Wallet eine Transaktion von einem Full Node anfordert, der Full Node die Transaktion ohne die Witness Daten schicken kann. Das bedeutet, pro Transaktion wird weniger Datenvolumen verbraucht. Diese Tatsache kann verwendet werden, um entweder

  • Behalte die Grösse des Bloom Filter bei und erhalte eine Einsparung im Datenvolumen von etwa 50%.

  • Die Privacy zu verbessern, indem die Grösse des Bloom Filters verringert wird, um mehr Fehltreffer zu erzeugen, ohne mehr Datenvolumen zu verbrauchen

10.2.8. Upgradebares Script

Das Versionsbyte wird für künftige Scriptsprachen-Upgrades benutzt. Vor SegWit mussten wir OP_NOPs benutzen, um der Sprache neue Features hinzuzufügen–zum Beispiel OP_CSV. Das war aus folgenden Gründen nicht optimal:

  • Irgendwann haben wir keine OP_NOPs mehr—es gibt nur noch acht.

  • Die OP_NOPs können nicht beliebig umdefiniert werden; sie müssen sich immer noch so benehmen wie OP_NOPs, wenn das neue Verhalten erfolgreich ist.

Das Versionsbyte erlaubt viel leistungsfähigere zukünftige Upgrades. Wir können alles machen, von leichten Modifikationen bestimmter Operatoren bis zur Implementation vollständig neuer Sprachen.

10.3. Wallet Kompatibilität

Die meisten alten Wallet werden das Senden von bitcoin an eine SegWit Adresse nicht unterstützen. Sie erlauben normalerweise nur p2pkh und p2sh Adressen. Daher haben die SegWit Entwickler zwei Wege geschaffen, die SegWit Verifikation anstelle der herkömmlichen Verifikation auszulösen: p2wsh eingebettet in p2sh und p2wsh eingebettet in p2wpkh.

Angenommen, du hast ein SegWit Wallet und willst deine Popcornmaschine an deinen Nachbarn Nina verkaufen. Aber Nina hat kein SegWit-fähiges Wallet. Sie kann nur an normale Adressen zahlen, wie p2pkh und p2sh. Du kannst aber eine p2sh Adresse machen, an die Nina zahlen kann (Abbildung 28).

10 28
Abbildung 28. Nina schickt 0,1 BTC an dein SegWit Wallet mit Hilfe einer in p2sh eingebetteten p2wpkh Adresse.

Nina bezahlt an 3KsJCgA6…k2G6C1Be, was eine klassische p2sh Adresse ist, die den Hash des Redeem Scripts 00 bb4d4977…75ff02d1 enthält. Dieses Redeem Script ist ein Versionsbyte 00, gefolgt von einem 20 Byte Witness Programm. Es entspricht damit dem Muster für p2wpkh, das wir vorher besprochen haben. Ninas Wallet weiss davon nichts. Es sieht nur eine p2sh Adresse und führt eine Zahlung an diesen Script Hash aus.

Später, wenn du deinen Output ausgeben willst, erzeugst du eine Transaktion wie die in Abbildung 29.

10 29
Abbildung 29. Du gibst das von Nina erhaltene Geld aus, indem du das Versionsbyte und Witness Programm als Redeem Script in das Signatur Script deines Inputs einträgst

Du generierst einen Witness, so wie du es mit einem normalen p2wpkh Input tun würdest, aber du legst das Redeem Script als einzelnes Datenobjekt in das Signatur Script. Das Redeem Script ist zufällig ein Versionsbyte 00 gefolgt von deinem 20 Byte PKH. Mit diesem Signatur Script können alte Nodes verifizieren, das der Script Hash im ausgegebenen Output zu dem Hash des Redeem Scripts im Signatur Script passt. Neue Nodes erkennen, dass das Redeem Script ein Versionsbyte und ein Witness Programm ist, und verifizieren den Witness entsprechend.

Diese Art der Einbettung von SegWit Zahlungen in p2sh Zahlungen kann auf ähnliche Weise auch für p2wsh Zahlungen benutzt werden: ein p2wsh eingebettet in p2sh.

10.4. Zusammenfassung der Zahlungsarten

Wir haben mehrere Zahlungsarten besprochen. Die Abbildungen Abbildung 30Abbildung 35 fassen die Häufigsten noch einmal zusammen.

10 30
Abbildung 30. p2pkh: Adressformat 1<some base58 characters>
10 31
Abbildung 31. p2sh: Adressformat 3<some base58 characters>
10 32
Abbildung 32. p2wpkh: Adressformat bc1q<38 base32 characters>
10 33
Abbildung 33. p2wsh: Adressformat bc1q<58 base32 characters>
10 34
Abbildung 34. p2wpkh eingebettet in p2sh: Adressformat 3<some base58 characters>
10 35
Abbildung 35. p2wsh eingebettet in p2sh: Adressformat 3<some base58 characters>

10.5. Block Limits

Bitcoin Blocks sind auf 1.000.000 Byte und 20.000 Signaturoperationen begrenzt.

10.5.1. Blockgrössen Limit

Im Jahr 2010 wurde die Bitcoin Software auf ein Blockgrössenlimit von 1.000.000 Bytes erweitert. Es ist nicht vollkommen klar weshalb dies geschah, aber die meisten nehmen an, dass die Begrenzung eingeführt wurde, um den Effekt bestimmter Denial-of-Service (DoS) Attacken zu verringern. DoS Attacken zielen darauf ab, Bitcoin Nodes zu verlangsamen oder abstürzen zu lassen, sodass das Netzwerk nicht ordentlich funktionieren kann.

Ein Weg, mit dem Netzwerk herumzupfuschen ist, einen sehr grossen Block zu erzeugen, der schon bei einer guten Internetverbindung 10 Sekunden zum Herunterladen braucht. Das mag schnell genug erscheinen, aber den Block an fünf Peers zu schicken würde 50 Sekunden dauern. Das führt dazu, dass sich der Block sehr langsam über das Peer-to-Peer Netzwerk verbreitet, was das Risiko eines unabsichtlichen Chain Splits vergrössert. Unabsichtliche Splits lösen sich im Laufe der Zeit von selbst, wie in [draw-lucky-numbers] gezeigt, aber die Sicherheit von Bitcoin verringert sich während solcher Splits.

Ein weiteres potentielles Problem mit grossen Blocks, das Angreifer ausnutzen könnten, ist, dass Leute mit schlechter Internetverbindung völlig aussen vor bleiben, weil sie mit dem Netzwerk nicht mithalten können oder nicht das benötigte Mindestmass an Rechenleistung, RAM oder Massenspeicher zum Betrieb eines Full Nodes haben. Diese Leute werden auf Systeme umschwenken müssen, die weniger Sicherheit bieten, wie Lightweight Wallets, was die Sicherheit für das gesamte Netzwerk verringert.

Egal weshalb, dieses Limit ist gesetzt.

10.5.2. Signatur-Operationslimit

Die Begrenzung der Signaturoperationen wurde eingeführt, weil Signaturverifikationen relativ langsam sind, besonders in non-SegWit Transaktionen. Ein Angreifer könnte eine Transaktion mit einer ungeheuren Menge von Signaturen vollstopfen, was die verifizierenden Nodes dann für eine lange Zeit beschäftigt halten würde. Das Limit von 20.000 solcher Operationen pro Block wurde mehr oder weniger willkürlich getroffen, um eine solche Attacke zu verhindern.

10.5.3. Vergrössern der Limits

Die Entfernung oder Vergrösserung solcher Limits benötigt eine Hard Fork. Eine Hard Fork ist eine Regeländerung, die zu Meinungsverschiedenheiten zwischen alten und neuen Nodes darüber führt, was die stärkste Chain ist. Wir betrachten Forks und Upgrades in [ch11]. Für den Moment, lass uns annehmen, dass neue Nodes beschliessen, dass 8.000.000 Bytes pro Block OK sind. Wenn ein Miner einen Block veröffentlicht, der grösser als 1.000.000 Byte ist, dann akzeptieren die neuen Nodes diesen, aber die alten Nodes tun dies nicht. Ein permanenter Chain Split würde passieren, und wir hätten im Effekt zwei Kryptowährungen.

SegWit bietet eine Gelegenheit, die Limits ohne eine Hard Fork zu erhöhen.

Erhöhen des Blockgrössenlimits

Die alte Regel von 1.000.000 Bytes bleibt, damit alte Nodes wie gewohnt weiterarbeiten können. Neue Nodes zählen die Blockgrösse anders, aber auf kompatible Art. Witness Bytes werden mit einem “Rabatt” gegenüber den anderen Bytes, wie Block Header oder Transaktion Outputs, gezählt. Eine neue Messgrösse, das Blockgewicht oder Block Weight, wird eingeführt. Das maximale Blockgewicht ist 4.000.000 Gewichtseinheiten oder Weight Units (WU; Abbildung 36).

10 36
Abbildung 36. Witness Bytes und nicht-Witness Bytes werden unterschiedlich gezählt. Witness Bytes tragen weniger zum Blockgewicht bei und überhaupt nicht zur bisherigen Blockgrösse, der Basis-Blockgrösse.

Nennen wir den Block ohne die Witnesses den Basisblock oder Base Block:

  • 1 Byte Base Block Daten zählt als 4 WU.

  • 1 Byte Witness Daten zählt als 1 WU.

Der Effekt ist, dass das alte 1.000.000 Byte Block Limit bleibt, weil die neuen und die alten Regeln bezüglich des Basis Blocks gleich sind. Aber je mehr SegWit benutzt wird, desto mehr Daten können aus dem Basis Block in die Witnesses verschoben werden, was eine grössere Gesamtblockgrösse erlaubt.

Angenommen die Witnesses in einem Block machen das Verhältnis stem\:[r] der Daten in einem Block aus. Das maximale Blockgewicht ist 4.000.000 und die gesamte Blockgrösse stem\:[T] ergibt sich aus:

\[4(1-r)T+rT \leq 4*10^{6} \\ (4-3r)T \leq 4*10^{6} \\ T \leq \frac {4*10^{6}} {4-3r}\]

Einsetzen von Werten für \(r\) in diese Formel ergibt verschiedene maximale Gesamtblockgrössen, wie Tabelle 2 zeigt.

Tabelle 2. Maximale Blockgrössen für verschiedene Verhältnisse von Witness Daten
\(r\) (Witness Bytes/Gesamt Bytes) Max Gesamtblockgrösse (Bytes)

0

1.000.000

0,1

1.081.081

0,3

1.290.323

0,5

1.600.000

0,6

1.818.182

0,7

2.105.263

0,8

2.500.000

Wenn die relative Witness Datenmenge im Block zunimmt, können wir mehr Transaktionen hineinstopfen. Der Effekt ist eine echte Zunahme der Blockgrösse.

Der Witness Rabatt wurde aus verschiedenen Gründen implementiert:

  • Das Signatur Script und die Witnesses landen nicht im UTXO Set. Daten, die in das UTXO Set eingehen, haben höhere Kosten, weil das UTXO Set zur schnellen Verifikation der Transaktionen vorzugsweise im RAM gespeichert wird.

  • Es gibt Wallet Entwicklern, Exchanges und Smart Contract Entwicklern einen höheren Anreiz, weniger Outputs zu erzeugen, was die Grösse des UTXO Sets verringert. Zum Beispiel könnte eine Exchange wählen, ihre vielen Outputs zu wenigen Outputs zu konsolidieren.

  • Die Witnesses brauchen nicht an Lightweight Wallets geschickt zu werden.

Vergrössern der Grenze für Signaturoperationen

Weil wir die Blockgrösse mit SegWit vergrössern, müssen wir auch die Anzahl erlaubter Signaturoperationen erhöhen; mehr Transaktionsdaten pro Block sollte implizieren, dass wir auch mehr Signaturoperationen erlauben müssen. Wir können das Limit auf dieselbe Weise erhöhen, wie wir das Blockgrössenlimit erhöht haben.

Wir erhöhen die Anzahl erlaubter Signaturoperationen von 20.000 auf 80.000 und zählen jede herkömmliche Signatur als vier Operationen und jede SegWit Operation als eine Operation. Eine SegWit Signaturoperation zählt weniger als eine herkömmliche Operation, weil diese effizienter ist, wie in Abschnitt 10.2.6 besprochen.

Das wird denselben Effekt haben wie die Blockgrössenerweiterung. Enthält ein Block nur herkömmliche Inputs, bleibt das alte Limit von 20.000 Operationen. Wenn der Block nur aus SegWit Transaktionen besteht, ist das Limit effektiv 80.000 Operationen. Jede Kombination von herkömmlichen und SegWit Inputs führt zu einer Grenze irgendwo zwischen 20.000 und 80.000 tatsächlichen Signaturoperationen.

10.6. Zusammenfassung

Dieses Kapitel hat SegWit durchgenommen, was einige Probleme löst:

  • Transaction Malleability, Transaktions-Umformbarkeit—Eine txid könnte sich ändern, ohne den Effekt der Transaktion zu verändern. Das könnte zu kaputten Verbindungen zwischen Transaktionen führen, womit die Child Transaktion ungültig wird.

  • Ineffizient Signaturverifikation—Wenn sich die Anzahl Inputs in einer Transaktion verdoppelt, nimmt die zur Verifikation dieser Transaktion benötigte Zeit quadratisch zu. Das liegt daran, dass sich sowohl die Transaktionsgrösse als auch die Anzahl Signaturen verdoppelt.

  • Bandbreitenverschwendung–Lightweight Wallets müssen die Transaktionen einschliesslich aller Signaturen herunterladen, um den Merkle Proof verifizieren zu können, aber die Signaturdaten sind nutzlos für sie, weil sie nicht die ausgegebenen Outputs kennen, gegen die sie prüfen müssten.

  • Schwierige Upgrades–Es gibt wenig Raum für Upgrades der Script Sprache. Eine Handvoll OP_NOPs sind noch übrig, und man kann einen OP_NOP nicht nach Belieben abändern. In den Fällen, in denen der neue Operator erfolgreich ist, muss er sich genau wie OP_NOP verhalten.

10.6.1. Lösungen

Durch das Verschieben der Signaturdaten aus der Basistransaktion heraus, sind diese Daten nicht mehr Teil der txid.

u10 03

Wenn die Signatur umgeformt wird, betrifft das nicht mehr die txid. Unbestätigte Verkettungen von Transaktionen werden unzerbrechlich.

Ein neuer Signatur-Hashing-Algorithmus wird benutzt, der für ein lineares Anwachsen der für die Verifikation benötigten Zeit bei wachsender Anzahl Inputs sorgt. Der alte Signatur-Hashing-Algorithmus hasht die gesamte Transaktion für jede Signatur.

u10 04

Signaturen in Witnesses hashen die Transaktion nur einmal.

10 26

Der Zwischenhash wird für jede Signatur wiederverwendet, was den Gesamtaufwand für das Hashen stark verringert.

Die Bandbreite, die Lightweight Wallets brauchen, verringert sich, weil sie die Witnesses nicht herunterladen müssen, um zu verifizieren, dass die Transaktion Teil eines Blocks ist. Sie können die Ersparnisse pro Transaktion zur Verbesserung ihrer Privacy verwenden, indem sie ihren Bloom Filter verkleinern, oder bei gleichbleibender Privacy ihren Datenverbrauch verringern.

Die Witness Version im Pubkey Script erlaubt zukünftige Upgrades der Script Sprache. Diese Upgrades können beliebig komplex werden, ohne Einschränkungen der Funktionalität.

Neue Regeln gelten für Blocks, die SegWit Transaktionen enthalten. Ein Output in der Coinbase Transaktion muss sich an alle Witnesses des Blocks binden.

u10 06

Alte Nodes funktionieren weiter, weil sie von dem Commitment in der Coinbase Transaktion nichts wissen. Das lässt uns SegWit einführen, ohne die Blockchain in zwei verschiedene Kryptowährungen aufzuspalten.

10.7. Übungen

10.7.1. Wärm dich auf

  1. Welcher Teil der Transaktion ist der Grund für die Transaction Malleability?

  2. Warum ist Transaction Malleability ein Problem?

  3. Warum sagen wir, dass die Zeit zur Verifikation herkömmlicher Transaktionen mit der Anzahl Inputs quadratisch wächst?

  4. Warum brauchen Lightweight Wallets die Signaturen einer herkömmlichen Transaktion, um zu verifizieren, dass sie Teil eines Blocks ist?

  5. Angenommen, du willst ein neues Feature zu Bitcoin Script hinzufügen, und du möchtest dazu das Verhalten von OP_NOP5 neu definieren. Woran musst du unbedingt denken, wenn du das neue Verhalten entwirfst, um einen Blockchain Split zu verhindern (denn nicht alle Nodes werden gleichzeitig upgraden)?

  6. Welche der folgenden sind Segwit Adressen? Um welche Art von Segwit Adresse handelt es sich?

    1. bc1qeqzjk7vume5wmrdgz5xyehh54cchdjag6jdmkj

    2. c8052b799cde68ed8da8150c4cdef4ae3176cba8

    3. bc1qnqaewluxhx7wzfrf9e5fqjf47hjk9jyzy6l0hpt4kjj3u2wmjp3qr3lft8

    4. 3KsJCgA6ubxgmmzvZaQYR485tsk2G6C1Be

    5. 00 bb4d49777d981096a75215ccdba8dc8675ff02d1

  7. Wofür wird die Witness Version benutzt? Die Witness Version ist die erste Zahl in einem SegWit Output–zum Beispiel die 00 in

    00 bb4d49777d981096a75215ccdba8dc8675ff02d1

10.7.2. Grabe tiefer

  1. Erläutere, wie eine SegWit Transaktion für einen alten Node gültig ist, der nichts von SegWit weiss. Das hier sieht der alte Node:

    u10 07
  2. Erkläre, wie eine SegWit Transaktion von einem neuen Node verifiziert wird, der SegWit kennt. Der Node sieht das hier:

    u10 08
  3. Angenommen, du willst das Bitcoin System upgraden. Du möchtest, dass sich das Witness Commitment zusätzlich zum Witness Root Hash auch an die Transaction Fees bindet, indem du einen Merkle Tree aller Transaction Fees baust. Schlage vor, wie man sich an den Fee Merkle Root im Block binden könnte, ohne die Kompatibilität mit alten Nodes zu verlieren. Du brauchst zukünftige Upgrades hierbei nicht zu berücksichtigen, denn das wäre zu komplex. Benutze die folgende Abbildung als Hinweis:

    u10 09
  4. Wie würden alte und neue Nodes Blocks verifizieren, die das Commitment aus der vorangegangenen Übung enthalten?

10.8. Zusammenfassung

  • SegWit löst Signatur Script Daten aus den Transaktionen heraus, um Probleme mit Transaktions-Umformbarkeit, oder Transaction Malleability, zu lösen.

  • SegWit führt einen neuen Signatur-Hashing-Algorithmus ein, der die Verifikation von Transaktionen schneller macht. Das hilft Nodes dabei, mit weniger Ressourcen auf dem aktuellen Stand zu bleiben.

  • Lightweight Wallets bekommen bessere Privacy mit eingespartem Datenvolumen, weil sie keine Witnessdaten mehr herunterladen müssen.

  • Das Witness Versionsbyte des Pubkey Scripts macht Upgrades der Scriptsprache einfacher.

  • Wir können die maximale Blockgrösse twas vergrössern, indem wir die Witness Bytes mit einem Rabatt zählen.

  • Ein neues Adressformat hilft Wallets dabei, zwischen herkömmlichen und SegWit Zahlungen zu unterscheiden.

  • SegWit kann in herkömmliche p2sh Adressen “eingebettet” werden, damit alte Wallets Geld an SegWit Wallets schicken können.