Helo bawb!
В
Gadewch i ni brofi'r un sydd wedi'i ddadosod ychydig nawr
Cam 3. Profi'r cyfrif dApp
Pa broblemau sy'n neidio allan atoch chi ar unwaith gydag Alice? dApp Cyfrif?
Yn gyntaf:
Gall Boob a Cooper anfon arian yn ddamweiniol i'r cyfeiriad dApp gan ddefnyddio rheolaidd trosglwyddo trafodion ac felly ni fydd yn gallu cael mynediad iddynt yn ôl.Yn ail:
Nid ydym yn cyfyngu Alice mewn unrhyw ffordd rhag tynnu arian yn ôl heb gymeradwyaeth Boob a/neu Cooper. Gan fod, rhowch sylw i wirio, bydd yr holl drafodion gan Alice yn cael eu gweithredu.
Gadewch i ni drwsio 2il trwy wahardd Alice trosglwyddo trafodion. Gadewch i ni ddefnyddio'r sgript wedi'i chywiro:

Rydym yn ceisio tynnu darnau arian o dApp Alice a'i llofnod. Rydym yn cael gwall:
Gadewch i ni geisio tynnu'n ôl trwy dynnu'n ôl:
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"withdraw",args:[{type:"integer", value: 1000000}]}, payment: []}))
Mae'r sgript yn gweithio ac fe wnaethom gyfrifo'r 2il bwynt!
Cam 4. Creu DAO gyda phleidleisio
Yn anffodus, nid yw'r iaith RIDE eto'n darparu'r gallu i weithio gyda chasgliadau (geiriaduron, iterwyr, gostyngwyr, ac ati). Fodd bynnag, ar gyfer unrhyw weithrediadau gyda chasgliadau fflat gwerth allweddol gallwn ddylunio system ar gyfer gweithio gyda llinynnau, yn unol â hynny gydag allweddi a'u dadgryptio.
Mae llinynnau'n hawdd iawn i'w cydgadwynu; gall llinynnau gael eu gwahanu gan fynegeion.
Gadewch i ni gasglu a dosrannu llinyn fel enghraifft brawf a gwirio sut mae hyn yn effeithio ar ganlyniad y trafodiad.
Fe wnaethom setlo ar y ffaith na allai Alice lofnodi'r trafodiad Trosglwyddo, gan fod y gallu hwn wedi'i rwystro yn @verifier ar gyfer y math hwn o drafodiad.
Gadewch i ni ymarfer gyda llinynnau ac yna datrys hyn.
Llinynnau RIDE
Mae'r trafodiad yn bosibl eto, rydym yn gwybod sut i weithio gyda llinynnau.

Yn gyfan gwbl, mae gennym bopeth sydd ei angen i ysgrifennu rhesymeg gymhleth DAO dApp.
Trafodion Data
Trafodion Data:
“Y maint mwyaf ar gyfer allwedd yw 100 nod, a gall allwedd gynnwys pwyntiau cod Unicode mympwyol gan gynnwys bylchau a symbolau eraill na ellir eu hargraffu. Mae gan werthoedd llinynnau derfyn o 32,768 beit ac uchafswm nifer y cofnodion posibl mewn trafodiad data yw 100. Yn gyffredinol, maint mwyaf trafodiad data yw tua 140kb — er gwybodaeth, bron yn union hyd drama Shakespeare 'Romeo and Juliet '.”
Rydym yn creu DAO gyda'r amodau canlynol:
Er mwyn i gwmni newydd dderbyn cyllid trwy ffonio caelFunds() mae angen cefnogaeth o leiaf 2 gyfranogwr - buddsoddwyr DAO. Tynnu'n ôl bydd yn bosibl yn union cymaint â'r cyfanswm a nodir ar pleidleisio Perchnogion DAO.
Gadewch i ni wneud 3 math o allwedd ac ychwanegu rhesymeg ar gyfer gweithio gyda balansau mewn 2 swyddogaeth newydd, pleidlais a getFunds:
xx…xx_ia = buddsoddwyr, balans sydd ar gael (pleidlais, blaendal, tynnu'n ôl)
xx…xx_sv = cychwyniadau, nifer y pleidleisiau (pleidlais, getFunds)
xx…xx_sf = cychwyniadau, nifer y pleidleisiau (pleidlais, getFunds)
xx…xx = cyfeiriad cyhoeddus (35 nod)
Sylwch fod angen i ni ddiweddaru sawl maes ar unwaith yn y Bleidlais:
WriteSet([DataEntry(key1, value1), DataEntry(key2, value2)]),
Mae WriteSet yn ein galluogi i wneud sawl cofnod ar unwaith o fewn un invokeScript trafodion.
Dyma sut mae'n edrych yn storfa gwerth allweddol y DAO dApp, ar ôl i Bob a Cooper ailgyflenwi ia- adneuon:
Mae ein swyddogaeth adneuo wedi newid ychydig:
Nawr daw'r foment bwysicaf yng ngweithgareddau'r DAO - pleidleisio i brosiectau gael eu hariannu.
Bob yn pleidleisio dros brosiect 500000 o donfeddi Neli:
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"vote",args:[{type:"integer", value: 500000}, {type:"string", value: "3MrXEKJr9nDLNyVZ1d12Mq4jjeUYwxNjMsH"}]}, payment: []}))
Yn y storfa ddata gwelwn yr holl gofnodion angenrheidiol ar gyfer cyfeiriad Neli:
Pleidleisiodd Cooper hefyd dros brosiect Neli.
Gadewch i ni edrych ar y cod swyddogaeth caelFunds. Rhaid i Neli gasglu o leiaf 2 bleidlais i allu tynnu arian o'r DAO.
Mae Neli yn mynd i dynnu hanner y swm a ymddiriedwyd iddi:
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"getFunds",args:[{type:"integer", value: 500000}]}, payment: []}))
Mae hi'n llwyddo, hynny yw, mae DAO yn gweithio!
Edrychon ni ar y broses o greu DAO yn yr iaith RIDE4DAPPS.
Yn y rhannau canlynol byddwn yn edrych yn agosach ar ailffactorio cod a phrofi achosion.
Fersiwn llawn o'r cod yn
# 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
}
}
Ffynhonnell: hab.com