Original by Eric Hopp: https://blog.iota.org/the-state-of-qubic-63ffb097da3f

TL;DR:

Die IOTA-Stiftung hat beschlossen, unseren Schwerpunkt auf einen neuen Ansatz für Smart Contracts zu verlagern, der sich aus unserer früheren Arbeit ableitet. IOTA Smart Contracts ist eine „Layer-2-Lösung“, die auf der Entwicklung von Coordicide in GoShimmer aufbaut. Eine kurze Einführung finden Sie hier. Die Weiterentwicklung von Qubic erfordert erhebliche Ressourcen und Zeit, und unser neuer Ansatz wird eine breitere und schnellere Anwendung ermöglichen. Wir haben einen funktionierenden Proof of Concept der Programmiersprache Qupla, der auf FPGA-Hardware ausgeführt werden kann, als Open Source zur Verfügung gestellt. Wir laden die Open-Source-Gemeinschaft ein, ihn zu erforschen.

Der Zustand von Qubic

Es ist schon eine Weile her, dass wir uns umfassend mit dem aktuellen Stand des Qubic-Projekts befasst haben. Dieser Artikel wird hier Abhilfe schaffen, indem er eingehend darauf eingeht, wo wir das Projekt derzeit sehen, wie weit wir gekommen sind, welche Lektionen wir gelernt haben und wie die IOTA-Stiftung die Entwicklung von Smart Contracts weiter vorantreiben wird.

Bitte beachte: Wir gehen davon aus, dass der Leser über ein grundlegendes Verständnis des Qubic-Systems sowie der Artikelserie über das Qubic-Berechnungsmodell verfügt. Einige der in diesen Ressourcen verwendeten Begriffe haben sich möglicherweise im Laufe der Zeit aus Gründen der Klarheit etwas geändert.

Qubic: ein layered-System

Wenn man sich Qubic genauer ansieht, dann besteht es eigentlich aus zwei sehr lose gekoppelten Schichten, die sich gegenseitig nicht so sehr zu brauchen scheinen. Diese beiden Schichten sind:

Die „Nachrichtenschicht“ Smart Contract (SC), die als Level-2-Protokoll über dem IOTA Tangle läuft. Diese Schicht regelt die Ausführung von SCs durch ein Komitee von Verarbeitungsknoten (Nodes). Die Nodes erzeugen einen beschlussfähigen Konsens über die Verarbeitungsergebnisse und bieten einen Prüfpfad für das Tangle. Diese Schicht kümmert sich nicht darum, wie die Verarbeitung erfolgt, sondern nur darum, dass die Ergebnisse durch den Prüfpfad, den SC-Code, die Eingabedaten und die Ausgabedaten nachweislich korrekt und überprüfbar sind.

Die Ebene der virtuellen Maschine (VM) von Abra. Diese Schicht regelt die tatsächliche Ausführung des SC-Codes. Sie hat einen besonderen Schwerpunkt auf der Fähigkeit, auf IoT-Geräten mit geringem Ressourcenbedarf ausgeführt werden zu können. Die Schicht nimmt Eingabedaten entgegen, führt den (möglicherweise hardwarebeschleunigten) Code aus und gibt Ergebnisse aus. Dieser Schicht ist es gleichgültig, woher die Eingabedaten kommen und wohin die Ergebnisse gesendet werden.

Diese beiden separaten Schichten werden durch das Qubic Computation Model (QCM), ein Ereignisverarbeitungssystem, zusammengeklebt. Das QCM regelt die Weiterleitung der Eingabedaten von der SC-Schicht an die VM-Schicht und die Rückgabe der Ergebnisse von der VM-Schicht an die SC-Schicht. Das QCM ist ein sehr generisches Modell. Es nimmt nichts über die Ereignisverarbeitung an, woher die Ereignisdaten kommen oder wohin die Verarbeitungsergebnisse gehen. Es handelt sich lediglich um einen einfachen Dispatching-Mechanismus, der eine vollständige Entkopplung zwischen den Schichten, die miteinander reden müssen, sicherstellt.

Verbinden der Schichten

Wo also findet die Kopplung dieser beiden Systeme statt, wenn sie fast vollständig entkoppelt sind? Zunächst besteht die Notwendigkeit, Berechnungsergebnisse unabhängig voneinander verifizieren zu können. Das bedeutet, dass Sie neben einem Audit-Trail für die Eingabedaten und Ergebnisse von SC-Aufrufen auch den entsprechenden SC-Code benötigen, der aufgerufen wurde, um Teil dieses Audit-Trails zu sein. Auf diese Weise weißt du genau, welchen Code du mit den Eingabedaten ausführen musst, wenn du das Ergebnis verifizieren willst.

