What is ICAP? From the glossary of the Ethereum Homestead Guide, you can see:
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 Co Ncerns a thing of the past.
The ICAP Interchange Client address protocol, an IBAN-compliant system for referencing and processing customer accounts, is designed to streamline the transfer of funds, carefree between exchanges, and ultimately make KYC and AML a past.
Here is an introduction to the ICAP that is relevant to Ethereum:
The
transfer of funds between third-party accounts (especially Exchange accounts) presents a considerable burden to the user and is prone to error due to the way in which the deposits in the client's account are identified. The existing banking industry solves this problem by having a generic code called the
IBAN . The code incorporates both institutional and customer accounts and error detection mechanisms, virtually eliminating trivial errors and providing users with considerable convenience. Unfortunately, this is a strictly regulated and centralized service that only large, well-established institutions can use. The current protocol ICAP may be considered as a decentralized version of any institution containing funds in the Ethereum system.
IBAN Introduction
The International Bank account number ~[1]~ (International, or IBAN) is an identification number that is established among banks in each country to reduce the international financial operation errors. It was originally adopted by the European Banking Standards Committee (ECBS) and was later adopted as an international standard ISO 13,616:1997. The current standard is ISO 13,616:2007, which indicates that the SWIFT code (ISO 9362) is in the formal format. Originally developed to promote EU-wide payments, it has now been implemented in most European countries and other countries, especially in the Middle East and the Caribbean. The IBAN contains up to 34 alphanumeric characters: the first two letters are the ISO 3166-1α-2 country code, and then two check bits, and the check bit checks the integrity. The last one is the country-specific basic bank account number (BBAN). The decision of the Bban format is governed by the banking sector of each state, and it must be a fixed-length, case-insensitive English number. It includes the domestic bank account number, the bank branch number, and the potential routing information.
Basic Bank Account Number
The format of the basic bank account number, or BBAN, is determined by the central bank of the State or by the appropriate authority and is not mandatory. A country's basic bank account number must be a fixed-length, non-case-sensitive number of English numerals. It includes the national account number, sub-branch identification code and path information. Each country can have a different numbering system, up to 30 words.
IBAN structure
The IBAN code consists of up to 34 case-insensitive alphanumeric characters with a range of characters ranging from 0-9 to A-Z. It consists of three messages:
- Country code; The top-level identifier for the following (ISO 3166-1 alpha-2);
- Error detection code; Using the mod-97-10 Checksum Protocol (ISO/IEC 7,064:2003);
- Basic Bank account (BBAN); The identifier of the institution, branch and client account, whose composition depends on the aforementioned countries.
For example, from Wikipedia, the English IBAN format is defined as:
National |
format |
Description |
United Kingdom |
GBkk bbbb ssss sscc cccc cc |
b = Bank Code s = Bank classification code c = account Number |
This GBkk bbbb ssss sscc cccc cc
format is interpreted as:
[国家代码:GB][错误校验码:kk][基本银行账号:bbbb ssss sscc cccc cc]
For the UK, Bban is made up of the following parts:
- An institutional identifier, 4-character letter, for example, on
MIDL
behalf of HSBC.
- The classification code (the branch identifier within the organization), a 6-digit decimal number, such as
402702
HSBC's Lancaster branch.
- Account number (customer identifier within the branch office), a 8-bit decimal number.
Ethereum ICAP Design
Ethereum introduced the new IBAN Country code: The XE,X prefix is extended meaning, E is represented as Ethereum (Ethereum), and is formulated as a non-legal currency (such as Xbox, Xeos). Ethereum has designed ICAP on the IBAN basis, and its design approach is compatible with the IBAN. The purpose is to facilitate the transfer of funds between the major public links? It has three types of Bban code: direct Type, base type, and indirect type.
Direct type
The direct bban of this code is 30 characters and will contain a field:
- Account identifier, 30 alphanumeric (<155 bit). This will be interpreted as a 36 binary integer that represents the least significant bit of the 160-bit ethereum address for the big-endian encoded. Therefore, these ethereum addresses usually start with 0 bytes.
For example the XE-38o073kygtwwzn0f2wz0r8px5zppzs, its corresponding address 00c5496aee77c1ba1f0854206a26dda82a81d6d8
.
Basic type
Same as direct encoding, but the code is 31 characters (not compatible with the IBAN) and consists of the same single field:
- Account identifier, 31-character alphanumeric (<161 bit). This will be interpreted as a 36 binary integer encoded as a big-endian 160-bit ethereum address.
Indirect type
The code's bban will be 16 characters in indirection, and will contain three fields:
- An asset identifier, a 3-character alphanumeric (<16 bit);
- Agency identifier, 4-character alphanumeric (<21 bit);
- Institutional client identifier, 9-character alphanumeric (<47 bit);
Includes four first characters, which results in a final customer account address length of 20 characters in the format:
XE81ETHXREGGAVOFYORK
Into:
XE
The country code of Ethereum;
81
The checksum;
ETH
Asset identifiers in the customer account-in this case, "ETH" is the only valid asset identifier, as the underlying registry contract for Ethereum supports only that asset;
XREG
The institution code of the account-in this case, the basic registry contract of Ethereum;
GAVOFYORK
Customer identifiers within the institution-in this case, additional data directly paid without any primary address is associated with the name "Gavofyork" in the Ethereum Foundation registration contract;
URI representation
iban:XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS
Specific implementation: Ethereum address converted to ICAP format
Conversion functions
//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 binary encoding
Its rules are like the decimal number to hexadecimal number, the algorithm is as follows:
The hexadecimal value range represents s= "0123456789ABCDEF". Its string array subscript range is 0-15, where the corresponding subscript: a=11,b=12 ... F=15.
The remainder array A,
- Divide the 10 binary number by 16, get the integer quotient and remainder, note the remainder and the integer quotient, and put the remainder in the remainder array A;
- The integer quotient is not 0 o'clock, executes the first step again, the integer quotient stops at 0 o'clock, and records the remainder at this time;
- The remainder array A is inverted, and the value of each positional value to the index of the s string array is mapped.
For example: decimal number 505,500/16 more than 31 9, put 9 into the remainder array a, because 31 is not 0, again with 31/16 1 more 15, 15 into a,1 not 0, again with 1/16 0 more 1, 1 into a, inverted row a, get [s[1],s[15],s[9]] = [' 1 ', ' F ', ' 9 '] = "0x1f9" = 505.
36 binary encoding is also using the above algorithm, just 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)}
Check code
The checksum code uses the mod-97-10 Checksum Protocol (ISO/IEC 7,064:2003), and it takes CHF 8,800 to view the ISO specific agreement.
For example, for string 794, the algorithm steps are:
Step 1: Append two x 0 Occupy check character position: 79400;
Step 2: Divide by 97, get quotient 818 and integer remainder 54;
Step 3: The officer character value is determined to be (97 + 1)-54 = 44 and append it to the original string to give 79444.
To check, divide the string by 97; If the reminder is 1, the checksum is passed.
Calculate check digit for international bank account Number (IBAN) (xx yyy zzzzzzzz KK)
- The remainder is not equal to 0 of the calculation.
bank account not including cheque number: 06 000 01234567.
a:06 01234567
b:060000123456700:97 = 618,557,973,780 remainder = 40
C: (97 + 1)-40 = 58 results: 01234567
Checksum: 06000123456758:97 = 618557973781 remainder = 1
- The calculation of the zero number or the remainder equals 0.
bank account not including cheque number: 06 000 01234586.
a:06 01234586
b:060000123458600:97 = 618557973800 remaining = 00
C: (97 + 1)-00 = 98 Results: 01234586 98.
Checksum: 06000123458698:97 = 618,557,973,801 remainder = 1.
func checkdigits (s string) string {expanded, _: = Iso13616expand (strings. Join ([]string{s, "XE00"}, "") num, _: = new (big. INT). SetString (expanded)//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 = ten, B = 11, ... Z = 35func Iso13616expand (s string) (string, error) {var parts []string if!validbase36 (s) {return ' ", Erri Capencoding} for _, c: = range S {i: = UInt64 (c) If I >= 65 {//character A-Z corresponds to 10 binary in ASCII code table respectively The value is 65,66 ... The character-A-Z 36 binary string index is a=10,b=11 ... The Code table value of the character-the index value of the character =55//character code table value -55= The index value of the character parts = append (Parts, StrConv. Formatuint (UInt64 (c) -55, ten))} else {parts = append (parts, string (c))}} return join (par TS ...), nil}
Implementation: ICAP format converted to Ethereum address
Check
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}
Transformation
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}
Use
Imtoken wallet QR code uses the ICAP format, and the format after the sweep code appears:
iban:XE86G29C8IV34UOJMYWHGDSGME33YKEC3QO?account=100&type=ETH
This is the address of the transfer, the amount of the transfer, the type of transfer, which represents the transfer to XE86G29C8IV34UOJMYWHGDSGME33YKEC3QO
account
type
eth.
box will be compatible with the Imtoken format.
The complete code snippet can be found here: Https://gist.github.com/alpha ...
Reference
1.) Wikipedia:international Bank account number
2.) Icap:inter Exchange Client Address Protocol
3.) Open Source:box a business wallet solution