Ein ICO-Beispiel auf Ergo

This page is machine-translated.
Alex Chepurnoy

10. April 2019

Dieser Artikel beschreibt ein voll funktionsfähiges ICO (Initial Coin Offering), das in ErgoScript implementiert ist. Das Beispiel behandelt mehrere wichtige und neuartige Funktionen der Ergo-Plattform und zeigt, wie sie komplexe Verträge mit minimalem Code unterstützen kann.

Teil 1. Vorbereitungen

Eine wichtige Designentscheidung in einem Kryptowährungsprotokoll besteht darin, festzulegen, was eine Ausgaben-Transaktion tatsächlich ausgibt. Es gibt hier zwei Möglichkeiten. Die erste ist ein UTXO-basiertes Modell, wie bei Bitcoin, bei dem eine Transaktion einmalige Vermögenscontainer (genannt 'Münzen' oder UTXOs in Bitcoin) ausgibt und neue erstellt. Die andere ist ein kontobasiertes Modell, wie bei Nxt, Ethereum oder Waves, bei dem eine Transaktion einen bestimmten Betrag von Vermögenswerten von einem bestehenden, langfristigen Konto auf ein anderes, möglicherweise neues, langfristiges Konto überträgt, mit möglichen Nebenwirkungen auf dem Weg, wie z.B. der Ausführung von Verträgen in Waves oder Ethereum. In dieser Hinsicht ist Ergo Bitcoin ähnlich, da es den UTXO-basierten Ansatz verwendet, bei dem einmalige Container, die als Boxen bezeichnet werden, ausgegeben werden. Interessanterweise kann eine Ergo-Transaktion auch Daten-Eingaben haben, die nicht ausgegeben werden, sondern vielmehr dazu verwendet werden, Informationen aus dem aktuellen Satz ungenutzter Boxen bereitzustellen.

Es ist nicht trivial, ein ICO auf einem UTXO-basierten Modell zu erstellen, da es im Gegensatz zu kontobasierten Modellen hier keinen expliziten persistenten Speicher gibt. Ergo bringt jedoch eine Ausgaben-Transaktion in den Ausführungskontext eines Skripts.
Mit dieser kleinen Änderung wird es möglich, Abhängigkeiten zwischen Transaktionsausgaben und -eingaben auszudrücken. Indem wir Abhängigkeiten festlegen, können wir sogar beliebig komplexe, Turing-vollständige Programme auf der Blockchain ausführen (siehe das "Selbstreproduzierende Münzen als universelle Turing-Maschine"-Papier). In diesem Artikel werden wir ein konkretes Szenario eines mehrstufigen Vertrags unter Verwendung eines ICO definieren, bei dem wir drei Phasen haben (Finanzierung, Token-Ausgabe, Abhebung).

Stellen Sie sich nun ein ICO für Tausende von Teilnehmern vor. Im Gegensatz zu Ethereum bietet Ergo nicht die Möglichkeit, große Datenmengen zu speichern und sie während der Vertragsausführung zu übertragen. Vielmehr erlaubt es nur, etwa 40 Bytes Header einer Datenstruktur zu speichern, die als Schlüssel -> Wert-Dictionary dargestellt wird, ähnlich wie ein Merkle-Baum authentifiziert. Um auf einige Elemente im Dictionary zuzugreifen oder es zu ändern, sollte eine Ausgaben-Transaktion, die die Ausführung des schützenden Skripts auslöst, Nachweis- oder Änderungsbeweise bereitstellen. Dies ermöglicht es einem Vertrag, potenziell riesige Datensätze zu authentifizieren, ohne viel Speicher für den Vertragsstatus zu benötigen. Das Speichern von Platz im Status (aktiver Verträge) würde jedoch größere Transaktionen bedeuten, aber dieses Problem ist aus Sicht der Skalierbarkeit einfacher, und Skalierbarkeit hat für Ergo oberste Priorität.

