什么是ICAP?从以太坊Homestead指南的词汇表中可以看出:

Interexchange Client Address Protocol, an IBAN-compatible system for referencing and transacting to client accounts aimed to streamline the process of transferring funds, worry-free between exchanges and, ultimately, making KYC and AML concerns a thing of the past.

ICAP 互换客户端地址协议,一种IBAN兼容系统,用于引用和处理客户帐户,旨在简化资金转移流程,在交易所之间无忧无虑,并最终使KYC和AML成为过去。

这里有相关于以太坊对ICAP的介绍:

在第三方账户之间(特别是交易所账户)之间转账资金给用户带来了相当大的负担,并且由于客户账户中的存款被识别的方式而容易出错。现有的银行业通过拥有一个被称为IBAN的通用代码解决了这个问题。该代码合并了机构和客户帐户以及错误检测机制,实际上消除了微不足道的错误并为用户提供了相当大的便利。不幸的是,这是一个严格监管和集中的服务,只有大型的,完善的机构才能使用。目前的议定书ICAP可被视为适用于以太坊系统中任何含有资金的机构的分散版本。

IBAN介绍

国际银行账户号码~[1]~ (International Bank Account Number,简称IBAN)是各国各银行之间互相定立的标识号码,可降低国际间金融操作的失误。它最初是由欧洲银行标准委员会(ECBS)通过,后来被采纳为国际标准 ISO 13616:1997。目前的标准是ISO 13616:2007,表明SWIFT代码(ISO 9362)为正式的格式。最初开发是为了促进欧盟范围内的支付,但现在也已经实施到大多数欧洲国家和其他国家,尤其是在中东和加勒比海地区。IBAN最多包含34个字母和数字字符:首两个字母是ISO 3166-1α-2国家代码,然后两个校验位,校验位可检查完整性。最后一个是特定国家的基本银行账户号码(BBAN)。BBAN格式的决定是由每个国家的银行界的约束下,它必须是一个固定长度的不区分大小写的英数字。它包括国内银行账户号码,银行分行的号码,和潜在的路由信息。

基本银行账户号码

基本银行账户号码(The Basic Bank Account Number,简称BBAN)的格式是由国家中央银行或相应机关所订定,格式并没有强制性。一国的基本银行账户号码须为固定长度且由大小写不敏感的英数字组成。其包括本国账户号码,子分支辨识码与路径资讯。各国皆可拥有不同的编号系统,最多三十字。

IBAN结构

IBAN代码由多达34个不区分大小写的字母数字字符组成,其字符取值范围为0-9和A-Z。它包含三个信息:

  • 国家代码; 以下内容的顶级标识符(ISO 3166-1 alpha-2);
  • 错误检测代码; 使用mod-97-10校验和协议(ISO / IEC 7064:2003);
  • 基本银行账号(BBAN); 该机构,分支和客户账户的标识符,其组成取决于上述国家。

举例来说,从维基百科可以得知,英国的IBAN格式定义为:

国家 格式 说明
英国?? GBkk bbbb ssss sscc cccc cc b = 银行代码 s = 银行分类代码 c = 账号

该 GBkk bbbb ssss sscc cccc cc 格式解读为:

[国家代码:GB][错误校验码:kk][基本银行账号:bbbb ssss sscc cccc cc]

对于英国来说,BBAN由以下部分组成:

  • 机构标识符,4个字符的字母,例如 MIDL 代表汇丰银行。
  • 分类代码(机构内的分行标识符),一个6位十进制数字,例如402702汇丰银行的Lancaster分行。
  • 帐号(分支机构内的客户标识符),一个8位十进制数字。

以太坊ICAP设计

以太坊引入了新的IBAN国家代码:XE,X前缀为扩展的意思,E表示为以太坊(Ethereum),制定为非法定货币(例如XBOX, XEOS)。以太坊在IBAN基础上设计了ICAP,其设计思路与IBAN兼容。目的是为了方便各大公链之间转账?它有三种BBAN代码类型:直接类型,基本类型和间接类型。

直接类型

此代码的直接BBAN为30个字符,将包含一个字段:

  • 帐户标识符,30个字母数字(<155位)。这将被解释为表示160位以太坊地址的最低有效位的大端编码的36进制整数。因此,这些以太坊地址通常以零字节开始。

例如XE 73 38O073KYGTWWZN0F2WZ0R8PX5ZPPZS,它的对应的地址00c5496aee77c1ba1f0854206a26dda82a81d6d8

基本类型

与直接编码相同,但代码为31个字符(与IBAN不兼容)并组成相同的单个字段:

  • 帐户标识符,31个字符字母数字(<161位)。这将被解释为一个代表160位以太坊地址的大端编码的36进制整数。

间接类型

该代码的BBAN在间接时将为16个字符,并将包含三个字段:

  • 资产标识符,3个字符的字母数字(<16位);
  • 机构标识符,4个字符的字母数字(<21位);
  • 机构客户标识符,9个字符的字母数字(<47位);

包括四个首字符,这导致最终的客户帐户地址长度为20个字符,格式为:

XE81ETHXREGGAVOFYORK

分成:

  • XE 以太坊的国家代码;
  • 81 校验和;
  • ETH 客户账户中的资产标识符 - 在这种情况下,“ETH”是唯一有效的资产标识符,因为以太坊的基础注册管理机构合同仅支持该资产;
  • XREG 账户的机构代码 - 在这种情况下,以太坊的基础注册管理机构合同;
  • GAVOFYORK 该机构内的客户标识符 - 在这种情况下,直接支付且无任何主要地址的额外数据与以太坊基础注册合同中的名称“GAVOFYORK”相关联;

URI表示形式

iban:XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS

具体实现:以太坊地址转换成ICAP格式

转换函数

