Az okos Bitcoin – a tx scriptek jelentősége

Sokszor kapom meg kérdésként, hogy miért is annyira jó a Bitcoin, miért nem döngölte még a földbe az Ethereum; ami ugye sokkal jobb, sokkal gyorsabb, lehet vele smart contractolni, sőt még valós életbeli javak tokenizálására is tökéletes. Mint evolúciós lépés az idő előre haladtával jogosan elvárható lenne, hogy egy sokkal fejlettebb, gyorsabb és biztonságosabb termék nyugdíjazza az elődjét. Persze ha az evolúció ennyire logikus elvek mentén szelektálna, akkor ma nem élnének kacsacsőrű emlősök és lássuk be, hogy a koalamackó is furán tekinthetne az együgyű életére…

A tegnap(-előtti…) estémet sikerült egy kifejezetten prominens hazai blockchain szakértői körben eltöltenem, ahol legnagyobb meglepetésemre előkerült a fentebbi alapkérdés (nem… nem a koalás meg a platipusos…). A téma kitárgyalása során vetődött fel bennem, hogy talán időszerű lenne erről egy blogpostot is írni.

Jelen cikkel nem kisebb kihívást próbálok teljesíteni, minthogy egyrészt meggyőzzem arról az olvasót, hogy a Bitcoin protokolljában ugyanúgy megtalálható a smart-contracting funkció (még ha nem is oly komplex módon). Hogy miért fontos ez? Nagyon sokszor találkozom azzal, hogy neves közgazdászok egyszerűen csak pénzként definiálják a Bitcoin. Egy pénznek (pillanatnyi) értéke van, míg egy árucikknek (commodity) funkciója, mellyel képes értéket kifejezni. Az alábbi cikk reményeim szerint mindenkit meggyőz arról, hogy a puszta pénzben kifejezhető értéken túlmenően a Bitcoin valóban képes commodity jellegű funkciókat is ellátni.

Főleg azok számára lehet érdekes ez a cikk, akik nem csak birtokolni/kereskedni akarnak, hanem akár üzleti vállalkozásokat, lehetőségeket is akarnak erre építeni. Talán már tudjátok néhányan, hogy előadóként meghívást kaptam egy hazai szakmai konferenciára novemberben, ahol lehetőségem lesz az okos szerződések jelentőségét bemutatni, az alábbi cikk (és ennek későbbi folytatásai) háttéranyagként szolgálnak majd az előadáshoz (is).

Kezdjünk is bele: a Bitcoin protokoll tervezésének korai fázisában már ráébredt Nakamoto, hogy komoly limitációkat fog elszenvedni a technológia, ha a tranzakciók küldése során kizárólagosan csak megadott publikus kulcsokra (addressekre) lehetne küldeni bitcoint. Bár a legtöbb felhasználó számára kétségtelenül elégséges lehet a konkrét címre történő utalás, de valós igény van arra, hogy egy-egy tranzakció fedezetének és jogosultságának vizsgálata túlmutasson egy egyszerű publikus kulcs (address) ellenőrzésen. Ennek megfelelően már a korai állapotban számos tranzakciót kezdeményező utasítás is implementálásra került, ezek közül kettőt emelnék ki: P2PKH s és a P2SH.

Előbbi a “Pay to Publickey Hash”, utóbbi pedig “Pay to Script Hash” rövidítése. A nevéből is látható, míg előbbi (P2PKH) lényegében az atom egyszerű utalást valósítja meg (amikor egy fix address-re akarsz küldeni bitcoint), addig az utóbbi esetben (P2SH) valójában egy olyan addressre küldesz pénzt, ahol minden további műveletnél egy script fut le, mely eldönti, hogy a tranzakciót kezdeményező valóban jogosult-e a műveletre. Fontos megjegyezni, hogy mind a P2PKH, mind pedig még annál is egyszerűbb P2PK tranzakció esetében is scriptről beszélünk, csak ezek a scriptek pofonegyszerűek (lényegében csak egy OP_CHECKSIG-et tartalmaznak).

