zoukankan      html  css  js  c++  java
  • ethereum/EIPs-55 Mixed-case checksum address encoding

    eiptitleauthortypecategorystatuscreated
    55
    Mixed-case checksum address encoding
    Vitalik Buterin
    Standards Track
    ERC
    Final
    2016-01-14

    Specification(python)

    from ethereum import utils
    
    def checksum_encode(addr): # Takes a 20-byte binary address as input
        o = ''
        v = utils.big_endian_to_int(utils.sha3(addr.hex()))
        for i, c in enumerate(addr.hex()):
            if c in '0123456789'://就是如果address在i位置上的值是数字的话,就不做任何改变
                o += c
            else: //但是如果是字符的话,就要另进行判断,(2**(255 - 4*i))这个的二进制的结果就是从后向前数的255 - 4*i个位置上的值为1,即是为了实现从前往后数为4*i位置的数字
                o += c.upper() if (v & (2**(255 - 4*i))) else c.lower()//255的原因是hash的v有32bytes,即32*8=256,从0开始
    //所以意思是如果小写十六进制地址的散列v的第4*i位也是1,则以大写形式打印,否则以小写形式打印。
    return '0x'+o def test(addrstr): assert(addrstr == checksum_encode(bytes.fromhex(addrstr[2:]))) test('0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed') test('0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359') test('0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB') test('0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb')

    注意:v = utils.big_endian_to_int(utils.sha3(addr.hex()))

    所谓的大端模式(Big-endian),是指数据的高字节,保存在内存的低地址中,而数据的低字节,保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;比如1234,如果是数字的话应该从低位开始读4321(即小端模式);但是这里为大端模式,所以读法就是1234。这是为了顺序处理addr的hash值

    In English, convert the address to hex, but if the ith digit is a letter (ie. it's one of abcdef) print it in uppercase if the 4*ith bit of the hash of the lowercase hexadecimal address is 1 otherwise print it in lowercase.

    Rationale

    Benefits:

    • Backwards compatible with many hex parsers that accept mixed case, allowing it to be easily introduced over time
    • Keeps the length at 40 characters。 address长度为40个字符
    • On average there will be 15 check bits per address, and the net probability that a randomly generated address if mistyped will accidentally pass a check is 0.0247%. This is a ~50x improvement over ICAP, but not as good as a 4-byte check code.  上面bit的转换效率没有字节的转化效率快,所以下面实现的是半字节(16进制一字符4bits)形式的转换方法:

    例子:

    const createKeccakHash = require('keccak');
    
    function toChecksumAddress (address) {
      address = address.toLowerCase().replace('0x', '');
      console.log(address);
      var hash = createKeccakHash('keccak256').update(address).digest('hex');//update就是输入要加密的值,digest就是将加密好的hash值以16进制的形式输出
      console.log(hash);//5cfac663f45837b409c4d3dc1cef5f4759734f4989dd53a31b1265734c0b28f4,64个
      var ret = '0x';
    
      for (var i = 0; i < address.length; i++) {//所以只用得到hash的前40个字符
        if (parseInt(hash[i], 16) >= 8) {//即将16进制的hash[i]转化成10进制的数值后与8进行比较,如果在i位置的hash的值大于或等于8,相应位置的address的值就换成大写,否则就还是小写
          ret += address[i].toUpperCase();//其实就是根据得到的hash值来相应将address转换成大小写皆有的形式
          console.log('if');
          console.log(ret);
        } else {
          ret += address[i];
          console.log('else');
          console.log(ret);
        }
      }
    
      return ret;
    }
    
    var addr = '0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359';//去掉0x是40个
    console.log(toChecksumAddress(addr));

    这里的例子address是16进制的,当然,如果the hex address encoded as ASCII,那么就写成:

    var hash = createKeccakHash('keccak256').update(Buffer.from(address.toLowerCase(), 'ascii')).digest()

    Adoption

    Walletdisplays checksummed addressesrejects invalid mixed-caserejects too shortrejects too long
    Etherwall 2.0.1 Yes Yes Yes Yes
    Jaxx 1.2.17 No Yes Yes Yes
    MetaMask 3.7.8 Yes Yes Yes Yes
    Mist 0.8.10 Yes Yes Yes Yes
    MyEtherWallet v3.9.4 Yes Yes Yes Yes
    Parity 1.6.6-beta (UI) Yes Yes Yes Yes

    Exchange support for mixed-case address checksums, as of 2017-05-27:

    Exchangedisplays checksummed deposit addressesrejects invalid mixed-caserejects too shortrejects too long
    Bitfinex No Yes Yes Yes
    Coinbase Yes No Yes Yes
    GDAX Yes Yes Yes Yes
    Kraken No No Yes Yes
    Poloniex No No Yes Yes
    Shapeshift No No Yes Yes

     

    References

    1. EIP 55 issue and discussion https://github.com/ethereum/eips/issues/55
    2. Python implementation in ethereum-utils
    3. Ethereumjs-util implementation https://github.com/ethereumjs/ethereumjs-util/blob/75f529458bc7dc84f85fd0446d0fac92d991c262/index.js#L452-L466
    /**
     * Returns a checksummed address
     * @param {String} address
     * @return {String}
     */
    exports.toChecksumAddress = function (address) {
      address = exports.stripHexPrefix(address).toLowerCase()
      var hash = exports.sha3(address).toString('hex')
      var ret = '0x'
    
      for (var i = 0; i < address.length; i++) {
        if (parseInt(hash[i], 16) >= 8) {
          ret += address[i].toUpperCase()
        } else {
          ret += address[i]
        }
      }
    
      return ret
    }

      4.Swift implementation in EthereumKit

  • 相关阅读:
    linux下编译sphinx拓展
    Java为什么使用连接池
    内部类之.this&&.new
    何为代理
    Qt install Phonon
    Gcc简介与常用命令
    Vim的设置和使用——编程者
    QT程序启动界面的使用
    slide from one widget to another
    Hide the common top menu in Ubuntu 12.04
  • 原文地址:https://www.cnblogs.com/wanghui-garcia/p/9709389.html
Copyright © 2011-2022 走看看