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,
mivel az ErgoScript koncepcionálisan 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, például az Ethereumhoz kapcsolódnak. 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 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 megkülönböztetik:
Paradigma
Az Ethereum fiók modellje imperatív. Ez azt jelenti, hogy a tipikus feladat, hogy érméket küldjünk
Alice-tó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 elfogadásához a blokkláncon (nem a tároló állapotának megváltoztatására
az okos 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
a láncon 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 összes csomópont által végrehajtott műveletek számát a hálózaton. Ezen kívül, a tranzakciós
grafikon megváltoztathatatlansága miatt különböző optimalizálási stratégiák lehetségesek a tranzakciók
másodpercenkénti á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
bonyolult 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 grafikonra
épül. Ez a megközelítés, amely a Bitcointól származik, jól illeszkedik a blokkláncok párhuzamos és
megosztott 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 gázköltségek, amelyek korlátozzák a szerződések
bonyolultságát, és más 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 bonyolultságát.
Ugyanazt a kifejezőerőt egy másik és szemantikailag megalapozottabb módon érik el.
A fent említett összes ponttal 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ői 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 egyenlegeket),
és végül közzéteszi a posztfeltételt a Sent eseményként. A tranzakció által felhasznált gáz
jutalomként kerül a bányászhoz 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 egyenlegé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
az adott token küldési példához nem kell 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,minErg
ERG-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 tartalmazza
B - minErg - txFeeERG-t éstB - amountTtokent. - 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 Transaction API használatával)
a felhasználó alkalmazása á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 módosítjuk az egyenlegeket és frissítjük a tárolót egy konkrét parancssorozattal.
Ez on-chain történik, és így egy új tranzakció is létrejön on-chain ennek a folyamatnak
az eredményeként.
Az Ergóban (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 ErgoScript használatára, amelyről most 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 az egyenlegeket
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óban, 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 a blokkhoz hozzáadhatnánk. Ezt teszik az ErgoScript
szerződések.
Nem lehetséges az "állapot megváltoztatása" az ErgoScript-ben, mert ez egy nyelv a költési
érvényességi feltételek 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. Ez azt jelenti, hogy
minden bemenet, kimenet és más tranzakciós paraméter, amely elérhető egy scriptben, megváltoztathatatlan.
Ez, más dolgok mellett, az ErgoScript-et egy 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öltségét (azaz eltávolítva a 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, hogy az ErgoScript az
Ergo szerződések nyelve, mert ez a javaslatok (logikai predikátumok, formulák, stb.) nyelve,
ami megvédi a dobozokat az "illegális" költéstől. A Bitcoinhoz képest az Ergóban az egész
tranzakció és a jelenlegi blokklánc kontextusának 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égei (ezt a képességet a példánk DEX szerződéseiben fogjuk használni), a jelenlegi blokk
száma stb.
_ Az ErgoScript-ben meghatározza a feltételeket, hogy a változások (azaz a coin költés) 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 egy sor alkalmazást nyit meg, mint például (DEX, DeFi
alkalmazások, LETS, stb.), a szerződések tervezése mint előfeltételek a coin költéshez (vagy
védő scriptként) közvetlenül nem intuitív. A következő szakaszokban egy hasznos grafikus
jelölést fogunk figyelembe venni a szerződések deklaratív tervezésére FlowCard Diagramos
formájában, amely egy vizuális reprezentációja a végrehajtható komponenseknek (FlowCards).
A FlowCards célja, hogy radikálisan leegyszerűsítse a dApp fejlesztést az Ergo platformon,
magas szintű deklaratív nyelvet, végrehajtási futási időt, tárolási formát és grafikus
jelölést biztosítva.
Magas szintű diagramokkal kezdünk, és lemegyünk a FlowCard specifikációra.
FlowCard Diagramos
A FlowCard diagramok mögötti ötlet a következő megfigyeléseken alapul: 1) Egy Ergo doboz
meg nem változtatható, é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 beáramló
dobozok elköltésre kerülnek, míg a kiáramló dobozok létrejönnek és hozzáadódnak az UTXO-hoz. - Egy tranzakció ebből a szempontból egyszerűen egy régi dobozok új dobozokká való átalakítója,
tartva az érintett ERG-k és tokenek egyenlegé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 reprezentációja (vagy nézete) az alapul szolgáló végrehajtható komponensnek
(FlowCard-nak) nevezik.
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 card-ot elneveznek és egy típusú paraméterek listáját kapja. Ez hasonló egy
paraméterekkel rendelkező sablonhoz. A fenti ábrán láthatjuk a Send flow card-ot, amely öt paramétert tartalmaz.
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
script 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 egy
Address típusú paraméter. Az ábrán a script sablon a pk(sender) paraméterre van alkalmazva,
és így egy konkrét tárca szerződést kapunk. Ezért a pk(sender) és pk(receiver)
különböző scripteket 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
template pk, és a pubkey paramétert a sender flow card paraméterével helyettesítjük.
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.
Megjegyzendő, hogy a pk(sender) a pk sablon példányosítása a konkrét sender paraméterrel,
a minerFee pedig a bányász jutalom dobozait védő előre definiált szerződés példányosítása.
4. Doboz név
A diagramon minden doboznak adhatunk nevet. 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 a OUTPUTS(2) helyett.
A doboz neveket a költési feltételek társítására is használjuk a dobozokkal.
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 van
kapcsolva, akár narancssárga, akár zöld nyilakkal, vagy mindkettővel. Egy output doboz
(bemenő zöld nyíllal) sok szövegsort tartalmazhat, ahol minden sor egy feltételt határoz meg,
amit a tranzakció részeként ellenőrizni kell. Az első sor a dobozba helyezendő ERG mennyiségére vonatkozó
feltételt határozza meg. A többi sor az alábbi formák egyikét vehetik fel:
amount: TOKEN- a doboznak tartalmaznia kell a megadottamountmennyiségű megadottTOKEN-t.R == value- a doboznak tartalmaznia kell a megadottvalue-t a megadottRregiszterben.boxName ? condition- aboxNamenevű doboznak ellenőriznie kell acondition-t a scriptjében.
Ezeket a feltételeket az alábbi szakaszokban vitatjuk meg.
6. ERG-k mennyisége a dobozban
Minden doboznak tárolnia kell egy minimális mennyiségű ERG-t. Ezt akkor ellenőrzik, amikor a
létrehozó tranzakciót érvényesítik. A diagramon az ERG-k mennyisége mindig az első sorban
látható (pl. B: ERG vagy B - minErg - txFee). Az érték típusú hozzárendelés B: ERG opcionális,
és olvashatóság érdekében használható. Amikor az érték képletként van megadva, akkor ezt a képletet
be kell tartani a tranzakciónak, amely létrehozza a dobozt.
Fontos megérteni, hogy az olyan változók, mint amount és txFee, nem a dobozok név szerinti
jellemzői. Ezek a diagram egészének paraméterei, amelyek valamilyen mennyiségeket képviselnek.
Vagy más szavakkal, ezek a tranzakciók közötti megosztott paraméterek (pl. A Sell Order és a Swap
tranzakciók a DEX példában megosztják a tAmt paramétert). Így a ugyanaz a név a diagram
során ugyanahhoz az értékhez van kötve (itt a szerszámok sokat segítenének). Azonban, amikor a
_ on-chain _ érvényesítésekről van szó, csak a ?-val megjelölt explicit feltételek kerülnek
átalakításra ErgoScript-re. Ugyanakkor minden más 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ége
Egy doboz sok token értéket tárolhat. A diagramon a tokenek elnevezettek, é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 például 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 elegendőek a szükséges védő scriptek szintetizálásához.
(több erről az alábbi "A Diagramból ErgoScript Szerződésekhez")
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 indexszel, azazfee@0vagy@2. Ez a nyíl célpontjának
jellemzője. A név a kapcsolódó dobozok feltételeiben használatos, és azindexa tranzakció
INPUTS gyűjteményében a megfelelő doboz helye.!action- a nyíl forrásának jellemzője, és egy alternatív költési útvonal nevével látja el a dobozt
(ebben a DEX példában látni fogjuk)
Az alternatív költési útvonalak miatt egy doboznak sok kimenő narancssárga nyila lehet,
az ilyen esetekben 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 dobozokat a
narancssárga nyilak adják meg, és a címkéknek a megfelelő indexekre kell helyezniük a
INPUTS gyűjteményben. Az output dobozokat a zöld nyilak adják meg. Minden tranzakciónak
meg kell őriznie az ERG értékek szigorú egyensúlyát (bemenetek összege == kimenetek összege),
és minden token esetében a bemenetek összege >= a kimenetek összege. A tervezési diagram
kifejezett 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
lehet a következő formában: name@index, ahol egy opcionális név indexszel van kísérve,
azaz fee@0 vagy @2. Ez a nyíl forrásának jellemzője. A név a kapcsolódó dobozok feltételeiben
használatos, és az index a tranzakció OUTPUTS gyűjteményében a megfelelő doboz helye.
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 számára. Elég
egyszerű, de ugyanakkor 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 váltani (vagy fordítva,
a eladó TID tokeneket szeretne ERG-re eladni, hogy ki küldi el a rendelést először, az nem
számít). Mind a vásárló, mind az eladó bármikor törölheti a rendelését. A DEX off-chain
illesztő szolgáltatás megtalálja a megfelelő rendeléseket, és létrehozza a Swap tranzakciót,
hogy befejezze a cserét.
A következő diagram teljesen (és formálisan) specifikálja az öt tranzakciót, amelyeket a DEX dApp-nak
off-chain kell létrehoznia. Ez is specifikálja az összes költési feltételt, amelyeket on-chain
e kell ellenőrizni.

Beszéljük meg a FlowCard diagramot és minden tranzakció logikáját részletesen:
Vásárlási Rendelés Tranzakció
A vásárló létrehoz egy Buy Order tranzakciót. A tranzakció E mennyiségű ERG-t
(kibővítjük E: ERG) költ el a pk(buyer) tárcából. 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
szerkeszthető (lásd alább a "A Diagramból ErgoScript Szerződésekhez"), akár manuálisan,
vagy automatikusan egy eszköz által. Bár a tervezés során nem kell kifejezetten definiálnunk a
buyOrder scriptet, a futásidő alatt a bid doboznak tartalmaznia kell a buyOrder
scripttel, mint védő javaslattal (amely ellenőrzi a doboz költési feltételeit), különben a diagramon
meghatározott 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 a Swap) eseteit, ahol sokféleképpen lehet kifizetni a tranzakciós díjat.
Vásárlás Törlése, Eladás Törlése Tranzakciók
Bármikor a buyer törölheti a rendelé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 spending paths) vannak,
akkor minden alternatívát egy egyedi név az ! előtaggal azonosítunk (!cancel és !swap
a bid dobozhoz). Minden alternatív útnak 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 olvasunk, hogy "a buyer cím aláírásának a tranzakcióban kell szerepelnie". Ezért
csak a vásárló törölheti a vásárlási rendelést. Ez a "signature" feltétel csak a !cancel
alternatív költési úton szükséges, és nem szükséges a !swap-nál.
Eladási Rendelé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
(a pk(seller) szerződés szerint). A két output a ask és a change. A change
egy standard doboz a tranzakció egyensúlyának megőrzésére. Az ask doboz tAmt: TID
tokeneket tartalmaz az cserére, és minErg: ERG - a minimum mennyiségű ERG, amely minden dobozban
kell, hogy legyen.
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
scriptekben 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
vannak meghatározva, hanem a tranzakció output dobozaiban.
Ez egy konvenció a jobb használhatóság érdekében, mert a legtöbb feltétel a kimeneti dobozok
jellemzőivel kapcsolatos. Megadhatnánk ezeket a jellemzőket 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
buyerOut néven hivatkozhatjuk. Így mind a dobozt, mind a nyilat címkézhetjük, hogy nevet adjunk a doboznak.
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 legyen.R4 == bid.idmegköveteli, hogy a doboz R4 regisztere egyenlő legyen abiddoboz id-jével.script == buyermegköveteli, hogy abuyerOutdoboz a diagramon található tárca scriptjét
tartalmazza, azazpk(buyer).
Hasonló jellemzők kerülnek hozzáadásra a sellerOut dobozhoz, amelyet az 1 indexre
specifikáltak, és a nevét a doboz címkéje alapján adják meg, nem pedig a nyíl alapján.
A Swap tranzakció a bid és ask dobozokat költi el a !swap költési úton mindkettőn,
de a !cancel-tól eltérően az úton a feltételek nincsenek meghatározva. Itt jönnek
játékba a bid ? és ask ? előtagok. Ezeket azért használják, hogy a buyerOut és
sellerOut dobozokban felsorolt feltételek a bid és ask dobozok !swap költési
útjára kerüljenek.
Ha megnézzük a kimeneti dobozok feltételeit, láthatjuk, hogy pontosan meghatározzák
az értékek cseréjét az eladó és a vásárló tárcái között. A vásárló megkapja a szükséges
mennyiségű TID tokent, é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 Diagramból ErgoScript Szerződésekhez
A FlowCard specifikációk érdekessége, hogy felhasználhatók a szükséges ErgoTree scriptek automatikus generálására.
A megfelelő szerszám támogatásával ez automatikusan elvégezhető, de ennek hiányában
manuálisan is megtehető. Így a FlowCard lehetővé teszi számunkra, hogy rögzítsük é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ünk az lesz, hogy mechanikusan létrehozzuk a buyOrder szerződést az
információk alapján, amelyeket a DEX flow card-ban 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 egyszerre teljesíteni, azokat logikai képletté egyesíthetjük az AND bináris
művelet használatával, és ha alternatíváink vannak (nem feltétlenül kizárólagosak),
akkor azokat OR műveletbe helyezhetjük.
A buyOrder doboznak alternatív költési útvonalai vannak !cancel és !swap. Így az
ErgoScript kódnak OR műveletet kell tartalmaznia két argumentummal - egyet minden költé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 !swap költési útvonal feltételei 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 szintaxisát 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
Megjegyzendő, hogy 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).
Ezért, amikor a diagramot ErgoScript-re fordítják, a TID a doboz tokens gyűjteményének
indexének elnevezett konstansává válik. A konstans konkrét értéke akkor van hozzárendelve,
amikor a BuyOrder tranzakció a buyOrder dobozzal létrejön. A tényleges tokenId, a TID
konstans és a buyerOut doboz tényleges tokenjei közötti megfelelőség és konzisztencia
_ off-chain _ alkalmazás kódja biztosítja, ami teljesen lehetséges, mivel az összes tranzakciót
az alkalmazás hozza létre a FlowCard mint irányadó specifikációval. Ez bonyolultnak tűnhet,
de ez a diagram specifikációjának tényleges végrehajtható alkalmazás kódra való fordításának
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. A szerszámok segítségével a szerződések kódja mechanikusan generálható a
diagram 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,
jobb és biztonságosabb alternatívát kínálva a most népszerű imperatív okos szerződés modellhez.
A FlowCard koncepciója a figyelmet a szerződés írásáról az értékek áramlására helyezi (innen a név),
úgy, hogy az ErgoScript mindig generálható legyen belőlük. Soha nem kell megnéznie az
ErgoScript kódot, amint a szerszámok a helyükön vannak.
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-ok stb.)
számára, hogy létrehozzák és használják a*.flowcardfájlokat. -
FlowCard Néző, amely generálhatja a diagramokat a
*.flowcardfájlokból. -
FlowCard Futási idő, amely képes futtatni a
*.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,
mint kódolásra hasonlítva. Ezen kívül a teljes dApp forgatókönyv helyessége ellenőrizhető
és kontrollálható a szerszámok által.
Hivatkozások
Share post
2025. augusztus 13.
2025. augusztus 12.
2025. július 9.
2025. május 12.






