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