eip | title | author | type | category | status | created |
---|---|---|---|---|---|---|
55
|
Mixed-case checksum address encoding
|
Vitalik Buterin
|
Standards Track
|
ERC
|
Final
|
2016-01-14
|
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()))python
所謂的大端模式(Big-endian),是指數據的高字節,保存在內存的低地址中,而數據的低字節,保存在內存的高地址中,這樣的存儲模式有點兒相似於把數據看成字符串順序處理:地址由小向大增長,而數據從高位往低位放;好比1234,若是是數字的話應該從低位開始讀4321(即小端模式);可是這裏爲大端模式,因此讀法就是1234。這是爲了順序處理addr的hash值git
In English, convert the address to hex, but if the i
th digit is a letter (ie. it's one of abcdef
) print it in uppercase if the 4*i
th bit of the hash of the lowercase hexadecimal address is 1 otherwise print it in lowercase.github
Benefits:swift
例子:dom
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,那麼就寫成:ide
var hash = createKeccakHash('keccak256').update(Buffer.from(address.toLowerCase(), 'ascii')).digest()
Wallet | displays checksummed addresses | rejects invalid mixed-case | rejects too short | rejects 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 | displays checksummed deposit addresses | rejects invalid mixed-case | rejects too short | rejects 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 |
ethereum-utils
/** * 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
ui