getblocktemplate协议

getblocktemplate协议
getblocktemplate协议是新的分散式的比特币挖矿协议,于2012年中旬在比特币社区开放自主研发,它取代了老的getwork挖矿协议。
为什么要改变一些有用的东西呢?
分散化(权力下放) Decentralization
原始的getwork挖掘协议仅仅为一个矿工发出区块头以供其解决。矿工对这个区块的实际情况一无所知,对它没有影响。实际上,矿商决定接受哪些事务等的权力,都被盲目地转移到池经营者。一个腐败的(或缺乏抵抗力的)池经营者可以使用所有矿工的混合散列能力来执行双重开销攻击或其他类似的攻击。
getblocktemplate将块创建移动到矿工,同时为池提供一种设置参与规则的方法。虽然通过在这些规则中表达, 资源池可以尽其所能地发挥作用,但矿工不能被蒙在鼓里,而是能够自由地选择他们参与开采的内容。 这将使块再次分散,从而提高比特币网络的安全性。
ASICs (一种为专门目的而设计的集成电路)
原始的getwork协议只提供了一个块头,这对于总共约4GH的采矿是足够的。随着"rollntime"扩展,这可以扩展到每秒4gh *,但即使这样也远远不能满足下一代能够在高端上达到1000 GH/s的采矿设备(ASICs)。
通过将块创建移动到矿工,它们可以在本地创建所需的工作,从而克服这个限制。
可伸缩性 Scalability
由于可扩展性问题, bitcoind的JSON-RPC堆栈无法跟上今天单独挖矿所需的 hashrate(哈希率?),由于getblocktemplate大大减少了网络上每个新块对单个请求所需要的负载,因此直接单独挖掘bitcoind仍然是可能的。poolserver同样受益于满足矿工的低得多的需求,他们可以自己做区块。
扩展性
原始网络协议(getwork)的设计与扩展非常不兼容。 因此,随着新功能的需要,扩展被HTTP头服务器“黑入”了。getBlock模板从一开始就被设计为对未来的扩展具有灵活性,BIP 23规范已经涵盖了如何干净地实现已建立的getwork扩展,而不管传输协议如何。

如何使用
对于矿工
采用GBT支持的采矿软件:
要利用getblocktemplate,您还需要兼容
对于池操作员


对于开发者
采矿软件
使用libblkmaker(C库)
如果您的矿工可以包含C库,那么您可以利 libblkmaker 为您做所有GBT解释:您的矿工所需要做的就是处理网络(libblkmaker可以为您准备JSON( JS 对象简谱 ))并向libblkmaker索取数据(块头搜索)请注意,libblkmaker不提供SHA256实现,您的矿工需要提供一个工作。libblkmaker目前仅支 Jansson JSON ,但其设计使其可以轻松移植到其他人;  Luke Dashjr 愿意根据请求免费将其移植到其他JSON库。
使用python-blkmaker
如果你的矿工是用Python编写的,你可以利用 python-blkmaker (一个 ibblkmaker 的本地Python端口)为你做所有的GBT解释:你所有的矿工需要做的就是处理网络(python-blkmaker可以为你准备JSON),并要求blkmaker模块的数据(块头来搜索)。包含一个简短的示例Python脚本,它使用CPU挖掘来查找准备好的共享。
从头开始
矿工请求块模板
要开始参与,矿工联系该池并请求初始模板:
{"id": 0, "method": "getblocktemplate", "params": [{"capabilities": ["coinbasetxn", "workid", "coinbase/append"]}]}
服务器将回复所需的全部细节,以立即开始挖掘块
{ "error": null, "result": { "coinbasetxn": { " data ": "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff1302955d0f00456c6967697573005047dc66085fffffffff02fff1052a010000001976a9144ebeb1cd26d6227635828d60d3e0ed7d0da248fb88ac01000000000000001976a9147c866aee1fa2f3b3d5effad576df3dbf1f07475588ac00000000" }, " previousblockhash ": "000000004d424dec1c660a68456b8271d09628a80cc62583e5904f5894a2483c", " transactions ": [], " expires ": 120, " target ": "00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", " longpollid ": "some gibberish", " height ": 23957, " version ": 2, " curtime ": 1346886758, " mutable ": ["coinbase/append"], " bits ": "ffff001d" }, "id": 0}

如何建立 coinbase交易
如果池允许通过将“coinbase / append”变体包含在“可变”键中,您可以重建coinbase事务以追加矿工想要的任何数据,例如extranonce - 您可以根据需要使用尽可能多的空间只要coinbase数据不会溢出100字节的硬限制。如果服务器不允许“coinbase / append”,或者您不想改变它,您可以完全跳过这。
coinbase的数据总是在coinbase交易的42字节之后开始。 第42字节(即数据之前的字节)是数据的长度.因此,如果你想要添加coinbase数据,只需在交易中插入42+DataLen字节,并根据插入数据的长度增加第42字节。

Python示例:
import binasciicoinbase = binascii.a2b_hex(template['coinbasetxn']['data'])extradata = b'my block'# The following can be done better in both Python 2 and Python 3, but this way works with bothorigLen = ord(coinbase[41:42])newLen = origLen + len(extradata)coinbase = coinbase[0:41] + chr(newLen).encode('ascii') + coinbase[42:42 + origLen] + extradata + coinbase[42 + origLen:]

如何建立Merkle
收集您的coinbase交易(修改与否)在服务器提供的“交易”列表的前面,将双SHA256哈希应用于列表中的每个事务。
现在,只要名单上有超过一个哈希表,就检查每一对并将它们混合在一起。也就是说,连接前两个,双sha256,重复下两个,以此类推。如果您遇到一对奇数的组合(也就是说,散列列表以单个项目结束,而没有结对),将它与自身连接并将其进行散列。继续这样做,直到只剩一个散列:那是你的merkle根。

