在学习《精通比特币》这本书的时候,在了解比特币的交易过程中,通过书籍的阅读以及网上查阅资料,下面来整理下自己对比特币交易过程的一个学习心得。
比特的交易流程可以简单的用下面这张图来表示:
在这里特别说明一下,创建账户并不算交易流程中的部分,但是由于它对于交易的理解特别重要,所以我也放在这里解释一下。
1.创建用户
比特币创建全部是匿名账户,在比特币中其实所谓的账户就是用非对称加密算法(比特币使用的椭圆曲线算法)创建的一对秘钥,分为公钥和私钥。 首先私钥是一个随机数,随机选取一个32字节的数,然后再使用椭圆曲线加密算法(ECDSA-secp256k1)对这个私钥压缩生成公钥。 也就是说比特币的账户本质上就是一个随机数而已,没有其他任何信息了,这也就为后来有人利用 比特币洗黑钱带来了前所未有的便利性。所以私钥一定要安全保管,不能让其他人知道,它是你拥有比特币的唯一凭证。公钥是可以暴露给别人的,事实上我们 通常发送给别人的钱包地址就是公钥通过一系列的 hash 计算和Base58编码得到的。但是钱包地址不等于公钥, 因为以上过程全部是不可逆的, 也就是说你不能通过钱包地址推算出公钥,也不能通过公钥反推算出私钥。其实从私钥到地址,中间经过了9个步骤的计算处理,所以私钥是绝对安全的,不可能 被破解。
通过以上解读我们可以提取以下几点信息:
私钥:私钥是一个随机数,随机选取的的一个32字节的数。
公钥:通过椭圆加密算法对这个私钥进行压缩生成公钥。
钱包地址 ≠ 公钥 :通常发送给别人的钱包地址就是公钥通过一系列的 hash 计算和Base58编码得到的
总的概括就是下面这句话:
比特币系统使用了椭圆曲线签名算法(ECC),算法的私钥由32个字节随机数组成,通过私钥可以计算出公钥,公钥经过一序列哈希算法和编码算法得到比特币地址,地址也可以理解为公钥的摘要
通过这张图我们可以清晰的知道如何从公钥生成比特币地址(钱包地址)。
在进一步的归纳,比特币地址生成步骤如下:
2.发送交易并广播
假如有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)
- 交易金额
- 收款人地址
- 收款人的公钥
- 时间戳
3.验证交易
其他比特币节点收到广播交易之后会对交易进行验证,主要是验证交易是否是本人发起的。因为私钥只有本人才有,所以只要验证签名信息是 是否正确,即是否是使用私钥签名的。当然在真实交易的时候还做一些其他验证,比如付款方的 UTXO(其实就是余额)是否足够等。
签名的验证过程大致如下:
summary = hash({
"付款地址":"address-A",
"收款地址":"address-B",
"金额":"5BTC"
})
if (verify(signature, public-key-A) == summary) {
//验证通过
//打包交易到区块
}
这里验证签名的是用的公钥去解密,这是非对称性加密的一个特性。
4.存储交易并广播
在交易验证通过之后,当前节点就会把交易写入账本,然后广播到与它相连接的节点,其他节点又会对交易进行验证,打包,广 播, 直到全网节点都确认了交易。