Sunday, February 19, 2017

Verificiranje potpisa transakcija za programe svjedočanstva verzije 0 (BIP143)


Originalni način hashiranja transakcije za potpisivanje ima složenost O(n2). Prosječno vrijeme verificiranja transakcija u bloku veličine 1MB je 2sekunde, dok u nekim slučajevima to vrijeme doseže 25 sekundi. Cilj novog algoritma je smanjiti složenost na O(n) uvođenjem međustanja koja su ista za sve ulaze transakcije.

Novi algoritam za hashiranje transakcije za potpisivanje je dvostruki SHA256 vrijednosti:
  1. nVersion
  2. hashPrevouts
  3. hashSequence
  4. outpoint
  5. scriptCode ulaza
  6. vrijednost izlaza koju ovaj ulaz troši
  7. nSequence ulaza
  8. hashOutputs
  9. nLocktime
  10. sighash
1, 4, 7, 9 i 10 imaju isto značenje kao i do sad.
Broj 5:
  • U slučaju P2WPKH scriptCode je 0x19761914{20 bajtova hasha javnog ključa}88ac
  • U slučaju P2WSH scriptCode je redeemScript.
Broj 6 je 8 bajtova koji predstavljaju iznos koji ovaj ulaz troši.
hashPrevouts:
  • Ako zastavica ANYONECANPAY nije postavljena, hashPrevouts je dvostruki SHA256 serijaliziranih outpointova u ulazima.
  • U suprotnom je vrijednost ovog polja 0x000…000 (256-bitova 0).
hashSequence:
  • Ako zastavica ANYONECANPAY, SINGLE ili NONE nije postavljena, hashSequence je dvostruki SHA256 serijalizacije nSequence polja svih ulaza.
  • U suprotnom je vrijednost ovog polja 0x000…000 (256-bitova 0).
 
hashOutputs:
  • Ako zastavice SINGLE ili NONE nije postavljena, hashOutputs je dvostruki SHA256 serijalizacije svih izlaza (iznos + scriptPubKey).
  • Ako je zastavica SINGLE postavljena, a indeks ulaza je manji od broja izlaza, hashOutputs je dvostruki SHA256 iznosa izlaza + scriptPubKey odgovarajućeg izlaza.
  • U suprotnom je vrijednost ovog polja 0x000…000 (256-bitova 0).
Polje hashPrevouts, hashSequence i hashOutputs mogu se ponovno koristiti za sve ulaze te ih je dovoljno računati samo jednom. Kompleksnost postupka se tako smanjuje s O(n2) na O(n).
Za P2WPKH i P2WSH koriste se samo kompresirani javni ključevi.

Primjer

P2WPKH

Transakcija koju treba potpisati:
nVersion: 01000000
txin: 02
fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f
00000000 00 eeffffff
ef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a
01000000 00 ffffffff
txout: 02 202cb20600000000
1976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac
9093510d00000000
1976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac
nLockTime: 11000000
Prvi ulaz pripada P2PK transakciji:
scriptPubKey: 2103c9f4836b9a4f77fc0d81f7bcb01b7f1b35916864b9476c241ce9fc198bd25432ac vrijednost: 6.25
privatni ključ: bbc27228ddcb9209d7fd6f36b02f7dfa6252af40bb2f1cbc7a557da8027ff866
Drugi ulaz pripada P2WPKH transakciji:
scriptPubKey: 00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1 value: 6
privatni ključ: 619c335025c7f4012e556c2a58b2506e30b8511b53ade95ea316fd8c3286feb9
javni ključ: 025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357
Algoritam se provodi za svaki ulaz transakcije. Potpisivat će se sa SIGHASH_ALL zastavicom.
hashPrevouts: dSHA256(fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad9
69f00000000ef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b
90ec68a01000000) =
96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37
hashSequence:
dSHA256(eeffffffffffffff) = 52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b
hashOutputs:
dSHA256(202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7
a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167f
aa815988ac) =
863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5
Prethodne se tri vrijednosti izračunavaju samo jednom i koriste u svim ulazima.
Za prvi ulaz transakcija koja će se hashirati da bi se potpisala izgleda ovako:
nVersion: 01000000
hashPrevouts: 96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37
hashSequence: 52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b
outpoint: fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000
scriptCode: 197614dcea56a687796f1038e2598cc256b627f49f823b88ac
amount: 40be402500000000
nSequence: eeffffff
hashOutputs: 863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5
nLockTime: 11000000
nHashType: 01000000
outpoint je hash prethodne transakcije i indeks izlaza na koju se ovaj ulaz referencira.
Scriptcode sadrži HASH160 javnog ključa P2PK transakcije.
Amount je heksadecimalni little-endian iznosa 6.25 kojeg taj ulaz troši.
Potpis te transakcije je 30450221008b9d1dc26ba6a9cb62127b02742fa9d754cd3bebf337f7a55d114c8e5
cdd30be022040529b194ba3f9281a99f2b1c0a19c0489bc22ede944ccf4ecbab4cc6
18ef3ed
Za drugi ulaz:
nVersion: 01000000
hashPrevouts: 96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37
hashSequence: 52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b
outpoint: ef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a01000000
scriptCode: 1976a9141d0f172a0ecb48aee1be1f2687d2963ae33f71a188ac
amount: 0046c32300000000
nSequence: ffffffff
hashOutputs: 863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5
nLockTime: 11000000
nHashType: 01000000
Hash te transakcije je c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670,
A potpis 304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01
cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de6
7eebee.
Konačna transakcija:
nVersion: 01000000
marker: 00
flag: 01
txin: 02 fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f 00000000 494830450221008b9d1dc26ba6a9cb62127b02742fa9d754cd3bebf337f7a55d11
4c8e5cdd30be022040529b194ba3f9281a99f2b1c0a19c0489bc22ede944ccf4ecb
ab4cc618ef3ed01 eeffffff
      ef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a 01000000 00 ffffffff
