áááºá¹ááá¬áá«áá°ááá¯ááºážá¡ááœááº!
Ð
á¡áᯠááŒá¯ááºáá¬ážáá²á· áá
á¹á
ááºážááᯠáááºážáááºáž á
ááºážáááºááŒáá·áºáá¡á±á¬ááº
á¡ááá·áº 3á dApp á¡áá±á¬áá·áºááᯠá ááºážáááºááŒááºážá
Alice áá²á· áááºážááᯠáá¬ááŒá¿áá¬áá»á¬áž áá»ááºááŒááºáž áá±á«áºáá¬áá¬áá²á dApp á¡áá±á¬ááºá·?
áááá¥á®ážá áœá¬:
Boob ááŸáá·áº Cooper ááá¯á·ááẠáá¯á¶ááŸááºá¡áá¯á¶ážááŒá¯á dApp ááááºá á¬ááá¯á· áá¶áá¯á¶ááœá±áá»á¬áž ááá±á¬áºáá áá±ážááá¯á·ááá¯ááºáá«áááºá ááœáŸá²ááŒá±á¬ááºáž ááœá±ááœáŸá²ááŸá¯áá»á¬ážááŒá±á¬áá·áº áááºážááá¯á·ááᯠááŒááºáááºáááºáá±á¬ááºááá¯ááºáááºááá¯ááºáá±ááá¯áááá¡:
Boob ááŸáá·áº/ááá¯á·ááá¯áẠCooper áááœáá·áºááŒá¯áá»ááºáááŸááá² Alice ááẠáááºááá·áºáááºážááŒáá·áºáááᯠáááºáá¯á¶ááœá±áá¯ááºáá°ááŒááºážááᯠáá»áœááºá¯ááºááá¯á· ááá·áºáááºááá¬ážáá±á á áá á áºááẠá¡á¬áá¯á¶á áá¯ááºáá±á¬ááŒá±á¬áá·áºá Alice á០ááœá±áá±ážááœá±áá°á¡á¬ážáá¯á¶ážááᯠáá¯ááºáá±á¬ááºáá«áááºá
á¡á²áá
áºááᯠáá¬ážááŒá
áºááŒááºážááŒáá·áº áá¯áááá¡áá»ááºááᯠááŒááºááŒáá«á
áá¯á· ááœáŸá²ááŒá±á¬ááºáž á¡áá±á¬ááºážá¡áááºáá»á¬ážá ááŒá¯ááŒááºáá¬ážáá±á¬ áá¬ááºááœáŸááºážááᯠá¡áá¯á¶ážááŒá¯ááŒáá«á
áá¯á·á
ᅩ
áá»áœááºá¯ááºááá¯á·ááẠdApp Alice ááŸáá·áº áá°áá áááºááŸááºá០á¡ááŒáœá±á
á±á·áá»á¬ážááᯠáá¯ááºáá°ááẠááŒáá¯ážá
á¬ážáá±áá«áááºá áá»áœááºá¯ááºááá¯á·ááẠá¡ááŸá¬ážáá
áºáá¯áááŸááááº-
áá¯ááºááááºážááŒááºážááŒáá·áº áá¯ááºááœá¬ááẠááŒáá¯ážá á¬ážááŒáá«á áá¯á·á
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"withdraw",args:[{type:"integer", value: 1000000}]}, payment: []}))
áá¬ááºááœáŸááºážá á¡áá¯ááºáá¯ááºááŒá®áž áá¯áááá¡áá»ááºááᯠááŸá¬ááœá±ááœá±á·ááŸááá²á·áá«áááºá
á¡ááá·áº 4á áá²áá±ážááŒááºážááŒáá·áº DAO áá áºáá¯ááᯠáááºáá®ážáá«á
áá¶ááá±á¬ááºážá áœá¬ááŒáá·áºá RIDE áá¬áá¬á áá¬ážááẠá á¯á ááºážááŸá¯áá»á¬áž (á¡áááá¬áẠá¡áááá¬ááºáá»á¬ážá áááºááá·áºáá±ážáá¬ážáá°áá»á¬ážá á¡áá»áŸá±á¬á·áá±ážáá°áá»á¬ážá á áááº) ááŒáá·áº áá¯ááºáá±á¬ááºááá¯ááºá áœááºáž áááŸááá±ážáá«á ááá¯á·áá±á¬áº áááºááá·áºá á áºáááºáá±ážá¡ááœááºáááᯠááŒá¬ážáá»ááºáá»ááºáá»á¬ážááŸáá·áº á á¯á ááºážááŸá¯áá»á¬áž áá±á¬á·áá»ááºáááºááá¯áž áá»áœááºá¯ááºááá¯á·ááẠáá±á¬á·áá»á¬ážááŸáá·áº áááºážááá¯á·á áá¯ááºááŸááºá áá áºááŸáá·áºá¡áá® strings áá»á¬ážááŸáá·áº á¡áá¯ááºáá¯ááºáááºá¡ááœáẠá áá áºáá áºáá¯ááᯠáá®ááá¯ááºážááœá²ááá¯ááºáááºá
á
á¬ááŒá±á¬ááºážáá»á¬ážááẠáá±á«ááºážá
ááºááẠá¡ááœááºááœááºáá°áááºá ááŒáá¯ážáá»á¬ážááᯠá¡ááœáŸááºážáá»á¬ážááŒáá·áº ááœá²ááŒá¬ážááá¯ááºáááºá
á
ááºážáááºááá°áá¬á¡ááŒá
Ạá
á¬ááŒá±á¬ááºážáá
áºáá¯ááᯠá
á¯áá±á¬ááºážááŒá®áž ááœá²ááŒááºážá
áááºááŒá¬ááŒá®áž áááºážááẠááœá±áá±ážááœá±áá°á ááááºá¡áá±á«áº áááºááá¯á·á¡áá»áá¯ážáááºáá±á¬ááºááŒá±á¬ááºáž á
á
áºáá±ážááŒáá·áºááŒáá«á
áá¯á·á
á€áá¯ááºáá±á¬ááºáá»ááºááᯠ@verifier ááœáẠááááºááá¯á·áá¬ážáá±á¬ááŒá±á¬áá·áº Alice ááẠTransfer ááœá±áá±ážááœá±áá°ááᯠáááºááŸááºáááá¯ážááá¯ááºáá²á·áá°áá±á¬á¡áá»ááºááᯠáá»áœááºá¯ááºááá¯á· ááŒá±ááŸááºážáá²á·áááºá
ááŒáá¯ážááœá±áá²á· áá±á·áá»áá·áºááŒá®ážáá±á¬á· áá«ááᯠááŒá±ááŸááºážááŒáá·áºáá¡á±á¬ááºá
RIDE Strings
á¡áá±á¬ááºážá¡áááºááŒááºááŒá
áºááá¯ááºáááºá áá»áœááºá¯ááºááá¯á·ááẠá
á¬ááŒá±á¬ááºážáá»á¬ážááŒáá·áº áááºááá¯á·áá¯ááºáá±á¬ááºááááºááᯠáááá«áááºá
ᅩ
á
á¯á
á¯áá±á«ááºážá áá»áœááºá¯ááºááá¯á·ááœáẠááŸá¯ááºááœá±ážáá±á¬áá¯áá¹áááá±áááᯠáá±ážáá¬ážááẠááá¯á¡ááºááá·áºá¡áá¬á¡á¬ážáá¯á¶ážááŸááááºá DAO dApp.
áá±áá¬ááœáŸá²ááŒá±á¬ááºážááŸá¯áá»á¬áž
áá±áá¬ááœáŸá²ááŒá±á¬ááºážááŸá¯áá»á¬áž-
âáá±á¬á·áá
áºáá¯á¡ááœáẠá¡áá»á¬ážáá¯á¶ážá¡ááœááºá¡á
á¬ážááŸá¬ á
á¬áá¯á¶ážáá± 100 ááŸáááŒá®áž áá±á¬á·áá
áºáá¯ááœáẠáá±áá¬ááœááºáá»á¬ážááŸáá·áº á¡ááŒá¬ážáá¯á¶ááŸáááºááááá¯ááºáá±á¬ áááºá¹áá±ááá»á¬ážá¡áá«á¡ááẠááááºáááᯠáá°áá®áá¯ááºáá¯ááºá¡ááŸááºáá»á¬áž áá«áááºááá¯ááºáááºá á
á¬áááºážáááºááá¯ážáá»á¬ážááẠ32,768 bytes ááá·áºáááºáá»ááºááŸáááŒá®áž áá±áá¬ááœáŸá²ááŒá±á¬ááºážááŸá¯ááœáẠááŒá
áºááá¯ááºáá»á±á¡áá»á¬ážáá¯á¶ážá¡áá±á¡ááœááºááŸá¬ 100 ááŒá
áºáááºá áá±áá¯áá»á¡á¬ážááŒáá·áºá áá±áá¬ááœáŸá²ááŒá±á¬ááºážááŸá¯áá
áºáá¯á á¡áá»á¬ážáá¯á¶ážá¡ááœááºá¡á
á¬ážááŸá¬ 140kb áááºážáá»ááºááŒá
áºááẠâ ááá¯ážáá¬ážáááºá¡ááœáẠShakespeare áááŒáá¬áẠ'Romeo and Juliet áá¡ááŸááºáá®ážáá«áž 'áâ
áá»áœááºá¯ááºááá¯á·ááẠá¡á±á¬ááºáá«á¡ááŒá±á¡áá±áá»á¬ážááŒáá·áº DAO áá
áºáá¯ááᯠáááºáá®ážáá«áááºá
áá±á«áºááá¯ááŒááºážááŒáá·áº áááºáá¯á¶ááœá±áááŸáááẠá
áááºáá¯ááºáá±á¬ááºáá«á getFunds() á¡áááºážáá¯á¶ážáá«áááºáá° 2 áŠáž - DAO áááºážááŸá®ážááŒáŸá¯ááºááŸá¶áá°áá»á¬ážá áá¶á·ááá¯ážáá°áá®ááŸá¯ ááá¯á¡ááºáá«áááºá áá¯ááºááœá¬ á
á¯á
á¯áá±á«ááºáž áá±á¬áºááŒáá¬ážááá·áºá¡ááá¯ááºáž ááŒá
áºááá¯ááºáá»á±ááŸáááẠáá²áá±ážááŒááºážá DAO áá¯ááºááá«áááºá
áá±á¬á· á áá»áá¯ážááᯠáááºáá®ážááŒá®áž áá¯ááºáá±á¬ááºáá»ááºá¡áá Ạá áá¯áá²ááŸáá·áº getFunds ááœáẠáá»áááºááœááºáá»áŸá¬ááŒáá·áº á¡áá¯ááºáá¯ááºáááºá¡ááœáẠáá±á¬á·áá»á áºááᯠááá·áºááŒáá«á áá¯á·á
xxâŠxx_ia = áááºážááŸá®ážááŒáŸá¯ááºááŸá¶áá°áá»á¬ážá áááºáá»ááºááœá± (áá²á ááœá±ááœááºážá ááœá±áá¯ááº)
xxâŠxx_sv = á áááºáá±á¬ááºááœááºáá°áá»á¬ážá áá²á¡áá±á¡ááœáẠ(áá²áá±ážááŒááºážá getFunds)
xxâŠxx_sf = á áááºáá±á¬ááºááœááºáá°áá»á¬ážá áá²á¡áá±á¡ááœáẠ(áá²áá±ážááŒááºážá getFunds)
xxâŠxx = á¡áá»á¬ážáá°ááŸá¬ ááááºá ᬠ(á á¬áá¯á¶áž áá áá¯á¶áž)
Vote ááœáẠáááºáááºáá»á¬ážá áœá¬ááᯠáá áºááŒáá¯ááºááẠá¡ááºááááºáá¯ááºááẠááá¯á¡ááºááŒá±á¬ááºáž áááááŒá¯áá«á
WriteSet([DataEntry(key1, value1), DataEntry(key2, value2)]),
WriteSet ááẠáá»áœááºá¯ááºááá¯á·á¡á¬áž áá áºááŒáááºáááºážááœáẠááŸááºáááºážáá»á¬ážá áœá¬ ááŒá¯áá¯ááºááá¯ááºá á±áá«áááºá invokeScript á¡áá±á¬ááºážá¡áááºáá»á¬ážá
Bob ááŸáá·áº Cooper ááŒáá·áºá
áœááºááŒá®ážáá±á¬áẠDAO dApp á áá±á¬á·áááºááá¯áž ááá¯ááŸá±á¬ááºááŸá¯ááœáẠáááºážááẠáá¯á¶á
á¶áá°ááŒá
áºááẠia- á¡ááºááœá±áá»á¬áž
áá»áœááºá¯ááºááá¯á·á á¡ááºááœá±áá¯ááºáá±á¬ááºáá»áẠá¡áááºážááẠááŒá±á¬ááºážáá²ááœá¬ážáááº-
ááᯠDAO á ááŸá¯ááºááŸá¬ážááŸá¯áá»á¬ážááœáẠá¡áá±ážááŒá®ážáá¯á¶ážá¡áá»áááºááᯠáá±á¬ááºáá¬ááẠá áá² ááœá±ááŒá±ážáá±á¬ááºáá¶á·ááá·áº ááá±á¬áá»ááºáá»á¬ážá¡ááœááºá
Bob ááẠNeli á 500000 wavelets ááá±á¬áá»ááºá¡ááœáẠáá²áá±ážááẠá
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"vote",args:[{type:"integer", value: 500000}, {type:"string", value: "3MrXEKJr9nDLNyVZ1d12Mq4jjeUYwxNjMsH"}]}, payment: []}))
áá±áá¬á
ááá¯ážááœáẠNeli áááááºá
á¬á¡ááœáẠááá¯á¡ááºáá±á¬ááá·áºááœááºážááŸá¯áá»á¬ážááᯠáá»áœááºá¯ááºááá¯á·ááœá±á·ááŒááºááááº-
Cooper áááºáááºáž Neli ááá±á¬áá»ááºá¡ááœáẠáá²áá±ážáá²á·áááºá
function code ááá¯ááŒáá·áºáá¡á±á¬áẠáááºáá¯á¶ááœá±áá»á¬áž. DAO á០áááºáá¯á¶ááœá±áá»á¬ážááᯠáá¯ááºáá°ááá¯ááºááẠNeli ááẠá¡áááºážáá¯á¶áž áá² 2 áá² á
á¯áá±á¬ááºážááá«áááºá
Neli ááẠáá°áá¡á¬áž á¡ááºááŸááºážáá¬ážááá·áº ááá¬áá áá áºáááºááᯠáá¯ááºáá°ááœá¬ážáááºááŒá áºáááºá
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"getFunds",args:[{type:"integer", value: 500000}]}, payment: []}))
áá°áá¡á±á¬ááºááŒááºáááºá ááá¯ááá¯áááºááŸá¬ DAO á¡áá¯ááºááŒá áºáááºá
áá¬áá¬á
áá¬ážááŒáá·áº DAO áá
áºáá¯áááºáá®ážááŒááºážáá¯ááºáááºážá
ááºááᯠáá»áœááºá¯ááºááá¯á·ááŒáá·áºááŸá¯áá²á·áááºá RIDE4DAPPS.
á¡á±á¬ááºáá«á¡ááá¯ááºážáá»á¬ážááœáẠcode refactoring ááŸáá·áº case testing ááᯠá¡áá®ážáááºááŒáá·áºááŸá¯áá«áááºá
áá¯ááºááá¬ážááŸááºážá¡ááŒáá·áºá¡á
á¯á¶
# 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
}
}
source: www.habr.com