Un Ejemplo de ICO Sobre Ergo

This page is machine-translated.
Alex Chepurnoy

10 de abril de 2019

Este artículo describe una ICO (Oferta Inicial de Monedas) completamente funcional implementada en ErgoScript. El ejemplo cubre varias características importantes y novedosas de la Plataforma Ergo y muestra cómo puede soportar contratos complejos con una pequeña cantidad de código.

Parte 1. Preliminares

Una decisión de diseño importante en un protocolo de criptomonedas es especificar qué gasta realmente una transacción de gasto. Aquí hay dos posibilidades. La primera es un modelo basado en UTXO, como en Bitcoin, donde una transacción gasta contenedores de activos de un solo uso (llamados 'monedas' o UTXOs en Bitcoin) y crea nuevos. La otra es un modelo basado en cuentas, como en Nxt, Ethereum o Waves, donde una transacción transfiere una cierta cantidad de activos de una cuenta existente de larga duración a otra, posiblemente nueva, cuenta de larga duración, con posibles efectos secundarios en el camino, como la ejecución de contratos en Waves o Ethereum. En este sentido, Ergo es similar a Bitcoin, porque utiliza el enfoque basado en UTXO, donde se gastan contenedores de un solo uso llamados cajas. Curiosamente, una transacción de Ergo también puede tener entradas de datos que no se gastan, sino que se utilizan para proporcionar información del conjunto actual de cajas no gastadas.

No es trivial crear una ICO sobre un modelo basado en UTXO, porque, a diferencia de los modelos basados en cuentas, no hay almacenamiento persistente explícito aquí. Sin embargo, Ergo lleva una transacción de gasto al contexto de ejecución de un script.
Con este pequeño cambio, se vuelve posible expresar dependencias entre las salidas e entradas de la transacción. A su vez, al establecer dependencias, podemos ejecutar incluso programas Turing-completos arbitrariamente complejos sobre la blockchain (ver el "Self-reproducing Coins as Universal Turing Machine" paper). En este artículo definiremos un escenario concreto de un contrato de múltiples etapas utilizando una ICO, donde tenemos tres etapas (financiación, emisión de tokens, retiro).

Ahora imagina una ICO para miles de participantes. A diferencia de Ethereum, Ergo no proporciona la posibilidad de almacenar grandes conjuntos de datos y llevarlos a cabo durante la ejecución del contrato. Más bien, permite almacenar solo aproximadamente 40 bytes de encabezado de una
estructura de datos, representada como un diccionario clave -> valor, autenticado de manera similar a un árbol de Merkle. Para acceder a algunos elementos
en el diccionario, o para modificarlo, una transacción de gasto que activa la ejecución del script de protección debe
proporcionar pruebas de búsqueda o modificación. Esto da la posibilidad a un contrato de autenticar conjuntos de datos potencialmente enormes sin requerir mucha memoria para almacenar el estado del contrato. Sin embargo, almacenar espacio en el estado (de contratos activos) significaría transacciones más grandes, pero este problema es más fácil desde el punto de vista de escalabilidad, y la escalabilidad es una prioridad máxima para Ergo.

Parte 2. El Contrato ICO

Podría haber muchos escenarios posibles asociados con una Oferta Inicial de Monedas (ICO). En este artículo consideramos una ICO que quiere recaudar al menos una cierta cantidad de fondos (en Ergs) para iniciar el proyecto. Una vez que se cruza el umbral de financiación y termina el período de financiación, el proyecto se inicia y se emiten tokens ICO por parte del proyecto en función de la financiación total recaudada. En la fase de retiro, que se extiende indefinidamente, los inversores retiran tokens ICO en función de la cantidad que habían invertido durante el período de financiación. Los pasos del contrato se describen brevemente a continuación con detalles proporcionados más adelante:

  • Primero, tiene lugar la época de financiación. Comienza con una caja del proyecto autenticando un diccionario vacío. El diccionario está destinado a contener pares (inversor, saldo), donde el inversor es un script que protege la caja que contiene los tokens retirados. Para el saldo, asumimos que 1 token es igual a 1 Ergo durante la ICO. Durante la época de financiación, solo es posible poner Ergs en la caja del proyecto.
    Una transacción de financiación gasta la caja del proyecto y crea una nueva caja del proyecto con información actualizada. Para ello, una transacción de gasto para la caja del proyecto también tiene otras entradas que contienen scripts de retiro de inversores. Los scripts de inversores y los valores de entrada deben añadirse al árbol de la nueva caja. Podría haber muchas transacciones de financiación encadenadas.
  • En segundo lugar, finaliza el período de financiación, después del cual el árbol que contiene los datos de los inversores se vuelve de solo lectura. Un árbol autenticado podría tener diferentes operaciones de modificación permitidas individualmente: inserciones, eliminaciones, actualizaciones, o todas las operaciones podrían estar prohibidas (por lo que el árbol podría estar en modo de solo lectura). Además, esta transacción crea tokens del proyecto ICO que se retirarán en la siguiente etapa. El proyecto puede retirar Ergs en esta etapa.
  • En tercer lugar, los inversores retiran sus tokens ICO. Para ello, una transacción de gasto crea salidas con condiciones de protección y valores de tokens tomados del árbol. Los pares retirados también se eliminan del árbol. Podría haber muchas transacciones de gasto encadenadas.

