RIDE va ​​RIDE4DAPPS-da Waves aqlli shartnomalarini yozishni o'rganish. 2-qism (DAO - markazlashtirilmagan avtonom tashkilot)

RIDE va ​​RIDE4DAPPS-da Waves aqlli shartnomalarini yozishni o'rganish. 2-qism (DAO - markazlashtirilmagan avtonom tashkilot)

Hammaga salom!

В birinchisi Ushbu bo'limda biz dApp (markazlashtirilmagan dastur) ni qanday yaratish va u bilan ishlashni batafsil ko'rib chiqdik To'lqinlar sayohati IDE.

Keling, endi demontaj qilinganini biroz sinab ko'raylik misol.

3-qadam: dApp hisobini sinab ko'rish

RIDE va ​​RIDE4DAPPS-da Waves aqlli shartnomalarini yozishni o'rganish. 2-qism (DAO - markazlashtirilmagan avtonom tashkilot)

Elis bilan qanday muammolar darhol ko'zingizni qamashtiradi? toza Hisobingiz?
Birinchidan:
Boob va Cooper tasodifan oddiy hisobdan foydalanib, dApp manziliga mablag' yuborishlari mumkin uzatish tranzaksiyalar va shuning uchun ularga qayta kira olmaydi.

Ikkinchisi:
Biz Elisga Boob va/yoki Cooperning roziligisiz mablag'larni yechib olishni cheklamaymiz. Ko'rib turganingizdek, Elisdan barcha tranzaksiyalar tasdiqlash tugmasi bilan ko'rsatilganidek amalga oshiriladi.

Keling, Elisni taqiqlash orqali 2-chi o'rinni tuzatamiz uzatish tranzaksiyalar. Tuzatilgan skriptni joylashtirish:
RIDE va ​​RIDE4DAPPS-da Waves aqlli shartnomalarini yozishni o'rganish. 2-qism (DAO - markazlashtirilmagan avtonom tashkilot)

Biz Alisning dApp va uning imzosidan tangalarni yechib olishga harakat qilmoqdamiz. Xatolik yuz bermoqda:
RIDE va ​​RIDE4DAPPS-da Waves aqlli shartnomalarini yozishni o'rganish. 2-qism (DAO - markazlashtirilmagan avtonom tashkilot)

Keling, pulni qaytarib olish orqali pulni qaytarib olishga harakat qilaylik:

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

Skript ishlayapti va biz 2-bandni hal qildik!

4-qadam: Ovoz berish orqali DAO yarating

Afsuski, RIDE tili hali to'plamlar (lug'atlar lug'atlari, iteratorlar, qisqartiruvchilar va boshqalar) bilan ishlash imkoniyatlarini taqdim etmaydi. Biroq, tekis to'plamlar bilan har qanday operatsiyalar uchun kalit-qiymat Biz satrlar bilan ishlash uchun tizimni, shunga mos ravishda kalitlar va ularning shifrini ochish tizimini loyihalashimiz mumkin.

Satrlarni birlashtirish juda oson, satrlarni indekslar bo'yicha ajratish mumkin.
Sinov misoli sifatida, keling, satrni yig'ib, tahlil qilaylik va bu tranzaksiya natijasiga qanday ta'sir qilishini tekshirib ko'ramiz.
Oxir-oqibat, biz Elisning o'tkazma tranzaksiyasini imzolay olmasligiga duch keldik, chunki bu imkoniyat @verifier da ushbu turdagi tranzaksiya uchun bloklangan edi.

Keling, torlar bilan mashq qilaylik va keyin buni yechaylik.

RIDE torlari

Tranzaksiya yana mumkin, biz satrlar bilan qanday ishlashni bilamiz.
RIDE va ​​RIDE4DAPPS-da Waves aqlli shartnomalarini yozishni o'rganish. 2-qism (DAO - markazlashtirilmagan avtonom tashkilot)


Shunday qilib, bizda murakkab mantiq yozish uchun kerak bo'lgan hamma narsa bor. DAO dApp.

Ma'lumotlar tranzaksiyalari

Ma'lumotlar tranzaksiyalari:
"Kalitning maksimal hajmi 100 ta belgidan iborat bo'lib, kalitda bo'shliqlar va boshqa chop etilmaydigan belgilarni o'z ichiga olgan ixtiyoriy Unicode kod nuqtalari bo'lishi mumkin. Satr qiymatlari 32 768 bayt chegarasiga ega va ma'lumotlar tranzaksiyasida mumkin bo'lgan maksimal yozuvlar soni 100 ta. Umuman olganda, ma'lumotlar tranzaksiyasining maksimal hajmi taxminan 140 kb ni tashkil qiladi - ma'lumot uchun, bu Shekspirning "Romeo va Juliet" pyesasining uzunligiga deyarli teng."

