From 68af0a221f6cc214ec4dd6074367f3032248f1a0 Mon Sep 17 00:00:00 2001 From: Intel Date: Sun, 22 Dec 2013 15:22:04 +0200 Subject: [PATCH] Bitcoin serialization --- src/server/poolserver/Server/Server.cpp | 18 +++-- src/server/shared/Bitcoin/Script.h | 4 ++ src/server/shared/Bitcoin/Serialization.cpp | 72 ++++++++++++++++++++ src/server/shared/Bitcoin/Transaction.h | 17 +++-- src/server/shared/Bitcoin/VarInt.h | 21 ++++++ src/server/shared/ByteBuffer.h | 75 +++++++++++++++++++++ src/server/shared/Util.cpp | 6 +- 7 files changed, 200 insertions(+), 13 deletions(-) create mode 100644 src/server/shared/Bitcoin/Serialization.cpp create mode 100644 src/server/shared/Bitcoin/VarInt.h create mode 100644 src/server/shared/ByteBuffer.h diff --git a/src/server/poolserver/Server/Server.cpp b/src/server/poolserver/Server/Server.cpp index 8c88cb8..78a06d3 100644 --- a/src/server/poolserver/Server/Server.cpp +++ b/src/server/poolserver/Server/Server.cpp @@ -5,6 +5,7 @@ #include "Stratum/Server.h" #include "ServerDatabaseEnv.h" #include "Crypto.h" +#include "Bitcoin.h" #include #include @@ -34,12 +35,17 @@ int Server::Run() //InitDatabase(); - //sLog.Info(LOG_SERVER, "Hash: %s", Util::BinToASCII(Crypto::SHA256("labas")).c_str()); - std::vector trans = Util::ASCIIToBin("010000002e0fb65201eb031afcccb670d0abbb94e0d2a97c2c81c8dd3eac02a92780578e06d1c5d067000000006c493046022100fdac85d847568c37edb07101ba0e7a32b47491c7cd81798190cbc190cbc439e5022100ab6145c93a822d861ae76482506425f05016bac7b901c08aa58dff8cd7d8e0cb012102421c601634e066fcc4d8aa768dfad475ae9eccc5daf3169522572468550483dbffffffff02a08fb502000000001976a9142ef2b6de3e3a269c5883a0717948e257814b6ba688ac8cf51300000000001976a9144221049afbb6ddb1886a12d7d0300365e8769f2088ac00000000"); - //std::vector trans = Util::ASCIIToBin("abcd"); - //std::reverse(trans.begin(), trans.end()); - sLog.Info(LOG_SERVER, "Trans: %s", Util::BinToASCII(trans).c_str()); - sLog.Info(LOG_SERVER, "Hash: %s", Util::BinToASCII(Util::Reverse(Crypto::SHA256D(trans))).c_str()); + Bitcoin::OutPoint outpoint; + outpoint.hash = Util::ASCIIToBin("6DBDDB085B1D8AF75184F0BC01FAD58D1266E9B63B50881990E4B40D6AEE3629"); + outpoint.n = 0; + + Bitcoin::TxOut txout; + txout.value = 5000000; + txout.scriptPubKey = Bitcoin::Script(Util::ASCIIToBin("76A9141AA0CD1CBEA6E7458A7ABAD512A9D9EA1AFB225E88AC")); + + ByteBuffer buf; + buf << txout; + sLog.Info(LOG_SERVER, "Serialized: %s", Util::BinToASCII(buf.vec).c_str()); // Main io service asio::io_service io_service; diff --git a/src/server/shared/Bitcoin/Script.h b/src/server/shared/Bitcoin/Script.h index 03fd0e7..5e65a06 100644 --- a/src/server/shared/Bitcoin/Script.h +++ b/src/server/shared/Bitcoin/Script.h @@ -2,6 +2,8 @@ #define BITCOIN_SCRIPT_H_ #include "Common.h" +#include "ByteBuffer.h" +#include "VarInt.h" #include #include @@ -60,6 +62,8 @@ namespace Bitcoin return tmp; } }; + + ByteBuffer& operator<<(ByteBuffer& a, Script& b); } #endif diff --git a/src/server/shared/Bitcoin/Serialization.cpp b/src/server/shared/Bitcoin/Serialization.cpp new file mode 100644 index 0000000..086d448 --- /dev/null +++ b/src/server/shared/Bitcoin/Serialization.cpp @@ -0,0 +1,72 @@ +#include "VarInt.h" +#include "Script.h" +#include "Transaction.h" + +using namespace Bitcoin; + +ByteBuffer& Bitcoin::operator<<(ByteBuffer& a, VarInt& b) +{ + if (b.value < 0xfd) { + a.Append(b.value, 1); + } else if (b.value <= 0xffff) { + a.Append(0xfd, 1); + a.Append(b.value, 2); + } else if (b.value <= 0xffffffff) { + a.Append(0xfe, 1); + a.Append(b.value, 4); + } else { + a.Append(0xff, 1); + a.Append(b.value, 8); + } + return a; +} + +ByteBuffer& Bitcoin::operator<<(ByteBuffer& a, Script& b) +{ + VarInt size(b.script.size()); + a << size; + a << b.script; + return a; +} + +ByteBuffer& Bitcoin::operator<<(ByteBuffer& a, OutPoint& b) +{ + a << b.hash; + a << b.n; + return a; +} + +ByteBuffer& Bitcoin::operator<<(ByteBuffer& a, TxIn& b) +{ + a << b.prevout; + a << b.script; + a << b.n; + return a; +} + +ByteBuffer& Bitcoin::operator<<(ByteBuffer& a, TxOut& b) +{ + a << b.value; + a << b.scriptPubKey; + return a; +} + +ByteBuffer& Bitcoin::operator<<(ByteBuffer& a, Transaction& b) +{ + a << b.version; + + // Inputs + VarInt insize(b.in.size()); + a << insize; + for (uint32 i = 0; i < b.in.size(); ++i) + a << b.in[i]; + + // Outputs + VarInt outsize(b.out.size()); + a << outsize; + for (uint32 i = 0; i < b.out.size(); ++i) + a << b.out[i]; + + a << b.lockTime; + return a; +} diff --git a/src/server/shared/Bitcoin/Transaction.h b/src/server/shared/Bitcoin/Transaction.h index 707f442..d4d0b8b 100644 --- a/src/server/shared/Bitcoin/Transaction.h +++ b/src/server/shared/Bitcoin/Transaction.h @@ -2,41 +2,50 @@ #define BITCOIN_TRANSACTION_H_ #include "Common.h" -#include "BigNum.h" +#include "ByteBuffer.h" +#include "VarInt.h" #include "Script.h" namespace Bitcoin { class OutPoint { + public: std::vector hash; uint32 n; }; - class InPoint - { - }; + ByteBuffer& operator<<(ByteBuffer& a, OutPoint& b); class TxIn { + public: OutPoint prevout; Script script; uint32 n; }; + ByteBuffer& operator<<(ByteBuffer& a, TxIn& b); + class TxOut { + public: int64 value; Script scriptPubKey; }; + ByteBuffer& operator<<(ByteBuffer& a, TxOut& b); + class Transaction { + public: uint32 version; std::vector in; std::vector out; uint32 lockTime; }; + + ByteBuffer& operator<<(ByteBuffer& a, Transaction& b); } #endif diff --git a/src/server/shared/Bitcoin/VarInt.h b/src/server/shared/Bitcoin/VarInt.h new file mode 100644 index 0000000..1e97f0c --- /dev/null +++ b/src/server/shared/Bitcoin/VarInt.h @@ -0,0 +1,21 @@ +#ifndef BITCOIN_VARINT_H_ +#define BITCOIN_VARINT_H_ + +#include "Common.h" +#include "ByteBuffer.h" + +namespace Bitcoin +{ + class VarInt + { + public: + VarInt(uint64 data) : value(data) {} + uint64 value; + + friend ByteBuffer& operator<<(ByteBuffer& a, VarInt& b); + }; + + ByteBuffer& operator<<(ByteBuffer& a, VarInt& b); +} + +#endif diff --git a/src/server/shared/ByteBuffer.h b/src/server/shared/ByteBuffer.h new file mode 100644 index 0000000..1b03b2d --- /dev/null +++ b/src/server/shared/ByteBuffer.h @@ -0,0 +1,75 @@ +#ifndef BYTEBUFFER_H_ +#define BYTEBUFFER_H_ + +#include "Common.h" +#include + +class ByteBuffer +{ +public: + ByteBuffer& operator<<(ByteBuffer& b) + { + Append(b.vec); + return *this; + } + ByteBuffer& operator<<(std::vector& b) + { + Append(b); + return *this; + } + ByteBuffer& operator<<(uint8& b) + { + Append(b, 1); + return *this; + } + ByteBuffer& operator<<(uint16& b) + { + Append(b, 2); + return *this; + } + ByteBuffer& operator<<(uint32& b) + { + Append(b, 4); + return *this; + } + ByteBuffer& operator<<(uint64& b) + { + Append(b, 8); + return *this; + } + ByteBuffer& operator<<(int8& b) + { + Append(b, 1); + return *this; + } + ByteBuffer& operator<<(int16& b) + { + Append(b, 2); + return *this; + } + ByteBuffer& operator<<(int32& b) + { + Append(b, 4); + return *this; + } + ByteBuffer& operator<<(int64& b) + { + Append(b, 8); + return *this; + } + + void Append(uint64 data, size_t size) + { + for (int i = 0; i < size; i++) + vec.push_back(data >> (i * 8)); + } + + void Append(std::vector data) + { + vec.insert(vec.end(), data.begin(), data.end()); + } + + std::vector vec; +}; + +#endif diff --git a/src/server/shared/Util.cpp b/src/server/shared/Util.cpp index 400f589..167f915 100644 --- a/src/server/shared/Util.cpp +++ b/src/server/shared/Util.cpp @@ -45,11 +45,11 @@ std::string Util::FromBase64(std::string input) uint8 Util::ASCIIToHex(char ch) { - if (ch > 47 && ch < 58) + if (ch > 47 && ch < 58) // Number return ch - 48; - else if (ch > 64 && ch < 71) + else if (ch > 64 && ch < 71) // Uppercase return ch - 55; - else if (ch > 96 && ch < 103) + else if (ch > 96 && ch < 103) // Lowercase return ch - 87; else return 0; // Invalid