ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ смарт-Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚ΠΎΠ² ΠΈ смарт-ассСтов Waves Π² финансовых инструмСнтах

ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ смарт-Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚ΠΎΠ² ΠΈ смарт-ассСтов Waves Π² финансовых инструмСнтах

Π’ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ рассмотрСли нСсколько кСйсов примСнСния смарт-Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚ΠΎΠ² Π² бизнСсС – Π²ΠΊΠ»ΡŽΡ‡Π°Ρ Π°ΡƒΠΊΡ†ΠΈΠΎΠ½Ρ‹ ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π»ΠΎΡΠ»ΡŒΠ½ΠΎΡΡ‚ΠΈ.
БСгодня ΠΌΡ‹ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ смарт-Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Ρ‹ ΠΈ смарт-ассСты ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΠ²Ρ‹ΡΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½ΠΎΡΡ‚ΡŒ ΠΈ Π½Π°Π΄Π΅ΠΆΠ½ΠΎΡΡ‚ΡŒ Ρ‚Π°ΠΊΠΈΡ… финансовых инструмСнтов, ΠΊΠ°ΠΊ ΠΎΠΏΡ†ΠΈΠΎΠ½Ρ‹, Ρ„ΡŒΡŽΡ‡Π΅Ρ€ΡΡ‹ ΠΈ вСксСля.

ΠžΠΏΡ†ΠΈΠΎΠ½

ΠžΠΏΡ†ΠΈΠΎΠ½ – Π±ΠΈΡ€ΠΆΠ΅Π²ΠΎΠΉ ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚, Π΄Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠΎΠΊΡƒΠΏΠ°Ρ‚Π΅Π»ΡŽ ΠΏΡ€Π°Π²ΠΎ ΠΊΡƒΠΏΠΈΡ‚ΡŒ Π°ΠΊΡ‚ΠΈΠ² ΠΏΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ Ρ†Π΅Π½Π΅ ΠΈΠ»ΠΈ Π΄ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ Π΄Π°Ρ‚Ρ‹, Π½ΠΎ Π½Π΅ ΠΎΠ±ΡΠ·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ Π΅Π³ΠΎ это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ.

РСализация ΠΎΠΏΡ†ΠΈΠΎΠ½Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ:

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ смарт-ассСт для самих ΠΎΠΏΡ†ΠΈΠΎΠ½ΠΎΠ² ΠΊΠ°ΠΊ инструмСнта ΠΈ смарт-Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚ для участника, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ выполняСт Ρ€ΠΎΠ»ΡŒ Π±ΠΈΡ€ΠΆΠΈ ΠΈ выпускаСт ΠΎΠΏΡ†ΠΈΠΎΠ½Ρ‹. Участник-Π±ΠΈΡ€ΠΆΠ° ΠΎΠ±Π΅Ρ‰Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ продаст Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ количСство ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ассСта ΠΏΠΎ Ρ†Π΅Π½Π΅ sellPrice ΠΌΠ΅ΠΆΠ΄Ρƒ высотами Π±Π»ΠΎΠΊΠΎΠ² expirationStart ΠΈ expirationEnd).

Π’ ΠΊΠΎΠ΄Π΅ смарт-ассСта ΠΌΡ‹ просто ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ торгуСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΌΠ΅ΠΆΠ΄Ρƒ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΌΠΈ высотами, ΠΈ большС Π½ΠΈΡ‡Π΅Π³ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ, оставим всю ΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ Π·Π° соблюдСниС ΠΏΡ€Π°Π²ΠΈΠ» Π½Π° ΠΊΠΎΠ΄ участника-Π±ΠΈΡ€ΠΆΠΈ.

Код смарт-ассСта:

let expirationStart = 100000
let expirationEnd = 101440

match tx {
   case some : ExchangeTransaction | TransferTransaction =>
       height > expirationStart && height <= expirationEnd
   case _ => false
}

Π‘ΡƒΠ΄Π΅ΠΌ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ дСйствия происходят ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ: участник-Π±ΠΈΡ€ΠΆΠ° ΠΏΡ€ΠΎΠ΄Π°Π΅Ρ‚ ΠΎΠΏΡ†ΠΈΠΎΠ½Ρ‹ Π½Π° ΠΏΠΎΠΊΡƒΠΏΠΊΡƒ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Ρ‚ΠΎ ассСта, ΠΈ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ участники ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅ΡΡ‹Π»Π°Ρ‚ΡŒ эти ΠΎΠΏΡ†ΠΈΠΎΠ½Ρ‹ ΠΈΠ»ΠΈ Ρ‚ΠΎΡ€Π³ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠΌΠΈ. Π§Ρ‚ΠΎΠ±Ρ‹ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ своим ΠΏΡ€Π°Π²ΠΎΠΌ Π½Π° ΠΏΠΎΠΊΡƒΠΏΠΊΡƒ, ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΠΊΡƒΠΏΠ°Ρ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ пСрСвСсти ΠΆΠ΅Π»Π°Π΅ΠΌΠΎΠ΅ количСство ΠΎΠΏΡ†ΠΈΠΎΠ½ΠΎΠ² Π½Π° счСт ΠΏΡ€ΠΎΠ΄Π°Π²Ρ†Π°, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ участника-Π±ΠΈΡ€ΠΆΠΈ. Π”Π°Π»Π΅Π΅ ΠΎΠ½ записываСт ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎΠΌ трансфСрС Π² стСйт Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π° участника-Π±ΠΈΡ€ΠΆΠΈ ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π·Π°Ρ‚Π΅ΠΌ ExchangeTransaction ΠΏΠΎ Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ условиям ΠΏΠΎΠΊΡƒΠΏΠΊΠΈ-ΠΏΡ€ΠΎΠ΄Π°ΠΆΠΈ смоТСт ΠΏΡ€ΠΎΠΉΡ‚ΠΈ.

Π’ ΠΊΠΎΠ΄Π΅ смарт-Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π° ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ любая проходящая Ρ‡Π΅Ρ€Π΅Π· Π½Π΅Π³ΠΎ ExchangeTransaction для Ρ„ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π°ΠΊΡ‚Π° ΠΏΠΎΠΊΡƒΠΏΠΊΠΈ-ΠΏΡ€ΠΎΠ΄Π°ΠΆΠΈ соотвСтствуСт Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ условиям, ΠΈ участник ΠΏΠΎΠΊΡƒΠΏΠ°Π΅Ρ‚ Ρ€ΠΎΠ²Π½ΠΎ Ρ‚ΠΎ число ΡŽΠ½ΠΈΡ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΎΠ½ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΠ» Π½Π° счСт участника-Π±ΠΈΡ€ΠΆΠΈ. ΠŸΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΠΊΡƒΠΏΠ°Ρ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΡƒΡŽ DataTransaction ΠΎ ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ΅Π΄ΡˆΠ΅ΠΌ трансфСрС, Ρ‡Ρ‚ΠΎΠ±Ρ‹ участник-Π±ΠΈΡ€ΠΆΠ° ΠΌΠΎΠ³ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ Π΄Π²ΠΎΠΉΠ½ΠΎΠΉ Ρ‚Ρ€Π°Ρ‚Ρ‹. Π’ этой DataTransaction ΠΏΠΎΠΊΡƒΠΏΠ°Ρ‚Π΅Π»ΡŒ ΠΊΠ»Π°Π΄Π΅Ρ‚ ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Ρƒ, Ρ€Π°Π²Π½ΠΎΠΌΡƒ Π΅Π³ΠΎ адрСсу, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ρ€Π°Π²Π½ΠΎΠ΅ числу ΠΎΠΏΡ†ΠΈΠΎΠ½ΠΎΠ² ΠΏΠ΅Ρ€Π΅Π²Π΅Π΄Π΅Π½Π½Ρ‹Ρ… Π½Π° счСт участника-Π±ΠΈΡ€ΠΆΠΈ, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ числу ΡŽΠ½ΠΈΡ‚ΠΎΠ² ассСта, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΊΡƒΠΏΠΈΡ‚ΡŒ.

Код смарт-Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π°:

#Π²Π»Π°Π΄Π΅Π»Π΅Ρ† Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π° Π΄Π°Π΅Ρ‚ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎ ΠΏΡ€ΠΎΠ΄Π°Ρ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ количСство ΡŽΠ½ΠΈΡ‚ΠΎΠ² ассСта
#ΠΏΠΎ Ρ†Π΅Π½Π΅ sellPrice ΠΌΠ΅ΠΆΠ΄Ρƒ высотами Π±Π»ΠΎΠΊΠΎΠ² expirationStart ΠΈ expirationEnd

let expirationStart = 100000
let expirationEnd = 101440
let sellPrice = 10000
let amountAsset = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
let priceAsset = base58'9jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
#ID ассСта-ΠΎΠΏΡ†ΠΈΠΎΠ½Π°
let optionsAsset = base58'7jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
#ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ ΠΈΠ· Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ адрСс отправитСля
let this = tx.sender
match tx {
   case dataTx : DataTransaction =>
       #ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ количСство ΡŽΠ½ΠΈΡ‚ΠΎΠ² ΠΈΠ· Π΄Π°Ρ‚Π°-Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Ρƒ (ID ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ)
       let units = extract(getInteger(dataTx.data, dataTx.data[0].key))

       #ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ трансфСр-Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ ΠΎΠΏΡ†ΠΈΠΎΠ½ΠΎΠ² ΠΈΠ· ΠΏΡ€ΡƒΡ„Π°
       let e = transactionById(dataTx.proofs[2]) #
       match e {
           case transferTx : TransferTransaction =>
               #убСТдаСмся, Ρ‡Ρ‚ΠΎ трансфСр Π±Ρ‹Π» Π½Π° Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ адрСс
               (transferTx.recipient == this) &&
               #убСТдаСмся, Ρ‡Ρ‚ΠΎ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚Π΅Π»ΡŒ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ написал Π² качСствС ΠΊΠ»ΡŽΡ‡Π° свой ID
               dataTx.data[0].key == toBase58String(transferTx.sender.bytes) &&
               sigVerify(dataTx.bodyBytes, dataTx.proofs[0], transferTx.senderPublicKey) &&
               #убСТдаСмся, Ρ‡Ρ‚ΠΎ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ΅ количСство ΡŽΠ½ΠΈΡ‚ΠΎΠ² соотвСтствуСт посланному количСству ΠΎΠΏΡ†ΠΈΠΎΠ½ΠΎΠ²
               (units == transferTx.amount) &&
               #убСТдаСмся, Ρ‡Ρ‚ΠΎ Π±Ρ‹Π» ΠΏΠ΅Ρ€Π΅Π²Π΅Π΄Π΅Π½ ΠΈΠΌΠ΅Π½Π½ΠΎ ассСт-ΠΎΠΏΡ†ΠΈΠΎΠ½
               (transferTx.assetId == optionsAsset)              
           case _ => false
       } &&
       size(dataTx.data) == 1 && !isDefined(getInteger(this, dataTx.data[0].key))
       && height > expirationStart && height <= expirationEnd
   case exchangeTx : ExchangeTransaction =>
       #убСТдаСмся, Ρ‡Ρ‚ΠΎ ΠΈΡ‚ΠΎΠ³ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΠΌΠ΅Π½ происходит ΠΏΠΎ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΌ Π·Π°Ρ€Π°Π½Π΅Π΅ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ
       let correctAssetPair = exchangeTx.sellOrder.assetPair.amountAsset == amountAsset &&
                                   exchangeTx.sellOrder.assetPair.priceAsset == priceAsset
       let correctPrice = exchangeTx.sellOrder.price == sellPrice
       #ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ Π΄Π°Ρ‚Π°-Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ ΠΈΠ· ΠΏΡ€ΡƒΡ„Π°      
       let d = transactionById(exchangeTx.proofs[2])
       match d{
           case dataTx : DataTransaction =>
               let buyOrderSender = dataTx.data[0].key
               toBase58String(exchangeTx.buyOrder.sender.bytes) == buyOrderSender &&
               exchangeTx.amount == extract(getInteger(dataTx.data, buyOrderSender))
           case _ => false
       } &&
       exchangeTx.sellOrder.sender == this &&
       correctAssetPair && correctPrice &&
       height > expirationStart && height <= expirationEnd
   case _ => false
}

Π€ΡŒΡŽΡ‡Π΅Ρ€ΡΡ‹ Π½Π° смарт-Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π°Ρ…

Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ΠΎΠΏΡ†ΠΈΠΎΠ½Π°, Ρ„ΡŒΡŽΡ‡Π΅Ρ€Ρ (Ρ„ΡŒΡŽΡ‡Π΅Ρ€ΡΠ½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚) – это Π½Π΅ ΠΏΡ€Π°Π²ΠΎ, Π° ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎ покупатСля ΡΠΎΠ²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ ΠΏΠΎΠΊΡƒΠΏΠΊΡƒ Π°ΠΊΡ‚ΠΈΠ²Π° ΠΏΠΎ зафиксированной ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚ΠΎΠΌ Ρ†Π΅Π½Π΅ Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ.

Π’ Ρ†Π΅Π»ΠΎΠΌ, рСализация Ρ„ΡŒΡŽΡ‡Π΅Ρ€ΡΠ° ΠΏΠΎΡ…ΠΎΠΆΠ° Π½Π° Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΎΠΏΡ†ΠΈΠΎΠ½Π°. Π—Π΄Π΅ΡΡŒ смарт-ассСт выступаСт Π² качСствС Ρ„ΡŒΡŽΡ‡Π΅Ρ€ΡΠ°.

