Miért vagyok az Ethereummal eddig… eddig… eddig…

Bő egy éve folyik aktívan az INLOCK körüli szolgáltatások fejlesztése, aminek az egyik nagyon fontos részét képezi a nyílt blokkláncokkal történő kapcsolattartás. Mit is jelent ez pontosan? Egy teljesen online rendszer esetén nyilvánvaló, hogy pl. a deposit (beutalás), withdraw (kiutalás) és a különböző (pl. exchange) művelet is teljesen automatikusan működjenek. Akinek kellett valaha is programoznia pl. Bitcoin ÉS Ethereum payment gatewayt az tudja pontosan, hogy miért pofon egyszerű ez a Bitcoin (és klónjai) esetén és miért egy totális világégéssel felérő katasztrófa az Ethereum kapcsán.

Aki viszont nem…

… annak álljon érdekességként itt ez a cikk. Anélkül, hogy túlságosan belevezetném az olvasót a technológia mélységeibe nézzük, hogy miért is annyira nagyon különböző a két technológia: a nyílt blokkláncoknál közismert tény, hogy a blokklánc valamilyen elv mentén tárolja az értékeket. Ez Bitcoin esetlén az UTXO (unspend transaction output), míg Ethereum kapcsán a blokkonkénti balance nyilvántartás.

Mit jelent ez a gyakorlatban? A Bitcoin esetén onnan tudod, hogy mennyi egy address egyenlege, hogy megnézed az adott addresshez tartozó összes UTXO-t és azok amountját összegzed, míg ezzel szemben az Etheruem-ban könnyedén le tudod kérni egy adott address egyenlegét, sőt node típustól függően akár visszamenőlegesen is le tudod kérni, hogy X blokkal korábban mennyi volt az egyenlege, így látszólag sokkal könnyebben tudsz pl. egy fizetésforgalmi szolgáltatást fejleszteni Ethereumra, hiszen a (geth/parity) node a kezed alá ad mindent. Blokkonként tudod a fogadó címek egyenlegét és a blokkból szépen ki is tudod olvasni, hogy az adott címre mennyi Ethereum érkezett. Ergo könnyedén lehet kezelni pl. a blokklánc elágazásait (Uncle blokkok), és ha megfelelő mennyiségű confirmationt hagysz rá, akkor egész komoly reorgok esetén sem kell attól félned, hogy olyan egyenleget írsz jóvá, ami valójában nem is létezik.

UTXO: A blokklánc nodejai egy kivonatot képeznek az összes el nem költött outputról, amik összege explicit megadja egy address szabadon felhasználható balanceát. A Bitcoin és abból forkolt blokkláncok az UTXO technológiát használják az egyenlegek nyomon követésére.

Uncle blokk: Ethereum esetén azon blokkok, amik bár elkészültek és propagálódtak is, de nem képezik részét a főláncnak.

Reorg: Ha egy blokk uncle-be kerül, akkor a nodeok újraépítik a saját főláncukat az uncle előtti állapotból, ezt a folyamatot nevezzük blokklánc reorganizációnak.

Ezen a ponton persze feltehetnénk a kérdést, hogyha egyszer ennyire egyszerű ás kezesbárány az Ethereum, akkor mégis mi is a bajom vele? Az ördög ezúttal is a részletekben lakozik.

Gaslimit nightmare

Kezdem a legtriviálisabbal, a gaslimittel, amivel bárki találkozhatott már. Az Ethereum egy blockchain alapú turing complete állapotgép, amiben tetszőleges kód futtatható. A kódok (smart contractok) futási költségét a platform fee-ben, Etherben kell megfizetni, amit ugye ilyen kontextusban gas-nak nevezünk. Egy kontraktus futtatásának ára attól függ, hogy pontosan mi fog lefutni, ez azonban, függően a feltételektől, ciklusoktól, stb. nem feltétlenül determinisztikus. Ha egy idegen contractot akarunk meghívni, akkor tudnunk kellene előre, hogy mennyi gas-t is adjunk neki, de erre nem igazán van mód. A legtöbb wallet megpróbál keresni korábbi tranzakciókat ugyanezen smartcontract adott funkciójára és abból végzi el a becslést ám ez általában nem tud megtörténni valós időben. Mi a megoldás? Küldjük el jól megpakolt puttyonnyal, adjunk meg egy olyan gaslimitet amibe biztos bele fog férni a szükséges mennyiségű gas. Ezzel csak annyi a baj, hogy a maradék gas (ami nem lett elhasználva) az a küldő számlán marad, ennek köszönhetően az Ethereum hálózat ma tele van sok-sok millió olyan addressel amin csak egy kis dust marad, olyan kevés Ether amit onnan képtelenség lenne kiutalni, hiszen az ehhez szükséges gas sokkal többe kerülne, mint ami ott pihen.

Transfer into -» Contract

Ha már gaslimit, akkor nézzük a másik nagyon kellemetlen dolgot. Amikor tömegesen kell kiszolgálni tranzakciókat (automatizmussal), akkor bizony gyakran ütközhetünk olyan esetbe, hogy tévesen azt hisszük, hogy egy walletbe akarunk utalni, holott valójában egy sc-be utalunk. Egy addressről az Ethereum esetén nem derül ki, hogy az sima wallet, vagy egy smart contract. Ehhez szintén az explorerekhez kell nyúlni. Ether-t transzferelni wallet címre 21.000 gaslimittel lehet. Tehát függően a hálózat terheltségétől fixen 21k gas (* gasprice) elég ahhoz, hogy tetszőleges mennyiségű Etheret küldj egyik számláról a másikra.

Azonban, ha a fogadó cím egy smart contract, akkor ebből garantáltan “out of gas” lesz, amire mind a küldő automatizmust fel kell készíteni, mind pedig számolni kell azzal, hogy ilyenkor az elburnölt gas-t is bukjuk.

Aki azt hiszi, hogy ez a probléma csak a fejlesztők gondja, hiszen csak ők meg az ICO-k használnak smart contractot az nagyot téved. Már majd az összes exchange és payment provider smart contractokat használ. Amikor beutalsz pl.: Etheret a Binancera és kérsz egy beutalási address-t, majd arra felelőtlenül beutalsz 21k gaslimittel, akkor garantált a “out of gas” revert. Hogy mutassak erre a példát, a fentebb már említett Binance egyik swiper (besöplő) addressén lévő contract fallback funkciója így néz ki:

function () public payable { }

Aki egy kicsit is konyít a solidityhez az pontosan tudja, hogy ez annyit jelent, hogy a contract tud fogadni és tárolni Ethereumot külön funkció hívás nélkül. Tehát nincs semmi extra kód, csak jelölve van, jöhet a lóvé. Amikor Ether érkezik egy ilyen címre, akkor ez a semmi kód fut le. Ennek a semmi kódnak az ára 51 gas, tehát ha erre a címre akarsz utalni, akkor tudnod kell, hogy nem 21000 gaslimitet kell beállítanod, hanem 21051-et…

Tehát ha akarsz egy saját payment providert vagy saját walletet fejleszteni, akkor tárold le és indexeld fel az összes valaha történt tranzakciót, vagy ha nem akarod, akkor használd a nyilvános apikat, amik vagy működnek vagy nem, esetleg fizess elő valamelyik fizetős api endpointra, ami vagy jó adatot ad, vagy nem… Ez aztán a decentralizáció csúcsa kérem szépen.

Transfer over » Contract

De ne akadjunk le ennyire a gaslimit körül. Nézzünk egy igazi csemegét! Mint ahogy fentebb is írtam, az Ethereum azért jó, mert minden blokkban pontosan tudod az addresseid egyenlegét, így nem kell folyamatosan rekonsziliálni az egyenlegeket az UTXO-kból, ráadásul validálni is tudod, hiszen az adott blokkban ott vannak a tranzakciók amik az adott addressre mutatnak, amiket ezáltal könnyedén ki lehet gyűjteni és tárolni.

