Feidhmchláir chliste Waves: ó cheantanna go cláir bónais

Feidhmchláir chliste Waves: ó cheantanna go cláir bónais

Is minic nach mbaineann Blockchain ach le cryptocurrencies, ach tá réimsí cur i bhfeidhm na teicneolaíochta DLT i bhfad níos leithne. Is é ceann de na réimsí is geallta maidir le húsáid blockchain ná conradh cliste a fhorghníomhaítear go huathoibríoch agus nach dteastaíonn muinín idir na páirtithe a chuaigh isteach ann.

RIDE - teanga le haghaidh conarthaí cliste

Tá teanga speisialta forbartha ag Waves le haghaidh conarthaí cliste - RIDE. Tá a cháipéisíocht iomlán le fáil anseo. Agus anseo - alt ar an ábhar seo ar Habr.

Is tuar é an conradh RIDE agus filleann sé “fíor” nó “bréagach” mar aschur. Dá réir sin, déantar an t-idirbheart a thaifeadadh sa blockchain nó a dhiúltú. Ráthaíonn an conradh cliste go hiomlán comhlíonadh na gcoinníollacha sonraithe. Ní féidir idirbhearta a ghiniúint ó chonradh in RIDE faoi láthair.

Sa lá atá inniu ann tá dhá chineál conarthaí cliste Waves: cuntais chliste agus sócmhainní cliste. Is cuntas úsáideora rialta é cuntas cliste, ach socraítear script dó a rialaíonn gach idirbheart. Seans go mbeidh cuma mar seo ar script chuntais chliste, mar shampla:

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

Is idirbheart é tx atá á phróiseáil a cheadaíonn dúinn an mheicníocht meaitseála patrún a úsáid ach amháin mura idirbheart aistrithe é. Úsáidtear meaitseáil patrún in RIDE chun an cineál idirbhirt a sheiceáil. Is féidir na cuntais go léir atá ann cheana a phróiseáil i script an chuntais chliste cineálacha idirbheart.

Is féidir leis an script athróga a dhearbhú freisin, úsáid a bhaint as tógálacha “más rud é ansin” agus modhanna eile chun coinníollacha a sheiceáil go hiomlán. Chun a chinntiú go bhfuil iomláine agus castacht (costas) inchruthaithe ag conarthaí atá éasca a thuar sula gcuirtear tús le forghníomhú an chonartha, níl lúba ná ráitis léime ag RIDE.

Áirítear le gnéithe eile de chuntais Waves láithreacht “stát,” is é sin, staid an chuntais. Is féidir leat líon gan teorainn na bpéirí (eochair, luach) a scríobh chuig an stát cuntais ag baint úsáide as idirbhearta sonraí (DataTransaction). Is féidir an fhaisnéis seo a phróiseáil ansin tríd an API REST agus go díreach sa chonradh cliste.

Is féidir raon cruthúnais a bheith i ngach idirbheart, inar féidir síniú an rannpháirtí, ID an idirbhirt riachtanach, etc. a chur isteach.

Ag obair le RIDE via IDE ligeann duit an dearcadh tiomsaithe den chonradh a fheiceáil (má chuirtear le chéile é), cuntais nua a chruthú agus scripteanna a shocrú dó, chomh maith le hidirbhearta a sheoladh tríd an líne ordaithe.