Annak érdekében, hogy már az elemi tranzakciónál kiderüljön, hogy az egy konkrét addresshez, vagy inkább egy scripthez tartozik bevezettek két különböző address type-ot, amit a mai napig ott láthattok az összes Bitcoin cím első karakterében. Ha egy bitcoin cím “1”-es karakterrel kezdődik, akkor arról csak P2PKH utasítással lehet coint küldeni (amihez csak a tx-source address tulajdonosának aláírása szükséges), míg P2SH esetén a kezdő karakter a “3”-as, mely utóbbi esetben csak akkor kezdeményezhető kimenő utalás az adott addressről, ha az azt biztosító script sikeresen lefut és engedélyezi a műveletet. Példaként, ha megnézed itt a blog jobb oldali widget sávjában a “BLOGRÓL” rovatot, akkor ott láthatod a blog donation addressei között a következőt: “3Dnw5G6V6SrQPhXMYhbERtsdXGfahxxM9w”. Ebből is látszik, hogy ez a cím egy P2SH script address.

Érdekességképpen: Nemrégiben pont a SegWit aktiválása miatt bevezetésre került a P2WPKH és a P2WSH utasítás is, melyekben a “W” a witnessre utal, ennek megfelelően ezen két utasítás csak a “SegWit-felkészültség” állapotát jelzi. A “3”-assal kezdődő un. script addressek minden esetben magukkal hordozzák (minden tranzakciónál) a teljes scriptet, ez egy-egy nagyobb forgalmú bonyolultabb jóváhagyási szintű script esetén komoly overheadet okoz a blockchainben, mely amúgy is áteresztő képességekkel küzd. Ezen scripteket szerzi ki a SegWit protokoll ezzel növelve a blocklánc áteresztő képességét. Ezen túlmenően a SegWit tranzakciók lényegében nem térnek el jelentősen a hagyományos P2PKH és P2SH tranzakcióktól, így a cikkben szorítkoznék az egyszerűség kedvéért ezekre, de nyilvánvaló, hogy egy jövőbeli implementáció tervezésénél már érdekes a P2WPKH és P2WSH tranzakciókra építeni hiszen ezek egyrészt olcsóbbak a tranzakciós költség tekintetében, másrészt pedig csökkentik is a blockchain terheltségét.

Mit is jelent az, hogy NEM egy publikus addressre, hanem egy script címre történik egy tranzakció? A normál pénzügyi rendszerben (fiat alapú) az utalások általában adott bankszámlaszámról (IBAN pl) adott bankszámlaszámra történnek. Az utalás során általában nem mozog pénz, hanem csak később a clearing folyamat részeként kerülhet esetleg pénzmozgás a bankok között. Egy pénzügyi utalásnál annak teljesültét követően nincs semmilyen ráhatásod arra, hogy a fogadó fél mit tehet azzal a pénzzel. Ennek biztosításához bonyolult jogi szerződéseket kell létrehozni, melyeket sok esetben akár több független nemzet helyi jogi környezetéhez is hozzá kell igazítani. Akinek valaha is kellett foglalkoznia nemzetközi joggal, különösen pl olyan extrém példákkal mint pl az islamic-banking jog és az európai pénzügyi jog harmonizálása az pontosan tudja, hogy ezek mind időben, mind erőforrásokban mérhetetlenül sokba kerülnek.

Hogy tudatosan, vagy sem, de Nakamoto már a Bitcoin protokolljának nulladik fázisában bebiztosította azt, hogy a ‘szuperpénznél’ úgy lehessen pénzügyi ügyeleteket folytatni, hogy azokhoz valójában ne nagyon kelljen jogi szerződéseket létrehozni. A való életben nehéz olyan összetett pénzügyi példát találni (legyen az akár öröklődés, adózás, részletes finanszírozás, multi-signature, stb.) mit ne lehetne a Bitcoin saját scriptnyelvével leképezni.

Amikor egy P2SH utalást hajtasz végre, akkor ezzel azt vállalod, hogy a coinok megérkeztét követően onnan csak akkor lehet azokat tovább utalni, ha a script sikeresen futtatható. Nézzünk egy konkrét példát:

<sig> <pubKey> OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

Ez egy check signature (aláírás ellenőrző) script ami annyit vizsgál, hogy a tranzakciót aláíró privát kulcs publikus kulcsa megegyezik-e a scriptben szereplő publikus kulccsal. Persze ránézésre is ennél kicsit bonyolultabb maga a script. Akit részleteiben is érdekel, hogy mi is történik ebben a scriptben, annak klikk az alábbi kinyitható magyarázatra:

Egyszerű checksig script technikai kifejtése (stackelt OP kódok műközése) {click}
A Bitcoin saját script nyelve elég fura lehet azoknak, akik soha korábban nem láttak már assemblyhez vagy Forthhoz hasonló programozási nyelvet. A scriptek operátor (OP) utasításokat tartalmaznak, amelyek a stacken lévő adatokkal végeznek bizonyos műveleteket. Minden space-szel elválasztott szakasz egy-egy külön utasítás. A <>-jelek közötti műveletek elhelyeznek valamilyen adatot a stacken, az OP_-kezdetűek pedig azokat felhasználva igaz/hamis döntéseket hoznak. Ha bármelyik OP_ utasítás is hamis értéket ad vissza, akkor a script megszakad és nem teljesülhet az adott tranzakció.Lépésről-lépésre mindez:

  • bekerül a tranzakció aláírása a stack tetejére. <sig>
  • bekerül az aláírást készítő publikus kulcs a stack tetjére <pubKey>
  • duplikálódik (OP_DUP) a stack tetején szereplő érték, tehát a stack tetején ezt követően kétszer fog szerepelni a <pubKey>
  • Az OP_HASH160 előbb kiszámolja a stack tetején lévő (<pubKey>) érték SHA256 hash-ét, majd annak a RIPEMD-160. Ezzel gyakorlatilag kiszámolja a publikus kulcs hashét, ami gyakorlatilag a nyers address, erre kicseréli a stack tetején lévő elemet.
  • Bekerül a stack tetejére a <pubKeyHash>, tehát annak a kulcsnak a hashe, ami elköltheti a script address-e által biztokolt coinokat.
  • OP_EQUALVERIFIER összehasonlítja a stack tetején lévő két legfelső elemet. Ha azok nem azonosak (tehát valaki más próbálja elkölteni a vagyon), akkor automatikusan invalidálódik a tranzakció
  • OP_CHECKSIG: Végezetük a stackre eredetileg bekerült (ScriptSig) két felső elem (<sig> <pubKey>) segítségével leellenőrzi, hogy egyáltalán helyes-e az aláírás.

Ha az összes op kód TRUE értékkel tért vissza akkor az address-en lévő coinok szabadon elkölthetők.

Ennek a fajta szabad scriptelhetőségnek köszönhetően akár olyan scriptet is létre lehet hozni, amit bárki elkölthet. Ehhez csak annyi kell, hogy a scriptben egy darab OP_TRUE opkód szerepeljen. Ezt követően az ezen a címen lévő coinokat bárki elköltheti. (Oké, ez talán egy eléggé extrém példa…). Persze ennek is megvan az ellen oldala, amit “Proof-of-Burn”-nek nevez a szakma, azaz olyan script output amire elküldött coinokat ezt követően már soha senki nem tud elkölteni, azok ugyanis kvázi elégetésre kerülnek. Mi értelme van ennek?

  • Az OP_RETURN (Proof-of-Burn) opcode engedélyez egy maximum 83 bytes (0.12.0 óta) extra paraméter mezőt, ez a mező direktben bekerül a blockchainbe.
  • A Proof-of-Burn tranzakciók mining-feeje fixen 0 statoshi kell, hogy legyen, ennek megfelelően ilyen tranzakció csak akkor kerülhet be a blockchainbe, ha éppen nem várakozik egyetlen tranzakció sem a mempoolban. Emellett fontos, hogy a tranzakciónak egy minimális coin darabkát el kell égetnie, ezzel ‘megvásárolva’ a jogot, hogy bele írj a blockchainbe.
  • Tehát ha szeretnéd beleírni a Bitcoin blockchainbe, hogy “Itt járt Józsi. Szeretlek Rozi!“, akkor ezt alacsony tranzakció volumen mellett és egy minimális bitcoin elégetése mellett nyugodtan megteheted.
  • Számos olyan szolgáltatás van, ami pl üzleti adatokat ír be kvázi bizonyíték jelleggel a Bitcoin blockchainbe, ezzel szavatolva pl egy privát alkalmazás vagy akár egy privát blockchain hitelességét. Ezek is mind Proof-of-Burn technológiát használnak.

