无法通过 JSON-RPC 将 GETBLOCKHASH 发布到比特币核心
Posted
技术标签:
【中文标题】无法通过 JSON-RPC 将 GETBLOCKHASH 发布到比特币核心【英文标题】:Unable to post GETBLOCKHASH to Bitcoin Core via JSON-RPC 【发布时间】:2020-07-25 13:02:35 【问题描述】:以下代码在大多数情况下都可以正常工作:
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;
然后我可以使用methodName
(例如getnewaddress
)从服务器取回数据:
static void Main(string[] args)
Console.WriteLine(RequestServer("getnewaddress", new List<string>()"","legacy"));
这将返回如下内容:
"result": "1EWJkGrirdhXpduoNdccxaCx7syqWHuDcK",
"error": null,
"id": "1"
上述方法名在使用终端时也可以正常工作:
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$
我可以以同样的方式使用一些方法名,它们工作正常。然而,当我使用getblockhash
:
static void Main(string[] args)
Console.WriteLine(RequestServer("getblockhash", new List<string>()"0"));
它给了我以下错误:
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$
调试时,错误发生在这一行:
WebResponse webResponse = webRequest.GetResponse();
如果我尝试在终端中使用该 methodName 手动检查输出,如下所示,它可以正常工作:
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$
除了 methodName 和发送的参数之外,请求示例结构在我看来是相同的:
https://bitcoincore.org/en/doc/0.20.0/rpc/wallet/getnewaddress/ https://bitcoincore.org/en/doc/0.20.0/rpc/blockchain/getblockhash/
有人知道为什么会这样吗?
【问题讨论】:
您是否检查了响应正文以查看是否有任何错误详细信息? 不确定如何检查响应正文。 ***.com/questions/11828843/… body 可能有某种错误原因。 @Charleh,这帮助我解决了这个问题。感谢您的帮助。 酷,如果您愿意,可以将您的解决方案作为答案发布,将来可能会对某人有所帮助 【参考方案1】:我认为问题是您在调用getblockhash
时为高度索引传递了错误的参数类型。您链接到的文档说它应该是一个数字(整数)参数,但您传递的是一个字符串。相比之下,getnewaddress
方法使用字符串参数,因此您现有的代码适用于此。
如果您捕获由 RequestServer
方法生成的 JSON,它看起来像这样:
"jsonrpc":"1.0","id":"1","method":"getblockhash","params":["0"]
但getblockhash
文档中的示例如下所示:
"jsonrpc":"1.0","id":"curltest","method":"getblockhash","params":[1000]
请注意,params
数组中的值未在示例中引用,而在您的示例中被引用。
要修复,请尝试以下操作:
从此更改现有RequestServer
方法的方法签名:
public static string RequestServer(string methodName, List<string> parameters)
到这里:
public static string RequestServer(string methodName, List<JToken> parameters)
使用旧签名创建RequestServer
方法的新重载,该签名调用您刚刚更改的现有签名。这将允许您已经工作的其他方法调用(例如getnewaddress
)继续工作而无需更改。
public static string RequestServer(string methodName, List<string> parameters)
return RequestServer(methodName, parameters.Select(p => new JValue(p)).ToList<JToken>());
从这里更改调用getblockhash
的代码:
Console.WriteLine(RequestServer("getblockhash", new List<string>() "0" ));
到这里:
Console.WriteLine(RequestServer("getblockhash", new List<JToken>() new JValue(0) ));
请注意,我在 2018 年为您回答了 similar question,其中我推荐了上面显示的相同步骤 1 和 2,因此您可能已经完成了该部分。如果是这样,您只需执行第 3 步即可。
【讨论】:
以上是关于无法通过 JSON-RPC 将 GETBLOCKHASH 发布到比特币核心的主要内容,如果未能解决你的问题,请参考以下文章