Π’Π°ΠΊΠΆΠ΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ ΠΈ ΠΏΠΎΠΊΡƒΠΏΠ°Ρ‚Π΅Π»ΡŒ, ΠΈ ΠΏΡ€ΠΎΠ΄Π°Π²Π΅Ρ† ΠΏΠΎΠ΄ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ ΠΎΡ€Π΄Π΅Ρ€ Π½Π° ΠΏΠΎΠΊΡƒΠΏΠΊΡƒ. Π€ΡŒΡŽΡ‡Π΅Ρ€Ρ являСтся ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎΠΌ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ исполнСно Π² любом случаС. Π—Π½Π°Ρ‡ΠΈΡ‚, Ссли ΠΏΡ€ΠΎΠ΄Π°Π²Π΅Ρ† ΠΈΠ»ΠΈ участник ΠΎΡ‚ΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΎΡ‚ своих ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΡΡ‚Π², любой участник сСти ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ, исполнив Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Ρ„ΡŒΡŽΡ‡Π΅Ρ€Ρ.

Π‘ΠΊΡ€ΠΈΠΏΡ‚ смарт-ассСта ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ всС TransferTransaction ΠΈ ExchangeTransaction ассСта-Ρ„ΡŒΡŽΡ‡Π΅Ρ€ΡΠ°, одобряя ΠΈΡ… Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Ρ‚ΠΎΠΌ случаС, Ссли участник-ΠΏΠΎΠΊΡƒΠΏΠ°Ρ‚Π΅Π»ΡŒ создал ΠΎΡ€Π΄Π΅Ρ€ Π½Π° Π±ΡƒΠ΄ΡƒΡ‰ΡƒΡŽ ΠΏΠΎΠΊΡƒΠΏΠΊΡƒ ассСта-Ρ„ΡŒΡŽΡ‡Π΅Ρ€ΡΠ° Ρƒ участника-Π±ΠΈΡ€ΠΆΠΈ.

Π­Ρ‚ΠΎΡ‚ ΠΎΡ€Π΄Π΅Ρ€ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΈ ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡ‚ΡŒ условиям, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π²Ρ‹ΠΏΡƒΡ‰Π΅Π½ Ρ„ΡŒΡŽΡ‡Π΅Ρ€Ρ. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ ΠΎΡ€Π΄Π΅Ρ€, ΠΌΠΎΠΆΠ½ΠΎ внСсти всС Π΅Π³ΠΎ поля Π² стСйт Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π°-покупатСля вмСстС с Π±Π°ΠΉΡ‚ΠΎΠ²Ρ‹ΠΌ прСдставлСниСм подписанного ΠΎΡ€Π΄Π΅Ρ€Π°, Π° Π·Π°Ρ‚Π΅ΠΌ провСсти Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΡŽ ΠΈΠ·Π²Π½Π΅.

На Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ RIDE Π½Π΅ содСрТит Π½Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ парсинга Π±Π°ΠΉΡ‚ΠΎΠ² Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ, Π½ΠΎ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ для Π΅Π΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ инструмСнты. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ.

Аккаунт с ΠΌΡƒΠ»ΡŒΡ‚ΠΈ-подписью / Эскроу

Аккаунт с ΠΌΡƒΠ»ΡŒΡ‚ΠΈ-подписью позволяСт нСскольким ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ совмСстно ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Π°ΠΊΡ‚ΠΈΠ²Π°ΠΌΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с Π°ΠΊΡ‚ΠΈΠ²Π°ΠΌΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ лишь ΠΏΡ€ΠΈ Π½Π°Π»ΠΈΡ‡ΠΈΠΈ подписСй Ρ‚Ρ€Π΅Ρ… ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΈΠ· Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅Ρ…). Для создания Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚ΠΎΠ² с ΠΌΡƒΠ»ΡŒΡ‚ΠΈ-подписью Π² языкС RIDE ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΡƒΡ„Ρ‹ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ.

Аккаунт с ΠΌΡƒΠ»ΡŒΡ‚ΠΈ-подписью ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ‚Π°ΠΊΠΆΠ΅ использован для эскроу-счСта, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Π΄Π΅Π½Π΅ΠΆΠ½Ρ‹Π΅ срСдства хранятся Π΄ΠΎ выполнСния сторонами, Π·Π°ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠΈΠΌΠΈ Π΄ΠΎΠ³ΠΎΠ²ΠΎΡ€, взятых Π½Π° сСбя ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΡΡ‚Π².

let alicePubKey  = base58'5AzfA9UfpWVYiwFwvdr77k6LWupSTGLb14b24oVdEpMM'
let bobPubKey    = base58'2KwU4vzdgPmKyf7q354H9kSyX9NZjNiq4qbnH2wi2VDF'
let cooperPubKey = base58'GbrUeGaBfmyFJjSQb9Z8uTCej5GzjXfRDVGJGrmgt5cD'
#выясняСм, ΠΊΡ‚ΠΎ прСдоставил ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Π΅ подписи
let aliceSigned  = if(sigVerify(tx.bodyBytes, tx.proofs[0], alicePubKey)) then 1 else 0
let bobSigned    = if(sigVerify(tx.bodyBytes, tx.proofs[1], bobPubKey)) then 1 else 0
let cooperSigned = if(sigVerify(tx.bodyBytes, tx.proofs[2], cooperPubKey)) then 1 else 0
#суммируСм всС ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Π΅ подписи ΠΈ провСряСм ΠΈΡ… количСство
aliceSigned + bobSigned + cooperSigned >= 2

УправляСмый Ρ‚ΠΎΠΊΠ΅Π½Π°ΠΌΠΈ рССстр β€” token curated registry (TCR)

На ΠΌΠ½ΠΎΠ³ΠΈΡ… Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½-ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°Ρ… сущСствуСт ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° токсичных ассСтов. НапримСр, ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ассСт Π½Π° Waves ΠΌΠΎΠΆΠ΅Ρ‚ любой адрСс, Π·Π°ΠΏΠ»Π°Ρ‚ΠΈΠ²ΡˆΠΈΠΉ комиссию.

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ Π·Π°Ρ‰ΠΈΡ‚Ρ‹ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΈ самого Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π° ΠΎΡ‚ токсичных ассСтов ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ управляСмый Ρ‚ΠΎΠΊΠ΅Π½Π°ΠΌΠΈ рССстр β€” token curated registry (TCR), β€” Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ дСрТатСлями Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ².

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ³ΠΎΠ»ΠΎΡΠΎΠ²Π°Ρ‚ΡŒ Π·Π° Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ Ρ‚ΠΎΠΊΠ΅Π½Π° Π² список, Π΄Π΅Ρ€ΠΆΠ°Ρ‚Π΅Π»ΡŒ Π΄Π΅Π»Π°Π΅Ρ‚ ставку, Ρ€Π°Π²Π½ΡƒΡŽ Π΅Π³ΠΎ Π΄ΠΎΠ»Π΅ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ² ΠΎΡ‚ ΠΎΠ±Ρ‰Π΅Π³ΠΎ числа Π²Ρ‹ΠΏΡƒΡ‰Π΅Π½Π½Ρ‹Ρ…. Π’ΠΎΠΊΠ΅Π½ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² рССстр, Ссли Π·Π° это проголосовали Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ Π΅Π³ΠΎ Π΄Π΅Ρ€ΠΆΠ°Ρ‚Π΅Π»Π΅ΠΉ.

Π’ нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ позволяСм ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ‚ΠΎΠΊΠ΅Π½ Π² список Π½Π° рассмотрСниС (Π² ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ Β«challengeΒ») ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Ρƒ стСйта key = asset_name, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ссли Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ count = 0.

Π’Π°ΠΊΠΆΠ΅ Ρƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π² кошСлькС Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠΉ баланс этого Ρ‚ΠΎΠΊΠ΅Π½Π°. Π—Π°Ρ‚Π΅ΠΌ наступаСт ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ голосования, Π²ΠΎ врСмя ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚Π΄Π°Ρ‚ΡŒ голос Π·Π° ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ассСт Π² своСм кошСлькС, Π½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ Ρ€Π°Π·Ρƒ, поставив ΠΎΡ†Π΅Π½ΠΊΡƒ ΠΎΡ‚ 1 Π΄ΠΎ 10. Голоса ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ прСдставлСны ΠΊΠ»ΡŽΡ‡Π°ΠΌΠΈ Π²ΠΈΠ΄Π° user_address+assetID.

let asset = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
let addingStartHeight = 1000
let votingStartHeight = 2000
let votingEndHeight = 3000

#ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ ΠΈΠ· Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ адрСс отправитСля
let this = extract(tx.sender)

#ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ адрСс ΠΈΠ· ΠΏΡ€ΡƒΡ„Π° Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ
let address = addressFromPublicKey(tx.proofs[1])
match tx {
   case t: DataTransaction =>
       if(height > addingStartHeight)
       then(
           if(height < votingStartHeight)
           then(
               #adding
               #выясняСм, Π΅ΡΡ‚ΡŒ Π»ΠΈ этот ассСт Ρƒ этого адрСса
               let hasTokens = assetBalance(address, asset) > 0
               size(t.data) == 1
                     #убСТдаСмся, Ρ‡Ρ‚ΠΎ этот ассСт Π΅Ρ‰Π΅ Π½Π΅ Π±Ρ‹Π» Π΄ΠΎΠ±Π°Π²Π»Π΅Π½
                     && !isDefined(getInteger(this, toBase58String(asset)))
                     #убСТдаСмся, Ρ‡Ρ‚ΠΎ ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Ρƒ-ассСту добавляСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ€Π°Π²Π½ΠΎΠ΅ 0
                     && extract(getInteger(t.data, toBase58String(asset))) == 0
                     && hasTokens
           )
           else(
               if(height < votingEndHeight)
               then
               (
                   #voting
                   #ΡƒΠ·Π½Π°Π΅ΠΌ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ количСство голосов Π·Π° Π΄Π°Π½Π½Ρ‹ΠΉ ассСт ΠΈ Π·Π°Π΄Π°Π²Π°Π΅ΠΌΠΎΠ΅ количСство
                   let currentAmount = extract(getInteger(this, toBase58String(asset)))
                   let newAmount = extract(getInteger(t.data, toBase58String(asset)))
                   let betString = toBase58String(address.bytes) + toBase58String(asset)

                   #убСТдаСмся, Ρ‡Ρ‚ΠΎ этот адрСс Π΅Ρ‰Π΅ Π½Π΅ голосовал Π·Π° этот ассСт
                   let noBetBefore = !isDefined(getInteger(this, betString))
                   let isBetCorrect = extract(getInteger(t.data, betString)) > 0
                       && extract(getInteger(t.data, betString)) <= 10
                  
                   #убСТдаСмся, Ρ‡Ρ‚ΠΎ Ρƒ Π³ΠΎΠ»ΠΎΡΡƒΡŽΡ‰Π΅Π³ΠΎ Π΅ΡΡ‚ΡŒ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ Ρ‚ΠΎΠΊΠ΅Π½Ρ‹
                   let hasTokens = assetBalance(address, asset) > 0
                   #провСряСм ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΡΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ
                   size(t.data) == 2 && isDefined(getInteger(this, toBase58String(asset)))
                       && newAmount == currentAmount + 1
                       && noBetBefore && isBetCorrect && hasTokens
               )
               else false
           ) && sigVerify(tx.bodyBytes, tx.proofs[0], tx.proofs[1])
       )
       else false
   case _ => false
}

АбонСнтская ΠΏΠ»Π°Ρ‚Π°

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ рассмотрим использованиС смарт-Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚ΠΎΠ² для осущСствлСния рСгулярных ΠΏΠ»Π°Ρ‚Π΅ΠΆΠ΅ΠΉ Π·Π° Ρ‚ΠΎΠ²Π°Ρ€ ΠΈΠ»ΠΈ услугу Ρ‡Π΅Ρ€Π΅Π· Π·Π°Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΊΠΈ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ – «абонСнтской ΠΏΠ»Π°Ρ‚Ρ‹Β».
Если ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ прСдоставляСт смарт-Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Ρƒ (Ρ‡Π΅Ρ€Π΅Π· ΠΏΡ€ΡƒΡ„Ρ‹ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ) ID TransferTransaction с Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹ΠΌ количСством ΠΏΠ΅Ρ€Π΅Π²Π΅Π΄Π΅Π½Π½Ρ‹Ρ… срСдств, ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² стСйт Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π° {key: address, value: true}.

Π­Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ·Π½Π°Ρ‡Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚ подписку Π½Π° Ρ‚ΠΎΠ²Π°Ρ€ ΠΈΠ»ΠΈ услугу. Когда срок подписки истСчСт, любой ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ сСти ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π½Π°ΠΏΡ€ΠΎΡ‚ΠΈΠ² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΊΠ»ΡŽΡ‡Π° Π² стСйтС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ false.

let subscriptionPeriod = 44000
let signature = tx.proofs[0]
let pk = tx.proofs[1]
let requiredAmount = 100000

#ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ ΠΈΠ· Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ адрСс отправитСля
let this = extract(tx.sender)
match tx {
   case d: DataTransaction =>
     #ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ Π΄Π°Ρ‚Ρƒ послСднСго ΠΏΠ»Π°Ρ‚Π΅ΠΆΠ°
     let lastPaymentHeight = extract(getInteger(this, d.data[0].key + "_lastPayment"))
     size(d.data) == 1 && d.data[0].value == "false" && lastPaymentHeight + subscriptionPeriod < height
     ||
     (
       let address = d.data[0].key

       #ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ трансфСр-Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ ΠΏΠΎ ID, ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ Π² ΠΏΡ€ΡƒΡ„Π°Ρ…
       let ttx = transactionById(d.proofs[0])
       
       size(d.data) == 2
           && d.data[0].value == "true"
           && d.data[1].key == address + "_lastPayment"
           && match ttx {
             case purchase : TransferTransaction =>
               d.data[1].value == transactionHeightById(purchase.id)
               && toBase58String(purchase.sender.bytes) == address
               && purchase.amount == requiredAmount
               && purchase.recipient == this
               #убСТдаСмся, Ρ‡Ρ‚ΠΎ ассСт waves
               && !isDefined(purchase.assetId)
         case _ => false
       }
     )
   case _ => false
}

ГолосованиС

