以太坊地址到底区不区分大小写?
阿牛哥 Lv4

以太坊地址以0x开头,代表十六进制。接下来是40个十六进字符,每个字符代表4比特位,那么以太坊的地址是160位(20字节)。

十六进制的A-F是不区分大小写的,也就是说像下面这两个地址应该是同一个:

0xBFB153499C9191F7049D839B436779614E5E6E03
0xbfb153499c9191f7049d839b436779614e5e6e03

既然不区分大小写,那么为什么我们经常看到的地址会有大小写的字符交替出现呢?

原因在于以太坊地址中不包含校验字符,导致应用无法判断用户在交易时手动输入的地址是否正确。也就是说,如果在转账时输错了地址,钱包依然会放行,从而造成损失。

为了降低出错的可能性,以太坊引入了校验功能,方法就是要求地址中部分字母必须大写,另一部分必须小写,钱包负责在交易时根据大小写来验证。

EIP-55规定了以太坊地址该如何大小写。

按照官方表述,采用EIP-55有如下好处:

  • 兼容早期不区分大小写的应用程序
  • 引入校验的同时仍然保持40个字符的地址长度
  • 校验的准确率高。输错的地址被验证成合法地址的概率很低

下面,我们以地址0xBfb153499c9191F7049D839B436779614e5E6e03为例,看下校验规则:

  1. 计算“bfb153499c9191f7049d839b436779614e5e6e03”的keccak哈希值

    1
    2
    >>> keccak("bfb153499c9191f7049d839b436779614e5e6e03")
    >>> 9505d558b2c39aa71108149d8fb22b0c67098756f1a5aa402182cf1b191d2cb1
  2. 从左到右遍历地址的每个字符,当遇到字母时,判断对应位置的keccak哈希值,如果值大于7,那么该字母就要大写,反之小写。
    比如,例子的第一个字母是b,keccak值为9,9 > 7,所以该字母b应当大写;第二个字母是f,keccak值为5,5 < 7,所以f小写;第三个字母b,keccak值为0,所以b应当小写;以此类推,最终结果是
    Bfb153499c9191F7049D839B436779614e5E6e03

最终得到能被校验的地址是:
0xBfb153499c9191F7049D839B436779614e5E6e03

所以,以太坊地址中的大小写字母是用于校验目的的。不论大写还是小写,所代表的地址还是同一个。而在早期的钱包应用中,可能因为不支持EIP-55,因此不区分大小写,此时请特别留意抄写是否正确。其他情况,例如新的应用或者交易所,一般都会校验地址的。

当然,EIP-55并不能检查地址对应的私钥是否存在,更不可能确认对方身份,这些都是要你通过其他途径确认的。EIP-55只负责校验,防止你抄错!