
一、Bitcoin
1.1 现实中的 Bitcoin 到底是什么样
1.2 区块链技术的诞生
中心化:

去中心化:

存在问题:
- 先付钱,没发货
- 先发货,没付钱

存在问题:
- 此时,随便一个人捏造一个数据
简单的区块链模型

1.3 在货币网络中可能的攻击方法
- 偷比特币。王一有没有可能去其他用户的比特币呢?譬如王一创建了一个区块,区块中她试图伪造一个交易
“王二 -----> 王一:100BTC”。如果要让这个交易合法,那么王一必须能够伪造王二的签名,但是王一如果没有王二的私钥,那么王一就不能伪造签名。所以,只要底层的密码学基础没有被破坏,王一就不可能偷王二的币。
拒绝服务。如果王一非常讨厌王二,她不愿意为王二提供服务,譬如在自己创建的区块中,王一就会故意忽略掉王二相关的交易。这个攻击的问题是,王一并不能控制区块的产生。即使王一在一个区块中忽略了王二的交易,其他诚实的节点会在交易中包括王二的交易。
双重支付。假如王二从王三那里买了东西,现在王二要支付比特币给王三,然后王二广播了一条交易
"王二 -----> 王三 : 50 BTC",诚实的节点看到了这条交易,并且将交易包含在区块中。当王三看到这条交易被包括进去的时候,王三认为王二已经支付了,所以将东西发送给了王二。然后王二开始准备攻击,她自己或者她控制的节点开始准备下一个区块,在这个区块中包含的消息是把王二刚才付给王三的币付给自己或者她控制的账号"王二 -----> 王二 : 50 BTC"。如果王二能够给成功地将第二条支付信息包含在区块链中,那么第一条消息,将会被忽视,就像从来没有出现过一样。

那么王三如何应对这个问题呢?
一个字形容就是:==等==
如果王三容易轻信,那么他可能在发现王二发布了付币给自己的时候就同意将东西发给王二,这个时候,称作 Zero-Confirmation Transaction(零确认交易)。如果王三有更多的保护自己的意识,他会等到王二付钱给自己的交易被多次确认之后才将软件发给王二。当交易被包含在区块中,称作一次确认;如果包含交易的区块之后又来了一个区块,称作2次确认。以此类推。
只要王三等足够的时间,那么当他发现包含王二付钱给自己的区块已经被遗弃的时候,他会放弃这次交易并且拒绝将东西发给王二。一般而言,一个交易获得的确认越多,这个交易成为最终的系统的共识的概率越大。
能够防止双重支付成功的原因,也即,包括双重支付的区块不能最终包括在链中的原因是我们假设大部分的节点是诚实的。
1.4 矿工怎么挖矿
在之前的过程中,我们多次做了假设,大部分的节点是诚实节点——诚实的节点会将自己收到的广播的交易打包,诚实的节点会沿着最长的分支扩展。
诚实节点到底是为什么是诚实的?一个字:==钱==
在比特币网络中,共有两个激励方式:
- Block reward(区块奖励)
- Transaction fees(交易费用)
区块奖励: 任何创造出区块的节点可以在区块中包括一个特殊的交易——创造币的交易
创造一个区块的奖励是25个币,然后每210,000个区块这个数字会减半。
第一眼看来,这个好像没什么用处。因为,不管节点创造的是好的区块还是包括攻击交易的区块,他都能获得奖励。但是,这个奖励什么时候才有用呢?只有在他的区块被包括在长链中才行。因此,如果一个区块中包括无效的交易,这个区块相当于会被丢弃。所以,所有的节点都能尽力表现得诚实,这样,其他节点才会沿着他的区块继续添加新的区块。
交易费用: 交易的创建者可以在创建交易时,输入大于输出,其中的差值就是交易费用。
Q:创造很多的节点以获得奖励?
A:挑选节点的时候,要根据一种人们不能独占的资源来选择:==算力==
比特币的工作证明就是hash puzzles。为了创建一个区块,节点需要能够找到一个数值:nonce,使得当计算哈希时,前一个hash,包含在区块中的交易,以及 nonce 这三者连接之后,它的哈希值小于某个 target。

找到这个Nonce的唯一方法就是尝试各种值,直到运气好找到一个
产生一个区块需要的计算大概是 10^20^ 次哈希
难度可调节。每2016个块,所有的节点一起参与计算,重新定义 target

1.5 真实的区块链