Teil 2. Der ICO-Vertrag

Es könnte viele mögliche Szenarien im Zusammenhang mit einem Initial Coin Offering (ICO) geben. In diesem Artikel betrachten wir ein ICO, das mindestens einen bestimmten Betrag an Mitteln (in Ergs) sammeln möchte, um das Projekt zu starten. Sobald die Finanzierungsgrenze überschritten ist und die Finanzierungsperiode endet, wird das Projekt gestartet und ICO-Token werden vom Projekt basierend auf der insgesamt gesammelten Finanzierung ausgegeben. In der Abhebungsphase, die für immer andauert, ziehen die Investoren ICO-Token basierend auf dem Betrag ab, den sie während der Finanzierungsperiode investiert haben. Die Schritte des Vertrags werden kurz beschrieben, mit weiteren Details:

  • Zuerst findet die Finanzierungs-Epoche statt. Sie beginnt mit einer Box des Projekts, die ein leeres Dictionary authentifiziert. Das Dictionary ist dazu gedacht, (Investor, Bilanz)-Paare zu halten, wobei der Investor ein Skript ist, das die Box mit den abgehobenen Token schützt. Für die Bilanz nehmen wir an, dass 1 Token während des ICO 1 Ergo entspricht. Während der Finanzierungs-Epoche ist es nur möglich, Ergs in die Box des Projekts einzuzahlen.
    Eine Finanzierungs-Transaktion gibt die Box des Projekts aus und erstellt eine neue Projektbox mit aktualisierten Informationen. Dazu hat eine Ausgaben-Transaktion für die Box des Projekts auch andere Eingaben, die die abhebenden Skripte der Investoren halten. Die Skripte der Investoren und die Eingabewerte sollten dem Baum der neuen Box hinzugefügt werden. Es könnte viele verkettete Finanzierungs-Transaktionen geben.
  • Zweitens endet die Finanzierungsperiode, nach der der Baum, der die Daten der Investoren hält, schreibgeschützt wird. Ein authentifizierter Baum könnte unterschiedliche Modifikationsoperationen individuell zulassen: Einfügungen, Löschungen, Aktualisierungen oder alle Operationen könnten untersagt werden (so könnte der Baum im schreibgeschützten Modus sein). Außerdem erstellt diese Transaktion Token des ICO-Projekts, die in der nächsten Phase abgehoben werden. Das Projekt kann in dieser Phase Ergs abheben.
  • Drittens ziehen die Investoren ihre ICO-Token ab. Dazu erstellt eine Ausgaben-Transaktion Ausgaben mit Schutzbedingungen und Token-Werten, die aus dem Baum entnommen werden. Die abgehobenen Paare werden ebenfalls aus dem Baum gelöscht. Es könnte viele verkettete Ausgaben-Transaktionen geben.

Diese drei Phasen sollten in logischer Reihenfolge miteinander verknüpft werden. Eine Sequenz von Boxen wird verwendet, um diese Ziele zu erreichen.

Teil 3. Die Details des ICO-Vertrags

Jetzt ist es an der Zeit, die Details und den ErgoScript-Code der Phasen des ICO-Vertrags bereitzustellen.

Die Finanzierungsphase

In der Finanzierungsphase, die zuerst kommt, nehmen wir an, dass ein Projekt zunächst eine Box erstellt, die sich zu einem leeren Dictionary (gespeichert im Register R5) mit einem bestimmten Schutzskript verpflichtet, das unten beschrieben wird. Diese Phase dauert mindestens bis zur Höhe von 2.000. Genauer gesagt sollte die erste Transaktion mit einer Höhe von 2.000 oder mehr das Skript der Ausgabebox ändern, wie im nächsten Abschnitt beschrieben (Transaktionen mit niedrigeren Höhen müssen eine Box mit demselben Skript ausgeben).