txout: 02 202cb20600000000 1976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac
       9093510d00000000 1976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac
witness: 00
                02 47304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f
01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de
67eebee01 21025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357
nLockTime: 11000000

Wednesday, January 18, 2017

Izdvojeno svjedočanstvo (segregated witness)


Izdvojeno svjedočanstvo (engl. segregated witness) struktura je koja se zapisuje u blok izvan Merkleovog stabla transakcija (svjedočanstva se zapisuju u poseban dio transakcije, a ulazi se referenciraju na njih). Sadrži podatke potrebne za provjeru ispravnosti transakcije, no ne i za provjeru rezultata transakcije. Točnije, sadrži skripte i potpise. Svjedočanstvo se zapisuje stablo koje se ugnježđuje u postojeće Merkleovo stablo preko coinbase transakcije.
Ovakav način strukturiranja transakcije omogućuje nekoliko stvari:
  1. Nema više promjenjivosti transakcije. Budući da potpis više nije dio hasha transakcije (jer je u izdvojenom svjedočanstvu), više nije moguće promijeniti potpis transakcije.
  2. SPV klijenti više ne moraju primati potpise transakcija, ako im je cilj samo provjeriti postoji li transakcija.
  3. Hashiranje transakcija kod potpisivanja više ne ovisi o kvadratu veličine bloka.
  4. Povećava se broj transakcija u bloku zbog mjesta koje je oslobođeno izdvajanjem potpisa.

 ID transakcije


Uvođenjem podatkovne strukture svjedočanstva (engl. witness) transakcija će imati dva identifikatora. Standardni txid koji je dvostruki SHA256 serijalizirane transakcije:
[nVersion][txins][txouts][nLockTime]
I novi wtxid koji je dvostruki SHA256 novog formata serijalizirane transakcije:
[nVersion][marker][flag][txins][txouts][witness][nLockTIme]
Marker je veličine jednog bajta i uvijek nula: 0x00.
Flag je veličine jednog bajta te ima vrijednost različitu od nule. Trenutačno: 0x01.
Witness je serijalizacija svih svjedočanstava transakcije. Svaki ulaz transakcije, txin, povezan je s poljem svjedočanstva. Svako polje svjedočanstva počinje var_int tipom podatka koji prikazuje broj podataka koji se stavljaju na stog za pojedini ulaz. Zatim slijede sami podaci od koji svaki opet počinje tipom podatka var_int koji opisuje duljinu podatka. Svjedočanstvo nije skripta.
Ako je transakciju kreirao stariji klijent koji ne podržava svjedočanstva, ulazi u transakciju moraju imati prazno witness polje: 0x00. U tom je slučaju wtxid = txid.

Zapis svjedočanstva

