RIDE və RIDE4DAPPS-də Waves ağıllı müqavilələri yazmağı öyrənmək. Hissə 2 (DAO - Mərkəzləşdirilməmiş Muxtar Təşkilat)

RIDE və RIDE4DAPPS-də Waves ağıllı müqavilələri yazmağı öyrənmək. Hissə 2 (DAO - Mərkəzləşdirilməmiş Muxtar Təşkilat)

Hello!

В birincisi hissədə dApp (mərkəzləşdirilməmiş proqram) yaratmağı və onunla işləməyi ətraflı nəzərdən keçirdik Dalğalar RIDE IDE.

İndi sökülən birini bir az sınaqdan keçirək misal.

Mərhələ 3. dApp hesabının sınaqdan keçirilməsi

RIDE və RIDE4DAPPS-də Waves ağıllı müqavilələri yazmağı öyrənmək. Hissə 2 (DAO - Mərkəzləşdirilməmiş Muxtar Təşkilat)

Alice ilə dərhal hansı problemlərlə qarşılaşırsınız? dApp Hesab?
Birincisi:
Boob və Cooper müntəzəm istifadə edərək təsadüfən dApp ünvanına pul göndərə bilər köçürmək əməliyyatları həyata keçirir və buna görə də onlara geri daxil ola bilməyəcək.

İkincisi:
Biz Boob və/və ya Kuperin razılığı olmadan Alicenin pul çıxarmasını heç bir şəkildə məhdudlaşdırmırıq. Doğrulamağa diqqət yetirdiyiniz üçün Alice-dən bütün əməliyyatlar yerinə yetiriləcəkdir.

Gəlin Aliceyə qadağa qoymaqla 2-ci yeri düzəldək köçürmək əməliyyatlar. Düzəliş edilmiş skripti yerləşdirək:
RIDE və RIDE4DAPPS-də Waves ağıllı müqavilələri yazmağı öyrənmək. Hissə 2 (DAO - Mərkəzləşdirilməmiş Muxtar Təşkilat)

Biz dApp Alice və onun imzasından sikkələri çıxarmağa çalışırıq. Səhv alırıq:
RIDE və RIDE4DAPPS-də Waves ağıllı müqavilələri yazmağı öyrənmək. Hissə 2 (DAO - Mərkəzləşdirilməmiş Muxtar Təşkilat)

Gəlin geri çəkilməklə geri çəkilməyə çalışaq:

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

Ssenari işləyir və biz 2-ci nöqtəni anladıq!

Mərhələ 4. Səsvermə ilə DAO yaradın

Təəssüf ki, RIDE dili kolleksiyalarla (lüğət lüğətləri, iteratorlar, reduktorlar və s.) işləmək qabiliyyətini hələ təmin etmir. Bununla belə, düz kolleksiyalarla istənilən əməliyyatlar üçün açar dəyəri biz sətirlərlə, müvafiq olaraq açarlarla və onların şifrəsinin açılması ilə işləmək üçün sistem tərtib edə bilərik.

Sətirləri birləşdirmək çox asandır; sətirləri indekslərlə ayırmaq olar.
Test nümunəsi kimi sətri toplayıb təhlil edək və bunun əməliyyatın nəticəsinə necə təsir etdiyini yoxlayaq.
Biz Alicenin Köçürmə əməliyyatını imzalaya bilməməsi ilə razılaşdıq, çünki bu imkan @verifier-də bu əməliyyat növü üçün bloklanıb.

Gəlin simlərlə məşq edək və sonra bunu həll edək.

RIDE Strings

Tranzaksiya yenidən mümkündür, biz strings ilə necə işləməyi bilirik.
RIDE və RIDE4DAPPS-də Waves ağıllı müqavilələri yazmağı öyrənmək. Hissə 2 (DAO - Mərkəzləşdirilməmiş Muxtar Təşkilat)


Ümumilikdə mürəkkəb məntiq yazmaq üçün lazım olan hər şeyimiz var DAO dApp.

Məlumat əməliyyatları

