分类 区块链 下的文章

介绍

在这篇文章中,我们将讨论一个典型区块链的生态系统。这里说的生态系统,指的是不同的利益相关者及其相互之间,系统和外部世界间的相互作用。我们将要探索的不同利益相关者是:

  1. 用户
  2. 投资者
  3. 矿工
  4. 开发商

了解这些利益相关者如何融入区块链生态系统,不仅可以让您更好地了解区块链的运作方式,还可以让您更好地评估其增长潜力。区块链对于上述每个利益相关者来说越有吸引力,就越有可能健康的增长。所以,不多说了,下面介绍区块链生态系统的丰富的特色。

用户

用户是使用区块链或加密货币实现某些目的的普通人,而不仅仅是投资者。为维护用户,加密货币必须具有一些实用程序(用于花费你的钱币)。让我们快速浏览三个最受欢迎的区块链,以了解它们当前和潜在的效用。

比特币

比特币只有一个功能,即用于货物和服务的付款。在撰写本文时,全球约有 48,000 家(编者注:截止到 2018 年 9 月)商家接受比特币为商品和服务付款(Coinbase)。事实上,包括 PayPal、Expedia、微软、赛百味、彭博、Reddit、戴尔、Steam、Whole Foods、Shopify 和 Webjet 在内的几个家用品牌和主要电子商务公司都将自己的名字添加到了不断增长的比特币商家名单中。未来十年,这个名单将不可避免地继续增长,并且在不远的将来的某个时候,比特币完全有可能像 Visa、AMEX 或万事达卡那样被广泛接受。这可以说意味着比特币目前比任何其他区块链更具实用性。与传统支付方式相比,比特币支付的优势在于:

  • 更快的国际支付和交易
  • 交易费用非常低
  • 伪匿名
  • 没有第三方介入

商家的额外好处包括:

  • 没有 chargeback(编者注:Chargeback 是信用卡中的一个术语,意思是顾客可以声明一笔交易并非本人发起的。根据国家法律,这种情况往往商家或银行要负责对顾客的全额退款,是一种保护顾客的机制,但也给商家和银行增加了支付处理中的风险。)
  • 额外的客户群

由于比特币的高效用,其生态系统的相当大部分由用户组成。从长期投资的角度来看,这非常好,因为它可以提高价格稳定性,并为投资者提供有详实的数据(用户增长,商家采用,交易数量等)以便预测其价格。

以太坊

以太坊区块链与比特币区块链根本不同,因为它能够将智能合约嵌入区块链(见前一篇区块链历史介绍)。因此,以太坊为其用户提供了两种不同类型的应用:

货币应用:虽然不是以太坊的主要目标,但用户可以使用 Ether(以太币,以太坊区块链的加密货币)来支付商品和服务。一些公司(TenXToken CardMonaco)正在竞相通过其加密货币借记卡和 Coinify 等在线支付平台获取市场份额,为在线商家提供即插即用解决方案,以接受像以太币这样的加密货币作为支付。然而,目前,比特币仍然是加密货币的王者,以太和其他加密货币可能不得不追赶几年。

常规应用:这是指用户与基于以太坊区块链的 dApp 交互。已有数百个 dApp 允许用户以各种方式与以太坊区块链进行交互。例如,Numerai 是一种独特的对冲基金,它为世界各地的数据科学家提供加密市场数据,激励他们超越当前的交易算法并提高对冲基金的整体表现。还有一些彩票 dApp,以公平透明的方式提供彩票服务。然而,这只是一个开始。新的 dApp 每天都在发布,将来必定会有人开发出一款真正吸引公众注意力并引领下一波以太坊用户浪潮的 dApp。

可以在此处找到以太坊区块链上所有 dApp 的列表。

瑞波

市值排名第三的区块链是 瑞波 Ripple 。 瑞波与比特币和以太坊的不同之处在于它的设计考虑了一个特定的目标:为金融机构提供任何规模的安全,即时和近乎免费的全球交易。瑞波也与大多数区块链不同,因为它的目标用户是金融机构而不是私人。瑞波已经宣布与渣打银行和 UniCredit 等世界上大型金融机构建立合作伙伴关系,已经在区块链市场排行榜上获得第三名。

投资者

几乎所有区块链生态系统中的大多数利益相关者仍然是投资者。因此,加密货币市场仍然具有高度投机性,一天内价格波动 +/- 30% 或更多并不罕见。区块链市场如此不稳定的部分原因是,评估加密货币或 dApp 的真正价值极其困难。该技术仍然年轻,由于实用性有限导致缺乏用户,因此很难预测在大规模采用时该技术将如何。

