Officine Bitcoin

Lezioni online Bitcoin-only

This project is maintained by valerio-vaccaro

Officine Bitcoin Bitcoin-only 课程 本项目由 valerio-vaccaro 维护

🌍 Traduzioni

🇨🇳 中文 🇬🇧 English 🇪🇸 Español 🇵🇹 Português 🇷🇺 Русский 🇫🇷 Français 🇩🇪 Deutsch 🇮🇹 Italiano 🇭🇺 Magyar 🏳️ Milanés 🏳️ Veneto

数字签名

本课的主题是数字签名,以及它们如何应用于 Bitcoin。

什么是签名?

我们需要理解数字签名是什么意思。当我们想到普通签名时,通常想到的是另一回事;因为这里讨论的是数字文档,数字签名同时绑定作者身份和被签名文档的状态,所以本质上,签名也取决于我们要签署的文档。

这与物理世界有很大不同。在物理世界里,我们签名时几乎不关心签在什么载体上。当然,我们也许不会毫不在意地签支票或其他文件,但本质上,我们要写下的签名并不会变化。

数字签名有些不同;数字签名通常依赖公钥和私钥算法。这意味着在世界上的某个地方,我们的 wallet 拥有一对密钥,即公钥和私钥,而我们的(伪)身份与所有人都知道、或者我们会公开给所有人的公钥相关联。

我们会使用自己的私钥,它是一个数字;通过一些数学魔法,我们会生成一个签名,这个签名是另一个不同的数字,并且它证明某个文档的某个状态属于、或被某个与公钥相连的身份所知晓。我要签署的是某个文档(或 PAYLOAD)的指纹(或 HASH)。

我还需要某种随机数生成器;我把所有这些数据放进一个“黑盒”,它为我生成一个签名。因此,签名一方面证明占有,因为我是用自己的秘密来签名;另一方面也证明我签署的内容没有被修改。

如果我修改 PAYLOAD,就会修改 HASH,而这显然会使签名失效。

那么,为什么要在数字世界引入这种更复杂的签名呢?因为在数字世界中,与物理世界不同(也许逃过课的人还记得),复制一个签名要简单得多。

数字签名则包含关于文档的信息,因此每个文档的签名都会变化,不能被粘贴并复用到另一个不同的文档上。

因此,数字签名用于:

Bitcoin 中的签名

这项技术在 Bitcoin 中以 ECDSA(Elliptic Curve Digital Signature Algorithm)的名称使用,它是一种在椭圆曲线上生成数字签名的算法;目前我们不会讨论其他签名方案。

请记住,在 Bitcoin 中可以为以下内容生成签名:

但这些签名如何与交易关联?每个地址都有一种花费机制,也就是必须执行的 scripts,用来判断某笔花费是否可以被授权。在这些 scripts 内部,有一些用于检查数字签名的命令(或 OPCODES),例如 OP_CHECKSIG, OP_CHECKSIGVERIFY, OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY

请记住,一笔 Bitcoin 交易由以下部分组成:

本质上,在大多数情况下,我必须为每个 INPUT 生成完成花费 script 所需的签名。

请记住,这个操作让我们能够证明那个 input 是我们的,并且我们想要花费它(我们想要完整转移所有权、把它拆分,或把它与其他 inputs 合并)。

显然,如果所有 inputs 都被正确签名,交易就是有效的;如果哪怕只有一个 input 没有签名,那笔交易就不能被视为有效。

签名可以被所有人验证,并且不可否认;但为了灵活性,Satoshi 非常巧妙地引入了多种签名模式。签名本身总是同一种机制,但 PAYLOAD 会变化,也就是作为签名对象的交易部分会变化;这使得可以生成复杂的方案和协议,让交易片段相互组合。Satoshi 把这些模式(scripting 语言中真正的 flags)称为 SIGHASH。

SIGHASH

最简单的 SIGHASH 是 SIGHASH_ALL,意思是用所有 INPUTS 和所有 OUTPUTS 生成签名;这是最简单、最常用的签名模式。

第一个差异来自 SIGHASH_NONE,它签署所有 INPUTS,但不签署任何 OUTPUTS,从而允许之后添加 outputs 或修改 fees。注意:在这种方案下,如果没有 multisig 或其他功能保护,miner 或任何看到使用这种签名方案的交易的人,都可以替换 outputs,把资金重定向到自己的地址。

一个更有意思的 flag 是 SIGHASH_SINGLE,在这种模式中,会签署一对 input 和 output,前提是它们在交易中处于相同的位置层级(例如第五个 input 和第五个 output);这允许基于这些配对组合更大的交易,但不给引入找零的可能性,也就是说,它要求完全花费该 input。

同时,所有这些 SIGHASH 都可以与 ANYONECANPAY flag 组合使用。ANYONECANPAY 将签名限制为正在为其生成签名的那个 input,从而让任何人都有可能向交易添加 inputs。

无论地址和 scripts 的类型如何,这些签名都是有效签名,从而给 wallet 留下最大的表达灵活性。wallet 通常会使用 SIGHASH_ALL,但也可能遵循需要不同签名方案的更复杂协议。在 multisig 的情况下,也没有必要使用同一种签名类型;一个 2-of-2 wallet 可以用 SIGHASH_NONE 和 ANYONECANPAY 签署它的一些 UTXO,以便把完全控制权交给第二个签名者,后者例如可以把所有这些 inputs 收集到一笔将用 SIGHASH_ALL 签署的交易中。

任意文本上的签名

为完整起见,用于交易 inputs 的同一类签名也可以用于签署任意文本。

Bitcoin 提出了一种方案,在其中加入文本,以防止该功能被用于签署交易的部分内容。因此,如果你有 Bitcoin Core,或者甚至某些 wallets,你可以寻找基于你某个地址的文本消息签名功能。

wallet 会使用与生成该地址的公钥相对应的私钥,来创建文本消息签名。

在验证时会得到公钥,然后可以用它重新生成地址。因此,如果我有文本和签名,就可以提取签署它的公钥,再从该公钥重新计算地址,并例如与提供的地址进行核对。

课程安排

签名课程可以重复开设;以下是已经举办过的列表:

日期 备注