Aplikasi akun pinter Waves: ti lelang ka program bonus

Aplikasi akun pinter Waves: ti lelang ka program bonus

Blockchain sering dikaitkeun ukur sareng mata uang kripto, tapi daérah aplikasi téknologi DLT langkung lega. Salah sahiji daérah anu paling ngajangjikeun pikeun panggunaan blockchain nyaéta kontrak pinter anu dieksekusi sacara otomatis sareng henteu meryogikeun kapercayaan antara pihak-pihak anu asup kana éta.

RIDE - basa pikeun kontrak pinter

Gelombang parantos ngembangkeun basa khusus pikeun kontrak pinter - RIDE. Dokuméntasi lengkepna aya di dieu. Sareng di dieu- artikel dina topik ieu dina Habr.

Kontrak RIDE mangrupikeun predikat sareng mulihkeun "leres" atanapi "palsu" salaku kaluaran. Sasuai, urus boh kacatet dina blockchain atawa ditolak. Kontrak pinter pinuh ngajamin minuhan kaayaan nu tangtu. Ngahasilkeun transaksi tina kontrak di RIDE ayeuna teu mungkin.

Kiwari aya dua jinis kontrak pinter Waves: akun pinter sareng aset pinter. Akun pinter mangrupikeun akun pangguna biasa, tapi naskah diatur pikeun éta anu ngatur sadaya transaksi. Skrip akun pinter sigana sapertos kieu, contona:

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

tx mangrupikeun transaksi anu diolah anu kami ngamungkinkeun ngagunakeun mékanisme pola anu cocog ngan upami sanés transaksi transfer. Pola anu cocog dina RIDE dianggo pikeun mariksa jinis transaksi. Sadaya akun anu aya tiasa diolah dina skrip akun pinter jenis transaksi.

Naskah ogé tiasa ngadéklarasikeun variabel, nganggo konstruksi "upami-lajeng-sejenna" sareng metode anu sanés pikeun mariksa kaayaan anu lengkep. Pikeun mastikeun yén kontrak ngagaduhan kasampurnaan sareng pajeulitna (biaya) anu gampang diprediksi sateuacan palaksanaan kontrak dimimitian, RIDE henteu ngandung puteran atanapi pernyataan luncat.

Fitur séjén tina akun Waves kalebet ayana "kaayaan", nyaéta, kaayaan akun. Anjeun tiasa nyerat pasangan anu henteu terbatas (konci, nilai) kana kaayaan akun nganggo transaksi data (DataTransaction). Inpormasi ieu teras tiasa diolah ku REST API sareng langsung dina kontrak pinter.

Unggal urus bisa ngandung hiji Asép Sunandar Sunarya ti proofs, kana nu signature pamilon, ID tina transaksi diperlukeun, jsb bisa diasupkeun.

Gawe sareng RIDE via IEUH ngamungkinkeun anjeun ningali tempoan kontrak anu disusun (upami disusun), nyiptakeun akun énggal sareng nyetél skrip pikeun éta, ogé ngirim transaksi via garis paréntah.

