比特币引入隔离见证后的矿工挖矿研究

我最近一直在尝试写一个比特币挖矿软件,不是为了真的挖比特币,纯粹是为了做技术研究。

在看了BIP一些关于隔离见证的文档之后,我想应该马上拿一个实际的例子来分析一下,加深印象。我选择在btc主网上拿一个区块来分析,这里我选择区块高度是638316,这是最新生成的区块。

用区块浏览器查看这个高度的区块信息以及它的coinbase交易,连接如下:https://btc.com/00000000000000000011d1260195a49f92eb720e8f1c4c8d23ea592760dac663

用网上公开的API查看coinbase交易的原始二进制数据:

https://api.blockchair.com/bitcoin/raw/transaction/f395f865fc046764cb8e2140b696528e9aee02d51e1c9504a4a173b6e0b08686

得到原始数据如下:

010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff54036cbd091b4d696e656420627920416e74506f6f6c3234a80083002078d4031efabe6d6d2fe32793d84d2d60b446f55dedce3cb2792f60bb2dcb417d07b9283d88fe014b0200000000000000706b0100f24d0000ffffffff03ab3fab27000000001976a91411dbe48cc6b617f9c6adaf4d9ed5f625b1c7cb5988ac0000000000000000266a24aa21a9edc16bd501e4b5d616ccf8d4ed95305ed8f7bf5bf0f9712a2c5af31a6e2f6e9b360000000000000000266a24b9e11b6d1a85afc306f75e4a446ddebd03bcffa5211696993ea106b804f9adc58d4de4e40120000000000000000000000000000000000000000000000000000000000000000000000000

计算原始数据的txHash:

func TestCoinbase(t *testing.T) {
	txStr := "010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff54036cbd091b4d696e656420627920416e74506f6f6c3234a80083002078d4031efabe6d6d2fe32793d84d2d60b446f55dedce3cb2792f60bb2dcb417d07b9283d88fe014b0200000000000000706b0100f24d0000ffffffff03ab3fab27000000001976a91411dbe48cc6b617f9c6adaf4d9ed5f625b1c7cb5988ac0000000000000000266a24aa21a9edc16bd501e4b5d616ccf8d4ed95305ed8f7bf5bf0f9712a2c5af31a6e2f6e9b360000000000000000266a24b9e11b6d1a85afc306f75e4a446ddebd03bcffa5211696993ea106b804f9adc58d4de4e40120000000000000000000000000000000000000000000000000000000000000000000000000"

	buf, err := hex.DecodeString(txStr)
	if err != nil {
		t.Error(err)
		return
	}
	txHash := common.Sha256AfterSha256(buf)
	t.Log(hex.EncodeToString(txHash[:]))
}

结果如下:

5af3bb3c88f26f5c2cd3e0850a302851d4e7983d780c2562f564e8280254275e

这个值和我用来查询这笔交易的时候用的txid相差很大。这是正常的,因为这个coinbase采用隔离见证的方式来打包交易数据。txid计算的时候不会包含witness data,但是txhash计算的时候会包含witness data。

下面要仔细考察一下这个用隔离见证方式打包的coinbase交易内容是怎样的(因为用csdn表格编辑发布文章有bug,后我发现表格不见了,所以才用下面这种丑陋的方式呈现)。

01000000 Version 版本号

0001 [marker][flag] 隔离见证标志

01 - input数量

0000000000000000000000000000000000000000000000000000000000000000 - input对应的前一个output所在的交易id

ffffffff -input对应的前一个output所在的交易中的位置

54 -input脚本大小

036cbd091b4d696e656420627920416e74506f6f6c3234a80083002078d4031efabe6d6d2fe32793d84d2d60b446f55dedce3cb2792f60bb2dcb417d07b9283d88fe014b0200000000000000706b0100f24d0000 -input脚本

ffffffff -sequence序列号

03 -output数量

ab3fab2700000000 -[0]output 的比特币金额

19 -[0]output脚本大小

76a91411dbe48cc6b617f9c6adaf4d9ed5f625b1c7cb5988ac -[0]output脚本

0000000000000000 -[1]output 的比特币金额

26 -[1]output脚本大小

6a24aa21a9edc16bd501e4b5d616ccf8d4ed95305ed8f7bf5bf0f9712a2c5af31a6e2f6e9b36 -[1]output脚本

0000000000000000 -[2]output 的比特币金额

26 -[2]output脚本大小

6a24b9e11b6d1a85afc306f75e4a446ddebd03bcffa5211696993ea106b804f9adc58d4de4e4 -[2]output脚本

01 -隔离见证数量

20 -隔离见证数据大小

0000000000000000000000000000000000000000000000000000000000000000 -隔离见证数据

