ethereumjs/ethereumjs-icap
https://github.com/ethereumjs/ethereumjs-icap
ethereumjs-icap
安裝:
npm install ethereumjs-icap --saveUtilities for handling?ICAP?addresses.
It works in Node.js as well as in the browser via?browserify. When minified for a browser, it should be less than 4K in size.
使用browserify使其能夠使用在瀏覽器中,大小少于4K
?
API(詳細實現看下面的index.js)
- fromAddress(address, print, nonstd)?- try encoding an address into an IBAN????? 將address編碼成IBAN
- fromAsset(asset, print)?- try encoding an asset description into an IBAN????? 將資產描述編碼成IBAN
- toAddress(iban)?- try decoding an IBAN into an address???? 把IBAN解碼成一個地址
- toAsset(iban)?- try decoding an IBAN into an asset description??? 把IBAN解碼成資產描述
- encode(address/asset)?- encode an address or asset description into an IBAN???? 將address或資產描述編碼成IBAN
- decode(iban)?- decode an IBAN into an address or asset description????? 將IBAN 解碼成address或資產描述
- encodeBBAN(address/asset)?- encode an address or asset description into a BBAN?? 將address或資產描述編碼成BBAN
- decodeBBAN(bban)?- decode a BBAN into an address or asset description????? 將BBAN解碼成address或資產描述
- isICAP(iban)?- return true if input is a valid ICAP, otherwise false
- isAddress(iban)?- return true if the input is a valid ICAP with an address, otherwise false
- isAsset(iban)?- return true if the input is a valid ICAP with an asset description, otherwise false
All of the above methods will throw exceptions on invalid inputs. The?to*?and?from*?method will also check for the expected inputs and outputs.以上所有方法都將對無效輸入拋出異常。to*和from*方法還將檢查預期的輸入和輸出
The?print?parameter above, when set to true, will create an IBAN in the?print format, which is space delimited groups of four characters:?
上面的print參數設置為true時,將以打印格式創建一個IBAN,它是由四個字符組成的空格分隔的組
XE73 38O0 73KY GTWW ZN0F 2WZ0 R8PX 5ZPP ZSThe?address?parameter only supports?0x?prefixed input and will include that in the output.
地址參數只支持0x前綴輸入,并將其包含在輸出中
The?nonstd?parameter of?fromAddress, when set to true, will turn on support for the?basic ICAP format?generating an invalid IBAN, but encoding the entire 160 bits of an Ethereum address.
fromAddress的nonstd參數設置為true時,將啟用對生成無效的IBAN的基本ICAP格式的支持,但將對Ethereum地址的全部160位進行編碼。
?
代碼實現:
ethereumjs-icap/index.js
var hex = require('convert-hex')// For simplicity we redefine it, as the default uses lowercase var BASE36_ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' var bs36 = require('base-x')(BASE36_ALPHABET)//36進制var ICAP = {}//decode a BBAN into an address or asset description ICAP.decodeBBAN = function (bban) {var length = bban.lengthif (length === 30 || length === 31) {//即BBAN的direct或basic類型var tmp = hex.bytesToHex(bs36.decode(bban))//將其轉成16進制// FIXME: horrible padding codewhile (tmp.length < 40) {//如果小于40,將在前面添0tmp = '0' + tmp}// NOTE: certain tools include an extra leading 0, drop thatif ((tmp.length === 42) && (tmp[0] === '0') && (tmp[1] === '0')) {//如果剛好為42且前兩個都為0,就將前兩個0去掉tmp = tmp.slice(2)}return '0x' + tmp //最后加上0x前綴,就得到的address} else if (length === 16) { //即BBAN的的indirect類型return { //將其分成相應的三個字段,得到的是asset descriptionasset: bban.slice(0, 3),institution: bban.slice(3, 7),client: bban.slice(7, 16)}} else {throw new Error('Not a valid Ethereum BBAN')} }//encode an address or asset description into a BBAN ICAP.encodeBBAN = function (bban) {//bban為address或asset descriptionif (typeof bban === 'object') {//即為asset description時if (bban.asset.length !== 3 ||bban.institution.length !== 4 ||bban.client.length !== 9) {throw new Error('Invalid \'indirect\' Ethereum BBAN') //先判斷傳進來的asset description是否正確 }return [ bban.asset, bban.institution, bban.client ].join('').toUpperCase() //正確則將他們合并在一起即可} else if ((bban.length === 42) && (bban[0] === '0') && (bban[1] === 'x')) { //即為address時// Workaround for base-x, see https://github.com/cryptocoinjs/base-x/issues/18if ((bban[2] === '0') && (bban[3] === '0')) {//去掉第三、四的0bban = '0x' + bban.slice(4)}return bs36.encode(hex.hexToBytes(bban)) //然后將其編碼成36進制} else {throw new Error('Not a valid input for Ethereum BBAN')} }// ISO13616 reordering and letter translation // NOTE: we assume input is uppercase only // based off code from iban.js function prepare (iban) {// move front to the back,將前4位移到后面,如XE00iban = iban.slice(4) + iban.slice(0, 4)// translate letters to numbersreturn iban.split('').map(function (n) {var code = n.charCodeAt(0) //將字母轉成對應的ASCII數字// 65 == A, 90 == Z in ASCIIif (code >= 65 && code <= 90) {// A = 10, B = 11, ... Z = 35return code - 65 + 10 //將其轉成類似16進制的數字表示形式} else {//不是A-Z字母的就不變return n}}).join('')//最后將這些十進制數字連在一起 }// Calculate ISO7064 mod 97-10 // NOTE: assumes all numeric input string function mod9710 (input) {//執行計算模97再減10var m = 0for (var i = 0; i < input.length; i++) {m *= 10m += input.charCodeAt(i) - 48 // parseInt()m %= 97}return m }//encode an address or asset description into an IBAN ICAP.encode = function (bban, print) {bban = ICAP.encodeBBAN(bban) //第一步,得到36進制的bbanvar checksum = 98 - mod9710(prepare('XE00' + bban)) //第二步:將XE00移到36進制的bban后,然后將其轉成10進制,再對10進制的值計算模97再減10得到校驗碼// format into 2 digitschecksum = ('0' + checksum).slice(-2)//第三步:將其轉成字符串形式,并只去后兩位值var iban = 'XE' + checksum + bban //第四步: 然后將他們連起來形成ibanif (print === true) { //print為true,則以打印格式,即四個字符組成的空格分隔的組將iban的結果輸出// split a group of 4 chars with spacesiban = iban.replace(/(.{4})/g, '$1 ')}return iban }//decode an IBAN into an address or asset description ICAP.decode = function (iban, novalidity) {// change from 'print format' to 'electronic format', e.g. remove spacesiban = iban.replace(/\ /g, '')//第一步:首先將打印格式的空格刪除并連接在一起// check for validityif (!novalidity) {//novalidity為false即不支持無效的IBAN的格式if (iban.slice(0, 2) !== 'XE') {//即如果不以XE開頭,則報錯throw new Error('Not in ICAP format')}if (mod9710(prepare(iban)) !== 1) {//如果校驗碼不對,則報錯throw new Error('Invalid checksum in IBAN')}}return ICAP.decodeBBAN(iban.slice(4, 35))//然后對剩下的部分進行解碼 }/** Convert Ethereum address to ICAP* @method fromAddress* @param {String} address Address as a hex string.* @param {bool} nonstd Accept address which will result in non-standard IBAN* @returns {String}*/ ICAP.fromAddress = function (address, print, nonstd) {var ret = ICAP.encode(address, print)//返回打印格式的IBANif ((ret.replace(' ', '').length !== 34) && (nonstd !== true)) {//去掉打印格式后長度為34,且不支持無效的IBAN的格式throw new Error('Supplied address will result in invalid an IBAN') //則說明將返回一個有效的IBAN }return ret }/** Convert asset into ICAP* @method fromAsset* @param {Object} asset Asset object, must contain the fields asset, institution and client* @returns {String}*/ ICAP.fromAsset = function (asset, print) {return ICAP.encode(asset, print) }/** Convert an ICAP into an address* @method toAddress* @param {String} iban IBAN/ICAP, must have an address encoded* @returns {String}*/ ICAP.toAddress = function (iban) {var address = ICAP.decode(iban)if (typeof address !== 'string') {throw new Error('Not an address-encoded ICAP')}return address }/** Convert an ICAP into an asset* @method toAsset* @param {String} iban IBAN/ICAP, must have an asset encoded* @returns {Object}*/ ICAP.toAsset = function (iban) {var asset = ICAP.decode(iban)if (typeof asset !== 'object') {throw new Error('Not an asset-encoded ICAP')}return asset }ICAP.isICAP = function (iban) {try {ICAP.decode(iban)return true} catch (e) {return false} }ICAP.isAddress = function (iban) {try {ICAP.toAddress(iban)return true} catch (e) {return false} }ICAP.isAsset = function (iban) {try {ICAP.toAsset(iban)return true} catch (e) {return false} }module.exports = ICAP?
Examples
var ICAP = require("ethereumjs-icap") console.log(ICAP.fromAsset({asset: 'ETH',institution: 'XREG',client: 'GAVOFYORK'}) ) // returns 'XE81ETHXREGGAVOFYORK' console.log(ICAP.fromAddress('0x00c5496aee77c1ba1f0854206a26dda82a81d6d8')) // returns 'XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS' console.log(ICAP.toAsset('XE81ETHXREGGAVOFYORK')) // returns { // asset: 'ETH', // institution: 'XREG', // client: 'GAVOFYORK' // } console.log(ICAP.toAddress('XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS')) // returns '0x00c5496aee77c1ba1f0854206a26dda82a81d6d8' console.log(ICAP.decodeBBAN('38O073KYGTWWZN0F2WZ0R8PX5ZPPZS'))//direct,0x00c5496aee77c1ba1f0854206a26dda82a81d6d8 console.log(ICAP.decodeBBAN('038O073KYGTWWZN0F2WZ0R8PX5ZPPZS'))//basic,0x00c5496aee77c1ba1f0854206a26dda82a81d6d8 console.log(ICAP.decodeBBAN('ETHXREGGAVOFYORK'))//indirect,{ asset: 'ETH', institution: 'XREG', client: 'GAVOFYORK' }try{console.log(ICAP.decodeBBAN('TOOSHORT'))//nothing,wrong: Error: Not a valid Ethereum BBAN }catch(e){console.log(e) }console.log(ICAP.encodeBBAN('0x00c5496aee77c1ba1f0854206a26dda82a81d6d8'))//direct,38O073KYGTWWZN0F2WZ0R8PX5ZPPZS console.log(ICAP.encodeBBAN('0x42c5496aee77c1ba1f0854206a26dda82a81d6d8'))//basic,7SS84LEE90PIULMR3DYBGOVBNJN5N14 console.log(ICAP.encodeBBAN({asset: 'ETH',institution: 'XREG',client: 'GAVOFYORK'}) )//indirect,ETHXREGGAVOFYORKtry{console.log(ICAP.encodeBBAN('0xc5496aee77c1ba1f08542'))//non-standard hex input,wrong: Error: Not a valid input for Ethereum BBAN }catch(e){console.log(e) }console.log(ICAP.decode('XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS'))//direct,0x00c5496aee77c1ba1f0854206a26dda82a81d6d8 console.log(ICAP.decode('XE73038O073KYGTWWZN0F2WZ0R8PX5ZPPZS'))//basic,0x00c5496aee77c1ba1f0854206a26dda82a81d6d8 console.log(ICAP.decode('XE81ETHXREGGAVOFYORK'))//indirect,{ asset: 'ETH', institution: 'XREG', client: 'GAVOFYORK' } console.log(ICAP.decode('XE73 38O0 73KY GTWW ZN0F 2WZ0 R8PX 5ZPP ZS'))//'direct' in print format,0x00c5496aee77c1ba1f0854206a26dda82a81d6d8 console.log(ICAP.encode('0x088f924eeceeda7fe92e1f5b0fffffffffffffff'))//direct,XE43ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ console.log(ICAP.encode('0x42c5496aee77c1ba1f0854206a26dda82a81d6d8'))//basic,XE657SS84LEE90PIULMR3DYBGOVBNJN5N14 console.log(//indirect,XE81ETHXREGGAVOFYORK ICAP.encode({asset: 'ETH',institution: 'XREG',client: 'GAVOFYORK'}) ) try{console.log(ICAP.encode('c5496aee77c1ba1f08542'))//non-standard hex input,wrong: Error: Not a valid input for Ethereum BBAN }catch(e){console.log(e) }console.log(ICAP.isICAP('XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS'))//true console.log(ICAP.isICAP('XE73 Invalid'))//false console.log(ICAP.isAddress('XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS'))//true console.log(ICAP.isAddress('XE81ETHXREGGAVOFYORK'))//false console.log(ICAP.isAsset('XE81ETHXREGGAVOFYORK'))//true console.log(ICAP.isAsset('XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS'))//false?
Direct?address generation
A?direct address ICAP?is an address less than 155 bits of length and therefore it safely fits into the length restrictions of IBAN (and the checksum method used). That upper limit is?0x03ffffffffffffffffffffffffffffffffffffff?or?XE91GTJRJEU5043IEF993XWE21DBF0BVGF.
直接地址ICAP是長度小于155位的地址,因此它完全符合IBAN的長度限制(以及使用的校驗和方法)。最大限制是0x03ffffffffffffffffffffffffffffffffffffff或XE91GTJRJEU5043IEF993XWE21DBF0BVGF
The following simple bruteforce code can be used to generate such addresses:
使用蠻力方法生成address
const ethUtil = require('ethereumjs-util') function generateDirectAddress () {while(true) {var privateKey = crypto.randomBytes(32) // or your favourite other random methodif (ethUtil.privateToAddress(privateKey)[0] <= 3) {return privateKey}} }Alternatively?ethereumjs-wallet?can be used to generate compatible addresses.
另外,可以使用ethereumjs-wallet生成兼容的地址
轉載于:https://www.cnblogs.com/wanghui-garcia/p/9989032.html
總結
以上是生活随笔為你收集整理的ethereumjs/ethereumjs-icap的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python房价数据分析统计服_Pyth
- 下一篇: 蛮力法