Estas tres etapas deben estar vinculadas en el orden lógico. Se utiliza una secuencia de cajas para lograr estos objetivos.

Parte 3. Detalles del Contrato ICO

Ahora es el momento de proporcionar detalles y código ErgoScript de las etapas del contrato ICO.

La Etapa de Financiación

En la etapa de financiación, que es la primera, asumimos que inicialmente un proyecto crea una caja comprometiéndose a un diccionario vacío (almacenado en el registro R5) con un script de protección descrito a continuación. Esta etapa dura al menos hasta la altura 2,000. Más concretamente, la primera transacción con una altura de 2,000 o más debe cambiar el script de la caja de salida como se describe en la siguiente sección (las transacciones a alturas más bajas deben producir una caja con el mismo script).

La caja del proyecto verifica que siempre es la primera entrada y salida de una transacción. Las otras entradas se consideran entradas de inversores. La entrada de un inversor contiene el hash de un script en el registro R4. Este hash representa el script de retiro que se utilizará más adelante en la fase de retiro. Los hashes, así como los valores monetarios de todas las entradas de inversión, deben añadirse al diccionario. La
transacción de gasto proporciona una prueba de que los datos del inversor se han añadido al diccionario, y la prueba se verifica en el contrato.

No se verifica en el subcontrato de financiación que el diccionario permita solo inserciones, y no actualizaciones de valores existentes o eliminaciones (sin embargo, no es difícil añadir una verificación explícita).

La transacción de gasto debe pagar una tarifa, de lo contrario, es poco probable que se incluya en un bloque. Por lo tanto, el contrato de financiación verifica que la transacción de gasto tiene dos salidas (una para sí misma, otra para pagar la tarifa), la tarifa no debe ser más de un cierto límite (solo un nanoErg en nuestro ejemplo), y la proposición de protección debe ser tal que solo un minero pueda gastar la salida (utilizamos solo una variable "feeProp" del entorno de compilación en nuestro ejemplo sin proporcionar detalles). Esta "feeProp" corresponde a un estándar, aunque no requerido por el protocolo.

El código a continuación hace cumplir las condiciones descritas anteriormente. Tenga en cuenta que la
"nextStageScriptHash" variable de entorno contiene el hash del script de la etapa de emisión serializado.

    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

La Etapa de Emisión

Esta etapa tiene solo una transacción de gasto para llegar a la siguiente etapa (la etapa de retiro). La transacción de gasto realiza las siguientes modificaciones. Primero, cambia la lista de operaciones permitidas en el diccionario de "solo inserciones" a "solo eliminaciones", ya que la siguiente etapa (retiro) solo se ocupa de eliminar entradas del diccionario.

En segundo lugar, el contrato verifica que se emita la cantidad adecuada de tokens ICO. En Ergo, se permite emitir un nuevo tipo de token por transacción, y el identificador del token debe ser igual al (único) identificador de la primera caja de entrada. El subcontrato de emisión verifica que se ha emitido un nuevo token, y la cantidad de este es igual a la cantidad de nanoErgs recaudados por la ICO hasta ahora.

En tercer lugar, el contrato verifica que una transacción de gasto esté recreando efectivamente la caja con el script de protección correspondiente a la siguiente etapa, la etapa de retiro.