Svi wtxid-ovi moraju se zapisati. Wtxid coinbase transakcije je 0x0000…0000.
Vršni hash svjedočanstava izračunava se iz svih wtxid-ova u bloku, slično korijenu Merkleovog stabla. Taj se hash zapisuje u scriptPubKey coinbase transakcije. Zapis je minimalne duljine 38 bajtova, s time da je prvih šest 0x6a24aa21a9ed:
1 bajt – OP_RETURN (0x6a)
1 bajt – Stavi sljedećih 36 bajtova (0x24) na stog
4 bajta – zaglavlje zapisa (0xaa21a9ed)
32 bajta – hash zapisa – dvostruki SHA356(vršni hash svjedočanstava | rezervirana vrijednost)
scriptPubKey polje sadrži i 32-bitnu rezerviranu vrijednost. Ako postoji više izlaza takve strukture, onaj s najvećim indeksom smatra se zapisom hasha svjedočanstva. Rezervirana vrijednost zasad nema nikakvog značenja

Program svjedočanstva (witness program)

Skripta scriptPubKey koja se sastoji od bajta [OP_0..OP_16] nakon kojeg slijedi 2 do 40 bajtova dobiva novo značenje. Prvi bajt naziva se bajt verzije. Ostali bajtovi predstavljaju program svjedočanstva.
Dva slučaja u kojima se svjedočanstvo verificira su:
  1. Ako se scriptPubKey sastoji od bajta verzije i programa svjedočanstva. U tom slučaju scriptSig mora biti prazan jer je u suprotnom transakcija neispravna.
  2. Ako je scriptPubKey P2SH skripta. U tom je slučaju redeemScript skripta u polju scriptSig bajt verzije plus program svjedočanstva. Ako u polju scriptSig nije BIP16 redeemScript, transakcija nije ispravna.
 
Ako je bajt verzije 0, a program svjedočanstva je duljine 20 bajtova:
  • Interpretira se kao pay-to-witness-public-key-hash (P2WPKH) program.
  • Svjedočanstvo se sastoji od 2 elementa (oba manja od 520 bajtova). Prvi je potpis, a drugi javni ključ.
  • HASH160 javnog ključa mora odgovarati programu svjedočanstva.
  • Nakon verifikacije skripte, potpis se verificira pomoću javnog ključa korištenjem naredbe CHECKSIG.
Ako je bajt verzije 0, a program svjedočanstva je duljine 32 bajta:
  • Interpretira se kao pay-to-witness-script-hash (P2WSH) program.
  • Svjedočanstvo se sastoji od elemenata koji su ulaz skripti te serijalizirane skripte (witnessScript < 10000 bajtova).
  • SHA256 skripte witnessScript mora odgovarati programu svjedočanstva.
  • witnessScript se deserijalizira i izvršava.


Ako je bajt verzije 0, a program svjedočanstva nije duljine 20 niti 32 bajta, skripta nije ispravna. Ako je verzija veća od nule, program svjedočanstva se ne interpretira.

Parametri i semantika

Težina bloka računa se kao veličina bloka (1 MB) plus ukupna veličina svjedočanstava (3 MB).
Broj potpisa po bloku povećava se s 20.000 na 80.000.
Uvode se tri nova pravila za rudarenje:
  1. Za P2WPKH i P2WSH prihvaćaju se samo komprimirani javni ključevi.
  2. Argumenti za OP_IF i OP_NOTIF moraju biti prazan vektor (neistina) ili 0x01 (istina).
  3. Ako OP_CHECKSIG ili OP_CHECKMULTISIG ne uspiju, potpis mora biti nul-vektor.

Primjeri

P2WPKH


Slijedi primjer verzije 0 P2WPKH:
scriptPubKey: 0 <20 bajtova hasha javnog ključa>
(0x0014{20 bajtova hasha})
scriptSig: (prazno)
svjedočanstvo: <potpis><javni ključ>
Ponašanje je vrlo slično dosadašnjem. Skripta scriptPubKey u izlazu transakcije šalje bitcoine na hash javnog ključa (adresu). Transakcija koja želi te bitcoine potrošiti daje javni ključ koji odgovara hashu u izlazu transakcije koja je bitcoin poslala i potpis transakcije. Umjesto da se potpis i javni ključ nalaze u polju scriptSig, nalaze se u polju svjedočanstva.
U skripti scriptPubKey 0 označuje verziju witness programa. Duljina programa kaže da se radi o vrsti P2WPKH. Potpis se verificira s: <signature><pubkey> CHECKSIG. U usporedbi s P2PKH, P2WPKH koristi tri bajta manje u scriptPubKey.

P2WSH

