To je zgodba o 184 milijardah bitcoinov – kako so nastali, kako je bilo to sploh možno in kam so na koncu šli.
Spremenljivke
V programiranju poznamo koncept, imenovan spremenljivke. Spremenljivka je kot nekakšna škatlica (ali kozarček), v katero shranimo neko vrednost.
Vanje se lahko spravi marsikaj: od celih števil, števil z decimalno vejico, logičnih pogojev, pa celo do črk, besed in povedi. Primer:
var a = 5
V zgornjem primeru je “a” spremenljivka (ang. “variable”), podobno kot je spremenljivka vsem zelo poznani “x”, ki smo ga uporabljali v šoli pri matematiki.
Dobro je vedeti: spremenljivke, ki shranjujejo tekst (npr. Črke, besede ali večje količine teksta), imenujemo po angleško “string”. Spremenljivka, ki shrani celo število število je “integer”, tista, ki shrani decimalno število, pa je “float”. Spremenljivka, ki shrani logični pogoj (true/false), se imenuje Boolean, po angleškem matematiku Georgu Booleu.
Ko shranimo število v spremenljivko, je maksimalna velikost tega števila omejena s kapaciteto spomina računalnika. Primer: Pri 64-bitnih računalnikih (večina sodobnih računalnikov) je največje možno število, ki ga lahko zapišemo v spremenljivko, število 9.223.372.036.854.775.807, najmanjše pa seveda -9.223.372.036.854.775.807. Da, to je 9 milijonov bilijonov v obe smeri – pozitivno in negativno.
Kako se števila zapisuje v binarnem sistemu
Računalniki lahko podatke shranjujejo le v binarnem formatu, to je z ničlami in enicami. Na primer, 0101 je 4-bitno število, ki ga lahko pretvorimo v desetiški sistem na naslednji način: (0 * 8) + (1 * 4) + (0 * 2) + (1 * 1) = 5. Vsako števko v binarnem številu pomnožimo s potenco števila dva, pri čemer se ta potenca nanaša na pozicijo števke (začenši z 0) v nasprotnem vrstnem redu: 2^0, 2^1, 2^2 itd.
Še en primer:
01000101001001 =
= 0*2^13 + 1*2^12 + 0*2^11 + 0*2^10 + 0*2^9 + 1*2^8 + 0*2^7 + 1*2^6 + 0*2^5 + 0*2^4 + 1*2^3 + 0*2^2 + 0*2^1 + 1*2^0
= 0*8192 + 1*4096 + 0*2048 + 0*1024 + 0*512 + 1*256 + 0*128 + 1*64 + 0*32 + 0*16 + 1*8 + 0*4 + 0*2 + 1*1
= 4096 + 256 + 64 + 8 + 1
= 4425
To je bilo 14-bitno število. Pri 64-bitnih številih pa ima število seveda 64 znakov (ničle ali enice):
0000000000000000000000000000000000000000000000000000000000000000
Kot primer je zapisano število samo z ničlami, vendar bi lahko imelo tudi enice (ali pa izključno enice). Bit, ki je čisto na levi strani, označuje, ali gre za pozitivno ali za negativno število.
Če upoštevamo dejstvo, da stanje na Bitcoin “računu” (balance) ne more biti negativno, potem lahko prvi (levi) bit uporabimo za cifro in tako povečamo (podvojimo) maksimalno možno število, ki ga lahko shranimo v spremenljivko: 18.446.744.073.709.551.615 (18 milijonov bilijonov).
Če bi želeli shraniti le za ena večje število (18.446.744.073.709.551.616), bi sprožili napako imenovano integer overflow (sl. “prekoračitev obsega števila”).
Predstavljajte si števec kilometrov v avtomobilu, ki ima 6 mest. Ko doseže število 999.999 kilometrov, ob naslednjem kilometru na števcu ne bo kazalo 1.000.000, temveč bo šlo nazaj na 000000. Enako se zgodi s števili v računalniških sistemih – ko presežejo maksimalno vrednost, se zgodi “overflow” in se ponastavijo nazaj na 0.
Bitcoin in števila
Bitcoin ima (trenutno) 8 decimalnih mest. Najmanjše enota v Bitcoinu se imenuje satoshi, najbolj pogosto pa se uporablja enota bitcoin, ki je enaka 100 milijonom satoshijev. Maksimalno možno število bitcoinov je 21 milijonov, kar je enako 2.100.000.000.000.000 (2 trilijona in 100 bilijonov) satoshijev.
Če maksimalnem številu, ki ga lahko shranimo v spremenljivko (18 milijonov bilijonov), odrežemo zadnjih 8 cifer (kot smo rekli, ima Bitcoin 8 decimalk), potem dobimo cca 184 milijard.
Ampak kaj je sploh bistvo vsega tega govoričenja o številkah?
184 milijard bitcoinov
Bitcoin denarnica (wallet) je program, preko katerega pošiljamo bitcoine iz svojega BTC naslova na nek drug naslov. Vendar leta 2010 je imel ta program zelo kritično napako.
Pri pošiljanju bitcoinov iz več svojih naslovov na več drugih naslovov (to je dejansko možno), je Bitcoin denarnica pregledovala le skupni znesek “inputov” (količina poslanih Bitcoinov) in skupni znesek “outputov” (količina Bitcoinov za prejemnika), ne pa tudi vsega, kar se dogaja vmes.
Nekdo je kmalu ugotovil, da je to možno zlorabiti, ter skonstruiral naslednjo transakcijo (poenostavljen zapis):
- v svoji denarnici je imel 50,51 BTC
- na naslov A je poslal 92 milijard BTC
- na naslov B je poslal 92 milijard BTC
- na naslov C je poslal 50,51 BTC
Vsota poslanih bitcoinov na naslova A in B je tako bila 184 milijard, kar je preseglo maksimum in sprožilo famozni “integer overflow”.
Na koncu je tako Bitcoin denarnica v transakciji videla le 50,51 BTC kot input in 50,51 BTC kot output, ter transakcijo priznala kot veljavno. Naslova A in B pa sta pridobila vsak 92 milijard bitcoinov, nastalih iz te napake.
Rešitev
Satoshi Nakamoto, Jeff Garzik in drugi aktivni člani takrat še majhne Bitcoin skupnosti, so hitro začeli iskati rešitev za nastali problem. V roku nekaj ur so napisali kodo, ki je zakrpala sistem ter plan kako izničiti problematično transakcijo, ki je že bila zapisana v blockchain.
Plan je zahteval, da vsi rudarji začasno ustavijo svoje aktivnosti, posodobijo svoje Bitcoin wallete ter ignorirajo blok, ki je vseboval neveljavno transakcijo (ter vse bloke za njim). Bilo je nekaj pomislekov, ali bo to sploh možno izvesti, vendar pa je bil sistem še tako mlad (in s tako malo rudarji), da je bilo možno o tem vse rudarje obvestiti in doseči konsenz glede načrta.
Vse je šlo gladko skozi in hack je bil odpravljen.
Avtor: Bruno Škvorc (original članek)
Prevod: Matej Ramuta
Bruno in Matej sva pripravila tudi čisto sveži SmartNinja tečaj: Blockchain tehnologija in kriptovalute. Tečaj je primeren (tudi) za ne-tehnične ljudi, saj na preprost ter razumljiv način razloži delovanje in tehnologijo za blockchainom ter različnimi kriptovalutami. Če te tematika zanima, se prijavi in obveščen/a boš, ko bo tečaj razpisan!