LÀr dig skriva Waves smarta kontrakt pÄ RIDE och RIDE4DAPPS. Del 2 (DAO - Decentraliserad autonom organisation)

LÀr dig skriva Waves smarta kontrakt pÄ RIDE och RIDE4DAPPS. Del 2 (DAO - Decentraliserad autonom organisation)

Hej alla!

В först del tittade vi i detalj pĂ„ hur man skapar och arbetar med dApp (decentraliserad applikation) i Waves RIDE IDE.

LÄt oss testa den demonterade lite nu exempel.

Steg 3. Testa dApp-kontot

LÀr dig skriva Waves smarta kontrakt pÄ RIDE och RIDE4DAPPS. Del 2 (DAO - Decentraliserad autonom organisation)

Vilka problem drabbar dig omedelbart med Alice? Dapp Konto?
För det första:
Boob och Cooper kan av misstag skicka pengar till dApp-adressen med vanliga överföring transaktioner och kommer dÀrför inte att kunna komma Ät dem tillbaka.

För det andra:
Vi hindrar inte Alice pÄ nÄgot sÀtt frÄn att ta ut pengar utan godkÀnnande av Boob och/eller Cooper. Eftersom, var uppmÀrksam pÄ att verifiera, kommer alla transaktioner frÄn Alice att utföras.

LÄt oss fixa 2:an genom att förbjuda Alice överföring transaktioner. LÄt oss distribuera det korrigerade skriptet:
LÀr dig skriva Waves smarta kontrakt pÄ RIDE och RIDE4DAPPS. Del 2 (DAO - Decentraliserad autonom organisation)
ïżŒ
Vi försöker ta ut mynt frÄn dApp Alice och hennes signatur. Vi fÄr ett felmeddelande:
LÀr dig skriva Waves smarta kontrakt pÄ RIDE och RIDE4DAPPS. Del 2 (DAO - Decentraliserad autonom organisation)

LÄt oss försöka dra tillbaka via dra ut:

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

Manuset fungerar och vi kom pÄ den andra punkten!

Steg 4. Skapa en DAO med röstning

TyvÀrr ger RIDE-sprÄket Ànnu inte möjligheten att arbeta med samlingar (ordboksordböcker, iteratorer, reducerare, etc.). Dock för alla operationer med platta samlingar nyckelvÀrde vi kan designa ett system för att arbeta med strÀngar, i enlighet dÀrmed med nycklar och deras dekryptering.

StrÀngar Àr mycket lÀtta att sammanfoga; strÀngar kan separeras med index.
LÄt oss samla och analysera en strÀng som ett testexempel och kontrollera hur detta pÄverkar resultatet av transaktionen.
Vi bestÀmde oss för att Alice inte kunde underteckna överföringstransaktionen, eftersom denna möjlighet var blockerad i @verifier för denna typ av transaktion.

LÄt oss öva med strÀngar och sedan lösa detta.

RIDE Strings

Transaktionen Àr möjlig igen, vi vet hur man arbetar med strÀngar.
LÀr dig skriva Waves smarta kontrakt pÄ RIDE och RIDE4DAPPS. Del 2 (DAO - Decentraliserad autonom organisation)

ïżŒ
Totalt har vi allt som behövs för att skriva komplex logik DAO dApp.

Datatransaktioner

Datatransaktioner:
"Den maximala storleken för en nyckel Àr 100 tecken, och en nyckel kan innehÄlla godtyckliga Unicode-kodpunkter inklusive mellanslag och andra icke-utskrivbara symboler. StrÀngvÀrden har en grÀns pÄ 32,768 100 byte och det maximala antalet möjliga poster i datatransaktionen Àr 140. Totalt sett Àr den maximala storleken pÄ en datatransaktion cirka XNUMX kb - för referens, nÀstan exakt lÀngden pÄ Shakespeares pjÀs 'Romeo och Julia' '.

Vi skapar en DAO med följande villkor:
För att en startup ska fÄ finansiering genom att ringa getFunds() stöd frÄn minst 2 deltagare - DAO-investerare - krÀvs. dra tillbaka det kommer att vara möjligt exakt sÄ mycket som summan som anges pÄ röstning DAO-Àgare.

LÄt oss skapa 3 typer av nycklar och lÀgga till logik för att arbeta med saldon i 2 nya funktioner rösta och getFunds:
xx
xx_ia = investerare, tillgĂ€ngligt saldo (rösta, insĂ€ttning, uttag)
xx
xx_sv = startups, antal röster (rösta, getFunds)
xx
xx_sf = startups, antal röster (rösta, getFunds)
xx
xx = offentlig adress (35 tecken)

Observera att vi i Vote behövde uppdatera flera fÀlt samtidigt:

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

WriteSet tillÄter oss att göra flera poster samtidigt inom en invokeScript transaktioner.

SÄ hÀr ser det ut i nyckel-vÀrde-lagringen av DAO dApp, efter att Bob och Cooper fyllt pÄ ia-insÀttningar:
LÀr dig skriva Waves smarta kontrakt pÄ RIDE och RIDE4DAPPS. Del 2 (DAO - Decentraliserad autonom organisation)

VÄr insÀttningsfunktion har Àndrats nÄgot:
LÀr dig skriva Waves smarta kontrakt pÄ RIDE och RIDE4DAPPS. Del 2 (DAO - Decentraliserad autonom organisation)

Nu kommer det viktigaste ögonblicket i DAO:s verksamhet - rösta för projekt som ska finansieras.

Bob röstar pÄ Nelis 500000 XNUMX wavelets-projekt:

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

LÀr dig skriva Waves smarta kontrakt pÄ RIDE och RIDE4DAPPS. Del 2 (DAO - Decentraliserad autonom organisation)

I datalagret ser vi alla nödvÀndiga poster för Nelis adress:
LÀr dig skriva Waves smarta kontrakt pÄ RIDE och RIDE4DAPPS. Del 2 (DAO - Decentraliserad autonom organisation)
Cooper röstade ocksÄ pÄ Neli-projektet.
LÀr dig skriva Waves smarta kontrakt pÄ RIDE och RIDE4DAPPS. Del 2 (DAO - Decentraliserad autonom organisation)

LÄt oss ta en titt pÄ funktionskoden getFunds. Neli mÄste samla minst 2 röster för att kunna ta ut pengar frÄn DAO.
LÀr dig skriva Waves smarta kontrakt pÄ RIDE och RIDE4DAPPS. Del 2 (DAO - Decentraliserad autonom organisation)

Neli kommer att ta ut hÀlften av det belopp som hon anförtrotts:

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

LÀr dig skriva Waves smarta kontrakt pÄ RIDE och RIDE4DAPPS. Del 2 (DAO - Decentraliserad autonom organisation)

Hon lyckas, det vill sÀga DAO fungerar!

Vi tittade pÄ processen att skapa en DAO pÄ sprÄket RIDE4DAPPS.
I de följande delarna kommer vi att titta nÀrmare pÄ kodrefaktorering och falltestning.

Den fullstÀndiga versionen av koden i 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
    }
}

Den första delen
Kod pÄ GitHub
Waves RIDE IDE
TillkÀnnagivande av bidragsprogrammet

KĂ€lla: will.com

Köp pĂ„litlig hosting för webbplatser med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster