Serlêdanên hesabên jîr ên Waves: ji mezadê heya bernameyên bonus

Serlêdanên hesabên jîr ên Waves: ji mezadê heya bernameyên bonus

Blockchain bi gelemperî tenê bi diravên krîptoyê ve girêdayî ye, lê qadên serîlêdana teknolojiya DLT pir berfirehtir in. Yek ji qadên herî hêvîdar ên ji bo karanîna zincîra blokê peymanek jîr e ku bixweber tê darve kirin û pêbaweriya di navbera aliyên ku ketine wê de hewce nake.

RIDE - zimanek ji bo peymanên jîr

Waves ji bo peymanên zîrek zimanek taybetî pêşxistiye - RIDE. Belgeya wê ya tevahî heye vir. Û li vir - gotara li ser vê mijarê li ser Habr.

Peymana RIDE pêşdarek e û "rast" an "derew" wekî encam vedigere. Li gorî vê yekê, danûstendin an di zincîra blokê de tê tomar kirin an jî tê red kirin. Peymana zîrek bi tevahî pêkanîna mercên diyarkirî garantî dike. Çêkirina danûstendinên ji peymanek li RIDE niha ne gengaz e.

Îro du celeb peymanên jîr ên Waves hene: Hesabên jîr û hebûnên jîr. Hesabek jîr hesabek bikarhênerek birêkûpêk e, lê ji bo wê skrîptek hatî danîn ku hemî danûstendinan kontrol dike. Nivîsarek hesabek jîr dibe ku bi vî rengî xuya bike, mînakî:

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

tx danûstendinek e ku tête pêvajo kirin ku em destûr didin ku mekanîzmaya berhevkirina nimûneyê bikar bînin tenê heke ew ne danûstendinek veguheztinê be. Lihevhatina nimûneyê di RIDE de ji bo kontrolkirina celebê danûstendinê tê bikar anîn. Hemî hesabên heyî dikarin di skrîpta hesabê biaqil de werin hilanîn cureyên danûstandinê.

Nivîsar di heman demê de dikare guherbaran ragihîne, ji bo kontrolkirina şert û mercên bi tevahî avahîyên "eger-paşê-din" û rêbazên din bikar bîne. Ji bo ku pê ewle bibin ku peyman xwedan temambûn û tevliheviya (lêçûn) ya îsbatkirî ne ku pêşbînkirina wê hêsan e berî ku cîbicîkirina peymanê dest pê bike, RIDE tixûb an daxuyaniyên bazdanê nagire.

Taybetmendiyên din ên hesabên Waves hebûna "dewletek", ango rewşa hesabê heye. Hûn dikarin bi karanîna danûstendinên daneyê (DataTransaction) hejmareke bêdawî ya cotan (key, nirx) li rewşa hesabê binivîsin. Dûv re ev agahdarî hem bi navgîniya REST API-yê û hem jî rasterast di peymana hişmend de dikare were hilberandin.

Her danûstendinek dikare komek delîlan hebe, ku tê de îmzeya beşdar, nasnameya danûstendina pêwîst, hwd.

Bi RIDE re dixebitin LI VIR destûrê dide te ku hûn dîmena berhevkirî ya peymanê bibînin (heke ew were berhev kirin), hesabên nû biafirînin û ji bo wê skrîptan saz bikin, û her weha bi riya rêzika fermanê danûstendinan bişînin.

Ji bo çerxek bêkêmasî, di nav de çêkirina hesabek, sazkirina peymanek biaqil li ser wê û şandina danûstendinan, hûn dikarin pirtûkxaneyek ji bo danûstendina bi REST API-yê re jî bikar bînin (mînak, C#, C, Java, JavaScript, Python, Rust, Elixir) . Ji bo ku hûn bi IDE-ê re dest bi xebatê bikin, tenê bişkoja NÛ bikirtînin.

Derfetên ji bo karanîna peymanên jîr berfireh in: ji qedexekirina danûstendinan bigire heya hin navnîşanan ("lîsteya reş") heya dAppên tevlihev.

Naha em li mînakên taybetî yên karanîna girêbestên biaqil di karsaziyê de binihêrin: dema ku mezad, bîme, û afirandina bernameyên dilsoziyê pêk tînin.

Auctions

Yek ji şertên mezadek serketî şefafiyet e: Divê beşdar pê pê bawer bin ku ne mimkun e ku meriv pêşnumayan manîpule bike. Ev dikare bi saya zincîra blokê were bidestxistin, ku daneyên neguhêrbar ên derbarê hemî behîs û dema ku ew hatine çêkirin dê ji hemî beşdaran re peyda bibin.

Li ser zincîra blokê ya Waves, bi navgîniya DataTransaction de pêşnûma dikarin di rewşa hesabê mezadê de bêne tomar kirin.

Her weha hûn dikarin dema destpêk û dawiya mezadê bi karanîna hejmarên blokê destnîşan bikin: Frekansa hilberîna blokê di zincîra bloka Waves de bi qasî hev e. 60 seconds.

1. Mezadê bihayê bihayê Englishngilîzî

Beşdarên di mezadeke Îngilîzî de bi hev re pêşbaziyê dikin. Divê her behîsa nû ji ya berê zêdetir be. Mezad diqede dema ku ji pêşnumaya paşîn zêdetir îtiraz nebin. Di vê rewşê de, pêdivî ye ku pêşkêşvanê herî bilind mîqdara diyarkirî peyda bike.

Di heman demê de vebijarkek mezadê jî heye ku tê de firoşkar bihayek hindiktirîn a lotikê destnîşan dike, û pêdivî ye ku nirxa dawî jê derbas bibe. Wekî din, pir nayê firotin.

Di vê nimûneyê de, em bi hesabek ku bi taybetî ji bo mezadê hatî afirandin re dixebitin. Demjimêra mezadê 3000 blok e, û bihayê destpêkê yê lotikê 0,001 WAVES e. Beşdarek dikare bi şandina DataTransaction bi mifteya "bihayê" û nirxa pêşnumaya xwe re pêşnumayek bide.

Bihayê pêşnumaya nû divê ji bihaya niha ya vê mifteyê bilindtir be, û divê beşdar di hesabê xwe de bi kêmî ve nîşaneyên [new_bid + komîsyon] hebin. Navnîşana pêşkêşker divê di qada "rêker" ya DataTransaction de were tomar kirin, û bilindahiya bloka pêşniyarê ya heyî divê di heyama mezadê de be.

Ger di dawiya mezadê de beşdaran bihayê herî bilind destnîşan kiribe, ew dikare ExchangeTransaction bişîne da ku ji bo lotika têkildar bi bihayê diyarkirî û cotê diravê bide.

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. Mezada Hollandî ya kêmbûna bihayên

Di mezadeke Holandî de, di destpêkê de gelek bi bihayek ji ya ku kiryar amade ye ku bide tê pêşkêş kirin. Biha gav bi gav kêm dibe heya ku yek ji beşdaran razî bibe ku pir bi bihayê heyî bikire.

Di vê nimûneyê de em heman sabitan wekî ya berê bikar tînin, û hem jî gava ku delta kêm dibe gavê bihayê bikar tînin. Skrîpta hesabê kontrol dike ka beşdar bi rastî yê yekem e ku behîsekê dide. Wekî din, DataTransaction ji hêla blokê ve nayê pejirandin.

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. Mezad "hemû-pay"

"Hemû-pay" mezadek e ku tê de hemî beşdar bexşeyê didin, bêyî ku kî lotikê bi dest bixe. Her beşdarekî nû bidekê dide, û beşdarê ku herî zêde teklîfê dike lotikê qezenc dike.

Di mînaka me de, her beşdarê mezadê bi navgîniya DataTransactionê bi (kilît, nirx)* = ("serketî", navnîşan), ("biha", biha) pêşniyarek dide. Danûstandinek wusa tenê tê pejirandin heke ev beşdar jixwe bi îmzeya xwe TransferTransactionek hebe û bihaya wî ji hemî yên berê bilindtir be. Mezad heta gihîştina dawiya Height berdewam dike.

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

Sîgorte / Crowdfunding

Ka em rewşek bifikirin ku hûn hewce ne ku malên bikarhêneran li hember zirarên darayî sîgorte bikin. Mînakî, bikarhênerek garantiyek dixwaze ku heke nîşanek kêm bibe, ew ê bikaribe tevahî mîqdara ku ji bo van tokenan hatî dayîn vegere, û amade ye ku mîqdarek maqûl ya bîmeyê bide.

Ji bo pêkanîna vê yekê, pêdivî ye ku "nîşanên bîmeyê" bêne derxistin. Dûv re skrîptek li ser hesabê xwedan polîtîkayê tê saz kirin, ku destûrê dide ku tenê ew ExchangeTransactions ku hin mercan bicîh tînin werin darve kirin.

Ji bo pêşîgirtina lêçûnên ducar, hûn hewce ne ku ji bikarhêner daxwaz bikin ku berê bi (key, nirx) = (purchaseTransactionId, sellOrderId) DataTransactionê bişîne hesabê xwedan polîtîkayê û şandina DataTransactionan bi mifteyek ku berê hatî bikar anîn qedexe bike.

Ji ber vê yekê, delîlên bikarhêner divê nasnameya danûstendinê ya kirîna nîşana bîmeyê hebe. Divê cotê diravê wekî di kirîna kirînê de be. Pêdivî ye ku lêçûn jî bi ya ku di dema kirînê de hatî sabît kirin, ji bihayê bîmeyê wekhev be.

Tê fêm kirin ku paşê hesabê sîgorteyê nîşaneyên bîmeyê ji bikarhêner bi bihayek ne kêmtir ji ya ku wî kirî dikire: hesabê sîgorteyê ExchangeTransaction diafirîne, bikarhêner fermanê îmze dike (heke danûstendin rast were qedandin), Hesabê sîgorteyê fermana duyemîn û tevahiya danûstendinê îmze dike û ji blokê re dişîne.

Heke kirîn çênebe, bikarhêner dikare li gorî qaîdeyên ku di skrîptê de têne diyar kirin ExchangeTransaction biafirîne û danûstendinê bişîne zincîra blokê. Bi vî rengî bikarhêner dikare pereyên ku li ser kirîna nîşaneyên bîmekirî hatine xerckirin vegerîne.

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

Nîşanek sîgorteyê dikare bibe sermayek jîr, mînakî, ku veguheztina wê ji aliyên sêyemîn re qedexe bike.

Di heman demê de ev plan dikare ji bo tokenên elaletê jî were sepandin, ku heke mîqdara pêwîst nehatibe berhev kirin ji xwedan re têne vegerandin.

Bacê Transaction

Peymanên biaqil di heman demê de di rewşên ku pêdivî ye ku li ser her danûstendinê bi çend cûrbecûr malûmanan re bac were berhev kirin jî tê sepandin. Ev dikare bi navgînek nû ya ku hatî saz kirin were kirin sponsorgeriyê ji bo danûstandinên bi hebûnên jîr:

1. Em FeeCoin diweşînin, ku dê bi bihayek sabit ji bikarhêneran re were şandin: 0,01 WAVES = 0,001 FeeCoin.

2. Ji bo FeeCoin û rêjeya danûstendinê sponsorgeriyê saz bikin: 0,001 WAVES = 0,001 FeeCoin.

3. Skrîpta jêrîn ji bo sermayeya zîrek saz bikin:

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
}

