diff --git a/src/Makefile.am b/src/Makefile.am
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -385,9 +385,7 @@
   seeder/netbase.h \
   seeder/protocol.cpp \
   seeder/protocol.h \
-  seeder/serialize.h \
   seeder/strlcpy.h \
-  seeder/uint256.h \
   seeder/util.cpp \
   seeder/util.h
 
@@ -444,7 +442,9 @@
 bitcoin_seeder_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
 bitcoin_seeder_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
 
-bitcoin_seeder_LDADD = $(LIBBITCOIN_SEEDER)
+bitcoin_seeder_LDADD = \
+  $(LIBBITCOIN_SEEDER) \
+  $(LIBBITCOIN_UTIL)
 
 bitcoin_seeder_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS)
 #
diff --git a/src/seeder/bitcoin.cpp b/src/seeder/bitcoin.cpp
--- a/src/seeder/bitcoin.cpp
+++ b/src/seeder/bitcoin.cpp
@@ -3,6 +3,7 @@
 #include "db.h"
 #include "netbase.h"
 #include "serialize.h"
+#include "streams.h"
 #include "uint256.h"
 
 #include <algorithm>
@@ -166,7 +167,8 @@
             CDataStream::iterator pstart =
                 search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart),
                        END(pchMessageStart));
-            int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader());
+            int nHeaderSize = GetSerializeSize(
+                CMessageHeader(), vRecv.GetType(), vRecv.GetVersion());
             if (vRecv.end() - pstart < nHeaderSize) {
                 if (vRecv.size() > nHeaderSize) {
                     vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize);
@@ -204,7 +206,7 @@
                 if (nChecksum != hdr.nChecksum) continue;
             }
             CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize,
-                             vRecv.nType, vRecv.nVersion);
+                             vRecv.GetType(), vRecv.GetVersion());
             vRecv.ignore(nMessageSize);
             if (ProcessMessage(strCommand, vMsg)) return true;
             //      printf("%s: done processing %s\n", ToString(you).c_str(),
@@ -215,17 +217,15 @@
 
 public:
     CNode(const CService &ip, std::vector<CAddress> *vAddrIn)
-        : you(ip), nHeaderStart(-1), nMessageStart(-1), vAddr(vAddrIn), ban(0),
+        : vSend(SER_NETWORK, 0), vRecv(SER_NETWORK, 0), you(ip),
+          nHeaderStart(-1), nMessageStart(-1), vAddr(vAddrIn), ban(0),
           doneAfter(0), nVersion(0) {
-        vSend.SetType(SER_NETWORK);
-        vSend.SetVersion(0);
-        vRecv.SetType(SER_NETWORK);
-        vRecv.SetVersion(0);
         if (time(nullptr) > 1329696000) {
             vSend.SetVersion(209);
             vRecv.SetVersion(209);
         }
     }
+
     bool Run() {
         bool res = true;
         if (!ConnectSocket(you, sock)) return false;
diff --git a/src/seeder/db.h b/src/seeder/db.h
--- a/src/seeder/db.h
+++ b/src/seeder/db.h
@@ -5,6 +5,7 @@
 #include "protocol.h"
 #include "sync.h"
 #include "util.h"
+#include "version.h"
 
 #include <cmath>
 #include <cstdint>
@@ -44,8 +45,14 @@
         weight = weight * f + (1.0 - f);
     }
 
-    IMPLEMENT_SERIALIZE(READWRITE(weight); READWRITE(count);
-                        READWRITE(reliability);)
+    ADD_SERIALIZE_METHODS;
+
+    template <typename Stream, typename Operation>
+    inline void SerializationOp(Stream &s, Operation ser_action) {
+        READWRITE(weight);
+        READWRITE(count);
+        READWRITE(reliability);
+    }
 
     friend class CAddrInfo;
 };
@@ -165,27 +172,37 @@
 
     friend class CAddrDb;
 