尽管投资区块链技术存在许多陷阱,但目前的市场条件实际上是一个有吸引力的投资机会:

  • 专家、顾问和投资者几乎一致同意,区块链技术市场将在未来十年内继续快速增长(麦肯锡世界经济论坛
  • 进入壁垒仍然很高,大多数人不愿意进入市场
  • 虽然区块链在 2016 年和 2017 年都经历了令人难以置信的增长,但所有公共区块链的总市值仍然相对较小,约为 150 亿美元。为了更好地理解这一点,在撰写本文时,整个区块链行业的市值将只是世界第 50 大公司,位于荷兰的消费品公司联合利华之后。HowMuch.net 的这篇文章将加密货币的总市值与其他类型的资产进行了比较,并且展望了未来:

话虽如此,并非所有的区块链都是平等的……在接下来的几年里,我们无疑会看到很多初创公司倒闭或烧钱,导致投资者辛苦赚来的钱损失掉。我们将看到诈骗公司,其唯一目标是从愚蠢的投资者那里榨取资金。我们将看到来自成熟公司的激烈竞争,以开发自己的区块链应用程序。生活中没有任何东西是免费的。如果想把钱投入区块链,将不得不接受高风险。我们将有足够的时间在未来的博客文章中讨论投资策略,但现在我们将给您留下两个想法:

  1. 在投资任何公司之前,请积极研究至少一周。向自己提出有关投资的一些棘手问题。如果您无法回答问题,请与社区和开发人员联系。如果他们采用某些主观信息来回答,要持怀疑态度。如果他们不能充分回答您的问题,那么不是说一定就要停止投资,但请注意它是一种风险,并在购买之前将其考虑在内。
  2. 多样化。必须强调这一点。在接下来的几年里,很多公司都会陷入困境,如果你把所有的鸡蛋都放在一个篮子里,你不仅会冒失去钱的风险,还可能有失去对该行业中最终占据主导地位的公司投资机会的风险。

我认为在任何区块链生态系统中,有 4 种不同类型的投资者:

新手

区块链市场的巨大增长和不断增加的宣传吸引了成千上万的新投资者。很大一部分投资者会被潜在的收益所吸引,而没有去充分了解这项技术。新手用自己的情绪做决定,而且没有比害怕这种情绪更强迫人行动的了。害怕失去钱,也害怕失去机会。因此,新手的买入价格经常过高。

同样,如果价格下跌超过其初始买入点 10-20%,由于害怕失去所有资金,新手经常会卖出。这在超级易变的区块链市场尤其危险。因此,新手经常会买高卖低卖。

Vanguard 的结论是:

  1. 对于大多数私人非专业投资者来说,追求投机绩效常常影响回报率
  2. 市场波动性越大,追逐绩效的负面影响就越大

在区块链市场上很难不扮演新手的角色。即使您有先前的投资经验,区块链市场的不确定性和极端波动性也将考验您的意志力和自制力。

鲸鱼

鲸鱼是那些拥有庞大储备的大型投资者,他们可以使市场向某一个方向发展。

通常,订单约为 1-500 万美元或以上的人被视为鲸鱼。像这样的大订单足以显著影响大多数加密货币或区块链令牌。如果这种变化吸引了小玩家的注意,并对他们的钱进行相同的操作(如果价格上涨则买入,或者如果价格下降则卖出),鲸鱼可以在稍后的时间执行相反的操作以获取利润。

另一个深渊,即巨鲸。

巨鲸在这里指对冲基金和比特币投资基金,通常管理约 1 亿美元以上的投资组合。他们管理的资本过于庞大,一次下单市场常无法消化。他们通常会在一周或更长时间内将成千上万的比特币注入或流出市场,从而慢慢推动价格上涨或下跌,以满足他们自己的需求。

这些听起来可能令人难以置信,但区块链市场确实具有一些特征,使其成为具有正确手段和风险承受能力的高风险对冲基金的理想场所:

  • 没有规定
  • 相对较少的竞争
  • 小市场给大型企业带来优势
  • 大量缺乏经验的投资者

还有最后一个水下野兽,一个足以完全吞噬世界巨头并永远改变区块链市场的人。这里说的是政府投资者。政府可能有一天将加密货币作为一种多样化储备货币组合的方式,这种想法非常有趣,无疑会导致之前闻所未闻的价格水平 (Coin Telegraph)。

套利者

套利者不断寻找并利用不同在线交易所之间的小价格差距。他们与数百家交易所相连,如果有机会,他们将在澳大利亚交易所买入低价并在瑞士交易所卖出高价。你可能认为套利者正在破坏区块链生态系统,但它们实际上发挥了一个非常特别和重要的功能。它们稳定了交易所的价格。他们就像大海的清洁工一样,总是在海底搜寻,以寻找市场上的不合理处。

聪明的八爪鱼

这种投资者是你想成为的人!这种聪明的八足动物买得低,卖得很高。他们在做出决定之前进行了广泛的研究,并认识到风险和潜在的回报。这种聪明的八足动物认识到,利用加密货币的短期波动操作非常困难,要关注长期回报。他们避免情绪化决策,并通过价格波动坚持他们的投资,除非他们的投资有一些根本性的变化。这种聪明的八足动物认识到在区块链这样的新兴行业中识别赢家和输家是极其困难的。他们认识到总体行业风险,关注传统公司进入市场并密切关注他们的投资。

如果你发展出聪明的八爪鱼的特性,你将有很大机会在未来十年内为你的投资带来非常好的回报。

虽然很希望告诉你,我们属于最后一类,而且我们从未做过情绪化或恐惧驱动的决定,但事实并非如此。在这一点上,我们可能介于新手和聪明的八足动物之间。希望通过撰写此博客并继续获得区块链市场的经验,将在未来几年内把我们变成聪明的八足动物。我希望你能加入我们,成为这次旅程的积极参与者。我们可以共同学习和研究,做出更好的决策。

矿工

为了使区块链能够运行并保持其完整性,它需要世界各地的独立节点网络来持续维护它。在私有区块链中,中心组织拥有网络上的每个节点。而在公共区块链中,任何人都可以将其计算机设置为节点。这些计算机的所有者称为矿工。

由于区块链的完整性与网络上独立节点的数量直接相关,因此还需要一些挖矿激励。不同的区块链使用不同的采矿系统,但大多数采用以下形式:

  • 激励系统:最常见的是微交易费用和块解决方案奖励的组合(比特币矿工每解决一个比特币块,获得 12.5 BTC 奖励。按照约定奖励着时间的推移逐渐减少)。
  • 共识算法:所有区块链都需要一种验证广播到网络的块的方法。比特币区块链使用工作证明(PoW)。您将在下一篇文章中了解有关 PoW 如何工作的更多信息。以太坊也使用 PoW,但将更改为权益证明 (PoS)(以太坊区块链包含故意放置在代码中的 难度炸弹 difficulty bomb ,以强制在某些时候更改为 PoS。之后将详细介绍)。

正如您将在下一篇文章中看到的那样,挖掘一个块是非常困难的,一台计算机需要多年来实现。因此,个体矿工组建了采矿行会,将他们的资源汇集在一起​​并分享回报。blockchain.info 的资料显示了过去 4 天比特币区块链中每个采矿公会的相对哈希率(工作量)。

因为矿工需要保持区块链的完整性,所以他们拥有很大的权力。如果比特币社区想以这种或那种方式改变比特币协议,他们将不得不说服大多数矿工采用新代码。对现有区块链协议的更改称为分叉。潜在的分叉一直是采矿论坛上讨论的热门话题,没有中央权威就很难达成共识。

开发商

正如上一篇文章中所讨论的,区块链有可能变得不仅仅是加密货币。区块链世界中目前有两种类型的开发人员:

  • 区块链开发人员
  • dApp 开发人员

区块链开发人员构建具有不同功能级别的全新区块链。dApp 开发人员可以构建在区块链上运行的去中心化应用程序,从而为用户提供使用区块链(即实用程序)的理由。

以太坊推出的智能合约为渴望创造下一个重大事件的 dApp 开发者打开了大门。在评估区块链时,重要的是要考虑开发人员如何对其做出反应。有些问题要问自己,包括:

  • 该平台允许开发人员使用哪些脚本语言?
  • 社区是否有足够的活跃,能够说服开发人员花时间为该平台开发 dApp?
  • 区块链中是否有一些特殊功能,当 dApp 开发人员无法在更受欢迎的区块链上创建其应用,而在这个区块链上可以?
  • 区块链的可扩展性如何?如果它最终变得流行,代码是否能够处理大量的交易?

要充分利用区块链技术,您需要同时了解区块链和 dApp 开发中的最新消息。

结论

区块链生态系统复杂而充满活力。

了解这一点将使您能够做出更好的决策并充分利用这一新兴技术。你喜欢这篇博文吗?我们是否错过了任何利益相关者?您对不同的利益相关者及其对整个区块链生态系统的影响有何看法?你认为会看到政府在他们的储备中加入加密货币吗?

我们很乐意在下面的留言板上收到您的来信!如果您发现我们的内容有任何错误或错误,请随时通知我们,我们会及时更正。我们的下一篇文章将为您提供加密功能的概述,使区块链能够安全且伪匿名地工作。希望能在那里见到你!


via: https://www.myblockchainblog.com/blog/the-blockchain-ecosystem

作者:Vegard Nordahl & Meghana Rao 选题:jasminepeng 译者:jasminepeng 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

序幕

很久以前,在一个遥远的星系……一份题为“比特币:点对点电子现金系统”的神秘白皮书以笔名 中本聪 Satoshi Nakamoto 发布。该文件用他们自己的话说, “不依赖于信任的电子交易系统” a system for electronic transactions without relying on trust <br/>

时间是 2008 年 11 月,我们所说的遥远的星系就是互联网。这是比特币历史的开端。直到今天,没有人确切知道中本聪是谁。我们所知道的是,第一个开源比特币客户端于 2009 年 1 月发布,在接下来的几年中,中本聪积累了大约 100 万比特币,然后在 2010 年中期完全从比特币世界中消失。直到今天,他(或他们)庞大的比特币财富仍未受到影响,分布在几个已知的比特币账户中。截至 2017 年中期,这些比特币总价值约为 40 亿美元。

比特币的历史

2009 年推出的比特币是区块链技术的第一次真实应用。在接下来的五年里,区块链的历史几乎与比特币的历史同义。以下是此期间的粗略时间表:

以太坊的历史

2014 年是区块链历史上一个重要里程碑。在此之前,区块链技术的应用仅限于加密货币。尽管比特币协议已在该领域证明了自己,但它缺乏开发区块链应用程序所需的脚本语言,以拓展到加密货币外的应用领域。

Vitalik Buterin 多年来一直是比特币的重要发烧友,并且在 2012 年他 18 岁时已经共同创立了《 比特币杂志 Bitcoin Magazine 》!在他想更新原始比特币协议未获比特币社区同意后,Vitalik 就聚集了一个超级程序员团队,开发一个全新的区块链协议,其中包含所谓的 智能合约 smart contract ,允许程序员在其区块链中构建称作合约的脚本,并在满足某些条件时执行。Vitalik 将他的新区块链命名为 以太坊 Ethereum

在以太坊区块链上使用智能合约需要小额支付以太币,即以太坊的加密货币。这些小额支付称为“ 燃料 gas ”,并奖励给“挖出了”包含该交易的数据块的计算机节点。智能合约的使用案例非常多样化,很可能在未来许多年中我们不会完全理解它的用处(就像 90 年代初期互联网刚兴起时,我们不知道 Facebook、YouTube 和 Skype 将怎样改变世界)。

一个有助于描述智能合约有用性的简单例子是去中心化彩票。在下面的示例中,开发了具有以下功能的智能合约并将其存储在以太坊区块链中:

  • 任何人可以发送以太币给智能合约。
  • 每 24 小时,智能合约随机选择一个贡献地址,并将合约中的所有以太币返回到该地址。
  • 你贡献的以太币越多,获胜的机会就越高。
  • 由于智能合约存储在以太坊区块链中,其内容是公开的,任何人都可以检查它以确保它不包含任何错误或蹊跷的逻辑。没有人(甚至是开发者)能够动存储在智能合约上的资金。从理论上讲,这样的彩票运营支出最小(只有燃料成本和创建者在智能合约中内置的其他费用)。这种彩票相比传统彩票,优势显著:
  • 由于运营支出减少,获胜的几率可以大大提高。
  • 整个系统是完全透明的,每个参与者将能够在参与彩票之前准确计算他们获胜的机会。
  • 由于它是完全去中心化的,区块链彩票将不会面临破产以及许多其他外部风险因素。
  • 支付是保证和即时的。
  • 参与者是 伪匿名 pseudo-anonymous 的。

自 2014 年推出以来,以太坊区块链经历了一个显著的增长期,现在成为仅次于比特币的区块链。以下时间表显示了 2014 年以后比特币相关事件的历史。

未来会怎样

现在你已经了解了区块链的历史,让我们简单预测一下它的未来。如前所述,与传统的会计和记录保存方法相比,区块链应用程序的去中心化性质提供了显著的优势。在过去的 12 个月中,区块链技术向主流认可迈出了重要一步,数百家蓝筹公司在其基础设施上投入巨资(参见 Finextra)。几乎所有主要的咨询公司都公开宣称他们看好区块链技术对一系列行业的潜在影响(埃森哲路透社德勤普华永道),一些分析机构预测价格在未来十年价格会大幅上涨(NewsBTCCNBCMoney Morning)。虽然我们并没有拥有预测的水晶球,而且区块链的大规模使用肯定存在很多障碍,但这种技术的未来似乎比以往更加光明。

你喜欢这篇博文吗?我们是否错过了任何重要的区块链里程碑?您对区块链的未来有何看法?我们很乐意在下面的留言板上收到您的来信!我们的下一篇博文将为您提供我们称之为区块链生态系统的概述。希望能在那里见到你!


via: https://www.myblockchainblog.com/blog/a-brief-history-of-blockchain

作者:Vegard Nordahl & Meghana Rao 选题:jasminepeng 译者:jasminepeng 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

编者按:本系列区块链文章改编自网络文章,本文主要基于 Vegard Nordahl & Meghana Rao 的文章,并补充修订了部分内容。

我们为什么要写这个博客?

想象一下,你穿越到 1990 年代早期。当时,互联网还处于起步阶段,老百姓几乎没有理解它是如何运作的。

1993 年,全球互联网用户总数约为 1400 万,整个互联网由大约 130 个网站组成(ourworldindata.org)。大多数人都听说过互联网,但是对于绝大多数人来说,还很难看到它的前景。

1995 年左右,风险投资开始意识到万维网的巨大潜力,互联网从默默无闻变为主流。数百万美元投入到初创公司中,通常只包括一小部分程序员和一个涉及互联网的想法。尽管如此,人们对互联网还是持怀疑态度,大规模采用似乎还远未确定。

“我预测互联网将很快成为超新星,并在 1996 年灾难性地崩溃。”
—— 以太网发明者 Robert Metcalfe,InfoWorld,1995 年

“事实上,在线数据库不会取代你的日报,光盘不会可以取代一个称职的老师,计算机网络也不会改变政府的工作方式。”

  • 新闻周刊,1995年

一年后,互联网拥有了 7500 万用户。到 1999 年,它已在全球范围内增长到 2.8 亿用户。

两年后 Robert Metcalfe 在万维网大会上不得不“吃掉他的话”,他将他的专栏副本与一些水混合,在观众面前吃下去(wired)。而新闻周刊于 2012 年停止了纸质印刷,改为纯在线方式发售……

那么, Robert Metcalfe 和新闻周刊在互联网趋势的判断上出了什么问题呢?我们认为,他们严重低估了互联网减少低效从而提高人类创造价值的能力。互联网现在渗透到我们生活的各个方面的真正原因是它使得个人和企业的效率大大提高了。

今天,由于区块链这个技术创新的出现,人类又一次站在一个潜在的效率飞跃的十字路口。风投已开始意识到区块链的巨大潜力,向初创公司投入大量资金,这些公司通常只包括一小组程序员和一个涉及区块链的想法(weusecoins.com)。与此同时,老百姓对区块链的运作方式几乎没有了解。

本博客试图向小白们介绍区块链,让他们了解这项技术并教他们如何成为参与者。在本博客的过程中,我们将深入探讨区块链的一些技术方面,探索其用例,分析不同的区块链,为初学者提供分步指南。

区块链,一场会计革命

虽然区块链通常被认为是计算机技术的进步,但它更容易被理解为会计的进步。本质上讲,会计的任务是追踪交易和价值所有权。仔细思考的话,你会发现所有权是一种模糊的概念。所有权不是物品的固有属性。相反,所有权完全由共识决定。你可以在一个物体上写下你的名字或在房产上插上你自己的旗帜,但你必须能说服你社会中的其他人同意这是真正属于你的资产。既然所有权不是内在属性,我们如何在任何时间确定所有权?我们如何建立一个系统来确保所有权信息是安全的,并且不会被恶意用户改变?

这不是一个简单的问题,随着我们的社会变得越来越复杂,人类发明了越来越聪明的解决方式。在现代社会,确定和记录所有权的方式因资产类型而异,但通常可归结为以下内容。

当前的所有权跟踪系统
当前,物品、资产或创意的所有权由我们的法律系统决定,通常涉及书面或数字的所有权记录(例如,土地所有权、收据、版权文件、专利等)。当两个非信任方之间发生所有权转让时,我们依靠银行或政府组织等中介机构来获取信任、真实性和确定性。对于数字或非实物资产(如货币、股票、知识产权或数字媒体)尤其如此。如果两个人都声称对同一资产拥有所有权,或者记录的合法性存在争议,则通过法院或法庭来解决争议,确定所有权。

我们目前的所有权跟踪系统复杂、效率低、不是特别可靠,而且往往不是很透明。这包括让中间人参与并使文档难以伪造/复制。这就是为什么许多国家要求您支付印花税或其他税款,以使结婚证书和土地所有权等文件具有法律约束力和可执行性。这也是为什么需要 3 天才能汇款给国外的亲戚。中间人必须确保资金进入和离开正确的账户,并确保适当的记录完整无缺。所有信息记账的情况都是如此,它们的准确性至关重要,例如支付和货币系统、资产管理、监管合规和审计、房地产、记录管理、身份管理、投票、税收等。
这就是区块链技术的用武之地。

区块链本质上是一种会计工具,它大大简化了这一过程,并提供了一个不依赖中介的记录保存系统,而且它具有以下特点:

  • 快速高效
  • 不受伪造/黑客攻击
  • 可靠
  • 不可更改(一旦信息被锁定,就无法更改)
  • 透明
  • 不需要双方之间的信任

区块链的内部运作

简而言之,区块链是一个数据库,它包含不断增长的安全加密信息链接块,这些信息块通过独立的分散节点网络进行复制和分发。

是不是有点拗口?下面简单介绍下。

在区块链术语中,“ block ”只是被认为同时发生的信息的集合。想象它的最简单方法是将单个块想象为一个电子表格。

电子表格中的每一行都包含一条信息,例如交易信息,例如“Vega 向 Meg 发送 4 美元”。最终,电子表格块“完成”并链接到链中的前一个块。

然后,新添加的块被广播到网络中的每个节点。节点是用于区块链的计算机。

结果是包含数百万行信息的长链电子表格,复制并存储在不同的节点上。由于任何人都可以将计算机设置为节点,因此您最终会在全球范围内建立庞大的公有计算机网络,这些都有助于整个区块链的健康和安全。

让我们看一个具体的例子来准确理解信息如何通过区块链传输。Joe 想要使用世界上最知名的区块链 —— 比特币区块链将 $5 发送给 Jane。要做到这一点,Joe 所要做的就是在他的计算机上写出这笔交易的代码并将其广播到比特币区块链网络。

随着区块链网络上的计算机收到此消息,它将进入一个称为 未确认事务云 unconfirmed transaction cloud 的特殊位置。

区块链网络中的每台计算机都在持续监听未确认事务云,尝试以解决特殊谜题的方式对消息进行排序(之后会详细介绍)。

当计算机设法找到解决特殊谜题的方法时,他们将其广播到区块链网络的其余部分,并获得对首个解决谜题的计算机的奖品。

然后,未确认事务云中的消息变成一个整齐的块(电子表格),并且每个计算机在验证该解决方案确实解决了特殊谜题之后,将此块附加到区块链。

每个计算机节点都将整个区块链存储在其硬盘驱动器上,并且可以独立于区块链网络上的其他节点来验证传入的消息和块。整个系统去中心化,没有单点故障。

这基本上就是比特币区块链的工作原理:

  1. 用户将交易广播到区块链网络
  2. 计算机节点以解决特殊谜题的方式竞争,获得打包事务权
  3. 当节点可以正确打包事务时,它们会将解决方案广播到网络上的所有其他节点
  4. 每个节点独立地验证解决方案
  5. 如果解决方案有效并且块中仅包含可信事务,每个节点就独立地将新块附加到区块链

与传统会计系统相比,区块链的优点是:

  • 没有单点故障:如果一台计算机突然关闭或被黑客入侵,不会打扰或损害网络的其余部分。其余的计算机将继续向区块链添加电子表格块。
  • 去中心化系统:基于区块链技术的所有权记录不受某个实体或组织的控制。
  • 超级高效:在验证传入消息时不涉及人工。建立信任不需要中间人或中间人。一切都是通过计算机代码完成的,通过独立的公有计算机网络实现完整性。
  • 完全透明性:每个电子表格上的每一行都存储在网络上的每个节点上。因此,区块链中的所有信息都是公开的,如果怀疑存在不法行为,任何人都可以对其进行检查和审查。
  • 非实名 pseudo-anonymous :区块链中不存储任何姓名或个人信息。交易和账户余额是公开的;换句话说,非实名是指每个人在区块链上有一个和真实身份无关的虚拟身份,但是这个虚拟身份做的所有事情都是透明的。

区块链安全

上面这些可能听起来很诱人,但您可能仍有疑问。

世界上存在着无数超级聪明的恶意黑客,这个方案真的安全吗?

区块链公开存储,会有严重的隐私问题吗?

可以在区块链中使用的加密保护机制中找到这两个问题的答案。要了解破解区块链多么困难,您必须了解一些基础技术。大多数区块链使用两种加密技术的组合:加密哈希函数和数字签名,实现两个目标:

  • 确保块是不可变的。也就是说,确保每个块在区块链中的特定位置,并且改变顺序或改变块的内容是不可能的。
  • 由整个区块链网络验证广播的交易确实来自帐户的私钥持有者。

这些保护机制的内部工作非常有趣,将在之后详细介绍。

许多人认为网络安全本质上是不安全的,如果有足够的时间和激励,超级聪明的恶意黑客将总能找到窃取您信息的方法。

但事实并非如此。绝大多数区块链中使用的加密系统从未被破解。专家们普遍认为,目前的最佳加密方法对于普通计算机是不可击穿的。如果有人真的找到了方法来破解这些系统,区块链程序也无需太担心,因为我们的整个金融系统目前使用完全相同的加密技术。

以比特币为例来看区块链技术的安全性。比特币是世界上第一个也是目前最大的区块链加密货币,于 2009 年 1 月投入使用。从那时起,它的市值已经增长到 400 多亿美元(编者注:到2018年9月,市值已达一千多亿美元),每天大约有 300,000 个比特币交易。尽管如此,基本的比特币算法并没有出现过一次破坏。不过,对于这个行业来说,发生过多次比特币交易网站被黑客入侵。然而,比特币本身从未被黑客入侵,并且继续保持 100% 的跟踪记录,其表现完全符合其创建者的预期。

这并不是说比特币的处理没有风险。要正确处理任何加密货币,您需要采取一些预防措施,以确保那些超级聪明的恶意黑客无法访问您的帐户。区块链安全性将成为本系列的关键主题之一,因为我们坚信,赋予人们安全和自信地使用区块链技术的能力对于实现该技术的大规模采用至关重要。

随着区块链技术的成熟,我们希望您将来加入我们。我们确信这项技术将改变世界,也很高兴能够在这个早期阶段参与这一旅程。

所以,无论你以前从未听说过区块链,你是一个想要了解更多技术的爱好者,或者你是寻找新机会的投资者,你来对了地方。我们将努力定期更新我们的系列文章,并提供关于区块链技术各方面的细致,公正的观点。

你喜欢这篇博文吗?我们很乐意在下面的留言板上收到您的来信!如果您在我们的内容中发现任何错误或错误,请随时告诉我们,我们会及时更正。我们的下一篇文章将简要介绍区块链和比特币的历史。希望能在那里见到你!


via: https://www.myblockchainblog.com/blog/what-the-hell-is-blockchain

作者:Vegard Nordahl & Meghana Rao 选题:jasminepeng 译者:jasminepeng 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

了解区块链是如何工作的最快的方法是构建一个。

你看到这篇文章是因为和我一样,对加密货币的大热而感到兴奋。并且想知道区块链是如何工作的 —— 它们背后的技术基础是什么。

但是理解区块链并不容易 —— 至少对我来说是这样。我徜徉在各种难懂的视频中,并且因为示例太少而陷入深深的挫败感中。

我喜欢在实践中学习。这会使得我在代码层面上处理主要问题,从而可以让我坚持到底。如果你也是这么做的,在本指南结束的时候,你将拥有一个功能正常的区块链,并且实实在在地理解了它的工作原理。

开始之前 …

记住,区块链是一个 不可更改的、有序的 记录(被称为区块)的链。它们可以包括 交易 transaction 、文件或者任何你希望的真实数据。最重要的是它们是通过使用哈希链接到一起的。

如果你不知道哈希是什么,这里有解释

本指南的目标读者是谁? 你应该能轻松地读、写一些基本的 Python 代码,并能够理解 HTTP 请求是如何工作的,因为我们讨论的区块链将基于 HTTP。

我需要做什么? 确保安装了 Python 3.6+(以及 pip),还需要去安装 Flask 和非常好用的 Requests 库:

pip install Flask==0.12.2 requests==2.18.4 

当然,你也需要一个 HTTP 客户端,像 Postman 或者 cURL。哪个都行。

最终的代码在哪里可以找到? 源代码在 这里

第 1 步:构建一个区块链

打开你喜欢的文本编辑器或者 IDE,我个人喜欢 PyCharm。创建一个名为 blockchain.py 的新文件。我将仅使用一个文件,如果你看晕了,可以去参考 源代码

描述一个区块链

我们将创建一个 Blockchain 类,它的构造函数将去初始化一个空列表(去存储我们的区块链),以及另一个列表去保存交易。下面是我们的类规划:

class Blockchain(object):
    def __init__(self):
        self.chain = []
        self.current_transactions = []

    def new_block(self):
        # Creates a new Block and adds it to the chain
        pass

    def new_transaction(self):
        # Adds a new transaction to the list of transactions
        pass

    @staticmethod
    def hash(block):
        # Hashes a Block
        pass

    @property
    def last_block(self):
        # Returns the last Block in the chain
        pass

我们的 Blockchain 类的原型

我们的 Blockchain 类负责管理链。它将存储交易并且有一些为链中增加新区块的辅助性质的方法。现在我们开始去充实一些类的方法。

区块是什么样子的?

每个区块有一个索引、一个时间戳(Unix 时间)、一个交易的列表、一个证明(后面会详细解释)、以及前一个区块的哈希。

单个区块的示例应该是下面的样子:

block = {
    'index': 1,
    'timestamp': 1506057125.900785,
    'transactions': [
        {
            'sender': "8527147fe1f5426f9dd545de4b27ee00",
            'recipient': "a77f5cdfa2934df3954a5c7c7da5df1f",
            'amount': 5,
        }
    ],
    'proof': 324984774000,
    'previous_hash': "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
}

我们的区块链中的块示例

此刻,链的概念应该非常明显 —— 每个新区块包含它自身的信息和前一个区域的哈希。这一点非常重要,因为这就是区块链不可更改的原因:如果攻击者修改了一个早期的区块,那么所有的后续区块将包含错误的哈希。

这样做有意义吗?如果没有,就让时间来埋葬它吧 —— 这就是区块链背后的核心思想。

添加交易到一个区块

我们将需要一种区块中添加交易的方式。我们的 new_transaction() 就是做这个的,它非常简单明了:

class Blockchain(object):
    ...

    def new_transaction(self, sender, recipient, amount):
        """
        Creates a new transaction to go into the next mined Block
        :param sender: <str> Address of the Sender
        :param recipient: <str> Address of the Recipient
        :param amount: <int> Amount
        :return: <int> The index of the Block that will hold this transaction
        """

        self.current_transactions.append({
            'sender': sender,
            'recipient': recipient,
            'amount': amount,
        })

        return self.last_block['index'] + 1

new_transaction() 运行后将在列表中添加一个交易,它返回添加交易后的那个区块的索引 —— 那个区块接下来将被挖矿。提交交易的用户后面会用到这些。

创建新区块

当我们的 Blockchain 被实例化后,我们需要一个创世区块(一个没有祖先的区块)来播种它。我们也需要去添加一些 “证明” 到创世区块,它是挖矿(工作量证明 PoW)的成果。我们在后面将讨论更多挖矿的内容。

除了在我们的构造函数中创建创世区块之外,我们还需要写一些方法,如 new_block()new_transaction() 以及 hash()

import hashlib
import json
from time import time


class Blockchain(object):
    def __init__(self):
        self.current_transactions = []
        self.chain = []

        # Create the genesis block
        self.new_block(previous_hash=1, proof=100)

    def new_block(self, proof, previous_hash=None):
        """
        Create a new Block in the Blockchain
        :param proof: <int> The proof given by the Proof of Work algorithm
        :param previous_hash: (Optional) <str> Hash of previous Block
        :return: <dict> New Block
        """

        block = {
            'index': len(self.chain) + 1,
            'timestamp': time(),
            'transactions': self.current_transactions,
            'proof': proof,
            'previous_hash': previous_hash or self.hash(self.chain[-1]),
        }

        # Reset the current list of transactions
        self.current_transactions = []

        self.chain.append(block)
        return block

    def new_transaction(self, sender, recipient, amount):
        """
        Creates a new transaction to go into the next mined Block
        :param sender: <str> Address of the Sender
        :param recipient: <str> Address of the Recipient
        :param amount: <int> Amount
        :return: <int> The index of the Block that will hold this transaction
        """
        self.current_transactions.append({
            'sender': sender,
            'recipient': recipient,
            'amount': amount,
        })

        return self.last_block['index'] + 1

    @property
    def last_block(self):
        return self.chain[-1]

    @staticmethod
    def hash(block):
        """
        Creates a SHA-256 hash of a Block
        :param block: <dict> Block
        :return: <str>
        """

        # We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes
        block_string = json.dumps(block, sort_keys=True).encode()
        return hashlib.sha256(block_string).hexdigest()

上面的内容简单明了 —— 我添加了一些注释和文档字符串,以使代码清晰可读。到此为止,表示我们的区块链基本上要完成了。但是,你肯定想知道新区块是如何被创建、打造或者挖矿的。

理解工作量证明

工作量证明 Proof of Work (PoW)算法是在区块链上创建或者挖出新区块的方法。PoW 的目标是去撞出一个能够解决问题的数字。这个数字必须满足“找到它很困难但是验证它很容易”的条件 —— 网络上的任何人都可以计算它。这就是 PoW 背后的核心思想。

我们来看一个非常简单的示例来帮助你了解它。

我们来解决一个问题,一些整数 x 乘以另外一个整数 y 的结果的哈希值必须以 0 结束。因此,hash(x * y) = ac23dc…0。为简单起见,我们先把 x = 5 固定下来。在 Python 中的实现如下:

from hashlib import sha256

x = 5
y = 0  # We don't know what y should be yet...

while sha256(f'{x*y}'.encode()).hexdigest()[-1] != "0":
    y += 1

print(f'The solution is y = {y}')

在这里的答案是 y = 21。因为它产生的哈希值是以 0 结尾的:

hash(5 * 21) = 1253e9373e...5e3600155e860

在比特币中,工作量证明算法被称之为 Hashcash。与我们上面的例子没有太大的差别。这就是矿工们进行竞赛以决定谁来创建新块的算法。一般来说,其难度取决于在一个字符串中所查找的字符数量。然后矿工会因其做出的求解而得到奖励的币——在一个交易当中。

网络上的任何人都可以很容易地去核验它的答案。

实现基本的 PoW

为我们的区块链来实现一个简单的算法。我们的规则与上面的示例类似:

找出一个数字 p,它与前一个区块的答案进行哈希运算得到一个哈希值,这个哈希值的前四位必须是由 0 组成。
import hashlib
import json

from time import time
from uuid import uuid4


class Blockchain(object):
    ...

    def proof_of_work(self, last_proof):
        """
        Simple Proof of Work Algorithm:
         - Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p'
         - p is the previous proof, and p' is the new proof
        :param last_proof: <int>
        :return: <int>
        """

        proof = 0
        while self.valid_proof(last_proof, proof) is False:
            proof += 1

        return proof

    @staticmethod
    def valid_proof(last_proof, proof):
        """
        Validates the Proof: Does hash(last_proof, proof) contain 4 leading zeroes?
        :param last_proof: <int> Previous Proof
        :param proof: <int> Current Proof
        :return: <bool> True if correct, False if not.
        """

        guess = f'{last_proof}{proof}'.encode()
        guess_hash = hashlib.sha256(guess).hexdigest()
        return guess_hash[:4] == "0000"

为了调整算法的难度,我们可以修改前导 0 的数量。但是 4 个零已经足够难了。你会发现,将前导 0 的数量每增加一,那么找到正确答案所需要的时间难度将大幅增加。

我们的类基本完成了,现在我们开始去使用 HTTP 请求与它交互。

第 2 步:以 API 方式去访问我们的区块链

我们将使用 Python Flask 框架。它是个微框架,使用它去做端点到 Python 函数的映射很容易。这样我们可以使用 HTTP 请求基于 web 来与我们的区块链对话。

我们将创建三个方法:

  • /transactions/new 在一个区块上创建一个新交易
  • /mine 告诉我们的服务器去挖矿一个新区块
  • /chain 返回完整的区块链

配置 Flask

我们的 “服务器” 将在我们的区块链网络中产生一个单个的节点。我们来创建一些样板代码:

import hashlib
import json
from textwrap import dedent
from time import time
from uuid import uuid4

from flask import Flask


class Blockchain(object):
    ...


# Instantiate our Node
app = Flask(__name__)

# Generate a globally unique address for this node
node_identifier = str(uuid4()).replace('-', '')

# Instantiate the Blockchain
blockchain = Blockchain()


@app.route('/mine', methods=['GET'])
def mine():
    return "We'll mine a new Block"

@app.route('/transactions/new', methods=['POST'])
def new_transaction():
    return "We'll add a new transaction"

@app.route('/chain', methods=['GET'])
def full_chain():
    response = {
        'chain': blockchain.chain,
        'length': len(blockchain.chain),
    }
    return jsonify(response), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

对上面的代码,我们做添加一些详细的解释:

  • Line 15:实例化我们的节点。更多关于 Flask 的知识读 这里
  • Line 18:为我们的节点创建一个随机的名字。
  • Line 21:实例化我们的区块链类。
  • Line 24–26:创建 /mine 端点,这是一个 GET 请求。
  • Line 28–30:创建 /transactions/new 端点,这是一个 POST 请求,因为我们要发送数据给它。
  • Line 32–38:创建 /chain 端点,它返回全部区块链。
  • Line 40–41:在 5000 端口上运行服务器。

交易端点

这就是对一个交易的请求,它是用户发送给服务器的:

{
 "sender": "my address",
 "recipient": "someone else's address",
 "amount": 5
}

因为我们已经有了添加交易到块中的类方法,剩下的就很容易了。让我们写个函数来添加交易:

import hashlib
import json
from textwrap import dedent
from time import time
from uuid import uuid4

from flask import Flask, jsonify, request

...

@app.route('/transactions/new', methods=['POST'])
def new_transaction():
    values = request.get_json()

    # Check that the required fields are in the POST'ed data
    required = ['sender', 'recipient', 'amount']
    if not all(k in values for k in required):
        return 'Missing values', 400

    # Create a new Transaction
    index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])

    response = {'message': f'Transaction will be added to Block {index}'}
    return jsonify(response), 201