Slijedi primjer 1 od 2 višepotpisne transakcije verzije 0 P2WSH:
scriptPubKey: 0 <32 bajta hasha skripte svjedočanstva>
(0x0020{32 bajta hasha})
scriptSig: (prazno)
svjedočanstvo: 0 <potpis1> <1 <javni1> <javni2> 2 CHECKMULTISIG>
U skripti scriptPubKey 0 označuje verziju witness programa. Duljina programa kaže da se radi o vrsti P2WSH. Posljednji element u svjedočanstvu (witnessScript) hashira se pomoću SHA256 te se hash uspoređuje s 32-bajtnom vrijednošću u polju scriptSig. Ako odgovaraju, skripta se izvršava. P2WSH povećava veličinu skripte s dosadašnjih 520 bajtova na 10.000.

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"

Friday, December 25, 2015

Vremenski zaključane transakcije: Primjeri

Zajamčeni polog (escrow)


Ako Alice i Bob žele zajedno upravljati poslom, zajednička sredtva mogu držati u 2-od-2 višepotpisnoj transakciji. No u slučaju smrti jedne strane, druga strana neće imati pristup zajedničkim sredstvima. Zato bi mogli zaposili odvjetnika Lennyja da bude treća strana u slučaju nezgode. No kod 2-od-3 višepotpisne transakcije, odvjetnik se može urotit s bilokojom stranom te ukrasti zajednička sredstva. U ovakvom se slučaju može iskoristiti operator CHECKLOCKTIMEVERIFY u scriptSig dijelu transakcije:

IF
    <sad + 3 mjeseca> CHECKLOCKTIMEVERIFY DROP
    <Lennyjev pubkey> CHECKSIGVERIFY
    1
ELSE
    2
ENDIF


<Alicin pubkey> <Bobov pubkey> 2 CHECKMULTISIG

Ovakva se transakcija može potrošiti u bilokojem trenutku ovako:

0 <Alicin potpis> <Bobov potpis> 0
Postupak trošenja je sljedeći:
 
0
Bobov potpis
Alicin potpis
0
 
 
Ovako izgleda stog nakon pokušaja trošenja gornje vremenski zaključane transakcije prije isteka roka valjanosti. Naredba IF provjerava prvi element na stogu te se izvršavanje dalje nastavlja ovisno o tom elementu. Na vrhu stoga je 0 koja se tretira kao neistina te se prelazi na ELSE dio naredbe koja na stog stavlja 2.

2
Bobov potpis
Alicin potpis
0

 
Izgled stoga nakon izvršavanja naredbe IF. Ovo je sada normalna 2-od-2 višepotpisna transakcija
0 <Bobov potpis> <Alicin potpis> 2 <Alicin pubkey> <Bobov pubkey> 2 CHECKMULTISIG
Zbog buga u naredbu CHECKMULTISIG, m-od-n višepotpisna transakcija uzima jedan više potpis nego je zapravo potrebno.

Nakon isteka roka valjanosti ovu je transakciju moguće potrošiti na sljedeći način:
0 <Alicin/Bobov potpis> <Lennyjev potpis> 1

1
Lennyje potpis
Alicin/Bobov potpis
0

 
Ovako izgleda stog nakon pokušaja trošenja gornje vremenski zaključane transakcije nakon isteka roka valjanosti. Na stogu je 1 koji se tretira kao istina te se prelazi na provjeru roka valjanosti. Rok valjanosti ističe tri mjeseca nakon nastanka transakcije.

sad + 3 mjeseca
Lennyjev potpis
Alicin/Bobov potpis
0

 
Na stog se stavlja rok valjanosti te se uspoređuje s poljem nLockTime transakcije koja taj izlaz želi potrošiti. Budući da je rok istekao, izlaz se smije potrošiti. Naredba DROP odbacuje gornji element stoga (u ovom slučaju rok valjanosti).

Zatim se uzima Lennyjev javni ključ s kojim naredba CHECKSIGVERIFY provjerava Lennyjev potpis na stogu. Ako je potpis ispravan na stog se na kraju stavlja 1.

1
Alicin/Bobov potpis
0

Sada je ovo 1-od-2 višepotpisna transakcija koja se može potrošiti pomoću Alicinog ili pomoću Bobovog potpisa
0 Alicin/Bobov potpis 1 <Alicin pubkey> <Bobov pubkey> 2 CHECKMULTISIG

Neinteraktivna vremenski zaključana nadoknada


U nekim je protokolima potrebna suradnja dvije strane da bi se potrošila neka transakcija. U slučaju nedostupnosti jedne strane, povrat novca (nadoknada) se vremenski zaključati kako bi se nakon isteka roka valjanosti vratio pošiljatelju. Takva transakcija u kojoj Alice šalje Bobu sredstva može izgledati ovako
 
IF
     <rok_valjanosti> CHECKLOCKTIMEVERIFY DROP
    1
