区块链百科

深度解析:Web3钱包中助记词、私钥与地址的生成逻辑

鉴于此前在阅读大量技术博客和社区讨论时,未能找到一篇能结合简洁理论与实例代码来透彻讲解钱包机制的文章,我决定亲自撰写这一系列教程,分享我的学习心得与技术研究成果。

我认为,通过编写代码逐步实现私钥、公钥和地址的生成,是掌握这些概念最高效的方式。接下来,我们将使用Go语言来完成这一过程。

在正式编码之前,我们先夯实一些必要的基础知识。

1. 什么是椭圆曲线?

以太坊与比特币底层均采用相同的椭圆曲线算法。所谓的公钥,实质上是该椭圆曲线上的一组(x, y)坐标值,而这组数值由私钥唯一确定。

由于x和y各占32字节,因此完整的公钥长度为64字节。你有时可能会遇到65字节的公钥表示形式,这源于SECG发布的行业标准序列化编码规范:即在头部增加一个字节作为前缀,其中“04”代表非压缩格式,意味着完整保留了x和y两个坐标(各32字节)。

为何存在压缩与非压缩两种公钥格式?

原因在于椭圆曲线方程的性质:已知其中一个坐标,即可通过方程推导出另一个。因此,我们只需存储单一坐标,从而节省32字节的空间,这便是压缩公钥的由来,其前缀通常为“02”或“03”。

综上所述:

  • 非压缩公钥:共65字节(1字节前缀04 + 64字节实际数据)。
  • 压缩公钥:共33字节(1字节前缀02/03 + 32字节单坐标数据)。

推荐阅读:吴军《数学之美》第 31 章 椭圆曲线加密原理

2. 私钥概述

以太坊的私钥本质上是一个随机生成的数字,位数为256位。关键在于其必须具备完全的随机性——理论上,你甚至可以通过连续投掷256次硬币得到一个二进制序列作为私钥。只要该数字不可预测且不可重复,具体的生成手段并不重要。

在实际开发中,我们通常通过代码生成私钥。此时,核心要点在于调用密码学安全的随机数源。严禁自行实现伪随机算法或使用编程语言默认的非安全随机函数,确保随机数的安全性至关重要。

私钥的安全性不言而喻。需要特别强调的是,私钥一旦遗失便无法找回,这与传统银行卡密码截然不同。这种不可恢复性是去中心化体系的固有特征。

在中心化世界里,我们用银行卡不担心密码丢失,因为可以找回,但是消费记录、数据隐私无法保证,好比在互联网上裸奔。

在去中心化世界,数据倒是可以做到隐私(虽然目前来看,大家并不关心隐私),但是很不方便,比如保存私钥就是个很麻烦的问题。

我不是想谈数据隐私、保存私钥的话题,因为目前没什么好的解决方案。而是想引出我一直以来的想法,就是任何事物都具有两面性。正所谓 "祸兮福所倚,福兮祸所伏",当你学习有负面情绪,坚持不下去的时候,想一想负面情绪的好处。我认为正是因为有了负面情绪的存在,才挡住了很多比我们更聪明的人的脚步,让我们得以有机会超越他们。如果学习没有负面情绪,那所有人都坚持学习了,那大家只能看谁最聪明了,这样哪还有普通人的机会。从这个角度,我们需要感谢负面情绪。

3. 助记词的作用

助记词涉及钱包的行业标准,我将在本系列的第三篇文章中深入探讨。在此仅作简要介绍:既然私钥是随机生成的数字,那么当我们拥有10个、100个甚至100万个账户时,难道要分别生成并管理100万个独立的私钥吗?面对如此庞大的数量,如何高效管理和保存成为难题。助记词正是为了解决这一痛点而诞生的。

借助助记词,我们可以统一管理成千上万个私钥。这需要我们了解以太坊中的两种钱包类型,下文将开始详细介绍钱包机制并动手开发一个简单的钱包。

Go语言实战:生成私钥、公钥与地址

下图展示了生成私钥、公钥和地址的基本原理流程。我们将依据此流程图编写相应代码。

以下是所需的依赖包引入:

第一步:初始化椭圆曲线对象。

第二步:生成私钥(长度32字节)。

第三步:生成公钥。对私钥执行椭圆曲线加密运算,输出公钥(64字节)。

第四步:生成地址。剔除公钥首部的“04”前缀,随后使用Keccak256算法对剩余数据进行哈希压缩,最终取后20字节作为以太坊地址。

第五步:验证匹配度。检查生成的私钥与计算出的地址是否对应。

第六步:跨平台验证。将第三步生成的私钥导入MetaMask钱包,对比MetaMask自动生成的地址与第五步手动计算的地址是否一致。

总结

牢记上述基本原理流程图,即标志着你已经掌握了本文最核心的知识点。