Itt talán tisztáznám is, hogy a Bitcoin saját smart contract scripting nyelve egy olyan scriptnyelv, ami minden esetben akkor fut le, amikor a scripthez tartozó coinokat valaki el akarja költeni. A scriptnyelv bár nem teljesíti a “Turing complete” elvárásokat, de számos egyedi feladata tökéletesen alkalmas. A szócséplés helyett nézzünk egy igazán érdekes példát:

A példából már látszik, hogy van itt lehetőség feltételek alkalmazására is. A konkrét példa Bitcoin scripting szinten oldja meg azt, hogyha valaki elveszítené a privát kulcsát (vagy akár az életét), akkor legyen egy vészforgatókönyv a beragadt coinok kinyerésére. A példa egyszerűen kifejtve annyit tesz, hogy az adott script címre küldött coinokat “Alice” szabadon tudja költeni, azonban ha az utálást követően 3 hónapon belül nem költi el azt újra (vagy küldi el azt ugyanerre a címre), akkor Bob ÉS Charlie KÖZÖSEN el tudja azt költeni. Tehát ebben a scriptben látható egy egyszerű tulajdonosi feltétel, ez időzár és a multi-signature check szakasz is.

De ha már multi-signature, akkor nézzük ennek a legtriviálisabb példáját: Multi-signature Escrow szolgáltatással:

2 <K1> <K2> <K3> 3 CHECKMULTISIGVERIFY

Itt látható, hogy három különböző publikus kulcs is megadásra kerül (K1, K2, K3), melyekre a 2-of-3 multi-signature szabály vonatkozik, tehát akkor lehet az outputot elkölteni (tovább utalni), ha a három kulcs közül legalább kettő aláírja azt. Milyen esetben lehet ez érdekes:

  • Vegyünk azt az esetet, hogy Józsi (K1) vásárolni akar 0,1BTC értékben Rozitól (K2) egy jófajta fahordóban érlelt kisüstit.
  • Ám Józsi és Rozi nem ismerik egymást (ami lehet hogy szerencse!) ráadásul az ország két végében élnek. Mégis hogyan induljon ez a tranzakció, ha egyik fél sem biztos, hogy a végén mindenki jól fog járni?
  • Józsinak és Rozinak van egy közös ismerőse a Jolán (K3), aki vállalja, hogy a felek között közvetít. Ennek megfelelően a három szereplő privát kulcsával létrehozásra kerül a multi-signature contract, mire Józsi elküldi a 0.1BTC-t. Ahogy ez a vagyon megjelenik, akkor Rozi már küldheti is a pálinkát.

Milyen kimenetelei lehetnek a feltételekhez kötött (escrow) kontraktusnak:

  • Megérkezik a pálinka, aminek annyira örül Józsi, hogy aláírja a multisign tranzakciót, ami továbbküldi a 0,1BTC-t Rozi számlájára, majd odaadja a tranzakciót Rozinak, aki szintén aláírja, melyet broadcastol a hálózat felé és mindenki boldog!
  • Megérkezik a pálinka Józsihoz, de Józsi roppantul rosszhiszemű és nem küldi el az aláírt kontraktust. Ekkor Rozi megkeresi Jolánt, akinek elpanaszolja bánatát, majd bemutatja a bizonyítékokat arról, hogy márpedig ő elküldte a kisüstit, amik alapján Jolán ellenőrzi azt, hogy Rozi valóban jóhiszeműen járt el és esetleg még azt is ellenőrzi, hogy Józsi nem-e otthon fetreng a pincében a kisüstitől bűzölögve; majd ha úgy ítéli meg, hogy Rozi tényleg megfelelt a kontraktusnak, akkor aláírja a tranzakciót saját maga Józsi helyett, azt odaadja Rozinak, aki szintén aláírva azt broadcastolja azt a hálózatba.
  • A harmadik eshetőség, hogy Rozi (K2) a rosszhiszemű és követeli a 0,1BTC-t holott vagy nem is küldte el a kisüstit, vagy ahelyett egy ócska megpimpósodott lőrét küldött csak. Ekkor Józsi fordulhat mediációs célzattal Jolánhoz, aki ha meggyőződik arról, hogy itt bizony Rozi tényleg rosszhiszemű volt, akkor Jolán (K3) és Józsi (K1) kezdeményezni tudja azt, hogy a 0,1BTC visszakerüljön Józsihoz.

