-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathchapter.blockchain.xml
646 lines (615 loc) · 42.2 KB
/
chapter.blockchain.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="blockchain">
<title>区块链</title>
<para>区块链可以说是2018年最火的技术,相信很多开发者已经跃跃欲试投入到区块链开发队伍当中来,可是又感觉无从下手,你会发现世面上的书籍大多是将理论纸上谈兵,都是一些无法落地的异想天开的想法,本书将用大量实例讲解如何让技术落地。</para>
<para>目前区块链技术无论是 Ethereum 还 Hyperledger 都处在高速发展阶段,每次版本迭代更新变化巨大,至少还需要一到三年才能变成成熟的技术。 </para>
<para>我个人认为区块链的出现不是仅仅是简单意义上技术的革新,若干年后回过头来再看区块链,很可能是一个人类社会体系的变革伊始,是一个里程碑。</para>
<section id="background">
<title>什么是区块链?</title>
<para>很多书籍谈到区块链都从比特币开始,媒体也经常把比特币拉出来说事,首先要高清一个问题:比特币是区块链,但区块链并不是比特币。</para>
<para>区块链是什么?一句话,它是一种特殊的(非关系型)分布式数据库,这种数据库只能做插入和查找操作,并且没有管理员。</para>
<para>首先,区块链的主要作用是储存信息。任何需要保存的信息,都可以写入区块链,也可以从里面读取,所以它是数据库。</para>
<para>其次,任何人都可以架设服务器,加入区块链网络,成为一个节点。区块链的世界里面,没有中心节点,每个节点都是平等的,都保存着整个数据库。你可以向任何一个节点,写入/读取数据,因为所有节点最后都会同步,保证区块链一致。</para>
</section>
<section id="what.contracts">
<title>什么是智能合约?</title>
<para>智能合约是区块数据业务逻辑的封装.</para>
<para>你可以理解为存储过程+数据库结构,这样应该很好理解了把?</para>
<para>访问只能合约就如同访问存储过程。在合约中定义的变量是不能直接访问的,只能通过函数操作他。</para>
<para>所以非常类似数据库定义了表结构,但是不能直接 select, insert, delete, update 数据,只能通过存储过程操作数据库一样。</para>
</section>
<section id="how">
<title>我们应该怎么做?</title>
<para>很简单,通过IP地址与端口号连接到区块链系统,通过API(通常是 json-rpc)调用合约方法完成一笔交易,产生一笔区块记录。</para>
<para>理论上区块链比数据库简单。</para>
</section>
<section id="learn">
<title>如何学习区块链</title>
<para>我学习区块链技术是没有看过任何书籍的,我采用的是碎片化学习方法,主要是通过搜索引擎和官方文档。我比较擅长自学,也很少和人交流。</para>
<para>也曾试图购买书籍,但是我发现这些书籍没有多大价值,几乎三分之二的内容在谈原理,理论的东西,剩下三分之一的内容,无非就是安装、配置、Helloword 实例。另外书籍的出版周期通常是半年至一年,等书籍出版出来,内容早已经过时,软件版本的差异导致书中的例子运行不了,所以我放弃了购买书籍的想法,同时萌生了自己要写一本以干货内容为主的电子书,尽量在书中回避理论的东西,软件版本我选择当前的主流版本,直接上例子,只要你对照步骤 Step by Step 实验就能成功,这种成就感会驱使你继续学习下去。</para>
<para>学习中遇到碰壁无法解决的问题可以借助搜索引擎解决,这是最好的学习工具。</para>
<para>我主张学习区块链不要看太多的原理,快速过一遍即可,很多书中从比特币开始讲起,我觉的是没有必要的。</para>
<para>学习区块链有两个方向,一个是代币开发,另一个才是区块链开发,现在媒体将两个方向混为一谈,这是两个独立的方向。研究前者的人称为币圈,研究后者的人称为链圈。</para>
<para>如果你想从事代币开发那么目标很明确以太坊是最佳选择,你的学习内容是代币合约开发,合约部署,web3合约操作,代币上交易所等等......</para>
<para>业界所指区块链并非代币开发,而是解决去中心化,期望区块链技术帮助企业解决实际问题。通常Ethereum和Hyperledger两种方案都能满足企业需求,你需要自己判断选择哪个方案。</para>
<para>区块链是一种工具,就如同手机是通讯工具,你不需要学习通信原理和计算机原理,一样可以使用手机。区块链的发展一定是趋向傻瓜化,越来越容易使用和开发。</para>
</section>
<section id="blockchain.group">
<title>币圈与链圈</title>
<para>币圈是一帮专注炒币,甚至自己发币的人。他们专注于市场行情,追涨杀跌;而链圈多为技术人员,认为单凭自己的技术,便可对行业做出巨大颠覆。</para>
</section>
<section id="blockchain.ok">
<title>区块链能做什么</title>
<para>区块链具有去中心化安全性、可追溯、不可篡改等特性。</para>
<para>区块链目前的底层只适合做,低频高价值的业务。例如区块链+征信,区块链+资产,区块链+支付,区块链+供应链,房地产+区块链(登记,转账)</para>
</section>
<section>
<title>区块链不能解决的问题</title>
<para>你能保证上链的数据绝对不会被篡改;但你不能保证,上传的数据是真的。</para>
<itemizedlist>
<title>区块链不能解决的问题:</title>
<listitem>
<para>用户上传假数据</para>
</listitem>
<listitem>
<para>物品被调包</para>
</listitem>
<listitem>
<para>高频交易</para>
</listitem>
</itemizedlist>
<para>我们举一个现实中的例子“身份证”,例如身份证是可能证明你是你,但是别人可以拿着你的身份证冒充你。另外你不能保证户籍人员在录入身份信息的时候不出错。现实中我们常有身份证重号或信息有误的情况。</para>
<para>并不是实施了区块链技术就安全无忧了,安全分为很多层,区块链只能做到存储层的安全。例如安全分为用户层,应用层,逻辑层,存储层等等。区块链无法解决用户层,应用层,逻辑层等安全问题,他只能保证存储在硬盘上的区块不被修改。</para>
</section>
<section>
<title>理解去中心化</title>
<para>传统数据库是中心化的,它通过一个IP地址和一个端口号为应用程序提供服务,后来出现了“主从”和“主主”结构,去中心化就是一种“多主”结构。</para>
<para>与数据库相比区块链的去中心化更为复杂,他们的数据同步不是简单的二进制日志同步,而是通过加密传输,节点共识后才做数据存储。</para>
</section>
<section>
<title>理解不可撰改</title>
<para>很多人被这句话误导,认为区块链的数据一旦创建是永久不能修改的,所以它安全。其实不然,区块链的数据可以修改,但不能撰改。</para>
<para>首先你要搞明白什么是撰改和修改,撰改是指非法修改区块链数据,而修改则是合法变更数据。</para>
<para>区块链上的数据是可以修改的,无论存储多久的数据,随时可以修改里面内容。</para>
<para>通常撰改区块链数据多指数据存储层面的修改。而修改则是通过chaincode 提供的修改函数变更区块链里面的数据。</para>
<para>举例一个场景例子,在征信系统中,用户有时被拉入黑名单,但用户缴纳欠费后应该立即将其移到白名单中,这个过程就需要修改区块链上的数据。</para>
<para>另外我还告诉你,多数区块链平台没有用户认证权限管理模块。所以无法控制区块中的那些数据可能修改,那些不能修改,那些数据XXX用户可以修改等等。即使有些区块链平台具备权限控制,颗粒度也无法想目前的数据库那些细。</para>
</section>
<section>
<title>理解分布式记账</title>
<para>首先说明区块链中提到的账本与记账等等词汇是与会计无关的词汇。</para>
<para>我们传统理解的账本是指二位表格,记录某年某月产生的费用。</para>
<screen>
<![CDATA[
时间 | 用途| 金额
-----------+-----+-----
2018-05-02 | 借 | 500
2018-05-10 | 还 | 500
2018-05-15 | 借 | 500
2018-05-20 | 借 | 500
]]>
</screen>
<para>如果账目比较多,可以拆账,将不同分类的账目,放到特定账本中。另外二位表格可以通过时间索引或者分类索引等等,快速找到一笔账目。</para>
<para>区块链是怎么记账的?</para>
<screen>
<![CDATA[
+----------------+ +----------------+ +----------------+ +----------------+
| blockNumber 0 | | blockNumber 1 | | blockNumber 2 | | blockNumber 3 |
| hash: 0x1 |<--- | hash: 0x2 | <---| hash: 0x3 | <---| hash: 0x4 |
| parent:0x0 | | parent:0x1 | | parent:0x2 | | parent:0x3 |
+----------------+ +----------------+ +----------------+ +----------------+
|时间:2018-05-02 | |时间:2018-05-10 | |时间:2018-05-15 | |时间:2018-05-20 |
|用途:借 | |用途:借 | |用途:借 | |用途:借 |
|金额:500 | |金额:500 | |金额:500 | |金额:500 |
+----------------+ +----------------+ +----------------+ +----------------+
]]>
</screen>
<para>区块链可以理解为是传统账本的行列矩阵做这转换,每个事件收尾相连指向上一个区块地址形成链状,区块链不能通过分类拆分账本,所有账目全部在一个链条上。</para>
<para>什么是分布式记账?上面链状的数据结构将保存在所有的区块链节点上,形成分布式集群,这就是分布式记账。</para>
<para>虽然区块链解决了分布式记账,但是也有很多弊端。我说过互联网上很多关于区块的文章都是臆想,纸上谈兵,他们根本没有实操经验。</para>
<itemizedlist>
<title>下面我们讲讲区块链账本存在的问题</title>
<listitem>
<para>区块链不能键索引,无法快速搜索区块中的数据,必须依赖区块链以外的中心化技术,例如搜索引擎,数据库。例如 etherscan.io 就是将以太坊上的区块重新入库,借助数据库实现数据检索。</para>
</listitem>
<listitem>
<para>区块链只能顺序检索,中心化账本我们汇总账目只需做 sum 求和操作,而区块链必须从 blockNumber 0 开始一次向后读取,运算成本极高。</para>
</listitem>
<listitem>
<para>所有账目均在一个链上,不同分类混在一起,彼此相连。</para>
<screen>
<![CDATA[
+----------------+ +----------------+ +----------------+ +----------------+
| blockNumber 0 | --> | blockNumber 1 | --> | blockNumber 2 | --> | blockNumber 3 | --> 时间轴
+----------------+ +----------------+ +----------------+ +----------------+
|时间:2018-05-02 | |时间:2018-05-10 | |时间:2018-05-15 | |时间:2018-05-20 |
|分类:A | |分类:B | |分类:A | |分类:A |
|金额:500 | |金额:500 | |金额:500 | |金额:500 |
+----------------+ +----------------+ +----------------+ +----------------+
]]>
</screen>
</listitem>
<listitem>
<para>无法归档</para>
<para>中心化数据库,可以归档一段时间内的数据,归档数据是冷数据,几乎不会再查询,这样一来中心数据库中的数据量减少,剩下的热数据处理起来非常快。我们有很多技术处理归档数据,将归档数据备份到存储介质上的解决方便有很多,也非常成熟。例如压缩,去重复等等,以减少存储成本开销。</para>
<para>而区块链从诞生之日起到今日所有数据必须放在热数据区。任何新增节点都必须从区块0开始同步,并且保持每日同步到最新区块,否则将无法交易。区块一直在膨胀,随时区块链的普及,交易量猛增,总有一天将不堪重负。</para>
<para>例如BTC(比特币) 安装钱包后,需要从92年的0区块开始同步,至少需要一周的时间,并且占用你硬盘203G的空间。</para>
<para>ETH(以太坊)采用 fast 模式也需要200G的磁盘空间同步一周左右。就算采用最新的 light 模式,同步过程中经常出现中断,没有peers节点,断断续续,体验极度不好。</para>
</listitem>
<listitem>
<para>区块链没有事务处理</para>
<para>因为区块链是首尾相连的,只能在尾部添加新区块,区块无法修改,所以区块链无法做事务处理。</para>
<screen>
<![CDATA[
Block 0 -> Block 1 -> Block 2 -> Block 3 -> Block 4
]]>
</screen>
<para>试想一下上面的 Block 2 回滚会怎样?如果 Block 2 回滚,Hash 值产生变化,后面所有区块都作废。所以区块链无法实现事务处理。</para>
<para>超级账本(Hyperledger Fabric)记不了帐</para>
<para>Hyperledger Fabric 中文名称叫超级账本,这个翻译坑害了无数人。 Hyperledger Fabric 跟账本没有任何关系。</para>
<para>实际工作中我使用 Hyperledger Fabric 实现了类似以太坊ERC20代币的功能,发行一个代币后将发行金额写入一个总账,然后从总账中项其他账号转账,用户消费后将金额从用户转会总账。</para>
<para>问题来了,因为超级账本没有事务处理,也无法串行执行每一笔操作,当并发执行的时候,账目出现混乱。</para>
<para>区块链无法将一组业务逻辑放到事物中执行。这样在实际的开发中我们只能依赖应用层,只能在应用层上实现事物锁的功能。由于区块存储在多个节点上,共识时间无法预计,不知道 stub.PutState(异步写入)执行完成的具体时间,无法达到100%无误。对于财务数据来不得半点马虎,我还是决定放弃这个功能,专为传统数据库。</para>
<para>所以超级账本记不了</para>
</listitem>
<listitem>
<para>TPS:Transactions Per Second(每秒传输的事物处理个数)</para>
<para>1. 区块链是异步执行,你无法知道什么时候才能完成这笔交易,无法实现瞬间到账。</para>
<para>2. 交易阻塞</para>
</listitem>
<listitem>
<para>蛋疼的 gas 费用</para>
</listitem>
</itemizedlist>
<para>总结:用区块链记账很蛋疼。</para>
</section>
<section>
<title>安全问题</title>
<para>我将安全划分为六层,分别是:</para>
<screen>
<![CDATA[
+----------+-----------------------------+
| 实体层 | 物 |
+----------+-----------------------------+
| 用户层 | 人 |
+----------+-----------------------------+
| 网络层 | 网络 |
+----------+-----------------------------+
| 应用层 | 操作系统,应用服务器 |
+----------+-----------------------------+
| 业务逻辑层 | 功能,业务逻辑 |
+----------+-----------------------------+
| 存储层 | 物理存储,硬盘 |
+----------+-----------------------------+
]]>
</screen>
<para>并不是实施了区块链技术就安全无忧了,安全分为很多层,区块链只能做到网络层和存储层的安全。区块链无法解决用户层,应用层,逻辑层等安全问题。</para>
<para>网络层,因为区块链是通过公私钥体系加密数据库传输与存储,所以在网络上传输区块链数据是安全的。</para>
<para>存储层,区块链存储是加密的,链与链之间通过通过Hash算法连接,保证数据不被修改,修改会有什么后果呢?首先链就会断裂。修改一处数据,当前位置后面的数据全部需要更新,就算你更新成功,其他共识节点,也会视为你的更新是非法,所以数据撰改不可能。</para>
</section>
<section>
<title>区块链落地面临的问题</title>
<section>
<title>性能问题</title>
<para>区块链目前的底层只适合做,低频高价值的业务。</para>
<para>区块链的读取性能通常是没有问题的,但是区块链的写入实际上无论你用多少个服务器节点都不能提升,因为写入区块需要做共识算法,这步操作,会在所有节点上进行,同时还需要加密运算,这些操作都是 CPU 密集型操作。所以写入操作是存在瓶颈的。</para>
<para>解决这个问题,我想出了几种方案:</para>
<itemizedlist>
<title>性能解决方案</title>
<listitem>
<para>通过消息队列技术异步写入,将需要写入的区块放入队列,异步完成上链操作。</para>
</listitem>
<listitem>
<para>并行写入,我们可以建设多个区块链平台。多个平台同时服务于业务。</para>
</listitem>
</itemizedlist>
<para>为了达到去中心化并行写入,我们将在客户端通过算法,匹配服务器。而不是在两个平台前面增加负载均衡。因为这样又回到了中心化系统。</para>
</section>
<section>
<title>颗粒度问题</title>
<para>朔源的颗粒度问题,例如“红酒”的溯源,我们是将单位溯源做到箱呢?还是打,或是瓶呢?</para>
<para>我们用“四象限法则”分析</para>
<screen>
<![CDATA[
高价值
o |
| o
|
低频率 --------------+------------- 高频率 操作频率
|
o | o
|
低价值
物品价值
]]>
</screen>
<para>通过观察上面图,我们可以看到可以有四种情况,低频低价值,低频高价值,高频高价值,高频低价值</para>
<para>我认为对于低频高价值和高频高价值的业务,尽量做到最小颗粒度。</para>
<para>而对于低频低价值和高频低价值的业务,可以颗粒度更粗。</para>
<para></para>
</section>
<section>
<title>区块链不能替代传统数据</title>
<para>回归技术本质,我认为区块链技术本身是一种追求分布一致性的数据库。</para>
<para>我们学过数据库的,都知道CAP理论。CAP理论是指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。大多数区块链,放弃了一些可用性,偏向了一致性和分区容错。</para>
<para>区块链并非能解决所有问题,虽然他也算是一种数据库,它能解决问题十分有限,它的数据管理和查询能力还打不到 NoSQL 的水平,更别提 SQL 的复杂应用。所以在实际的应用中,区块链不能替代数据,只能互补。</para>
<para>所以在项目实施前,仔细想想自己需求,真的需要区块链吗?还是需要区块链上的一些特性?例如数据不可撰改。如果仅仅是需要区块链的某一个特性。我们可以针对这个需求,思考一下能否使用传统数据库解决。</para>
</section>
<section>
<title>链上,链下数据一致性问题</title>
<para>既然区块链替代不了传统数据库,那么必然要在项目中同时使用两种技术。这样问题来了,会有两份数据,一份存储在链下,即传统数据库,另外一部分数据上链,这样就有两份重复的数据,那么怎样保证他们的一致性呢?</para>
<para>非链上的原生资产在上链过程中,有一个重要的问题:原生资产的真实性问题,即链上资产、链下资产如何保持一致性问题。</para>
<para>区块链和比特币网络不同,比特币是在链上产生的,它与区块链密布可分,是一体的,所以它的数据安全性是自闭环的。而我们的链下数据并不是在区块链中产生的,将链下数据与区块链对接上链</para>
<orderedlist>
<title>我们需要考虑几个问题</title>
<listitem>
<para>怎样能保证数据的真实和一致性呢?</para>
</listitem>
<listitem>
<para>当出现不一致的时候以哪个为准呢?</para>
</listitem>
<listitem>
<para>当需要读取数据时,是走连上,还是链下呢?</para>
</listitem>
<listitem>
<para>什么数据上链,什么数据不上链?</para>
</listitem>
</orderedlist>
<itemizedlist>
<title>下面回答上面提出的问题</title>
<listitem>
<para>两端都将数据做一次hash,可以快速对比是否数据一致</para>
</listitem>
<listitem>
<para>我认为以连上数据为准较好,因为数据库数据更容易被撰改。</para>
</listitem>
<listitem>
<para>前台走上链,后台走数据库,前台是为用户提供服务的,所以要走连上数据,后台是管理的,可以直接走数据库,然后保证数据库与区块链数据一致。</para>
</listitem>
<listitem>
<para>共享数据上链,私有数据不上链,想象一下在盟链系统中,需要共享给其他成员数据,之前采用 Api接口,有了区块链更好的解决了资源共享问题。</para>
</listitem>
</itemizedlist>
<para>例如下图我们将共享数据上链,在联盟中共享。私有数据(不能公开的数据)放到自己本地数据库,或者私链中。</para>
<screen>
<![CDATA[
盟链系统
+----------+ +----------+ +----------+
| 你 | | 我 | | 他 |
+----------+ +----------+ +----------+
| | |
V V V
+------------------------------------+
| Block Chain |
+------------------------------------+
]]>
</screen>
</section>
</section>
<section>
<title>区块链未来</title>
<para>我认为区块链未来发展一定是易用,傻瓜化。</para>
<para>例如区块链的SQL网关,通过SQL访问区块链。</para>
</section>
<section>
<title>区块链的六层模型</title>
<para>区块链技术的模型是由自下而上的数据层、网络层、共识层、激励层、合约层和应用层组成。</para>
<screen>
<![CDATA[
第一层“数据层”,封装了底层数据区块的链式结构,以及相关的非对称公私钥数据加密技术和时间戳等技术,这是整个区块链技术中最底层的数据结构。这些技术是构建全球金融系统的基础,数十年的使用证明了它非常安全的可靠性。而区块链,正式巧妙地把这些技术结合在了一起。
第二层“网络层”,包括P2P组网机制、数据传播机制和数据验证机制等。P2P组网技术早期应用在BT这类P2P下载软件中,这就意味着区块链具有自动组网功能。
第三层“共识层”,封装了网络节点的各类共识机制算法。共识机制算法是区块链的核心技术,因为这决定了到底是谁来进行记账,而记账决定方式将会影响整个系统的安全性和可靠性。目前已经出现了十余种共识机制算法,其中比较最为知名的有工作量证明机制(PoW,Proof of Work)、权益证明机制(PoS,Proof ofStake)、股份授权证明机制(DPoS,Delegated ProofofStake)等。数据层、网络层、共识层是构建区块链技术的必要元素,缺少任何一层都将不能称之为真正意义上的区块链技术。
第四层“激励层”,将经济因素集成到区块链技术体系中来,包括经济激励的发行机制和分配机制等,主要出现在公有链当中。在公有链中必须激励遵守规则参与记账的节点,并且惩罚不遵守规则的节点,才能让整个系统朝着良性循环的方向发展。而在私有链当中,则不一定需要进行激励,因为参与记账的节点往往是在链外完成了博弈,通过强制力或自愿来要求参与记账。
第五层“合约层”,封装各类脚本、算法和智能合约,是区块链可编程特性的基础。比特币本身就具有简单脚本的编写功能,而以太坊极大的强化了编程语言协议,理论上可以编写实现任何功能的应用。如果把比特币看成是全球账本的话,以太坊可以看作是一台“全球计算机”,任何人都可以上传和执行任意的应用程序,并且程序的有效执行能得到保证。
第六层“应用层”,封装了区块链的各种应用场景和案例,比如搭建在以太坊上的各类区块链应用即部署在应用层,而未来的可编程金融和可编程社会也将会是搭建在应用层。
]]>
</screen>
</section>
<section>
<title>共识机制</title>
<para>共识机制,就是所有记账节点之间如何达成共识,去认定一个记录的有效性,这既是认定的手段,也是防止篡改的手段。目前主要有四大类共识机制:PoW、PoS、DPoS和分布式一致性算法。</para>
<section>
<title>PoW(Proofof Work,工作量证明)</title>
<para>PoW机制,也就是像比特币的挖矿机制,矿工通过把网络尚未记录的现有交易打包到一个区块,然后不断遍历尝试来寻找一个随机数,使得新区块加上随机数的哈希值满足一定的难度条件。找到满足条件的随机数,就相当于确定了区块链最新的一个区块,也相当于获得了区块链的本轮记账权。矿工把满足挖矿难度条件的区块在网络中广播出去,全网其他节点在验证该区块满足挖矿难度条件,同时区块里的交易数据符合协议规范后,将各自把该区块链接到自己版本的区块链上,从而在全网形成对当前网络状态的共识。</para>
<para>优点:完全去中心化,节点自由进出,避免了建立和维护中心化信用机构的成本。只要网络破坏者的算力不超过网络总算力的50%,网络的交易状态就能达成一致。</para>
<para>缺点:目前比特币挖矿造成大量的资源浪费;另外挖矿的激励机制也造成矿池算力的高度集中,背离了当初去中心化设计的初衷。更大的问题是PoW机制的共识达成的周期较长,每秒只能最多做7笔交易,不适合商业应用。</para>
</section>
<section>
<title>PoS(Proofof Stake,权益证明)</title>
<para>PoS机制,要求节点提供拥有一定数量的代币证明来获取竞争区块链记账权的一种分布式共识机制。如果单纯依靠代币余额来决定记账者必然使得富有者胜出,导致记账权的中心化,降低共识的公正性,因此不同的PoS机制在权益证明的基础上,采用不同方式来增加记账权的随机性来避免中心化。例如点点币(Peer Coin)PoS机制中,拥有最多链龄长的比特币获得记账权的几率就越大。NXT和Blackcoin则采用一个公式来预测下一记账的节点。拥有多的代币被选为记账节点的概率就会大。未来以太坊也会从目前的PoW机制转换到PoS机制,从目前看到的资料看,以太坊的PoS机制将采用节点下赌注来赌下一个区块,赌中者有额外以太币奖,赌不中者会被扣以太币的方式来达成下一区块的共识。</para>
<para>优点:在一定程度上缩短了共识达成的时间,降低了PoW机制的资源浪费。</para>
<para>缺点:破坏者对网络攻击的成本低,网络的安全性有待验证。另外拥有代币数量大的节点获得记账权的几率更大,会使得网络的共识受少数富裕账户支配,从而失去公正性。</para>
</section>
<section>
<title>DPoS(DelegatedProof-Of-Stake,股份授权证明)</title>
<para>DPoS很容易理解,类似于现代企业董事会制度。比特股采用的DPoS机制是由持股者投票选出一定数量的见证人,每个见证人按序有两秒的权限时间生成区块,若见证人在给定的时间片不能生成区块,区块生成权限交给下一个时间片对应的见证人。持股人可以随时通过投票更换这些见证人。DPoS的这种设计使得区块的生成更为快速,也更加节能。从某种角度来说,DPOS可以理解为多中心系统,兼具去中心化和中心化优势。</para>
<para>优点:大幅缩小参与验证和记账节点的数量,可以达到秒级的共识验证。</para>
<para>缺点:选举固定数量的见证人作记账候选人有可能不适合于完全去中心化的场景。另外在网络节点数少的场景,选举的见证人的代表性也不强。</para>
</section>
</section>
<section id="sha256">
<title>SHA-256</title>
<para>sha256 是一个摘要算法与常见的md5作用相同,因为区块链的数据量安全性md5,sha1都已经无法满足。实际上 sha512标准也已经出来,目前区块链主流采用 sha256,主要是考虑性能和存储空间。</para>
<para>目前区块链数据存储hash值占了 1/3 ~ 2/3</para>
<screen>
<![CDATA[
neo@netkiller ~ % sha256sum /etc/hosts
be0b4786b1169533329b2ab5292d8d1c16bbea5bd24c882a983ab4b754a398c8 /etc/hosts
neo@netkiller ~ % sha1sum /etc/hosts
48bea81a95c75efa52608a9d384126be3131e40f /etc/hosts
neo@netkiller ~ % sha224sum /etc/hosts
65bf519aa94d15c3e62406b8e1f8dd8b7fb513a5dac439606f954822 /etc/hosts
neo@netkiller ~ % sha384sum /etc/hosts
65478594d45d1f1054bea0f19b320607682a2c96c6efe39de9ab0a176a2623b94728937346b1ede6b92cb36c013b0d93 /etc/hosts
neo@netkiller ~ % sha512sum /etc/hosts
275a4258fb570d897c67a65a65e73ac1e38cdb4166b1fdf290d7f6361892f81d663cbab51a32cf827a4d4bc26edcd0a34bed36c170dc373058f3606c02c1c5ae /etc/hosts
]]>
</screen>
</section>
<section id="base58">
<title>Base58编码</title>
<para>Base64是常见的可读性编码算法,所谓Base64,即是说在编码过程中使用了64种字符:大写A到Z、小写a到z、数字0到9、“+”和“/”。</para>
<para>Base58是Bitcoin中使用的一种编码方式,主要用于产生Bitcoin的钱包地址。相比Base64,Base58不使用数字"0",字母大写"O",字母大写"I",和字母小写"i",以及"+"和"/"符号。</para>
<para>IPFS 也使用了 Base58</para>
</section>
<section id="Merkle">
<title>Merkle</title>
<para>而Merkle名字来源于其发明者Ralph Merkle,他在1979年获得了哈系树的专利。</para>
</section>
<section id="bip39">
<title>BIP39协议:使用助记词生成确定性钱包</title>
<literallayout>
<![CDATA[
BIP:39
层:应用层
标题:使用助记词生成确定性钱包秘钥
作者:Marek Palatinus <[email protected]>
Pavol Rusnak <[email protected]>
Aaron Voisine <[email protected]>
Sean Bowe <[email protected]>
状态:已经被提议
类型:标准化跟踪
创建日期:2013-09-10
译者:kimziv
]]>
</literallayout>
<section id="摘要">
<title>摘要</title>
<para>这个BIP描述了使用助记码或者助记句子(简称助记词)--一组便于记忆的单词来生成确定性钱包。</para>
<para>这个BIP由两部分构成:生成助记词和把生成的助记词转化成一个二进制种子。这个种子后面会更急类似于BIP32的方法生成确定性钱包。</para>
</section>
<section id="动机">
<title>动机</title>
<para> 与处理原始的二进制或者十六进制的钱包种子相比,在人机交互过程中助记词是更胜一筹的。这些助记单词可以被写在纸上或者通过电话说出来。 </para>
<para>本指南旨在通过人类可读的转录来传输计算机生成的随机性。并不是将用户创建的句子(也称为脑钱包)处理到钱包种子中的方法。</para>
</section>
<section id="生成助记词">
<title>生成助记词</title>
<para>助记符必须以32位的倍数编码熵。随着熵的安全性提高,同时句子的长度也在增加。我们将初始熵长度称为ENT。ENT允许的大小为128-256位。</para>
<para>首先,生成ENT位的初始熵。通过取第一个生成的校验和</para>
<literallayout>
<![CDATA[
ENT/32
]]>
</literallayout>
<para>它的SHA256哈希的位。该校验和附加到初始熵的末尾。接下来,这些连接的比特位被分成多个11位的组,每个组用从0-2047的数字编码,用作单词表的索引。最后,我们将这些数字转换为单词,并将加入的所有单词组成助记句。</para>
<para>下表描述了初始熵长度(ENT),校验和长度(CS)和生成助记词(MS)的长度之间的关系。</para>
<literallayout>
<![CDATA[
CS = ENT / 32
MS = (ENT + CS) / 11
]]>
</literallayout>
<screen>
<![CDATA[
ENT CS ENT + CS MS
------------------------------
128 4 132 12
160 5 165 15
192 6 198 18
224 7 231 21
256 8 264 24
]]>
</screen>
</section>
<section id="单词表">
<title>单词表</title>
<itemizedlist>
<title>理想的单词列表具有以下特点:</title>
<listitem>
<para>智能选词</para>
<para>单词列表以这种方式创建:输入前四个字母来就足以明确地标识这个单词;</para>
</listitem>
<listitem>
<para>避免相似的单词</para>
<para>"build" and "built", "woman" and "women", or "quick" and "quickly" 这样的词对,不仅使记忆困难,而且更容易出错,更难猜到;</para>
</listitem>
<listitem>
<para>排序的单词列表</para>
<para>排序的单词列表允许更有效地查找代码字(即,实现可以使用二分搜索而不是线性搜索)</para>
<para>这也允许使用字典树(前缀树),例如用于更好的压缩</para>
</listitem>
</itemizedlist>
<para>单词表可以包含本土字符,但必须使用规范化形式兼容性分解(NFKD)以UTF-8编码。</para>
</section>
<section id="从助记词到种子">
<title>从助记词到种子</title>
<para>用户可以决定用密码保护他们的助词。如果密码不存在,则使用空字符串“”代替。</para>
<para>要通过助记词创建一个二进制种子,我们使用助记符作为密码(UTF-8 NFKD)和字符串“mnemonic”+ passphrase 作为盐(再次以UTF-8 NFKD)来调用PBKDF2函数。迭代计数设置为2048,HMAC-SHA512用作伪随机函数。派生密钥的长度为512位(= 64字节)。</para>
<para>该种子可以随后用于使用BIP-0032或类似方法产生确定性钱包。</para>
<para>助记词转换为二进制种子完全独立于生成这个助记词。这导致相当简单的代码; 助记词结构没有约束,客户可以自由地实现自己的单词列表,甚至是整个助记词的生成器,允许字典列表中的输入错误检测或其他用途的灵活性。</para>
<para>虽然使用的助记词可能不是通过“生成助记词”部分中描述的算法生成的,但这是不建议的,软件必须使用单词表计算助记词的校验和,如果无效则发出警告。</para>
<para>所描述的方法还提供似乎可信的可否认性,因为每个密码短语产生一个有效的种子(因此产生确定性钱包),但是只有正确的那一个才能使所需的钱包可用。 </para>
</section>
<section id="单词列表">
<title>单词列表</title>
<para>
<ulink url="https://github.com/bitcoin/bips/blob/master/bip-0039/bip-0039-wordlists.md" />
</para>
<para>如果一个 HD 钱包助记词是 12 个单词,一共有 2048 个单词可能性,如何算出随机的生成的助记词可能性是一个排列问题,根据公式: n!/( n - r )! ,既 2048!/(2048-12)! = 5.2715379713014884760003093175282e+39。 </para>
<orderedlist>
<title>Wordlists</title>
<listitem>
<para>
English
<ulink url="https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt" />
</para>
</listitem>
<listitem>
<para>
Japanese
<ulink url="https://github.com/bitcoin/bips/blob/master/bip-0039/japanese.txt" />
</para>
</listitem>
<listitem>
<para>
Korean
<ulink url="https://github.com/bitcoin/bips/blob/master/bip-0039/korean.txt" />
</para>
</listitem>
<listitem>
<para>
Spanish
<ulink url="https://github.com/bitcoin/bips/blob/master/bip-0039/spanish.txt" />
</para>
</listitem>
<listitem>
<para>
Chinese (Simplified)
<ulink url="https://github.com/bitcoin/bips/blob/master/bip-0039/chinese_simplified.txt" />
</para>
</listitem>
<listitem>
<para>
Chinese (Traditional)
<ulink url="https://github.com/bitcoin/bips/blob/master/bip-0039/chinese_traditional.txt" />
</para>
</listitem>
<listitem>
<para>
French
<ulink url="https://github.com/bitcoin/bips/blob/master/bip-0039/french.txt" />
</para>
</listitem>
<listitem>
<para>
Italian
<ulink url="https://github.com/bitcoin/bips/blob/master/bip-0039/italian.txt" />
</para>
</listitem>
</orderedlist>
</section>
<section id="开发库">
<title>开发库</title>
<section id="">
<title>Node.js</title>
<para>
<ulink url="https://www.npmjs.com/package/bip39" />
</para>
</section>
<section>
<title>Python</title>
<para>
<ulink url="https://github.com/trezor/python-mnemonic" />
</para>
</section>
<section id="其他实现">
<title>其他实现</title>
<screen>
<![CDATA[
Elixir: https://github.com/izelnakri/mnemonic
Objective-C: https://github.com/nybex/NYMnemonic
Haskell: https://github.com/haskoin/haskoin
.NET C# (PCL): https://github.com/Thashiznets/BIP39.NET
.NET C# (PCL): https://github.com/NicolasDorier/NBitcoin
JavaScript: https://github.com/bitpay/bitcore-mnemonic, https://github.com/bitcoinjs/bip39 (used by blockchain.info)
Ruby: https://github.com/sreekanthgs/bip_mnemonic
Rust: https://github.com/infincia/bip39-rs
Swift: https://github.com/CikeQiu/CKMnemonic
C++: https://github.com/libbitcoin/libbitcoin/blob/master/include/bitcoin/bitcoin/wallet/mnemonic.hpp
C (with Python/Java/Javascript bindings): https://github.com/ElementsProject/libwally-core
]]>
</screen>
</section>
</section>
<section id="">
<title>Netkiller 助记词词库</title>
<para>HD Wallet 采用 2048 个单词,或者汉字作为助记词,这些词库对外公开,很多钱包仅仅使用path第一个地址并且没有加密。如果你知道某个用户的助记词中的11各词的排列顺序,那么我们就可以通过穷举方法,算出所有地址的私钥,如果碰巧找到了已经在使用的地址。就可以将里面的ETH全部转走。</para>
<para>为了增加 HD Wallet 的安全,我做了一个词库,这个词库不对外公开,并且使用的汉字均是不常用汉字。只能复制粘贴,几乎很难使用输入法输入该汉字。</para>
<para>同时path 还做了分层,和索引地址。分层采用时间维度,索引采用随机数, Seed 做加密处理。助记词共 15 个汉字。</para>
<para>效果如下</para>
<programlisting>
<![CDATA[
汉字助记词:欈 戀 髎 響 麢 戵 邎 蠢 鶖 躒 蠈 鰘 譥 趱 巆
地址:0x4949225eab0121d1e0b0eeb286a12b04ff596471
私钥:b5ce4ac958fbdcd385d6ae850c1870c6da7b990981363c25036a31ba06be6636
汉字助记词:霼 彎 曤 纀 鸇 鷔 鶹 纚 鱱 讁 艣 鼴 黭 纒 贛
地址:0x430097d16819108068a7af22a116285e54bc3e6b
私钥:3b78431a43a2c69e861870f0eff1d54d3965247ca5e588a9f907904f9ea5b822
汉字助记词:聾 鱦 骥 鬘 鰕 蘲 韃 鏻 雤 鑀 瓤 蘣 壥 躠 罋
地址:0x641fd58728cf08bc8795d41cfd3885a4f1c8dced
私钥:b7c2ff2a39e3a534e6e89288b05b4a283b10b34b2dfca2b336676729c7a68ad1
汉字助记词:轕 鶼 瀝 钁 麝 鸑 灙 纞 躐 嚹 櫞 鱁 贑 癠 躤
地址:0xae6ad7cf3e31556bc7262e25fba2ebad9954d08b
私钥:c989fe5c108b0bd33e5731919e09c30c639a4ff29fb4e66fe3052975855181f6
汉字助记词:鰵 鐗 鱇 彏 鱞 鷮 鼯 矃 曟 鬙 衢 斅 櫜 鸒 襨
地址:0x7fc6bca55c51ab3b4266d8f67d63c196ac874d93
私钥:53e755075653a64867f885e702ca0a2612bdd13ec2bed0df647bf568a639bc46
]]>
</programlisting>
</section>
</section>
<section id="区块链比较">
<title>Ethereum vs Hypterledger Fabic vs EOS 对比</title>
<table xml:id="ex.htmltable">
<caption>智能合约对比</caption>
<thead>
<tr>
<td></td>
<td>Ethereum</td>
<td>Hypterledger Fabic</td>
<td>EOS</td>
</tr>
</thead>
<tbody>
<tr>
<td>合约语言</td>
<td>Solidity</td>
<td>Go/Node.js/Java</td>
<td>C/C++</td>
</tr>
<tr>
<td>难易程度</td>
<td>容易</td>
<td>较容易</td>
<td>难</td>
</tr>
<tr>
<td>成熟度</td>
<td>非常成熟</td>
<td>较成熟</td>
<td>不成熟</td>
</tr>
<tr>
<td>调试环境</td>
<td>有Remix,Truffle,钱包合约工具等等</td>
<td>没有较好的调试环境</td>
<td>只能手工排查</td>
</tr>
<tr>
<td>扩展性</td>
<td>Solidity 无法扩展,不能引用外部开发库</td>
<td>可以扩展,导入第三方库</td>
<td>可以扩展,并且支持STL开发库</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</section>
&chapter.solution.xml;
</chapter>