Sunday, November 13, 2016

Promjenjivost transakcija (malleability)


Svaka Bitcoin transakcija referencira se na neku prethodnu transakciju. Referenca na transakciju dvostruki je hash cijele transakcije. Prije nego se transakcije uključi u blok, taj hash može promijeniti bilo tko od primatelja transakcije. To se naziva promjenjivost transakcija i predstavlja problem ako se transakciju želi koristiti prije nego je dodana u blok.

U Bitcoinu postoji nekoliko uzroka promjenjivosti:
  1. Potpisi koji nisu u DER formatu.
  2. Operacije u polju scriptSig koje ne stavljaju podatke na stog.
  3. Operacije koje stavljaju podatke na stog za transakcije nestandardne veličine.
  4. Brojevi predvođeni nulama.
  5. Negativna vrijednost broja S u potpisu.
  6. Suvišni podaci u polju scriptSig.
  7. Skripta zanemaruje ulazne podatke.
  8. Maskiranje na temelju sighash zastavice.

Potpisi koji nisu u DER formatu

U prošlosti se Bitcoin klijent oslanjao na OpenSSL biblioteku koja nije zahtijevala strogo pridržavanje DER formata. Prihvaćanjem promjena koje je donio BIP66, ovo više nije problem.

Operacije u polju scriptSig koje ne stavljaju podatke na stog

Dodatne operacije u polju scriptSig mogu dati isti rezultat skripte, ali drugačiji hash. Npr. <sig><pubkey><2>OP_DROP.

Operacije koje stavljaju podatke na stog za transakcije nestandardne veličine

Kod višepotpisnih transakcija može se dogoditi da je potpis prevelik (> 75 bajtova) pa se polje za veličinu potpisa počinje tumačiti kao naredba u skripti. Zbog toga je potrebno dodati neku od OP_PUSHDATA naredbi.

Brojevi predvođeni nulama

U polju scriptPubKey brojevi koji se koriste mogu biti predvođeni nulama.

Negativna vrijednost broja S u potpisu

Kod računanja broja S može se uzeti njegova pozitivna ili negativna vrijednost. To je moguće jer se kod izračuna potpisa koristi aritmetika nad eliptičkom krivuljom y2 = x3 + 7. Obje vrijednosti daju ispravan rezultat. BIP66 propisuje da se uzme manja pozitivna vrijednost. To pravilo je dio konsenzusa ne protokola pa ga nije nužno poštivati.

Suvišni podaci u polju scriptSig

Dodavanje podataka na početak polja scriptSig koji se neće koristiti u odgovarajućem polju scriptPubKey.

Skripta zanemaruje ulazne podatke

Ako skripta scriptPubKey počinje naredbom OP_DROP, ostatke skripte se zanemaruje.

Maskiranje na temelju sighash zastavice 

Sighash zastavice mogu se koristiti za ignoriranje pojedinih dijelova transakcije.

Gorenavedene situacije u kojima je moguća promjenjivost transakcija rješava segregated witness.

Sunday, July 17, 2016

Relativno vremensko zaključavanje transakcija (CHECKSEQUENCEVERIFY)


BIP65 odnosno naredba CHECKLOCKTIMEVERIFY omogućuje trošenje transakcije u budućnosti, na točno određeni datum ili visinu bloka. BIP112, odnosno naredba CHECKSEQUENCEVERIFY, omogućuje zaključavanje transakcije na neki vremenski period, npr. tjedan dana ili 48 sati. Specifikacija se sastoji od tri dijela: BIP113 (srednje prošlo vrijeme), BIP68 (relativno vremensko zaključavanje korištenjem broja niza [sequence numbera]) i BIP112 (naredba CHECKSEQUENCEVERIFY).

Srednje prošlo vrijeme



Prije pojave BIP113 transakcije nisu se uključivale u blok ako su trenutačno vrijeme ili visina bloka manji od onoga specificiranog u polju locktime. Ovakvo ponašanje omogućivalo je rudarima da netočno prijavljuju vrijeme blokova kako bi u njih uključili što više transakcija.


BIP113 mijenja određivanje proteklog vremena na temelju oznake iz prethodnog bloka u određivanje proteklog vremena na temelju srednje vrijednosti polja locktime zadnjih 11 blokova. Potrebno je uzeti prethodnih 11 blokova te ih poredati po veličini prema vrijednosti polja locktime. Na kraju se iz tog niza uzima srednja vrijednost kao proteklo vrijeme. Ovo garantira da će se vrijednost proteklog vremena monotono povećavati.


Ovakav mehanizam koristit će se i kod apsolutnog vremenskog zaključavanja transakcija (BIP65).

Broj niza



Prije pojave relativnog vremenskog zaključavanja transakcija, polje broj niza nije se koristilo, odnosno uvijek je bilo postavljeno na maksimalnu vrijednost 0xFFFFFFFF. U novoj specifikaciji prvi bit (1<<31) određuje kako će se polje interpretirati. Ako je prvi bit postavljen, vrijednost se polja zanemaruje, a ako nije postavljen, polje se tretira kao relativno vrijeme zaključavanja.


Bit 1<<22 određuje kako će se zapisano vrijeme tumačiti. Ako je bit postavljen, tumači se kao relativno vrijeme u intervalima od 512 sekundi. Vremenski interval počinje srednjim prošlim vremenom prethodnog bloka izlaza koji se zaključava, a završava srednjim prošlim vremenom prethodnog bloka. Ako bit nije postavljen, tumači se kao broj blokova. Sam vremenski interval zapisan je u bitovima 0-15.



Interval od 512 sekundi odabran je da bude sličan intervalu u kojem se blokovi generiraju. Na taj se način u isti broj bitova može zapisati ili visina bloka ili relativno vrijeme.

Primjena



CHECKSEQUENCEVERIFY primjenjuje se na zaključavanje pojedniih izlaza kao i CHECKLOCKTIMEVERIFY. Može se koristiti kod zajamčenih pologa (escrow), dvosmjerne platne kanale, mrežu Lighntning i slične mehanizme za transakcije izvan lanca blokova.

Wednesday, June 22, 2016

Logička hijerarhija determinističkih novčanika (BIP44)


BIP32 ostavlja previše slobode u implementiranje logičke strukture HD novčanika što može uzrokovati probleme prilikom restoracije novčanika. BIP44 predlaže logičku strukturu na više razina.

Struktura


m / purpose' / coin_type' / account' / change / address_index
Apostrof označava da se radi o ojačanom izvodu ključa. Svaka razina ima određeno značenje i ondnosi se na indeks za BIP32 CKD.

Purpose (svrha)


Polje 'svrha' je konstanta koja iznosi 44 (0x8000002C). Označuje da se radi o stalastoj strukturi kakvu definira ovaj BIP.

Coin_type (vrsta kriptovalute)


Ovo polje označuje za koju se kriptovalutu izvode ključevi (Bitcoin, Litecoin, Dogecoin...). Npr. oznaka Bitcona je 0 (0x80000000), Litecoina 2 (0x80000002) i sl. Sve oznake mogu se pronaći ovdje.

Account (račun)


Na ovoj se razini ključevi dijele prema identitetima korisnika.tako da se različiti računi nikad ne pomiješaju. Brojevi računa kreću od 0 te se povećavaju.

Change (kusur)


0 označuje da se radi o normalnoj adresi na koju korisnik prima sredstva. 1 označuje da se radi o adresi nakoju korisnik prima ostatak sredstava (kusur) poslanih na neku adresu.

Address_index (indeks adresa)


Indeksi adresa počinju od nule te se inkrementiraju.

Saturday, June 11, 2016

Bitovi verzija (BIP9)