ELSE
     2
ENDIF
<Alicin pubkey> <Bobov pubkey> 2 CHECKMULTISIG

Slično kao i u prethodnom primjeru, ovakva se transakcija može prije isteka roka potrošiti s

0 <Alicin potpis> <Bobov potpis> 0

U slučaju nedostupnosti jedne strane i nakon isteka roka valjanosti, transakcija se može potrošiti s

0 <Alicin/Bobov potpis> 1

Plaćanje za objavljivanje podataka


Postoje usluge koje omogućuju plaćanje za objavljivanje informacija. Osoba koja objavljuje informaciju prvo mora dokazati da kriptirani dokument sadrži tražene podatke, a zatim konstruirati transakciju koja će otkriti ključ za dekripciju podataka. Trenutačne implementacije takvih sustava omogućuju osobi koja objavljuje informaciju da nikad ne otkrije tajni ključ. Taj se nedostatak može riješiti korištenjem naredbe CHECKLOCKTIMEVERIFY:

IF
    HASH160 <hash160(tajni_ključ)> EQUALVERIFY
    <pubkey objavljivača> CHECKSIG
ELSE
     <rok valjanosti> CHECKLOCKTIMEVERIFY DROP
     <pubkey platitelja> CHECKSIG
ENDIF

Objavljivač informacije transakciju može potrošiti ovako:
<potpis objavljivača> <tajni ključ> 1
 
1
Tajni ključ
Pubkey objavljivača

Ovako izgleda stog nakon pokušaja trošenja transakcije. 1 se smatra istinom te se prelazi na verifikaciju tajnog ključa.
 
Tajni ključ
Pubkey objavljivača

Gornji element stoga se hashira funkcijom HASH160 te uspoređuje s hashem podatka u transakciji. U slučaju da su identični (objavljen je pravi tajni ključ), verificira se potpis objavljivača te je tajna otkrivena onome tko je platio za nju.

U slučaju da objavljivač ne objavi tajni ključ, platitelj može dobit povrat novca nakon isteka roka valjanosti:
 
0 <potpis platitelja>
 
0
potpis platitelja

Zbog 0 se pralazi u ELSE dio transakcije koji na stog stavlja rok valjanosti i uspoređuje ga s poljem nLockTime:
 
Rok valjanosti
Potpis platitelja

Ako je rok prošao, odbacuje se sa stoga te se verificira potpis platitelja te on dobiva uplaćeni novac natrag.

Friday, December 18, 2015

Vremenski zaključane transakcije (BIP 65)


Svaka bitcoin transakcija ima polje nLockTime. Zamišljeno je da sadrži vrijednost koja govori kada se transakcija može potrošiti u budućnosti. Vrijednost polja može se interpertirati na dva načina: ako je vrijednost manja od 500.000.000 tretira se kao visina bloka u kojem transakcija postane validna, a ako je vrijednost veća od toga, tretira se kao datum kada transakcija postaje validna (broj sekundi od 1. siječnja 1970.).

Takva se transakcija može uključiti u blok koji je na zadanoj ili većoj visini, odnosno čije je vrijeme pronalaska veće ili jednako onome u polju nLockTime. Problem je što se ne može garantirati da izlazi koje koristi transakcija s popunjem nLockTime poljem neće prije potrošiti neka druga transakcija.

Zato je definirana naredba CHECKLOCKTIMEVERIFY (odnosno redefinirana je naredba NOP2). Ona služi tome da se zaključaju pojedini izlazi iz transakcija koji će se potrošiti u budućnosti te prima jedan parametar: rok valjanosti. Kada se tako zaključani izlaz želi potrošiti, njegov se rok valjanosti uspoređuje s poljem nLockTime transakcije koja ga troši. Izlaz će se potrošiti samo ako je rok valjanosti manji od nLockTime. Transakcije zaključane s CHECKLOCKTIMEVERIFY mogu se normalno uvrstiti u blok.

Primjer zamrzavanja sredstava


Slijedi primjer skripte u skriptnom jeziku Bitcoina kojom je moguće zamrznuti sredstva sve dok ne istekne zadani rok valjanosti:


<rok valjanosti> CHECKLOCKTIMEVERIFY DROP DUP HASH160 <pubKeyHash> EQUALVERIFY CHECKSIG


Transakcija koja će potrošiti ovaj izlaz mora imati nLockTime veći od roka valjanosti. Budući da se transakcija s takvim poljem može tek uključiti u blok čija je visina ili vrijeme veće od vrijednosti nLockTime, originalna će transakcija ostati nepotrošena do zadanog vremena. Nakon isteka roka valjanosti, transakcija se dalje normalno validira.

