Kujifunza kuandika mikataba mahiri ya Waves kwenye RIDE na RIDE4DAPPS. Sehemu ya 2 (DAO - Shirika Linalojiendesha Lililogatuliwa)

Kujifunza kuandika mikataba mahiri ya Waves kwenye RIDE na RIDE4DAPPS. Sehemu ya 2 (DAO - Shirika Linalojiendesha Lililogatuliwa)

Hello kila mtu!

В kwanza sehemu tuliangalia kwa undani jinsi ya kuunda na kufanya kazi na dApp (programu iliyogawanywa) katika Mawimbi RIDE IDE.

Wacha tujaribu ile iliyovunjwa kidogo sasa mfano.

Hatua ya 3. Kujaribu akaunti ya dApp

Kujifunza kuandika mikataba mahiri ya Waves kwenye RIDE na RIDE4DAPPS. Sehemu ya 2 (DAO - Shirika Linalojiendesha Lililogatuliwa)

Je, ni matatizo gani yanakujia mara moja na Alice? dApp Akaunti?
Kwanza:
Boob na Cooper wanaweza kutuma pesa kimakosa kwa anwani ya dApp kwa kutumia kawaida kuhamisha shughuli na hivyo hawataweza kuzipata tena.

Pili:
Hatumzuii Alice kwa njia yoyote ile kutoa pesa bila idhini ya Boob na/au Cooper. Kwa kuwa, makini na kuthibitisha, shughuli zote kutoka kwa Alice zitatekelezwa.

Hebu turekebishe ya 2 kwa kumpiga marufuku Alice kuhamisha shughuli. Wacha tupeleke hati iliyosahihishwa:
Kujifunza kuandika mikataba mahiri ya Waves kwenye RIDE na RIDE4DAPPS. Sehemu ya 2 (DAO - Shirika Linalojiendesha Lililogatuliwa)

Tunajaribu kutoa sarafu kutoka kwa dApp Alice na sahihi yake. Tunapata hitilafu:
Kujifunza kuandika mikataba mahiri ya Waves kwenye RIDE na RIDE4DAPPS. Sehemu ya 2 (DAO - Shirika Linalojiendesha Lililogatuliwa)

Wacha tujaribu kujiondoa kupitia kujiondoa:

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

Maandishi hufanya kazi na tukagundua hatua ya 2!

Hatua ya 4. Unda DAO kwa kupiga kura

Kwa bahati mbaya, lugha ya RIDE bado haitoi uwezo wa kufanya kazi na makusanyo (kamusi za kamusi, iterators, vipunguzi, nk). Walakini, kwa shughuli zozote zilizo na makusanyo ya gorofa thamani muhimu tunaweza kubuni mfumo wa kufanya kazi na kamba, ipasavyo na funguo na usimbuaji wao.

Kamba ni rahisi sana kubatanishwa; mifuatano inaweza kutenganishwa na faharasa.
Hebu tukusanye na tuchanganue mfuatano kama mfano wa jaribio na tuangalie jinsi hii inavyoathiri matokeo ya muamala.
Tulikubaliana na ukweli kwamba Alice hangeweza kusaini muamala wa Uhamisho, kwa kuwa fursa hii ilizuiwa katika @verifier kwa aina hii ya ununuzi.

Wacha tufanye mazoezi na kamba kisha tusuluhishe hili.

RIDE Kamba

Shughuli hiyo inawezekana tena, tunajua jinsi ya kufanya kazi na masharti.
Kujifunza kuandika mikataba mahiri ya Waves kwenye RIDE na RIDE4DAPPS. Sehemu ya 2 (DAO - Shirika Linalojiendesha Lililogatuliwa)


Kwa jumla, tuna kila kitu muhimu kuandika mantiki ngumu DAO dApp.

Miamala ya Data

Miamala ya Data:
"Ukubwa wa juu wa ufunguo ni herufi 100, na ufunguo unaweza kuwa na alama za nambari za Unicode kiholela ikijumuisha nafasi na alama zingine zisizoweza kuchapishwa. Thamani za kamba zina kikomo cha baiti 32,768 na idadi ya juu zaidi ya maingizo yanayowezekana katika shughuli ya data ni 100. Kwa ujumla, ukubwa wa juu wa shughuli ya data ni karibu 140kb - kwa marejeleo, karibu urefu wa tamthilia ya Shakespeare 'Romeo na Juliet. '."

