
Hello kila mtu!
В Katika sehemu hii tuliangalia kwa undani jinsi ya kuunda na kufanya kazi na dApp (programu iliyogatuliwa) katika .
Hebu tujaribu ile iliyovunjwa kidogo sasa .
Hatua ya 3: Kujaribu akaunti ya dApp

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:


Tunajaribu kutoa sarafu kutoka kwa dApp ya Alice na sahihi yake. Tunapata hitilafu:

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.


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:

Kipengele chetu cha kuweka amana kimebadilika kidogo:

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: []}))
Katika ghala la data, tunaona rekodi zote muhimu kwa anwani ya Neli:

Cooper pia alipigia kura mradi wa Neli.

Hebu tuangalie msimbo wa utendaji kazi getFundsNeli lazima akusanye angalau kura 2 ili aweze kutoa fedha 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: []}))
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
# 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
