Lisebelisoa tsa li-account tse bohlale tsa Waves: ho tloha fantising ho isa mananeong a bonase

Lisebelisoa tsa li-account tse bohlale tsa Waves: ho tloha fantising ho isa mananeong a bonase

Hangata Blockchain e amahanngoa feela le li-cryptocurrensets, empa libaka tsa ts'ebeliso ea theknoloji ea DLT li pharalletse haholo. E 'ngoe ea libaka tse tšepisang ka ho fetisisa bakeng sa tšebeliso ea blockchain ke konteraka e bohlale e etsoang ka boithaopo 'me ha e hloke ho tšepana pakeng tsa lihlopha tse keneng ho eona.

RIDE - puo ea likonteraka tse bohlale

Maqhubu a hlahisitse puo e khethehileng bakeng sa likonteraka tse bohlale - RIDE. Litokomane tsa eona tse felletseng li fumaneha mona. Mme mona - sehlooho se buang ka taba ena ka Habr.

Konteraka ea RIDE ke leetsi mme e khutlisetsa "nete" kapa "false" joalo ka tlhahiso. Ka hona, transaction e ka tlalehoa ho blockchain kapa ea hanoa. Konteraka e bohlale e tiisa ka botlalo phethahatso ea maemo a boletsoeng. Ho hlahisa transactions ho tsoa konteraka ho RIDE ha joale ha ho khonehe.

Kajeno ho na le mefuta e 'meli ea likonteraka tse bohlale tsa Waves: li-account tse bohlale le thepa e bohlale. Ak'haonte e bohlale ke ak'haonte e tloaelehileng ea mosebelisi, empa mongolo o behiloe bakeng sa eona o laolang litšebelisano tsohle. Sengoliloeng sa ak'haonte se bohlale se ka shebahala tjena, mohlala:

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

tx ke transaction e ntseng e sebetsoa eo re e lumellang ho sebelisa mokhoa oa ho bapisa le mohlala ha feela e se transaction. Ho bapisa mohlala ho RIDE ho sebelisoa ho lekola mofuta oa transaction. Liakhaonto tsohle tse seng li ntse li le teng li ka sebetsoa ka har'a script ea ak'haonte e bohlale mefuta ea khoebo.

Script e ka boela ea phatlalatsa mefuta-futa, sebelisa "haeba-e mong" e hahang le mekhoa e meng bakeng sa ho hlahloba maemo ka botlalo. Ho etsa bonnete ba hore likonteraka li na le botlalo le ho rarahana (litšenyehelo) tseo ho leng bonolo ho li tseba pele konteraka e qala, RIDE ha e na loops kapa li- jump statements.

Likarolo tse ling tsa litlaleho tsa Waves li kenyelletsa boteng ba "boemo," ke hore, boemo ba akhaonto. U ka ngola palo e sa lekanyetsoang ea lipara (senotlolo, boleng) ho boemo ba ak'haonte u sebelisa lits'ebetso tsa data (DataTransaction). Lintlha tsena li ka sebetsoa ka bobeli ka REST API le ka kotloloho ho konteraka e bohlale.

Ts'ebetso e 'ngoe le e' ngoe e ka ba le bopaki bo bongata, boo ho ka kenngoa tekenetso ea motho ea nkang karolo, ID ea transaction e hlokahalang, joalo-joalo.

Ho sebetsa le RIDE ka MONA e u lumella ho bona pono e hlophisitsoeng ea konteraka (haeba e hlophisitsoe), etsa li-account tse ncha 'me u behe mangolo bakeng sa eona, hammoho le ho romella litšebelisano ka mohala oa taelo.

Bakeng sa potoloho e felletseng, ho kenyelletsa ho theha ak'haonte, ho kenya konteraka e bohlale ho eona le ho romella litšebelisano, o ka sebelisa laeborari ho sebelisana le REST API (mohlala, C #, C, Java, JavaScript, Python, Rust, Elixir) . Ho qala ho sebetsa ka IDE, tobetsa feela konopo e NCHA.

Monyetla oa ho sebelisa likonteraka tse bohlale o pharaletse: ho tloha ho thibelang litšebelisano ho ea ho liaterese tse itseng ("lethathamo le letšo") ho isa ho li-dApp tse thata.

Joale a re shebeng mehlala e tobileng ea tšebeliso ea likonteraka tse bohlale khoebong: ha ho etsoa lifantisi, inshorense, le ho theha mananeo a botšepehi.

Lifantisi

E 'ngoe ea lipehelo tsa fantisi e atlehileng ke ponaletso: barupeluoa ba tlameha ho ba le ts'epo ea hore ha ho khonehe ho laola litefiso. Sena se ka finyelloa ka lebaka la blockchain, moo data e sa fetoheng mabapi le libethe tsohle le nako eo li entsoeng ka eona li tla fumaneha ho barupeluoa bohle.

Ho Waves blockchain, litefiso li ka tlalehoa sebakeng sa akhaonto ea fantisi ka DataTransaction.

U ka boela ua beha nako ea ho qala le ea ho qetela ea fantisi u sebelisa linomoro tsa li-block: khafetsa ea tlhahiso ea block ho Waves blockchain e batla e lekana le 60 metsotsoana.

1. Fantisi ea theko ea Senyesemane e nyolohang

Barupeluoa ba fantisi ea Senyesemane ba fana ka litefiso ka tlholisano le ba bang. Bete e 'ngoe le e 'ngoe e ncha e tlameha ho feta ea pele. Fantisi e fela ha ho se ho se ho se na batho ba batlang ho feta tefiso ea ho qetela. Tabeng ena, moreki ea phahameng ka ho fetisisa o tlameha ho fana ka chelete e boletsoeng.

Ho boetse ho na le khetho ea fantisi eo morekisi a behang bonyane theko ea lotho, 'me theko ea ho qetela e tlameha ho e feta. Ho seng joalo, lotho e lula e sa rekisoe.

Mohlala ona, re sebetsa ka akhaonto e etselitsoeng fantisi ka ho khetheha. Nako ea fantisi ke li-blocks tse 3000, 'me theko ea ho qala ea lotho ke 0,001 WAVES. Motho ea nkang karolo a ka kenya kopo ka ho romella DataTransaction ka "theko" ea bohlokoa le boleng ba tlhahiso ea bona.

Theko ea tefiso e ncha e tlameha ho ba e phahameng ho feta theko ea hona joale ea senotlolo sena, 'me morupeluoa o tlameha ho ba le bonyane li-tokens tsa [new_bid + commission] akhaonteng ea hae. Aterese ea mofani oa thepa e tlameha ho ngoloa tšimong ea "moromeli" ho DataTransaction, 'me bophahamo ba hona joale ba li-bid block bo tlameha ho ba nakong ea fantisi.

Haeba qetellong ea fantisi morupeluoa a behile theko e phahameng ka ho fetisisa, a ka romela ExchangeTransaction ho lefella lotho e lumellanang ka theko e boletsoeng le chelete ea lichelete.

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. Fantisi ea Dutch ea litheko tse theohang

Fantising ea Madache, qalong ho fanoa ka lintho tse ngata ka theko e phahameng ho feta eo moreki a ikemiselitseng ho e lefa. Theko e fokotsehile mohato ka mohato ho fihlela e mong oa barupeluoa a lumela ho reka lotho ka theko ea hona joale.

Mohlala ona re sebelisa li-constants tse tšoanang le tse fetileng, hammoho le mohato oa theko ha delta e fokotseha. Sengoliloeng sa ak'haonte se hlahloba hore na monkakarolo ke eena oa pele oa ho becha. Ho seng joalo, DataTransaction ha e amoheloe ke 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. Fantisi "ho lefa tsohle"

“Pay-All” ke fantisi eo barupeluoa bohle ba lefang tefiso, ho sa tsotelehe hore na ke mang ea hapang lotho. Motho e mong le e mong e mocha o lefa tefiso, 'me monkakarolo ea etsang tefiso e ngata o tla hapa lotho.

Mohlala oa rona, monkakarolo e mong le e mong oa fantisi o beha tekete ka DataTransaction ka (senotlolo, boleng)* = ("mohlodi", aterese),("theko", theko). DataTransaction e joalo e amoheloa feela haeba morupeluoa enoa a se a ntse a e-na le TransferTransaction ka signature ea hae 'me tlhahiso ea hae e phahame ho feta tsohle tse fetileng. Fantisi e tsoela pele ho fihlela endHeight e fihletsoe.

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

Inshorense / Bongata ba batho

Ha re nahaneng ka boemo boo o hlokang ho netefatsa thepa ea basebelisi khahlano le tahlehelo ea lichelete. Ka mohlala, mosebedisi o batla tiiso ea hore haeba lets'oao le theoha, o tla khona ho khutlisa chelete e feletseng e lefshoang bakeng sa li-tokens tsena, 'me o ikemiselitse ho lefa chelete e lekaneng ea inshorense.

Ho phethahatsa sena, "li-tokens tsa inshorense" li hloka ho ntšoa. Ebe script e kenngoa ho akhaonto ea policyholder, e lumella feela ExchangeTransactions tse finyellang maemo a itseng hore li phethoe.

Ho thibela tšebeliso ea chelete habeli, o hloka ho kopa mosebelisi ho romella DataTransaction ho akhaonto ea mohlokomeli oa pholisi esale pele ka (key, value) = (purchaseTransactionId, sellOrderId) le ho thibela ho romela DataTransactions ka senotlolo se seng se sebelisitsoe.

Ka hona, bopaki ba mosebelisi bo tlameha ho ba le ID ea transaction ea theko ea tokenyo ea inshorense. Lichelete tse peli li tlameha ho tšoana le tsa thekiso ea theko. Litsenyehelo li tlameha ho lekana le tse behiloeng ka nako ea theko, ho tlosoe theko ea inshorense.

Ho utloisisoa hore ka mor'a moo akhaonto ea inshorense e reka li-tokens tsa inshorense ho mosebedisi ka theko e seng tlase ho feta eo a ba rekileng ka eona: akhaonto ea inshorense e theha ExchangeTransaction, mosebedisi o saena taelo (haeba transaction e phethiloe ka nepo), ak'haonte ea inshorense e saena taelo ea bobeli le transaction eohle mme e e romella ho blockchain.

Haeba ho se na theko e hlahang, mosebeletsi a ka etsa ExchangeTransaction ho ea ka melao e hlalositsoeng ho script mme a romela transaction ho blockchain. Ka tsela ena mosebelisi a ka khutlisa chelete e sebelisitsoeng ho reka li-tokens tse nang le inshorense.

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

Letšoao la inshorense le ka etsoa letlotlo le bohlale, ka mohlala, ho thibela ho fetisetsoa ho batho ba boraro.

Morero ona o ka boela oa sebelisoa bakeng sa li-tokens tsa batho ba bangata, tse khutlisetsoang ho beng ba tsona haeba chelete e hlokahalang e sa bokelloa.

Lekhetho la transaction

Likonteraka tse bohlale li boetse li sebetsa maemong ao ho hlokahalang ho bokella lekhetho khoebong ka 'ngoe ka mefuta e mengata ea thepa. Sena se ka etsoa ka thepa e ncha e kentsoeng tšehetso bakeng sa ditransekshene ka thepa e bohlale:

1. Re fana ka FeeCoin, e tla romelloa ho basebelisi ka theko e tsitsitseng: 0,01 WAVES = 0,001 FeeCoin.

2. Beha tšehetso bakeng sa FeeCoin le sekhahla sa phapanyetsano: 0,001 WAVES = 0,001 FeeCoin.

3. Beha mongolo o latelang bakeng sa thepa e bohlale:

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
}

Hona joale nako le nako ha motho a fetisetsa thepa e bohlale ea N, o tla u fa FeeCoin ka chelete ea N/taxDivisor (e ka rekoang ho uena ho 10 * N/taxDivisor WAVES), 'me u tla fa mosebetsi oa morafo N/taxDivisor WAVES. Ka lebaka leo, phaello ea hau (lekhetho) e tla ba 9*N / taxDivisor WAVES.

U ka boela ua etsa lekhetho u sebelisa mongolo o bohlale oa thepa le 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
}

Mananeo a ho khutlisa chelete le botšepehi

Cashback ke mofuta oa lenaneo la botšepehi moo moreki a khutlisang karolo ea chelete e sebelisitsoeng sehlahisoa kapa tšebeletso.

Ha re kenya ts'ebetsong nyeoe ena re sebelisa ak'haonte e bohlale, re tlameha ho hlahloba bopaki ka tsela e tšoanang le eo re entseng nyeoeng ea inshorense. Ho thibela tšebeliso ea chelete habeli, mosebelisi o tlameha ho romela DataTransaction le (key, value) = (purchaseTransactionId, cashbackTransactionId) pele a fumana chelete ea chelete.

Hape re tlameha ho beha thibelo ea linotlolo tse teng ho sebelisa DataTransaction. cashbackDivisor - yuniti e arotsoeng ke karolo ea chelete ea chelete. Tseo. haeba kabelo ea chelete ke 0.1, ebe 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)
}

Phetoho ea atomic

Ho fapanyetsana ha atomic ho lumella basebelisi ho fapanyetsana thepa ntle le thuso ea phapanyetsano. Ka phapanyetsano ea athomo, barupeluoa ka bobeli khoebong ba tlameha ho e netefatsa ka nako e itseng.

Haeba bonyane e mong oa barupeluoa a sa fane ka tiiso e nepahetseng ea transaction ka nako e behiloeng bakeng sa ts'ebetso, ts'ebetso e hlakotsoe 'me phapanyetsano ha e hlahe.

Mohlala oa rona, re tla sebelisa sengoloa se latelang sa ak'haonte e bohlale:

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
}

Sehloohong se latelang re tla sheba tšebeliso ea li-account tse bohlale ho lisebelisoa tsa lichelete tse kang likhetho, bokamoso le likoloto.

Source: www.habr.com

Eketsa ka tlhaloso