Python示例:
import hashlibdef dblsha(data): return hashlib.sha256(hashlib.sha256(data).digest()).digest()txnlist = [coinbase] + [binascii.a2b_hex(a['data']) for a in template['transactions']]merklehashes = [dblsha(t) for t in txnlist]while len(merklehashes) > 1: if len(merklehashes) % 2: merklehashes.append(merklehashes[-1]) merklehashes = [dblsha(merklehashes[i] + merklehashes[i + 1]) for i in range(0, len(merklehashes), 2)]merkleroot = merklehashes[0]
如何构建区块头
使用块模板中提供的数据以及您自己的merkle根,按照比特币块哈希算法中的规定组装块头。 请注意,矿工需要检查“版本”号码,并且不应该为他们不明白的版本创建块,除非服务器指示他们使用“版本/强制”或“版本/减少”突变来执行此操作 - 如果您不支持服务器提供的版本,请了解如果服务器不符合某些未知的未来规则,服务器可能会拒绝提交。
Python示例:
import structblkheader = struct.pack('<I', template['version']) + \ binascii.a2b_hex(template['previousblockhash']) + \ merkleroot + \ struct.pack('<I', template['curtime']) + \ binascii.a2b_hex(template['bits']) + \ b'NONC'
当你在挖矿
因为你自己制造了所有的区块,你真的不需要再得到一个模板。直到它是无效的。一般来说,为了获得更多的事务,最好刷新一下,但是最好还是让池来决定什么时候该做,因为它知道在此期间已经发生了什么变化。
如果您的模板包含一个“ longpollid ”键,那么您可以在池决定您应该更改的时候排队等待新模板的请求。这与任何其他模板请求都是一样的,除了您在 req 中包含了“longpollid”参数。 如果已经有了一个新的模板,池可能会立即响应,所以请确保不要依赖于延迟!
为了修正我们最初使用的模板请求,现在我们使用:
{"id": 0, "method": "getblocktemplate", "params": [{ "capabilities": ["coinbasetxn", "workid", "coinbase/append"], "longpollid": "some gibberish",}]}
提交shares
当矿工找到符合要求难度的工作时,可以将该块作为份额提交给服务器:
{"id": 0, "method": " submitblock ",
"params": [ "020000003c48a294584f90e58325c60ca82896d071826b45680a661cec4d424d00000000de6433d46c0c7f50d84a05aec77be0199176cdd47f77e344b6f50c84380fddba66dc47501d00ffff000001000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff1302955d0f00456c6967697573005047dc66085fffffffff02fff1052a010000001976a9144ebeb1cd26d6227635828d60d3e0ed7d0da248fb88ac01000000000000001976a9147c866aee1fa2f3b3d5effad576df3dbf1f07475588ac00000000"]}
要汇总块数据,只需将您的块头,以比特币 varint格式 编码的交易数连接起来,然后再连接块中的每个交易(以coinbase开头)。 如果服务器在其“可变”键中列出了“submit/coinbase”,那么您可以选择忽略coinbase之后的事务。

Python示例
def varintEncode(n): if n < 0xfd: return struct.pack('<B', n) # NOTE: Technically, there are more encodings for numbers bigger than # 16-bit, but transaction counts can't be that high with version 2 Bitcoin # blocks return b'\xfd' + struct.pack('<H', n)blkdata = blkheader + varintEncode(len(txnlist)) + coinbaseif 'submit/coinbase' not in template.get('mutable', ()): for txn in txnlist[1:]: blkdata += txn
Poolserver软件
首先推荐的标准(按重要性排列)
技术说明书
历史
Getblocktemplate的起源追溯到forrestv的bitmemory的getmemorypool JSON-RPC方法。他创建了它,以便他的矿池(P2Pool)可以在bitcoind上捎带回去,以避免损害比特币网络(到目前为止,它只挖掘了从未确认交易的空块)。一直在pushpool / bitcoind中与可扩展性问题斗争数月(Eligius),Luke-Jr开始着手实现一个使用getmemorypool进行自己的块生产的快速池服务器(这成为了Eloipool,这是第一个开源代码 - 它的-own-blocks poolserver)。其他池服务器在接下来的几个月内也使用getmemorypool实现了块创建。
 
与此同时,对集中采矿权下放的兴趣成为热门话题。虽然BitPenny最初在几个月之前发布了自己的分散式挖矿代理,但P2Pool的实施变得非常流行。参与比特币采矿协议的任何人都可以看到需要将块创建的控制权交还给矿工手中。不幸的是,BitPenny和P2Pool都使用特定于池的专有协议来实现其分散化。另一方面,getmemorypool几乎完全适合这项任务 - 它只是缺乏对随着时间的推移围绕网络协议开发的现在无处不在的池式挖掘扩展的支持。
 
2012年2月,卢克在Eloipool(和Eligius)实施并部署了第一个getmemorypool挖掘支持草案以及概念验证的代理(现在称为gmp-proxy),并根据需要添加了修订以作为通用分散采矿协议。在他确认它正在工作之后,他在比特币发展邮件列表中记录并提出了它以便在2月28日进行审查,讨论开始时缺少的内容以及需要更改或澄清的内容。在接下来的几个月中,一些其他开发人员和测试人员提供了建设性的批评和建议,并将其融入标准。卢克还积极鼓励参与池中操作员和池服务器作者的标准开发工作,特别是因为有必要推进ASIC“采矿一代”。最后,决定最好将其重命名为更合适的“getblocktemplate”名称,并简化与getmemorypool的向后兼容性。该标准分为两部分,技术规格可在BIP 22和BIP 23中找到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值