Beachte, dass dies immer noch nicht die Verwendung des Qubic-spezifischen Qupla-Codes und des entsprechenden Abra VM zur Ausführung des SC erfordern würde. Du könntest im Wesentlichen jede VM und jede Programmiersprache verwenden, solange der SC-Code mit diesen kompatibel ist. Unsere erste Proof-of-Concept-Implementierung des QCM vermischt in der Game of Life-Demo tatsächlich Qubic-spezifischen Abra-Code mit Standard-Java-UI-Code. Es gibt jedoch einen ganz bestimmten Grund, bei der Auswahl einer VM zur Ausführung Ihres SC-Codes vorsichtig zu sein. Da Knoten diesen Code immer dann ausführen, wenn Daten für die SC automatisch und unbeaufsichtigt ankommen, möchten Sie verhindern, dass laufende SC-Programme in der VM-Schicht ausgeführt werden (unbegrenzte Schleifen/Rekursionen). Du benötigst einen Mechanismus, um das SC-Programm in Schach zu halten, so dass es nur für eine vernünftige, vorhersehbare Zeitspanne läuft.

In Ethereum wird dieses Runaway-Problem durch die Einführung von Gasgebühren (Gas) gelöst. Die Höhe der vorgesehenen Gebühren entspricht einem bestimmten Höchstbetrag für die SC-Verarbeitung. Sobald dieses Maximum überschritten wird, wird die SC-Ausführung abgebrochen, wodurch verhindert wird, dass der unkontrollierte SC-Code unbegrenzt weiterläuft. Der Nachteil dieser Methode besteht darin, dass es schwierig sein kann, die Höhe der Gasgebühren, die Sie für Ihre SC benötigen werden, im Voraus vorherzusagen, wenn die SC irgendeine Art von nicht-trivialer Verarbeitung durchführt. Und wenn Sie zu wenig Gasgebühren bereitstellen, könnte dies dazu führen, dass Ihre SC-Ausführung abgebrochen wird, bevor sie abgeschlossen ist. In diesem Fall haben Sie die Gasgebühren verloren, ohne dass die Vollstreckung zu einem Vollstreckungsergebnis geführt hätte.

In Qubic lösen wir dieses Problem deterministisch, indem wir ein funktionales Datenflussprogrammierungsmodell in der Abra VM haben, das keine unbegrenzten Schleifen/Rekursion zulässt und daher an und für sich nicht Turing-fähig ist. Jede Funktion definiert klar, wie viel Verarbeitung sie leisten wird. Es gibt keine direkte Verzweigung oder Schleifenbildung in der Abra VM, was bedeutet, dass jede Funktion immer genau die gleiche Anzahl von Anweisungen ausführt. Selbst wenn eine Funktion rekursiv aufgerufen wird, ist sie auf eine bestimmte maximale Anzahl von Aufrufen beschränkt. Unbegrenzte Schleifen können auf einer höheren Ebene, durch das QCM, aktiviert werden, aber die Einheit der Ausführung ist absolut klar und garantiert auf Funktionsebene begrenzt. Wenn du erwartest, dass dir die Aufrufe für eine Funktion ‚ausgehen‘, kannst du deinen Code so gestalten, dass der Fortsetzungszustand des SC Teil der resultierenden Ausgabe ist. Und das wiederum ermöglicht es dir, die Ausführung von diesem Punkt aus in einer nächsten Runde begrenzter Aufrufe fortzusetzen. Wir sagen daher, dass die Ausführung durch den QCM Quasi-Turing-Abschluss ist.

Beachte, dass, obwohl die Möglichkeit der Bereitstellung von Belohnungen als potenzieller Anreiz für die Verarbeitung besteht, es in Qubic nicht erforderlich ist, das Äquivalent der Ethereum-Gebühren für die Verarbeitung bereitzustellen. Es könnte andere Anreize geben, die genauso gut oder sogar besser funktionieren. Zum Beispiel, wenn eine Baugruppe speziell dafür ausgelegt ist, bestimmte Sensordaten zu aggregieren. Ein Prüfpfad oder sogar redundante Berechnungen könnten in einem solchen Fall Anreiz genug sein.

