区块链前哨导语:在本指南中,我们将探讨如何成为一个比特币开发者。事实上,“比特币”和“区块链技术”现在是世界上最热门的话题。特别是最近几个月,比特币的价格暴涨之后。
更多干货内容请关注微信公众号“区块链前哨”,(ID:blockchain-666)
什么是比特币?
比特币是一种加密货币(cryptocurrency),神秘的中本聪(Satoshi Nakamoto)于 2009 年把它概念化。这是一种去中心化的数字货币,利用区块链技术,在 P2P(peer-to-peer)系统中运行。如果你希望成为一个比特币开发者,那么,你需要做的第一件事是,去读读由中本聪写的比特币白皮书(Bitcoin Whitepaper:https://bitcoin.org/bitcoin.pdf)。
对任何希望进入区块链游戏的人来说,该白皮书是必不可少的读物。该白皮书不仅概念化了比特币,还让我们看到拜占庭容错系统(byzantine fault tolerant system)是如何在去中心化的环境中运行的。
如果你渴望成为一个比特币开发者,那么对你来说,了解区块链是如何工作的就很重要。
什么是区块链?
区块链是多个区块形成的一个链,链上的每个区块都包含有价值的数据,而没有任何中心化的监督。它采用密码保证安全而且是不可变的。区块链用到两个重要的数据结构:指针和链表。
指针
指针是编程中用到的变量,它存储另一个变量的地址。通常,编程语言中的普通变量是存储数据。
例如,int a = 10,这条语句的意思是有个变量“a”,它是用来存储整数值。在本例中,存储的整数值是 10。它是一个普通变量。
然而,指针不是存储数值,而是存储其他变量的地址,这就是它们被称作指针的原因,因为从字面上看,它们指向其他变量的位置。
链表
链表是数据结构中最重要的项目之一。下图是链表的示意图。
这是一串块,每个块都包含通过指针和下个块链接的信息。在这种情况下,指针变量内含有下一个节点的地址,因此就建立了链接。正如你所见,最后一个块含有一个空指针,这意味着该指针没有值。
这里要注意的是,每个块内的指针都包含下一个块的地址。这就是指针实现的原理。现在,你也许会问,对于链表中的第一个块,它又意味着什么呢?第一个块的指针在哪里?
第一个块叫做“创世块(genesis block)”,它的指针位于系统本身。它看上去像这样:
图像来源:Coursera
如果你想知道“哈希指针(hash pointer)”的意思,那么我来告诉你,它是一个指针,包含前一个块的哈希值。
你也许已经猜到了,这就是区块链的结构。一个区块链基本上就是一个链表,看起来像这样:
区块链是一个链表,包含数据和一个哈希指针,这个指针指向前一个区块,这样就形成了链表。什么是哈希指针?哈希指针跟指针类似,但不仅包括前一个区块的地址,还包含前一个区块所含的数据的哈希值。正是这个小小的调整,使得区块链具有令人惊讶的可靠性和开创性。
想象一下,黑客攻击第 3 个区块,试图改变数据。由于哈希函数的性质,数据的微小变化会引起哈希值极大的改变。这意味着,在第 3 个区块中做出的任何细微改变,都会改变存储在第 2 个区块中的哈希值,现在反过来会改变第 2 个区块中的数据信息和哈希值,而第 2 个区块中的变化又会改变第 1 个区块中的数据信息等等诸如此类的变化。这会彻底改变这个链表,而这是不可能的。这就是区块链如何实现不变性的。
那么区块头是什么样子的?
一个区块头包含:
版本信息:该区块的版本号。
时间:当前时间戳。
当前难度目标。
前一个区块的哈希值。
现时标志(稍后详细介绍)
梅克尔根(Merkle Root)的哈希值。
什么是挖矿?
“挖矿”就是你如何生产新的比特币。挖矿按照“工作量证明(proof-of-work)”原则工作。工作量证明的基本意思是:解决问题一定是极端困难的,但是一旦你解决了它,证明这个解决方案是正确的应该很简单。
稍后,我们会看到比特币和大多数加密货币是如何使用它的。但是现在,我们必须了解为什么首先需要有工作量证明。
中本聪遇到的许多问题中的一个是,解决拜占庭将军问题(Byzantine Generals Problem)。每个数字 P2P 去中心化货币系统的失败是因为它们没能解决这个拜占庭将军问题。中本聪终于成功地用工作量证明解决了这个问题。
那么,什么是拜占庭将军问题呢?
好吧,想象一下,有一群拜占庭将军,他们要攻打一座城市。他们遇到下面两个截然不同的问题:
将军们及其军队相距甚远,因此实施集中管理是不可能的,这让协调攻击极其艰难。
这座城市有一支庞大的军队,将军们要赢得战争的方式只能是他们同时发起攻击。
为了协调成功,城堡左侧的军队派出一位信使去城堡右侧,带去“周三发动攻击”的消息。然而,假设城堡右侧的军队还没做好准备,说“不行。周五发动攻击”,并让信使带这个消息回去城堡左侧。
这就是我们遇到问题的地方。
可怜的信使可能会遇到很多事情。他可能被捕、受到威胁、被杀以及被该城的另一位信使替换。这会导致军队收到被篡改的信息,也许会导致军队一次不协调的进攻而被打败。
这也清楚地提到了区块链。区块链是一个巨大的网络,你怎么可能相信他们?如果你从你的钱包里发送 4 个以太币(Ether)给某人,你如何确保这个网络中没人准备篡改它,把 4 个以太币改成 40 个以太币?
中本聪通过发明工作量证明机制绕过了拜占庭将军问题。下面介绍它的工作原理。假设城堡左侧的军队想发送一个“星期一发动攻击”的信息给城堡右侧的军队,他们将遵循一定的步骤。
首先,他们会在原始文本中附加一个随机数(nonce)。这个随机数可以是任何随机的 16 进制值。
接着,他们对附加了随机数的文本进行哈希运算,并查看结果。假设,军队决定只分享那些哈希运算后,有以 5 个“0”打头结果的消息。
如果满足哈希条件,他们将派出携带信息哈希值的信使。如果没有,那么他们会继续随机改变随机值,直到他们获得期望的结果。这个行动是极其繁琐和费时的,需要大量的计算能力。
如果信使被该城俘获,消息被篡改,根据哈希函数的性质,哈希值本身会有很大的变化。如果右侧的将军们看到被哈希过的消息不是以所要求个数的 0 打头,那么他们只需简单地取消攻击命令。
然而,存在一个可能的漏洞。
哈希函数不是百分百没有冲突。抗冲突性意味着:给定两个不同的输入 A 和 B,H(A) 和 H(B) 分别代表 A 和 B 的哈希值,H(A) 要等于 H(B) 是不可行的。这意味着,在大多数情况下,每个输入将有自己唯一的哈希值。然而,在实践中,哈希函数不是百分百没有冲突的。
因此,如果这座城市获得了消息,篡改它,然后相应地改变随机值,直到他们获得期望的结果,该结果带有所希望个数的“0”?这将会非常耗时,但是仍有可能。为了解决这个问题,将军们准备利用数量上的优势。
假设,不是只有一位左侧的将军发送信息给右侧的将军,而是左侧的三位将军都要发送信息给右侧的将军们。为了做到这一个点,他们可以创建自己的信息,然后对累积起来的信息加以哈希运算,然后附加上一个随机数,并再次进行哈希运算。这一次,他们希望得到一个以 6 个“0”打头的信息。
很显然,这会很费时,但是这次,如果信使真的被该城俘获,那么他们用于篡改这个累积信息所花费的和接着要找到哈希的相应随机数的时间肯定要多得多。甚至可能要花上几年时间。因此,例如,如果不是只有一个信使,将军们派出多个信使,那么该城就算计算到一半的过程中,也会受到攻击,并被摧毁。
右侧的将军们非常轻松。他们要做就是把给他们的正确随机数附加到消息后面,并对它们进行哈希运算,然后看看哈希值是否匹配。对一串字符进行哈希运算是非常容易的。这本质上就是工作量证明背后的处理过程。
为适当的哈希目标寻找随机数背后的处理过程应该是非常困难和费时的。
但是,检查结果以查看是否有作弊的过程是很简单的。
因此,这就是比特币的矿工们是如何获得他们挖矿工作量证明的。
他们用他们的计算能力通过解决密码谜题来挖矿以获得区块。每 10 分钟就有一个比特币被挖出来。
比特币交易如何运作?
在我们继续这个话题之前,先了解一下 Donald J Patterson 教授和他的油管频道“djp3”。
假设 Alice 想发送若干个比特币给 Bob。比特币交易系统是如何运作的?比特币交易和 Fiat 钱包交易很不同。如果 Alice 想给 Bob 两美元,她实际上需要从她的钱包里拿出两美元,然后把钱交给 Bob。然而,比特币的情况并不是这样的。你无需实际上拥有比特币,你拥有的只是你拥有比特币的证明。
这里还有两件事情你需要知道:
矿工们通过把数据放入他们已经封锁的矿来验证你的交易。作为这项服务的回报,他们收取交易费用。
对于 FIAT 币来说,你并不真正了解你是如何从哪里获得这个 FIAT 币。比如,现在就打开你的钱包,把所有的纸币和硬币都拿出来。你是否能够说出你到底是从哪里拿到这些钱的?几乎不可能。然而,在比特币交易中,每个比特币及其交易历史都是有记录的。
好了,现在让我们深入研究一下在 Alice 和 Bob 之间的比特币交易是如何发生的吧。一个交易有输入(Input)和输出(Output)两方。这整个交易会有个名字,这个名字我们最后可以弄明白的。现在,来看看动态情况。
交易输入
为了达成这笔交易,Alice 需要有从各种前期交易中收到的比特币。请记住,像我们之前说过的那样,在比特币中,每一个比特币都是有交易历史记录的。
因此,假设 Alice 需要从接下来的交易中取出比特币,我们把那几个交易命名为 TX(0)、TX(1) 和 TX(2)。这 3 个交易会被叠加在一起,这就给你了一个我们叫做 TX(input) 的输入交易。
用图来表示的话,如下所示:
因此,这就是输入一方的样子,让我们来看看输出一方是怎样的。
交易输出
输出方基本上会有 Bob 将拥有的比特币数量和任何剩下的比特币,剩下的比特币会发送回 Alice。然后,这些剩下的比特币会成为她所有未来交易的输入值。
输出端的图形表示,如下图所示:
现在,这是一个非常简单的交易,只有一个输出(除了 CHANGE),交易也有可能有多个输出。这是交易的基本布局。然而,要完成这整件事,还必须满足某些条件。
交易的条件
TX(Inupt) > TX(output)。这个输入交易必须总是大于输出交易。在任何交易中,在输入和输出(output+change)之间的赤字是矿工们收取的交易费用。因此,交易费用(Transaction fees)= TX(Input) - (TX(output) + Change)。
在输入这方:TX(0) + TX(1) + TX(2) = TX(Input)。如果 Alice 没有足够的比特币来进行交易,那么矿工们会直接拒绝交易。
Bob 将必须证明他能够提供获得比特币所需的证据。Alice 将用 Bob 的公共地址来锁定交易。他将需要用他的私钥来解锁交易,并获得他的费用。
Alice 也需要证明她首先具有发送比特币所要求的权利。她通过用她的数字签名(也即她的私钥)签署交易。任何人能可以使用她的公钥对此进行解码,并验证确实是 Alice 本人发送的信息。这个证明叫做“签名数据(Signature data)”。要记住这一点,因为这在以后会非常重要。
那么,这整个交易的名字会是什么呢?
输入(包括签名数据)和输出数据加在一起,用 SHA256 哈希算法进行哈希运算。输出的哈希值就是这个交易的名字。
交易细节代码
下图显示的是交易在代码或脚本形式中看起来的样子。假设 Alice 想发送 0.0015 个比特币给 Bob,为了完成这个操作,她发送的输入值为 0.0015770 个比特币。交易细节看起来就是这样:
图像来源:油管频道 djp3
你看到的第一样东西是:交易的名字是输入和输出值的哈希值。
Vin_sz 是输入数据的个数,因为 Alice 只使用她之前交易的其中一个发送信息,所以这个数值是 1。
Vout_sz 是 2,因为唯一的输出是 Bob 和 change。
看到输入数据了吗?Alice 只用了一个输入交易(在上面我们给出的例子中,这个是 TX(0)),这就是 vin_sz 是 1 的原因。
在输入数据下面是她的签名数据。
最底下是输出数据。
数据的第一部分表示 Bob 收到 0.0015 个比特币。
第二部分表示 Alice 将拿回作为 change 的 0.000512 个比特币。
现在,你是否还记得输入数据是 0.0015770 个比特币?这个值比(0.0015+0.00005120)的值要大。这两个值之间的赤字是矿工们收取的交易费用。
在我们继续讲解之前,我们先来讨论一下一种特殊的交易,Coinbase 交易。它基本上是块上的第一个交易数据,它表示矿工们在挖这个块时获得的挖矿报酬。到目前为止是 12.5 个比特币。这些交易没有输入数据,它们只有输出数据。
你得记住一件事,比特币的交易能够进行是有条件的,那就是只有在矿工已经把这个块挖出来,并且实际上把你的交易放入这个块后才能进行。矿工可以是这个他挖出来的块的临时全权管理者。他们可以对每一个他们放入块的交易收取交易费。
随着交易的数量突飞猛进,写进每个块的费率也在增加。人们事实上往往要等到新的块被挖出来,他们的交易才能进行。这造成了大量交易的积压,事实上,要让你的交易优先排序的唯一方法就是支付足够高的交易费用来吸引和激励矿工们优先处理你的交易。
这就引入了“费用替代(replace-by-fee)”系统。基本上,这就是它的工作原理。假设 Alice 正在发送 5 个比特币给 Bob,由于交易积压的原因,交易无法完成。她不能“删除(delete)”本次交易,因为比特币一旦被用,就永远不能退回。但是,她可以和 Bob 进行另一笔 5 个比特币的交易,这次的交易费用高到足够激励矿工们。由于矿工们把她的这次交易放入了块,它就会覆盖前一次的交易,让它变为空,不再有效。
比特币开发者:比特币编程
最初的比特币核心是中本聪用 C++ 编写的。
在我们开始之前,先来看看区块链开发者面临的一些挑战。创建和维护一个公共区块链不是一件容易的事情,这有很多原因。
(在我们继续讲解之前,看看 David Schwartz 在 CPPCON 2016 上关于在区块链软件开发中使用 C++ 的主旨演讲。)
第一个原因:安全性
正如 David Schwartz 提到的,区块链应该有个安全保障。首先,代码是公开的,供所有人查看。任何人都可以查看代码,寻找错误和漏洞。但是,跟其他开源代码不同,在区块链代码中发现漏洞的缺点是巨大的。任何程序员都能够侵入,并拿走可能价值数以百万计的美元。因为这些合理的安全考量,区块链的开发通常非常缓慢。
第二个原因:资源管理
跟上网络的步伐很重要。你不能落后太多,不能满足所有的网络需求。你应该能够很好地处理远程和本地查询。
第三个原因:性能
区块链必须总是以最高的可能性运行,但是为了做到这一点,所选择的语言必须非常灵活。问题在于,在区块链中有些任务是并行的,而有些任务不能并行完成。
关于“可并行”任务,有个很好的例子,它是数字签名认证。对于签名认证,所有你需要做的是密钥、交易和签名。只需要这三个数据,你能以并行方式进行验证。
但是,不是区块链上的所有功能都应该这样实现。考虑交易执行本身。多个交易不能并行执行,一次只能做一个交易,以避免像双重支付这样的错误。有些语言擅长并行操作,有些擅长非并行操作。
第四个原因:隔离
什么是确定性行为?
如果有 A + B = C,那么无论环境如何变化,A+B 的值将会永远和 C 的值相等。这个就叫做确定性行为。
哈希函数是确定性的,意思是 A 的哈希值永远是 H(A)。
因此,在区块链开发中,所有的交易操作必须是确定性的。你不能有一个交易今天是这样的,而明天又是那样的。类似的,你不能有在两台不同的机子上以两种不同方式工作的智能合约。
唯一的解决方案是隔离。基本上,你将你的智能合约和交易与非确定性因素隔离开来。
使用比特币钱包
如果你想成为比特币者,那么你一定要了解比特币钱包的工作原理。毫无疑问,任何加密货币最安全的存放方式是使用纸钱包(paper wallet)。通过下面几个指示,你完全可以免费设置一个。这让你确确实实地成为你的投资的主人,如果采取了预防措施,其他人完全没有可能知道你的私钥。
当然,这意味着保存它们的记录甚至更重要。丢失私钥意味着你将失去你纸钱包中的全部东西(但话说回来,对每个钱包都是如此)
什么是纸钱包?
简单地说,纸钱包是保存加密货币的离线冷存储方式。它包括在一张纸上打印出你的公钥和私钥,然后把这张纸保存在安全的地方。这些密钥以二维码的形式打印出来,以供你将来扫描用于所有的交易。它之所以如此安全,是因为它给了你这个用户完全的控制权。你无需担心这个硬件的健康状态,也无需担心黑客或者恶意软件。你只需保管好这张纸。
设置一个纸钱包
纸钱包是通过一个程序随机生成公钥和私钥形成的。这些密钥是唯一的,生成它们的程序是开源的。那些有编程高级知识的人可以自己查看程序的后端,以获得结果的随机性。更重要的是,我们将离线生成我们的密钥。这消除了对在线威胁的暴露,并且在使用后删除这个简单的程序会破坏所有的痕迹。
如果听起来让你感到困惑,不用担心,事实并非如此。你不需要任何特定的编码知识或加密知识。你需要的就是一台计算机、能上互联网以及记录你密钥的东西。
不管怎样,让我们来创建我们的纸钱包吧。跟着下面的步骤做:
确保你的计算机上没有任何恶意软件。一台全新的计算机是最理想的了,但是通常是做不到的。
访问网页 WalletGenerotor.net。
点击这里下载软件包:
一旦下载完成,打开“index.html”文件,但是在打开之前,确认你已和互联网断开。完成这整个过程是确保你的钱包不会被黑客侵入。
现在,是时候生成你的钱包了。保持悬停在高亮的文本上,它会生成更多字符。或者,你也可以手动输入随机字符。一直到计数器变为“0”。
计数器变为“0”的时候,你的钱包就生成了。
打印这个页面,或者制作多个这些数字的副本(重点:确保打印机这时是没有连接到 Wi-Fi 的)。
删除保存的页面。现在你可以安全地连上互联网了。
把你的私钥保存在长期私密安全的地方。
现在,你有了你的钱包,你可以去那些交易平台把你的 fiat 币换成比特币了。你可以使用的交易平台有:
Bitfinex.
Bitstamp.
BTC-e.
Coinbase.
你得自己做些研究,找出你所在的地区最好的交易平台。
比特币开发者结论
这个指南将给你一个基本概念,你要做些和学习什么以成为一个比特币开发者。
通常来说,比特币和加密货币在未来有着无限的可能性。我们也许正处在下一个伟大的定义式协议时代的尖端。区块链技术会成为下一代互联网吗?只有时间能告诉我们答案。无论如何,毫无疑问的是,比特币和其他区块链应用的绝对范围是无限的。
查看英文原文:https://blockgeeks.com/guides/bitcoin-developer
今日荐文
领取专属 10元无门槛券
私享最新 技术干货