Biz quyidagi shartlar bilan DAO yaratamiz:
Startap qo'ng'iroq qilish orqali mablag' olishi uchun getFunds() Kamida 2 ishtirokchining - DAO investorlarining - ko'magi talab qilinadi. Chiqish ko'rsatilgan umumiy miqdorga teng bo'lishi mumkin bo'ladi ovoz berish DAO egalari.

Keling, 3 xil kalit yaratamiz va 2 ta yangi funksiyada, vote va getFunds da balanslar bilan ishlash uchun mantiq qo'shamiz:
xx…xx_ia = investorlar, mavjud qoldiq (ovoz berish, depozit qo'yish, pulni qaytarib olish)
xx…xx_sv = startaplar, ovozlar soni (ovoz bering, mablag'larni oling)
xx…xx_sf = startaplar, ovozlar soni (ovoz bering, mablag'larni oling)
xx…xx = ommaviy manzil (35 belgi)

E'tibor bering, Ovoz berishda biz bir vaqtning o'zida bir nechta maydonlarni yangilashimiz kerak edi:

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

WriteSet bizga bir vaqtning o'zida bir nechta yozuvlarni bitta faylda yaratish imkonini beradi invokeScript tranzaksiyalar.

Bob va Kuper to'ldirgandan so'ng, DAO dApp kalit qiymatlari do'konida shunday ko'rinadi ia-omonatlar:
RIDE va ​​RIDE4DAPPS-da Waves aqlli shartnomalarini yozishni o'rganish. 2-qism (DAO - markazlashtirilmagan avtonom tashkilot)

Bizning depozit funksiyamiz biroz o'zgardi:
RIDE va ​​RIDE4DAPPS-da Waves aqlli shartnomalarini yozishni o'rganish. 2-qism (DAO - markazlashtirilmagan avtonom tashkilot)

Endi DAO faoliyatidagi eng muhim lahzalar keldi - ovoz berish moliyalashtiriladigan loyihalar uchun.

Bob Nelining 500 000 ta veylets loyihasiga ovoz berdi:

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

RIDE va ​​RIDE4DAPPS-da Waves aqlli shartnomalarini yozishni o'rganish. 2-qism (DAO - markazlashtirilmagan avtonom tashkilot)

Ma'lumotlar omborida biz Nelining manzili uchun barcha kerakli yozuvlarni ko'ramiz:
RIDE va ​​RIDE4DAPPS-da Waves aqlli shartnomalarini yozishni o'rganish. 2-qism (DAO - markazlashtirilmagan avtonom tashkilot)
Kuper ham Neli loyihasiga ovoz berdi.
RIDE va ​​RIDE4DAPPS-da Waves aqlli shartnomalarini yozishni o'rganish. 2-qism (DAO - markazlashtirilmagan avtonom tashkilot)

Keling, funksiya kodini ko'rib chiqaylik getFundsNeli DAOdan mablag'larni olish uchun kamida 2 ta ovoz to'plashi kerak.
RIDE va ​​RIDE4DAPPS-da Waves aqlli shartnomalarini yozishni o'rganish. 2-qism (DAO - markazlashtirilmagan avtonom tashkilot)

Neli unga ishonib topshirilgan summaning yarmini olib qo'ymoqchi:

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

RIDE va ​​RIDE4DAPPS-da Waves aqlli shartnomalarini yozishni o'rganish. 2-qism (DAO - markazlashtirilmagan avtonom tashkilot)

U muvaffaqiyatga erishadi, ya'ni DAO ishlaydi!

Biz tilda DAO yaratish jarayonini ko'rib chiqdik RIDE4DAPPS.
Keyingi qismlarda biz kodni qayta ishlash va holatlarni sinovdan o'tkazishni batafsil ko'rib chiqamiz.

Kodning to'liq versiyasi To'lqinlar sayohati 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
    }
}

Birinchi qism
GitHub’dagi kod
To'lqinlar sayohati IDE
Grant dasturi e'lon qilindi

Manba: www.habr.com

DDoS himoyasi, VPS VDS serverlari bo'lgan saytlar uchun ishonchli hosting sotib oling 🔥 DDoS himoyasi, VPS VDS serverlari bilan ishonchli veb-sayt xostingini sotib oling | ProHoster