创建交易的方法

挖矿端点

我们的挖矿端点是见证奇迹的地方,它实现起来很容易。它要做三件事情:

  1. 计算工作量证明
  2. 因为矿工(我们)添加一个交易而获得报酬,奖励矿工(我们) 1 个币
  3. 通过将它添加到链上而打造一个新区块
import hashlib
import json

from time import time
from uuid import uuid4

from flask import Flask, jsonify, request

...

@app.route('/mine', methods=['GET'])
def mine():
    # We run the proof of work algorithm to get the next proof...
    last_block = blockchain.last_block
    last_proof = last_block['proof']
    proof = blockchain.proof_of_work(last_proof)

    # We must receive a reward for finding the proof.
    # The sender is "0" to signify that this node has mined a new coin.
    blockchain.new_transaction(
        sender="0",
        recipient=node_identifier,
        amount=1,
    )

    # Forge the new Block by adding it to the chain
    previous_hash = blockchain.hash(last_block)
    block = blockchain.new_block(proof, previous_hash)

    response = {
        'message': "New Block Forged",
        'index': block['index'],
        'transactions': block['transactions'],
        'proof': block['proof'],
        'previous_hash': block['previous_hash'],
    }
    return jsonify(response), 200

注意,挖掘出的区块的接收方是我们的节点地址。现在,我们所做的大部分工作都只是与我们的 Blockchain 类的方法进行交互的。到目前为止,我们已经做完了,现在开始与我们的区块链去交互。

第 3 步:与我们的区块链去交互

你可以使用简单的 cURL 或者 Postman 通过网络与我们的 API 去交互。

启动服务器:

$ python blockchain.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

我们通过生成一个 GET 请求到 http://localhost:5000/mine 去尝试挖一个区块:

使用 Postman 去生成一个 GET 请求

我们通过生成一个 POST 请求到 http://localhost:5000/transactions/new 去创建一个区块,请求数据包含我们的交易结构:

使用 Postman 去生成一个 POST 请求

如果你不使用 Postman,也可以使用 cURL 去生成一个等价的请求:

$ curl -X POST -H "Content-Type: application/json" -d '{
 "sender": "d4ee26eee15148ee92c6cd394edd974e",
 "recipient": "someone-other-address",
 "amount": 5
}' "http://localhost:5000/transactions/new"

我重启动我的服务器,然后我挖到了两个区块,这样总共有了 3 个区块。我们通过请求 http://localhost:5000/chain 来检查整个区块链:

{
  "chain": [
    {
      "index": 1,
      "previous_hash": 1,
      "proof": 100,
      "timestamp": 1506280650.770839,
      "transactions": []
    },
    {
      "index": 2,
      "previous_hash": "c099bc...bfb7",
      "proof": 35293,
      "timestamp": 1506280664.717925,
      "transactions": [
        {
          "amount": 1,
          "recipient": "8bbcb347e0634905b0cac7955bae152b",
          "sender": "0"
        }
      ]
    },
    {
      "index": 3,
      "previous_hash": "eff91a...10f2",
      "proof": 35089,
      "timestamp": 1506280666.1086972,
      "transactions": [
        {
          "amount": 1,
          "recipient": "8bbcb347e0634905b0cac7955bae152b",
          "sender": "0"
        }
      ]
    }
  ],
  "length": 3
}

