Armin van Bruggen (OP)
Full Member
![*](https://bitcointalk.org/Themes/custom1/images/star.gif) ![*](https://bitcointalk.org/Themes/custom1/images/star.gif)
Offline
Activity: 232
Merit: 101
Stratege, berechnend
|
![](https://bitcointalk.org/Themes/custom1/images/post/question.gif) |
November 04, 2016, 10:21:25 AM |
|
After reading this article: http://bitzuma.com/posts/how-to-clear-a-stuck-bitcoin-transaction/I would like to try a double spending (in bitcoin testnetwork). Creating the transaction and signing it wasn't a problem. Now I'm looking for a way to send the second transaction (the first one was sent with 0.00000000 fee), now I would need to resent the transaction with a fee, so it get's processed by the testnet network of bitcoin. How to submit now these second transaction? All services I tried blocked this transaction. As the article says: We can’t publish this new transaction using Coinbin because it will be rejected as a double spend.
|
|
|
|
Jhanzo
|
![](https://bitcointalk.org/Themes/custom1/images/post/xx.gif) |
November 04, 2016, 10:38:46 AM |
|
It got rejected because the the node(s) those services are relying on still have the first transaction. You'll have to wait until they drop it.
|
Trusted an exchange that climbed to the top 3 in just under 2 years with your money? you are fucking stupid.
|
|
|
Armin van Bruggen (OP)
Full Member
![*](https://bitcointalk.org/Themes/custom1/images/star.gif) ![*](https://bitcointalk.org/Themes/custom1/images/star.gif)
Offline
Activity: 232
Merit: 101
Stratege, berechnend
|
![](https://bitcointalk.org/Themes/custom1/images/post/xx.gif) |
November 04, 2016, 10:43:05 AM |
|
It got rejected because the the node(s) those services are relying on still have the first transaction. You'll have to wait until they drop it.
In case I want to get this transaction appear too in the network without the first transaction being dropped/processed by the network, how can I do so?
|
|
|
|
Jhanzo
|
![](https://bitcointalk.org/Themes/custom1/images/post/xx.gif) |
November 04, 2016, 10:54:46 AM Last edit: November 04, 2016, 11:05:13 AM by Jhanzo |
|
It got rejected because the the node(s) those services are relying on still have the first transaction. You'll have to wait until they drop it.
In case I want to get this transaction appear too in the network without the first transaction being dropped/processed by the network, how can I do so? Unconfirmed transactions rarely gets dropped by the entire network. There can be more than 1 identical unconfirmed transactions in the network, but not in a nodes mempool. As long as a node doesn't have the first transaction, it can accept the second transaction and will try to relay it to the rest of the network. So to answer your question (replacing the word "network" with "nodes"), you can't. BTW RBF pretty much erased the need to manually double spending a transaction because they're stuck. Use RBF instead.
|
Trusted an exchange that climbed to the top 3 in just under 2 years with your money? you are fucking stupid.
|
|
|
Armin van Bruggen (OP)
Full Member
![*](https://bitcointalk.org/Themes/custom1/images/star.gif) ![*](https://bitcointalk.org/Themes/custom1/images/star.gif)
Offline
Activity: 232
Merit: 101
Stratege, berechnend
|
![](https://bitcointalk.org/Themes/custom1/images/post/xx.gif) |
November 04, 2016, 11:10:27 AM |
|
@Jhanzo First of all, thanks for this detailed answer! Let me try, what I would like to do, please check this video: https://www.youtube.com/watch?v=RtGzV_-agcII would like to built the same, but open source the code. I'm running bitcoin-classic daemon on my ubuntu server. Now I'm looking for a description how to "double spend" the coins I received from a user (first transaction with no fee, second transaction with small fee, so user receives his depoisted amount nearly full back and a double spend was done). I would like to use testnet for whole script. Could you explain me how to process the transactions (I know how to create & sign them), but how to send them now?
|
|
|
|
amaclin
Legendary
Offline
Activity: 1260
Merit: 1019
|
![](https://bitcointalk.org/Themes/custom1/images/post/xx.gif) |
November 06, 2016, 06:25:09 AM |
|
Could you explain me how to process the transactions (I know how to create & sign them), but how to send them now? This is very "dirty" piece of code, but it works. Of course, this one is "for educational purposes only" #include <QTimer> #include <QDebug> #include <QFile> #include <QList> #include <QByteArray> #include <QDateTime> #include <QHostAddress> #include <QCoreApplication> #include <QDataStream>
#include "Bitcoin.h"
#define _xtrace(X) qDebug ( ) << ( X ) #define _xassert(X) Q_ASSERT ( X )
#define MAGIC_ID 0x709110b
#define TYPE_VERSION ( "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 ( "getdata" "\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" ) #define TYPE_PING ( "ping" "\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" ) #define TYPE_PONG ( "pong" "\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" ) #define TYPE_TX ( "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) // can be NODE_NETWORK
Bitcoin::Bitcoin ( const QByteArray& tx, QObject* parent) : QObject ( parent ) { this -> children = 0; this -> tx = tx; QTimer::singleShot ( 10, this, SLOT ( start ( ) ) ); } //-------------------------------------------------------------- void Bitcoin::start ( ) { QFile conf ( "PushTxTool.conf" ); _xassert ( conf.open ( QIODevice::ReadOnly ) ); QByteArray data ( conf.readAll ( ) ); data.replace ( '\n', ' ' ); data.replace ( '\r', ' ' ); data.replace ( '\t', ' ' ); const QList<QByteArray> list ( data.split ( ' ' ) ); for ( int i ( 0 ); i < list.size ( ); i++ ) if ( !list.at ( i ).isEmpty ( ) ) { static QSet<QByteArray> set; if ( !set.contains ( list.at ( i ) ) ) { new NetSocket ( list.at ( i ), tx, this ); children++; set.insert ( list.at ( i ) ); } else _xtrace ( QString ( "err %1 ..." ).arg ( list.at ( i ).constData ( ) ) ); } } //-------------------------------------------------------------- void Bitcoin::finished ( ) { if ( --children == 0 ) QTimer::singleShot ( 10, this, SLOT ( done ( ) ) ); } //-------------------------------------------------------------- void Bitcoin::done ( ) { _xtrace ( "-----------done------------" ); QCoreApplication::exit ( ); } //============================================================== NetSocket::NetSocket ( const QByteArray& host, const QByteArray& tx, QObject* parent ) : QObject ( parent ) { this -> host = host; _xtrace ( QString ( "%1 ..." ).arg ( host.constData ( ) ) ); this -> tx = tx; this -> socket = new QTcpSocket ( this ); connect ( this, SIGNAL ( destroyed ( ) ), parent, SLOT ( finished ( ) ) ); QTimer::singleShot ( 1, this, SLOT ( start ( ) ) ); } //-------------------------------------------------------------- void NetSocket::start ( ) { _xtrace ( QString ( "%1 start ..." ).arg ( host.constData ( ) ) ); connect ( socket, SIGNAL ( connected ( ) ), this, SLOT ( onConnected ( ) ) ); connect ( socket, SIGNAL ( readyRead ( ) ), this, SLOT ( onReadyRead ( ) ) ); connect ( socket, SIGNAL ( error ( QAbstractSocket::SocketError ) ), this, SLOT ( onError ( QAbstractSocket::SocketError ) ) ); socket -> connectToHost ( host.constData ( ), 18333 ); } //-------------------------------------------------------------- void NetSocket::onConnected ( ) { _xtrace ( QString ( "%1 connected" ).arg ( host.constData ( ) ) ); write ( packet ( TYPE_VERSION, versionPacket ( 600000, USER_AGENT ) ) ); } //-------------------------------------------------------------- void NetSocket::onReadyRead ( ) { QDataStream in ( socket ); for ( qint64 length; (length = socket -> bytesAvailable ( )) >= 0; ) { char data [length]; const int read ( in.readRawData ( data, length ) ); if ( read > 0 ) buf.append ( data, read ); else break; } for ( QByteArray b; buf.readPacket ( b ); ) proc ( b ); buf.squeeze ( ); } //-------------------------------------------------------------- void NetSocket::proc ( const QByteArray& data ) { const char* type = data.constData ( ) + 4; if ( !strcmp ( type, "version" ) ) { procVersionPacket ( data ); return; } if ( !strcmp ( type, "verack" ) ) { procVerackPacket ( data ); return; } } //-------------------------------------------------------------- void NetSocket::onError ( QAbstractSocket::SocketError code ) { _xtrace ( QString ( "%1 : error %2" ).arg ( host.constData ( ) ).arg ( code ) ); deleteLater ( ); } //-------------------------------------------------------------- const QByteArray NetSocket::packet ( const char* type, const QByteArray& payload ) { return MyByteArray ( ) .putInt32 ( MAGIC_ID ) .putAscii_12 ( type ) .putInt32 ( payload.size ( ) ) .append ( MyKey32 ( payload.constData ( ), payload.size ( ) ).constData ( ), 4 ) .append ( payload ); } //-------------------------------------------------------------- const QByteArray NetSocket::versionPacket ( const int known, const char* ua ) const { return MyByteArray ( ) .putInt32 ( PROTO_VERSION ) .putInt64 ( PROTO_SERVICES ) .putInt64 ( QDateTime::currentMSecsSinceEpoch ( ) / 1000 ) .putInt64 ( PROTO_SERVICES ) .putInt64 ( 0 ) // date .putInt32 ( 0xFFFF0000 ) .putInt32_be ( socket -> peerAddress ( ).toIPv4Address ( ) ) .putInt16_be ( socket -> peerPort ( ) ) .putInt64 ( 0 ) .putInt64 ( 0 ) .putInt32 ( 0xFFFF0000 ) .putInt32 ( 0 ) .putInt16_be ( 18333 ) .putInt64 ( (quint64)qrand ( ) ^ QDateTime::currentMSecsSinceEpoch ( ) ) .putVarAscii ( ua ) .putInt32 ( known ) .putInt8 ( 1 ); } //-------------------------------------------------------------- void NetSocket::procVersionPacket ( const QByteArray& ) { write ( packet ( TYPE_VERACK, verackPacket ( ) ) ); } //-------------------------------------------------------------- void NetSocket::procVerackPacket ( const QByteArray& ) { write ( packet ( TYPE_TX, txPacket ( tx ) ) ); _xtrace ( QString ( "%1 sent %2" ).arg ( host.constData ( ) ).arg ( MyKey32 ( tx.constData ( ), tx.size ( ) ).toString ( ) ) ); QTimer::singleShot ( 0, this, SLOT ( deleteLater ( ) ) ); } //-------------------------------------------------------------- MyByteArray& MyByteArray::putVarInt ( const unsigned value ) { return ( value < 0xFD ) ? putInt8 ( value ) : ( value <= 0xFFFF ) ? putInt8 ( 0xFD ).putInt16 ( value ) : putInt8 ( 0xFE ).putInt32 ( value ); } //-------------------------------------------------------------- bool MyByteArray::readPacket ( QByteArray& buf ) { if ( size ( ) > 20 ) { _xassert ( *(quint32*)(constData ( )) == MAGIC_ID ); const int sz ( *(qint32*)(constData ( ) + 16) ); if ( size ( ) >= ( 24 + sz ) ) { buf = QByteArray ( constData ( ), 24 + sz ); remove ( 0, 24 + sz ); return true; } } return false; }
|
|
|
|
Armin van Bruggen (OP)
Full Member
![*](https://bitcointalk.org/Themes/custom1/images/star.gif) ![*](https://bitcointalk.org/Themes/custom1/images/star.gif)
Offline
Activity: 232
Merit: 101
Stratege, berechnend
|
![](https://bitcointalk.org/Themes/custom1/images/post/xx.gif) |
November 06, 2016, 06:00:25 PM |
|
Could you explain me how to process the transactions (I know how to create & sign them), but how to send them now? This is very "dirty" piece of code, but it works. Of course, this one is "for educational purposes only" #include <QTimer> #include <QDebug> #include <QFile> #include <QList> #include <QByteArray> #include <QDateTime> #include <QHostAddress> #include <QCoreApplication> #include <QDataStream>
#include "Bitcoin.h"
#define _xtrace(X) qDebug ( ) << ( X ) #define _xassert(X) Q_ASSERT ( X )
#define MAGIC_ID 0x709110b
#define TYPE_VERSION ( "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 ( "getdata" "\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" ) #define TYPE_PING ( "ping" "\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" ) #define TYPE_PONG ( "pong" "\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" ) #define TYPE_TX ( "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) // can be NODE_NETWORK
Bitcoin::Bitcoin ( const QByteArray& tx, QObject* parent) : QObject ( parent ) { this -> children = 0; this -> tx = tx; QTimer::singleShot ( 10, this, SLOT ( start ( ) ) ); } //-------------------------------------------------------------- void Bitcoin::start ( ) { QFile conf ( "PushTxTool.conf" ); _xassert ( conf.open ( QIODevice::ReadOnly ) ); QByteArray data ( conf.readAll ( ) ); data.replace ( '\n', ' ' ); data.replace ( '\r', ' ' ); data.replace ( '\t', ' ' ); const QList<QByteArray> list ( data.split ( ' ' ) ); for ( int i ( 0 ); i < list.size ( ); i++ ) if ( !list.at ( i ).isEmpty ( ) ) { static QSet<QByteArray> set; if ( !set.contains ( list.at ( i ) ) ) { new NetSocket ( list.at ( i ), tx, this ); children++; set.insert ( list.at ( i ) ); } else _xtrace ( QString ( "err %1 ..." ).arg ( list.at ( i ).constData ( ) ) ); } } //-------------------------------------------------------------- void Bitcoin::finished ( ) { if ( --children == 0 ) QTimer::singleShot ( 10, this, SLOT ( done ( ) ) ); } //-------------------------------------------------------------- void Bitcoin::done ( ) { _xtrace ( "-----------done------------" ); QCoreApplication::exit ( ); } //============================================================== NetSocket::NetSocket ( const QByteArray& host, const QByteArray& tx, QObject* parent ) : QObject ( parent ) { this -> host = host; _xtrace ( QString ( "%1 ..." ).arg ( host.constData ( ) ) ); this -> tx = tx; this -> socket = new QTcpSocket ( this ); connect ( this, SIGNAL ( destroyed ( ) ), parent, SLOT ( finished ( ) ) ); QTimer::singleShot ( 1, this, SLOT ( start ( ) ) ); } //-------------------------------------------------------------- void NetSocket::start ( ) { _xtrace ( QString ( "%1 start ..." ).arg ( host.constData ( ) ) ); connect ( socket, SIGNAL ( connected ( ) ), this, SLOT ( onConnected ( ) ) ); connect ( socket, SIGNAL ( readyRead ( ) ), this, SLOT ( onReadyRead ( ) ) ); connect ( socket, SIGNAL ( error ( QAbstractSocket::SocketError ) ), this, SLOT ( onError ( QAbstractSocket::SocketError ) ) ); socket -> connectToHost ( host.constData ( ), 18333 ); } //-------------------------------------------------------------- void NetSocket::onConnected ( ) { _xtrace ( QString ( "%1 connected" ).arg ( host.constData ( ) ) ); write ( packet ( TYPE_VERSION, versionPacket ( 600000, USER_AGENT ) ) ); } //-------------------------------------------------------------- void NetSocket::onReadyRead ( ) { QDataStream in ( socket ); for ( qint64 length; (length = socket -> bytesAvailable ( )) >= 0; ) { char data [length]; const int read ( in.readRawData ( data, length ) ); if ( read > 0 ) buf.append ( data, read ); else break; } for ( QByteArray b; buf.readPacket ( b ); ) proc ( b ); buf.squeeze ( ); } //-------------------------------------------------------------- void NetSocket::proc ( const QByteArray& data ) { const char* type = data.constData ( ) + 4; if ( !strcmp ( type, "version" ) ) { procVersionPacket ( data ); return; } if ( !strcmp ( type, "verack" ) ) { procVerackPacket ( data ); return; } } //-------------------------------------------------------------- void NetSocket::onError ( QAbstractSocket::SocketError code ) { _xtrace ( QString ( "%1 : error %2" ).arg ( host.constData ( ) ).arg ( code ) ); deleteLater ( ); } //-------------------------------------------------------------- const QByteArray NetSocket::packet ( const char* type, const QByteArray& payload ) { return MyByteArray ( ) .putInt32 ( MAGIC_ID ) .putAscii_12 ( type ) .putInt32 ( payload.size ( ) ) .append ( MyKey32 ( payload.constData ( ), payload.size ( ) ).constData ( ), 4 ) .append ( payload ); } //-------------------------------------------------------------- const QByteArray NetSocket::versionPacket ( const int known, const char* ua ) const { return MyByteArray ( ) .putInt32 ( PROTO_VERSION ) .putInt64 ( PROTO_SERVICES ) .putInt64 ( QDateTime::currentMSecsSinceEpoch ( ) / 1000 ) .putInt64 ( PROTO_SERVICES ) .putInt64 ( 0 ) // date .putInt32 ( 0xFFFF0000 ) .putInt32_be ( socket -> peerAddress ( ).toIPv4Address ( ) ) .putInt16_be ( socket -> peerPort ( ) ) .putInt64 ( 0 ) .putInt64 ( 0 ) .putInt32 ( 0xFFFF0000 ) .putInt32 ( 0 ) .putInt16_be ( 18333 ) .putInt64 ( (quint64)qrand ( ) ^ QDateTime::currentMSecsSinceEpoch ( ) ) .putVarAscii ( ua ) .putInt32 ( known ) .putInt8 ( 1 ); } //-------------------------------------------------------------- void NetSocket::procVersionPacket ( const QByteArray& ) { write ( packet ( TYPE_VERACK, verackPacket ( ) ) ); } //-------------------------------------------------------------- void NetSocket::procVerackPacket ( const QByteArray& ) { write ( packet ( TYPE_TX, txPacket ( tx ) ) ); _xtrace ( QString ( "%1 sent %2" ).arg ( host.constData ( ) ).arg ( MyKey32 ( tx.constData ( ), tx.size ( ) ).toString ( ) ) ); QTimer::singleShot ( 0, this, SLOT ( deleteLater ( ) ) ); } //-------------------------------------------------------------- MyByteArray& MyByteArray::putVarInt ( const unsigned value ) { return ( value < 0xFD ) ? putInt8 ( value ) : ( value <= 0xFFFF ) ? putInt8 ( 0xFD ).putInt16 ( value ) : putInt8 ( 0xFE ).putInt32 ( value ); } //-------------------------------------------------------------- bool MyByteArray::readPacket ( QByteArray& buf ) { if ( size ( ) > 20 ) { _xassert ( *(quint32*)(constData ( )) == MAGIC_ID ); const int sz ( *(qint32*)(constData ( ) + 16) ); if ( size ( ) >= ( 24 + sz ) ) { buf = QByteArray ( constData ( ), 24 + sz ); remove ( 0, 24 + sz ); return true; } } return false; }
Isn't there a way to use the bitcoin daemon I run on a server in testnetmode to send a double spend transaction?
|
|
|
|
amaclin
Legendary
Offline
Activity: 1260
Merit: 1019
|
![](https://bitcointalk.org/Themes/custom1/images/post/xx.gif) |
November 06, 2016, 06:34:24 PM |
|
Isn't there a way to use the bitcoin daemon I run on a server in testnetmode to send a double spend transaction? Sorry. I thought that you are asking "how to send conflicting transaction?" not "how to send conflicting transaction with custom bitcoin client?"
|
|
|
|
Armin van Bruggen (OP)
Full Member
![*](https://bitcointalk.org/Themes/custom1/images/star.gif) ![*](https://bitcointalk.org/Themes/custom1/images/star.gif)
Offline
Activity: 232
Merit: 101
Stratege, berechnend
|
![](https://bitcointalk.org/Themes/custom1/images/post/xx.gif) |
November 06, 2016, 06:39:56 PM |
|
Isn't there a way to use the bitcoin daemon I run on a server in testnetmode to send a double spend transaction? Sorry. I thought that you are asking "how to send conflicting transaction?" not "how to send conflicting transaction with custom bitcoin client?" Would be fine if you could show me how to do this using bitcoind command set: https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_calls_listWould drop you a tip if working of course ![Wink](https://bitcointalk.org/Smileys/default/wink.gif)
|
|
|
|
amaclin
Legendary
Offline
Activity: 1260
Merit: 1019
|
![](https://bitcointalk.org/Themes/custom1/images/post/xx.gif) |
November 06, 2016, 08:02:34 PM |
|
I can not. I never used bitcoin client for sending transactions. I gave you a program written in C++ for broadcasting raw transactions for a number of nodes. (Sorry, I havent't looked the sources for a couple of years - the program works and there is no reason to remember how ![Grin](https://bitcointalk.org/Smileys/default/grin.gif) )
|
|
|
|
|