
Салом хама!
В Дар ин қисм мо ба таври муфассал дар бораи чӣ гуна эҷод кардан ва кор кардан бо dApp (барномаи ғайримарказӣ) дар .
Биёед ҳоло каме ҷудошударо санҷем .
Қадами 3: Санҷиши ҳисоби dApp

Кадом мушкилот дарҳол чашми шуморо бо Алис ҷалб мекунанд? dapper Ҳисоб?
Якум:
Boob ва Cooper метавонанд тасодуфан бо истифода аз суроғаи муқаррарӣ ба суроғаи dApp маблағ фиристанд интиқол додан транзаксияҳо ва аз ин рӯ ба онҳо баргашта наметавонанд.Дуюм:
Мо Алисаро аз гирифтани маблағ бе иҷозати Boob ё Cooper маҳдуд намекунем. Тавре ки шумо мебинед, ҳама амалиётҳо аз Алис иҷро карда мешаванд.
Биёед дуюмро бо манъ кардани Алис ислоҳ кунем интиқол додан муомилот. Ҷойгир кардани скрипти ислоҳшуда:

Мо кӯшиш мекунем, ки тангаҳоро аз dApp Алиса ва имзои он бигирем. Мо хато мегирем:

Биёед кӯшиш кунем, ки тавассути бозхонд бозхонд:
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"withdraw",args:[{type:"integer", value: 1000000}]}, payment: []}))Скрипт кор мекунад ва мо нуқтаи 2-ро ҷудо кардем!
Қадами 4: Эҷоди DAO бо овоздиҳӣ
Мутаассифона, забони RIDE ҳанӯз имкониятҳои кор бо коллексияҳоро таъмин намекунад (лугатҳои луғатҳо, итераторҳо, редукторҳо ва ғ.). Бо вуҷуди ин, барои ҳама гуна амалиёт бо коллексияҳои ҳамвор арзиши калидӣ Мо метавонем системаеро барои кор бо сатрҳо, мувофиқан бо калидҳо ва рамзкушоии онҳо тарҳрезӣ кунем.
Пайваст кардани сатрҳо хеле осон аст, сатрҳоро аз рӯи индексҳо тақсим кардан мумкин аст.
Ҳамчун намунаи санҷиш, биёед сатрро ҷамъ кунем ва таҳлил кунем ва бифаҳмем, ки ин ба натиҷаи транзаксия чӣ гуна таъсир мерасонад.
Мо ба анҷом расидем, ки Алис натавонист амалиёти интиқолро имзо кунад, зеро ин қобилият дар @verifier барои ин намуди транзаксия баста шудааст.
Биёед бо сатр машқ кунем ва баъд инро ҳал кунем.
Сатрҳои RIDE
Муомилот боз имконпазир аст, мо медонем, ки чӣ тавр бо сатр кор кардан лозим аст.

Ҳамин тавр, мо ҳама чизеро дорем, ки барои навиштани мантиқи мураккаб лозим аст. DAO dApp.
Амалиётҳои маълумот
Амалиётҳои маълумот:
"Андозаи максималии калид 100 аломат аст ва калид метавонад дорои нуқтаҳои худсаронаи коди Юникод, аз ҷумла фосилаҳо ва дигар рамзҳои чопнашаванда бошад. Қиматҳои сатр маҳдудияти 32,768 байт доранд ва шумораи максималии вурудоти имконпазир дар транзаксияи додаҳо 100 аст. Дар маҷмӯъ, андозаи максималии транзаксияи додаҳо тақрибан 140 кб дарозии маълумотро ташкил медиҳад. «Ромео ва Ҷулетта».
Мо DAO-ро бо шартҳои зерин эҷод мекунем:
Барои он ки як стартап тавассути занг маблағгузорӣ кунад getFunds() Дастгирии ҳадди аққал 2 иштирокчӣ - сармоягузорони DAO - талаб карда мешавад. Боздорад ба он андозае, ки дар он нишон дода шудааст, ба даст овардан мумкин аст овоздиҳӣ Соҳибони DAO.
Биёед 3 намуди калидҳоро эҷод кунем ва мантиқи кор бо тавозун дар 2 функсияи нав, овоздиҳӣ ва getFunds илова кунем:
хх...хх_ia = сармоягузорон, тавозуни дастрас (овоз, амонат, бозхонд)
хх...хх_св = стартапҳо, шумораи овозҳо (овоз додан, getFunds)
хх...хх_sf = стартапҳо, шумораи овозҳо (овоз додан, getFunds)
xx…xx = суроғаи умумӣ (35 аломат)
Дар хотир доред, ки дар Овоздиҳӣ ба мо лозим буд, ки якбора якчанд майдонҳоро навсозӣ кунем:
WriteSet([DataEntry(key1, value1), DataEntry(key2, value2)]),WriteSet ба мо имкон медиҳад, ки дар як вақт якчанд сабтҳоро созем invokeScript муомилот.
Ин аст он чизест, ки дар мағозаи калидии DAO dApp пас аз пур кардани Боб ва Купер ia- амонатҳо:

Функсияи амонатии мо каме тағйир ёфт:

Ҳоло лаҳзаи муҳимтарин дар фаъолияти DAO фаро мерасад - овоздиҳӣ барои лоиҳаҳое, ки маблағгузорӣ мешаванд.
Боб ба лоиҳаи 500000 мавҷҳои Нели овоз медиҳад:
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"vote",args:[{type:"integer", value: 500000}, {type:"string", value: "3MrXEKJr9nDLNyVZ1d12Mq4jjeUYwxNjMsH"}]}, payment: []}))
Дар анбори маълумот мо ҳама сабтҳои заруриро барои суроғаи Нели мебинем:

Купер инчунин ба лоиҳаи Нели овоз дод.

Биёед рамзи функсияро дида бароем getFundsНели бояд ҳадди аққал 2 овоз ҷамъоварӣ кунад, то тавонанд маблағро аз DAO бозпас гирад.

Нели нисфи маблаги ба у бовар кардашударо гирифтанй мешавад:
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"getFunds",args:[{type:"integer", value: 500000}]}, payment: []}))
Вай муваффак мешавад, яъне ДАО кор мекунад!
Мо раванди эҷоди DAO-ро дар забон фаро гирифтем RIDE4DAPPS.
Дар қисматҳои зерин мо ба рефакторинги код ва санҷиши парванда бодиққат назар хоҳем кард.
Версияи пурраи код дар
# 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
}
}
Манбаъ: will.com
