Browse Source

ICAP class for everything ICAP.

cl-refactor
Gav Wood 10 years ago
parent
commit
231dc01bc0
  1. 76
      alethzero/MainWin.cpp
  2. 21
      libdevcore/Base64.h
  3. 5
      libethcore/Common.cpp
  4. 2
      libethcore/Common.h
  5. 159
      libethcore/ICAP.cpp
  6. 77
      libethcore/ICAP.h

76
alethzero/MainWin.cpp

@ -46,6 +46,7 @@
#include <libdevcrypto/FileSystem.h>
#include <libethcore/CommonJS.h>
#include <libethcore/EthashAux.h>
#include <libethcore/ICAP.h>
#include <liblll/Compiler.h>
#include <liblll/CodeFragment.h>
#include <libsolidity/Scanner.h>
@ -520,82 +521,11 @@ QString Main::pretty(dev::Address _a) const
return fromRaw(n);
}
template <size_t N> inline string toBase36(FixedHash<N> const& _h)
{
static char const* c_alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
typename FixedHash<N>::Arith a = _h;
std::string ret;
for (; a > 0; a /= 36)
ret = c_alphabet[(unsigned)a % 36] + ret;
return ret;
}
template <size_t N> inline FixedHash<N> fromBase36(string const& _h)
{
typename FixedHash<N>::Arith ret = 0;
for (char c: _h)
ret = ret * 36 + (c < 'A' ? c - '0' : (c - 'A' + 10));
return ret;
}
static string 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();
}
static std::pair<string, string> 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);
}
static string directICAP(dev::Address _a)
{
if (!!_a[0])
return string();
std::string d = toBase36<Address::size>(_a);
while (d.size() < 30)
d = "0" + d;
return iban("XE", d);
}
static Address fromICAP(std::string const& _s)
{
std::string country;
std::string data;
std::tie(country, data) = fromIban(_s);
if (country.empty())
return Address();
if (country == "XE" && data.size() == 30)
// Direct ICAP
return fromBase36<Address::size>(data);
// TODO: Indirect ICAP
return Address();
}
QString Main::render(dev::Address _a) const
{
QString p = pretty(_a);
if (!_a[0])
p += QString(p.isEmpty() ? "" : " ") + QString::fromStdString(directICAP(_a));
p += QString(p.isEmpty() ? "" : " ") + QString::fromStdString(ICAP(_a).encoded());
if (!p.isEmpty())
return p + " (" + QString::fromStdString(_a.abridged()) + ")";
return QString::fromStdString(_a.abridged());
@ -639,7 +569,7 @@ Address Main::fromString(QString const& _n) const
return Address();
}
}
else if (Address a = fromICAP(_n.toStdString()))
else if (Address a = ICAP::decoded(_n.toStdString()).direct())
return a;
else
return Address();

21
libdevcore/Base64.h

@ -30,7 +30,8 @@
#include <vector>
#include <string>
#include <libdevcore/Common.h>
#include "Common.h"
#include "FixedHash.h"
namespace dev
{
@ -38,4 +39,22 @@ namespace dev
std::string toBase64(bytesConstRef _in);
bytes fromBase64(std::string const& _in);
template <size_t N> inline std::string toBase36(FixedHash<N> const& _h)
{
static char const* c_alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
typename FixedHash<N>::Arith a = _h;
std::string ret;
for (; a > 0; a /= 36)
ret = c_alphabet[(unsigned)a % 36] + ret;
return ret;
}
template <size_t N> inline FixedHash<N> fromBase36(std::string const& _h)
{
typename FixedHash<N>::Arith ret = 0;
for (char c: _h)
ret = ret * 36 + (c < 'A' ? c - '0' : (c - 'A' + 10));
return ret;
}
}

5
libethcore/Common.cpp

@ -21,6 +21,8 @@
#include "Common.h"
#include <random>
#include <boost/algorithm/string/case_conv.hpp>
#include <libdevcore/Base64.h>
#include <libdevcrypto/SHA3.h>
#include "Exceptions.h"
#include "ProofOfWork.h"
@ -100,4 +102,5 @@ std::string formatBalance(bigint const& _b)
return ret.str();
}
}}
}
}

2
libethcore/Common.h

@ -23,6 +23,8 @@
#pragma once
#include <string>
#include <functional>
#include <libdevcore/Common.h>
#include <libdevcore/FixedHash.h>
#include <libdevcrypto/Common.h>

159
libethcore/ICAP.cpp

@ -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");
}
}
}

77
libethcore/ICAP.h

@ -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…
Cancel
Save