You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
3.8 KiB
157 lines
3.8 KiB
/*
|
|
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
|
|
throw InterfaceNotSupported("ICAP::lookup(), XET asset");
|
|
}
|
|
else if (m_asset == "ETH")
|
|
{
|
|
// TODO
|
|
// return resolve(m_institution + "/" + m_client).primary();
|
|
throw InterfaceNotSupported("ICAP::lookup(), ETH asset");
|
|
}
|
|
else
|
|
throw InterfaceNotSupported("ICAP::lookup(), non XET asset");
|
|
}
|
|
|
|
}
|
|
}
|
|
|