Die Box des Projekts überprüft, dass sie immer die erste Eingabe und Ausgabe einer Transaktion ist. Die anderen Eingaben werden als Eingaben der Investoren betrachtet. Eine Eingabe eines Investors enthält den Hash eines Skripts im Register R4. Dieser Hash repräsentiert das Abhebungs-Skript, das später in der Abhebungsphase verwendet wird. Die Hashes sowie die monetären Werte aller Investitionseingaben sollten dem Dictionary hinzugefügt werden. Die
Ausgaben-Transaktion liefert einen Nachweis, dass die Daten des Investors tatsächlich dem Dictionary hinzugefügt wurden, und der Nachweis wird im Vertrag überprüft.

Es wird im Finanzierungsuntervertrag nicht überprüft, dass das Dictionary nur Einfügungen erlaubt und keine bestehenden Werte oder Löschungen aktualisiert (es ist jedoch nicht schwer, eine explizite Überprüfung hinzuzufügen).

Die Ausgaben-Transaktion sollte eine Gebühr zahlen, andernfalls ist es unwahrscheinlich, dass sie in einen Block aufgenommen wird. Daher überprüft der Finanzierungsvertrag, dass die Ausgaben-Transaktion zwei Ausgaben hat (eine für sich selbst, eine andere zur Zahlung der Gebühr), die Gebühr darf nicht mehr als ein bestimmtes Limit betragen (nur ein NanoErg in unserem Beispiel), und die schützende Proposition sollte so sein, dass nur ein Miner die Ausgabe ausgeben kann (wir verwenden in unserem Beispiel nur eine Variable "feeProp" aus der Kompilierungsumgebung, ohne weitere Details bereitzustellen). Dieses "feeProp" entspricht einem Standard, der jedoch nicht vom Protokoll gefordert wird.

Der folgende Code setzt die oben beschriebenen Bedingungen durch. Bitte beachten Sie, dass die
"nextStageScriptHash"-Umgebungsvariable den Hash des serialisierten Skripts der Ausgabephase enthält.

    val selfIndexIsZero = INPUTS(0).id == SELF.id

    val proof = getVar[Coll[Byte]](1).get

    val inputsCount = INPUTS.size

    val toAdd: Coll[(Coll[Byte], Coll[Byte])] = INPUTS.slice(1, inputsCount).map({ (b: Box) =>
        val pk = b.R4[Coll[Byte]].get
        val value = longToByteArray(b.value)
        (pk, value)
    })

    val modifiedTree = SELF.R5[AvlTree].get.insert(toAdd, proof).get

    val expectedTree = OUTPUTS(0).R5[AvlTree].get

    val properTreeModification = modifiedTree == expectedTree

    val outputsCount = OUTPUTS.size == 2

    val selfOutputCorrect = if(HEIGHT < 2000) {
        OUTPUTS(0).propositionBytes == SELF.propositionBytes
    } else {
        blake2b256(OUTPUTS(0).propositionBytes) == nextStageScriptHash
    }

    val feeOutputCorrect = (OUTPUTS(1).value <= 1) && (OUTPUTS(1).propositionBytes == feeBytes)

    val outputsCorrect = outputsCount && feeOutputCorrect && selfOutputCorrect

    selfIndexIsZero && outputsCorrect && properTreeModification

Die Ausgabephase

Diese Phase hat nur eine Ausgaben-Transaktion, um zur nächsten Phase (der Abhebungsphase) zu gelangen. Die Ausgaben-Transaktionen nehmen die folgenden Änderungen vor. Erstens ändert sie die Liste der erlaubten Operationen im Dictionary von "nur Einfügungen" zu "nur Löschungen", da die nächste Phase (Abhebung) nur mit dem Entfernen von Einträgen aus dem Dictionary zu tun hat.

