FlowCards: Deklaratív Keretrendszer az Ergo dApp-ok Fejlesztéséhez
2020. április 29.

Köszönet Robert Kornacki -nak a tervezet finomításáért.
Bevezetés
ErgoScript az okos szerződés nyelv, amelyet az
Ergo blokklánc használ. Míg a szintaxisa tömör, a Scala/Kotlin-ból átvett, kezdetben zavarónak
tűnhet, mert fogalmilag az ErgoScript meglehetősen eltér a hagyományos nyelvektől, amelyeket
mindannyian ismerünk és szeretünk. Ennek az az oka, hogy az Ergo egy UTXO alapú
blokklánc, míg az okos szerződések hagyományosan a fiók alapú rendszerekhez kapcsolódnak,
mint például az Ethereum. Azonban az Ergo tranzakciós modellje számos előnnyel bír a fiók
alapú modellel szemben, és a megfelelő megközelítéssel még jelentősen könnyebb is lehet
Ergo szerződéseket fejleszteni, mint Solidity kódot írni és hibakeresni.
Az alábbiakban bemutatjuk az Ergo szerződés modell kulcsfontosságú aspektusait, amelyek
különbözővé teszik:
Paradigma
Az Ethereum fiók modellje imperatív. Ez azt jelenti, hogy a tipikus feladat, hogy érméket
küldjünk Alistól Bobnak, a tárolók egy sor műveletének megváltoztatását igényli. Az Ergo UTXO
alapú programozási modellje ezzel szemben deklaratív. Az ErgoScript szerződések feltételeket
határoznak meg a tranzakciók blockchain általi elfogadásához (nem a tároló állapotának
megváltoztatására a szerződés végrehajtása következtében).
Skálázhatóság
Az Ethereum fiók modelljében mind a tárolási változások, mind a érvényességi ellenőrzések
táblán történnek a kód végrehajtása során. Ezzel szemben az Ergo tranzakciók
off-chain jönnek létre, és csak az érvényességi ellenőrzések történnek a láncon, így csökkentve
az egyes csomópontok által végrehajtott műveletek számát a hálózaton. Ezenkívül a tranzakciós
grafikon megváltoztathatatlansága miatt különböző optimalizálási stratégiák lehetségesek a
másodpercenkénti tranzakciók áteresztőképességének javítására a hálózaton. Könnyű
ellenőrző csomópontok is lehetségesek, így tovább segítve a hálózat skálázhatóságát és
hozzáférhetőségét.
Megosztott állapot
A fiók alapú modell a megosztott, módosítható állapotra támaszkodik, amelyről ismert,
hogy összetett szemantikához (és finom, millió dolláros hibákhoz) vezet a párhuzamos/
megosztott számítások kontextusában. Az Ergo modellje egy megváltoztathatatlan tranzakciós
grafikonon alapul. Ez a megközelítés, amely a Bitcointól származik, jól illeszkedik a
blokkláncok párhuzamos és elosztott természetéhez, és megkönnyíti a könnyű, bizalmatlan
klienseket.
Kifejezőerő
Az Ethereum a blokkláncon egy turing-teljes nyelv végrehajtását szorgalmazta. Elméletileg
korlátlan potenciált ígért, azonban a gyakorlatban súlyos korlátozások derültek ki a
túlzott blokklánc bloat, finom millió dolláros hibák, a szerződés összetettségét korlátozó
gázköltségek és egyéb hasonló problémák miatt. Az Ergo ezzel szemben kiterjeszti a UTXO-t,
hogy lehetővé tegye a turing-teljesítményt, miközben korlátozza az ErgoScript nyelv
összetettségét. Ugyanazt a kifejezőerőt egy másik és szemantikailag megalapozottabb módon
érjük el.
A fent említett összes pont alapján világos, hogy sok előnye van az Ergo által használt
modellnek. A cikk további részében bemutatom a FlowCards koncepcióját - egy dApp
fejlesztő komponenst, amely lehetővé teszi bonyolult Ergo szerződések tervezését
deklaratív és vizuális módon.
Az Imperatívról a Deklaratívra
Az Ethereum imperatív programozási modelljében egy tranzakció egy műveletek sorozata,
amelyet az Ethereum VM hajt végre. Az alábbi Solidity függvény
megvalósít egy token átvitelét a sender-től a receiver-hez. A tranzakció akkor kezdődik,
amikor a sender ezt a függvényt hívja meg egy szerződés példányán, és akkor ér véget,
amikor a függvény visszatér.
// Küld egy meglévő érmét bármely hívótól egy címre
function send(address receiver, uint amount) public {
require(amount <= balances[msg.sender], "Insufficient balance.");
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Sent(msg.sender, receiver, amount);
}
A függvény először ellenőrzi az előfeltételeket, majd frissíti a tárolót (azaz a
mérlegeket), és végül közzéteszi a posztfeltételt a Sent eseményként. A tranzakció
által felhasznált gáz a bányásznak jutalomként kerül elküldésre a tranzakció végrehajtásáért.
Az Ethereummal ellentétben az Ergo tranzakció egy adatstruktúra, amely egy listát tartalmaz
az input érmékről, amelyeket elkölt, és egy listát az output érmékről, amelyeket létrehoz,
tartva az ERG-k és tokenek összesített mérlegét (amelyben az Ergo hasonlít a Bitcoinra).
Visszatérve a fenti példához, mivel az Ergo natívan támogatja a tokeneket, ezért ehhez a
konkrét token küldési példához nem kell semmilyen kódot írni az ErgoScript-ben. Ehelyett
létre kell hoznunk a 'send' tranzakciót, amelyet a következő ábra mutat, amely ugyanazt a
token átvitelét írja le, de deklaratívan.

A kép vizuálisan leírja a következő lépéseket, amelyeket a hálózati felhasználónak
kell végrehajtania:
- Válassza ki a fel nem használt küldő dobozokat, amelyek összesen
tB >= amounttokenet
ésB >= txFee + minErgERG-t tartalmaznak. - Hozzon létre egy output
targetdobozt, amelyet areceivernyilvános kulcs véd,
minErgERG-vel ésamountTtokennel. - Hozzon létre egy fee outputot, amelyet a
minerFeeszerződés véd,txFeeERG-vel. - Hozzon létre egy change outputot, amelyet a
sendernyilvános kulcs véd, amely
tB - amountTtoken ésB - minErg - txFeeERG-t tartalmaz. - Hozzon létre egy új tranzakciót, írja alá a küldő titkos kulcsával, és küldje el az Ergo
hálózatra.
Ami itt fontos megérteni, hogy mindezeket a lépéseket off-chain hajtják végre (például
az Appkit Tranzakció API használatával)
az alkalmazás által. Az Ergo hálózati csomópontoknak nem kell megismételniük ezt a tranzakció
létrehozási folyamatot, csak az előre elkészített tranzakciót kell érvényesíteniük. Az
ErgoScript szerződések a tranzakció bemeneteiben tárolódnak, és ellenőrzik a költési
feltételeket. A csomópont a szerződéseket on-chain hajtja végre, amikor a tranzakciót
érvényesítik. A tranzakció érvényes, ha minden feltétel teljesül.
Így az Ethereumban, amikor "küldünk egy összeget a küldőtől a címzettnek", akkor
szó szerint a mérlegeket szerkesztjük és a tárolót frissítjük egy konkrét parancssorozattal.
Ez on-chain történik, és így egy új tranzakció is on-chain jön létre ennek a folyamatnak
az eredményeként.
Az Ergón (mint a Bitcoinban) a tranzakciók off-chain jönnek létre, és a hálózati
csomópontok csak ellenőrzik őket. A tranzakció hatásai a blokklánc állapotára az, hogy a
bemeneti érmék (vagy dobozok az Ergo terminológiájában) eltávolításra kerülnek, és az
output dobozok hozzáadódnak a UTXO
halmazhoz.
A fenti példában nem használunk ErgoScript szerződést, hanem feltételezzük, hogy egy
aláírás-ellenőrzést használnak költési előfeltételként. Azonban bonyolultabb alkalmazási
forgatókönyvekben természetesen szükség van az ErgoScript használatára, amelyről a
következő részben fogunk beszélni.
Állapotváltoztatásról a Kontextus Ellenőrzésére
A send függvény példájában először ellenőriztük az előfeltételt (require(amount <= balances[msg.sender],...)), majd megváltoztattuk az állapotot (azaz frissítettük a
mérlegeket balances[msg.sender] -= amount). Ez tipikus az Ethereum tranzakciókban. Mielőtt
bármilyen változást végrehajtanánk, ellenőriznünk kell, hogy érvényes-e ezt megtenni.
Az Ergónál, ahogy korábban megbeszéltük, az állapot (azaz a dobozok UTXO halmaza) implicit módon
változik, amikor egy érvényes tranzakciót egy blokkba foglalnak. Így csak az előfeltételeket
kell ellenőriznünk, mielőtt a tranzakciót hozzáadhatnánk a blokkhoz. Ezt teszik az
ErgoScript szerződések.
Nem lehetséges az "állapot megváltoztatása" az ErgoScript-ben, mert ez egy nyelv a
érmék költésének előfeltételeinek ellenőrzésére. Az ErgoScript egy tisztán funkcionális
nyelv, amely mellékhatások nélkül működik, és megváltoztathatatlan adatértékeken alapul.
Ez azt jelenti, hogy minden bemenet, kimenet és egyéb tranzakciós paraméter, amely
elérhető egy scriptben, megváltoztathatatlan. Ez, más dolgok mellett, az ErgoScript-et
nagyon egyszerű nyelvvé teszi, amelyet könnyű megtanulni és biztonságosan használni. Hasonlóan
a Bitcoinhoz, minden bemeneti doboz tartalmaz egy scriptet, amelynek true értéket kell
visszaadnia ahhoz, hogy 1) lehetővé tegye a doboz költését (azaz eltávolítását az UTXO
halmazból) és 2) hozzáadja a tranzakciót a blokkhoz.
Ha pedánsak vagyunk, ezért helytelen (szigorúan véve) úgy gondolni az ErgoScript-re,
mint az Ergo szerződések nyelvére, mert ez a javaslatok (logikai predikátumok, formulák,
stb.) nyelve, amely megvédi a dobozokat az "illegális" költéstől. A Bitcoinhoz képest az
Ergónál az egész tranzakció és a jelenlegi blokklánc kontextus egy része elérhető minden
script számára. Ezért minden script ellenőrizheti, hogy mely outputok jönnek létre a
tranzakció által, azok ERG és token mennyiségeit (ezt a képességet a példánk DEX
szerződéseiben fogjuk használni), a jelenlegi blokk számát stb.
"Az ErgoScript-ben meghatározzuk a feltételeket, hogy a változások (azaz az érmék
költése) megengedettek-e egy adott kontextusban. Ez ellentétben áll a változások
imperatív programozásával a szerződés kódjában.
Míg az Ergo tranzakciós modellje számos alkalmazást nyit meg (mint például DEX, DeFi
alkalmazások, LETS, stb.), a szerződések tervezése érmék költésének előfeltételeiként
(k vagy védő scriptként) közvetlenül nem intuitív. A következő szakaszokban egy hasznos
grafikai jelölést fogunk figyelembe venni a szerződések deklaratív tervezésére FlowCard
Diagramok használatával, amelyek az végrehajtható komponensek (FlowCards) vizuális
ábrázolása.
A FlowCards célja, hogy radikálisan leegyszerűsítse a dApp fejlesztést az Ergo
platformon, egy magas szintű deklaratív nyelvet, végrehajtási futtatási időt, tárolási
formátumot és grafikai jelölést biztosítva.
Magas szintű diagramokkal kezdünk, és lemegyünk a FlowCard specifikációra.
FlowCard Diagramok
A FlowCard diagramok mögötti ötlet a következő megfigyeléseken alapul: 1) Egy Ergo doboz
megváltoztathatatlan, és csak abban a tranzakcióban költhető el, amely bemenetként használja.
- Ezért rajzolhatunk egy dobozok áramlását a tranzakciókon keresztül, így a tranzakcióba
befolyó dobozok elköltésre kerülnek, míg a kiáramló dobozok létrejönnek és hozzáadódnak
az UTXO-hoz. 3) Egy tranzakció ebből a szempontból egyszerűen a régi dobozok újakká
alakítója, megőrizve az érintett ERG-k és tokenek mérlegét.
A következő ábra bemutatja az Ergo tranzakció fő elemeit, amelyeket már korábban láttunk
(most FlowCard Diagram néven).

Minden elem mögött szigorúan meghatározott jelentés (szemantika) áll, így a diagram
vizuális ábrázolása (vagy nézete) az alapul szolgáló végrehajtható komponensnek
(FlowCard-nak) felel meg.
A FlowCard felhasználható az Ergo dApp újrahasználható komponenseként a tranzakció
létrehozására és kezdeményezésére az Ergo blokkláncon. Ezt a következő szakaszokban
fogjuk megvitatni.
Most nézzük meg a FlowCard diagram egyes elemeit egyesével.
1. Név és Paraméterek
Minden flow cardnak nevet és egy típusos paraméterek listáját adunk. Ez hasonló egy
paraméterekkel rendelkező sablonhoz. A fenti ábrán látható a Send flow card, amelynek
öt paramétere van. A paraméterek a specifikációban használatosak.
2. Szerződés Tárca
Ez a flow card kulcsfontosságú eleme. Minden doboznak van egy védő scriptje. Gyakran ez
az a script, amely ellenőrzi az aláírást egy nyilvános kulccsal szemben. Ez a script
triviális az ErgoScript-ben, és a def pk(pubkey: Address) = { pubkey } sablonként
van definiálva, ahol pubkey az Address típusú paraméter. Az ábrán a script sablon
alkalmazva van a pk(sender) paraméterre, így egy konkrét tárca szerződés jön létre.
Ezért a pk(sender) és pk(receiver) különböző scriptet ad, és a diagramon különböző
tárcákat képvisel, még akkor is, ha ugyanazt a sablont használják.
A Szerződés Tárca tartalmazza az összes UTXO doboz halmazát, amelynek adott scriptje
származik a megadott script sablonból a flow card paraméterek felhasználásával. Például,
az ábrán a sablon pk, és a pubkey paramétert a sender flow card paraméter
helyettesíti.
3. Szerződés
Bár a szerződés egy doboz tulajdonsága, a diagramon a dobozokat a szerződéseik szerint
csoportosítjuk, így úgy tűnik, hogy a dobozok a szerződésekhez tartoznak, nem pedig a
szerződések a dobozokhoz. A példában három példányosított szerződésünk van:
pk(sender), pk(receiver) és minerFee. Ne feledje, hogy a pk(sender) a
pk sablon példányosítása a konkrét sender paraméterrel, és a minerFee a
előre definiált szerződés példányosítása, amely védi a bányász jutalom dobozokat.
4. Doboz név
A diagramon minden doboznak nevet adhatunk. A diagram olvashatósága mellett a nevet
a doboz szerződésében való bonyolultabb indexelt hozzáférés szinonimájaként is használjuk.
Például, a change a doboz neve, amelyet az ErgoScript feltételekben is használhatunk
OUTPUTS(2) helyett. A doboz neveket a költési feltételek társítására is használjuk.
5. Dobozok a tárcában
A diagramon a dobozokat (sötétebb téglalapok) a szerződés tárcákhoz (világosabb
téglalapok) tartozónak mutatjuk. Minden ilyen doboz téglalap egy szürke tranzakció
téglalaphoz kapcsolódik, narancssárga vagy zöld nyilakkal, vagy mindkettővel.
Egy output doboz (beérkező zöld nyíllal) sok szövegsort tartalmazhat, ahol minden sor
megad egy feltételt, amelyet a tranzakció részeként ellenőrizni kell. Az első sor
megadja a feltételt az ERG mennyiségére, amelyet a dobozban el kell helyezni. A többi
sor az alábbi formák egyikét öltheti:
amount: TOKEN- a doboznak tartalmaznia kell a megadottamountmennyiségű
adottTOKEN-tR == value- a doboznak tartalmaznia kell a megadottvalue-t a megadott
regiszterR-benboxName ? condition- aboxNamenevű doboznak ellenőriznie kell acondition
tartalmát a scriptjében.
Ezeket a feltételeket az alábbi szakaszokban tárgyaljuk.
6. ERG mennyiség a dobozban
Minden doboznak tárolnia kell egy minimális ERG mennyiséget. Ezt ellenőrzik, amikor a
létrehozó tranzakciót érvényesítik. A diagramon az ERG mennyisége mindig az első
sorként jelenik meg (pl. B: ERG vagy B - minErg - txFee). Az érték típusú
meghatározás B: ERG opcionális, és olvashatóság céljából használható. Amikor az
érték képletként van megadva, akkor ezt a képletet be kell tartani a tranzakciónak,
ami létrehozza a dobozt.
Fontos megérteni, hogy az olyan változók, mint amount és txFee, nem a dobozok
nevesített tulajdonságai. Ezek a diagram egészének paraméterei, és bizonyos mennyiségeket
képviselnek. Vagy más szavakkal, ezek megosztott paraméterek a tranzakciók között (pl.
Sell Order és Swap tranzakciók a DEX példában megosztják a tAmt paramétert). Így
ugyanaz a név ugyanahhoz az értékhez van kötve a diagram egészében (itt a
eszközök sokat segítenek). Azonban, amikor a on-chain érvényesítésről van szó,
csak a ?-val megjelölt explicit feltételek kerülnek átalakításra ErgoScript-re. Ugyanakkor
minden egyéb feltételt off-chain biztosítanak a tranzakció építése során (például egy
alkalmazásban, amely az Appkit API-t használja) és a tranzakció érvényesítésekor, amikor
hozzáadják a blokklánchoz.
7. T token mennyiség
Egy doboz sok token értéket tárolhat. A diagramon a tokenek neveket kapnak, és egy
value változó társítható a T tokenhez a value: T kifejezés használatával. A
value képletként is megadható. Ha a képlet egy doboz névével van előtagolva, mint
boxName ? formula, akkor ezt a boxName doboz védő scriptjében is ellenőrizni kell.
Ez a kiegészítő specifikáció nagyon kényelmes, mert 1) lehetővé teszi a vizuális
tervezés automatikus érvényesítését, és 2) a diagram dobozaiban megadott feltételek
elégségesek a szükséges védő script szintéziséhez. (több erről
alább a "A Diagramoktól az ErgoScript Szerződésekig")
8. Tx Bemenetek
A bemenetek a megfelelő tranzakcióhoz narancssárga nyilakkal kapcsolódnak. Egy
bemeneti nyíl címkéje a következő formák egyikét viselheti:
name@index- opcionális név egy indexszel, azazfee@0vagy@2. Ez a nyíl
célpontjának tulajdonsága. A név a kapcsolódó dobozok feltételeiben használatos, és az
indexa tranzakció INPUTS gyűjteményében a megfelelő doboz helyét jelöli.!action- a nyíl forrásának tulajdonsága, és egy alternatív költési útvonalat ad a
doboznak (ezt a DEX példában látni fogjuk).
Az alternatív költési útvonalak miatt egy doboznak sok kimenő narancssárga nyila
lehet, amelyek esetében különböző akciókkal kell címkézni őket.
9. Tranzakció
A tranzakció bemeneti dobozokat költ el, és output dobozokat hoz létre. A bemeneti dobozok
az narancssárga nyilakkal vannak megadva, és a címkék várhatóan a megfelelő indexekre
helyezik a bemeneteket az INPUTS gyűjteményben. Az output dobozokat a zöld nyilak
adják meg. Minden tranzakciónak szigorú egyensúlyt kell fenntartania az ERG értékek
(az inputok összege == az outputok összege) és minden token esetében az inputok
összege >= az outputok összege. A tervezési diagram explicit specifikációt igényel az
ERG és token értékekre az összes output doboz esetében, hogy elkerülje az implicit
hibákat és biztosítsa a jobb olvashatóságot.
10. Tx Kimenetek
A kimenetek a megfelelő tranzakcióhoz zöld nyilakkal kapcsolódnak. Egy output nyíl
címkéje a következő formában lehet: name@index, ahol egy opcionális név egy indexszel
van kísérve, azaz fee@0 vagy @2. Ez a nyíl forrásának tulajdonsága. A név a
kapcsolódó dobozok feltételeiben használatos, és az index a tranzakció OUTPUTS
gyűjteményében a megfelelő doboz helyét jelöli.
Példa: Decentralizált Tőzsde (DEX)
Most használjuk a fent leírt jelölést egy FlowCard tervezésére egy DEX dApp-hoz. Elég
egyszerű, mégis bemutatja a FlowCard diagramok összes kulcsfontosságú jellemzőjét,
amit a korábbi szakaszban bemutattunk.
A dApp forgatókönyve az alábbi ábrán látható:
Három résztvevő (vásárló,
eladó és DEX) van a DEX dApp-ban, és öt különböző tranzakciótípus, amelyeket a
résztvevők hoznak létre. A vásárló ergAmt ERG-t szeretne tAmt TID tokenre
cserélni (vagy fordítva, az eladó TID tokeneket szeretne ERG-ért eladni, hogy ki
küldi el a megrendelést először, az nem számít). Mind a vásárló, mind az eladó bármikor
lemondhatja a megrendelését. A DEX off-chain
illesztőszolgáltatása megtalálhatja a megfelelő megrendeléseket, és létrehozhatja a
Swap tranzakciót a csere befejezéséhez.
A következő diagram teljes mértékben (és formálisan) specifikálja az öt tranzakciót,
amelyet off-chain kell létrehozni a DEX dApp által. Ezenkívül specifikálja az összes
költési feltételt, amelyet on-chain kell ellenőrizni.

