6 changed files with 265 additions and 75 deletions
@ -0,0 +1,159 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/** @file ICAP.cpp
|
||||
|
* @author Gav Wood <i@gavwood.com> |
||||
|
* @date 2014 |
||||
|
*/ |
||||
|
|
||||
|
#include "ICAP.h" |
||||
|
#include <boost/algorithm/string/case_conv.hpp> |
||||
|
#include <libdevcore/Base64.h> |
||||
|
#include <libdevcrypto/SHA3.h> |
||||
|
#include "Exceptions.h" |
||||
|
using namespace std; |
||||
|
using namespace dev; |
||||
|
using namespace dev::eth; |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace eth |
||||
|
{ |
||||
|
|
||||
|
string ICAP::iban(std::string _c, std::string _d) |
||||
|
{ |
||||
|
boost::to_upper(_c); |
||||
|
boost::to_upper(_d); |
||||
|
auto totStr = _d + _c + "00"; |
||||
|
bigint tot = 0; |
||||
|
for (char x: totStr) |
||||
|
if (x >= 'A') |
||||
|
tot = tot * 100 + x - 'A' + 10; |
||||
|
else |
||||
|
tot = tot * 10 + x - '0'; |
||||
|
unsigned check = (unsigned)(u256)(98 - tot % 97); |
||||
|
ostringstream out; |
||||
|
out << _c << setfill('0') << setw(2) << check << _d; |
||||
|
return out.str(); |
||||
|
} |
||||
|
|
||||
|
std::pair<string, string> ICAP::fromIBAN(std::string _iban) |
||||
|
{ |
||||
|
if (_iban.size() < 4) |
||||
|
return std::make_pair(string(), string()); |
||||
|
boost::to_upper(_iban); |
||||
|
std::string c = _iban.substr(0, 2); |
||||
|
std::string d = _iban.substr(4); |
||||
|
if (iban(c, d) != _iban) |
||||
|
return std::make_pair(string(), string()); |
||||
|
return make_pair(c, d); |
||||
|
} |
||||
|
|
||||
|
ICAP ICAP::decoded(std::string const& _encoded) |
||||
|
{ |
||||
|
ICAP ret; |
||||
|
std::string country; |
||||
|
std::string data; |
||||
|
std::tie(country, data) = fromIBAN(_encoded); |
||||
|
if (country != "XE") |
||||
|
throw InvalidICAP(); |
||||
|
if (data.size() == 30) |
||||
|
{ |
||||
|
ret.m_type = Direct; |
||||
|
// Direct ICAP
|
||||
|
ret.m_direct = fromBase36<Address::size>(data); |
||||
|
} |
||||
|
else if (data.size() == 16) |
||||
|
{ |
||||
|
ret.m_type = Indirect; |
||||
|
ret.m_asset = data.substr(0, 3); |
||||
|
if (ret.m_asset == "XET") |
||||
|
{ |
||||
|
ret.m_institution = data.substr(3, 4); |
||||
|
ret.m_client = data.substr(7); |
||||
|
} |
||||
|
else if (ret.m_asset == "ETH") |
||||
|
ret.m_client = data.substr(4); |
||||
|
else |
||||
|
throw InvalidICAP(); |
||||
|
} |
||||
|
else |
||||
|
throw InvalidICAP(); |
||||
|
|
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
std::string ICAP::encoded() const |
||||
|
{ |
||||
|
if (m_type == Direct) |
||||
|
{ |
||||
|
if (!!m_direct[0]) |
||||
|
return string(); |
||||
|
std::string d = toBase36<Address::size>(m_direct); |
||||
|
while (d.size() < 30) |
||||
|
d = "0" + d; |
||||
|
return iban("XE", d); |
||||
|
} |
||||
|
else if (m_type == Indirect) |
||||
|
{ |
||||
|
if ( |
||||
|
m_asset.find_first_not_of("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890") != string::npos || |
||||
|
m_institution.find_first_not_of("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890") != string::npos || |
||||
|
m_client.find_first_not_of("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890") != string::npos || |
||||
|
m_asset.size() != 3 |
||||
|
) |
||||
|
throw InvalidICAP(); |
||||
|
if (boost::to_upper_copy(m_asset) == "XET") |
||||
|
{ |
||||
|
if (m_institution.size() != 4 || m_client.size() != 9) |
||||
|
throw InvalidICAP(); |
||||
|
} |
||||
|
else if (boost::to_upper_copy(m_asset) == "ETH") |
||||
|
{ |
||||
|
if (m_client.size() != 13) |
||||
|
throw InvalidICAP(); |
||||
|
} |
||||
|
else |
||||
|
throw InvalidICAP(); |
||||
|
return iban("XE", m_asset + m_institution + m_client); |
||||
|
} |
||||
|
else |
||||
|
throw InvalidICAP(); |
||||
|
} |
||||
|
|
||||
|
Address ICAP::lookup(std::function<bytes(Address, bytes)> const& _call, Address const& _reg) const |
||||
|
{ |
||||
|
(void)_call; |
||||
|
(void)_reg; |
||||
|
if (m_asset == "XET") |
||||
|
{ |
||||
|
// TODO
|
||||
|
// _call(_reg, );
|
||||
|
return Address(); |
||||
|
} |
||||
|
else if (m_asset == "ETH") |
||||
|
{ |
||||
|
// TODO
|
||||
|
|
||||
|
// return resolve(m_institution + "/" + m_client).primary();
|
||||
|
return Address(); |
||||
|
} |
||||
|
else |
||||
|
throw InterfaceNotSupported("ICAP::lookup(), non XET asset"); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,77 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/** @file ICAP.h
|
||||
|
* @author Gav Wood <i@gavwood.com> |
||||
|
* @date 2014 |
||||
|
* |
||||
|
* Ethereum-specific data structures & algorithms. |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <string> |
||||
|
#include <functional> |
||||
|
#include <libdevcore/Common.h> |
||||
|
#include <libdevcore/Exceptions.h> |
||||
|
#include <libdevcore/FixedHash.h> |
||||
|
#include "Common.h" |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace eth |
||||
|
{ |
||||
|
|
||||
|
struct InvalidICAP: virtual public dev::Exception {}; |
||||
|
|
||||
|
class ICAP |
||||
|
{ |
||||
|
public: |
||||
|
ICAP() = default; |
||||
|
ICAP(Address const& _a): m_direct(_a) {} |
||||
|
ICAP(std::string const& _target): m_client(_target), m_asset("ETH") {} |
||||
|
ICAP(std::string const& _client, std::string const& _inst): m_client(_client), m_institution(_inst), m_asset("XET") {} |
||||
|
ICAP(std::string const& _c, std::string const& _i, std::string const& _a): m_client(_c), m_institution(_i), m_asset(_a) {} |
||||
|
|
||||
|
enum Type |
||||
|
{ |
||||
|
Invalid, |
||||
|
Direct, |
||||
|
Indirect |
||||
|
}; |
||||
|
|
||||
|
static std::string iban(std::string _c, std::string _d); |
||||
|
static std::pair<std::string, std::string> fromIBAN(std::string _iban); |
||||
|
|
||||
|
static ICAP decoded(std::string const& _encoded); |
||||
|
std::string encoded() const; |
||||
|
Type type() const { return m_type; } |
||||
|
|
||||
|
Address const& direct() const { return m_direct; } |
||||
|
Address lookup(std::function<bytes(Address, bytes)> const& _call, Address const& _reg) const; |
||||
|
Address address(std::function<bytes(Address, bytes)> const& _call, Address const& _reg) const { return m_type == Direct ? direct() : lookup(_call, _reg); } |
||||
|
|
||||
|
private: |
||||
|
Type m_type = Invalid; |
||||
|
Address m_direct; |
||||
|
std::string m_client; |
||||
|
std::string m_institution; |
||||
|
std::string m_asset; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
} |
||||
|
} |
Loading…
Reference in new issue