Author

Topic: Need some help with sendmany and php... (Read 2891 times)

hero member
Activity: 576
Merit: 514
June 30, 2011, 01:51:18 PM
#16
Excellent, got it working finally!  Thanks a bunch, small donation sent your way.  Smiley
Thanks!
legendary
Activity: 1400
Merit: 1005
Excellent, got it working finally!  Thanks a bunch, small donation sent your way.  Smiley
hero member
Activity: 576
Merit: 514
Ok, this was annoying me too much, so I set up a test environment.

I'm using bitcoin 0.3.20.2 in server mode and curl 7.21.7 on Windows.

On the client host, I issue this command:
curl -u myuser:mypass --data-binary @json.txt -H "content-type: text/plain;" http://internal.ip:8332/

And json.txt contains
{"jsonrpc":"2.0","id":"curltest","method":"getinfo","params":[]}

This request is successful, but it fails when the json.txt contains single quotes instead of double quotes. I didn't see a request going out in the tcpdump when it fails, so I assume the error is generated by curl. I would consider this a bug in the way curl handles json data parsing.

Problem solved, test environment goes down again.
legendary
Activity: 1400
Merit: 1005
Still no go.  I tried:

Code:
curl -u myusername:mypassword --data-binary @json.txt -H 'content-type: application/json-rpc;' "http://192.168.1.10:8332/"

I got the same result as before - the parse error.  I also tried changing 1.0 to 2.0 in the json.txt file, still no go.  :\

Thanks for attempting to help, at least.  Tongue  Let me know if you have anything else I can try.  As you can probably tell by now, I am completely brand new to cURL, so I don't know syntax, etc yet.
hero member
Activity: 576
Merit: 514
Some more things I came across:

1. You mixed --data-binary and -d; however, -d is -data-ascii. Give --data-binary @json.txt a try to.

2. According to the JSON specs, the content type should be application/json-rpc for POST requests, which is what cURL sends. I don't know if bitcoind cares about that though.

3. The error code, -32700, is a JSON 2.0 code, but the call specifies JSON 1.0


I hope that helps, since I'm running out of ideas.
legendary
Activity: 1400
Merit: 1005
Haha, didn't even catch that.  Still the same result though, with changing json.txt to have getinfo instead of getwork.

Code:
{"result":null,"error":{"code":-32700,"message":"Parse error"},"id":null}
hero member
Activity: 576
Merit: 514
Just noticed that you're using "getwork". The wiki example uses getinfo.

Did you try that with the fixed quote issue?
legendary
Activity: 1400
Merit: 1005
June 30, 2011, 11:35:38 AM
#9
Bitsky, bitcoind does not accept rpc requests from any ip's except those specified in the config file.  I have specified my local IP in the config, since I am on the same network.  The bitcoind server has no 3rd party firewall installed and the windows firewall is turned off.
hero member
Activity: 576
Merit: 514
June 30, 2011, 11:29:54 AM
#8
That the error vanished when you switched single to double quotes underlines a potential quoting issue.

You could also try running the request on the bitcoind host to rule out network related problems. If it works fine on that host, you can start thinking about possible network issues, like a firewall. Or perhaps you need to configure a listen address in bitcoind because it might not accept external requests by default (which would made sense from a security point of view). I almost sounds like the json string itself is buggy.
legendary
Activity: 1400
Merit: 1005
June 30, 2011, 10:34:12 AM
#7
Thanks for the reply Bitsky.  I tried using a textfile, along with this text in the command line:
Code:
curl -u myusername:mypassword --data-binary -d json.txt -H 'content-type: text/plain;' "http://192.168.1.10:8332/"

My json.txt had:
Code:
{"jsonrpc": "1.0", "id": "curltest", "method": "getwork", "params": [] }

And this is the error it came back with:
Code:
curl: (6) Could not resolve host: text; No data record of requested type
{"result":null,"error":{"code":-32700,"message":"Parse error"},"id":null}

EDIT:  I tried putting the content-type argument in double quotes, and the curl: (6) error went away, but the result with the parse error still remained.  Does that mean that my connection is fine, but the json arguments aren't being handled properly by bitcoind?  If so, what is another string I could try?
hero member
Activity: 576
Merit: 514
June 30, 2011, 04:01:58 AM
#6
It looks like your Windows has problems dealing with single/double quotes and tries to resolve your json values.

Perhaps it's better to store the json string in a plaintext file and let curl read it by using something like -d @jsonfile.txt
legendary
Activity: 1400
Merit: 1005
June 30, 2011, 02:36:41 AM
#5
I suppose I'll keep replying to my own topic...

Now I am attempting the cURL route, based on the example put forth here:  https://en.bitcoin.it/wiki/API_reference_%28JSON-RPC%29

Problem is, this example doesn't work - it just errors out.  Any idea why?  Ultimately, I'd like to use a batch script along with curl to try using the sendmany command with a predefined list of addresses and amounts set in a batch script.  But to start, I've at least got to get some sort of legitimate response from the bitcoind service.

