本文详细介绍了Bitcoin的挖掘,直到十六进制数据和网络流量。如果您曾经想过Bitcoin采矿业发生了什么,您会来到正确的地方。我以前的文章,Bitcoins的硬的方式描述了我如何手动创建比特币交易并将其发送到系统。在本文中,我将展示下一步将会发生的事情:事务如何被挖掘到一个块中。

比特币挖掘困难的方式:算法,协议和字节

采矿的目的

比特币矿业通常被认为是创造新的比特币的方式。但这只是次要目的。采矿的主要重要性是确保所有参与者对比特币数据有一致的看法。因为比特币是一个分布式的对等系统,所以没有中心数据库可以跟踪谁拥有比特币。而是将所有事务的日志分布在网络中。

分布式事务日志的主要问题是如何避免可能允许某人花费相同的比特币两次的不一致。比特币的解决方案是将大部分交易的交易大概每10分钟开采一次,这使得它们成为官方。冲突或无效的交易不允许进入块,因此避免双重支出问题。

虽然采矿交易成块避免双重支出,但却引发了新的问题:什么阻止人们从随机采矿块?你如何决定谁来挖掘一个区块?网络如何同意哪些区块有效?解决这些问题是比特币的关键创新:采矿是非常非常困难的,这是一种称为工作证明的技术。挖掘一个块需要大量的计算量,但网络上的对等体很容易验证块是否成功开采。[1]

每个开采块参考前一个块,形成一条连续的链条回到第一个比特币块。这个块链确保每个人都同意交易记录。它还确保没有人可以篡改链中的块,因为重新挖掘所有以下块将在计算上是不可行的。[2] 只要没有人拥有一半以上的计算资源,采矿仍然具有竞争力,没有人能够控制块状。

作为副作用,采矿业为系统增加了新的比特币。对于每个开采的矿区,矿工目前获得25个新的比特币(目前价值约15,000美元),这鼓励矿工们开采矿区的艰苦工作。有可能每10分钟收到15000美元,在采矿中有很多钱。

采矿如何工作

采矿需要一个非常难以执行但容易验证的任务。比特币挖掘使用密码学,具有称为双SHA-256的散列函数。哈希将一大块数据作为输入,并将其缩小为较小的哈希值(在这种情况下为256位)。使用加密哈希,没有办法得到您想要的哈希值,而不尝试大量的输入。但是,一旦找到一个给出你想要的值的输入,任何人都很容易验证哈希。因此,加密散列成为实施比特币“工作证明”的好方法。

更详细地说,要挖掘一个块,您首先将新的交易收集到块中。然后,您将哈希块形成一个256位的块哈希值。如果哈希从足够的零开始[3],则该块已经被成功地挖出并被发送到比特币网络,并且哈希成为该块的标识符。大多数时候哈希不成功,所以你稍微修改块,再试一次,超过数十亿次。大约每10分钟有人会成功挖掘一个区块,过程重新开始。

下图显示了特定块的结构以及它是如何散列的。黄色部分是块标题,其后是进入块的事务。第一笔交易是向矿工授予矿业报酬的特殊组合交易。剩下的交易是标准的Bitcoin交易,移动比特币。如果标题的散列从足够的零开始[3],则块被成功开采。对于下面的块,哈希成功:0000000000000000e067a478024addfecdc93628978aa52d91fabd4292982a50块成块 #286819块。

比特币块的结构

比特币块的结构

块标题包含描述块的少数字段。该块中的第一个字段是协议版本。之后是块链中先前块的散列,这确保所有块在块链中形成完整的序列。(不方便的是,标题中的哈希相反)。下一个字段是Merkle根,[4]块中所有事务的特殊散列。这也是比特币安全的关键部分,因为它确保事务在块成为一部分后不能更改。[5] 接下来是块的(中等精度)时间戳,后跟挖掘难度值位。[3] 最后,随机数是在每个散列尝试中增加的任意值,以提供新的哈希值。挖掘的棘手部分是找到一个可行的工具。

无标题

ASIC Bitcoin Miner 
照片由Mirko Tobias Schaefer,(CC BY 2.0)

一个简单的程序来挖一个块

我写了一个Python程序,挖掘上面的块。程序本身很简单 - 代码中最难的部分是从位计算难度目标。[3]否则,它只是循环不同的随机值。每次迭代将数据放入一个结构中,对它进行散列,然后测试结果。

import hashlib, struct

ver = 2
prev_block = "000000000000000117c80378b8da0e33559b5997f2ad55e2f7d18ec1975b9717"
mrkl_root = "871714dcbae6c8193a2bb9b2a69fe1c0440399f38d94b3a0f1b447275a29978a"
time_ = 0x53058b35 # 2014-02-20 04:57:25
bits = 0x19015f53

# https://en.bitcoin.it/wiki/Difficulty
exp = bits >> 24
mant = bits & 0xffffff
target_hexstr = '%064x' % (mant * (1<<(8*(exp - 3))))
target_str = target_hexstr.decode('hex')