第 4 步:共识

这是很酷的一个地方。我们已经有了一个基本的区块链,它可以接收交易并允许我们去挖掘出新区块。但是区块链的整个重点在于它是 去中心化的 decentralized 。而如果它们是去中心化的,那我们如何才能确保它们表示在同一个区块链上?这就是 共识 Consensus 问题,如果我们希望在我们的网络上有多于一个的节点运行,那么我们将必须去实现一个共识算法。

注册新节点

在我们能实现一个共识算法之前,我们需要一个办法去让一个节点知道网络上的邻居节点。我们网络上的每个节点都保留有一个该网络上其它节点的注册信息。因此,我们需要更多的端点:

  1. /nodes/register 以 URL 的形式去接受一个新节点列表
  2. /nodes/resolve 去实现我们的共识算法,由它来解决任何的冲突 —— 确保节点有一个正确的链。

我们需要去修改我们的区块链的构造函数,来提供一个注册节点的方法:

...
from urllib.parse import urlparse
...


class Blockchain(object):
    def __init__(self):
        ...
        self.nodes = set()
        ...

    def register_node(self, address):
        """
        Add a new node to the list of nodes
        :param address: <str> Address of node. Eg. 'http://192.168.0.5:5000'
        :return: None
        """

        parsed_url = urlparse(address)
        self.nodes.add(parsed_url.netloc)

