持续更新中,观看更多内容~
在本文中,我试图解释比特币的早期源代码,并将其与当前使用的源代码进行关联。我的目的是帮助您更好地了解有关比特币历史的早期细节和中本聪这个神秘人物。对于比特币或区块链领域的新手来说,这可能是一篇相当复杂的文章,因为我的目标受众是普通和更有经验的用户。尽管如此,我还是力求让它尽可能的容易理解。
比特币是卓越的加密货币,也是第一个被开发和发布的加密货币。比特币于2008年底由一群开发者或一个名叫中本聪(SatoshiNakamoto)的开发者创建,它现在代表着替代货币的概念,在当今的时代精神中扮演着重要角色。
在比特币发展的早期,许多爱好者被一个新奇的想法所吸引:创造一种不受中心实体束缚的货币。近13年后,我们可以说,中本聪成功地将其核心理念灌输给了许多比特币爱好者和非比特币爱好者。
然而,有一个很多人不知道的故事,揭示了中本聪匿名身份背后的人运作方式的一些特征。这是比特币“另类”genesis区块链背后的故事。别担心,我们不是在谈论任何黑客,这只是一个诞生于2009年1月之前的替代网络。请注意,我们将把中本聪称为一个人;不过你必须记住,更多的研究指出,中本聪是由一群开发者组成的。
项目的开始
让我们从头开始,中本聪在metzdowd邮件列表中发布了比特币白皮书的链接——一个相当“革命性”的想法。它是如此“革命性”,以至于邮件列表管理员敦促用户不要谈论经济政策,而是关注技术方面和技术的影响。
作为背景,是一个邮件列表,用来讨论与加密技术及其影响相关的主题和新闻。2008年10月31日14:10:00,中本聪向发送了第一封电子邮件,说他已经发表了一份白皮书,描述了一种叫做比特币的新技术。
随着关于比特币的新邮件的回复和对话,许多人开始与中本聪讨论这种新货币的发展。特别是,在公开的电子邮件通信中,我们可以引用2008年11月17日发给JamesA.Donald的电子邮件中的一个重要段落。
中本聪的回应如下:
我相信在过去一年半的时间里,我在编码的时候已经解决了所有这些小细节。文章中没有涉及功能细节,但源代码很快就会发布。我把主要文件发给你了。(目前可根据要求提供,很快会正式发布)
源代码
对于想开始研究比特币源代码的初学者和新手来说,源代码预发布是一个很好的资源。事实上,预发布版可以被认为是后来的比特币的原型。
在早期,源代码只能应要求提供,那时中本聪并不像今天这样出名。2013年底,一位收到源代码的用户将其发布在BitcoinTalk.org论坛上。在那里,Cryddit发布了收到的源代码,有效地删除了元数据等与这些文件相关的重要信息。
第一个版本的比特币的源代码由四个文件组成:
node.cppenode.h——节点的代码
Main.cppemain.h——钱包、交易、区块(从磁盘读取)和genesis区块
当然,源代码并不包含生成二进制文件所需的所有文件。可以认为,中本聪之所以没有包含所有的文件,是因为他害怕其他人可能会复制他的想法,或者只是因为他还在研究这个想法。还可以确认的是,源代码的第一个版本被大量修改,许多最初的注释已被删除。
在源代码中,有一些缺失的文件被提及,特别是我们发现:
headers.h——可能是一个全局文件,包含对库的所有引用(boost)
SHA.h——包含SHA哈希算法的库文件
当将源代码与更接近(比特币0.1)但更完整的源代码进行比较时,第一个奇怪的地方是增加了sha.h头文件。中本聪似乎忘记了删除它,因为sha.h并没有在任何地方使用。另外,sha.h文件也不是中本聪编写的,因为它是公共域代码(更确切地说,是cryptopp)。
因此,我想到了另一个(可能是更有效的)假设:通过发布源代码的第一个版本,中本聪想从专家那里得到项目中最重要部分的反馈——而不是其他多余的部分。特别是,中本聪试图获得关于网络、交易管理和区块链元素的反馈。
在node.cpp(函数ThreadBitcoinMiner)中可以找到的另一个奇怪之处是,它提到了一个矿工(函数BitcoinMiner()),然而,它实际上并没有包含在源代码中。文件script.cpp没有被包含在内,其他所有用于生成公钥/私钥的文件也没有被包括在内。
Genesis区块
现在我们已经对源代码有了一个概述,我们可以深入研究一下这个看似不真实的故事。让我们从介绍区块链开始。在描述比特币的白皮书中,中本聪假设了一个包含交易的区块被放置在其中的链。在源代码的第一个版本中,这个链被称为“时间链”。
区块通过“链”绑定在一起——在每个区块中,都有一个哈希值,允许两个区块进行数学连接。如果有一个区块的哈希值是无效的,那么与之相连的后续区块也将是无效的。
在链上的所有区块中,有一个十分特别,它就是Genesis区块,它是源代码所有者在区块链上开采的第一个区块。这个区块是区块链的创建点,也是唯一由中心化机构实际发布的区块。
为了从技术上理解Genesis区块是如何插入区块链的,我们可以分析比特币的第一个版本。在这里,我们有兴趣找出区块链是如何初始化的,以及它插入了哪个区块。Genesis区块通过LoadBlockIndex函数插入。将此注释插入代码中可能是为了验证它是否正常工作:
////debug
//GenesisBlock:
//GetHash()=0x000006b15d1327d67e971d1de9116bd60a3a01556c91b6ebaa416ebc0cfaa646
//hashPrevBlock=0x0000000000000000000000000000000000000000000000000000000000000000
//hashMerkleRoot=0x769a5e93fac273fd825da42d39ead975b5d712b2d50953f35a4fdebdec8083e3
//txNew.vin.scriptSig=247422313
//txNew.vout.nValue=10000
//txNew.vout.scriptPubKey=OP_CODESEPARATOR0x31D18A083F381B4BDE37B649AACF8CD0AFD88C53A3587ECDB7FAF23D449C800AF1CE516199390BFE42991F10E7F5340F2A63449F0B639A7115C667E5D7B051D404OP_CHECKSIG
//nTime=1221069728
//nBits=20
//nNonce=141755
//CBlock(hashPrevBlock=000000,hashMerkleRoot=769a5e,nTime=1221069728,nBits=20,nNonce=141755,vtx=1)
//CTransaction(vin.size=1,vout.size=1,nLockTime=0)
//CTxIn(COutPoint(000000,-1),coinbase04695dbf0e)
//CTxOut(nValue=10000,nSequence=4294967295,scriptPubKey=51b0,posNext=null)
//vMerkleTree:769a5e
区块的详细信息
为了让读者更容易理解,让我们确定以下字段,并注意与当前标准版本的比特币的一些差异。区块的定义可以在main.h文件中找到,我们将引用其中定义字段的部分。
classCBlock
{
Public:
//header
uint256hashPrevBlock;
uint256hashMerkleRoot;
unsignedintnTime;
unsignedintnBits;
unsignedintnNonce;
//networkanddisk
vectorvtx;
//memoryonly
mutablevectorvMerkleTree;
//…
}
区块哈希
哈希是指将哈希函数应用于区块头(哈希字段)的特定字符串。哈希函数是一种将任意大小的数据作为输入并产生与输入密切相关的位序列的函数。从位序列来看,原始输入无法轻易追溯。
我们知道,每个区块可以分为头(一个全局数据集)和体(区块的主要内容,即交易)。函数sha256(sha256(header_block))返回哈希值0x000006b15d1327d67e971d1de9116bd60a3a01556c91b6ebaa416ebc0cfaa646。区块哈希字段的含义在当前版本的比特币中没有改变。
前一个区块的哈希值
为了使区块队列有意义,每个区块必须包含对前一个区块的引用(hashPrevBlock字段)。使用哈希值来引用前一个区块是非常有效的,原因有二。
第一个原因在于存在一个可验证的数学链接,它允许节点忽略不属于该链的任何区块。另一方面,第二种方法包括优化搜索一个区块的内部。
在数据结构中进行搜索的最著名的算法之一是哈希表。简单地说,我们对每个元素应用一个哈希函数,并将每个哈希映射到我们已知的内存位置。要检查一个元素是否存在,我们只需访问哈希值被映射到的内存位置。在常数时间O(1)内,我们可以通过哈希值搜索链内的区块。当然,搜索区块的方法因项目而异。
在genesis区块的特殊情况下,前一个区块的哈希值被设置为0,因为第一个区块没有任何母块。该字段在当前版本的比特币中具有相同的含义。
比特币的情况并非如此,但这是一个很好的机会来谈谈genesis区块的验证。要了解一个d区块是否是genesis区块,必须将区d块的哈希值与genesis区块的哈希值进行比较。建议不要去检查d.hhashprevblock===0这个条件。有了这个条件,就不能保证一个区块的哈希值为0(或者更危险的是,不能保证它被某些深奥的编程语言转换为0。
MerkleTreeRoot
MerkleTree是比特币内部大量使用的数据结构。此数据结构是由节点组成的树形数据结构类别的一部分。为了更好地理解这个概念,假设我们有一张图,其中有相互连接的节点。图形通常可以向任何方向发展,包括垂直、水平等。
树状图是一个从上到下的特殊图形。在顶部是图形开始的节点,而从上到下逐渐滚动,我们会发现不同的节点。我们把与节点x相连的节点称为x的子节点。位于x节点“上方”的节点称为x的母节点。树状图有一个根顶点,由此产生各种弧——树状图中的“分支”,将根连接到新的顶点。
每个顶点都可以有起源于新顶点并指向新顶点的分支。没有向外分支的最后顶点被称为“叶子”。比特币使用的MerkleTree是由叶子构成的。每个叶子都包含一个交易的哈希值(如果是奇数,最后一个是重复的),其中(一次一对)叶子的内容被连接起来,并应用哈希函数来创建一个新的顶点。这个过程一层一层地重复,直到只剩下两个顶点,它们在连接和散列时就形成了roothash。
因此,要验证包含交易的数据结构,只需检查MerkleTree根的哈希值就足够了(即hashMerkleRoot字段)。MerkleTree是表示这组交易的一种紧凑方式——它被用作一种校验和。经过检查,具有精确roothash的新区块包含有一个在MerkleTree中操作,并返回roothash的交易集。
如果没有MerkleTree,对于每个区块,一个比特币节点将被迫验证N个区块,N是交易,与使用MerkleTreeO(1)相比,时间将与O(N*M)成正比。对于该区块,值为0x769a5e93fac273fd825da42d39ead975b5d712b2d50953f35a4fdebdec8083e3。
交易
区块的内容由一组交易(txNew字段)表示,在每个区块中有一个称为vtx的交易向量。
我们在下表中总结了一个交易的字段:
第一个区块中的交易是coinbase交易——由输入和输出组成。我们从一个关键元素认识到这是一个coinbase交易:输入的数量等于1(中本聪的代码中明确了此条件)。这笔交易被发送给挖出它的人,也就是中本聪;因此他获得了第一个比特币。在这个区块中,中本聪将比特币的较小面值称为“cent”(10,000),而不是“satoshis”。
不幸的是,由于第一个公开版本的比特币也存在一个问题,中本聪永远不能花这笔交易的钱。正如我们可以用代码验证的那样,当在区块链中插入genesis区块时,开发人员还应该将交易插入包含所有交易的数据结构中。然而,中本聪并没有包括第一笔交易。因此,该区块是存在的,然而,该交易对于系统并不存在——即使它仍然包含在genesis区块中。
在输出字段中,第一笔交易的金额被设置为10,000(nValue字段)。此外还指定了scriptPubKey:这是一个指定特定条件的字段(在本例中是OP_CHECKSIG)。如果这个条件为真,那么交易是有效的,金额可以消费。关于scriptPubKey的更深入的概述,我推荐阅读Bitcoinwiki的“Scripts”部分。
例如,让我们以一个普通交易的构造为例,在其中我们希望使用输入“A”,它是前一个交易的输出。之前的交易为“A”指定了一个scriptpubkey,在最简单的情况下,它包含一个公钥和使用该密钥签名的请求(OP_CHECKSIG)。在使用“A”作为输入构建交易时,必须提供一个scriptsig,它是使用前面的sciptpubkey指定的密钥构建交易的签名版本。“正在构建的交易”是除了scriptsigs之外所有字段都被填充的交易,而scriptsigs必须为空。genesis区块的特点是scriptsig字段是完全任意的,因为没有以前的交易可以从中获取验证规则,所以中本聪可以输入任何东西。
时间戳
时间戳字段表示自UnixEpoch(1970年1月1日)以来所经过的秒数。对于这个区块,时间戳的值是1221069728,指的是2008年9月10日星期三,18:02:08(GMT)。
事实上,该区块似乎是在2008年9月10日添加的。之所以说“似乎是被添加的”是因为不确定它是否在当天被添加到链上。相反,2008年9月10日提醒了我们一个非常重要的事件。
2008年9月10日:雷曼兄弟公布第三季度业绩
在这一天,全球投资银行雷曼兄弟公布了其第三季度的业绩,公布了大约39亿美元的亏损,并最终在五天后宣布破产。因此,不清楚时间戳是真实的还是人为插入的。中本聪会包含一些2008年金融危机的线索并不令人陌生(因此,很容易看出中本聪是如何反对传统支付系统的)。
为第一个区块选择这样一个日期只能是一个奇怪的巧合。对于那些感兴趣的人,我检索了《泰晤士报》发表的一些文章,特别选择了一篇,并决定以文章的名字命名区块链。如果我是中本聪,我会选择这一篇:“2008年9月10日,泰晤士报,雷曼兄弟以39亿美元的亏损出售房地产资产”。
请注意,这种关联是非常“推测性”的,没有其他证据表明中本聪是否有意将此事件与区块链联系起来。然而,这种巧合仍然令人好奇。
目标/难度
nBits字段是唯一一个与当前版本比特币有实质性区别的字段。在标准版本(当前版本)中,它是目标部分:区块头的哈希值必须小于或等于该区块才能被网络所接受。目标字段的值越低,区块就越难被挖掘。
在非常早期的版本中,nBits字段是关于的,但它代表了在一个区块被接受之前可以完成的最小“工作量”。这似乎是一种意义的反转,因为正如上面所提到的,它代表了在被网络接受之前必须完成的最小工作量。简单地说,通过产生的哈希值(除了有效外)必须大于nBits。事实上,nBits字段的值等于main.h文件中声明的常量,该文件名为MINPROOFOFWORK,注释为“非常容易测试”。
Nonce
Nonce字段是一个由矿工选择的任意数字,用于满足哈希值的约束条件。事实上,区块的哈希值必须以若干个零开头。nonce字段与当前版本的比特币使用的字段相同。
中本聪的背后是谁?
自比特币故事开始以来,中本聪背后的身份一直是个谜。一些投机者将矛头指向了计算机和经济学领域的杰出人物。从全球知名人士(如埃隆·马斯克)到狂热分子,很明显,这个谜题让许多人兴奋不已。
人们对中本聪创作的文本进行了文体分析,包括在BitcoinTalk论坛上发布的消息、电子邮件和白皮书等中本聪创作的主要文本。此外,为了进一步分析,人们收集了第一批与中本聪关系密切的人的信息(如HalFinney,NickSzabo)。
多年来,CraigWright等人物站出来声称自己是中本聪。当然,验证一个人是否真的是中本聪的唯一方法是通过PGP密钥。如果有人设法用中本聪的私钥签署消息,那么有两种可能:这个人真的是中本聪,或者私钥被偷了。
一些人大胆地认为,中本聪背后可能有一群人,这将解释为什么文体分析失败(或者说为什么研究中存在很多偏见)。在比特币社区内,有一些研究反驳或证实了某个人和中本聪之间的联系;然而,这些研究分析的数据集相当有限,人数也很有限。
然而,关于中本聪性格的一个非常重要的细节是有可能已经被揭示出来。事实上,中本聪选择了带有特定时间戳的genesis区块(其中包括英国《泰晤士报》文章中的句子),这让人意识到中本聪的身份背后花了多少精心准备。中本聪并不希望源代码预览被公布。
比特币的准备、早期SVN提交中发现的一些评论以及中本聪所追求的完美主义可能暗示着一个由一群人“临时”创造的形象。当然,这一切还只是猜测——要真正把一个身份归到中本聪身上,需要社区方面付出更多努力,从每一次对话中尽可能多地获取信息。
希望这篇文章对大家有一定的帮助。
在加密行业你想抓住下一波牛市机会你得有一个优质圈子,大家就能抱团取暖,保持洞察力。如果只是你一个人,四顾茫然,发现一个人都没有,想在这个行业里面坚持下来其实是很难的。
想抱团取暖,或者有疑惑的,欢迎加入我们-----公众号:布里克熊
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。