今天看完《精通比特币》这本书第二遍之后,对比特币的交易流程有了更清晰的认识,结合自己以前的认知,记录一下心得。

比特的交易流程可以简单的用下面这张图来表示:

在这里特别说明一下,创建账户并不算交易流程中的部分,但是由于它对于交易的理解特别重要,所以我也放在这里解释一下。

创建账户

   比特币创建全部是匿名账户,在比特币中其实所谓的账户就是用非对称加密算法(比特币使用的椭圆曲线算法)创建的一对秘钥,分为公钥和私钥。 首先私钥是一个随机数,随机选取一个32字节的数,然后再使用椭圆曲线加密算法(ECDSA-secp256k1)对这个私钥压缩生成公钥。 也就是说比特币的账户本质上就是一个随机数而已,没有其他任何信息了,这也就为后来有人利用 比特币洗黑钱带来了前所未有的便利性。所以私钥一定要安全保管,不能让其他人知道,它是你拥有比特币的唯一凭证。公钥是可以暴露给别人的,事实上我们 通常发送给别人的钱包地址就是公钥通过一系列的 hash 计算和Base58编码得到的。但是钱包地址不等于公钥, 因为以上过程全部是不可逆的, 也就是说你不能通过钱包地址推算出公钥,也不能通过公钥反推算出私钥。其实从私钥到地址,中间经过了9个步骤的计算处理,所以私钥是绝对安全的,不可能 被破解。

我们简单把比特币的账户生产过程总结如下

  1. 生成一个 32 字节的随机数作为私钥
  2. 把私钥使用椭圆曲线算法加密,生成公钥
  3. 把公钥进行一系列的 hash 计算生成公钥摘要
  4. 使用 Base58 编码技术对公钥摘要进行编码得到地址(这一步是可逆的)

发送交易

假如有A, B 两个账户, 他们的账户信息分别如下

户名 私钥 公钥 钱包地址
A 0xtjnpelimdkygfoqsuhvxzwarcb 0xDNnPoyw0QKVfssQy 0x9SDYFw46EANVMp6P3F754k
B 0xwehsSivmE4IHN1aVzwDEzkVC 0xp7cNc9rpnz23pEHc 0xErho6FVqTqgHTpcLiE2R6A

为了方便理解和记录我们假设

A 的私钥,公钥,地址分别对应为: private-key-A, public-key-A, address-A.

B 的私钥,公钥,地址分别对应为: private-key-B, public-key-B, address-B.

假设 A 要给 B 转账5个BTC, 则付款方会发送这么一笔交易

{
	"付款地址""address-A",
	"收款地址""address-B",
	"金额""5BTC"
}

在实际发送交易之前,A 还需要对交易进行签名,以便于其他接收节点来验证交易。由于非对称加密算法一般一次加密的数据长度有限制(一般是1024字节), 所以在签名之前先会使用 hash 计算得到交易的摘要,然后再对交易摘要进行签名,这样也可以节约计算资源。

summary = hash({
	"付款地址""address-A",
	"收款地址""address-B",
	"金额""5BTC"
}) => "KrDsjT4J7vo6GbibMQMPYkcA2f5bck"

假设得到摘要信息是: KrDsjT4J7vo6GbibMQMPYkcA2f5bck , 接下来再用 A 的私钥对摘要进行签名

signature = sign(summary, private-key-A) -> "RAJ8uRurwWQVQRO5"

签名之后付款节点就会把交易广播到全网节点:我给 B 转账了5个BTC, 大家快来确认. 广播的信息包含了交易原始信息和签名信息.

当然,上面是模拟主要数据,实际交易包含的信息还要多一些,下面贴出比特币的真实交易数据结构:

  • 付款方的签名
  • 付款方的资金来源的交易ID(也即上一个入账区块ID)
  • 交易金额
  • 收款人地址
  • 收款人的公钥
  • 时间戳

验证交易

  其他比特币节点收到广播交易之后会对交易进行验证,主要是验证交易是否是本人发起的。因为私钥只有本人才有,所以只要验证签名信息是 是否正确,即是否是使用私钥签名的。当然在真实交易的时候还做一些其他验证,比如付款方的 UTXO(其实就是余额)是否足够等。

签名的验证过程大致如下:

summary = hash({
	"付款地址""address-A",
	"收款地址""address-B",
	"金额""5BTC"
})
if (verify(signature, public-key-A) == summary) {
	//验证通过
	//打包交易到区块
}

这里验证签名的是用的公钥去解密,这是非对称性加密的一个特性,如果不清楚什么是非对称性加密的,请去看下我之前的一篇博客 《区块链技术指南》读书笔记(二)

存储交易

   在交易验证通过之后,当前节点就会把交易写入账本,然后广播到与它相连接的节点,其他节点又会对交易进行验证,打包,广播… 直到全网节点都确认了交易。