Ez egészen addig igaz is amíg csak wallet«»wallet műveletekről beszélünk. Ha a küldő fél egy smart contract, akkor a balance változásról SEMMILYEN evidencia nem kerül rögzítésre a blokkláncon. Ez így elég zordul hangzik, nemde? Hogy egy kicsit tompítsam, semmilyen evidencia nem kerül tárolásra, amit egy automatizmussal fel lehetne dolgozni.

Az előző pontban már bemutattam, hogy lehet Ethert küldeni egy smart contract fallback addressére. Azonban a smart contract számláján lévő Ethert onnan ki is lehet utalni, amit rendszerint a contract egy funkciójának meghívásával lehet elérni. A fentebbi binance contractban ez így néz ki (kiszedve belőle a tokenes részt…)

   function sweep(address _token, uint _amount)
    canSweep
    returns (bool) {
        bool success = false;
        address destination = controller.destination();
        uint amountInWei = _amount;
        if (amountInWei > this.balance) {
                return false;
        }
        success = destination.send(amountInWei);
        return success;
    }

Ebből ugye a destination.send(…) a lényeg. Ez egy teljesen standard web3 hívás (send), ami külön eventként nem kerül belogolásra a blokkláncon. Mindez lefutva így néz ki:

Function: sweep(address _token, uint256 _amount) ***

MethodID: 0x6ea056a9
[0]:  0000000000000000000000000000000000000000000000000000000000000000
[1]:  00000000000000000000000000000000000000000000000002c79bc9ec82c000

Tehát ha szeretném megtudni, hogy az én egyik addressemre érkezett-e pénz egy ilyen contractból, akkor tudnom kellene, hogy az adott contract sweep funkciójával lehet Ethert küldeni, de még az sem elég, ha ezeket a contract hívásokat figyelem, mivel a sweep() függvény paraméterei között nincs ott a célcím, mivel azt contract egy másik osztályából szedi. Tehát a blokkláncon SEMMI nyoma nem marad annak, hogy honnan hova mennyi pénz került utalásra.

Ha ez így van, akkor pl. egy etherscan.io, vagy bármely másik explorer hogyan tudja kihámozni az ilyen műveleteket? Nos a legtöbb (jobb) explorer kényszerből egy igen csak költséges trükköt alkalmaz. Nevezetesen folyamatosan tárolják a teljes tracelogot, amiből kihámozzák, hogy történt-e contracton belüli utalás. A tracelog nem része a blokkláncnak az a blokklánc validálása során tud keletkezni azáltal, hogy a geth vagy parity a lánc újraépítése során lefuttat minden tranzakciót újra amit a minerek is lefuttattak és így ellenőrzi mindennek a kimenetelét.

Tehát mi kell ahhoz, hogy meggyőződj arról, hogy honnan jött Ether egy általad kezelt címre?

  • Minden újabb blokknál ellenőrizd az egyenlegét az addressnek, ha változott, akkor tuti történt valami, ha nem, az sem bizonyíték semmire, hiszen lehet hogy blokkon belül történt két azonos összegű de ellenirányú művelelet… (Ez az első facepalm…)
  • Mivel a block balance legjobb szándékkal is csak indikatív információ, ezért nézzük meg hogy milyen tranzakciók töréntek. Mondjuk látjuk, hogy sima transfer nem történt, DE a balance változott (másik facepalm… itt már tiszta, hogy contract transfer történt)
  • Ezek után keríts az adott blokkhoz egy teljes tracelogot és nézd végig, hogy van-e olyan funkcióhívás benne, ami a Te addressedre küldött Etheret.

Mondhatnátok, hogy ez azért nem annyira nagy kaland. Azonban Ethereumban nem csak egyféleképpen lehet Ethert küldeni contractból, csak néhány példa:

  • <address>.send(weitosend)
  • <address>.transfer(weitosend)
  • <address>.call.gas(_g).value(weitosend)
  • <address>.call.gas(_g).value(_wei)(method_id), _p1 … )
  • <address>.call.gas(_g).value(_wei)(bytes4(keccak256(‘pay(uint256)’)), _p1 … )
  • <address>.delegatecall.gas(_g)( _methodId, _p1, _p2, …)

És ez csak néhány példa, közel sem a teljes repertoár…

Token transfer nightmare

