Guten Tag, liebe Leser!
Dieser Artikel befasst sich mit der Plasma-Geldkette und beleuchtet die folgenden Themen:
- das Skalierbarkeitstrilemma und die Methoden für seine Lösung;
- Datenstrukturen der untergeordneten Kette und ihre Anzeige in der Wurzelkette;
- Implementierung von Eingaben in die Wurzelkette;
- Umsetzung des Rückzugs aus der Wurzelkette.
Opporty verwendete die Programmiersprache Javascript, um die untergeordnete Kette zu implementieren, sowie Solidity für die Stammkette. Codebeispiele werden in diesen Sprachen bereitgestellt.

Blockchain und Dezentralisierung ermöglichen es, die Arbeit in nahezu allen Lebensbereichen, in denen das Internet und Informationstechnologien verwendet werden, zu optimieren und zu verbessern. Sie erhöhen die Zuverlässigkeit, die finanzielle Effizienz und erleichtern die Digitalisierung realer Dinge und Güter.
Intelligente Verträge bringen Geschäftslogik in dezentrale Netzwerke. Auf diese Weise können Sie neue DAPP-Anwendungen erstellen.
Die Ausführung intelligenter Verträge und der schnelle Betrieb von Anwendungen mit einer verteilten Datenbank ist nur möglich, wenn die Skalierbarkeitsbedingung erfüllt ist.
Moderne dezentrale Blockchains haben mehrere Nachteile. Das wichtigste ist die Skalierbarkeit. Das Ethereum verarbeitet ungefähr 20 tx / s. Dies reicht in modernen Finanzrealitäten nicht aus. Gleichzeitig bietet Ethereum den höchstmöglichen Schutz vor Hacking und Netzwerkausfällen. Andere Kryptowährungen und Systeme, die auf der Blockchain basieren, weisen keinen so hohen Dezentralisierungsgrad auf, was das Vertrauen in das Netzwerk verringert.
Das Skalierbarkeitstrilemma
Es gibt ein Blockchain-Skalierbarkeitstrilemma, das drei Komponenten umfasst:
- Dezentralisierung;
- Sicherheit
- Skalierbarkeit.
Dezentralisierung im Trilemma
Die Dezentralisierung spiegelt, wie der Begriff schon sagt, den Grad der Diversifizierung des Eigentums an Aktivitäten in der Blockchain sowie den Grad der Diversifizierung der Erstellung von Blöcken und der Generierung neuer Hauptbucheinträge wider.
Aus Gründen der Klarheit ist es notwendig, über die am stärksten zentralisierten Organisationen zu sprechen. Normalerweise wird anstelle der Blockchain eine einfache Datenbank verwendet. Eine solche Organisation wird von speziellen Administratoren betrieben. Alle Transaktionen können durch manuelles Eingreifen storniert werden.
In vollständig dezentralen Netzwerken kann jeder Benutzer am Aufbau eines Netzwerks teilnehmen.
Die wichtigste Folge der Dezentralisierung ist, dass der größte Teil des Werts an die Community geht, die an der Erstellung der Blockchain beteiligt ist. Es gibt kein zwischengeschaltetes Team von Managern, die alle Vorteile erhalten, anstatt diejenigen, die die Netzwerkstruktur selbst generieren. Tatsächlich sind die meisten Krypto-Projekte zu 100% im Besitz ihrer Mitwirkenden oder Benutzer, nicht der Gründer. Dies ist offensichtlich ein attraktiveres Modell für diejenigen, die kein Gründer sind.
Sicherheit im Trilemma
Es geht um die Fähigkeit der Blockchain, Angriffen von externen Quellen standzuhalten und das System in einem unveränderten Zustand zu halten. Die meisten Blockchains sind vielen potenziellen Sicherheitsbedrohungen ausgesetzt. Es ist unbedingt erforderlich, die gängigsten Angriffsmethoden und Verteidigungsoptionen zu kennen.
In diesem Fall gehen Dezentralisierung und Sicherheit Hand in Hand. Je mehr Knoten vorhanden sind, desto weniger hängt das Netzwerk von der zentralen Seite ab und daher besteht das Risiko eines zentralen Fehlerpunkts. Es gibt jedoch viele andere Angriffsmethoden, die eine Bedrohung für dezentrale Netzwerke darstellen, darunter:
>
50% Angriff - Ein Objekt, das mehr als 50% der Gesamtzahl der nicht bezahlten Token besitzt, besitzt tatsächlich das Netzwerk.
>
Sybil-Angriff - Der Benutzer kann viele Kennungen im System generieren, um einen signifikanten Anteil am Eigentum und / oder an der Entscheidungsfindung im Netzwerk effektiv zu steuern.
>
DDoS - Ein DDoS-Angriff (Distributed Denial of Service) tritt auf, wenn der Datenverkehr im Netzwerk unterbrochen und das Netzwerk mit böswilligen Transaktionen gefüllt werden soll.
>
Kollusionsangriff - Ein oder mehrere Objekte (oder Knoten) werden zusammengeführt, um böswillige Vorgänge im Netzwerk auszuführen.
Skalierbarkeit im Trilemma
Der Grad der Skalierbarkeit ist wichtig, da er den endgültigen Durchsatz bestimmt, dh die Obergrenze der Netzwerkgröße. Die wichtigste Frage bei der Bewertung eines Netzwerks lautet: „Wie vielen Benutzern kann dieses System standhalten?“ Bitcoin hat derzeit zwischen 2,9 und 5,8 Millionen Brieftascheninhaber. EOS hat mehrere tausend Mitglieder.
Skalierbarkeit und Dezentralisierung können nebeneinander bestehen, die Sicherheit wird jedoch verringert. Entwickler wählen die Plattformen aus, die ihren Anforderungen am besten entsprechen. Benutzer tun dasselbe. Die Meinungen der beiden Seiten sind manchmal unterschiedlich. Einige Benutzer sind bereit, die Sicherheit für die Skalierbarkeit zu opfern, andere sind bereit, die Skalierbarkeit für die Sicherheit zu opfern, aber das Balancieren ist viel schwieriger.
"Heiliger Gral" in Blockchain-Technologie
Per Definition hat eine Blockchain nur zwei der folgenden drei Eigenschaften:
- Dezentralisierung (jeder Teilnehmer hat nur Zugriff auf O © -Ressourcen, dh auf einen normalen Laptop oder einen kleinen VPS);
- Skalierbarkeit (Fähigkeit zur Verarbeitung von Transaktionen O (n)> O ©);
- Sicherheit (Schutz vor Eindringlingen mit O (n) -Ressourcen).

Grün: Ein ausgeglichener Zustand mit drei Bedingungen.
Rot: Starke Sicherheit, aber eingeschränkte Dezentralisierung und Skalierbarkeit.
Blau: Die Effizienz ist hoch, aber Sicherheit und Dezentralisierung sind begrenzt.
Schwarz: Die Dezentralisierung ist hoch, aber es gibt keine Aspekte der Skalierbarkeit und Sicherheit.
Grau: vollständige Dezentralisierung mit minimalen oder fehlenden Sicherheits- und Skalierbarkeitseigenschaften.
Violett: ein ausgewogenes Verhältnis zwischen Sicherheit und Skalierbarkeit, die Ablehnung der Dezentralisierung.
Der „heilige Gral“ in der Blockchain-Technologie bedeutet, alle drei Aspekte zu kombinieren.
In den meisten aktuellen Projekten, die mit Kryptowährungen arbeiten, werden zwei grundlegende Eigenschaften erreicht: Dezentralisierung und Sicherheit. Die Skalierbarkeit leidet.
Vielversprechende Lösungen für das Trilemma
Nachweis des Einsatzes (PoS)
Proof of Stake (PoS) bietet potenzielle Verbesserungen der Skalierbarkeit. POS ersetzt Cryptocurrency Mining basierend auf dem PoW-System (Proof of Work). Die Wahl des Validators ist sehr schnell - deterministisch. Gleichzeitig fallen keine Energiekosten an und es ist umweltfreundlich.
Seitenketten
Im virtuellen Ethereum-Netzwerk ist es möglich, ein Seitennetzwerk zu erstellen, in dem das Projekt seine einzelnen Transaktionen verarbeiten kann, und dann nur die Anfangs- und Endergebnisse im Ethereum-Netzwerk aufzuzeichnen. Dies reduziert die Belastung des EVM, gibt jedoch mehr Vertrauen in die Verwaltung der Sidechain. Das Vertrauen in Dritte reduziert somit die Dezentralisierung.
Scherben
Durch das Sharding werden Transaktionen in kleinere Daten aufgeteilt. Anstelle jedes einzelnen Knotens im Netzwerk, der ganze Transaktionen verarbeitet, werden Knoten in Gruppen unterteilt, und diese Knotengruppen verarbeiten bestimmte Daten. Später, während der Verarbeitung, werden diese Daten zur dauerhaften Speicherung in der Blockchain erneut assimiliert.
Blockgröße erhöhen
Litecoin und Bitcoin Cash (BCH) sind „Gabeln“ für die Bitcoin-Blockchain. Forking kopiert grundsätzlich eine Blockchain. Nach der Verzweigung können Sie Änderungen vornehmen. Sowohl LTC als auch BCH erhöhten die Größe jedes Blocks, wodurch mehr Transaktionen pro Block gespeichert werden konnten, wodurch die Verarbeitungsgeschwindigkeit von Transaktionen erhöht wurde.
Blitznetzwerk
Die allererste Sidechain-Lösung war Lightning. Die Hauptidee des Lightning-Netzwerks besteht darin, dass nicht alle Transaktionen in der Blockchain aufgezeichnet werden sollten, da dies das Netzwerk überlastet. Wenn Benutzer mehrmals Geld untereinander überweisen, ist die Registrierung jeder Überweisung optional. Es reicht aus, nur eine Art Zahlungskanal zu öffnen und die Daten über die Öffnung in der Blockchain aufzuschreiben. Dieser Kanal bleibt nach Bedarf geöffnet. Wenn es notwendig ist, es zu schließen, wird das Ergebnis aller in diesem Kanal getätigten Transaktionen einfach in die Blockchain geschrieben. Nach dieser Idee können Sie ein ganzes Netzwerk von Zahlungskanälen erstellen. Dann werden Transaktionen in der Blockchain viel seltener verwendet.
Ein Zahlungskanal ist nur eine Kombination mehrerer Transaktionen. Ein Kanal kann von jedem seiner Mitglieder geschlossen werden. Diese Aktion ist wie das Öffnen eines Safes, mit dem Sie die Gelder der Teilnehmer nehmen und die Daten zu ihrer Überweisung in die Blockchain aufschreiben können.
Diese Technologie wird sehr leistungsfähig, wenn mehrere solcher Kanäle zu einem Netzwerk namens The Lightning Network kombiniert werden. Dieses Netzwerk wurde speziell für Bitcoin entwickelt.
Raiden-Netzwerk
Für Ethereum ist das Raiden-Netzwerk das bekannteste Gegenstück zu Lightning.
Dies ist eine Lösung für die Skalierung außerhalb der Hauptblockkette. Es ist kompatibel mit der Übertragung von ERC-20-Token in bidirektionale Zahlungskanäle.
Die grundlegende Architektur ist komplex, aber für die Interaktion mit Raiden müssen Entwickler nur mit der API interagieren, um skalierbare Anwendungen auf Raiden zu erstellen.
Raiden wurde entwickelt, um sofortige Zahlungen und niedrige Provisionen bereitzustellen, die Vertraulichkeit von Transaktionen zu erhöhen und Mikrozahlungen zu leisten. Die meisten Zahlungskanäle existieren außerhalb des Netzwerks und bilden nur gelegentlich Transaktionen innerhalb der Stammkette, wodurch der Durchsatz der untergeordneten Kette erheblich reduziert wird.
Optimale Lösung
Blitzideologen haben ein neues Childchain-Konzept entwickelt, das Blockchain-Geschwindigkeitsprobleme löst.
Opporty setzt das Konzept von Plasma und Plasma Cash praktisch um.
Plasma ist eine Reihe intelligenter Verträge, die über der Ethereum-Wurzelkette ausgeführt werden und aus einem Netzwerk von untergeordneten Ketten bestehen, die in einer hierarchischen Baumstruktur mit der Wurzelkette verbunden sind.
Das heißt, die Sicherheit der Ethereum-Rootchain wird verwendet, um die Skalierbarkeit zu optimieren.
Plasma Cash: Gelegenheitsoption
Opporty verwendet die Implementierung von Plasma Cash in der ersten Version.Dieses Modell ist hinsichtlich der Skalierbarkeit die effektivste Plasmaimplementierung.
Plasma Cash ist ein System, das auf der Verwendung eindeutiger Kennungen für jeden Token in der Plasmakette basiert. Das heißt, NFT wird angewendet und Token im Netzwerk erhalten eindeutige Seriennummern.
Eigenschaften von Plasma Cash:
- Sharded Validation auf der Client-Seite - Kunden müssen nur ihre Plasmakette überwachen, um ihre Token zu erhalten. Dies bedeutet, dass der Transaktionsdurchsatz erhöht werden kann, ohne die Belastung einzelner Benutzer zu erhöhen.
- Vereinfachung des Massenausgangs - Massenausgänge stellen eine geringere Bedrohung für das Netzwerk dar, da der Dieb für jeden Token, den er stehlen möchte, eine Exit-Transaktion einreichen muss.
- Keine bidirektionalen Bestätigungen - Transaktionen erfordern kein zweistufiges Senden und Bestätigen mehr. Stattdessen kann eine Transaktion ausgegeben werden, sobald sie in der Hauptkette enthalten ist.
Nachteil:
Große Stückelungen von Token - da jedem Token eine Seriennummer zugewiesen werden muss, ist es unmöglich, beliebig kleine Token zu produzieren. Dies liegt an der Tatsache, dass der Wert des Token-Kaufs irgendwann höher sein wird als der Wert des Tokens.
Transaktionsstruktur in Opportunity Plasma Cash
Opporty verwendete Javascript, um die Kinderkette zu implementieren. Jede Transaktion in Opporty Plasma Cash hat eine ähnliche Struktur:
const transactionFields = [ {name: 'prevHash'}, {name: 'prevBlock', int: true, default: 0}, {name: 'tokenId', isDecimal: true}, {name: 'newOwner'}, {name: 'type'}, {name: 'signature'}, ]
Die Hauptelemente hier sind eine Verknüpfung zum vorherigen prevBlock-Block (der zum Bewegen in der Blockkette erforderlich ist), die Token-ID tokenId (muss eindeutig sein) und newOwner, der letzte Eigentümer des Tokens.
Ferner wird ein spezieller Typ des Patricia Merkle Trie-Baums verwendet, um den Block zusammenzusetzen und den Wurzelketten-Hash zu erhalten. Der gleiche Baum wird im Ethereum verwendet. Es hat einen komprimierten Look. Gleichzeitig können Sie weiterhin Nachweise über die Aufnahme oder Nichteinbeziehung einer Transaktion in einen Block erhalten.
Signatur ist eine Signatur auf elliptischen Kurven.
Eine Transaktion, die ein Token mit einer bestimmten Token-ID ausgibt, ist nur gültig, wenn sie im Merkle-Baum an der Position Token-ID enthalten ist, dh für jedes Token im Merkle-Baum gibt es nur einen „Ort“, an dem dieses Token ausgegeben wird, an dem Transaktionen zulässig sind. Mit diesem Format können Benutzer den vollständigen Verlauf der Plasmakette überprüfen sowie den Besitz bestimmter Token nachweisen und widerlegen.
Um ein Token auszugeben, müssen Sie die Kette validieren, nach fehlenden Blöcken suchen und erst dann die Transaktion zusammen mit dem gesamten Verlauf neu signieren.
Der Block ist wie folgt:
const blockFields = [ {name: 'prevHash'}, {name: 'blockNum', isDecimal: true}, {name: 'transactions'}, {name: 'merkleRoot'}, {name: 'time'} ]
Grundsätzlich ist eine Blockchain einfach eine Blockkette mit einer Verknüpfung zum vorherigen Block. Eine solche Struktur ermöglicht es, die Eigenschaft der Unveränderlichkeit zu erhalten, dh die Geschichte nicht neu zu schreiben. merkleRoot ermöglicht das Schreiben von Prüfpunkten in die Stammkette.
In der Stammkette sieht es auf der Ebene der intelligenten Verträge folgendermaßen aus (Solidity-Sprache):
/* * Block structure (represents one block in a chain) */ struct Block { uint block_num; bytes32 merkle_root; uint time; /* * Transaction structure (decoded from RLP form) */ struct Transaction { bytes32 prevhash; uint prev_block; uint token_id; address new_owner; }
Die Codierung erfolgt mit den Funktionen Codierung / Decodierung - RLP-Serialisierung / Deserialisierung.
Möglichkeiten zur Eingabe von Plasma Cash
Jeder kann Geld in Plasma Cash einzahlen, indem er einfach Äther auf einen intelligenten Vertrag überträgt. Infolgedessen wird ein OPP-Token an einer bestimmten Token-ID-Position empfangen.
Hier ist die Implementierung in Solidity:
function deposit() public payable { uint token_id = uint(keccak256(msg.sender, msg.value, deposit_blk)); // token.index = deposit_blk; tokens[token_id] = msg.value; deposit_blk += 1; emit DepositAdded(msg.sender, msg.value, token_id, current_blk); }
Das heißt, tokenId wird als Zufallszahl (Hash) generiert. Als nächstes wird ein Ereignis generiert, das in der untergeordneten Kette gescannt wird.
Möglichkeiten zum Abheben von Plasma Cash
Jede Person kann ihren Token zurückziehen, indem sie die letzten beiden Transaktionen in der Besitzhistorie des Tokens bereitstellt.
Implementierung des Ausstiegs aus der Wurzelkette:
function startExit(uint block_num, bytes tx1, bytes tx0, bytes proof1, bytes proof0) public returns (uint exit_id) { require(checkPatriciaProof(keccak256(tx1), childChain[block_num].merkle_root, proof1)); bytes32 prev_hash; uint prev_blk; uint token_id; address new_owner; (prev_hash, prev_blk, token_id, new_owner,) = getTransactionFromRLP(tx1); require(msg.sender == new_owner); require(tokens[token_id] > 0); bytes32 hashPrevTx = keccak256(tx0); require(checkPatriciaProof(hashPrevTx, childChain[prev_blk].merkle_root, proof0)); require(prev_hash == hashPrevTx); Exit storage record = exitRecords[token_id]; require(record.block_num == 0); record.block_num = block_num; record.new_owner = msg.sender; record.prev_block = prev_blk; if (childChain[block_num].time > block.timestamp - week) record.priority = childChain[block_num].time; else record.priority = block.timestamp - week; exits.add(record.priority); exit_ids[record.priority].push(token_id); emit ExitAdded(msg.sender, record.priority, token_id); return token_id; }
Zunächst werden zwei Transaktionen geprüft. Wenn der aktuelle Benutzer der Eigentümer der Transaktion ist, fügen wir einfach die Ausgabe zur Struktur hinzu und lassen zwei Wochen Zeit, um die Ausgabe herauszufordern.
Die Schlussfolgerung kann auf drei Arten angefochten werden:
- Bestätigung der Ausgaben für Transaktionen:
function challengeSpent(uint exit_id, uint blk_num, bytes tx1, bytes proof) public { require(checkPatriciaProof(keccak256(tx1), childChain[blk_num].merkle_root, proof)); Exit memory record = exitRecords[exit_id]; require(record.block_num > 0); uint prev_block; uint token_id; (, prev_block , token_id, ) = getTransactionFromRLP(tx1); require(tokens[token_id] > 0); require(prev_block == record.block_num && record.block_num < blk_num); require(token_id == exit_id); exit_ids[record.priority].remove(exit_id); delete exitRecords[exit_id]; emit ExitChallengedEvent(exit_id); }
Wenn es eine Transaktion gibt, die den angezeigten Token bereits ausgibt, wird eine solche Auszahlung storniert!
- Kostennachweis für die vorherige Transaktion:
/* * Challenge exit by providing * a proof of a transaction spending P(C) that appears before C */ function challengeDoubleSpend(uint exit_id, uint blk_num, bytes tx1, bytes proof) public { require(checkPatriciaProof(keccak256(tx1), childChain[blk_num].merkle_root, proof)); Exit memory record = exitRecords[exit_id]; require(record.block_num > 0); // bytes32 prev_hash; uint prev_block; uint token_id; (, prev_block , token_id, ) = getTransactionFromRLP(tx1); require(tokens[token_id] > 0); // check if token double spent require(prev_block == record.prev_block && blk_num < record.block_num); // require(token_id == exit_id); exit_ids[record.priority].remove(exit_id); delete exitRecords[exit_id]; emit ExitChallengedEvent(exit_id); }
Dies ist die gleiche Prüfung, als ob der Token vor der Auszahlung ausgegeben worden wäre. Suchen Sie zunächst im Root-Hash nach einer Transaktion. Als nächstes löschen wir die Ausgabe, wenn sie bereits ausgegeben wurde.
- Bereitstellen einer Transaktion in der Transaktionshistorie des Tokens davor.
Dies kann eine falsche Geschichte sein, daher müssen Sie sie mit einer untergeordneten Transaktion bestätigen:
// */ function challengeInvalidHistory(uint exit_id, uint blk_num, bytes tx0, bytes proof) public { // check if proof is valid require(checkPatriciaProof(keccak256(tx0), childChain[blk_num].merkle_root, proof)); Exit memory record = exitRecords[exit_id]; require(record.block_num > 0); bytes32 prev_hash; uint token_id; (prev_hash, , token_id, ) = getTransactionFromRLP(tx0); //require(exit_id == token_id); require(tokens[token_id] > 0); // transaction should be before exit tx in history require(blk_num < record.block_num - 1); challenged[exit_id] = blk_num; emit ChallengedInvalidHistory(exit_id, token_id); }
Das Aufrufen des ersten und zweiten Skripts blockiert die Ausgabe sofort.
Der Aufruf zum dritten Szenario kann durch Angabe eines direkten Nachkommen beantwortet werden. Es muss gleich oder vor der übergeordneten Transaktion sein.
/* * Respond to invalid history challenge by providing * the direct child of C*, which must be either equal to or before P( C ) */ function respondChallenge(uint exit_id, uint blk_num, bytes childtx, bytes proof) public { require(challenged[exit_id] > 0); Exit memory record = exitRecords[exit_id]; require(record.block_num > 0); require(checkPatriciaProof(keccak256(childtx), childChain[blk_num].merkle_root, proof)); // get transaction from rlpencoded form bytes32 prev_hash; uint prev_block; uint token_id; (prev_hash, prev_block, token_id, ) = getTransactionFromRLP(childtx); // if direct child if (prev_block == challenged[exit_id] ) { if (blk_num <= record.prev_block && token_id == exit_id ) { delete challenged[exit_id]; emit ExitRespondedEvent(exit_id); } else { exit_ids[record.priority].remove(exit_id); delete exitRecords[exit_id]; emit ExitChallengedEvent(exit_id); } } }
Das heißt, wenn die richtige untergeordnete Transaktion empfangen wird, ist die Ausgabe umstritten und bleibt in der Warteschlange!
Nach dem Aufbau eines Teils des Opporty Plasma Cash-Protokolls wurde die folgende Schlussfolgerung gezogen:
Dieses Protokoll bietet Sicherheit über die Ethereum-Stammkette.
Durch die Komplikation der Eingabe- und Ausgabeprozeduren aus der Stammkette und der Statuskomprimierung (Transaktionsblöcke) haben wir alle Methoden der Ausgabe und Eingabe in die Stammkette untersucht und auch die grundlegenden Datenstrukturen untersucht: Transaktionen und Blöcke.
Mit der Sidechain, die auf dem Ethereum-Netzwerk basiert, können Sie Transaktionen erheblich beschleunigen. Opporty erhielt bis zu
300.000 Transaktionen pro Sekunde mit einem einzigen Bediener. Dies ist viel mehr als das, was aktuelle Zahlungssysteme bieten können.
Trotz einiger Probleme bei der Datenverfügbarkeit bietet der Betreiber ein hohes Maß an Stabilität der Blockchain und ermöglicht die Durchführung effektiver internationaler Geschäftstransaktionen.
Plasma Cash bringt eine enorme Steigerung der Skalierbarkeit. Daher verwendet Opporty Plasma als Teil seines PoE-Protokolls.
Nützliche Links
- Weißbuchplasma
- Git Hub
- Anwendungsfälle und Architekturbeschreibung
- Lightning-Netzwerkpapier