1 Most of this information is now at the Protocol Specification page at the bitcoin wiki:
2 https://en.bitcoin.it/wiki/Protocol_specification
4 One of these days I might check this document against the wiki, add any missing information to the wiki, and remove the information below.
7 Transaction dissection notes:
8 -----------------------------
10 My first two transactions look like this:
12 ==WalletTransaction== f240...2582
13 Merkle hashBlock: 6d40...0000
15 ['TxIn: prev(e9d4...d2f4:0) pubkey: 1Lfic7L3z7xUbxRDvMNFiE3QxKRmSSrvEH sig: 72:3045...1a01 65:0403...7b86']
16 ['TxOut: value: 500.00 pubkey: 19vcWM6EEbQHVdN2W8NXv9ySgsPjbZ6gU3 Script: DUP HASH160 20:61e4...614c EQUALVERIFY CHECKSIG']
17 timeReceived:Thu May 27 14:25:48 2010 fromMe:True spent:True
19 ==WalletTransaction== f961...4472
20 Merkle hashBlock: 7707...0000
22 ['TxIn: prev(f240...2582:0) pubkey: 19vcWM6EEbQHVdN2W8NXv9ySgsPjbZ6gU3 sig: 72:3045...a801 65:04a6...a541']
23 ['TxOut: value: 142.40 pubkey: 15F9miF9egehbeCiPKVSJSwgw5J96my7Rf Script: DUP HASH160 20:2e8d...5179 EQUALVERIFY CHECKSIG', 'TxOut: value: 357.60 pubkey: 1Av6tJSFv3bZvUfaALm4TQZmYvdeuHcbUb Script: DUP HASH160 20:6cc4...1755 EQUALVERIFY CHECKSIG']
24 timeReceived:Fri May 28 13:55:23 2010 fromMe:True spent:True
26 So: whoever has sending bc address 1Lfic7L3z7xUbxRDvMNFiE3QxKRmSSrvEH sent 500 bitcoins to
27 my 19vcWM6EEbQHVdN2W8NXv9ySgsPjbZ6gU3 receiving address.
29 I then sent 142.40 to bcaddress 15F9miF9egehbeCiPKVSJSwgw5J96my7Rf.
30 And got 357.60 in change (Bitcoin created a new address for the change: 1Av6tJSFv3bZvUfaALm4TQZmYvdeuHcbUb)
32 Spending generated coins looks different:
34 Transaction 6403...cc0e
35 ['TxIn: COIN GENERATED coinbase:0464ba0e1c010a']
36 ['TxOut: value: 50.00 pubkey: 1Cpr8WJYa5igdo8AtPS24hfVLkk6ANZSWN Script: 65:0442...11c2 CHECKSIG']
38 Transaction db39...8dcd:
39 ['TxIn: COIN GENERATED coinbase:0464ba0e1c0130']
40 ['TxOut: value: 50.00 pubkey: 1LuamEE1rL1QAdgn48gGFD9T9mnqSeP17w Script: 65:04f2...e10f CHECKSIG']
42 ==WalletTransaction== 3860...f888
43 ['TxIn: prev(6403...cc0e:0) pubkey: (None) sig: 72:3045...f501', 'TxIn: prev(db39...8dcd:0) pubkey: (None) sig: 73:3046...9\
45 ['TxOut: value: 100.00 pubkey: 1BBWNxMqU2bTwSVeUDVKmNYJrWr4D1pBrf Script: DUP HASH160 20:6fad...ab90 EQUALVERIFY CHECKSIG']
47 Here I received 100 bitcoins from two 50 COIN GENERATED transactions.
50 blkindex.dat serialization notes:
51 ---------------------------------
53 Keys beging with a serialized string, rest of key and value depend on that first string. Possibilities are:
55 tx : key continues with uint256 transaction hash/id (32 bytes)
57 version : 32-bit unsigned int
58 CDiskTxPos : location of transaction (in the blk000N.dat files)
59 vector<CDiskTxPos> : location of transactions that spend this transaction's inputs
61 blockindex : key continues with uint256 block hash (32 bytes)
62 value is serialized CDiskBlockIndex
64 version : value is integer version number
66 hashBestChain : value is 32-byte SHA256 hash of last block in the longest block chain.
69 wallet.dat serialization notes:
70 -------------------------------
71 Berkely DB BTREE file (key-value pairs).
73 Keys begin with a serialized string, rest of key and value depend on that first string. Possibilities are:
75 name : key continues with 34-character Bitcoin "hash160" address
76 value is a simple string.
78 tx : key continues with uint256 (32 bytes)
79 value is a serialized CTransaction+CMerkleTx+CWalletTx (see below for details)
81 key : key continues with vector<unsigned char> that is public key
82 value is vector<unsigned char> that is private key (full 271-byte
83 OpenSSL representation)
85 wkey : key continues with vector<unsigned char> that is public key
86 value is serialized CWalletKey:
87 vector<unsigned char> that is private key
92 ckey : enCrypted key continues with vector<unsigned char> that is public key
93 value is vector<unsigned char> that is private key (32 byte private part,
94 not full 271-byte OpenSSL representation)
96 mkey : master key continues with unsigned int that is ID of the master key
97 value is serialized CMasterKey:
98 vector<unsigned char> encrypted key
99 vector<unsigned char> encrypted salt
100 unsigned int indicating the method to derive key from password
101 unsigned int indicating the number of times the derivation algorithm should be iterated
102 vector<unsigned char> holding other parameters to the derivation algorithm
105 value is vector<unsigned char> default key
108 value is int version number
110 setting : key continues with setting name, value depends on setting as follows:
111 addrIncoming : CAddress serialized
112 addrProxy : CAddress serialized
113 fGenerateBitcoins : 1-character (boolean)
114 fLimitProcessors : 1-character (boolean)
115 fMinimizeOnClose : 1-character (boolean)
116 fMinimizeToTray : 1-character (boolean)
117 fUseProxy : 1-character (boolean)
118 nLimitProcessors : int
119 nTransactionFee : int64
122 Complex value type serialization:
123 ---------------------------------
126 uint32 nFile : Which of the blk000*.dat files
127 uint32 nBlockPos : Byte position in file
128 uint32 nTxPos : Byte position in file
133 uint32 nFile : Which of the blk000*.dat files
134 uint32 nBlockPos : Byte position in file
135 int nHeight : height in block chain
136 int blockVersion : ??? Not sure why version is repeated...
138 uint256 hashMerkleRoot
144 # Note: 4 bytes: f9 be b4 d9 are written before records in blk000N.dat files
145 # But the nBlockPos pointers in CDiskBlockIndex points to start of serializedSize
149 uint256 hashMerkleRoot
159 unsigned char[12] pchReserved
167 unsigned int nLockTime
172 unsigned int nSequence
179 36 bytes(FLATDATA): 32-byte hash, 4-byte unsigned int
182 vector<unsigned char> containing built-in little scripting-language script
183 (opcodes and arguments to do crypto stuff)
186 ... serialize CTransaction, then:
188 vector<uint256> vMerkleBranch
192 ... serialized CMerkleTx, then:
193 vector<CMerkleTx> vtxPrev
194 map<string,string> mapValue
195 vector<pair<string,string> > vOrderForm
196 unsigned int fTimeReceivedIsTxTime
197 unsigned int nTimeReceived
202 int type : 1:tx 2:block
207 vector<uint256> # Block hashes, newest back to genesis block (dense to start, but then sparse)
210 1/3/5/9 bytes giving length:
211 1 byte if length < 253.
212 otherwise byte value '253'+ushort, '254'+uint, '255'+uint64
216 1/3/5/9 bytes giving count (see string, above)
217 followed by that many <types> serialized one-after-another
220 just first item followed by second item
223 PUBLIC KEYS TO BITCOIN ADDRESSES
224 --------------------------------
226 Public key, in memory (65 bytes):
228 0x94c7818: 0x04 0x57 0xcc 0xad 0xd7 0x1e 0xb0 0xf3
229 0x94c7820: 0xc1 0x9d 0x22 0xb9 0xba 0x0e 0xa1 0xf3
230 0x94c7828: 0x44 0x2a 0x6f 0x12 0x31 0x46 0xb5 0xbd
231 0x94c7830: 0xff 0x10 0x60 0xbc 0xd1 0x11 0x68 0xe6
232 0x94c7838: 0x6a 0x71 0xbe 0xd4 0xda 0x17 0x7c 0x12
233 0x94c7840: 0xd7 0x30 0x9a 0xdd 0xfd 0xf5 0x6c 0x31
234 0x94c7848: 0xd5 0xc8 0xa2 0x7b 0x8e 0x6a 0x22 0x20
235 0x94c7850: 0x38 0x42 0xc6 0xc2 0x4f 0xd5 0x9b 0xd7
238 public_key = "\x04\x57\xcc\xad\xd7\x1e\xb0\xf3\xc1\x9d\x22\xb9\xba\x0e\xa1\xf3\x44\x2a\x6f\x12\x31\x46\xb5\xbd\xff\x10\x60\xbc\xd1\x11\x68\xe6\x6a\x71\xbe\xd4\xda\x17\x7c\x12\xd7\x30\x9a\xdd\xfd\xf5\x6c\x31\xd5\xc8\xa2\x7b\x8e\x6a\x22\x20\x38\x42\xc6\xc2\x4f\xd5\x9b\xd7\xb7"
240 SHA256 hash of that is:
241 0xb6890938: 0x0d 0x72 0xab 0x02 0xc8 0xab 0x52 0xce
242 0xb6890940: 0x7e 0x6b 0x04 0x00 0x95 0x58 0x09 0xf0
243 0xb6890948: 0x93 0x48 0x21 0xb6 0x26 0xc3 0x27 0xc7
244 0xb6890950: 0x9a 0x07 0x62 0xfd 0xbc 0x5e 0xb8 0xa5
245 h1 = SHA256.new(public_key).digest()
247 RIPEMD160(SHA256(public key)) is:
248 0xb68909ac: 0x5c 0xc8 0x7f 0x4a 0x3f 0xdf 0xe3 0xa2
249 0xb68909b4: 0x34 0x6b 0x69 0x53 0x26 0x7c 0xa8 0x67
250 0xb68909bc: 0x28 0x26 0x30 0xd3
251 h2 = RIPEMD160.new(h1).digest()
253 Put version number '0x00' byte onto front:
254 0x9eeb840: 0x00 0x5c 0xc8 0x7f 0x4a 0x3f 0xdf 0xe3
255 0x9eeb848: 0xa2 0x34 0x6b 0x69 0x53 0x26 0x7c 0xa8
256 0x9eeb850: 0x67 0x28 0x26 0x30 0xd3
259 Hash (double-SHA256) that:
260 0xb68908e8: 0xf9 0xb7 0x8e 0x64 0x6e 0x20 0x27 0xc4
261 0xb68908f0: 0xaa 0x62 0x66 0x04 0x2e 0xb6 0xa2 0xe0
262 0xb68908f8: 0x41 0x03 0x9d 0xd8 0xe2 0x24 0x24 0xe8
263 0xb6890900: 0x50 0xac 0x20 0x29 0xfb 0xcd 0xb4 0x6e
264 h3=SHA256.new(SHA256.new(vh2).digest()).digest()
266 Add first 4 bytes from Hash object onto end as check-bytes:
267 0x9fa6628: 0x00 0x5c 0xc8 0x7f 0x4a 0x3f 0xdf 0xe3
268 0x9fa6630: 0xa2 0x34 0x6b 0x69 0x53 0x26 0x7c 0xa8
269 0x9fa6638: 0x67 0x28 0x26 0x30 0xd3 0xf9 0xb7 0x8e
273 Result length should be: int(math.floor(len(addr)*8/math.log(58,2)))
274 Base58 encode that, front-pad with '1's if less than expected length
275 to get: 19TbMSWwHvnxAKy12iNm3KdbGfzfaMFViT
283 // (4) message start { 0xf9, 0xbe, 0xb4, 0xd9 }
285 // (4) size -- number of bytes of data
286 // (4) checksum -- First four bytes of double SHA256 hash of data
289 --> messages might be split by network layer...
298 CAddress addrFrom # if nVersion > 106
300 string strSubVer # if nVersion > 106
301 int nStartingHeight # if nVersion > 209
303 nNonce is random value (I think), used to detect self-connection.
305 "verack" : no data. Sent to sync min version (peer, peer)
309 (relayed to 10 random nodes so they spread)
314 "getdata" : Asks for blocks or tx's (response is "block" or "tx" messages)
327 "getaddr" : no data ("please send me addr messages")
340 "ping" : no data (and no reply)
343 TRANSACTION SIGNING NOTES
344 -------------------------
346 So, I want to spend some bitcoin.
347 First, I gotta have a Transaction to me-- specifically, a Transaction with a TxOut that contains a scriptPubKey that I can satisfy.
349 TxOut.scriptPubKey's come in a couple different flavors:
350 DUP HASH160 {hash160(public_key) EQUALVERIFY CHECKSIG
351 --> I have to be able to supply a matching TxIn.scriptSig with: signature and public key
352 (public key) CHECKSIG
353 --> I have to supply a matching TxIn.scriptSig with: signature
355 TODO: figure out what, exactly, is hashed (and how), and how, exactly, that hash value is signed with the private key.
357 DIFFICULTY, NBITS, BN_mpi2bn
358 ----------------------------
360 Hash targets are stored as "compact bignums;" the production block chain has an initial target of:
361 0x1d00ffff ... which means "create a bignum that is 0x1d (29) bytes long and has 0x00ffff as the
362 three bytes on the big end." Or: 0xffff0000000000000000000000000000000000000000000000000000
364 As I write this, the current block->nBits is 0x1c010c5. To compute difficulty:
365 php -r '$nBits = 0x1c010c5a; print( (0xffff << ((0x1d-($nBits>>24))*8)) / ($nBits&0xffffff) );'