Pikeun siklus pinuh, kaasup nyieun hiji akun, masang kontrak pinter dina eta jeung ngirim transaksi, anjeun ogé tiasa make perpustakaan pikeun interacting jeung REST API (Contona, C #, C, Java, JavaScript, Python, Rust, Elixir). . Pikeun ngamimitian gawé bareng IDE, ngan klik tombol NEW.

Kamungkinan pikeun ngagunakeun kontrak pinter téh lega: ti prohibiting transaksi ka alamat nu tangtu ("daptar hideung") pikeun dApps kompléks.

Ayeuna hayu urang nempo conto husus ngeunaan pamakéan kontrak pinter dina bisnis: nalika ngalakonan auctions, asuransi, sarta nyieun program kasatiaan.

Lelang

Salah sahiji syarat pikeun lelang suksés nyaéta transparansi: pamilon kedah yakin yén mustahil pikeun ngamanipulasi tawaran. Ieu bisa dihontal berkat blockchain, dimana data immutable ngeunaan sagala bets jeung waktu nalika aranjeunna dijieun bakal sadia pikeun sakabéh pamilon.

Dina blockchain Waves, tawaran tiasa dirékam dina kaayaan akun lelang via DataTransaction.

Anjeun ogé tiasa nyetél waktos awal sareng akhir lelang nganggo nomer blok: frékuénsi produksi blok dina Waves blockchain kirang langkung sami sareng 60 detik.

1. lelang harga naek Inggris

Pamilon dina lelang Inggris nempatkeun tawaran dina kompetisi saling. Unggal alungan anyar kudu ngaleuwihan hiji saméméhna. Lelang ditungtungan nalika teu aya deui panawar anu ngaleuwihan tawaran terakhir. Dina hal ieu, bidder pangluhurna kudu nyadiakeun jumlah nyatakeun.

Aya ogé pilihan lélang dimana seller netepkeun harga minimum pikeun lot, sareng harga akhir kedah langkung seueur. Upami teu kitu, loba tetep unsold.

Dina conto ieu, urang damel sareng akun anu didamel khusus pikeun lelang. Durasi lelang nyaéta 3000 blok, sareng harga awal tempatna nyaéta 0,001 GELOMBANG. Pamilon tiasa nempatkeun tawaran ku ngirim DataTransaction kalayan konci "harga" sareng nilai tawaran na.

Harga nawar anyar kudu leuwih luhur ti harga ayeuna keur konci ieu, sarta pamilon kudu boga sahanteuna [new_bid + komisi] tokens dina akun na. Alamat panawar kedah dirékam dina widang "pangirim" dina DataTransaction, sareng jangkungna blok nawar ayeuna kedah aya dina waktos lelang.

Lamun dina ahir lelang pamilon geus diatur harga pangluhurna, manéhna bisa ngirim hiji ExchangeTransaction mayar loba pakait dina harga nu tangtu jeung pasangan mata uang.

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. lelang Walanda turunna harga

Dina lélang Walanda, seueur anu mimitina ditawarkeun dina harga anu langkung luhur tibatan anu badé dibayar ku pembeli. Harga turun step by step nepi ka salah sahiji pamilon satuju meuli lot dina harga ayeuna.

Dina conto ieu kami nganggo konstanta anu sami sareng anu sateuacana, ogé léngkah harga nalika délta turun. Skrip akun mariksa naha pamilon memang anu mimiti nempatkeun taruhan. Upami teu kitu, DataTransaction henteu ditarima ku 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. Lelang "sadayana bayar"

"Sadaya-mayar" mangrupa lelang nu sakabeh pamilon mayar nawar, paduli saha nu meunang pisan. Unggal pamilon anyar mayar tawaran a, sarta pamilon anu ngajadikeun tawaran maksimum meunang pisan.

Dina conto urang, unggal pamilon lelang nempatkeun nawar via DataTransaction kalawan (konci, nilai) * = ("meunangna", alamat), ("harga", harga). DataTransaction sapertos ieu disatujuan ngan upami pamilon ieu parantos gaduh TransferTransaction sareng tandatanganana sareng tawaran na langkung luhur tibatan sadayana sateuacana. Lelang terus dugi endHeight ngahontal.

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

Asuransi / Crowdfunding

Hayu urang nganggap kaayaan dimana anjeun kedah nanggungkeun ka kantor asuransi aset pamaké ngalawan karugian finansial. Contona, hiji pamaké hayang jaminan yén lamun token a depreciates, anjeunna bakal bisa meunangkeun deui jumlah pinuh dibayar pikeun tokens ieu, sarta daék mayar jumlah lumrah asuransi.

Pikeun ngalaksanakeun ieu, "token asuransi" kedah dikaluarkeun. Lajeng skrip dipasang dina akun nu boga kawijakan, sahingga ngan maranéhanana ExchangeTransactions nu minuhan kaayaan nu tangtu bisa dieksekusi.

Pikeun nyegah belanja ganda, Anjeun kudu menta pamaké pikeun ngirim DataTransaction ka akun nu policyholder sateuacanna kalawan (konci, nilai) = (purchaseTransactionId, sellOrderId) jeung nyaram ngirim DataTransactions ku konci nu geus dipaké.

Ku alatan éta, proofs pamaké kudu ngandung ID urus tina meuli token asuransi. Pasangan mata uang kedah sami sareng dina transaksi pameseran. Biaya ogé kedah sami sareng anu tetep dina waktos ngagaleuh, dikurangan harga asuransi.

Hal ieu dipikaharti yén salajengna akun asuransi mundut token asuransi ti pamaké kalawan harga teu leuwih handap hiji di mana anjeunna dibeuli aranjeunna: akun asuransi nyieun ExchangeTransaction, pamaké nandatanganan pesenan (lamun urus geus réngsé leres), nu akun asuransi nandatanganan urutan kadua jeung sakabéh transaksi sarta ngirimkeun ka blockchain nu.

Upami teu aya pameseran, pangguna tiasa nyiptakeun ExchangeTransaction numutkeun aturan anu dijelaskeun dina naskah sareng ngirim transaksi ka blockchain. Ku cara kieu pamaké bisa balik duit spent dina meuli tokens insured.

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 asuransi tiasa janten aset pinter, contona, pikeun ngalarang transferna ka pihak katilu.

skéma ieu ogé bisa dilaksanakeun pikeun tokens crowdfunding, nu balik ka nu boga lamun jumlah diperlukeun teu acan dikumpulkeun.

Pajeg transaksi

Kontrak pinter ogé lumaku dina kasus dimana perlu pikeun ngumpulkeun pajeg dina unggal transaksi jeung sababaraha jenis aset. Ieu bisa dilakukeun ngaliwatan asset anyar kalawan dipasang sponsor pikeun transaksi sareng aset pinter:

1. Urang ngaluarkeun FeeCoin, nu bakal dikirim ka pamaké kalawan harga tetep: 0,01 GELOMBANG = 0,001 FeeCoin.

2. Atur sponsor pikeun FeeCoin sarta Nilai tukeur: 0,001 WAVES = 0,001 FeeCoin.

3. Setel skrip di handap pikeun aset pinter:

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
}

