Mësoni të shkruani kontrata inteligjente të Waves në RIDE dhe RIDE4DAPPS. Pjesa 2 (DAO - Organizata Autonome e Decentralizuar)

Mësoni të shkruani kontrata inteligjente të Waves në RIDE dhe RIDE4DAPPS. Pjesa 2 (DAO - Organizata Autonome e Decentralizuar)

Përshëndetje të gjithëve!

В i pari pjesë ne shikuam në detaje se si të krijoni dhe punoni me dApp (aplikacion i decentralizuar) në Valët RIDE IDE.

Le të testojmë pak tani atë të çmontuar shembull.

Faza 3. Testimi i llogarisë dApp

Mësoni të shkruani kontrata inteligjente të Waves në RIDE dhe RIDE4DAPPS. Pjesa 2 (DAO - Organizata Autonome e Decentralizuar)

Çfarë problemesh ju lindin menjëherë me Alice? DAPP Llogari?
Во-первых:
Boob dhe Cooper mund të dërgojnë aksidentalisht fonde në adresën dApp duke përdorur të rregullt transferuar transaksionet dhe kështu nuk do të jetë në gjendje t'i qaset përsëri.

Во-вторых:
Ne nuk e kufizojmë në asnjë mënyrë Alice nga tërheqja e fondeve pa miratimin e Boob dhe/ose Cooper. Meqenëse, kushtojini vëmendje verifikimit, të gjitha transaksionet nga Alice do të ekzekutohen.

Le të rregullojmë të dytën duke e ndaluar Alice transferuar transaksionet. Le të vendosim skriptin e korrigjuar:
Mësoni të shkruani kontrata inteligjente të Waves në RIDE dhe RIDE4DAPPS. Pjesa 2 (DAO - Organizata Autonome e Decentralizuar)

Ne po përpiqemi të tërheqim monedha nga dApp Alice dhe nënshkrimi i saj. Ne marrim një gabim:
Mësoni të shkruani kontrata inteligjente të Waves në RIDE dhe RIDE4DAPPS. Pjesa 2 (DAO - Organizata Autonome e Decentralizuar)

Le të përpiqemi të tërhiqemi përmes tërheqjes:

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

Skenari funksionon dhe ne kuptuam pikën e dytë!

Faza 4. Krijo një DAO me votim

Fatkeqësisht, gjuha RIDE nuk ofron ende aftësinë për të punuar me koleksione (fjalorë fjalorë, përsëritës, reduktues, etj.). Megjithatë, për çdo operacion me koleksione të sheshta vlera kryesore ne mund të dizajnojmë një sistem për të punuar me vargje, në përputhje me rrethanat me çelësat dhe deshifrimin e tyre.

Vargjet janë shumë të lehta për t'u lidhur; vargjet mund të ndahen me indekse.
Le të mbledhim dhe analizojmë një varg si një shembull testimi dhe të kontrollojmë se si kjo ndikon në rezultatin e transaksionit.
Ne u vendosëm për faktin se Alice nuk mund të nënshkruante transaksionin e Transferimit, pasi kjo aftësi u bllokua në @verifier për këtë lloj transaksioni.

Le të praktikojmë me vargje dhe më pas ta zgjidhim këtë.

RIDE Strings

Transaksioni është i mundur përsëri, ne dimë të punojmë me vargje.
Mësoni të shkruani kontrata inteligjente të Waves në RIDE dhe RIDE4DAPPS. Pjesa 2 (DAO - Organizata Autonome e Decentralizuar)


Në total, ne kemi gjithçka të nevojshme për të shkruar logjikë komplekse DAO dApp.

Transaksionet e të dhënave

Transaksionet e të dhënave:
"Madhësia maksimale për një çelës është 100 karaktere dhe një çelës mund të përmbajë pika arbitrare të kodit të Unicode duke përfshirë hapësira dhe simbole të tjera jo të printueshme. Vlerat e vargut kanë një kufi prej 32,768 byte dhe numri maksimal i hyrjeve të mundshme në transaksionin e të dhënave është 100. Në përgjithësi, madhësia maksimale e një transaksioni të dhënash është rreth 140 kb - për referencë, pothuajse saktësisht gjatësia e shfaqjes së Shekspirit 'Romeo dhe Zhulieta '."