Röviden kitérnék a tokenekre is, mivel ez szintén egy olyan issue, amivel bárki találkozhat. Bár az INLOCK éles szolgáltatásai kevesebb, mint egy hónapja futnak, de már nálunk is megtörtént, hogy az egyik ügyfél tévedésből nem ILK tokent utalt be hozzánk, hanem egy másik tokent. Ilyenkor az ügyfél persze jajveszékelve ír a supportnak, hogy tévedés történt és kérné vissza a tokenjét, amit egyelőre (mivel kicsik vagyunk), így készséggel meg is tudunk tenni, azonban jó oka van annak, hogy ilyen esetekben a nagy exchangek vagy eleve kizárják a nem támogatott tokenekkel kapcsolatos ügyintézést, vagy ezeket egy hosszú és fárasztó bürokratikus útvesztőbe terelik be.

Ennek oka igen prózai: bár az Ethereum nagyon szépen tárolja minden egyes blokkban az összes address egyenlegét, azonban ugyanilyen lelkesedéssel már nem teszi meg ugyanezt a token balanceokkal. Tehát honnan tudhatom meg, hogy az egyik addressemen menni ILK token van? Onnan, hogy meghívom a INLOCK contract balanceOf() függvényét. Honnan tudom meg, hogy mennyi OmiseGo token van ugyanezen az addressen? Meghívom az OmiseGo smart contractjának is a balanceOf() függvényét. Honnan tudom meg, hogy további 100 tokenből mennyi van? Meghívom azokat is…

És honnan tudhatom meg, hogy pl. egy adott blokkban érkezett-e az egyik addressemre ILK token? Onnan, hogy figyelem a blokkon belül az INLOCK smart contract transfer() hívásait. Honnan tudhatom meg, hogy egy address-en mennyi féle token van? SEHONNAN. Ilyen funkció nem létezik. Ha ezt szeretném, akkor az összes általam ismert token smart contract balanceOf() függvényét kéne meghívnom vagy a transfer() függvényét kellene nyomon követnem.

Nos ez az oka annak, amiért a wallet providerek vagy az exchangek a falra tudnak mászni attól, hogyha valaki bejelentkezik nálunk egy rosszul utalt token visszakérése kapcsán és pont ezért van az, hogy a legtöbb ilyen szolgáltató inkább eleve contract deposit addresseket ad, sima helyett, ahol meg tudja oldani kódból az ilyen tévesen odautalt tokenek összesöprését.

Konkludáljunk…

Mindezen példák persze csak a jéghegy csúcsai. A web3 layeren és az egyes node típusok szintjén még számtalan egyéb ennél is meredekebb facepalm létezik, amikre mindre fel kell készülnie annak, aki kimozdul a meglévő walletek és exchangek kényelmes világából és úgy dönt, hogy valamilyen saját natív alkalmazást akar építeni az Ethereum blokkláncra.

Akkor amikor Vitalik és barátai Ethereum 2.0-ról álmodnak, akkor csak helyeselni tudok. Ami most, ma az Ethereum az legjobb szándékkal is csak egy deszkamodellnek nevezhető, amin bőven van mit hegeszteni és jobbá tenni ahhoz, hogy ez bármikor is a mainstream adaptáció szintjére léphessen. Lehet itt (és kell is…) álmodozni Casperről, PoS-ról, Plasmáról és Shardingról, de ha ezzel párhuzamosan nem találnak ki valamit a fentebb felsorolt issuekra, az nagyon komolyan visszavetheti az üzleti adaptációt, mivel jelenleg finoman szólva is orosz rulett az egész hálózat. Egy olyan blokkláncról kell folyamatosan manuálisan rekonsziliálni információkat (tracekből és akár több ezer contract-ból egyszerre), amin bármikor bekövetkezhet egy uncle és akár 2-3 blokkra visszamenőlegesen is tudni kell reorgolni a tracekből és eventekből kihámozott információkat.

Ez egyelőre nem az a szint amire holnap már indulhat is az OKJ-s blockchain analyst, kóder, whatever képzés… (Márpedig a mainstream adoptationhez ugyebár ez nem ártana…)

