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.

0

Решение

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

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

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 — это простой массив, как показано выше. Никакого другого форматирования не требуется. Никаких двойных кавычек, ничего, просто передайте массив. Да, глупо, я знаю. Но мы здесь. Спасибо всем, кто посмотрел.

0

Другие решения

Других решений пока нет …