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