Systém obchodovania na miestnej burze bez dôvery
29. mája 2019

Systém obchodovania na miestnej burze (LETS) je zameraný na rozvoj miestnej ekonomiky a zvyčajne ho používajú ľudia z lokality, ktorí sú si navzájom blízki. Pre stručný prehľad LETS si pozrite tento odkaz, ktorý tiež popisuje implementáciu ErgoScript riadeného LETS výborom. Takýto systém nazývame riadený alebo s povolením, pretože závisí od výboru dôveryhodných členov, ktorí zapisujú nových členov do LETS.
Tu popisujeme systém LETS bez dôvery, t.j. taký, kde nie je potrebný riadiaci výbor na zápis.
Prehľad
LETS zahŕňa niekoľko strán, ktoré súhlasia s používaním nejakej formy "miestnej meny", zvyčajne viazanej na hlavnú menu krajiny v pomere 1:1. Predpokladajme, že náš LETS je založený v európskej krajine, kde je menou euro, a výmena sa uskutočňuje v "miestnych eurách", ktoré sú považované za ekvivalentné národným eurom.
Každý používateľ v LETS má účet, ktorý obsahuje zostatok LETS tohto používateľa (v miestnych eurách). Pri vstupe má každý používateľ zostatok nula. Zostatok je uložený v (možno decentralizovanej) knihe. Zaujímavou vlastnosťou LETS je, že používateľ s nulovým zostatkom môže tiež "vybrať" peniaze, ale iba na zaplatenie inému používateľovi LETS. Kedykoľvek je súčet zostatkov LETS všetkých používateľov nula.
Ako príklad, Alice s nulovým zostatkom si želá kúpiť liter mlieka za 2 eurá od Boba, ktorý je tiež členom LETS s nulovým zostatkom. Prevedie 2 eurá zo svojho účtu na Bobov, čím sa jej zostatok stane -2 a Bobov +2. Bob potom môže previesť niektoré alebo všetky svoje zostatky inému používateľovi LETS výmenou za tovar alebo služby.
LETS bez dôvery
Keďže si želáme LETS bez dôvery, nemôžeme sa spoliehať na žiadnu dôveryhodnú skupinu ľudí, aby prijímali používateľov. Upozorňujeme, že stále budeme mať výbor na vykonávanie niektorých úloh, ako je nastavenie parametrov LETS (miestna mena, maximálny počet členov atď.) a spotrebovanie akýchkoľvek poplatkov za vstup.
Predpokladáme iba dôveryhodného cenového orákula, ktoré poskytuje aktuálnu sadzbu eur na ergy identifikované nejakým globálnym id (rateTokenID) a singleton box, ktorý obsahuje presne jeden token s týmto id. Singleton box, popísaný tu, je box obsahujúci singleton token, t.j. token s iba jednou existujúcou kvantitou. Tento box tiež obsahuje sadzbu ergov na eurá v akomkoľvek danom časovom období. Sadzba sa aktualizuje výdavkom tohto boxu a vytvorením ďalšieho singleton boxu s novou sadzbou.
V akomkoľvek okamihu je náš LETS jedinečne definovaný globálnym token boxom, ktorý obsahuje niektoré členské tokeny s id letsTokenID. Tento box definuje parametre LETS, ako je umiestnenie, jednotka meny, rateTokenID atď. Token box je pôvodne spustený s, povedzme, 10000 členskými tokenmi. Používatelia môžu tento box minúť a vytvoriť svoje individuálne LETS boxy ako výstupy transakcie, pričom každý takýto výstup má presne jeden členský token a zostatkové členské tokeny sú umiestnené v novo vytvorenom token boxe.
LETS box predstavuje člena LETS a musí byť použitý v každej transakcii. Pre jednoduchosť tento článok obmedzuje všetky transakcie LETS na presne dvoch členov, pričom jeden je odosielateľ a druhý príjemca, tak, že odosielateľ prevádza nejakú pozitívnu sumu LETS meny (miestne eurá) na príjemcu. Takáto transakcia spotrebuje boxy člena a znovu ich vytvorí ako výstup s aktualizovaným zostatkom.
Základná varianta
Aby sme predišli spamu a DDoS útokom, vyžadujeme, aby bolo v novo vytvorenom boxe člena uzamknuté aspoň minimálne množstvo ergov (minErgsToJoin). Ergy budú uzamknuté, kým nebude vytvorený aspoň minWithdrawTime počet blokov. Box môže mať negatívny LETS zostatok až do výšky, ktorú môžu pokryť uzamknuté ergy (použitím sadzby v čase obchodu).
// a tokenBox stores the membership tokens and has this script
val tokenBox = OUTPUTS(0) // the first output must also be a tokenBox
// first output contains remaining LETS tokens
def isLets(b:Box) = { // returns true if b is a LETS box
// A LETS box must have exactly 1 membership token in tokens(0)
b.tokens(0)._1 == letsTokenID && b.tokens(0)._2 == 1 &&
blake2b256(b.propositionBytes) == memberBoxScriptHash &&
SELF.R4[Long].get == 0 && // start the box with zero LETS balance
b.value >= minErgsToJoin && // the box must contain some minimum ergs
b.R6[Long].get <= HEIGHT // store the creation height in R6
}
// how many lets boxes creared in the tx
val numLetsBoxes = OUTPUTS.filter({(b:Box) => isLets(b)}).size
// In the transaction following is preserved for the token box ...
tokenBox.tokens(0)._1 == SELF.tokens(0)._1 && // token id
tokenBox.tokens(0)._2 == SELF.tokens(0)._2 - numLetsBoxes && // quantity
tokenBox.propositionBytes == SELF.propositionBytes // script
Box člena LETS je chránený skriptom nižšie, ktorého hash memberBoxScriptHash je použitý vyššie. Skript vyžaduje presne jeden (odosielateľ, príjemca) pár na transakciu.
val validRateOracle = CONTEXT.dataInputs(0).tokens(0)._1 == rateTokenID
val rate = CONTEXT.dataInputs(0).R4[Int].get
val inBalance = SELF.R4[Long].get // LETS balance of current input
val pubKey = SELF.R5[SigmaProp].get // owner of the current input
val createdAt = SELF.R6[Long].get // height at which current input was mined
val index = getVar[Int](0).get // index of the corresponding output
val out = OUTPUTS(index)
val outBalance = out.R4[Long].get // LETS balance of the output
// A LETS box is one that has the same script as the current box
val isMemberBox = {(b:Box) => b.propositionBytes == SELF.propositionBytes}
val letsInputs = INPUTS.filter(isMemberBox) // all LETS input boxes
val letsOutputs = OUTPUTS.filter(isMemberBox) // all LETS output boxes
// The current input belongs to the receiver if its LETS balance increases
// There may be some ergs in receiver's input box. We need to ensure that
// the receiver's output box also contains the same amount of ergs as input
val receiver = outBalance > inBalance && out.value == SELF.value
val getBalance = {(b:Box) => b.R4[Long].get} // returns LETS balance of a box
val letsBalIn = letsInputs.map(getBalance).fold(0L, {(l:Long, r:Long) => l + r})
val letsBalOut = letsOutputs.map(getBalance).fold(0L, {(l:Long, r:Long) => l + r})
// sender box can contain less amount of ergs (sender may withdraw ergs provided
// that any negative LETS balance of sender in out is backed by sufficient ergs)
val correctErgs = out.value >= -outBalance * rate && (
out.value >= SELF.value || SELF.R6[Long].get + minWithdrawTime > HEIGHT
)
// for the receiver, we don't touch the erg balance,
// since a receiver is not actively involved in the transaction
inBalance != outBalance && // some transaction should occur; balance must change
SELF.tokens(0)._1 == letsTokenID && // the current input has the right token
out.tokens(0)._1 == letsTokenID && // corresponding output has the right token
validRateOracle && // oracle providing rate has the correct "rate token"
letsBalIn == letsBalOut && // total LETS balance is preserved in the transaction
letsInputs.size == 2 && letsOutputs.size == 2 && // only two LETS inputs, outputs
out.propositionBytes == SELF.propositionBytes && // out is a LETS box ...
out.R5[SigmaProp].get == pubKey && // ... with the right pub key
out.R6[Long].get == SELF.R6[Long].get && // ... and creation height
(receiver || // either current input belongs to receiver ...
(pubKey && correctErgs) // ... or out has correct ergs and tx has signature
)
Transakcia, ktorá míňa box s vyššie uvedeným skriptom, vyžaduje:
- Súčet LETS zostatku vstupov a výstupov je zachovaný
- Existujú dva LETS vstupy a dva LETS výstupy
- Verejné kľúče (uložené v R5) sú zachované v príslušnom výstupe
- Výška vytvorenia (uložená v R6) je zachovaná v príslušnom výstupe
Hovoríme, že nejaký verejný kľúč je príjemca, ak je LETS zostatok jeho výstupu vyšší ako zostatok jeho vstupu.
Posledná podmienka vyžaduje, aby buď vstupné a výstupné boxy patrili príjemcovi (tak, aby sa ergov zachovali), alebo, v prípade, že patria odosielateľovi, bola poskytnutá podpis a výstup je krytý požadovaným počtom ergov, ak je jeho LETS zostatok negatívny. Okrem toho vyžaduje, aby zostatok ergov odosielateľa nemohol byť znížený, kým neboli vytvorené aspoň minWithdrawTime počet blokov po uzamknutí ergov.
V porovnaní s riadeným LETS má vyššie uvedený systém nasledujúce rozdiely:
- Žiadny záznam o členstve: Na rozdiel od riadeného LETS tu neuchovávame žiadne informácie o členstve.
- Viacero boxov: Osoba môže vytvoriť viacero členských boxov, čo je povolené. Vyžadujeme iba to, aby akýkoľvek negatívny zostatok bol krytý zodpovedajúcim počtom ergov uzamknutých v ňom.
LETS-1: Nulový súčet, Zábezpeka
Vyššie uvedené je základná varianta, ktorú nazývame LETS-1. Má nasledujúce vlastnosti:
- Časovo uzamknutý poplatok za vstup: Aby sme predišli spamovým útokom, člen musí zaplatiť určitý minimálny poplatok v ergov pri vstupe. Tento poplatok je vratný, ale iba po preddefinovanom počte blokov.
- Nulový súčet: Súčet LETS zostatkov všetkých členských boxov je nula. Členské boxy môžu mať negatívny zostatok, pokiaľ je to v rámci určitého limitu.
- Zábezpeka: Pre výstup odosielateľa sa ergy používajú ako zábezpeka na pokrytie negatívneho LETS zostatku pri aktuálnej výmene.
Nasledujú niektoré variácie LETS-1.
LETS-2: Nulový súčet, Bez zábezpeky
Toto je mierna variácia LETS-1, ako nasleduje:
- Nevratný poplatok za vstup: Podobne ako LETS-1, je potrebný poplatok za vstup, aby sa predišlo spamovým útokom. Avšak, na rozdiel od LETS-1, tento poplatok je nevratný a musí byť zaslaný nejakému preddefinovanému riadiacemu výboru.
- Nulový súčet: Ako v LETS-1.
LETS-3: Pozitívny súčet, Zábezpeka
Vyššie uvedené dve varianty vyžadujú, aby celkový LETS zostatok bol vždy nula. Tu zvažujeme pozitívnu hodnotu pre tento súčet. Konkrétne, táto varianta má nasledujúce vlastnosti:
- Časovo uzamknutý poplatok za vstup: Ako v LETS-1.
- Pozitívny súčet: LETS zostatok každého člena musí byť vždy kladný. To zabezpečuje, že súčet LETS zostatkov všetkých členských boxov je pozitívny. Počiatočný LETS zostatok je nastavený na pozitívnu hodnotu na základe poplatku za vstup pri aktuálnej sadzbe, s maximálnym limitom.
- Zábezpeka: Akékoľvek zníženie zostatku ergov odosielateľa musí byť sprevádzané znížením zodpovedajúceho LETS zostatku pri aktuálnej výmene.
Môžeme tiež povoliť doplnenie LETS zostatku počas transakcie pridaním ekvivalentného množstva ergov.
LETS-4: Pozitívny súčet, Bez zábezpeky
Toto je podobné LETS-3, ale s niektorými malými variáciami:
- Nevratný poplatok za vstup: Ako v LETS-2
- Pozitívny súčet: Ako v LETS-3
Nasledujúca tabuľka sumarizuje varianty:
| Nulový súčet | Pozitívny súčet | |
|---|---|---|
| Zábezpeka | LETS-1 | LETS-3 |
| Bez zábezpeky | LETS-2 | LETS-4 |
Zvážili sme LETS transakcie, ktoré zahŕňajú jediný pár odosielateľ-príjemca. Pokročilejšie modely môžu povoliť viacero odosielateľov a príjemcov a nemusia byť v pároch.
Share post
9. júla 2025







