Bitcoin Forum
May 11, 2024, 12:52:46 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: PHP - Bidcoind check for new transactions.  (Read 1609 times)
OsNaP (OP)
Newbie
*
Offline Offline

Activity: 46
Merit: 0


View Profile
September 06, 2014, 10:30:52 AM
 #1

Hi Guys,

My question is about the "bitcoind listtransactions" method.
I want to have a scalable way of getting all the new "receive" transactions.
This means the only method available would be "bitcoind listtransactions".
Because only that method lets me define a "count" and "from" parameter.

> bitcoind help listtransactions
listtransactions [account] [count=10] [from=0]

So even if i have 100.000 transactions, i could loop through a 100 at a time.
But I don't want to loop over all 100.000 each time i need to check for new transactions.
Only the new transactions are relevant.
This is my main problem.

Ofc, I could stop the loop if I encounter any old transactions.
But this would only be possible if all new transactions would always be added on top of the list.
This wouldnt work if transactions can be added in de middle of the list.
1715388766
Hero Member
*
Offline Offline

Posts: 1715388766

View Profile Personal Message (Offline)

Ignore
1715388766
Reply with quote  #2

1715388766
Report to moderator
1715388766
Hero Member
*
Offline Offline

Posts: 1715388766

View Profile Personal Message (Offline)

Ignore
1715388766
Reply with quote  #2

1715388766
Report to moderator
1715388766
Hero Member
*
Offline Offline

Posts: 1715388766

View Profile Personal Message (Offline)

Ignore
1715388766
Reply with quote  #2

1715388766
Report to moderator
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
OsNaP (OP)
Newbie
*
Offline Offline

Activity: 46
Merit: 0


View Profile
September 06, 2014, 01:13:52 PM
 #2

Doesn't anyone know if new transactions are added to the list at random places.
Or are they always added on top.
theymos
Administrator
Legendary
*
Offline Offline

Activity: 5194
Merit: 12983


View Profile
September 06, 2014, 03:34:59 PM
Last edit: September 06, 2014, 03:45:44 PM by theymos
 #3

Doesn't anyone know if new transactions are added to the list at random places.
Or are they always added on top.

Transactions aren't reordered within a single wallet, and new transactions are always added to the top, though transactions could be reordered if you move keys between wallets or use -zapwallettxes.

Quote
I want to have a scalable way of getting all the new "receive" transactions.

listtransactions loops through every transaction in your wallet, so it isn't very fast or scalable. It's better to use one of these:
- getreceivedbyaccount or getreceivedbyaddress
- -walletnotify + gettransaction
- listsinceblock

Keep in mind that the chain can reorg, which can cause confirmed transactions to have a different number of confirmations or even become invalid. You need to handle this, especially if you use walletnotify or listsinceblock. I know that they're limited and a bit confusing, but I usually recommend bitcoind accounts for small- to medium-size sites because it's very easy to do things correctly with them.

1NXYoJ5xU91Jp83XfVMHwwTUyZFK64BoAD
OsNaP (OP)
Newbie
*
Offline Offline

Activity: 46
Merit: 0


View Profile
September 06, 2014, 04:03:17 PM
 #4

listtransactions loops through every transaction in your wallet, so it isn't very fast or scalable.

I could make the "listtransactions" loop scalable by using the "[count=10] [from=0]" parameters.
Right now I loop 50 entries at a time.
And if I see a transaction thats already in my database i stop the loop.

This will make my approach scalable.
But it will only work if all new incoming transactions are added to the top of the list.

Because if any new transaction is added before a known transaction, my approach will skip that transaction.
theymos
Administrator
Legendary
*
Offline Offline

Activity: 5194
Merit: 12983


View Profile
September 06, 2014, 04:21:19 PM
 #5

I could make the "listtransactions" loop scalable by using the "[count=10] [from=0]" parameters.

listtransactions loops through all wallet transactions (internally, in the implementation) no matter what arguments you give it.

1NXYoJ5xU91Jp83XfVMHwwTUyZFK64BoAD
OsNaP (OP)
Newbie
*
Offline Offline

Activity: 46
Merit: 0


View Profile
September 06, 2014, 04:54:59 PM
 #6

Ha ok,
So lets say i'll use listsinceblock.
Will new transactions always be added in higher blocks.
Or could there be blocks added before a older block.

Basically my question is, will I loss transactions using "listsinceblock".
theymos
Administrator
Legendary
*
Offline Offline

Activity: 5194
Merit: 12983


View Profile
September 06, 2014, 05:06:55 PM
 #7

New transactions will either be in new blocks or there will be a reorg and the block hash you give to listsinceblock will be outside of the main chain, causing listsinceblock to dump all of your transactions.