Π‘ΠΌΠ°Ρ€Ρ‚-Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Ρ‹ для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ голосования Π½Π° Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ»ΡƒΠΆΠΈΡ‚ΡŒ голосованиС Π·Π° Π»ΡƒΡ‡ΡˆΠΈΠΉ ΠΎΡ‚Ρ‡Π΅Ρ‚ амбассадора Π² Ρ€Π°ΠΌΠΊΠ°Ρ… амбассадорской ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Π‘Ρ‚Π΅ΠΉΡ‚ Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² качСствС ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ для записи голосов Π·Π° Ρ‚ΠΎΡ‚ ΠΈΠ»ΠΈ ΠΈΠ½ΠΎΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚.

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π³ΠΎΠ»ΠΎΡΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ΠΌ, ΠΊΡ‚ΠΎ ΠΏΡ€ΠΈΠΎΠ±Ρ€Π΅Π» ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ β€œΠ³ΠΎΠ»ΠΎΡΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅β€ Ρ‚ΠΎΠΊΠ΅Π½Ρ‹. Участник Π·Π°Ρ€Π°Π½Π΅Π΅ отправляСт DataTransaction с ΠΏΠ°Ρ€ΠΎΠΉ (key, value) = (purchaseTransactionId, buyTransactionId). Установка Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ значСния ΠΏΠΎ этому ΠΊΠ»ΡŽΡ‡Ρƒ Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½Π°. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ свой адрСс ΠΈ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ голосования, ΠΌΠΎΠΆΠ½ΠΎ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ DataEntry Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€Π°Π·. ГолосованиС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² установлСнный ΠΏΠ΅Ρ€ΠΈΠΎΠ΄.

let asset = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
let address = addressFromPublicKey(tx.proofs[1])
let votingStartHeight = 2000
let votingEndHeight = 3000

#ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ ΠΈΠ· Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ адрСс отправитСля
let this = extract(tx.sender)
 match tx {
   case t: DataTransaction =>
     (height > votingStartHeight && height < votingEndHeight) &&
     #убСТдаСмся, Ρ‡Ρ‚ΠΎ Ρƒ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Π°Ρ подпись
     sigVerify(tx.bodyBytes, tx.proofs[0], tx.proofs[1]) &&

     #провСряСм, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΎΡ‚Π΄Π°Π΅Ρ‚ свой голос Π½Π°ΠΏΡ€ΠΎΡ‚ΠΈΠ² своСго адрСса
     if (t.data[0].key == toBase58String(address.bytes))
     then (
       #ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ Π³ΠΎΠ»ΠΎΡΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ Ρ‚ΠΎΠΊΠ΅Π½Π° ΠΈΠ· ΠΏΡ€ΡƒΡ„ΠΎΠ²
       let purchaseTx = transactionById(t.proofs[7])
       
       match purchaseTx {
         case purchase : TransferTransaction =>
           let correctSender = purchase.sender == t.sender
           let correctAsset = purchase.assetId == asset
           let correctPrice = purchase.amount == 1
           let correctProof = extract(getBinary(this, toBase58String(purchase.id))) == t.id
           correctSender && correctAsset && correctPrice && correctProof
         case _ => false
       }
     )
     else
         size(t.data) == 1 && !isDefined(getBinary(this, t.data[0].key))
   case _ => false
}

Π’Π΅ΠΊΡΠ΅Π»ΡŒ

Π’Π΅ΠΊΡΠ΅Π»ΡŒ β€” письмСнноС ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎ, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΎΠ΄Π½Π° сторона Π΄ΠΎΠ»ΠΆΠ½Π° Π²Ρ‹ΠΏΠ»Π°Ρ‚ΠΈΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠΉ Ρ„ΠΈΠΊΡΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ сумму Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ трСбования ΠΈΠ»ΠΈ Π² Π·Π°Ρ€Π°Π½Π΅Π΅ ΡƒΡΡ‚Π°Π½ΠΎΠ²Π»Π΅Π½Π½ΡƒΡŽ Π΄Π°Ρ‚Ρƒ.

Π’ нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ смарт-Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚, Π΄Π°Ρ‚Π° экспирации ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ соотвСтствуСт Π΄Π°Ρ‚Π΅ Π²Ρ‹ΠΏΠ»Π°Ρ‚Ρ‹ ΠΏΠΎ вСксСлю.

let expiration = 100000
let amount = 10
let asset =  base58'9jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
  
let Bob = Address(base58'3NBVqYXrapgJP9atQccdBPAgJPwHDKkh6A8')
let Alice = Address(base58'3PNX6XwMeEXaaP1rf5MCk8weYeF7z2vJZBg')
  
