@@ -1038,7 +1038,7 @@ d2.to_s # convert 32-byte (256-bit) binary to hex string
1038
1038
```
1039
1039
1040
1040
Note: Classic bitcoin uses a double hash, that is,
1041
- for even higher security the hash gets hashed twice with the SHA256 algorithm
1041
+ for even higher security the hash gets hashed twice with the SHA256 algorithm
1042
1042
e.g. ` sha256(sha256(header)) ` .
1043
1043
1044
1044
In practice let's deal with the different byte order conversions
@@ -1184,13 +1184,125 @@ bin_to_hex32( d2 )
1184
1184
```
1185
1185
1186
1186
1187
+ Bonus. For easy (re)use let's package up the bitcoin block header code into a class:
1188
+
1189
+ ``` ruby
1190
+ require ' digest'
1191
+
1192
+ module Bitcoin
1193
+ class Header
1194
+ attr_reader :version
1195
+ attr_reader :prev
1196
+ attr_reader :merkleroot
1197
+ attr_reader :time
1198
+ attr_reader :bits
1199
+ attr_reader :nonce
1200
+
1201
+ def initialize ( version , prev , merkleroot , time , bits , nonce )
1202
+ @version = version
1203
+ @prev = prev
1204
+ @merkleroot = merkleroot
1205
+ @time = time
1206
+ @bits = bits
1207
+ @nonce = nonce
1208
+ end
1209
+
1210
+ # # lets add a convenience c'tor helper
1211
+ def self .from_hash ( h )
1212
+ new ( h[:version ],
1213
+ h[:prev ],
1214
+ h[:merkleroot ],
1215
+ h[:time ],
1216
+ h[:bits ],
1217
+ h[:nonce ] )
1218
+ end
1219
+
1220
+ def to_bin
1221
+ i4( version ) +
1222
+ h32( prev ) +
1223
+ h32( merkleroot ) +
1224
+ i4( time ) +
1225
+ i4( bits.to_i(16 ) ) +
1226
+ i4( nonce )
1227
+ end
1228
+
1229
+ def hash
1230
+ bytes = sha256(sha256( to_bin ))
1231
+ bin_to_h32( bytes )
1232
+ end
1233
+
1234
+ def sha256 ( bytes )
1235
+ Digest ::SHA256 .digest( bytes )
1236
+ end
1237
+
1238
+ # # binary pack/unpack conversion helpers
1239
+ def i4 ( num ) # # integer (4 byte / 32bit) to binary (in little endian)
1240
+ [num].pack( ' V' )
1241
+ end
1242
+
1243
+ def h32 ( hex ) # # hex string (32 byte / 256 bit / 64 hex chars) to binary
1244
+ [hex].pack( ' H*' ).reverse # # change byte order (w/ reverse)
1245
+ end
1246
+
1247
+ def bin_to_h32 ( bytes )
1248
+ bytes.reverse.unpack( ' H*' )[0 ] # # note: change byte order (w/ reverse)
1249
+ end
1250
+ end # class Header
1251
+ end # module Bitcoin
1252
+ ` ` `
1253
+
1254
+ and let's test drive it with the genesis block #0 and block #125552:
1255
+
1256
+ ` ` ` ruby
1257
+ b0 =
1258
+ Bitcoin ::Header .from_hash(
1259
+ version: 1 ,
1260
+ prev: ' 0000000000000000000000000000000000000000000000000000000000000000' ,
1261
+ merkleroot: ' 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b' ,
1262
+ time: 1231006505 ,
1263
+ bits: ' 1d00ffff' ,
1264
+ nonce: 2083236893 )
1265
+
1266
+ b0.hash
1267
+ # => "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
1268
+
1269
+ b125552 =
1270
+ Bitcoin ::Header .from_hash(
1271
+ version: 1 ,
1272
+ prev: ' 00000000000008a3a41b85b8b29ad444def299fee21793cd8b9e567eab02cd81' ,
1273
+ merkleroot: ' 2b12fcf1b09288fcaff797d71e950e71ae42b91e8bdb2304758dfcffc2b620e3' ,
1274
+ time: 1305998791 ,
1275
+ bits: ' 1a44b9f2' ,
1276
+ nonce: 2504433986 )
1277
+
1278
+ b125552.hash
1279
+ # => "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d"
1280
+ ```
1281
+
1282
+
1283
+
1187
1284
1188
1285
1189
1286
## (Crypto) Block with Transactions (Tx)
1190
1287
1191
1288
To be continued.
1192
1289
1193
1290
1291
+
1292
+
1293
+
1294
+
1295
+
1296
+
1297
+ ## References / Links
1298
+
1299
+ - [ Programming Cryptocurrencies and Blockchains in Ruby] ( http://yukimotopress.github.io/blockchains )
1300
+ @ [ Yuki & Moto Press Bookshelf] ( http://yukimotopress.github.io ) , Free (Online) Booklet
1301
+ - [ Awesome Blockchains] ( https://github.com/openblockchains/awesome-blockchains ) @ [ Open Bockchains] ( https://github.com/openblockchains )
1302
+ - [ Awesome Crypto] ( https://github.com/planetruby/awesome-crypto ) @ [ Planet Ruby] ( https://github.com/planetruby )
1303
+
1304
+
1305
+
1194
1306
## Questions? Comments?
1195
1307
1196
1308
Send them to the [ ruby-talk mailing list] ( https://www.ruby-lang.org/en/community/mailing-lists/ )
0 commit comments