Virtuelle Maschine Abra

Das Abra VM-Programmiermodell ist insofern sehr ehrgeizig, als dass es uns nicht nur ein Programmiermodell zur Verfügung stellt, das Quasi-Turing-fähig gemacht werden kann, sondern es entfernt sich auch von Standard-Opcode-basierten sequentiellen Befehlen, die von einer komplexen CPU verarbeitet werden. Stattdessen bietet es uns eine maximale Parallelisierung von Operationen durch ein Datenflussmodell, das letztlich nur zwei Arten von Operationen hat, mit denen jede Funktion implementiert werden kann: Lookup-Tabellen (LUTs) und Fusionen. Diese Operationen wurden speziell wegen ihrer Fähigkeit ausgewählt, einfach direkt in der Schaltung instanziiert zu werden. Die maximale Parallelisierung von Operationen wird nur bei der Instantiierung in Schaltkreisen erreicht. Die einzigen sequentiellen Datenflusspfade werden durch Operationen gebildet, die direkt von den Ergebnissen früherer Operationen abhängen. Alles andere kann parallel ausgeführt werden. Sie erhalten also maximal parallele sequentielle Datenflusspfade.

Die Einfachheit des Abra VM-Programmiermodells bedeutet auch, dass es sehr einfach ist, einen Software-Emulator (Interpreter) zu erstellen, der diese VM auf einem Standardprozessor ausführen kann. In diesem Fall gehen viele Möglichkeiten der Parallelverarbeitung verloren, aber es werden trotzdem korrekte Verarbeitungsergebnisse geliefert. Für einfache SCs, die nur spärlich aufgerufen werden, könnten Sie also auf eine software-emulierte Abra-VM zurückgreifen. Wenn Sie jedoch Hardware-Beschleunigung benötigen, müssen Sie die VM tatsächlich in einer Schaltung implementieren. An dieser Stelle stellen wir uns drei Ebenen der Hardware-Implementierung vor.

Verwenden Sie vorhandene FPGAs, um die Abra-VM zu implementieren. Dies hat den Vorteil, dass Sie den VM-Schaltkreis nur einmal für jeden unterschiedlichen FPGA-Typ erstellen müssen und Sie anschließend beliebigen Abra-VM-Code auf einem solchen Gerät ausführen können. Allein diese Fähigkeit ist bahnbrechend. Derzeit benötigen Sie einen sehr leistungsfähigen PC, der lange Zeit läuft, um die Schaltung für ein Programm zu entwerfen, das auf einem bestimmten FPGA-Typ läuft. Und das ist etwas, das Sie jedes Mal tun müssen, wenn Sie etwas an Ihrem Programm ändern oder wenn Sie einen anderen FPGA-Typ anvisieren. Stattdessen layouten Sie jetzt die Schaltung für unsere Open Source Abra VM nur einmal für jeden FPGA-Typ. Danach können Sie das Programm, das Sie auf der VM ausführen möchten, einfach ändern, neu kompilieren, laden und auf jedem FPGA ausführen, der die Abra-VM ohne weitere Änderungen implementiert hat. Verwenden Sie ein ASIC, um die Abra-VM direkt zu implementieren. Das bedeutet, dass wir ein Open-Source-ASIC-Design für eine Abra-VM erstellen werden. Der Vorteil besteht darin, dass wir die Erstellung eines programmierbaren Bausteins vermeiden, der auf einem anderen (proprietären) programmierbaren Baustein (FPGA) läuft. Statt die Bausteine des FPGA zu programmieren, können wir direkt eine ASIC-Schaltung erstellen, die die Abra-VM implementiert. Das bedeutet nicht nur eine Geschwindigkeitssteigerung, sondern auch eine enorme Verringerung der erforderlichen Schaltungsmenge. Ein solcher Abra VM ASIC könnte leicht als Koprozessor für aktuelle Hardware oder als Hauptprozessor für bestimmte IoT-Anwendungen eingesetzt werden. Wenn Sie einen spezifischen Code für den Abra VM programmiert haben und überprüft haben, dass er korrekt funktioniert, könnten Sie auch einen ASIC erstellen, der die Operationen für diesen spezifischen Code als dedizierte Schaltung implementiert. Sie würden den allgemeinen Aspekt der Programmierbarkeit der VM-Implementierung verlieren, aber es gibt viele Anwendungsfälle, in denen Sie die einmal eingesetzte Hardware nie mehr ändern werden. Vor allem bei Sensoren und anderen Geräten, die Sie in Bereichen einsetzen, in denen Sie nach dem Einsatz nicht mehr so leicht darauf zugreifen können. Dies ist die IoT-Vision, auf die wir letztendlich hinarbeiten. Die Einfachheit der Operationen, aus denen sich der spezifische Programmcode zusammensetzt, macht die Erstellung eines ASICs relativ einfach. Und der generierte Schaltkreis erlaubt tatsächlich eine Reihe verrückter Optimierungen auf der Ebene der Logikgatter, da er keine programmierbaren Allzweck-Schaltkreise mehr verwendet.

Die wirklichen Verbesserungen des Abra-VM-Programmiermodells, wie der reduzierte Energiebedarf, die Aspekte des Datenflusses und die Möglichkeit des Wave-Pipelining werden diese letzte Implementierungsebene benötigen, um wirklich zu glänzen. Die allgemeineren programmierbaren Ebenen sind mit bestimmten Designeinschränkungen verbunden, die zusätzlichen „Overhead“ verursachen werden.

Ternäre Kodierung

Vielleicht ist Ihnen aufgefallen, dass in all dem oben Gesagten das Wort ternär noch nicht erwähnt wurde. Und natürlich wäre es möglich, diese gesamte Vision binär umzusetzen. Aber ein Teil der Qubic-Vision war schon immer die Fähigkeit, über die Grenzen der aktuellen Ausführungsmodelle hinauszugehen und die Hardware über das Mooresche Gesetz hinaus zu erweitern, das wohl ausgelaufen ist. Zu diesem Zweck haben wir immer die Vision eines ternären Ausführungsmodells gehabt. Auch wenn es noch keine nativen ternären Prozessoren gibt, kann dieses Modell dennoch einige Vorteile bieten. Die bemerkenswertesten unmittelbaren Vorteile sind: Datendichte und Berechnungsgeschwindigkeit.

Unser Programmiermodell arbeitet mit Schaltungen und daher mit der Informationseinheit der untersten Ebene. Bei binären Systemen wäre das nur ein bisschen. Aber das Abra-Datenflussmodell erfordert auch eine Darstellung der „Abwesenheit von Daten“ (Null), die für seinen Entscheidungslogikmechanismus entscheidend ist. Die normale Art und Weise, dies in binären Systemen darzustellen, wäre, ein zusätzliches Bit zu haben, um diesen Zustand anzuzeigen. Das bedeutet, dass jedes Informationsbit durch zwei Bits repräsentiert werden muss, um alle drei möglichen sich gegenseitig ausschließenden Zustände (0, 1 und null) kodieren zu können. Da aber 2 Bits 4 Zustände repräsentieren können, erscheint es nur natürlich, dies in vollem Umfang zu nutzen. Durch die Verwendung der ternären Kodierung benötigen wir immer noch nur 2 Bits, um die 4 sich gegenseitig ausschließenden Zustände (-, 0, 1 und null) darzustellen. Das bedeutet, dass wir Werte im Vergleich zur binären Kodierung, die sonst einen dieser 4 möglichen Zustände verschwenden würde, effizienter kodieren können. Im Vergleich zur ternären Kodierung benötigt die binäre Kodierung etwa 50% mehr 2-Bit-Informationseinheiten, um den gleichen Wertebereich darstellen zu können. Beispielsweise können 16 Bit Werte von -32768 bis +32767 kodieren, während nur 11 Trits bereits Werte von -88573 bis +88573 kodieren können.

Sobald Sie weniger Informationseinheiten zur Darstellung desselben Wertebereichs benötigen, sind auch bestimmte Berechnungen so viel schneller. Nehmen Sie zum Beispiel einen einfachen Ripple-Carry-Addierer. Um zwei Werte zu addieren, addiert er zwei entsprechende Informationseinheiten, was jedoch zu einem Übertrag auf die Addition der nächsten Einheit führen kann. Das heißt, wenn Sie 50% mehr Einheiten benötigen, um einen Wertebereich darzustellen, dauert die Ausführung einer solchen Addition ebenfalls 50% länger. Der Engpaß hierbei ist die Tatsache, daß jede Addition von der vorhergehenden Addition abhängt, da sie den Übertrag berücksichtigen muß. Die nächste Addition kann also erst dann erfolgen, wenn die vorhergehende vollständig ist und der Wert des Übertrags bekannt ist. Bringen Sie dies nun auf eine andere Ebene: die Multiplikation. Wenn Sie die einfache Methode verwenden, jede Einheit mit jeder Einheit zu multiplizieren, erhalten Sie eine zweidimensionale Abhängigkeit, was bedeutet, dass die Verarbeitungszeit bei Verwendung desselben Algorithmus mit binärer Kodierung 150% x 150% oder 225% der Zeit benötigt, die der Algorithmus bei Verwendung einer ternären Kodierung benötigen würde.

Die ternäre Kodierung, die wir für unsere Prototyp-FPGA-Implementierung verwendet haben, nennen wir 2b-Kodierung. Diese kodiert die 4 Zustände (-, 0, 1 und null) jeweils als (10, 11, 01 und 00). Wir nennen diese 2b-Kodierung, weil sie, wie oben diskutiert, 2 Bits pro Informationseinheit verwendet. Wir haben auch eine Alternative entwickelt, die wir 3b-Kodierung nennen, die 3 Bits pro Informationseinheit verwendet und die 4 Zustände jeweils als (100, 010, 001 und 000) kodiert. Die 3b-Kodierung mag vielleicht verschwenderischer erscheinen, aber sie hat eine Reihe interessanter Eigenschaften, die für die dritte Ebene der Hardware-Implementierung (direkter Code zur Schaltung) von größerer Bedeutung sind und in Zukunft noch eingehender untersucht werden sollen. Der Abra-Code ist völlig unabhängig von der verwendeten Kodierung. Die tatsächlich verwendete Kodierung wird letztlich von der spezifischen Implementierung der Abra-VM diktiert.

Sowohl die 2b- als auch die 3b-Kodierung verwenden alle Nullen, um den Nullzustand zu kodieren. Dies sollte dazu beitragen, den Energiebedarf der Hardware zu reduzieren, da der Null-Zustand der Standardzustand für alle Schaltkreise ist und normalerweise die meiste Energie darauf verwendet wird, den Zustand zu ändern. Abra ist so konzipiert, dass Entscheidungspfade so früh wie möglich zur Verwendung des Null-Zustands gezwungen werden, so dass keine Daten durch den größten Teil der Schaltung wandern und nicht verwendete Schaltungen ohne Umschalten im Standard-Null-Zustand bleiben können.

„Echte“ ternäre Hardware

Wie die Kodierung auf tatsächlich nativer ternärer Hardware aussehen wird, ist derzeit schwer vorstellbar, da wir noch kein funktionierendes ternäres System haben, mit dem wir arbeiten könnten. Eine interessante Idee, die aus der Qubic-Forschung hervorging, ist, dass man, da ternäre Prozessoren angeblich mit 3 Zuständen arbeiten, ein binäres Bit und den erforderlichen Nullzustand mit einem einzigen ternären Trit kodieren könnte. Dies würde bedeuten, dass ternäre Hardware unser Datenflussmodell direkt mit binärer Informationskodierung unterstützen kann. Anstatt also 2 Leitungen und alle zugehörigen Schaltkreise pro Leitung zu benötigen, um ein Bit und ein Null-Flag darzustellen, würden Sie nur eine einzige Leitung und die zugehörigen Schaltkreise benötigen, wodurch vielleicht sogar die Schaltungstechnik/Energie halbiert würde, die sonst für die gleiche binär codierte Verarbeitung in binärer Hardware erforderlich wäre. Ternäre Hardware ist derzeit in erster Linie eine Denksportaufgabe, aber es ist definitiv ein aufregendes Unterfangen für die Zukunft.

Hardware-Operationen

Das Abra-Programmiermodell hat ursprünglich 5 verschiedene explizite Operationen. 3 dieser Operationen reduzieren sich auf eine einfache Verdrahtung, sobald man sie auf Schaltungsebene implementiert. Sie sind nur notwendig, um Informationen als Trit-Vektoren zu gruppieren und weiterzugeben. Da aber auf der Schaltungsebene alles auf einzelnen Trits arbeitet, sind diese Trit-Vektoren meist konzeptionell. Daher erzwingen die Verkettungs- und Slicing-Operationen lediglich die korrekte Gruppierung von Informationen. Die Aufrufoperation ist nur vorhanden, um den Code effizient in einen Aufrufbaum zu reduzieren, aber sobald sie in einer Schaltung implementiert ist, erzwingt jede Aufrufoperation die Instantiierung des gesamten aufgerufenen Funktionsbaums in der Schaltung und verknüpft die Eingangs- und Ausgangs-Trit-Vektoren mit ihren Quell- und Zielvektoren.