Zweitens überprüft der Vertrag, dass die richtige Menge an ICO-Token ausgegeben wird. In Ergo ist es erlaubt, pro Transaktion eine neue Art von Token auszugeben, und der Bezeichner des Tokens sollte gleich dem (einzigartigen) Bezeichner der ersten Eingabebox sein. Der Ausgabeuntervertrag überprüft, dass ein neuer Token ausgegeben wurde und die Menge davon gleich der Menge an NanoErgs ist, die bis jetzt vom ICO gesammelt wurden.

Drittens überprüft der Vertrag, dass eine Ausgaben-Transaktion tatsächlich die Box mit dem Schutzskript, das der nächsten Phase, der Abhebungsphase, entspricht, neu erstellt.

Schließlich sollte das Projekt die gesammelten Ergs abheben, und natürlich sollte jede Ausgaben-Transaktion eine Gebühr zahlen. Daher überprüft der Untervertrag, dass die Ausgaben-Transaktion tatsächlich 3 Ausgaben hat (eine für die Projekt-Token-Box, die Ergs-Abhebungs-Box und die Gebühr-Box) und dass die erste Ausgabe die ausgegebenen Token trägt. Da wir keine Details zur Abhebung von Projektgeldern angeben, verlangen wir eine Unterschrift des Projekts auf der Ausgaben-Transaktion.

    val openTree = SELF.R5[AvlTree].get
    
    val closedTree = OUTPUTS(0).R5[AvlTree].get
    
    val digestPreserved = openTree.digest == closedTree.digest
    val keyLengthPreserved = openTree.keyLength == closedTree.keyLength
    val valueLengthPreserved = openTree.valueLengthOpt == closedTree.valueLengthOpt
    val treeIsClosed = closedTree.enabledOperations == 4
    
    val tokenId: Coll[Byte] = INPUTS(0).id
    
    val tokensIssued = OUTPUTS(0).tokens(0)._2
    
    val outputsCountCorrect = OUTPUTS.size == 3
    val secondOutputNoTokens = OUTPUTS(0).tokens.size == 1 && OUTPUTS(1).tokens.size == 0 && OUTPUTS(2).tokens.size == 0
    
    val correctTokensIssued = SELF.value == tokensIssued
    
    val correctTokenId = OUTPUTS(0).R4[Coll[Byte]].get == tokenId && OUTPUTS(0).tokens(0)._1 == tokenId
    
    val valuePreserved = outputsCountCorrect && secondOutputNoTokens && correctTokensIssued && correctTokenId
    val stateChanged = blake2b256(OUTPUTS(0).propositionBytes) == nextStageScriptHash
    
    val treeIsCorrect = digestPreserved && valueLengthPreserved && keyLengthPreserved && treeIsClosed
    
    projectPubKey && treeIsCorrect && valuePreserved && stateChanged

Die Abhebungsphase

In dieser Phase dürfen die Investoren Projekt-Token abheben, die durch ein vordefiniertes Schutzskript geschützt sind (dessen Hash im Dictionary gespeichert ist). Angenommen, die Abhebung erfolgt in Chargen der Größe N. Eine abhebende Transaktion hat somit N + 2 Ausgaben, wobei die erste Ausgabe den Abhebungsuntervertrag und die Bilanz-Token trägt, die letzte Ausgabe die Gebühr zahlt und die verbleibenden N Ausgaben Schutzskripte und Token-Werte gemäß dem Dictionary haben. Der Vertrag erfordert zwei Nachweise für die Dictionary-Elemente: einen, der beweist, dass die abzuhobenden Werte tatsächlich im Dictionary sind, und den zweiten, der beweist, dass das resultierende Dictionary die abgehobenen Werte nicht mehr enthält. Der Untervertrag ist unten.

    val removeProof = getVar[Coll[Byte]](2).get
    val lookupProof = getVar[Coll[Byte]](3).get
    val withdrawIndexes = getVar[Coll[Int]](4).get

    val out0 = OUTPUTS(0)

    val tokenId: Coll[Byte] = SELF.R4[Coll[Byte]].get

    val withdrawals = withdrawIndexes.map({(idx: Int) =>
        val b = OUTPUTS(idx)
        if(b.tokens(0)._1 == tokenId) {
            (blake2b256(b.propositionBytes), b.tokens(0)._2)
        } else {
            (blake2b256(b.propositionBytes), 0L)
        }
    })

    val withdrawValues = withdrawals.map({(t: (Coll[Byte], Long)) => t._2})

    val withdrawTotal = withdrawValues.fold(0L, { (l1: Long, l2: Long) => l1 + l2 })

    val toRemove = withdrawals.map({(t: (Coll[Byte], Long)) => t._1})

    val initialTree = SELF.R5[AvlTree].get

    val removedValues = initialTree.getMany(toRemove, lookupProof).map({(o: Option[Coll[Byte]]) => byteArrayToLong(o.get)})
    val valuesCorrect = removedValues == withdrawValues

    val modifiedTree = initialTree.remove(toRemove, removeProof).get

    val expectedTree = out0.R5[AvlTree].get

    val selfTokensCorrect = SELF.tokens(0)._1 == tokenId
    val selfOutTokensAmount = SELF.tokens(0)._2
    val soutTokensCorrect = out0.tokens(0)._1 == tokenId
    val soutTokensAmount = out0.tokens(0)._2

    val tokensPreserved = selfTokensCorrect && soutTokensCorrect && (soutTokensAmount + withdrawTotal == selfOutTokensAmount)

    val properTreeModification = modifiedTree == expectedTree

    val selfOutputCorrect = out0.propositionBytes == SELF.propositionBytes

    properTreeModification && valuesCorrect && selfOutputCorrect && tokensPreserved

Mögliche Verbesserungen

Bitte beachten Sie, dass es viele Nuancen gibt, die unser Beispielvertrag ignoriert. Zum Beispiel darf jeder, der die Blockchain überwacht, den Vertrag ausführen und ordnungsgemäße Ausgaben-Transaktionen während der Finanzierungs- und Abhebungsphasen erstellen. In der realen Welt kann eine zusätzliche Unterschrift des Projekts oder eines vertrauenswürdigen Schiedsrichters verwendet werden.

Außerdem wird im Abhebungsvertrag kein Selbstzerstörungsfall berücksichtigt, sodass er bis zu seiner Zerstörung durch Miner über das Speicher-Mietmechanismus potenziell Jahrzehnte oder sogar Jahrhunderte überdauern kann. Für die Finanzierungsphase wäre es sinnvoll, einen zusätzlichen Input vom Projekt mit einem Wert gleich dem Wert der Gebühr-Ausgabe zu haben. Und so weiter.

Share post

Ergo Infrastructure DAO: Dezentralisierung des Rückgrats des Ergo-Ökosystems

Ergo Infrastructure DAO: Dezentralisierung des Rückgrats des Ergo-Ökosystems

Die Mission von Ergo war schon immer in der Dezentralisierung verwurzelt, nicht nur auf der Konsensschicht, sondern über den gesam.

Ergo Platform

13. August 2025

Mew Finance: Ein verspieltes DeFi-Toolkit für das Ergo-Ökosystem

Mew Finance: Ein verspieltes DeFi-Toolkit für das Ergo-Ökosystem

Mew Finance ist eine dezentrale Anwendungs-Suite auf der Ergo-Blockchain.

Ergo Platform

12. August 2025

Lithos: Dezentralisierung des Minings mit On-Chain-Pools

Lithos: Dezentralisierung des Minings mit On-Chain-Pools

Lithos ist ein neues Protokoll, das darauf abzielt, die Funktionsweise von Mining-Pools zu revolutionieren, indem es sie on-chain .

Ergo Platform

24. Juli 2025

Sigma 6.0: Ein intelligenteres, flexibleres Ergo

Sigma 6.0: Ein intelligenteres, flexibleres Ergo

