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