Pag-aaral na magsulat ng mga Waves smart contract sa RIDE at RIDE4DAPPS. Bahagi 2 (DAO - Desentralisadong Autonomous Organization)

Pag-aaral na magsulat ng mga Waves smart contract sa RIDE at RIDE4DAPPS. Bahagi 2 (DAO - Desentralisadong Autonomous Organization)

Kumusta sa lahat!

Π’ una Sa bahaging ito, tinalakay namin nang detalyado kung paano lumikha at gumamit ng dApp (desentralisadong aplikasyon) sa Waves RIDE IDE.

Subukan natin nang kaunti ang na-disassemble na ngayon halimbawa.

Hakbang 3: Pagsubok sa dApp account

Pag-aaral na magsulat ng mga Waves smart contract sa RIDE at RIDE4DAPPS. Bahagi 2 (DAO - Desentralisadong Autonomous Organization)

Anong mga problema ang agad na pumupukaw sa iyong atensyon ni Alice? dApp Account?
Una:
Maaaring aksidenteng magpadala sina Boob at Cooper ng pondo sa isang dApp address gamit ang isang regular ilipat mga transaksyon at sa gayon ay hindi na nila maa-access muli ang mga ito.

Pangalawa:
Hindi namin pinaghihigpitan si Alice sa pag-withdraw ng pondo nang walang pag-apruba mula kina Boob o Cooper. Gaya ng nakikita mo, lahat ng transaksyon mula kay Alice ay isasagawa.

Ayusin natin ang pangalawa sa pamamagitan ng pag-ban kay Alice ilipat mga transaksyon. Pag-deploy ng naitama na script:
Pag-aaral na magsulat ng mga Waves smart contract sa RIDE at RIDE4DAPPS. Bahagi 2 (DAO - Desentralisadong Autonomous Organization)
οΏΌ
Sinusubukan naming mag-withdraw ng mga coin mula sa dApp ni Alice at sa signature nito. Nakakakuha kami ng error:
Pag-aaral na magsulat ng mga Waves smart contract sa RIDE at RIDE4DAPPS. Bahagi 2 (DAO - Desentralisadong Autonomous Organization)

Subukan nating mag-withdraw gamit ang withdraw:

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

Gumagana ang script at naayos na natin ang punto 2!

Hakbang 4: Gumawa ng DAO gamit ang pagboto

Sa kasamaang palad, ang wikang RIDE ay hindi pa nagbibigay ng mga kakayahan para sa pagtatrabaho sa mga koleksyon (mga diksyunaryo ng mga diksyunaryo, mga iterator, mga reducer, atbp.). Gayunpaman, para sa anumang operasyon na may mga flat collection mahalagang halaga Maaari tayong magdisenyo ng isang sistema para sa pagtatrabaho gamit ang mga string, nang naaayon sa mga key at sa kanilang decryption.

Napakadaling pagdugtungin ang mga string, maaaring hatiin ang mga string gamit ang mga index.
Bilang isang halimbawa ng pagsubok, ating tipunin at i-parse ang isang string at suriin kung paano nito naaapektuhan ang resulta ng transaksyon.
Hindi natuloy ang pagpirma ni Alice sa transaksyon ng Transfer dahil naharang ang kakayahang ito sa @verifier para sa ganitong uri ng transaksyon.

Magsanay tayo gamit ang mga tali at pagkatapos ay lutasin ito.

Mga Kuwerdas ng RIDE

Posible na ulit ang transaksyon, alam na natin kung paano gumamit ng mga string.
Pag-aaral na magsulat ng mga Waves smart contract sa RIDE at RIDE4DAPPS. Bahagi 2 (DAO - Desentralisadong Autonomous Organization)

οΏΌ
Kaya, mayroon tayo ng lahat ng kailangan natin para magsulat ng kumplikadong lohika. DAO dApp.

Mga Transaksyon ng Datos

Mga Transaksyon ng Datos:
"Ang pinakamataas na laki para sa isang susi ay 100 karakter, at ang isang susi ay maaaring maglaman ng mga arbitraryong Unicode code point kabilang ang mga espasyo at iba pang hindi maaaring i-print na mga simbolo. Ang mga halaga ng string ay may limitasyon na 32,768 bytes at ang pinakamataas na bilang ng mga posibleng entry sa transaksyon ng data ay 100. Sa pangkalahatan, ang pinakamataas na laki ng isang transaksyon ng data ay nasa humigit-kumulang 140kb β€” bilang sanggunian, halos eksaktong haba ng dula ni Shakespeare na 'Romeo and Juliet'."

