Amparate à scrive i cuntratti intelligenti di Waves in RIDE è RIDE4DAPPS. Parte 2 (DAO - Organisazione Autònuma Decentralizata)

Amparate à scrive i cuntratti intelligenti di Waves in RIDE è RIDE4DAPPS. Parte 2 (DAO - Organisazione Autònuma Decentralizata)

Bonghjornu ognunu!

В u primu parte avemu guardatu in dettu cumu per creà è travaglià cù dApp (applicazione decentralizata) in Waves RIDE IDE.

Testemu un pocu avà u disassemblatu esempiu.

Stage 3. Testing u contu dApp

Amparate à scrive i cuntratti intelligenti di Waves in RIDE è RIDE4DAPPS. Parte 2 (DAO - Organisazione Autònuma Decentralizata)

Chì prublemi ti saltanu immediatamente cun Alice? dApp U so contu?
Prima:
Boob è Cooper ponu accidentalmente mandà fondi à l'indirizzu dApp utilizendu regularmente trasferimentu transazzione è cusì ùn sarà capaci di accede à elli daretu.

Siconda:
Ùn limitemu micca Alice in alcun modu da ritirare fondi senza l'appruvazioni di Boob è / o Cooper. Dapoi, fate attenzione à verificà, tutte e transazzione da Alice seranu eseguite.

Fixemu a 2ª pruibiscendu Alice trasferimentu transazzioni. Implementemu u script currettu:
Amparate à scrive i cuntratti intelligenti di Waves in RIDE è RIDE4DAPPS. Parte 2 (DAO - Organisazione Autònuma Decentralizata)

Pruvamu di ritirà muniti da dApp Alice è a so firma. Avemu un errore:
Amparate à scrive i cuntratti intelligenti di Waves in RIDE è RIDE4DAPPS. Parte 2 (DAO - Organisazione Autònuma Decentralizata)

Pruvemu di ritirà via ritirata:

broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"withdraw",args:[{type:"integer", value: 1000000}]}, payment: []}))

U script funziona è avemu capitu u 2u puntu!

Stage 4. Crea un DAO cù votu

Sfurtunatamente, a lingua RIDE ùn furnisce ancu a capacità di travaglià cù cullezzione (dizziunarii, iteratori, riduttori, etc.). Tuttavia, per ogni operazione cù cullezzione flat chjave-valore pudemu disignà un sistema per travaglià cù strings, in cunseguenza cù i chjavi è a so decryption.

E stringhe sò assai faciuli di concatenate; i stringi ponu esse separati da indici.
Raccogliemu è analizà una stringa cum'è un esempiu di prova è verificate cumu questu affetta u risultatu di a transazzione.
Avemu stabilitu nantu à u fattu chì Alice ùn pudia micca firmà a transazzione di trasferimentu, postu chì sta capacità hè stata bluccata in @verifier per stu tipu di transazzione.

Pratichemu cù e corde è poi risolve questu.

Corde RIDE

A transazzione hè pussibule di novu, sapemu cumu travaglià cù strings.
Amparate à scrive i cuntratti intelligenti di Waves in RIDE è RIDE4DAPPS. Parte 2 (DAO - Organisazione Autònuma Decentralizata)


In tuttu, avemu tuttu ciò chì hè necessariu per scrive una logica cumplessa DAO dApp.

Transazzione di dati

Transazzioni di dati:
"A dimensione massima per una chjave hè di 100 caratteri, è una chjave pò cuntene punti di codice Unicode arbitrarii cumpresi spazii è altri simboli non stampabili. I valori di stringa anu un limitu di 32,768 100 bytes è u numeru massimu di entrate pussibuli in a transazzione di dati hè 140. In generale, a dimensione massima di una transazzione di dati hè di circa XNUMX kb - per riferimentu, quasi esattamente a durata di l'opera di Shakespeare "Romeo and Juliet". '. "

Creemu un DAO cù e seguenti cundizioni:
Per chì una startup riceve un finanziamentu chjamendu ottene fondi () u sustegnu di almenu 2 participanti - investitori DAO - hè necessariu. Ritirassi serà pussibule esattamente quant'è u tutale indicatu vutatu I pruprietarii di DAO.