Ar feadh timthriall iomlán, lena n-áirítear cuntas a chruthú, conradh cliste a shuiteáil air agus idirbhearta a sheoladh, is féidir leat leabharlann a úsáid freisin chun idirghníomhú leis an REST API (mar shampla, C #, C, Java, JavaScript, Python, Rust, Elixir) . Chun tosú ag obair leis an IDE, níl le déanamh ach cliceáil ar an gcnaipe NUA.

Is leathan na féidearthachtaí maidir le conarthaí cliste a úsáid: ó idirbhearta a thoirmeasc chuig seoltaí áirithe (“liosta dubh”) go dApps casta.

Breathnaímid anois ar shamplaí sonracha d’úsáid conarthaí cliste i ngnó: nuair a bhíonn ceantanna, árachas agus cruthú cláir dílseachta á ndéanamh againn.

Ceantanna

Ceann de na coinníollacha le haghaidh ceant rathúil ná trédhearcacht: ní mór do rannpháirtithe a bheith muiníneach go bhfuil sé dodhéanta tairiscintí a ionramháil. Is féidir é seo a bhaint amach a bhuíochas leis an blockchain, áit a mbeidh sonraí domhalartaithe faoi na geallta go léir agus an t-am ar cuireadh iad ar fáil do na rannpháirtithe go léir.

Ar blockchain Waves, is féidir tairiscintí a thaifeadadh i stát an chuntais ceant trí DataTransaction.

Is féidir leat amanna tosaigh agus deiridh an cheant a shocrú freisin trí úsáid a bhaint as blocuimhreacha: tá minicíocht giniúna bloc i blockchain Waves thart ar cóimhéid le 60 soicind.

1. Ceant praghas ardaitheach Béarla

Cuireann rannpháirtithe i gceant Béarla tairiscintí i gcomórtas lena chéile. Ní mór do gach geall nua níos mó ná an ceann roimhe sin. Críochnaíonn an ceant nuair nach mbíonn níos mó tairgeoirí ann le dul thar an tairiscint dheireanach. Sa chás seo, ní mór don tairgeoir is airde an méid sonraithe a sholáthar.

Tá rogha ceant ann freisin ina leagann an díoltóir praghas íosta don chrannchur, agus caithfidh an praghas deiridh a bheith níos mó ná é. Seachas sin, tá an luchtóg gan díol.

Sa sampla seo, táimid ag obair le cuntas a cruthaíodh go sonrach don cheant. Is é fad an cheant ná 3000 bloic, agus is é 0,001 WAVES an praghas tosaigh don chrannchur. Is féidir le rannpháirtí tairiscint a dhéanamh trí DataTransaction a sheoladh leis an eochair “phraghas” agus luach a dtairisceana.

Caithfidh praghas an tairiscint nua a bheith níos airde ná an praghas reatha don eochair seo, agus ní mór go mbeadh comharthaí [new_bid + commission] ar a laghad ag an rannpháirtí ina chuntas. Ní mór seoladh an tairgeora a thaifeadadh sa réimse "seoltóir" sa DataTransaction, agus ní mór an airde bloc tairiscint reatha a bheith laistigh den tréimhse ceant.

Más rud é ag deireadh an cheant go bhfuil an praghas is airde socraithe ag an rannpháirtí, is féidir leis ExchangeTransaction a sheoladh chun íoc as an gcrannchur comhfhreagrach ag an bpraghas sonraithe agus an péire airgeadra.

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. Ceant Ísiltír ar phraghsanna laghdaithe

I gceant Ollannach, tairgtear go leor ar dtús ar phraghas níos airde ná an méid atá an ceannaitheoir sásta a íoc. Laghdaítear an praghas céim ar chéim go dtí go n-aontaíonn duine de na rannpháirtithe an crannchur a cheannach ar an bpraghas reatha.

Sa sampla seo úsáidimid na tairisigh chéanna agus a bhí sa cheann roimhe seo, chomh maith leis an gcéim praghais nuair a thagann laghdú ar an deilte. Seiceálann script an chuntais an é an rannpháirtí an chéad duine a chuir geall. Seachas sin, ní ghlacann an blockchain leis an DataTransaction.

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. “uile-íoc” ar ceant

Is ceant é “All-pay” ina n-íocann gach rannpháirtí an tairiscint, is cuma cé a bhuaigh an crannchur. Íocann gach rannpháirtí nua tairiscint, agus is é an rannpháirtí a dhéanann an t-uasthairiscint a bhuaigh an crannchur.

Inár sampla, cuireann gach rannpháirtí ceant tairiscint trí DataTransaction le (eochair, luach) * = (“buaiteoir”, seoladh), (“praghas”, praghas). Ní cheadaítear a leithéid de DataTransaction ach amháin má tá TransferTransaction ag an rannpháirtí seo cheana féin lena shíniú agus go bhfuil a thairiscint níos airde ná gach ceann roimhe seo. Leanann an ceant ar aghaidh go dtí go sroichtear endHeight.

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

Árachas / Sluaite

Déanaimis machnamh ar chás ina gcaithfidh tú sócmhainní úsáideoirí a árachú i gcoinne caillteanas airgeadais. Mar shampla, tá ráthaíocht ag teastáil ó úsáideoir má dhéantar dímheas ar chomhartha, go mbeidh sé in ann an méid iomlán a íocadh as na comharthaí seo a fháil ar ais, agus go bhfuil sé sásta méid réasúnta árachais a íoc.

Chun é seo a chur i bhfeidhm, ní mór “comharthaí árachais” a eisiúint. Ansin cuirtear script isteach ar chuntas an tsealbhóra polasaí, rud a fhágann nach féidir ach na hIdirbhearta Malairte sin a chomhlíonann coinníollacha áirithe a fhorghníomhú.

Chun caiteachas dúbailte a chosc, ní mór duit iarraidh ar an úsáideoir DataTransaction a sheoladh chuig cuntas an tsealbhóra polasaí roimh ré le (eochair, luach) = (purchaseTransactionId, sellOrderId) agus toirmeasc a chur ar DataTransaction a sheoladh le heochair a úsáideadh cheana féin.

Mar sin, ní mór aitheantas idirbhirt an cheannaigh dearbháin árachais a bheith i gcruthúnais an úsáideora. Caithfidh an péire airgeadra a bheith mar an gcéanna leis an idirbheart ceannaigh. Caithfidh an costas a bheith comhionann leis an gcostas a socraíodh tráth an cheannaigh, lúide praghas an árachais.

Tuigtear go gceannaíonn an cuntas árachais ina dhiaidh sin comharthaí árachais ón úsáideoir ar phraghas nach ísle ná an ceann ar cheannaigh sé iad: cruthaíonn an cuntas árachais ExchangeTransaction, síníonn an t-úsáideoir an t-ordú (má chríochnaítear an t-idirbheart i gceart), an síníonn cuntas árachais an dara hordú agus an t-idirbheart iomlán agus seolann chuig an blockchain é.

Mura dtarlaíonn aon cheannach, is féidir leis an úsáideoir ExchangeTransaction a chruthú de réir na rialacha a thuairiscítear sa script agus an t-idirbheart a sheoladh chuig an blockchain. Ar an mbealach seo is féidir leis an úsáideoir an t-airgead a chaitear ar chomharthaí árachaithe a cheannach a thabhairt ar ais.

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

Is féidir sócmhainn chliste a dhéanamh de chomhartha árachais, mar shampla, chun a aistriú chuig tríú páirtithe a thoirmeasc.

Is féidir an scéim seo a chur i bhfeidhm freisin le haghaidh comharthaí crowdfunding, a chuirtear ar ais chuig na húinéirí mura bhfuil an méid riachtanach bailithe.

Cánacha idirbhirt

Tá conarthaí cliste infheidhme freisin i gcásanna inar gá cáin a bhailiú ar gach idirbheart le roinnt cineálacha sócmhainní. Is féidir é seo a dhéanamh trí shócmhainn nua le suiteáilte urraíocht le haghaidh idirbhearta le sócmhainní cliste:

1. Eisímid FeeCoin, a sheolfar chuig úsáideoirí ar phraghas seasta: 0,01 WAVES = 0,001 FeeCoin.

2. Socraigh urraíocht do FeeCoin agus ráta malairte: 0,001 WAVES = 0,001 FeeCoin.

3. Socraigh an script seo a leanas don tsócmhainn chliste:

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
}

