Учимся ΠΏΠΈΡΠ°Ρ‚ΡŒ Waves смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ Π½Π° RIDE ΠΈ RIDE4DAPPS. Π§Π°ΡΡ‚ΡŒ 2 (DAO β€” Decentralized Autonomous Organization)

Учимся ΠΏΠΈΡΠ°Ρ‚ΡŒ Waves смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ Π½Π° RIDE ΠΈ RIDE4DAPPS. Π§Π°ΡΡ‚ΡŒ 2 (DAO — Decentralized Autonomous Organization)

ВсСм ΠΏΡ€ΠΈΠ²Π΅Ρ‚!

Π’ ΠΏΠ΅Ρ€Π²ΠΎΠΉ части ΠΌΡ‹ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ рассмотрСли ΠΊΠ°ΠΊ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с dApp (Π΄Π΅Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ) Π² Waves RIDE IDE.

Π”Π°Π²Π°ΠΉΡ‚Π΅ сСйчас Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ потСстируСм Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€.

Π­Ρ‚Π°ΠΏ 3. ВСстированиС dApp Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π°

Учимся ΠΏΠΈΡΠ°Ρ‚ΡŒ Waves смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ Π½Π° RIDE ΠΈ RIDE4DAPPS. Π§Π°ΡΡ‚ΡŒ 2 (DAO — Decentralized Autonomous Organization)

КакиС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ сразу Π±Ρ€ΠΎΡΠ°ΡŽΡ‚ΡΡ Π½Π° гласа с Alice dApp Account?
Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…:
Boob ΠΈ Cooper ΠΌΠΎΠ³ΡƒΡ‚ случайно ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π½Π° адрСс dApp срСдства с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΉ transfer Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΈ, Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π½Π΅ смогут ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΊ Π½ΠΈΠΌ доступ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ.

Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…:
ΠœΡ‹ Π½ΠΈΠΊΠ°ΠΊ Π½Π΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ Alice Π² Π²Ρ‹Π²ΠΎΠ΄Π΅ срСдств Π±Π΅Π· согласования с Boob ΠΈΠ»ΠΈ(ΠΈ) Cooper. Π’Π°ΠΊ ΠΊΠ°ΠΊ, ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° verify, всС Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΎΡ‚ Alice Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ.

Π”Π°Π²Π°ΠΉΡ‚Π΅ исправим 2-Π΅, Π·Π°ΠΏΡ€Π΅Ρ‚ΠΈΠ² Alice transfer Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ. Π”Π΅ΠΏΠ»ΠΎΠΈΠΌ исправлСнный скрипт:
Учимся ΠΏΠΈΡΠ°Ρ‚ΡŒ Waves смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ Π½Π° RIDE ΠΈ RIDE4DAPPS. Π§Π°ΡΡ‚ΡŒ 2 (DAO — Decentralized Autonomous Organization)
οΏΌ
ΠŸΡ€ΠΎΠ±ΡƒΠ΅ΠΌ вывСсти ΠΌΠΎΠ½Π΅Ρ‚Ρ‹ с dApp Alice ΠΈ Π΅Π΅ подписью. ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΎΡˆΠΈΠ±ΠΊΡƒ:
Учимся ΠΏΠΈΡΠ°Ρ‚ΡŒ Waves смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ Π½Π° RIDE ΠΈ RIDE4DAPPS. Π§Π°ΡΡ‚ΡŒ 2 (DAO — Decentralized Autonomous Organization)

ΠŸΡ€ΠΎΠ±ΡƒΠ΅ΠΌ вывСсти Ρ‡Π΅Ρ€Π΅Π· withdraw:

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

Π‘ΠΊΡ€ΠΈΠΏΡ‚ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΈ со 2-ΠΌ ΠΏΡƒΠ½ΠΊΡ‚ΠΎΠΌ ΠΌΡ‹ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π»ΠΈΡΡŒ!

Π­Ρ‚Π°ΠΏ 4. Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ DAO с голосованиСм

К соТалСнию, Π² языкС RIDE ΠΏΠΎΠΊΠ° Π½Π΅ прСдусмотрСны возмоТности Ρ€Π°Π±ΠΎΡ‚Ρ‹ с коллСкциями (словари-словарСй, ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹, Ρ€Π΅Π΄ΡŒΡŽΡΠ΅Ρ€Ρ‹ ΠΈ ΠΏΡ€ΠΎΡ‡). Однако, для Π»ΡŽΠ±Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ с плоскими коллСкциями key-value ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ систСму Ρ€Π°Π±ΠΎΡ‚Ρ‹ со строками, соотвСствСнно с ΠΊΠ»ΡŽΡ‡Π°ΠΌΠΈ ΠΈ ΠΈΡ… Ρ€Π°ΡΡˆΠΈΡ„Ρ€ΠΎΠ²ΠΊΠΎΠΉ.

Π‘Ρ‚Ρ€ΠΎΠΊΠΈ ΠΎΡ‡Π΅Π½ΡŒ просто ΠΊΠΎΠ½ΠΊΠ°Ρ‚Π΅Π½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, строки ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π·Π΄Π΅Π»ΡΡ‚ΡŒ ΠΏΠΎ индСксам.
Π”Π°Π²Π°ΠΉΡ‚Π΅ Π² качСствС тСстового ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° собСрСм ΠΈ Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ строку ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ ΠΊΠ°ΠΊ это повлияСт Π½Π° исход Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ.
ΠœΡ‹ ΠΎΡΡ‚Π°Π½ΠΎΠ²ΠΈΠ»ΠΈΡΡŒ Π½Π° Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Alice Π½Π΅ ΠΌΠΎΠ³Π»Π° ΠΏΠΎΠ΄ΠΏΠΈΡΠ°Ρ‚ΡŒ Transfer Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ эта Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π±Ρ‹Π»Π° Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π° Π² @verifier для Ρ‚Π°ΠΊΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ.

Π”Π°Π²Π°ΠΉΡ‚Π΅ поупраТняСмся со строками ΠΈ ΠΏΠΎΡ‚ΠΎΠΌ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΠΌ это.

RIDE Strings

Вранзакция снова Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π°, ΠΌΡ‹ ΡƒΠΌΠ΅Π΅ΠΌ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ со строками.
Учимся ΠΏΠΈΡΠ°Ρ‚ΡŒ Waves смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ Π½Π° RIDE ΠΈ RIDE4DAPPS. Π§Π°ΡΡ‚ΡŒ 2 (DAO — Decentralized Autonomous Organization)

οΏΌ
Π˜Ρ‚ΠΎΠ³ΠΎ, ΠΌΡ‹ ΠΈΠΌΠ΅Π΅ΠΌ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ΅ для написания слоТной Π»ΠΎΠ³ΠΈΠΊΠΈ DAO dApp.

Data Transactions

Data Transactions:
β€œThe maximum size for a key is 100 characters, and a key can contain arbitrary Unicode code points including spaces and other non-printable symbols. String values have a limit of 32,768 bytes and the maximum number of possible entries in data transaction is 100. Overall, the maximum size of a data transaction is around 140kbβ€Šβ€”β€Šfor reference, almost exactly the length of Shakespeare’s play β€˜Romeo and Juliet’.”

Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ DAO со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌΠΈ условиями:
Для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ стартапу ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ финансированиС, Π²Ρ‹Π·Π²Π°Π² getFunds() Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠ° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ 2-Ρ… участников β€” инвСсторов DAO. ВывСсти ΠΌΠΎΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€ΠΎΠ²Π½ΠΎ ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ, сколько Π² суммС ΡƒΠΊΠ°Π·Π°Π»ΠΈ Π½Π° голосовании Π²Π»Π°Π΄Π΅Π»ΡŒΡ†Ρ‹ DAO.

Π”Π°Π²Π°ΠΉΡ‚Π΅ сдСлаСм 3 Ρ‚ΠΈΠΏΠ° ΠΊΠ»ΡŽΡ‡Π΅ΠΉ ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π»ΠΎΠ³ΠΈΠΊΡƒ ΠΏΠΎ Ρ€Π°Π±ΠΎΡ‚Π΅ с балансами Π² 2-Ρ… Π½ΠΎΠ²Ρ‹Ρ… функциях vote ΠΈ getFunds:
xx…xx_ia = инвСсторы, доступный баланс (vote, deposit, withdrawal)
xx…xx_sv = стартапы, количСство голосов (vote, getFunds)
xx…xx_sf = стартапы, количСство голосов (vote, getFunds)
xx…xx = ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ адрСс (35 символов)

Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅ Π² Vote Π½Π°ΠΌ понадобилось ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒ сразу нСсколько ΠΏΠΎΠ»Π΅ΠΉ:

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

