Miestny systém obchodovania s výmenou na vrchole Ergo
22. apríla 2019

Miestny systém obchodovania s výmenou (LETS) je miestne vzájomné úverové združenie, ktorého členovia môžu individuálne vytvárať spoločné
úverové peniaze, pričom všetky obchody v systéme sú zapísané do spoločnej knihy.
Ako príklad predpokladajme, že Alice s nulovým zostatkom chce kúpiť liter surového mlieka od Boba.
Najprv sa dohodnú na cene, predpokladajme, že cena je približne 2 eurá (keďže Alice a Bob
žijú v Írsku). Po zapísaní obchodu do knihy sa Alicein zostatok stane -2 (mínus
dva) eurá a Bobov zostatok sa stane 2 eurá. Potom môže Bob minúť svoje 2 eurá, napríklad na
homemade pivo od Charlieho. Často takéto systémy ukladajú obmedzenia na negatívne zostatky a niekedy
a dokonca aj na pozitívne, aby podporili výmenu v komunite.
Historicky sa takéto systémy stali populárnymi počas krízových období. Prvý systém bol založený Michaelom Lintonom v
kanadskom meste, ktoré bolo uviaznuté v depresii v roku 1981. Miestne systémy obchodovania s výmenou boli mimoriadne populárne počas
argentínskej veľkej depresie v rokoch 1998-2002. Väčšina skupín LETS má od 50 do 250 členov, s papierovými úverovými poznámkami a
knihou, ktorú spravuje jadrový výbor. Avšak papierové LETS meny ukázali niektoré problémy, ako sú
falošné poznámky, možné zlé správanie správcov systému a podobne. Preto by mohli byť LETS založené na blockchaine nadriadené
starej systémom. Viac informácií o LETS nájdete v
"Ekológii peňazí" (od Richarda Douthwaite) a
Wikipedia.
V tomto článku ukazujeme, ako by sa LETS mohli implementovať na vrchole Ergo. Podľa našich najlepších vedomostí ide o
prvú implementáciu takého druhu komunitnej meny na vrchole blockchainu.
Naša referenčná implementácia
sú jednoduché a pozostáva z dvoch zmlúv, a to z manažérskej zmluvy a zmluvy o výmene.
Preskočíme úvod do Ergo, takže si prosím prečítajte
článok ICO a
ErgoScript tutoriály (základné a
pokročilé) pre začiatočníkov.
Napriek tomu sa chystáme predstaviť niekoľko nových pojmov v nasledujúcich vetách.
Ak je token vydaný s množstvom rovnakým ako jeden, nazývame ho singleton token. Podobne,
box, ktorý obsahuje singleton token, sa nazýva singleton box.
Manažérska zmluva ovláda singleton box, ktorý obsahuje členov systému LETS.
Zmluva umožňuje pridávanie nových členov tempom jedného člena na jednu transakciu. Box
neukladá členov, ale iba malý digest autentifikovanej dátovej štruktúry postavenej na
adresári členov. Člen je spojený so singleton tokenom vydaným v transakcii, ktorá
pridáva člena do adresára. Transakcia vytvára nový box člena, ktorý obsahuje
singleton token člena. Box člena je chránený zmluvou o výmene. Taktiež, novovytvorený
box člena má počiatočný zostatok zapísaný do registra R4 a zostatok je
erovný nule v našom príklade. Transakcia vytvárajúca nového člena musí poskytnúť dôkaz o správnosti pre
transformáciu adresára.
Box manažérskej zmluvy je zvyčajne kontrolovaný výborom a výbor sa môže časom vyvíjať. Na podporu
toho umožňujeme logiku výboru sídliť v registri R5.
Napríklad, predpokladajme, že nový člen výboru bol pridaný spolu s novým členom LETS,
vstupný box manažérskej zmluvy vyžaduje 2 z 3 podpisov a výstupný box vyžaduje 3 z 4 podpisov.
V tomto prípade by sa obsah registra R5 vo vstupnom a výstupnom boxe líšil.
Kód manažérskej zmluvy v ErgoScripte s komentármi je uvedený nižšie. Upozorňujeme, že
"userContractHash" sa týka hash zmluvy o výmene.
val selfOut = OUTPUTS(0)
// Manažérsky skript
val managementScript = selfOut.R5[SigmaProp].get
// Šablóna manažérskeho skriptu replikujúca seba, a manažérsky skript je splnený
val scriptCorrect = (selfOut.propositionBytes == SELF.propositionBytes) && managementScript
// Transakcia výdavkov vytvára boxy pre adresár, používateľa, poplatok.
val outsSizeCorrect = OUTPUTS.size == 3
// Kontroluje, že manažérska označkovaná token replikujúca seba
val outTokenCorrect = (selfOut.tokens.size == 1) && (selfOut.tokens(0)._1 == letsToken)
// Kontroluje, že nový token je vydaný a jeho množstvo je správne
// OUTPUTS(0) tokeny už boli skontrolované prostredníctvom outtokenCorrect
val issuedTokenId = INPUTS(0).id
val userOut = OUTPUTS(1)
val correctTokenAmounts =
(userOut.tokens.size == 1 &&
userOut.tokens(0)._1 == issuedTokenId &&
userOut.tokens(0)._2 == 1 &&
OUTPUTS(2).tokens.size == 0 &&
outTokenCorrect)
// Kontroluje, že nový používateľ bol vytvorený so zostatkom nula
val zeroUserBalance = userOut.R4[Long].get == 0
val properUserScript = blake2b256(userOut.propositionBytes) == userContractHash
// Kontroluje, že nový identifikátor tokenu bol pridaný do adresára
val selfTree = SELF.R4[AvlTree].get
val toAdd: Coll[(Coll[Byte], Coll[Byte])] = Coll((issuedTokenId, Coll[Byte]()))
val proof = getVar[Coll[Byte]](1).get
val modifiedTree = selfTree.insert(toAdd, proof).get
val expectedTree = selfOut.R4[AvlTree].get
val treeCorrect = modifiedTree == expectedTree
correctTokenAmounts && scriptCorrect && treeCorrect && zeroUserBalance && properUserScript
correctTokenAmounts && scriptCorrect && treeCorrect && zeroUserBalance && properUserScript correctTokenAmounts && scriptCorrect && treeCorrect && zeroUserBalance && properUserScript
Skript zmluvy o výmene je celkom jednoduchý a je uvedený nižšie spolu s komentármi popisujúcimi jeho logiku. V
zmluve sa predpokladá, že transakcia výdavkov pre box zmluvy o výmene prijíma aspoň dva vstupy,
a prvé dva vstupy by mali byť chránené skriptom zmluvy o výmene a obsahovať tokeny členov LETS. Aby sa skontrolovalo,
že singleton členové tokeny vo vstupoch skutočne patria do systému LETS, transakcia výdavkov poskytuje box manažérskej zmluvy ako prvý vstup s obmedzeným prístupom a mala by tiež poskytnúť dôkaz, že tokeny členov skutočne patria do
adresára autentifikovaného prostredníctvom registra R4 boxu manažérskej zmluvy. "letsToken" v skripte sa týka
tokenu singleton boxu.
// Minimálny zostatok povolený pre obchodníka LETS
val minBalance = -20000
val lookupProof = getVar[Coll[Byte]](1).get
// Box s obmedzeným prístupom, ktorý obsahuje adresár členov LETS
val treeHolderBox = CONTEXT.dataInputs(0)
val properLetsToken = treeHolderBox.tokens(0)._1 == letsToken
val membersTree = treeHolderBox.R4[AvlTree].get
// Transakcia výdavkov berie dva boxy členov LETS, ktorí chcú uzavrieť obchod,
// a vracia boxy s upravenými zostatkami.
val participant0 = INPUTS(0)
val participant1 = INPUTS(1)
val participantOut0 = OUTPUTS(0)
val participantOut1 = OUTPUTS(1)
// Skontrolujte, že členovia skutočne patria do LETS
val token0 = participant0.tokens(0)._1
val token1 = participant1.tokens(0)._1
val memberTokens = Coll(token0, token1)
val membersExist = membersTree.getMany(memberTokens, lookupProof).forall({ (o: Option[Coll[Byte]]) => o.isDefined })
// Skontrolujte, že zmeny zostatku členov počas obchodu sú správne
val initialBalance0 = participant0.R4[Long].get
val initialBalance1 = participant1.R4[Long].get
val finishBalance0 = participantOut0.R4[Long].get
val finishBalance1 = participantOut1.R4[Long].get
val diff0 = finishBalance0 - initialBalance0
val diff1 = finishBalance1 - initialBalance1
val diffCorrect = diff0 == -diff1
val balancesCorrect = (finishBalance0 > minBalance) && (finishBalance1 > minBalance) && diffCorrect
// Skontrolujte, že boxy členov ukladajú svoje skripty.
// todo: optimalizácia by sa mohla vykonať tu
val script0Saved = participantOut0.propositionBytes == participant0.propositionBytes
val script1Saved = participantOut1.propositionBytes == participant1.propositionBytes
val scriptsSaved = script0Saved && script1Saved
// Ochrana boxu špecifického pre člena
val selfPubKey = SELF.R5[SigmaProp].get
selfPubKey && properLetsToken && membersExist && diffCorrect && scriptsSaved
Upozorňujeme, že obe zmluvy by sa mohli upraviť rôznymi spôsobmi, aby sa získali nové systémy s rôznymi vlastnosťami. Dúfajme, že
niekedy bude tento článok pokračovať!
Share post
9. júla 2025