Gumagawa kami ng DAO na may mga sumusunod na kondisyon:
Para makatanggap ng pondo ang isang startup sa pamamagitan ng pagtawag kumuha ng mga Pondo() Kinakailangan ang suporta ng kahit 2 kalahok – mga mamumuhunan ng DAO. Mag-withdraw magiging posible na magkaroon ng eksaktong dami ng kabuuang nakasaad sa pagboto Mga may-ari ng DAO.

Gumawa tayo ng 3 uri ng mga susi at magdagdag ng lohika para sa pagtatrabaho sa mga balanse sa 2 bagong function, bumoto at kumuha ng mga pondo:
xx…xx_ia = mga mamumuhunan, magagamit na balanse (boto, deposito, pag-withdraw)
xx…xx_sv = mga startup, bilang ng mga boto (boto, kumuha ng mga pondo)
xx…xx_sf = mga startup, bilang ng mga boto (boto, kumuha ng mga pondo)
xx…xx = pampublikong adres (35 karakter)

Tandaan na sa Vote kailangan naming i-update ang ilang field nang sabay-sabay:

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

Pinapayagan tayo ng WriteSet na gumawa ng maraming talaan nang sabay-sabay sa loob ng isa invokeScript mga transaksyon.

Ganito ang hitsura sa DAO dApp key-value store pagkatapos mag-refill nina Bob at Cooper ia-mga deposito:
Pag-aaral na magsulat ng mga Waves smart contract sa RIDE at RIDE4DAPPS. Bahagi 2 (DAO - Desentralisadong Autonomous Organization)

Bahagyang nagbago ang aming tungkulin sa pagdeposito:
Pag-aaral na magsulat ng mga Waves smart contract sa RIDE at RIDE4DAPPS. Bahagi 2 (DAO - Desentralisadong Autonomous Organization)

Ngayon ay dumating ang pinakamahalagang sandali sa mga aktibidad ng DAO - bumoto para sa mga proyektong kailangang pondohan.

Bumoto si Bob para sa proyektong 500000 wavelets ni Neli:

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

Pag-aaral na magsulat ng mga Waves smart contract sa RIDE at RIDE4DAPPS. Bahagi 2 (DAO - Desentralisadong Autonomous Organization)

Sa data warehouse, makikita natin ang lahat ng kinakailangang rekord para sa address ni Neli:
Pag-aaral na magsulat ng mga Waves smart contract sa RIDE at RIDE4DAPPS. Bahagi 2 (DAO - Desentralisadong Autonomous Organization)
Bumoto rin si Cooper para sa proyektong Neli.
Pag-aaral na magsulat ng mga Waves smart contract sa RIDE at RIDE4DAPPS. Bahagi 2 (DAO - Desentralisadong Autonomous Organization)

Tingnan natin ang function code kumuha ng mga PondoKailangang makakuha si Neli ng kahit dalawang boto para makapag-withdraw ng pondo mula sa DAO.
Pag-aaral na magsulat ng mga Waves smart contract sa RIDE at RIDE4DAPPS. Bahagi 2 (DAO - Desentralisadong Autonomous Organization)

Babawiin ni Neli ang kalahati ng halagang ipinagkatiwala sa kanya:

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

Pag-aaral na magsulat ng mga Waves smart contract sa RIDE at RIDE4DAPPS. Bahagi 2 (DAO - Desentralisadong Autonomous Organization)

Nagtatagumpay siya, ibig sabihin, gumagana ang DAO!

Natalakay na natin ang proseso ng paggawa ng DAO sa wikang RIDE4DAPPS.
Sa mga susunod na bahagi, susuriin natin nang mas malapitan ang code refactoring at case testing.

Ang buong bersyon ng code ay nasa IDE NG PAGSAKAY SA Waves:

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

Ang unang bahagi
Kodigo sa GitHub
Waves RIDE IDE
Anunsyo ng programa ng grant

Pinagmulan: www.habr.com

Bumili ng maaasahang pagho-host para sa mga site na may proteksyon ng DDoS, mga server ng VPS VDS πŸ”₯ Bumili ng maaasahang website hosting na may proteksyon ng DDoS, VPS VDS servers | ProHoster