精通区块链(二)

原文:zh.annas-archive.org/md5/0290aeea847c6aa4c7f7f8ed538e33ef

译者:飞龙

协议:CC BY-NC-SA 4.0

第四章:比特币

比特币是区块链技术的第一个应用。在本章中,读者将详细介绍比特币技术。

比特币随着第一个完全去中心化数字货币的推出而开启了一场革命,并且已被证明是非常安全稳定的。这也引发了学术和工业研究的极大兴趣,并引入了许多新的研究领域。自 2008 年推出以来,比特币受到了很大的欢迎,并且目前是世界上最成功的数字货币,投资额达数十亿美元。它建立在密码学、数字现金和分布式计算领域数十年的研究基础上。在接下来的部分中,将介绍一个简要的历史,以便提供理解比特币发明背后基础所需的背景。

数字货币一直是多个十年的研究活跃领域。早期提出创建数字现金的建议可以追溯到上世纪 80 年代初。1982 年,大卫·乔姆提出了一种利用盲签名构建不可追踪数字货币的方案。在这个方案中,银行将通过签署用户提供的盲目且随机的序列号来发行数字货币。用户随后可以使用银行签署的数字令牌作为货币。这个方案的局限性在于银行必须跟踪所有已使用的序列号。这是一个中心化系统,需要用户信任。随后在 1990 年,大卫·乔姆提出了一个名为 e-cash 的改进版本,不仅使用了盲签名,还使用了一些私有识别数据来制作一个然后发送给银行的消息。这个方案允许检测双重支付,但不能防止它。如果同一令牌在两个不同的位置使用,则会显露双重支付者的身份。e-cash 只能表示固定金额的货币。亚当·巴克于 1997 年提出的 hashcash 最初是为了防止电子邮件垃圾邮件。hashcash 背后的思想是解决一个易于验证但相对难以计算的计算难题。

这个想法是,对于单个用户和单个电子邮件,额外的计算工作是不可感知的,但是发送大量垃圾邮件的人会因为运行垃圾邮件活动所需的时间和资源大大增加而感到沮丧。

B-money 是魏·戴在 1998 年提出的,引入了使用工作量证明来创造货币的概念。系统的一个主要弱点是,具有更高计算能力的对手可以生成未经邀请的货币,而不允许网络调整到适当的困难级别。该系统缺乏有关节点之间共识机制的细节,也没有解决诸如 Sybil 攻击等一些安全问题。与此同时,尼克·萨博介绍了 BitGold 的概念,它也基于工作量证明机制,但与 b-money 一样存在相同的问题,唯一的区别是网络难度水平是可调整的。托马斯·桑德阿蒙·塔沙马在 1999 年介绍了一个电子现金方案,该方案首次使用 Merkle 树表示硬币,并使用零知识证明证明了对硬币的拥有权。在这个方案中,需要一个中央银行,它记录了所有已使用的序列号。尽管存在计算成本,但这个方案允许用户完全匿名。RPOW可重复使用工作量证明)是由哈尔·芬尼在 2004 年推出的,使用亚当·贝克的 hashcash 方案作为消耗资源来创建货币的证明。这也是一个保留中央数据库以跟踪所有已使用 POW 令牌的中央系统。这是一个使用可信计算平台TPM 硬件)实现的基于远程证实的在线系统。

所有先前提到的方案都设计得很巧妙,但从某个方面来看都存在弱点。特别是,所有这些方案都依赖于一个需要用户信任的中央服务器。

比特币

2008 年,中本聪撰写了一篇关于比特币的论文比特币:一种点对点的电子现金系统。文中首次提出的关键思想是,纯粹的点对点电子现金不需要中介银行来在对等方之间转移支付。

比特币是建立在几十年的密码学研究基础上的,诸如 Merkle 树、哈希函数、公钥密码学和数字签名等研究。此外,BitGold、b-money、hashcash 和密码时间戳等概念为比特币的发明奠定了基础。所有这些技术在比特币中被巧妙地结合起来,创造了世界上第一个去中心化货币。比特币所解决的关键问题是对拜占庭将军问题的优雅解决方案,以及双花问题的实际解决方案。

自 2011 年以来,比特币的价值显著增长,如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2012 年以来比特币价格和交易量(对数刻度)

对比特币的监管是一个有争议的话题,尽管它是自由主义者的梦想,执法机构和政府正在提出各种规定来控制它,比如纽约州金融服务部门颁发的 BitLicense。这是针对进行虚拟货币相关活动的企业颁发的许可证。

比特币的增长也是因为所谓的网络效应。也称为需求端的规模经济,这个概念基本上意味着更多使用网络的用户,它就变得更有价值。随着时间的推移,比特币网络增长呈指数增长。尽管比特币的价格相当波动,但在过去几年里它有了显著的增长。目前(在编写时),比特币的价格是 815 英镑。

比特币定义

比特币可以以各种方式定义;它是一个协议,一个数字货币,也是一个平台。它是一个由点对点网络、协议和软件组成的组合,用于方便创建和使用名为比特币的数字货币。请注意,大写字母B的比特币用于指代比特币协议,而小写字母b的比特币用于指代比特币这个货币。这个点对点网络中的节点使用比特币协议进行通信。

通过比特币的发明,货币的去中心化首次成为可能。此外,比特币还以一种巧妙而聪明的方式解决了双花问题。双花问题是指当一个用户同时向两个不同的用户发送硬币时,并且这些硬币独立验证为有效交易时产生的问题。

密钥和地址

椭圆曲线加密被用于在比特币网络中生成公钥和私钥对。比特币地址是通过取私钥的对应公钥并对其进行两次哈希来创建的,首先用 SHA256 算法,然后再用 RIPEMD160。然后将结果的 160 位哈希值前缀加上版本号,最后使用 Base58Check 编码方案进行编码。比特币地址通常是 26-35 个字符长,并以数字 1 或 3 开始。一个典型的比特币地址看起来像是以下显示的字符串:

1ANAguGG8bikEv2fYsTBnRUmx7QUcK58wt

这通常也被编码成 QR 码以便分享。前述地址的 QR 码如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比特币地址 1ANAguGG8bikEv2fYsTBnRUmx7QUcK58wt 的 QR 码

目前,有两种类型的地址,常用的是 P2PKH 和另一种 P2SH 类型,分别以 1 和 3 开头。在早期,比特币使用直接的 Pay-to-Pubkey,现在已被 P2PKH 取代。但是,直接的 Pay-to-Pubkey 在比特币中仍然用于 coinbase 地址。地址不应重复使用;否则,可能会出现隐私和安全问题。避免地址重用可在一定程度上规避匿名问题,比特币还存在其他安全问题,例如交易篡改,需要采用不同的方法来解决。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从 bitaddress.org 中的纸钱包中的私钥和比特币地址

比特币中的公钥

在公钥密码学中,公钥是从私钥生成的。比特币使用基于 SECP256K1 标准的 ECC。私钥是随机选择的,长度为 256 位。公钥可以以未压缩或压缩格式呈现。公钥基本上是椭圆曲线上的 xy 坐标,在未压缩格式下以十六进制格式带有前缀 04 呈现。XY 坐标都是 32 位长。总的来说,压缩公钥的长度为 33 字节,而未压缩格式为 65 字节。压缩版的公钥基本上只包括 X 部分,因为 Y 部分可以由它导出。压缩版的公钥之所以有效是因为比特币客户端最初使用未压缩密钥,但从比特币核心客户端 0.6 开始,压缩密钥被用作标准。

密钥由各种前缀标识,描述如下:

  • 未压缩的公钥以 0x04 作为前缀

  • 如果公钥的 y 32 位部分为奇数,则压缩公钥以 0x03 开头

  • 如果公钥的 y 32 位部分为偶数,则压缩公钥以 0x02 开头

更详细的数学描述及其工作原理在此描述。如果可视化 ECC 图表,将显示 y 坐标可以位于 x 轴下方或上方,由于曲线对称,因此只需存储在素数域中的位置。

比特币中的私钥

私钥基本上是根据 SECP256K1 ECDSA 推荐规范指定的范围中选择的 256 位数字。从 0x1 到 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4140 中随机选择的任意 256 位数字都是有效的私钥。

私钥通常使用钱包导入格式WIF)进行编码,以便更容易地复制和使用。WIF 可以转换为私钥,反之亦然。具体步骤请参见此处。

此外,迷你私钥格式有时用于在不到 30 个字符的情况下对密钥进行编码,以允许在空间有限的情况下存储,例如,在实体硬币上刻写或耐损 QR 码上。比特币核心客户端还允许加密包含私钥的钱包。

比特币货币单位

比特币货币单位描述如下。最小的比特币单位是 Satoshi。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Base58Check 编码

此编码用于限制不同字体中相似字符(例如 0OIl)之间的混淆。该编码基本上将二进制字节数组转换为人类可读字符串。这个字符串是通过使用一组 58 个字母数字符号来构成的。有关更多解释和逻辑,请参阅比特币源代码中的 base58.h 源文件。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来自比特币源代码的解释

比特币地址使用 Base58check 编码进行编码。

虚荣地址

由于比特币地址基于 base 58 编码,因此可以生成包含人类可读消息的地址。以下是一个示例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QR 中编码的公共地址

虚荣地址是使用纯粹的暴力方法生成的。以下截图显示了一个示例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从 https://bitcoinvanitygen.com/ 生成的虚荣地址

交易

交易是比特币生态系统的核心。交易可以简单到只是将一些比特币发送到比特币地址,也可以根据需求变得非常复杂。每个交易至少由一个输入和输出组成。输入可以被视为在先前交易中创建的被花费的硬币,而输出则被视为被创建的硬币。如果交易正在铸造新的硬币,则没有输入,因此不需要签名。如果交易是将硬币发送给其他用户(比特币地址),则需要由发送者使用其私钥签名,并且还需要参考先前交易以显示硬币的来源。事实上,硬币是以 Satoshi 表示的未花费交易输出。

交易未加密,可以在区块链中公开查看。区块由交易组成,这些交易可以使用任何在线区块链浏览器查看。

交易生命周期

  1. 用户/发送者使用钱包软件或其他界面发送交易。

  2. 钱包软件使用发送者的私钥对交易进行签名。

  3. 交易使用洪泛算法广播到比特币网络。

  4. 挖掘节点将此交易包含在下一个要挖掘的块中。

  5. 一旦解决工作量证明问题的矿工向网络广播新挖掘的区块,挖矿就开始了。工作量证明将在本章后面详细解释。

  6. 节点验证块并传播块,确认开始生成。

  7. 最后,确认开始出现在接收方的钱包中,大约六次确认后,交易被视为最终确定。然而,六只是一个建议的数字;即使在第一次确认后,交易也可以被视为最终确定。等待六次确认背后的关键思想是,六次确认后几乎消除了双重支付的可能性。

交易结构

高层次上,每个交易都包含元数据、输入和输出。交易被组合创建一个块。交易结构如下表所示:

字段大小描述
版本号4 字节用于指定矿工和节点用于交易处理的规则。
输入计数器1 字节至 9 字节交易中包含的输入数量。
输入列表可变每个输入由多个字段组成,包括前一笔交易哈希、前一笔交易输出-索引、Txin 脚本长度、Txin 脚本和可选的序号。块中的第一个交易也称为 coinbase 交易。它指定一个或多个交易输入。
输出计数器1 字节至 9 字节代表输出数量的正整数。
输出列表可变包含在交易中的输出。
锁定时间4 字节定义交易有效的最早时间。可以是 Unix 时间戳或区块号。
  • 元数据: 交易的这部分包含一些值,如交易大小、输入和输出数量、交易的哈希和一个lock_time字段。每个交易都有一个指定版本号的前缀。

  • 输入: 通常,每个输入都花费之前的输出。每个输出都被视为未被花费的交易输出(UTXO)直到有输入消耗它。

  • 输出: 输出只有两个字段,并包含比特币发送的指令。第一个字段包含 Satoshis 的金额,而第二个字段是一个锁定脚本,其中包含必须满足的条件,以便花费输出。稍后在本节中将讨论使用锁定和解锁脚本以及产生输出进行交易支出的更多信息。

  • 验证: 使用比特币的脚本语言进行验证。

一个示例交易如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

显示了各个早期描述的字段的样例解码交易

脚本语言

比特币使用一种简单的基于堆栈的语言称为脚本来描述比特币如何被花费和转移。它不是图灵完备的,并且没有循环,以避免长时间运行/挂起脚本对比特币网络产生任何不良影响。这种脚本语言基于类似于 Forth 的语法,并使用逆波兰表示法,其中每个操作数都跟随其操作符。它从左到右使用后进先出LIFO)堆栈进行评估。

脚本使用各种操作码或指令来定义其操作。操作码也称为字、命令或函数。比特币节点的早期版本有一些操作码,由于在设计中发现了错误而不再使用。

脚本操作码的各种类别包括常量、流程控制、堆栈、位逻辑、拼接、算术、密码学和锁定时间。

通过组合ScriptSigScriptPubKey来评估交易脚本。ScriptSig是解锁脚本,而ScriptPubKey是锁定脚本。这就是如何评估交易是否已经花费;首先解锁,然后花费。ScriptSig由希望解锁交易的用户提供。ScriptPubkey是交易输出的一部分,并指定了必须满足的条件才能花费输出。换句话说,输出由包含条件的ScriptPubKey(锁定脚本)锁定,当满足条件时将解锁输出,然后可以兑现硬币。

常用操作码

所有操作码都在比特币参考客户端源代码中的 script.h 文件中声明。这可以通过以下链接访问:github.com/bitcoin/bitcoin/blob/master/src/script/script.h,在以下注释下:

/ 脚本操作码 /*

下面列出了最常用的操作码的描述。这个表格摘自比特币开发者指南:

操作码描述
OP_CHECKSIG这获取一个公钥和签名,并验证交易哈希的签名。如果匹配,则将 TRUE 推送到堆栈上;否则将 FALSE 推送。
OP_EQUAL如果输入完全相等,则返回 1;否则返回 0。
OP_DUP这会复制堆栈中的顶部项。
OP_HASH160输入被两次哈希,首先使用 SHA-256,然后使用 RIPEMD-160。
OP_VERIFY如果顶部堆栈值不为真,则将交易标记为无效。
OP_EQUALVERIFY这与OP_EQUAL相同,但之后运行OP_VERIFY
OP_CHECKMULTISIG这获取第一个签名并将其与每个公钥进行比较,直到找到匹配项,并重复此过程直到检查所有签名。如果所有签名都有效,则返回 1 作为结果;否则返回 0。

交易类型

比特币中有各种脚本可用于处理从源到目的地的价值转移。这些脚本的复杂程度因交易需求的不同而异,从非常简单到相当复杂。在此讨论标准交易类型。标准交易是通过IsStandard()IsStandardTx()测试进行评估的,通常只有通过测试的标准交易才被允许在比特币网络上进行挖掘或广播。然而,非标准交易是有效的,也允许在网络上进行。

  • 支付到公钥哈希P2PKH):P2PKH 是最常用的交易类型,用于将交易发送到比特币地址。交易的格式如下所示:

    ScriptPubKey: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG

    ScriptSig:

    ScriptPubKeyScriptSig 参数连接在一起并执行。在本节中很快将会有一个示例,更详细地解释这一点。

  • 支付到脚本哈希P2SH):P2SH 用于将交易发送到脚本哈希(即以 3 开头的地址),并在 BIP16 中标准化。除了通过脚本,还必须评估赎回脚本并确保其有效。模板如下所示:

    ScriptPubKey: OP_HASH160 OP_EQUAL

    ScriptSig: […]

  • 多重签名(支付到多重签名):M of n 多重签名交易脚本是一种复杂类型的脚本,可以构建一个需要多重签名才能有效赎回交易的脚本。使用此脚本可以构建各种复杂的交易,如担保和存款。模板如下所示:

    ScriptPubKey: [ . . . ] OP_CHECKMULTISIG

    ScriptSig: 0 [ . . . ]

    原始多重签名已过时,多重签名通常是 P2SH 赎回脚本的一部分,如前述条目中所述。

  • 支付到公钥:此脚本是一种非常简单的脚本,通常用于 coinbase 交易。它现在已经过时,并且在比特币的旧版本中使用。在这种情况下,公钥存储在脚本中,解锁脚本需要用私钥签署交易。

    模板如下所示:

    OP_CHECKSIG

  • 空数据/OP_RETURN:此脚本用于以一定费用将任意数据存储在区块链上。消息的限制为 40 字节。此脚本的输出无法赎回,因为OP_RETURN在任何情况下都会验证失败。在这种情况下不需要ScriptSig

    模板非常简单,如下所示:

    OP_RETURN

P2PKH 脚本执行如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

P2PKH 脚本执行

所有交易最终都会在传输到比特币网络之前被编码为十六进制。使用以下命令在比特币测试网络上使用 bitcoin-cli 检索的十六进制中显示了示例交易:

drequinox@drequinox-OP7010:~$ bitcoin-cli --testnet getrawtransaction "08af7960ca9255c67686296fb65452ed3f96f18831c9a3d8ea552e4ccee5c4af"
0100000001b008bb28e3fde10a2161a9ae9029ebcfe6156e57b63e04f76048a9a06032553e010000006b483045022100cfb31edabc62c82b41d12f651d2e3e013ee1a7ee2bb4526f3dda640e6d8d224502207d8d1d8e41350b9cdf36f389f942ab68c12f113fe99014f5d6df6610407877d20121037bc82d0078993f6943e7ff6e82e82da600f34edc8bca136331a9901c8bb60b0dfeffffff028085b50d000000001976a91407e78644a61343068fa8d4940a79976e758ac6ef88ac95bddc1c000000001976a914dad770cccb1026ebf87acacfe35f2d6f2d336faa88ac33cb0e00

Coinbase 交易

Coinbase 交易或生成交易总是由矿工创建的,并且是区块中的第一笔交易。它用于创建新的硬币。它包括一个特殊字段,也称为coinbase,它充当 coinbase 交易的输入。该交易还允许最多 100 字节的任意数据,该数据可用于存储任意数据。在创世区块中,这包括从《泰晤士报》中选取的最著名的评论:

“泰晤士报 2009 年 1 月 3 日 央行行长准备为银行进行第二次纾困”

这条消息证明了创世区块不会早于 2009 年 1 月 3 日被挖掘出来。

什么是 UTXO?

未花费交易输出UTXO)是可以作为新交易的输入花费的未花费交易输出。比特币中与交易相关的其他概念如下所述。

交易费

交易费用由矿工收取。收取的费用取决于交易的大小。交易费用通过减去输入总和和输出总和来计算。这些费用被用作激励,鼓励矿工将用户交易包含在他们正在创建的区块中。所有交易最终都会进入内存池,矿工会根据它们的优先级挑选交易,以便将它们包含在提议的区块中。关于优先级的计算将在本章后面介绍;然而,从交易费用的角度来看,交易费较高的交易将被矿工更早地挑选出来。根据不同的规则计算各种操作的费用,例如发送交易、包含在区块中以及节点中继。比特币协议中没有固定的费用,也不是强制性的;即使没有费用的交易也会在适当的时候处理,但可能需要很长时间。

合约

根据比特币核心开发者指南的定义,合约基本上是使用比特币系统执行财务协议的交易。这是一个简单的定义,但其影响深远,因为它允许用户设计可以用于许多现实场景的复杂合约。合约允许开发完全去中心化、独立且降低风险的平台。可以使用比特币脚本语言构建各种合约,例如第三方担保、仲裁和微支付通道。脚本的当前实现非常有限,但仍然可以开发各种类型的合约。例如,仅在多方签署交易后才释放资金,或者仅在经过一定时间后才释放资金。这两种情况都可以使用multiSig和交易锁定时间选项来实现。

交易可塑性

比特币中的交易可塑性是由于比特币实现中的错误而引入的。由于这个错误,对手有可能改变交易的交易 ID,从而导致某个交易似乎没有被执行的情况。这可能导致双重存款或取款的情况发生。换句话说,在比特币交易被确认之前,这个错误允许改变比特币交易的唯一 ID。

如果在确认之前 ID 被更改,那么该交易似乎根本没有发生,这样可以允许双重存款或取款攻击。

交易池

也称为内存池,这些池基本上是由节点在本地内存中创建的,以维护尚未在区块中确认的交易的临时列表。交易在通过验证后,并根据它们的优先级被包含在一个块中。

交易验证

这个验证过程是由比特币节点执行的。在比特币开发者指南中描述了以下内容:

  1. 检查语法并确保交易的语法正确。

  2. 验证输入和输出不为空。

  3. 检查字节大小是否小于当前的最大块大小,即 1 MB。

  4. 输出值必须在允许的货币范围内(0 至 2100 万比特币)。

  5. 所有输入必须有指定的前一输出,除了 coinbase 交易,不应进行中继。

  6. 验证nLockTime必须不超过 31 位。为了使交易有效,它的大小不应小于 100 字节。此外,标准签名中的签名操作数的数量应少于或不超过 2。

  7. 拒绝非标准交易;例如,ScriptSig只允许在堆栈上推送数字。ScriptPubkey不通过isStandard()检查。

  8. 如果池中已经存在匹配的交易或者在主分支的一个块中存在匹配的交易,则拒绝该交易。

  9. 如果每个输入的引用输出存在于池中的任何其他交易中,则将拒绝该交易。

  10. 对于每个输入,必须存在一个引用的输出交易。这是在主分支和交易池中搜索的,以查找是否有任何输入缺失输出交易,如果匹配的交易尚未在池中,则将其视为孤立交易,将其添加到孤立交易池中。

  11. 对于每个输入,如果引用的输出交易是 coinbase,则必须至少有 100 次确认;否则,将拒绝该交易。

  12. 对于每个输入,如果引用的输出不存在或已经花费,则将拒绝该交易。

  13. 使用引用的输出交易获取输入值,验证每个输入值以及总和是否在 0-2100 万比特币的允许范围内。

  14. 如果输入值的总和小于输出值的总和,则拒绝该交易。

  15. 如果交易费用过低而无法进入空区块,则拒绝交易。

区块链

区块链是比特币网络上所有交易的时间戳、有序和不可变列表的公共分类帐。每个区块在链中由哈希标识,并通过引用前一个区块的哈希链接到其前一个区块。

在以下区块结构中,描述了一个区块头,随后是一个详细的图表,提供了对区块链结构的洞察。

区块的结构

字节名称描述
80区块头这包括了下一节中描述的区块头的字段。
可变交易计数器该字段包含区块中的所有交易总数,包括 coinbase 交易。
可变交易区块中的所有交易。

区块头的结构

字节名称描述
4版本指定要遵循的区块验证规则的区块版本号。
32上一个区块头哈希这是上一个区块头的双重 SHA256 哈希。
32默克尔根哈希这是包含在区块中的所有交易的默克尔树的双重 SHA256 哈希。
4时间戳此字段以 Unix 纪元时间格式包含了区块的大致创建时间。更确切地说,这是矿工开始对头部进行哈希计算的时间(从矿工的角度看)。
4难度目标这是区块的难度目标。
4随机数这是矿工反复更改的任意数字,以产生一个满足难度目标阈值的哈希。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

区块链、区块、区块头、交易和脚本的可视化

正如前图所示,区块链是一个区块链,其中每个区块通过引用前一个区块头的哈希链接到其前一个区块。这种链接确保除非记录它的区块及其后续所有区块也被修改,否则不会修改任何交易。第一个区块未链接到任何前一个区块,并且被称为创世区块。

创世区块

这是比特币区块链中的第一个区块。创世区块已经在比特币核心软件中硬编码。它位于 chainparams.cpp 文件中。

github.com/bitcoin/bitcoin/blob/master/src/chainparams.cpp

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比特币通过强制对交易进行严格规则验证和通过挖矿来防止双重支付。在严格规则检查和成功的工作量证明解决方案后,区块才会添加到区块链中。区块高度是指在特定区块之前的区块数量。目前(在撰写本文时)区块链的高度为 434755 个区块。工作量证明用于保护区块链。每个区块包含一个或多个交易,其中第一个交易是 coinbase 交易。对于 coinbase 交易,有一个特殊条件,即要防止它们在至少 100 个区块之前被使用,以避免出现后来可能被宣布为过时的情况。

当一个区块被解决并且其它仍在努力解决哈希难题的矿工都在工作,这时就会产生过时区块。挖矿和哈希难题将在本章后面详细讨论。因为区块不再需要进行工作,所以被认为是过时的区块。

孤立区块也被称为分离区块,曾经被网络一度接受为有效区块,但在创建一个不包括这个最初接受的区块的被证明更长的链后被拒绝。它们不是主链的一部分,有时会出现在两个矿工同时产生区块的情况下。

最新的区块版本是版本 4,它是由 BIP65 提出的,并自比特币核心客户端 0.11.2 以来一直在使用,因为在nVersion字段中实施了 BIP9 位来指示软叉变更。

由于比特币的分布式性质,网络分叉可能会自然发生。在两个节点同时宣布一个有效的区块的情况下,会出现两个具有不同交易的区块链的情况。这是一个不希望发生的情况,但仅通过接受最长链的比特币网络才能解决。在这种情况下,较小的链将被视为孤立的。如果对手设法获得对网络算力(计算能力)51%的控制权,那么他们就可以强加自己的交易历史版本。

区块链中的分叉可能是由于比特币协议的变化引起的。在软分叉的情况下,只有以前的有效区块不再被接受,从而使软分叉向后兼容。在软分叉的情况下,只需要矿工升级到新的客户端软件以利用新的协议规则。计划升级不一定会造成分叉,因为所有用户都应该已经更新了。另一方面,硬分叉会使先前有效的区块无效,并要求所有用户进行升级。有时会添加新的交易类型作为软分叉,而任何变化,如区块结构变化或主要协议变化都会导致硬分叉。

截至 2017 年 2 月 4 日,比特币区块链的当前大小约为 101 GB。下图显示了区块链大小随时间变化的情况:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

截至 2017 年 6 月 2 日,区块链的当前大小为。

新的区块大约每 10 分钟添加到区块链中,并且网络难度在每 2016 个区块动态调整,以保持对网络的稳定增加新区块。

网络难度使用以下方程计算:

目标=上一个目标时间/201610 分钟

难度和目标是可以互换的,表示同一件事。上一个目标表示旧的目标值,时间是生成前 2016 个区块所花费的时间。网络难度基本上意味着对矿工来说找到新区块有多困难,也就是说,现在哈希难题有多难。

在本节中,讨论了挖矿,将解释哈希难题是如何被解决的。

挖矿

挖矿是一个资源密集型过程,通过该过程新的区块被添加到区块链中。区块包含通过挖矿过程由挖矿节点验证的交易,并添加到区块链中。为了确保区块被接受,这个过程是资源密集型的。矿工通过花费必要的计算资源铸造新的硬币。这也确保了系统抵御欺诈和双重支付攻击,同时为比特币生态系统增加了更多的虚拟货币。

大约每 10 分钟产生(挖掘)一个新区块。如果矿工创建新区块,并在其中包含交易,他们将获得新的硬币,并作为交易费用。新区块以大约固定的速度创建。此外,每 210,000 个区块,大约每四年,新比特币的产生速度会减半。当比特币初始推出时,区块奖励是 50 个比特币;然后在 2012 年,这被减少到 25 个比特币。到 2016 年 7 月,这进一步减少到 12.5 个硬币(12 个硬币),预计下一次减少将在 2020 年 7 月 4 日。这将进一步将硬币奖励减少到大约六个硬币。

每天大约产生 144 个区块,即 1728 个比特币。实际硬币数量每天可能有所变化,但是每天的区块数量保持在 144 个。比特币供应也是有限的,在 2140 年,大约将终于创造出 2100 万个比特币,之后将不会再创造新的比特币。然而,比特币矿工仍然能够通过收取交易费从生态系统中获利。

矿工的任务

一旦一个节点连接到比特币网络,比特币矿工执行几个任务。

与网络同步

一旦一个新节点加入比特币网络,它通过向其他节点请求历史区块下载区块链。这里提到比特币矿工,但这不一定是一个仅供矿工完成的任务。

  • 交易验证:全节点通过验证和验证签名和输出来验证网络广播的交易。

  • 区块验证:矿工和全节点可以通过对其收到的区块根据某些规则进行评估来开始验证这些区块。这包括验证区块中每笔交易以及验证随机数值的正确性。

  • 创建新区块:矿工通过验证后结合网络广播的交易提出一个新区块。

  • 执行工作量证明:这一任务是挖矿过程的核心,矿工通过解决一个计算难题找到一个有效的区块。区块头包含一个 32 位随机数字段,矿工需要反复改变随机数,直到结果哈希小于预定目标。

  • 获取奖励:一旦一个节点解决了哈希难题,它立即广播结果,其他节点验证并接受该区块。由于与大致同时发现的另一个区块冲突的可能性微弱,新铸造的区块有可能不被其他矿工接受,但一旦接受,矿工将获得 12.5 个比特币(截至 2016 年)以及任何相关的交易费用。

工作量证明

这是一个证明足够的计算资源已经被消耗以构建一个有效区块证明。工作量证明PoW)基于这样一个思想:每次选择一个随机节点来创建一个新区块。在这个模型中,节点根据其计算能力的比例彼此竞争以被选中。以下等式总结了比特币中工作量证明的要求:

H ( N || P_hash || Tx || Tx || . . . Tx) < 目标

其中 N 是一个随机数,P_hash是上一个区块的哈希,Tx代表区块中的交易,目标是目标网络难度值。这意味着上述连接字段的哈希应小于目标哈希值。找到这个随机数的唯一方法是穷举法。一旦某个矿工满足一定数量的零的某种模式,该区块将立即被广播并被其他矿工接受。

挖掘算法

挖掘算法包括以下步骤。

  • 从比特币网络中检索上一个哈希区块。

  • 将网络广播的一组潜在交易组合成一个区块。

  • 使用 SHA256 算法计算区块头部与一个随机数和上一个哈希的双哈希。

  • 如果结果哈希低于当前难度水平(目标),则停止该过程。

  • 如果结果哈希大于当前难度级别(目标),则通过增加 nonce 来重复该过程。随着比特币网络的哈希率增加,32 位 nonce 的总量耗尽得太快。为了解决这个问题,额外 nonce 解决方案被实施,即使用 coinbase 交易作为额外 nonce 的来源,以提供更大范围的 nonce 供矿工搜索。

  • 随着时间的推移,挖矿难度不断增加,现在需要专用的挖矿中心来解决哈希难题,曾经能够通过单个 CPU 笔记本电脑挖掘的比特币现在已经需要专用的挖矿中心来解决哈希难题。可以使用比特币命令行界面查询当前难度级别,命令如下:

 $ bitcoin-cli getdifficulty 
 258522748404.5154

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

随时间变化的挖矿难度

getdifficulty 命令返回的值。

哈希率

哈希率基本上表示每秒计算哈希的速率。在比特币早期,由于使用 CPU,哈希率非常低,但是现在,随着专用挖矿池和 ASIC 的出现,过去几年里呈指数增长。这导致了难度的增加。下面的哈希率图显示了随时间的变化而增加的哈希率,并且目前以 Exa 哈希来测量。这意味着在 1 秒钟内,比特币网络矿工正在计算超过 1 000 000 000 000 000 000 个哈希。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2017 年 6 月 2 日的哈希率,展示了两年的时间段

挖矿系统

随着时间的推移,比特币矿工们使用了各种方法来挖掘比特币。由于挖掘背后的核心原理是基于双 SHA256 算法,随着时间的推移,矿工们开发出了更快速计算哈希的复杂系统。以下是对比特币中使用的不同挖矿方法及其随时间演变的回顾。

CPU

CPU 挖矿是最初在原始比特币客户端中可用的一种挖矿类型。用户甚至可以使用笔记本或台式电脑来挖掘比特币。CPU 挖矿已不再盈利,现在更先进的挖矿方法,如基于 ASIC 的挖矿正在使用。

GPU

随着比特币网络的难度增加和寻找更快挖掘方法的一般趋势,矿工开始使用 PC 上可用的 GPU 或图形卡来进行挖掘。GPU 支持更快速和并行计算,通常使用 OpenCL 语言进行编程。这被证明是一个比 CPU 更快的选项。用户还使用了超频等技术来充分利用 GPU 的性能。此外,使用多个图形卡的可能性增加了图形卡用于比特币挖矿的流行度。然而,GPU 挖矿也有一些局限性,如过热和需要专用主板和额外硬件来容纳多个图形卡。

FPGA

即使 GPU 挖矿也没有持续多久,很快矿工们找到了另一种使用 FPGAs 进行挖矿的方法。Field Programmable Gate ArrayFPGA)基本上是一个可以编程执行特定操作的集成电路。FPGAs 通常使用硬件描述语言HDLs)进行编程,如 Verilog 和 VHDL。双 SHA256 很快成为 FPGA 程序员的吸引人的编程任务,并出现了几个开源项目。与 GPU 相比,FPGA 提供了更好的性能;然而,可访问性、编程难度以及需要专门的知识来编程和配置 FPGA 等问题导致了比特币挖矿 FPGA 时代的短期。此外,ASIC 的出现迅速取代了基于 FPGA 的挖矿系统。在 FPGA 挖矿盈利期间开发了如 X6500 矿工、Ztex 和 Icarus 等挖矿硬件。各种 FPGA 制造商,如赛灵思和阿尔特拉,都生产可以用于编程挖矿算法的 FPGA 硬件和开发板。

ASICs

Application Specific Integrated CircuitASIC),是设计用来执行 SHA-256 操作的。这些特殊的芯片由各种制造商出售,提供了非常高的散列率。这在一段时间内是有效的,但由于挖矿难度迅速增加,单个 ASIC 不再盈利。

目前,挖矿已经超出了个人的能力范围,现在专业的矿业中心利用数千个 ASIC 单元并行提供矿业合同给用户,代表用户进行挖矿。这里没有技术限制,这就是为什么单个用户无法并行运行数千个 ASIC,但将需要专用数据中心和硬件,单个个人的成本可能会变得不可行。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

四种类型的挖矿(CPU、GPU、FPGA 和 ASIC)

挖矿矿池

矿池在一群矿工共同工作以挖掘一个区块时形成。如果成功挖掘了区块,矿池管理者将接收 coinbase 交易,然后负责向投入资源以挖掘该区块的矿工群体分配奖励。与单独挖矿相比,这是有利可图的,因为在矿池中,无论他们(更具体地说,他们的个体节点)是否解决了谜题,奖励都会支付给矿池的每个成员。

挖矿池管理者可以采用各种模式向矿工支付报酬,如按份计费模式和比例模式。在按份计费模式中,挖矿池管理者向所有参与挖矿的矿工支付固定费用,而在比例模式中,份额是根据用于解决哈希谜题的计算资源量来计算的。

现在存在许多商业矿池,并通过云端和易于使用的网络界面提供挖矿服务合同。最常用的是安特池(AntPool)、F2PoolBW.COM。以下图片显示了所有主要矿池的哈希功率的比较:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

截至 2017 年 6 月 2 日,挖矿池及其哈希功率(哈希率)情况,取自 https://blockchain.info/pools

挖矿集中化是一个重要问题,如果一个矿池成功控制了比特币网络超过 51%的网络,即生成了超过 51%的哈希率,这可能会发生。正如前文所述,在介绍部分中,51%攻击可能导致双重支付攻击,这可能会影响共识,并实际上在比特币网络上强加另一个版本的交易历史。

比特币历史上曾经发生过这样的情况,即一个大型矿池 GHash.IO 成功获得了超过 51%的网络容量。学术界已经提出了理论解决方案,比如双重工作证明,以防止大型矿池的出现。该方案引入了第二个密码谜题,导致挖矿池透露其私钥或提供其挖矿池的相当部分哈希率,从而降低了挖矿池的总哈希率。

不同类型的硬件目前都可以在商业市场上用于挖矿。目前最赚钱的是 ASIC 挖矿,许多供应商提供专用硬件。除非花费大量资金和能源来建造自己的挖矿设备甚至中心,否则独立挖矿现在不太赚钱。根据当前的难度因子(2016 年 10 月),如果用户设法产生 12 TH/s 的哈希率,他们可以希望每天赚取 0.01366887 BTC(约 8 美元),这与购买可以产生 12 TH/s 哈希率的设备所需的投资相比非常低。考虑到电费等运营成本,这并不是非常有利可图。

比特币网络

比特币网络是一个 P2P 网络,节点之间交换交易和区块。网络上有不同类型的节点。主要有两种类型的节点,完整节点和 SPV 节点。完整节点如其名所示,是比特币核心客户端的实现,执行钱包、矿工、完整的区块链存储和网络路由功能。然而,并不需要执行所有这些功能。SPV 节点或轻量级客户端仅执行钱包和网络路由功能。比特币协议的最新版本是 70014,是通过比特币核心客户端 0.13.0 引入的。

一些节点只愿意成为完整的区块链节点,包含完整的区块链并执行网络路由功能,但不进行挖矿或存储私钥(钱包功能)。另一种类型是独立挖矿节点,它可以进行挖矿、存储完整的区块链,并充当比特币网络路由节点。

有一些非标准但被广泛使用的节点被称为池协议服务器。这些节点使用替代协议,如 Stratum 协议。一些节点仅执行挖矿功能,称为挖矿节点。只计算哈希的节点使用 Stratum 协议将其解决方案提交给矿池。可以在没有区块链的情况下运行 SPV 客户端,它运行钱包和网络路由功能。

互联网上的大多数协议都是基于行的,这意味着每一行都由回车和换行符 \r \n 分隔。Stratum 也是一种基于行的协议,它利用普通的 TCP 套接字和易读的 JSON-RPC 在节点之间进行操作和通信。

比特币网络通过其不同的魔法值进行识别。以下是一个列表:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比特币网络魔法值

魔法值用于指示消息的来源网络。

完整节点执行四个功能:钱包、矿工、区块链和网络路由节点。

当比特币核心节点启动时,首先会初始化发现所有对等节点。这是通过查询硬编码到比特币核心客户端中并由比特币社区成员维护的 DNS 种子来实现的。此查找返回多个 DNS A 记录。比特币协议默认在 TCP 端口 8333 上运行于主网络,TCP 18333 上运行于测试网络。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

chainparams.cpp 中的 DNSSeeds

首先,客户端发送一个包含各种字段的协议消息 Version,如版本、服务、时间戳、网络地址、随机数和一些其他字段。远程节点响应其自己的版本消息,然后两个节点之间进行 verack 消息交换,表示连接已建立。

然后,G etaddraddr 消息交换以查找客户端不知道的对等节点。同时,任一节点都可以发送一个 ping 消息来查看连接是否仍然活动。

现在可以开始区块下载。如果节点已经完全同步了所有区块,那么它会使用 Inv 协议消息监听新区块;否则,它首先检查是否对 inv 消息有响应并且已经有了存货。如果有,那么它使用 Getdata 协议消息请求区块;如果没有,那么它使用 GetBlocks 消息请求存货。这种方法一直被使用直到版本 0.9.3。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

协议可视化节点发现

初始区块下载可以使用区块优先或标题优先的方法来同步区块,具体取决于比特币核心客户端的版本。区块优先方法非常慢,在版本 0.10.0 之后被停止使用。

自版本 0.10.0 以来,引入了名为标题优先的初始区块下载方法。这导致了主要的性能改进,原本需要数天才能完成的区块链同步现在只需要几个小时。其核心思想是,新节点首先向对等方请求区块头并验证它们。一旦完成,就可以从所有可用的对等方并行请求区块,因为完整链的蓝图已经以区块头链的形式下载。

在此方法中,当客户端启动时,它会检查区块链是否已完全同步,如果标题链已经同步,则会从其他对等方请求标题,如果没有,则会请求其他对等方的头部链。区块链已经完全同步,则通过 Inv 消息监听新区块,如果已经完全同步了头部链,则使用 Getdata 协议消息请求区块。节点还会检查标题链是否比区块多,然后通过发出 Getdata 协议消息请求区块。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比特币核心客户端 >= 0.10.0 标题和区块同步,IBD = 初始区块下载和同步节点指的是从该节点请求区块的节点

Getblockchaininfogetpeerinfo RPCs 更新了新功能以适应这一变化。一个名为 getchaintips 的 RPC 用于列出区块链的所有已知分支。这也包括仅包含标题的区块。Getblockchaininfo 用于提供有关当前区块链状态的信息。Getpeerinfo 用于列出对等方之间共有的区块数和标题数。

Wireshark 也可以用于可视化对等方之间的消息交换,并且可以作为学习比特币协议的宝贵工具。这里展示了一个示例。这是一个基本示例,显示了版本、verack、getaddr、ping、addr 和 inv 消息。

在详细信息中,可以看到诸如数据包类型、命令名称和协议消息结果等有价值的信息。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Wireshark 中的样本块消息

此处显示了两个对等方之间数据流动的协议图。 这可以帮助您了解节点何时启动以及使用了什么类型的消息。

在以下示例中,比特币解析器被用来分析流量并识别比特币协议命令。

在以下示例中,可以看到消息的交换,如versiongetaddrgetdata,以及描述消息名称的适当注释。 这个练习对于学习比特币可能非常有用,建议在比特币测试网络上进行实验,可以在该网络上发送各种消息和交易,然后通过 Wireshark 进行分析。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

总共有 27 种协议消息,但随着协议的增长,它们很可能会增加。 最常用的协议消息及其解释如下:

  • Version: 这是节点向网络发送的第一个消息,宣传其版本和块计数。 然后,远程节点以相同的信息回复,连接随后建立。

  • Verack: 这是版本消息的响应,接受连接请求。

  • Inv: 节点使用此消息广告其对块和交易的了解。

  • Getdata: 这是对 inv 的响应,请求由其哈希标识的单个块或交易。

  • Getblocks: 这返回一个包含自上一个已知哈希或 500 个块之后的所有块列表的inv数据包。

  • Getheaders: 这用于请求指定范围内的块头。

  • Tx: 这用于作为对 getdata 协议消息的响应发送交易。

  • Block: 这是对getdata协议消息的响应,发送一个块。

  • Headers: 此数据包作为对 getheaders 请求的回复返回高达 2000 个块头。

  • Getaddr: 这作为获取已知对等方信息的请求发送。

  • Addr: 这提供有关网络上节点的信息。 它包含地址数量和地址列表,格式为 IP 地址和端口号。

  • 完整客户端和 SPV 客户端: 完整客户端是下载整个区块链的厚客户端或完整节点; 这是作为客户端验证区块链最安全的方法。 比特币网络节点可以以两种基本模式运行:完整客户端或轻量级 SPV 客户端。 SPV 客户端用于验证支付而无需下载完整的区块链。 SPV 节点仅保留当前有效最长区块链的块头副本。 验证是通过查看将交易链接到交易被接受的原始块的默克尔分支来执行的。 这不太实用,需要更实用的方法,该方法已使用 BIP37 实施,其中使用了布隆过滤器仅过滤出相关交易。

  • 布隆过滤器:布隆过滤器基本上是一种数据结构(带有索引的位向量),用于以概率方式测试元素的成员资格。它基本上提供了具有误报但没有误报的概率查询。元素被添加到布隆过滤器后,通过对它们进行多次哈希,然后将相应的位设置为 1 来设置位向量中的相应索引。为了检查元素在布隆过滤器中的存在,应用相同的哈希函数并将其与位向量中的位进行比较,以查看是否将相同的位设置为 1。并非每个哈希函数(例如 SHA1)都适用于布隆过滤器,因为它们需要快速、独立和均匀分布。布隆过滤器最常用的哈希函数是 fnv、mumur 和 Jenkins。

这些过滤器主要由简单支付验证(SPV)客户端使用,以请求交易和他们感兴趣的默克尔块。默克尔块是区块的轻量级版本,其中包括区块头、一些哈希、1 位标志位列表和交易计数。然后可以使用这些信息构建默克尔树。这通过创建一个仅匹配 SPV 客户端请求的交易和块的过滤器来实现。一旦版本消息被交换并且节点之间建立了连接,节点就可以根据自己的需求设置过滤器。这些概率过滤器根据设置的精确程度或宽松程度提供不同程度的隐私或精度。严格的布隆过滤器只会过滤节点请求的交易,但会以泄露用户地址的可能性为代价,对手可能会将交易与他们的 IP 地址相关联,从而损害隐私。另一方面,宽松设置的过滤器可能导致检索更多不相关的交易,但会提供更多的隐私。此外,对于 SPV 客户端,布隆过滤器允许它们使用低带宽,而不是下载所有交易进行验证。

  • BIP 37 提出了比特币布隆过滤器的实现,并向比特币协议引入了三个新消息。

  • Filterload: 这用于在连接上设置布隆过滤器。

  • Filteradd: 这将新的数据元素添加到当前过滤器中。

  • FilterClear: 这会删除当前加载的过滤器。

更多细节可以在 BIP37 规范中找到。

钱包

钱包软件用于存储私钥或公钥和比特币地址。它执行各种功能,例如接收和发送比特币。现在,软件通常提供两种功能:比特币客户端和钱包。在磁盘上,比特币核心客户端钱包存储为伯克利数据库文件:

:~/.bitcoin$ file wallet.dat

wallet.dat: 伯克利数据库(B 树,版本 9,本机字节顺序)

私钥可以以不同的方式生成,并由不同类型的钱包使用。钱包不存储任何硬币,也没有钱包为用户存储余额或硬币的概念。事实上,在比特币网络中,硬币并不存在;相反,只有交易信息存储在区块链上(更确切地说,是 UTXO,未花费的输出),然后用于计算比特币的数量。

钱包类型

在比特币中,有不同类型的钱包可以用来存储私钥。作为软件程序,它们还为用户提供一些功能,以在比特币网络上管理和执行交易。

非确定性钱包

这些钱包包含随机生成的私钥,也称为一堆键钱包。比特币核心客户端在首次启动时生成一些密钥,并在需要时生成密钥。管理大量密钥非常困难,一个错误的过程可能导致偷窃和硬币丢失。此外,有必要定期备份密钥并适当保护它们,以防止偷窃或丢失。

确定性钱包

在这种类型的钱包中,密钥通过哈希函数从种子值派生而来。这个种子号码是随机生成的,并且通常用人类可读的助记码词来表示。助记码词在 BIP39 中定义。这个短语可以用来恢复所有密钥,并使私钥管理相对容易。

分层确定性钱包

在 BIP32 和 BIP44 中定义,HD 钱包将密钥存储在从种子派生的树结构中。种子生成父密钥(主密钥),用于生成子密钥,随后生成孙密钥。HD 钱包中的密钥生成不直接生成密钥;相反,它产生一些信息(私钥生成信息),可以用来生成一系列私钥。如果已知主私钥,HD 钱包中的私钥完整层次结构很容易恢复。正是因为这个属性,HD 钱包非常容易维护,并且非常便携。

大脑钱包

主私钥也可以从被记忆的密码的哈希派生出来。关键的想法是这个密码用于派生私钥,如果在 HD 钱包中使用,这可以导致从单个记忆的密码派生出的完整 HD 钱包。这被称为大脑钱包。这种方法容易受到密码猜测和暴力破解攻击,但是可以使用密钥延展等技术来减慢攻击者的进展。

纸质钱包

顾名思义,这是一个纸质钱包,上面打印了所需的密钥材料。它需要物理安全来存储。纸质钱包可以从各种服务提供商在线生成,例如bitcoinpaperwallet.com/www.bitaddress.org/

硬件钱包

另一种方法是使用防篡改设备来存储密钥。这种防篡改设备可以是定制的,或者随着 NFC 手机的出现,它也可以是 NFC 手机中的安全元素SE)。Trezor 和 Ledger 钱包(各种类型)是最常用的比特币硬件钱包。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Trezor 钱包

线上钱包

正如名称所示,线上钱包完全存储于网络上,并通常通过云服务提供。它们为用户提供一个网页界面,用以管理钱包并执行诸如支付和接收款项等多种功能。它们使用方便,但前提是用户需要信任线上钱包服务提供商。

移动钱包

如名称所示,移动钱包安装在移动设备上。它们可以提供各种支付方法,最显著的是能够使用智能手机相机快速扫描二维码并进行支付。移动钱包适用于 Android 平台和 iOS,例如 breadwallet、copay 和 Jaxx。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Jaxx 移动钱包

比特币支付

使用各种技术可以接受比特币作为支付。虽然比特币在许多司法管辖区内并未被认可为合法货币,但它越来越多地被许多在线商家和电子商务网站接受为支付方式。有许多方法可以让买家向接受比特币的商家支付。例如,在线商店中可以使用比特币商家解决方案,而在传统的实体商店中,可以使用销售点终端和其他专用硬件。顾客可以简单地扫描含有卖家支付 URI 的二维码,并通过移动设备进行支付。比特币 URI 允许用户通过点击链接或扫描二维码来进行支付。URI统一资源标识符)基本上是代表交易信息的字符串。它在 BIP21 中定义。二维码可以显示在销售终端附近。几乎所有的比特币钱包都支持这一功能。

商家可以使用以下截图来宣传他们可以接受比特币作为支付方式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比特币接受此处标志

各种支付解决方案,如 xbtterminal 和 34 字节比特币 POS 终端,均可商业购买。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

34 字节 POS 解决方案。

比特币支付处理器,由许多在线服务提供商提供,支持与电子商务网站集成。简单的互联网搜索可以揭示许多选项。

已经提出并最终确定了各种 BIP,以引入和规范化比特币支付。最值得注意的是,BIP70(安全支付协议)描述了商户和客户之间进行安全通信的协议。该协议使用 X.509 证书进行身份验证,并在 HTTP 和 HTTPS 上运行。该协议中有三条消息:PaymentRequest、Payment 和 PaymentACK。这一提议的关键特点是防范中间人攻击和安全的支付证明。中间人攻击可能导致这样一种情况:攻击者位于商户和买家之间,买家看起来似乎在与商户交谈,但实际上,“中间人”正在与买家而不是商户交互。这可能导致篡改商户的比特币地址以欺诈买家。

还有其他几个 BIP,比如 BIP71 和 BIP72,也已经被提出,以规范支付消息封装和 URI 方案,以支持 BIP70。

比特币闪电网络,是一个可扩展的链下即时支付解决方案,于 2016 年初推出,允许链下支付。该网络利用在区块链之外运行的支付通道。这使得比特币的速度和可扩展性更大。此论文可在lightning.network/获取,鼓励感兴趣的读者阅读论文,以了解这一发明背后的理论和基础。

比特币投资和买卖比特币

有许多在线交易所,用户可以在那里买卖比特币。这现在是互联网上的一个大生意,它提供比特币交易、差价合约、点差投丨注、保证金交易以及各种其他选择。交易员可以通过开设多头或空头头寸来购买比特币或交易,从而在比特币价格上涨或下跌时获利。还有其他一些功能,比如将比特币兑换成其他虚拟货币,也是可能的,许多在线比特币交易所提供了这个功能。还提供了高级市场数据、交易策略、图表和相关数据,以支持交易员。这里展示了CEX.IO的一个示例。其他交易所提供类似类型的服务。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比特币交易所 cex.io 的示例

下面的截图显示了交易所的订单簿,其中列出了所有的买单和卖单:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比特币交易所 cex.io 的订单簿示例

比特币安装

比特币核心客户端可从bitcoin.org/en/download下载安装。该软件适用于不同的架构和平台,从 x86 Windows 到 ARM Linux,如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

设置比特币节点

在此处显示了在 Ubuntu 上运行比特币核心安装的示例;对于其他平台,可以从www.bitcoin.org获取详细信息。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

步骤 2:

drequinox@drequinox-OP7010:~$ sudo apt-get update

根据需要的客户端,用户可以使用以下命令之一,或者同时发出两个命令:

sudo apt-get install bitcoind
sudo apt-get install bitcoin-qt
drequinox@drequinox-OP7010:~$ sudo apt-get install bitcoin-qt bitcoind
Reading package lists... Done
Building dependency tree
Reading state information... Done
.......

设置源代码

如果用户希望参与比特币代码或学习目的,可以下载并编译比特币源代码。可以使用 Git 下载比特币源代码:

$ sudo apt-get install git 
$ mkdir bcsource 
$ cd bcsource 
drequinox@drequinox-OP7010:~/bcsource $ git clone https://github.com/bitcoin/bitcoin.git 
Cloning into 'bitcoin'... 
remote: Counting objects: 78960, done. 
remote: Compressing objects: 100% (3/3), done. 
remote: Total 78960 (delta 0), reused 0 (delta 0), pack-reused 78957 
Receiving objects: 100% (78960/78960), 72.53 MiB | 1.85 MiB/s, done. 
Resolving deltas: 100% (57908/57908), done. 
Checking connectivity... done. 
drequinox@drequinox-OP7010:~/bcsource$

将目录更改为比特币:

drequinox@drequinox-OP7010:~/bcsource$ cd bitcoin

当前步骤完成后,代码可以编译:

drequinox@drequinox-OP7010:~/bcsource/bitcoin$ ./autogen.sh 
drequinox@drequinox-OP7010:~/bcsource/bitcoin$ ./configure.sh 
drequinox@drequinox-OP7010:~/bcsource/bitcoin$ make 
drequinox@drequinox-OP7010:~/bcsource/bitcoin$ sudo make install

设置 bitcoin.conf

bitcoin.conf文件是一个配置文件,被比特币核心客户端用来保存配置设置。所有 bitcoind 客户端的命令行选项(除了-conf开关)都可以在配置文件中设置,在 bitcoin-qt 或 bitcoind 启动时,将从该文件中获取配置信息。

在 Linux 系统中,通常可以在$HOME/.bitcoin/中找到,或者也可以在命令行中使用-conf=<file>开关指定给 bitcoind 核心客户端软件。

在测试网络中启动节点

如果您想要测试比特币网络并进行实验,可以以测试网络模式启动比特币节点。与现场网络相比,这是一个更快的网络,并且对于挖矿和交易有更宽松的规定。

可用于比特币测试网络的各种水龙头服务。一个例子是 Bitcoin TestNet sandbox,用户可以请求比特币支付到他们的测试网比特币地址。可以通过testnet.manu.backend.hamburg/访问。这对于在测试网络上进行交易实验非常有用。

启动测试网络的命令行如下:

bitcoind --testnet -daemon 
bitcoin-cli --testnet <command> 
bitcoin-qt --testnet

在 regtest 中启动节点

可以使用 regtest 模式(回归测试模式)创建用于测试的本地区块链。

可以使用以下命令启动 regtest 模式中的节点:

bitcoind -regtest -daemon 
Bitcoin server starting

可以使用以下命令生成区块:

bitcoin-cli -regtest generate 200

在 Linux 系统中,可以在.bitcoin/regtest目录下的debug.log中查看相关日志消息。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在生成区块后,可以通过以下方式查看余额:

drequinox@drequinox-OP7010:~/.bitcoin/regtest$ bitcoin-cli -regtest getbalance 
8750.00000000

可以使用以下命令停止节点:

drequinox@drequinox-OP7010:~/.bitcoin$ bitcoin-cli -regtest stop 
Bitcoin server stopping

在主网中启动节点

Bitcoind是可以作为守护程序运行的核心客户端软件,并提供 JSON RPC 接口。Bitcoin-cli是用于与守护程序交互的功能丰富的命令行工具;然后守护程序与区块链交互并执行各种功能。 Bitcoin-cli 仅调用 JSON-RPC 函数,不会在区块链上执行任何操作。

Bitcoin-qt是比特币核心客户端的图形用户界面。当钱包软件首次启动时,它会验证磁盘上的区块,然后启动并显示以下图形用户界面:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Bitcoin Core QT 客户端在安装后显示区块链未同步

验证过程不仅适用于比特币-qt 客户端;也可以由bitcoind客户端执行。

使用 bitcoin-cli 进行实验

Bitcoin-cli 是比特币核心客户端提供的命令行接口,并且可以使用比特币核心客户端提供的 RPC 接口执行各种功能。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

运行 bitcoin-cli getinfo 的示例;相同格式可用于调用其他命令

可以通过以下命令显示所有命令的列表:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Testnet bitcoin-cli,这只是输出的前几行,实际的输出有很多命令。

  • HTTP REST:从比特币核心客户端 0.10.0 开始,也提供了 HTTP REST 接口。默认情况下,它在与 JSON-RPC 相同的 TCP 端口 8332 上运行。

比特币编程和命令行界面

比特币编程现在非常丰富。比特币核心客户端提供了各种 JSON RPC 命令,可以用于构建原始交易,并通过自定义脚本或程序执行其他功能。此外,还提供了命令行工具 Bitcoin-cli,该工具利用 JSON-RPC 接口,并提供了丰富的工具集来处理比特币。

这些 API 也可以通过许多在线服务提供商以比特币 API 的形式获得,并提供简单的 HTTP REST 接口。比特币 API,比如blockchain.info和 bitpay、block.io 等,提供了大量选项以开发基于比特币的解决方案。

有许多用于比特币编程的库可用。下面显示了一个列表,如果您有兴趣,可以进一步探索这些库。

Libbitcoin:可在libbitcoin.dyne.org/找到,并提供功能强大的命令行实用工具和客户端。Pycoin:可在github.com/richardkiss/pycoin找到,是 Python 的库。

Bitcoinj:此库可在bitcoinj.github.io/上找到,并使用 Java 实现。

有许多在线比特币 API 可用;以下列出了最常用的 API:

bitcore.io/

bitcoinjs.org/

blockchain.info/api 所有 API 提供的功能几乎相同,很难选择哪个 API 最好。

比特币改进提案(BIPs)

这些文档用于建议或通知比特币社区提出的改进、设计问题,或者比特币生态系统某些方面的信息。有三种比特币改进提案,简称为 BIPs:

  • 标准 BIP:用于描述对比特币系统产生重大影响的主要更改,例如区块大小更改、网络协议更改或交易验证更改。

  • 流程 BIP:标准 BIP 和流程 BIP 的主要区别在于,标准 BIP 涵盖协议更改,而流程 BIP 通常涉及提议改变核心比特币协议之外的流程。这些只有在比特币用户之间达成共识后才会实施。

  • 信息性 BIP:通常用于仅建议或记录有关比特币生态系统的一些信息,例如设计问题。

摘要

本章介绍了比特币及相关概念。从一些与比特币相关的历史和基本定义开始。介绍了诸如密钥和地址以及公钥和私钥等概念。还讨论了比特币网络中的交易工作原理(以及脚本、操作码和交易类型等相关概念)。此外,还介绍了作为比特币网络基础的区块链。还介绍了与此相关的概念,如挖矿、工作证明、挖矿系统和钱包。最后,还提供了有关设置比特币客户端、使用 bitcoin-cli 以及介绍不同比特币网络的一些实用信息。在下一章中,将介绍替代货币及相关概念。

第五章:替代币

自比特币最初成功以来,许多替代货币项目已经启动。比特币于 2009 年发布,第一个替代币项目(名为 Namecoin)于 2011 年推出。在 2013 年和 2014 年,替代币市场呈指数级增长,并启动了许多不同类型的替代币项目。其中一些取得了成功,而许多则不受欢迎且未能成功。少数是一些短期出现的炒作和倾销骗局,但很快就消失了。对比特币的替代方法可以广泛分为两类,根据其开发的主要目的。如果主要目的是构建去中心化的区块链平台,则称为替代链;如果替代项目的唯一目的是引入新的虚拟货币,则称为替代币。替代区块链将在本书的后续章节中详细讨论。

本章主要专注于替代币(altcoins),其主要目的是引入一种新的虚拟货币(币),尽管部分内容也会介绍构建在比特币之上的替代协议,以提供各种服务。其中包括诸如 Namecoin 等概念,其主要目的是提供去中心化的命名和身份服务,而不是货币。

目前,截至 2016 年末,市场上有数百种替代币,并且它们具有一定的货币价值。许多这些替代项目直接是比特币源代码的分叉,尽管其中一些是从头开始编写的。一些替代币旨在解决比特币的局限,例如隐私问题。还有一些提供不同类型的挖矿、更改区块时间和分发方案。

按定义,另类币是在硬分叉的情况下生成的。如果比特币经历了一次硬分叉,那么另一个更老的链实际上被视为另一种币。然而,关于哪条链成为另类币并没有已经建立的规则。最近就发生了这样的情况,以太坊就出现了这种情况,一次硬分叉导致了一种新的货币ETC以太经典)的产生,除了现有的以太币ETH)。以太经典是旧链,以太是分叉后的新链。因为一次引发争议的硬分叉无法在许多方面令人满意。首先,它违背了去中心化的真正精神,因为以太坊基金会,一个中心实体,决定继续进行硬分叉,即使并非每个人都同意这一提议;其次,由于对硬分叉的分歧,它也分裂了用户社区。尽管从理论上讲,硬分叉会产生一种另类币,但由于即使改变引发了硬分叉,基础币的基本参数通常没有发生剧烈变化,它在所能提供的方面存在限制。通常它们保持不变。因此,最好要么从零开始编写一种新币,要么分叉比特币(或其他币种的源代码)以创建一个具有所需参数和功能的新货币。

另类币必须能够吸引新用户、交易和矿工,否则该货币将毫无价值。货币在虚拟货币领域获得其价值,主要是因为网络效应和社区接受能力。如果一种币无法吸引足够的用户,那么很快它就会被遗忘。可以通过提供初始数量的币来吸引用户,并且可以通过使用各种方法来实现。提供初始数量的另类币的方法如下所述:

  • 创建新区块链:另类币可以创建一个新的区块链并将币分配给初始矿工,但由于许多欺诈计划或炒作和倒腾计划,这种方法现在不受欢迎,初始矿工通过推出新币获利然后消失。

  • 销毁证明:为新另类币分配初始资金的另一种方法是销毁证明,也称为单向锚定或价格上限。通过这种方法,用户可以永久销毁与要认领的另类币数量成比例的一定数量的比特币。例如,如果销毁了 10 个比特币,那么另类币的价值就不会超过所销毁的比特币数量。这基本上意味着通过销毁比特币来将其转换为另类币。

  • 拥有权的证明:与永久销毁比特币不同,一种替代方法是证明用户拥有一定数量的比特币。这种拥有权的证明可以用于通过将另类币区块系到比特币区块来认领另类币。例如,这可以通过合并挖矿来实现,这样一来比特币矿工就可以在挖掘比特币的同时挖掘另类币区块,而不需要额外工作。

  • 挂钩侧链:侧链,顾名思义,是与比特币网络分开的区块链,但比特币可以转移到它们上面。替代币也可以转回比特币网络。这个概念被称为双向挂钩。

投资和交易这些替代币也是一项大生意,虽然规模不及比特币,但足以吸引新投资者和交易者,并为市场提供流动性。从 coinmarketcap.com 生成的图表显示了综合替代币市值如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这表明,在撰写本文时,综合替代币市值超过了 20 亿美元。

当前前十大币种的市值(截至 2016 年 10 月)如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据来源于 https://coinmarketcap.com/

替代币引入了各种因素和新概念。许多概念甚至在比特币之前就已经发明,但是随着比特币的出现,不仅首次引入了新概念,比如拜占庭将军问题的解决方案,而且以巧妙的方式使用了之前的概念,比如哈希现金和工作证明,并且备受瞩目。从那时起,随着替代币项目的推出,各种新技术和概念得以开发和推出。为了了解替代加密货币的当前格局,首先必须理解一些理论概念。在以下部分,向读者介绍了一些随替代币项目引入的新概念。

理论基础

在本节中,向读者介绍了过去几年引入不同替代币时开发的各种理论概念。

工作证明的替代方案

工作证明PoW)方案在加密货币背景下首次用于比特币,并作为一种机制,提供了保证矿工已经完成了所需数量的工作以找到一个区块。这反过来为区块链提供了去中心化、安全性和稳定性。此外,这也是比特币中提供去中心化分布式共识的主要手段。PoW 方案需要具有一个被称为进度自由的非常理想的属性,这基本上意味着消耗计算资源的奖励应该是随机的,并且与矿工所做的贡献成比例。在这种情况下,即使是那些计算能力相对较低的矿工也有一定机会赢得区块奖励。术语进度自由是由阿尔温德·纳拉扬等人在书籍比特币和加密货币技术中引入的。挖掘计算难题的其他要求包括可调整的难度和快速验证。可调整的难度确保了区块链上的挖矿难度目标能够根据增加的哈希功率和用户数量进行调节。快速验证是一种属性,意味着挖掘计算难题应该易于验证且快速。 PoW 方案的另一个方面,特别是比特币中使用的方案(双 SHA-256),是自 ASIC 推出以来,算力正在向那些能够负担得起大规模 ASIC 矿场运营的矿工或矿池倾斜,这挑战了比特币去中心化的核心理念。

有一些替代方案被提出,例如抗 ASIC 谜题,设计得这样一种谜题,使得构建 ASIC 来解决这个谜题变得不可行,且不会比通用硬件带来重大的性能提升。用于此目的的一种常见技术是应用一类称为内存硬计算难题的计算难题。这种方法的核心思想是,由于解决谜题需要大量内存,因此在基于 ASIC 的系统上实现它是不可行的。这种技术最初在 Litecoin 和 Tenebrix 中使用,其中 Scrypt 哈希函数被用作 ASIC 抗性 PoW 方案。尽管最初将此方案宣传为抗 ASIC,但最近 Scrypt ASIC 现已推出,否定了 Litecoin 的原始声明。

抵抗 ASIC 的另一种方法是需要计算多个哈希函数以提供 PoW。这也称为链式哈希方案。这个想法背后的理念是,在 ASIC 上设计多个哈希函数是不太可行的。最常见的例子是 Dash 实现的 X11 内存硬函数。X11 由 11 个 SHA3 参与者组成,其中一个算法将计算的哈希输出到下一个算法,直到所有 11 个算法都按顺序使用。这些算法包括 blake、bmw、groestl、jh、keccak、skein、luffa、cubehash、shavite、simd 和 echo。

初始时,这种方法确实对 ASIC 的发展提供了一些抵抗,但现在 ASIC 矿工机已经商业化,并支持 X11 和类似方案的挖矿。最近的一个例子是 ASIC Baikal Miner,它支持 X11、X13、X14 和 X15 挖矿。其他例子包括矿工,如 iBeLink DM384M X11 矿工和 Pinidea X11 ASIC 矿工。

或许另一种方法可能是设计自变异难题,它可以智能地或随机地改变 PoW 方案或其要求,作为时间函数。这将使其几乎不可能在 ASIC 中实现,因为每个功能都需要设计多个 ASIC,并且随机变化的方案几乎不可能在 ASIC 中处理。目前尚不清楚如何在实践中实现这一点。

PoW 有各种缺点,其中最大的缺点是能源消耗。据估计,到 2020 年,比特币矿工所消耗的总电力将相当于丹麦的电力消耗。这是巨大的,而且所有的能源在某种程度上都被浪费了;事实上,除了挖矿之外,没有提供任何有用的用途。环保主义者对这种情况提出了真正的担忧。

有人提出 PoW(工作量证明)难题可以设计成具有两个目的。首先,它们的主要目的是在共识机制中,其次是执行一些有用的科学计算。这样一来,这些方案不仅可以用于挖矿,而且还可以帮助潜在地解决其他科学问题。这种有用工作的证明最近由 Primecoin 实践,其中的要求是找到特殊的素数链,称为 Cunningham 链和双生链。由于素数分布的研究在物理等科学学科中具有特殊意义,通过挖掘 Primecoin,矿工不仅可以获得区块奖励,还可以帮助找到特殊的素数。

存储证明

又称为不可检索性证明,这是另一种需要存储大量数据的有用工作证明类型。由微软研究引入,此方案提供了分布式存储归档数据的有用好处。矿工需要存储大数据的伪随机选择子集以执行挖矿。

权益证明

这个证明也被称为虚拟挖矿。这是另一种挖矿难题,被提出作为传统 PoW 方案的替代方案。它首次在 2012 年 8 月的 PeerCoin 中提出。在这个方案中,用户需要证明拥有一定数量的货币(硬币),从而证明他们对硬币有一份利益。权益证明的最简单形式是,对于那些可以明确拥有更多数字货币的用户,挖矿相对容易。这种方案的好处是双重的;首先,相对于购买高端 ASIC 设备,获取大量数字货币相对困难,其次,它可以节省计算资源。已经提出了各种形式的权益证明,并且以下简要讨论。

硬币年龄证明

硬币的年龄是硬币上次被使用或持有的时间。这与通常的权益证明形式不同,后者会使拥有最高权益的用户挖矿变得更容易。在基于硬币年龄的方法中,每次挖掘一个区块时,硬币的年龄(硬币年龄)都会被重置。矿工会因为持有而不花费硬币而获得奖励一段时间。这个机制已经以一种创造性的方式与 PoW 结合在 Peercoin 中实现。挖矿难题(PoW)的难度与硬币年龄成反比,这意味着如果矿工使用硬币权益交易消耗了一些硬币年龄,那么 PoW 要求会减轻。

存款证明

这个方案的核心思想是,由矿工新铸造的区块在一定时间内无法使用。更确切地说,硬币在挖矿过程中被锁定一定数量的区块。该方案通过允许矿工以冻结一定数量的硬币一段时间的代价来执行挖矿。这是一种权益证明的类型。

燃烧证明

作为与计算能力的替代支出,实际上是销毁一定数量的比特币以获得等值的替代币的燃烧证明。在启动新的币项目时,这通常被用作提供公平的初始分配手段。这可以被认为是一种替代的挖矿方案,新币的价值来自于之前销毁了一定数量的币。

活动证明

这个方案是 PoW 和权益证明的混合体。在这个方案中,区块最初是通过 PoW 产生的,但然后每个区块会随机分配三个需要对其进行数字签名的利益相关者。后续区块的有效性取决于成功签署之前随机选择的区块。

不过,有一个可能存在的问题,即漠视问题,在这个问题中创建区块链分叉是微不足道的。这是可能的,因为在 PoW 中,挖矿需要适当的计算资源,而在 PoS 中则没有这样的要求;结果是,攻击者可以尝试在多条链上使用相同的代币进行挖矿。

非外包谜题

这个谜题背后的关键动机是为了对抗矿池的发展。正如之前所讨论的那样,矿池按照它们消耗的计算能力比例奖励所有参与者。然而,在这个模型中,矿池操作员是所有奖励都归属的中央权威,并且可以强制执行某些规则。而且,在这个模型中,所有矿工之间只相互信任,因为他们共同为了矿池经理获得奖励的共同目标而努力。非外包谜题是一种允许矿工为自己主张奖励的方案;因此,由于匿名矿工之间的固有不信任,矿池形成变得不太可能。

难度调整和重新定位算法

随着比特币和替代币的出现,另一个概念是调整难度的算法。在比特币中,难度目标简单地通过以下方程计算;但是,其他硬币要么开发了自己的算法,要么实现了修改版的比特币难度算法:

T = (上一个时间 * 当前时间) / (2016 * 10 min)

比特币中难度调节的思想是,挖掘 2016 个区块大约需要 2 周时间(区块之间的时间应该大约为 10 分钟)。如果挖掘 2016 个区块花费的时间超过 2 周,则难度会减少;如果挖掘 2016 个区块的时间少于两周,则难度会增加。当 ASIC 矿机的速率因高区块生成速度而增长时,难度会呈指数增加,这是 PoW 算法的一个缺点,不具备 ASIC 抗性。这导致了挖矿算力的集中。这也带来了另一个问题;如果一个新币现在以与比特币的 SHA256 算法相同的工作量证明开始,那么一个恶意用户可以轻而易举地使用 ASIC 矿机并控制整个网络。如果对新替代币没有足够的兴趣且有人决定通过使用充足的计算资源来接管网络,这种攻击可能会变得更加可行。如果其他具有类似计算能力的矿工也加入到替代币网络中,这可能就不再是一个可行的攻击,因为矿工们会互相竞争。此外,多重矿池带来更大的威胁,因为一组矿工可以自动切换到变得有利可图的货币。这种现象被称为矿池跳跃,可以对区块链产生不利影响,从而影响替代币的增长。矿池跳跃对网络造成不利影响,因为矿池跳跃者只会在难度较低并且可以快速获得奖励时加入网络;一旦难度上升(或重新调整),他们就会跳出,然后在难度重新调整后再次加入。例如,如果一个多重矿池迅速耗尽资源挖掘一种新币,难度会迅速增加;当多重矿池离开货币网络时,它几乎无法使用,因为现在难度已经增加到一个水平,对于独立矿工来说不再有利可图,也无法维持。这个问题的唯一解决方法是发起一个硬分叉,但这通常对社区是不可取的。

有一些算法已经出现来解决这个问题,并在后面进行了讨论。所有这些算法都是基于根据哈希率变化重新调整各种参数的想法;这些参数包括先前区块的数量、先前区块的难度、调整比例以及可以重新调整难度的数量。在接下来的部分,读者将介绍一些正在使用和提出给各种替代币的难度算法。

木本重力井

此算法用于各种替代币中以调节难度。这最初是在 Megacoin 中首次引入的,并用于每个区块自适应地调整网络的难度。该算法的逻辑如下所示:

KGW = 1 + (0.7084 * pow((double(PastBlocksMass)/double(144)), -1.228))

基本上,该算法在一个循环中运行,遍历一组预定的块(PastBlockMass)并计算一个新的重新调整值。该算法背后的核心思想是开发一种自适应难度调节机制,以响应哈希率的急剧波动。Kimoto Gravity Well (KGW) 确保区块之间的时间保持大致相同。在比特币中,难度每 2016 个块调整一次,但在 KGW 中,难度每个区块都会调整。

这种算法容易受到时间扭曲攻击的影响,这允许攻击者暂时享受较低的难度来创建新的区块。这种攻击会在一个时间窗口内使难度降低,攻击者可以轻松地以快速的速度生成许多硬币。

暗重力波

暗重力波 (DGW) 是一种新的算法,旨在解决 KGW 算法中的某些缺陷,如时间扭曲攻击。这最初是在之前被称为 Darkcoin 的 Dash 中引入的。它利用多个指数移动平均和简单移动平均来实现更平滑的重新调整机制。该公式如下所示:

2222222/ (((难度+2600)/9)²)

这个公式是在 Dash 币和其他各种替代币中实现的一种调整难度的机制。

DGW 3.0 版是该算法的最新实现,与 KGW 相比,它允许改进的难度重新调整。

数字盾

这是另一种最近在 Zcash 中使用的调整难度算法,经过了适当的实验,并且有些微的变化。该算法通过遍历固定数量的先前区块来计算它们生成所需的时间,然后通过将实际时间跨度除以目标时间的平均值来重新调整难度到上一个区块的难度。在这个方案中,重新调整速度要快得多,而且对于哈希率的突然增加或减少的恢复也很快。这种算法可以防止多池,它可以导致哈希率的快速增加。网络难度根据实现的方式每个区块或每分钟重新调整一次。关键的创新是比 KGW 更快的重新调整时间。

MIDAS

多间隔难度调整系统 (MIDAS) 是一个相对于先前讨论的算法更为复杂的算法。这种方法对哈希率的突然变化反应更快。该算法还提供了对时间扭曲攻击的保护。

许多货币的出现是为了解决比特币的各种限制。以下简要讨论了比特币的限制。

比特币的限制

比特币的各种限制也引发了对替代币的兴趣,这些替代币专门开发来解决比特币的限制。最突出和广泛讨论的限制是比特币的匿名性缺乏。以下详细讨论了这个限制。

隐私和匿名性

由于区块链是所有交易的公开账本,并且是公开可用的,因此分析它变得非常容易。结合交易分析,可以将交易追溯到其源 IP 地址,从而可能揭示交易的发起者。这是从隐私的角度来看一个很大的问题。尽管在比特币中,为每笔交易生成一个新地址是一种推荐和常见的做法,从而允许一定程度的不可链接性,但这还不够,已经开发并成功使用各种技术来追踪整个网络中的交易流动,并将其追溯到其发起者。研究人员已经使用各种分析区块链的方法,如交易图、地址图和实体图,将用户与交易联系起来,从而引起了隐私问题。上述分析技术可以通过使用关于交易的公开可用信息并将其与实际用户联系起来进一步丰富。有开源区块解析器可用,可以从区块链数据库中提取交易信息、余额和脚本。一个可在 github.com/mikispag/rusty-blockparser 上找到的解析器是用 Rust 编写的,提供了先进的区块链分析功能。这项工作的早期版本称为 BitIodine,但已不再积极开发。

已经提出了各种提议来解决比特币的隐私问题。这些提议分为三类:混合协议、第三方混合网络和固有匿名性。对每个类别的简要讨论如下。

混合协议

这些方案用于为比特币交易提供匿名性。在这个模型中,使用混合服务提供商(中间人或共享钱包)。用户将硬币存入这个共享钱包作为押金,然后共享钱包可以将其他一些硬币(由其他用户存入的相同价值的硬币)发送到目的地。用户还可以通过这个中间人接收其他人发送的硬币。这样,输出和输入之间的链接就不复存在,交易图分析将无法揭示发送者和接收者之间的真实关系。

CoinJoin 是混合协议的一个例子,其中两个交易被合并成一个单一的交易,同时保持输入和输出不变。CoinJoin 背后的核心思想是构建一个由所有参与者签名的共享交易。这种技术提高了所有参与交易的参与者的隐私:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

CoinJoin 交易,三个用户将他们的交易合并成一个更大的 CoinJoin 交易

第三方混合协议

有各种第三方混合服务可用,但如果服务是集中的,那么它存在跟踪发送者和接收者之间映射的风险,因为混合服务了解所有输入和输出。除此之外,完全集中化的矿工甚至会造成服务管理员窃取比特币的风险。

有各种各样复杂程度的服务可用,比如 CoinShuffle、Coinmux 以及 Dash(coin)中的 dark send,它们都是基于 CoinJoin(混合)交易的想法。 CoinShuffle 是传统混合服务的分散替代品,因为它不需要信任的第三方。

基于 CoinJoin 的方案,然而,存在一些弱点,其中最突出的是可能出现的拒绝服务攻击,因为最初承诺签署交易的用户现在没有提供他们的签名,从而延迟或停止联合交易。

内在的匿名性

该类别包括天生支持隐私并内置在货币设计中的货币。最流行的是 Zcash,这在本章后面将详细讨论。其他示例包括 Monero,它利用环签名提供匿名服务。

下一节将介绍已实施或拟议的各种增强措施,以扩展比特币协议。

比特币上的扩展协议

已经提出并实施了几个协议,以增强并扩展比特币协议,并用于各种其他用途,而不仅仅是作为一种虚拟货币。

彩色比特币

彩色比特币是一组已开发出来的方法,用于在比特币区块链上表示数字资产。彩色比特币口语上指更新带有表示数字资产(智能财产)的一些元数据的比特币。该比特币仍然像比特币一样运作,但另外携带了一些表示某些资产的元数据。这种机制允许发行和追踪特定的比特币。如有必要,可以使用比特币的OP_RETURN操作码记录元数据,或者选择在多重签名地址中。如果需要,这些元数据也可以加密以解决任何隐私问题。彩色比特币可以用来代表各种资产,包括但不限于商品、证书、股票、债券和投票。还应该注意,为了使用彩色比特币,需要一个解释彩色比特币的钱包,普通的比特币钱包将无法正常工作。可以使用www.coinprism.com/提供的服务在线设置彩色比特币钱包。使用这项服务,可以创建和发行各种类型的数字资产通过彩色比特币。

彩色币的理念非常诱人,因为它不需要对现有的比特币协议进行任何修改,可以利用已经存在的安全比特币网络。除了传统的数字资产表示形式外,还有创建智能资产的可能性,它们可以根据其定义的参数和条件进行行为。这些参数包括时间验证、转让限制和费用。这开启了创建智能合约的可能性。

一个主要的用例可能是在区块链上发行金融工具。这将确保低交易费用,有效且数学上安全的所有权证明,无需中介即可进行快速转让,并且立即向投资者支付股息。

彩色币提供了丰富的 API,网址为coloredcoins.org/

Counterparty

这是另一个可以用来创建充当加密货币的自定义代币的服务,可用于各种用途,例如在比特币区块链上发行数字资产。这是一个非常强大的平台,它在比特币区块链的基础上运行,但发展了自己的客户端和其他组件以支持发行数字资产。体系结构包括 Counterparty 服务器、Counterblock、Counterwallet 和 Armory_utxsvr。Counterparty 基于彩色币的相同理念,通过向常规比特币交易嵌入数据来支持数字资产的处理,但提供了更丰富的库和强大的工具集来支持数字资产的处理。这种嵌入也被称为嵌入式共识,因为 Counterparty 交易嵌入到比特币交易中。嵌入数据的方法是使用比特币中的OP_RETURN操作码。

由 Counterparty 产生和使用的货币被称为 XCP,并且作为运行合约的费用。在撰写本文时,其价格为 2.78 美元。通过使用先前讨论的燃烧证明方法创建了 XCP。

Counterparty 允许使用 Solidity 语言在以太坊上开发智能合约,并与比特币区块链进行交互。为了实现这一点,使用 BTC Relay 作为在以太坊和比特币之间提供互操作性的手段。这是一个聪明的概念,以太坊合约可以通过 BTC Relay 与比特币区块链和交易进行通信。Relayer(运行 BTC Relay 的节点)获取比特币块头并将它们中继到以太坊网络上的智能合约,该合约验证 PoW。此过程验证了在比特币网络上发生了一笔交易。网址为btcrelay.org/

从技术角度来看,这基本上是一个以太坊合约,能够像比特币简单支付验证轻量级客户端一样存储和验证比特币区块头,它们使用布隆过滤器。SPV 客户端在上一章进行了详细讨论。这个概念可以通过下图进行可视化:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

BTC 中继概念

注意

Counterparty 可以在 counterparty.io/ 找到。

山寨币的发展

从编程角度来看,简单地通过分叉比特币或其他币种的源代码可以非常轻松地启动山寨币项目,但这可能还不够。当启动一个新的币种项目时,有若干事项需要考虑,以确保成功启动和币种的长期发展。通常,代码库是用 C++编写的,就像比特币一样,但几乎任何语言都可以用于开发币种项目,例如 Golang 或 Rust。

编写代码或对现有币种的代码进行分叉是相对简单的部分,具有挑战性的问题是如何启动一种新货币,以便吸引新的投资者和用户。通常,为了启动一个新的币种项目,会采取以下步骤。

从技术角度来看,如果是分叉其他币种的代码,例如比特币,可以更改各种参数以有效地创建一种新币。这些参数需要进行调整或引入以创建新币。这些参数可以包括但不限于以下内容。

共识算法

可以选择共识算法:工作量证明PoW),如比特币所用,或者权益证明PoS),如 Peercoin 所用。

哈希算法

这可能是 SHA256、Scrypt、X11、X13、X15,或者任何其他足够适合作为共识算法的哈希算法。

难度调整算法

在这个类别中有多种选项可以提供难度重定向机制。最显著的例子是 KGW、DGW、Nite’s Gravity Wave 和 DigiShield。此外,这些算法都可以根据需求进行调整以产生不同的结果;因此,可能会有许多变体。

区块间时间

这是生成每个区块之间的时间。在比特币中,区块每 10 分钟生成一次,在莱特币中则是每 2.5 分钟。可以使用任何值,但适当的值通常在几分钟之间;如果生成时间过快,可能会使区块链不稳定,如果过慢,则可能无法吸引太多用户。

区块奖励

区块奖励是给解决挖矿难题的矿工的,并允许他们拥有包含奖励的 Coinbase 交易。最初在比特币中这个奖励是 50 个币,现在许多山寨币将这一参数设定得非常高;例如,在狗狗币中,目前是 10,000 个。

奖励减半率

这是另一个重要因素;在比特币中,每 4 年减半一次,现在设置为 12.5 比特币。这是一个可变的数字,可以根据需求设置为任何时间段,或者根本不设置。

区块大小和交易大小

这是另一个重要因素,它决定了网络上的交易率可以有多高或有多低。比特币的区块大小限制为 1 MB,但在另类币中,它可以根据需求变化。

利率

此属性仅适用于 PoS 系统,在该系统中,持有者可以根据网络定义的利率,以持有在网络上作为 PoS 来保护网络的硬币数量获得利息。

币龄

此参数定义了硬币必须保持未使用多长时间,以使其有资格被视为可以进行投票的。

货币的总供应量

这个数字设定了可以生成的货币的总限制。例如,比特币的限制是 2100 万,而 Dogecoin 的限制是无限的。这个限制是由上面讨论的区块奖励和减半时间表确定的。

创建自己的虚拟货币有两种选择:分叉现有的已建立的加密货币源代码或从头开始编写一个新的。后者不太流行,但第一种选择更容易,并且在过去几年已经允许创建了许多虚拟货币。基本上,这个想法是首先分叉加密货币源代码,然后在源代码的不同战略位置进行适当的更改,从而有效地创建一个新的货币。

在下一节中,读者将介绍一些另类币项目。在本章节中不可能涵盖所有替代货币,但下面讨论了一些精选的货币。选择是基于其长期性、市值和创新。每个货币都从不同的角度进行讨论,如理论基础、交易和挖矿。

Namecoin

Namecoin 是比特币源代码的第一个分叉。Namecoin 背后的关键思想不是生产一种替代币,而是提供改进的去中心化、抗审查、隐私、安全性和更快的去中心化命名。去中心化命名服务旨在提供对互联网传统域名系统DNS)协议的固有限制的响应,例如传统的 DNS 协议在互联网上的使用的缓慢和集中控制。Namecoin 也是对之前章节中简要讨论的 Zooko 三角形的第一个解决方案。

Namecoin 主要用于提供注册键/值对的服务。Namecoin 的一个主要用途是,它可以提供一种由区块链驱动的去中心化传输层安全性TLS)证书验证机制,通过基于区块链的分布式和去中心化共识。

它基于与比特币引入的相同技术,但具有自己的区块链和钱包软件。Namecoin 核心的源代码可在github.com/namecoin/namecoin-core找到。

总之,Namecoin 提供以下三项服务:

  • 名称(密钥)的安全存储和转让

  • 通过将最多 520 字节的数据附加到名称上,赋予名称一些价值

  • 数字货币(Namecoin)的发行

Namecoin 还首次引入了合并挖矿,这使得矿工可以同时在多条链上进行挖矿。这个想法很简单但非常有效:矿工创建一个 Namecoin 区块并生成该区块的哈希。然后,该哈希被添加到比特币区块中,矿工解决该区块的难度等于或大于 Namecoin 区块的难度,以证明已经为解决 Namecoin 区块做出了足够的工作。

更准确地说,Coinbase 交易被用来包含来自 Namecoin(或任何其他代币)的交易哈希。挖矿任务是解决包含对 Namecoin(或任何其他代币)区块的哈希指针的比特币区块。这在下面的图表中显示。如果矿工成功解决比特币区块难度级别的哈希,比特币块就建成并成为比特币网络的一部分。在这种情况下,比特币区块链将忽略 Namecoin 哈希。另一方面,如果矿工在 Namecoin 区块链难度级别解决了一个区块,会在 Namecoin 区块链中创建一个新区块。这种方案的核心好处在于,矿工消耗的所有计算能力都有助于保护 Namecoin 和比特币:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

合并挖矿图表

交易 Namecoins

根据coinmarketcap.com/,Namecoin 的当前市值为£2,736,537,可以在各种交易所(如cryptonit.net/)购买和出售。通过简单的在线搜索可以找到其他各种交易所。

获取 Namecoins

尽管 Namecoins 可以独立挖矿,但通常作为比特币挖矿的一部分进行挖矿,利用上述合并挖矿技术。这样,Namecoin 可以作为比特币挖矿的副产品而被挖掘。独立挖矿已不再盈利,从下面的难度图表可以明显看出;因此建议进行合并挖矿,使用矿池,或甚至使用加密货币交易所购买 Namecoin。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Namecoin 难度显示在:https://bitinfocharts.com/comparison/difficulty-nmc.html

一些矿池(如slushpool.com)也提供合并挖矿的选项。这使得矿工可以主要挖掘比特币,同时也因此获得 Namecoin。

另一种快速获取一些 Namecoin 的方法是用现有的货币与 Namecoin 进行交换,例如,如果您已经拥有一些比特币或其他可用于与 Namecoin 交换的加密货币。有一个名为 shapeshift.io/ 的在线服务可提供此服务。该服务允许使用简单易用的界面从一种加密货币转换为另一种加密货币。

例如,支付 BTC 以接收 NMC 如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

点击 开始交易 后,交易开始并指示用户将比特币发送到特定的比特币地址。用户发送所需金额后,转换过程如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当进程完成时,可以在 Namecoin 钱包中查看交易记录:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

确认交易可能需要一些时间;在此期间,不可能使用 Namecoins 管理名称。一旦 Namecoins 在钱包中可用,可以使用 管理名称 选项来生成 Namecoin 记录。

生成 Namecoin 记录

Namecoin 记录以键值对的形式存在。名称是一个形如 d/examplename 的小写字符串,而值是一个区分大小写的、UTF-8 编码的 JSON 对象,最大长度为 520 字节。名称应符合 RFC1035 (tools.ietf.org/html/rfc1035) 标准。通用的 Namecoin 名称可以是一个任意的二进制字符串,最长为 255 字节,附带 1024 位的相关识别信息。Namecoin 链上的记录仅在大约 200 天或 36,000 个区块后有效,之后需要更新。Namecoin 还引入了可以使用 Namecoin 注册并可以使用专用的 Namecoin 启用解析器浏览的 .bit 顶级域。如下截图所示的 Namecoin 钱包软件可用于注册 .bit 域名。

输入名称,并在按下 提交 按钮后,将要求配置信息,如 DNS、IP 或身份:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如下截图所示,掌握区块链将在 Namecoin 区块链上注册为 masteringblockchain.bit

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Litecoin

Litecoin 是基于比特币源代码的一个分支,于 2011 年发布。它使用 Scrypt 作为 PoW,最初在 Tenebrix 币中引入。由于其更快的出块时间为 2.5 分钟,Litecoin 比比特币允许更快的交易。此外,由于更快的出块时间,大约每 3.5 天就会进行一次难度调整。总共发行 8400 万个硬币。

Scrypt 是一个顺序内存硬函数,是第一个替代 SHA-256 基础 PoW 算法的函数。它最初被提议作为基于密码的密钥派生函数 PBKDF。其关键思想是,如果函数需要大量内存来运行,那么定制硬件(如 ASIC)将需要更多的 VLSI 区域,这是不可行的。Scrypt 算法需要在内存中保存大量伪随机位,并以伪随机方式从中派生密钥。该算法基于一种称为 时间-内存折衷TMTO)的现象。如果内存需求放松,那么会导致增加计算成本。换句话说,如果给予更多内存,则 TMTO 会缩短程序的运行时间。这种折衷使得攻击者无法获得更多内存,因为这是昂贵且难以在定制硬件上实现的,或者如果攻击者选择不增加内存,则由于高处理要求而导致算法运行缓慢。

Scrypt 使用以下参数生成派生密钥(Kd):

  • 口令:这是一串要进行哈希的字符。

  • :这是提供给 Scrypt 函数(通常是所有哈希函数)的随机字符串,以抵御使用彩虹表的暴力字典攻击。

  • N:这是一个内存/CPU 成本参数,必须是大于 1 的 2 的幂。

  • P:并行化参数

  • R:块大小参数

  • dkLen:派生密钥的预期长度(以字节为单位)

形式上,此函数可写为:

Kd = scrypt (P, S, N, P, R, dkLen)

在应用核心 Scrypt 函数之前,算法以 PS 作为输入,并应用 PBKDF2 和基于 SHA-256 的 HMAC。然后,输出馈送到称为 ROMix 的算法,该算法内部使用 Blockmix 算法利用 Salsa20/8 核心流密码来填充需要大内存才能操作的内存,从而强制实施顺序内存硬性质。

从算法的这一步骤得到的输出最终再次馈送到 PBKDF2 函数中,以生成派生密钥。该过程如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Scrypt 算法

Scrypt 在 litecoin 挖矿中使用特定参数,其中 N= 1024,R = 1,P=1,而 S= 随机 80 字节产生一个 256 位的输出。

由于选择了这些参数,为莱特币挖矿开发 ASIC 并不是很困难。在用于莱特币挖矿的 ASIC 中,可以开发一个顺序逻辑,将数据和随机数作为输入,并应用PBKDF2算法与HMAC-SHA256;然后,生成的比特流被提供给SALSA20/8函数,该函数生成一个哈希值,再次输入到PBKDF2HMAC-256函数中生成 256 位哈希输出。与比特币 PoW 相同,在 Scrypt 中,如果输出哈希值小于目标哈希值(在开始时作为输入传递,存储在内存中,并在每次迭代中检查),则该函数终止;否则,随机数递增,进程再次重复,直到找到一个小于难度目标的哈希值:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Scrypt ASIC 设计简化流程图

  • 莱特币交易: 与其他数字货币一样,莱特币的交易很容易在各种在线交易所进行。莱特币当前的市值为£161,239,005。当前莱特币价格为£3.25/LTC。

  • 挖矿: 莱特币的挖矿可以独自进行,也可以在矿池中进行。目前,用于 Scrypt 算法的 ASIC 已经问世,通常用于挖掘莱特币。

与许多其他数字货币一样,莱特币在 CPU 上的挖矿已不再盈利。有在线云挖矿服务提供商和可用的 ASIC 矿机可用于挖掘莱特币。莱特币的挖矿从 CPU 开始,通过 GPU 挖矿设备的发展,最终现在已经达到了需要使用专业 ASIC 矿机才能挖矿的程度,例如来自 EhsMiner 的 Asic Scrypt Miner Wolf。一般来说,即使使用 ASIC,也最好在矿池中挖矿,而不是独自挖矿,因为矿池采用的比例奖励方案使得矿池挖矿比独自挖矿更有利可图。这些矿工可以在 Scrypt 算法上产生 2 Gh/s 的哈希率。

质数币

Primecoin 是市场上第一个引入有用 PoW(与比特币的基于 SHA256 的 PoW 相对)的数字货币。 Primecoin 使用搜索素数作为 PoW。 并非所有类型的素数都满足被选为 PoW 的要求。 三种类型的素数(称为第一类康宁汉链,第二类康宁汉链和双生链)符合 PoW 算法的要求,可用于加密货币中。 通过 Primecoin 区块链中的连续难度评估方案动态调整难度。基于素数的 PoW 的高效验证也非常重要,因为如果验证很慢,则 PoW 就不适合。 因此,选择素数链作为 PoW,因为随着链长度的增加,查找素数链变得困难,而验证仍然足够快,可以用作高效的 PoW 算法。 重要的是,一旦 PoW 在一个区块上被验证,就不能在另一个区块上被重复使用。 通过将工作证明证书与父块的标题进行哈希组合,在 Primecoin 中完成了这一点。 PoW 证书是通过将素数链链接到区块头哈希而生成的。 还要求区块头的原点可被区块头哈希整除。 如果可以,就进行除法,然后商用作 PoW 证书。 PoW 算法的可调节难度的另一个特性是每个区块都进行难度调整,而不是像比特币那样每 2,016 个区块进行一次。 这是一种与比特币相比更顺畅的方法,并且在哈希功率突然增加的情况下允许重新调整。 此外,生成的硬币总数由社区驱动,并且 Primecoin 能够生成的硬币数量没有具体限制。

交易 Primecoin

Primecoin 可以在主要虚拟货币交易所交易。 撰写时,Primecoin 的市值为£828,002。 它并非很大,但由于 Primecoin 基于一个新颖的想法,并且有一个专注的社区支持,因此仍继续保持一定的市场份额。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

挖矿指南

第一步是下载一个钱包。 Primecoin 支持钱包内的本地挖矿,就像原始比特币客户端一样,也可以通过各种在线挖矿服务提供商在云中挖矿。

以下是一个简短的 Windows 指南:

  1. 第一步是从以下地址下载 Primecoin 钱包:primecoin.io/index.php.

  2. 安装钱包并与网络同步后,可以通过以下步骤开始挖矿。 在 Primecoin 钱包中,可以通过单击帮助菜单并选择调试窗口菜单项来打开调试窗口。 通过在控制台窗口中键入help,还可以获得其他帮助:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    调试窗口用于启用 Primecoin 挖矿功能

  3. 一旦前述命令成功执行,挖矿将以独立模式开始。这可能并不十分有利,但挖矿者可以使用在线挖矿池:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    Primecoin 钱包软件,与网络同步

Primecoin 源代码可在 github.com/primecoin/primecoin 上获取。尽管 Primecoin 引入的 PoW 具有科学意义,但看起来没有活跃的开发正在进行以进一步开发 Primecoin。读者可以通过阅读 Sunny King(化名)的 Primecoin 白皮书进一步探索 Primecoin:primecoin.io/bin/primecoin-paper.pdf

Zcash

Zcash 在 2016 年 10 月 28 日推出。这是第一种使用特定类型的零知识证明(称为零知识简洁非交互式知识参数zk-SNARKs))为用户提供完全隐私的货币。这些证明非常短并且易于验证;然而,设置初始的公共参数是一个复杂的过程。后者包括两个密钥:证明密钥和验证密钥。该过程需要随机选择一些随机数以构建公共参数。问题在于这些随机数,也称为有毒废物,必须在参数生成后被销毁以防止 Zcash 的伪造。为此,Zcash 团队提出了一种多方计算协议,以从独立位置协作生成所需的公共参数,以确保有毒废物不会产生。由于所需的公共参数必须由 Zcash 团队创建,这意味着仪式的参与者是受信任的。这就是为什么仪式非常公开并采用多方计算机制进行的原因。该机制具有一个特性,那就是为了破坏最终参数,所有仪式参与者都必须被破坏。仪式完成后,所有参与者都会销毁用于私钥生成的设备。这一举动消除了设备上参与者私钥的任何痕迹。

zk-SNARKs 必须满足完整性、声音性、简洁性和非互动性的属性。完整性意味着存在一个明确的策略,使证明者能够使验证者相信一个断言是真实的。另一方面,声音性意味着没有证明者可以说服验证者一个假的陈述是真实的。简洁性意味着证明者和验证者之间传递的消息非常小。最后,非互动属性意味着可以在没有任何互动或非常少的互动的情况下验证断言的正确性。此外,作为零知识证明,还需要满足零知识的属性(在 第三章,密码学和技术基础中讨论)。

Zcash 开发人员引入了一个称为去中心化匿名支付方案DAP 方案)的概念,该方案用于 Zcash 网络以实现直接和私密支付。交易不会透露有关支付的来源、目的地和金额的任何信息。Zcash 中有两种类型的地址,z-addr 和 t-addr。Z 地址基于零知识证明并提供隐私保护,而 T 地址类似于比特币的地址。

Zcash 使用一种称为非对称 PoWEquihash)的高效 PoW 方案,它基于广义生日问题。它允许非常有效的验证。这是一个内存硬和 ASIC 抗性的函数。Zcash 引入了一个新颖的想法(初始缓慢挖矿),这意味着区块奖励会逐渐增加,直到达到第 20,000 个区块。这允许网络的初始扩展和早期矿工的实验,如果需要,Zcash 开发人员可以进行调整。初始缓慢启动对价格产生了影响,因为由于稀缺性,ZEC 在首日上涨到大约 25,000 美元。Zcash 实施了稍微修改过的 Digishield 难度调整算法。公式如下所示:

(下一个难度) = (上一个难度) x SQRT [ (150 秒) / (上一个求解时间) ]

Zcash 的各种属性快照(初始缓慢启动后)如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

交易 Zcash

Zcash 可以在主要数字货币交易所购买。在撰写时,Zcash 的价格非常高。如下图所示,价格一度飙升至每个 Zcash 约 10 比特币。一些交易所的订单甚至高达 2,500 BTC 每个 ZEC:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

挖掘指南

挖掘 Zcash 有多种方法。目前,可以进行 CPU 和 GPU 挖掘。各种商业云挖矿池也提供挖掘 Zcash 的合约。要使用 CPU 进行独立挖矿,可以按照以下步骤进行:

  1. 第一步是使用以下命令安装先决条件:

    sudo apt-get install \
    build-essential pkg-config libc6-dev m4 g++-multilib \
    autoconf libtool ncurses-dev unzip git python \
    zlib1g-dev wget bsdmainutils automake
    
    

    如果先决条件已安装,将显示消息指示组件已经是最新版本。如果尚未安装或版本旧于最新软件包,则安装将继续,将下载所需软件包,并完成安装。

  2. 接下来,运行命令从git克隆 Zcash,如下屏幕截图所示:

    $ git clone https://github.com/zcash/zcash.git
    
    

    此命令将在本地克隆 Zcash git 存储库。输出如下屏幕截图所示:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  3. 下一步是通过使用以下命令从屏幕截图中下载证明和验证密钥:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  4. 运行此命令后,将在~/.zcash-params/目录中下载约 911 MB 的密钥。该目录包含用于证明和验证密钥的文件:

    drequinox@drequinox-OP7010:~/.zcash-params$ pwd
    /home/drequinox/.zcash-params
    drequinox@drequinox-OP7010:~/.zcash-params$ ls -ltr
    -rw-rw-r-- 1 drequinox drequinox      1449 Oct 24 16:46 sprout-     
            verifying.key
    -rw-rw-r-- 1 drequinox drequinox 910173851 Oct 24 16:46 sprout-   
            proving.key
    
    
  5. 一旦上述命令成功完成,可以使用以下命令构建源代码:

    ./zcutil/build.sh -j$(nproc)
    
    

这将产生非常长的输出;如果一切顺利,它将生成一个zcashd二进制文件。请注意,此命令将nproc作为参数,nproc基本上是一个查找系统中核心或处理器数量并显示该数字的命令。如果您没有该命令,则用您系统中的处理器数量替换nproc

构建完成后,下一步是配置 Zcash。这可以通过在~/.zcash/目录中创建名为zcash.conf的配置文件来实现。

示例配置文件如下所示:

addnode=mainnet.z.cash 
rpcuser=drequinox 
rpcpassword=xxxxxxoJNo4o5c+F6E+J4P2C1D5izlzIKPZJhTzdW5A= 
gen=1 
genproclimit=8 
equihashsolver=tromp 

前述配置启用了各种功能。第一行添加了主网节点并启用了主网连接。rpcuserrpcpassword是 RPC 接口的用户名和密码。gen = 1用于启用挖矿。genproclimit是可用于挖矿的处理器数量。最后一行启用了更快的挖矿解算器;如果要使用标准 CPU 挖矿,则不需要此功能。

现在可以使用以下命令启动 Zcash:

./zcashd --daemon

一旦启动,这将允许通过 Zcash-cli 命令行界面与 RPC 接口交互。这几乎与比特币命令行界面相同。一旦 Zcash 守护进程运行起来,可以运行各种命令来查询 Zcash 的不同属性。可以通过 CLI 或区块链浏览器在本地查看交易。Zcash 的区块链浏览器位于:explorer.zcha.in/

地址生成

可以使用以下命令生成新的 Z 地址:

$:~/zcash/src$ ./zcash-cli z_getnewaddress
zcPDBKuuwHJ4gqT5Q59zAMXDHhFoihyTC1aLE5Kz4GwgUXfCBWG6SDr45SFLUsZhpcdvHt7nFmC3iQcn37rKBcVRa93DYrA

使用getinfo参数运行 Zcash-cli 命令会产生以下屏幕截图中显示的输出。它显示有关区块、难度和余额等有价值的信息:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

显示getinfo输出的屏幕截图

可以使用以下命令生成新的 T 地址:

drequinox@drequinox-OP7010:~/zcash/src$ ./zcash-cli getnewaddress
t1XRCGMAw36yPVCcxDUrxv2csAAuGdS8Nny

GPU 挖矿

除了 CPU 挖矿之外,还可以选择 GPU 挖矿。目前还没有官方的 GPU 矿工,但开源开发者已经制作出了各种概念证明和可工作的矿工。Zcash 公司举办了一场公开竞赛,鼓励开发者构建并提交 CPU 和 GPU 矿工。截至撰写时还没有宣布获胜者。读者可以访问zcashminers.org/参考更多信息。

还有另一种挖矿方式:使用各种在线云挖矿提供商提供的云挖矿合约。云挖矿服务商代表客户进行挖矿。除了云挖矿合约,矿工还可以使用自己的设备通过矿池使用 stratum 或其他协议进行挖矿。一个关键的示例是 nicehash 的 Zcash 矿池。通过这个矿池,矿工可以出售他们的算力。以下是在 Zcash 挖矿矿池上构建和使用 CPU 矿工的示例。

下载和编译 nheqminer

可以使用以下步骤在 Ubuntu Linux 系统上下载和编译nheqminer

sudo apt-get install cmake build-essential libboost-all-dev
git clone https://github.com/nicehash/nheqminer.git
cd nheqminer/nheqminer
mkdir build
cd build
cmake ..
make

当所有步骤都成功完成后,可以使用以下命令运行 nhequminer:

./nhequminer -l eu -u <btc address> -t <number of threads>

Windows 版本的 Nhequminer 可以在以下网址找到:github.com/nicehash/nheqminer/releases

Nheqminer 需要几个参数,如位置(-l),用户名(-u),以及用于挖矿的线程数(-t)。

以下是 Windows 版本 Zcash 矿工的运行示例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用比特币地址接收出售算力的支付

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用 Zcash T 地址接收出售算力的支付

这完成了对 Zcash 的介绍;读者可以在网上了解更多关于 Zcash 的信息,因为现在它的波动性很大,事情可能会发生很快。有一件事是肯定的;Zcash 的零知识证明是一个重大的创新,并为未来需要固有隐私的应用程序铺平了道路,如银行业、医学或法律业。

摘要

本章介绍了整个加密货币领域的概况。详细讨论了一些替代币,特别是 Zcash 和 Namecoin。加密货币是一个非常活跃的研究领域,特别是在可扩展性、隐私和安全方面。也进行了一些研究,以发明新的难度重新调整算法,以阻止加密货币中央化的威胁。在隐私和特别是可扩展性领域可以进行进一步的研究。读者现在应该能够欣赏到替代币的概念及其背后的各种动机。还讨论了一些实际方面,如挖矿和启动新的货币项目,希望这些讨论将为读者打下坚实的基础,并使他们能够进一步探索这些领域。替代币是一个迷人的研究领域,为去中心化的未来打开了许多可能性。

第六章:智能合约

本章介绍了智能合约的概念。这并不是一个新概念,但随着区块链的发展,对这个概念的兴趣得到了重新激发,这现在是区块链领域中的一个活跃研究领域。由于智能合约可以通过减少交易成本和简化复杂合同给金融服务行业带来的节约成本而带来的益处,各种金融和学术机构正在进行严格的研究,以便尽快系统化并使智能合约的实施容易和实际。

历史

智能合约最初是由尼克·萨博在上世纪 90 年代末提出的,但真正意识到它们的潜力和好处还要等上 20 年。萨博描述智能合约如下:

“智能合约是一种计算机化的交易协议,执行合同条款。一般目标是满足常见的合同条件(如付款条款、留置权、机密性,甚至执行),最小化恶意和意外情况,并尽量减少对信任第三方的需求。相关的经济目标包括降低欺诈损失、仲裁和执行成本,以及其他交易成本。”

这种智能合约的理念在 2009 年以有限的方式应用于比特币中,比特币交易可用于在用户之间传输价值,在对等网络上用户不一定信任对方,也无需信任第三方。

定义

对于智能合约的标准定义并没有达成共识。定义智能合约的重要性是不言而喻的,以下是作者试图提供的智能合约的广义定义。

注意

智能合约是一种安全且不可阻挡的计算机程序,代表着一份自动可执行和可强制执行的协议。

进一步解析这个定义会发现,智能合约实际上是一种用计算机或目标机器可以理解的语言编写的计算机程序。此外,它包括以商业逻辑形式达成的各方协议。另一个关键观点是,在满足某些条件时,智能合约会自动执行。它们是可执行的,这意味着所有合同条款都按照定义和预期执行,即使存在对手方也是如此。执行是一个更广泛的术语,它包括以法律形式的传统执行,以及实施某些措施和控制,使得能够在不需要任何调解的情况下执行合同条款。应当注意,真正的智能合约不应依赖传统的执行方法。相反,它们应该遵循代码即法律的原则,这意味着没有必要由仲裁员或第三方控制或影响智能合约的执行。智能合约是自我执行的,而不是法律可执行的。这可能被视为自由主义者的梦想,但这是完全可能的,并且符合智能合约的真正精神。

此外,它们是安全的和不可阻挡的,这意味着这些计算机程序需要被设计成容错的,并在合理的时间内可执行。这些程序应该能够执行和维护健康的内部状态,即使外部因素不利也应如此。例如,想象一下一个正常的计算机程序,它编码了一些逻辑并根据其中编码的指令执行,但如果它运行的环境或者依赖的外部因素偏离了正常或预期的状态,该程序可能会以任意的方式作出反应或者简单地中止。重要的是智能合约对这种问题是免疫的。

安全和不可阻挡可能被认为是要求或理想特性,但从长远来看,如果安全性和不可阻挡性被纳入智能合约的定义,将会带来更大的好处。这将使研究人员能够从一开始就专注于这些方面,并有助于建立坚实的基础,以便进一步研究。一些研究人员还建议,智能合约不必自动执行;相反,它们可以是所谓的可自动化,因为在某些情况下需要手动人工输入。虽然在某些情况下人工输入和控制是可取的,但并非绝对必要;并且,在作者看来,要想合约真正智能,它必须是完全自动化的。某些需要人们提供的输入也可以和应该通过使用 Oracles 来自动化。后面将在本章中更详细地讨论 Oracles。

智能合约通常通过使用状态机模型来管理其内部状态进行操作。这使得可以开发一个有效的智能合约编程框架,在其中,合约的状态根据一些预定义的标准和条件进一步推进。

目前也正在围绕代码是否能在法庭上作为合同被接受进行讨论。这与传统法律文体的表现完全不同,尽管它们代表和执行了所有合同条款,但法庭并不理解代码。这引发了一些关于智能合约如何具有法律约束力的问题:是否可以开发一种方式,使其在法庭上能够被快速接受和理解?代码内又如何实施争议解决?此外,监管和合规要求是另一个需要在智能合约能够有效地像传统法律文书一样使用之前解决的主题。

上述问题打开了各种可能性,比如使智能合约代码不仅可以被机器理解,还可以被人理解。如果人类和机器都能理解智能合约中编写的代码,它可能在法律情况下更容易被接受,而不仅仅是程序员能理解的代码。这一理想的性质是一个需要研究的领域,已经在这一领域花费了大量的研究努力来回答关于合同的语义、意义和解释的问题。

智能合约固有地要求具有确定性。这一性质使得智能合约可以在网络上的任何节点上运行并获得相同的结果。如果不同节点之间的结果即使有微小差异,就无法达成共识,整个区块链上的分布式共识模式就会失败。此外,合约语言本身也应该是确定性的,以确保智能合约的完整性和稳定性。也就是说,确定性指的是,在语言中没使用可以在不同节点上产生不同结果的非确定性函数。例如,各种编程语言中由各种函数进行的浮点运算在不同的运行环境中可能会产生不同的结果。另一个例子是 JavaScript 中的一些数学函数,在不同浏览器上对于相同输入可能产生不同的结果,这可能导致各种错误。在智能合约中,这是极不可取的,因为如果节点之间的结果不一致,就永远无法达成共识。确定性特性可以确保智能合约总是对特定输入产生相同的输出。换句话说,一旦编译完成,程序就会产生一个与高级代码中编程的要求完全一致的坚实和准确的业务逻辑。

总之,智能合同具有以下四个属性:

  • 自动执行

  • 可强制执行

  • 语义上合理

  • 安全且不可阻止。

前两个属性至少是必需的,而后两个可能在某些情况下不需要或无法实现,并且可以放宽。例如,衍生品合同可能不需要语义上合理且不可阻止,但至少应该能够在基本水平上自动执行和可强制执行。另一方面,产权证书需要在语义上合理和完整,因此,为了将其实施为智能合同,语言必须被计算机和人理解。这个解释问题由伊恩·格里格在他发明里卡第安合同时解决了,我们将在下一节中更详细地讨论这个问题。

里卡第安合同

里卡第安合同最初是在 20 世纪 90 年代末由伊恩·格里格在《金融密码学七层》一文中提出的。这些合同最初在名为里卡多的债券交易和支付系统中使用。其关键思想是编写一个法院和计算机软件都能理解和接受的文档。里卡第安合同解决了通过互联网发行价值的挑战。它确定了发行人,并在文档中捕获了合同的所有条款和条款,以使其作为法律约束合同被接受。根据伊恩·格里格iang.org/papers/ricardian_contract.html中的原始定义,里卡第安合同是具有以下几个属性的文件:

  • 由发行人提供给持有人的合同

  • 由持有人持有的有价权利,并由发行人管理

  • 易于人们阅读(如纸质合同)

  • 可由程序阅读(可解析,如数据库)

  • 数字签名

  • 携带密钥和服务器信息

  • 与独特且安全的标识符相匹配

在实践中,合同是通过生成一份包含合同条款的法律文本和所需的机器可读标签的单一文档来实现的。该文档由发行人使用其私钥进行数字签名。然后,使用消息摘要函数对该文档进行散列,以产生一个可以识别文档的哈希。然后,此哈希在合同执行期间由各方进一步使用和签署,以链接每笔交易,因此标识哈希作为意图的证据。这在下面的图表中描述,通常称为蝴蝶结模型。

下图显示了左侧的法律世界,文档的来源就在这里。然后对其进行哈希处理,使用所得的消息摘要作为会计世界中的标识符。会计世界基本上可以代表业务中使用的任何或多个会计、交易和信息系统,用于执行各种业务操作。这个流程背后的思想是,通过对文档进行哈希处理生成的消息摘要首先在所谓的创世交易或第一笔交易中使用,然后在合同的运行执行过程中的每笔交易中都使用。

这样,原始书面合同与会计世界中的每笔交易之间就建立了安全链接。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

李嘉图合同,蝴蝶结图

李嘉图合同与智能合同有所不同,智能合同不包括任何合同文件,纯粹专注于合同的执行。另一方面,李嘉图合同更关注合同的语义丰富性和生成包含合同法律条文的文件。合同的语义可以分为两种类型:操作语义和指称语义。第一种类型定义了合同的实际执行、正确性和安全性,而后者关注合同整体的现实意义。一些研究人员区分了智能合同代码和智能法律合同,智能合同仅关注合同的执行,第二种类型涵盖了法律协议的指称和操作语义。或许基于语义差异对智能合同进行分类是有道理的,但更好的方式是将智能合同视为一个独立的实体,能够在其中编码法律条文和代码(业务逻辑)。

在比特币中,可以观察到一个非常简单的智能合同实现,完全专注于合同的执行,而李嘉图合同更倾向于生成一个人类可理解的文件,其中有一些部分是计算机程序可以理解的。这可以被视为法律语义与操作性能(语义与性能)的区别,如下图所示。这最初是由伊恩·格里格在他的论文关于李嘉图与智能合同的交汇中提出的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明性能与语义是伊恩·格里格描述的正交问题;稍作修改以显示两个轴上不同类型合同的示例。

智能合同由这两个元素(执行和语义)组成,这样就完成了智能合同的理想模型。

Ricardian 合约可以表示为三个对象的元组,即 Prose参数代码。 Prose 表示常规语言中的法律合同;代码表示程序,是对法律文言的计算机可理解表示;参数将法律合同的适当部分与相应的代码连接起来。

Ricardian contracts 已经在许多系统中实现,例如 CommonAccord、OpenBazaar、OpenAssets 和 Askemos。

智能合约模板

智能合约可以为任何需要的行业实现,但目前大多数用例与金融行业有关。智能合约领域最近的工作专注于金融行业,提出了智能合约模板的概念。这一想法是构建标准模板,为金融工具的法律协议提供支持框架。这是由 Clack 等 在他们的论文中提出的,论文名为 智能合约模板:基础、设计概况和研究方向。该论文还提出应该构建领域特定语言来支持智能合约模板的设计和实现。一种名为 CLACK 的语言,即用于增强合同知识的通用语言已经被提出,并且已经开始研发这种语言。这种语言旨在非常丰富,并提供各种功能,从支持法律文言到能够在多个平台上执行和进行密码功能。

金融业中的合同并不是一个新概念,各种领域特定语言 DSLs 已经在金融业中使用,为特定领域提供特定语言。例如,有可用的 DSL 支持保险产品的开发,代表能源衍生品,或用于构建交易策略。清单还在继续,可以在 www.dslfin.org/resources.html 找到金融领域特定语言的综合清单。

重要的是要理解领域特定语言的概念。这些语言是为特定应用程序或兴趣领域开发的,具有有限的表达能力。领域特定语言DSLs)与通用编程语言GPLs)不同:DSLs 具有一小组特性,足以满足并针对其用途进行了优化,并且与 GPLs 不同,通常不用于构建通用的大型应用程序。基于 DSL 的设计哲学,可以设想开发这样的语言,以编写智能合约。一些工作已经做过了,Solidity 就是一种这样的语言,它已经被引入到以太坊区块链中用于编写智能合约。Serpent 是另一种语言,尽管没有 Solidity 那么常用,但也已经被引入到以太坊中。

智能合约编程的领域特定语言的这一理念可以进一步扩展到图形领域特定语言,即智能合约建模平台,其中领域专家(而不是程序员)可以使用图形用户界面和画布来定义和绘制金融合约的语义和性能。一旦流程被绘制和完成,就可以首先模拟测试,然后从同一系统部署到目标平台,该平台可以是区块链。这也不是一个新概念,类似的方法在 Tibco streambase 产品中使用,该产品是用于构建事件驱动高频交易系统的基于 Java 的系统。

建议在开发高级 DSL 的领域进行研究,这些 DSL 可以用于在用户友好的图形用户界面中编写智能合约,从而允许非程序员设计智能合约。

Oracles

Oracles 是智能合约生态系统的重要组成部分。智能合约的局限性在于它们无法访问可能需要的外部数据来控制业务逻辑的执行;例如,合约需要股票价格来释放股息支付。Oracles 可以用于向智能合约提供外部数据。Oracle 是从外部来源向智能合约传递数据的接口。根据行业和要求,Oracles 可以提供不同类型的数据,范围从天气报告、现实世界新闻和企业行动到来自物联网设备的数据。Oracles 是受信任的实体,它们使用安全通道将数据传输到智能合约。

Oracles 还能够数字签名数据,证明数据来源是真实的。智能合约可以订阅 Oracles,智能合约可以拉取数据,或者 Oracles 可以将数据推送到智能合约。Oracles 不应该能够操纵他们提供的数据,必须能够提供真实的数据。尽管 Oracles 是受信任的,但在某些情况下,数据由于操纵可能仍然是不正确的。因此,Oracles 无法更改数据是必要的。可以使用后面在本章中讨论的各种公证方案来提供此验证。在这种方法中,可能已经可以看到一个问题,这在某些情况下可能是不可取的,那就是信任问题。如何信任第三方提供的数据的质量和真实性?在金融世界尤其如此,市场数据必须准确可靠。对于智能合约设计者接受由大型值得信赖的可信第三方提供的 Oracle 数据可能是可以接受的,但中心化的问题仍然存在。这些类型的 Oracles 可以称为标准或简单的 Oracles。

另一种类型的 Oracle,基本上是由于去中心化的要求而出现的,可以称为去中心化的 Oracle。这些类型的 Oracle 可以基于某些分布式机制构建。也可以设想,Oracle 可以从另一个由分布式共识驱动的区块链中获取数据,从而确保数据的真实性。例如,一个运行自己私有区块链的机构可以通过 Oracle 发布其数据源,然后被其他区块链所使用。

研究人员还引入了另一种硬件 Oracle 的概念,其中需要来自物理设备的实时数据。例如,这可以用于遥测和物联网。然而,这种方法需要一个硬件设备不能被篡改的机制。这可以通过使用防篡改设备来实现。

现在有平台可以使用 Oracle 让智能合约获取外部数据。根据所使用的区块链类型,Oracle 使用不同的方法将数据写入区块链。例如,在比特币区块链中,Oracle 可以通过OP_RETURN Opcode 将数据写入特定交易,智能合约可以监视该交易并读取数据。提供 Oracle 服务的各种在线服务,如www.oraclize.it/www.realitykeys.com/,以及提供外部数据和使用智能合约进行支付功能的另一个服务smartcontract.com/ 都是可用的。所有这些服务的目标都是使智能合约能够获取其执行和做出决策所需的数据。为了证明 Oracle 从外部源检索的数据的真实性,可以使用诸如 TLSnotary 的机制,它产生数据源和 Oracle 之间通信的证明。这确保了反馈给智能合约的数据绝对是从源头检索的。关于 TLSnotary 的更多细节可以在这里找到 tlsnotary.org/

以下图示展示了 Oracle 和智能合约生态系统的通用模型:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

与区块链上智能合约交互的 Oracle 的简化模型

智能 Oracle

Codius 中还提出并实现了智能 Oracle 的概念。智能 Oracle 基本上与 Oracle 一样,但具有合约代码执行的额外功能。Codius 提出的智能 Oracle 使用 Google Native Client 运行。这是一个用于运行不受信任的 x86 本地代码的沙箱环境。Codius 可以在 www.codius.org/ 找到。

在区块链上部署智能合约

智能合约可能部署在区块链上,也可能不部署在区块链上,但由于区块链提供的分布式共识机制,将它们部署在区块链上是有意义的。以太坊是原生支持智能合约开发和部署的区块链的一个例子。以太坊区块链上的智能合约通常是去中心化自治组织DAOs)的一部分。

作为比较,在比特币区块链中,比特币交易中的lock_time字段可以被视为基本版本的智能合约的一种实现。lock_time字段使交易在指定的时间或一定数量的区块之后被锁定,从而强制执行某种基本的合约,即只有在满足某些条件(经过的时间或区块数量)时才能解锁某笔交易。然而,这在性质上非常有限,应该只被视为基本智能合约的一个例子。除了上述例子之外,比特币脚本语言,尽管有限,也可以用于构建基本的智能合约。一个可能性是为一个可以由任何能够展示哈希冲突攻击的人花费比特币地址提供资金。这个想法是在 Bitcointalk 论坛上提出的,更多信息可以在bitcointalk.org/index.php?topic=293382.0找到。这也可以被认为是基本形式的智能合约。

DAO

DAO 是最高众筹项目之一,于 2016 年 4 月开始。基本上,这是一组智能合约,旨在提供一个投资平台。由于代码中的错误,这在 2016 年 6 月被黑客攻击,相当于 5000 万美元被转移到 DAO 之外的另一个账户。这导致以太坊进行了硬分叉以从这次攻击中恢复。需要注意的是,代码即法律或无法阻止的智能合约的概念应该以一定的怀疑态度看待,因为这些概念的实施还不够成熟,无法获得完全可信的信任。最近的事件表明以太坊基金会能够通过引入硬分叉来停止和改变The DAO的执行。尽管这次硬分叉是出于真正的原因,但它违背了去中心化的真正精神和代码即法律的概念。另一方面,对这次硬分叉的抵制以及一些矿工决定继续在原始链上进行挖矿导致了以太坊经典的创建。这是原始的、未经分叉的以太坊区块链,其中代码仍然是法律

这次攻击突显了智能合约的危险性,并绝对需要开发一个正式的智能合约语言。这次攻击还凸显了彻底测试的重要性。最近在以太坊智能合约开发语言周围发现了各种漏洞。因此,开发一个标准框架来解决所有这些问题至关重要。正如之前讨论的那样,一些工作已经开始,但这个领域有待更多研究,以解决智能合约语言的局限性。

总结

本章首先介绍了智能合约的历史,接着详细讨论了智能合约的定义。由于对智能合约的标准定义尚无一致意见,我们尝试介绍一个涵盖智能合约要点的定义。还提供了对里卡迪安合约的介绍,并解释了里卡迪安合约与智能合约的区别,突出了里卡迪安合约关注合约的定义,而智能合约则关注合约的实际执行。讨论了智能合约模板的概念,就此主题,学术界和行业目前正在进行高质量的活跃研究。还讨论了创建高级领域特定语言以创建智能合约或智能合约模板的可能性。在章节的后续部分,介绍了 Oracles 的概念,随后简要讨论了 DAO 以及 DAO 和智能合约中的安全问题。

第七章:以太坊 101

本章旨在介绍以太坊区块链。您将介绍以太坊背后的基本和高级理论概念。将详细讨论与以太坊区块链相关的各种组件、协议和算法,以便您理解这一区块链范式背后的理论。此外,本章还将介绍有关钱包软件、挖矿和设置以太坊节点的实际深入介绍。还将介绍以太坊所面临的安全性和可扩展性等各种挑战的一些材料。此外,还将讨论交易和市场动态。

介绍

以太坊是由Vitalik Buterin于 2013 年 11 月构想的。他提出的关键想法是开发一种图灵完备的语言,允许为区块链和去中心化应用程序开发任意程序(智能合约)。这与比特币形成鲜明对比,比特币的脚本语言非常有限,只允许基本和必要的操作。

以太坊客户端和版本发布

使用不同语言开发了各种以太坊客户端,目前最流行的是 go-Ethereum 和 parity。go-Ethereum 是使用 Golang 开发的,而 parity 是使用 Rust 构建的。也有其他可用的客户端,但通常来说,go-Ethereum 客户端被称为geth对所有目的都是足够的。Mist 是一个用户友好的图形用户界面GUI)钱包,后台运行 geth 与网络同步。稍后的章节中将提供更多关于这一点的细节,在安装和挖矿部分。

以太坊的第一个版本被称为Frontier,当前版本称为Homestead。下一个版本被命名为Metropolis,它专注于协议简化和性能改进。最终版本被命名为serenity,预计将实施权益证明算法(Casper)。serenity 的其他研究领域包括可扩展性、隐私和以太坊虚拟机EVM)升级。由于这是持续的开发工作,以太坊生态系统将不断改进和发展,因此 serenity 不应被视为一个最终版本,而是一个长期持续改进之旅的重要里程碑。进一步的版本尚未命名。Web 3.0的愿景已经提出,并在社区中进行讨论。Web 3.0 是一个基于现有 Web 2.0 技术演变而来的语义和智能 Web 的概念。这是一个人们、应用程序、数据和网络都能智能互连并相互交互的生态系统愿景。随着区块链技术的出现,去中心化网络的想法也出现了,这实际上是互联网的最初愿景。核心思想是在 web 3.0 中所有主要服务,如 DNS、搜索引擎和互联网身份都将被去中心化。以太坊被设想为一个可以帮助实现这一愿景的平台。

以太坊堆栈

以太坊堆栈由各种组件组成。在核心位置,有以太坊区块链运行在点对点以太坊网络上。其次,有一个以太坊客户端(通常是 geth),在节点上运行并连接到点对点以太坊网络,从中下载和本地存储区块链。它提供各种功能,如挖矿和账户管理。区块链的本地副本定期与网络同步。另一个组件是web3.js库,允许通过远程过程调用RPC)接口与 geth 进行交互。

这可以在下图中可视化:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以太坊堆栈显示了各种组件

以太坊区块链

以太坊,就像任何其他区块链一样,可以被视为基于交易的状态机。这在由Dr. Gavin Wood撰写的以太坊黄皮书中提到。其思想是通过逐步执行交易,将初始状态转化为最终状态。最终转换随后被接受为状态的绝对不可争议的版本。在下图中,展示了以太坊状态转换函数,其中事务执行导致状态转换。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以太坊状态转换函数

在前面的例子中,发起了从地址 4718bf7a地址 741f7a2的 2 以太币的转账。初始状态表示交易执行之前的状态,最终状态表示变化后的状态。这将在本章后面更详细地讨论,但本例的目的是介绍以太坊中状态转换的核心思想。

货币(ETH 和 ETC)

作为对矿工的激励,以太坊还奖励其本地货币称为以太币,缩写为 ETH。在 DAO 黑客事件之后,提出了一个硬分叉以减轻问题;因此,现在有两个以太坊区块链:一个称为 Ethereum Classic,其货币用 ETC 表示,而硬分叉版本是 ETH,它仍在增长并且正在进行积极的开发。然而,ETC 有自己的追随者,拥有一个致力于进一步发展 ETC 的专门社区,这是以太坊的未分叉原始版本。本章主要关注 ETH,这是目前最活跃和官方的以太坊区块链。

分叉

由于主要协议升级,homestead 的最新版本导致了硬分叉。协议在区块号 1,150,000 上升级,从以太坊的第一个版本 Frontier 迁移到了被称为 homestead 的第二个版本的以太坊。

最近发生的一个意外分叉发生在 2016 年 11 月 24 日,UTC 时间 14:12:07,这是由于 geth 客户端的日志机制中的一个错误导致的。网络分叉发生在区块号 2,686,351。这个错误导致 geth 在空账户删除的情况下无法回滚空的 gas 异常。这在 parity(另一个流行的以太坊客户端)中不是问题。这意味着从区块号 2686351 开始,以太坊区块链分成两个部分,一个使用 parity 客户端,另一个使用 geth。这个问题在 geth 版本 1.5.3 发布后得到解决。

Gas

以太坊中的另一个关键概念是 gas。以太坊区块链上的所有交易都需要支付它们执行的计算成本。这个成本由称为 gas 或加密燃料的东西来支付,这是以太坊引入的一个新概念。这个 gas 作为执行费用是由交易发起者提前支付的。每个操作都会消耗燃料。每个操作都有一个预定义的与之关联的 gas 量。每个交易都指定了它愿意为其执行消耗的 gas 量。如果在执行完成之前 gas 用尽,则任何由交易执行的操作都会被回滚。如果交易成功执行,则剩余的 gas 将退还给交易发起者。

本概念不应与挖矿费混淆,挖矿费是一种用于向矿工支付燃气作为费用的不同概念。有关燃气和操作相关概念和计算的更多信息将在本章后面提供。

共识机制

以太坊中的共识机制基于 GHOST 协议,最初由ZoharSompolinsky于 2013 年 12 月提出。有兴趣的人可以在eprint.iacr.org/2013/881.pdf上探索详细的原始论文。

以太坊使用了协议的简化版本,其中花费最多计算工作量来构建链的链被识别为确定版本。另一种看待它的方式是寻找最长的链,因为最长的链必须是通过消耗足够的挖矿工作量建立的。 贪婪最重子树GHOST)最初被引入作为一种缓解由快速区块生成时间导致的陈旧或孤立区块问题的机制。在 GHOST 中,陈旧的区块被加入计算中以找出最长和最重的链。在以太坊中,陈旧的区块被称为 Uncles 或 Ommers。

下图显示了最长和最重链之间的快速比较:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最长与最重链

世界状态

以太坊中的世界状态代表了以太坊区块链的全局状态。它基本上是以太坊地址和账户状态之间的映射关系。这些地址是 20 个字节长。这种映射关系是一个使用递归长度前缀RLP)序列化的数据结构。RLP 是一种特别开发的编码方案,用于在以太坊中对二进制数据进行存储或通过网络进行传输,也用于在 Patricia 树中保存状态。RLP 函数将一个项目作为输入,该项目可以是一个字符串或一组项目,并生成适合存储和通过网络传输的原始字节。RLP 不对数据进行编码;它的主要目的是对结构进行编码。

账户状态

账户状态由四个字段组成:nonce、balance、storageroot 和 codehash,并在此详细描述。

随机数

这是一个每次从地址发送交易时就会递增的值。在合同账户情况下,它表示由该账户创建的合同数量。合同账户是以太坊中存在的两种账户类型之一;它们稍后会在本章中更详细地解释。

余额

这个值表示以太坊中地址持有的货币(以太币)的最小单位——Wei 的数量。

存储根

此字段代表默克尔帕特里夏树的根节点,该树编码了账户的存储内容。

代码哈希

这是一个不可变字段,包含与账户关联的智能合约代码的哈希。在普通账户的情况下,此字段包含空字符串的 Keccak 256 位哈希。此代码通过消息调用调用。

世界状态及其与账户 trie、账户和区块头的关系可以在下图中可视化。它显示了图表中间的账户数据结构,其中包含从左侧显示的账户存储 trie 的根节点导出的存储根哈希。然后,在世界状态 trie 中使用账户数据结构,它是地址与账户状态之间的映射。最后,使用 Keccak 256 位算法哈希世界状态 trie 的根节点,并将其作为状态根哈希的一部分添加到右侧显示的区块头数据结构中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

账户 trie(账户存储内容)、账户元组、世界状态 trie 和状态根哈希及它们之间的关系

账户 trie 基本上是用于编码账户存储内容的 Merkle Patricia 树。内容存储为从 256 位整数键的 Keccak 256 位哈希到 RLP 编码的 256 位整数值的映射。

交易

以太坊中的交易是使用私钥签名的数字化数据包,其中包含指令,完成后要么产生消息调用,要么创建合约。交易可以根据它们产生的输出分为两种类型:

  • 消息调用交易:此交易简单地产生一个消息调用,用于在账户之间传递消息。

  • 合约创建交易:顾名思义,这些交易会导致创建新合约。这意味着当此交易成功执行时,它会创建一个带有关联代码的账户。

这两种交易都由一些常见字段组成,这些字段在这里描述。

Nonce

Nonce 是一个数字,每次发送交易时都会增加一次。它必须等于发送的交易数,用作交易的唯一标识符。一个 Nonce 值只能使用一次。

gasPrice

gasPrice 字段表示执行交易所需的 Wei 量。

gasLimit

gasLimit 字段包含一个值,表示执行交易所需的最大 gas 量。有关 gas 和 gas 限制的概念将在本章后面更详细地讨论。目前,可以说这是用户(例如,交易发送者)愿意支付用于计算的以太的费用量。

如其名,to 字段是表示交易接收者地址的值。

Value 表示要转移到接收者的 Wei 总数;在合约账户的情况下,这代表合约将持有的余额。

签名

签名由三个字段组成,即 vrs。这些值代表数字签名(RS)和一些信息,可用于恢复公钥(V)。还有发送方的交易,也可以确定发送方的交易。签名基于 ECDSA 方案,并利用了 SECP256k1 曲线。椭圆曲线密码学理论在 第三章 中讨论,Cryptography and technical foundations。在本节中,ECDSA 将在以太坊中的使用环境中进行介绍。

V 是一个单字节值,表示椭圆曲线点的大小和符号,可以是 27 或 28。V 在 ECDSA 恢复合约中用作恢复 ID。该值用于从私钥派生公钥。在 secp256k1 中,恢复 ID 预期为 0 或 1。在以太坊中,这个偏移量为 27。有关 ECDSARECOVER 函数的更多详细信息将在本章后面提供。

R 是从曲线上的一个计算点派生出来的。首先,选择一个随机数,将其与曲线的生成器相乘以计算曲线上的一个点。该点的 x 坐标部分为 RR 被编码为一个 32 字节序列。R 必须大于 0 并且小于 secp256k1n 限制(115792089237316195423570985008687907852837564279074904382605163141518161494337)。

S 是通过将 R 与私钥相乘并将其添加到待签名消息的哈希中来计算的,最后通过所选的随机数除以它。S 也是一个 32 字节序列。RS 一起表示签名。

为了对交易进行签名,使用 ECDSASIGN 函数,该函数将待签名的消息和私钥作为输入,并产生 V,一个单字节值;R,一个 32 字节值,和 S,另一个 32 字节值。方程如下:

ECDSASIGN (Message, Private Key) = (V, R, S)

初始化

Init 字段仅用于旨在创建合约的交易中。这表示一个无限长度的字节数组,指定要在账户初始化过程中使用的 EVM 代码。该字段中包含的代码仅在创建账户时执行一次,并在此后立即销毁。

Init 也返回另一个称为 body 的代码部分,该部分持久存在并在合约账户可能接收到的消息调用响应中运行。这些消息调用可能通过交易或内部代码执行发送。

数据

如果交易是一个消息调用,那么使用 init 字段而不是 init,它代表消息调用的输入数据。它的大小也是不受限制的,组织为一个字节数组。

这可以在下图中可视化,其中一个交易是上面提到的字段的元组,然后包含在一个交易 trie(修改过的默克尔-帕特里夏树)中,由要包含的交易组成。最后,交易 trie 的根节点使用 Keccak 256 位算法进行哈希,并包含在区块头中,同时还包括区块中的交易列表。

交易可以在交易池或区块中找到。当一个挖矿节点开始验证区块的操作时,它会从交易池中选择报酬最高的交易开始执行,逐一执行这些交易。当燃气限制达到或者交易池中没有更多交易需要处理时,挖矿就开始了。在这个过程中,区块将被反复哈希,直到找到一个有效的只需和区块一起哈希就能得到一个比难度目标小的值的 nonce。一旦区块成功挖矿,它将立即广播到网络上,宣告成功,并且将被网络验证和接受。这个过程类似于前一章讨论的比特币挖矿过程。唯一的区别是以太坊的工作证明算法是 ASIC 抗性的,称为 Ethash,在这个算法中寻找 nonce 需要大量的内存。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

交易、交易 trie 和区块头之间的关系

合约创建交易

创建账户时需要一些重要的参数。这些参数列举如下:

  • 发送者

  • 原始转账者

  • 可用燃气

  • 燃气价格

  • 资金,即最初分配的以太量

  • 一个任意长度的字节数组

  • 初始化 EVM 代码

  • 消息调用/合约创建堆栈的当前深度(当前深度意味着堆栈中已经存在的项的数量)

由合约创建交易生成的地址长度为 160 位。准确地说,根据黄皮书的定义,它们是仅包含发送者和 nonce 的结构的 RLP 编码的 Keccak 哈希的右 160 位。初始时,账户中的 nonce 设置为零。账户的余额设置为传递给合约的值。存储也设置为空。代码哈希是空字符串的 Keccak 256 位哈希。

当 EVM 代码(初始化 EVM 代码)执行时,帐户被初始化。在代码执行过程中出现任何异常情况,比如没有足够的 gas,状态不会发生改变。如果执行成功,那么在支付适当的 gas 成本后,帐户将被创建。以太坊的当前版本(家宅)规定,合约交易的结果要么是带有余额的新合约,要么是没有价值转移的不创建新合约。这与之前的版本不同,之前的合约无论合约代码部署是否成功,都可以创建合约,因为存在 gas 用尽异常。

消息调用事务

消息调用需要执行多个参数,列举如下:

  • 发送方

  • 事务发起者

  • 收件人

  • 需要执行其代码的帐户

  • 可用的 gas

  • gas 价格

  • 任意长度的字节数组

  • 调用的输入数据

  • 消息调用/合约创建栈的当前深度

消息调用会导致状态转换。消息调用也会产生输出数据,如果事务被执行则不会使用该数据。在 VM 代码触发消息调用的情况下,将使用事务执行产生的输出。

在下图中,显示了两种类型事务之间的隔禅:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

事务类型,执行所需的参数

以太坊区块链的元素

在下一节中,你将了解以太坊网络和区块链的各个组成部分。首先,下一节将介绍 EVM 的基本概念。

以太坊虚拟机(EVM)

EVM 是一个简单的基于堆栈的执行机器,可以运行字节码指令,以便将系统状态从一种状态转换为另一种状态。虚拟机的字大小设置为 256 位。堆栈大小限制为 1024 个元素,并基于LIFO(后进先出)队列。EVM 是图灵完备的机器,但由于运行任何指令所需的 gas 量有限制,所以无法出现可能导致拒绝服务攻击的无限循环。EVM 还支持异常处理,以处理诸如没有足够的 gas 或无效指令等异常情况,这种情况下,机器会立即停止并将错误返回给执行代理。

EVM 是一个完全隔离和沙箱化的运行时环境。在 EVM 上运行的代码无法访问任何外部资源,比如网络或文件系统。

正如之前讨论的,EVM 是一种基于堆栈的架构。EVM 采用大端设计,并使用 256 位宽字。这个字大小允许 Keccak 256 位哈希和椭圆曲线密码算法的计算。

合约和 EVM 可用的存储有两种类型。第一种称为内存,它是一个字节数组。当合约完成代码执行时,内存会被清除。它类似于 RAM 的概念。另一种类型称为存储,永久存储在区块链上。它是一个键值存储。

内存是无限的,但受到燃料费用要求的约束。虚拟机相关的存储是一个可以寻址的字数组,是非易失性的,并且作为系统状态的一部分而维护。键和值的大小为 32 字节。程序代码存储在一个虚拟只读存储器虚拟 ROM)中,可以使用 CODECOPY 指令进行访问。CODECOPY 指令用于将程序代码复制到主内存中。初始时,EVM 中的所有存储和内存都设置为零。

下图显示了 EVM 的设计,其中虚拟 ROM 存储程序代码,该代码使用 CODECOPY 复制到主内存中。然后 EVM 通过引用程序计数器读取主内存,并逐步执行指令。每执行一条指令,程序计数器和 EVM 栈都会相应更新。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

EVM 操作

EVM 优化是一个活跃的研究领域,最近的研究表明,EVM 可以被优化和微调到非常细微的程度,以实现高性能。已经在研究使用Web 汇编WASM)的可能性。WASM 由 Google、Mozilla 和 Microsoft 开发,现在正在由 W3C 社区组设计为一个开放标准。WASM 的目标是能够在浏览器中运行机器码,以实现原生速度的执行。同样,EVM 2.0 的目标是能够在 CPU 上原生运行 EVM 指令集(操作码),从而使其更快速和高效。

执行环境

为了执行代码,执行环境需要一些关键元素。关键参数由执行代理(例如交易)提供。这些如下所列:

  1. 拥有执行代码的账户的地址。

  2. 交易的发送者地址和执行的原始地址。

  3. 发起执行的交易中的燃料价格。

  4. 输入数据或取决于执行代理类型的交易数据。这是一个字节数组;在消息调用的情况下,如果执行代理是一个交易,则将交易数据包含为输入数据。

  5. 发起代码执行或交易发送者的账户地址。这是在代码执行由交易发起的情况下的发送者地址;否则,它是账户的地址。

  6. 值或交易价值。这是以 Wei 为单位的金额。如果执行代理是一个交易,那么它就是交易的价值。

  7. 每个执行周期中迭代器函数选取的以字节数组形式呈现的待执行代码。

  8. 当前块的块头

  9. 当前正在执行的消息调用或合约创建事务的数量。换句话说,这是当前正在执行的 CALLs 或 CREATEs 的数量。

执行环境可以被视为包含九个元素的元组,如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

执行环境元组

除了之前提到的九个字段之外,系统状态和剩余燃气也提供给了执行环境。执行的结果产生了结果状态,执行后剩余的燃气,自毁或自杀设置(稍后描述),日志系列(稍后描述)以及任何燃气退款。

机器状态

机器状态也由 EVM 在内部维护。机器状态在每次 EVM 执行周期后更新。虚拟机中运行的迭代器函数(在下一节中详细介绍)输出状态机的单个周期的结果。机器状态是一个包含以下元素的元组:

  • 可用的燃气

  • 程序计数器,一个最多达到 256 的正整数

  • 内存内容

  • 内存中活动的字数

  • 堆栈的内容

EVM 设计用于处理异常,并且在发生以下任何异常情况时将停止执行:

  • 没有足够的燃气用于执行

  • 无效的指令

  • 堆栈项不足

  • 跳转操作码的无效目标

  • 无效的堆栈大小(大于 1024)

迭代器函数

早期提到的迭代器函数执行各种重要函数,用于设置机器的下一个状态和最终世界状态。这些功能包括以下内容:

  • 它从存储在执行环境中的机器码的字节数组中提取下一条指令。

  • 它相应地向堆栈添加/移除(PUSH/POP)项目。

  • 燃气根据指令/操作码的燃气成本进行减少。

  • 它递增程序计数器PC)。

机器状态可以看作是下图所示的元组:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

机器状态元组

如果在执行周期中遇到 STOP 或 SUICIDE 或 RETURN 操作码,虚拟机也能够在正常情况下停止执行。

使用 serpent、LLL 或 Solidity 等高级语言编写的代码被转换为 EVM 可理解的字节码,以便通过 EVM 执行。Solidity 是为以太坊开发的高级语言,具有类似 JavaScript 的语法,用于编写智能合约代码。一旦代码编写完成,它就会被编译成可被 EVM 理解的字节码,使用名为 solc 的 Solidity 编译器。

LLL(类似 Lisp 的低级语言)是另一种用于编写智能合约代码的语言。Serpent 是一种类似 Python 的高级语言,可用于为以太坊编写智能合约。

例如,一个简单的 Solidity 程序如下所示:

pragma solidity ⁰.4.0; 
contract Test1
 { 
    uint x=2; 
    function addition1(uint x) returns (uint y) { 
    y=x+2; 
 } 
}  

该程序转换为字节码,如下所示。如何编译 Solidity 代码并附有示例将在下一章中给出。

运行时字节码
606060405260e060020a6000350463989e17318114601c575b6000565b346000576029600435603b565b60408051918252519081900360200190f35b600281015b91905056 
Opcodes PUSH1 0x60 PUSH1 0x40 MSTORE PUSH1 0x2 PUSH1 0x0 SSTORE CALLVALUE PUSH1 0x0 JUMPI JUMPDEST PUSH1 0x45 DUP1 PUSH1 0x1A PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN PUSH1 0x60 PUSH1 0x40 MSTORE PUSH1 0xE0 PUSH1 0x2 EXP PUSH1 0x0 CALLDATALOAD DIV PUSH4 0x989E1731 DUP2 EQ PUSH1 0x1C JUMPI JUMPDEST PUSH1 0x0 JUMP JUMPDEST CALLVALUE PUSH1 0x0 JUMPI PUSH1 0x29 PUSH1 0x4 CALLDATALOAD PUSH1 0x3B JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST PUSH1 0x2 DUP2 ADD JUMPDEST SWAP2 SWAP1 POP JUMP 

操作码及其含义

在 EVM 中引入了不同的操作码。操作码根据其执行的操作进行多个类别的划分。这里呈现了操作码及其含义和用法的列表。

算术操作

在 EVM 中,所有算术运算都是模 2²⁵⁶ 运算。这组操作码用于执行基本算术运算。这些操作的值从 0x00 开始,最高为 0x0b。

助记符弹出推入Gas描述
STOP0x00000终止执行
ADD0x01213两个值相加
MUL0x02215两个值相乘
SUB0x03213减法操作
DIV0x04215整数除法操作
SDIV0x05215有符号整数除法操作
MOD0x06215模余操作
SMOD0x07215有符号模余操作
ADDMOD0x08318模加操作
MULMOD0x09318模乘操作
EXP0x0a2110指数操作(底数的重复乘法)
SIGNEXTEND0x0b215扩展 2 的补码有符号整数长度

请注意,STOP 不是算术操作,但由于其值范围为 0,因此被归类为这个算术操作(arithmetic operations)列表中。

逻辑操作

逻辑操作包括用于执行比较和布尔逻辑操作的操作。这些操作的值范围为 0x10 到 0x1a。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

加密操作

在这个类别中只有一个操作被命名为 SHA3。值得注意的是,这不是 NIST 标准化的标准 SHA3,而是原始的 Keccak 实现。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

环境信息

在这个类别中总共有 13 条指令。这些操作码用于提供与地址、运行时环境和数据复制操作相关的信息。

助记符弹出推入Gas描述
ADDRESS0x30012用于获取当前执行账户的地址
BALANCE0x311120用于获取给定账户的余额
ORIGIN0x32012用于获取原始交易发送者的地址
CALLER0x33012用于获取发起执行的账户地址
CALLVALUE0x34012检索由指令或交易存入的价值
CALLDATALOAD0x35113检索通过消息调用传递的参数输入数据
CALLDATASIZE0x36012用于检索与消息调用传递的输入数据的大小
CALLDATACOPY0x37303用于将消息调用传递的输入数据从当前环境复制到内存中。
CODESIZE0x38012检索当前环境中正在运行的代码的大小
CODECOPY0x39303将当前环境中的运行代码复制到内存中
GASPRICE0x3a012检索发起交易指定的燃气价格。
EXTCODESIZE0x3b1120获取指定账户代码的大小
EXTCODECOPY0x3c4020用于将账户代码复制到内存中。
区块信息

这组指令与检索与区块相关的各种属性相关:

助记符POPPUSH燃气描述
BLOCKHASH0x401120获取最近完成的 256 个区块中的一个的哈希
COINBASE0x41012检索区块中设置的受益人地址
TIMESTAMP0x42012检索区块中设置的时间戳
NUMBER0x43012获取区块的编号
DIFFICULTY0x44012获取区块的难度
GASLIMIT0x45012获取区块的燃气限制值
栈、内存、存储和流操作
助记符POPPUSH燃气描述
POP0x50102从栈中移除项目
MLOAD0x51113用于从内存中加载一个字。
MSTORE0x52203用于将一个字存储到内存中。
MSTORE80x53203用于将一个字节保存到内存中
SLOAD0x541150用于从存储中加载一个字。
SSTORE0x55200将一个字保存到存储中
JUMP0x56108改变程序计数器
JUMPI0x572010根据条件改变程序计数器
PC0x58012用于在增量前检索程序计数器中的值。
MSIZE0x59012检索活动内存的大小(以字节为单位)。
GAS0x5a012检索可用燃气量
JUMPDEST0x5b001用于标记在执行期间对机器状态没有影响的跳转的有效目的地。
Push 操作

这些操作包括 PUSH 操作,用于将项目放入栈中。这些指令的范围是从 0x60 到 0x7f。EVM 中总共有 32 个 PUSH 操作。PUSH 操作,它从程序代码的字节数组中读取。

助记符POPPUSH燃气描述
PUSH1 . . . PUSH 320x60 … 0x7f013用于在堆栈上放置N个右对齐的大端字节项。 N是一个值,根据使用的助记符,范围从 1 字节到 32 字节(完整字)不等。
复制操作

如其名称所示,复制操作用于复制堆栈项。 值的范围从 0x80 到 0x8f。 在 EVM 中有 16 个 DUP 指令可用。 放置在堆栈上或从堆栈上移除的项目随着使用的助记符而改变; 例如,DUP1 从堆栈中删除一个项目并将两个项目放在堆栈上,而 DUP16 从堆栈中删除 16 个项目并放置 17 个项目。

助记符数值POPPUSHGas描述
DUP1 . . . DUP160x80 … 0x8fXY3用于复制第n个堆栈项,其中n是对应于所使用的 DUP 指令的数字。 XY分别是从堆栈中移除和放置的项目。
交换操作

SWAP 操作提供了交换堆栈项的能力。 有 16 个 SWAP 指令可用,并且随着每个指令的使用,堆栈项被递增地移除和放置,最多到 17 个项目,具体取决于使用的操作码类型。

助记符数值POPPUSHGas描述
SWAP1 . . . SWAP160x90 … 0x9fXY3用于交换第n个堆栈项,其中n是对应于使用的 SWAP 指令的数字。 XY 分别是从堆栈中移除和放置的项目。
记录操作

记录操作提供了用于在子状态元组的日志序列字段上附加日志条目的操作码。 总共有四个日志操作可用,范围从值 0x0a 到 0xa4。

助记符数值POPPUSHGas描述
LOG0 . . . LOG40x0a … 0xa4XY (0)375,750,1125,1500,1875用于附加具有N个主题的日志记录,其中N是与所使用的 LOG 操作码对应的数字。 例如,LOG0 表示没有主题的日志记录,LOG4 表示具有四个主题的日志记录。 XY 分别代表从堆栈上移除和放置的项目。 根据使用的 LOG 操作,XY会逐渐增加,从 2,0 到 6,0。
系统操作

系统操作用于执行各种与系统相关的操作,例如账户创建,消息调用和执行控制。 在该类别中总共有六个操作码可用。

助记符数值POPPUSHGas描述
CREATE0xf03132000用于创建具有相关代码的新账户。
CALL0xf17140用于启动对账户的消息调用。
CALLCODE0xf27140用于使用替代账户的代码启动对此账户的消息调用。
RETURN0xf3200终止执行并返回输出数据。
DELEGATECALL0xf46140与 CALLCODE 相同,但不改变发送方和值的当前值。
SUICIDE0xff100停止(中止)执行,并且账户被注册以便稍后删除

在本节中,已经讨论了所有的 EVM 操作码。在以太坊的 Homestead 发布中,总共有 129 个可用的 EVM 操作码。

预编译合约

以太坊有四个预编译合约。以下是这些合约及其详细信息的列表。

椭圆曲线公钥恢复函数

ECDSARECOVER(椭圆曲线 DSA 恢复函数)位于地址 1。它表示为 ECREC,并且执行时需要 3000 gas。如果签名无效,则此函数不返回任何输出。公钥恢复是一种标准机制,可以从椭圆曲线密码学中的私钥推导出公钥。

ECDSA 恢复函数如下所示:

ECDSARECOVER(H, V, R, S) = Public Key

它接受四个输入:H,它是要签名的消息的 32 字节哈希,以及 VRS,它们代表带有恢复 ID 的 ECDSA 签名,并产生一个 64 字节的公钥。VRS 在本章中之前已经详细讨论过。

SHA-256 位哈希函数

SHA-256 位哈希函数是一个预编译合约,位于地址 2,并产生输入的 SHA256 哈希。它几乎就像是一个传递函数。SHA-256(SHA256)的燃气需求取决于输入数据的大小。输出是一个 32 字节值。

RIPEMD-160 位哈希函数

RIPEMD-160 位哈希函数用于提供 RIPEMD 160 位哈希,并且位于地址 3。此函数的输出是一个 20 字节的值。与 SHA-256 类似,燃气需求取决于输入数据的量。

身份函数

身份函数位于地址 4 并且由 ID 表示。它简单地将输出定义为输入;换句话说,无论输入是什么,ID 函数都会输出相同的值。燃气需求通过一个简单的公式计算:15 + 3 [I[d]/32],其中 I[d] 是输入数据。这意味着在高层次上,燃气需求取决于输入数据的大小,尽管进行了一些计算,如前面的方程所示。

所有先前提到的预编译合约都可以成为本机扩展,并且将来可以包含在 EVM 操作码中。

账户

账户是以太坊区块链的主要构建块之一。状态是由账户之间和账户上的交互导致的。在账户之间和账户上执行的操作代表状态转换。状态转换是通过所谓的以太坊状态转换函数实现的,其工作方式如下:

  1. 通过检查语法、签名有效性和 nonce 来确认交易的有效性。

  2. 计算交易费用,并使用签名解析发送地址。此外,检查并相应减少发送方的账户余额,并递增 nonce。如果账户余额不足,则返回错误。

  3. 提供足够的以太(gas 价格)以支付交易成本。根据交易的大小,逐字节收费增加。

  4. 在此步骤中,实际的价值转移发生。流程是从发送方账户到接收方账户。如果交易中指定的目标账户尚不存在,则会自动创建该账户。此外,如果目标账户是一个合约账户,则会执行合约代码。这也取决于可用的 gas 数量。如果有足够的 gas,则合约代码将被完全执行;否则,它将运行到用尽 gas 的地方。

  5. 在由于账户余额不足或 gas 而导致交易失败的情况下,除了支付给矿工的手续费之外,所有状态更改都会被回滚。

  6. 最后,将剩余的手续费(如果有)作为找零发送回发送方,并相应地支付手续费给矿工。在这一点上,函数返回结果状态。

账户类型

以太坊有两种类型的账户:

  • 外部拥有账户

  • 合约账户

首先是外部拥有账户EOAs),另一个是合约账户。EOAs 类似于比特币中由私钥控制的账户。合约账户是与私钥一起关联有代码的账户。EOA 具有以太坊余额,能够发送交易,并且没有关联的代码,而合约账户CA)具有以太坊余额,关联代码,并且能够在收到交易或消息时被触发并执行代码。值得注意的是,由于以太坊区块链的图灵完备性质,合约账户内的代码可以具有任何复杂程度。该代码由以太坊网络上的每个挖矿节点的 EVM 执行。此外,合约账户能够维护自己的永久状态并调用其他合约。预计在 serenity 版本中,可能会消除外部拥有账户和合约账户之间的区别。

区块

如前所述,区块是区块链的主要构建块。以太坊区块包含各种组件,描述如下:

  • 区块头

  • 交易列表

  • Ommers 或叔叔的头列表

交易列表简单来说就是包含在区块中的所有交易的列表。此外,叔叔的头列表也包含在区块中。最重要且最复杂的部分是区块头,在此讨论。

区块头

区块头是以太坊区块的最关键和详细的组件。头包含有价值的信息,以下将详细描述。

父哈希

这是父(上一个)区块头的 Keccak 256 位哈希。

祖先哈希

这是包含在区块中的 Ommers(叔块)区块列表的 Keccak 256 位哈希。

受益人

受益人字段包含接收采矿奖励的 160 位地址,一旦区块成功挖掘完成,受益人将获得奖励。

状态根

状态根字段包含状态 trie 的根节点的 Keccak 256 位哈希。它是在所有交易被处理和结束后计算的。

交易根

交易根是交易 trie 的根节点的 Keccak 256 位哈希。交易 trie 表示包括在区块中的交易列表。

收据根

收据根是交易收据 trie 的根节点的 keccak 256 位哈希。这个 trie 由包含在区块中的所有交易的收据组成。交易收据在每笔交易处理后生成,包含有用的交易后信息。更多关于交易收据的详细信息将在下一节中提供。

日志布隆

日志布隆是一个由每个区块中包含的交易清单的每个交易收据的日志器地址和日志主题组成的布隆过滤器。日志将在下一节中详细解释。

难度

当前区块的难度级别。

数字

所有先前区块的总数;起源区块是区块零。

燃气限制

该字段包含代表每个区块燃气消耗上限的值。

使用的燃气

该字段包含区块中包括的交易消耗的总燃气。

时间戳

时间戳是区块初始化时间的纪元 Unix 时间。

额外数据

额外数据字段可用于存储与区块相关的任意数据。

Mixhash

Mixhash 字段包含一个 256 位哈希,一旦与随机数结合使用,可以证明已经花费了足够的计算工作来创建这个区块。

随机数

随机数是一个 64 位哈希(一个数字),用来证明,结合 Mixhash 字段,已经花费了足够的计算工作来创建这个区块。

以下图显示了区块和区块头的详细结构:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

带有区块头的区块结构详细图

起源区块

起源区块在其所包含的数据和从普通区块创建方式上略有不同。它包含了 15 项描述如下。

从 Etherscan.io,实际版本如下所示:

元素描述
时间戳(2015 年 7 月 30 日下午 03:26:13 +协调世界时)
交易该区块中包含 8893 笔交易和 0 笔合约内部交易
哈希0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3
父哈希0x0000000000000000000000000000000000000000000000000000000000000000
Sha3 叔眷0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
由谁挖掘0x0000000000000000000000000000000000000000 在 15 秒内
难度17,179,869,184
总难度17,179,869,184
大小540 字节
Gas 限制5,000
Gas 使用0
Nonce0x0000000000000042
区块奖励5 以太币
叔眷奖励0
额外数据»èÛN4{NŒ"|ƒpäµí3­³ÛiËÛz8áå ‚ú(十六进制:0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa)

交易收据

交易收据被用作存储交易执行后的状态的机制。换句话说,这些结构被用于记录交易执行的结果。在每次交易执行完成后产生。所有收据都存储在索引键字典树中。这个字典树的根哈希(Keccak 256 位)被放置在区块头部作为收据根。它由在这里描述的四个元素组成。

交易后状态

该项是在交易执行后保存状态的字典树结构。它被编码为一个字节数组。

已使用的 Gas

这一项代表在包含交易收据的区块中所使用的总 Gas 数量。该值在交易执行完成后立即被取得。总 Gas 使用量预计应为非负整数。

日志集合

此字段显示作为交易执行结果创建的日志条目集合。日志条目包含记录者地址、一系列日志主题和日志数据。

布隆过滤器

从之前讨论的日志条目中所包含的信息创建了一个布隆过滤器。日志条目被简化为一个哈希值为 256 字节,然后作为日志布隆嵌入到区块头部。日志条目是由记录者地址、日志主题和日志数据组成的。日志主题被编码为一系列 32 字节的数据结构。日志数据由一些字节数据组成。

这个过程可以在以下图表中可视化:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

交易收据和日志布隆

交易验证和执行

交易在验证有效性后执行。初始测试如下所列:

  • 一个交易必须是形式良好的,并且是没有额外的尾随字节的 RLP 编码的

  • 用于签署交易的数字签名是有效的

  • 交易 nonce 必须等于发送方账户的当前 nonce

  • Gas 限制不能小于交易使用的 Gas

  • 发送方账户包含足够的余额来支付执行成本

交易子状态

在执行交易后立即被处理时产生了一个交易子状态。这个交易子状态是由三个项目组成的元组。

自杀集合

此元素包含在执行事务后被处置的帐户列表。

日志系列

这是一系列索引检查点,允许监视和通知与以太坊环境外部实体的合同调用,例如应用前端。它的工作方式类似于触发机制,每次调用特定函数或发生特定事件时执行。日志是响应智能合约中发生的事件而创建的。它还可以用作更便宜的存储形式。事件将在第八章 以太坊开发中通过实际示例进行讨论。

退款余额

这是发起执行的交易中的气体总价格。退款不会立即执行;相反,它们被用来部分抵消总执行成本。

以下图描述了事务子状态元组:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

子状态元组

块验证机制

如果 Ethereum 块通过以下检查,则视为有效:

  • 与 Uncles 和交易一致。这意味着所有 Ommers(Uncles)满足它们确实是 Uncles 的属性,并且 Uncles 的工作证明是否有效。

  • 如果先前的块(父块)存在且有效。

  • 如果块的时间戳有效。这基本上意味着当前块的时间戳必须高于父块的时间戳。此外,它应该在未来 15 分钟之内。所有块时间都以纪元时间(Unix 时间)计算。

如果这些检查中的任何一个失败,该块将被拒绝。

块最终化

块最终化是由矿工运行的过程,目的是验证块的内容并应用奖励。它导致执行四个步骤。这些步骤在此详细描述。

Ommers 验证

验证 Ommers(也称为已过时的块 Uncles)。在挖矿的情况下,确定 Ommers。过时块头的验证过程检查头是否有效以及 Uncle 与当前块的关系是否满足最大深度为六个块。一个块最多可以包含两个 Uncles。

交易验证

验证交易。在挖矿的情况下,确定交易。该过程涉及检查块中使用的总气体是否等于最终交易后的最终气体消耗。

奖励申请

应用奖励,这意味着更新受益者帐户的奖励余额。在以太坊中,矿工还为过时的块提供奖励,这是块奖励的 1/32。包含在块中的 Uncles 还将获得总块奖励的 7/8。当前块奖励为 5 个以太。一个块最多可以有两个 Uncles。

状态和随机数验证

验证状态和随机数。在挖矿的情况下,计算一个有效的状态和随机数。

块难度

如果两个区块之间的时间缩短,则区块难度会增加,而如果两个区块之间的时间增加,难度也会增加。这是为了保持大致一致的区块生成时间。以太坊家园版发布的难度调整算法如下所示:

block_diff = parent_diff + parent_diff // 2048 *  
max(1 - (block_timestamp - parent_timestamp) // 10, -99) +  
int(2**((block.number // 100000) - 2))  

前述算法意味着,如果父区块和当前区块生成之间的时间差小于 10 秒,则难度增加。如果时间差在 10 到 19 秒之间,则难度级别保持不变。最后,如果时间差为 20 秒或更多,则难度级别降低。这种降低与时间差成比例。

除了基于时间戳差异的难度调整外,在前述算法的最后一行还有另一部分,即在每挖出 100,000 个区块后难度会呈指数增长。这就是以太坊网络引入的所谓难度时间炸弹冰河时代,它将在未来某个时间点使在以太坊区块链上的挖矿变得非常困难。这将鼓励用户转向权益证明,因为在工作量证明链上的挖矿最终将变得极其困难。根据最新的更新和基于算法的估计,区块生成时间将在 2017 年下半年显著增加,在 2021 年将变得如此之高,以至于在工作量证明链上挖矿几乎不可能。这样一来,矿工们将别无选择,只能转向以太坊提出的叫做卡斯珀的权益证明方案。

以太币

以太币是由矿工挖矿产生的作为奖励的货币,用于支付他们在验证和验证交易和区块的过程中所花费的计算工作。以太币在以太坊区块链内用于支付在 EVM 上执行合约的费用。以太币用于购买作为加密燃料的 Gas,这是在以太坊区块链上执行计算所需的。

分数表如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

每次 EVM 在区块链上执行计算都会收取费用。详细的费用表将在接下来的部分中展示。

Gas

每次在以太坊区块链上执行操作时都需要支付 gas。这是一种机制,它确保了由于 EVM 的图灵完备性质,无限循环不能导致整个区块链因而停滞。交易费用以一定数量的以太币收取,并从交易发起者的帐户余额中扣除。交易费用是为了让矿工将交易包含在挖掘中而收取的。如果此费用过低,则可能永远不会被挑选出来;费用越高,被矿工挑选出来并包含在区块中的机会就越大。相反,如果矿工将费用适当支付的交易包含在区块中,但要执行的操作过于复杂,则如果 gas 成本不足,可能会导致 gas 耗尽异常。在这种情况下,交易将失败,但仍将被包含在区块中,并且交易发起者将不会获得任何退款。

交易成本可以使用以下公式估算:

总成本 = gasUsed * gasPrice

在这里,gasUsed 是交易在执行过程中应该使用的总 gas,gasPrice 是由交易发起者指定的奖励给矿工的激励,以便将交易包含在下一个区块中。这以以太币指定。每个 EVM 操作码都分配了一个费用。这只是一个估计,因为实际使用的 gas 可能会比交易发起者最初指定的值多或少。例如,如果计算时间过长或者智能合约的行为随其他因素的变化而改变,那么交易执行可能会执行比最初预期的更多或更少的操作,从而导致消耗更多或更少的 gas。如果执行耗尽了 gas,一切都会立即回滚;否则,如果执行成功且还有一些剩余的 gas,则会将其返回给交易发起者。

每个操作都会消耗一些 gas;以下是一些操作的高级费用计划示例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

根据前面的费用计划和前面讨论的公式,可以计算 SHA3 操作的示例计算如下:

  • SHA3 消耗 30 gas

  • 当前 gas 价格为 25 GWei,相当于 0.000000025 以太币

  • 将两者相乘:0.000000025 * 30 = 0.00000075 以太币

总共,0.00000075 以太币是将被收取的总 gas。

费用计划

作为执行操作的先决条件,gas 在三种情况下被收取:

  • 操作的计算

  • 用于合约创建或消息调用

  • 内存使用增加

在本章节之前提供了一系列指令和具有 gas 值的各种操作。

消息

消息,如黄皮书所定义,是在两个账户之间传递的数据和价值。消息是在两个账户之间传递的数据包。这个数据包包含数据和价值(以太币数量)。它可以通过智能合约(自治对象)发送,也可以通过数字签名的方式由外部参与者(外部用户账户)发出的交易方式发送。

合同可以向其他合同发送消息。消息只存在于执行环境中,永远不会被存储。消息类似于交易;然而,主要区别在于它们是由合同产生的,而交易是由以太坊环境外部实体(外部用户账户)产生的。

一条消息由这里提到的组件组成:

  1. 消息的发送者

  2. 消息的接收者

  3. 欲转移的 Wei 数量和消息到合同地址

  4. 可选的数据字段(合同的输入数据)

  5. 可以消耗的最大燃气数量

当合同执行CALLDELEGATECALL 操作码时生成消息。

调用

调用不会向区块链广播任何内容;相反,它是对合同函数的本地调用,并在节点上本地运行。它几乎像是本地函数调用。由于它是一个只读操作,因此它不会消耗任何燃气。这类似于试运行。调用在节点上本地执行,通常不会导致任何状态变化。在黄皮书中定义,这是将消息从一个账户传递到另一个账户的行为。如果目标帐户有关联的 EVM 代码,那么虚拟机将在接收消息后启动以执行所需的操作。如果消息发送者是一个自治对象,那么调用将传递虚拟机操作返回的任何数据。

状态通过交易改变。这些交易由外部因素创建,签名然后广播到以太坊网络。

挖矿

挖矿是向区块链添加新货币的过程。这是矿工验证和验证由交易组成的区块的激励。挖矿过程通过验证计算来帮助确保网络安全。

在理论层面上,矿工执行以下功能:

  1. 监听在以太坊网络上广播的交易,并确定要处理的交易。

  2. 确定过时的块,称为 Uncles 或 Ommers,并将它们包含在块中。

  3. 更新账户余额,获得成功挖矿的奖励。

  4. 最后,计算出一个有效状态并完成块,这定义了所有状态转换的结果。

当一个块被认为是有效时,它不仅必须满足一般的一致性要求,还必须包含给定难度的工作证明。

随着 serenity 发布,工作量证明算法将被权益证明算法取代。已经进行了大量的研究工作,以构建适用于以太坊网络的权益证明算法。

已经开发了一种名为 Casper 的算法,它将替换以太坊中现有的工作量证明算法。这是一个基于经济协议的安全押金,节点需要在它们能够产生区块之前放置一个安全押金。在 Casper 中,节点被称为有抵押验证器,而放置押金的行为被称为绑定。

Ethash

Ethash 是以太坊使用的工作量证明算法的名称。最初,这被提出为“Dagger-Hashimoto”算法,但自第一次实施以来发生了许多变化,而 PoW 算法现在已经演变为现在所知的 Ethash。与比特币类似,挖矿背后的核心思想是找到一个一旦哈希的随机数在预定的难度级别下结果。最初,以太坊刚刚推出时的难度很低,即使是 CPU 和单个 GPU 挖矿也是有利可图的,但现在情况已经不再如此。现在,要么是挖矿合集有利可图,要么是大型 GPU 挖矿农场被用于挖矿目的。

Ethash 是一种内存硬算法,这使得在专用硬件上实施它变得困难。与比特币一样,ASIC 已经被开发出来,这多年来导致了挖矿的集中化,但内存硬工作量证明算法是阻止这种威胁的一种方式,以太坊实现了 Ethash 来阻止 ASIC 发展用于挖矿。该算法需要根据随机数和区块头部选择一个称为DAG有向无环图)的固定资源的子集。DAG 大约有 2 GB 大小,并且每 30000 个区块改变一次。只有当 DAG 第一次完全生成时,挖矿才能开始。每 30000 个区块之间的时间大约为 5.2 天,称为纪元。这个 DAG 被称为 Proof of Work 算法 Ethash 的种子。根据当前的规格,纪元时间被定义为 30000 个区块。

当成功找到有效随机数时,当前的奖励方案是 5 以太。除了获得 5 以太外,成功的矿工还会获得区块内消耗的 gas 的费用以及将陈旧区块(叔块)包含在区块中的额外奖励。每个区块最多允许两个叔块,并且以正常区块奖励的 7/8 进行奖励。为了实现 12 秒的区块时间,每个区块都会调整难度。奖励与矿工的哈希速率成正比,这基本上意味着矿工可以有多快地进行哈希计算。

挖矿可以通过简单地加入以太坊网络并运行适当的客户端来进行。关键要求是节点在挖矿开始之前应完全与主网络同步。

在即将到来的章节中,将提到各种挖矿方法。

CPU 挖矿

即使在主网上不盈利,CPU 挖矿仍然在测试网络或甚至私有网络上进行挖掘和合约部署实验中非常有价值。私有和测试网络将在下一章节中通过实际示例进行讨论。此处展示了如何启动 CPU 挖矿的 geth 示例。可以通过 mine 开关启动 geth 以开始挖矿:

geth --mine --minerthreads <n>

使用 web 3 geth 控制台也可以启动 CPU 挖矿。通过发出以下命令可以启动 geth 控制台:

geth attach 

然后,可以通过发出以下命令启动挖矿程序,如果成功将返回 true,否则返回 false。看看下面的命令:

Miner.start(4)
True

上述命令将启动带有四个线程的挖矿程序。看看下面的命令:

Miner.stop
True

上述命令将停止挖矿程序。如果成功,该命令将返回 true。

GPU 挖矿

在基本水平上,通过运行两个命令可以轻松进行 GPU 挖矿:

geth --rpc

一旦 geth 运行起来并且区块链完全下载完成,就可以运行 Ethminer 以开始挖矿。Ethminer 是一个独立的挖矿程序,也可以在农场模式下用于贡献到挖矿池。可以从github.com/Genoil/cpp-ethereum/tree/master/releases下载:

ethminer -G

使用G开关运行假设已安装并正确配置适当的显卡。如果找不到适当的显卡,ethminer 会返回错误,如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果找不到适当的 GPU 则出现错误

GPU 挖矿需要一块 AMD 或 Nvidia 显卡和适用的 OpenCL SDK。对于 Nvidia 芯片组,可以从developer.nvidia.com/cuda-downloads下载。对于 AMD 芯片组,可在developer.amd.com/tools-and-sdks/opencl-zone/amd-accelerated-parallel-processing-app-sdk下载。

一旦显卡安装并正确配置,可以通过发出ethminer -G命令启动该进程。

Ethminer 也可以用于运行基准测试,如下图所示。可以调用两种模式进行基准测试。可以是 CPU 或 GPU。命令如下所示。

CPU 基准测试

$ ethminer -M -C

GPU 基准测试

$ ethminer -M -G

下图示例展示了 CPU 挖矿基准测试:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

CPU 基准测试

也可以在命令行中指定要使用的 GPU 设备:

$ ethminer -M -G --opencl-device 1

由于 GPU 挖矿是使用 OpenCL AMD 实现的,基于芯片组的 GPU 比 NVidia GPU 工作得更快。由于高内存需求(DAG 创建),FPGAs 和 ASICs 不会比 GPU 提供任何主要优势。这是有意为之,以阻止为挖矿开发专用硬件。

挖矿机

随着挖掘以太坊的难度随时间增加,矿工开始建造带有多个 GPU 的挖矿设备。一个挖矿设备通常包含约五块 GPU 卡,它们都并行工作进行挖矿,从而提高了挖掘有效 nonce 的几率。

挖矿设备可以通过一些努力来构建,也可以从各种供应商处商业购买。典型的挖矿设备配置包括后续章节讨论的组件。

主板

需要一个具有多个 PCI-E x1 或 x16 插槽的专用主板,例如 BIOSTAR Hi-Fi 或 ASRock H81。

SSD 硬盘

需要一个 SSD 硬盘。推荐使用 SSD 硬盘,因为它比模拟等效硬盘性能更快。这将主要用于存储区块链。

GPU

GPU 是挖矿设备中最重要的组件,因为它是主要的工作马,将用于挖矿。例如,它可以是一块 Sapphire AMD Radeon R9 380,配备 4 GB RAM。

Linux Ubuntu 的最新版本通常被选择作为挖矿设备的操作系统。还有另一种 Linux 变体可用,称为 EthOS(可在ethosdistro.com/找到),专门用于以太坊挖矿,并支持本地挖矿操作。

最后,安装了 Ethminer 和 geth 等挖矿软件。此外,还安装了一些远程监控和管理软件,以便需要时可以远程监视和管理挖矿设备。同样重要的是要安装适当的空调或冷却机制,因为运行多个 GPU 可能会产生大量热量。这也需要使用适当的监控软件,以便在硬件出现任何问题时提醒用户,例如 GPU 过热。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 eBay 上出售的以太坊挖矿设备

挖矿池

有许多在线挖矿池提供以太坊挖矿服务。可以使用 Ethminer 通过以下命令连接到挖矿池。每个挖矿池都会发布自己的指南,但通常连接到池的过程相似。这里以 ethereumpool.co 为例:

ethminer -C -F http://ethereumpool.co/?miner=0.1@0x024a20cc5feba7f3dc3776075b3e60c20eb1459c@DrEquinox

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ethminer 的屏幕截图

客户端和钱包

由于以太坊正处于快速发展和演变之中,过去几年中已开发和推出了许多组件、客户端和工具。以下是可用于以太坊的所有主要组件、客户端软件和工具的列表。提供此列表是为了减少许多可用于以太坊的工具和客户端的歧义性。此处提供的列表还解释了各种组件的用途和重要性。

Geth

这是以太坊客户端的 Go 语言实现。

以太坊

这是以太坊客户端的 C++实现。

Pyethapp

这是以太坊客户端的 Python 实现。

Parity

此实现是使用 Rust 构建的,并由 EthCore 开发。 EthCore 是一家致力于开发 parity 客户端的公司。 Parity 可以从ethcore.io/parity.html下载。

轻量级客户端

SPV 客户端仅下载区块链的一个小子集。这允许低资源设备,如手机、嵌入式设备或平板电脑,能够验证交易。在这种情况下,不需要完整的以太坊区块链和节点,SPV 客户端仍然可以验证交易的执行。SPV 客户端也称为轻量级客户端。这个想法类似于比特币 SPV 客户端。在 iOS 和 Android 上可以安装的 Jaxx 提供了一个钱包,它提供了SPV简单支付验证)功能,网址是jaxx.io/

安装

下面的安装过程描述了在 Ubuntu 系统上安装各种以太坊客户端的过程。其他操作系统的说明可以在以太坊维基上找到。由于后面的示例将使用 Ubuntu 系统,因此这里仅描述了在 Ubuntu 上的安装。

Geth 客户端可以通过在 Ubuntu 系统上使用以下命令安装:

> sudo apt-get install -y software-properties-common
> sudo add-apt-repository -y ppa:ethereum/ethereum
> sudo apt-get update
> sudo apt-get install -y ethereum

完成安装后。只需在命令提示符处发出geth命令,即可启动 Geth,因为它预先配置了连接到现场以太网的所有必需参数:

> geth

Eth 安装

Eth 是以太坊客户端的 C ++实现,可以使用以下命令在 Ubuntu 上安装:

> sudo apt-get install cpp-ethereum 

Mist 浏览器

Mist 浏览器是一个用户友好的界面,用于最终用户,具有功能丰富的图形用户界面,用于浏览 DAPPS 以及账户和合同管理。 Mist 的安装在下一章中介绍。

第一次启动 Mist 时,它将在后台初始化 geth 并与网络同步。根据网络的速度和类型,完全与网络同步可能需要几个小时到几天不等的时间。如果使用 TestNet,则同步相对较快,因为 TestNet(Ropsten)的大小不如 MainNet 大。有关如何连接到 TestNet 的更多信息将在下一章中提供。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Mist 浏览器启动并与主网络同步

Mist 浏览器不是一个钱包; 实际上,它是一个 DAPPS 浏览器,并为创建和管理合同、账户和浏览去中心化应用程序提供了用户友好的用户界面。以太坊钱包是随 Mist 一起发布的 DAPP。

钱包是一个通用程序,可以存储私钥和关联账户,并且根据其中存储的地址,可以通过查询区块链计算与这些地址相关联的以太的现有余额。

其他钱包包括但不限于 MyEtherWallet,这是一个用 JavaScript 开发的开源以太坊钱包。MyEtherWallet 在客户端浏览器中运行。该网址为 www.myetherwallet.com

Icebox 由 Consensys 开发。这是一个冷存储浏览器,提供以太币的安全存储。这取决于运行 Icebox 的计算机是否连接到互联网。

以太坊有多种钱包可供桌面、移动和 Web 平台使用。一个名为 Jaxx 的流行 Ethereum iOS 钱包如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Jaxx 以太坊 iOS 钱包显示交易和当前余额

区块链同步完成后,Mist 将启动并显示以下界面。在本示例中,显示了四个账户,但没有余额:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Mist 浏览器

新账户可以通过多种方式创建。在 Mist 浏览器中,可以通过单击账户菜单并选择新建账户,或者在 Mist 账户概览屏幕上单击添加账户选项来创建。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

添加新账户

账户需要设置密码,如上图所示;一旦账户设置完成,它将显示在 Mist 浏览器的账户概览部分。

也可以通过命令行使用 geth 或 parity 命令行界面添加账户。此过程在下一节中显示。

Geth

$ geth account new 
Your new account is locked with a password. Please give a password. Do not forget this password. 
Passphrase: 
Repeat passphrase: 
Address: {21c2b52e18353a2cc8223322b33559c1d900c85d} 
drequinox@drequinox-OP7010:~$

可以使用以下命令使用 geth 显示账户列表:

$ geth account list 

Account #0: {11bcc1d0b56c57aefc3b52d37e7d6c2c90b8ec35} /home/drequinox/.ethereum/keystore/UTC--2016-05-07T13-04-15.175558799Z--11bcc1d0b56c57aefc3b52d37e7d6c2c90b8ec35 

Account #1: {e49668b7ffbf031bbbdab7a222bdb38e7e3e1b63} /home/drequinox/.ethereum/keystore/UTC--2016-05-10T19-16-11.952722205Z--e49668b7ffbf031bbbdab7a222bdb38e7e3e1b63 

Account #2: {21c2b52e18353a2cc8223322b33559c1d900c85d} /home/drequinox/.ethereum/keystore/UTC--2016-11-29T22-48-09.825971090Z--21c2b52e18353a2cc8223322b33559c1d900c85d

geth 控制台

可以使用 geth JavaScript 控制台执行各种功能。例如,可以通过附加 geth 创建账户。

可以将 Geth 附加到运行的守护程序中,如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一旦成功将 geth 附加到以太坊客户端的运行实例(在本例中为 parity),它将显示命令提示符’>',该提示符提供了一个交互式命令行界面,以使用 JavaScript 符号与以太坊客户端进行交互。

例如,可以使用以下命令在 geth 控制台中添加新账户:

> personal.newAccount() 
Passphrase: 
Repeat passphrase: 
"0xc64a728a67ba67048b9c160ec39bacc5626761ce" 
>

可以类似地显示账户列表:

> eth.accounts 
["0x024a20cc5feba7f3dc3776075b3e60c20eb1459c", "0x11bcc1d0b56c57aefc3b52d37e7d6c2c90b8ec35", "0xdf482f11e3fbb7716e2868786b3afede1c1fb37f", "0xe49668b7ffbf031bbbdab7a222bdb38e7e3e1b63", "0xf9834defb35d24c5a61a5fe745149e9470282495"]

使用比特币为账户充值

这个选项在 Mist 浏览器中可用,通过单击账户然后选择资助账户选项。此操作使用的后端引擎是 shapeshift.io,可以用来从比特币或其他货币(包括法定货币选项)资助账户。

交易完成后,转移的以太币将出现在账户中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Parity 安装

Parity 是以太坊客户端的另一个实现。它是使用 Rust 编程语言编写的。parity 开发的主要目标是高性能、小占地面积和可靠性。在 Ubuntu 或 Mac 系统上可以使用以下命令安装 parity:

bash <(curl https://get.parity.io -Lk)

这将启动 parity 客户端的下载和安装。安装 parity 完成后,安装程序还将提供安装 netstats 客户端的选项。netstat 客户端是在后台运行的守护程序,会收集重要统计信息并在 stats.ethdev.com 上显示。

示例中展示了 parity 的一个示例安装情况,如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

安装成功后,将显示以下消息。然后可以使用 parity -j 启动以太坊 parity 节点。如果需要与 geth 兼容以便在 parity 中使用以太坊钱包(Mist 浏览器),则应使用 parity -geth 命令运行 parity。这将以 geth 客户端的兼容模式运行 parity,并允许 Mist 在 parity 之上运行。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

parity 安装

客户端还可以选择在 ethstats.net/ 上列出。示例如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

所有连接的客户端都会显示在 ethstats.net 上,如下截图所示。这些客户端会列出相关属性,例如节点名称、节点类型、延迟、挖矿状态、对等节点数量、待处理交易数量、上一个区块、难度、区块交易量和叔块数量。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

客户端在 ethstats.net/ 上列出。

Parity 还提供了一个用户友好的 web 界面,可以在该界面上管理各种任务,如账户管理、地址簿管理、DAPP 管理、合约管理以及状态和签名者操作。

可以通过发出以下命令访问此内容:

$ parity ui

这将弹出以下界面:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

parity 用户界面。

如果 parity 正在以 geth 兼容模式运行,则会禁用 parity UI。为了同时启用 UI 和 geth 兼容性,可以使用以下命令:

$ parity --geth --force-ui

上述命令将以 geth 兼容模式启动 parity,并启用 web 用户界面。

使用 parity 命令行创建账户

可以使用以下命令使用 parity 创建新账户:

$ parity account new
Please note that password is NOT RECOVERABLE.
Type password:
Repeat password:
2016-11-30 02:18:55 UTC c8c92a910cfbce2e655c88d37a89b6657d1498fb

交易与投资

以太币可在各个交易所进行买卖。撰写本文时,以太坊的当前市值为£680,277,967,一枚以太币的价值为£7.89。最近,由于最近以太坊遭受攻击以及随后在以太坊网络上进行的分叉,价格非常波动且显著下降。

下图显示了历史市值的详细信息:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以太历史市值(来源 Etherscan.io)

以太可以在各种交易所购买,也可以进行挖掘。有一些在线服务,如shapeshift.io,可以实现货币间的转换。

各种在线交易所,如 kraken、coinbase 等,提供以太以便用信用卡或其他虚拟货币,如比特币购买。

黄皮书

以太坊黄皮书由加文·伍德博士撰写,作为以太坊协议的正式定义。任何人都可以按照该论文中定义的协议规范来实现以太坊客户端。这篇论文对于那些没有代数或数学背景,不熟悉数学符号的读者来说可能有些难以理解。

论文中提供了所有符号及其意义的列表,以便更容易阅读论文。一旦了解了符号的含义,就会很容易理解和欣赏黄皮书中描述的概念和规范。

有用的符号

符号意义符号意义
定义为小于或等于
=等于外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传Sigma,世界状态
不等于外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传Mu,机器状态
║…║长度为外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传Upsilon,以太坊状态转换函数
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传是元素外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传区块级状态转换函数
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传不是元素.序列连接
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传对于所有外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传存在
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传并集合约创建函数
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传逻辑与外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传递增
:这样的
{}集合
()元组函数
[]数组索引
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传逻辑或
>大于
+加法
-减法
求和
{描述 if,otherwise 的各种情况
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传下取整,最低元素
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传上取整,最高元素
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传字节数
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传异或
(a,b)实数 >= a 且 < b
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传空集,空值

以太坊网络

以太坊网络是一个点对点网络,节点参与其中以维护区块链并促进共识机制。根据需求和使用情况,网络可以分为三种类型。

MainNet

MainNet 是以太坊当前的实时网络。MainNet 的当前版本是 Homestead。

TestNet

TestNet 也称为 Ropsten,是以太坊区块链的测试网络。该区块链用于测试智能合约和 DApp,然后再部署到生产实时区块链。此外,作为测试网络,它允许实验和研究。

私有网络

顾名思义,这是可以通过生成新的创世块来创建的私有网络。这通常是分布式账本网络中的情况,在该网络中,一组私有实体启动自己的区块链并将其用作权限控制的区块链。

关于如何连接测试网络和如何设置私有网络的更多讨论将在下一章中进行。

支持的协议

有各种各样的支持协议正在开发中,以支持完全去中心化的生态系统。这包括 whisper 和 Swarm 协议。除了合同层(即核心区块链层)之外,还有其他需要去中心化的层,以实现完全去中心化的生态系统。这包括去中心化存储和去中心化消息传递。Whisper 正在为以太坊开发,是一种去中心化的消息传递协议,而 Swarm 是一种去中心化的存储协议。这两种技术目前正在开发中,并被设想为提供完全去中心化网络的基础。在接下来的部分中,将详细讨论这两种技术。

Whisper

Whisper 为以太坊网络提供了去中心化的点对点消息传递能力。实质上,whisper 是一种通信协议,节点使用它来相互通信。消息的数据和路由在 whisper 通信中是加密的。此外,它被设计用于较小的数据传输和不需要实时通信的场景。Whisper 还被设计为提供一个通信层,不能被追踪,并为各方提供“暗通信”。区块链可以用于通信,但这很昂贵,而且节点之间交换的消息并不真正需要共识。因此,whisper 可以用作允许

Whisper 已经与 geth 一起提供,并可以在运行 geth 以太坊客户端时使用--shh选项启用。

Swarm

Swarm 正在作为一个分布式文件存储平台进行开发。它是一个去中心化、分布式和点对点的存储网络。在该网络中,文件通过其内容的哈希进行寻址。这与传统的集中式服务形成对比,其中存储仅在中央位置可用。这是作为以太坊 Web 3.0 栈的本地基础层服务开发的。Swarm 与 Ethereum 的多协议网络层 DevP2P 集成。Swarm 设想为以太坊 Web 3.0 提供一个DDOS(分布式拒绝服务)-抵抗和容错的分布式存储层。尽管 Swarm 的概念验证和 alpha 代码已发布,但尚无稳定的生产版本可用。

下图概述了 Swarm 和 Whisper 如何结合并与区块链配合工作的高层次概述:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图表展示了区块链、Whisper 和 Swarm。

在以太坊上开发的应用程序。

在以太坊上有各种 DAO 和智能合约的实现,其中最显著的是DAO,它最近被黑客攻击,需要进行硬分叉才能恢复资金。DAO 被创建为一个分散的平台,用于收集和分发投资。

Augur 是另一个在以太坊上实施的 DAPP,它是一个去中心化的预测市场。各种其他去中心化应用程序列在 dapps.ethercasts.com/ 上。

可扩展性和安全性问题。

区块链中的可扩展性是一个基本问题。安全性也至关重要。隐私和机密性等问题已经导致了一些适应性问题,特别是在金融行业。然而,这些领域正在进行大量的研究。关于所有与区块链相关的问题的更详细讨论将在第十二章 中进行,可扩展性和其他挑战

总结

本章开始讨论了以太坊的历史,以太坊开发背后的动机以及以太坊客户端。然后,您被介绍了以太坊区块链的核心概念,如状态机模型、世界和机器状态、账户以及账户类型。此外,还详细介绍了以太坊虚拟机EVM)的核心组件。其他概念,如区块、区块结构、Gas 和消息也被详细介绍和讨论。本章的后续部分介绍了以太坊客户端的实际安装和管理。其中讨论了两个最流行的客户端,geth 和 parity。对这些客户端的进一步开发特定讨论将在下一章进行,该章将讨论使用以太坊进行开发。最后,还介绍了与以太坊面临的挑战相关的支持协议和主题。以太坊正在不断发展,并且由一群专注的开发者社区定期进行改进。以太坊改进提案,可在 github.com/ethereum/EIPs 获取,也是社区对这项技术研究和浓厚兴趣的体现。此外,最近推出的企业以太坊联盟EAA)旨在开发符合企业级业务需求的企业级以太坊平台。随着对可扩展性、优化、吞吐量、容量和安全性等主题的研究,预计以太坊将会随着时间的推移演变为更健壮、更用户友好和更稳定的区块链生态系统。

  • 24
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值