WriteSet позволяСт Π½Π°ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ сразу нСсколько записСй Π² Ρ€Π°ΠΌΠΊΠ°Ρ… ΠΎΠ΄Π½ΠΎΠΉ invokeScript Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ.

Π’ΠΎΡ‚ Ρ‚Π°ΠΊ это выглядит Π² key-value Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ DAO dApp, послС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ Bob ΠΈ Cooper ΠΏΠΎΠΏΠΎΠ»Π½ΠΈΠ»ΠΈ ia-Π΄Π΅ΠΏΠΎΠ·ΠΈΡ‚Ρ‹:
Учимся ΠΏΠΈΡΠ°Ρ‚ΡŒ Waves смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ Π½Π° RIDE ΠΈ RIDE4DAPPS. Π§Π°ΡΡ‚ΡŒ 2 (DAO — Decentralized Autonomous Organization)

Ѐункция Π΄Π΅ΠΏΠΎΠ·ΠΈΡ‚Π° Ρƒ нас слСгка измСнилась:
Учимся ΠΏΠΈΡΠ°Ρ‚ΡŒ Waves смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ Π½Π° RIDE ΠΈ RIDE4DAPPS. Π§Π°ΡΡ‚ΡŒ 2 (DAO — Decentralized Autonomous Organization)

БСйчас наступаСт самый Π²Π°ΠΆΠ½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π² Π΄Π΅ΡΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ 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: []}))

Учимся ΠΏΠΈΡΠ°Ρ‚ΡŒ Waves смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ Π½Π° RIDE ΠΈ RIDE4DAPPS. Π§Π°ΡΡ‚ΡŒ 2 (DAO — Decentralized Autonomous Organization)

Π’ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΌΡ‹ Π²ΠΈΠ΄ΠΈΠΌ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ записи для адрСса Neli:
Учимся ΠΏΠΈΡΠ°Ρ‚ΡŒ Waves смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ Π½Π° RIDE ΠΈ RIDE4DAPPS. Π§Π°ΡΡ‚ΡŒ 2 (DAO — Decentralized Autonomous Organization)
ΠšΡƒΠΏΠ΅Ρ€ Ρ‚Π°ΠΊΠΆΠ΅ проголосовал Π·Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Neli.
Учимся ΠΏΠΈΡΠ°Ρ‚ΡŒ Waves смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ Π½Π° RIDE ΠΈ RIDE4DAPPS. Π§Π°ΡΡ‚ΡŒ 2 (DAO — Decentralized Autonomous Organization)

Π”Π°Π²Π°ΠΉΡ‚Π΅ взглянСм Π½Π° ΠΊΠΎΠ΄ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ getFunds. Neli Π΄ΠΎΠ»ΠΆΠ½Π° ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ 2 голоса, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ вывСсти срСдства ΠΈΠ· DAO.
Учимся ΠΏΠΈΡΠ°Ρ‚ΡŒ Waves смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ Π½Π° RIDE ΠΈ RIDE4DAPPS. Π§Π°ΡΡ‚ΡŒ 2 (DAO — Decentralized Autonomous Organization)

Neli собираСтся вывСсти ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Ρƒ Π΄ΠΎΠ²Π΅Ρ€Π΅Π½Π½ΠΎΠΉ Π΅ΠΉ суммы:

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

Учимся ΠΏΠΈΡΠ°Ρ‚ΡŒ Waves смарт-ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹ Π½Π° RIDE ΠΈ RIDE4DAPPS. Π§Π°ΡΡ‚ΡŒ 2 (DAO — Decentralized Autonomous Organization)

Π•ΠΉ это удаСтся, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ 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
    }
}

ΠŸΠ΅Ρ€Π²Π°Ρ Ρ‡Π°ΡΡ‚ΡŒ
Код Π½Π° Π³ΠΈΡ‚Ρ…Π°Π±Π΅
Waves RIDE IDE
Анонс Π³Ρ€Π°Π½Ρ‚ΠΎΠ²ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