Zaobilaženje roka valjanosti


Rok valjanosti moguće je zaobići ako transakcija koja troši vremenski zaključani izlaz redne brojeve svojih izlaza postavi na maksimum (0xffffffff). To je zaostatak iz starih verzija protokola Bitcoin te operacija CHECKLOCKTIMEVERIFY provjerava vrijednosti rednih brojeva ulaza. Ako redni broj nije maksimum transakcija će moći normalno potrošiti izlaz ako je prošao rok valjanosti. U suprotnom, transakcija ne može potrošiti izlaz.

Sunday, December 6, 2015

Detalji coinbase transakcije


Na početku svakog bloka transakcija nalazi se tzv. coinbase transakcija. Ona donosi nagradu onome tko je uspješno izrudario blok. Sama nagrada sastoji se od subvencije za blok (trenutačno 25 BTC) te od naknada za sve transakcije u bloku.

Primjer strukture coinbase transakcije je
Version
1
Inputs
Prevoius hash
0
Index
0xFFFFFFFF
ScriptSig
03dae7052f4249503130302f040e7164560902c8108999000000d3072f425443432f20
Sequence
0
Outputs
Value
2510629190
ScriptPubKey
76a9142c30a6aaac6d96687291475d7d52f4b469f665a688ac
Locktime
0

U odnosu na ostale transakcije, coinbase transakcija je pojednostavljena. Nema referencu na prethodnu transakciju jer stvara nove bitcoine, a ne preuzima već postojeće. Budući da se ne referira na prethodnu transakciju, nema niti indeks prethodnog izlaza.

Coinbase transakcija nije niti potpisana digitalnim potpisom nego se polje ScriptSig koristi kao tzv. extra nonce polje. Često polje nonce u zaglavlju transakcije nije dovoljno veliko da bi se moglo samo koristiti za pretraživanje svih mogućih vrijednosti noncea. Zato se ono dopunjava poljem ScriptSig u koje se upisuje dio noncea koji nije stao u zaglavlje. Na taj način rudari dobivaju više mogućnosti za kombiniranje.

BIP34

Osim što služi kao extra nonce, u prvi bajt polja ScriptSig zapisuje se i visina bloka u kojem se nalazi coinbase transakcija. To osigurava da je hash svakog idućeg bloka i transakcije jedinstven. Format zapisa je broj bajtova u visini te sama visina zapisana u little endian formatu. U gornjem primjeru to je "03dae705", odnosno "03" bajta za visinu te visina u little endian formatu "dae705", odnosno u big endianu 05e7da te u decimalnom formatu 387034. Blok 227835 je prvi blok takvog formata te on i svi sljedeći imaju verziju 2.

Sunday, November 1, 2015

Vrste potpisa bitcoin transakcija


Bitcoin transakcije sastoje se od ulaza i izlaza. Ulazi sadrže reference na izlaze prethodnih transakcija koji su pod kontrolom korisnika te skripte za svaki ulaz koje omogućuju trošenje sredstava s prethodnih transakcija. Izlazi šalju vrijednosti iz trenutačne transakcije na adrese drugih korisnika.
Kada se bitcoin transakcija potpisuje, moguće je potpisati razne kombinacije ulaza i izlaza. Postoje tri moguće vrste potpisa, tzv. sighash_all, sighash_none te sighash_single. Uz to, uz svaki od tri tipa može ići dodatan modifikator anyonecanpay.

SIGHASH_ALL


Sighash_all najčešća je vrsta potpisa kod koje se potpisuju svi ulazi i izlazi iz transakcije. Ovaj način potpisivanja štiti cijelu transakciju od mogućih promjena.

SIGHASH_NONE


Ovaj način potpisivanja transakcije potpisuje sve ulaze, ali niti jedan izlaz što omogućuje bilokome da odredi kuda će se poslati satoshiji iz transakcije.

SIGHASH_SINGLE


Kod ovakvog se načina potpisivanja potpisuje se točno jedan izlaz čiji indeks odgovara ulazu specificiranom parametrom. Dakle, potpisuje se samo jedan ulaz i izlaz. Ostali se izlazi potpisuju samo djelomično (može im se promijeniti broj u nizu, engl. Sequence number). Takva transakcija omogućue drugim korisnicima da dodaju vlastite izlaze u nju.


Ovaj tip potpisa ne bi smio imati više ulaza nego izlaza, no Bitcoin protokol to ne zabranjuje. Ako se specificira ulaz koji nema pripadajući izlaz, nepostojećem će se izlazu pridijeliti hash 0x01.

SIGHASH_ANYONECANPAY

Ovaj modifikator znači da se potpisuje samo ulaz specificiran parametrom. Ostali korisnici mogu dodavati ulaze po želji.


To daje još tri mogućnosti potpisivanja transakcija.

SIGHASH_ALL SIGHASH_ANYONECANPAY


Potpisuje sve izlaze i samo jedan ulaz. Ovo omogućuje bilo kome da doda još ulaza u transakciju no ostali ne mogu promijeniti koliko će se satoshija poslati i na koju adresu.

SIGHASH_NONE SIGHASH_ANYONECANPAY


Potpisuje samo jedan ulaz te niti jedan od izlaza. Omogućuje ostalima da dodaju ulaze i izlaze po želji, odnosno da potroše transakciju kako žele.

SIGHASH_SINGLE SIGHASH_ANYONECANPAY

 Potpisuje samo jedan ulazi i izlaz. Ostalima omogućuje proizvoljno dodavanje ulaza i izlaza.

Sunday, October 18, 2015

Striktni DER potpisi (BIP66)


U protokolu Bitcoin digitalni se potpisi enkodiraju u DER formatu. DER (distinguished encoding rules) je potskup BER formata (basic encoding rules) koji služi za enkodiranje podatkovnih struktura. DER format koristi se za jednoznačno enkodiranje, na primjer u kriptografskim protokolima.

Za validaciju potpisa transakcija u protokolu Bitcoin koristila se biblioteka OpenSSL. Budući da je ta biblioteka dopuštala određena odstupanja od DER formata, propisan je striktni DER format za enkodiranje potpisa. Taj format ne dopušta odstupanja te potpis koji nije u striktnom DER formatu nije validan.

Striktni DER format


Striktni DER format izgleda ovako:

0x30 [ukupna-duljina] 0x02 [R-duljina] [R-vrijednost] 0x02 [S-duljina] [S-vrijednost][tip potpisa]
 
  • Svaki DER potpis počinje bajtom 0x30.
  • Ukupna-duljina je duljina u bajtovima svega što slijedi, ne računajući bajt za tip potpisa.
  • 0x02 je bajt separatora.
  • R-duljina je bajt koji predstavlja duljina vrijednosti R u bajtovima.
  • R je vrijednost proizvoljne duljine enkodirana u big-endian formatu. Predstavlja r vrijednost u algoritmu ECDSA. Vrijednost ne može počinjati bajtom 0x00, osim ako bajt koji slijedi nije 0x80 ili veći. Ako je to slučaj, početni bajt mora biti 0x00.
  • S-duljina je bajt koji predstavlja duljina vrijednosti S u bajtovima.
  • S je vrijednost proizvoljne duljine enkodirana u big-endian formatu. Predstavlja s vrijednost u algoritmu ECDSA. Vrijednost ne može počinjati bajtom 0x00, osim ako bajt koji slijedi nije 0x80 ili veći. Ako je to slučaj, početni bajt mora biti 0x00.
  • Tip potpisa je bajt koji označuje vrstu potpisa. Dozvoljene su mu vrijednosti 0x01, 0x02, 0x03, 0x81, 0x82 te 0x83.
Ukupna duljina potpisa je najviše 72 bajta. Svi blokovi čiji rudari prepoznaju BIP66 imaju verziju 3.

Thursday, October 8, 2015

Formati ključeva


U protokolu Bitcoin postoje dvije vrste ključeva: privatni i javni. Privatni je ključ broj u rasponu od 1 do 115792089237316195423570985008687907852837564279074904382605163141518161494336. Javni ključ generira se iz privatnog množenjem privatnog ključa generatorom sliptičke krivulje. Rezultat su dva broja, x koordinata krivulje te y koordinata krivulje. Javni se i privatni ključevi radi praktičnosti zapisa ne prikauzju uvijek u decimalnom obliku.
Slijede primjeri različitih oblika zapisa ključeva. Za primjer privatnog ključa uzet je
d = 105627842363267744400190144423808258002852957479547731009248450467191077417570. Njemu pripadajući javni ključ je
Q = [40052878126280527701260741223305245603564636128202744842713277751919610658249,
 112427920116541844817408230468149218341228927370925731589596315545721129686052] gdje je prvi broj x koordinata, a drugi y koordinata eliptičke krivulje.

Privatni ključevi

Slijede formati zapisa privatnih ključeva. Duljina privatnog ključa je 32 bajta ili 256 bitova.