Tunaunda DAO na masharti yafuatayo:
Ili kuanza kupokea ufadhili kwa kupiga simu getFunds() msaada wa angalau washiriki 2 - wawekezaji wa DAO - inahitajika. Ondoa itawezekana sawasawa na jumla iliyoonyeshwa kupiga kura Wamiliki wa DAO.

Hebu tutengeneze aina 3 za funguo na tuongeze mantiki ya kufanya kazi na salio katika kura 2 za utendaji mpya na getFunds:
xx…xx_ia = wawekezaji, usawa unaopatikana (kura, kuweka, kutoa)
xx…xx_sv = kuanza, idadi ya kura (piga kura, pataFunds)
xx…xx_sf = kuanza, idadi ya kura (piga kura, pataFunds)
xx…xx = anwani ya umma (herufi 35)

Tafadhali kumbuka kuwa katika Kura tulihitaji kusasisha sehemu kadhaa mara moja:

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

WriteSet huturuhusu kutengeneza rekodi kadhaa mara moja ndani ya moja invokeScript shughuli.

Hivi ndivyo inavyoonekana katika uhifadhi wa thamani ya DAO dApp, baada ya Bob na Cooper kujaza tena. ia-amana:
Kujifunza kuandika mikataba mahiri ya Waves kwenye RIDE na RIDE4DAPPS. Sehemu ya 2 (DAO - Shirika Linalojiendesha Lililogatuliwa)

Utendaji wetu wa amana umebadilika kidogo:
Kujifunza kuandika mikataba mahiri ya Waves kwenye RIDE na RIDE4DAPPS. Sehemu ya 2 (DAO - Shirika Linalojiendesha Lililogatuliwa)

Sasa inakuja wakati muhimu zaidi katika shughuli za DAO - kupiga kura kwa miradi itakayofadhiliwa.

Bob anapigia kura mradi wa Neli wa mawimbi 500000:

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

Kujifunza kuandika mikataba mahiri ya Waves kwenye RIDE na RIDE4DAPPS. Sehemu ya 2 (DAO - Shirika Linalojiendesha Lililogatuliwa)

Katika hifadhi ya data tunaona maingizo yote muhimu ya anwani ya Neli:
Kujifunza kuandika mikataba mahiri ya Waves kwenye RIDE na RIDE4DAPPS. Sehemu ya 2 (DAO - Shirika Linalojiendesha Lililogatuliwa)
Cooper pia alipigia kura mradi wa Neli.
Kujifunza kuandika mikataba mahiri ya Waves kwenye RIDE na RIDE4DAPPS. Sehemu ya 2 (DAO - Shirika Linalojiendesha Lililogatuliwa)

Hebu tuangalie msimbo wa kazi getFunds. Neli lazima akusanye angalau kura 2 ili kuweza kutoa pesa kutoka kwa DAO.
Kujifunza kuandika mikataba mahiri ya Waves kwenye RIDE na RIDE4DAPPS. Sehemu ya 2 (DAO - Shirika Linalojiendesha Lililogatuliwa)

Neli atatoa nusu ya kiasi alichokabidhiwa:

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

Kujifunza kuandika mikataba mahiri ya Waves kwenye RIDE na RIDE4DAPPS. Sehemu ya 2 (DAO - Shirika Linalojiendesha Lililogatuliwa)

Anafaulu, yaani, DAO inafanya kazi!

Tuliangalia mchakato wa kuunda DAO katika lugha RIDE4DAPPS.
Katika sehemu zifuatazo tutaangalia kwa karibu urekebishaji wa nambari na upimaji wa kesi.

Toleo kamili la msimbo ndani Mawimbi 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
    }
}

sehemu ya kwanza
Rekodi kwenye GitHub
Mawimbi RIDE IDE
Tangazo la mpango wa ruzuku

Chanzo: mapenzi.com

Kuongeza maoni