
¡Hola a todos!
Recientemente, Waves Labs organizó un concurso para desarrolladores con motivo del lanzamiento de la red de prueba de la expansión del lenguaje de contratos inteligentes RIDE para aplicaciones descentralizadas Ride4Dapps.
Elegimos el caso DAO porque planea desarrollar una dApp con funciones sociales: votación, recaudación de fondos, gestión fiduciaria, etc.
Comenzamos con un ejemplo simple en y en — un ejemplo con .
Analicemos este ejemplo, verifiquemos las hipótesis y discutamos algunas peculiaridades:
Supongamos que tenemos a Alice — propietaria de la dApp
Boob y Cooper — socios de Alice, cofundadores de Alice-BC DAO
Neli — propietaria de un negocio, que necesita financiamiento
Bank — un banco que distribuye tokens
Etapa 1. Inicialización de saldos
Para obtener tokens en la red de prueba de Waves, es necesario dirigirse a y proporcionar la dirección a la que se enviarán los tokens.
La dirección se puede obtener en IDE, abriendo los datos de la cuenta.
Asignamos 10 WAVES al Bank. Después, verificamos que se hayan recibido a través del explorador de bloques y transacciones:
Ahora procedemos a distribuir los tokens desde el banco a los demás participantes. (Notas: Todas las transacciones en la red Waves no son gratuitas, por lo que es necesario que todos los participantes tengan un saldo positivo mínimo para realizar transacciones).
1 WAVES = 100000000 unidades (wavelets), dado que los montos solo pueden ser enteros.
0.01 WAVES (Tarifa de Transacción) = 1000000
Bank -> [3 WAVES] -> Alice, a través de TransferTransaction (Tipo: 4).
Verificamos que env.SEED, del cual se firman las transacciones, corresponde a nuestro Bank:


Si no tienes coincidencia con la frase semilla, simplemente cámbiate a ella en la pestaña Cuentas y verifica nuevamente.
Después de esto, creamos, anunciamos y firmamos la transacción para transferir 3 WAVES a Alice.
Los datos de Alice también se pueden obtener a través de la variable env.accounts. La numeración comienza en 0, por lo que Alice es env.accounts[1].

broadcast(transfer({recipient:address(env.accounts[1]), amount: 300000000, fee: 1000000}))El resultado también se puede observar en el explorador, y se nos devolverá un enlace inmediatamente después de la ejecución .
Nos aseguramos de que el saldo de Alice se haya incrementado en 3 WAVES, y en el saldo del banco quedó 10 — 3 — 0.01 = 0.699.


Enviamos a Boob y Cooper 3 WAVES cada uno, y a Neli, Xena y Mark 0.2 WAVES de la misma manera.
(Notas: Cometimos un error de un dígito y enviamos a Neli 0.02 WAVES. ¡Ten cuidado!)
broadcast(transfer({recipient:address(env.accounts[4]), amount: 20000000, fee: 1000000}))Después de aumentar los saldos de todos los participantes, vemos:

Etapa 2. Creación de la cuenta dApp
Hemos acordado que Alice será la creadora y propietaria de la aplicación descentralizada.
En Accounts, la establecemos como SEED y verificamos que env.SEED corresponde a Alice.
Intentemos instalar en la cuenta de Alice el script (contrato) más simple posible.
Los contratos inteligentes en Waves son predicados que prohíben o permiten la ejecución de un tipo de transacción saliente bajo ciertas condiciones. En este caso, la condición es ALWAYS. El código del contrato es true. Llamamos a deploy().

La tarifa por la transacción de setScript es 1400000/100000000 = 0.014 WAVES. Alice tiene un saldo restante de 2.986 WAVES.
Ahora intentaremos establecer en la cuenta de Alice una lógica más compleja de contrato inteligente, descrita en
Ride4Dapps ahora incluye 2 nuevos tipos de anotaciones:
- @Callable(i) — acepta como parámetro i, que contiene los datos sobre qué cuenta llamó/firma la transacción. El resultado de esta función determina el cambio en el estado de la cuenta dApp. Otras cuentas pueden crear transacciones y ejecutar funciones con esta anotación y cambiar el estado de la cuenta dApp.
- @Verifier(tx) — Verificador de transacción con el parámetro tx de la transacción. Se corresponde con la lógica de predicados en RIDE. En esta expresión se puede permitir o prohibir cambios adicionales en la lógica de los contratos inteligentes en la cuenta dApp.
Hagamos dApp la cuenta como una billetera común para todos los participantes.

Para verificar qué contrato está activo en la cuenta, se puede copiar el código base64 del contrato inteligente en el explorador de bloques y reconocerlo a través del decompilador ()



Asegurémonos de que la lógica del contrato inteligente se corresponde con nuestras expectativas.
Alice tiene un saldo restante de 2.972 WAVES.
Este dApp lleva el registro de cuánto contribuye cada participante al fondo común a través del mecanismo data transaction — DataEntry(currentKey, newAmount), donde currentKey es la cuenta que llama a la función deposit, y newAmount es el valor del saldo aumentado.
Bob y Cooper depositan 1 WAVES cada uno en la cuenta dApp.

Cometemos un error y la transacción no se completa. A pesar de que nos aseguramos de que estamos haciendo la transacción en nombre de Bob, nos equivocamos en el índice y especificamos la cuenta Bank, que no tiene un contrato inteligente. Es importante señalar que no se cobra una tarifa por intentos fallidos de iniciar transacciones. ¡No se cobra! Alice tiene un saldo restante de 2.972 WAVES. Bob tiene 3 WAVES.
Bob envió 1 WAVES a la cuenta dApp.
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"deposit",args:[]}, payment: [{amount: 100000000, asset:null }]}))
A Bob le quedan 1.99 WAVES. Es decir, Bob pagó 0.01 WAVES de comisión.

Alice tenía un saldo de 2.972 WAVES, ahora tiene 3.972. También hay una transacción registrada en la cuenta de Alice, sin embargo, no se le ha cobrado ninguna comisión a la cuenta de dApp (Alice).
Después de que Cooper también aumentara el saldo de Alice, ahora tiene 4.972 WAVES.

Se puede averiguar cuánto WAVES pertenece a cada uno en la billetera común utilizando el explorador de bloques en la pestaña Datos.
Cooper cambió de opinión sobre dejar la suma de 1 WAVES en la billetera común y decidió retirar la mitad de los fondos. Para ello, debe llamar a la función withdraw.

Sin embargo, de nuevo estamos equivocados, ya que la función withdraw tiene parámetros completamente diferentes y otra firma. Al diseñar contratos inteligentes en RIDE4DAPPS, este aspecto debe tenerse en cuenta.

Cooper ahora tiene 2.48 WAVES en su saldo. Por lo tanto, 3 WAVES — 1 — 0.01, y luego + 0.5 — 0.01. Por lo tanto, cada llamada a deposit y withdraw cuesta 0.01 WAVES. En consecuencia, en la tabla de propietarios de dApps, los registros han cambiado de la siguiente manera.

Bob también decidió retirar una cierta cantidad de la billetera común, pero se equivocó e intentó extraer 1.5 WAVES.

Sin embargo, en el contrato inteligente había una verificación para tal situación.
Xena es una estafadora, intentó retirar 1 WAVES de la cuenta común.

Ella tampoco tuvo éxito.
En la siguiente parte, abordaremos aspectos más complejos relacionados con las imperfecciones de la cuenta dApp de Alice.
Fuente: habr.com
