The following code works fine for the most part:
public static string RequestServer(string methodName, List<string> parameters)
{
// Use the values you specified in the bitcoin server command line
string ServerIp = "http://localhost.:8332";
string UserName = "username";
string Password = "password";
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(ServerIp);
webRequest.Credentials = new NetworkCredential(UserName, Password);
webRequest.ContentType = "application/json-rpc";
webRequest.Method = "POST";
string responseValue = string.Empty;
// Configure request type
JObject joe = new JObject();
joe.Add(new JProperty("jsonrpc", "1.0"));
joe.Add(new JProperty("id", "1"));
joe.Add(new JProperty("method", methodName));
JArray props = new JArray();
foreach (var parameter in parameters)
{
props.Add(parameter);
}
joe.Add(new JProperty("params", props));
// serialize JSON for request
string s = JsonConvert.SerializeObject(joe);
byte[] byteArray = Encoding.UTF8.GetBytes(s);
webRequest.ContentLength = byteArray.Length;
Stream dataStream = webRequest.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
// deserialze the response
StreamReader sReader = null;
WebResponse webResponse = webRequest.GetResponse();
sReader = new StreamReader(webResponse.GetResponseStream(), true);
responseValue = sReader.ReadToEnd();
var data = JsonConvert.DeserializeObject(responseValue).ToString();
return data;
}
I can then use a methodName
such as getnewaddress
to get data back from the server:
static void Main(string[] args)
{
Console.WriteLine(RequestServer("getnewaddress", new List<string>(){"","legacy"}));
}
That will return something like this:
{
"result": "1EWJkGrirdhXpduoNdccxaCx7syqWHuDcK",
"error": null,
"id": "1"
}
The above methodName works fine when using the terminal too:
bitcoin@desktop:~/Downloads/bitcoin-0.20.0-x86_64-linux-gnu/bitcoin-0/bin$ ./bitcoin-cli getnewaddress "" "legacy"
1EWJkGrirdhXpduoNdccxaCx7syqWHuDcK
bitcoin@desktop:~/Downloads/bitcoin-0.20.0-x86_64-linux-gnu/bitcoin-0.20.0/bin$
I can use a few methodNames the same way and they work fine. However, when I use getblockhash
:
static void Main(string[] args)
{
Console.WriteLine(RequestServer("getblockhash", new List<string>(){"0"}));
}
It gives me the following error:
bitcoin@desktop:~/Code/blockchain-app$ dotnet run
Unhandled exception. System.Net.WebException: The remote server returned an error: (500) Internal Server Error.
at System.Net.HttpWebRequest.GetResponse()
at blockchain-app.Program.RequestServer(String methodName, List`1 parameters) in /home/bitcoin/Code/blockchain-app/Program.cs:line 72
at blockchain-app.Program.Main(String[] args) in /home/bitcoin/Code/blockchain-app/Program.cs:line 29
bitcoin@desktop:~/Code/blockchain-app$
When debugging, the error happens on this line:
WebResponse webResponse = webRequest.GetResponse();
If I try to check the output manually using that methodName in the terminal such as the following, it works fine:
bitcoin@desktop:~/Downloads/bitcoin-0.20.0-x86_64-linux-gnu/bitcoin-0.20.0/bin$ ./bitcoin-cli getblockhash 0
000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
bitcoin@desktop:~/Downloads/bitcoin-0.20.0-x86_64-linux-gnu/bitcoin-0.20.0/bin$
The request example structures look the same to me other than the methodName and the parameters sent:
https://bitcoincore.org/en/doc/0.20.0/rpc/wallet/getnewaddress/ https://bitcoincore.org/en/doc/0.20.0/rpc/blockchain/getblockhash/
Anyone know why this is happening?
I think the problem is that you are passing the wrong parameter type for the height index when calling getblockhash
. The documentation you linked to says that it should be a numeric (integer) parameter, but you are passing a string. In contrast, the getnewaddress
method uses string parameters, so your existing code works for that.
If you capture the JSON that is being generated by your RequestServer
method, it looks like this:
{"jsonrpc":"1.0","id":"1","method":"getblockhash","params":["0"]}
But the sample in the documentation for getblockhash
looks like this:
{"jsonrpc":"1.0","id":"curltest","method":"getblockhash","params":[1000]}
Notice that the value in the params
array is not quoted in the sample, whereas it is quoted in yours.
To fix, try the following:
Change the method signature for your existing RequestServer
method from this:
public static string RequestServer(string methodName, List<string> parameters)
to this:
public static string RequestServer(string methodName, List<JToken> parameters)
Create a new overload of the RequestServer
method using the old signature which calls the existing one you just changed. This will allow your other method call(s) which already work (eg getnewaddress
) to keep working with no changes.
public static string RequestServer(string methodName, List<string> parameters) { return RequestServer(methodName, parameters.Select(p => new JValue(p)).ToList<JToken>()); }
Change the code which calls getblockhash
from this:
Console.WriteLine(RequestServer("getblockhash", new List<string>() { "0" }));
to this:
Console.WriteLine(RequestServer("getblockhash", new List<JToken>() { new JValue(0) }));
Note that I answered a similar question for you back in 2018 in which I recommended the same steps 1 and 2 shown above, so you may have already done that part. If so, all you need to do is step 3.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.