RIDE болон RIDE4DAPPS дээр Waves ухаалаг гэрээг хэрхэн бичиж сурах. 2-р хэсэг (ДАО - Төвлөрсөн бус бие даасан байгууллага)

RIDE болон RIDE4DAPPS дээр Waves ухаалаг гэрээг хэрхэн бичиж сурах. 2-р хэсэг (ДАО - Төвлөрсөн бус бие даасан байгууллага)

хүн бүрт Сайн байна уу!

В Эхнийх нь хэсэгт бид dApp (төвлөрсөн бус програм)-г хэрхэн үүсгэж, түүнтэй ажиллах талаар нарийвчлан судалсан Waves RIDE IDE.

Одоо задаргаатайгаар бага зэрэг туршиж үзье жишээ нь.

Үе шат 3. dApp бүртгэлийг турших

RIDE болон RIDE4DAPPS дээр Waves ухаалаг гэрээг хэрхэн бичиж сурах. 2-р хэсэг (ДАО - Төвлөрсөн бус бие даасан байгууллага)

Ямар асуудал тэр даруй Алистай дуу хоолой руу яарав dApp Данс уу?
Нэгдүгээрт:
Boob, Cooper нар санамсаргүй байдлаар dApp хаяг руу мөнгө илгээж магадгүй шилжүүлэх гүйлгээ хийх бөгөөд ингэснээр тэдгээрт буцаж хандах боломжгүй болно.

Хоёрдугаарт:
Бид Алисыг Boob ба/эсвэл Куперийн зөвшөөрөлгүйгээр мөнгө татахыг ямар ч байдлаар хязгаарладаггүй. Учир нь шалгахад анхаарлаа хандуулаарай, Алисаас хийсэн бүх гүйлгээ хийгдэх болно.

Алисыг хориглож 2-ыг засъя шилжүүлэх гүйлгээ. Залруулсан скриптийг байрлуул:
RIDE болон RIDE4DAPPS дээр Waves ухаалаг гэрээг хэрхэн бичиж сурах. 2-р хэсэг (ДАО - Төвлөрсөн бус бие даасан байгууллага)

Бид dApp Алис болон түүний гарын үсэг бүхий зоосыг гаргахыг оролдож байна. Бид алдаа авдаг:
RIDE болон RIDE4DAPPS дээр Waves ухаалаг гэрээг хэрхэн бичиж сурах. 2-р хэсэг (ДАО - Төвлөрсөн бус бие даасан байгууллага)

Татаж авах замаар буцаан татахыг оролдож байна:

broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"withdraw",args:[{type:"integer", value: 1000000}]}, payment: []}))

Скрипт ажиллаж, бид 2-р цэгийг ойлголоо!

Үе шат 4. Санал хураалтаар ДАО байгуулна

Харамсалтай нь RIDE хэл нь цуглуулгатай (толь бичиг, толь бичиг, давталт, бууруулагч гэх мэт) ажиллах чадварыг хараахан хангаагүй байна. Гэсэн хэдий ч, хавтгай цуглуулга дээр аливаа үйл ажиллагааны хувьд түлхүүр утга Бид түлхүүрүүд болон тэдгээрийн шифрийг тайлах мөрүүдтэй ажиллах системийг зохион бүтээх боломжтой.

Мөрүүдийг холбоход маш хялбар, мөрүүдийг индексээр тусгаарлаж болно.
Туршилтын жишээ болгон мөрийг цуглуулж, задлан шинжилж, энэ нь гүйлгээний үр дүнд хэрхэн нөлөөлөхийг шалгацгаая.
Энэ төрлийн гүйлгээний хувьд @verifier-д энэ боломжийг хаасан тул Алис шилжүүлгийн гүйлгээнд гарын үсэг зурж чадахгүй гэдгийг бид шийдсэн.

Мөртэй дасгал хийж, дараа нь үүнийг шийдье.

RIDE мөрүүд

Гүйлгээ дахин боломжтой, бид мөртэй хэрхэн ажиллахаа мэддэг.
RIDE болон RIDE4DAPPS дээр Waves ухаалаг гэрээг хэрхэн бичиж сурах. 2-р хэсэг (ДАО - Төвлөрсөн бус бие даасан байгууллага)


Нийтдээ нарийн төвөгтэй логик бичихэд хэрэгтэй бүх зүйл бидэнд байна DAO dApp.

Өгөгдлийн гүйлгээ

Өгөгдлийн гүйлгээ:
“Түлхүүрийн хамгийн дээд хэмжээ нь 100 тэмдэгт бөгөөд түлхүүр нь хоосон зай болон хэвлэх боломжгүй бусад тэмдэгтүүдийг багтаасан дурын Юникод кодын цэгүүдийг агуулж болно. Мөрний утгуудын хязгаар нь 32,768 байт бөгөөд өгөгдлийн гүйлгээнд оруулах боломжит хамгийн дээд тоо нь 100 байна. Нийтдээ өгөгдлийн гүйлгээний хамгийн дээд хэмжээ нь ойролцоогоор 140 кб байна. '. ”

