Príklad ICO na platforme Ergo

This page is machine-translated.
Alex Chepurnoy

10. apríla 2019

Tento článok popisuje plne funkčný ICO (počiatočná ponuka mincí) implementovaný v ErgoScripte. Príklad pokrýva niekoľko dôležitých a nových funkcií platformy Ergo a ukazuje, ako môže podporovať komplexné zmluvy s malým množstvom kódu.

Časť 1. Predpoklady

Dôležité rozhodnutie pri návrhu protokolu kryptomeny je špecifikovať, čo vlastne transakcia míňa. Existujú tu dve možnosti. Prvá je model založený na UTXO, ako v Bitcoine, kde transakcia míňa jednorazové kontajnery aktív (nazývané 'mince' alebo UTXO v Bitcoine) a vytvára nové. Druhá je model založený na účtoch, ako v Nxt, Ethereu alebo Waves, kde transakcia prenáša určitú sumu aktíva z existujúceho dlhodobého účtu na iný, možno nový, dlhodobý účet, s možnými vedľajšími účinkami, ako je vykonávanie zmlúv v Waves alebo Ethereu. V tomto ohľade je Ergo podobné Bitcoinu, pretože používa prístup založený na UTXO, kde sa míňajú jednorazové kontajnery nazývané boxy. Zaujímavé je, že transakcia Ergo môže mať aj vstupy údajov, ktoré sa nemíňajú, ale skôr sa používajú na poskytnutie informácií z aktuálneho súboru nemíňaných boxov.

Nie je triviálne vytvoriť ICO na vrchole modelu založeného na UTXO, pretože, na rozdiel od modelov založených na účtoch, tu nie je explicitné trvalé úložisko. Avšak, Ergo prináša transakciu míňania do kontextu vykonávania skriptu.
S touto malou zmenou sa stáva možné vyjadriť závislosti medzi výstupmi a vstupmi transakcie. Na oplátku, nastavením závislostí môžeme vykonávať aj arbitrárne komplexné Turingovo kompletné programy na vrchole blockchainu (pozri "Self-reproducing Coins as Universal Turing Machine" článok). V tomto článku definujeme konkrétny scenár viacstupňovej zmluvy pomocou ICO, kde máme tri fázy (financovanie, vydanie tokenov, výber).

Teraz si predstavte ICO pre tisíce účastníkov. Na rozdiel od Etherea, Ergo neposkytuje možnosť ukladať veľké množstvá údajov a prenášať ich počas vykonávania zmluvy. Namiesto toho umožňuje uložiť iba približne 40-bajtový hlavičku dátovej
štruktúry, reprezentovanej ako kľúč -> hodnota slovník, autentifikovaný podobne ako Merkleho strom. Na prístup k niektorým prvkom
v slovníku, alebo na jeho úpravu, by mala transakcia míňania, ktorá spúšťa vykonávanie ochranného skriptu, poskytnúť dôkazy o vyhľadávaní alebo úprave. To dáva možnosť zmluve autentifikovať potenciálne obrovské súbory údajov bez potreby veľkej pamäte na uloženie stavu zmluvy. Avšak, uloženie priestoru v stave (aktívnych zmlúv) by znamenalo väčšie transakcie, ale tento problém je z pohľadu škálovateľnosti jednoduchší, a škálovateľnosť je pre Ergo najvyššou prioritou.

Časť 2. Zmluva ICO

Môže existovať mnoho možných scenárov spojených s počiatočnou ponukou mincí (ICO). V tomto článku zvažujeme ICO, ktoré chce vyzbierať aspoň určitú sumu prostriedkov (v Ergs), aby mohlo začať projekt. Akonáhle je prekročený prah financovania a obdobie financovania končí, projekt je naštartovaný a ICO tokeny sú vydané projektom na základe celkového vyzbieraného financovania. V fáze výberu, ktorá trvá navždy, investori vyberajú ICO tokeny na základe sumy, ktorú investovali počas obdobia financovania. Kroky zmluvy sú stručne popísané nižšie s podrobnosťami uvedenými ďalej:

  • Najprv sa uskutoční finančné obdobie. Začína sa boxom projektu autentifikujúcim prázdny slovník. Slovník je určený na uchovávanie (investor, zostatok) párov, kde investor je skript chránia box obsahujúci vybrané tokeny. Pre zostatok predpokladáme, že 1 token je rovný 1 Ergo počas ICO. Počas finančného obdobia je možné do boxu projektu vložiť iba Ergs.
    Transakcia financovania míňa box projektu a vytvára nový box projektu s aktualizovanými informáciami. Na to má transakcia míňania boxu projektu aj iné vstupy, ktoré obsahujú skripty na vyberanie investorov. Skripty investorov a hodnoty vstupov by mali byť pridané do stromu nového boxu. Môže existovať mnoho reťazených transakcií financovania.
  • Po druhé, obdobie financovania končí, po ktorom sa strom obsahujúci údaje investorov stáva iba na čítanie. Autentifikovaný strom môže mať rôzne operácie úprav povolené individuálne: vkladanie, mazanie, aktualizácie, alebo všetky operácie môžu byť zakázané (takže strom môže byť v režime iba na čítanie). Taktiež táto transakcia vytvára tokeny ICO projektu, ktoré budú vybrané v nasledujúcej fáze. Projekt môže v tejto fáze vybrať Ergs.
  • Po tretie, investori vyberajú svoje ICO tokeny. Na to vytvára transakcia míňania výstupy s ochrannými podmienkami a hodnotami tokenov prevzatými zo stromu. Vybrané páry sú tiež vymazané zo stromu. Môže existovať mnoho reťazených transakcií míňania.