Beszéljük meg a FlowCard diagramot és minden tranzakció logikáját részletesen:
Vásárlási Megrendelés Tranzakció
A vásárló létrehoz egy Buy Order tranzakciót. A tranzakció E mennyiségű ERG-t
(ként írjuk E: ERG) költ el egy vagy több dobozból a pk(buyer) tárcában. A
tranzakció létrehoz egy bid dobozt ergAmt: ERG értékkel, amelyet a buyOrder
script véd. A buyOrder script a specifikációból származik (lásd
alább a "A Diagramoktól az ErgoScript Szerződésekig") vagy manuálisan, vagy
automatikusan egy eszköz által. Bár a tervezés során nem szükséges a buyOrder
scriptet kifejezetten definiálni, a futásidő alatt a bid doboznak tartalmaznia kell a
buyOrder scriptet, mint védő javaslatot (amely ellenőrzi a doboz költési feltételeit),
máskülönben a diagramon megadott feltételek nem lesznek ellenőrizve.
A change doboz létrejön, hogy a tranzakció bemeneti és kimeneti összegei egyensúlyban
legyenek. A tranzakciós díj doboz elhagyható, mert azt a szerszámok automatikusan
hozzáadhatják. A gyakorlatban azonban a tervező kifejezetten hozzáadhatja a díj dobozt
a diagramhoz. Ez lefedi a bonyolultabb tranzakciók (mint például a Swap) eseteit,
amikor sokféleképpen lehet kifizetni a tranzakciós díjat.
Vásárlás Lemondás, Eladás Lemondás Tranzakciók
Bármikor a buyer lemondhatja a megrendelést a CancelBuy tranzakció elküldésével.
A tranzakciónak meg kell felelnie a védő buyOrder szerződésnek, amely védi a bid
dobozt. Ahogy a diagramon látható, mind a Cancel, mind a Swap tranzakciók
költhetik a bid dobozt. Amikor egy doboznak költési alternatívái (vagy költségi
útvonalai) vannak, akkor minden alternatívát egy egyedi név az ! előtaggal
azonosítanak (!cancel és !swap a bid doboz esetében). Minden alternatív
útvonalnak specifikus költési feltételei vannak. A példánkban, amikor a Cancel Buy
tranzakció költi a bid dobozt, a ?buyer feltételnek teljesülnie kell, amit úgy
olvashatunk, hogy "a buyer cím aláírásának a tranzakcióban kell szerepelnie".
Ezért csak a vásárló mondhatja le a vásárlási megrendelést. Ez a "signature" feltétel
csak a !cancel alternatív költési útvonalra kötelező, és nem kötelező a !swap-ra.
Eladási Megrendelés Tranzakció
Az Sell Order tranzakció hasonló a BuyOrder-hoz, mivel tokenekkel is foglalkozik
az ERG-k mellett. A tranzakció E: ERG és T: TID tokeneket költ el az eladó
tárcájából (amelyet pk(seller) szerződésként határozunk meg). A két output a ask
és a change. A change egy standard doboz a tranzakció egyensúlyának fenntartására.
Az ask doboz tAmt: TID tokeneket tartalmaz az cserére, és minErg: ERG -t,
a minimum ERG mennyiséget, amely minden dobozban szükséges.
Swap Tranzakció
Ez a kulcsfontosságú tranzakció a DEX dApp forgatókönyvében. A tranzakciónak több
költési feltétele van a bemeneti dobozokon, és ezek a feltételek a buyOrder és
sellOrder scriptjeiben szerepelnek (amelyeket ellenőriznek, amikor a tranzakciót
hozzáadják a blokklánchoz). Azonban a diagramon ezek a feltételek nem a bid és
ask dobozokban szerepelnek, hanem a tranzakció output dobozaiban vannak definiálva.
Ez egy konvenció a jobb használhatóság érdekében, mert a legtöbb feltétel a kimeneti
dobozok tulajdonságaira vonatkozik. Megadhatnánk ezeket a tulajdonságokat a bid
dobozban, de akkor bonyolultabb kifejezéseket kellene használnunk.
Nézzük meg a buyerOut@0 nyíllal címkézett outputot. Ez a címke azt mondja,
hogy a kimenet az OUTPUTS gyűjtemény 0 indexén található, és hogy a diagramon
ezt a dobozt a buyerOut névvel hivatkozhatjuk. Így mind a dobozt, mind a nyilat
címkézhetjük, hogy a doboznak nevet adjunk.
A buyerOut dobozban látható feltételek a bid ? condition formát öltik, ami azt
jelenti, hogy ezeket on-chain kell ellenőrizni a bid doboz költéséhez.
A feltételek a következő jelentéssel bírnak:
tAmt: TIDmegköveteli, hogy a dobozbantAmtmennyiségűTIDtoken legyenR4 == bid.idmegköveteli, hogy a doboz R4 regisztere egyenlő legyen abid
doboz azonosítójával.script == buyermegköveteli, hogy abuyerOutdobozban a diagramon található
wallet scriptje legyen, azazpk(buyer)
Hasonló tulajdonságokat adunk a sellerOut dobozhoz, amelyet az 1 indexre
specifikálunk, és a név a doboz címkéjén keresztül van megadva, nem pedig a nyíl
címkéjén.
A Swap tranzakció a bid és ask dobozokat költi el az !swap költési
útvonalon, azonban a !cancel-al ellentétben az útvonalon a feltételek nincsenek
meghatározva. Itt jönnek a bid ? és ask ? előtagok szerepbe. Ezeket azért
használják, hogy a buyerOut és sellerOut dobozokban felsorolt feltételek
átkerüljenek a bid és ask dobozok !swap költési útvonalára.
Ha megnézi a kimeneti dobozok feltételeit, láthatja, hogy pontosan meghatározzák
a vásárló és az eladó tárcái közötti értékek cseréjét. A vásárló megkapja a szükséges
TID token mennyiséget, és az eladó megkapja a megfelelő mennyiségű ERG-t. A Swap
tranzakció akkor jön létre, amikor két megfelelő doboz van a buyOrder és sellOrder
szerződésekkel.
A Diagramoktól az ErgoScript Szerződésekig
A FlowCard specifikációk érdekessége, hogy felhasználhatók a szükséges ErgoTree script-ek automatikus
generálására. A megfelelő eszköztámogatással ez automatikusan elvégezhető, de ennek
hiányában manuálisan is megtehető. Így a FlowCard lehetővé teszi számunkra, hogy
megragadjuk és vizuálisan ábrázoljuk az Ergo dApp összes tervezési választását és
szemantikai részletét.
A következő lépés az lesz, hogy mechanikusan létrehozzuk a buyOrder szerződést az
információk alapján, amelyeket a DEX flow cardban adtunk meg.
Emlékezzünk arra, hogy minden script egy javaslat (logikai értékű kifejezés), amelynek
true-ra kell értékelődnie ahhoz, hogy lehetővé tegye a doboz költését. Amikor
sok feltételt kell teljesíteni egyszerre, azokat logikai képletté egyesíthetjük az
ÉS bináris művelet használatával, és ha alternatíváink vannak (nem feltétlenül
exkluzívak), akkor azokat az V műveletbe helyezhetjük.
A buyOrder doboznak az alternatív költési útvonalai !cancel és !swap. Így az
ErgoScript kódnak V műveletet kell tartalmaznia két argumentummal - egyet minden
költsési útvonalhoz.
/** buyOrder szerződés */
{
val cancelCondition = {}
val swapCondition = {}
cancelCondition || swapCondition
}
A cancelCondition kifejezés képlete a buyOrder doboz !cancel költési
útvonalán található. Közvetlenül beilleszthetjük a scriptbe.
/** buyOrder szerződés */
{
val cancelCondition = { buyer }
val swapCondition = {}
cancelCondition || swapCondition
}
A buyOrder doboz !swap költési útvonalához a feltételek a Swap tranzakció
buyerOut output dobozában vannak meghatározva. Ha egyszerűen beillesztjük őket a
swapCondition-be, akkor szintaktikailag helytelen scriptet kapunk.
/** buyOrder szerződés */
{
val cancelCondition = { buyer }
val swapCondition = {
tAmt: TID &&
R4 == bid.id &&
@contract
}
cancelCondition || swapCondition
}
Azonban lefordíthatjuk a diagram feltételeit ErgoScript kifejezésekké a következő
egyszerű szabályok használatával:
buyerOut@0==>val buyerOut = OUTPUTS(0)tAmt: TID==>tid._2 == tAmtaholtid = buyerOut.tokens(TID)R4 == bid.id==>R4 == SELF.idaholR4 = buyerOut.R4[Coll[Byte]].getscript == buyer==>buyerOut.propositionBytes == buyer.propBytes
Megjegyzés, a diagramon a TID egy token azonosítót képvisel, de az ErgoScript
nem fér hozzá a tokenekhez az azonosítók alapján, így nem írhatjuk tokens.getByKey(TID).
Ennek következtében, amikor a diagramot ErgoScript-re fordítják, a TID a doboz
tokens gyűjteményének indexének névleges állandójává válik. Az állandó konkrét
értéke akkor van hozzárendelve, amikor a BuyOrder tranzakció a buyOrder dobozzal
létrejön. Az aktuális tokenId, a TID állandó és a buyerOut doboz tényleges tokenjei
közötti megfelelőséget és konzisztenciát az off-chain alkalmazás kód biztosítja,
ami teljesen lehetséges, mivel az összes tranzakciót az alkalmazás hozza létre a FlowCard
mint irányadó specifikáció használatával. Ez bonyolultnak tűnhet, de ez a diagram
specifikáció és a tényleges végrehajtható alkalmazáskód közötti fordítás része, amelynek
nagy része automatizálható.
A transzformáció után helyes scriptet kaphatunk, amely ellenőrzi az összes szükséges
előfeltételt a buyOrder doboz költéséhez.
/** buyOrder szerződés */
def DEX(buyer: Addrss, seller: Address, TID: Int, ergAmt: Long, tAmt: Long)
{
val cancelCondition: SigmaProp = { buyer } // ellenőrzi a vásárló aláírását (ProveDlog)
val swapCondition = OUTPUTS.size > 0 && { // biztosítja az OUTPUTS hozzáférést
val buyerOut = OUTPUTS(0) // a buyerOut@0-ból
buyerOut.tokens.size > TID && { // biztosítja a tokenek hozzáférését
val tid = buyerOut.tokens(TID)
val regR4 = buyerOut.R4[Coll[Byte]]
regR4.isDefined && { // biztosítja az R4 hozzáférését
val R4 = regR4.get
tid._2 == tAmt && // a tAmt: TID-ből
R4 == SELF.id && // az R4 == bid.id-ből
buyerOut.propositionBytes == buyer.propBytes // a script == buyer-ből
}
}
}
cancelCondition || swapCondition
}
Hasonló scriptet a sellOrder dobozhoz is létrehozhatunk a fenti fordítási szabályok
használatával. Az eszközök segítségével a szerződések kódja mechanikusan generálható
az ábra specifikációjából.
Következtetések
A deklaratív programozási modellek már megnyerték a csatát az imperatív programozás
ellen sok alkalmazási területen, mint például Big Data, Stream Processing, Deep Learning,
Adatbázisok, stb. Az Ergo úttörő szerepet játszik a dApp fejlesztés deklaratív modelljében,
mint jobb és biztonságosabb alternatíva a most népszerű imperatív okos szerződés
modellhez.
A FlowCard koncepciója a figyelmet a szerződések írásáról az értékek áramlására
(onnan a név) helyezi, úgy, hogy az ErgoScript mindig generálható legyen belőlük.
Soha nem kell megnéznie az ErgoScript kódot, amint az eszközök a helyükre kerülnek.
Itt vannak a lehetséges következő lépések a jövőbeli munkához:
-
Tárolási formátum a FlowCard Spec és a megfelelő EIP szabványosított fájlformátum
(Json/XML/Protobuf). Ez lehetővé teszi különböző eszközök (Diagram Szerkesztő, Futási idő,
dApp-k stb.) számára, hogy*.flowcardfájlokat hozzanak létre és használjanak. -
FlowCard Néző, amely generálhatja a diagramokat
*.flowcardfájlokból. -
FlowCard Futási idő, amely képes futtatni
*.flowcardfájlokat, tranzakciókat létrehozni
és küldeni az Ergo hálózatra. -
FlowCard Tervező Eszköz, amely egyszerűsítheti a bonyolult diagramok fejlesztését.
Ez kellemes élménnyé teszi az Ergo szerződések tervezését és érvényesítését, inkább
rajzolásra hasonlít, mint kódolásra. Ezenkívül a teljes dApp forgatókönyv helyessége
ellenőrizhető és kontrollálható az eszközök által.
Hivatkozások
Share post
2025. augusztus 13.
2025. augusztus 12.
2025. július 9.
2025. május 12.