Code:
C:\curl\bin>curl -u myusernamewashere:mypasswordwashere --data-binary '{"jsonrpc": "1
.0", "id":"curltest", "method": "getwork", "params": [] }' -H 'content-type: tex
t/plain;' "http://192.168.1.10:8332/"
curl: (6) Could not resolve host: 1.0,; No data record of requested type
curl: (6) Could not resolve host: id; No data record of requested type
curl: (6) Could not resolve host: method; No data record of requested type
curl: (6) Could not resolve host: getwork,; No data record of requested type
curl: (6) Could not resolve host: params; No data record of requested type
curl: (3) [globbing] illegal character in range specification at pos 2
curl: (3) [globbing] unmatched close brace/bracket at pos 1
curl: (6) Could not resolve host: text; No data record of requested type
{"result":null,"error":{"code":-32700,"message":"Parse error"},"id":null}
legendary
Activity: 1400
Merit: 1005
June 30, 2011, 01:52:12 AM
#4
Well this attempt failed...

Code:
  public function sendmany($addressarr, $amountarr, $comment = NULL, $comment_to = NULL) {
      if (!$addressarr || empty($addressarr))
        throw new BitcoinClientException("sendmany requires a destination address");
      if (!$amountarr || empty($amountarr))
        throw new BitcoinClientException("sendmany requires an amount to send");
      //if (!is_numeric($amountarr) || $amountarr <= 0)
      //  throw new BitcoinClientException("sendmany requires the amount sent to be a number > 0");
      //$amountarr = floatval($amountarr);
      if (!$comment && !$comment_to)
        return $this->query("sendmany", $addressarr, $amountarr);
      if (!$comment_to)
        return $this->query("sendmany", $addressarr, $amountarr, $comment);
      return $this->query("sendmany", $addressarr, $amountarr, $comment, $comment_to);
  }
It literally crashes my http service if I try using this function by sending two arrays to it.  Note that I also commented out the isnumeric check, since an array isn't numeric.

Suggestions?
legendary
Activity: 1400
Merit: 1005
June 29, 2011, 02:26:12 PM
#3
Ok, new question:  How can I easily utilize the sendmany command?  There's no way to do it through any of the current GUI's (that I am aware of), so what's the next-best thing?  How do ANY of you utilize it?
legendary
Activity: 1400
Merit: 1005
June 29, 2011, 02:09:31 AM
#2
No answers.... sadpanda is sad.  Cry

I just have no idea where to start, and am afraid of wasting BTC by doing something wrong.

Surely the pools use sendmany?  Maybe a pool-owner or someone who wrote pool code could chime in?

EDIT:  More code below.

From what I can gather, the query() function is what I need to use to send the rpc call.  But I am just uncertain of the formatting of $message.  $message is a compilation of the arguments sent, but how do I format the array of addresses that need to be sent?  Do I just format it exactly like it is shown here?

bitcoind sendmany "SomeAccount" '{"myeTWjh876opYp6R5VRj8rzkLFPE4dP3Uw":10,"mikZVLuasDcY1Jmph3rqgT1NXfjB1srSEc":15,"mvTt8hav6e9ESjSrXJ1yaJhyULHv8ywcN7":50}'

Would the call to the function be query("sendmany", $account, '{"myeTWjh876opYp6R5VRj8rzkLFPE4dP3Uw":10,"mikZVLuasDcY1Jmph3rqgT1NXfjB1srSEc":15,"mvTt8hav6e9ESjSrXJ1yaJhyULHv8ywcN7":50}') ?

Code:
  public function query($message) {
    if (!$message || empty($message))
      throw new BitcoinClientException("Bitcoin client query requires a message");
    $msg = new jsonrpcmsg($message);
    if (func_num_args() > 1) {
      for ($i = 1; $i < func_num_args(); $i++) {
        $msg->addParam(self::query_arg_to_parameter(func_get_arg($i)));
      }
    }
    $response = $this->send($msg);
    if ($response->faultCode()) {
      throw new BitcoinClientException($response->faultString());
    }
    return php_xmlrpc_decode($response->value());
  }

Code:
  public function query_arg_to_parameter($argument) {
    $type = "";// "string" is encoded as this default type value in xmlrpc.inc
    if (is_numeric($argument)) {
      if (intval($argument) != floatval($argument)) {
        $argument = floatval($argument);
        $type = "double";
      } else {
        $argument = intval($argument);
        $type = "int";
      }
    }
    if (is_bool($argument))
      $type = "boolean";
    if (is_int($argument))
      $type = "int";
    if (is_float($argument))
      $type = "double";
    if (is_array($argument))
      $type = "array";
    return new jsonrpcval($argument, $type);
  }
legendary
Activity: 1400
Merit: 1005
June 28, 2011, 01:09:59 PM
#1
I am using bitcoin-php, and am looking for a way to modify the library to include the sendmany command.

Right now, this is the current code for "sendToAddress()".  I am guessing this is where I should start with regards to implementing an rpc call to sendmany.

Code:
00715   public function sendtoaddress($address, $amount, $comment = NULL, $comment_to = NULL) {
00716     if (!$address || empty($address))
00717       throw new BitcoinClientException("sendtoaddress requires a destination address");
00718     if (!$amount || empty($amount))
00719       throw new BitcoinClientException("sendtoaddress requires an amount to send");
00720     if (!is_numeric($amount) || $amount <= 0)
00721       throw new BitcoinClientException("sendtoaddress requires the amount sent to be a number > 0");
00722     $amount = floatval($amount);
00723     if (!$comment && !$comment_to)
00724       return $this->query("sendtoaddress", $address, $amount);
00725     if (!$comment_to)
00726       return $this->query("sendtoaddress", $address, $amount, $comment);
00727     return $this->query("sendtoaddress", $address, $amount, $comment, $comment_to);
00728   }

Thoughts on how to do this?
Jump to: