denpamusic / php-bitcoinrpc

Fully unit-tested Bitcoin JSON-RPC client based on GuzzleHttp.
MIT License
282 stars 100 forks source link

sendmany fails when passing valid json string #57

Open beertastic opened 3 years ago

beertastic commented 3 years ago

When I prep a valid json string and pass it to sendmany, I get told it's not a valid json object: https://developer.bitcoin.org/reference/rpc/sendmany.html

Denpa\Bitcoin\Exceptions\BadRemoteCallException JSON value is not an object as expected

Here are some testnet addresses and amounts:

$payments = '{"tb1q87nfvuezn53pv5c6fwzz5tm9mp3dga9dajzel2":0.00014664,"tb1q87nfvuezn53pv5c6fwzz5tm9mp3dga9dajzel2":0.00048881,"tb1qmcnn8mxhdxa742nzdpcz0kzrdqtg7m0xvkes8t":0.0002444,"tb1qgc5vlfnt7fhnx5ly9yjt8zte8jppre0fa68xjl":0.00019776}';

Addresses to deduct fees from:

$addresses = '["tb1q87nfvuezn53pv5c6fwzz5tm9mp3dga9dajzel2","tb1q87nfvuezn53pv5c6fwzz5tm9mp3dga9dajzel2","tb1qmcnn8mxhdxa742nzdpcz0kzrdqtg7m0xvkes8t","tb1qgc5vlfnt7fhnx5ly9yjt8zte8jppre0fa68xjl"]';

I'm calling:

    $send = $this->jsonrpc->sendmany(
        "",
        $payments,
        1,
        "My Comment",
        $addresses
    )->get();

And getting the error described above.

I'm expecting a TXID returned from the BTC node

Logs If applicable, attach log files. Feel free to omit any sensitive information.

Environment Describe your runtime environment:

I've tried creating an array and json_encode() etc.. all fails. Seems I need to explicitly send an object, but JSON is just a string.

denpamusic commented 3 years ago

Thank you for your feedback!

This client accepts only standard php arrays as parameters ($payments and $addresses in this case) and doesn't support json strings at all. Please use php arrays directly (do NOT convert them to string via json_encode) as shown in example below and everything should work. Hope that helps.

// payments must be passed as an array instead of json string
$payments = array(
    "tb1q87nfvuezn53pv5c6fwzz5tm9mp3dga9dajzel2" => "0.00014664",
    "tb1q87nfvuezn53pv5c6fwzz5tm9mp3dga9dajzel2" => "0.00048881",
    "tb1qmcnn8mxhdxa742nzdpcz0kzrdqtg7m0xvkes8t" => "0.0002444",
    "tb1qgc5vlfnt7fhnx5ly9yjt8zte8jppre0fa68xjl" => "0.00019776"
);

// same with addresses
$addresses = array(
    "tb1q87nfvuezn53pv5c6fwzz5tm9mp3dga9dajzel2",
    "tb1q87nfvuezn53pv5c6fwzz5tm9mp3dga9dajzel2",
    "tb1qmcnn8mxhdxa742nzdpcz0kzrdqtg7m0xvkes8t",
    "tb1qgc5vlfnt7fhnx5ly9yjt8zte8jppre0fa68xjl"
);
beertastic commented 3 years ago

Ah! I was so focused on the RPC docs that I forgot you've done much of the heavy lifting for us!

I assume this array: ^ array:2 [▼ 0 => "2N1xuawT4ndgDGR6g3Z3x8LR9oSvqjnN3jf" 1 => "2N2HJYuPaJEmRvzvkRcQEUCyDRCy3LTFkWt" ]

For addresses to take fees from is OK? The keys are 'always' there, or do I need to explicitly state an array with 'no' keys?

beertastic commented 3 years ago

Quick Q.. I'm noticing that the sendmany option isn't quite correct. I really think this is a Bitcoin issue and not your great code.. But :

I'm telling my node to send 990000 sats to two addresses each Here's my txid ea413397269e53a734c981a912fb703904df843aea296de6f91138b02f36e3da

You'll see that I'm actually sending -0.00989901 + fee: -0.00000197 AND -0.00989902 + fee: -0.00000197

Making -0.00990099 AND -0.00990098

So I'm logging on my system, that I've sent 990000 sats, and telling the sendmany to send that and take the fees from those payments...

BUT, I'm still sending MORE than the 990000 sats I've told the function to.

You come across this before? Before I go bleat to the BTC community.. your code is my first place to check...

Cheers!

tinodj commented 3 years ago

You'll see that I'm actually sending -0.00989901 + fee: -0.00000197

No, you did not.

https://www.blockchain.com/btc-testnet/tx/ea413397269e53a734c981a912fb703904df843aea296de6f91138b02f36e3da

You sent -0.989868 + fee: -0.00000132 = -0.990000