欧意最新版本
欧意最新版本app是一款安全、稳定、可靠的数字货币交易平台。
APP下载 官网地址
在
比特币中,交易被分为五大类,但与前文所述的Gcoin的七种交易类型有所不同。Gcoin之所以有七种交易类型,是因为其采用了联盟制架构,并且具备多货币功能的区块链,这导致了交易形态的多样性。而在
比特币中,这五种交易类型被称为标准交易,它们根据交易
脚本的不同进行分类。Gcoin同样具备这五种分类,它们分别是:支付给公钥哈希(Pay-to-Public_Key_Hash,P2PKH)、支付给公钥(Pay-to-Public-Key,P2PK)、多重签名、支付给
脚本哈希(Pay-to-Script-Hash,P2SH)和数据输出(OP_RETURN)。如果您想深入了解这五种交易类型的差异,可以参考我的同学制作的笔记。
本文将聚焦于交易签名的流程,并以P2PKH为例进行说明。
引言
在解析交易的过程中,我们提到过交易输出有一个锁定
脚本(locking script),其作用是定义该输出被消耗的条件。而在交易输入中,存在另一个解锁
脚本(unlocking script),其任务是满足消费该输出的锁定
脚本。一旦输入解锁
脚本通过验证,与上一笔交易输出锁定
脚本相匹配,这笔交易将被解锁并被认为合法。P2PKH交易
脚本通常如下所示:
[图片]
在
比特币脚本中,使用一种名为
脚本语言的语言,它是一种基于栈的语言,从左到右执行。因此,在查看
比特币脚本时,无论是锁定
脚本还是解锁
脚本,都建议结合
脚本语言一起阅读,以了解
脚本的动作。例如,当
脚本中出现数字63时,我们应知道它代表OP_IF操作。
现在,让我们回顾一下上一篇文章中的原始交易,锁定
脚本值如下所示:
76a9149dd353a079ad3b149e00dcc9f6a62f399d3d1c8f88ac
通过
比特币脚本对照表,我们可以将其翻译为:
OP_DUP OP_HASH160 9dd353a079ad3b149e00dcc9f6a62f399d3d1c8f OP_EQUALVERIFY OP_CHECKSIG
会发现其结构与上图相同!但仔细观察会发现,76a9后面的14实际上被省略了,在对照表中没有实际动作,它表示接下来这么多bytes会被推送到栈上,而0x14代表20 bytes,因此接下来的20 bytes(9dd353a079ad3b149e00dcc9f6a62f399d3d1c8f)才是重点。在执行时,这串数据会被推送到栈上,而这串数据就是上图中的公钥哈希(PubKHash),它实际上是公钥经过hash160后的结果,也可以从地址推导出来。由于锁定
脚本中包含公钥,因此也称为scriptPubKey。那么,它的作用是什么?以及为什么解锁
脚本的结构与上图不同,等等,将在后续介绍。
签名
交易签名意味着用可以满足消费该输出的锁定
脚本的解锁
脚本替换输入解锁
脚本。因此,可以预期完成后的解锁
脚本结构也将与上图相同。还记得上一篇文章中的原始交易吗?
01000000018eff490c3dac592caf4954ad1e142e6e8d8fbb427909bb18d7271e7d66dcf9d4000000001976a9149dd353a079ad3b149e00dcc9f6a62f399d3d1c8f88acffffffff0200e40b54020000001976a9144400e18b93766b106220343dbd37d4135501d6da88ac01000000003bbf15f08623001976a9149dd353a079ad3b149e00dcc9f6a62f399d3d1c8f88ac010000000000000000000000
首先,我们在原始交易后面临时挂上4 bytes的哈希类型代码,对于一般交易而言,使用SIGHASH_ALL(0x00000001)。要记住,也是使用little endian表示,因此为01000000。然后,我们将整个原始交易复制一份,进行两次SHA256运算,接着将两次SHA256的结果连同我的私钥一起送入ECDSA签名,得到一个签名。然后,在签名后面再挂上1 byte的哈希类型代码,在这里同样使用01的SIGHASH_ALL。最后,将上一步的签名连同我的公钥一起取代原始交易中原本的输入解锁
脚本,注意也要符合
脚本语言,因此签名和公钥前面都需要添加它们的长度。
步骤看似不多,但第3步的ECDSA是如何签名的呢?在这之前,我们需要先回忆一下公钥是如何产生的。
比特币使用的椭圆曲线是secp256k1,如下所示:
[图片]
图中的G为生成点,在
比特币中是一个满足此方程式的点:
G * k = K
其中k为你的私钥,而产生的K就是你的公钥。而椭圆曲线的乘法如左边所示,因此可以知道公钥实际上也是曲线上的一个点,只是我们通常看到的是将其两个坐标连接在一起而已。
回到我们的签名,它实际上是由G乘以一个k产生的一个坐标,而这个k不仅限于私钥,它是由私钥和传入的消息(两次SHA256的原始交易)以及一个随机数组成的。因此,要签名一个交易,一定要有私钥才能产生。
然而,如果要验证交易签名是否合法,除了需要原始消息之外,只需要用到公钥即可,而消息很容易再次创建,因为毕竟它只是一个空有输入输出信息的原始交易,经过两次SHA256而已。因此,这就是为什么我们的解锁
脚本是由签名和公钥两个组成的,因为等等验证交易时并不需要其他的东西了。
ECDSA的详细内容我也没有完全理解,可能需要请教数学系的专家。
总之,以下就是我们新的解锁
脚本,它将用来取代旧的解锁
脚本。
上述解析中有几个比较特别的地方,签名和公钥虽然都是一个坐标,但它们的表示方式却不同。签名使用一种称为DER编码的方式编码,而公钥则比较正常,但前面有一个byte的类型码需要写在前面。另外要注意,签名后面也挂有一个byte的哈希类型代码,它并不是签名的一部分。
验证
先来看一眼我们签名过的交易长什么样子:
01000000018eff490c3dac592caf4954ad1e142e6e8d8fbb427909bb18d7271e7d66dcf9d4000000008b4830450221009227b2e4f8c36518049bafc88839c19c5597a7a5cfd1e133b84bd6ff8046c6c50220077fdcbb210f4361f20cbe4c056982a798b1d009c391a1447ccef11ea7a1675c01 046036a0a8f54895704ac5cba5b642153331bc2d13dda142665c6a501a606e2099a61d22d22a5cbe8c966672e2a353631f05014157ae37659238381b59bbbcce80ffffffff0200e40b54020000001976a9144400e18b93766b106220343dbd37d4135501d6da88ac01000000003bbf15f08623001976a9149dd353a079ad3b149e00dcc9f6a62f399d3d1c8f88ac010000000000000000000000
虽然看起来变长了,但仔细解析会发现只有输入的解锁
脚本发生了变化,而真正的解锁
脚本是由一个签名和一个公钥组成的,也称为scriptSig。现在,我们的交易已经准备好了。当我们将其广播到网络上,就会进行交易验证流程。一旦验证成功,它就会被收到区块中。现在,让我们来看看验证是如何进行的。
因为这笔交易的输入会记录着我要消费哪个交易哪个输出的信息,所以会取出那个输出的锁定
脚本,如下所示:
OP_DUP OP_HASH160 9dd353a079ad3b149e00dcc9f6a62f399d3d1c8f OP_EQUALVERIFY OP_CHECKSIG
接下来,我们要用这笔交易的输入解锁
脚本去解锁它。而我们的解锁
脚本如下所示:
30450221009227b2e4f8c36518049bafc88839c19c5597a7a5cfd1e133b84bd6ff8046c6c50220077fdcbb210f4361f20cbe4c056982a798b1d009c391a1447ccef11ea7a1675c01 046036a0a8f54895704ac5cba5b642153331bc2d13dda142665c6a501a606e2099a61d22d22a5cbe8c966672e2a353631f05014157ae37659238381b59bbbcce80
它实际上是由两个字串组成的,分别是签名和公钥。记得前面提到过
比特币的
脚本语言是一个基于栈的语言吗?下面就是栈的操作。如果最后出来的是正确的,那就验证成功,代表我们可以消费这笔钱;如果是错误的,当然交易就会失败。
将前一个输出的锁定
脚本和我们的输入解锁
脚本连接起来,将签名和公钥都推送到栈上。将栈顶的东西复制一份,因此现在栈上又多了一个公钥。将刚刚复制的公钥进行OP_HASH160操作,注意,如果你是在电脑上自己进行验证,要记得将公钥从hex转换为bytes,才能丢入HASH160,出来才会与看到的pubKeyHash相同。然后将原本锁定
脚本中的pubKeyHash推送到栈上,并比较它与栈上原本的pubKeyHash是否相同。如果相同,就将它们两个都弹出栈,继续操作;如果不同,就代表这个锁定
脚本根本不是你可以掌控的,也就是说,你想要消费的那个输出根本不是你的钱,因此交易验证就会失败。最后,将签名和我们的公钥一起进行ECDSA验证,看看是否匹配。前面提到过,验证交易只需要公钥就可以了。
当以上步骤都成功之后,交易验证也就完成了。虽然这个范例只有P2PKH,但其实其他的概念也差不多。有空也会再介绍其他的,或可以看看最上面我贴的强者我朋友的文章。
标签: 数字货币
版权声明: 本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任