Bitcoin Forum
July 21, 2018, 08:16:56 PM *
News: Latest stable version of Bitcoin Core: 0.16.1  [Torrent]. (New!)
 
   Home   Help Search Donate Login Register  
Pages: [1]
  Print  
Author Topic: sending rawtransaction in bitcoin testnet (double spend)  (Read 880 times)
Armin van Bruggen
Full Member
***
Offline Offline

Activity: 225
Merit: 100


Stratege, berechnend


View Profile
November 04, 2016, 10:21:25 AM
 #1

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:
Quote
We can’t publish this new transaction using Coinbin because it will be rejected as a double spend.
1532204216
Hero Member
*
Offline Offline

Posts: 1532204216

View Profile Personal Message (Offline)

Ignore
1532204216
Reply with quote  #2

1532204216
Report to moderator
1532204216
Hero Member
*
Offline Offline

Posts: 1532204216

View Profile Personal Message (Offline)

Ignore
1532204216
Reply with quote  #2

1532204216
Report to moderator
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.
Jhanzo
Hero Member
*****
Offline Offline

Activity: 728
Merit: 503



View Profile
November 04, 2016, 10:38:46 AM
 #2

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.
Armin van Bruggen
Full Member
***
Offline Offline

Activity: 225
Merit: 100


Stratege, berechnend


View Profile
November 04, 2016, 10:43:05 AM
 #3

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
Hero Member
*****
Offline Offline

Activity: 728
Merit: 503



View Profile
November 04, 2016, 10:54:46 AM
 #4

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.
Armin van Bruggen
Full Member
***
Offline Offline

Activity: 225
Merit: 100


Stratege, berechnend


View Profile
November 04, 2016, 11:10:27 AM
 #5

@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_-agcI

I 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 Offline

Activity: 1260
Merit: 1000


View Profile
November 06, 2016, 06:25:09 AM
 #6

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"

Code:
#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
Full Member
***
Offline Offline

Activity: 225
Merit: 100


Stratege, berechnend


View Profile
November 06, 2016, 06:00:25 PM
 #7

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"

Code:
#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 Offline

Activity: 1260
Merit: 1000


View Profile
November 06, 2016, 06:34:24 PM
 #8

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
Full Member
***
Offline Offline

Activity: 225
Merit: 100


Stratege, berechnend


View Profile
November 06, 2016, 06:39:56 PM
 #9

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_list

Would drop you a tip if working of course Wink
amaclin
Legendary
*
Offline Offline

Activity: 1260
Merit: 1000


View Profile
November 06, 2016, 08:02:34 PM
 #10

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_list
Would drop you a tip if working of course Wink
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 )
Pages: [1]
  Print  
 
Jump to:  

Sponsored by , a Bitcoin-accepting VPN.
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!