nonce = 0
while nonce < 0x100000000:
header = ( struct.pack(" mrkl_root.decode('hex')[::-1] + struct.pack(" hash = hashlib.sha256(hashlib.sha256(header).digest()).digest()
print nonce, hash[::-1].encode('hex')
if hash[::-1] < target_str:
print 'success'
break
nonce += 1

view rawmine.py hosted with ❤ by GitHub

下表显示了为选定的随机值获取的哈希值。关键是每个随机数生成一个基本随机的哈希值。经常,“幸运”的随机数将生成一个从零开始的哈希。为了获得很多零值,您需要尝试大量数量的随机数。对于这个块,“获胜”随机数是856192328。

现时哈希
05c56c2883435b38aeba0e69fb2e0e3db3b22448d3e17b903d774dd5650796f76
128902a23a194dee94141d1b70102accd85fc2c1ead0901ba0e41ade90d38a08e
2729577af82250aaf9e44f70a72814cf56c16d430a878bf52fdaceeb7b4bd37f4
38491452381016cf80562ff489e492e00331de3553178c73c5169574000f1ed1c
3903fd5ff1048668cd3cde4f3fb5bde1ff306d26a4630f420c78df1e504e24f3c7
9900001e3a4583f4c6d81251e8d9901dbe0df74d7144300d7c03cab15eca04bd4bb
521170000642411733cd63264d3bedc046a5364ff3c77d2b37ca298ad8f1b5a9f05ba
181315200000c94a85b5c06c9b06ace1ba7c7f759e795715f399c9c1b1b7f5d387a319f
19745650000000cdccf49f13f5c3f14a2c12a56ae60e900c5e65bfe1cc24f038f0668a6c
2439898010000000ce99e2a00633ca958a16e17f30085a54f04667a5492db49bcae15d190
8561923280000000000000000e067a478024addfecdc93628978aa52d91fabd4292982a50

我应该指出,我从一个可以成功开采的区块开始被骗。大多数尝试挖掘一个块将完全失败 - 没有一个随机值将成功。在这种情况下,您需要稍微修改块,然后重试。可以调整时间戳(这就是为什么开采块中的时间戳通常是错误的)。新事务可以添加到块中,更改Merkle哈希。可以修改投币系统交易 - 对于采矿池来说,这一点非常重要。任何这些更改将导致完全不同的哈希值,因此可以再次尝试随机值。

我的Python程序每秒大约有42,000个散列,比真正的矿工使用的硬件慢了百万倍。我的方案平均需要大约1100万年的时间才能从头开始。

采矿非常困难

挖掘块的难度是惊人的。在目前的困难中,散列成功的几率在10 19以前有一点差。找到一个成功的哈希比从地球上的所有砂粒中找到特定的沙子更困难。为了每10分钟找一个哈希,比特币哈希率需要非常大。目前,Bitcoin网络矿工每秒大约有2500万千克拉。也就是说,每秒钟大约有25,000,000,000,000块的数据被散列。我估计(非常粗略地),用于比特币矿业的总硬件花费数千万美元,并且使用与柬埔寨国家一样多的权力。[6]

请注意,找到一个成功的哈希是一个完全任意的任务,本身并没有完成任何有用的任务。找到一个小的哈希的唯一目的是使采矿困难,这是Bitcoin安全的基础。在我看来,比特币矿业的努力最近已经走了。

矿业主要由每个块的25个比特币奖励资金,以及交易费用(每个块大约0.1个比特币)。由于目前的采矿报酬目前每块大约为15,000美元,所以支付了很多硬件。根据交易,矿工获得约34美元的采矿报酬和0.10美元的费用(统计)。

FPGA比特币采矿设置与41伊卡洛斯

15 GH / s FPGA Bitcoin采矿配置与41 Icarus。刘照福许可照片

开采一个游泳池

因为采矿是如此困难,所以通常在采矿池中完成,一批矿工分享工作并分享奖励。如果你自己挖掘,你可能会成功挖掘一个块,每隔几年就得到25比特币。通过采矿作为游泳池的一部分,您可以每天得到比特币的一小部分,而对于大多数人来说,这是可取的。

采矿池采用有趣的技术来看待矿工们在做多少工作。他们发出一个要开采的块,每当矿工得到部分解决方案时,从矿工得到更新。每个部分解决方案证明矿工正在努力解决问题,并且当有人成功开采该矿区时,给予矿工最终奖励的份额。

例如,如果比特币挖掘需要以15个零开始的哈希值,则采矿池可以要求以10个零开始的散列,这比以前容易上百万。根据硬件的功率,矿工可能会每隔几秒钟或几小时就能找到这样的解决方案。最终,这些解决方案中的一个将不仅仅是10个零,而且是15个零,从而成功挖掘块并赢得游泳池的奖励。[7]然后,根据每个矿工的股份数量作为总分数的一部分,奖励分配,池运营商占用开销的一小部分。[8]

大多数时候,游泳池外的人都会先挖一个街区。在这种情况下,池操作员发出新数据,矿工们刚刚开始挖掘新块。如果长时间没有支付,因为在采矿中运气不好,游泳池里的人们会变得前卫。

层层:池与矿工之间的沟通

接下来我将详细介绍矿工和采矿池之间的沟通。游泳池和矿工之间的沟通很有趣。游泳池必须有效地向矿工提供工作,并迅速收集结果。游泳池必须确保矿工不重复工作。而游泳池必须确保矿工不要浪费时间在已经开采的地块上工作。

采矿池的一个重要问题是如何支持快速矿工。标题中的随机数字段对于快速采矿者而言太小,因为它们将比池可以发送块快速运行所有可能的值。解决方案是允许矿工更新投币系统交易,以便他们可以在其中添加额外的数据。这使得采矿更加复杂,因为在建立投币系统交易之后,矿工必须重新计算Merkle散列树,然后尝试挖掘块。

我将看看许多池使用的Stratum挖掘池协议。(一些替代协议是GetworkGetblocktemplate协议。)以下Python程序使用Stratum协议向GHash.IO挖掘池提交挖掘请求并显示结果。(这个程序是一个最小的演示;不要使用这个代码进行真正的挖掘。)

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("us1.ghash.io", 3333))

sock.send("""{"id": 1, "method": "mining.subscribe", "params": []}\n""")
print sock.recv(4000)

sock.send("""{"params": ["kens_1", "password"], "id": 2, "method": "mining.authorize"}\n""")
print sock.recv(4000)

view rawstratum.py hosted with ❤ by GitHub

以下信息是采矿池响应上述程序通过网络发回的信息。由于Stratum协议使用 JSON-RPC, 所以结果是可读的ASCII码,而不是大多数Bitcoin使用的二进制数据包。这提供了作为池的一部分开始挖掘所需的所有数据:

{ “ID”:1, “结果”:[[[ “mining.set_difficulty”, “b4b6693b72a50c7116db18d6497cac52”],[ “mining.notify”, “ae6812eb4cd7735a302a8a9dd95cf71f”]] “4bc6af58”,4], “错误”:空}{ “ID”:NULL, “PARAMS”:[16], “方法”: “mining.set_difficulty”}{ “ID”:NULL, “PARAMS”:[ “58af8d8c”, “975b9717f7d18ec1f2ad55e2559b5997b8da0e3317c803780000000100000000”, “01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4803636004062f503253482f04428b055308”, “2e522cfabe6d6da0bd01f57abe963d25879583eea5ea6f08f83e3327eba9806b14119718cbb1cf04000000000000000000000001fb673495000000001976a91480ad90d403581fa3bf46086a91b2d9d4125db6c188ac00000000”,[ “ea9da84d55ebf07f47def6b9b35ab30fc18b6e980fc618f262724388f2e9c591”, “f8578e6b5900de614aabe563c9622a8f514e11d368caa78890ac2ed615a2300c”, “1632f2b53febb0a999784c4feb1655144793c4e662226aff64b71c6837430791”, “ad4328979dba3e30f11c2d94445731f461a25842523fcbfa53cd42b585e63fcd”, “a904a9a41d1c8f9e860ba2b07ba13187b41aa7246f341489a730c6dc6fb42701”,” dd7e026ac1fff0feac6bed6872b6964f5ea00bd8913a956e6b2eb7e22363dc5c”, “2c3b18d8edff29c013394c28888c6b50ed8733760a3d4d9082c3f1f5a43afa64”], “00000002”, “19015f53”, “53058b41”,假], “方法”: “mining.notify”{ “ID”:2, “结果”:真正的 “错误”:空}{ “ID”:NULL, “PARAMS”:[16], “方法”: “mining.set_difficulty”}

第一行是具有订阅详细信息的池服务器的响应。第一个值并不重要。该值4bc6af58是构建块时使用的值extranonce1。每个客户端都获得唯一的值,以确保所有采矿客户端都生成唯一的块,并且不重复工作。以下值(4bytes)是矿工在采矿时投入到投币台的extranonce2_size值的长度。

第二行是给我们的客户的一个mining.set_difficulty消息。在16岁的困难下,我可以在PC上每两个小时获得一次份额。相比之下,比特币采矿难度为3,129,573,174.52 [3] - 因此在这个池中获得份额比独立成功开采块大约2亿倍。这就是人们加入游泳池的原因。

第三行是对我们客户的采矿通知。这个消息定义了我们挖掘的块。“params”下有很多数据返回,所以我将按字段解释它。

JOB_ID58af8d8c
prevhash975b9717f7d18ec1f2ad55e2559b5997b8da0e3317c803780000000100000000
coinb101000000010000000000000000000000000000000000000000000000000000000000 0000000000ffffffff4803636004062f503253482f04428b055308
coinb22e522cfabe6d6da0bd01f57abe963d25879583eea5ea6f08f83e3327eba9806b 14119718cbb1cf04000000000000000000000001fb673495000000001976a914 80ad90d403581fa3bf46086a91b2d9d4125db6c188ac00000000
merkle_branch[“ea9da84d55ebf07f47def6b9b35ab30fc18b6e980fc618f262724388f2e9c591”,...]
版00000002
NBITS19015f53
n时间53058b41
clean_jobs假

如果矿工报告成功,job_id用于识别此采矿任务。

大多数字段用于块头。该prevhash是的哈希先前块。显然混合大端和小端的并不足够混淆,所以这个哈希值也有4个字节的每一个块反转。的版本是块协议版本。所述NBITS表示难度[3]的块的。时间戳ntime不一定准确。

该coinb1和coinb2域允许矿工打造为块coinbase交易。这种交易是通过连接形成coinb1,所述extranonce1在开始时获得的值,所述extranonce2该矿工已经产生,并且coinb2。结果是Bitcoin协议的交易。该merkle_branch散列表让矿工有效地与新coinbase交易重新计算哈希梅克尔。

如果矿工需要重新启动采矿作业,则使用clean_jobs。

收到这些数据后,矿工可以开始生成组合交易和采矿块。

蝴蝶实验室Jalapeño

Butterfly LabsJalapeñoASIC矿工,7+ GH / s,0xF2, (CC BY-ND 2.0)

为池创建一个块

一旦矿工从池中收到信息,就可以通过加入coinb1,extranonce1,extranonce2和coinb2来形成硬币基交易,形成一个投币系统交易。下面的图表显示了这四个值的组合如何形成一个完整的交易,而在这个基准脚本的中间是随机数。(下面的块与前面描述的略有不同)

由GHash.io采矿池生成的投币系统交易

由GHash.io采矿池生成的投币系统交易

硬币类交易的结构类似于常规交易,但有一些重要的区别。正常的事务将bitcoins从输入(通常是源地址)传输到输出(通常是目标地址)。一个投币系统的交易是通过稀薄的空气生成新的比特币,而不是进行转移,所以交易略有不同。以前的输出哈希和索引与coinbase事务无关。第一个脚本是scriptSig,它用于签署交易以证明传入的比特币的所有权。在一个投币系统交易中,这是无关紧要的,因此这个领域被称为投币系统,主要是任意数据。[9](许多矿工在那里隐藏信息)。投币系统交易中的价值领域是25比特币采矿回报加上从其他交易中剩下的任何比特币(左边比特币被视为采矿费用)。最后,常规交易和coinbase交易都使用第二个脚本(scriptPubKey)来指定比特币的收件人。[10] 有关交易的详细信息,请参阅我之前的文章

一旦创建了coinbase事务,这个coinbase事务的哈希与来自池的merkle_branch数据组合,为整个事务集合生成Merkle哈希[4]。由于Merkle哈希的结构(如下所述),这允许容易地重新计算整个事务集合的散列。

最后,块头是从新的Merkle哈希值和池中提供的数据构建出来的,哈希算法可以像前面的Python程序一样遍历头部中的nonce值。一旦所有的随机数值被尝试,矿工会增加extranonce2,生成一个新的硬币基交易并继续。

比特币块头

比特币块头

通知采矿池成功

采矿池的困难[3]远低于Bitcoin采矿难度(需要较少的前导零),所以获得份额要容易得多。当一个块被缓存到池的难度时,您可以向采矿池发送一个简单的JSON消息来提交它:

{“method”:“mining.submit”,“params”:[“kens.worker1”,“58af8db7”,“00000000”,“53058d7b”,“e8832204”],“id”:4}

参数是工作者名称,作业ID,extranonce2,时间和标题随机数。这个信息足以使池建立匹配的投币系统事务和头,并验证该块。如果哈希符合游泳池的难度,你会得到一个份额。如果哈希也符合比特币困难的困难,那么该块已成功开采。在这种情况下,池将该块提交到比特币网络,每个拥有股票的人都将得到相应的付款。

挖掘乐趣和利润

如果您对采矿感到好奇,那么尝试挖掘自己是非常容易的,尽管您将会幸运地赚取一分钱。只需在BTC公会等采矿池创建一个帐户,下载cpuminer(minerd.exe)等采矿软件,并运行软件开始挖掘。对于难度低的游泳池,您应该在几分钟内得到股票; 在一个难度较高的游泳池(如GHash.IO)中,可能需要一两个小时才能获得分享,这更令人沮丧。[3]

比特币开采示例

我的PC上无利可图的Bitcoin CPU挖掘

上面的屏幕截图显示了当您获得共享和块开采时,采矿的样子。我很幸运,只花了我一分钟才能成功挖掘一份。一分钟后,有人成功地开了一个街区,所以游泳池告诉大家重新开始。另外一块地块在不到一分钟之后就被开采了 - 尽管街区平均间隔10分钟,但时间可能差别很大。我下一次分享花了12分钟才能生成。跑了一段时间后,我获得了0.00000043 BTC,这是一小部分。

比特币矿业是一场“军备竞赛”。原来人们可以在普通PC上使用CPU,但是一段时间以来并不实用。下一次采矿被卸载到GPU。现在,采用专用ASIC硬件,速度正在迅速提高。盈利的采矿是非常有竞争力的,你需要在其他地方寻找信息。

如果你想尝试采矿只是为了乐趣,你可能更喜欢挖掘一种货币,如Dogecoin而不是比特币。首先,Dogecoin使用与ASIC硬件不兼容的不同哈希算法,因此与专业矿工相比,您并没有处于劣势。第二,因为dogecoins的价值远低于比特币,你会得到更多的dogecoins,这似乎更有益。对于Dogecoin挖掘,我稍微使用了dogepool.pw池。该过程与比特币挖掘几乎相同,只是使用scrypt算法而不是sha256d。还有许多其他可选择的加密货币可供选择。

注释和参考

[1]比特币挖掘似乎是一个NP(非确定性多项式)问题,因为解决方案可以快速验证。然而,使这个严谨的问题有几个问题。首先,由于哈希是一个固定的大小,挖掘可以在恒定的时间内完成(但是具有非常大的常数2 ^ 256)。因此,您需要考虑一个扩展挖掘方案,其难度可以达到无穷大。第二,采矿需要变成一个决策问题 - 例如,不是找到一个随机数,而是“有一个成功的小于k”。(请注意,如果可以解决这个问题,可以使用二进制搜索快速找到随机数。)

随着这些变化,采矿问题在NP。下一个问题是NP是否完成。那么,任意一个NP完整的问题能否变成一个挖掘问题呢?我相信目前是未知数。

[2]你可能会想,如果两个矿工在大约同一时间成功地开采一个区块,会发生什么。事务冲突的问题刚刚被冲突块的问题所取代?)规则是只使用最长 的有效块,而另一个分支被忽略。因此,当矿工用两个平行块中的一个延伸链时,另一个块变成孤立块并被忽略。

孤儿街是相当普遍的,大概每天一个。因此,(有些任意)建议是等待六次确认(约一小时),然后再考虑交易确认。

[3]我已经将一个成功的哈希描述为从零开始,但是有一个官方的难点定义。一个有效的块必须在目标值之下有一个哈希值。(由于目标以一堆零开始,所以有效的哈希值。)

有两种不同的难以理解的方式来表示目标。第一,位是目标在32位的尾数/指数表示。第二个困难是基准目标和当前目标之间的比率。的难度Ñ是Ñ倍此基准目标一样困难。基准目标是0x00000000FFFF0000000000000000000000000000000000000000000000000000对应于42亿次哈希成功中的大约1 32或1。

难度大约每两周更改一次,以便每10分钟保持块散列率约为1。所述https://blockchain.info/stats难度值是3,129,573,174.52,对应于目标00000000000000015f5300000000000000000000000000000000000000000000。将PC的性能乘以目前的难度显示,我的电脑需要大约35000年的时间来挖掘。

使用采矿池时,水池的困难很重要。我的电脑可以做大约12百万的散列/秒运行cpuminer,所以在1的困难我的电脑可以找到一个块每6分钟。BTC公会池的难度为2,所以我每12分钟会得到一个分摊。另一方面,GHash.IO的最低难度为16,所以平均每两个小时只能获得一次份额。(我的整体收入将是相似的,因为每个块的股票数量与难度相反)。

[4]代替将所有事务直接散列到块中,事务首先散列在一起以产生Merkle根。Merkle根是二进制Merkle树的根。这个想法是从所有的事务哈希开始。一对哈希散列在一起,产生新的散列。在新的哈希列表上重复该过程,并递归地继续,直到获得单个散列。最后的根哈希是计算块时使用的值。(有关更多详情,请参阅维基百科

在Merkle树中,每个交易都是散列的。然后将一对哈希散列在一起。然后,新的散列对将被散列在一起,依此类推,直到单个散列仍然存在。这样可以有效地验证单个事务的散列,而无需重新计算所有的哈希值。一个有用的地方是为采矿池生成一个新的投币系统交易。

Merkle树的(获得专利)的想法是,如果您需要修改或验证单个事务,则不需要重新计算所有内容,但可以重新计算受影响的对。就个人而言,我认为Merkle树是比特币的一个无意义的优化,对于合理的交易号码来说,做一个单一的大哈希会更快,而不是Merkle树上的多个哈希。

这里有一些演示代码来计算我正在讨论的块的Merkle根。为方便起见,99个交易散列是硬编码的。所产生的Merkle根是871714dcbae6c8193a2bb9b2a69fe1c0440399f38d94b3a0f1b447275a29978a

import hashlib

# Hash pairs of items recursively until a single value is obtained
def merkle(hashList):
if len(hashList) == 1:
return hashList[0]
newHashList = []
# Process pairs. For odd length, the last is skipped
for i in range(0, len(hashList)-1, 2):
newHashList.append(hash2(hashList[i], hashList[i+1]))
if len(hashList) % 2 == 1: # odd, hash last item twice
newHashList.append(hash2(hashList[-1], hashList[-1]))
return merkle(newHashList)

def hash2(a, b):
# Reverse inputs before and after hashing
# due to big-endian / little-endian nonsense
a1 = a.decode('hex')[::-1]
b1 = b.decode('hex')[::-1]
h = hashlib.sha256(hashlib.sha256(a1+b1).digest()).digest()
return h[::-1].encode('hex')

# https://blockexplorer.com/rawblock/0000000000000000e067a478024addfecdc93628978aa52d91fabd4292982a50
txHashes = [
"00baf6626abc2df808da36a518c69f09b0d2ed0a79421ccfde4f559d2e42128b",
"91c5e9f288437262f218c60f986e8bc10fb35ab3b9f6de477ff0eb554da89dea",
"46685c94b82b84fa05b6a0f36de6ff46475520113d5cb8c6fb060e043a0dbc5c",
"ba7ed2544c78ad793ef5bb0ebe0b1c62e8eb9404691165ffcb08662d1733d7a8",
"b8dc1b7b7ed847c3595e7b02dbd7372aa221756b718c5f2943c75654faf48589",
"25074ef168a061fcc8663b4554a31b617683abc33b72d2e2834f9329c93f8214",
"0fb8e311bffffadc6dc4928d7da9e142951d3ba726c8bde2cf1489b62fb9ebc5",
"c67c79204e681c8bb453195db8ca7d61d4692f0098514ca198ccfd1b59dbcee3",
"bd27570a6cbd8ad026bfdb8909fdae9321788f0643dea195f39cd84a60a1901b",
"41a06e53ffc5108358ddcec05b029763d714ae9f33c5403735e8dee78027fe74",
"cc2696b44cb07612c316f24c07092956f7d8b6e0d48f758572e0d611d1da6fb9",
"8fc508772c60ace7bfeb3f5f3a507659285ea6f351ac0474a0a9710c7673d4fd",
"62fed508c095446d971580099f976428fc069f32e966a40a991953b798b28684",
"928eadbc39196b95147416eedf6f635dcff818916da65419904df8fde977d5db",
"b137e685df7c1dffe031fb966a0923bb5d0e56f381e730bc01c6d5244cfe47c1",
"b92207cee1f9e0bfbd797b05a738fab9de9c799b74f54f6b922f20bd5ec23dd6",
"29d6f37ada0481375b6903c6480a81f8deaf2dcdba03411ed9e8d3e5684d02dd",
"48158deb116e4fd0429fbbbae61e8e68cb6d0e0c4465ff9a6a990037f88c489c",
"be64ea86960864cc0a0236bbb11f232faf5b19ae6e2c85518628f5fae37ec1ca",
"081363552e9fff7461f1fc6663e1abd0fb2dd1c54931e177479a18c4c26260e8",
"eb87c25dd2b2537b1ff3dbabc420e422e2a801f1bededa6fa49ef7980feaef70",
"339e16fcc11deb61ccb548239270af43f5ad34c321416bada4b8d66467b1c697",
"4ad6417a3a04179482ed2e4b7251c396e38841c6fba8d2ce9543337ab7c93c02",
"c28a45cded020bf424b400ffc9cb6f2f85601934f18c34a4f78283247192056a",
"882037cc9e3ee6ddc2d3eba86b7ca163533b5d3cbb16eaa38696bb0a2ea1137e",
"179bb936305b46bb0a9df330f8701984c725a60e063ad5892fa97461570b5c04",
"9517c585d1578cb327b7988f38e1a15c663955ea288a2292b40d27f232fbb980",
"2c7e07d0cf42e5520bcbfe2f5ef63761a9ab9d7ccb00ea346195eae030f3b86f",
"534f631fc42ae2d309670e01c7a0890e4bfb65bae798522ca14df09c81b09734",
"104643385619adb848593eb668a8066d1f32650edf35e74b0fc3306cb6719448",
"87ac990808239c768182a752f4f71cd98558397072883c7e137efb49d22b9231",
"9b3e2f1c47d59a444e9b6dc725f0ac6baf160d22f3a9d399434e5e65b14eccb0",
"fbe123066ae5add633a542f151663db4eb5a7053e388faadb40240671ae1b09b",
"1dd07e92e20b3cb9208af040031f7cfc4efd46cc31ec27be20a1047965a42849",
"2709bb9ed27353c1fd76b9240cab7576a44de68945e256ad44b2cb8d849a8060",
"d0174db2c712573432a7869c1508f371f3a1058aeedddc1b53a7e04d7c56c725",
"b4a16f724cddb8f77ddf3d2146a12c4be13d503885eaba3518a03da005009f62",
"2aa706d75decbe57745e01d46f9f5d30a08dedaf3288cee14cc4948e3684e1d4",
"ee49c5f6a5129ccaf2abebbc1d6d07a402a600af6221476b89aafaa683ca95b7",
"bea1011c77874845e9b4c876ed2ceebd530d428dd4a564ad003d9211d40bb091",
"f1e88ffc2b1de2aa4827002f06943ce5468735f7433f960bf01e75885b9f832b",
"19247d017e002fb9143d1a89eb921222a94f8a3d0faaf2e05b0f594989edc4c4",
"13f714ff62ee7d26b6d69ca980c141ebc54e9f71d2697083fe6c5efc1b02bd0f",
"0c78cbb8246572f015fbdc53dc9798fa54d1119ec77c1f07ac310bcbcc40dbf8",
"4bcde0ef92a6d24a2be7be50ac5e5299d776df2e6229ba5d475c2491da94f255",
"0cfd7d1058502730cf0b2ffa880c78ef534651e06832b5d87c0d7eb84eac5b0c",
"3a168f794d6e0c614429ad874317cc4cd67a8177214880ff6ea1704d29228c2f",
"f9a555d817334397b402518d6fd959dc73d981ee7f5fe67969b63974ebbef127",
"24b52691f66eaed4ce391a473902e309018257c98b9f02aaa33b399c9e6f3168",
"a37b5e623dc26a180d9e2c9510d06885b014e86e533adb63ec40511e10b55046",
"9dbaeb485e51d9e25a5621dc46e0bc0aaf51fb26be5acc4e370b96f62c469b80",
"a6431d3d39f6c38c5df48405090752cab03bfdf5c77cf881b18a946807fba74a",
"faa77e309f125373acf19855dd496fffe2f74962e545420844557a3adc7ebc11",
"3523f52543ecfea2f78486dc91550fad0e6467d46d9d9c82ca63b2e0230bfa71",
"a0583e358e42d77d18d1fd0533ff0a65615fc3b3112061ef92f168a00bf640c1",
"42ae900888d5e5dde59c8e3d06e13db9e84ef05d27726d4b67fd00c50cd9406a",
"154940777d3ff78f592ef02790131a59263c36b4958bbc836f9a767ea1a9f178",
"6a0337de6ac75eecf748306e8ebc5bfe5c811a1481ae50f6956a9e7f26a679f5",
"c99530c2148e09688d0b88795625943371183bf1f5d56c7446c6ed51ea133589",
"626421dbe8ad6a0fd0d622d5dd3308a1cdc00b98575a41a91fe01a439e6f40bd",
"b2f3a559f605a158cc395126c3cf394a7e92a53b7514c75157e1dc43a6c7f93e",
"dffe06d1bea81f2a01c76786404bb867258f9e68013bf25454097ce935090738",
"0860159ec7a2a51ce107c182a988c40b4bc2057a734354a1219b6c65e72640ed",
"a405ff1bb51846b1867acc0b0da17f6f9616e592a0a7ff5ef3297c1ecfd60911",
"a7d451924263284765f6343bca8a21b79b89ebfe611c7355dd88e0ec1c29e232",
"41c758d08a4d3fe4d90645711589b832a2cd54dd25bd5b66e463e5d389a53aff",
"a05c1a93a521fa5dbc1790cfbb808893453a428a65f2c6b2d51249fbb12db309",
"90997920aa9786e10f513cfdd14e294feee6739cee1ab61b3fb1e3f42e7a915d",
"99fcb9cb62c20a3135484a70bd3f73983f8f3b7b26266dad34f3993958a7642c",
"e05f9a668b37e5f78bd3b9d047f29f92b33a87f11dd48390410006f858188b7b",
"56dbc65895f7992da4a6985e7edba4d1c00879f1b28442c644c8a07658ceab27",
"5e9004fe262b829563d0804656ba68b1de1690401f08a1915273230d8c902fc0",
"1ea9ed3717523c5e304b7a7ac8058a87fb4f3fed8c6004769f226c9bb67e79c5",
"f0f1a4c009b3f1b2729e89898e2f5c0fcdc312edea5df884a9c897cb90e4c566",
"b5bb4ddf04863e6a60f33cb96c20dac8175d3bae55f335781503143c97a50e43",
"f14cc97a20c6f627b4b78301352ae35463bc359362589cd178a06c0fa90850b7",
"628801c8f614015c0fa0ccb2768cccc3e7b9d41ceed06071ce2534d31f7236d6",
"3be1013c8f8da150e2195408093153b55b08b037fd92db8bb5e803f4c2538aae",
"c9e1f8777685f54ba65c4e02915fd649ee1edcbf9c77ddf584b943d27efb86c3",
"4274e92ed3bd02eb101baa5fb8ff7b96236830762d08273749fbb5166db8ab0b",
"aa84c955bea04c7cee8f5bbbec97d25930fcaca363eed1b8cad37b931556d3e3",
"d6a29c948677fb1f71aaf16debc3d071a4dd349458eb9e056dce3a000ff853da",
"ba84bdb3d78367ca365016ac4bff9269576eb010f874c2967af73e0de5638de0",
"1546c79951e3b541bc64d1957b565b7a2850fc87192c7b374aee6cfc69b9805e",
"f119227d492ebe27fe9aae321980802454dfa64b2691efbe796c5075d5b07f62",
"b8cf13d64818b32f96bbb585998b1bc9505f6a94055488e5a71fee9479c6f2a9",
"1aaf459705b6afef2d7b83e3f181f1af55be0813daf55edce104cc59abc28ed7",
"61ac185c8f520b5e3134953dc52ff292a40e1e96b088dab259558a9d240ec02f",
"2da96e3154d7ec2329f787b73cb8a436b92d64cf3cc28e920d073279ea73b5f8",
"1c4d72ce733b971b9ec4e24f37d733355f6f2ea635cc67ffb3e22748484df446",
"2a6f89769f3272ac8c7a36a42a57627eca6b260ab2c76d8046a27d44d4034893",
"f8d11df51a2cc113698ebf39a958fe81179d7d973d2044322771c0fe63f4d7c9",
"f2287f17a4fa232dca5715c24a92f7112402a8101b9a7b276fb8c8f617376b90",
"bb5ee510a4fda29cae30c97e7eee80569d3ec3598465f2d7e0674c395e0256e9",
"647ab8c84365620d60f2523505d14bd230b5e650c96dee48be47770063ee7461",
"34b06018fcc33ba6ebb01198d785b0629fbdc5d1948f688059158f053093f08b",
"ff58b258dab0d7f36a2908e6c75229ce308d34806289c912a1a5f39a5aa71f9f",
"232fc124803668a9f23b1c3bcb1134274303f5c0e1b0e27c9b6c7db59f0e2a4d",
"27a0797cc5b042ba4c11e72a9555d13a67f00161550b32ede0511718b22dbc2c",
]

print merkle(txHashes)

view rawmerkle.py hosted with ❤ by GitHub

[5]第三方可以通过几种方式修改交易,而不会使交易中的签名无效。这被称为交易延展性。这些修改会更改事务的哈希。由于散列是块的一部分,事务具有固定的散列,并且一旦它被挖掘到块中就不能被可延展性修改。(除非整个街区是孤儿,当然)

[6]由于硬件变化如此之快,目前还不清楚实际使用的是什么,因此很难估计采矿成本,但是我会做一个粗略的计算。看看比特币矿业硬件采矿硬件比较页面,HashBlaster看起来像现在最高效率为375 MH / s / $和1818 MH / s / W。比特币网络是250亿MH / s,其硬件成本约为7000万美元,15兆瓦。(这是柬埔寨的总耗电量)。以0.15美元/ kWh计算,每天电费约为50,000美元(每块300美元,或每笔交易0.70美元)。由于采矿每天生产约14万美元,每天花费5万美元的电力似乎是正确的球场。其他估计是在黑客新闻

[7]你可能会想,为什么矿工不会作弊。如果他们成功地挖了一块,为什么不自己提交,以便他们能够索取全部的矿工奖励,而不是分裂?主要原因是投币系统交易有池的地址,而不是矿工的地址。如果矿工提交块绕过游泳池,奖励仍然到达游泳池。如果矿工更改地址,则哈希不再有效。

[8] 采矿池使用了几种不同的奖励制度。例如,一个池可以支付从一个块获得的确切数量或平均数量。或者一个池可以每股支付固定的金额。一个池可以按时分配份量,以避免矿工在中间块之间切换。这些不同的系统可以平衡矿工和池运营商之间的风险,并调整付款方式。有关详细信息,请参阅这里此处的Bitcoin维基。

[9]我已经找出了很多上面的coinbase脚本的结构。首先它包含块高度(0x046063或286819),这是 版本2所需的)。接下来是字符串'/ P2SH /',表示矿工支持 付费脚本哈希值。之后是时间戳。接下来是两个随机数的8个字节。其次是随机数据,然后是文字“Happy NY!Yours GHash.IO”。

[10]典型的硬币基脚本格式随着时间的推移而改变。原来,输出脚本都是付费到pubkey,脚本:public_key OP_CHECKSIG。该脚本将公钥本身放在脚本中。然而,现在大约95%的投币系统交易使用标准付费到公钥哈希脚本:。该脚本仅包括公钥哈希(地址),并要求兑换器提供公钥。要查看差异,请比较此事务中的输出脚本 和 此事务OP_DUP OP_HASH160 addr OP_EQUALVERIFY OP_CHECKSIG



你的表情