
Edellisessä Tarkastelimme useita tapauksia älykkäiden tilien käytöstä liiketoiminnassa, mukaan lukien huutokaupat ja kanta-asiakasohjelmat.
Tänään puhumme siitä, kuinka älykkäät tilit ja älykkäät varat voivat parantaa rahoitusinstrumenttien, kuten optioiden, futuurien ja laskujen, läpinäkyvyyttä ja luotettavuutta.
Vaihtoehto
Optio on vaihtosopimus, joka antaa ostajalle oikeuden ostaa omaisuuserän tiettyyn hintaan tai ennen tiettyä päivämäärää, mutta ei velvoita häntä tekemään niin.
Vaihtoehdon toteutus voi olla seuraava:
Käytämme itse optioita varten älykästä omaisuutta instrumenttina ja älytiliä osallistujalle, joka toimii vaihto- ja liikkeeseenlaskijana. Pörssin osallistuja lupaa myydä tietyn määrän tiettyä omaisuutta myyntihinnalla expirationStart ja expirationEnd lohkokorkeuksien välillä).
Smart Asset -koodissa tarkistamme vain, että sillä käydään kauppaa vain määritettyjen korkeuksien välillä, emmekä tarkista mitään muuta, jätämme kaiken vastuun sääntöjen noudattamisesta pörssin osanottajan koodille.
Älykäs omaisuuskoodi:
let expirationStart = 100000
let expirationEnd = 101440
match tx {
case some : ExchangeTransaction | TransferTransaction =>
height > expirationStart && height <= expirationEnd
case _ => false
}
Oletetaan, että toimet tapahtuvat seuraavasti: Pörssin osallistuja myy optioita ostaakseen jonkin omaisuuden, ja muut osallistujat voivat välittää nämä optiot tai käydä niillä kauppaa. Voidakseen käyttää osto-oikeuttaan mahdollisen ostajan on siirrettävä haluttu määrä optioita myyjän eli pörssiin osallistujan tilille. Seuraavaksi hän kirjoittaa tiedot suoritetusta siirrosta pörssin osanottajan valtion tilille, ja vasta sitten ExchangeTransaction voi edetä määritettyjen osto- ja myyntiehtojen mukaisesti.
Älykäs tilikoodissa meidän on varmistettava, että kaikki sen kautta kulkeva ExchangeTransaction oston ja myynnin lopputoimia varten täyttää määritetyt ehdot ja osallistuja ostaa täsmälleen sen määrän yksiköitä, jonka hän lähetti vaihtoon osallistujan tilille. Potentiaalisen ostajan tulee lähettää oikea DataTransaction siirrosta, jotta vaihtoon osallistuja voi välttää kaksinkertaisen kulutuksen. Tässä DataTransactionissa ostaja asettaa osoitettaan vastaavan avaimen mukaan arvon, joka on yhtä suuri kuin pörssin osanottajan tilille siirrettyjen optioiden määrä, eli kuinka monta omaisuusyksikköä hän voi ostaa.
Älykäs tilikoodi:
#владелец аккаунта дает обязательство продать определенное количество юнитов ассета
#по цене sellPrice между высотами блоков expirationStart и expirationEnd
let expirationStart = 100000
let expirationEnd = 101440
let sellPrice = 10000
let amountAsset = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
let priceAsset = base58'9jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
#ID ассета-опциона
let optionsAsset = base58'7jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
#извлекаем из транзакции адрес отправителя
let this = tx.sender
match tx {
case dataTx : DataTransaction =>
#извлекаем количество юнитов из дата-транзакции по ключу (ID пользователя)
let units = extract(getInteger(dataTx.data, dataTx.data[0].key))
#извлекаем трансфер-транзакцию опционов из пруфа
let e = transactionById(dataTx.proofs[2]) #
match e {
case transferTx : TransferTransaction =>
#убеждаемся, что трансфер был на текущий адрес
(transferTx.recipient == this) &&
#убеждаемся, что отправитель транзакции написал в качестве ключа свой ID
dataTx.data[0].key == toBase58String(transferTx.sender.bytes) &&
sigVerify(dataTx.bodyBytes, dataTx.proofs[0], transferTx.senderPublicKey) &&
#убеждаемся, что указанное количество юнитов соответствует посланному количеству опционов
(units == transferTx.amount) &&
#убеждаемся, что был переведен именно ассет-опцион
(transferTx.assetId == optionsAsset)
case _ => false
} &&
size(dataTx.data) == 1 && !isDefined(getInteger(this, dataTx.data[0].key))
&& height > expirationStart && height <= expirationEnd
case exchangeTx : ExchangeTransaction =>
#убеждаемся, что итоговый обмен происходит по указанным заранее правилам
let correctAssetPair = exchangeTx.sellOrder.assetPair.amountAsset == amountAsset &&
exchangeTx.sellOrder.assetPair.priceAsset == priceAsset
let correctPrice = exchangeTx.sellOrder.price == sellPrice
#извлекаем дата-транзакцию из пруфа
let d = transactionById(exchangeTx.proofs[2])
match d{
case dataTx : DataTransaction =>
let buyOrderSender = dataTx.data[0].key
toBase58String(exchangeTx.buyOrder.sender.bytes) == buyOrderSender &&
exchangeTx.amount == extract(getInteger(dataTx.data, buyOrderSender))
case _ => false
} &&
exchangeTx.sellOrder.sender == this &&
correctAssetPair && correctPrice &&
height > expirationStart && height <= expirationEnd
case _ => false
}
Futuurit älytileillä
Toisin kuin optio, futuuri (futuurisopimus) ei ole ostajan oikeus, vaan velvollisuus ostaa omaisuuserä sopimuksessa määrättyyn hintaan jossain vaiheessa tulevaisuudessa.
Yleensä tulevaisuuden kirjoittaminen on samanlaista kuin option kirjoittaminen. Tässä älykäs omaisuus toimii tulevaisuutena.
Sinun on myös varmistettava, että sekä ostaja että myyjä allekirjoittavat ostotilauksen. Tulevaisuus on velvoite, joka on täytettävä joka tapauksessa. Tämä tarkoittaa, että jos myyjä tai osallistuja kieltäytyy velvollisuuksistaan, kuka tahansa verkoston osallistuja voi lähettää tapahtuman ja siten toteuttaa tulevaisuuden.
Älykäs omaisuuskomentosarja ohjaa kaikkia futuuriomaisuuden TransferTransactions- ja ExchangeTransactions-tapahtumia ja hyväksyy ne vain, jos ostajaosapuoli on luonut tilauksen tulevasta futuuriomaisuuden ostosta pörssiosapuolelta.
Tämän toimeksiannon on oltava voimassa ja täytettävä futuurien liikkeeseenlaskuehdot. Vahvistaaksesi tilauksen, voit syöttää kaikki sen kentät ostajan tilin tilaan yhdessä allekirjoitetun tilauksen tavuesityksen kanssa ja suorittaa sitten ulkoisen vahvistuksen.
Tällä hetkellä RIDE ei sisällä natiivitoimintoa tapahtumatavujen jäsentämiseen, mutta sisältää kaikki sen toteuttamiseen tarvittavat työkalut. Siksi kehittäjät voivat yrittää ottaa tämän ominaisuuden käyttöön itse.
Usean allekirjoituksen tili / Escrow
Usean allekirjoituksen tilin avulla useat käyttäjät voivat hallinnoida omaisuutta yhdessä (esimerkiksi omaisuustapahtumat voivat olla mahdollisia vain, jos kolmella neljästä käyttäjästä on allekirjoitukset). Usean allekirjoituksen tilien luomiseen RIDE-kielellä voimme käyttää tapahtumatodistuksia.
Usean allekirjoituksen tiliä voidaan käyttää myös sulkutilinä, jolla säilytetään varoja, kunnes sopimuspuolet täyttävät velvoitteensa.
let alicePubKey = base58'5AzfA9UfpWVYiwFwvdr77k6LWupSTGLb14b24oVdEpMM'
let bobPubKey = base58'2KwU4vzdgPmKyf7q354H9kSyX9NZjNiq4qbnH2wi2VDF'
let cooperPubKey = base58'GbrUeGaBfmyFJjSQb9Z8uTCej5GzjXfRDVGJGrmgt5cD'
#выясняем, кто предоставил корректные подписи
let aliceSigned = if(sigVerify(tx.bodyBytes, tx.proofs[0], alicePubKey)) then 1 else 0
let bobSigned = if(sigVerify(tx.bodyBytes, tx.proofs[1], bobPubKey)) then 1 else 0
let cooperSigned = if(sigVerify(tx.bodyBytes, tx.proofs[2], cooperPubKey)) then 1 else 0
#суммируем все корректные подписи и проверяем их количество
aliceSigned + bobSigned + cooperSigned >= 2
Token kuratoitu rekisteri (TCR)
Monilla blockchain-alustoilla on ongelma myrkyllisten omaisuuserien kanssa. Esimerkiksi mikä tahansa palkkion maksanut osoite voi luoda omaisuuden Wavesissa.
Käyttäjien ja itse lohkoketjun suojaaminen myrkyllisiltä omaisuuksilta voidaan ratkaista tunnuksenhaltijoiden luomalla token curated registry (TCR) -rekisterillä.
Äänestääkseen tietyn tokenin listalle lisäämisen puolesta haltija tekee tarjouksen, joka vastaa hänen osuuttaan myönnettyjen rahakkeiden kokonaismäärästä. Token kirjataan rekisteriin, jos sen haltijoiden enemmistö äänestää sen puolesta.
Esimerkissämme sallimme käyttäjän lisätä tunnuksen luetteloon harkittavaksi ("haaste"-jakson aikana) käyttämällä tilaavainta avain = asset_name, vain jos nykyinen count-arvo = 0.
Lisäksi käyttäjällä on oltava nollasta poikkeava saldo lompakossaan. Sitten tulee äänestysjakso, jonka aikana käyttäjä voi äänestää jokaista lompakkossaan olevaa omaisuutta, mutta vain kerran, antaen arvosanan 1-10. Käyttäjäääniä edustavat avaimet muotoa user_address+assetID.
let asset = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
let addingStartHeight = 1000
let votingStartHeight = 2000
let votingEndHeight = 3000
#извлекаем из транзакции адрес отправителя
let this = extract(tx.sender)
#извлекаем адрес из пруфа транзакции
let address = addressFromPublicKey(tx.proofs[1])
match tx {
case t: DataTransaction =>
if(height > addingStartHeight)
then(
if(height < votingStartHeight)
then(
#adding
#выясняем, есть ли этот ассет у этого адреса
let hasTokens = assetBalance(address, asset) > 0
size(t.data) == 1
#убеждаемся, что этот ассет еще не был добавлен
&& !isDefined(getInteger(this, toBase58String(asset)))
#убеждаемся, что по ключу-ассету добавляется значение равное 0
&& extract(getInteger(t.data, toBase58String(asset))) == 0
&& hasTokens
)
else(
if(height < votingEndHeight)
then
(
#voting
#узнаем текущее количество голосов за данный ассет и задаваемое количество
let currentAmount = extract(getInteger(this, toBase58String(asset)))
let newAmount = extract(getInteger(t.data, toBase58String(asset)))
let betString = toBase58String(address.bytes) + toBase58String(asset)
#убеждаемся, что этот адрес еще не голосовал за этот ассет
let noBetBefore = !isDefined(getInteger(this, betString))
let isBetCorrect = extract(getInteger(t.data, betString)) > 0
&& extract(getInteger(t.data, betString)) <= 10
#убеждаемся, что у голосующего есть необходимые токены
let hasTokens = assetBalance(address, asset) > 0
#проверяем корректность значений транзакции
size(t.data) == 2 && isDefined(getInteger(this, toBase58String(asset)))
&& newAmount == currentAmount + 1
&& noBetBefore && isBetCorrect && hasTokens
)
else false
) && sigVerify(tx.bodyBytes, tx.proofs[0], tx.proofs[1])
)
else false
case _ => false
}
Tilausmaksu
Tässä esimerkissä tarkastellaan älytilien käyttöä tuotteen tai palvelun säännöllisten maksujen suorittamiseen tietyin väliajoin - "tilausmaksut".
Jos käyttäjä antaa älytilille (tapahtumatodisteiden kautta) TransferTransaction-tunnuksen, jossa on vaadittu määrä siirrettyjä varoja, hän voi kirjoittaa tilin tilaan {avain: osoite, arvo:). totta}.
Tämä tarkoittaa, että käyttäjä vahvistaa tilauksensa tuotteelle tai palvelulle. Kun liittymä päättyy, kuka tahansa verkon käyttäjä voi asettaa tilassa vastaavan avaimen vastakkaisen arvon väärä.
let subscriptionPeriod = 44000
let signature = tx.proofs[0]
let pk = tx.proofs[1]
let requiredAmount = 100000
#извлекаем из транзакции адрес отправителя
let this = extract(tx.sender)
match tx {
case d: DataTransaction =>
#извлекаем дату последнего платежа
let lastPaymentHeight = extract(getInteger(this, d.data[0].key + "_lastPayment"))
size(d.data) == 1 && d.data[0].value == "false" && lastPaymentHeight + subscriptionPeriod < height
||
(
let address = d.data[0].key
#извлекаем трансфер-транзакцию по ID, указанному в пруфах
let ttx = transactionById(d.proofs[0])
size(d.data) == 2
&& d.data[0].value == "true"
&& d.data[1].key == address + "_lastPayment"
&& match ttx {
case purchase : TransferTransaction =>
d.data[1].value == transactionHeightById(purchase.id)
&& toBase58String(purchase.sender.bytes) == address
&& purchase.amount == requiredAmount
&& purchase.recipient == this
#убеждаемся, что ассет waves
&& !isDefined(purchase.assetId)
case _ => false
}
)
case _ => false
}
Äänestää
Älykkäitä tilejä voidaan käyttää äänestämisen toteuttamiseen lohkoketjussa. Esimerkkinä voisi olla äänestäminen parhaan suurlähettiläsraportin puolesta. Tilin tilaa käytetään alustana tietyn vaihtoehdon äänien tallentamiseen.
Tässä esimerkissä vain ne, jotka ovat ostaneet erityisiä "äänestysmerkkejä", saavat äänestää. Osallistuja lähettää DataTransactionin etukäteen parilla (avain, arvo) = (purchaseTransactionId, buyTransactionId). Toisen arvon asettaminen tälle avaimelle on kielletty. Voit määrittää DataEntryn vain kerran käyttämällä osoitettasi ja äänestysvaihtoehtoasi. Äänestys on mahdollista vain määrättynä aikana.
let asset = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
let address = addressFromPublicKey(tx.proofs[1])
let votingStartHeight = 2000
let votingEndHeight = 3000
#извлекаем из транзакции адрес отправителя
let this = extract(tx.sender)
match tx {
case t: DataTransaction =>
(height > votingStartHeight && height < votingEndHeight) &&
#убеждаемся, что у транзакции правильная подпись
sigVerify(tx.bodyBytes, tx.proofs[0], tx.proofs[1]) &&
#проверяем, что пользователь отдает свой голос напротив своего адреса
if (t.data[0].key == toBase58String(address.bytes))
then (
#извлекаем транзакцию перевод голосовательного токена из пруфов
let purchaseTx = transactionById(t.proofs[7])
match purchaseTx {
case purchase : TransferTransaction =>
let correctSender = purchase.sender == t.sender
let correctAsset = purchase.assetId == asset
let correctPrice = purchase.amount == 1
let correctProof = extract(getBinary(this, toBase58String(purchase.id))) == t.id
correctSender && correctAsset && correctPrice && correctProof
case _ => false
}
)
else
size(t.data) == 1 && !isDefined(getBinary(this, t.data[0].key))
case _ => false
}
Velkakirja
Velkakirja on kirjallinen velvoite, joka edellyttää, että toinen osapuoli maksaa toiselle kiinteän summan vaadittaessa tai ennalta määrättynä päivänä.
Esimerkissämme käytämme älytiliä, jonka vanhenemispäivä vastaa laskun maksupäivää.
let expiration = 100000
let amount = 10
let asset = base58'9jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
let Bob = Address(base58'3NBVqYXrapgJP9atQccdBPAgJPwHDKkh6A8')
let Alice = Address(base58'3PNX6XwMeEXaaP1rf5MCk8weYeF7z2vJZBg')
match tx {
case t: TransferTransaction =>
(t.assetId == asset)&&
(t.amount == amount)&&
(t.sender == Bob)&&
(t.recipient == Alice)&&
(sigVerify(t.bodyBytes, t.proofs[0], t.senderPublicKey))&&
(height >= expiration)
case _ => false
}
Talletus
Talletus on varojen sijoittamista pankkiin tietyin ehdoin (termi, korko).
Esimerkissämme pankin tehtävää suorittaa älytili. Tietyn lohkomäärän jälkeen, joka vastaa talletusaikaa, käyttäjä voi palauttaa rahansa korkoineen. Skripti määrittää lohkon korkeuden (finalHeight), jonka saavuttamisen jälkeen käyttäjä voi nostaa rahaa tililtä.
korkeusyksikkö - lohkojen määrä yhdessä aikayksikössä (esimerkiksi kuukausi, vuosi jne.). Tarkistamme ensin merkinnän parilla (avain, arvo) = (initialTransferTransaction, futureDataTransaction). Tämän jälkeen käyttäjän tulee lähettää TransferTransaction, jossa on oikeat tiedot talletuksen määrästä ja talletusajalta kertyneestä korosta. Nämä tiedot tarkistetaan alkuperäiseen TransferTransactioniin, joka sisältyy nykyiseen TransferTransaction-todisteeseen. DepositDivisor on talletusosuuden käänteisluku (jos talletus hyväksytään 10 %:lla, talletusosuus on 0,1 ja depositDevisor = 1/0,1 = 10).
let this = extract(tx.sender)
let depositDivisor = 10
let heightUnit = 1000
let finalHeight = 100000
match tx {
case e : TransferTransaction =>
#извлекаем высоту транзакции по ID транзакции в седьмом пруфе
let depositHeight = extract(transactionHeightById(e.proofs[7]))
#извлекаем транзакцию депозита
let purchaseTx = transactionById(e.proofs[7])
match purchaseTx {
case deposit : TransferTransaction =>
let correctSender = deposit.sender == e.sender
#убеждаемся, что пользователь переводит себе корректную сумму депозита + проценты
let correctAmount = deposit.amount + deposit.amount / depositDivisor * (height - depositHeight) / heightUnit == e.amount
let correctProof = extract(getBinary(this, toBase58String(deposit.id))) == e.id
correctSender && correctProof && correctAmount
case _ => false
}
&& finalHeight <= height
case _ => sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
}
Tämän sarjan kolmannessa ja viimeisessä artikkelissa tarkastelemme älykkäiden resurssien lisää käyttötapoja, mukaan lukien tiettyjen osoitteiden tapahtumien jäädyttäminen ja rajoittaminen.
Lähde: will.com