Finalmente, el proyecto debe retirar los Ergs recaudados, y, por supuesto, cada transacción de gasto debe pagar una tarifa. Por lo tanto, el subcontrato verifica que la transacción de gasto tiene efectivamente 3 salidas (una para la caja de tokens del proyecto, la caja de retiro de Ergs y la caja de tarifas), y que la primera salida y salida lleva los tokens emitidos. Como no especificamos los detalles del retiro de dinero del proyecto, requerimos una firma del proyecto en la transacción de gasto.

    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

La Etapa de Retiro

En esta etapa, se permite a los inversores retirar tokens del proyecto protegidos por un script de guardia predefinido (cuyo hash se almacena en el diccionario). Supongamos que el retiro se realiza en lotes de tamaño N. Una transacción de retiro, por lo tanto, tiene N + 2 salidas, donde la primera salida lleva el subcontrato de retiro y los tokens de saldo, la última salida paga la tarifa y las N salidas restantes tienen scripts de protección y valores de tokens de acuerdo con el diccionario. El contrato requiere dos pruebas para los elementos del diccionario: una que prueba que los valores a retirar están efectivamente en el diccionario, y la segunda que prueba que el diccionario resultante no tiene los valores retirados. El subcontrato es el siguiente.

    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

Posibles Mejoras

Tenga en cuenta que hay muchas matices que nuestro contrato de ejemplo está ignorando. Por ejemplo, cualquier persona que escuche la blockchain puede ejecutar el contrato y construir transacciones de gasto adecuadas durante las etapas de financiación y retiro. En el mundo real, se puede utilizar una firma adicional del proyecto o un árbitro de confianza.

Además, no se considera un caso de autodestrucción en el contrato de retiro, por lo que vivirá hasta ser destruido por mineros a través del mecanismo de alquiler de almacenamiento, potencialmente durante décadas o incluso siglos. Para la etapa de financiación, sería razonable tener una entrada adicional del proyecto con un valor igual al valor de la salida de tarifa. Y así sucesivamente.

Share post

Ergo Infrastructure DAO: Descentralizando la columna vertebral del ecosistema Ergo

Ergo Infrastructure DAO: Descentralizando la columna vertebral del ecosistema Ergo

La misión de Ergo siempre ha estado arraigada en la descentralización, no solo en la capa de consenso, sino en toda la pila.

Ergo Platform

13 de agosto de 2025

Mew Finance: Un Kit de Herramientas DeFi Divertido para el Ecosistema Ergo

Mew Finance: Un Kit de Herramientas DeFi Divertido para el Ecosistema Ergo

Mew Finance es un conjunto de aplicaciones descentralizadas en la Blockchain de Ergo.

Ergo Platform

12 de agosto de 2025

Lithos: Descentralizando la Minería con Pools On-Chain

Lithos: Descentralizando la Minería con Pools On-Chain

Lithos es un nuevo protocolo diseñado para reformar cómo funcionan los pools de minería al trasladarlos a la cadena, dando a los m.

Ergo Platform

24 de julio de 2025

Sigma 6.0: Un Ergo Más Inteligente y Flexible

Sigma 6.0: Un Ergo Más Inteligente y Flexible

Sigma 6.0 es una importante actualización propuesta para la blockchain de Ergo.

Ergo Platform

23 de julio de 2025

Dando forma al futuro de Rosen: Una llamada comunitaria sobre cinco propuestas clave del Tesoro

Dando forma al futuro de Rosen: Una llamada comunitaria sobre cinco propuestas clave del Tesoro

El cofundador de Rosen, Armeanio, ha presentado cinco nuevas propuestas al Tesoro de Rosen.

Ergo Platform

9 de julio de 2025

El UTXO Ampliado de Ergo y el Auge de la Inteligencia Económica Artificial

El UTXO Ampliado de Ergo y el Auge de la Inteligencia Económica Artificial

Una Visión Práctica para Agentes Económicos Autónomos Los agentes económicos autónomos en la blockchain de Ergo realizan trabajos.

Ergo Platform

12 de mayo de 2025

ErgoHACK X: Inteligencia Artificial en la Blockchain de Ergo

ErgoHACK X: Inteligencia Artificial en la Blockchain de Ergo

Celebrando una Década de Innovación Descentralizada ¡Únete al décimo aniversario de ErgoHACK y sé parte de la revolución de la IA .

Ergo Platform

10 de abril de 2025

Introduccion a Privacidad y Seguridad en la Blockchain

Introduccion a Privacidad y Seguridad en la Blockchain