Az escrow típusú kontraktusoknál mindig egy harmadik fél dönti el, hogy a kontraktus mindkét fél részéről teljesült vagy sem. Azonban ennek a harmadik félnek nem kell feltétlenül egy szubjektív személynek lennie. Van számos olyan escrow szolgáltató ami publikusan elérhető információk alapján végez mediációt. Ennek egyik leglogikusabb példája a csomag nyomkövetés. A vásárló elutalja a pénzt a 2-of-3 multisign scriptnek, amiben bevonnak pl egy fedex csomagkövető szolgáltatót. Ha a csomag megérkezik, akkor az eladó akár úgy is megkaphatja a pénzét, ha a küldő időközben ellenségessé válik. Az automatizált és a blockláncból kiszervezett döntéshozatali mechanizmust “oracle”-nek nevezi a szakzsargon. Ennek lényege, hogy egy külső alkalmazás automatikusan dönti el külső tényezők alapján, hogy a tranzakció érvényes avagy sem és ennek megfelelően vagy aláírja a multi-sign tranzakció rá eső részét vagy sem.

commercial break...

A fenti példákból is talán jól látható, hogy a Bitcoin protokoll  lényegében semmilyen valós megkötést nem határoz meg egy tranzakció ellenőrzése kapcsán. A scriptből akár teljesen kihagyható mind az aláírás ellenőrzése (OP_CHECKSIG), de még akár a publikus kulcs (vagy annak hashének) ellenőrzése is. Ezek mind csak feltételek. Ha Te úgy döntesz, hogy létrehozol egy olyan script address-t, amin lévő pénz szabadon elkölthető, ha bárki ismeri a születési dátumod SHA256(UTF8(x)) leképzését, akkor szabadon megteheted, hogy a scriptbe csak ennyit írsz be: “OP_HASH256 9817….0000 OP_EQUAL”. Ebben az esetben ha a tx ScriptSigjébe bárki is beírja a születési dátumod hashét és az megegyezik a scriptben lévő értékkel, akkor már költheti is a pénzed.

Mindez persze csak néhány ma már triviálisnak tekinthető alkalmazási formája a Bitcoin saját transaction script képességének. Persze mindez eltörpül pl az Ethereum vagy a NEO dAPP (decentralizált alkalmazás) képességei mellett, azonban a hétköznapi felhasználási célokra még így is bőven elégséges. Minden másra pedig ott a… ETH.

Nem szabad azt sem elfelejteni, hogy a Bitcoin tx scripting lehetősége is szó szerint napról napra fejlődik. A scriptek segítségével már évek óta meg lehet atomic-swapet (láncok közötti pénzcserét) létrehozni, bár a ‘mainstream’ ezt még csak most fedezi fel, de pl a ennek segítségével már évekkel ezelőtt sikeresen hoztak létre ‘zero knowledge’ tranzakciót (évekkel a ZCash előtt), sőt a Lightning Network alapját adót HTLC (Hashed Time Locked Contract) sem mai gyerek. Ellenben annak fog számítani a Schnorr és a MAST (Mekelized Abstract Syntax Trees). Utóbbi nem kisebb célt tűz ki mint a scriptek méretének drasztikus csökkentése mellett a scriptszintű privacy megvalósítását. Hogy ezek megvalósulnak-e és ha igen, akkor mikorra az erősen függ a november közepi hard-forktól is.

Bookmark the permalink.

