Waves kontu adimendunen aplikazioak: enkanteetatik hasi eta bonus programetara

Waves kontu adimendunen aplikazioak: enkanteetatik hasi eta bonus programetara

Blockchain sarritan kriptografiako monetaekin bakarrik lotzen da, baina DLT teknologiaren aplikazio eremuak askoz zabalagoak dira. Blockchain-en erabilerarako eremu itxaropentsuenetako bat automatikoki gauzatzen den kontratu adimenduna da eta ez du konfiantzarik eskatzen bertan sartu diren alderdien artean.

RIDE – kontratu adimendunen hizkuntza

Waves-ek kontratu adimentsuetarako hizkuntza berezi bat garatu du: RIDE. Bere dokumentazio osoa dago kokatuta Hemen. Eta hemen - gai honi buruzko artikulua on Habr.

RIDE kontratua predikatu bat da eta irteera gisa "egia" edo "gezurra" itzultzen du. Horren arabera, transakzioa bloke-katean erregistratzen da edo baztertzen da. Kontratu adimendunak zehaztutako baldintzak betetzea guztiz bermatzen du. RIDEn kontratu batetik transakzioak sortzea ezinezkoa da gaur egun.

Gaur egun, bi kontratu adimendun mota daude Waves: kontu adimendunak eta aktibo adimendunak. Kontu adimenduna erabiltzaile-kontu arrunta da, baina transakzio guztiak kontrolatzen dituen script bat ezarrita dago. Kontu adimendunaren script-a honelakoa izan daiteke, adibidez:

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

tx prozesatzen ari den transakzio bat da, eta ereduak bat etortzeko mekanismoa erabiltzea onartzen dugu transferentzia transakzio bat ez bada soilik. RIDE-n eredu bat etortzea transakzio mota egiaztatzeko erabiltzen da. Lehendik dauden kontu guztiak kontu adimendunaren scriptean prozesatu daitezke transakzio motak.

Scriptak aldagaiak ere deklara ditzake, "if-then-else" eraikuntzak eta beste metodo batzuk erabil ditzake baldintzak guztiz egiaztatzeko. Kontratuak exekutatzen hasi baino lehen aurreikusteko erraza den osotasuna eta konplexutasuna (kostua) frogagarriak direla ziurtatzeko, RIDEk ez du begiztarik edo jauzi-adierazpenik.

Waves kontuen beste ezaugarri batzuk "egoera" baten presentzia dira, hau da, kontuaren egoera. Bikote kopuru infinitua (gakoa, balioa) idatz dezakezu kontuaren egoeran datu-transakzioak erabiliz (DataTransaction). Ondoren, informazio hori REST APIaren bidez eta zuzenean kontratu adimendunean prozesatu daiteke.

Transakzio bakoitzak froga-sorta bat izan dezake, eta bertan parte-hartzailearen sinadura, beharrezko transakzioaren IDa, etab. sar daitezke.

RIDE bidez lan egiten IDE aukera ematen du kontratuaren ikuspegi konpilatua ikusteko (konpilatuta badago), kontu berriak sortzeko eta horretarako script-ak ezartzeko, baita transakzioak komando-lerroaren bidez bidaltzeko ere.

