酷玩网

Transaction签名的流程

linx
欧意最新版本

欧意最新版本

欧意最新版本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,但其实其他的概念也差不多。有空也会再介绍其他的,或可以看看最上面我贴的强者我朋友的文章。

标签: 数字货币