在加密货币的世界里,以太坊无疑是“智能合约”与“去中心化应用”的代名词,但当我们谈论以太坊时,目光往往聚焦于价格波动、DApp交互或DeFi收益,却很少有人问:一笔以太坊交易从发送到上链,究竟经历了怎样的数学运算?一个新区块如何通过“挖矿”被创造出来?这些看似自动化的过程,底层都由一系列精密的算法和计算支撑,我们就来“手算以太坊”——从交易签名到区块哈希,亲手拆解区块链的底层逻辑,看看代码与数学如何构建起一个去中心化的世界。
手算第一步:从私钥到地址,加密算法的“身份生成术”
以太坊的核心是“账户系统”,每个账户

以太坊使用的椭圆曲线是secp256k1,其方程为:
$$y^2 = x^3 + 7 \pmod{p}$$
p$是一个巨大的质数:$p = 2^{256} - 2^{32} - 977$,这个曲线上的点构成了一个有限 Abel 群,满足“点加”运算规则:给定曲线上两点$P$和$Q$,可以通过几何作图法找到第三点$R = P + Q$,且运算满足交换律和结合律。
私钥的生成:本质上是一个随机数,以太坊要求私钥是一个256位的随机整数,范围在$[1, n-1]$之间,n$是曲线的阶(约$2^{256}$),我们随机生成一个私钥$d = 0x1a2b3c...$(256位十六进制数)。
公钥的生成:通过椭圆曲线“标量乘法”计算:$P = d \cdot G$,G$是曲线的基点(固定点,坐标已知),$d$是私钥,这里的“标量乘法”不是简单的乘法,而是$G$点自加$d$次(d=3$时,$P = G + G + G$),由于椭圆曲线离散对数问题的困难性,已知$P$和$G$几乎无法反推出$d$,保证了私钥的安全。
地址的生成:以太坊地址由公钥$P$的坐标$(x,y)$通过哈希算法生成:
- 取公钥的未压缩格式(前缀0x04,后接$x$和$y$坐标,各32字节);
- 对其进行Keccak-256哈希,得到32字节的哈希值;
- 取哈希值的后20字节,作为以太坊地址(前缀添加0x)。
举个例子:假设私钥$d = 1$(仅作示例,实际私钥需随机),则公钥$P = 1 \cdot G = G$,基点$G$的坐标是$(x_G, y_G) = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)$,对公钥(0x04 + $x_G$ + $y_G$)做Keccak-256哈希,后20字节为:0x339901210647260860143311AF3603F6F64180FF53A96C13754891E0140A13A,这就是以“1”开头的经典地址(实际地址前缀为0x,完整地址为0x339901210647260860143311AF3603F6F64180FF53A96C13754891E0140A13A)。
手算第二步:交易签名,ECDSA如何“证明所有权”
以太坊交易的核心是“签名”——用私钥对交易数据进行签名,接收方通过公钥验证签名,从而证明交易确实由账户所有者发起,这个过程依赖椭圆曲线数字签名算法(ECDSA)。
ECDSA签名包含两个值:$(r, s)$,计算步骤如下(以“原始交易”为例,不含EIP-1559优化):
准备交易数据
交易数据包括:接收方地址、转账金额、nonce、gas limit、gas price等,需编码为RLP(Recursive Length Prefix)格式,再计算其Keccak-256哈希值,作为“消息哈希”$m$。
假设一笔简单转账的交易数据RLP编码后为0xf86...(具体略),其Keccak-256哈希$m = 0x8c...$(32字节)。
生成随机数$k$
选择一个随机整数$k \in [1, n-1]$($n$为曲线阶),计算椭圆曲线点$R = k \cdot G$,取$R$的$x$坐标模$n$,得到$r = R_x \mod n$(若$r=0$,需重新选$k$)。
计算$s$
计算$s = k^{-1} \cdot (m + r \cdot d) \mod n$,d$是私钥,$k^{-1}$是$k$模$n$的乘法逆数(可用扩展欧几里得算法计算)。
验证签名(可选)
验证时,计算$u_1 = m \cdot s^{-1} \mod n$,$u_2 = r \cdot s^{-1} \mod n$,然后点$P' = u_1 \cdot G + u_2 \cdot P$($P$为公钥),若$P'$的$x$坐标模$n$等于$r$,则签名有效。
举个例子:假设私钥$d = 0x1a2b3c...$(简化为$d=5$),消息哈希$m = 0x1234...$(简化为$m=0x10$),随机数$k=7$(secp256k1曲线$n \approx 2^{256}$,此处为简化假设)。
- 计算$R = 7 \cdot G$,取$R_x \mod n = r$(假设$r=0x3a$);
- 计算$k^{-1}$:$7 \times x \equiv 1 \mod n$,假设$x=0x2b$(实际需用扩展欧几里得算法);
- 计算$s = 0x2b \cdot (0x10 + 0x3a \times 5) \mod n = 0x2b \cdot (0x10 + 0x12c) \mod n = 0x2b \times 0x13c \mod n$(假设$s=0x5d$);
- 最终签名为$(r, s) = (0x3a, 0x5d)$。
矿节点收到交易后,会用发送方的公钥重复上述验证步骤,若签名有效,则将交易打包进候选区块。
手算第三步:区块哈希,PoW共识的“数学谜题”
以太坊最初采用工作量证明(PoW)共识,矿工的核心任务是“挖矿”——找到一个随机数(nonce),使得候选区块的哈希值满足特定条件(如前导零个数),这个过程本质上是“暴力破解”哈希函数的计算。
构建候选区块
区块包含区块头和交易列表,区块头是哈希计算的关键,包含以下字段(部分):
- parentHash:父区块的哈希;
- number:区块高度;
- stateRoot:状态树根哈希;
- transactionsRoot:交易树根哈希;
- receiptsRoot:收据树根哈希;
- difficulty:难度值;
- nonce:矿工填入的随机数(32位);
- mixHash:与nonce配合的值(早期PoW中)。
stateRoot、transactionsRoot、receiptsRoot是通过Merkle Patricia Tree(MPT)计算得到的树根哈希,需单独计算。
计算区块头的哈希
区块头数据需编码为RLP格式,然后计算其Keccak-256哈希,这就是“候选哈希”(header hash)。
挖矿:调整nonce满足难度条件
PoW要求候选哈希$\leq 2^{256} / \text{difficulty}$,即: