ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

比特币的交易消息到底长啥样?

2021-01-27 12:02:23  阅读:185  来源: 互联网

标签:脚本 公钥 私钥 到底 解锁 比特 消息 OP


交易(transaction)长啥样

比特币使用的是区块链技术,所以它的所有产生的区块(一个区块里面包含很多条交易)都是透明可查的,可进这个网站:https://btc.com/stats/pool/BTC.com 进行查询。

binfun选取BTC历史区块里面的一条transaction:
https://btc.com/0627052b6f28912f2703066a912ea577f2ce4da4caa5a5fbd8a57286c345c2f2

该条transaction的编号为:0627052b6f28912f2703066a912ea577f2ce4da4caa5a5fbd8a57286c345c2f2

该交易的内容如截图:

从上图我们可以看到“输入”中的账户1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK把0.1个BTC分别转给了“输出”中的账户1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA(该账户收到了0.01500000个BTC)
1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK(该账户也就是原账户发送给了自己0.08450000个BTC)。

所以这交易就是账户1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK转了0.015个BTC给1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA

但是输出中的0.0845 + 0.015 = 0.0995,并不等于0.1啊,这是因为去掉的0.0005就是矿工费。

进一步看看

上面的那张图片实际上把这条交易可视化了,这条交易的真实样子是长这样的:

{
  "version": 1,
  "locktime": 0,
  "vin": [
    {
      "txid":"7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",
      "vout": 0,
      "scriptSig": "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL] 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf",
      "sequence": 4294967295
    }
 ],
  "vout": [
    {
      "value": 0.01500000,
      "scriptPubKey": "OP_DUP OP_HASH160 ab68025513c3dbd2f7b92a94e0581f5d50f654e7 OP_EQUALVERIFY OP_CHECKSIG"
    },
    {
      "value": 0.08450000,
      "scriptPubKey": "OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG",
    }
  ]
}

是不是一脸懵逼,懵逼就对了。这条交易主要由vinvout两大块组成。看不懂我们就从似曾相识的数字看起:vout里面有个"value": 0.01500000和"value": 0.08450000,这两个数字我懂,这就是转账数字啊。

就是刚才的比特币地址1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK发送给另一个比特币地址1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA的钱嘛。

听说比特币地址是由Base58编码的,Base58编码是啥咱也不知道,咱也不敢问,反正估计和Base64大差不差。

于是binfun毫不知情地从https://github.com/grondilu/bitcoin-bash-tools上下载了一个脚本bitcoin.sh,一顿猛操作对地址进行Base58解码:

. bitcoin.sh
decodeBase58 1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK

得到了:

007f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a801974ac6

这串16进制数有点眼熟啊,这不就和上面看到的

    {
      "value": 0.08450000,
      "scriptPubKey": "OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG",
    }

7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 

非常接近了,就是多出了头上的"00"和尾巴上的"01974ac6"

其中头上的"00"代表了主网版本号,而"01974ac6"代表了校验和,这个校验和可以由以下python命令生成:

import hashlib
import codecs
key = codecs.decode('007f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8', 'hex')
r = hashlib.new('sha256', key).digest()
r = hashlib.new('sha256', r).digest()
print(codecs.encode(r, 'hex').decode("utf-8"))
01974ac64161c88c363cc701200f529e517ab8a68d11e5f9e46bdb459cc34cd9

可以看到该校验和由连续两次的sha256后的结果,取该结果的前四个字节,也就是01974ac6

以上过程就是类似比特币地址和比特币公钥的转换过程。

再仔细看看

为了便于理解,我们可以认为在vout中,以上所述的两个比特币地址中分别获得了0.015和0.0845个BTC。

换句话说vout就是把比特币“锁定”在上述两个比特币地址中,上面出现的scriptPubKey就是所谓的“锁定脚本”。

那么vin是干啥的,就是解锁呀,让我们再看一眼vin

  "vin": [
    {
      "txid":"7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",
      "vout": 0,
      "scriptSig": "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL] 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf",
      "sequence": 4294967295
    }
 ],

以上的txid是transaction id的缩写,我们当前的txid是0627052b6f28912f2703066a912ea577f2ce4da4caa5a5fbd8a57286c345c2f2
(下图中用txid0627052b简写)

但是vin中却引用了

"txid":"7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",

(下图中用txid7957a35f简写)

这显得有点绕,具体意思如下图所示:

所以scriptSig就是“解锁脚本”的意思,其中内容就是用户A使用他的私钥进行了一项签名,证明我是地址A的私钥拥有者,我有权对锁定到地址A内的余额进行使用。

那么问题又来了,用户A的钱又是哪里来的???实际上不断追溯源头的话,最终大家的比特币都来自于一种叫做币基交易(coinbase)的特殊交易,币基交易是没有vin的,币基交易是由挖到矿的矿工生成的,所以挖矿挖到的都是“新币”,平时用户转账的币追溯到最上面的话,都是矿工挖出来的。

解锁和锁定脚本

现在我们知道,有用来解锁资金的解锁脚本,以及锁定资金的锁定脚本,解锁脚本是在"vin"中,锁定脚本是在"vout"中。

那么这些脚本长什么样呢?比特币交易脚本语言是一种逆波兰表达式的基于堆栈的执行语言。

在介绍解锁、锁定脚本之前,先介绍一下比特币的私钥、公钥、比特币地址之间的关系。

关于比特币公钥私钥的特性,只需要知道这两点:

  1. 私钥经过椭圆算法之后生成公钥,公钥经过哈希算法之后生成比特币地址(也就是公钥哈希)。这个过程是不可逆的,也就是说通过公钥不能倒推出私钥,但是私钥却可以生成公钥。

  2. 一段文本经过私钥加密之后只能由公钥进行解密,而由公钥加密之后的文本只能由私钥解密,这就是非对称加密算法。

vout中的一种典型的锁定脚本如下:

OP_DUP OP_HASH160 <Public Key Hash> 
OP_EQUALVERIFY OP_CHECKSIG

其中需要注意的是,是公钥哈希(可以通过它推出比特币地址),锁定脚本中指定了拥有该公钥哈希的私钥人,才能解锁该脚本。

vin中的一种典型的的解锁脚本如下:

<Signature> <Public Key>

解锁脚本提供了签名以及公钥,该签名是私钥将交易加密后产生的。

当验证脚本的时候,需要把两个脚本组合起来如下:

<Signature> <Public Key> OP_DUP OP_HASH160 <Public Key Hash> OP_EQUALVERIFY OP_CHECKSIG

以上的运行规则类似逆波兰表达式的堆栈脚本,流程如下:

  1. 首先验证的是解锁脚本提供的公钥,在进行HASH160的哈希运算之后,确定是否和锁定脚本中提供的比特币地址(公钥哈希)一致。

  2. 然后验证的是解锁脚本提供的签名,验证节点会使用公钥对这个签名进行解密,并确认解密后的文本是否正确。

以上最关键的一点就是使用公钥将签名进行解密,这让该比特币的拥有者在不透露私钥的情况证明了所有权,只需要使用私钥生成签名即可。那么私钥加密的文本是什么呢?又或者换个问法,公钥把签名解密后的文本又是什么呢?额,我是在说下面这段本质上是什么:

      "scriptSig": "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL] 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf",

以下将txid7957a35f简称为交易A,将txid0627052b简称为交易B。

从各种资料中,我们可以提取出以下信息:

  • 解锁用的签名(即scriptSig)是放在交易B中的。

  • 解锁用的签名是使用私钥将交易B加密后的产物。

那么问题来了,到底是如何用私钥把交易B给加密——生成签名,然后又把这个生成好的签名放在交易B的scriptSig中。

答案是这样的,签名生成的步骤如下:

  1. 把交易B中的解锁脚本字段填充成相应交易A的输出中的锁定脚本

  2. 在第一步产生的文本加上小端序4字节的签名类型0x01(灰色部分),并计算两次SHA256。

  3. 再把第二步中计算完的SHA256的文本进行私钥加密,最后得到签名。

从以上步骤中可以看出,因为交易B的scriptSig字段首先被交易A的输出中的锁定脚本所填充,而当签名生成之后,再将签名放在scriptSig中,这样交易B就完整地生成了!!!

如下图中的sigScript就是解锁脚本,pkScript就是锁定脚本。

参考资料:
https://github.com/tianmingyun/MasterBitcoin2CN/blob/master/ch06.md
http://www.infoq.com/cn/articles/deep-understanding-of-bitcoin-transaction-script
https://www.cnblogs.com/zhaoweiwei/p/address.html

标签:脚本,公钥,私钥,到底,解锁,比特,消息,OP
来源: https://www.cnblogs.com/binfun/p/14334237.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有