Blokovi originalnog protokola Bitcoin imali su verziju 1. Polje za verziju bloka veliko je 32 bita, a zapisuje se u little-endian formatu. Pojavom BIP 34, verzija je povećana na 2 te je uveden mehanizam za provođenje soft-fork promjena. Mehanizam je provjeravao koliko blokova na 1000 ima zadanu verziju bloka što je signaliziralo da je promjena softvera prihvaćena. Problem ove metode je što podržava samo jedan soft-fork u paraleli. BIP 66 povećao je verziju bloka na 3, a BIP 65 na 4.

BIP 9 uvodi nov mehanizam provođenja soft-fork promjena te nov način tretiranja polja verizije u bloku. Verzija se od sada tretira kao vektor bitova u kojem se svaki bit može koristiti za praćenje verzije soft-forka. U dvotjednom (retarget) periodu zbrajaju se bitovi pojedinih verzija kako bi se ustanovilo ima li pojedina promjena dovoljnu podršku rudara (jesu li prešli "prag").

Specifikacija

 

Svaki soft-fork obilježavaju sljedeći parametri:
  • Ime: Vrlo kratko opisuje soft-fork (npr. bip N).
  • Bit: Označuje koji će se bit u verziji bloka koristiti za praćenje konkretnog soft-forka. Bira se iz skupa [0, 28].
  • Starttime: Vrijeme u budućnost od kada bit počinje vrijediti specificirano kao srednje proteklo vrijeme (medium time past).
  • Timeout: Specificira vrijeme nakon kojeg se prihvaćanje soft-forka smatra neuspjelim.

 

Stanja



Uz svaki blok i soft-fork vežu se stanja:
  • DEFINED – svaki soft-fork započinje u ovom stanju.
  • STARTED – svi blokoi za koje je prošlo starttime.
  • LOCKED_IN – svi blokovi kojih nakon stanja STARTED u dvotjednom periodu ima barem za prijelaz praga određene verzije.
  • ACTIVE – svi blokovi nakon stanja LOCKED_IN.
  • FAILED – svi blokovi za koje prošao timeout, a LOCKED_IN nije postignut.

 

Bitovi kao zastavice


Blokovi u stanju STARTED postavljaju bitove u polju verzije na 1 kako bi signalizirali koji soft-fork podržavaju. Vršna tri bita takvih blokova moraju biti 001. Budući da su BIP 34, 66 i 65 imali verzije 00000000000000000000000000000010 (2), 00000000000000000000000000000011 (3) i 00000000000000000000000000000100 (4), odnosno u little-endian formatu 10000000000000000000000000000000, 11000000000000000000000000000000 i 00100000000000000000000000000000, mogu se koristiti samo bitovi od 3. do 31., odnosno svaka verzija mora imati tri vršna bita 001.
Dakle, mogući raspon bitova je [0x20000000, 0x3FFFFFFF]. Do tog se raspona dolazi ako se uzme najmanja moguća verzija u little-endian formatu 00100000000000000000000000000000 (0x20000000) i najveća moguća verzija 00111111111111111111111111111111 (0x3fffffff). To predstavlja 29 mogućih paralelnih soft-forkova.

Prijelazi između stanja

 

 
 
Svi blokovi unutar dvotjednog perioda imaju isto stanje. Iduće stanje ovisi o prethodnom. Prag za prijelaz u stanje LOCKED_IN je 1915 (95%) blokova.

Sunday, April 3, 2016

Trošenje Bitcoin transakcije (dio drugi)

9. scriptPubKey


Ovo polje sadrži uvjete otključavanja gorenavedenih sredstava usmjerenih na neku bitcoin adresu. Ovo je polje usko vezano uz polje scriptSig (kao što je opisanu u člancima o Bitcoin skriptama). Zapisuje se u var_string big-endian formatu. Najčešće sadrži skriptu 76a914097072524438d003d23a2f23edb65aae1bb3e46988ac. Napisana je u skriptnom jeziku Bitcoina koji kad se deserijalizira kaže
DUP HASH160 <14> 097072524438d003d23a2f23edb65aae1bb3e469 EQUALVERIFY CHECKSIG
Detalji su opisani u člancima o Bitcoin skriptama. U ovo se polje prvo upisuje duljina skripte u bajtovima (u heksadecimalnom formatu) te zatim sama skripta.


Hex: "01000000
01 
eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2
01000000
76a914010966776006953d5567439e5e39f86a0d273bee88ac
ffffffff
01
605af40500000000
19
76a914097072524438d003d23a2f23edb65aae1bb3e46988ac"


10. Polje lock-time



Polje koje se može koristiti za vremensko zaključavanje transakcije. U slučaju da se transakcija može odmah potrošiti, polje je prazno. Veličine je četiri bajta te se zapisuje u little-endian formatu.

Hex: "01000000
    01
    eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2
    01000000
    76a914010966776006953d5567439e5e39f86a0d273bee88ac
    ffffffff
    01
    605af40500000000
    19
    76a914097072524438d003d23a2f23edb65aae1bb3e46988ac
    00000000"

11. Način potpisivanja transakcine (hashcode)

Ovom se zastavicom opsiuje kako će se transakcija potpisivati. Gotovo u svim slučajevima ova zastavica predstavlja sighash_all, odnosno potpisivanje svih ulaza i izlaza. Zastavica je veličine osam bajtova zapisanih u little-endian formatu.

Hex: "01000000
01
eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2
01000000
76a914010966776006953d5567439e5e39f86a0d273bee88ac
ffffffff
01
605af40500000000
19
76a914097072524438d003d23a2f23edb65aae1bb3e46988ac
00000000
01000000"

14. Hashiranje transakcije

Goreprikazani oblik transakcije spreman je za potpisivanje. Prije toga transakcija se sažima dvostrukim korištenjem funkcije SHA256(SHA256(tx)). Rezultat je

9302bda273a887cb40c13e02a50b4071a31fd3aae3ae04021b0b843dd61ad18e.

15. Potpisivanje transakcije


Transakcija se sada potpisuje privatnim ključem primatelja. Za to se koristi algoritam ECDSA, odnosno digitalni potpis zasnovan na eliptičkoj krivulji. Taj se potpis zatim enkodira u tzv. strogi DER format. Ovo je primjer takvog potpisa


0460221009e0339f72c793a89e664a8a932df073962a3f84eda0bd9e02084a6a95
67f75aa022100bd9cbaca2e5ec195751efdfac164b76250b1e21302e51ca86dd7eb
d7020cdc06. 

16. Popunjavanje polja scriptSig

Sada se može ispravno popuniti polje scriptSig iz petog koraka koje je do sada sadržavalo skriptu scriptPubKey. U polje scriptSig upisuje se ukupna duljina polja, duljina i potpis transakcije u DER formatu, hashcode (01 najčešće), duljina javnog ključa te sam javni ključ.

8c4930460221009e0339f72c793a89e664a8a932df073962a3f84eda0bd9e0208
4a6a9567f75aa022100bd9cbaca2e5ec195751efdfac164b76250b1e21302e51ca
86dd7ebd7020cdc0601410450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d
8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df3885
5ed6f2ee187e9c582ba6.

17. Micanje zastavice hashcode

U zadnjem koraku se miče zastavica hashcode s kraja transakcije jer je dodana u polje scriptSig iza potpisa transakcije.

Hex: "01000000
01
eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2
01000000
8c    4930460221009e0339f72c793a89e664a8a932df073962a3f84eda0bd9e02084
a6a9567f75aa022100bd9cbaca2e5ec195751efdfac164b76250b1e21302e51ca
86dd7ebd7020cdc0601410450863ad64a87ae8a2fe83c1af1a8403cb53f53e486
d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38
855ed6f2ee187e9c582ba6
ffffffff
01
605af40500000000
19
76a914097072524438d003d23a2f23edb65aae1bb3e46988ac
00000000"

Saturday, April 2, 2016

Trošenje Bitcoin transakcije (dio prvi)


Nakon što primatelj dobije bitcoine od pošiljatelja, kako se konstruira transakcija koja te bitcoine troši (šalje novom primatelju)?
Postupak konstruiranja nove transakcije sastoji se od više koraka i bit će prikazan u hex(string) formatu.

