Hello kila mtu!
В
Wacha tujaribu ile iliyovunjwa kidogo sasa
Hatua ya 3. Kujaribu akaunti ya dApp
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:

Tunajaribu kutoa sarafu kutoka kwa dApp Alice na sahihi yake. Tunapata hitilafu:
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.

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:
Utendaji wetu wa amana umebadilika kidogo:
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: []}))
Katika hifadhi ya data tunaona maingizo yote muhimu ya anwani ya Neli:
Cooper pia alipigia kura mradi wa Neli.
Hebu tuangalie msimbo wa kazi getFunds. Neli lazima akusanye angalau kura 2 ili kuweza kutoa pesa kutoka kwa DAO.
Neli atatoa nusu ya kiasi alichokabidhiwa:
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"getFunds",args:[{type:"integer", value: 500000}]}, payment: []}))
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
# 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
}
}
Chanzo: mapenzi.com