区块链研习社

《以太坊白皮书》笔记(1)—— 比特币介绍

2017-12-31  本文已影响335人  JOJOTOV

《以太坊白皮书》原文链接:https://github.com/ethereum/wiki/wiki/White-Paper

Bitcoin

#1 State Transaction System

State

状态转换的过程

在 Bitcoin 当中,"state" 代表了所有被挖出且没有被消费的货币的集合 (UTXO - "unspent transaction outputs"),并且每一个货币都有面值和持有者。

Bitcoin 交易:

  1. 有 1 个或多个输入,包含现有的 UTXO 和由持有者地址相关的私钥签名
  2. 有 1 个或多个输出, 包含一个新的 UTXO 并更新状态

State Transaction Function

输入当前状态和一笔交易,输出新的状态或者ERROR

APPLY(S,TX) -> S' or ERROR
  1. For each input in TX:
  • If the referenced UTXO is not in S, return an error.
  • If the provided signature does not match the owner of the UTXO, return an error.
  1. If the sum of the denominations of all input UTXO is less than the sum of the denominations of all output UTXO, return an error.
  2. Return S' with all input UTXO removed and all output UTXO added.

#2 Mining

比特币中一部分 block 示例

Decentralized

如果有一个足够信赖的中心化服务,那么挖矿系统存在的意义就变得微乎其微。因为这个中心化服务可以实时追踪全局的状态。

但比特币努力打造了一个去中心化的货币系统。因此,比特币的状态转换系统必须配上一个共识系统,为了确保每一笔交易的可信度。

比特币的去中心化系统要求网络中的节点去不断地尝试去制造一个个包含交易的集合 —— 区块。在比特币网络中,每十分钟会产出一个新的区块,这个区块会包含创建时的时间戳、一个临时随机数、一个前一区块的哈希串以及一个在这期间发生的所有交易的列表。经过一段时间之后,这会产生一个持久的、持续增长并且持续保持最新状态的比特币账本——区块链

Validation

校验块是否正确的算法:

  1. 检查父块是否存在并且合法
  2. 检查块的时间戳是否大于父块的时间戳,并且差值小于 2 小时
  3. 检查 POW 是否合法
  4. 让父块的最终状态变为 S[0]
  5. 假设 TX 为当前块中 n 条交易的列表,对于 i in 0...n-1,让s[i+1] = APPLY(S[i],TX[i]),如果任何一次操作返回错误,则检验返回错误
  6. 返回正确,并注册 S[n] 为当前块的最终状态

Note:

each transaction in the block must provide a valid state transition from what was the canonical state before the transaction was executed to some new state
每条交易必须提供一个已经验证的状态,这个状态由交易真正被进行前的一个权威状态转变而来。

Proof of Work (POW)

比特币目前的POW条件:double-SHA256 hash (必须小于一个动态调整的 target值)

因为 SHA256 的设计,就是为了使其完全不可预测。而创造一个新的区块的唯一办法,就是不停地进行运算并递增临时随机数以尝试让得出的哈希值通过验证。因此,这样可以让每个块的生成有一定的难度,从而防止区块链被攻击。

比特币的目标值会在每 2016 个区块创造出来后更新一次,因此,比特币系统可以保证每 10 分钟才会创造出一个新的区块。同时,每个矿工挖出一个新的区块会得到一定数量的比特币奖励。另外,如果在此区块中的任何交易发生时的比特币价值大于这次交易被确认时的价值,那么这个差值也会当做 “手续费” 给予矿工。

为了更好的理解挖矿的意义,以下是假设有人要攻击比特币系统时会发生的事:

因为比特币的密码学基础被公认为安全的,所以攻击者的目标会是比特币系统中没有被密码学基础所保护的地方:交易的顺序。其策略如下:

  1. 用 100 BTC 向一位供应商换取一项商品 (通常是可以快速交付的电子商品)
  2. 等待供应商交付
  3. 生成另一笔向自己支付 100 BTC 的交易
  4. 尝试让比特币网络 “认同” 这笔向自己支付的交易是先发生的

当步骤 1 发生时,几分钟后会有一个矿工把这笔交易囊括在自己发现的区块中,假设是区块 27,000。大约一个小时后,更多的 5 个区块会被加入到区块链当中,且这 5 个区块每个都间接指向区块 27,000。因此,区块 27,000 是被 ”确认“ 过的区块。

这时,供应商会确认这笔交易并交付商品。然后,攻击者会创建另一条向自己支付 100 BTC 的交易。如果攻击者直接把它公布出去,那这笔交易并不会被承认并加入。因为矿工们会去跑 APPLY(S,TX) 并注意到 TX 消费了一个不存在于当前状态中的 UTXO。

因此,攻击者会选择其他方法,比如会创建一条比特币区块链的 “分支”,且这条分支中有了一个包含那条向自己支付 100 BTC 交易的区块 27,000 指向一个与原区块 27,000 相同的父区块 —— 区块 26,999。因为这个区块 27,000 的数据与原先不同,因此这个区块会被要求重新运算 POW。而且,由于原先的区块 27,001 - 27,005 并没有 “指向” 这个新的区块,因此攻击者的新区块链和原有的区块链可以说时完全分离了。

在比特币的规则中,如果区块链有分支,那么最长的分支总是最被信任的。所以其他所有的矿工都会基于区块 27,005 所在的这条链上进行作业,而攻击者只能一个人基于他自己的链进行作业。那么攻击者为了使他自己的区块链变成最长的链,他必须拥有比其他所有矿工更高的算力才能达到!

更有意思的是,在中本聪 (比特币发明者) 本人的说明中,由挖矿带来的奖励,要远远大于破坏现有的比特币网络 (需要注意,这在矿工数量很少的情况下并不适用)。

#3 Merkle Trees

Merkle Tree 示例

比特币中所有交易的数据都被存储在一种二叉树类型的名为 Merkle Tree 的数据结构中。

  1. 具有树结构的所有特点
  2. 叶子节点的值为 HASH 值
  3. 非叶子节点的值是根据其下面的所有子节点的值通过 HASH 算法计算得出

Merkle Tree 在比特币中应用的目的是为了验证数据的有效性。因为哈希值向上传递的特性,如果有人试图传递一个假的交易数据,那么这会导致此节点在 Merkle Tree 中的父节点数据发生改变,以及父节点的父节点……

使用 Merkle Tree 的另一个重要的原因是:**Simplified Payment Verification (SPV) **协议。SPV 允许一种称为 “light nodes” 的节点集合。SPV 协议使得在验证某一交易的有效性时,能够只下载比特币区块链中所有数据的其中一小部分,同时也可以强有力地保证数据的有效性。

只需要较小一部分的节点便可以验证某一叶子节点的数据有效性 对任一叶子节点数据的修改最后都会导致整条链中某一处产生错误

#4 Scripting

在比特币中,由于没有现实中的 “账户” 的概念。因此如何判断用户所拥有的 UTXO,并不单单是依靠一个公钥地址,而是一个更为复杂的脚本。比特币中的脚本,是一种基于栈运行的程序语言。

在这样的设计下,任何一笔交易如果要达成,这笔交易所花费的 UTXO 必须满足这个脚本(由产生这个 UTXO 的交易输出)。

假设,Bob 向 Alice 支付了 1BTC,这笔交易输出了类似一个包含 Alice 公钥的脚本。现在,Alice 想花费这 1BTC,她必须提供自己私钥生成的签名(私钥是 Alice 唯一的 )和公钥作为输入。如果脚本能够顺利跑通,那么这个交易就会被认可,同时所有人都可以去验证这笔交易。

比特币脚本的几个缺陷:

  1. 缺少图灵完备性
  2. 缺少状态的声明
  3. 没有绑定任何数据
  4. 过依赖区块链

阅读 Github 上 《Ethereum - White Paper》 的一些笔记

上一篇下一篇

猜你喜欢

热点阅读