Damit bleiben nur noch 2 Operationen übrig, die tatsächlich als logische Schaltung implementiert werden. Die erste ist die ternäre Lookup-Operation, die 3 Eingangstrits nimmt und einen einzelnen Trit gemäß der entsprechenden Lookup-Tabelle ausgibt. Die zweite ist die Merge-Operation, die getrennte Datenfluss-Eingänge zu einem einzigen Ausgang kombiniert und entweder als eine sehr spezielle Lookup-Operation oder durch Verwendung einfacher ODER-Gatter implementiert werden kann. Nur eine Eingabe darf ungleich Null sein und wird zur Ausgabe. Die Sprache Qupla, die den Abra-Code generiert, stellt sicher, dass nur ein Pfad ungleich Null sein kann. Alle anderen Werkzeuge, die direkt Abrac-Code erzeugen würden, sind erforderlich, um dies sicherzustellen.

Der FPGA-Konzeptnachweis

Um das Programmiermodell auf FPGA zu erleichtern, haben wir den FPGA so programmiert, dass er eine Bank von so genannten QLUTs (Qubic Look-Up Tables) bereitstellt. Jeder QLUT nimmt drei 2b-kodierte Trits als Eingabe und gibt dann einen weiteren 2b-kodierten Trit über eine konfigurierbare Nachschlagetabelle aus. Fusionen werden innerhalb der QLUTs durch Setzen eines speziellen Konfigurationsbits implementiert, das sie veranlasst, eine vordefinierte Lookup-Operation mit leicht unterschiedlicher Semantik zu verwenden.

Natürlich enthält der FPGA auch die zusätzliche Konfigurationslogik, die notwendig ist, um jede Eingangsoperation mit jeder Ausgangsoperation verbinden zu können. Diese Logik kann durch eine spezielle binäre Konfigurationsdatei konfiguriert werden, die leicht direkt aus dem auszuführenden VM-Code generiert werden kann. Der Code wird derzeit „on the fly“ konvertiert, wenn er an den FPGA gesendet wird. Sie enthält die Konfigurationsdaten für jedes einzelne QLUT und die Konfigurationsdaten für die Verbindungen zwischen den QLUTs.

Die QLUTs wurden bereits getestet, indem die gesamte Qupla-Testsuite im Emulator ausgeführt wurde, während eine bestimmte Funktion hardwarebeschleunigt wurde. Wir erlauben dem Benutzer, eine Funktion als hardwarebeschleunigt zu markieren, und die Qupla-Umgebung lädt automatisch die Konfigurationsdaten für diese Funktion in den FPGA. Wenn der Emulator dann den Emulator ausführt, übergibt er jedes Mal, wenn er auf diese spezifische Funktion trifft, die Eingangsdaten der Funktion an das FPGA und verwendet die resultierenden Ausgangsdaten, anstatt das Ergebnis für diese Funktion vom Emulator berechnen zu lassen. Wir haben mehrere repräsentative Funktionen auf diese Weise getestet und freuen uns, berichten zu können, dass dies perfekt funktioniert.

Als Nächstes benötigen wir eine FPGA-Version des Qubic Supervisors, d.h. der Entität, die Eingangsdatenereignisse an den korrekten VM-Code sendet und die berechneten Ergebnisse weiterleitet. Um zu vermeiden, dass wir ein Miniaturbetriebssystem schreiben müssen, werden wir zunächst eine einfache Embedded-Linux-Version verwenden, die auf einer CPU laufen kann, die auf dem FPGA eingebettet ist. Auf diese Weise können wir bestimmte Funktionen out of the box nutzen, ohne sie selbst entwickeln zu müssen. Wir haben es geschafft, dieses Linux bereits auf dem FPGA zu booten und es zu benutzen, um die Kommunikation zwischen dem Emulator und dem FPGA über ein einfaches Socket-Protokoll abzuwickeln. Der nächste Schritt wird die Implementierung des Supervisors und einiger zusätzlicher Glue-Code sein, um stattdessen die Kommunikation mit der Außenwelt über HTTP zu ermöglichen.

Der nächste Schritt wäre die Implementierung eines HTTP-Listeners auf dem Embedded-Linux des FPGAs, der auf zwei Arten von Anfragen reagieren kann. Der erste Anfragetyp kann verwendet werden, um die Konfigurationsdatei auf den FPGA zu übertragen, und dieser wird dann zur Konfiguration des Programmiermodells, zur Einrichtung einer HTTP-Callback-Adresse und zur Initialisierung des Supervisors verwendet. Der zweite Anforderungstyp ist eine Eingabedatenanforderung, die verwendet werden kann, um die Ausführung einer Funktion mit den vom Supervisor bereitgestellten Eingabedaten auszulösen. Nach der Berechnung des Ergebnisses sendet der Supervisor die resultierenden Ausgabedaten asynchron an die HTTP-Callback-Adresse.

Beachten Sie, dass dies bedeutet, dass der anfängliche End-to-End-Konzeptnachweis (Qupla-to-FPGA, der ursprünglich für Ende Januar 2020 geplant war) noch nicht die volle Supervisor-Funktionalität haben wird, sondern nur in der Lage sein wird, eine einzige beliebige Funktion auf dem FPGA einzurichten und aufzurufen und das Ergebnis zurückzugeben. Das Laden und Aufrufen mehrerer Funktionen und komplexere Planung durch EEE wird der nächste Schritt für die Implementierung im Supervisor-Code sein.

Auf der Softwareseite ist der Qupla-Compiler jetzt in der Lage, eine spezifische Version des Abra-Codes zu erzeugen, die leichter eine 1-zu-1-Konvertierung in die binäre Konfigurationsdatei ermöglicht, indem alle Verkettungs-, Slice- und Aufrufoperationen eliminiert werden. Wir haben überprüft, dass der resultierende transformierte Code immer noch korrekt funktioniert, indem wir die Testsuite mit diesem Code im Emulator ausgeführt haben. Der Emulator selbst ist nun in der Lage, über die Socket-Schnittstelle eine Schnittstelle zum FPGA herzustellen. Er sendet die generierte Konfigurationsdatei an das FPGA und ruft diese Funktion bei Bedarf auf. In Zukunft wird der Qupla-Supervisor in der Lage sein, Ereignisse über die HTTP-Schnittstelle zum und vom FPGA zu senden.

Erste Lehren aus dem PoC

Bis jetzt funktioniert alles wie vorgesehen. Wir haben ein völlig neues Verarbeitungsmodell geschaffen, das jede Art von allgemeiner Verarbeitung durchführen kann. Das Modell behandelt die RAM-Speicherung genauso wie jede andere Art von E/A, d.h. es liegt außerhalb des Geltungsbereichs des Abra-Codes und wird an Entitäten weitergegeben, die Daten für uns mit Hilfe von EEE speichern/abrufen können. Dies erfordert eine andere Art der Problembetrachtung, und es wird wichtig sein, die resultierende Komplexität zu bewerten und/oder zu sehen, ob es eine Möglichkeit gibt, die Komplexität in Qupla-Sprachkonstrukten zu verbergen, oder ob eine noch höhere Computersprache erforderlich ist. So wurde beispielsweise bereits die Notwendigkeit einer Art von Schleifenkonstrukt gesehen.

Zwei unmittelbare Hürden zeichnen sich derzeit ab und erfordern eine Lösung:

Der derzeitige Ressourcenbedarf der QLEs auf dem ausgewählten FPGA (DE10-Nano) begrenzt uns auf insgesamt nur 512 QLEs. Dies mag ein wenig optimiert werden, aber wir erwarten nicht, dass sich dieser Bedarf auf mehr als etwa das Doppelte erhöht. Natürlich könnten wir einen größeren, teureren FPGA auswählen, aber für das Prototyping wollen wir es einfach und erschwinglich halten für Leute, die unsere Anstrengungen verdoppeln und damit herumspielen möchten. Eine direkte Folge davon ist, dass wir nur einige kleinere Funktionen auf den FPGA laden können, und der Kommunikations-Overhead beim Aufruf dieser Funktionen überwiegt meist den Verarbeitungsgewinn. Das war zu erwarten, und wir hoffen, dass wir, sobald wir zum nächsten Schritt übergehen, einem ASIC Abra VM, Größenordnungen darüber hinaus gehen können. Die Instantiierung von Funktionsaufrufen wird sehr schnell unerschwinglich. Aufgrund der „Call-Tree-Natur“ des Codes hat die Expansion eines solchen Aufrufbaums ein exponentielles Wachstum. Wenn X dreimal Y aufruft, was wiederum viermal Z aufruft, erhalten Sie drei vollständige Y-Instanziierungen, die 3×4 oder 12 vollständige Z-Instanziierungen verursachen. Sie können sehen, wie schnell dies eskaliert. Die Lösung dieses Problems wird unser Hauptaugenmerk sein müssen. Derzeit schwirren einige Ideen herum, aber wir haben uns noch nicht mit allen Konsequenzen für das Datenflussmodell befasst.

