Սովորում ենք գրել Waves խելացի պայմանագրեր RIDE-ի և RIDE4DAPPS-ի վրա: Մաս 2 (DAO - Ապակենտրոնացված ինքնավար կազմակերպություն)

Սովորում ենք գրել Waves խելացի պայմանագրեր RIDE-ի և RIDE4DAPPS-ի վրա: Մաս 2 (DAO - Ապակենտրոնացված ինքնավար կազմակերպություն)

Hello everyone!

В առաջինը մասում մենք մանրամասնորեն նայեցինք, թե ինչպես ստեղծել և աշխատել dApp-ի հետ (ապակենտրոնացված հավելված): Ալիքներ RIDE IDE.

Եկեք հիմա մի փոքր փորձարկենք ապամոնտաժվածը օրինակ.

Փուլ 3. dApp հաշվի փորձարկում

Սովորում ենք գրել Waves խելացի պայմանագրեր RIDE-ի և RIDE4DAPPS-ի վրա: Մաս 2 (DAO - Ապակենտրոնացված ինքնավար կազմակերպություն)

Ի՞նչ խնդիրներ են անմիջապես առաջանում ձեզ Ալիսի հետ: դԱՊ Հաշիվ?
Առաջին
Boob-ը և Cooper-ը կարող են պատահաբար միջոցներ ուղարկել dApp հասցեին՝ սովորական օգտագործելով փոխանցել գործարքներ և, հետևաբար, չեն կարողանա ետ մուտք գործել դրանց:

Երկրորդ `
Մենք ոչ մի կերպ չենք սահմանափակում Ալիսին միջոցների դուրսբերումը առանց Boob-ի և/կամ Cooper-ի հավանության: Քանի որ ուշադրություն դարձրեք ստուգմանը, Ալիսից բոլոր գործարքները կկատարվեն:

Եկեք ուղղենք 2-րդը՝ արգելելով Ալիսին փոխանցել գործարքներ. Եկեք տեղակայենք շտկված սցենարը.
Սովորում ենք գրել Waves խելացի պայմանագրեր RIDE-ի և RIDE4DAPPS-ի վրա: Մաս 2 (DAO - Ապակենտրոնացված ինքնավար կազմակերպություն)

Մենք փորձում ենք մետաղադրամներ հանել dApp Alice-ից և նրա ստորագրությունից: Մենք ստանում ենք սխալ.
Սովորում ենք գրել Waves խելացի պայմանագրեր RIDE-ի և RIDE4DAPPS-ի վրա: Մաս 2 (DAO - Ապակենտրոնացված ինքնավար կազմակերպություն)

Փորձենք հանել դուրսբերման միջոցով.

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

Սցենարն աշխատում է, և մենք պարզեցինք 2-րդ կետը:

Փուլ 4. Ստեղծեք DAO քվեարկությամբ

Ցավոք, RIDE լեզուն դեռ չի ապահովում հավաքածուների հետ աշխատելու հնարավորություն (բառարանային բառարաններ, կրկնողներ, կրճատիչներ և այլն): Այնուամենայնիվ, հարթ հավաքածուներով ցանկացած գործողությունների համար առանցքային արժեք մենք կարող ենք նախագծել լարերի հետ աշխատելու համակարգ, համապատասխանաբար՝ բանալիների և դրանց վերծանման:

Տողերը շատ հեշտ են միացվում, տողերը կարելի է բաժանել ինդեքսներով:
Եկեք հավաքենք և վերլուծենք տողը որպես թեստային օրինակ և ստուգենք, թե ինչպես է դա ազդում գործարքի արդյունքի վրա:
Մենք որոշեցինք այն փաստը, որ Ալիսը չէր կարող ստորագրել Փոխանցման գործարքը, քանի որ այս հնարավորությունն արգելափակված էր @verifier-ում այս տեսակի գործարքի համար:

Եկեք պարապենք լարերի հետ և հետո լուծենք սա:

RIDE Strings

Գործարքը կրկին հնարավոր է, մենք գիտենք, թե ինչպես աշխատել տողերի հետ:
Սովորում ենք գրել Waves խելացի պայմանագրեր RIDE-ի և RIDE4DAPPS-ի վրա: Մաս 2 (DAO - Ապակենտրոնացված ինքնավար կազմակերպություն)


Ընդհանուր առմամբ, մենք ունենք այն ամենը, ինչ անհրաժեշտ է բարդ տրամաբանություն գրելու համար DAO dApp.

Տվյալների գործարքներ

Տվյալների գործարքներ.
«Բանալին առավելագույն չափը 100 նիշ է, և բանալին կարող է պարունակել կամայական Unicode ծածկագրի կետեր՝ ներառյալ բացատները և այլ ոչ տպագրվող նշանները: Լարային արժեքներն ունեն 32,768 բայթ սահմանաչափ, իսկ տվյալների գործարքում հնարավոր մուտքերի առավելագույն քանակը 100 է: Ընդհանուր առմամբ տվյալների գործարքի առավելագույն չափը կազմում է մոտ 140 կբ. '.

Մենք ստեղծում ենք DAO հետևյալ պայմաններով.
Որպեսզի ստարտափը ֆինանսավորում ստանա զանգահարելով getFunds () Պահանջվում է առնվազն 2 մասնակիցների՝ DAO ներդրողների աջակցությունը: Վերցրեք դա հնարավոր կլինի ճիշտ այնքան, որքան նշված է ընդհանուր գումարը քվեարկություն DAO-ի սեփականատերերը.

Եկեք ստեղծենք 3 տեսակի ստեղներ և ավելացնենք տրամաբանություն մնացորդների հետ աշխատելու համար 2 նոր գործառույթների ձայնագրման և ստացման համար:
xx…xx_իա = ներդրողներ, հասանելի մնացորդ (քվեարկություն, ավանդ, դուրսբերում)
xx…xx_sv = ստարտափներ, ձայների քանակ (քվեարկել, ստանալ միջոցներ)
xx…xx_sf = ստարտափներ, ձայների քանակ (քվեարկել, ստանալ միջոցներ)
xx…xx = հանրային հասցե (35 նիշ)

Խնդրում ենք նկատի ունենալ, որ Vote-ում մեզ անհրաժեշտ էր թարմացնել միանգամից մի քանի դաշտ.

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

WriteSet-ը թույլ է տալիս մեզ միանգամից մի քանի գրառում կատարել մեկում invokeScript գործարքներ.

Ահա թե ինչ տեսք ունի DAO dApp-ի բանալիների արժեքի պահեստում՝ Բոբի և Կուպերի համալրումից հետո։ ia- ավանդներ:
Սովորում ենք գրել Waves խելացի պայմանագրեր RIDE-ի և RIDE4DAPPS-ի վրա: Մաս 2 (DAO - Ապակենտրոնացված ինքնավար կազմակերպություն)

Մեր ավանդի գործառույթը մի փոքր փոխվել է.
Սովորում ենք գրել Waves խելացի պայմանագրեր RIDE-ի և RIDE4DAPPS-ի վրա: Մաս 2 (DAO - Ապակենտրոնացված ինքնավար կազմակերպություն)

Այժմ գալիս է DAO-ի գործունեության ամենակարևոր պահը. քվեարկություն ֆինանսավորվելիք ծրագրերի համար։

Բոբը քվեարկում է Նելիի 500000 ալիքների նախագծի օգտին.

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

Սովորում ենք գրել Waves խելացի պայմանագրեր RIDE-ի և RIDE4DAPPS-ի վրա: Մաս 2 (DAO - Ապակենտրոնացված ինքնավար կազմակերպություն)

Տվյալների պահեստում մենք տեսնում ենք Նելի հասցեի համար անհրաժեշտ բոլոր գրառումները.
Սովորում ենք գրել Waves խելացի պայմանագրեր RIDE-ի և RIDE4DAPPS-ի վրա: Մաս 2 (DAO - Ապակենտրոնացված ինքնավար կազմակերպություն)
Կուպերը նույնպես քվեարկել է Neli նախագծի օգտին։
Սովորում ենք գրել Waves խելացի պայմանագրեր RIDE-ի և RIDE4DAPPS-ի վրա: Մաս 2 (DAO - Ապակենտրոնացված ինքնավար կազմակերպություն)

Եկեք նայենք ֆունկցիայի կոդը getFunds. Նելին պետք է հավաքի նվազագույնը 2 ձայն, որպեսզի կարողանա միջոցներ հանել DAO-ից:
Սովորում ենք գրել Waves խելացի պայմանագրեր RIDE-ի և RIDE4DAPPS-ի վրա: Մաս 2 (DAO - Ապակենտրոնացված ինքնավար կազմակերպություն)

Նելին պատրաստվում է հետ վերցնել իրեն վստահված գումարի կեսը.

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

Սովորում ենք գրել Waves խելացի պայմանագրեր RIDE-ի և RIDE4DAPPS-ի վրա: Մաս 2 (DAO - Ապակենտրոնացված ինքնավար կազմակերպություն)

Նրան հաջողվում է, այսինքն՝ DAO-ն աշխատում է։

Մենք նայեցինք լեզվով DAO ստեղծելու գործընթացին RIDE4DAPPS.
Հետևյալ մասերում մենք ավելի մանրամասն կանդրադառնանք կոդերի վերամշակմանը և դեպքերի փորձարկմանը:

Կոդի ամբողջական տարբերակը մուտքագրվում է Ալիքներ 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
    }
}

Առաջին մասը
Կոդ GitHub-ում
Ալիքներ RIDE IDE
Դրամաշնորհային ծրագրի հայտարարություն

Source: www.habr.com

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