aceat64/EasyBitcoin-PHP

Bitcoind returns error “JSON value is not an array as expected”, using easybitcoin.php to call sendmany()

rhinogroup opened this issue · 2 comments

[Posted the below in stackoverflow as well]
Link: Here

I am creating a php script to use the sendmany() call to bitcoind. After some database calisthenics involving hitting three tables for permissions, checking user privileges and ensuring the send amounts are correct and there are enough bitcoins on the server, I wind up with the following array to send bitcoins to:

Array
(
    [0] => Array
        (
            [coinadd] => mteCLqiEK7v5d3YbDQtxj8oKcdhtHRtXcw
            [amount] => 0.21445033
        )

    [1] => Array
        (
            [coinadd] => 2N5aa9FBxGf5xmeLiDz1yJVNYdsfK9GUWWe
            [amount] => 0.02588679
        )

    [2] => Array
        (
            [coinadd] => 2Muf4WEzFqNviURTdvkGSswHyrgMzR8optK
            [amount] => 0.02601681
        )

)

$max = count($paynow);
$b=1;
$amount = 0;
$emit = '{"';
foreach($paynow as $key => $val){
    foreach($val as $k => $v){
        $emit .= "$v";
        if($b <= $max){
            if($k == 'coinadd'){
                $emit .= '":';
            } elseif($k == 'amount') {
                $amnt = $amount += $v;
                if($b !== $max){
                    $emit .= ', "'; 
                }               
            }
        }
    }
    $b++;
}
$emit .= "}";

The above foreach takes the $paytoo array and generates the following json string:

{
"mteCLqiEK7v5d3YbDQtxj8oKcdhtHRtXcw":0.21445033, "2N5aa9FBxGf5xmeLiDz1yJVNYdsfK9GUWWe":0.02588679, "2Muf4WEzFqNviURTdvkGSswHyrgMzR8optK":0.02601681
}

This string passes the JSON lint test on jsonlint.com

I then decode the string to create an array.

$send = json_decode($emit,true);

Array
(
    [mteCLqiEK7v5d3YbDQtxj8oKcdhtHRtXcw] => 0.21445033
    [2N5aa9FBxGf5xmeLiDz1yJVNYdsfK9GUWWe] => 0.02588679
    [2Muf4WEzFqNviURTdvkGSswHyrgMzR8optK] => 0.02601681
)

So far so good.

Now on to the RPC call

$sent = $bitcoin->sendmany( "", $send, 1, "", "", 1, 1, "CONSERVATIVE" );
$err = $bitcoin->error;

Aaaand Kablooie! I get the following error from Bitcoind:

"JSON value is not an array as expected"

If I turn the JSON string into an object, then the error switches to

"JSON value is not an object as expected".

From a comment in Github Here
This snippet of code is from the library's __call method in easybitcoin.php

// If no parameters are passed, this will be an empty array
$params = array_values($params);

// Build the request, it's ok that params might have any empty array
$request = json_encode(array(
    'method' => $method,
    'params' => $params,
    'id'     => $this->id
));So depending on the parameters of the RPC command the general format will be the following.
$myVar->nameofRPCcommand(...);

For example a command that takes two strings will be
$myVar->nameofRPCcommand($myStr1, $myStr2);

Or with a string followed by an array
$myVar->nameofRPCcommand($myStr, $myArr);

Other than slitting my wrists and offering my blood to the programming gods, I've done everything I can think of. Can anyone spot what I am doing wrong here?

I found the problem.

I am going to place it as an answer here in the event someone else has this issue.

foreach($paydata as $pay){
    $mrules = getmerchrules($pay['merchant_id']);
    $coinadd = get_merch_address_to_send_to($pay['merchant_id']);
    if($mrules['autopay'] == 'yes'){
        if($pay['balance'] > $mrules['minpay']){
            if($coinadd !== ''){
                $paynow[$coinadd['coinadd']] = $pay['balance'];
            }
        }
    }
}
Array
(
    [mteCLqiEK7v5d3YbDQtxj8oKcdhtHRtXcw] => 0.21445033
    [2N5aa9FBxGf5xmeLiDz1yJVNYdsfK9GUWWe] => 0.02588679
    [2Muf4WEzFqNviURTdvkGSswHyrgMzR8optK] => 0.02601681
)

At the point in the code that the array above is created, there is no need to do anything else. The problem was that I was converting this array into a json object to send to easybitcoin.php.

What easybitcoin.php expects is an array. So feeding it the array by itself worked. Even though this can'be blamed on anyone but me, the documentation out there is pretty sketchy. So once and for all, I am going to leave this here and hopefully it will save someone some time in the future.

$sent = $bitcoin->sendmany( "", $send, 1, "", "", 1, 1, "CONSERVATIVE" );

Where $send is a simple array as shown above. No other formatting needed. No double quotes, nothing, just pass the array. Yes, stupid, I know. But here we are. Thanks to all those who looked.

LNAPI commented

Works only $sent = $bitcoin->sendmany( "", $send).
But thx! Appreciated.