Не могли бы вы объяснить мне, как обрабатывать транзакции
(Я знаю, как создать & подписать их), но, как отправить их сейчас?
Это очень "грязный" кусок кода, но это работает.
Конечно, это один "только для образовательных целей"
#включают
#включают
#включают
#включают
#включают
#включают
#включают
#включают
#включают
#включают "Bitcoin.h"
#define _xtrace (Х) QDebug () << ( ИКС )
#define _xassert (Х) Q_ASSERT (Х)
#define MAGIC_ID 0x709110b
#define TYPE_VERSION ( "версия" "\ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" )
#define TYPE_VERACK ( "verack" "\ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" )
#define TYPE_GETDATA ( "получить данные" "\ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" )
#define TYPE_PING ( "пинг" "\ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" )
#define TYPE_PONG ( "понг" "\ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" )
#define TYPE_TX ( "Техас" "\ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" "\ 0 \ 0 \ 0 \ 0" )
#define USER_AGENT "/Satoshi:0.9.1/"
#define PROTO_VERSION 70002
#define PROTO_SERVICES (1) // может быть NODE_NETWORK
Bitcoin :: Bitcoin (Const QByteArray& ТХ, QObject * родитель): QObject (родитель)
{
это -> дети = 0;
это -> ТХ = ТХ;
QTimer :: SingleShot (10, это, SLOT (старт ()));
}
// ------------------------------------------------ --------------
аннулированию Bitcoin :: заводится ()
{
QFile конф ( "PushTxTool.conf" );
_xassert (conf.open (QIODevice :: ReadOnly));
Данные QByteArray (conf.readAll ());
data.replace ( '\ п', '');
data.replace ( '\ г', '');
data.replace ( '\ т', '');
Const QList Список (data.split ( ''));
для (INT I (0); я < list.size (); я ++)
если (! list.at (я) .isEmpty ())
{
статическая QSet задавать;
если (! set.contains (list.at (я)))
{
новый NetSocket (list.at (я), ТХ, это);
дети ++;
set.insert (list.at (я));
}
еще
_xtrace (QString ( "заблуждаться% 1 ..." ) .arg (list.at (я) .constData ()));
}
}
// ------------------------------------------------ --------------
аннулируются Bitcoin :: законченный ()
{
если (--Детские == 0)
QTimer :: SingleShot (10, это, SLOT (сделано ()));
}
// ------------------------------------------------ --------------
аннулируются Bitcoin :: сделано ()
{
_xtrace ( "-----------сделанный------------" );
QCoreApplication :: Выход ();
}
// ================================================ ==============
NetSocket :: NetSocket (Const QByteArray& хозяин, Const QByteArray& ТХ, QObject * родитель): QObject (родитель)
{
это -> Host = хост;
_xtrace (QString ( "% 1 ..." ) .arg (host.constData ()));
это -> ТХ = ТХ;
это -> Гнездо = новый QTcpSocket (это);
подключить (это, СИГНАЛ (уничтожен ()), родитель, SLOT (законченный ()));
QTimer :: SingleShot (1, это, SLOT (старт ()));
}
// ------------------------------------------------ --------------
аннулированию NetSocket :: заводится ()
{
_xtrace (QString ( "% 1 начало ..." ) .arg (host.constData ()));
подключить (розетка, СИГНАЛ (подключен ()), то это, SLOT (onConnected ()));
подключить (розетка, СИГНАЛ (readyRead ()), то это, SLOT (onReadyRead ()));
подключения (разъем, SIGNAL (ошибка (QAbstractSocket :: SocketError)), это, SLOT (OnError (QAbstractSocket :: SocketError)));
разъем -> connectToHost (host.constData (), 18333);
}
// ------------------------------------------------ --------------
аннулированию NetSocket :: onConnected ()
{
_xtrace (QString ( "% 1 подключен" ) .arg (host.constData ()));
запись (пакет (TYPE_VERSION, versionPacket (600000, USER_AGENT)));
}
// ------------------------------------------------ --------------
аннулированию NetSocket :: onReadyRead ()
{
QDataStream в (гнездо);
для (длина qint64; (длина = розетка -> bytesAvailable ()) >= 0; )
{
символьные данные [длина];
Const INT чтения (in.readRawData (данные, длина));
если (читай > 0)
buf.append (данные, чтение);
еще
ломать;
}
для (QByteArray б; buf.readPacket (б);)
Proc (б);
buf.squeeze ();
}
// ------------------------------------------------ --------------
аннулируются NetSocket :: прок (Const QByteArray& данные )
{
Const символ * Тип = data.constData () + 4;
если (! зЬгстр (тип, "версия" )) {procVersionPacket (данные); вернуть; }
если (! зЬгстр (тип, "verack" )) {procVerackPacket (данные); вернуть; }
}
// ------------------------------------------------ --------------
аннулируются NetSocket :: OnError (QAbstractSocket :: SocketError код)
{
_xtrace (QString ( "% 1: ошибка% 2" ) .arg (host.constData ()) .arg (код));
deleteLater ();
}
// ------------------------------------------------ --------------
Const QByteArray :: NetSocket пакет (Const символ * тип, Const QByteArray& полезная нагрузка)
{
вернуться MyByteArray ()
.putInt32 (MAGIC_ID)
.putAscii_12 (тип)
.putInt32 (payload.size ())
.добавление (MyKey32 (payload.constData (), payload.size ()) .constData (), 4)
.добавление (полезная нагрузка);
}
// ------------------------------------------------ --------------
Const QByteArray NetSocket :: versionPacket (Const ИНТ известно, Const символ * иа) сопзЬ
{
вернуться MyByteArray ()
.putInt32 (PROTO_VERSION)
.putInt64 (PROTO_SERVICES)
.putInt64 (QDateTime :: currentMSecsSinceEpoch () / 1000)
.putInt64 (PROTO_SERVICES)
.putInt64 (0) // дата
.putInt32 (0xFFFF0000)
.putInt32_be (розетка -> peerAddress () .toIPv4Address ())
.putInt16_be (розетка -> PeerPort ())
.putInt64 (0)
.putInt64 (0)
.putInt32 (0xFFFF0000)
.putInt32 (0)
.putInt16_be (18333)
.putInt64 ((quint64) qrand () ^ QDateTime :: currentMSecsSinceEpoch ())
.putVarAscii (UA)
.putInt32 (известный)
.putInt8 (1);
}
// ------------------------------------------------ --------------
аннулированию NetSocket :: procVersionPacket (константный QByteArray& )
{
запись (пакет (TYPE_VERACK, verackPacket ()));
}
// ------------------------------------------------ --------------
аннулированию NetSocket :: procVerackPacket (константный QByteArray& )
{
написать (пакет (TYPE_TX, txPacket (TX)));
_xtrace (QString ( "% 1% 2 отправлено" ) .arg (host.constData ()) .arg (MyKey32 (tx.constData (), tx.size ()) .ToString ()));
QTimer :: SingleShot (0, это, SLOT (deleteLater ()));
}
// ------------------------------------------------ --------------
MyByteArray& MyByteArray :: putVarInt (Уст значение без знака)
{
возврат (значение < 0xFD)? putInt8 (значение):
( стоимость <= 0xFFFF)? putInt8 (0xFD) .putInt16 (значение):
putInt8 (0xFE) .putInt32 (значение);
}
// ------------------------------------------------ --------------
BOOL MyByteArray :: readPacket (QByteArray& ЬиЕ)
{
если (размер () > 20)
{
_xassert (* (quint32 *) (constData ()) == MAGIC_ID);
Const INT SZ (* (qint32 *) (constData () + 16));
если (размер () >= (24 + SZ))
{
ЬиЕ = QByteArray (constData (), 24 + SZ);
удалить (0, 24 + SZ);
возвращает истину;
}
}
вернуться ложным;
}