Ayeuna unggal waktos batur mindahkeun N aset pinter, aranjeunna bakal masihan anjeun FeeCoin dina jumlah N / taxDivisor (anu bisa dibeuli ti anjeun dina 10 * N / taxDivisor GELOMBANG), sarta anjeun bakal masihan panambang N / taxDivisor GELOMBANG. Hasilna, kauntungan (pajeg) anjeun bakal jadi 9*N / taxDivisor WAVES.

Anjeun ogé tiasa ngalaksanakeun perpajakan nganggo skrip aset pinter sareng 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
}

Cashback sarta program kasatiaan

Cashback mangrupakeun tipe program kasatiaan nu meuli meunang deui bagian tina jumlah spent dina produk atawa jasa.

Nalika ngalaksanakeun kasus ieu nganggo akun pinter, urang kedah pariksa buktina dina cara anu sami sareng anu urang lakukeun dina kasus asuransi. Pikeun nyegah belanja ganda, pamaké kudu ngirim DataTransaction kalawan (konci, nilai) = (purchaseTransactionId, cashbackTransactionId) saméméh narima cashback.

Urang ogé kedah nyetél larangan dina konci anu aya nganggo DataTransaction. cashbackDivisor - Unit dibagi ku pangsa cashback. Jelema. lamun pangsa cashback nyaeta 0.1, mangka 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)
}

Swap atom

Swap atom ngamungkinkeun pamaké pikeun tukeur aset tanpa bantuan bursa. Kalayan swap atom, duanana pamilon dina transaksi diwajibkeun pikeun ngonfirmasi dina jangka waktu anu tangtu.

Lamun sahenteuna salah sahiji pamilon teu nyadiakeun konfirmasi bener tina urus dina waktu allotted pikeun urus, urus dibatalkeun jeung bursa teu lumangsung.

Dina conto urang, urang bakal nganggo skrip akun pinter ieu:

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
}

Dina artikel salajengna urang bakal kasampak di pamakéan rekening pinter dina instrumen finansial kayaning pilihan, futures jeung tagihan.

sumber: www.habr.com

Tambahkeun komentar