一个添加邻居节点到我们的网络的方法

注意,我们将使用一个 set() 去保存节点列表。这是一个非常合算的方式,它将确保添加的节点是 幂等 idempotent 的 —— 这意味着不论你将特定的节点添加多少次,它都是精确地只出现一次。

实现共识算法

正如前面提到的,当一个节点与另一个节点有不同的链时就会产生冲突。为解决冲突,我们制定一个规则,即最长的有效的链才是权威的链。换句话说就是,网络上最长的链就是事实上的区块链。使用这个算法,可以在我们的网络上节点之间达到共识。

...
import requests


class Blockchain(object)
    ...

    def valid_chain(self, chain):
        """
        Determine if a given blockchain is valid
        :param chain: <list> A blockchain
        :return: <bool> True if valid, False if not
        """

        last_block = chain[0]
        current_index = 1

        while current_index < len(chain):
            block = chain[current_index]
            print(f'{last_block}')
            print(f'{block}')
            print("\n-----------\n")
            # Check that the hash of the block is correct
            if block['previous_hash'] != self.hash(last_block):
                return False

            # Check that the Proof of Work is correct
            if not self.valid_proof(last_block['proof'], block['proof']):
                return False

            last_block = block
            current_index += 1

        return True

    def resolve_conflicts(self):
        """
        This is our Consensus Algorithm, it resolves conflicts
        by replacing our chain with the longest one in the network.
        :return: <bool> True if our chain was replaced, False if not
        """

        neighbours = self.nodes
        new_chain = None

        # We're only looking for chains longer than ours
        max_length = len(self.chain)

        # Grab and verify the chains from all the nodes in our network
        for node in neighbours:
            response = requests.get(f'http://{node}/chain')

            if response.status_code == 200:
                length = response.json()['length']
                chain = response.json()['chain']

                # Check if the length is longer and the chain is valid
                if length > max_length and self.valid_chain(chain):
                    max_length = length
                    new_chain = chain

        # Replace our chain if we discovered a new, valid chain longer than ours
        if new_chain:
            self.chain = new_chain
            return True

        return False

第一个方法 valid_chain() 是负责来检查链是否有效,它通过遍历区块链上的每个区块并验证它们的哈希和工作量证明来检查这个区块链是否有效。

resolve_conflicts() 方法用于遍历所有的邻居节点,下载它们的链并使用上面的方法去验证它们是否有效。如果找到有效的链,确定谁是最长的链,然后我们就用最长的链来替换我们的当前的链。

在我们的 API 上来注册两个端点,一个用于添加邻居节点,另一个用于解决冲突:

@app.route('/nodes/register', methods=['POST'])
def register_nodes():
    values = request.get_json()

    nodes = values.get('nodes')
    if nodes is None:
        return "Error: Please supply a valid list of nodes", 400

    for node in nodes:
        blockchain.register_node(node)

    response = {
        'message': 'New nodes have been added',
        'total_nodes': list(blockchain.nodes),
    }
    return jsonify(response), 201


@app.route('/nodes/resolve', methods=['GET'])
def consensus():
    replaced = blockchain.resolve_conflicts()

    if replaced:
        response = {
            'message': 'Our chain was replaced',
            'new_chain': blockchain.chain
        }
    else:
        response = {
            'message': 'Our chain is authoritative',
            'chain': blockchain.chain
        }

    return jsonify(response), 200

这种情况下,如果你愿意,可以使用不同的机器来做,然后在你的网络上启动不同的节点。或者是在同一台机器上使用不同的端口启动另一个进程。我是在我的机器上使用了不同的端口启动了另一个节点,并将它注册到了当前的节点上。因此,我现在有了两个节点:http://localhost:5000http://localhost:5001

注册一个新节点

我接着在节点 2 上挖出一些新区块,以确保这个链是最长的。之后我在节点 1 上以 GET 方式调用了 /nodes/resolve,这时,节点 1 上的链被共识算法替换成节点 2 上的链了:

工作中的共识算法

然后将它们封装起来 … 找一些朋友来帮你一起测试你的区块链。


我希望以上内容能够鼓舞你去创建一些新的东西。我是加密货币的狂热拥护者,因此我相信区块链将迅速改变我们对经济、政府和记录保存的看法。

更新: 我正计划继续它的第二部分,其中我将扩展我们的区块链,使它具备交易验证机制,同时讨论一些你可以在其上产生你自己的区块链的方式。(LCTT 译注:第二篇并没有~!)


via: https://hackernoon.com/learn-blockchains-by-building-one-117428612f46

作者:Daniel van Flymen 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

虽然有些人认为区块链是一个早晚会出现问题的解决方案,但是毫无疑问,这个创新技术是一个计算机技术上的奇迹。那么,究竟什么是区块链呢?

区块链

比特币 Bitcoin 或其它加密货币按时间顺序公开地记录交易的数字账本。

更通俗的说,它是一个公开的数据库,新的数据存储在被称之为 区块 block 的容器中,并被添加到一个不可变的 chain 中(因此被称为 区块链 blockchain ),之前添加的数据也在该链中。对于比特币或其它加密货币来说,这些数据就是一组组交易,不过,也可以是其它任何类型的数据。

区块链技术带来了全新的、完全数字化的货币,如比特币和 莱特币 Litecoin ,它们并不由任何中心机构管理。这给那些认为当今的银行系统是骗局并将最终走向失败的人带来了自由。区块链也革命性地改变了分布式计算的技术形式,如 以太坊 Ethereum 就引入了一种有趣的概念: 智能合约 smart contract

在这篇文章中,我将用不到 50 行的 Python 2.x 代码实现一个简单的区块链,我把它叫做 SnakeCoin。

不到 50 行代码的区块链

我们首先将从定义我们的区块是什么开始。在区块链中,每个区块随同时间戳及可选的索引一同存储。在 SnakeCoin 中,我们会存储这两者。为了确保整个区块链的完整性,每个区块都会有一个自识别的哈希值。如在比特币中,每个区块的哈希是该块的索引、时间戳、数据和前一个区块的哈希值等数据的加密哈希值。这里提及的“数据”可以是任何你想要的数据。

import hashlib as hasher

class Block:
  def __init__(self, index, timestamp, data, previous_hash):
    self.index = index
    self.timestamp = timestamp
    self.data = data
    self.previous_hash = previous_hash
    self.hash = self.hash_block()
  
  def hash_block(self):
    sha = hasher.sha256()
    sha.update(str(self.index) + 
               str(self.timestamp) + 
               str(self.data) + 
               str(self.previous_hash))
    return sha.hexdigest()

真棒,现在我们有了区块的结构了,不过我们需要创建的是一个区块链。我们需要把区块添加到一个实际的链中。如我们之前提到过的,每个区块都需要前一个区块的信息。但问题是,该区块链中的第一个区块在哪里?好吧,这个第一个区块,也称之为创世区块,是一个特别的区块。在很多情况下,它是手工添加的,或通过独特的逻辑添加的。

我们将创建一个函数来简单地返回一个创世区块解决这个问题。这个区块的索引为 0 ,其包含一些任意的数据值,其“前一哈希值”参数也是任意值。

import datetime as date

def create_genesis_block():
  # Manually construct a block with
  # index zero and arbitrary previous hash
  return Block(0, date.datetime.now(), "Genesis Block", "0")

现在我们可以创建创世区块了,我们需要一个函数来生成该区块链中的后继区块。该函数将获取链中的前一个区块作为参数,为要生成的区块创建数据,并用相应的数据返回新的区块。新的区块的哈希值来自于之前的区块,这样每个新的区块都提升了该区块链的完整性。如果我们不这样做,外部参与者就很容易“改变过去”,把我们的链替换为他们的新链了。这个哈希链起到了加密的证明作用,并有助于确保一旦一个区块被添加到链中,就不能被替换或移除。

def next_block(last_block):
  this_index = last_block.index + 1
  this_timestamp = date.datetime.now()
  this_data = "Hey! I'm block " + str(this_index)
  this_hash = last_block.hash
  return Block(this_index, this_timestamp, this_data, this_hash)

这就是主要的部分。

现在我们能创建自己的区块链了!在这里,这个区块链是一个简单的 Python 列表。其第一个的元素是我们的创世区块,我们会添加后继区块。因为 SnakeCoin 是一个极小的区块链,我们仅仅添加了 20 个区块。我们通过循环来完成它。

# Create the blockchain and add the genesis block
blockchain = [create_genesis_block()]
previous_block = blockchain[0]

# How many blocks should we add to the chain
# after the genesis block
num_of_blocks_to_add = 20

# Add blocks to the chain
for i in range(0, num_of_blocks_to_add):
  block_to_add = next_block(previous_block)
  blockchain.append(block_to_add)
  previous_block = block_to_add
  # Tell everyone about it!
  print "Block #{} has been added to the blockchain!".format(block_to_add.index)
  print "Hash: {}\n".format(block_to_add.hash) 

让我们看看我们的成果:

别担心,它将一直添加到 20 个区块

很好,我们的区块链可以工作了。如果你想要在主控台查看更多的信息,你可以编辑其完整的源代码并输出每个区块的时间戳或数据。

这就是 SnakeCoin 所具有的功能。要使 SnakeCoin 达到现今的产品级的区块链的高度,我们需要添加更多的功能,如服务器层,以在多台机器上跟踪链的改变,并通过工作量证明算法(POW)来限制给定时间周期内可以添加的区块数量。

如果你想了解更多技术细节,你可以在这里查看最初的比特币白皮书

让这个极小区块链稍微变大些

这个极小的区块链及其简单,自然也相对容易完成。但是因其简单也带来了一些缺陷。首先,SnakeCoin 仅能运行在单一的一台机器上,所以它相距分布式甚远,更别提去中心化了。其次,区块添加到区块链中的速度同在主机上创建一个 Python 对象并添加到列表中一样快。在我们的这个简单的区块链中,这不是问题,但是如果我们想让 SnakeCoin 成为一个实际的加密货币,我们就需要控制在给定时间内能创建的区块(和币)的数量。

从现在开始,SnakeCoin 中的“数据”将是交易数据,每个区块的“数据”字段都将是一些交易信息的列表。接着我们来定义“交易”。每个“交易”是一个 JSON 对象,其记录了币的发送者、接收者和转移的 SnakeCoin 数量。注:交易信息是 JSON 格式,原因我很快就会说明。

{
  "from": "71238uqirbfh894-random-public-key-a-alkjdflakjfewn204ij",
  "to": "93j4ivnqiopvh43-random-public-key-b-qjrgvnoeirbnferinfo",
  "amount": 3
}

现在我们知道了交易信息看起来的样子了,我们需要一个办法来将其加到我们的区块链网络中的一台计算机(称之为节点)中。要做这个事情,我们会创建一个简单的 HTTP 服务器,以便每个用户都可以让我们的节点知道发生了新的交易。节点可以接受 POST 请求,请求数据为如上的交易信息。这就是为什么交易信息是 JSON 格式的:我们需要它们可以放在请求信息中传递给服务器。