Tieto tri fázy by mali byť prepojené v logickom poradí. Sekvencia boxov sa používa na dosiahnutie týchto cieľov.

Časť 3. Podrobnosti zmluvy ICO

Teraz je čas poskytnúť podrobnosti a kód ErgoScript fáz zmluvy ICO.

Fáza financovania

V fáze financovania, ktorá prichádza ako prvá, predpokladáme, že projekt najprv vytvorí box, ktorý sa zaväzuje k prázdnemu slovníku (uloženému v registri R5) s niektorým ochranným skriptom popísaným nižšie. Táto fáza trvá aspoň do výšky 2 000. Konkrétnejšie, prvá transakcia s výškou 2 000 alebo viac by mala zmeniť skript výstupného boxu, ako je popísané v nasledujúcej sekcii (transakcie na nižších výškach musia výstupovať box so rovnakým skriptom).

Box projektu kontroluje, že je vždy prvým vstupom a výstupom transakcie. Ostatné vstupy sú považované za vstupy investorov. Vstup investora obsahuje hash skriptu v registri R4. Tento hash predstavuje skript na vyberanie, ktorý bude použitý neskôr vo fáze výberu. Hashy, ako aj peňažné hodnoty všetkých investičných vstupov by mali byť pridané do slovníka.
transakcia míňania poskytuje dôkaz, že údaje investora sú skutočne pridané do slovníka, a dôkaz je skontrolovaný v zmluve.

Nie je skontrolované v sub-zmluve financovania, že slovník povoľuje iba vkladanie, a nie aktualizáciu existujúcich hodnôt alebo odstraňovanie (nie je ťažké pridať explicitnú kontrolu).

Transakcia míňania by mala zaplatiť poplatok, inak je nepravdepodobné, že by bola zahrnutá do bloku. Takže zmluva o financovaní kontroluje, že transakcia míňania má dva výstupy (jeden pre seba, druhý na zaplatenie poplatku), poplatok by nemal presiahnuť určitý limit (len jeden nanoErg v našom príklade), a ochranná podmienka by mala byť taká, že iba baník môže minúť výstup (v našom príklade používame len premennú "feeProp" z kompilátorského prostredia bez poskytnutia akýchkoľvek podrobností). Tento "feeProp" zodpovedá štandardu, hoci nie je požadovaný protokolom.

Kód nižšie vynucuje podmienky popísané vyššie. Upozorňujeme, že
"nextStageScriptHash" premenná prostredia obsahuje hash skriptu fázy vydania.

    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

Fáza vydania

Táto fáza má iba jednu transakciu míňania, aby sa dostala do nasledujúcej fázy (fázy výberu). Transakcia míňania vykonáva nasledujúce úpravy. Po prvé, mení zoznam povolených operácií na slovníku z "iba vkladania" na "iba odstraňovania", pretože nasledujúca fáza (výber) sa zaoberá iba odstraňovaním položiek zo slovníka.

Po druhé, zmluva kontroluje, že správne množstvo ICO tokenov je vydané. V Ergu je povolené vydávať jeden nový druh tokenu na transakciu, a identifikátor tokenu by mal byť rovný (unikátnemu) identifikátoru prvého vstupného boxu. Sub-zmluva o vydaní kontroluje, že nový token bol vydaný, a jeho množstvo je rovné množstvu nanoErgs vyzbieraných ICO doteraz.

Po tretie, zmluva kontroluje, že transakcia míňania skutočne znovu vytvára box s ochranným skriptom zodpovedajúcim nasledujúcej fáze, fáze výberu.

