Alert Source Discuss
📢 Last Call Standards Track: ERC

ERC-1191: 向混合大小写校验和地址编码添加链 ID

Authors Juliano Rizzo (@juli)
Created 2018-03-18
Last Call Deadline 2019-11-18
Requires EIP-55, EIP-155

简单总结

本 EIP 通过选择性地将由 EIP-155 定义的链 ID 添加到校验和计算中来扩展 EIP-55

摘要

创建 EIP-55 是为了防止用户因将资金发送到无效地址而损失资金。本 EIP 扩展了 EIP-55,以保护用户免受因将资金发送到有效但从另一个网络客户端获得的地址而造成的损失。例如,如果实现了此 EIP,则钱包可以提醒用户尝试从以太坊主网钱包向以太坊测试网地址发送资金。

动机

本提案的动机是提供一种机制,使软件能够区分来自不同以太坊网络的地址。 该提案是必要的,因为以太坊地址是公钥的哈希,不包含任何元数据。 通过扩展 EIP-55 校验和算法,可以实现此目标。

规范

使用 EIP-55 定义的相同算法转换地址,但如果提供了已注册的链 ID,则将其添加到哈希函数的输入中。 如果传递给该函数的链 ID 属于选择使用此校验和变体的网络,请在计算哈希之前,在地址前加上链 ID 和 0x 分隔符。 然后将地址转换为十六进制,但如果第 i 位数字是字母(即它是 abcdef 之一),如果计算出的哈希的 4*i 位为 1,则以大写形式打印它,否则以小写形式打印。

理由

优点:

  • 通过对现有库进行最小的代码更改,用户可以避免因混合不同以太坊网络的地址而导致资金损失。

实现

#!/usr/bin/python3
from sha3 import keccak_256
import random
"""
   addr (str): Hexadecimal address, 40 characters long with 2 characters prefix
   chainid (int): chain id from EIP-155 """
def eth_checksum_encode(addr, chainid=1):
    adopted_eip1191 = [30, 31]
    hash_input = str(chainid) + addr.lower() if chainid in adopted_eip1191 else addr[2:].lower()
    hash_output = keccak_256(hash_input.encode('utf8')).hexdigest()
    aggregate = zip(addr[2:].lower(),hash_output)
    out = addr[:2] + ''.join([c.upper() if int(a,16) >= 8 else c for c,a in aggregate])
    return out

测试用例

eth_mainnet = [
"0x27b1fdb04752bbc536007a920d24acb045561c26",
"0x3599689E6292b81B2d85451025146515070129Bb",
"0x42712D45473476b98452f434e72461577D686318",
"0x52908400098527886E0F7030069857D2E4169EE7",
"0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",
"0x6549f4939460DE12611948b3f82b88C3C8975323",
"0x66f9664f97F2b50F62D13eA064982f936dE76657",
"0x8617E340B3D01FA5F11F306F4090FD50E238070D",
"0x88021160C5C792225E4E5452585947470010289D",
"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb",
"0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB",
"0xde709f2102306220921060314715629080e2fb77",
"0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359",
]
rsk_mainnet = [
"0x27b1FdB04752BBc536007A920D24ACB045561c26",
"0x3599689E6292B81B2D85451025146515070129Bb",
"0x42712D45473476B98452f434E72461577d686318",
"0x52908400098527886E0F7030069857D2E4169ee7",
"0x5aaEB6053f3e94c9b9a09f33669435E7ef1bEAeD",
"0x6549F4939460DE12611948B3F82B88C3C8975323",
"0x66F9664f97f2B50F62d13EA064982F936de76657",
"0x8617E340b3D01Fa5f11f306f4090fd50E238070D",
"0x88021160c5C792225E4E5452585947470010289d",
"0xD1220A0Cf47c7B9BE7a2e6ba89F429762E7B9adB",
"0xDBF03B407c01E7CD3cBea99509D93F8Dddc8C6FB",
"0xDe709F2102306220921060314715629080e2FB77",
"0xFb6916095cA1Df60bb79ce92cE3EA74c37c5d359",
]
rsk_testnet = [
"0x27B1FdB04752BbC536007a920D24acB045561C26",
"0x3599689e6292b81b2D85451025146515070129Bb",
"0x42712D45473476B98452F434E72461577D686318",
"0x52908400098527886E0F7030069857D2e4169EE7",
"0x5aAeb6053F3e94c9b9A09F33669435E7EF1BEaEd",
"0x6549f4939460dE12611948b3f82b88C3c8975323",
"0x66f9664F97F2b50f62d13eA064982F936DE76657",
"0x8617e340b3D01fa5F11f306F4090Fd50e238070d",
"0x88021160c5C792225E4E5452585947470010289d",
"0xd1220a0CF47c7B9Be7A2E6Ba89f429762E7b9adB",
"0xdbF03B407C01E7cd3cbEa99509D93f8dDDc8C6fB",
"0xDE709F2102306220921060314715629080e2Fb77",
"0xFb6916095CA1dF60bb79CE92ce3Ea74C37c5D359",
]
test_cases = {30 : rsk_mainnet, 31 : rsk_testnet, 1 : eth_mainnet}

for chainid, cases in test_cases.items():
    for addr in cases:
        assert ( addr == eth_checksum_encode(addr,chainid) )

用法

用法表

网络 链 ID 支持此 EIP
RSK 主网 30
RSK 测试网 31

实现表

项目 EIP 用法 实现
MyCrypto JavaScript
MyEtherWallet JavaScript
Ledger C
Trezor PythonC
Web3.js JavaScript
EthereumJS-util JavaScript
ENS address-encoder TypeScript

版权

版权及相关权利通过 CC0 放弃。

Citation

Please cite this document as:

Juliano Rizzo (@juli), "ERC-1191: 向混合大小写校验和地址编码添加链 ID [DRAFT]," Ethereum Improvement Proposals, no. 1191, March 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1191.