$ pip install flask # 首先安装 Web 服务器框架
from flask import Flask
from flask import request
node = Flask(__name__)

# Store the transactions that
# this node has in a list
this_nodes_transactions = []

@node.route('/txion', methods=['POST'])
def transaction():
  if request.method == 'POST':
    # On each new POST request,
    # we extract the transaction data
    new_txion = request.get_json()
    # Then we add the transaction to our list
    this_nodes_transactions.append(new_txion)
    # Because the transaction was successfully
    # submitted, we log it to our console
    print "New transaction"
    print "FROM: {}".format(new_txion['from'])
    print "TO: {}".format(new_txion['to'])
    print "AMOUNT: {}\n".format(new_txion['amount'])
    # Then we let the client know it worked out
    return "Transaction submission successful\n"

node.run()

真棒!现在我们有了一种保存用户彼此发送 SnakeCoin 的记录的方式。这就是为什么人们将区块链称之为公共的、分布式账本:所有的交易信息存储给所有人看,并被存储在该网络的每个节点上。

但是,有个问题:人们从哪里得到 SnakeCoin 呢?现在还没有办法得到,还没有一个称之为 SnakeCoin 这样的东西,因为我们还没有创建和分发任何一个币。要创建新的币,人们需要“挖”一个新的 SnakeCoin 区块。当他们成功地挖到了新区块,就会创建出一个新的 SnakeCoin ,并奖励给挖出该区块的人(矿工)。一旦挖矿的矿工将 SnakeCoin 发送给别人,这个币就流通起来了。

我们不想让挖新的 SnakeCoin 区块太容易,因为这将导致 SnakeCoin 太多了,其价值就变低了;同样,我们也不想让它变得太难,因为如果没有足够的币供每个人使用,它们对于我们来说就太昂贵了。为了控制挖新的 SnakeCoin 区块的难度,我们会实现一个 工作量证明 Proof-of-Work (PoW)算法。工作量证明基本上就是一个生成某个项目比较难,但是容易验证(其正确性)的算法。这个项目被称之为“证明”,听起来就像是它证明了计算机执行了特定的工作量。

在 SnakeCoin 中,我们创建了一个简单的 PoW 算法。要创建一个新区块,矿工的计算机需要递增一个数字,当该数字能被 9 (“SnakeCoin” 这个单词的字母数)整除时,这就是最后这个区块的证明数字,就会挖出一个新的 SnakeCoin 区块,而该矿工就会得到一个新的 SnakeCoin。

# ...blockchain
# ...Block class definition

miner_address = "q3nf394hjg-random-miner-address-34nf3i4nflkn3oi"

def proof_of_work(last_proof):
  # Create a variable that we will use to find
  # our next proof of work
  incrementor = last_proof + 1
  # Keep incrementing the incrementor until
  # it's equal to a number divisible by 9
  # and the proof of work of the previous
  # block in the chain
  while not (incrementor % 9 == 0 and incrementor % last_proof == 0):
    incrementor += 1
  # Once that number is found,
  # we can return it as a proof
  # of our work
  return incrementor

@node.route('/mine', methods = ['GET'])
def mine():
  # Get the last proof of work
  last_block = blockchain[len(blockchain) - 1]
  last_proof = last_block.data['proof-of-work']
  # Find the proof of work for
  # the current block being mined
  # Note: The program will hang here until a new
  #       proof of work is found
  proof = proof_of_work(last_proof)
  # Once we find a valid proof of work,
  # we know we can mine a block so 
  # we reward the miner by adding a transaction
  this_nodes_transactions.append(
    { "from": "network", "to": miner_address, "amount": 1 }
  )
  # Now we can gather the data needed
  # to create the new block
  new_block_data = {
    "proof-of-work": proof,
    "transactions": list(this_nodes_transactions)
  }
  new_block_index = last_block.index + 1
  new_block_timestamp = this_timestamp = date.datetime.now()
  last_block_hash = last_block.hash
  # Empty transaction list
  this_nodes_transactions[:] = []
  # Now create the
  # new block!
  mined_block = Block(
    new_block_index,
    new_block_timestamp,
    new_block_data,
    last_block_hash
  )
  blockchain.append(mined_block)
  # Let the client know we mined a block
  return json.dumps({
      "index": new_block_index,
      "timestamp": str(new_block_timestamp),
      "data": new_block_data,
      "hash": last_block_hash
  }) + "\n"

现在,我们能控制特定的时间段内挖到的区块数量,并且我们给了网络中的人新的币,让他们彼此发送。但是如我们说的,我们只是在一台计算机上做的。如果区块链是去中心化的,我们怎样才能确保每个节点都有相同的链呢?要做到这一点,我们会使每个节点都广播其(保存的)链的版本,并允许它们接受其它节点的链。然后,每个节点会校验其它节点的链,以便网络中每个节点都能够达成最终的链的共识。这称之为 共识算法 consensus algorithm

我们的共识算法很简单:如果一个节点的链与其它的节点的不同(例如有冲突),那么最长的链保留,更短的链会被删除。如果我们网络上的链没有了冲突,那么就可以继续了。

@node.route('/blocks', methods=['GET'])
def get_blocks():
  chain_to_send = blockchain
  # Convert our blocks into dictionaries
  # so we can send them as json objects later
  for block in chain_to_send:
    block_index = str(block.index)
    block_timestamp = str(block.timestamp)
    block_data = str(block.data)
    block_hash = block.hash
    block = {
      "index": block_index,
      "timestamp": block_timestamp,
      "data": block_data,
      "hash": block_hash
    }
  # Send our chain to whomever requested it
  chain_to_send = json.dumps(chain_to_send)
  return chain_to_send

def find_new_chains():
  # Get the blockchains of every
  # other node
  other_chains = []
  for node_url in peer_nodes:
    # Get their chains using a GET request
    block = requests.get(node_url + "/blocks").content
    # Convert the JSON object to a Python dictionary
    block = json.loads(block)
    # Add it to our list
    other_chains.append(block)
  return other_chains

def consensus():
  # Get the blocks from other nodes
  other_chains = find_new_chains()
  # If our chain isn't longest,
  # then we store the longest chain
  longest_chain = blockchain
  for chain in other_chains:
    if len(longest_chain) < len(chain):
      longest_chain = chain
  # If the longest chain wasn't ours,
  # then we set our chain to the longest
  blockchain = longest_chain

我们差不多就要完成了。在运行了完整的 SnakeCoin 服务器代码之后,在你的终端可以运行如下代码。(假设你已经安装了 cCUL)。

1、创建交易

curl "localhost:5000/txion" \  
     -H "Content-Type: application/json" \  
     -d '{"from": "akjflw", "to":"fjlakdj", "amount": 3}'

2、挖一个新区块

curl localhost:5000/mine

3、 查看结果。从客户端窗口,我们可以看到。

对代码做下美化处理,我们看到挖矿后我们得到的新区块的信息:

{  
  "index": 2,  
  "data": {  
    "transactions": [  
      {  
        "to": "fjlakdj",  
        "amount": 3,  
        "from": "akjflw"  
      },  
      {  
        "to": "q3nf394hjg-random-miner-address-34nf3i4nflkn3oi",  
        "amount": 1,  
        "from": "network"  
      }  
    ],  
    "proof-of-work": 36  
  },  
  "hash": "151edd3ef6af2e7eb8272245cb8ea91b4ecfc3e60af22d8518ef0bba8b4a6b18",  
  "timestamp": "2017-07-23 11:23:10.140996"  
}

大功告成!现在 SnakeCoin 可以运行在多个机器上,从而创建了一个网络,而且真实的 SnakeCoin 也能被挖到了。

你可以根据你的喜好去修改 SnakeCoin 服务器代码,并问各种问题了。

在下一篇(LCTT 译注:截止至本文翻译,作者还没有写出下一篇),我们将讨论创建一个 SnakeCoin 钱包,这样用户就可以发送、接收和存储他们的 SnakeCoin 了。