match tx {
    case t: TransferTransaction =>
        (t.assetId == asset)&&      
        (t.amount == amount)&&       
        (t.sender == Bob)&&
        (t.recipient == Alice)&&
        (sigVerify(t.bodyBytes, t.proofs[0], t.senderPublicKey))&&
        (height >= expiration)
    case _ => false
}

Π”Π΅ΠΏΠΎΠ·ΠΈΡ‚

Π”Π΅ΠΏΠΎΠ·ΠΈΡ‚ β€” Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Π΄Π΅Π½Π΅ΠΆΠ½Ρ‹Ρ… срСдств Π² Π±Π°Π½ΠΊΠ΅ Π½Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… условиях (срок, ΠΏΡ€ΠΎΡ†Π΅Π½Ρ‚).
Π’ нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π±Π°Π½ΠΊΠ° выполняСт смарт-Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚. ПослС ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ количСства Π±Π»ΠΎΠΊΠΎΠ², Ρ‡Ρ‚ΠΎ соотвСтствуСт сроку Π΄Π΅ΠΏΠΎΠ·ΠΈΡ‚Π°, ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ свои дСньги с ΠΏΡ€ΠΎΡ†Π΅Π½Ρ‚ΠΎΠΌ. Π’ скриптС Π·Π°Π΄Π°Π½Π° высота Π±Π»ΠΎΠΊΠ° (finalHeight), послС достиТСния ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ½ΡΡ‚ΡŒ дСньги со счСта.

heightUnit β€” количСство Π±Π»ΠΎΠΊΠΎΠ² Π² ΠΎΠ΄Π½ΠΎΠΉ Π΅Π΄ΠΈΠ½ΠΈΡ†Π΅ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, мСсяц, Π³ΠΎΠ΄ ΠΈ Ρ‚. Π΄.). Π‘Π½Π°Ρ‡Π°Π»Π° ΠΌΡ‹ провСряСм Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ записи с ΠΏΠ°Ρ€ΠΎΠΉ (key, value) = (initialTransferTransaction, futureDataTransaction). Π—Π°Ρ‚Π΅ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ TransferTransaction с ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠ΅ΠΉ ΠΎ суммС Π΄Π΅ΠΏΠΎΠ·ΠΈΡ‚Π° ΠΈ ΠΏΡ€ΠΎΡ†Π΅Π½Ρ‚ΠΎΠ², начислСнных Π·Π° ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ Π΄Π΅ΠΏΠΎΠ·ΠΈΡ‚Π°. Π­Ρ‚Π° информация свСряСтся с исходной TransferTransaction, которая содСрТится Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ ΠΏΡ€ΡƒΡ„Π΅ TransferTransaction. depositDivisor β€” число, ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ΅ Π΄ΠΎΠ»Π΅ Π΄Π΅ΠΏΠΎΠ·ΠΈΡ‚Π° (Ссли Π΄Π΅ΠΏΠΎΠ·ΠΈΡ‚ принимаСтся ΠΏΠΎΠ΄ 10%, доля Π΄Π΅ΠΏΠΎΠ·ΠΈΡ‚Π° составляСт 0,1, Π° depositDevisor = 1/0,1 = 10).

let this = extract(tx.sender)
let depositDivisor = 10
let heightUnit = 1000
let finalHeight = 100000
 match tx {
   case e : TransferTransaction =>
     #ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ высоту Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΏΠΎ ID Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π² сСдьмом ΠΏΡ€ΡƒΡ„Π΅  
     let depositHeight = extract(transactionHeightById(e.proofs[7]))

     #ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ Π΄Π΅ΠΏΠΎΠ·ΠΈΡ‚Π°
     let purchaseTx = transactionById(e.proofs[7])    
     match purchaseTx {
       case deposit : TransferTransaction =>
         let correctSender = deposit.sender == e.sender
         #убСТдаСмся, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ сСбС ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΡƒΡŽ сумму Π΄Π΅ΠΏΠΎΠ·ΠΈΡ‚Π° + ΠΏΡ€ΠΎΡ†Π΅Π½Ρ‚Ρ‹
         let correctAmount = deposit.amount + deposit.amount / depositDivisor * (height - depositHeight) / heightUnit == e.amount
         let correctProof = extract(getBinary(this, toBase58String(deposit.id))) == e.id
         correctSender && correctProof && correctAmount
       case _ => false
     }
     && finalHeight <= height 
 case _ => sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
}

Π’ Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ΠΉ ΠΈ Π·Π°ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ этой сСрии ΠΌΡ‹ рассмотрим Π΅Ρ‰Π΅ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ примСнСния смарт-ассСтов, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ Π·Π°ΠΌΠΎΡ€ΠΎΠ·ΠΊΡƒ ΠΈ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ для ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Ρ… адрСсов.

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