Ziklo oso baterako, kontu bat sortzea, kontratu adimenduna instalatzea eta transakzioak bidaltzea barne, liburutegi bat ere erabil dezakezu REST APIarekin elkarreragiteko (adibidez, C#, C, Java, JavaScript, Python, Rust, Elixir) . IDEarekin lanean hasteko, egin klik BERRIA botoian.

Kontratu adimendunak erabiltzeko aukerak zabalak dira: transakzioak debekatuz helbide batzuetara (β€œzerrenda beltza”) dApps konplexuetaraino.

Ikus ditzagun orain negozioetan kontratu adimendunen erabileraren adibide zehatzak: enkanteak egitean, aseguruak eta leialtasun programak sortzean.

Enkanteak

Enkante arrakastatsua izateko baldintzetako bat gardentasuna da: parte hartzaileek ziur egon behar dute ezinezkoa dela eskaintzak manipulatzea. Hori blokeo-kateari esker lor daiteke, non apustu guztiei buruzko datu aldaezinak eta egin ziren ordua parte-hartzaile guztien eskura egongo diren.

Waves blockchain-en, eskaintzak enkante-kontuaren egoeran erregistra daitezke DataTransaction bidez.

Enkantearen hasiera eta amaiera ordua ere ezar dezakezu bloke-zenbakiak erabiliz: Waves bloke-katean blokeak sortzeko maiztasuna gutxi gorabehera berdina da. 60 segundoak.

1. Ingelesez goranzko prezioen enkantea

Ingelesezko enkante batean parte hartzen dutenek elkarren artean lehian jartzen dituzte eskaintzak. Apustu berri bakoitzak aurrekoa gainditu behar du. Enkantea amaitzen da azken eskaintza gainditzeko lizitatzaile gehiago ez dagoenean. Kasu horretan, lizitatzaile handienak adierazitako zenbatekoa eman beharko du.

Enkanterako aukera ere badago, saltzaileak lotearen gutxieneko prezioa ezartzen duena, eta azken prezioak hori gainditu behar du. Bestela, lotea saldu gabe geratzen da.

Adibide honetan, enkanterako berariaz sortutako kontu batekin ari gara lanean. Enkantearen iraupena 3000 blokekoa da, eta lotearen hasierako prezioa 0,001 OLATU. Parte-hartzaile batek eskaintza bat egin dezake DataTransaction bat bidaliz "prezioa" gakoarekin eta eskaintzaren balioarekin.

Eskaintza berriaren prezioak gako honen egungo prezioa baino handiagoa izan behar du, eta parte hartzaileak gutxienez [new_bid + komisioa] tokenak izan behar ditu bere kontuan. Lizitatzailearen helbidea DataTransaction-ko "igorlea" eremuan erregistratu behar da, eta egungo eskaintza-blokearen altuerak enkantearen epean egon behar du.

Enkantearen amaieran parte hartzaileak preziorik altuena ezarri badu, TrukeTransaction bat bidal dezake dagokion lotea ordaintzeko zehaztutako prezioan eta moneta-parean.

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. Holandako prezioen enkantea

Holandako enkante batean, hasiera batean lote asko eskaintzen da erosleak ordaintzeko prest dagoena baino prezio altuagoan. Prezioa pausoz pauso murrizten da, parte-hartzaileetako batek lotea egungo prezioan erostea onartzen duen arte.

Adibide honetan aurrekoaren konstante berberak erabiltzen ditugu, baita delta jaisten denean prezioaren urratsa ere. Kontuaren gidoiak egiaztatzen du parte-hartzailea apustua egiten lehena den. Bestela, DataTransaction ez du onartzen bloke-kateak.

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. Enkantea "guztia ordaindu"

"All-pay" parte-hartzaile guztiek eskaintza ordaintzen duten enkante bat da, lotea nork irabazten duen kontuan hartu gabe. Parte-hartzaile berri bakoitzak eskaintza bat ordaintzen du, eta gehieneko eskaintza egiten duen partaideak irabaziko du lotea.

Gure adibidean, enkantean parte-hartzaile bakoitzak DataTransaction bidez eskaintza egiten du (gakoa, balioa)* = ("irabazlea", helbidea), ("prezioa", prezioa). Datu-transakzio hori parte-hartzaile honek transferentzia-transakzio bat badu bere sinadurarekin eta bere eskaintza aurreko guztiak baino handiagoa bada soilik onartzen da. Enkanteak amaierara iritsi arte jarraitzen du.

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

Aseguruak / Crowdfunding

Ikus dezagun erabiltzaileen aktiboak finantza-galeren aurka aseguratu behar dituzun egoera bat. Esate baterako, erabiltzaile batek bermea nahi du token bat amortizatzen bada, token horiengatik ordaindutako kopuru osoa berreskuratu ahal izango duela eta arrazoizko asegurua ordaintzeko prest dagoela.

Hori ezartzeko, "aseguru-token" igorri behar dira. Ondoren, aseguru-hartzailearen kontuan script bat instalatzen da, baldintza jakin batzuk betetzen dituzten ExchangeTransactions soilik exekutatzeko aukera emanez.

Gastu bikoitza saihesteko, erabiltzaileari eskatu behar diozu aldez aurretik DataTransaction bat aseguru-hartzailearen kontura bidaltzeko (gakoa, balioa) = (erosketaTransakzioarenId, salduOrderId) eta debekatu egin behar duzu DataTransactions bidaltzea dagoeneko erabilitako gako batekin.

Beraz, erabiltzailearen frogak aseguru-token erosketaren transakzio IDa izan behar dute. Moneta bikoteak erosketa-transakzioaren berdina izan behar du. Kostua ere erosteko unean finkatutakoaren berdina izan behar da, aseguruaren prezioa kenduta.

Ulertzen da, ondoren, aseguru-kontuak erabiltzaileari aseguru-tokenak erosten dizkiola erosi zuena baino prezio baxuagoan: aseguru-kontuak TrukeTransakzio bat sortzen du, erabiltzaileak eskaera sinatzen du (eragiketa behar bezala egiten bada), aseguru-kontuak bigarren eskaera eta transakzio osoa sinatzen ditu eta blockchain-era bidaltzen du.

Erosketarik gertatzen ez bada, erabiltzaileak ExchangeTransaction bat sor dezake scriptean deskribatutako arauen arabera eta transakzioa bloke-katera bidali. Horrela erabiltzaileak aseguratutako tokenak erosteko gastatutako dirua itzuli ahal izango du.

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

Aseguru-token bat aktibo adimendun bihurtu daiteke, adibidez, hirugarrenei transferitzea debekatzeko.

Eskema hau crowdfunding tokenetarako ere inplementa daiteke, jabeei itzultzen zaizkiela eskatutako zenbatekoa bildu ez bada.

Transakzio zergak

Kontratu adimentsuak ere aplikagarriak dira hainbat aktibo motatako transakzio bakoitzaren zerga biltzea beharrezkoa den kasuetan. Hau instalatuta dagoen aktibo berri baten bidez egin daiteke babesa aktibo adimendunekin egindako transakzioetarako:

1. FeeCoin jaulkitzen dugu, erabiltzaileei prezio finko batean bidaliko zaiena: 0,01 WAVES = 0,001 FeeCoin.

2. Ezarri FeeCoin-en babesa eta truke-tasa: 0,001 WAVES = 0,001 FeeCoin.

3. Ezarri script hau aktibo adimendunerako:

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
}