Бид дараах нөхцлөөр DAO-г бий болгодог.
Гарааны бизнесийг дуудаж санхүүжилт авахын тулд getFunds() дор хаяж 2 оролцогчийн дэмжлэг - DAO хөрөнгө оруулагчид шаардлагатай. Ачаалах дээр заасан нийлбэрийн хэмжээгээр боломжтой болно санал хураалт DAO эзэмшигчид.

3 төрлийн түлхүүр хийж, үлдэгдэлтэй ажиллах логикийг санал болгож, getFunds гэсэн 2 шинэ функцээр оруулъя:
хх...хх_ia = хөрөнгө оруулагчид, бэлэн үлдэгдэл (санал өгөх, барьцаалах, татах)
хх...хх_sv = стартапууд, саналын тоо (санал өгөх, сан авах)
хх...хх_sf = стартапууд, саналын тоо (санал өгөх, сан авах)
xx…xx = нийтийн хаяг (35 тэмдэгт)

Санал өгөх хэсэгт бид хэд хэдэн талбарыг нэгэн зэрэг шинэчлэх шаардлагатайг анхаарна уу:

WriteSet([DataEntry(key1, value1), DataEntry(key2, value2)]),

WriteSet нь нэг дор хэд хэдэн бичлэг хийх боломжийг бидэнд олгодог invokeScript гүйлгээ.

Боб, Купер хоёрыг нөхөж авсны дараа DAO dApp-н түлхүүр утгын дэлгүүрт иймэрхүү харагдаж байна. ia- хадгаламж:
RIDE болон RIDE4DAPPS дээр Waves ухаалаг гэрээг хэрхэн бичиж сурах. 2-р хэсэг (ДАО - Төвлөрсөн бус бие даасан байгууллага)

Манай хадгаламжийн функц бага зэрэг өөрчлөгдсөн:
RIDE болон RIDE4DAPPS дээр Waves ухаалаг гэрээг хэрхэн бичиж сурах. 2-р хэсэг (ДАО - Төвлөрсөн бус бие даасан байгууллага)

Одоо DAO-ийн үйл ажиллагааны хамгийн чухал мөч ирж байна - санал өгөх санхүүжилтийн төслүүдийн хувьд.

Боб 500000 долгион дээр Neli төсөлд саналаа өгсөн:

broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"vote",args:[{type:"integer", value: 500000}, {type:"string", value: "3MrXEKJr9nDLNyVZ1d12Mq4jjeUYwxNjMsH"}]}, payment: []}))

RIDE болон RIDE4DAPPS дээр Waves ухаалаг гэрээг хэрхэн бичиж сурах. 2-р хэсэг (ДАО - Төвлөрсөн бус бие даасан байгууллага)

Мэдээллийн дэлгүүрт бид Neli хаягийн шаардлагатай бүх оруулгуудыг харж байна.
RIDE болон RIDE4DAPPS дээр Waves ухаалаг гэрээг хэрхэн бичиж сурах. 2-р хэсэг (ДАО - Төвлөрсөн бус бие даасан байгууллага)
Купер мөн Нели төслийн төлөө саналаа өгсөн.
RIDE болон RIDE4DAPPS дээр Waves ухаалаг гэрээг хэрхэн бичиж сурах. 2-р хэсэг (ДАО - Төвлөрсөн бус бие даасан байгууллага)

Функцийн кодыг харцгаая getFunds. Нели DAO-аас мөнгө татахын тулд дор хаяж 2 санал цуглуулах ёстой.
RIDE болон RIDE4DAPPS дээр Waves ухаалаг гэрээг хэрхэн бичиж сурах. 2-р хэсэг (ДАО - Төвлөрсөн бус бие даасан байгууллага)

Нели өөрт нь итгэмжлэгдсэн мөнгөн дүнгийн тал хувийг авах гэж байна.

broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"getFunds",args:[{type:"integer", value: 500000}]}, payment: []}))

RIDE болон RIDE4DAPPS дээр Waves ухаалаг гэрээг хэрхэн бичиж сурах. 2-р хэсэг (ДАО - Төвлөрсөн бус бие даасан байгууллага)

Тэр амжилтанд хүрсэн, өөрөөр хэлбэл DAO ажилладаг!

Бид хэлээр DAO үүсгэх үйл явцыг хянаж үзсэн RIDE4DAPPS.
Дараах хэсгүүдэд бид кодын рефакторинг болон кейс тестийг нарийвчлан авч үзэх болно.

Бүтэн код Waves RIDE IDE:

# 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
    }
}

Нэгдүгээр хэсэг
Github дээрх код
Waves RIDE IDE
Тэтгэлэгт хөтөлбөрийн зарлал

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх