https://github.com/ethereumjs/ethereumjs-icap

ethereumjs-icap

安装:

npm install ethereumjs-icap --save

Utilities 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 ZS

The 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.length
if (length === || length === ) {//即BBAN的direct或basic类型
var tmp = hex.bytesToHex(bs36.decode(bban))//将其转成16进制 // FIXME: horrible padding code
while (tmp.length < ) {//如果小于40,将在前面添0
tmp = '' + tmp
} // NOTE: certain tools include an extra leading 0, drop that
if ((tmp.length === ) && (tmp[] === '') && (tmp[] === '')) {//如果刚好为42且前两个都为0,就将前两个0去掉
tmp = tmp.slice()
} return '0x' + tmp //最后加上0x前缀,就得到的address
} else if (length === ) { //即BBAN的的indirect类型
return { //将其分成相应的三个字段,得到的是asset description
asset: bban.slice(, ),
institution: bban.slice(, ),
client: bban.slice(, )
}
} 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 description
if (typeof bban === 'object') {//即为asset description时
if (bban.asset.length !== ||
bban.institution.length !== ||
bban.client.length !== ) {
throw new Error('Invalid \'indirect\' Ethereum BBAN') //先判断传进来的asset description是否正确
}
return [ bban.asset, bban.institution, bban.client ].join('').toUpperCase() //正确则将他们合并在一起即可
} else if ((bban.length === ) && (bban[] === '') && (bban[] === 'x')) { //即为address时
// Workaround for base-x, see https://github.com/cryptocoinjs/base-x/issues/18
if ((bban[] === '') && (bban[] === '')) {//去掉第三、四的0
bban = '0x' + bban.slice()
} 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位移到后面,如XE00
iban = iban.slice() + iban.slice(, ) // translate letters to numbers
return iban.split('').map(function (n) {
var code = n.charCodeAt() //将字母转成对应的ASCII数字
// 65 == A, 90 == Z in ASCII
if (code >= && code <= ) {
// A = 10, B = 11, ... Z = 35
return code - + //将其转成类似16进制的数字表示形式
} else {//不是A-Z字母的就不变
return n
}
}).join('')//最后将这些十进制数字连在一起
} // Calculate ISO7064 mod 97-10
// NOTE: assumes all numeric input string
function mod9710 (input) {//执行计算模97再减10
var m =
for (var i = ; i < input.length; i++) {
m *=
m += input.charCodeAt(i) - // parseInt()
m %=
}
return m
} //encode an address or asset description into an IBAN
ICAP.encode = function (bban, print) {
bban = ICAP.encodeBBAN(bban) //第一步,得到36进制的bban var checksum = - mod9710(prepare('XE00' + bban)) //第二步:将XE00移到36进制的bban后,然后将其转成10进制,再对10进制的值计算模97再减10得到校验码 // format into 2 digits
checksum = ('' + checksum).slice(-)//第三步:将其转成字符串形式,并只去后两位值 var iban = 'XE' + checksum + bban //第四步: 然后将他们连起来形成iban
if (print === true) { //print为true,则以打印格式,即四个字符组成的空格分隔的组将iban的结果输出
// split a group of 4 chars with spaces
iban = iban.replace(/(.{})/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 spaces
iban = iban.replace(/\ /g, '')//第一步:首先将打印格式的空格删除并连接在一起 // check for validity
if (!novalidity) {//novalidity为false即不支持无效的IBAN的格式
if (iban.slice(, ) !== 'XE') {//即如果不以XE开头,则报错
throw new Error('Not in ICAP format')
} if (mod9710(prepare(iban)) !== ) {//如果校验码不对,则报错
throw new Error('Invalid checksum in IBAN')
}
} return ICAP.decodeBBAN(iban.slice(, ))//然后对剩下的部分进行解码
} /*
* 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)//返回打印格式的IBAN if ((ret.replace(' ', '').length !== ) && (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,ETHXREGGAVOFYORK try{
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

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的长度限制(以及使用的校验和方法)。最大限制是0x03ffffffffffffffffffffffffffffffffffffffXE91GTJRJEU5043IEF993XWE21DBF0BVGF

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() // or your favourite other random method
if (ethUtil.privateToAddress(privateKey)[] <= ) {
return privateKey
}
}
}

Alternatively ethereumjs-wallet can be used to generate compatible addresses.

另外,可以使用ethereumjs-wallet生成兼容的地址

ethereumjs/ethereumjs-icap的更多相关文章

  1. ethereumjs/ethereumjs-wallet

    Utilities for handling Ethereum keys ethereumjs-wallet A lightweight wallet implementation. At the m ...

  2. ethereumjs/ethereumjs-util

    ethereumjs/ethereumjs-util Most of the string manipulation methods are provided by ethjs-util 更多的字符串 ...

  3. ethereumjs/ethereumjs-tx

    https://github.com/ethereumjs/ethereumjs-tx A simple module for creating, manipulating and signing e ...

  4. ethereumjs/ethereumjs-common-1-简介

    为了了解ethereumjs/ethereumjs-block-3-代码的使用需要了解的一个模块 https://github.com/ethereumjs/ethereumjs-common Com ...

  5. ethereumjs/ethereumjs-common-2-API文档

    https://github.com/ethereumjs/ethereumjs-common/blob/master/docs/index.md 该API的调用的详细例子可见ethereumjs/e ...

  6. ethereumjs/browser-builds

    https://github.com/ethereumjs/browser-builds ethereumjs - Browser Builds This repository contains br ...

  7. ethereumjs/ethereumjs-vm-3-StateManager

    https://github.com/ethereumjs/ethereumjs-vm/blob/master/docs/stateManager.md StateManager 要与本博客的ethe ...

  8. ethereumjs/ethereumjs-vm-2-API文档

    https://github.com/ethereumjs/ethereumjs-vm/blob/master/docs/index.md vm.runBlockchain Processes blo ...

  9. ethereumjs/ethereumjs-vm-4-tests

    根据代码发现还要了解的模块有: ethereumjs/merkle-patricia-tree -对应数据存储的数据结构 ethereumjs-blockchain —— 区块链 ethereumjs ...

随机推荐

  1. Java - 线程优先级和守护线程

    Java多线程系列--“基础篇”10之 线程优先级和守护线程 概要 本章,会对守护线程和线程优先级进行介绍.涉及到的内容包括:1. 线程优先级的介绍2. 线程优先级的示例3. 守护线程的示例 转载请注 ...

  2. PDO添加数据的预处理语句

    1.添加页面<h1>添加数据</h1><form action="chuli.php" method="post"> < ...

  3. Linux 多个vi、vim进程编辑同一文件时的临时文件问题

    多个vi.vim进程编辑同一文件时的临时文件问题 by:授客 QQ:1033553122   使用vi.vim编辑文件,实际是先copy一份临时文件并映射到内存里进行编辑,所以你编辑的是临时文件,不是 ...

  4. go语言练习:幂、函授接收和返回参数、转义字符、变量和常量

    1.实现a^b次方 package main func main() { r2 := power1(2,4) println(r2) } func power1(a uint64, b uint64) ...

  5. Windows 自动更新服务恢复

    之前手贱删除了Windows的自动更新服务,命令: SC DELETE Wuauserv 悲剧的是最近中了[永恒之蓝]病毒,很恼人!杀了毒,最后还是得仰仗Windows的补丁来加固系统.于是想通过SC ...

  6. PHP剔除删除掉危险字符

    本文出至:新太潮流网络博客 /** * [剔除掉危险字符] * @E-mial wuliqiang_aa@163.com * @TIME 2017-04-07 * @WEB http://blog.i ...

  7. 将 HPC 作业从本地计算机提交到部署在 Azure 中的 HPC Pack 群集

    Note Azure 具有用于创建和处理资源的两个不同的部署模型:Resource Manager 和经典. 这篇文章介绍了如何使用这两种模型,但 Azure 建议大多数最新部署使用 Resource ...

  8. SQL Server中怎么查看每个数据库的日志大小,以及怎么确定数据库的日志文件,怎么用语句收缩日志文件

    一,找到每个数据库的日志文件大小 SQL Server:查看SQL日志文件大小命令:dbcc sqlperf(logspace) DBA 日常管理工作中,很重要一项工作就是监视数据库文件大小,及日志文 ...

  9. MySQL MTS复制: hitting slave_pending_jobs_size_max

    测试步骤: 从库停止复制:stop slave; 主库创建大表400万条记录. 开启从库复制:start slave; 监测从库error log持续输出: 2018-12-06T10:40:52.6 ...

  10. android的hwc浅析【转】

    https://blog.csdn.net/alien75/article/details/39290109 注:本文档基于kk进行分析,着重于概念的精确定义和版本历史演变 一.关于hwc的介绍 广义 ...