-    IMPLEMENT_SERIALIZE(uint8_t version = 4; READWRITE(version); READWRITE(ip);
-                        READWRITE(services); READWRITE(lastTry);
-                        uint8_t tried = ourLastTry != 0; READWRITE(tried);
-                        if (tried) {
-                            READWRITE(ourLastTry);
-                            READWRITE(ignoreTill);
-                            READWRITE(stat2H);
-                            READWRITE(stat8H);
-                            READWRITE(stat1D);
-                            READWRITE(stat1W);
-                            if (version >= 1)
-                                READWRITE(stat1M);
-                            else if (!fWrite)
-                                *((CAddrStat *)(&stat1M)) = stat1W;
-                            READWRITE(total);
-                            READWRITE(success);
-                            READWRITE(clientVersion);
-                            if (version >= 2) READWRITE(clientSubVersion);
-                            if (version >= 3) READWRITE(blocks);
-                            if (version >= 4) READWRITE(ourLastSuccess);
-                        })
+    ADD_SERIALIZE_METHODS;
+
+    template <typename Stream, typename Operation>
+    inline void SerializationOp(Stream &s, Operation ser_action) {
+        uint8_t version = 4;
+        READWRITE(version);
+        READWRITE(ip);
+        READWRITE(services);
+        READWRITE(lastTry);
+        uint8_t tried = ourLastTry != 0;
+        READWRITE(tried);
+        if (tried) {
+            READWRITE(ourLastTry);
+            READWRITE(ignoreTill);
+            READWRITE(stat2H);
+            READWRITE(stat8H);
+            READWRITE(stat1D);
+            READWRITE(stat1W);
+            if (version >= 1) {
+                READWRITE(stat1M);
+            } else if (!ser_action.ForRead()) {
+                *((CAddrStat *)(&stat1M)) = stat1W;
+            }
+            READWRITE(total);
+            READWRITE(success);
+            READWRITE(clientVersion);
+            if (version >= 2) READWRITE(clientSubVersion);
+            if (version >= 3) READWRITE(blocks);
+            if (version >= 4) READWRITE(ourLastSuccess);
+        }
+    }
 };
 
 class CAddrDbStats {
@@ -299,53 +316,57 @@
     // assume that only happens at startup, single-threaded)
     // this way, dumping does not interfere with GetIPs_, which is called from
     // the DNS thread
-    IMPLEMENT_SERIALIZE(({
-                            int nVersion = 0;
-                            READWRITE(nVersion);
-                            LOCK(cs);
-                            if (fWrite) {
-                                CAddrDb *db = const_cast<CAddrDb *>(this);
-                                int n = ourId.size() + unkId.size();
-                                READWRITE(n);
-                                for (std::deque<int>::const_iterator it =
-                                         ourId.begin();
-                                     it != ourId.end(); it++) {
-                                    std::map<int, CAddrInfo>::iterator ci =
-                                        db->idToInfo.find(*it);
-                                    READWRITE((*ci).second);
-                                }
-                                for (std::set<int>::const_iterator it =
-                                         unkId.begin();
-                                     it != unkId.end(); it++) {
-                                    std::map<int, CAddrInfo>::iterator ci =
-                                        db->idToInfo.find(*it);
-                                    READWRITE((*ci).second);
-                                }
-                            } else {
-                                CAddrDb *db = const_cast<CAddrDb *>(this);
-                                db->nId = 0;
-                                int n;
-                                READWRITE(n);
-                                for (int i = 0; i < n; i++) {
-                                    CAddrInfo info;
-                                    READWRITE(info);
-                                    if (!info.GetBanTime()) {
-                                        int id = db->nId++;
-                                        db->idToInfo[id] = info;
-                                        db->ipToId[info.ip] = id;
-                                        if (info.ourLastTry) {
-                                            db->ourId.push_back(id);
-                                            if (info.IsGood())
-                                                db->goodId.insert(id);
-                                        } else {
-                                            db->unkId.insert(id);
-                                        }
-                                    }
-                                }
-                                db->nDirty++;
-                            }
-                            READWRITE(banned);
-                        });)
+    template <typename Stream> void Serialize(Stream &s) const {
+        LOCK(cs);
+
+        int nVersion = 0;
+        s << nVersion;
+
+        CAddrDb *db = const_cast<CAddrDb *>(this);
+        int n = ourId.size() + unkId.size();
+        s << n;
+        for (std::deque<int>::const_iterator it = ourId.begin();
+             it != ourId.end(); it++) {
+            std::map<int, CAddrInfo>::iterator ci = db->idToInfo.find(*it);
+            s << (*ci).second;
+        }
+        for (std::set<int>::const_iterator it = unkId.begin();
+             it != unkId.end(); it++) {
+            std::map<int, CAddrInfo>::iterator ci = db->idToInfo.find(*it);
+            s << (*ci).second;
+        }
+        s << banned;
+    }
+
+    template <typename Stream> void Unserialize(Stream &s) {
+        LOCK(cs);
+
+        int nVersion;
+        s >> nVersion;
+
+        CAddrDb *db = const_cast<CAddrDb *>(this);
+        db->nId = 0;
+        int n;
+        s >> n;
+        for (int i = 0; i < n; i++) {
+            CAddrInfo info;
+            s >> info;
+            if (!info.GetBanTime()) {
+                int id = db->nId++;
+                db->idToInfo[id] = info;
+                db->ipToId[info.ip] = id;
+                if (info.ourLastTry) {
+                    db->ourId.push_back(id);
+                    if (info.IsGood()) db->goodId.insert(id);
+                } else {
+                    db->unkId.insert(id);
+                }
+            }
+        }
+        db->nDirty++;
+
+        s >> banned;
+    }
 
     void Add(const CAddress &addr, bool fForce = false) {
         LOCK(cs);
diff --git a/src/seeder/main.cpp b/src/seeder/main.cpp
--- a/src/seeder/main.cpp
+++ b/src/seeder/main.cpp
@@ -1,5 +1,7 @@
 #include "bitcoin.h"
+#include "clientversion.h"
 #include "db.h"
+#include "streams.h"
 
 #include <algorithm>
 #include <atomic>
@@ -360,7 +362,7 @@
             FILE *f = fopen("dnsseed.dat.new", "w+");
             if (f) {
                 {
-                    CAutoFile cf(f);
+                    CAutoFile cf(f, SER_DISK, CLIENT_VERSION);
                     cf << db;
                 }
                 rename("dnsseed.dat.new", "dnsseed.dat");
@@ -434,12 +436,9 @@
     "seed.bitcoinabc.org", "seed-abc.bitcoinforks.org", "seed.bitprim.org",
     "seed.deadalnix.me",   "seeder.criptolayer.net",    ""};
 static const std::string testnet_seeds[] = {
-    "testnet-seed.bitcoinabc.org",
-    "testnet-seed-abc.bitcoinforks.org",
-    "testnet-seed.bitprim.org",
-    "testnet-seed.deadalnix.me",
-    "testnet-seeder.criptolayer.net",
-    ""};
+    "testnet-seed.bitcoinabc.org",    "testnet-seed-abc.bitcoinforks.org",
+    "testnet-seed.bitprim.org",       "testnet-seed.deadalnix.me",
+    "testnet-seeder.criptolayer.net", ""};
 static const std::string *seeds = mainnet_seeds;
 
 extern "C" void *ThreadSeeder(void *) {
@@ -521,7 +520,7 @@
     FILE *f = fopen("dnsseed.dat", "r");
     if (f) {
         printf("Loading dnsseed.dat...");
-        CAutoFile cf(f);
+        CAutoFile cf(f, SER_DISK, CLIENT_VERSION);
         cf >> db;
         if (opts.fWipeBan) db.banned.clear();
         if (opts.fWipeIgnore) db.ResetIgnores();
diff --git a/src/seeder/netbase.h b/src/seeder/netbase.h
--- a/src/seeder/netbase.h
+++ b/src/seeder/netbase.h
@@ -81,7 +81,12 @@
     friend bool operator!=(const CNetAddr &a, const CNetAddr &b);
     friend bool operator<(const CNetAddr &a, const CNetAddr &b);
 
-    IMPLEMENT_SERIALIZE(READWRITE(FLATDATA(ip));)
+    ADD_SERIALIZE_METHODS;
+
+    template <typename Stream, typename Operation>
+    inline void SerializationOp(Stream &s, Operation ser_action) {
+        READWRITE(FLATDATA(ip));
+    }
 };
 
 /** A combination of a network address (CNetAddr) and a (TCP) port */
@@ -117,10 +122,18 @@
     CService(const struct in6_addr &ipv6Addr, unsigned short port);
     CService(const struct sockaddr_in6 &addr);
 
-    IMPLEMENT_SERIALIZE(CService *pthis = const_cast<CService *>(this);
-                        READWRITE(FLATDATA(ip));
-                        unsigned short portN = htons(port); READWRITE(portN);
-                        if (fRead) pthis->port = ntohs(portN);)
+    ADD_SERIALIZE_METHODS;
+
+    template <typename Stream, typename Operation>
+    inline void SerializationOp(Stream &s, Operation ser_action) {
+        CService *pthis = const_cast<CService *>(this);
+        READWRITE(FLATDATA(ip));
+        unsigned short portN = htons(port);
+        READWRITE(portN);
+        if (ser_action.ForRead()) {
+            pthis->port = ntohs(portN);
+        }
+    }
 };
 
 enum Network ParseNetwork(std::string net);
diff --git a/src/seeder/protocol.h b/src/seeder/protocol.h
--- a/src/seeder/protocol.h
+++ b/src/seeder/protocol.h
@@ -39,10 +39,17 @@
     std::string GetCommand() const;
     bool IsValid() const;
 
-    IMPLEMENT_SERIALIZE(READWRITE(FLATDATA(pchMessageStart));
-                        READWRITE(FLATDATA(pchCommand));
-                        READWRITE(nMessageSize);
-                        if (nVersion >= 209) READWRITE(nChecksum);)
+    ADD_SERIALIZE_METHODS;
+
+    template <typename Stream, typename Operation>
+    inline void SerializationOp(Stream &s, Operation ser_action) {
+        READWRITE(FLATDATA(pchMessageStart));
+        READWRITE(FLATDATA(pchCommand));
+        READWRITE(nMessageSize);
+        if (s.GetVersion() >= 209) {
+            READWRITE(nChecksum);
+        }
+    }
 
     // TODO: make private (improves encapsulation)
 public:
@@ -68,14 +75,26 @@
 
     void Init();
 
-    IMPLEMENT_SERIALIZE(CAddress *pthis = const_cast<CAddress *>(this);
-                        CService *pip = (CService *)pthis;
-                        if (fRead) pthis->Init();
-                        if (nType & SER_DISK) READWRITE(nVersion);
-                        if ((nType & SER_DISK) ||
-                            (nVersion >= 31402 && !(nType & SER_GETHASH)))
-                            READWRITE(nTime);
-                        READWRITE(nServices); READWRITE(*pip);)
+    ADD_SERIALIZE_METHODS;
+
+    template <typename Stream, typename Operation>
+    inline void SerializationOp(Stream &s, Operation ser_action) {
+        int nVersion = s.GetVersion();
+        CAddress *pthis = const_cast<CAddress *>(this);
+        CService *pip = (CService *)pthis;
+        if (ser_action.ForRead()) {
+            pthis->Init();
+        }
+        if (s.GetType() & SER_DISK) {
+            READWRITE(nVersion);
+        }
+        if ((s.GetType() & SER_DISK) ||
+            (nVersion >= 31402 && !(s.GetType() & SER_GETHASH))) {
+            READWRITE(nTime);
+        }
+        READWRITE(nServices);
+        READWRITE(*pip);
+    }
 
     void print() const;
 
@@ -93,7 +112,13 @@
     CInv(int typeIn, const uint256 &hashIn);
     CInv(const std::string &strType, const uint256 &hashIn);
 
-    IMPLEMENT_SERIALIZE(READWRITE(type); READWRITE(hash);)
+    ADD_SERIALIZE_METHODS;
+
+    template <typename Stream, typename Operation>
+    inline void SerializationOp(Stream &s, Operation ser_action) {
+        READWRITE(type);
+        READWRITE(hash);
+    }
 
     friend bool operator<(const CInv &a, const CInv &b);
 
diff --git a/src/seeder/protocol.cpp b/src/seeder/protocol.cpp
--- a/src/seeder/protocol.cpp
+++ b/src/seeder/protocol.cpp
@@ -90,7 +90,7 @@
 
 CInv::CInv() {
     type = 0;
-    hash = 0;
+    hash.SetNull();
 }
 
 CInv::CInv(int typeIn, const uint256 &hashIn) {
diff --git a/src/seeder/serialize.h b/src/seeder/serialize.h
deleted file mode 100644
--- a/src/seeder/serialize.h
+++ /dev/null
@@ -1,1320 +0,0 @@
-// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-#ifndef BITCOIN_SEEDER_SERIALIZE_H
-#define BITCOIN_SEEDER_SERIALIZE_H
-
-#include <cassert>
-#include <climits>
-#include <cstdint>
-#include <cstdio>
-#include <cstring>
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-
-#include <boost/tuple/tuple.hpp>
-#include <boost/tuple/tuple_comparison.hpp>
-#include <boost/tuple/tuple_io.hpp>
-#include <boost/type_traits/is_fundamental.hpp>
-
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#define for if (false); else for
-#endif
-
-#ifdef WIN32
-#include <windows.h>
-// This is used to attempt to keep keying material out of swap
-// Note that VirtualLock does not provide this as a guarantee on Windows,
-// but, in practice, memory that has been VirtualLock'd almost never gets
-// written to
-// the pagefile except in rare circumstances where memory is extremely low.
-#include <windows.h>
-#define mlock(p, n) VirtualLock((p), (n));
-#define munlock(p, n) VirtualUnlock((p), (n));
-#else
-#include <climits>
-#include <sys/mman.h>
-/* This comes from limits.h if it's not defined there set a sane default */
-#ifndef PAGESIZE
-#include <unistd.h>
-#define PAGESIZE sysconf(_SC_PAGESIZE)
-#endif
-#define mlock(a, b)                                                            \
-    mlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),                       \
-          (((((size_t)(a)) + (b)-1) | ((PAGESIZE)-1)) + 1) -                   \
-              (((size_t)(a)) & (~((PAGESIZE)-1))))
-#define munlock(a, b)                                                          \
-    munlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),                     \
-            (((((size_t)(a)) + (b)-1) | ((PAGESIZE)-1)) + 1) -                 \
-                (((size_t)(a)) & (~((PAGESIZE)-1))))
-#endif
-
-class CScript;
-class CDataStream;
-class CAutoFile;
-static const unsigned int MAX_SIZE = 0x02000000;
-
-static const int PROTOCOL_VERSION = 60000;
-
-// Used to bypass the rule against non-const reference to temporary
-// where it makes sense with wrappers such as CFlatData or CTxDB
-template <typename T> inline T &REF(const T &val) {
-    return const_cast<T &>(val);
-}
-
-/////////////////////////////////////////////////////////////////
-//
-// Templates for serializing to anything that looks like a stream,
-// i.e. anything that supports .read(char*, int) and .write(char*, int)
-//
-
-enum {
-    // primary actions
-    SER_NETWORK = (1 << 0),
-    SER_DISK = (1 << 1),
-    SER_GETHASH = (1 << 2),
-
-    // modifiers
-    SER_SKIPSIG = (1 << 16),
-    SER_BLOCKHEADERONLY = (1 << 17),
-};
-
-#define IMPLEMENT_SERIALIZE(statements)                                        \
-    unsigned int GetSerializeSize(int nType = 0,                               \
-                                  int nVersion = PROTOCOL_VERSION) const {     \
-        CSerActionGetSerializeSize ser_action;                                 \
-        const bool fGetSize = true;                                            \
-        const bool fWrite = false;                                             \
-        const bool fRead = false;                                              \
-        unsigned int nSerSize = 0;                                             \
-        ser_streamplaceholder s;                                               \
-        s.nType = nType;                                                       \
-        s.nVersion = nVersion;                                                 \
-        { statements }                                                         \
-        return nSerSize;                                                       \
-    }                                                                          \
-    template <typename Stream>                                                 \
-    void Serialize(Stream &s, int nType = 0, int nVersion = PROTOCOL_VERSION)  \
-        const {                                                                \
-        CSerActionSerialize ser_action;                                        \
-        const bool fGetSize = false;                                           \
-        const bool fWrite = true;                                              \
-        const bool fRead = false;                                              \
-        unsigned int nSerSize = 0;                                             \
-        { statements }                                                         \
-    }                                                                          \
-    template <typename Stream>                                                 \
-    void Unserialize(Stream &s, int nType = 0,                                 \
-                     int nVersion = PROTOCOL_VERSION) {                        \
-        CSerActionUnserialize ser_action;                                      \
-        const bool fGetSize = false;                                           \
-        const bool fWrite = false;                                             \
-        const bool fRead = true;                                               \
-        unsigned int nSerSize = 0;                                             \
-        { statements }                                                         \
-    }
-
-#define READWRITE(obj)                                                         \
-    (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action))
-
-//
-// Basic types
-//
-#define WRITEDATA(s, obj) s.write((char *)&(obj), sizeof(obj))
-#define READDATA(s, obj) s.read((char *)&(obj), sizeof(obj))
-
-inline unsigned int GetSerializeSize(int8_t a, int, int = 0) {
-    return sizeof(a);
-}
-inline unsigned int GetSerializeSize(uint8_t a, int, int = 0) {
-    return sizeof(a);
-}
-inline unsigned int GetSerializeSize(int16_t a, int, int = 0) {
-    return sizeof(a);
-}
-inline unsigned int GetSerializeSize(uint16_t a, int, int = 0) {
-    return sizeof(a);
-}
-inline unsigned int GetSerializeSize(int32_t a, int, int = 0) {
-    return sizeof(a);
-}
-inline unsigned int GetSerializeSize(uint32_t a, int, int = 0) {
-    return sizeof(a);
-}
-inline unsigned int GetSerializeSize(int64_t a, int, int = 0) {
-    return sizeof(a);
-}
-inline unsigned int GetSerializeSize(uint64_t a, int, int = 0) {
-    return sizeof(a);
-}
-inline unsigned int GetSerializeSize(float a, int, int = 0) {
-    return sizeof(a);
-}
-inline unsigned int GetSerializeSize(double a, int, int = 0) {
-    return sizeof(a);
-}
-
-template <typename Stream>
-inline void Serialize(Stream &s, int8_t a, int, int = 0) {
-    WRITEDATA(s, a);
-}
-template <typename Stream>
-inline void Serialize(Stream &s, uint8_t a, int, int = 0) {
-    WRITEDATA(s, a);
-}
-template <typename Stream>
-inline void Serialize(Stream &s, int16_t a, int, int = 0) {
-    WRITEDATA(s, a);
-}
-template <typename Stream>
-inline void Serialize(Stream &s, uint16_t a, int, int = 0) {
-    WRITEDATA(s, a);
-}
-template <typename Stream>
-inline void Serialize(Stream &s, int32_t a, int, int = 0) {
-    WRITEDATA(s, a);
-}
-template <typename Stream>
-inline void Serialize(Stream &s, uint32_t a, int, int = 0) {
-    WRITEDATA(s, a);
-}
-template <typename Stream>
-inline void Serialize(Stream &s, int64_t a, int, int = 0) {
-    WRITEDATA(s, a);
-}
-template <typename Stream>
-inline void Serialize(Stream &s, uint64_t a, int, int = 0) {
-    WRITEDATA(s, a);
-}
-template <typename Stream>
-inline void Serialize(Stream &s, float a, int, int = 0) {
-    WRITEDATA(s, a);
-}
-template <typename Stream>
-inline void Serialize(Stream &s, double a, int, int = 0) {
-    WRITEDATA(s, a);
-}
-
-template <typename Stream>
-inline void Unserialize(Stream &s, int8_t &a, int, int = 0) {
-    READDATA(s, a);
-}
-template <typename Stream>
-inline void Unserialize(Stream &s, uint8_t &a, int, int = 0) {
-    READDATA(s, a);
-}
-template <typename Stream>
-inline void Unserialize(Stream &s, int16_t &a, int, int = 0) {
-    READDATA(s, a);
-}
-template <typename Stream>
-inline void Unserialize(Stream &s, uint16_t &a, int, int = 0) {
-    READDATA(s, a);
-}
-template <typename Stream>
-inline void Unserialize(Stream &s, int32_t &a, int, int = 0) {
-    READDATA(s, a);
-}
-template <typename Stream>
-inline void Unserialize(Stream &s, uint32_t &a, int, int = 0) {
-    READDATA(s, a);
-}
-template <typename Stream>
-inline void Unserialize(Stream &s, int64_t &a, int, int = 0) {
-    READDATA(s, a);
-}
-template <typename Stream>
-inline void Unserialize(Stream &s, uint64_t &a, int, int = 0) {
-    READDATA(s, a);
-}
-template <typename Stream>
-inline void Unserialize(Stream &s, float &a, int, int = 0) {
-    READDATA(s, a);
-}
-template <typename Stream>
-inline void Unserialize(Stream &s, double &a, int, int = 0) {
-    READDATA(s, a);
-}
-
-inline unsigned int GetSerializeSize(bool a, int, int = 0) {
-    return sizeof(char);
-}
-template <typename Stream>
-inline void Serialize(Stream &s, bool a, int, int = 0) {
-    char f = a;
-    WRITEDATA(s, f);
-}
-template <typename Stream>
-inline void Unserialize(Stream &s, bool &a, int, int = 0) {
-    char f;
-    READDATA(s, f);
-    a = f;
-}
-
-//
-// Compact size
-//  size <  253        -- 1 byte
-//  size <= USHRT_MAX  -- 3 bytes  (253 + 2 bytes)
-//  size <= UINT_MAX   -- 5 bytes  (254 + 4 bytes)
-//  size >  UINT_MAX   -- 9 bytes  (255 + 8 bytes)
-//
-inline unsigned int GetSizeOfCompactSize(uint64_t nSize) {
-    if (nSize < 253)
-        return sizeof(uint8_t);
-    else if (nSize <= USHRT_MAX)
-        return sizeof(uint8_t) + sizeof(uint16_t);
-    else if (nSize <= UINT_MAX)
-        return sizeof(uint8_t) + sizeof(uint32_t);
-    else
-        return sizeof(uint8_t) + sizeof(uint64_t);
-}
-
-template <typename Stream> void WriteCompactSize(Stream &os, uint64_t nSize) {
-    if (nSize < 253) {
-        uint8_t chSize = nSize;
-        WRITEDATA(os, chSize);
-    } else if (nSize <= USHRT_MAX) {
-        uint8_t chSize = 253;
-        uint16_t xSize = nSize;
-        WRITEDATA(os, chSize);
-        WRITEDATA(os, xSize);
-    } else if (nSize <= UINT_MAX) {
-        uint8_t chSize = 254;
-        uint32_t xSize = nSize;
-        WRITEDATA(os, chSize);
-        WRITEDATA(os, xSize);
-    } else {
-        uint8_t chSize = 255;
-        uint64_t xSize = nSize;
-        WRITEDATA(os, chSize);
-        WRITEDATA(os, xSize);
-    }
-    return;
-}
-
-template <typename Stream> uint64_t ReadCompactSize(Stream &is) {
-    uint8_t chSize;
-    READDATA(is, chSize);
-    uint64_t nSizeRet = 0;
-    if (chSize < 253) {
-        nSizeRet = chSize;
-    } else if (chSize == 253) {
-        uint16_t xSize;
-        READDATA(is, xSize);
-        nSizeRet = xSize;
-    } else if (chSize == 254) {
-        uint32_t xSize;
-        READDATA(is, xSize);
-        nSizeRet = xSize;
-    } else {
-        uint64_t xSize;
-        READDATA(is, xSize);
-        nSizeRet = xSize;
-    }
-    if (nSizeRet > uint64_t(MAX_SIZE)) {
-        throw std::ios_base::failure("ReadCompactSize() : size too large");
-    }
-    return nSizeRet;
-}
-
-//
-// Wrapper for serializing arrays and POD
-// There's a clever template way to make arrays serialize normally, but MSVC6
-// doesn't support it
-//
-#define FLATDATA(obj)                                                          \
-    REF(CFlatData((char *)&(obj), (char *)&(obj) + sizeof(obj)))
-class CFlatData {
-protected:
-    char *pbegin;
-    char *pend;
-
-public:
-    CFlatData(void *pbeginIn, void *pendIn)
-        : pbegin((char *)pbeginIn), pend((char *)pendIn) {}
-    char *begin() { return pbegin; }
-    const char *begin() const { return pbegin; }
-    char *end() { return pend; }
-    const char *end() const { return pend; }
-
-    unsigned int GetSerializeSize(int, int = 0) const { return pend - pbegin; }
-
-    template <typename Stream> void Serialize(Stream &s, int, int = 0) const {
-        s.write(pbegin, pend - pbegin);
-    }
-
-    template <typename Stream> void Unserialize(Stream &s, int, int = 0) {
-        s.read(pbegin, pend - pbegin);
-    }
-};
-
-//
-// string stored as a fixed length field
-//
-template <std::size_t LEN> class CFixedFieldString {
-protected:
-    const std::string *pcstr;
-    std::string *pstr;
-
-public:
-    explicit CFixedFieldString(const std::string &str)
-        : pcstr(&str), pstr(nullptr) {}
-    explicit CFixedFieldString(std::string &str) : pcstr(&str), pstr(&str) {}
-
-    unsigned int GetSerializeSize(int, int = 0) const { return LEN; }
-
-    template <typename Stream> void Serialize(Stream &s, int, int = 0) const {
-        char pszBuf[LEN];
-        strncpy(pszBuf, pcstr->c_str(), LEN);
-        s.write(pszBuf, LEN);
-    }
-
-    template <typename Stream> void Unserialize(Stream &s, int, int = 0) {
-        if (pstr == nullptr)
-            throw std::ios_base::failure("CFixedFieldString::Unserialize : "
-                                         "trying to unserialize to const "
-                                         "string");
-        char pszBuf[LEN + 1];
-        s.read(pszBuf, LEN);
-        pszBuf[LEN] = '\0';
-        *pstr = pszBuf;
-    }
-};
-
-//
-// Forward declarations
-//
-
-// string
-template <typename C>
-unsigned int GetSerializeSize(const std::basic_string<C> &str, int, int = 0);
-template <typename Stream, typename C>
-void Serialize(Stream &os, const std::basic_string<C> &str, int, int = 0);
-template <typename Stream, typename C>
-void Unserialize(Stream &is, std::basic_string<C> &str, int, int = 0);
-
-// vector
-template <typename T, typename A>
-unsigned int GetSerializeSize_impl(const std::vector<T, A> &v, int nType,
-                                   int nVersion, const boost::true_type &);
-template <typename T, typename A>
-unsigned int GetSerializeSize_impl(const std::vector<T, A> &v, int nType,
-                                   int nVersion, const boost::false_type &);
-template <typename T, typename A>
-inline unsigned int GetSerializeSize(const std::vector<T, A> &v, int nType,
-                                     int nVersion = PROTOCOL_VERSION);
-template <typename Stream, typename T, typename A>
-void Serialize_impl(Stream &os, const std::vector<T, A> &v, int nType,
-                    int nVersion, const boost::true_type &);
-template <typename Stream, typename T, typename A>
-void Serialize_impl(Stream &os, const std::vector<T, A> &v, int nType,
-                    int nVersion, const boost::false_type &);
-template <typename Stream, typename T, typename A>
-inline void Serialize(Stream &os, const std::vector<T, A> &v, int nType,
-                      int nVersion = PROTOCOL_VERSION);
-template <typename Stream, typename T, typename A>
-void Unserialize_impl(Stream &is, std::vector<T, A> &v, int nType, int nVersion,
-                      const boost::true_type &);
-template <typename Stream, typename T, typename A>
-void Unserialize_impl(Stream &is, std::vector<T, A> &v, int nType, int nVersion,
-                      const boost::false_type &);
-template <typename Stream, typename T, typename A>
-inline void Unserialize(Stream &is, std::vector<T, A> &v, int nType,
-                        int nVersion = PROTOCOL_VERSION);
-
-// others derived from vector
-extern inline unsigned int GetSerializeSize(const CScript &v, int nType,
-                                            int nVersion = PROTOCOL_VERSION);
-template <typename Stream>
-void Serialize(Stream &os, const CScript &v, int nType,
-               int nVersion = PROTOCOL_VERSION);
-template <typename Stream>
-void Unserialize(Stream &is, CScript &v, int nType,
-                 int nVersion = PROTOCOL_VERSION);
-
-// pair
-template <typename K, typename T>
-unsigned int GetSerializeSize(const std::pair<K, T> &item, int nType,
-                              int nVersion = PROTOCOL_VERSION);
-template <typename Stream, typename K, typename T>
-void Serialize(Stream &os, const std::pair<K, T> &item, int nType,
-               int nVersion = PROTOCOL_VERSION);
-template <typename Stream, typename K, typename T>
-void Unserialize(Stream &is, std::pair<K, T> &item, int nType,
-                 int nVersion = PROTOCOL_VERSION);
-
-// 3 tuple
-template <typename T0, typename T1, typename T2>
-unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2> &item, int nType,
-                              int nVersion = PROTOCOL_VERSION);
-template <typename Stream, typename T0, typename T1, typename T2>
-void Serialize(Stream &os, const boost::tuple<T0, T1, T2> &item, int nType,
-               int nVersion = PROTOCOL_VERSION);
-template <typename Stream, typename T0, typename T1, typename T2>
-void Unserialize(Stream &is, boost::tuple<T0, T1, T2> &item, int nType,
-                 int nVersion = PROTOCOL_VERSION);
-
-// 4 tuple
-template <typename T0, typename T1, typename T2, typename T3>
-unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3> &item,
-                              int nType, int nVersion = PROTOCOL_VERSION);
-template <typename Stream, typename T0, typename T1, typename T2, typename T3>
-void Serialize(Stream &os, const boost::tuple<T0, T1, T2, T3> &item, int nType,
-               int nVersion = PROTOCOL_VERSION);
-template <typename Stream, typename T0, typename T1, typename T2, typename T3>
-void Unserialize(Stream &is, boost::tuple<T0, T1, T2, T3> &item, int nType,
-                 int nVersion = PROTOCOL_VERSION);
-
-// map
-template <typename K, typename T, typename Pred, typename A>
-unsigned int GetSerializeSize(const std::map<K, T, Pred, A> &m, int nType,
-                              int nVersion = PROTOCOL_VERSION);
-template <typename Stream, typename K, typename T, typename Pred, typename A>
-void Serialize(Stream &os, const std::map<K, T, Pred, A> &m, int nType,
-               int nVersion = PROTOCOL_VERSION);
-template <typename Stream, typename K, typename T, typename Pred, typename A>
-void Unserialize(Stream &is, std::map<K, T, Pred, A> &m, int nType,
-                 int nVersion = PROTOCOL_VERSION);
-
-// set
-template <typename K, typename Pred, typename A>
-unsigned int GetSerializeSize(const std::set<K, Pred, A> &m, int nType,
-                              int nVersion = PROTOCOL_VERSION);
-template <typename Stream, typename K, typename Pred, typename A>
-void Serialize(Stream &os, const std::set<K, Pred, A> &m, int nType,
-               int nVersion = PROTOCOL_VERSION);
-template <typename Stream, typename K, typename Pred, typename A>
-void Unserialize(Stream &is, std::set<K, Pred, A> &m, int nType,
-                 int nVersion = PROTOCOL_VERSION);
-
-//
-// If none of the specialized versions above matched, default to calling member
-// function.
-// "int nType" is changed to "long nType" to keep from getting an ambiguous
-// overload error.
-// The compiler will only cast int to long if none of the other templates
-// matched.
-// Thanks to Boost serialization for this idea.
-//
-template <typename T>
-inline unsigned int GetSerializeSize(const T &a, long nType,
-                                     int nVersion = PROTOCOL_VERSION) {
-    return a.GetSerializeSize((int)nType, nVersion);
-}
-
-template <typename Stream, typename T>
-inline void Serialize(Stream &os, const T &a, long nType,
-                      int nVersion = PROTOCOL_VERSION) {
-    a.Serialize(os, (int)nType, nVersion);
-}
-
-template <typename Stream, typename T>
-inline void Unserialize(Stream &is, T &a, long nType,
-                        int nVersion = PROTOCOL_VERSION) {
-    a.Unserialize(is, (int)nType, nVersion);
-}
-
-//
-// string
-//
-template <typename C>
-unsigned int GetSerializeSize(const std::basic_string<C> &str, int, int) {
-    return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]);
-}
-
-template <typename Stream, typename C>
-void Serialize(Stream &os, const std::basic_string<C> &str, int, int) {
-    WriteCompactSize(os, str.size());
-    if (!str.empty()) os.write((char *)&str[0], str.size() * sizeof(str[0]));
-}
-
-template <typename Stream, typename C>
-void Unserialize(Stream &is, std::basic_string<C> &str, int, int) {
-    unsigned int nSize = ReadCompactSize(is);
-    str.resize(nSize);
-    if (nSize != 0) is.read((char *)&str[0], nSize * sizeof(str[0]));
-}
-
-//
-// vector
-//
-template <typename T, typename A>
-unsigned int GetSerializeSize_impl(const std::vector<T, A> &v, int nType,
-                                   int nVersion, const boost::true_type &) {
-    return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
-}
-
-template <typename T, typename A>
-unsigned int GetSerializeSize_impl(const std::vector<T, A> &v, int nType,
-                                   int nVersion, const boost::false_type &) {
-    unsigned int nSize = GetSizeOfCompactSize(v.size());
-    for (typename std::vector<T, A>::const_iterator vi = v.begin();
-         vi != v.end(); ++vi)
-        nSize += GetSerializeSize((*vi), nType, nVersion);
-    return nSize;
-}
-
-template <typename T, typename A>
-inline unsigned int GetSerializeSize(const std::vector<T, A> &v, int nType,
-                                     int nVersion) {
-    return GetSerializeSize_impl(v, nType, nVersion,
-                                 boost::is_fundamental<T>());
-}
-
-template <typename Stream, typename T, typename A>
-void Serialize_impl(Stream &os, const std::vector<T, A> &v, int nType,
-                    int nVersion, const boost::true_type &) {
-    WriteCompactSize(os, v.size());
-    if (!v.empty()) os.write((char *)&v[0], v.size() * sizeof(T));
-}
-
-template <typename Stream, typename T, typename A>
-void Serialize_impl(Stream &os, const std::vector<T, A> &v, int nType,
-                    int nVersion, const boost::false_type &) {
-    WriteCompactSize(os, v.size());
-    for (typename std::vector<T, A>::const_iterator vi = v.begin();
-         vi != v.end(); ++vi)
-        ::Serialize(os, (*vi), nType, nVersion);
-}
-
-template <typename Stream, typename T, typename A>
-inline void Serialize(Stream &os, const std::vector<T, A> &v, int nType,
-                      int nVersion) {
-    Serialize_impl(os, v, nType, nVersion, boost::is_fundamental<T>());
-}
-
-template <typename Stream, typename T, typename A>
-void Unserialize_impl(Stream &is, std::vector<T, A> &v, int nType, int nVersion,
-                      const boost::true_type &) {
-    // unsigned int nSize = ReadCompactSize(is);
-    // v.resize(nSize);
-    // is.read((char*)&v[0], nSize * sizeof(T));
-
-    // Limit size per read so bogus size value won't cause out of memory
-    v.clear();
-    unsigned int nSize = ReadCompactSize(is);
-    unsigned int i = 0;
-    while (i < nSize) {
-        unsigned int blk =
-            std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
-        v.resize(i + blk);
-        is.read((char *)&v[i], blk * sizeof(T));
-        i += blk;
-    }
-}
-
-template <typename Stream, typename T, typename A>
-void Unserialize_impl(Stream &is, std::vector<T, A> &v, int nType, int nVersion,
-                      const boost::false_type &) {
-    // unsigned int nSize = ReadCompactSize(is);
-    // v.resize(nSize);
-    // for (std::vector<T, A>::iterator vi = v.begin(); vi != v.end(); ++vi)
-    //    Unserialize(is, (*vi), nType, nVersion);
-
-    v.clear();
-    unsigned int nSize = ReadCompactSize(is);
-    unsigned int i = 0;
-    unsigned int nMid = 0;
-    while (nMid < nSize) {
-        nMid += 5000000 / sizeof(T);
-        if (nMid > nSize) nMid = nSize;
-        v.resize(nMid);
-        for (; i < nMid; i++)
-            Unserialize(is, v[i], nType, nVersion);
-    }
-}
-
-template <typename Stream, typename T, typename A>
-inline void Unserialize(Stream &is, std::vector<T, A> &v, int nType,
-                        int nVersion) {
-    Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental<T>());
-}
-
-//
-// others derived from vector
-//
-inline unsigned int GetSerializeSize(const CScript &v, int nType,
-                                     int nVersion) {
-    return GetSerializeSize((const std::vector<uint8_t> &)v, nType, nVersion);
-}
-
-template <typename Stream>
-void Serialize(Stream &os, const CScript &v, int nType, int nVersion) {
-    Serialize(os, (const std::vector<uint8_t> &)v, nType, nVersion);
-}
-
-template <typename Stream>
-void Unserialize(Stream &is, CScript &v, int nType, int nVersion) {
-    Unserialize(is, (std::vector<uint8_t> &)v, nType, nVersion);
-}
-
-//
-// pair
-//
-template <typename K, typename T>
-unsigned int GetSerializeSize(const std::pair<K, T> &item, int nType,
-                              int nVersion) {
-    return GetSerializeSize(item.first, nType, nVersion) +
-           GetSerializeSize(item.second, nType, nVersion);
-}
-
-template <typename Stream, typename K, typename T>
-void Serialize(Stream &os, const std::pair<K, T> &item, int nType,
-               int nVersion) {
-    Serialize(os, item.first, nType, nVersion);
-    Serialize(os, item.second, nType, nVersion);
-}
-
-template <typename Stream, typename K, typename T>
-void Unserialize(Stream &is, std::pair<K, T> &item, int nType, int nVersion) {
-    Unserialize(is, item.first, nType, nVersion);
-    Unserialize(is, item.second, nType, nVersion);
-}
-
-//
-// 3 tuple
-//
-template <typename T0, typename T1, typename T2>
-unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2> &item, int nType,
-                              int nVersion) {
-    unsigned int nSize = 0;
-    nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion);
-    nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion);
-    nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion);
-    return nSize;
-}
-
-template <typename Stream, typename T0, typename T1, typename T2>
-void Serialize(Stream &os, const boost::tuple<T0, T1, T2> &item, int nType,
-               int nVersion) {
-    Serialize(os, boost::get<0>(item), nType, nVersion);
-    Serialize(os, boost::get<1>(item), nType, nVersion);
-    Serialize(os, boost::get<2>(item), nType, nVersion);
-}
-
-template <typename Stream, typename T0, typename T1, typename T2>
-void Unserialize(Stream &is, boost::tuple<T0, T1, T2> &item, int nType,
-                 int nVersion) {
-    Unserialize(is, boost::get<0>(item), nType, nVersion);
-    Unserialize(is, boost::get<1>(item), nType, nVersion);
-    Unserialize(is, boost::get<2>(item), nType, nVersion);
-}
-
-//
-// 4 tuple
-//
-template <typename T0, typename T1, typename T2, typename T3>
-unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3> &item,
-                              int nType, int nVersion) {
-    unsigned int nSize = 0;
-    nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion);
-    nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion);
-    nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion);
-    nSize += GetSerializeSize(boost::get<3>(item), nType, nVersion);
-    return nSize;
-}
-
-template <typename Stream, typename T0, typename T1, typename T2, typename T3>
-void Serialize(Stream &os, const boost::tuple<T0, T1, T2, T3> &item, int nType,
-               int nVersion) {
-    Serialize(os, boost::get<0>(item), nType, nVersion);
-    Serialize(os, boost::get<1>(item), nType, nVersion);
-    Serialize(os, boost::get<2>(item), nType, nVersion);
-    Serialize(os, boost::get<3>(item), nType, nVersion);
-}
-
-template <typename Stream, typename T0, typename T1, typename T2, typename T3>
-void Unserialize(Stream &is, boost::tuple<T0, T1, T2, T3> &item, int nType,
-                 int nVersion) {
-    Unserialize(is, boost::get<0>(item), nType, nVersion);
-    Unserialize(is, boost::get<1>(item), nType, nVersion);
-    Unserialize(is, boost::get<2>(item), nType, nVersion);
-    Unserialize(is, boost::get<3>(item), nType, nVersion);
-}
-
-//
-// map
-//
-template <typename K, typename T, typename Pred, typename A>
-unsigned int GetSerializeSize(const std::map<K, T, Pred, A> &m, int nType,
-                              int nVersion) {
-    unsigned int nSize = GetSizeOfCompactSize(m.size());
-    for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin();
-         mi != m.end(); ++mi)
-        nSize += GetSerializeSize((*mi), nType, nVersion);
-    return nSize;
-}
-
-template <typename Stream, typename K, typename T, typename Pred, typename A>
-void Serialize(Stream &os, const std::map<K, T, Pred, A> &m, int nType,
-               int nVersion) {
-    WriteCompactSize(os, m.size());
-    for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin();
-         mi != m.end(); ++mi)
-        Serialize(os, (*mi), nType, nVersion);
-}
-
-template <typename Stream, typename K, typename T, typename Pred, typename A>
-void Unserialize(Stream &is, std::map<K, T, Pred, A> &m, int nType,
-                 int nVersion) {
-    m.clear();
-    unsigned int nSize = ReadCompactSize(is);
-    typename std::map<K, T, Pred, A>::iterator mi = m.begin();
-    for (unsigned int i = 0; i < nSize; i++) {
-        std::pair<K, T> item;
-        Unserialize(is, item, nType, nVersion);
-        mi = m.insert(mi, item);
-    }
-}
-
-//
-// set
-//
-template <typename K, typename Pred, typename A>
-unsigned int GetSerializeSize(const std::set<K, Pred, A> &m, int nType,
-                              int nVersion) {
-    unsigned int nSize = GetSizeOfCompactSize(m.size());
-    for (typename std::set<K, Pred, A>::const_iterator it = m.begin();
-         it != m.end(); ++it)
-        nSize += GetSerializeSize((*it), nType, nVersion);
-    return nSize;
-}
-
-template <typename Stream, typename K, typename Pred, typename A>
-void Serialize(Stream &os, const std::set<K, Pred, A> &m, int nType,
-               int nVersion) {
-    WriteCompactSize(os, m.size());
-    for (typename std::set<K, Pred, A>::const_iterator it = m.begin();
-         it != m.end(); ++it)
-        Serialize(os, (*it), nType, nVersion);
-}
-
-template <typename Stream, typename K, typename Pred, typename A>
-void Unserialize(Stream &is, std::set<K, Pred, A> &m, int nType, int nVersion) {
-    m.clear();
-    unsigned int nSize = ReadCompactSize(is);
-    typename std::set<K, Pred, A>::iterator it = m.begin();
-    for (unsigned int i = 0; i < nSize; i++) {
-        K key;
-        Unserialize(is, key, nType, nVersion);
-        it = m.insert(it, key);
-    }
-}
-
-//
-// Support for IMPLEMENT_SERIALIZE and READWRITE macro
-//
-class CSerActionGetSerializeSize {};
-class CSerActionSerialize {};
-class CSerActionUnserialize {};
-
-template <typename Stream, typename T>
-inline unsigned int SerReadWrite(Stream &s, const T &obj, int nType,
-                                 int nVersion,
-                                 CSerActionGetSerializeSize ser_action) {
-    return ::GetSerializeSize(obj, nType, nVersion);
-}
-
-template <typename Stream, typename T>
-inline unsigned int SerReadWrite(Stream &s, const T &obj, int nType,
-                                 int nVersion, CSerActionSerialize ser_action) {
-    ::Serialize(s, obj, nType, nVersion);
-    return 0;
-}
-
-template <typename Stream, typename T>
-inline unsigned int SerReadWrite(Stream &s, T &obj, int nType, int nVersion,
-                                 CSerActionUnserialize ser_action) {
-    ::Unserialize(s, obj, nType, nVersion);
-    return 0;
-}
-
-struct ser_streamplaceholder {
-    int nType;
-    int nVersion;
-};
-
-//
-// Allocator that locks its contents from being paged
-// out of memory and clears its contents before deletion.
-//
-template <typename T> struct secure_allocator : public std::allocator<T> {
-    // MSVC8 default copy constructor is broken
-    typedef std::allocator<T> base;
-    typedef typename base::size_type size_type;
-    typedef typename base::difference_type difference_type;
-    typedef typename base::pointer pointer;
-    typedef typename base::const_pointer const_pointer;
-    typedef typename base::reference reference;
-    typedef typename base::const_reference const_reference;
-    typedef typename base::value_type value_type;
-    secure_allocator() throw() {}
-    secure_allocator(const secure_allocator &a) throw() : base(a) {}
-    template <typename U>
-    secure_allocator(const secure_allocator<U> &a) throw() : base(a) {}
-    ~secure_allocator() throw() {}
-    template <typename _Other> struct rebind {
-        typedef secure_allocator<_Other> other;
-    };
-
-    T *allocate(std::size_t n, const void *hint = 0) {
-        T *p;
-        p = std::allocator<T>::allocate(n, hint);
-        if (p != nullptr) mlock(p, sizeof(T) * n);
-        return p;
-    }
-
-    void deallocate(T *p, std::size_t n) {
-        if (p != nullptr) {
-            memset(p, 0, sizeof(T) * n);
-            munlock(p, sizeof(T) * n);
-        }
-        std::allocator<T>::deallocate(p, n);
-    }
-};
-
-//
-// Double ended buffer combining vector and stream-like interfaces.
-// >> and << read and write unformatted data using the above serialization
-// templates.
-// Fills with data in linear time; some stringstream implementations take N^2
-// time.
-//
-class CDataStream {
-protected:
-    typedef std::vector<char, secure_allocator<char>> vector_type;
-    vector_type vch;
-    unsigned int nReadPos;
-    short state;
-    short exceptmask;
-
-public:
-    int nType;
-    int nVersion;
-
-    typedef vector_type::allocator_type allocator_type;
-    typedef vector_type::size_type size_type;
-    typedef vector_type::difference_type difference_type;
-    typedef vector_type::reference reference;
-    typedef vector_type::const_reference const_reference;
-    typedef vector_type::value_type value_type;
-    typedef vector_type::iterator iterator;
-    typedef vector_type::const_iterator const_iterator;
-    typedef vector_type::reverse_iterator reverse_iterator;
-
-    explicit CDataStream(int nTypeIn = SER_NETWORK,
-                         int nVersionIn = PROTOCOL_VERSION) {
-        Init(nTypeIn, nVersionIn);
-    }
-
-    CDataStream(const_iterator pbegin, const_iterator pend,
-                int nTypeIn = SER_NETWORK, int nVersionIn = PROTOCOL_VERSION)
-        : vch(pbegin, pend) {
-        Init(nTypeIn, nVersionIn);
-    }
-
-#if !defined(_MSC_VER) || _MSC_VER >= 1300
-    CDataStream(const char *pbegin, const char *pend, int nTypeIn = SER_NETWORK,
-                int nVersionIn = PROTOCOL_VERSION)
-        : vch(pbegin, pend) {
-        Init(nTypeIn, nVersionIn);
-    }
-#endif
-
-    CDataStream(const vector_type &vchIn, int nTypeIn = SER_NETWORK,
-                int nVersionIn = PROTOCOL_VERSION)
-        : vch(vchIn.begin(), vchIn.end()) {
-        Init(nTypeIn, nVersionIn);
-    }
-
-    CDataStream(const std::vector<char> &vchIn, int nTypeIn = SER_NETWORK,
-                int nVersionIn = PROTOCOL_VERSION)
-        : vch(vchIn.begin(), vchIn.end()) {
-        Init(nTypeIn, nVersionIn);
-    }
-
-    CDataStream(const std::vector<uint8_t> &vchIn, int nTypeIn = SER_NETWORK,
-                int nVersionIn = PROTOCOL_VERSION)
-        : vch((char *)&vchIn.begin()[0], (char *)&vchIn.end()[0]) {
-        Init(nTypeIn, nVersionIn);
-    }
-
-    void Init(int nTypeIn = SER_NETWORK, int nVersionIn = PROTOCOL_VERSION) {
-        nReadPos = 0;
-        nType = nTypeIn;
-        nVersion = nVersionIn;
-        state = 0;
-        exceptmask = std::ios::badbit | std::ios::failbit;
-    }
-
-    CDataStream &operator+=(const CDataStream &b) {
-        vch.insert(vch.end(), b.begin(), b.end());
-        return *this;
-    }
-
-    friend CDataStream operator+(const CDataStream &a, const CDataStream &b) {
-        CDataStream ret = a;
-        ret += b;
-        return (ret);
-    }
-
-    std::string str() const { return (std::string(begin(), end())); }
-
-    //
-    // Vector subset
-    //
-    const_iterator begin() const { return vch.begin() + nReadPos; }
-    iterator begin() { return vch.begin() + nReadPos; }
-    const_iterator end() const { return vch.end(); }
-    iterator end() { return vch.end(); }
-    size_type size() const { return vch.size() - nReadPos; }
-    bool empty() const { return vch.size() == nReadPos; }
-    void resize(size_type n, value_type c = 0) { vch.resize(n + nReadPos, c); }
-    void reserve(size_type n) { vch.reserve(n + nReadPos); }
-    const_reference operator[](size_type pos) const {
-        return vch[pos + nReadPos];
-    }
-    reference operator[](size_type pos) { return vch[pos + nReadPos]; }
-    void clear() {
-        vch.clear();
-        nReadPos = 0;
-    }
-    iterator insert(iterator it, const char &x = char()) {
-        return vch.insert(it, x);
-    }
-    void insert(iterator it, size_type n, const char &x) {
-        vch.insert(it, n, x);
-    }
-
-    void insert(iterator it, std::vector<char>::const_iterator first,
-                std::vector<char>::const_iterator last) {
-        if (it == vch.begin() + nReadPos && last - first <= nReadPos) {
-            // special case for inserting at the front when there's room
-            nReadPos -= (last - first);
-            memcpy(&vch[nReadPos], &first[0], last - first);
-        } else
-            vch.insert(it, first, last);
-    }
-
-#if !defined(_MSC_VER) || _MSC_VER >= 1300
-    void insert(iterator it, const char *first, const char *last) {
-        if (it == vch.begin() + nReadPos && last - first <= nReadPos) {
-            // special case for inserting at the front when there's room
-            nReadPos -= (last - first);
-            memcpy(&vch[nReadPos], &first[0], last - first);
-        } else
-            vch.insert(it, first, last);
-    }
-#endif
-
-    iterator erase(iterator it) {
-        if (it == vch.begin() + nReadPos) {
-            // special case for erasing from the front
-            if (++nReadPos >= vch.size()) {
-                // whenever we reach the end, we take the opportunity to clear
-                // the buffer
-                nReadPos = 0;
-                return vch.erase(vch.begin(), vch.end());
-            }
-            return vch.begin() + nReadPos;
-        } else
-            return vch.erase(it);
-    }
-
-    iterator erase(iterator first, iterator last) {
-        if (first == vch.begin() + nReadPos) {
-            // special case for erasing from the front
-            if (last == vch.end()) {
-                nReadPos = 0;
-                return vch.erase(vch.begin(), vch.end());
-            } else {
-                nReadPos = (last - vch.begin());
-                return last;
-            }
-        } else
-            return vch.erase(first, last);
-    }
-
-    inline void Compact() {
-        vch.erase(vch.begin(), vch.begin() + nReadPos);
-        nReadPos = 0;
-    }
-
-    bool Rewind(size_type n) {
-        // Rewind by n characters if the buffer hasn't been compacted yet
-        if (n > nReadPos) return false;
-        nReadPos -= n;
-        return true;
-    }
-
-    //
-    // Stream subset
-    //
-    void setstate(short bits, const char *psz) {
-        state |= bits;
-        if (state & exceptmask) throw std::ios_base::failure(psz);
-    }
-
-    bool eof() const { return size() == 0; }
-    bool fail() const { return state & (std::ios::badbit | std::ios::failbit); }
-    bool good() const { return !eof() && (state == 0); }
-    void clear(short n) { state = n; } // name conflict with vector clear()
-    short exceptions() { return exceptmask; }
-    short exceptions(short mask) {
-        short prev = exceptmask;
-        exceptmask = mask;
-        setstate(0, "CDataStream");
-        return prev;
-    }
-    CDataStream *rdbuf() { return this; }
-    int in_avail() { return size(); }
-
-    void SetType(int n) { nType = n; }
-    int GetType() { return nType; }
-    void SetVersion(int n) { nVersion = n; }
-    int GetVersion() { return nVersion; }
-    void ReadVersion() { *this >> nVersion; }
-    void WriteVersion() { *this << nVersion; }
-
-    CDataStream &read(char *pch, int nSize) {
-        // Read from the beginning of the buffer
-        assert(nSize >= 0);
-        unsigned int nReadPosNext = nReadPos + nSize;
-        if (nReadPosNext >= vch.size()) {
-            if (nReadPosNext > vch.size()) {
-                setstate(std::ios::failbit,
-                         "CDataStream::read() : end of data");
-                memset(pch, 0, nSize);
-                nSize = vch.size() - nReadPos;
-            }
-            memcpy(pch, &vch[nReadPos], nSize);
-            nReadPos = 0;
-            vch.clear();
-            return (*this);
-        }
-        memcpy(pch, &vch[nReadPos], nSize);
-        nReadPos = nReadPosNext;
-        return (*this);
-    }
-
-    CDataStream &ignore(int nSize) {
-        // Ignore from the beginning of the buffer
-        assert(nSize >= 0);
-        unsigned int nReadPosNext = nReadPos + nSize;
-        if (nReadPosNext >= vch.size()) {
-            if (nReadPosNext > vch.size()) {
-                setstate(std::ios::failbit,
-                         "CDataStream::ignore() : end of data");
-                nSize = vch.size() - nReadPos;
-            }
-            nReadPos = 0;
-            vch.clear();
-            return (*this);
-        }
-        nReadPos = nReadPosNext;
-        return (*this);
-    }
-
-    CDataStream &write(const char *pch, int nSize) {
-        // Write to the end of the buffer
-        assert(nSize >= 0);
-        vch.insert(vch.end(), pch, pch + nSize);
-        return (*this);
-    }
-
-    template <typename Stream>
-    void Serialize(Stream &s, int nType = 0,
-                   int nVersion = PROTOCOL_VERSION) const {
-        // Special case: stream << stream concatenates like stream += stream
-        if (!vch.empty()) s.write((char *)&vch[0], vch.size() * sizeof(vch[0]));
-    }
-
-    template <typename T> unsigned int GetSerializeSize(const T &obj) {
-        // Tells the size of the object if serialized to this stream
-        return ::GetSerializeSize(obj, nType, nVersion);
-    }
-
-    template <typename T> CDataStream &operator<<(const T &obj) {
-        // Serialize to this stream
-        ::Serialize(*this, obj, nType, nVersion);
-        return (*this);
-    }
-
-    template <typename T> CDataStream &operator>>(T &obj) {
-        // Unserialize from this stream
-        ::Unserialize(*this, obj, nType, nVersion);
-        return (*this);
-    }
-};
-
-#ifdef TESTCDATASTREAM
-// VC6sp6
-// CDataStream:
-// n=1000       0 seconds
-// n=2000       0 seconds
-// n=4000       0 seconds
-// n=8000       0 seconds
-// n=16000      0 seconds
-// n=32000      0 seconds
-// n=64000      1 seconds
-// n=128000     1 seconds
-// n=256000     2 seconds
-// n=512000     4 seconds
-// n=1024000    8 seconds
-// n=2048000    16 seconds
-// n=4096000    32 seconds
-// stringstream:
-// n=1000       1 seconds
-// n=2000       1 seconds
-// n=4000       13 seconds
-// n=8000       87 seconds
-// n=16000      400 seconds
-// n=32000      1660 seconds
-// n=64000      6749 seconds
-// n=128000     27241 seconds
-// n=256000     109804 seconds
-#include <iostream>
-int main(int argc, char *argv[]) {
-    vector<uint8_t> vch(0xcc, 250);
-    printf("CDataStream:\n");
-    for (int n = 1000; n <= 4500000; n *= 2) {
-        CDataStream ss;
-        time_t nStart = time(nullptr);
-        for (int i = 0; i < n; i++)
-            ss.write((char *)&vch[0], vch.size());
-        printf("n=%-10d %d seconds\n", n, time(nullptr) - nStart);
-    }
-    printf("stringstream:\n");
-    for (int n = 1000; n <= 4500000; n *= 2) {
-        stringstream ss;
-        time_t nStart = time(nullptr);
-        for (int i = 0; i < n; i++)
-            ss.write((char *)&vch[0], vch.size());
-        printf("n=%-10d %d seconds\n", n, time(nullptr) - nStart);
-    }
-}
-#endif
-
-//
-// Automatic closing wrapper for FILE*
-//  - Will automatically close the file when it goes out of scope if not null.
-//  - If you're returning the file pointer, return file.release().
-//  - If you need to close the file early, use file.fclose() instead of
-//  fclose(file).
-//
-class CAutoFile {
-protected:
-    FILE *file;
-    short state;
-    short exceptmask;
-
-public:
-    int nType;
-    int nVersion;
-
-    typedef FILE element_type;
-
-    CAutoFile(FILE *filenew = nullptr, int nTypeIn = SER_DISK,
-              int nVersionIn = PROTOCOL_VERSION) {
-        file = filenew;
-        nType = nTypeIn;
-        nVersion = nVersionIn;
-        state = 0;
-        exceptmask = std::ios::badbit | std::ios::failbit;
-    }
-
-    ~CAutoFile() { fclose(); }
-
-    void fclose() {
-        if (file != nullptr && file != stdin && file != stdout &&
-            file != stderr)
-            ::fclose(file);
-        file = nullptr;
-    }
-
-    FILE *release() {
-        FILE *ret = file;
-        file = nullptr;
-        return ret;
-    }
-    operator FILE *() { return file; }
-    FILE *operator->() { return file; }
-    FILE &operator*() { return *file; }
-    FILE **operator&() { return &file; }
-    FILE *operator=(FILE *pnew) { return file = pnew; }
-    bool operator!() { return (file == nullptr); }
-
-    //
-    // Stream subset
-    //
-    void setstate(short bits, const char *psz) {
-        state |= bits;
-        if (state & exceptmask) throw std::ios_base::failure(psz);
-    }
-
-    bool fail() const { return state & (std::ios::badbit | std::ios::failbit); }
-    bool good() const { return state == 0; }
-    void clear(short n = 0) { state = n; }
-    short exceptions() { return exceptmask; }
-    short exceptions(short mask) {
-        short prev = exceptmask;
-        exceptmask = mask;
-        setstate(0, "CAutoFile");
-        return prev;
-    }
-
-    void SetType(int n) { nType = n; }
-    int GetType() { return nType; }
-    void SetVersion(int n) { nVersion = n; }
-    int GetVersion() { return nVersion; }
-    void ReadVersion() { *this >> nVersion; }
-    void WriteVersion() { *this << nVersion; }
-
-    CAutoFile &read(char *pch, int nSize) {
-        if (!file)
-            throw std::ios_base::failure(
-                "CAutoFile::read : file handle is nullptr");
-        if (fread(pch, 1, nSize, file) != nSize)
-            setstate(std::ios::failbit, feof(file)
-                                            ? "CAutoFile::read : end of file"
-                                            : "CAutoFile::read : fread failed");
-        return (*this);
-    }
-
-    CAutoFile &write(const char *pch, int nSize) {
-        if (!file)
-            throw std::ios_base::failure(
-                "CAutoFile::write : file handle is nullptr");
-        if (fwrite(pch, 1, nSize, file) != nSize)
-            setstate(std::ios::failbit, "CAutoFile::write : write failed");
-        return (*this);
-    }
-
-    template <typename T> unsigned int GetSerializeSize(const T &obj) {
-        // Tells the size of the object if serialized to this stream
-        return ::GetSerializeSize(obj, nType, nVersion);
-    }
-
-    template <typename T> CAutoFile &operator<<(const T &obj) {
-        // Serialize to this stream
-        if (!file)
-            throw std::ios_base::failure(
-                "CAutoFile::operator<< : file handle is nullptr");
-        ::Serialize(*this, obj, nType, nVersion);
-        return (*this);
-    }
-
-    template <typename T> CAutoFile &operator>>(T &obj) {
-        // Unserialize from this stream
-        if (!file)
-            throw std::ios_base::failure(
-                "CAutoFile::operator>> : file handle is nullptr");
-        ::Unserialize(*this, obj, nType, nVersion);
-        return (*this);
-    }
-};
-
-#endif
diff --git a/src/seeder/uint256.h b/src/seeder/uint256.h
deleted file mode 100644
--- a/src/seeder/uint256.h
+++ /dev/null
@@ -1,825 +0,0 @@
-// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-#ifndef BITCOIN_SEEDER_UINT256_H
-#define BITCOIN_SEEDER_UINT256_H
-
-#include "serialize.h"
-
-#include <climits>
-#include <cstdint>
-#include <string>
-#include <vector>
-
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#define for if (false); else for
-#endif
-
-inline int Testuint256AdHoc(std::vector<std::string> vArg);
-
-// We have to keep a separate base class without constructors
-// so the compiler will let us use it in a union
-template <unsigned int BITS> class base_uint {
-protected:
-    enum { WIDTH = BITS / 32 };
-    unsigned int pn[WIDTH];
-
-public:
-    bool operator!() const {
-        for (int i = 0; i < WIDTH; i++)
-            if (pn[i] != 0) return false;
-        return true;
-    }
-
-    const base_uint operator~() const {
-        base_uint ret;
-        for (int i = 0; i < WIDTH; i++)
-            ret.pn[i] = ~pn[i];
-        return ret;
-    }
-
-    const base_uint operator-() const {
-        base_uint ret;
-        for (int i = 0; i < WIDTH; i++)
-            ret.pn[i] = ~pn[i];
-        ret++;
-        return ret;
-    }
-
-    base_uint &operator=(uint64_t b) {
-        pn[0] = (unsigned int)b;
-        pn[1] = (unsigned int)(b >> 32);
-        for (int i = 2; i < WIDTH; i++)
-            pn[i] = 0;
-        return *this;
-    }
-
-    base_uint &operator^=(const base_uint &b) {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] ^= b.pn[i];
-        return *this;
-    }
-
-    base_uint &operator&=(const base_uint &b) {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] &= b.pn[i];
-        return *this;
-    }
-
-    base_uint &operator|=(const base_uint &b) {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] |= b.pn[i];
-        return *this;
-    }
-
-    base_uint &operator^=(uint64_t b) {
-        pn[0] ^= (unsigned int)b;
-        pn[1] ^= (unsigned int)(b >> 32);
-        return *this;
-    }
-
-    base_uint &operator&=(uint64_t b) {
-        pn[0] &= (unsigned int)b;
-        pn[1] &= (unsigned int)(b >> 32);
-        return *this;
-    }
-
-    base_uint &operator|=(uint64_t b) {
-        pn[0] |= (unsigned int)b;
-        pn[1] |= (unsigned int)(b >> 32);
-        return *this;
-    }
-
-    base_uint &operator<<=(unsigned int shift) {
-        base_uint a(*this);
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = 0;
-        int k = shift / 32;
-        shift = shift % 32;
-        for (int i = 0; i < WIDTH; i++) {
-            if (i + k + 1 < WIDTH && shift != 0)
-                pn[i + k + 1] |= (a.pn[i] >> (32 - shift));
-            if (i + k < WIDTH) pn[i + k] |= (a.pn[i] << shift);
-        }
-        return *this;
-    }
-
-    base_uint &operator>>=(unsigned int shift) {
-        base_uint a(*this);
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = 0;
-        int k = shift / 32;
-        shift = shift % 32;
-        for (int i = 0; i < WIDTH; i++) {
-            if (i - k - 1 >= 0 && shift != 0)
-                pn[i - k - 1] |= (a.pn[i] << (32 - shift));
-            if (i - k >= 0) pn[i - k] |= (a.pn[i] >> shift);
-        }
-        return *this;
-    }
-
-    base_uint &operator+=(const base_uint &b) {
-        uint64_t carry = 0;
-        for (int i = 0; i < WIDTH; i++) {
-            uint64_t n = carry + pn[i] + b.pn[i];
-            pn[i] = n & 0xffffffff;
-            carry = n >> 32;
-        }
-        return *this;
-    }
-
-    base_uint &operator-=(const base_uint &b) {
-        *this += -b;
-        return *this;
-    }
-
-    base_uint &operator+=(uint64_t b64) {
-        base_uint b;
-        b = b64;
-        *this += b;
-        return *this;
-    }
-
-    base_uint &operator-=(uint64_t b64) {
-        base_uint b;
-        b = b64;
-        *this += -b;
-        return *this;
-    }
-
-    base_uint &operator++() {
-        // prefix operator
-        int i = 0;
-        while (++pn[i] == 0 && i < WIDTH - 1)
-            i++;
-        return *this;
-    }
-
-    const base_uint operator++(int) {
-        // postfix operator
-        const base_uint ret = *this;
-        ++(*this);
-        return ret;
-    }
-
-    base_uint &operator--() {
-        // prefix operator
-        int i = 0;
-        while (--pn[i] == -1 && i < WIDTH - 1)
-            i++;
-        return *this;
-    }
-
-    const base_uint operator--(int) {
-        // postfix operator
-        const base_uint ret = *this;
-        --(*this);
-        return ret;
-    }
-
-    friend inline bool operator<(const base_uint &a, const base_uint &b) {
-        for (int i = base_uint::WIDTH - 1; i >= 0; i--) {
-            if (a.pn[i] < b.pn[i])
-                return true;
-            else if (a.pn[i] > b.pn[i])
-                return false;
-        }
-        return false;
-    }
-
-    friend inline bool operator<=(const base_uint &a, const base_uint &b) {
-        for (int i = base_uint::WIDTH - 1; i >= 0; i--) {
-            if (a.pn[i] < b.pn[i])
-                return true;
-            else if (a.pn[i] > b.pn[i])
-                return false;
-        }
-        return true;
-    }
-
-    friend inline bool operator>(const base_uint &a, const base_uint &b) {
-        for (int i = base_uint::WIDTH - 1; i >= 0; i--) {
-            if (a.pn[i] > b.pn[i])
-                return true;
-            else if (a.pn[i] < b.pn[i])
-                return false;
-        }
-        return false;
-    }
-
-    friend inline bool operator>=(const base_uint &a, const base_uint &b) {
-        for (int i = base_uint::WIDTH - 1; i >= 0; i--) {
-            if (a.pn[i] > b.pn[i])
-                return true;
-            else if (a.pn[i] < b.pn[i])
-                return false;
-        }
-        return true;
-    }
-
-    friend inline bool operator==(const base_uint &a, const base_uint &b) {
-        for (int i = 0; i < base_uint::WIDTH; i++)
-            if (a.pn[i] != b.pn[i]) return false;
-        return true;
-    }
-
-    friend inline bool operator==(const base_uint &a, uint64_t b) {
-        if (a.pn[0] != (unsigned int)b) return false;
-        if (a.pn[1] != (unsigned int)(b >> 32)) return false;
-        for (int i = 2; i < base_uint::WIDTH; i++)
-            if (a.pn[i] != 0) return false;
-        return true;
-    }
-
-    friend inline bool operator!=(const base_uint &a, const base_uint &b) {
-        return (!(a == b));
-    }
-
-    friend inline bool operator!=(const base_uint &a, uint64_t b) {
-        return (!(a == b));
-    }
-
-    std::string GetHex() const {
-        char psz[sizeof(pn) * 2 + 1];
-        for (int i = 0; i < sizeof(pn); i++)
-            sprintf(psz + i * 2, "%02x", ((uint8_t *)pn)[sizeof(pn) - i - 1]);
-        return std::string(psz, psz + sizeof(pn) * 2);
-    }
-
-    void SetHex(const char *psz) {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = 0;
-
-        // skip leading spaces
-        while (isspace(*psz))
-            psz++;
-
-        // skip 0x
-        if (psz[0] == '0' && tolower(psz[1]) == 'x') psz += 2;
-
-        // hex string to uint
-        static char phexdigit[256] = {
-            0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 1,   2,   3,   4,   5,   6,   7, 8, 9, 0, 0, 0, 0, 0, 0,
-            0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-        const char *pbegin = psz;
-        while (phexdigit[(uint8_t)*psz] || *psz == '0')
-            psz++;
-        psz--;
-        uint8_t *p1 = (uint8_t *)pn;
-        uint8_t *pend = p1 + WIDTH * 4;
-        while (psz >= pbegin && p1 < pend) {
-            *p1 = phexdigit[(uint8_t)*psz--];
-            if (psz >= pbegin) {
-                *p1 |= (phexdigit[(uint8_t)*psz--] << 4);
-                p1++;
-            }
-        }
-    }
-
-    void SetHex(const std::string &str) { SetHex(str.c_str()); }
-
-    std::string ToString() const { return (GetHex()); }
-
-    uint8_t *begin() { return (uint8_t *)&pn[0]; }
-
-    uint8_t *end() { return (uint8_t *)&pn[WIDTH]; }
-
-    unsigned int size() { return sizeof(pn); }
-
-    unsigned int GetSerializeSize(int nType = 0,
-                                  int nVersion = PROTOCOL_VERSION) const {
-        return sizeof(pn);
-    }
-
-    template <typename Stream>
-    void Serialize(Stream &s, int nType = 0,
-                   int nVersion = PROTOCOL_VERSION) const {
-        s.write((char *)pn, sizeof(pn));
-    }
-
-    template <typename Stream>
-    void Unserialize(Stream &s, int nType = 0,
-                     int nVersion = PROTOCOL_VERSION) {
-        s.read((char *)pn, sizeof(pn));
-    }
-
-    friend class uint160;
-    friend class uint256;
-    friend inline int Testuint256AdHoc(std::vector<std::string> vArg);
-};
-
-typedef base_uint<160> base_uint160;
-typedef base_uint<256> base_uint256;
-
-//
-// uint160 and uint256 could be implemented as templates, but to keep
-// compile errors and debugging cleaner, they're copy and pasted.
-//
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// uint160
-//
-
-class uint160 : public base_uint160 {
-public:
-    typedef base_uint160 basetype;
-
-    uint160() {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = 0;
-    }
-
-    uint160(const basetype &b) {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = b.pn[i];
-    }
-
-    uint160 &operator=(const basetype &b) {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = b.pn[i];
-        return *this;
-    }
-
-    uint160(uint64_t b) {
-        pn[0] = (unsigned int)b;
-        pn[1] = (unsigned int)(b >> 32);
-        for (int i = 2; i < WIDTH; i++)
-            pn[i] = 0;
-    }
-
-    uint160 &operator=(uint64_t b) {
-        pn[0] = (unsigned int)b;
-        pn[1] = (unsigned int)(b >> 32);
-        for (int i = 2; i < WIDTH; i++)
-            pn[i] = 0;
-        return *this;
-    }
-
-    explicit uint160(const std::string &str) { SetHex(str); }
-
-    explicit uint160(const std::vector<uint8_t> &vch) {
-        if (vch.size() == sizeof(pn))
-            memcpy(pn, &vch[0], sizeof(pn));
-        else
-            *this = 0;
-    }
-};
-
-inline bool operator==(const uint160 &a, uint64_t b) {
-    return (base_uint160)a == b;
-}
-inline bool operator!=(const uint160 &a, uint64_t b) {
-    return (base_uint160)a != b;
-}
-inline const uint160 operator<<(const base_uint160 &a, unsigned int shift) {
-    return uint160(a) <<= shift;
-}
-inline const uint160 operator>>(const base_uint160 &a, unsigned int shift) {
-    return uint160(a) >>= shift;
-}
-inline const uint160 operator<<(const uint160 &a, unsigned int shift) {
-    return uint160(a) <<= shift;
-}
-inline const uint160 operator>>(const uint160 &a, unsigned int shift) {
-    return uint160(a) >>= shift;
-}
-
-inline const uint160 operator^(const base_uint160 &a, const base_uint160 &b) {
-    return uint160(a) ^= b;
-}
-inline const uint160 operator&(const base_uint160 &a, const base_uint160 &b) {
-    return uint160(a) &= b;
-}
-inline const uint160 operator|(const base_uint160 &a, const base_uint160 &b) {
-    return uint160(a) |= b;
-}
-inline const uint160 operator+(const base_uint160 &a, const base_uint160 &b) {
-    return uint160(a) += b;
-}
-inline const uint160 operator-(const base_uint160 &a, const base_uint160 &b) {
-    return uint160(a) -= b;
-}
-
-inline bool operator<(const base_uint160 &a, const uint160 &b) {
-    return (base_uint160)a < (base_uint160)b;
-}
-inline bool operator<=(const base_uint160 &a, const uint160 &b) {
-    return (base_uint160)a <= (base_uint160)b;
-}
-inline bool operator>(const base_uint160 &a, const uint160 &b) {
-    return (base_uint160)a > (base_uint160)b;
-}
-inline bool operator>=(const base_uint160 &a, const uint160 &b) {
-    return (base_uint160)a >= (base_uint160)b;
-}
-inline bool operator==(const base_uint160 &a, const uint160 &b) {
-    return (base_uint160)a == (base_uint160)b;
-}
-inline bool operator!=(const base_uint160 &a, const uint160 &b) {
-    return (base_uint160)a != (base_uint160)b;
-}
-inline const uint160 operator^(const base_uint160 &a, const uint160 &b) {
-    return (base_uint160)a ^ (base_uint160)b;
-}
-inline const uint160 operator&(const base_uint160 &a, const uint160 &b) {
-    return (base_uint160)a & (base_uint160)b;
-}
-inline const uint160 operator|(const base_uint160 &a, const uint160 &b) {
-    return (base_uint160)a | (base_uint160)b;
-}
-inline const uint160 operator+(const base_uint160 &a, const uint160 &b) {
-    return (base_uint160)a + (base_uint160)b;
-}
-inline const uint160 operator-(const base_uint160 &a, const uint160 &b) {
-    return (base_uint160)a - (base_uint160)b;
-}
-
-inline bool operator<(const uint160 &a, const base_uint160 &b) {
-    return (base_uint160)a < (base_uint160)b;
-}
-inline bool operator<=(const uint160 &a, const base_uint160 &b) {
-    return (base_uint160)a <= (base_uint160)b;
-}
-inline bool operator>(const uint160 &a, const base_uint160 &b) {
-    return (base_uint160)a > (base_uint160)b;
-}
-inline bool operator>=(const uint160 &a, const base_uint160 &b) {
-    return (base_uint160)a >= (base_uint160)b;
-}
-inline bool operator==(const uint160 &a, const base_uint160 &b) {
-    return (base_uint160)a == (base_uint160)b;
-}
-inline bool operator!=(const uint160 &a, const base_uint160 &b) {
-    return (base_uint160)a != (base_uint160)b;
-}
-inline const uint160 operator^(const uint160 &a, const base_uint160 &b) {
-    return (base_uint160)a ^ (base_uint160)b;
-}
-inline const uint160 operator&(const uint160 &a, const base_uint160 &b) {
-    return (base_uint160)a & (base_uint160)b;
-}
-inline const uint160 operator|(const uint160 &a, const base_uint160 &b) {
-    return (base_uint160)a | (base_uint160)b;
-}
-inline const uint160 operator+(const uint160 &a, const base_uint160 &b) {
-    return (base_uint160)a + (base_uint160)b;
-}
-inline const uint160 operator-(const uint160 &a, const base_uint160 &b) {
-    return (base_uint160)a - (base_uint160)b;
-}
-
-inline bool operator<(const uint160 &a, const uint160 &b) {
-    return (base_uint160)a < (base_uint160)b;
-}
-inline bool operator<=(const uint160 &a, const uint160 &b) {
-    return (base_uint160)a <= (base_uint160)b;
-}
-inline bool operator>(const uint160 &a, const uint160 &b) {
-    return (base_uint160)a > (base_uint160)b;
-}
-inline bool operator>=(const uint160 &a, const uint160 &b) {
-    return (base_uint160)a >= (base_uint160)b;
-}
-inline bool operator==(const uint160 &a, const uint160 &b) {
-    return (base_uint160)a == (base_uint160)b;
-}
-inline bool operator!=(const uint160 &a, const uint160 &b) {
-    return (base_uint160)a != (base_uint160)b;
-}
-inline const uint160 operator^(const uint160 &a, const uint160 &b) {
-    return (base_uint160)a ^ (base_uint160)b;
-}
-inline const uint160 operator&(const uint160 &a, const uint160 &b) {
-    return (base_uint160)a & (base_uint160)b;
-}
-inline const uint160 operator|(const uint160 &a, const uint160 &b) {
-    return (base_uint160)a | (base_uint160)b;
-}
-inline const uint160 operator+(const uint160 &a, const uint160 &b) {
-    return (base_uint160)a + (base_uint160)b;
-}
-inline const uint160 operator-(const uint160 &a, const uint160 &b) {
-    return (base_uint160)a - (base_uint160)b;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// uint256
-//
-
-class uint256 : public base_uint256 {
-public:
-    typedef base_uint256 basetype;
-
-    uint256() {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = 0;
-    }
-
-    uint256(const basetype &b) {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = b.pn[i];
-    }
-
-    uint256 &operator=(const basetype &b) {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = b.pn[i];
-        return *this;
-    }
-
-    uint256(uint64_t b) {
-        pn[0] = (unsigned int)b;
-        pn[1] = (unsigned int)(b >> 32);
-        for (int i = 2; i < WIDTH; i++)
-            pn[i] = 0;
-    }
-
-    uint256 &operator=(uint64_t b) {
-        pn[0] = (unsigned int)b;
-        pn[1] = (unsigned int)(b >> 32);
-        for (int i = 2; i < WIDTH; i++)
-            pn[i] = 0;
-        return *this;
-    }
-
-    explicit uint256(const std::string &str) { SetHex(str); }
-
-    explicit uint256(const std::vector<uint8_t> &vch) {
-        if (vch.size() == sizeof(pn))
-            memcpy(pn, &vch[0], sizeof(pn));
-        else
-            *this = 0;
-    }
-};
-
-inline bool operator==(const uint256 &a, uint64_t b) {
-    return (base_uint256)a == b;
-}
-inline bool operator!=(const uint256 &a, uint64_t b) {
-    return (base_uint256)a != b;
-}
-inline const uint256 operator<<(const base_uint256 &a, unsigned int shift) {
-    return uint256(a) <<= shift;
-}
-inline const uint256 operator>>(const base_uint256 &a, unsigned int shift) {
-    return uint256(a) >>= shift;
-}
-inline const uint256 operator<<(const uint256 &a, unsigned int shift) {
-    return uint256(a) <<= shift;
-}
-inline const uint256 operator>>(const uint256 &a, unsigned int shift) {
-    return uint256(a) >>= shift;
-}
-
-inline const uint256 operator^(const base_uint256 &a, const base_uint256 &b) {
-    return uint256(a) ^= b;
-}
-inline const uint256 operator&(const base_uint256 &a, const base_uint256 &b) {
-    return uint256(a) &= b;
-}
-inline const uint256 operator|(const base_uint256 &a, const base_uint256 &b) {
-    return uint256(a) |= b;
-}
-inline const uint256 operator+(const base_uint256 &a, const base_uint256 &b) {
-    return uint256(a) += b;
-}
-inline const uint256 operator-(const base_uint256 &a, const base_uint256 &b) {
-    return uint256(a) -= b;
-}
-
-inline bool operator<(const base_uint256 &a, const uint256 &b) {
-    return (base_uint256)a < (base_uint256)b;
-}
-inline bool operator<=(const base_uint256 &a, const uint256 &b) {
-    return (base_uint256)a <= (base_uint256)b;
-}
-inline bool operator>(const base_uint256 &a, const uint256 &b) {
-    return (base_uint256)a > (base_uint256)b;
-}
-inline bool operator>=(const base_uint256 &a, const uint256 &b) {
-    return (base_uint256)a >= (base_uint256)b;
-}
-inline bool operator==(const base_uint256 &a, const uint256 &b) {
-    return (base_uint256)a == (base_uint256)b;
-}
-inline bool operator!=(const base_uint256 &a, const uint256 &b) {
-    return (base_uint256)a != (base_uint256)b;
-}
-inline const uint256 operator^(const base_uint256 &a, const uint256 &b) {
-    return (base_uint256)a ^ (base_uint256)b;
-}
-inline const uint256 operator&(const base_uint256 &a, const uint256 &b) {
-    return (base_uint256)a & (base_uint256)b;
-}
-inline const uint256 operator|(const base_uint256 &a, const uint256 &b) {
-    return (base_uint256)a | (base_uint256)b;
-}
-inline const uint256 operator+(const base_uint256 &a, const uint256 &b) {
-    return (base_uint256)a + (base_uint256)b;
-}
-inline const uint256 operator-(const base_uint256 &a, const uint256 &b) {
-    return (base_uint256)a - (base_uint256)b;
-}
-
-inline bool operator<(const uint256 &a, const base_uint256 &b) {
-    return (base_uint256)a < (base_uint256)b;
-}
-inline bool operator<=(const uint256 &a, const base_uint256 &b) {
-    return (base_uint256)a <= (base_uint256)b;
-}
-inline bool operator>(const uint256 &a, const base_uint256 &b) {
-    return (base_uint256)a > (base_uint256)b;
-}
-inline bool operator>=(const uint256 &a, const base_uint256 &b) {
-    return (base_uint256)a >= (base_uint256)b;
-}
-inline bool operator==(const uint256 &a, const base_uint256 &b) {
-    return (base_uint256)a == (base_uint256)b;
-}
-inline bool operator!=(const uint256 &a, const base_uint256 &b) {
-    return (base_uint256)a != (base_uint256)b;
-}
-inline const uint256 operator^(const uint256 &a, const base_uint256 &b) {
-    return (base_uint256)a ^ (base_uint256)b;
-}
-inline const uint256 operator&(const uint256 &a, const base_uint256 &b) {
-    return (base_uint256)a & (base_uint256)b;
-}
-inline const uint256 operator|(const uint256 &a, const base_uint256 &b) {
-    return (base_uint256)a | (base_uint256)b;
-}
-inline const uint256 operator+(const uint256 &a, const base_uint256 &b) {
-    return (base_uint256)a + (base_uint256)b;
-}
-inline const uint256 operator-(const uint256 &a, const base_uint256 &b) {
-    return (base_uint256)a - (base_uint256)b;
-}
-
-inline bool operator<(const uint256 &a, const uint256 &b) {
-    return (base_uint256)a < (base_uint256)b;
-}
-inline bool operator<=(const uint256 &a, const uint256 &b) {
-    return (base_uint256)a <= (base_uint256)b;
-}
-inline bool operator>(const uint256 &a, const uint256 &b) {
-    return (base_uint256)a > (base_uint256)b;
-}
-inline bool operator>=(const uint256 &a, const uint256 &b) {
-    return (base_uint256)a >= (base_uint256)b;
-}
-inline bool operator==(const uint256 &a, const uint256 &b) {
-    return (base_uint256)a == (base_uint256)b;
-}
-inline bool operator!=(const uint256 &a, const uint256 &b) {
-    return (base_uint256)a != (base_uint256)b;
-}
-inline const uint256 operator^(const uint256 &a, const uint256 &b) {
-    return (base_uint256)a ^ (base_uint256)b;
-}
-inline const uint256 operator&(const uint256 &a, const uint256 &b) {
-    return (base_uint256)a & (base_uint256)b;
-}
-inline const uint256 operator|(const uint256 &a, const uint256 &b) {
-    return (base_uint256)a | (base_uint256)b;
-}
-inline const uint256 operator+(const uint256 &a, const uint256 &b) {
-    return (base_uint256)a + (base_uint256)b;
-}
-inline const uint256 operator-(const uint256 &a, const uint256 &b) {
-    return (base_uint256)a - (base_uint256)b;
-}
-
-inline int Testuint256AdHoc(std::vector<std::string> vArg) {
-    uint256 g(0);
-
-    printf("%s\n", g.ToString().c_str());
-    g--;
-    printf("g--\n");
-    printf("%s\n", g.ToString().c_str());
-    g--;
-    printf("g--\n");
-    printf("%s\n", g.ToString().c_str());
-    g++;
-    printf("g++\n");
-    printf("%s\n", g.ToString().c_str());
-    g++;
-    printf("g++\n");
-    printf("%s\n", g.ToString().c_str());
-    g++;
-    printf("g++\n");
-    printf("%s\n", g.ToString().c_str());
-    g++;
-    printf("g++\n");
-    printf("%s\n", g.ToString().c_str());
-
-    uint256 a(7);
-    printf("a=7\n");
-    printf("%s\n", a.ToString().c_str());
-
-    uint256 b;
-    printf("b undefined\n");
-    printf("%s\n", b.ToString().c_str());
-    int c = 3;
-
-    a = c;
-    a.pn[3] = 15;
-    printf("%s\n", a.ToString().c_str());
-    uint256 k(c);
-
-    a = 5;
-    a.pn[3] = 15;
-    printf("%s\n", a.ToString().c_str());
-    b = 1;
-    b <<= 52;
-
-    a |= b;
-
-    a ^= 0x500;
-
-    printf("a %s\n", a.ToString().c_str());
-
-    a = a | b | (uint256)0x1000;
-
-    printf("a %s\n", a.ToString().c_str());
-    printf("b %s\n", b.ToString().c_str());
-
-    a = 0xfffffffe;
-    a.pn[4] = 9;
-
-    printf("%s\n", a.ToString().c_str());
-    a++;
-    printf("%s\n", a.ToString().c_str());
-    a++;
-    printf("%s\n", a.ToString().c_str());
-    a++;
-    printf("%s\n", a.ToString().c_str());
-    a++;
-    printf("%s\n", a.ToString().c_str());
-
-    a--;
-    printf("%s\n", a.ToString().c_str());
-    a--;
-    printf("%s\n", a.ToString().c_str());
-    a--;
-    printf("%s\n", a.ToString().c_str());
-    uint256 d = a--;
-    printf("%s\n", d.ToString().c_str());
-    printf("%s\n", a.ToString().c_str());
-    a--;
-    printf("%s\n", a.ToString().c_str());
-    a--;
-    printf("%s\n", a.ToString().c_str());
-
-    d = a;
-
-    printf("%s\n", d.ToString().c_str());
-    for (int i = uint256::WIDTH - 1; i >= 0; i--)
-        printf("%08x", d.pn[i]);
-    printf("\n");
-
-    uint256 neg = d;
-    neg = ~neg;
-    printf("%s\n", neg.ToString().c_str());
-
-    uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111");
-    printf("\n");
-    printf("%s\n", e.ToString().c_str());
-
-    printf("\n");
-    uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111");
-    uint256 x2;
-    printf("%s\n", x1.ToString().c_str());
-    for (int i = 0; i < 270; i += 4) {
-        x2 = x1 << i;
-        printf("%s\n", x2.ToString().c_str());
-    }
-
-    printf("\n");
-    printf("%s\n", x1.ToString().c_str());
-    for (int i = 0; i < 270; i += 4) {
-        x2 = x1;
-        x2 >>= i;
-        printf("%s\n", x2.ToString().c_str());
-    }
-
-    for (int i = 0; i < 100; i++) {
-        uint256 k = (~uint256(0) >> i);
-        printf("%s\n", k.ToString().c_str());
-    }
-
-    for (int i = 0; i < 100; i++) {
-        uint256 k = (~uint256(0) << i);
-        printf("%s\n", k.ToString().c_str());
-    }
-
-    return (0);
-}
-
-#endif