Məlumat əməliyyatları:
“Açar üçün maksimum ölçü 100 simvoldur və açarda boşluqlar və digər çap olunmayan simvollar daxil olmaqla ixtiyari Unicode kod nöqtələri ola bilər. Simli dəyərlərin həddi 32,768 baytdır və məlumat tranzaksiyasında mümkün daxiletmələrin maksimum sayı 100-dür. Ümumilikdə, məlumat əməliyyatının maksimum ölçüsü təxminən 140 kb-dir — istinad üçün, demək olar ki, Şekspirin “Romeo və Cülyetta” pyesinin uzunluğuna bərabərdir. '. ”

Aşağıdakı şərtlərlə DAO yaradırıq:
Başlanğıcın zəng edərək maliyyə alması üçün getFunds() ən azı 2 iştirakçının - DAO investorlarının dəstəyi tələb olunur. Geri çəkin üzərində göstərilən cəmi qədər mümkün olacaq səsvermə DAO sahibləri.

Gəlin 3 növ açar yaradaq və 2 yeni səs və getFunds funksiyasında balanslarla işləmək üçün məntiq əlavə edək:
xx...xx_ia = investorlar, mövcud balans (səs vermə, depozit, geri götürmə)
xx...xx_sv = startaplar, səslərin sayı (səs verin, pul qazanın)
xx...xx_sf = startaplar, səslərin sayı (səs verin, pul qazanın)
xx…xx = ümumi ünvan (35 simvol)

Nəzərə alın ki, Səsvermədə bir anda bir neçə sahəni yeniləməliydik:

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

WriteSet bizə eyni anda bir neçə qeyd etmək imkanı verir invokeScript əməliyyatlar.

Bob və Cooper doldurulduqdan sonra DAO dApp-ın əsas dəyər yaddaşında belə görünür ia- depozitlər:
RIDE və RIDE4DAPPS-də Waves ağıllı müqavilələri yazmağı öyrənmək. Hissə 2 (DAO - Mərkəzləşdirilməmiş Muxtar Təşkilat)

Depozit funksiyamız bir qədər dəyişdi:
RIDE və RIDE4DAPPS-də Waves ağıllı müqavilələri yazmağı öyrənmək. Hissə 2 (DAO - Mərkəzləşdirilməmiş Muxtar Təşkilat)

İndi DAO-nun fəaliyyətində ən vacib məqam gəlir - səsvermə maliyyələşdiriləcək layihələr üçün.

Bob Neli-nin 500000 dalğacık layihəsinə səs verir:

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

RIDE və RIDE4DAPPS-də Waves ağıllı müqavilələri yazmağı öyrənmək. Hissə 2 (DAO - Mərkəzləşdirilməmiş Muxtar Təşkilat)

Məlumat mağazasında Nelinin ünvanı üçün bütün lazımi qeydləri görürük:
RIDE və RIDE4DAPPS-də Waves ağıllı müqavilələri yazmağı öyrənmək. Hissə 2 (DAO - Mərkəzləşdirilməmiş Muxtar Təşkilat)
Kuper də Neli layihəsinə səs verib.
RIDE və RIDE4DAPPS-də Waves ağıllı müqavilələri yazmağı öyrənmək. Hissə 2 (DAO - Mərkəzləşdirilməmiş Muxtar Təşkilat)

Gəlin funksiya koduna nəzər salaq getFunds. Neli DAO-dan pul çıxara bilmək üçün minimum 2 səs toplamalıdır.
RIDE və RIDE4DAPPS-də Waves ağıllı müqavilələri yazmağı öyrənmək. Hissə 2 (DAO - Mərkəzləşdirilməmiş Muxtar Təşkilat)

Neli ona əmanət olunan məbləğin yarısını götürmək niyyətindədir:

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

RIDE və RIDE4DAPPS-də Waves ağıllı müqavilələri yazmağı öyrənmək. Hissə 2 (DAO - Mərkəzləşdirilməmiş Muxtar Təşkilat)

O, uğur qazanır, yəni DAO işləyir!

Dildə DAO-nun yaradılması prosesinə baxdıq RIDE4DAPPS.
Növbəti hissələrdə kodun refaktorinqi və iş testi ilə daha yaxından tanış olacağıq.

Kodun tam versiyası 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
    }
}

Birinci hissə
GitHub-da kod
Dalğalar RIDE IDE
Qrant proqramının elanı

Mənbə: www.habr.com

Добавить комментарий