Bookmark the permalink.

12 Comments

  1. Végeredményben már egy csomó Ethereum 2.0 létezik, más kérdés, hogy nem úgy hívják őket.

    • Ahogy eljutunk odáig, hogy a jelenlegi 3+1 támogatott crypto mellett elkezdjük bevonni a platformra a további cryptofabartkákat is, akkor várható hogy ezekről is születik hasonló post… Főleg, ha ugyanilyen körülményes implementációkba ütközünk.

  2. Köszönjük. Ennek fényében még a 110 dollár is sok az Eth-ért. Kérdés h a többi fejlesztő eszköz pl. Eos stb. Nem e jobb.

  3. Vitalikék nem gondolták át ezt eléggé, pedig valahol úgy éreztem az ethereum hálózat jobb mint a bitcoin, már legalábbis fejlettebb a smart contractok miatt, de ezek szerint a fejlesztés is nehezebb rá.

    Amúgy inlock pörög? Vagy pang a piac? Csak mert az ethscan-es block explorer nem mutat nagy aktivítást és nem tudom jól látom-e.

    • Az elmúlt években nagyon sokszor előkerült már az az érv, hogy a Bitcoin Core fejlesztők hatalmas hibát vétettek akkor, hogy mikor nem hagyták Vitaliknak, hogy a BTC láncon élje ki magát és “elüldözték”. Túl az egész felvetés nonszenzitásán mai fejjel azt tudom mondani, hogy bármit is akart Vitalik csinálni a BTC láncon… jobb, hogy nem engedték neki. Önmagában az Ethereum egy remekmű, de valóban csak egy béta állapotú valami, amit az évek során komolyan toldoztak és foltoztak és ezt nem feltétlenül a legszebb módon tették, ennek az eredménye az amit a fentebbi cikkben is leírtam.

      INLOCKra: Mi most a fejlesztésre koncentrálunk, hogy minél hamarabb le tudjuk rakni azokat a termékeket, amiket beigértünk és el tudjon kezdődni a valós token körforgás. Az INLOCK nincs és nem is lesz bevezetve egyetlen exchangere sem idén szeptemberig (regulációs megfontolások nyomán). Ennek megfelelően jelenleg a token cirkulációja valóan eléggé enervált, viszont jól látszik, hogy ahogy kihozunk valamilyen újabb funkciót, akkor folyamatosan felélénkül. Részemről nem látok okot a panaszra.

      • A többi ETH-ra hajazó elképzelésről mi a véleményed?
        Gondolok itt a Cardanora, Neora, Zilliqa-ra, distrixt0x-re, Nem-re.
        Ez utóbbi már süllyedőben is van ha jól tudom, elfogyott a pénz..

        • Általánosságban van véleményem ezekről, de amíg nincs ezekről is olyan szintű háttértudásom mint az Ethereum kapcsán, addig nem szivesen nyilatkoznék.

          • És az általános véleményed mi ezekről?
            A kínai Blokklánc megoldásokról van véleményed?
            Nekem alapvetően azzal van bajom, hogy egy diktatúrában a tényleges decentralizáltságot nem tudom elhinni, hogy engedélyezik.
            Az ONT felül is jönnek hírek, hogy a decentralizáltság csak egy hangzatos szólam, amivel manapság el lehet adni szinte bármit.
            És ott van Neo, Vechain, Wanchain, Zilliqa, ezek felett is a kínai állam bábáskodik.

      • van arrol valami statisztika hogy eth-ben hany normalis token es hany shittoken (ami csak kamuico, scam, stb) van?

  4. Látom Zcasht elfogadsz támogatás gyanánt. Megkérdezhetem, hogy miért Zcash és miért nem Monero?

    • Ennek teljesen legacy okai vannak, nem is tudom, hogy miért van még kint egyáltalán az a widget. Anno amikor reloadoltam a blogot cryptoként, akkor éppen Zcasht bányásztam és nagyon sokat blogoltam is róla (akkor éppen elég nagy story volt a zkSNARKs és komolyabban is érdekelt)

Leave a Reply

Your email address will not be published. Required fields are marked *