//ConvertAddressToICAP 将以太坊地址转换为ICAP格式的地址
func ConvertAddressToICAP(a common.Address) (string, error) { enc := base36Encode(a.Big()) if len(enc) < 30 { enc = join(strings.Repeat("0", 30-len(enc)), enc) } // 以太坊国家代码XE + 校验码 + 账号 icap := join("XE", checkDigits(enc), enc) return icap, nil }

36进制编码

其规则如同十进制数转十六进制数,其算法如下:

十六进制数取值范围表示s="0123456789ABCDEF"。其字符串数组下标范围为0-15,其中对应的下标:A=11,B=12… F=15。

记余数数组a,

  1. 把10进制数除以16,获取整数商和余数,记下余数和整数商,并把余数放入余数数组a;
  2. 整数商不为0时,再次执行第一个步骤,整数商为0时停止,并记录下此时的余数;
  3. 倒排余数数组a,同时影射每个位置值到s字符串数组下标对应的值。

例如:十进制数505,500/16 得31余9,将9放入余数数组a,由于31不为0,再次用31/16 得1余15,将15放入a,1不为0,再次用1/16 得0余1,将1放入a,倒排a,得[s[1],s[15],s[9]] = ['1', 'F', '9'] = "0x1F9" = 505。

36进制编码也是采用了如上算法,只是s="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"。

var (Base36Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"Big36 = big.NewInt(36)
)
func base36Encode(i *big.Int) string { var chars []rune x := new(big.Int) for { x.Mod(i, Big36) chars = append(chars, rune(Base36Chars[x.Uint64()])) i.Div(i, Big36) if i.Cmp(Big0) == 0 { break } } // reverse slice for i, j := 0, len(chars)-1; i < j; i, j = i+1, j-1 { chars[i], chars[j] = chars[j], chars[i] } return string(chars) }

校验码

校验码使用了mod-97-10校验和协议 (ISO / IEC 7064:2003),查看ISO具体协议需要8,800瑞士法郎。

举例,对于字符串794,其算法步骤为:

步骤1:追加两个零占据校验字符位置:79400; 
步骤2:除以97,得到商818和整数余数54; 
步骤3:将校验字符值确定为(97 + 1) - 54 = 44并将其附加到原始字符串以给出79444。

为了检查,将字符串除以97; 如果提醒是1,则校验通过。

计算国际银行帐号(IBAN)的校验位(xx yyy zzzzzzzz kk)

  • 余数不等于0的计算。

不包括支票号码的银行账号:06 000 01234567。

a:06 000 01234567 00
b:060000123456700:97 = 618557973780余数= 40 
c:(97 + 1) - 40 = 58结果:06 000 01234567 58

校验和:06000123456758:97 = 618557973781其余= 1

  • 无余数计算或余数等于0。

不包括支票号码的银行账号:06 000 01234586。

a:06 000 01234586 00
b:060000123458600:97 = 618557973800其余= 00 
c:(97 + 1) - 00 = 98结果:06 000 01234586 98

校验和:06000123458698:97 = 618557973801余数= 1。

func checkDigits(s string) string { expanded, _ := iso13616Expand(strings.Join([]string{s, "XE00"}, "")) num, _ := new(big.Int).SetString(expanded, 10) //mod-97-10 num.Sub(Big98, num.Mod(num, Big97)) checkDigits := num.String() // zero padd checksum if len(checkDigits) == 1 { checkDigits = join("0", checkDigits) } return checkDigits } // not base-36, but expansion to decimal literal: A = 10, B = 11, ... Z = 35 func iso13616Expand(s string) (string, error) { var parts []string if !validBase36(s) { return "", errICAPEncoding } for _, c := range s { i := uint64(c) if i >= 65 { //字符A-Z在ASCII码表中分别对应10进制值为65,66... //字符A-Z的36进制字符串索引分别是A=10,B=11... //字符的码表值-字符的索引值=55 //字符码表值-55=字符的索引值 parts = append(parts, strconv.FormatUint(uint64(c)-55, 10)) } else { parts = append(parts, string(c)) } } return join(parts...), nil }

具体实现:ICAP格式转换成以太坊地址

校验

func validCheckSum(s string) error { s = join(s[4:], s[:4]) expanded, err := iso13616Expand(s) if err != nil { return err } checkSumNum, _ := new(big.Int).SetString(expanded, 10) if checkSumNum.Mod(checkSumNum, Big97).Cmp(Big1) != 0 { return errICAPChecksum } return nil }

转换

func parseICAP(s string) (common.Address, error) {if !strings.HasPrefix(s, "XE") { return common.Address{}, errICAPCountryCode } if err := validCheckSum(s); err != nil { return common.Address{}, err } // checksum is ISO13616, Ethereum address is base-36 bigAddr, _ := new(big.Int).SetString(s[4:], 36) return common.BigToAddress(bigAddr), nil }

用途

imToken钱包二维码使用了ICAP格式,扫码之后出现的格式为:

iban:XE86G29C8IV34UOJMYWHGDSGME33YKEC3QO?account=100&type=ETH

其中XE86G29C8IV34UOJMYWHGDSGME33YKEC3QO是转账的地址,account是转账的数额,type是转账的类型,这里代表转ETH。

BOX将兼容imToken格式。

完整的代码片段可以在这里找到:https://gist.github.com/alpha...点击预览

参考

1.) Wikipedia: International Bank Account Number

2.) ICAP: Inter exchange Client Address Protocol

3.) Open source: BOX a business wallet solution

ICAP: 互换客户端地址协议相关推荐

  1. ICAP: 互换客户端地址协议 1

    什么是ICAP?从以太坊Homestead指南的词汇表中可以看出: Interexchange Client Address Protocol, an IBAN-compatible system f ...

  2. ICAP互换客户端地址协议iOS实现示例

    之前我写了一篇关于ICAP: 互换客户端地址协议的文章.文章中介绍和详细解析了关于ICAP协议算法,并给出Go语言版本的具体实现.实际上以太坊全节点Geth提供了WEB3接口,来转换ICAP格式地址( ...

  3. python request大批量发送请求调用接口时,报错:[WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。

    接到一个项目需求,其中需要调用到供应商的Http  API,因为有大量的测试资源,所以代码中会循环调用API. 然而在测试代码执行过程中,过程中偶尔报错: 此时看到报错,怀疑是可能是同时并发的问题, ...

  4. Exchange Server 2007客户端访问协议部署SSL

    安全套接字层是用来加密客户端和服务器之间通讯的一种方法.Microsoft Exchange Server 2007 能够为所有的客户端访问协议部署SSL.这些协议包括Microsoft Exchan ...

  5. 计算机网络实验arp协议分析,计算机网络ARP地址协议解析实验报告

    计算机网络ARP地址协议解析实验报告 (5页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 计算机网络实验报告.实验目的:1. 掌握ARP协议 ...

  6. 前端学习(1856)vue之电商管理系统电商系统之安装mysql出现mysql报错:Can’t start server: Bind on TCP/IP port: 通常每个套接字地址(协议/网络地址

    2020-07-26T11:44:29.778919Z 0 [ERROR] [MY-010262] [Server] Can't start server: Bind on TCP/IP port: ...

  7. 服务器地址和客户端地址详解与区别

    一.客户端地址 客户端访问服务器的地址,是一个外部地址.因为服务器中可能有多个web应用,所以客户端地址要加上web应用名. /webprogram/url-petten  其中最前面的/表示当前服务 ...

  8. SQL Server 2012笔记分享-35:配置客户端网络协议

    客户端应用程序可以使用 TCP/IP.命名管道.VIA 或共享内存协议连接到 Microsoft SQL Server.可以通过使用 SQL Server Native Client dll 中包含的 ...

  9. OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。

    OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次. import socket s = socket.socket(socket.AF_IN ...

最新文章

  1. codeblock 恢复默认字体设置
  2. sql backup database备份d盘_Oracle RMAN备份与恢复
  3. Spring @Async注解
  4. 手把手教你完成CSDN对接百度统计 看完这篇文章你还不会对接 欢迎您提刀顺着网线来砍我!!!!
  5. java 输出全部小写_输入小写,输出大写,为什么报错?
  6. NO.1_python_scrapy组成爬取多页数据连接数据库配置文件书写
  7. 【每日SQL打卡】​​​​​​​​​​​​​​​DAY 8丨判断三角形【难度简单】
  8. 2007年上半年软件测试_洪恩教育成功登陆纽交所,上市首日大涨超33%!成2020年首家美股上市的中国教育公司...
  9. 《无边界触达——数字化时代的高等教育》白皮书,附下载地址
  10. java名称服务_java – UnknownHostException:名称或服务未知
  11. 11-标志寄存器+adc/sbb+cmp+条件转移指令
  12. coreos_CoreOS简介
  13. 网上商城建设:微信小程序直播申请开通流程及开通方法
  14. 灰色系统学习总结(一)
  15. odb 使用指南(一)环境搭建
  16. 大数据工程师工作笔记之集群节点准备
  17. JS模块化说明视频-张晓飞-专题视频课程
  18. 揭密SQL Server DATETIME数据类型
  19. charles 抓包图片显示_charles 抓包简单使用
  20. 证券IT:冬虫夏草之技术路线图

热门文章

  1. 如何评估互阻抗放大器(第 2 部分)
  2. HttpComponents
  3. 局域网怎样自动安装FLASH插件(浏览器不安装flashplayer都可以浏览.swf文件)
  4. Excel访问局域网中OLAP方案
  5. 70个Python练手项目列表,看了让你茅塞顿开~
  6. 电脑装机必备软件清单_推荐15款超赞Windows装机必备软件,让你的电脑再好用10倍!...
  7. oracle9201怎么安装,Solaris10上安装64位Oracle9201
  8. python中关于sqlite3数据库插入数据的使用
  9. 练习10-1 使用递归函数计算1到n之和 (10 分)
  10. LCA 朴素算法+树差分倍增+Tarjan算法 三种算法实现c++代码实现