Facemu 3 tipi di chjavi è aghjunghje logica per travaglià cù saldi in 2 funzioni novi vote è getFunds:
xx...xx_ia = investitori, saldo dispunibule (vote, depositu, ritirata)
xx...xx_sv = startups, numeru di voti (vote, uttene i fondi)
xx...xx_sf = startups, numeru di voti (vote, uttene i fondi)
xx…xx = indirizzu publicu (35 caratteri)

Per piacè nutate chì in Vote avemu bisognu di aghjurnà parechji campi à una volta:

WriteSet([DataEntry(key1, value1), DataEntry(key2, value2)]),

WriteSet ci permette di fà parechji registri à una volta in unu invokeScript transazzioni.

Questu hè ciò chì pare in l'almacenamiento di u valore chjave di u DAO dApp, dopu chì Bob è Cooper si rimpianu. ia- depositi:
Amparate à scrive i cuntratti intelligenti di Waves in RIDE è RIDE4DAPPS. Parte 2 (DAO - Organisazione Autònuma Decentralizata)

A nostra funzione di depositu hà cambiatu pocu:
Amparate à scrive i cuntratti intelligenti di Waves in RIDE è RIDE4DAPPS. Parte 2 (DAO - Organisazione Autònuma Decentralizata)

Avà vene u mumentu più impurtante in l'attività di u DAO - vutà per i prughjetti da esse finanziati.

Bob vota per u prughjettu di 500000 wavelets di Neli:

broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"vote",args:[{type:"integer", value: 500000}, {type:"string", value: "3MrXEKJr9nDLNyVZ1d12Mq4jjeUYwxNjMsH"}]}, payment: []}))

Amparate à scrive i cuntratti intelligenti di Waves in RIDE è RIDE4DAPPS. Parte 2 (DAO - Organisazione Autònuma Decentralizata)

In u magazzinu di dati vedemu tutte e voci necessarie per l'indirizzu di Neli:
Amparate à scrive i cuntratti intelligenti di Waves in RIDE è RIDE4DAPPS. Parte 2 (DAO - Organisazione Autònuma Decentralizata)
Cooper hà ancu vutatu per u prughjettu Neli.
Amparate à scrive i cuntratti intelligenti di Waves in RIDE è RIDE4DAPPS. Parte 2 (DAO - Organisazione Autònuma Decentralizata)

Fighjemu un ochju à u codice di a funzione ottene i fondi. Neli deve cullà un minimu di 2 voti per pudè ritirà fondi da u DAO.
Amparate à scrive i cuntratti intelligenti di Waves in RIDE è RIDE4DAPPS. Parte 2 (DAO - Organisazione Autònuma Decentralizata)

Neli hà da ritirarà a mità di a quantità chì li hè affidata :

broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"getFunds",args:[{type:"integer", value: 500000}]}, payment: []}))

Amparate à scrive i cuntratti intelligenti di Waves in RIDE è RIDE4DAPPS. Parte 2 (DAO - Organisazione Autònuma Decentralizata)

Ella riesce, vale à dì, DAO travaglia !

Avemu vistu u prucessu di creà un DAO in a lingua RIDE4DAPPS.
In i seguenti parti, daremu un ochju più vicinu à a refactoring di codice è a prova di casu.

Versione cumpleta di u codice in Waves RIDE IDE:

# In this example multiple accounts can deposit their funds to DAO and safely take them back, no one can interfere with this.
# DAO participants can also vote for particular addresses and let them withdraw invested funds then quorum has reached.
# An inner state is maintained as mapping `address=>waves`.
# https://medium.com/waves-lab/waves-announces-funding-for-ride-for-dapps-developers-f724095fdbe1

# You can try this contract by following commands in the IDE (ide.wavesplatform.com)
# Run commands as listed below
# From account #0:
#      deploy()
# From account #1: deposit funds
#      broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"deposit",args:[]}, payment: [{amount: 100000000, asset:null }]}))
# From account #2: deposit funds
#      broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"deposit",args:[]}, payment: [{amount: 100000000, asset:null }]}))
# From account #1: vote for startup
#      broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"vote",args:[{type:"integer", value: 500000}, {type:"string", value: "3MrXEKJr9nDLNyVZ1d12Mq4jjeUYwxNjMsH"}]}, payment: []}))
# From account #2: vote for startup
#      broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"vote",args:[{type:"integer", value: 500000}, {type:"string", value: "3MrXEKJr9nDLNyVZ1d12Mq4jjeUYwxNjMsH"}]}, payment: []}))
# From account #3: get invested funds
#      broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"getFunds",args:[{type:"integer", value: 500000}]}, payment: []}))