在区块链中,多个交易是被打包到一个区块中。使用包含多个交易区块而不是单个交易作为共识的单位,主要的目的是优化,因为如果矿工是针对每个交易而不是多个交易一起进行共识,那么效率就太低了。
父区块
由于区块头里面包含“父区块哈希值”字段,所以当前区块的哈希值也受到该字段的影响。如果父区块的身份标识发生变化,子区块的身份标识也会跟着变化。当父区块有任何改动时,父区块的哈希值也发生变化。这将迫使子区块的“父区块哈希值”字段发生改变,从而又将导致子区块的哈希值发生改变。而子区块的哈希值发生改变又将迫使孙区块的“父区块哈希值”字段发生改变,又因此改变了孙区块哈希值,以此类推。一旦一个区块有很多代以后,这种瀑布效应将保证该区块不会被改变,除非强制重新计算该区块所有后续的区块。
Merkle树
区块中的所有交易都使用二进制 ==raw transaction== 的格式保存在区块中,然后对 raw transaction 进行哈希得到交易id(txid)。merkle 树就是使用这样的 txid 进行构造的。

为什么使用 Merkle树?
默认情况下,一旦接受到一个新交易,节点需要验证它,特别是,验证交易的输入中的每一个之前是否被花费。为了完成这个验证,需要访问区块链。如果节点不信任网络上的其他节点,那么 这个节点需要保存网络上的所有区块,以便验证交易。这种节点称作全节点。在比特币发展的早期,所有节点都是全节点;当前的比特币核心客户端也是完整区块链节点。
因为全验证节点会维护整个区块链的数据,由于区块链的不可篡改和append-only,随着时间的增加,整个区块链的数据量非常大。现在要完整下载比特币的所有区块数据,需要200GB以上的空间。
全验证节点对硬件提出了很高要求,个人用户(移动设备)参与这个过程几乎是不可能的。为了客户友好,对于仅仅使用钱包的普通用户,也即轻量级的节点,比特币网络中的大部分用户都是轻量级的用户,比特币网络并不要求它们也存储所有的信息。这种节点只需要维护能够验证用户自己所 care 的交易的部分信息就行了。这也是中本聪在比特币白皮书中所提出的SPV(simple payment verification)的概念。SPV可以不需整个网络的数据而确认交易是否存在。
轻量级节点往往只需要存储区块链头部就可以了。使用有限的信息,轻节点就能够证明某一笔交易是否存在与区块链中。区块头是80字节,一个区块至少是1M,完整交易的区块比区块头的要大的多。因为区块头部信息很少,每年的增加总量大概是在5M左右,所以简单的硬件设备也完全可以运行。

我们来使用分布式文件服务器做例子。如果两个服务器A和B都是对某个文件系统的冗余备份。现在希望A和B通信来确认一下,它们所保存的文件是一致的。如果不使用哈希,那么这个通信代价是整个的文件系统,需要把所有的文件都传递到一个进行比较的服务器上,然后进行字符串比较。这无疑是非常低效的。比较哈希当然是一个好方法。因为哈希的单向性和固定的输出长度,所以通信代价就大大降低了。那么为什么要用一棵树呢?
如果A和B两个服务器上存储的文件系统都是一致的,也即两个的哈希值是一样的,那么自然是很好的。如果两个不一致呢?譬如说A服务器上有一个文件更新了,而B服务器还没有来得及更新。怎么样能够快速地定位到导致两个文件系统不一致的文件?
这时就能体现树结构的好处了。如果两个哈希值不一致,A服务器就可以向B服务器要两个子节点的哈希值;然后沿着不一样的路径一直走下去,从而可以确定导致根哈希值不同的文件。
1.6 总结
去中心化
整个服务没有中心,意味着整个服务无需访问第三方机构,达成共识后,可以直接点对点的对接,具有一定的公平、公开的特点。但对外界来说,整个服务中的每个参与节点都是“中心”,同时也构成了一个“中心”。
防篡改
已存储的区块防止被非法修改,整个提交过程中,既要防止请求被篡改,也要防止非法消息的提交。
可追溯
依靠区块链的链式存储结构,每一次提交区块都是顺序执行。因此可以通过链式结构追溯到任意一次提交的信息。
二、Hyperledger Fabric
2.1 区块链 1.0 VS 区块链 2.0
| 区块链 1.0 | 区块链 2.0 | |
|---|---|---|
| 代表 | 比特币 | 以太坊 |
| 图灵完备 | 否 | 是 |
| 适用 | 单一应用,如:货币网络 | 平台应用 |
| 支持智能合约 | 否 | 是 |
2.2 私有链、公有链、联盟链
私有链:一般适用于一个团体内使用,容错、安全可以酌情考虑,如果节点可信度较高,在选择共识算法上可以考虑无“不可控节点”(拜占庭)问题存在的paxos算法。
公有链:适用于公开使用,所有参与者都是不可控的,每个节点都是直接的参与者,并且对待每个参与者都是无差别的,这样平台需要面对更多的问题,例如节点频繁加入、退出平台,或发送虚假消息,甚至被黑客劫持。因此平台对安全、容错性要求较高,同时“复杂”的共识算法也会导致整个共识过程非常缓慢。
联盟链:适用于多个团体之间的链,参与者在进入服务平台之前,需要进行认证,确定参与者的属性后,才能使用平台。联盟链具有一定的约定性,可以接受“多中心化”的共识算法的介入,如果团体之间并不认可,也可以采取完全中心化的共识算法。
2.3 为什么是 Hyperledger Fabric
Q:为什么不是比特币?
A:需要智能合约
Q:为什么不是以太坊?
A:典型的联盟链
2.4 Hyperledger Fabric 模型

2.5 证书颁发机构(Certificate Authorities,CA)
- 在区块链网络中的不同组件之间,彼此是使用证书来标识自己是来自于特定组织的;
- 可以用来为交易提供签名,来表明一个组织对交易的结果进行背书,背书是一笔交易可以被接受并记录到账本上的前提条件
2.6 Peer 节点
Peer节点和应用程序

- 应用程序 A 连接到了 P1 并且调用了链码 S1 来查询或者更新账本 L1
- P1 调用了链码 S1 来生成提案响应,这个响应包含了查询结果或者账本更新的提案
- 应用程序 A 接收到了提案的响应,对于查询来说,流程到这里就结束了
- 对于更新来说,应用程序 A 会从所有的响应中创建一笔交易
- 它会把这笔交易发送给排序节点 O1 进行排序;
- O1 会搜集网络中的交易并打包到区块中;
- 然后将这些区块分发到所有 Peer 节点上,包括 P1。P1 在把交易提交到账本 L1 之前对交易进行验证。
Peer节点和排序节点
应用程序和 Peer 节点彼此互相交互来确保每个 Peer 节点的账本永远保持一致是通过以==排序节点==作为中心媒介的一种特殊机制
==1. 提案==

- 应用程序 A1 生成了交易 T1 和提案 P,应用程序会将交易及提案发送给通道 C 上的 Peer 节点 P1 和 Peer 节点 P2;
- P1 使用交易 T1 和 提案 P 来执行链码 S1,这会生成对交易 T1 的响应 R1,它会提供背书 E1。P2 使用交易 T1 提案 P 执行了链码 S1,这会生成对于交易 T1 的响应 R2,它会提供背书 E2;
- 应用程序 A1 对于交易 T1 接收到了两个背书响应,称为 E1 和 E2。
==2. 排序和将交易打包到区块==
- 排序节点是这个过程的关键——它接收交易,这些交易中包含了来自很多个应用的已经背书过的交易提案,并且将交易排序并打包进区块。
==3. 验证和提交==

- 排序节点 O1 将区块 B2 分发给了 Peer 节点 P1 和 Peer 节点 P2;
- Peer P1 处理了区块 B2,产生了一个会被添加到 P1 的账本 L1 中的新区块;
- Peer P2 处理了区块 B2,产生了一个会被添加到 P2 的账本 L1 中的新区块;
- 当这个过程结束之后,账本 L1 就会被一致地更新到了 Peer 节点 P1 和 P2 上,他们也可能会通知所连接的应用程序关于这笔交易已经被处理过的消息。
2.7 账本

世界状态是一个数据库,它存储了一组账本状态的当前值。通过世界状态,程序可以直接访问一个账本状态的当前值,不需要遍历整个交易日志来计算当前值

区块链是交易日志,它记录了促成当前世界状态的所有改变。交易被收集在附加到区块链的区块中,能帮助我们理解所有促成当前世界状态的改变的历史。区块链数据结构与世界状态相差甚远,因为一旦把数据写入区块链,就无法修改,它是不可篡改的。


我理解的区块链 VS 真正的区块链:
