Penggunaan akaun pintar Waves: daripada lelongan kepada program bonus

Penggunaan akaun pintar Waves: daripada lelongan kepada program bonus

Blockchain selalunya dikaitkan hanya dengan mata wang kripto, tetapi bidang aplikasi teknologi DLT adalah lebih luas. Salah satu bidang yang paling menjanjikan untuk penggunaan blockchain ialah kontrak pintar yang dilaksanakan secara automatik dan tidak memerlukan kepercayaan antara pihak yang menyertainya.

RIDE – bahasa untuk kontrak pintar

Waves telah membangunkan bahasa khas untuk kontrak pintar - RIDE. Dokumentasi lengkapnya terdapat di sini. Dan di sini - artikel mengenai topik ini pada Habr.

Kontrak RIDE ialah predikat dan mengembalikan "benar" atau "salah" sebagai output. Sehubungan itu, urus niaga itu sama ada direkodkan dalam rantaian blok atau ditolak. Kontrak pintar menjamin sepenuhnya pemenuhan syarat yang ditentukan. Menjana urus niaga daripada kontrak dalam RIDE pada masa ini tidak boleh dilakukan.

Hari ini terdapat dua jenis kontrak pintar Waves: akaun pintar dan aset pintar. Akaun pintar ialah akaun pengguna biasa, tetapi skrip ditetapkan untuknya yang mengawal semua transaksi. Skrip akaun pintar mungkin kelihatan seperti ini, sebagai contoh:

match tx {
  case t: TransferTransaction | MassTransferTransaction => false
  case _ => true
}

tx ialah transaksi sedang diproses yang kami benarkan menggunakan mekanisme padanan corak hanya jika ia bukan transaksi pemindahan. Padanan corak dalam RIDE digunakan untuk menyemak jenis transaksi. Semua akaun sedia ada boleh diproses dalam skrip akaun pintar jenis transaksi.

Skrip juga boleh mengisytiharkan pembolehubah, menggunakan binaan "jika-maka-lain" dan kaedah lain untuk menyemak keadaan sepenuhnya. Untuk memastikan bahawa kontrak mempunyai kesempurnaan dan kerumitan (kos) yang boleh dibuktikan yang mudah diramal sebelum pelaksanaan kontrak bermula, RIDE tidak mengandungi penyata gelung atau lompat.

Ciri lain akaun Waves termasuk kehadiran "keadaan", iaitu, keadaan akaun. Anda boleh menulis pasangan (kunci, nilai) yang tidak terhingga kepada keadaan akaun menggunakan transaksi data (DataTransaction). Maklumat ini kemudiannya boleh diproses melalui API REST dan terus dalam kontrak pintar.

Setiap transaksi boleh mengandungi pelbagai bukti, di mana tandatangan peserta, ID transaksi yang diperlukan, dsb. boleh dimasukkan.

Bekerja dengan RIDE melalui IDE membolehkan anda melihat paparan terkumpul kontrak (jika ia disusun), buat akaun baharu dan tetapkan skrip untuknya, serta menghantar transaksi melalui baris arahan.