1NXYoJ5xU91Jp83XfVMHwwTUyZFK64BoAD
OsNaP (OP)
Newbie
*
Offline Offline

Activity: 46
Merit: 0


View Profile
September 06, 2014, 05:24:41 PM
 #8

New transactions will either be in new blocks or there will be a reorg and the block hash you give to listsinceblock will be outside of the main chain, causing listsinceblock to dump all of your transactions.

But dumping all transactions is a problem right?
Like memory.
Is there a way to batch the transactions?
We will be having a lot of transactions.
theymos
Administrator
Legendary
*
Offline Offline

Activity: 5194
Merit: 12983


View Profile
September 07, 2014, 01:51:22 AM
 #9

You could check that the block is in the main chain by using getblock and ensuring that the number of confirmations is non-zero. You need to do something to handle reorgs, though; probably something like bitcoind's CBlockLocator.

walletnotify is also good.

1NXYoJ5xU91Jp83XfVMHwwTUyZFK64BoAD
OsNaP (OP)
Newbie
*
Offline Offline

Activity: 46
Merit: 0


View Profile
September 08, 2014, 11:24:44 PM
 #10

So if a block has 0 confirmations its labeled an orphan block.
And listsinceblock will return all my transactions.

I just came up with some concept code.
It fixes the memory problem.
But my concept will only work if reorgs stops happening after a certain amount of confirmations (7).
Could you maybe verify.


Code:
min = 1
max = 7

lastBlockHash = database.lastBlockHash
blockData = bitcoind.getblock(lastBlockHash)

if(blockData.confirmations < min)
{
    lastBlockHash = bitcoind.getblockhash(max)
}

response = bitcoind.listsinceblock(lastBlockHash)

foreach(response.transactions)
{
    ...
}

01BTC10
VIP
Hero Member
*
Offline Offline

Activity: 756
Merit: 503



View Profile
September 09, 2014, 04:28:37 AM
Last edit: September 09, 2014, 05:20:54 AM by 01BTC10
 #11

I wonder if this snippet could help:

Code:
#!/usr/bin/env php

/* depends on: */
/* php5-curl */
/* https://github.com/aceat64/EasyBitcoin-PHP */

<?php
require_once 'include/easybitcoin.php';

$min_confirm 6;
$bitcoinrpc_user 'bitcoinrpc';
$bitcoinrpc_pass 'bitcoinrpc_pass';
$bitcoinrpc_host 'localhost';
$bitcoinrpc_port '8332'

if (
$argc != || strlen($argv[1]) != 64)
  {
    echo 
"usage:$argv[0] tx\n";
    die();
  }

$tx $argv[1];
$file "/tmp/".md5($tx);
$lock fopen($file"w+");

if (
flock($lockLOCK_EX LOCK_NB))
  {
    
fwrite($lock$tx);
  }
else
  {
    echo 
"Process already running for same tx, exiting\n";
    die();
  }

$bitcoin = new Bitcoin($bitcoinrpc_user$bitcoinrpc_pass$bitcoinrpc_host$bitcoinrpc_port);
$bitcoin->gettransaction($tx);

if (
$bitcoin->status != 200)
  {
    echo 
"Error: $bitcoin->error\n";
    die();
  }

if (
$bitcoin->response['result']['details'][0]['category'] === "receive")
  {
    while (
1)
      {
        
$bitcoin->gettransaction($tx);
        
$address =$bitcoin->response['result']['details'][0]['address'];
        
$amount  =$bitcoin->response['result']['amount'];
        
$confirm =$bitcoin->response['result']['confirmations'];

        echo 
"$address -> $amount confirmations:$confirm\n";

        if (
$confirm >= $min_confirm)
          {
            echo 
"$min_confirm or more confirmations for $tx\n";
            
$payment = array("address" => $address"tx" => $tx"amount" => $amount);

            
/****************************************** Process tx stored in $payment here ******************************************/
            
die();
          }

        
sleep(30); // Check number of confirmations every 30sec.
      
}
  }

?>

The infinite loop has to be modified so it won't loop to infinity when getting a tx from a yet to be orphaned block.

Then you only need to add this line to bitcoin.conf to trigger the script for each new tx that is affecting the wallet:
Code:
walletnotify=/path_to/script.php %s

OsNaP (OP)
Newbie
*
Offline Offline

Activity: 46
Merit: 0


View Profile
September 09, 2014, 06:00:26 AM
 #12

Hi 01BTC10,

Srry, but thats not really helpful.
I wouldn't really recommend using walletnotify.
Because I can't afford to loss or skip any transactions.

Let's say something goes wrong.
Maybe your website is down for some hours.
Bitcoind will still call walletnotify, but your script can't process the transactions.

I would prefer using listsinceblock.
Because you'll get all transactions since your last synced up.
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!