Übrigens leidet der Abra-Emulator nicht unter diesen Problemen, da er die Funktionsinstantiierung durch einen gewöhnlichen stapelbasierten Funktionsaufrufmechanismus emuliert und die Lookup-Tabellen in einem von den Lookup-Anweisungen getrennten Speicher ablegt. Heutige Gigabyte RAM-Größen würden Millionen von Abra VM-Befehlen ohne Probleme ermöglichen.

Schlussfolgerung

Nach einem langen Weg mit vielen unvorhergesehenen Hürden haben wir bewiesen, dass das Abra-Datenflussprogrammiermodell durchgängig funktioniert, von der Programmiersprache Qupla bis zur Ausführung des generierten Codes auf dedizierter FPGA-Hardware. Wir laden alle ein, mit dem Qupla-Repository herumzuspielen und zu sehen, was Qupla kann und wie es im Emulator läuft. Diejenigen, die sich mehr für Hardware interessieren, können mit dem Qubic HDL-Repository herumspielen und tatsächlich Code auf einem DE10-Nano ausführen, so wie wir es tun, oder sogar den Code an Ihr eigenes bevorzugtes FPGA-System anpassen.

Eine neue Richtung für intelligente Verträge auf IOTA

Auch wenn diese Arbeit die Vision hinter Qubic beweist und einen großen Schritt nach vorn darstellt, sind noch weitere Fragen zu lösen und es sind noch erhebliche Entwicklungsinvestitionen erforderlich, um Qubic produktionsreif zu machen. Unsere umfangreiche Arbeit an Qubic hat viel wertvolle Forschung und Entwicklung hervorgebracht und bildet die Grundlage für unseren weiteren Ansatz. Dementsprechend hat die IOTA-Stiftung die Entscheidung getroffen, die Entwicklung von Qubic einzustellen und unseren Schwerpunkt speziell auf die Ebene der intelligenten Verträge zu legen.

Der Hauptgrund für diese Entscheidung besteht darin, dass IOTA mit einer neuartigen intelligenten Vertragslösung, die in Verbindung mit der Coordicide-Knotenpunkt-Software arbeitet, schneller auf den Markt kommen kann. Am Ende verfügen wir über ein komplettes System – bereit für eine breitere und schnellere Einführung.

IOTA Smart Contracts ist das, was wir unsere intelligente Layer-2-Vertragslösung nennen. Sie ist aus der in diesem Beitrag beschriebenen Arbeit hervorgegangen und wurde von Grund auf neu konzipiert. Mit IOTA Smart Contracts wollen wir eine Vision für intelligente Verträge verfolgen, die skalierbar sind und niedrige Transaktionskosten haben.

Wir arbeiten derzeit an einer Alpha-Version von IOTA Smart Contracts durch die GoShimmer-Implementierung, und wir werden in Kürze weitere Informationen über diesen neuen Weg veröffentlichen. Wenn die Alpha-Version fertig ist, wird sie von einer Reihe einfacher intelligenter Vertrags-PoCs begleitet werden, um Gemeinschaftsentwickler auf den Weg zu bringen und zu demonstrieren, was möglich ist, um eine neue Ära von Anwendungen auf der Grundlage von IOTA anzustoßen.

Fühlen Sie sich frei, unser Ingenieursteam direkt in den Smart Contract-Kanälen über den IOTA-Discord zu erreichen und Fragen zu diesem neuen Weg, den wir beschreiten, zu stellen.

Spenden: OOXKDDPERSTNHSCQGYDYEWGDRLQEUZCIBDLYCDKSKIHGWAG9WFPVDVSRAUN9GDUOJ9INP9LMSMHYKNLNCOKMGFBZFA

Teilen mit: Twitter

Facebook

Reddit

Telegram

Tumblr

LinkedIn

Pinterest