Anois, gach uair a aistríonn duine N sócmhainní cliste, tabharfaidh siad FeeCoin duit sa mhéid N/Tonntóir Cánach (is féidir a cheannach uait ag 10 *N/Tonn Roinnte cánach), agus tabharfaidh tú N/Tonnta an Rannpháirtí cánach don mhianadóir. Mar thoradh air sin, beidh do bhrabús (cáin) cothrom le 9*N / taxDivisor WAVES.

Is féidir leat cánachas a dhéanamh freisin trí úsáid a bhaint as script chliste sócmhainne agus 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
}

Cláir airgead ar ais agus dílseacht

Is cineál cláir dílseachta é Cashback ina bhfaigheann an ceannaitheoir cuid den mhéid a chaitear ar tháirge nó ar sheirbhís ar ais.

Agus an cás seo á chur i bhfeidhm ag baint úsáide as cuntas cliste, ní mór dúinn na cruthúnais a sheiceáil ar an mbealach céanna agus a rinneamar sa chás árachais. Chun caiteachas dúbailte a chosc, ní mór don úsáideoir DataTransaction a sheoladh le (eochair, luach) = (purchaseTransactionId, cashbackTransactionId) sula bhfaighidh sé aisíocaíocht.

Ní mór dúinn freisin cosc ​​a chur ar eochracha atá ann cheana féin ag baint úsáide as DataTransaction. cashbackDivisor - aonad roinnte ar an sciar cashback. Iad siúd. más é 0.1 an sciar aisíocaíochta, ansin 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)
}

Babhtáil adamhach

Ligeann babhtáil adamhach d’úsáideoirí sócmhainní a mhalartú gan cabhair ó mhalartú. Le babhtáil adamhach, ceanglaítear ar an dá rannpháirtí san idirbheart é a dhearbhú laistigh de thréimhse áirithe ama.

Mura dtugann ar a laghad duine amháin de na rannpháirtithe deimhniú ceart ar an idirbheart laistigh den am a leithroinneadh don idirbheart, cuirtear an t-idirbheart ar ceal agus ní tharlaíonn an malartú.

Inár sampla, úsáidfimid an script cuntas cliste seo a leanas:

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
}

Sa chéad alt eile féachfaimid ar úsáid na gcuntas cliste in ionstraimí airgeadais amhail roghanna, todhchaíochtaí agus billí.

Foinse: will.com

Add a comment