Heksadecimalni


Najčešći format zapisa privatnog ključe je heksadecimalni. To je ujedno i najjednostavniji zapis jer je privatni ključ potrebno samo pretvoriti u heksadecimalni oblik. Takav zapis izgledao bi ovako:
E9873D79C6D87DC0FB6A5778633389F4453213303DA61F20BD67FC233AA33262. Njegova duljina je 64 heksadecimalna znaka.

Heksadecimalni kompresirani


Još jedan jednostavni format zapisa privatnog ključa je heksadecimalni kompresirani format. Sastoji se od dodavanja bajta '0x1' na kraj ključa. Tako bi ključ iz primjera izgledao ovako: E9873D79C6D87DC0FB6A5778633389F4453213303DA61F20BD67FC233AA3326201. Duljina mu je 66 heksadecimalna znaka.

Heksadecimalni kompresirani format zapravo je dulji od normalnog heksadecimalnog formata. Naziva se kompresirani samo zato što služi za generiranje kompresiranih javnih ključeva koji umjesto 65 bajtova zauzimaju samo 33 bajta.

Wallet Import Format (WIF)

WIF je jedan od najčešćih formata zapisa privatnog ključa. Najčešće ga koriste novčanici za spremanje ključa. Postupak pretvaranja privatnog ključa u WIF format ima nekoliko koraka:
  1. Generira se privatni ključ.
  2. Na početak mu se doda bajt 0x80.
  3. Taj se niz dva puta hashira algoritmom SHA256.
  4. Od dobivenog se rezultata uzmu početna četiri bajta koji će služiti kao zaština suma.
  5. Ta se četiri bajta dodaju na kraju niza dobivenog u drugom koraku.
  6. Dobiveni se niz zatim pretvori u base58check bazu.
Za ključ iz primjera WIF je 5Kb8kLf9zgWQnogidDA76MzPL6TsZZY36hWXMssSzNydYXYB9KF. Wallet import format uvijek počinje brojem 5.

Kompresirani WIF

Kompresirani WIF sličan je normalnom WIF zapisu samo što se dobiva iz kompresiranog privatnog ključa. U koracima navedenima za dobivanje wallet import formata u drugom je koraku potrebno dodati i bajt '0x1' na kraj niza uz bajt '0x80' na početku niza. Rezultat je L53fCHmQhbNp1B4JipfBtfeHZH7cAibzG9oK19XfiFzxHgAkz6JK. Kompresirani WIF ključevi počinju s 'K' ili 'L'.

Javni ključevi

Slijede formati zapisa javnih ključeva. Duljina privatnog ključa je 64 bajta plus bajt prefiksa što daje 512, odnosno 520 bitova.

Heksadecimalni

Zapis javnog ključa u heksadecimalnom formatu je: 04 || x || y. Operator || označuje konkatenaciju, a x i y su x i y koordinate javnog ključa u heksadecimalnom obliku. Javni ključbi tad izgledao:
04588d202afcc1ee4ab5254c7847ec25b9a135bbda0f2bc69ee1a714749fd77dc9f88ff2a00d7e752d44cbe16e1ebcf0890b76ec7c78886109dee76ccfc8445424. Duljina mu je 130 heksadecimalnih znakova odnosno 65 bajtova računajući bajt prefiksa '0x4'.

Heksadecimalni kompresirani

Kompresirani javni ključ dobiva se iz kompresiranog privatnog ključa. Umjesto da se sastoji od x i y koordinate, dovoljna je samo x koordinata. Y se dobije rješavanjem jednadžbe eliptičke krivulje (y2 = x3 + 7) mod p. Da bi se jednoznačno odredio y potrebna je informacija je li on pozitivan ili negativan (odnosno, u slučaju konačnog polja, paran ili neparan). Ako je y paran, x koordinati dodaje se bajt prefiksa '0x2', ako je neparan dodaje se '0x3'. Kompresirani ključ tada izgleda ovako: 02588d202afcc1ee4ab5254c7847ec25b9a135bbda0f2bc69ee1a714749fd77dc9. U ovom je slučaju y paran pa je prefiks '0x2'. Duljina mu je 66 znakova, odnosno 33 bajta računajući bajt prefiksa.

Budući da se i kompresirani i nekompresirani javni ključevi komu koristiti za dobivanje bitcoin adresa te da će te adrese biti različite, potrebno je paziti koji se ključ koristi. O tome računa vode bitcoin novčanici koji uglavnom koriste kompresirani format budući da zauzima manje mjesta.