aboutsummaryrefslogtreecommitdiffstats
path: root/libdevcore
diff options
context:
space:
mode:
Diffstat (limited to 'libdevcore')
-rw-r--r--libdevcore/ABI.h100
-rw-r--r--libdevcore/Assertions.h111
-rw-r--r--libdevcore/Base64.cpp146
-rw-r--r--libdevcore/Base64.h42
-rw-r--r--libdevcore/CMakeLists.txt16
-rw-r--r--libdevcore/Common.cpp27
-rw-r--r--libdevcore/Common.h210
-rw-r--r--libdevcore/CommonData.cpp107
-rw-r--r--libdevcore/CommonData.h182
-rw-r--r--libdevcore/CommonIO.cpp90
-rw-r--r--libdevcore/CommonIO.h54
-rw-r--r--libdevcore/Exceptions.h87
-rw-r--r--libdevcore/FixedHash.cpp50
-rw-r--r--libdevcore/FixedHash.h306
-rw-r--r--libdevcore/Hash.cpp440
-rw-r--r--libdevcore/Hash.h38
-rw-r--r--libdevcore/SHA3.cpp223
-rw-r--r--libdevcore/SHA3.h59
-rw-r--r--libdevcore/UndefMacros.h46
-rw-r--r--libdevcore/debugbreak.h125
-rw-r--r--libdevcore/picosha2.h360
-rw-r--r--libdevcore/vector_ref.h120
22 files changed, 2939 insertions, 0 deletions
diff --git a/libdevcore/ABI.h b/libdevcore/ABI.h
new file mode 100644
index 00000000..5b7d160d
--- /dev/null
+++ b/libdevcore/ABI.h
@@ -0,0 +1,100 @@
+/*
+ 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 ABI.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#pragma once
+
+#include <libdevcore/Common.h>
+#include <libdevcore/FixedHash.h>
+#include <libdevcore/CommonData.h>
+#include <libdevcore/SHA3.h>
+
+namespace dev
+{
+namespace eth
+{
+
+inline string32 toString32(std::string const& _s)
+{
+ string32 ret;
+ for (unsigned i = 0; i < 32; ++i)
+ ret[i] = i < _s.size() ? _s[i] : 0;
+ return ret;
+}
+
+template <class T> struct ABISerialiser {};
+template <unsigned N> struct ABISerialiser<FixedHash<N>> { static bytes serialise(FixedHash<N> const& _t) { static_assert(N <= 32, "Cannot serialise hash > 32 bytes."); static_assert(N > 0, "Cannot serialise zero-length hash."); return bytes(32 - N, 0) + _t.asBytes(); } };
+template <> struct ABISerialiser<u256> { static bytes serialise(u256 const& _t) { return h256(_t).asBytes(); } };
+template <> struct ABISerialiser<u160> { static bytes serialise(u160 const& _t) { return bytes(12, 0) + h160(_t).asBytes(); } };
+template <> struct ABISerialiser<string32> { static bytes serialise(string32 const& _t) { bytes ret; bytesConstRef((byte const*)_t.data(), 32).populate(bytesRef(&ret)); return ret; } };
+template <> struct ABISerialiser<std::string>
+{
+ static bytes serialise(std::string const& _t)
+ {
+ bytes ret = h256(u256(32)).asBytes() + h256(u256(_t.size())).asBytes();
+ ret.resize(ret.size() + (_t.size() + 31) / 32 * 32);
+ bytesConstRef(&_t).populate(bytesRef(&ret).cropped(64));
+ return ret;
+ }
+};
+
+inline bytes abiInAux() { return {}; }
+template <class T, class ... U> bytes abiInAux(T const& _t, U const& ... _u)
+{
+ return ABISerialiser<T>::serialise(_t) + abiInAux(_u ...);
+}
+
+template <class ... T> bytes abiIn(std::string _id, T const& ... _t)
+{
+ return sha3(_id).ref().cropped(0, 4).toBytes() + abiInAux(_t ...);
+}
+
+template <class T> struct ABIDeserialiser {};
+template <unsigned N> struct ABIDeserialiser<FixedHash<N>> { static FixedHash<N> deserialise(bytesConstRef& io_t) { static_assert(N <= 32, "Parameter sizes must be at most 32 bytes."); FixedHash<N> ret; io_t.cropped(32 - N, N).populate(ret.ref()); io_t = io_t.cropped(32); return ret; } };
+template <> struct ABIDeserialiser<u256> { static u256 deserialise(bytesConstRef& io_t) { u256 ret = fromBigEndian<u256>(io_t.cropped(0, 32)); io_t = io_t.cropped(32); return ret; } };
+template <> struct ABIDeserialiser<u160> { static u160 deserialise(bytesConstRef& io_t) { u160 ret = fromBigEndian<u160>(io_t.cropped(12, 20)); io_t = io_t.cropped(32); return ret; } };
+template <> struct ABIDeserialiser<string32> { static string32 deserialise(bytesConstRef& io_t) { string32 ret; io_t.cropped(0, 32).populate(bytesRef((byte*)ret.data(), 32)); io_t = io_t.cropped(32); return ret; } };
+template <> struct ABIDeserialiser<std::string>
+{
+ static std::string deserialise(bytesConstRef& io_t)
+ {
+ unsigned o = (uint16_t)u256(h256(io_t.cropped(0, 32)));
+ unsigned s = (uint16_t)u256(h256(io_t.cropped(o, 32)));
+ std::string ret;
+ ret.resize(s);
+ io_t.cropped(o + 32, s).populate(bytesRef((byte*)ret.data(), s));
+ io_t = io_t.cropped(32);
+ return ret;
+ }
+};
+
+template <class T> T abiOut(bytes const& _data)
+{
+ bytesConstRef o(&_data);
+ return ABIDeserialiser<T>::deserialise(o);
+}
+
+template <class T> T abiOut(bytesConstRef& _data)
+{
+ return ABIDeserialiser<T>::deserialise(_data);
+}
+
+}
+}
diff --git a/libdevcore/Assertions.h b/libdevcore/Assertions.h
new file mode 100644
index 00000000..7b4a4a76
--- /dev/null
+++ b/libdevcore/Assertions.h
@@ -0,0 +1,111 @@
+/*
+ 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 Assertions.h
+ * @author Christian <c@ethdev.com>
+ * @date 2015
+ *
+ * Assertion handling.
+ */
+
+#pragma once
+
+#include "Exceptions.h"
+#include "debugbreak.h"
+
+namespace dev
+{
+
+#if defined(_MSC_VER)
+#define ETH_FUNC __FUNCSIG__
+#elif defined(__GNUC__)
+#define ETH_FUNC __PRETTY_FUNCTION__
+#else
+#define ETH_FUNC __func__
+#endif
+
+#define asserts(A) ::dev::assertAux(A, #A, __LINE__, __FILE__, ETH_FUNC)
+#define assertsEqual(A, B) ::dev::assertEqualAux(A, B, #A, #B, __LINE__, __FILE__, ETH_FUNC)
+
+inline bool assertAux(bool _a, char const* _aStr, unsigned _line, char const* _file, char const* _func)
+{
+ bool ret = _a;
+ if (!ret)
+ {
+ std::cerr << "Assertion failed:" << _aStr << " [func=" << _func << ", line=" << _line << ", file=" << _file << "]" << std::endl;
+#if ETH_DEBUG
+ debug_break();
+#endif
+ }
+ return !ret;
+}
+
+template<class A, class B>
+inline bool assertEqualAux(A const& _a, B const& _b, char const* _aStr, char const* _bStr, unsigned _line, char const* _file, char const* _func)
+{
+ bool ret = _a == _b;
+ if (!ret)
+ {
+ std::cerr << "Assertion failed: " << _aStr << " == " << _bStr << " [func=" << _func << ", line=" << _line << ", file=" << _file << "]" << std::endl;
+ std::cerr << " Fail equality: " << _a << "==" << _b << std::endl;
+#if ETH_DEBUG
+ debug_break();
+#endif
+ }
+ return !ret;
+}
+
+/// Assertion that throws an exception containing the given description if it is not met.
+/// Use it as assertThrow(1 == 1, ExceptionType, "Mathematics is wrong.");
+/// Do NOT supply an exception object as the second parameter.
+#define assertThrow(_condition, _ExceptionType, _description) \
+ ::dev::assertThrowAux<_ExceptionType>(_condition, _description, __LINE__, __FILE__, ETH_FUNC)
+
+using errinfo_comment = boost::error_info<struct tag_comment, std::string>;
+
+template <class _ExceptionType>
+inline void assertThrowAux(
+ bool _condition,
+ ::std::string const& _errorDescription,
+ unsigned _line,
+ char const* _file,
+ char const* _function
+)
+{
+ if (!_condition)
+ ::boost::throw_exception(
+ _ExceptionType() <<
+ ::dev::errinfo_comment(_errorDescription) <<
+ ::boost::throw_function(_function) <<
+ ::boost::throw_file(_file) <<
+ ::boost::throw_line(_line)
+ );
+}
+
+template <class _ExceptionType>
+inline void assertThrowAux(
+ void const* _pointer,
+ ::std::string const& _errorDescription,
+ unsigned _line,
+ char const* _file,
+ char const* _function
+)
+{
+ assertThrowAux<_ExceptionType>(_pointer != nullptr, _errorDescription, _line, _file, _function);
+}
+
+}
diff --git a/libdevcore/Base64.cpp b/libdevcore/Base64.cpp
new file mode 100644
index 00000000..8ee2b29f
--- /dev/null
+++ b/libdevcore/Base64.cpp
@@ -0,0 +1,146 @@
+/*
+ base64.cpp and base64.h
+
+ Copyright (C) 2004-2008 René Nyffenegger
+
+ This source code is provided 'as-is', without any express or implied
+ warranty. In no event will the author be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this source code must not be misrepresented; you must not
+ claim that you wrote the original source code. If you use this source code
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original source code.
+
+ 3. This notice may not be removed or altered from any source distribution.
+
+ René Nyffenegger rene.nyffenegger@adp-gmbh.ch
+*/
+/// Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c
+/// Originally by René Nyffenegger, modified by some other guy and then devified by Gav Wood.
+
+#include "Base64.h"
+
+using namespace std;
+using namespace dev;
+
+static inline bool is_base64(byte c)
+{
+ return (isalnum(c) || (c == '+') || (c == '/'));
+}
+
+static inline byte find_base64_char_index(byte c)
+{
+ if ('A' <= c && c <= 'Z') return c - 'A';
+ else if ('a' <= c && c <= 'z') return c - 'a' + 1 + find_base64_char_index('Z');
+ else if ('0' <= c && c <= '9') return c - '0' + 1 + find_base64_char_index('z');
+ else if (c == '+') return 1 + find_base64_char_index('9');
+ else if (c == '/') return 1 + find_base64_char_index('+');
+ else return 1 + find_base64_char_index('/');
+}
+
+string dev::toBase64(bytesConstRef _in)
+{
+ static const char base64_chars[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+
+ string ret;
+ int i = 0;
+ int j = 0;
+ byte char_array_3[3];
+ byte char_array_4[4];
+
+ auto buf = _in.data();
+ auto bufLen = _in.size();
+
+ while (bufLen--)
+ {
+ char_array_3[i++] = *(buf++);
+ if (i == 3)
+ {
+ char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
+ char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
+ char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
+ char_array_4[3] = char_array_3[2] & 0x3f;
+
+ for (i = 0; i < 4; i++)
+ ret += base64_chars[char_array_4[i]];
+ i = 0;
+ }
+ }
+
+ if (i)
+ {
+ for (j = i; j < 3; j++)
+ char_array_3[j] = '\0';
+
+ char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
+ char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
+ char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
+ char_array_4[3] = char_array_3[2] & 0x3f;
+
+ for (j = 0; j < i + 1; j++)
+ ret += base64_chars[char_array_4[j]];
+
+ while (i++ < 3)
+ ret += '=';
+ }
+
+ return ret;
+}
+
+bytes dev::fromBase64(string const& encoded_string)
+{
+ auto in_len = encoded_string.size();
+ int i = 0;
+ int j = 0;
+ int in_ = 0;
+ byte char_array_3[3];
+ byte char_array_4[4];
+ bytes ret;
+
+ while (in_len-- && encoded_string[in_] != '=' && is_base64(encoded_string[in_]))
+ {
+ char_array_4[i++] = encoded_string[in_]; in_++;
+ if (i == 4)
+ {
+ for (i = 0; i < 4; i++)
+ char_array_4[i] = find_base64_char_index(char_array_4[i]);
+
+ char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
+ char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
+ char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+
+ for (i = 0; (i < 3); i++)
+ ret.push_back(char_array_3[i]);
+ i = 0;
+ }
+ }
+
+ if (i)
+ {
+ for (j = i; j < 4; j++)
+ char_array_4[j] = 0;
+
+ for (j = 0; j < 4; j++)
+ char_array_4[j] = find_base64_char_index(char_array_4[j]);
+
+ char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
+ char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
+ char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+
+ for (j = 0; j < i - 1; j++)
+ ret.push_back(char_array_3[j]);
+ }
+
+ return ret;
+}
diff --git a/libdevcore/Base64.h b/libdevcore/Base64.h
new file mode 100644
index 00000000..d5481570
--- /dev/null
+++ b/libdevcore/Base64.h
@@ -0,0 +1,42 @@
+/*
+ base64.cpp and base64.h
+
+ Copyright (C) 2004-2008 René Nyffenegger
+
+ This source code is provided 'as-is', without any express or implied
+ warranty. In no event will the author be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this source code must not be misrepresented; you must not
+ claim that you wrote the original source code. If you use this source code
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original source code.
+
+ 3. This notice may not be removed or altered from any source distribution.
+
+ René Nyffenegger rene.nyffenegger@adp-gmbh.ch
+*/
+/// Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c
+/// Originally by René Nyffenegger.
+/// DEVified by Gav Wood.
+#pragma once
+
+#include <string>
+#include "Common.h"
+#include "FixedHash.h"
+
+namespace dev
+{
+
+std::string toBase64(bytesConstRef _in);
+bytes fromBase64(std::string const& _in);
+
+
+}
diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt
new file mode 100644
index 00000000..43dd71c3
--- /dev/null
+++ b/libdevcore/CMakeLists.txt
@@ -0,0 +1,16 @@
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
+
+aux_source_directory(. SRC_LIST)
+
+set(EXECUTABLE devcore)
+
+file(GLOB HEADERS "*.h")
+
+include_directories(..)
+add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
+
+eth_use(${EXECUTABLE} REQUIRED Jsoncpp Dev::base)
+
+install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
+install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )
+
diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp
new file mode 100644
index 00000000..579e0f62
--- /dev/null
+++ b/libdevcore/Common.cpp
@@ -0,0 +1,27 @@
+/*
+ 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 Common.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "Common.h"
+
+namespace dev
+{
+const u256 Invalid256 = ~(u256)0;
+}
diff --git a/libdevcore/Common.h b/libdevcore/Common.h
new file mode 100644
index 00000000..7d301833
--- /dev/null
+++ b/libdevcore/Common.h
@@ -0,0 +1,210 @@
+/*
+ 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 Common.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ *
+ * Very common stuff (i.e. that every other header needs except vector_ref.h).
+ */
+
+#pragma once
+
+// way to many unsigned to size_t warnings in 32 bit build
+#ifdef _M_IX86
+#pragma warning(disable:4244)
+#endif
+
+#if _MSC_VER && _MSC_VER < 1900
+#define _ALLOW_KEYWORD_MACROS
+#define noexcept throw()
+#endif
+
+#ifdef __INTEL_COMPILER
+#pragma warning(disable:3682) //call through incomplete class
+#endif
+
+#include <map>
+#include <unordered_map>
+#include <vector>
+#include <set>
+#include <unordered_set>
+#include <functional>
+#include <string>
+#include <chrono>
+
+#if defined(__GNUC__)
+#pragma warning(push)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif // defined(__GNUC__)
+
+// See https://github.com/ethereum/libweb3core/commit/90680a8c25bfb48b24371b4abcacde56c181517c
+// See https://svn.boost.org/trac/boost/ticket/11328
+// Bob comment - perhaps we should just HARD FAIL here with Boost-1.58.00?
+// It is quite old now, and requiring end-users to use a newer Boost release is probably not unreasonable.
+#include <boost/version.hpp>
+#if (BOOST_VERSION == 105800)
+ #include "boost_multiprecision_number_compare_bug_workaround.hpp"
+#endif // (BOOST_VERSION == 105800)
+
+#include <boost/multiprecision/cpp_int.hpp>
+
+#if defined(__GNUC__)
+#pragma warning(pop)
+#pragma GCC diagnostic pop
+#endif // defined(__GNUC__)
+
+#include "vector_ref.h"
+
+// CryptoPP defines byte in the global namespace, so must we.
+using byte = uint8_t;
+
+// Quote a given token stream to turn it into a string.
+#define DEV_QUOTED_HELPER(s) #s
+#define DEV_QUOTED(s) DEV_QUOTED_HELPER(s)
+
+#define DEV_IGNORE_EXCEPTIONS(X) try { X; } catch (...) {}
+
+namespace dev
+{
+
+// Binary data types.
+using bytes = std::vector<byte>;
+using bytesRef = vector_ref<byte>;
+using bytesConstRef = vector_ref<byte const>;
+
+template <class T>
+class secure_vector
+{
+public:
+ secure_vector() {}
+ secure_vector(secure_vector<T> const& /*_c*/) = default; // See https://github.com/ethereum/libweb3core/pull/44
+ explicit secure_vector(unsigned _size): m_data(_size) {}
+ explicit secure_vector(unsigned _size, T _item): m_data(_size, _item) {}
+ explicit secure_vector(std::vector<T> const& _c): m_data(_c) {}
+ explicit secure_vector(vector_ref<T> _c): m_data(_c.data(), _c.data() + _c.size()) {}
+ explicit secure_vector(vector_ref<const T> _c): m_data(_c.data(), _c.data() + _c.size()) {}
+ ~secure_vector() { ref().cleanse(); }
+
+ secure_vector<T>& operator=(secure_vector<T> const& _c)
+ {
+ if (&_c == this)
+ return *this;
+
+ ref().cleanse();
+ m_data = _c.m_data;
+ return *this;
+ }
+ std::vector<T>& writable() { clear(); return m_data; }
+ std::vector<T> const& makeInsecure() const { return m_data; }
+
+ void clear() { ref().cleanse(); }
+
+ vector_ref<T> ref() { return vector_ref<T>(&m_data); }
+ vector_ref<T const> ref() const { return vector_ref<T const>(&m_data); }
+
+ size_t size() const { return m_data.size(); }
+ bool empty() const { return m_data.empty(); }
+
+ void swap(secure_vector<T>& io_other) { m_data.swap(io_other.m_data); }
+
+private:
+ std::vector<T> m_data;
+};
+
+using bytesSec = secure_vector<byte>;
+
+// Numeric types.
+using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>;
+using u64 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<64, 64, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
+using u128 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<128, 128, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
+using u256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
+using s256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;
+using u160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
+using s160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;
+using u512 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 512, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
+using s512 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 512, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;
+using u256s = std::vector<u256>;
+using u160s = std::vector<u160>;
+using u256Set = std::set<u256>;
+using u160Set = std::set<u160>;
+
+// Map types.
+using StringMap = std::map<std::string, std::string>;
+
+// Hash types.
+using StringHashMap = std::unordered_map<std::string, std::string>;
+
+// String types.
+using strings = std::vector<std::string>;
+// Fixed-length string types.
+using string32 = std::array<char, 32>;
+
+// Null/Invalid values for convenience.
+static const bytes NullBytes;
+extern const u256 Invalid256;
+
+/// Interprets @a _u as a two's complement signed number and returns the resulting s256.
+inline s256 u2s(u256 _u)
+{
+ static const bigint c_end = bigint(1) << 256;
+ if (boost::multiprecision::bit_test(_u, 255))
+ return s256(-(c_end - _u));
+ else
+ return s256(_u);
+}
+
+/// @returns the two's complement signed representation of the signed number _u.
+inline u256 s2u(s256 _u)
+{
+ static const bigint c_end = bigint(1) << 256;
+ if (_u >= 0)
+ return u256(_u);
+ else
+ return u256(c_end + _u);
+}
+
+template <size_t n> inline u256 exp10()
+{
+ return exp10<n - 1>() * u256(10);
+}
+
+template <> inline u256 exp10<0>()
+{
+ return u256(1);
+}
+
+/// RAII utility class whose destructor calls a given function.
+class ScopeGuard
+{
+public:
+ ScopeGuard(std::function<void(void)> _f): m_f(_f) {}
+ ~ScopeGuard() { m_f(); }
+
+private:
+ std::function<void(void)> m_f;
+};
+
+enum class WithExisting: int
+{
+ Trust = 0,
+ Verify,
+ Rescue,
+ Kill
+};
+
+}
diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp
new file mode 100644
index 00000000..fc438276
--- /dev/null
+++ b/libdevcore/CommonData.cpp
@@ -0,0 +1,107 @@
+/*
+ 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 CommonData.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "CommonData.h"
+#include <random>
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4724) // potential mod by 0, line 78 of boost/random/uniform_int_distribution.hpp (boost 1.55)
+#endif
+#include <boost/random/uniform_int_distribution.hpp>
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+#include "Exceptions.h"
+using namespace std;
+using namespace dev;
+
+std::string dev::escaped(std::string const& _s, bool _all)
+{
+ static const map<char, char> prettyEscapes{{'\r', 'r'}, {'\n', 'n'}, {'\t', 't'}, {'\v', 'v'}};
+ std::string ret;
+ ret.reserve(_s.size() + 2);
+ ret.push_back('"');
+ for (auto i: _s)
+ if (i == '"' && !_all)
+ ret += "\\\"";
+ else if (i == '\\' && !_all)
+ ret += "\\\\";
+ else if (prettyEscapes.count(i) && !_all)
+ {
+ ret += '\\';
+ ret += prettyEscapes.find(i)->second;
+ }
+ else if (i < ' ' || _all)
+ {
+ ret += "\\x";
+ ret.push_back("0123456789abcdef"[(uint8_t)i / 16]);
+ ret.push_back("0123456789abcdef"[(uint8_t)i % 16]);
+ }
+ else
+ ret.push_back(i);
+ ret.push_back('"');
+ return ret;
+}
+
+int dev::fromHex(char _i, WhenError _throw)
+{
+ if (_i >= '0' && _i <= '9')
+ return _i - '0';
+ if (_i >= 'a' && _i <= 'f')
+ return _i - 'a' + 10;
+ if (_i >= 'A' && _i <= 'F')
+ return _i - 'A' + 10;
+ if (_throw == WhenError::Throw)
+ BOOST_THROW_EXCEPTION(BadHexCharacter() << errinfo_invalidSymbol(_i));
+ else
+ return -1;
+}
+
+bytes dev::fromHex(std::string const& _s, WhenError _throw)
+{
+ unsigned s = (_s.size() >= 2 && _s[0] == '0' && _s[1] == 'x') ? 2 : 0;
+ std::vector<uint8_t> ret;
+ ret.reserve((_s.size() - s + 1) / 2);
+
+ if (_s.size() % 2)
+ {
+ int h = fromHex(_s[s++], WhenError::DontThrow);
+ if (h != -1)
+ ret.push_back(h);
+ else if (_throw == WhenError::Throw)
+ BOOST_THROW_EXCEPTION(BadHexCharacter());
+ else
+ return bytes();
+ }
+ for (unsigned i = s; i < _s.size(); i += 2)
+ {
+ int h = fromHex(_s[i], WhenError::DontThrow);
+ int l = fromHex(_s[i + 1], WhenError::DontThrow);
+ if (h != -1 && l != -1)
+ ret.push_back((byte)(h * 16 + l));
+ else if (_throw == WhenError::Throw)
+ BOOST_THROW_EXCEPTION(BadHexCharacter());
+ else
+ return bytes();
+ }
+ return ret;
+}
diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h
new file mode 100644
index 00000000..5ffcdcca
--- /dev/null
+++ b/libdevcore/CommonData.h
@@ -0,0 +1,182 @@
+/*
+ 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 CommonData.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ *
+ * Shared algorithms and data types.
+ */
+
+#pragma once
+
+#include <vector>
+#include <algorithm>
+#include <unordered_set>
+#include <type_traits>
+#include <cstring>
+#include <string>
+#include "Common.h"
+
+namespace dev
+{
+
+// String conversion functions, mainly to/from hex/nibble/byte representations.
+
+enum class WhenError
+{
+ DontThrow = 0,
+ Throw = 1,
+};
+
+enum class HexPrefix
+{
+ DontAdd = 0,
+ Add = 1,
+};
+/// Convert a series of bytes to the corresponding string of hex duplets.
+/// @param _w specifies the width of the first of the elements. Defaults to two - enough to represent a byte.
+/// @example toHex("A\x69") == "4169"
+template <class T>
+std::string toHex(T const& _data, int _w = 2, HexPrefix _prefix = HexPrefix::DontAdd)
+{
+ std::ostringstream ret;
+ unsigned ii = 0;
+ for (auto i: _data)
+ ret << std::hex << std::setfill('0') << std::setw(ii++ ? 2 : _w) << (int)(typename std::make_unsigned<decltype(i)>::type)i;
+ return (_prefix == HexPrefix::Add) ? "0x" + ret.str() : ret.str();
+}
+
+/// Converts a (printable) ASCII hex character into the correspnding integer value.
+/// @example fromHex('A') == 10 && fromHex('f') == 15 && fromHex('5') == 5
+int fromHex(char _i, WhenError _throw);
+
+/// Converts a (printable) ASCII hex string into the corresponding byte stream.
+/// @example fromHex("41626261") == asBytes("Abba")
+/// If _throw = ThrowType::DontThrow, it replaces bad hex characters with 0's, otherwise it will throw an exception.
+bytes fromHex(std::string const& _s, WhenError _throw = WhenError::DontThrow);
+/// Converts byte array to a string containing the same (binary) data. Unless
+/// the byte array happens to contain ASCII data, this won't be printable.
+inline std::string asString(bytes const& _b)
+{
+ return std::string((char const*)_b.data(), (char const*)(_b.data() + _b.size()));
+}
+
+/// Converts byte array ref to a string containing the same (binary) data. Unless
+/// the byte array happens to contain ASCII data, this won't be printable.
+inline std::string asString(bytesConstRef _b)
+{
+ return std::string((char const*)_b.data(), (char const*)(_b.data() + _b.size()));
+}
+
+/// Converts a string to a byte array containing the string's (byte) data.
+inline bytes asBytes(std::string const& _b)
+{
+ return bytes((byte const*)_b.data(), (byte const*)(_b.data() + _b.size()));
+}
+
+// Big-endian to/from host endian conversion functions.
+
+/// Converts a templated integer value to the big-endian byte-stream represented on a templated collection.
+/// The size of the collection object will be unchanged. If it is too small, it will not represent the
+/// value properly, if too big then the additional elements will be zeroed out.
+/// @a Out will typically be either std::string or bytes.
+/// @a T will typically by unsigned, u160, u256 or bigint.
+template <class T, class Out>
+inline void toBigEndian(T _val, Out& o_out)
+{
+ static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift
+ for (auto i = o_out.size(); i != 0; _val >>= 8, i--)
+ {
+ T v = _val & (T)0xff;
+ o_out[i - 1] = (typename Out::value_type)(uint8_t)v;
+ }
+}
+
+/// Converts a big-endian byte-stream represented on a templated collection to a templated integer value.
+/// @a _In will typically be either std::string or bytes.
+/// @a T will typically by unsigned, u160, u256 or bigint.
+template <class T, class _In>
+inline T fromBigEndian(_In const& _bytes)
+{
+ T ret = (T)0;
+ for (auto i: _bytes)
+ ret = (T)((ret << 8) | (byte)(typename std::make_unsigned<typename _In::value_type>::type)i);
+ return ret;
+}
+inline bytes toBigEndian(u256 _val) { bytes ret(32); toBigEndian(_val, ret); return ret; }
+inline bytes toBigEndian(u160 _val) { bytes ret(20); toBigEndian(_val, ret); return ret; }
+
+/// Convenience function for toBigEndian.
+/// @returns a byte array just big enough to represent @a _val.
+template <class T>
+inline bytes toCompactBigEndian(T _val, unsigned _min = 0)
+{
+ static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift
+ int i = 0;
+ for (T v = _val; v; ++i, v >>= 8) {}
+ bytes ret(std::max<unsigned>(_min, i), 0);
+ toBigEndian(_val, ret);
+ return ret;
+}
+inline bytes toCompactBigEndian(byte _val, unsigned _min = 0)
+{
+ return (_min || _val) ? bytes{ _val } : bytes{};
+}
+
+/// Convenience function for conversion of a u256 to hex
+inline std::string toHex(u256 val, HexPrefix prefix = HexPrefix::DontAdd)
+{
+ std::string str = toHex(toBigEndian(val));
+ return (prefix == HexPrefix::Add) ? "0x" + str : str;
+}
+
+// Algorithms for string and string-like collections.
+
+/// Escapes a string into the C-string representation.
+/// @p _all if true will escape all characters, not just the unprintable ones.
+std::string escaped(std::string const& _s, bool _all = true);
+/// Determine bytes required to encode the given integer value. @returns 0 if @a _i is zero.
+template <class T>
+inline unsigned bytesRequired(T _i)
+{
+ static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift
+ unsigned i = 0;
+ for (; _i != 0; ++i, _i >>= 8) {}
+ return i;
+}
+/// Concatenate the contents of a container onto a vector
+template <class T, class U> std::vector<T>& operator+=(std::vector<T>& _a, U const& _b)
+{
+ for (auto const& i: _b)
+ _a.push_back(i);
+ return _a;
+}
+/// Concatenate two vectors of elements.
+template <class T>
+inline std::vector<T> operator+(std::vector<T> const& _a, std::vector<T> const& _b)
+{
+ std::vector<T> ret(_a);
+ return ret += _b;
+}
+
+template <class T, class V>
+bool contains(T const& _t, V const& _v)
+{
+ return std::end(_t) != std::find(std::begin(_t), std::end(_t), _v);
+}
+
+}
diff --git a/libdevcore/CommonIO.cpp b/libdevcore/CommonIO.cpp
new file mode 100644
index 00000000..60ac518d
--- /dev/null
+++ b/libdevcore/CommonIO.cpp
@@ -0,0 +1,90 @@
+/*
+ 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 CommonIO.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "CommonIO.h"
+#include <iostream>
+#include <cstdlib>
+#include <fstream>
+#include <stdio.h>
+#if defined(_WIN32)
+#include <windows.h>
+#else
+#include <termios.h>
+#endif
+#include <boost/filesystem.hpp>
+#include "Exceptions.h"
+using namespace std;
+using namespace dev;
+
+
+template <typename _T>
+inline _T contentsGeneric(std::string const& _file)
+{
+ _T ret;
+ size_t const c_elementSize = sizeof(typename _T::value_type);
+ std::ifstream is(_file, std::ifstream::binary);
+ if (!is)
+ return ret;
+
+ // get length of file:
+ is.seekg(0, is.end);
+ streamoff length = is.tellg();
+ if (length == 0)
+ return ret; // do not read empty file (MSVC does not like it)
+ is.seekg(0, is.beg);
+
+ ret.resize((length + c_elementSize - 1) / c_elementSize);
+ is.read(const_cast<char*>(reinterpret_cast<char const*>(ret.data())), length);
+ return ret;
+}
+
+string dev::contentsString(string const& _file)
+{
+ return contentsGeneric<string>(_file);
+}
+
+void dev::writeFile(std::string const& _file, bytesConstRef _data, bool _writeDeleteRename)
+{
+ namespace fs = boost::filesystem;
+ if (_writeDeleteRename)
+ {
+ fs::path tempPath = fs::unique_path(_file + "-%%%%%%");
+ writeFile(tempPath.string(), _data, false);
+ // will delete _file if it exists
+ fs::rename(tempPath, _file);
+ }
+ else
+ {
+ // create directory if not existent
+ fs::path p(_file);
+ if (!fs::exists(p.parent_path()))
+ {
+ fs::create_directories(p.parent_path());
+ DEV_IGNORE_EXCEPTIONS(fs::permissions(p.parent_path(), fs::owner_all));
+ }
+
+ ofstream s(_file, ios::trunc | ios::binary);
+ s.write(reinterpret_cast<char const*>(_data.data()), _data.size());
+ if (!s)
+ BOOST_THROW_EXCEPTION(FileError() << errinfo_comment("Could not write to file: " + _file));
+ DEV_IGNORE_EXCEPTIONS(fs::permissions(_file, fs::owner_read|fs::owner_write));
+ }
+}
diff --git a/libdevcore/CommonIO.h b/libdevcore/CommonIO.h
new file mode 100644
index 00000000..8238fe0f
--- /dev/null
+++ b/libdevcore/CommonIO.h
@@ -0,0 +1,54 @@
+/*
+ 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 CommonIO.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ *
+ * File & stream I/O routines.
+ */
+
+#pragma once
+
+#include <sstream>
+#include <string>
+#include "Common.h"
+
+namespace dev
+{
+
+/// Retrieve and returns the contents of the given file as a std::string.
+/// If the file doesn't exist or isn't readable, returns an empty container / bytes.
+std::string contentsString(std::string const& _file);
+
+/// Write the given binary data into the given file, replacing the file if it pre-exists.
+/// Throws exception on error.
+/// @param _writeDeleteRename useful not to lose any data: If set, first writes to another file in
+/// the same directory and then moves that file.
+void writeFile(std::string const& _file, bytesConstRef _data, bool _writeDeleteRename = false);
+/// Write the given binary data into the given file, replacing the file if it pre-exists.
+inline void writeFile(std::string const& _file, bytes const& _data, bool _writeDeleteRename = false) { writeFile(_file, bytesConstRef(&_data), _writeDeleteRename); }
+inline void writeFile(std::string const& _file, std::string const& _data, bool _writeDeleteRename = false) { writeFile(_file, bytesConstRef(_data), _writeDeleteRename); }
+/// Converts arbitrary value to string representation using std::stringstream.
+template <class _T>
+std::string toString(_T const& _t)
+{
+ std::ostringstream o;
+ o << _t;
+ return o.str();
+}
+
+}
diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h
new file mode 100644
index 00000000..a6c1f9ab
--- /dev/null
+++ b/libdevcore/Exceptions.h
@@ -0,0 +1,87 @@
+/*
+ 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 Exceptions.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#pragma once
+
+#include <exception>
+#include <string>
+#include <boost/exception/exception.hpp>
+#include <boost/exception/info.hpp>
+#include <boost/exception/info_tuple.hpp>
+#include <boost/exception/diagnostic_information.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/tuple/tuple.hpp>
+#include "CommonData.h"
+#include "FixedHash.h"
+
+namespace dev
+{
+
+/// Base class for all exceptions.
+struct Exception: virtual std::exception, virtual boost::exception
+{
+ Exception(std::string _message = std::string()): m_message(std::move(_message)) {}
+ const char* what() const noexcept override { return m_message.empty() ? std::exception::what() : m_message.c_str(); }
+
+private:
+ std::string m_message;
+};
+
+#define DEV_SIMPLE_EXCEPTION(X) struct X: virtual Exception { const char* what() const noexcept override { return #X; } }
+
+/// Base class for all RLP exceptions.
+struct RLPException: virtual Exception { RLPException(std::string _message = std::string()): Exception(_message) {} };
+#define DEV_SIMPLE_EXCEPTION_RLP(X) struct X: virtual RLPException { const char* what() const noexcept override { return #X; } }
+
+DEV_SIMPLE_EXCEPTION_RLP(BadCast);
+DEV_SIMPLE_EXCEPTION_RLP(BadRLP);
+DEV_SIMPLE_EXCEPTION_RLP(OversizeRLP);
+DEV_SIMPLE_EXCEPTION_RLP(UndersizeRLP);
+
+DEV_SIMPLE_EXCEPTION(BadHexCharacter);
+DEV_SIMPLE_EXCEPTION(NoNetworking);
+DEV_SIMPLE_EXCEPTION(NoUPnPDevice);
+DEV_SIMPLE_EXCEPTION(RootNotFound);
+struct BadRoot: virtual Exception { public: BadRoot(h256 const& _root): Exception("BadRoot " + _root.hex()), root(_root) {} h256 root; };
+DEV_SIMPLE_EXCEPTION(FileError);
+DEV_SIMPLE_EXCEPTION(Overflow);
+DEV_SIMPLE_EXCEPTION(FailedInvariant);
+DEV_SIMPLE_EXCEPTION(ValueTooLarge);
+
+struct InterfaceNotSupported: virtual Exception { public: InterfaceNotSupported(std::string _f): Exception("Interface " + _f + " not supported.") {} };
+struct ExternalFunctionFailure: virtual Exception { public: ExternalFunctionFailure(std::string _f): Exception("Function " + _f + "() failed.") {} };
+
+// error information to be added to exceptions
+using errinfo_invalidSymbol = boost::error_info<struct tag_invalidSymbol, char>;
+using errinfo_wrongAddress = boost::error_info<struct tag_address, std::string>;
+using errinfo_comment = boost::error_info<struct tag_comment, std::string>;
+using errinfo_required = boost::error_info<struct tag_required, bigint>;
+using errinfo_got = boost::error_info<struct tag_got, bigint>;
+using errinfo_min = boost::error_info<struct tag_min, bigint>;
+using errinfo_max = boost::error_info<struct tag_max, bigint>;
+using RequirementError = boost::tuple<errinfo_required, errinfo_got>;
+using errinfo_hash256 = boost::error_info<struct tag_hash, h256>;
+using errinfo_required_h256 = boost::error_info<struct tag_required_h256, h256>;
+using errinfo_got_h256 = boost::error_info<struct tag_get_h256, h256>;
+using Hash256RequirementError = boost::tuple<errinfo_required_h256, errinfo_got_h256>;
+using errinfo_extraData = boost::error_info<struct tag_extraData, bytes>;
+
+}
diff --git a/libdevcore/FixedHash.cpp b/libdevcore/FixedHash.cpp
new file mode 100644
index 00000000..420e2bb1
--- /dev/null
+++ b/libdevcore/FixedHash.cpp
@@ -0,0 +1,50 @@
+/*
+ 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 FixedHash.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "FixedHash.h"
+#include <ctime>
+#include <boost/algorithm/string.hpp>
+
+using namespace std;
+using namespace dev;
+
+boost::random_device dev::s_fixedHashEngine;
+
+h128 dev::fromUUID(std::string const& _uuid)
+{
+ try
+ {
+ return h128(boost::replace_all_copy(_uuid, "-", ""));
+ }
+ catch (...)
+ {
+ return h128();
+ }
+}
+
+std::string dev::toUUID(h128 const& _uuid)
+{
+ std::string ret = toHex(_uuid.ref());
+ for (unsigned i: {20, 16, 12, 8})
+ ret.insert(ret.begin() + i, '-');
+ return ret;
+}
+
diff --git a/libdevcore/FixedHash.h b/libdevcore/FixedHash.h
new file mode 100644
index 00000000..cf79bab0
--- /dev/null
+++ b/libdevcore/FixedHash.h
@@ -0,0 +1,306 @@
+/*
+ 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 FixedHash.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ *
+ * The FixedHash fixed-size "hash" container type.
+ */
+
+#pragma once
+
+#include <array>
+#include <cstdint>
+#include <algorithm>
+#include <boost/random/random_device.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
+#include <boost/functional/hash.hpp>
+#include "CommonData.h"
+
+namespace dev
+{
+
+/// Compile-time calculation of Log2 of constant values.
+template <unsigned N> struct StaticLog2 { enum { result = 1 + StaticLog2<N/2>::result }; };
+template <> struct StaticLog2<1> { enum { result = 0 }; };
+
+extern boost::random_device s_fixedHashEngine;
+
+/// Fixed-size raw-byte array container type, with an API optimised for storing hashes.
+/// Transparently converts to/from the corresponding arithmetic type; this will
+/// assume the data contained in the hash is big-endian.
+template <unsigned N>
+class FixedHash
+{
+public:
+ /// The corresponding arithmetic type.
+ using Arith = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<N * 8, N * 8, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
+
+ /// The size of the container.
+ enum { size = N };
+
+ /// A dummy flag to avoid accidental construction from pointer.
+ enum ConstructFromPointerType { ConstructFromPointer };
+
+ /// Method to convert from a string.
+ enum ConstructFromStringType { FromHex, FromBinary };
+
+ /// Method to convert from a string.
+ enum ConstructFromHashType { AlignLeft, AlignRight, FailIfDifferent };
+
+ /// Construct an empty hash.
+ FixedHash() { m_data.fill(0); }
+
+ /// Construct from another hash, filling with zeroes or cropping as necessary.
+ template <unsigned M> explicit FixedHash(FixedHash<M> const& _h, ConstructFromHashType _t = AlignLeft) { m_data.fill(0); unsigned c = std::min(M, N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _h[_t == AlignRight ? M - 1 - i : i]; }
+
+ /// Convert from the corresponding arithmetic type.
+ FixedHash(Arith const& _arith) { toBigEndian(_arith, m_data); }
+
+ /// Convert from unsigned
+ explicit FixedHash(unsigned _u) { toBigEndian(_u, m_data); }
+
+ /// Explicitly construct, copying from a byte array.
+ explicit FixedHash(bytes const& _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min<unsigned>(_b.size(), N)); else { m_data.fill(0); if (_t != FailIfDifferent) { auto c = std::min<unsigned>(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } }
+
+ /// Explicitly construct, copying from a byte array.
+ explicit FixedHash(bytesConstRef _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min<unsigned>(_b.size(), N)); else { m_data.fill(0); if (_t != FailIfDifferent) { auto c = std::min<unsigned>(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } }
+
+ /// Explicitly construct, copying from a bytes in memory with given pointer.
+ explicit FixedHash(byte const* _bs, ConstructFromPointerType) { memcpy(m_data.data(), _bs, N); }
+
+ /// Explicitly construct, copying from a string.
+ explicit FixedHash(std::string const& _s, ConstructFromStringType _t = FromHex, ConstructFromHashType _ht = FailIfDifferent): FixedHash(_t == FromHex ? fromHex(_s, WhenError::Throw) : dev::asBytes(_s), _ht) {}
+
+ /// Convert to arithmetic type.
+ operator Arith() const { return fromBigEndian<Arith>(m_data); }
+
+ /// @returns true iff this is the empty hash.
+ explicit operator bool() const { return std::any_of(m_data.begin(), m_data.end(), [](byte _b) { return _b != 0; }); }
+
+ // The obvious comparison operators.
+ bool operator==(FixedHash const& _c) const { return m_data == _c.m_data; }
+ bool operator!=(FixedHash const& _c) const { return m_data != _c.m_data; }
+ bool operator<(FixedHash const& _c) const { for (unsigned i = 0; i < N; ++i) if (m_data[i] < _c.m_data[i]) return true; else if (m_data[i] > _c.m_data[i]) return false; return false; }
+ bool operator>=(FixedHash const& _c) const { return !operator<(_c); }
+ bool operator<=(FixedHash const& _c) const { return operator==(_c) || operator<(_c); }
+ bool operator>(FixedHash const& _c) const { return !operator<=(_c); }
+
+ // The obvious binary operators.
+ FixedHash& operator^=(FixedHash const& _c) { for (unsigned i = 0; i < N; ++i) m_data[i] ^= _c.m_data[i]; return *this; }
+ FixedHash operator^(FixedHash const& _c) const { return FixedHash(*this) ^= _c; }
+ FixedHash& operator|=(FixedHash const& _c) { for (unsigned i = 0; i < N; ++i) m_data[i] |= _c.m_data[i]; return *this; }
+ FixedHash operator|(FixedHash const& _c) const { return FixedHash(*this) |= _c; }
+ FixedHash& operator&=(FixedHash const& _c) { for (unsigned i = 0; i < N; ++i) m_data[i] &= _c.m_data[i]; return *this; }
+ FixedHash operator&(FixedHash const& _c) const { return FixedHash(*this) &= _c; }
+ FixedHash operator~() const { FixedHash ret; for (unsigned i = 0; i < N; ++i) ret[i] = ~m_data[i]; return ret; }
+
+ // Big-endian increment.
+ FixedHash& operator++() { for (unsigned i = size; i > 0 && !++m_data[--i]; ) {} return *this; }
+
+ /// @returns true if all one-bits in @a _c are set in this object.
+ bool contains(FixedHash const& _c) const { return (*this & _c) == _c; }
+
+ /// @returns a particular byte from the hash.
+ byte& operator[](unsigned _i) { return m_data[_i]; }
+ /// @returns a particular byte from the hash.
+ byte operator[](unsigned _i) const { return m_data[_i]; }
+
+ /// @returns an abridged version of the hash as a user-readable hex string.
+ std::string abridged() const { return toHex(ref().cropped(0, 4)) + "\342\200\246"; }
+
+ /// @returns a version of the hash as a user-readable hex string that leaves out the middle part.
+ std::string abridgedMiddle() const { return toHex(ref().cropped(0, 4)) + "\342\200\246" + toHex(ref().cropped(N - 4)); }
+
+ /// @returns the hash as a user-readable hex string.
+ std::string hex() const { return toHex(ref()); }
+
+ /// @returns a mutable byte vector_ref to the object's data.
+ bytesRef ref() { return bytesRef(m_data.data(), N); }
+
+ /// @returns a constant byte vector_ref to the object's data.
+ bytesConstRef ref() const { return bytesConstRef(m_data.data(), N); }
+
+ /// @returns a mutable byte pointer to the object's data.
+ byte* data() { return m_data.data(); }
+
+ /// @returns a constant byte pointer to the object's data.
+ byte const* data() const { return m_data.data(); }
+
+ /// @returns a copy of the object's data as a byte vector.
+ bytes asBytes() const { return bytes(data(), data() + N); }
+
+ /// @returns a mutable reference to the object's data as an STL array.
+ std::array<byte, N>& asArray() { return m_data; }
+
+ /// @returns a constant reference to the object's data as an STL array.
+ std::array<byte, N> const& asArray() const { return m_data; }
+
+ /// Populate with random data.
+ template <class Engine>
+ void randomize(Engine& _eng)
+ {
+ for (auto& i: m_data)
+ i = (uint8_t)boost::random::uniform_int_distribution<uint16_t>(0, 255)(_eng);
+ }
+
+ /// @returns a random valued object.
+ static FixedHash random() { FixedHash ret; ret.randomize(s_fixedHashEngine); return ret; }
+
+ struct hash
+ {
+ /// Make a hash of the object's data.
+ size_t operator()(FixedHash const& _value) const { return boost::hash_range(_value.m_data.cbegin(), _value.m_data.cend()); }
+ };
+
+ template <unsigned P, unsigned M> inline FixedHash& shiftBloom(FixedHash<M> const& _h)
+ {
+ return (*this |= _h.template bloomPart<P, N>());
+ }
+
+ template <unsigned P, unsigned M> inline bool containsBloom(FixedHash<M> const& _h)
+ {
+ return contains(_h.template bloomPart<P, N>());
+ }
+
+ template <unsigned P, unsigned M> inline FixedHash<M> bloomPart() const
+ {
+ unsigned const c_bloomBits = M * 8;
+ unsigned const c_mask = c_bloomBits - 1;
+ unsigned const c_bloomBytes = (StaticLog2<c_bloomBits>::result + 7) / 8;
+
+ static_assert((M & (M - 1)) == 0, "M must be power-of-two");
+ static_assert(P * c_bloomBytes <= N, "out of range");
+
+ FixedHash<M> ret;
+ byte const* p = data();
+ for (unsigned i = 0; i < P; ++i)
+ {
+ unsigned index = 0;
+ for (unsigned j = 0; j < c_bloomBytes; ++j, ++p)
+ index = (index << 8) | *p;
+ index &= c_mask;
+ ret[M - 1 - index / 8] |= (1 << (index % 8));
+ }
+ return ret;
+ }
+
+ /// Returns the index of the first bit set to one, or size() * 8 if no bits are set.
+ inline unsigned firstBitSet() const
+ {
+ unsigned ret = 0;
+ for (auto d: m_data)
+ if (d)
+ for (;; ++ret, d <<= 1)
+ if (d & 0x80)
+ return ret;
+ else {}
+ else
+ ret += 8;
+ return ret;
+ }
+
+ void clear() { m_data.fill(0); }
+
+private:
+ std::array<byte, N> m_data; ///< The binary data.
+};
+
+/// Fast equality operator for h256.
+template<> inline bool FixedHash<32>::operator==(FixedHash<32> const& _other) const
+{
+ const uint64_t* hash1 = (const uint64_t*)data();
+ const uint64_t* hash2 = (const uint64_t*)_other.data();
+ return (hash1[0] == hash2[0]) && (hash1[1] == hash2[1]) && (hash1[2] == hash2[2]) && (hash1[3] == hash2[3]);
+}
+
+/// Fast std::hash compatible hash function object for h256.
+template<> inline size_t FixedHash<32>::hash::operator()(FixedHash<32> const& value) const
+{
+ uint64_t const* data = reinterpret_cast<uint64_t const*>(value.data());
+ return boost::hash_range(data, data + 4);
+}
+
+/// Stream I/O for the FixedHash class.
+template <unsigned N>
+inline std::ostream& operator<<(std::ostream& _out, FixedHash<N> const& _h)
+{
+ _out << std::noshowbase << std::hex << std::setfill('0');
+ for (unsigned i = 0; i < N; ++i)
+ _out << std::setw(2) << (int)_h[i];
+ _out << std::dec;
+ return _out;
+}
+
+// Common types of FixedHash.
+using h2048 = FixedHash<256>;
+using h1024 = FixedHash<128>;
+using h520 = FixedHash<65>;
+using h512 = FixedHash<64>;
+using h256 = FixedHash<32>;
+using h160 = FixedHash<20>;
+using h128 = FixedHash<16>;
+using h64 = FixedHash<8>;
+using h512s = std::vector<h512>;
+using h256s = std::vector<h256>;
+using h160s = std::vector<h160>;
+using h256Set = std::set<h256>;
+using h160Set = std::set<h160>;
+using h256Hash = std::unordered_set<h256>;
+using h160Hash = std::unordered_set<h160>;
+
+/// Convert the given value into h160 (160-bit unsigned integer) using the right 20 bytes.
+inline h160 right160(h256 const& _t)
+{
+ h160 ret;
+ memcpy(ret.data(), _t.data() + 12, 20);
+ return ret;
+}
+
+/// Convert the given value into h160 (160-bit unsigned integer) using the left 20 bytes.
+inline h160 left160(h256 const& _t)
+{
+ h160 ret;
+ memcpy(&ret[0], _t.data(), 20);
+ return ret;
+}
+
+h128 fromUUID(std::string const& _uuid);
+
+std::string toUUID(h128 const& _uuid);
+
+inline std::string toString(h256s const& _bs)
+{
+ std::ostringstream out;
+ out << "[ ";
+ for (auto i: _bs)
+ out << i.abridged() << ", ";
+ out << "]";
+ return out.str();
+}
+
+}
+
+namespace std
+{
+ /// Forward std::hash<dev::FixedHash> to dev::FixedHash::hash.
+ template<> struct hash<dev::h64>: dev::h64::hash {};
+ template<> struct hash<dev::h128>: dev::h128::hash {};
+ template<> struct hash<dev::h160>: dev::h160::hash {};
+ template<> struct hash<dev::h256>: dev::h256::hash {};
+ template<> struct hash<dev::h512>: dev::h512::hash {};
+}
diff --git a/libdevcore/Hash.cpp b/libdevcore/Hash.cpp
new file mode 100644
index 00000000..c6b917b9
--- /dev/null
+++ b/libdevcore/Hash.cpp
@@ -0,0 +1,440 @@
+/*
+ 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 Hash.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "Hash.h"
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include "picosha2.h"
+using namespace std;
+using namespace dev;
+
+namespace dev
+{
+
+h256 sha256(bytesConstRef _input)
+{
+ h256 ret;
+ picosha2::hash256(_input.begin(), _input.end(), ret.data(), ret.data() + 32);
+ return ret;
+}
+
+namespace rmd160
+{
+
+/********************************************************************\
+ *
+ * FILE: rmd160.h
+ * FILE: rmd160.c
+ *
+ * CONTENTS: Header file for a sample C-implementation of the
+ * RIPEMD-160 hash-function.
+ * TARGET: any computer with an ANSI C compiler
+ *
+ * AUTHOR: Antoon Bosselaers, ESAT-COSIC
+ * DATE: 1 March 1996
+ * VERSION: 1.0
+ *
+ * Copyright (c) Katholieke Universiteit Leuven
+ * 1996, All Rights Reserved
+ *
+ \********************************************************************/
+
+// Adapted into "header-only" format by Gav Wood.
+
+/* macro definitions */
+
+#define RMDsize 160
+
+/* collect four bytes into one word: */
+#define BYTES_TO_DWORD(strptr) \
+(((uint32_t) *((strptr)+3) << 24) | \
+((uint32_t) *((strptr)+2) << 16) | \
+((uint32_t) *((strptr)+1) << 8) | \
+((uint32_t) *(strptr)))
+
+/* ROL(x, n) cyclically rotates x over n bits to the left */
+/* x must be of an unsigned 32 bits type and 0 <= n < 32. */
+#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* the five basic functions F(), G() and H() */
+#define F(x, y, z) ((x) ^ (y) ^ (z))
+#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define H(x, y, z) (((x) | ~(y)) ^ (z))
+#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define J(x, y, z) ((x) ^ ((y) | ~(z)))
+
+/* the ten basic operations FF() through III() */
+#define FF(a, b, c, d, e, x, s) {\
+(a) += F((b), (c), (d)) + (x);\
+(a) = ROL((a), (s)) + (e);\
+(c) = ROL((c), 10);\
+}
+#define GG(a, b, c, d, e, x, s) {\
+(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
+(a) = ROL((a), (s)) + (e);\
+(c) = ROL((c), 10);\
+}
+#define HH(a, b, c, d, e, x, s) {\
+(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
+(a) = ROL((a), (s)) + (e);\
+(c) = ROL((c), 10);\
+}
+#define II(a, b, c, d, e, x, s) {\
+(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
+(a) = ROL((a), (s)) + (e);\
+(c) = ROL((c), 10);\
+}
+#define JJ(a, b, c, d, e, x, s) {\
+(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
+(a) = ROL((a), (s)) + (e);\
+(c) = ROL((c), 10);\
+}
+#define FFF(a, b, c, d, e, x, s) {\
+(a) += F((b), (c), (d)) + (x);\
+(a) = ROL((a), (s)) + (e);\
+(c) = ROL((c), 10);\
+}
+#define GGG(a, b, c, d, e, x, s) {\
+(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
+(a) = ROL((a), (s)) + (e);\
+(c) = ROL((c), 10);\
+}
+#define HHH(a, b, c, d, e, x, s) {\
+(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
+(a) = ROL((a), (s)) + (e);\
+(c) = ROL((c), 10);\
+}
+#define III(a, b, c, d, e, x, s) {\
+(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
+(a) = ROL((a), (s)) + (e);\
+(c) = ROL((c), 10);\
+}
+#define JJJ(a, b, c, d, e, x, s) {\
+(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
+(a) = ROL((a), (s)) + (e);\
+(c) = ROL((c), 10);\
+}
+
+void MDinit(uint32_t *MDbuf)
+{
+ MDbuf[0] = 0x67452301UL;
+ MDbuf[1] = 0xefcdab89UL;
+ MDbuf[2] = 0x98badcfeUL;
+ MDbuf[3] = 0x10325476UL;
+ MDbuf[4] = 0xc3d2e1f0UL;
+
+ return;
+}
+
+/********************************************************************/
+
+void MDcompress(uint32_t *MDbuf, uint32_t *X)
+{
+ uint32_t aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2],
+ dd = MDbuf[3], ee = MDbuf[4];
+ uint32_t aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
+ ddd = MDbuf[3], eee = MDbuf[4];
+
+ /* round 1 */
+ FF(aa, bb, cc, dd, ee, X[ 0], 11);
+ FF(ee, aa, bb, cc, dd, X[ 1], 14);
+ FF(dd, ee, aa, bb, cc, X[ 2], 15);
+ FF(cc, dd, ee, aa, bb, X[ 3], 12);
+ FF(bb, cc, dd, ee, aa, X[ 4], 5);
+ FF(aa, bb, cc, dd, ee, X[ 5], 8);
+ FF(ee, aa, bb, cc, dd, X[ 6], 7);
+ FF(dd, ee, aa, bb, cc, X[ 7], 9);
+ FF(cc, dd, ee, aa, bb, X[ 8], 11);
+ FF(bb, cc, dd, ee, aa, X[ 9], 13);
+ FF(aa, bb, cc, dd, ee, X[10], 14);
+ FF(ee, aa, bb, cc, dd, X[11], 15);
+ FF(dd, ee, aa, bb, cc, X[12], 6);
+ FF(cc, dd, ee, aa, bb, X[13], 7);
+ FF(bb, cc, dd, ee, aa, X[14], 9);
+ FF(aa, bb, cc, dd, ee, X[15], 8);
+
+ /* round 2 */
+ GG(ee, aa, bb, cc, dd, X[ 7], 7);
+ GG(dd, ee, aa, bb, cc, X[ 4], 6);
+ GG(cc, dd, ee, aa, bb, X[13], 8);
+ GG(bb, cc, dd, ee, aa, X[ 1], 13);
+ GG(aa, bb, cc, dd, ee, X[10], 11);
+ GG(ee, aa, bb, cc, dd, X[ 6], 9);
+ GG(dd, ee, aa, bb, cc, X[15], 7);
+ GG(cc, dd, ee, aa, bb, X[ 3], 15);
+ GG(bb, cc, dd, ee, aa, X[12], 7);
+ GG(aa, bb, cc, dd, ee, X[ 0], 12);
+ GG(ee, aa, bb, cc, dd, X[ 9], 15);
+ GG(dd, ee, aa, bb, cc, X[ 5], 9);
+ GG(cc, dd, ee, aa, bb, X[ 2], 11);
+ GG(bb, cc, dd, ee, aa, X[14], 7);
+ GG(aa, bb, cc, dd, ee, X[11], 13);
+ GG(ee, aa, bb, cc, dd, X[ 8], 12);
+
+ /* round 3 */
+ HH(dd, ee, aa, bb, cc, X[ 3], 11);
+ HH(cc, dd, ee, aa, bb, X[10], 13);
+ HH(bb, cc, dd, ee, aa, X[14], 6);
+ HH(aa, bb, cc, dd, ee, X[ 4], 7);
+ HH(ee, aa, bb, cc, dd, X[ 9], 14);
+ HH(dd, ee, aa, bb, cc, X[15], 9);
+ HH(cc, dd, ee, aa, bb, X[ 8], 13);
+ HH(bb, cc, dd, ee, aa, X[ 1], 15);
+ HH(aa, bb, cc, dd, ee, X[ 2], 14);
+ HH(ee, aa, bb, cc, dd, X[ 7], 8);
+ HH(dd, ee, aa, bb, cc, X[ 0], 13);
+ HH(cc, dd, ee, aa, bb, X[ 6], 6);
+ HH(bb, cc, dd, ee, aa, X[13], 5);
+ HH(aa, bb, cc, dd, ee, X[11], 12);
+ HH(ee, aa, bb, cc, dd, X[ 5], 7);
+ HH(dd, ee, aa, bb, cc, X[12], 5);
+
+ /* round 4 */
+ II(cc, dd, ee, aa, bb, X[ 1], 11);
+ II(bb, cc, dd, ee, aa, X[ 9], 12);
+ II(aa, bb, cc, dd, ee, X[11], 14);
+ II(ee, aa, bb, cc, dd, X[10], 15);
+ II(dd, ee, aa, bb, cc, X[ 0], 14);
+ II(cc, dd, ee, aa, bb, X[ 8], 15);
+ II(bb, cc, dd, ee, aa, X[12], 9);
+ II(aa, bb, cc, dd, ee, X[ 4], 8);
+ II(ee, aa, bb, cc, dd, X[13], 9);
+ II(dd, ee, aa, bb, cc, X[ 3], 14);
+ II(cc, dd, ee, aa, bb, X[ 7], 5);
+ II(bb, cc, dd, ee, aa, X[15], 6);
+ II(aa, bb, cc, dd, ee, X[14], 8);
+ II(ee, aa, bb, cc, dd, X[ 5], 6);
+ II(dd, ee, aa, bb, cc, X[ 6], 5);
+ II(cc, dd, ee, aa, bb, X[ 2], 12);
+
+ /* round 5 */
+ JJ(bb, cc, dd, ee, aa, X[ 4], 9);
+ JJ(aa, bb, cc, dd, ee, X[ 0], 15);
+ JJ(ee, aa, bb, cc, dd, X[ 5], 5);
+ JJ(dd, ee, aa, bb, cc, X[ 9], 11);
+ JJ(cc, dd, ee, aa, bb, X[ 7], 6);
+ JJ(bb, cc, dd, ee, aa, X[12], 8);
+ JJ(aa, bb, cc, dd, ee, X[ 2], 13);
+ JJ(ee, aa, bb, cc, dd, X[10], 12);
+ JJ(dd, ee, aa, bb, cc, X[14], 5);
+ JJ(cc, dd, ee, aa, bb, X[ 1], 12);
+ JJ(bb, cc, dd, ee, aa, X[ 3], 13);
+ JJ(aa, bb, cc, dd, ee, X[ 8], 14);
+ JJ(ee, aa, bb, cc, dd, X[11], 11);
+ JJ(dd, ee, aa, bb, cc, X[ 6], 8);
+ JJ(cc, dd, ee, aa, bb, X[15], 5);
+ JJ(bb, cc, dd, ee, aa, X[13], 6);
+
+ /* parallel round 1 */
+ JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
+ JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
+ JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
+ JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
+ JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
+ JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
+ JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
+ JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
+ JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
+ JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
+ JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
+ JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
+ JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
+ JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
+ JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
+ JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
+
+ /* parallel round 2 */
+ III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
+ III(ddd, eee, aaa, bbb, ccc, X[11], 13);
+ III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
+ III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
+ III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
+ III(eee, aaa, bbb, ccc, ddd, X[13], 8);
+ III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
+ III(ccc, ddd, eee, aaa, bbb, X[10], 11);
+ III(bbb, ccc, ddd, eee, aaa, X[14], 7);
+ III(aaa, bbb, ccc, ddd, eee, X[15], 7);
+ III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
+ III(ddd, eee, aaa, bbb, ccc, X[12], 7);
+ III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
+ III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
+ III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
+ III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
+
+ /* parallel round 3 */
+ HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
+ HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
+ HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
+ HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
+ HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
+ HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
+ HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
+ HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
+ HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
+ HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
+ HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
+ HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
+ HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
+ HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
+ HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
+ HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
+
+ /* parallel round 4 */
+ GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
+ GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
+ GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
+ GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
+ GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
+ GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
+ GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
+ GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
+ GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
+ GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
+ GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
+ GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
+ GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
+ GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
+ GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
+ GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
+
+ /* parallel round 5 */
+ FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
+ FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
+ FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
+ FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
+ FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
+ FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
+ FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
+ FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
+ FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
+ FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
+ FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
+ FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
+ FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
+ FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
+ FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
+ FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
+
+ /* combine results */
+ ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */
+ MDbuf[1] = MDbuf[2] + dd + eee;
+ MDbuf[2] = MDbuf[3] + ee + aaa;
+ MDbuf[3] = MDbuf[4] + aa + bbb;
+ MDbuf[4] = MDbuf[0] + bb + ccc;
+ MDbuf[0] = ddd;
+
+ return;
+}
+
+void MDfinish(uint32_t *MDbuf, byte const *strptr, uint32_t lswlen, uint32_t mswlen)
+{
+ unsigned int i; /* counter */
+ uint32_t X[16]; /* message words */
+
+ memset(X, 0, 16*sizeof(uint32_t));
+
+ /* put bytes from strptr into X */
+ for (i=0; i<(lswlen&63); i++) {
+ /* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */
+ X[i>>2] ^= (uint32_t) *strptr++ << (8 * (i&3));
+ }
+
+ /* append the bit m_n == 1 */
+ X[(lswlen>>2)&15] ^= (uint32_t)1 << (8*(lswlen&3) + 7);
+
+ if ((lswlen & 63) > 55) {
+ /* length goes to next block */
+ MDcompress(MDbuf, X);
+ memset(X, 0, 16*sizeof(uint32_t));
+ }
+
+ /* append length in bits*/
+ X[14] = lswlen << 3;
+ X[15] = (lswlen >> 29) | (mswlen << 3);
+ MDcompress(MDbuf, X);
+
+ return;
+}
+
+#undef ROL
+#undef F
+#undef G
+#undef H
+#undef I
+#undef J
+#undef FF
+#undef GG
+#undef HH
+#undef II
+#undef JJ
+#undef FFF
+#undef GGG
+#undef HHH
+#undef III
+#undef JJJ
+
+}
+
+/*
+ * @returns RMD(_input)
+ */
+h160 ripemd160(bytesConstRef _input)
+{
+ h160 hashcode;
+ uint32_t buffer[RMDsize / 32]; // contains (A, B, C, D(, E))
+ uint32_t current[16]; // current 16-word chunk
+
+ // initialize
+ rmd160::MDinit(buffer);
+ byte const* message = _input.data();
+ uint32_t remaining = _input.size(); // # of bytes not yet processed
+
+ // process message in 16x 4-byte chunks
+ for (; remaining >= 64; remaining -= 64)
+ {
+ for (unsigned i = 0; i < 16; i++)
+ {
+ current[i] = BYTES_TO_DWORD(message);
+ message += 4;
+ }
+ rmd160::MDcompress(buffer, current);
+ }
+ // length mod 64 bytes left
+
+ // finish:
+ rmd160::MDfinish(buffer, message, _input.size(), 0);
+
+ for (unsigned i = 0; i < RMDsize / 8; i += 4)
+ {
+ hashcode[i] = buffer[i >> 2]; // implicit cast to byte
+ hashcode[i + 1] = (buffer[i >> 2] >> 8); //extracts the 8 least
+ hashcode[i + 2] = (buffer[i >> 2] >> 16); // significant bits.
+ hashcode[i + 3] = (buffer[i >> 2] >> 24);
+ }
+
+ return hashcode;
+}
+
+#undef BYTES_TO_DWORD
+#undef RMDsize
+
+}
diff --git a/libdevcore/Hash.h b/libdevcore/Hash.h
new file mode 100644
index 00000000..d4401014
--- /dev/null
+++ b/libdevcore/Hash.h
@@ -0,0 +1,38 @@
+/*
+ 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 Hash.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ *
+ * The FixedHash fixed-size "hash" container type.
+ */
+
+#pragma once
+
+#include <string>
+#include "FixedHash.h"
+#include "vector_ref.h"
+#include "SHA3.h"
+
+namespace dev
+{
+
+h256 sha256(bytesConstRef _input);
+
+h160 ripemd160(bytesConstRef _input);
+
+}
diff --git a/libdevcore/SHA3.cpp b/libdevcore/SHA3.cpp
new file mode 100644
index 00000000..584ef07e
--- /dev/null
+++ b/libdevcore/SHA3.cpp
@@ -0,0 +1,223 @@
+/*
+ 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 SHA3.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "SHA3.h"
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include "picosha2.h"
+using namespace std;
+using namespace dev;
+
+namespace dev
+{
+
+namespace keccak
+{
+
+/** libkeccak-tiny
+ *
+ * A single-file implementation of SHA-3 and SHAKE.
+ *
+ * Implementor: David Leon Gil
+ * License: CC0, attribution kindly requested. Blame taken too,
+ * but not liability.
+ */
+
+#define decshake(bits) \
+ int shake##bits(uint8_t*, size_t, const uint8_t*, size_t);
+
+#define decsha3(bits) \
+ int sha3_##bits(uint8_t*, size_t, const uint8_t*, size_t);
+
+decshake(128)
+decshake(256)
+decsha3(224)
+decsha3(256)
+decsha3(384)
+decsha3(512)
+
+/******** The Keccak-f[1600] permutation ********/
+
+/*** Constants. ***/
+static const uint8_t rho[24] = \
+ { 1, 3, 6, 10, 15, 21,
+ 28, 36, 45, 55, 2, 14,
+ 27, 41, 56, 8, 25, 43,
+ 62, 18, 39, 61, 20, 44};
+static const uint8_t pi[24] = \
+ {10, 7, 11, 17, 18, 3,
+ 5, 16, 8, 21, 24, 4,
+ 15, 23, 19, 13, 12, 2,
+ 20, 14, 22, 9, 6, 1};
+static const uint64_t RC[24] = \
+ {1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL,
+ 0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL,
+ 0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL,
+ 0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL,
+ 0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL,
+ 0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL};
+
+/*** Helper macros to unroll the permutation. ***/
+#define rol(x, s) (((x) << s) | ((x) >> (64 - s)))
+#define REPEAT6(e) e e e e e e
+#define REPEAT24(e) REPEAT6(e e e e)
+#define REPEAT5(e) e e e e e
+#define FOR5(v, s, e) \
+ v = 0; \
+ REPEAT5(e; v += s;)
+
+/*** Keccak-f[1600] ***/
+static inline void keccakf(void* state) {
+ uint64_t* a = (uint64_t*)state;
+ uint64_t b[5] = {0};
+ uint64_t t = 0;
+ uint8_t x, y;
+
+ for (int i = 0; i < 24; i++) {
+ // Theta
+ FOR5(x, 1,
+ b[x] = 0;
+ FOR5(y, 5,
+ b[x] ^= a[x + y]; ))
+ FOR5(x, 1,
+ FOR5(y, 5,
+ a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); ))
+ // Rho and pi
+ t = a[1];
+ x = 0;
+ REPEAT24(b[0] = a[pi[x]];
+ a[pi[x]] = rol(t, rho[x]);
+ t = b[0];
+ x++; )
+ // Chi
+ FOR5(y,
+ 5,
+ FOR5(x, 1,
+ b[x] = a[y + x];)
+ FOR5(x, 1,
+ a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); ))
+ // Iota
+ a[0] ^= RC[i];
+ }
+}
+
+/******** The FIPS202-defined functions. ********/
+
+/*** Some helper macros. ***/
+
+#define _(S) do { S } while (0)
+#define FOR(i, ST, L, S) \
+ _(for (size_t i = 0; i < L; i += ST) { S; })
+#define mkapply_ds(NAME, S) \
+ static inline void NAME(uint8_t* dst, \
+ const uint8_t* src, \
+ size_t len) { \
+ FOR(i, 1, len, S); \
+ }
+#define mkapply_sd(NAME, S) \
+ static inline void NAME(const uint8_t* src, \
+ uint8_t* dst, \
+ size_t len) { \
+ FOR(i, 1, len, S); \
+ }
+
+mkapply_ds(xorin, dst[i] ^= src[i]) // xorin
+mkapply_sd(setout, dst[i] = src[i]) // setout
+
+#define P keccakf
+#define Plen 200
+
+// Fold P*F over the full blocks of an input.
+#define foldP(I, L, F) \
+ while (L >= rate) { \
+ F(a, I, rate); \
+ P(a); \
+ I += rate; \
+ L -= rate; \
+ }
+
+/** The sponge-based hash construction. **/
+static inline int hash(uint8_t* out, size_t outlen,
+ const uint8_t* in, size_t inlen,
+ size_t rate, uint8_t delim) {
+ if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) {
+ return -1;
+ }
+ uint8_t a[Plen] = {0};
+ // Absorb input.
+ foldP(in, inlen, xorin);
+ // Xor in the DS and pad frame.
+ a[inlen] ^= delim;
+ a[rate - 1] ^= 0x80;
+ // Xor in the last block.
+ xorin(a, in, inlen);
+ // Apply P
+ P(a);
+ // Squeeze output.
+ foldP(out, outlen, setout);
+ setout(a, out, outlen);
+ memset(a, 0, 200);
+ return 0;
+}
+
+/*** Helper macros to define SHA3 and SHAKE instances. ***/
+#define defshake(bits) \
+ int shake##bits(uint8_t* out, size_t outlen, \
+ const uint8_t* in, size_t inlen) { \
+ return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x1f); \
+ }
+#define defsha3(bits) \
+ int sha3_##bits(uint8_t* out, size_t outlen, \
+ const uint8_t* in, size_t inlen) { \
+ if (outlen > (bits/8)) { \
+ return -1; \
+ } \
+ return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \
+ }
+
+/*** FIPS202 SHAKE VOFs ***/
+defshake(128)
+defshake(256)
+
+/*** FIPS202 SHA3 FOFs ***/
+defsha3(224)
+defsha3(256)
+defsha3(384)
+defsha3(512)
+
+}
+
+unsigned g_sha3Counter = 0;
+
+bool sha3(bytesConstRef _input, bytesRef o_output)
+{
+ // FIXME: What with unaligned memory?
+ if (o_output.size() != 32)
+ return false;
+ ++g_sha3Counter;
+ keccak::sha3_256(o_output.data(), 32, _input.data(), _input.size());
+// keccak::keccak(ret.data(), 32, (uint64_t const*)_input.data(), _input.size());
+ return true;
+}
+
+}
diff --git a/libdevcore/SHA3.h b/libdevcore/SHA3.h
new file mode 100644
index 00000000..5393952f
--- /dev/null
+++ b/libdevcore/SHA3.h
@@ -0,0 +1,59 @@
+/*
+ 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 SHA3.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ *
+ * The FixedHash fixed-size "hash" container type.
+ */
+
+#pragma once
+
+#include <string>
+#include "FixedHash.h"
+#include "vector_ref.h"
+
+namespace dev
+{
+
+// SHA-3 convenience routines.
+
+/// Calculate SHA3-256 hash of the given input and load it into the given output.
+/// @returns false if o_output.size() != 32.
+bool sha3(bytesConstRef _input, bytesRef o_output);
+
+/// Calculate SHA3-256 hash of the given input, returning as a 256-bit hash.
+inline h256 sha3(bytesConstRef _input) { h256 ret; sha3(_input, ret.ref()); return ret; }
+
+/// Calculate SHA3-256 hash of the given input, returning as a 256-bit hash.
+inline h256 sha3(bytes const& _input) { return sha3(bytesConstRef(&_input)); }
+
+/// Calculate SHA3-256 hash of the given input (presented as a binary-filled string), returning as a 256-bit hash.
+inline h256 sha3(std::string const& _input) { return sha3(bytesConstRef(_input)); }
+
+/// Calculate SHA3-256 hash of the given input (presented as a FixedHash), returns a 256-bit hash.
+template<unsigned N> inline h256 sha3(FixedHash<N> const& _input) { return sha3(_input.ref()); }
+
+/// Calculate SHA3-256 hash of the given input, possibly interpreting it as nibbles, and return the hash as a string filled with binary data.
+inline std::string sha3(std::string const& _input, bool _isNibbles) { return asString((_isNibbles ? sha3(fromHex(_input)) : sha3(bytesConstRef(&_input))).asBytes()); }
+
+/// Calculate SHA3-256 MAC
+inline void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output) { sha3(_secret.toBytes() + _plain.toBytes()).ref().populate(_output); }
+
+extern unsigned g_sha3Counter;
+
+}
diff --git a/libdevcore/UndefMacros.h b/libdevcore/UndefMacros.h
new file mode 100644
index 00000000..91249523
--- /dev/null
+++ b/libdevcore/UndefMacros.h
@@ -0,0 +1,46 @@
+/*
+ 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 UndefMacros.h
+ * @author Lefteris <lefteris@ethdev.com>
+ * @date 2015
+ *
+ * This header should be used to #undef some really evil macros defined by
+ * windows.h which result in conflict with our libsolidity/Token.h
+ */
+#pragma once
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+
+#undef DELETE
+#undef IN
+#undef VOID
+#undef THIS
+#undef CONST
+
+// Conflicting define on MinGW in windows.h
+// windows.h(19): #define interface struct
+#ifdef interface
+#undef interface
+#endif
+
+#elif defined(DELETE) || defined(IN) || defined(VOID) || defined(THIS) || defined(CONST) || defined(interface)
+
+#error "The preceding macros in this header file are reserved for V8's "\
+"TOKEN_LIST. Please add a platform specific define above to undefine "\
+"overlapping macros."
+
+#endif
diff --git a/libdevcore/debugbreak.h b/libdevcore/debugbreak.h
new file mode 100644
index 00000000..65612a34
--- /dev/null
+++ b/libdevcore/debugbreak.h
@@ -0,0 +1,125 @@
+/* Copyright (c) 2013, Scott Tsai
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DEBUG_BREAK_H
+#define DEBUG_BREAK_H
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+
+#define debug_break __debugbreak
+
+#else
+
+#include <signal.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ /* gcc optimizers consider code after __builtin_trap() dead.
+ * Making __builtin_trap() unsuitable for breaking into the debugger */
+ DEBUG_BREAK_PREFER_BUILTIN_TRAP_TO_SIGTRAP = 0,
+};
+
+#if defined(__i386__) || defined(__x86_64__)
+enum { HAVE_TRAP_INSTRUCTION = 1, };
+__attribute__((gnu_inline, always_inline))
+static void __inline__ trap_instruction(void)
+{
+ __asm__ volatile("int $0x03");
+}
+#elif defined(__thumb__)
+enum { HAVE_TRAP_INSTRUCTION = 1, };
+/* FIXME: handle __THUMB_INTERWORK__ */
+__attribute__((gnu_inline, always_inline))
+static void __inline__ trap_instruction(void)
+{
+ /* See 'arm-linux-tdep.c' in GDB source.
+ * Both instruction sequences below works. */
+#if 1
+ /* 'eabi_linux_thumb_le_breakpoint' */
+ __asm__ volatile(".inst 0xde01");
+#else
+ /* 'eabi_linux_thumb2_le_breakpoint' */
+ __asm__ volatile(".inst.w 0xf7f0a000");
+#endif
+
+ /* Known problem:
+ * After a breakpoint hit, can't stepi, step, or continue in GDB.
+ * 'step' stuck on the same instruction.
+ *
+ * Workaround: a new GDB command,
+ * 'debugbreak-step' is defined in debugbreak-gdb.py
+ * that does:
+ * (gdb) set $instruction_len = 2
+ * (gdb) tbreak *($pc + $instruction_len)
+ * (gdb) jump *($pc + $instruction_len)
+ */
+}
+#elif defined(__arm__) && !defined(__thumb__)
+enum { HAVE_TRAP_INSTRUCTION = 1, };
+__attribute__((gnu_inline, always_inline))
+static void __inline__ trap_instruction(void)
+{
+ /* See 'arm-linux-tdep.c' in GDB source,
+ * 'eabi_linux_arm_le_breakpoint' */
+ __asm__ volatile(".inst 0xe7f001f0");
+ /* Has same known problem and workaround
+ * as Thumb mode */
+}
+#else
+enum { HAVE_TRAP_INSTRUCTION = 0, };
+#endif
+
+__attribute__((gnu_inline, always_inline))
+static void __inline__ debug_break(void)
+{
+ if (HAVE_TRAP_INSTRUCTION) {
+#if defined(ETH_EMSCRIPTEN)
+ asm("debugger");
+#else
+ trap_instruction();
+#endif
+ } else if (DEBUG_BREAK_PREFER_BUILTIN_TRAP_TO_SIGTRAP) {
+ /* raises SIGILL on Linux x86{,-64}, to continue in gdb:
+ * (gdb) handle SIGILL stop nopass
+ * */
+ __builtin_trap();
+ } else {
+ raise(SIGTRAP);
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
diff --git a/libdevcore/picosha2.h b/libdevcore/picosha2.h
new file mode 100644
index 00000000..44b6bee5
--- /dev/null
+++ b/libdevcore/picosha2.h
@@ -0,0 +1,360 @@
+/*
+The MIT License (MIT)
+
+Copyright (C) 2014 okdshin
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#ifndef PICOSHA2_H
+#define PICOSHA2_H
+//picosha2:20140213
+#include <cstdint>
+#include <iostream>
+#include <vector>
+#include <iterator>
+#include <cassert>
+#include <sstream>
+#include <algorithm>
+
+namespace picosha2
+{
+
+namespace detail
+{
+
+inline uint8_t mask_8bit(uint8_t x){
+ return x&0xff;
+}
+
+inline uint32_t mask_32bit(uint32_t x){
+ return x&0xffffffff;
+}
+
+static const uint32_t add_constant[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+static const uint32_t initial_message_digest[8] = {
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+ 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+};
+
+inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z){
+ return (x&y)^((~x)&z);
+}
+
+inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z){
+ return (x&y)^(x&z)^(y&z);
+}
+
+inline uint32_t rotr(uint32_t x, std::size_t n){
+ assert(n < 32);
+ return mask_32bit((x>>n)|(x<<(32-n)));
+}
+
+inline uint32_t bsig0(uint32_t x){
+ return rotr(x, 2)^rotr(x, 13)^rotr(x, 22);
+}
+
+inline uint32_t bsig1(uint32_t x){
+ return rotr(x, 6)^rotr(x, 11)^rotr(x, 25);
+}
+
+inline uint32_t shr(uint32_t x, std::size_t n){
+ assert(n < 32);
+ return x >> n;
+}
+
+inline uint32_t ssig0(uint32_t x){
+ return rotr(x, 7)^rotr(x, 18)^shr(x, 3);
+}
+
+inline uint32_t ssig1(uint32_t x){
+ return rotr(x, 17)^rotr(x, 19)^shr(x, 10);
+}
+
+template<typename RaIter1, typename RaIter2>
+void hash256_block(RaIter1 message_digest, RaIter2 first, RaIter2 last){
+ (void)last; // FIXME: check this is valid
+ uint32_t w[64];
+ std::fill(w, w+64, 0);
+ for(std::size_t i = 0; i < 16; ++i){
+ w[i] = (static_cast<uint32_t>(mask_8bit(*(first+i*4)))<<24)
+ |(static_cast<uint32_t>(mask_8bit(*(first+i*4+1)))<<16)
+ |(static_cast<uint32_t>(mask_8bit(*(first+i*4+2)))<<8)
+ |(static_cast<uint32_t>(mask_8bit(*(first+i*4+3))));
+ }
+ for(std::size_t i = 16; i < 64; ++i){
+ w[i] = mask_32bit(ssig1(w[i-2])+w[i-7]+ssig0(w[i-15])+w[i-16]);
+ }
+
+ uint32_t a = *message_digest;
+ uint32_t b = *(message_digest+1);
+ uint32_t c = *(message_digest+2);
+ uint32_t d = *(message_digest+3);
+ uint32_t e = *(message_digest+4);
+ uint32_t f = *(message_digest+5);
+ uint32_t g = *(message_digest+6);
+ uint32_t h = *(message_digest+7);
+
+ for(std::size_t i = 0; i < 64; ++i){
+ uint32_t temp1 = h+bsig1(e)+ch(e,f,g)+add_constant[i]+w[i];
+ uint32_t temp2 = bsig0(a)+maj(a,b,c);
+ h = g;
+ g = f;
+ f = e;
+ e = mask_32bit(d+temp1);
+ d = c;
+ c = b;
+ b = a;
+ a = mask_32bit(temp1+temp2);
+ }
+ *message_digest += a;
+ *(message_digest+1) += b;
+ *(message_digest+2) += c;
+ *(message_digest+3) += d;
+ *(message_digest+4) += e;
+ *(message_digest+5) += f;
+ *(message_digest+6) += g;
+ *(message_digest+7) += h;
+ for(std::size_t i = 0; i < 8; ++i){
+ *(message_digest+i) = mask_32bit(*(message_digest+i));
+ }
+}
+
+}//namespace detail
+
+template<typename InIter>
+void output_hex(InIter first, InIter last, std::ostream& os){
+ os.setf(std::ios::hex, std::ios::basefield);
+ while(first != last){
+ os.width(2);
+ os.fill('0');
+ os << static_cast<unsigned int>(*first);
+ ++first;
+ }
+ os.setf(std::ios::dec, std::ios::basefield);
+}
+
+template<typename InIter>
+void bytes_to_hex_string(InIter first, InIter last, std::string& hex_str){
+ std::ostringstream oss;
+ output_hex(first, last, oss);
+ hex_str.assign(oss.str());
+}
+
+template<typename InContainer>
+void bytes_to_hex_string(const InContainer& bytes, std::string& hex_str){
+ bytes_to_hex_string(bytes.begin(), bytes.end(), hex_str);
+}
+
+template<typename InIter>
+std::string bytes_to_hex_string(InIter first, InIter last){
+ std::string hex_str;
+ bytes_to_hex_string(first, last, hex_str);
+ return hex_str;
+}
+
+template<typename InContainer>
+std::string bytes_to_hex_string(const InContainer& bytes){
+ std::string hex_str;
+ bytes_to_hex_string(bytes, hex_str);
+ return hex_str;
+}
+
+class hash256_one_by_one {
+public:
+ hash256_one_by_one(){
+ init();
+ }
+
+ void init(){
+ buffer_.clear();
+ std::fill(data_length_digits_, data_length_digits_+4, 0);
+ std::copy(detail::initial_message_digest, detail::initial_message_digest+8, h_);
+ }
+
+ template<typename RaIter>
+ void process(RaIter first, RaIter last){
+ add_to_data_length(std::distance(first, last));
+ std::copy(first, last, std::back_inserter(buffer_));
+ std::size_t i = 0;
+ for(;i+64 <= buffer_.size(); i+=64){
+ detail::hash256_block(h_, buffer_.begin()+i, buffer_.begin()+i+64);
+ }
+ buffer_.erase(buffer_.begin(), buffer_.begin()+i);
+ }
+
+ void finish(){
+ uint8_t temp[64];
+ std::fill(temp, temp+64, 0);
+ std::size_t remains = buffer_.size();
+ std::copy(buffer_.begin(), buffer_.end(), temp);
+ temp[remains] = 0x80;
+
+ if(remains > 55){
+ std::fill(temp+remains+1, temp+64, 0);
+ detail::hash256_block(h_, temp, temp+64);
+ std::fill(temp, temp+64-4, 0);
+ }
+ else {
+ std::fill(temp+remains+1, temp+64-4, 0);
+ }
+
+ write_data_bit_length(&(temp[56]));
+ detail::hash256_block(h_, temp, temp+64);
+ }
+
+ template<typename OutIter>
+ void get_hash_bytes(OutIter first, OutIter last)const{
+ for(const uint32_t* iter = h_; iter != h_+8; ++iter){
+ for(std::size_t i = 0; i < 4 && first != last; ++i){
+ *(first++) = detail::mask_8bit(static_cast<uint8_t>((*iter >> (24-8*i))));
+ }
+ }
+ }
+
+private:
+ void add_to_data_length(uint32_t n) {
+ uint32_t carry = 0;
+ data_length_digits_[0] += n;
+ for(std::size_t i = 0; i < 4; ++i) {
+ data_length_digits_[i] += carry;
+ if(data_length_digits_[i] >= 65536u) {
+ data_length_digits_[i] -= 65536u;
+ carry = 1;
+ }
+ else {
+ break;
+ }
+ }
+ }
+ void write_data_bit_length(uint8_t* begin) {
+ uint32_t data_bit_length_digits[4];
+ std::copy(
+ data_length_digits_, data_length_digits_+4,
+ data_bit_length_digits
+ );
+
+ // convert byte length to bit length (multiply 8 or shift 3 times left)
+ uint32_t carry = 0;
+ for(std::size_t i = 0; i < 4; ++i) {
+ uint32_t before_val = data_bit_length_digits[i];
+ data_bit_length_digits[i] <<= 3;
+ data_bit_length_digits[i] |= carry;
+ data_bit_length_digits[i] &= 65535u;
+ carry = (before_val >> (16-3)) & 65535u;
+ }
+
+ // write data_bit_length
+ for(int i = 3; i >= 0; --i) {
+ (*begin++) = static_cast<uint8_t>(data_bit_length_digits[i] >> 8);
+ (*begin++) = static_cast<uint8_t>(data_bit_length_digits[i]);
+ }
+ }
+ std::vector<uint8_t> buffer_;
+ uint32_t data_length_digits_[4]; //as 64bit integer (16bit x 4 integer)
+ uint32_t h_[8];
+};
+
+inline void get_hash_hex_string(const hash256_one_by_one& hasher, std::string& hex_str){
+ uint8_t hash[32];
+ hasher.get_hash_bytes(hash, hash+32);
+ return bytes_to_hex_string(hash, hash+32, hex_str);
+}
+
+inline std::string get_hash_hex_string(const hash256_one_by_one& hasher){
+ std::string hex_str;
+ get_hash_hex_string(hasher, hex_str);
+ return hex_str;
+}
+
+template<typename RaIter, typename OutIter>
+void hash256(RaIter first, RaIter last, OutIter first2, OutIter last2){
+ hash256_one_by_one hasher;
+ //hasher.init();
+ hasher.process(first, last);
+ hasher.finish();
+ hasher.get_hash_bytes(first2, last2);
+}
+
+template<typename RaIter, typename OutContainer>
+void hash256(RaIter first, RaIter last, OutContainer& dst){
+ hash256(first, last, dst.begin(), dst.end());
+}
+
+template<typename RaContainer, typename OutIter>
+void hash256(const RaContainer& src, OutIter first, OutIter last){
+ hash256(src.begin(), src.end(), first, last);
+}
+
+template<typename RaContainer, typename OutContainer>
+void hash256(const RaContainer& src, OutContainer& dst){
+ hash256(src.begin(), src.end(), dst.begin(), dst.end());
+}
+
+
+template<typename RaIter>
+void hash256_hex_string(RaIter first, RaIter last, std::string& hex_str){
+ uint8_t hashed[32];
+ hash256(first, last, hashed, hashed+32);
+ std::ostringstream oss;
+ output_hex(hashed, hashed+32, oss);
+ hex_str.assign(oss.str());
+}
+
+template<typename RaIter>
+std::string hash256_hex_string(RaIter first, RaIter last){
+ std::string hex_str;
+ hash256_hex_string(first, last, hex_str);
+ return hex_str;
+}
+
+inline void hash256_hex_string(const std::string& src, std::string& hex_str){
+ hash256_hex_string(src.begin(), src.end(), hex_str);
+}
+
+template<typename RaContainer>
+void hash256_hex_string(const RaContainer& src, std::string& hex_str){
+ hash256_hex_string(src.begin(), src.end(), hex_str);
+}
+
+template<typename RaContainer>
+std::string hash256_hex_string(const RaContainer& src){
+ return hash256_hex_string(src.begin(), src.end());
+}
+
+}//namespace picosha2
+
+#endif //PICOSHA2_H
diff --git a/libdevcore/vector_ref.h b/libdevcore/vector_ref.h
new file mode 100644
index 00000000..46d06946
--- /dev/null
+++ b/libdevcore/vector_ref.h
@@ -0,0 +1,120 @@
+#pragma once
+
+#include <cstring>
+#include <cassert>
+#include <type_traits>
+#include <vector>
+#include <string>
+
+#ifdef __INTEL_COMPILER
+#pragma warning(disable:597) //will not be called for implicit or explicit conversions
+#endif
+
+namespace dev
+{
+
+/**
+ * A modifiable reference to an existing object or vector in memory.
+ */
+template <class _T>
+class vector_ref
+{
+public:
+ using value_type = _T;
+ using element_type = _T;
+ using mutable_value_type = typename std::conditional<std::is_const<_T>::value, typename std::remove_const<_T>::type, _T>::type;
+
+ static_assert(std::is_pod<value_type>::value, "vector_ref can only be used with PODs due to its low-level treatment of data.");
+
+ vector_ref(): m_data(nullptr), m_count(0) {}
+ /// Creates a new vector_ref to point to @a _count elements starting at @a _data.
+ vector_ref(_T* _data, size_t _count): m_data(_data), m_count(_count) {}
+ /// Creates a new vector_ref pointing to the data part of a string (given as pointer).
+ vector_ref(typename std::conditional<std::is_const<_T>::value, std::string const*, std::string*>::type _data): m_data(reinterpret_cast<_T*>(_data->data())), m_count(_data->size() / sizeof(_T)) {}
+ /// Creates a new vector_ref pointing to the data part of a vector (given as pointer).
+ vector_ref(typename std::conditional<std::is_const<_T>::value, std::vector<typename std::remove_const<_T>::type> const*, std::vector<_T>*>::type _data): m_data(_data->data()), m_count(_data->size()) {}
+ /// Creates a new vector_ref pointing to the data part of a string (given as reference).
+ vector_ref(typename std::conditional<std::is_const<_T>::value, std::string const&, std::string&>::type _data): m_data(reinterpret_cast<_T*>(_data.data())), m_count(_data.size() / sizeof(_T)) {}
+#if DEV_LDB
+ vector_ref(ldb::Slice const& _s): m_data(reinterpret_cast<_T*>(_s.data())), m_count(_s.size() / sizeof(_T)) {}
+#endif
+ explicit operator bool() const { return m_data && m_count; }
+
+ bool contentsEqual(std::vector<mutable_value_type> const& _c) const { if (!m_data || m_count == 0) return _c.empty(); else return _c.size() == m_count && !memcmp(_c.data(), m_data, m_count * sizeof(_T)); }
+ std::vector<mutable_value_type> toVector() const { return std::vector<mutable_value_type>(m_data, m_data + m_count); }
+ std::vector<unsigned char> toBytes() const { return std::vector<unsigned char>(reinterpret_cast<unsigned char const*>(m_data), reinterpret_cast<unsigned char const*>(m_data) + m_count * sizeof(_T)); }
+ std::string toString() const { return std::string((char const*)m_data, ((char const*)m_data) + m_count * sizeof(_T)); }
+
+ template <class _T2> explicit operator vector_ref<_T2>() const { assert(m_count * sizeof(_T) / sizeof(_T2) * sizeof(_T2) / sizeof(_T) == m_count); return vector_ref<_T2>(reinterpret_cast<_T2*>(m_data), m_count * sizeof(_T) / sizeof(_T2)); }
+ operator vector_ref<_T const>() const { return vector_ref<_T const>(m_data, m_count); }
+
+ _T* data() const { return m_data; }
+ /// @returns the number of elements referenced (not necessarily number of bytes).
+ size_t count() const { return m_count; }
+ /// @returns the number of elements referenced (not necessarily number of bytes).
+ size_t size() const { return m_count; }
+ bool empty() const { return !m_count; }
+ /// @returns a new vector_ref pointing at the next chunk of @a size() elements.
+ vector_ref<_T> next() const { if (!m_data) return *this; else return vector_ref<_T>(m_data + m_count, m_count); }
+ /// @returns a new vector_ref which is a shifted and shortened view of the original data.
+ /// If this goes out of bounds in any way, returns an empty vector_ref.
+ /// If @a _count is ~size_t(0), extends the view to the end of the data.
+ vector_ref<_T> cropped(size_t _begin, size_t _count) const { if (m_data && _begin <= m_count && _count <= m_count && _begin + _count <= m_count) return vector_ref<_T>(m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count); else return vector_ref<_T>(); }
+ /// @returns a new vector_ref which is a shifted view of the original data (not going beyond it).
+ vector_ref<_T> cropped(size_t _begin) const { if (m_data && _begin <= m_count) return vector_ref<_T>(m_data + _begin, m_count - _begin); else return vector_ref<_T>(); }
+ void retarget(_T* _d, size_t _s) { m_data = _d; m_count = _s; }
+ void retarget(std::vector<_T> const& _t) { m_data = _t.data(); m_count = _t.size(); }
+ template <class T> bool overlapsWith(vector_ref<T> _t) const { void const* f1 = data(); void const* t1 = data() + size(); void const* f2 = _t.data(); void const* t2 = _t.data() + _t.size(); return f1 < t2 && t1 > f2; }
+ /// Copies the contents of this vector_ref to the contents of @a _t, up to the max size of @a _t.
+ void copyTo(vector_ref<typename std::remove_const<_T>::type> _t) const { if (overlapsWith(_t)) memmove(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); else memcpy(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); }
+ /// Copies the contents of this vector_ref to the contents of @a _t, and zeros further trailing elements in @a _t.
+ void populate(vector_ref<typename std::remove_const<_T>::type> _t) const { copyTo(_t); memset(_t.data() + m_count, 0, std::max(_t.size(), m_count) - m_count); }
+ /// Securely overwrite the memory.
+ /// @note adapted from OpenSSL's implementation.
+ void cleanse()
+ {
+ static unsigned char s_cleanseCounter = 0;
+ uint8_t* p = (uint8_t*)begin();
+ size_t const len = (uint8_t*)end() - p;
+ size_t loop = len;
+ size_t count = s_cleanseCounter;
+ while (loop--)
+ {
+ *(p++) = (uint8_t)count;
+ count += (17 + ((size_t)p & 0xf));
+ }
+ p = (uint8_t*)memchr((uint8_t*)begin(), (uint8_t)count, len);
+ if (p)
+ count += (63 + (size_t)p);
+ s_cleanseCounter = (uint8_t)count;
+ memset((uint8_t*)begin(), 0, len);
+ }
+
+ _T* begin() { return m_data; }
+ _T* end() { return m_data + m_count; }
+ _T const* begin() const { return m_data; }
+ _T const* end() const { return m_data + m_count; }
+
+ _T& operator[](size_t _i) { assert(m_data); assert(_i < m_count); return m_data[_i]; }
+ _T const& operator[](size_t _i) const { assert(m_data); assert(_i < m_count); return m_data[_i]; }
+
+ bool operator==(vector_ref<_T> const& _cmp) const { return m_data == _cmp.m_data && m_count == _cmp.m_count; }
+ bool operator!=(vector_ref<_T> const& _cmp) const { return !operator==(_cmp); }
+
+#if DEV_LDB
+ operator ldb::Slice() const { return ldb::Slice((char const*)m_data, m_count * sizeof(_T)); }
+#endif
+
+ void reset() { m_data = nullptr; m_count = 0; }
+
+private:
+ _T* m_data;
+ size_t m_count;
+};
+
+template<class _T> vector_ref<_T const> ref(_T const& _t) { return vector_ref<_T const>(&_t, 1); }
+template<class _T> vector_ref<_T> ref(_T& _t) { return vector_ref<_T>(&_t, 1); }
+template<class _T> vector_ref<_T const> ref(std::vector<_T> const& _t) { return vector_ref<_T const>(&_t); }
+template<class _T> vector_ref<_T> ref(std::vector<_T>& _t) { return vector_ref<_T>(&_t); }
+
+}