Sigma 6.0 ist ein bedeutendes vorgeschlagenes Upgrade für die Ergo-Blockchain.

Ergo Platform

23. Juli 2025

Die Zukunft von Rosen gestalten: Ein Gemeinschaftsaufruf zu fünf wichtigen Treasury-Vorschlägen

Die Zukunft von Rosen gestalten: Ein Gemeinschaftsaufruf zu fünf wichtigen Treasury-Vorschlägen

Der Mitbegründer von Rosen, Armeanio, hat fünf neue Vorschläge an die Rosen Treasury eingereicht.

Ergo Platform

9. Juli 2025

Ergos erweitertes UTXO und der Aufstieg der künstlichen wirtschaftlichen Intelligenz

Ergos erweitertes UTXO und der Aufstieg der künstlichen wirtschaftlichen Intelligenz

Eine praktische Vision für autonome wirtschaftliche Agenten Autonome wirtschaftliche Agenten auf der Ergo-Blockchain leisten nütz.

Ergo Platform

12. Mai 2025

ErgoHACK X: Künstliche Intelligenz auf der Ergo-Blockchain

ErgoHACK X: Künstliche Intelligenz auf der Ergo-Blockchain

Feier eines Jahrzehnts dezentraler Innovation Feiern Sie das 10-jährige Jubiläum von ErgoHACK und seien Sie an der Spitze der KI-R.

Ergo Platform

10. April 2025

Ergohack 9: Innovationen in UI/UX und Mining – Lernen Sie die visionären Gewinner kennen!

Ergohack 9: Innovationen in UI/UX und Mining – Lernen Sie die visionären Gewinner kennen!

Der letzte jährliche Ergo-Hackathon, ErgoHack IX, war eine sechstägige Veranstaltung, die Ende Oktober stattfand.

Ergo Platform

9. Dezember 2024

ErgoHack IX: Nächste Schritte zur erhöhten Akzeptanz

ErgoHack IX: Nächste Schritte zur erhöhten Akzeptanz

Wir haben einen langen Weg seit den frühen Tagen von Bitcoin zurückgelegt, und Kryptowährungen haben sich zu einer Branche mit Tau.

Ergo Platform

20. Oktober 2024

Ergo Vs Andere Blockchain-Plattformen: Was ist der Unterschied?

Ergo Vs Andere Blockchain-Plattformen: Was ist der Unterschied?

Ergo bietet eine Reihe einzigartiger Funktionen, die es von anderen Blockchain-Plattformen abheben.

Ergo Platform

19. August 2024

Verdienen Mit Der Rosen Brücke

Verdienen Mit Der Rosen Brücke

Bitcoin hat offiziell die Ergo-Ökosystem über die Rosen Brücke verbunden! Diese neu gebaute, dezentrale Infrastruktur ermöglicht v.

Ergo Platform

8. August 2024

Verdienen Mit Der Rosen Brücke

Verdienen Mit Der Rosen Brücke

Bitcoin hat offiziell die Ergo-Ökosystem über die Rosen Brücke verbunden! Diese neu gebaute, dezentrale Infrastruktur ermöglicht v.

Ergo Platform

8. August 2024

Wie Sigma Chains Bitcoin zu Ergo bringen werden

Wie Sigma Chains Bitcoin zu Ergo bringen werden

Ergos leistungsstarke, flexible und sichere Smart-Contract-Funktionalität öffnet die Tür zu einer ganzen Reihe neuer Anwendungsfäl.

Ergo Platform

15. Juli 2024

Wie Sigma Chains Bitcoin zu Ergo bringen werden

Wie Sigma Chains Bitcoin zu Ergo bringen werden

Die leistungsstarke, flexible und sichere Smart-Contract-Funktionalität von Ergo öffnet die Tür zu einer ganzen Reihe neuer Anwend.

Ergo Platform

15. Juli 2024