Naha her gava ku kesek N hebûnên jîr vediguhezîne, ew ê bi mîqdara N/taxDivisor (ku dikare ji we bi 10 *N/taxDivisor WAVES were kirîn) FeeCoin bide we, û hûn ê bidin miner N/taxDivisor WAVES. Wekî encamek, qezenca we (bac) dê bibe 9*N / taxDivisor WAVES.

Her weha hûn dikarin bacê bi karanîna skrîptek sermayeya hişmend û MassTransferTransaction bikar bînin:

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 û bernameyên dilsoziyê

Cashback celebek bernameyek dilsoziyê ye ku tê de kiryar beşek ji dravê ku li ser hilberek an karûbarek hatî xerckirin vedigere.

Dema ku vê dozê bi karanîna hesabek jîr bikar tînin, divê em delîlan bi heman awayê ku me di doza sîgorteyê de kir kontrol bikin. Ji bo pêşîgirtina lêçûnên ducar, divê bikarhêner berî wergirtina cashback bi (key, nirx) = (purchaseTransactionId, cashbackTransactionId) DataTransaction bişîne.

Her weha divê em bi karanîna DataTransaction-ê li ser mifteyên heyî jî qedexeyek saz bikin. cashbackDivisor - yekîneya ku bi parvekirina cashback ve hatî dabeş kirin. Ewan. heke para dravê 0.1 be, wê hingê 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)
}

Veguherîna atomî

Veguheztina atomî destûrê dide bikarhêneran ku bêyî alîkariya danûstendinê malûmilkan biguhezînin. Bi veguheztina atomî re, her du beşdarên danûstendinê hewce ne ku wê di demek diyarkirî de piştrast bikin.

Ger bi kêmanî yek ji beşdaran di dema ku ji bo danûstendinê ve hatî veqetandin de piştrastkirina rast a danûstendinê peyda neke, danûstendin tê betal kirin û danûstendin pêk nayê.

Di mînaka xwe de, em ê skrîpta hesabê aqilmend a jêrîn bikar bînin:

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
}

Di gotara pêş de em ê li karanîna hesabên jîr ên di amûrên darayî yên wekî vebijark, pêşeroj û fatûreyan de binêrin.

Source: www.habr.com

Add a comment