Bitcoind возвращает ошибку "Значение JSON не является ожидаемым массивом", используя easybitcoin.php для вызова sendmany()

Я создаю PHP-скрипт для использования вызова sendmany() для bitcoind. После некоторой проверки базы данных, включающей выбор трех таблиц для разрешений, проверку пользовательских привилегий и обеспечение правильности отправляемых сумм и наличия достаточного количества биткойнов на сервере, я получаю следующий массив для отправки биткойнов:

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

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

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

)

РЕДАКТИРОВАТЬ: я изменил ниже foreach в гораздо более простую версию. Я бы сделал зачеркнуть, хотя бы показать, что это было изменено, но не могу найти, как зачеркнуть.

$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 .= "}";

Вышеупомянутый foreach берет массив $ paytoo и генерирует следующую строку json:

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

Эта строка проходит тест JSON Lint на jsonlint.com

Затем я декодирую строку, чтобы создать массив.

$send = json_decode($emit,true);

Редактировать; Теперь новый foreach генерирует приведенный ниже массив напрямую, без строки json, просто direct. Кажется, намного чище, чем раньше.

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
)

Все идет нормально.

Теперь к вызову RPC

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

РЕДАКТИРОВАТЬ: Некоторое причудливое эхо получает мне эту строку, которая фактически отправляется на сервер биткойн через curl. Эта строка также проходит тест jsonlint.com.

Array
(
    [19913] => 1
    [52] => 1
    [68] => 10
    [10023] => Array
        (
            [0] => Content-type: application/json
        )

    [47] => 1
    [10015] => {"method":"sendmany","params":["","{\"mteCLqiEK7v5d3YbDQtxj8oKcdhtHRtXcw\":\"0.24020698\",\"2N5aa9FBxGf5xmeLiDz1yJVNYdsfK9GUWWe\":\"0.02588679\",\"2Muf4WEzFqNviURTdvkGSswHyrgMzR8optK\":\"0.02601681\"}",1],"id":4}
)

РЕДАКТИРОВАТЬ: ВСЕГО НЕ ИЗМЕНЯТЬ

Array
(
    [result] => 
    [error] => Array
        (
            [code] => -1
            [message] => JSON value is not an object as expected
        )

    [id] => 4
)

Аааа и каблуи! Я получаю следующую ошибку от Bitcoind:

"Значение JSON не является ожидаемым массивом"

Если я превращаю строку JSON в объект, то ошибка переключается на

Msgstr "Значение JSON не является ожидаемым объектом".

Этот фрагмент кода взят из библиотечного метода __call в 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
));

Кроме разрезания моих запястий и предложения моей крови богам программирования, я сделал все, что мог придумать. Кто-нибудь может заметить, что я здесь делаю неправильно?

Для всех, кто интересуется, эта команда работает на./bitcoin-cli

./bitcoin-cli sendmany "" "{\"mteCLqiEK7v5d3YbDQtxj8oKcdhtHRtXcw\":0.21445033, \"2N5aa9FBxGf5xmeLiDz1yJVNYdsfK9GUWWe\":0.02588679, \"2Muf4WEzFqNviURTdvkGSswHyrgMzR8optK\":0.02601681}" 1

Ответ Bitcoind - это номер txid

f4c443881a40054efbd5c3064268a91253f4cb2f7ba8caca96878d0dec46d774

Извините за множественные правки, не понял, что вводит клавиша Enter.

1 ответ

Я нашел проблему.

Я собираюсь разместить его здесь как ответ на случай, если у кого-то еще возникнет эта проблема.

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
)

В тот момент, когда в коде создан вышеуказанный массив, больше ничего не нужно делать. Проблема заключалась в том, что я преобразовывал этот массив в объект json для отправки в easybitcoin.php.

Easybitcoin.php ожидает, что это массив. Так что кормление этого массива само по себе сработало. Хотя в этом можно винить кого угодно, кроме меня, документация там довольно схематична. Итак, раз и навсегда, я собираюсь оставить это здесь и, надеюсь, это сэкономит кому-то время в будущем.

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

Где $ send - это простой массив, как показано выше. Никакого другого форматирования не требуется. Никаких двойных кавычек, ничего, просто передайте массив. Да, глупо, я знаю. Но мы здесь. Спасибо всем, кто посмотрел.

Другие вопросы по тегам