Nakoniec by projekt mal vybrať vyzbierané Ergs, a samozrejme, každá transakcia míňania by mala zaplatiť poplatok. Takže sub-zmluva kontroluje, že transakcia míňania má skutočne 3 výstupy (jeden pre box tokenov projektu, box na výber Ergs a box na poplatok), a že prvý výstup a výstup nesie vydané tokeny. Keďže nešpecifikujeme podrobnosti o výbere peňazí projektu, požadujeme podpis projektu na transakcii míňania.

    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

Fáza výberu

V tejto fáze sú investori oprávnení vyberať tokeny projektu chránené preddefinovaným ochranným skriptom (ktorého hash je uložený v slovníku). Povedzme, že výber sa robí v dávkach veľkosti N. Transakcia vyberania má teda N + 2 výstupy, kde prvý výstup nesie podzmluvu o výbere a zostatkové tokeny, posledný výstup platí poplatok a zostávajúce N výstupy majú ochranné skripty a hodnoty tokenov podľa slovníka. Zmluva vyžaduje dva dôkazy pre prvky slovníka: jeden dokazujúci, že hodnoty na vybratie sú skutočne v slovníku, a druhý dokazujúci, že výsledný slovník nemá vybrané hodnoty. Sub-zmluva je nižšie.

    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

Možné vylepšenia

Upozorňujeme, že existuje mnoho nuáns, ktoré náš príklad zmluvy ignoruje. Napríklad, každý, kto počúva blockchain, je oprávnený vykonávať zmluvu a konštruovať správne transakcie míňania počas fáz financovania a výberu. V reálnom svete môže byť použitý dodatočný podpis od projektu alebo dôveryhodného rozhodcu.

Taktiež nie je zohľadnený prípad seba-zničenia v zmluve o výbere, takže bude žiť, kým nebude zničená baníkmi prostredníctvom mechanizmu prenájmu úložiska, potenciálne desaťročia alebo dokonca storočia. Pre fázu financovania by bolo rozumné mať dodatočný vstup od projektu s hodnotou rovnou hodnote výstupu poplatku. A tak ďalej.

Share post

Ergo Infrastructure DAO: Decentralizácia chrbtice ekosystému Ergo

Ergo Infrastructure DAO: Decentralizácia chrbtice ekosystému Ergo

Misia Ergo bola vždy zakorenená v decentralizácii, nielen na konsenzuálnej vrstve, ale naprieč celým stackom.

Ergo Platform

13. augusta 2025

Mew Finance: Hravý DeFi nástroj pre ekosystém Ergo

Mew Finance: Hravý DeFi nástroj pre ekosystém Ergo

Mew Finance je decentralizovaná aplikácia na blockchainu Ergo.

Ergo Platform

12. augusta 2025

Lithos: Decentralizácia ťažby s on-chain poolmi

Lithos: Decentralizácia ťažby s on-chain poolmi

Lithos je nový protokol navrhnutý na prepracovanie fungovania ťažobných poolov presunutím ich na on-chain, čo dáva ťažiarom plnú k.

Ergo Platform

24. júla 2025

Sigma 6.0: Inteligentnejší, flexibilnejší Ergo

Sigma 6.0: Inteligentnejší, flexibilnejší Ergo

Sigma 6.0 je významná navrhovaná aktualizácia blockchainu Ergo.

Ergo Platform

23. júla 2025

Formovanie budúcnosti Rosen: Výzva komunity na päť kľúčových návrhov pokladnice

Formovanie budúcnosti Rosen: Výzva komunity na päť kľúčových návrhov pokladnice

Spoluzakladateľ Rosen, Armeanio, predložil päť nových návrhov pre Rosen Treasury.

Ergo Platform

9. júla 2025

Ergo's Extended UTXO a vzostup umelej ekonomickej inteligencie

Ergo's Extended UTXO a vzostup umelej ekonomickej inteligencie

Praktická vízia pre autonómne ekonomické agentov Autonómne ekonomické agenti na blockchaine Ergo vykonávajú užitočnú prácu v reál.

Ergo Platform

12. mája 2025

ErgoHACK X: Umelá inteligencia na Ergo blockchaine

ErgoHACK X: Umelá inteligencia na Ergo blockchaine

Oslavujeme desaťročie decentralizovanej inovácií Pridajte sa k 10.

Ergo Platform

10. apríla 2025

The Ergo Manifesto

The Ergo Manifesto

Ergo Manifesto dúfa vo vzdelanie a ukážku vízie, čo blockchain technológia môže dosiahnuť.

Ergo Foundation

26. apríla 2021