6 Comments

  1. Üdv.

    Nagyon érdekes és hasznoss cikk, én egy kicsit paranoiás vagyok azvégett, hogy elvesztem a privát kulcsom. Ezekszerint meg lehet azt is oldani ezzel a szkripteléssel, hogy egy wallet addresen levő pénz pár hónap után hozzáférhető legyen mondjuk a születési dátumoddal?

    Mennyire elvetemült gondolat létrehozni olyan walleteket amik 12 hónap után hozzáférhetővé válnak a születési időpontoddal? Így amíg a tárca tulajdonosa életben van, évente elutalgatja a pénzét egy másik címre, amiken pont ilyen feltétel van. Ha pedig valami történne vele, vagy csak elveszne a privát kulcsa a címen levő bitcoin nem veszne el örökre, hozzáférhetővé válna pár hónapon belül.

    • Igen, ezt meg lehet oldani.

    • Ez további problémát vetne fel. Börtönben van, nem tud hozzáférni és “feloldásra kerül” közben a Bitcoinja. Vagy éppen közeledik az egy év, utalna rá, hogy hosszabbítson, de valami közbeszól (természeti katasztrófa).

      Egyébként igen, valahogy ezt meg kell oldani. Már így is egyre nagyobb a digitális hagyaték, ami elveszik. A régi világban a falu tagjai körbenéztek és az volt a hagyaték, amit láttak. Egy-két évtizeddel ezelőttig is elég volt egy hagyatékátadás, pár helyről befutó leltár, aztán kiadták a hagyatékot. Most? Most az ember életének egyre jelentősebb része láthatatlan. Ehhez jön hozzá a digitális pénz és kész is a káosz. Ez a fekete lyuk, nem az, ami az égen van. 🙂

      Azt valószínűsítem, hogy az emberiséget átterelik valamilyen hagyományos módon elérhető Bitcoin tartásra. Megint felröppent, hogy jönnek az ETF-ek. Erre rácuppan a fél világ és máris “meg van oldva” a gond, veszélytelenül lehet Bitcoint tartani. Kár, hogy a privát kulcs nem a tulajnál van, talán nem is tudja, hogy létezik olyan.
      Szép új világ. Visszatértünk oda, ahonnan a Bitcoin szabadulni akart.

      • De ugyanakkor szerintem a társadalomnak nagyon kis hányada az akik felelőséggel tudják kezelni és biztonságban tartani a privát kulcsaikat (a rajta levő értékhez mérten). A többieknek szükségük van egy olyan applikációra/szoftverre/módszerre amely valamelyest helyettük teszi ezt biztonságosan – szerintem. Persze nehéz kigondolni ilyet úgy, hogy az eredeti elképzelés se sérüljön.

        Börtön, természeti katasztrófa igen ez jó érv (és esetleg betegség), mind problémát vet fel, viszont talán nem kell az utolsó pillanatig várni az új címre utalással.

        Azonkívül talán ha két lépcsős feloldás lenne: 1év után feloldhatóvá válna egy a privát kulcsnál sokkal egyszerűbb mégis elég bonyolult jelszóval két év után pedig a születési dátummal. Vagy ugyanez csak 2+3 éves konstrukcióban, stb..

        Ha jól sejtem a támadó nem tudja hogy a több milliard lehetséges addresből melyik és mikor fog születési dátummal nyílni. Ezért nagyon kevés lenne az esélye egy olyan programnak amely véletlenszerűen próbálgatja az addreseket, arra várva hogy melyik nyílik valamely dátummal. Ennyi erővel véletlenszerűen privát kulcsokat is generálhatna abban bízva hogy épp valaki walletjebe beletrafál. Nemde? Javítsatok ki ha tévedek..

        Egy kérdés felvetődött bennem: A blokkláncból ki lehet olvasni valahogy, hogy mely címeken, milyen szkript van feloldási paraméterként megadva?

        • A script a kuldo tranzakcio cel outputjaban van benne, tehat most is lehet tudni melyik “address” hogy koltheto el. Az evszammal az a gond hogy kicsi az entropiaja, es egy rainbow tablaval siman “torheto”. igy a rossz fiunak csak meg kell varnia az egy ev lejartat, egybol kuldheti is (akar bottal, 1 seccel a lejarat utan). igy elobb el fogja kuldni mint hogy ismerosod megmentene.

  2. Na, pontosan az ilyen cikkek miatt ajánlottalak Csaba a kecskeméti hallgatóságnak névvel, oldallal, hogy aki akar, el tudjon mélyülni az ilyen jellegű témákban:-D

    (Azon viszont nagyon meglepődtem, hogy az informatikus hallgatók közül ilyen kevesen programoznak. Tudom, h nem ugyanaz a kettő, de gondoltam volna, hogy van indíttatás a programozásra…de nem.)

Szólj hozzá: