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 Katika sehemu hii tuliangalia kwa undani jinsi ya kuunda na kufanya kazi na dApp (programu iliyogatuliwa) katika IDE ya Mawimbi ya Safari.

Hebu 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)

Ni matatizo gani yanayokuvutia mara moja na Alice? dApp Akaunti?
Kwanza:
Boob na Cooper wanaweza kutuma pesa kwa bahati mbaya kwa anwani ya dApp kwa kutumia njia ya kawaida kuhamisha miamala na hivyo haitaweza kuifikia tena.

Pili:
Hatumzuii Alice kutoa pesa bila idhini kutoka kwa Boob na/au Cooper. Kama unavyoona, miamala yote kutoka kwa Alice itatekelezwa, kama inavyoonyeshwa na kitufe cha kuthibitisha.

Turekebishe la pili kwa kupiga marufuku Alice kuhamisha miamala. Kutumia 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 ya Alice na sahihi yake. Tunapata hitilafu:
Kujifunza kuandika mikataba mahiri ya Waves kwenye RIDE na RIDE4DAPPS. Sehemu ya 2 (DAO - Shirika Linalojiendesha Lililogatuliwa)

Hebu tujaribu kutoa pesa kupitia kutoa pesa:

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

Hati inafanya kazi na tumetatua nukta 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, virudiarudia, vipunguzaji, n.k.). Hata hivyo, kwa shughuli zozote zenye makusanyo tambarare thamani ya ufunguo Tunaweza kubuni mfumo wa kufanya kazi na nyuzi, ipasavyo na funguo na usimbaji fiche wao.

Mistari ni rahisi sana kuunganisha, mistari inaweza kugawanywa kwa faharasa.
Kama mfano wa majaribio, hebu tukusanye na kuchanganua mfuatano na tuangalie jinsi hii inavyoathiri matokeo ya muamala.
Tuliishia na ukweli kwamba Alice hakuweza kusaini muamala wa Uhamisho, kwa kuwa uwezo huu ulizuiwa katika @verifier kwa aina hii ya muamala.

Tufanye mazoezi na nyuzi kisha tutatue hili.

Mistari ya RIDE

Muamala unawezekana tena, tunajua jinsi ya kufanya kazi na nyuzi.
Kujifunza kuandika mikataba mahiri ya Waves kwenye RIDE na RIDE4DAPPS. Sehemu ya 2 (DAO - Shirika Linalojiendesha Lililogatuliwa)


Kwa hivyo, tuna kila kitu tunachohitaji ili kuandika mantiki tata. DAO dApp.

Miamala ya Data

Miamala ya Data:
"Ukubwa wa juu zaidi wa ufunguo ni herufi 100, na ufunguo unaweza kuwa na pointi za msimbo wa Unicode holela 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 muamala wa data ni 100. Kwa ujumla, ukubwa wa juu zaidi wa muamala wa data ni karibu 140kb — kwa marejeleo, karibu urefu halisi wa tamthilia ya Shakespeare ya 'Romeo na Juliet'."

Tunaunda DAO yenye masharti yafuatayo:
Ili kampuni changa ipate ufadhili kwa kupiga simu getFunds() Usaidizi wa angalau washiriki 2 - wawekezaji wa DAO - unahitajika. Ondoa itawezekana kuwa na kiasi sawa na jumla iliyoonyeshwa kwenye kupiga kura Wamiliki wa DAO.

Tuunde aina 3 za funguo na tuongeze mantiki ya kufanya kazi na mizani katika chaguo 2 mpya, kura na getFunds:
xx…xx_ia = wawekezaji, salio linalopatikana (kupiga kura, kuweka pesa, kutoa pesa)
xx…xx_sv = makampuni mapya, idadi ya kura (piga kura, getFunds)
xx…xx_sf = makampuni mapya, idadi ya kura (piga kura, getFunds)
xx…xx = anwani ya umma (herufi 35)

Kumbuka kwamba katika Vote tulihitaji kusasisha sehemu kadhaa kwa wakati mmoja:

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

WriteSet inaturuhusu kutengeneza rekodi nyingi kwa wakati mmoja ndani ya moja invokeScript miamala.

Hivi ndivyo inavyoonekana katika duka la 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)

Kipengele chetu cha kuweka amana kimebadilika 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 inayofadhiliwa.

Bob apigia 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 ghala la data, tunaona rekodi zote muhimu kwa 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 utendaji kazi getFundsNeli lazima akusanye angalau kura 2 ili aweze kutoa fedha 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)

Anafanikiwa, yaani, DAO inafanya kazi!

Tumeshughulikia mchakato wa kuunda DAO katika lugha RIDE4DAPPS.
Katika sehemu zifuatazo, tutaangalia kwa undani zaidi urekebishaji wa msimbo na upimaji wa kesi.

Toleo kamili la msimbo katika Kitambulisho cha Mawimbi ya Safari:

# 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
Nambari kwenye GitHub
IDE ya Mawimbi ya Safari
Tangazo la mpango wa ruzuku

Chanzo: mapenzi.com

Nunua upangishaji wa kuaminika wa tovuti zilizo na ulinzi wa DDoS, seva za VPS VDS 🔥 Nunua upangishaji wa tovuti unaoaminika kwa ulinzi wa DDoS, seva za VPS VDS | ProHoster