1. Verzija


Svaka bitcoin transakcija ima verziju. Verzija je uvijek "01". Polje u koje se zapisuje transakcija veličine je četiri bajta te se verzija zapisuje u little-endian formatu "01000000".
Hex: "01000000"

2. Broj ulaza


Nakon verzije dolazi broj i lista ulaza koje transakcija ima. Ulazi se referenciraju na izlaze prethodnih transakcija koje su poslane tom korisniku. Broj ulaza je cijeli broj varijabilne duljine (tzv. var_int), a najčešće zauzima jedan bajt. Za transakciju s jednim ulazom taj broj je "01".
Hex: "01000000
          01"

3. Indeks prethodne transakcije


Sada slijedi lista ulaza. Svaki ulaz u transakciju sastoji se od četiri dijela: indeks transakcije čiji se izlaz (odnosno bitcoini vezani uz taj izlaz) želi potrošiti, indeksa izlaza, potpisa te oznake niza (sequence). Indeks transakcije je zapravo dvostruki SHA256 hash prethodne transakcije. To je polje veličine 32 bajta te se zapisuje u little-endian formatu. Npr. takav hash može izgledati ovako
"eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2"
 
Hex: "01000000
01
eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2"

4. Indeks izlaza prethodne transakcije

Druga komponenta ulaza u transakciju, nakon indeksa prethodne transakcije, je indeks izlaza prethodne transakcije koji se želi potrošiti. Budući da transakcija može imati više od jednog izlaza, potrebno je označiti koji se točno od tih izlaza želi potrošiti. To je polje veličine četiri bajta te se zapisuje u little-endian formatu. Ako se radi o izlazu "01" to je "01000000".
 
Hex: "01000000
01
eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2
01000000 "

5. Polje scriptSig

Polje scriptSig u svakom ulazu dokazuje da primatelj ima pravo trošenja izlaza iz prethodne transakcije koji referenciraju goreopisani indeks prethodne transakcije i indeks izlaza. To polje sadrži potpis ove transakcije i javni ključ na koji su bitcoini poslani (iz kojeg je izvedena bitcoin adresa na koju su bitcoini poslani). Budući da je transakcija tek u nastajanju, umjesto potpisa transakcije, privremeno se kopira sadržaj polja scripPubKey.
Polje je varijabilne duljine i zapisano je u var_string big-endian formatu. Sadrži duljinu skripte u bajtovima te samu skriptu.

Hex: "01000000
01
eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2
01000000
76a914010966776006953d5567439e5e39f86a0d273bee88ac"

 

6. Oznaka niza (sequence)

Ovo polje uvijek ima maksimalnu vrijednost budući da se nikada nije koristilo onako kako je originalno bilo zamišljeno. Duljine je četiri bajta te se zapisauje u little-endian formatu. U budućnosti će se to polje koristiti za vremenski zaključane transakcije.
Hex: "01000000
01
eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2
01000000
76a914010966776006953d5567439e5e39f86a0d273bee88ac
ffffffff"

7. Broj izlaza

Osim broja ulaza, transakcija sadrži i broj izlaza. Izlazi sadrže adrese i bitcoine koji se na njih šalju. Kao i broj ulaza, broj je izlaza cijeli broj varijabilne duljine (tzv. var_int), a najčešće zauzima jedan bajt. Za transakciju s jednim izlazom taj broj je "01".

Hex: "01000000
01
eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2
01000000
76a914010966776006953d5567439e5e39f86a0d273bee88ac
ffffffff 
01"

8. Iznosi


Iznosi vezani uz pojedini izlaz zapisuju se u satoshijima. Polje je veličine osam bajtova te se prikazuje u little-endian formatu. Za iznos od 0.999 BTC, odnosno 99900000 satoshija to je 605af40500000000.

Hex: "01000000
01
eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2
01000000
76a914010966776006953d5567439e5e39f86a0d273bee88ac
ffffffff 
01
605af40500000000"