
Hello kulħadd!
В parti aħna ħares fid-dettall lejn kif toħloq u taħdem ma dApp (applikazzjoni deċentralizzata) fi .
Ejja nittestjaw dak żarmat ftit issa .
Stadju 3. Ittestjar tal-kont dApp

X'problemi jaqbżu immedjatament fuqek ma 'Alice? dApp Kont?
L-ewwelnett:
Boob u Cooper jistgħu aċċidentalment jibagħtu fondi lill-indirizz dApp bl-użu regolari trasferiment transazzjonijiet u għalhekk ma jkunux jistgħu jaċċessawhom lura.It-tieni:
Aħna ma nirrestrinġu Alice bl-ebda mod milli tirtira fondi mingħajr l-approvazzjoni ta 'Boob u/jew Cooper. Peress li, agħti attenzjoni biex tivverifika, it-tranżazzjonijiet kollha minn Alice se jiġu esegwiti.
Ejja nirranġaw it-2 billi tipprojbixxi lil Alice trasferiment transazzjonijiet. Ejja niskjeraw l-iskript korrett:


Qed nippruvaw nirtiraw il-muniti minn dApp Alice u l-firma tagħha. Ikollna żball:

Ejja nippruvaw nirtiraw permezz tal-irtirar:
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"withdraw",args:[{type:"integer", value: 1000000}]}, payment: []}))
L-iskript jaħdem u sibna t-2 punt!
Stadju 4. Oħloq DAO bil-votazzjoni
Sfortunatament, il-lingwa RIDE għadha ma tipprovdix l-abbiltà li taħdem ma 'kollezzjonijiet (dizzjunarji ta' dizzjunarji, iteraturi, reducers, eċċ.). Madankollu, għal kwalunkwe operazzjoni b'kollezzjonijiet ċatti valur ewlieni nistgħu niddisinjaw sistema biex naħdmu ma 'kordi, kif xieraq b'ċwievet u d-deċifrar tagħhom.
Il-kordi huma faċli ħafna biex jiġu konkatenati;
Ejja niġbru u parse string bħala eżempju tat-test u tivverifika kif dan jaffettwa r-riżultat tat-tranżazzjoni.
Aħna konna fuq il-fatt li Alice ma setgħetx tiffirma t-tranżazzjoni tat-Trasferiment, peress li din il-kapaċità kienet imblukkata f'@verifier għal dan it-tip ta 'tranżazzjoni.
Ejja nipprattikaw bil-kordi u mbagħad isolvu dan.
RIDE Strings
It-tranżazzjoni hija possibbli għal darb'oħra, nafu kif naħdmu ma 'kordi.


B'kollox, għandna dak kollu meħtieġ biex niktbu loġika kumplessa DAO dApp.
Transazzjonijiet tad-Data
Tranżazzjonijiet tad-Data:
“Id-daqs massimu għal ċavetta huwa ta’ 100 karattru, u ċavetta jista’ jkun fiha punti ta’ kodiċi Unicode arbitrarji inklużi spazji u simboli oħra li ma jistgħux jiġu stampati. Il-valuri ta' string għandhom limitu ta' 32,768 bytes u n-numru massimu ta' daħliet possibbli fit-tranżazzjoni tad-dejta huwa 100. B'mod ġenerali, id-daqs massimu ta' transazzjoni tad-dejta huwa ta' madwar 140kb — għal referenza, kważi eżattament it-tul tad-dramm ta' Shakespeare 'Romeo and Juliet. '.
Aħna noħolqu DAO bil-kundizzjonijiet li ġejjin:
Sabiex startup tirċievi finanzjament billi ċċempel getFunds() l-appoġġ ta' mill-inqas 2 parteċipanti - investituri DAO - huwa meħtieġ. Iġbed ikun possibbli eżattament daqs it-total indikat fuq votazzjoni Sidien DAO.
Ejja nagħmlu 3 tipi ta 'ċwievet u żid loġika biex naħdmu mal-bilanċi f'2 funzjonijiet ġodda jivvotaw u getFunds:
xx...xx_ia = investituri, bilanċ disponibbli (votazzjoni, depożitu, irtirar)
xx...xx_sv = startups, numru ta' voti (vota, getFunds)
xx...xx_sf = startups, numru ta' voti (vota, getFunds)
xx…xx = indirizz pubbliku (35 karattru)
Jekk jogħġbok innota li fil-Vot kellna naġġornaw diversi oqsma f'daqqa:
WriteSet([DataEntry(key1, value1), DataEntry(key2, value2)]),
WriteSet jippermettilna nagħmlu diversi rekords f'daqqa f'wieħed invokeScript transazzjonijiet.
Dan huwa kif jidher fil-ħażna tal-valur ewlieni tad-DAO dApp, wara li Bob u Cooper reġgħu ia-depożiti:

Il-funzjoni tad-depożitu tagħna nbidlet xi ftit:

Issa ġej l-iktar mument importanti fl-attivitajiet tad-DAO - vot għal proġetti li għandhom jiġu ffinanzjati.
Bob jivvota għall-proġett ta' 500000 wavelets ta' Neli:
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"vote",args:[{type:"integer", value: 500000}, {type:"string", value: "3MrXEKJr9nDLNyVZ1d12Mq4jjeUYwxNjMsH"}]}, payment: []}))

Fil-maħżen tad-dejta naraw l-entrati kollha meħtieġa għall-indirizz ta 'Nelli:

Cooper ivvota wkoll għall-proġett Neli.

Ejja nagħtu ħarsa lejn il-kodiċi tal-funzjoni getFunds. Neli jrid jiġbor minimu ta’ 2 voti biex ikun jista’ jirtira l-fondi mid-DAO.

Neli se tirtira nofs l-ammont fdat lilha:
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"getFunds",args:[{type:"integer", value: 500000}]}, payment: []}))

Hija tirnexxi, jiġifieri, DAO jaħdem!
Ħarsa lejn il-proċess tal-ħolqien ta 'DAO fil-lingwa RIDE4DAPPS.
Fil-partijiet li ġejjin se nagħtu ħarsa aktar mill-qrib lejn ir-refactoring tal-kodiċi u l-ittestjar tal-każijiet.
Verżjoni sħiħa tal-kodiċi fi
# 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
}
}
Sors: www.habr.com
