Programming Bitcoin 第四章:序列化技术详解

Programming Bitcoin 第四章:序列化技术详解

概述

在区块链开发中,序列化是将复杂数据结构转换为字节流的过程,这对于网络传输和存储至关重要。本章将深入探讨区块链系统中几种关键的序列化格式,包括SEC公钥格式、DER签名格式以及Base58地址编码。

SEC公钥序列化格式

未压缩SEC格式

椭圆曲线数字签名算法(ECDSA)的公钥本质上是曲线上的一个坐标点(x,y)。未压缩SEC格式序列化方法如下:

  1. 前缀字节固定为0x04
  2. 追加32字节大端序编码的x坐标
  3. 追加32字节大端序编码的y坐标

Python实现示例:

def sec(self):
    return b'\x04' + self.x.num.to_bytes(32, 'big') + self.y.num.to_bytes(32, 'big')

这种格式总长度为65字节(1+32+32),效率较低但实现简单。

压缩SEC格式

利用椭圆曲线的对称性,y坐标只可能是两个值之一且奇偶性相反。压缩格式仅存储x坐标和y的奇偶性:

  1. 前缀字节:y为偶数用0x02,奇数用0x03
  2. 追加32字节大端序编码的x坐标

Python实现关键点:

def sec(self, compressed=True):
    if compressed:
        prefix = b'\x02' if self.y.num % 2 == 0 else b'\x03'
        return prefix + self.x.num.to_bytes(32, 'big')
    ...

这种格式仅需33字节,节省了近50%的空间。要从压缩格式恢复完整坐标,需要使用有限域平方根计算:

def sqrt(self):
    return self**((P + 1) // 4)

DER签名序列化格式

区块链签名(r,s)使用DER(Distinguished Encoding Rules)格式序列化:

  1. 起始标志0x30
  2. 后续数据长度
  3. r值标记0x02
  4. 大端序编码的r值(必要时补0x00)
  5. s值标记0x02
  6. 大端序编码的s值(必要时补0x00)

Python实现示例:

def der(self):
    rbin = self.r.to_bytes(32, 'big').lstrip(b'\x00')
    if rbin[0] & 0x80:
        rbin = b'\x00' + rbin
    sbin = self.s.to_bytes(32, 'big').lstrip(b'\x00')
    if sbin[0] & 0x80:
        sbin = b'\x00' + sbin
    result = bytes([2, len(rbin)]) + rbin + bytes([2, len(sbin)]) + sbin
    return bytes([0x30, len(result)]) + result

DER格式虽然标准但效率不高,每个签名至少需要6字节额外开销。

Base58地址编码

Base58编码原理

为解决二进制数据可读性问题,区块链采用Base58编码,特点:

  • 排除易混淆字符(0/O, l/I)
  • 包含校验和
  • 比Base64更安全可靠

编码过程:

  1. 统计前导零字节数量
  2. 将数值转换为58进制
  3. 映射到Base58字符集
  4. 补回前导'1'

Python实现:

def encode_base58(s):
    count = 0
    for c in s:
        if c == 0:
            count += 1
        else:
            break
    num = int.from_bytes(s, 'big')
    prefix = '1' * count
    result = ''
    while num > 0:
        num, mod = divmod(num, 58)
        result = BASE58_ALPHABET[mod] + result
    return prefix + result

区块链地址生成

完整地址生成流程:

  1. 主网前缀0x00,测试网0x6f
  2. 对SEC格式公钥进行hash160(先sha256再ripemd160)
  3. 组合前缀和hash160结果
  4. 计算前4字节校验和(双重sha256)
  5. Base58编码最终结果

Python实现关键方法:

def hash160(self, compressed=True):
    return hash160(self.sec(compressed))

def address(self, compressed=True, testnet=False):
    h160 = self.hash160(compressed)
    prefix = b'\x6f' if testnet else b'\x00'
    return encode_base58_checksum(prefix + h160)

WIF私钥格式

私钥的Wallet Import Format序列化:

  1. 主网前缀0x80,测试网0xef
  2. 32字节大端序私钥
  3. 压缩标志0x01(如使用压缩公钥)
  4. 4字节校验和
  5. Base58编码

技术要点总结

  1. 大端序与小端序:区块链中不同数据采用不同字节序,SEC格式使用大端序而交易版本号使用小端序

  2. 有限域计算:压缩公钥恢复依赖有限域平方根计算,当p ≡ 3 mod 4时可高效计算

  3. 编码演进:Base58正逐渐被Bech32取代,后者具有更好的错误检测能力

  4. 空间优化:压缩SEC格式节省空间,这对区块链 scalability 至关重要

理解这些序列化技术是开发区块链应用的基础,它们影响着交易大小、网络带宽和存储效率等关键指标。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潘轲利

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值