Aufrufen des listunspent-Befehls über json-rpc auf einem vollständigen Knoten

Ich versuche, den folgenden Beispielcode für die C#-Programmierung zu verwenden, damit ich eine Verbindung zu meinem eigenen Bitcoin-Vollknoten herstellen kann:

https://en.bitcoin.it/wiki/API_reference_(JSON-RPC)#.NET_.28C.23.29

Was zu so etwas geführt hat:

public static string RequestServer(string methodName, List<string> parameters)
{
    string ServerIp = "http://localhost:18332";
    string UserName = "user name goes here";
    string Password = "password goes here";

    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(ServerIp);
    webRequest.Credentials = new NetworkCredential(UserName, Password);

    webRequest.ContentType = "application/json-rpc";
    webRequest.Method = "POST";

    string respVal = string.Empty;

    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 the 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();

    StreamReader streamReader = null;
    try
    {
        WebResponse webResponse = webRequest.GetResponse();

        streamReader = new StreamReader(webResponse.GetResponseStream(), true);

        respVal = streamReader.ReadToEnd();
        var data = JsonConvert.DeserializeObject(respVal).ToString();
        return data;
    }
    catch (Exception exp)
    {
        throw (exp);
    }
    finally
    {
        if (streamReader != null)
        {
            streamReader.Close();
        }
    }

    return string.Empty;
}

Mit dem obigen Code kann ich den Bitcoin-Befehl ausführen sendtoaddress. In der Bitcoin-Konsole würde beispielsweise Folgendes funktionieren:

senttoaddress 2N8hwP1WmJrFF5QWABn38y63uYLhnJYJYTF 0.01

Mit der RequestServerFunktion im obigen C#-Code kann ich dasselbe tun:

double AmountToSend = Convert.ToDouble(txtAmountToSend.Text);
string ReceivingAddress = txtSendToAddress.Text;
JObject data = JObject.Parse(RequestServer("sendtoaddress", new List<string>() { ReceivingAddress, Convert.ToString(AmountToSend) }));

Alles gut so weit.

Jetzt möchte ich dasselbe mit tunlistunspent

In der Bitcoin-Konsole funktionieren die folgenden Arbeitsbeispiele einwandfrei:

listunspent
listunspent 1000

Mit der obigen C#-Funktion funktioniert Folgendes, wenn ich ihr keinen Parameter gebe:

JObject data = JObject.Parse(RequestServer("listunspent", new List<string>() { }));

Aber wenn ich einen Parameter hinzufüge, funktioniert es nicht:

JObject data = JObject.Parse(RequestServer("listunspent", new List<string>() { Convert.ToString(1000) }));

Der Fehler, den es gibt, ist:

C:\Users\oshirowanen\Documents\Visual Studio 2017\Projects\ConsoleApp1\ConsoleApp1\bin\Debug>ConsoleApp1.exe

Unhandled Exception: System.Net.WebException: The remote server returned an error: (500) Internal Server Error.
   at System.Net.HttpWebRequest.GetResponse()
   at ConsoleApp1.Program.RequestServer(String methodName, List`1 parameters) in C:\Users\oshirowanen\Documents\Visual Studio 2017\Projects\ConsoleApp1\ConsoleApp1\Program.cs:line 63
   at ConsoleApp1.Program.Main(String[] args) in C:\Users\oshirowanen\Documents\Visual Studio 2017\Projects\ConsoleApp1\ConsoleApp1\Program.cs:line 18

C:\Users\oshirowanen\Documents\Visual Studio 2017\Projects\ConsoleApp1\ConsoleApp1\bin\Debug>

Weiß jemand warum das so ist?

Der Fehler, den Sie erhalten, sollte eine Meldung über den Fehler enthalten, nicht nur den Fehlercode. Es ist wahrscheinlich, dass Sie nur die Parameter falsch einstellen. Können Sie die Fehlermeldung finden und diese auch in Ihre Frage aufnehmen?
@AndrewChow Ich habe die vollständige Fehlermeldung hinzugefügt.
Ich meinte den Hauptteil der HTTP-Antwort mit dem Fehler 500, nicht den Stack-Trace. Allerdings glaube ich zu wissen was das Problem ist.

Antworten (2)

1000Das Problem ist, dass Sie den Parameter als Zeichenfolge und nicht als Zahl senden . Der JSON-Typ, wenn der RPC-Server ihn empfängt, ist eine Zeichenfolge, was falsch ist. Es konvertiert dies nicht implizit in eine Ganzzahl, sodass Sie den Typ explizit festlegen müssen. Stattdessen sollten Sie Folgendes tun:

JObject data = JObject.Parse(RequestServer("listunspent", new List<Integer>() { 1000 }));

vielleicht verkomplizieren Sie es zu sehr

Ruf einfach an:

requestserver("listunspent 1000")    

also sendet es "listunspent 1000"

JObject data = JObject.Parse(RequestServer("listunspent 1000", new List<string>() { }));
Das ergibt die folgende Fehlermeldung: Unbehandelte Ausnahme: System.Net.WebException: Der Remote-Server hat einen Fehler zurückgegeben: (404) Not Found. bei System.Net.HttpWebRequest.GetResponse() bei ConsoleApp1.Program.RequestServer(String methodName, List`1 parameters) in C:\Users\oshirowanen\Documents\Visual Studio 2017\Projects\ConsoleApp1\ConsoleApp1\Program.cs:line 63 unter ConsoleApp1.Program.Main(String[] args) in C:\Users\oshirowanen\Documents\Visual Studio 2017\Projects\ConsoleApp1\ConsoleApp1\Program.cs:line 18