00000000 -锁定时间

从上面的解析数据可以看出,这个coinbase交易有一个输入,却有三个输出。其中第一个输出是旷工用来接收BTC的,第二个输出是旷工的commitment,更多详情请移步这里。这最后一个输出是做什么的?我一直不知道。另外,看来coinbase交易其实是不需要旷工进行签名的,因为witness字段全都是空值。

那这里的ScriptSig字段里填写的都是什么内容呢?试着用BTC脚本语言解码看看。

03 - 把后面3个字节数据压到栈顶
6cbd09 - 等于十进制638316,这正是区块高度
1b - 把后面27个字节数据压到栈顶
4d696e656420627920416e74506f6f6c3234a80083002078d4031e - Mined by AntPool24࠸ԃ,这是旷工的相关信息

fabe6d6d2fe32793d84d2d60b446f55dedce3cb2792f60bb2dcb417d07b9283d88fe014b0200000000000000706b0100f24d0000 - 后面这一大堆就解码不出来了

由于BTC脚本语言中没有0xfa这个字节对应的操作码,所以到这里我就看不懂最后那一大段数据是什么意思了,也许是旷工随便写的呢。

对于这里未知的内容,一方面需要更仔细去查看一下BIP相关内容,另一方面也需要去努力写代码测试。

 

最后来计算一下txid,把上面的[marker][flag]和最后跟witness相关的字段数据删除后重新组合数据计算txid,代码如下:

func TestCoinbase(t *testing.T) {
	txStr := "010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff54036cbd091b4d696e656420627920416e74506f6f6c3234a80083002078d4031efabe6d6d2fe32793d84d2d60b446f55dedce3cb2792f60bb2dcb417d07b9283d88fe014b0200000000000000706b0100f24d0000ffffffff03ab3fab27000000001976a91411dbe48cc6b617f9c6adaf4d9ed5f625b1c7cb5988ac0000000000000000266a24aa21a9edc16bd501e4b5d616ccf8d4ed95305ed8f7bf5bf0f9712a2c5af31a6e2f6e9b360000000000000000266a24b9e11b6d1a85afc306f75e4a446ddebd03bcffa5211696993ea106b804f9adc58d4de4e40120000000000000000000000000000000000000000000000000000000000000000000000000"
	tx := Transaction{}

	if err := tx.Parse(txStr); err != nil {
		t.Error("parse transaction wrong")
		t.Error()
		return
	}
	tx.Print()

	buf, err := hex.DecodeString(txStr)
	if err != nil {
		t.Error(err)
		return
	}
	txHash := common.Sha256AfterSha256(buf)
	t.Log("txhash:",hex.EncodeToString(txHash[:]))

	txWithoutWitness := "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff54036cbd091b4d696e656420627920416e74506f6f6c3234a80083002078d4031efabe6d6d2fe32793d84d2d60b446f55dedce3cb2792f60bb2dcb417d07b9283d88fe014b0200000000000000706b0100f24d0000ffffffff03ab3fab27000000001976a91411dbe48cc6b617f9c6adaf4d9ed5f625b1c7cb5988ac0000000000000000266a24aa21a9edc16bd501e4b5d616ccf8d4ed95305ed8f7bf5bf0f9712a2c5af31a6e2f6e9b360000000000000000266a24b9e11b6d1a85afc306f75e4a446ddebd03bcffa5211696993ea106b804f9adc58d4de4e400000000"
	buf, err = hex.DecodeString(txWithoutWitness)
	if err != nil {
		t.Error(err)
		return
	}
	txHash = common.Sha256AfterSha256(buf)
	t.Log("txid:",hex.EncodeToString(txHash[:]))
}

计算结果如下:

transaction_test.go:97: txhash: 5af3bb3c88f26f5c2cd3e0850a302851d4e7983d780c2562f564e8280254275e
transaction_test.go:106: txid: 8686b0e0b673a1a404951c1ed502ee9a8e5296b640218ecb646704fc65f895f3

拿这两个值和api获取到的txid和hash值对比一下,发现是可以对得上的(但是注意字节序列刚好相反)。

https://api.blockchair.com/bitcoin/raw/transaction/f395f865fc046764cb8e2140b696528e9aee02d51e1c9504a4a173b6e0b08686

(全文完)

参考资料和帮助工具:

https://en.bitcoin.it/wiki/Script

https://blockchair.com/api/docs#link_M3

https://www.bejson.com/convert/ox2str/

https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#Transaction_ID

https://learnmeabitcoin.com/guide/coinbase-transaction

https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:精致技术 设计师:CSDN官方博客 返回首页

打赏作者

maxdaic

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值