Luego del primer whitepaper que apareció en Internet en el 2008, la tecnología blockchain evoluciono enormemente.

Ergo Platform

17 de febrero de 2022

Método híbrido de calcular costes de Ergo

Método híbrido de calcular costes de Ergo

Introducción Verificar la validez de los contratos inteligentes en una blockchain de Prueba de trabajo (PoW) tiene costos, tanto.

Ergo Platform (Translated by Darkkknight, original version will always prevail)

9 de febrero de 2022

Ergo: una respuesta a los fallos de la teoría monetaria moderna

Ergo: una respuesta a los fallos de la teoría monetaria moderna

En 2008, un grupo o persona desconocida lanzó un depósito de valor peer-to-peer y lo llamó Bitcoin.

Ergo Platform (Translated by Comet Community, original version will always prevail)

8 de febrero de 2022

Summit de Ergo : Evento para la privacidad

Summit de Ergo : Evento para la privacidad

Únase a nosotros del 17 al 23 de febrero de 2022 para este evento.

Ergo Foundation (translated by Daniu, original version will always prevail)

5 de febrero de 2022

Finanza descentralizada y privacidad opcional en Ergo

Finanza descentralizada y privacidad opcional en Ergo

Privacidad financial y blockchains públicas Bitcoin es una red de contabilidad distribuida pública a la que pueden acceder todos.

Ergo Platform (translated by Daniu, original version will always prevail)

1 de febrero de 2022

Alquiler por almacenamiento y el futuro de la minería

Alquiler por almacenamiento y el futuro de la minería

Terminología Storage Rent: Alquiler por almacenamiento (se entenderá más adelante) Introducción Los mineros son la capa de con.

Ergo Platform (translated by Daniu, original version will always prevail)

27 de enero de 2022

ErgoHack III: Construyendo la privacidad y seguridad del mañana

ErgoHack III: Construyendo la privacidad y seguridad del mañana

Ergo es una plataforma PoW de contratos inteligentes de código abierto basada en principios económicos de base.

Ergo Foundation (translated by Daniu, original version will always prevail)

20 de enero de 2022

Ergo & Blockchain: Escalabilidad y adopción

Ergo & Blockchain: Escalabilidad y adopción

En este episodio de la serie Ergo & Blockchain, veremos varios aspectos de escalabilidad y por qué son cruciales para la adopció.

Ergo Platform (translated by Daniu, original version will always prevail)

18 de enero de 2022

ErgoHack III Información para registrarse

ErgoHack III Información para registrarse

ErgoHack III tendrá lugar en Febrero 11-13, 2022 Registros abiertos hasta el 31 de Enero, 2022 Con el registro ya abierto, exi.

Ergo Foundation (translated by Daniu, original version will always prevail)

6 de enero de 2022

Ergo Rewards de minería: primera reducción de la emisión

Ergo Rewards de minería: primera reducción de la emisión

Las recompensas de la minería Ergo experimentaron su primera caída en el calendario de emisiones el 2 de enero de 2022 con el bl.

Ergo Platform (translated by Daniu, original version will always prevail)

4 de enero de 2022

¡Hola! soy nuevo, ¿por qué es Ergo un buen proyecto?

¡Hola! soy nuevo, ¿por qué es Ergo un buen proyecto?

¿Qué encontrarás en este artículo? Son numerosas las veces que un nuevo ergonauta en potencia entra a uno de los grupos en españo.

Daniu

1 de enero de 2022

Ergo Platform 2021: Resumen de este año

Ergo Platform 2021: Resumen de este año

A medida que el mundo intenta recuperarse de los efectos de Covid y las diferentes etapas de las restricciones de bloqueo, las c.

Ergo Platform (translated by Daniu, original version will always prevail)

30 de diciembre de 2021

Ergo y Blockchain: Tecnología e Innovación

Ergo y Blockchain: Tecnología e Innovación

La idea inicial detrás de Bitcoin se basó en la promesa de un comercio protegido de puntos centralizados de falla.

Ergo Platform (translated by Daniu, original version will always prevail)

28 de diciembre de 2021

Minería en Ergo: Herramientas de descentralización

Minería en Ergo: Herramientas de descentralización

Ergo es una cadena de bloques PoW (Prueba de trabajo) en el modelo de consenso llamado Autolykos.

Ergo Platform (translated by Daniu, original version will always prevail)

23 de diciembre de 2021