Ne krijojmë një DAO me kushtet e mëposhtme:
Në mënyrë që një startup të marrë fonde duke telefonuar getFunds () kërkohet mbështetja e të paktën 2 pjesëmarrësve - investitorë DAO. Të tërheqë do të jetë e mundur saktësisht aq sa është treguar totali votimi Pronarët e DAO.

Le të bëjmë 3 lloje çelësash dhe të shtojmë logjikën për të punuar me bilancet në 2 funksione të reja votoni dhe merrni fonde:
xx…xx_ia = investitorët, bilanci i disponueshëm (votim, depozitë, tërheqje)
xx…xx_sv = startups, numri i votave (votoni, merrni fonde)
xx…xx_sf = startups, numri i votave (votoni, merrni fonde)
xx…xx = adresë publike (35 karaktere)

Ju lutemi vini re se në Vote na është dashur të përditësojmë disa fusha njëherësh:

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

WriteSet na lejon të bëjmë disa regjistrime njëherësh brenda një invokeScript transaksionet.

Kështu duket në hapësirën ruajtëse të vlerës së çelësit të DAO dApp, pasi Bob dhe Cooper plotësuan ia-depozita:
Mësoni të shkruani kontrata inteligjente të Waves në RIDE dhe RIDE4DAPPS. Pjesa 2 (DAO - Organizata Autonome e Decentralizuar)

Funksioni ynë i depozitimit ka ndryshuar pak:
Mësoni të shkruani kontrata inteligjente të Waves në RIDE dhe RIDE4DAPPS. Pjesa 2 (DAO - Organizata Autonome e Decentralizuar)

Tani vjen momenti më i rëndësishëm në aktivitetet e DAO - votoj për projektet që do të financohen.

Bob voton për projektin 500000 valëzues të Nelit:

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

Mësoni të shkruani kontrata inteligjente të Waves në RIDE dhe RIDE4DAPPS. Pjesa 2 (DAO - Organizata Autonome e Decentralizuar)

Në dyqanin e të dhënave shohim të gjitha shënimet e nevojshme për adresën e Nelit:
Mësoni të shkruani kontrata inteligjente të Waves në RIDE dhe RIDE4DAPPS. Pjesa 2 (DAO - Organizata Autonome e Decentralizuar)
Cooper votoi gjithashtu për projektin Neli.
Mësoni të shkruani kontrata inteligjente të Waves në RIDE dhe RIDE4DAPPS. Pjesa 2 (DAO - Organizata Autonome e Decentralizuar)

Le të hedhim një vështrim në kodin e funksionit merrni fondet. Neli duhet të mbledhë një minimum prej 2 votash që të mund të tërheqë fonde nga DAO.
Mësoni të shkruani kontrata inteligjente të Waves në RIDE dhe RIDE4DAPPS. Pjesa 2 (DAO - Organizata Autonome e Decentralizuar)

Neli do të tërheqë gjysmën e shumës që i është besuar:

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

Mësoni të shkruani kontrata inteligjente të Waves në RIDE dhe RIDE4DAPPS. Pjesa 2 (DAO - Organizata Autonome e Decentralizuar)

Ajo ka sukses, domethënë DAO punon!

Ne shikuam procesin e krijimit të një DAO në gjuhë RIDE4DAPPS.
Në pjesët në vijim do t'i hedhim një vështrim më të afërt rifaktorimit të kodit dhe testimit të rasteve.

Versioni i plotë i kodit në IDE RIDE për valët:

# 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
    }
}

Pjesa e pare
Kodi në GitHub
Valët RIDE IDE
Shpallja e programit të granteve

Burimi: www.habr.com

Shto një koment