Untuk kitaran penuh, termasuk membuat akaun, memasang kontrak pintar padanya dan menghantar transaksi, anda juga boleh menggunakan pustaka untuk berinteraksi dengan REST API (contohnya, C#, C, Java, JavaScript, Python, Rust, Elixir) . Untuk mula bekerja dengan IDE, cuma klik butang BARU.

Kemungkinan untuk menggunakan kontrak pintar adalah luas: daripada melarang transaksi ke alamat tertentu (β€œsenarai hitam”) kepada dApps yang kompleks.

Sekarang mari kita lihat contoh khusus penggunaan kontrak pintar dalam perniagaan: semasa menjalankan lelongan, insurans dan mencipta program kesetiaan.

Lelongan

Salah satu syarat untuk lelongan yang berjaya ialah ketelusan: peserta mesti yakin bahawa adalah mustahil untuk memanipulasi tawaran. Ini boleh dicapai terima kasih kepada rantaian blok, di mana data tidak berubah tentang semua pertaruhan dan masa ia dibuat akan tersedia kepada semua peserta.

Pada blockchain Waves, bidaan boleh direkodkan dalam keadaan akaun lelongan melalui DataTransaction.

Anda juga boleh menetapkan masa mula dan tamat lelongan menggunakan nombor blok: kekerapan penjanaan blok dalam rantaian Waves adalah lebih kurang sama dengan 60 detik.

1. Bahasa Inggeris lelongan harga menaik

Peserta dalam lelongan bahasa Inggeris meletakkan tawaran dalam persaingan antara satu sama lain. Setiap pertaruhan baru mesti melebihi pertaruhan sebelumnya. Lelongan tamat apabila tiada lagi pembida yang melebihi bidaan terakhir. Dalam kes ini, pembida tertinggi mesti memberikan jumlah yang dinyatakan.

Terdapat juga pilihan lelongan di mana penjual menetapkan harga minimum untuk lot tersebut dan harga akhir mesti melebihi harga tersebut. Jika tidak, lot itu kekal tidak terjual.

Dalam contoh ini, kami bekerja dengan akaun yang dibuat khusus untuk lelongan. Tempoh lelongan ialah 3000 blok, dan harga permulaan lot ialah 0,001 GELOMBANG. Seorang peserta boleh membuat tawaran dengan menghantar DataTransaction dengan "harga" utama dan nilai bida mereka.

Harga bida baharu mestilah lebih tinggi daripada harga semasa untuk kunci ini dan peserta mesti mempunyai sekurang-kurangnya token [new_bid + commission] dalam akaunnya. Alamat pembida mesti direkodkan dalam medan "pengirim" dalam DataTransaction dan ketinggian blok bida semasa mestilah dalam tempoh lelongan.

Jika pada akhir lelongan peserta telah menetapkan harga tertinggi, dia boleh menghantar ExchangeTransaction untuk membayar lot yang sepadan pada harga dan pasangan mata wang yang ditetapkan.

let startHeight = 384120
let finishHeight = startHeight + 3000
let startPrice = 100000
 
#ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ ΠΈΠ· Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ адрСс отправитСля
let this = extract(tx.sender)
let token = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
 
match tx {
case d : DataTransaction =>
  #провСряСм, Π·Π°Π΄Π°Π½Π° Π»ΠΈ Π² стСйтС Ρ†Π΅Π½Π°
  let currentPrice = if isDefined(getInteger(this, "price"))
 
                      #ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ Ρ†Π΅Π½Ρƒ ΠΈΠ· стСйта
                      then extract(getInteger(this, "price"))
                      else startPrice
 
  #ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ Ρ†Π΅Π½Ρƒ ΠΈΠ· Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ
  let newPrice = extract(getInteger(d.data, "price"))
  let priceIsBigger = newPrice > currentPrice
  let fee = 700000
  let hasMoney = wavesBalance(tx.sender) + fee >= newPrice
 
  #убСТдаСмся, Ρ‡Ρ‚ΠΎ Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π΄Π²Π° поля ΠΈ Ρ‡Ρ‚ΠΎ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚Π΅Π»ΡŒ совпадаСт с ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΌ Π² Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ
  let correctFields = size(d.data) == 2 &&      
      d.sender == addressFromString(extract(getString(d.data,"sender")))
  startHeight <= height && height <= finishHeight && priceIsBigger && hasMoney && correctFields
case e : ExchangeTransaction =>
  let senderIsWinner = e.sender == addressFromString(extract(getString(this, "sender"))) #убСТдаСмся, Ρ‡Ρ‚ΠΎ Π»ΠΎΡ‚ ΠΎΠ±ΠΌΠ΅Π½ΠΈΠ²Π°Π΅Ρ‚ Ρ‚ΠΎΡ‚, ΠΊΡ‚ΠΎ Π΅Π³ΠΎ Π²Ρ‹ΠΈΠ³Ρ€Π°Π»
  let correctAssetPair = e.sellOrder.assetPair.amountAsset == token && ! isDefined(e.sellOrder.assetPair.priceAsset)
  let correctAmount = e.amount == 1
  let correctPrice = e.price == extract(getInteger(this, "price"))
 
  height > finishHeight && senderIsWinner && correctAssetPair && correctAmount && correctPrice
case _ => false
}

2. Lelongan Belanda penurunan harga

Dalam lelongan Belanda, banyak yang ditawarkan pada mulanya pada harga yang lebih tinggi daripada yang pembeli sanggup bayar. Harga dikurangkan langkah demi langkah sehingga salah seorang peserta bersetuju untuk membeli lot pada harga semasa.

Dalam contoh ini kita menggunakan pemalar yang sama seperti yang sebelumnya, serta langkah harga apabila delta berkurangan. Skrip akaun menyemak sama ada peserta sememangnya yang pertama membuat pertaruhan. Jika tidak, DataTransaction tidak diterima oleh blockchain.

let startHeight = 384120
let finishHeight = startHeight + 3000
let startPrice = 100000000
let delta = 100
 
#ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ ΠΈΠ· Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ адрСс отправитСля
let this = extract(tx.sender)
let token = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
match tx {
case d : DataTransaction =>
  let currentPrice = startPrice - delta * (height - startHeight)
 
  #ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ ΠΈΠ· ΠΏΠΎΡΡ‚ΡƒΠΏΠΈΠ²ΡˆΠ΅ΠΉ Π΄Π°Ρ‚Π°-Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΏΠΎΠ»Π΅ "price"
  let newPrice = extract(getInteger(d.data, "price"))
 
  #убСТдаСмся, Ρ‡Ρ‚ΠΎ Π² стСйтС Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π° Π½Π΅ содСрТится поля "sender"
  let noBetsBefore = !isDefined(getInteger(this, "sender"))
  let fee = 700000
  let hasMoney = wavesBalance(tx.sender) + fee >= newPrice
 
  #убСТдаСмся, Ρ‡Ρ‚ΠΎ Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΄Π²Π° поля
  let correctFields = size(d.data) == 2 && newPrice == currentPrice && d.sender == addressFromString(extract(getString(d.data, "sender")))
  startHeight <= height && height <= finishHeight && noBetsBefore && hasMoney && correctFields
case e : ExchangeTransaction =>
 
  #убСТдаСмся, Ρ‡Ρ‚ΠΎ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚Π΅Π»ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΡƒΠΊΠ°Π·Π°Π½ Π² стСйтС Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π° ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Ρƒ sender
  let senderIsWinner = e.sender == addressFromString(extract(getString(this, "sender")))
 
  #убСТдаСмся, Ρ‡Ρ‚ΠΎ Π°mount ассСта ΡƒΠΊΠ°Π·Π°Π½ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ, ΠΈ Ρ‡Ρ‚ΠΎ прайс-ассСт - waves
  let correctAssetPair = e.sellOrder.assetPair.amountAsset == token && ! isDefined(e.sellOrder.assetPair.priceAsset)
  let correctAmount = e.amount == 1
  let correctPrice = e.price == extract(getInteger(this, "price"))
  height > finishHeight && senderIsWinner && correctAssetPair && correctAmount && correctPrice
case _ => false
}

3. Lelong "bayar semua"

"All-pay" ialah lelongan di mana semua peserta membayar bida, tanpa mengira siapa yang memenangi lot. Setiap peserta baharu membayar tawaran, dan peserta yang membuat tawaran maksimum memenangi lot.

Dalam contoh kami, setiap peserta lelongan meletakkan bida melalui DataTransaction dengan (kunci, nilai)* = (β€œpemenang”, alamat),(β€œharga”, harga). DataTransaction sedemikian diluluskan hanya jika peserta ini sudah mempunyai TransferTransaction dengan tandatangannya dan bidaannya lebih tinggi daripada semua yang sebelumnya. Lelongan diteruskan sehingga endHeight dicapai.

let startHeight = 1000
let endHeight = 2000
let this = extract(tx.sender)
let token = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
match tx {
 case d: DataTransaction =>
   #ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ ΠΈΠ· ΠΏΠΎΡΡ‚ΡƒΠΏΠΈΠ²ΡˆΠ΅ΠΉ Π΄Π°Ρ‚Π°-Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΏΠΎΠ»Π΅ "price"
   let newPrice = extract(getInteger(d.data, "price"))
 
   #ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ ΠΈΠ· ΠΏΡ€ΡƒΡ„ΠΎΠ² Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π°
   let pk = d.proofs[1]
   let address = addressFromPublicKey(pk)
 
   #ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ Π΄ΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎ ΠΈΠ· ΠΏΡ€ΡƒΡ„ΠΎΠ² ΠΏΠΎΡΡ‚ΡƒΠΏΠΈΠ²ΡˆΠ΅ΠΉ Π΄Π°Ρ‚Π° Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ
   let proofTx = extract(transactionById(d.proofs[2]))
   
   height > startHeight && height < endHeight
   && size(d.data) == 2
   #убСТдаСмся, Ρ‡Ρ‚ΠΎ адрСс побСдитСля, ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½Π½Ρ‹ΠΉ ΠΈΠ· Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ, совпадаСт с адрСсом, ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½Π½Ρ‹ΠΌ ΠΈΠ· ΠΏΡ€ΡƒΡ„ΠΎΠ²
   && extract(getString(d.data, "winner")) == toBase58String(address.bytes)
   && newPrice > extract(getInteger(this, "price"))
   #провСряСм, Ρ‡Ρ‚ΠΎ транзакция подписана
   && sigVerify(d.bodyBytes, d.proofs[0], d.proofs[1])
   #провСряСм ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΡΡ‚ΡŒ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ, ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ Π² ΠΏΡ€ΡƒΡ„Π°Ρ…
   && match proofTx {
     case tr : TransferTransaction =>
       tr.sender == address &&
       tr.amount == newPrice
     case _ => false
   }
 case t: TransferTransaction =>
 sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
 || (
   height > endHeight
   && extract(getString(this, "winner")) == toBase58String((addressFromRecipient(t.recipient)).bytes)
   && t.assetId == token
   && t.amount == 1
 )
 case _ => sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
}

Insurans / Crowdfunding

Mari kita pertimbangkan situasi di mana anda perlu menginsuranskan aset pengguna terhadap kerugian kewangan. Sebagai contoh, pengguna mahukan jaminan bahawa jika token susut nilai, dia akan dapat mendapatkan kembali jumlah penuh yang dibayar untuk token ini, dan sanggup membayar jumlah insurans yang munasabah.

Untuk melaksanakan ini, "token insurans" perlu dikeluarkan. Kemudian skrip dipasang pada akaun pemegang polisi, membenarkan hanya ExchangeTransactions yang memenuhi syarat tertentu untuk dilaksanakan.

Untuk mengelakkan perbelanjaan berganda, anda perlu meminta pengguna menghantar DataTransaction ke akaun pemegang polisi terlebih dahulu dengan (kunci, nilai) = (purchaseTransactionId, sellOrderId) dan melarang menghantar DataTransactions dengan kunci yang telah digunakan.

Oleh itu, bukti pengguna mesti mengandungi ID transaksi pembelian token insurans. Pasangan mata wang mestilah sama seperti dalam transaksi pembelian. Kos juga mestilah sama dengan yang ditetapkan pada masa pembelian, tolak harga insurans.

Difahamkan bahawa selepas itu akaun insurans membeli token insurans daripada pengguna pada harga yang tidak lebih rendah daripada yang dia membelinya: akaun insurans mencipta ExchangeTransaction, pengguna menandatangani pesanan (jika transaksi selesai dengan betul), akaun insurans menandatangani pesanan kedua dan keseluruhan transaksi dan menghantarnya ke rantaian blok .

Jika tiada pembelian berlaku, pengguna boleh membuat ExchangeTransaction mengikut peraturan yang diterangkan dalam skrip dan menghantar transaksi ke blockchain. Dengan cara ini pengguna boleh memulangkan wang yang dibelanjakan untuk pembelian token yang diinsuranskan.

let insuranceToken = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
 
#ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ ΠΈΠ· Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ адрСс отправитСля
let this = extract(tx.sender)
let freezePeriod = 150000
let insurancePrice = 10000
match tx {
 
 #убСТдаСмся, Ρ‡Ρ‚ΠΎ, Ссли поступила Π΄Π°Ρ‚Π°-транзакция, Ρ‚ΠΎ Ρƒ Π½Π΅Π΅ Ρ€ΠΎΠ²Π½ΠΎ ΠΎΠ΄Π½ΠΎ ΠΏΠΎΠ»Π΅ ΠΈ Π² стСйтС Π΅Ρ‰Π΅ Π½Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π°
 case d : DataTransaction => size(d.data) == 1 && !isDefined(getBinary(this, d.data[0].key))
 case e : ExchangeTransaction =>
 
   #Ссли Ρƒ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π½Π΅Ρ‚ сСдьмого ΠΏΡ€ΡƒΡ„Π°, провСряСм ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΡΡ‚ΡŒ подписи
   if !isDefined(e.proofs[7]) then
     sigVerify(e.bodyBytes, e.proofs[0], e.senderPublicKey)
   else
     #Ссли Ρƒ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π΅ΡΡ‚ΡŒ сСдьмой ΠΏΡ€ΡƒΡ„, ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ ΠΈΠ· Π½Π΅Π³ΠΎ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ ΠΈ ΡƒΠ·Π½Π°Ρ‘ΠΌ Π΅Ρ‘ высоту
     let purchaseTx = transactionById(e.proofs[7])
     let purchaseTxHeight = extract(transactionHeightById(e.proofs[7]))
    
     #ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ ΠΈΠ· ΠΏΡ€ΡƒΡ„Π°
     match purchaseTx {
       case purchase : ExchangeTransaction =>
         let correctSender = purchase.sender == e.sellOrder.sender
         let correctAssetPair = e.sellOrder.assetPair.amountAsset == insuranceToken &&
                                purchase.sellOrder.assetPair.amountAsset == insuranceToken &&
                                e.sellOrder.assetPair.priceAsset == purchase.sellOrder.assetPair.priceAsset
         let correctPrice = e.price == purchase.price - insurancePrice && e.amount == purchase.amount
         let correctHeight = height > purchaseTxHeight + freezePeriod
 
         #убСТдаСмся, Ρ‡Ρ‚ΠΎ Π² Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ-ΠΏΡ€ΡƒΡ„Π΅ ΡƒΠΊΠ°Π·Π°Π½ Π²Π΅Ρ€Π½Ρ‹ΠΉ ID Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ
         let correctProof = extract(getBinary(this, toBase58String(purchase.id))) == e.sellOrder.id
         correctSender && correctAssetPair && correctPrice && correctHeight && correctProof
     case _ => false
   }
 case _ => sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
}

Token insurans boleh dijadikan aset pintar, sebagai contoh, untuk melarang pemindahannya kepada pihak ketiga.

Skim ini juga boleh dilaksanakan untuk token crowdfunding, yang dikembalikan kepada pemilik jika jumlah yang diperlukan belum dikutip.

Cukai urus niaga

Kontrak pintar juga terpakai dalam kes di mana perlu untuk mengutip cukai ke atas setiap transaksi dengan beberapa jenis aset. Ini boleh dilakukan melalui aset baharu dengan dipasang penajaan untuk transaksi dengan aset pintar:

1. Kami mengeluarkan FeeCoin, yang akan dihantar kepada pengguna pada harga tetap: 0,01 WAVES = 0,001 FeeCoin.

2. Tetapkan tajaan untuk FeeCoin dan kadar pertukaran: 0,001 WAVES = 0,001 FeeCoin.

3. Tetapkan skrip berikut untuk aset pintar:

let feeAssetId = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
let taxDivisor = 10
 
match tx {
  case t: TransferTransaction =>
    t.feeAssetId == feeAssetId && t.fee == t.amount / taxDivisor
  case e: ExchangeTransaction | MassTransferTransaction => false
  case _ => true
}

Kini setiap kali seseorang memindahkan N aset pintar, mereka akan memberi anda FeeCoin dalam jumlah N/taxDivisor (yang boleh dibeli daripada anda pada 10 *N/taxDivisor WAVES), dan anda akan memberikan pelombong N/taxDivisor WAVES. Akibatnya, keuntungan (cukai) anda akan menjadi 9*N / cukaiDivisor WAVES.

Anda juga boleh melaksanakan cukai menggunakan skrip aset pintar dan MassTransferTransaction:

let taxDivisor = 10
 
match tx {
  case t : MassTransferTransaction =>
    let twoTransfers = size(t.transfers) == 2
    let issuerIsRecipient = t.transfers[0].recipient == addressFromString("3MgkTXzD72BTfYpd9UW42wdqTVg8HqnXEfc")
    let taxesPaid = t.transfers[0].amount >= t.transfers[1].amount / taxDivisor
    twoTransfers && issuerIsRecipient && taxesPaid
  case _ => false
}

Pulangan tunai dan program kesetiaan

Pulangan Tunai ialah sejenis program kesetiaan di mana pembeli mendapat kembali sebahagian daripada jumlah yang dibelanjakan untuk produk atau perkhidmatan.

Apabila melaksanakan kes ini menggunakan akaun pintar, kami mesti menyemak bukti dengan cara yang sama seperti yang kami lakukan dalam kes insurans. Untuk mengelakkan perbelanjaan berganda, pengguna mesti menghantar DataTransaction dengan (kunci, nilai) = (purchaseTransactionId, cashbackTransactionId) sebelum menerima cashback.

Kami juga mesti menetapkan larangan ke atas kunci sedia ada menggunakan DataTransaction. cashbackDivisor - unit dibahagikan dengan bahagian cashback. Itu. jika bahagian cashback ialah 0.1, maka cashbackDivisor 1 / 0.1 = 10.

let cashbackToken = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
 
#ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ ΠΈΠ· Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ адрСс отправитСля
let this = extract(tx.sender)
let cashbackDivisor = 10
match tx {
 
 #убСТдаСмся, Ρ‡Ρ‚ΠΎ, Ссли поступила Π΄Π°Ρ‚Π°-транзакция, Ρ‚ΠΎ Ρƒ Π½Π΅Π΅ Ρ€ΠΎΠ²Π½ΠΎ ΠΎΠ΄Π½ΠΎ ΠΏΠΎΠ»Π΅ ΠΈ Π² стСйтС Π΅Ρ‰Π΅ Π½Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π°
 case d : DataTransaction => size(d.data) == 1 && !isDefined(getBinary(this, d.data[0].key))
 case e : TransferTransaction =>
 
   #Ссли Ρƒ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π½Π΅Ρ‚ сСдьмого ΠΏΡ€ΡƒΡ„Π°, провСряСм ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΡΡ‚ΡŒ подписи
   if !isDefined(e.proofs[7]) then
     sigVerify(e.bodyBytes, e.proofs[0], e.senderPublicKey)
   else
 
     #Ссли Ρƒ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π΅ΡΡ‚ΡŒ сСдьмой ΠΏΡ€ΡƒΡ„, ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ ΠΈΠ· Π½Π΅Π³ΠΎ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ ΠΈ ΡƒΠ·Π½Π°Ρ‘ΠΌ Π΅Ρ‘ высоту
     let purchaseTx = transactionById(e.proofs[7])
     let purchaseTxHeight = extract(transactionHeightById(e.proofs[7]))
    
     #ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ ΠΈΠ· ΠΏΡ€ΡƒΡ„Π°
     match purchaseTx {
       case purchase : TransferTransaction =>
         let correctSender = purchase.sender == e.sender
         let correctAsset = e.assetId == cashbackToken
         let correctPrice = e.amount == purchase.amount / cashbackDivisor
 
         #убСТдаСмся, Ρ‡Ρ‚ΠΎ Π² Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ-ΠΏΡ€ΡƒΡ„Π΅ ΡƒΠΊΠ°Π·Π°Π½ Π²Π΅Ρ€Π½Ρ‹ΠΉ ID Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ
         let correctProof = extract(getBinary(this, toBase58String(purchase.id))) == e.id
         correctSender && correctAsset && correctPrice && correctProof
     case _ => false
   }
 case _ => sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
}

Pertukaran atom

Pertukaran atom membolehkan pengguna menukar aset tanpa bantuan pertukaran. Dengan pertukaran atom, kedua-dua peserta dalam transaksi dikehendaki mengesahkannya dalam tempoh masa tertentu.

Jika sekurang-kurangnya seorang daripada peserta tidak memberikan pengesahan yang betul tentang transaksi dalam masa yang diperuntukkan untuk transaksi, transaksi tersebut dibatalkan dan pertukaran tidak berlaku.

Dalam contoh kami, kami akan menggunakan skrip akaun pintar berikut:

let Bob = Address(base58'3NBVqYXrapgJP9atQccdBPAgJPwHDKkh6A8')
let Alice = Address(base58'3PNX6XwMeEXaaP1rf5MCk8weYeF7z2vJZBg')
 
let beforeHeight = 100000
 
let secret = base58'BN6RTYGWcwektQfSFzH8raYo9awaLgQ7pLyWLQY4S4F5'
match tx {
  case t: TransferTransaction =>
    let txToBob = t.recipient == Bob && sha256(t.proofs[0]) == secret && 20 + beforeHeight >= height
    let backToAliceAfterHeight = height >= 21 + beforeHeight && t.recipient == Alice
    txToBob || backToAliceAfterHeight
  case _ => false
}

Dalam artikel seterusnya kita akan melihat penggunaan akaun pintar dalam instrumen kewangan seperti opsyen, niaga hadapan dan bil.

Sumber: www.habr.com

Tambah komen