Sekarang kita akan melihat aset pintar dan beberapa kes penggunaannya, termasuk membekukan aset dan membuat sekatan ke atas urus niaga di alamat yang ditentukan.
Aset Pintar Waves membenarkan pengguna menindih skrip pada aset, mengikut mekanik yang sama seperti Akaun Pintar. Setiap urus niaga baharu yang dibuat menggunakan aset pintar akan disahkan terlebih dahulu oleh skrip, dan kemudian oleh blockchain.
Perlu diperhatikan perbezaan berikut antara aset pintar dan akaun pintar:
Dalam kod aset pintar, adalah mustahil untuk menyemak bukti (kami bercakap tentangnya dalam artikel pertama).
Dalam kod akaun pintar, anda boleh menyemak ExchangeTransaction hanya jika akaun anda ialah akaun pemadan. Jika tidak, hanya pesanan yang disemak. Dalam kod aset pintar, anda tidak boleh menyemak pesanan secara langsung; anda boleh menyemak ExchangeTransaction dan, jika perlu, dapatkan semula pesanan daripadanya.
Aset pintar, tidak seperti akaun pintar, tidak mempunyai keadaan, tetapi kami masih mempunyai akses kepada keadaan akaun daripada skrip.
Aset pintar sangat memudahkan penulisan kontrak, menjadikan pelaksanaan banyak kes ringkas dan elegan.
Pembekuan aset
Untuk membekukan aset pada ketinggian blok tertentu targetHeight, anda hanya boleh menetapkan nilai ini dalam skrip aset pintar berikut:
let targetHeight = 1500000
height >= targetHeight
height - функция языка, возращающая текущую высоту.
Keadaan Khusus Pencocok
Untuk menetapkan padanan tertentu sebagai yang diingini, anda boleh menetapkan alamatnya sebagai pengirim dalam skrip aset pintar yang kelihatan seperti ini:
match tx {
case t : ExchangeTransaction =>
t.sender == addressFromString("3PJaDyprvekvPXPuAtxrapacuDJopgJRaU3")
case _ => true
}
"Senarai putih" penerima
Untuk membenarkan token dihantar hanya ke akaun tertentu - untuk membuat "senarai putih" penerima - anda boleh menggunakan aset pintar dengan skim berikut yang menyemak kemasukan dalam senarai:
match tx {
case t : TransferTransaction =>
let trustedRecipient1 = addressFromString("3P6ms9EotRX8JwSrebeTXYVnzpsGCrKWLv4")
let trustedRecipient2 = addressFromString("3PLZcCJyYQnfWfzhKXRA4rteCQC9J1ewf5K")
let trustedRecipient3 = addressFromString("3PHrS6VNPRtUD8MHkfkmELavL8JnGtSq5sx")
t.recipient == trustedRecipient1 || t.recipient == trustedRecipient2 || t.recipient == trustedRecipient3
case _ => false
}
Atas sebab keselamatan dan kesempurnaan bahasa yang boleh dibuktikan, senarai itu tidak mengandungi pelaksanaan iterator. Oleh itu ia ditakrifkan sebagai satu set elemen konkrit.
"Senarai hitam" penerima
Begitu juga, untuk melarang penghantaran token ke akaun tertentu, anda boleh membuat "senarai hitam". Dalam kes ini, aset pintar yang sama digunakan, tetapi dengan alamat disemak untuk memastikan ia tidak berada dalam senarai hitam:
match tx {
case t : TransferTransaction =>
let bannedRecipient1 = addressFromString("3P6ms9EotRX8JwSrebeTXYVnzpsGCrKWLv4")
let bannedRecipient2 = addressFromString("3PLZcCJyYQnfWfzhKXRA4rteCQC9J1ewf5K")
let bannedRecipient3 = addressFromString("3PHrS6VNPRtUD8MHkfkmELavL8JnGtSq5sx")
t.recipient != bannedRecipient1 && t.recipient != bannedRecipient2 && t.recipient != bannedRecipient3
case _ => false
}
Menghantar dengan kebenaran pengeluar
Menggunakan aset pintar, anda juga boleh menetapkan pilihan untuk menghantar aset pintar hanya dengan kebenaran pengeluar (label komitmen/hutang). Pengeluar menyatakan persetujuannya dengan meletakkan ID transaksi dalam keadaan akaunnya:
match tx {
case t : TransferTransaction =>
let issuer = extract(addressFromString("3P6ms9EotRX8JwSrebeTXYVnzpsGCrKWLv4"))
#убеждаемся, что в стейте эмитента содержится ID текущей транзакции
isDefined(getInteger(issuer, toBase58String(t.id)))
case _ => false
}
Tukar hanya untuk syiling tertentu
Aset pintar membenarkan kebenaran untuk menukarnya hanya dengan syiling tertentu. Contohnya, untuk membenarkan pertukaran Bitcoin sahaja, anda boleh menggunakan kod berikut:
let BTCId = base58'8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS'
match tx {
case t : ExchangeTransaction =>
t.sellOrder.assetPair.priceAsset == BTCId ||
t.sellOrder.assetPair.amountAsset == BTCId
case _ => true
}
Berdagang mengikut harga daripada oracle
Dalam skrip aset pintar, anda boleh menetapkan kebenaran untuk berdagang hanya pada harga yang ditetapkan dalam keadaan oracle yang boleh dipercayai. Berikut adalah contoh skrip sedemikian:
let oracle = Address(base58'3PLNmokt22NrSiNvCLvwMUP84LCMJqbXwAD')
let assetId = toBase58String(base58'oWgJN6YGZFtZrV8BWQ1PGktZikgg7jzGmtm16Ktyvjd')
match tx {
#запрещаем передачу ассета
case t: TransferTransaction | MassTransferTransaction => false
case e: ExchangeTransaction =>
#убеждаемся, что торговля происходит по цене, заданной в стейте оракла для этого ассета
let correctPrice = e.price == extract(getInteger(oracle, assetId))
#убеждаемся, что торговля происходит в обмен на WAVES
let correctPriceAsset = !isDefined(e.sellOrder.assetPair.priceAsset)
correctPrice && correctPriceAsset
case _ => true
}
Di sini kita berhadapan dengan titik yang tidak jelas apabila menyemak ID aset yang digunakan untuk perdagangan. Maksudnya ialah jika ID aset tidak ditakrifkan, maka kita bercakap tentang WAVES. Dalam skrip, kami memastikan bahawa perdagangan dijalankan seiring dengan WAVES, dengan cara ini.
Kenaikan harga tetap
Anda boleh menetapkan harga tetap untuk aset pintar, yang akan meningkatkan langkah demi langkah dalam perkadaran tertentu. Berikut ialah contoh skrip aset yang harganya akan meningkat sebanyak 5% setiap 1000 blok:
let startPrice = 10
let startHeight = 1000
let interval = 1000
#на сколько процентов цена увеличивается за один шаг
let raise = 5
match tx {
case t: TransferTransaction | MassTransferTransaction => false
case e: ExchangeTransaction =>
e.price == startPrice + ((height - startHeight) / interval) * (100 + raise) / 100
&& !isDefined(e.sellOrder.assetPair.priceAsset)
case _ => true
}
Perdagangan selang
Selain itu, terima kasih kepada skrip, perdagangan aset pintar boleh dihadkan kepada selang masa yang telah ditetapkan. Berikut adalah contoh skrip sedemikian:
let startHeight = 10000
let interval = 44000
let limit = 1500
match tx {
case t: TransferTransaction | MassTransferTransaction | ExchangeTransaction =>
(height - startHeight) % interval < limit
case _ => true
}
Dalam skrip kami memastikan bahawa dari permulaan perdagangan startHeight tidak lebih daripada menghadkan selang waktu. Panjang selang adalah sama dengan bilangan blok yang dinyatakan dalam medan selang.