{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}

@Callable(i)
func deposit() = {
   let pmt = extract(i.payment)
   if (isDefined(pmt.assetId)) then throw("can hodl waves only at the moment")
   else {
        let currentKey = toBase58String(i.caller.bytes)
        let xxxInvestorBalance = currentKey + "_" + "ib"
        let currentAmount = match getInteger(this, xxxInvestorBalance) {
            case a:Int => a
            case _ => 0
        }
        let newAmount = currentAmount + pmt.amount
        WriteSet([DataEntry(xxxInvestorBalance, newAmount)])
   }
}
@Callable(i)
func withdraw(amount: Int) = {
        let currentKey = toBase58String(i.caller.bytes)
        let xxxInvestorBalance = currentKey + "_" + "ib"
        let currentAmount = match getInteger(this, xxxInvestorBalance) {
            case a:Int => a
            case _ => 0
        }
        let newAmount = currentAmount - amount
     if (amount < 0)
            then throw("Can't withdraw negative amount")
    else if (newAmount < 0)
            then throw("Not enough balance")
            else ScriptResult(
                    WriteSet([DataEntry(xxxInvestorBalance, newAmount)]),
                    TransferSet([ScriptTransfer(i.caller, amount, unit)])
                )
    }
@Callable(i)
func getFunds(amount: Int) = {
        let quorum = 2
        let currentKey = toBase58String(i.caller.bytes)
        let xxxStartupFund = currentKey + "_" + "sf"
        let xxxStartupVotes = currentKey + "_" + "sv"
        let currentAmount = match getInteger(this, xxxStartupFund) {
            case a:Int => a
            case _ => 0
        }
        let totalVotes = match getInteger(this, xxxStartupVotes) {
            case a:Int => a
            case _ => 0
        }
        let newAmount = currentAmount - amount
    if (amount < 0)
            then throw("Can't withdraw negative amount")
    else if (newAmount < 0)
            then throw("Not enough balance")
    else if (totalVotes < quorum)
            then throw("Not enough votes. At least 2 votes required!")
    else ScriptResult(
                    WriteSet([
                        DataEntry(xxxStartupFund, newAmount)
                        ]),
                    TransferSet([ScriptTransfer(i.caller, amount, unit)])
                )
    }
@Callable(i)
func vote(amount: Int, address: String) = {
        let currentKey = toBase58String(i.caller.bytes)
        let xxxInvestorBalance = currentKey + "_" + "ib"
        let xxxStartupFund = address + "_" + "sf"
        let xxxStartupVotes = address + "_" + "sv"
        let currentAmount = match getInteger(this, xxxInvestorBalance) {
            case a:Int => a
            case _ => 0
        }
        let currentVotes = match getInteger(this, xxxStartupVotes) {
            case a:Int => a
            case _ => 0
        }
        let currentFund = match getInteger(this, xxxStartupFund) {
            case a:Int => a
            case _ => 0
        }
    if (amount <= 0)
            then throw("Can't withdraw negative amount")
    else if (amount > currentAmount)
            then throw("Not enough balance")
    else ScriptResult(
                    WriteSet([
                        DataEntry(xxxInvestorBalance, currentAmount - amount),
                        DataEntry(xxxStartupVotes, currentVotes + 1),
                        DataEntry(xxxStartupFund, currentFund + amount)
                        ]),
                    TransferSet([ScriptTransfer(i.caller, amount, unit)])
            )
    }
@Verifier(tx)
func verify() = {
    match tx {
        case t: TransferTransaction =>false
        case _ => true
    }
}

Prima parte
Codice nantu à GitHub
Waves RIDE IDE
L'annunziu di u prugramma di cuncessione

Source: www.habr.com

Add a comment