Orain norbaitek N aktibo adimendunak transferitzen dituen bakoitzean, FeeCoin emango dizu N/taxDivisor-en zenbatekoan (10 *N/taxDivisor WAVES-en eros dezakezu zuregandik), eta meatzariari N/taxDivisor WAVES emango diozu. Ondorioz, zure irabazia (zerga) 9*N / taxDivisor WAVES izango da.

Zergak ere egin ditzakezu aktibo adimendunen script bat eta MassTransferTransaction erabiliz:

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 eta leialtasun programak

Cashback leialtasun-programa mota bat da, non erosleak produktu edo zerbitzu batean gastatutako zenbatekoaren zati bat itzultzen du.

Kasu hau kontu adimendun bat erabiliz ezartzean, frogak egiaztatu behar ditugu aseguru-kasuan egin genuen moduan. Gastu bikoitza saihesteko, erabiltzaileak DataTransaction bat bidali behar du (gakoa, balioa) = (purchaseTransactionId, cashbackTransactionId) cashback jaso aurretik.

DataTransaction erabiliz dauden gakoen debekua ere ezarri behar dugu. cashbackDivisor - unitatea cashback zatiarekin banatuta. Horiek. cashback zatia 0.1 bada, orduan 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)
}

Truke atomikoa

Truke atomikoak erabiltzaileei aktiboak trukatzeko aukera ematen die truke baten laguntzarik gabe. Truke atomiko batekin, transakzioaren parte-hartzaile biek denbora-tarte jakin batean berretsi behar dute.

Parte-hartzaileetako batek gutxienez transakzioaren berrespen zuzena ematen ez badu transakziorako emandako denboran, transakzioa bertan behera utziko da eta trukea ez da gertatzen.

Gure adibidean, kontu adimendunaren script hau erabiliko dugu:

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
}

Hurrengo artikuluan kontu adimendunen erabilera aztertuko dugu finantza-tresnetan, hala nola, aukerak, etorkizunak eta fakturak.

Iturria: www.habr.com

Gehitu iruzkin berria