Intro to Ravencoin Development

This… is going to be a long one.

All code examples are available on Github,

I noticed when looking around ravencoin subreddits and googling, there is very little information on how to actually develop software against a ravencoin node. Ravencoin is a fork of bitcoin so there should be plenty of information on this right? Well, even that led me down some rabbit holes that didn’t even get me the basic connectivity to a node.

So I decided I’d attempt to provide a newbie-type guide to get basic connectivity configured to a Raven Core Wallet/Node, do some test calls using Postman, and then make a project to call it in code.


Setting up your Ravencoin Wallet as a full server node:

Go and get yourself the official Ravencoin wallet from https://www.ravencoin.org/wallet and install it/set up your wallet.

It’s going to download the ravencoin blockchain, which is a long process – We’re going to add things to the config that will require it to do that a 2nd time, so if this is your first time setting it up you can save yourself some time here. If you already had a synced blockchain – sorry, this is going to take a day.

First thing we’re going to do is click the Wallet menu, and go to Options. You’ll be presented with this screen:

Click Open Configuration File. It will give you a warning, Click OK.

You should now have a blank text file open. You need to put the following lines in. I added some comments about what these do, since there wasn’t much documentation out there about them.

#Accept cli/json RPC
server=1

#Maintains the full transaction index on your node. Needed if you call getrawtransaction. Default is 0.
txindex=1

#Maintains the full Address index on your node. Needed if you call getaddress* calls. Default is 0.
addressindex=1

#Maintains the full Asset index on your node. Needed if you call getassetdata. Default is 0.
assetindex=1

#Maintains the full Timestamp index on your node. Default is 0.
timestampindex=1

#Maintains the full Spent index on your node. Default is 0.
spentindex=1

#Username and password - You can make this whatever you want.
rpcuser=cryptobullsh
rpcpassword=test12311

#What IP address is allowed to make calls to the RPC server. If youre running the wallet on the same machine youre
#developing on, this is fine. If not, you need to put the IP address of the machine CALLING the node here.
rpcallowip=127.0.0.1

Save the file and close out your text editor after putting this info in. Restart Raven Core. It will tell you it needs to reindex everything.

The reason it needs to reindex everything, is now you are storing every transaction, asset etc on the blockchain on your computer, not just your own transactions. This will take up significantly more space on your HD. At the current time of writing, the size on disk for me is 42GB. Plan accordingly.

If everything went well, you won’t really see any difference to the ravencore wallet. Behind the scenes however, we’ve now downloaded the entire blockchain, opened port 8766 for RPC transactions and converted this wallet into a ravencore server. Whooo!


Testing connectivity over RPC/HTTP

Cool, we got a node acting as a server now. How do we make sure we can talk to it?

First, download Postman – https://www.postman.com/downloads/. I like postman for things like this. You could do this with Curl or Invoke-WebRequest powershell, but visually, postman is good.

Set your request type to POST, then enter the address you want to connect to. This will be your username and password you put in your raven.conf, along with your host (localhost in my case) and port (8766).

So your host should look like this if you used my example in your raven.conf:

http://cryptobullsh:test12311@127.0.0.1:8766

Click the Body option under the address, set it to “raw” and choose “JSON” as the content type. In the body, use this as an example:

{"id": 0, "method": "getblockchaininfo", "params": [], "jsonrpc": "2.0"}

Click “Send” If all goes well, you’ll see the output like the one below, and you’ve now successfully connected to your Ravencoin server!


Setting up your Development Environment and Project

The example I’m going to write is in C#. I like C#, but it’s not for everyone. However, yo could probably take my code example and do the same thing in Python, Java, etc. It’s not super complicated code.

First, if you don’t have Visual Studio 2019 installed, go on over to https://visualstudio.microsoft.com/ and click Download-> Visual Studio 2019 Community. It’s free.

Once installed, Create a new WebAPI project. Choose ASP.Net Core WebApp (Model-View-Controller):

Now, Name it something and choose a location for the code. I used RavencoinApiExample, you can too if you like.

Choose .Net Core 3.1, and none for authentication. You can configure for HTTPS if you like, it will ask you to install a self-signed certificate for this to work.

OK, you should have a new project with some boilerplate code. First thing we’re going to want to do is install Newtonsoft.Json package in our project.

In the solution Explorer, right click the Project and choose “Manage NuGet Packages”

Click Browse and search for Newtonsoft.Json. Install that.

OK, Let’s start writing some code!!

Disclaimer – I’m not an awesome developer. I know enough to make me dangerous. This code is probably not the best optimized code, and obviously I should keep hosts/usernames/passwords etc in protected config files. This is the barebones to get everyone with communicating with ravencoin. Use at your own risk.

First thing we’re going to do is set up a class, which will serve us as a definition of the object we’re going to be passing around for each request.

Right click your RavencoinApiExample Project, and go to Add->Class. (Or Shift-Alt-C). Call it RavencoinRequest.cs

Inside this file, we’re going to define some properties. Additionally, since the ravencoin server uses property names that are considered protected (such as “params”), we’re going to use the Newtonsoft Json library to annotate we want a different name for these properties when we serialize the json.

using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace RavencoinApiExample
{
    public class RavencoinRequest
    {
        [JsonProperty(PropertyName = "id")]
        public string reqid { get; set; }

        [JsonProperty(PropertyName = "method")]
        public string reqmethod { get; set; }

        [JsonProperty(PropertyName = "params")]
        public JObject reqparams{get;set;}

        [JsonProperty(PropertyName = "jsonrpc")]
        public string reqjsonrpc { get; set; }

    }
}

Notice how the name of the property in c# is “reqid” for example, but we’re telling Newtonsoft.Json to consider it “id”.

One important thing of note, is the “reqparameters” type is a JObject. You might ask – why not use a dictionary etc? I did at first. Then I realized serializing the json directly is easier. Also there might be a node command that only takes one value instead of a key/value pair. If you’re using a dictionary, that makes it pretty annoying to work with.


Now, we’re going create a class that will actually interact with the server. Right click your RavencoinApiExample Project, and go to Add->Class. (Or Shift-Alt-C). Call it Ravencore.cs

We’re going to define a method called “Connect” here, that will take the previously created RavencoinRequest Object and use the data to execute something on the ravencoin node. Similar to what we did in postman, this is doing something very similar – it’s using a HttpClient to set up the connection to the node, set the right headers, set up authentication and send the body of the request.

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;

namespace RavencoinApiExample
{
    public class Ravencore
    {
        static string hostName = "127.0.0.1";
        static string port = "8766";
        static string userName = "cryptobullsh";
        static string password = "test12311";

        public static string Connect(RavencoinRequest rreq)
        {
            HttpClient client = new HttpClient();
            Uri baseUri = new Uri($"http://{hostName}:{port}");
            client.BaseAddress = baseUri;
            client.DefaultRequestHeaders.Clear();
            client.DefaultRequestHeaders.ConnectionClose = true;
            client.DefaultRequestHeaders.Add("Accept", "application/json");

            //Set up authentication
            var authenticationString = $"{userName}:{password}";
            var base64EncodedAuthenticationString = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(authenticationString));

            //Set up the body of the message.
            //This adds the authorization header and encoding the RavencoinRequest object into json.
            var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/");
            requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Basic", base64EncodedAuthenticationString);

            //Set the content of the body
            requestMessage.Content = new StringContent(JsonConvert.SerializeObject(rreq), Encoding.UTF8, "application/json");

            //make the request
            var task = client.SendAsync(requestMessage);
            var response = task.Result;
            response.EnsureSuccessStatusCode();
            string responseBody = response.Content.ReadAsStringAsync().Result;

            return responseBody;
        }
    }
}

So now we have an object with defined properties that we pass to this method that will connect to the node and return a string of data back.


Now, we need to define Controllers for our WebAPI to listen to requests to then pass to this method.

Let’s do that now. Right click your “Controllers” Directory, and go to Add->Class. (Or Shift-Alt-C). Call it GetBlockchainInfo.cs.

Pay close attention to the “using” block, we’re specifically using Microsoft.AspNetCore.Mvc libraries here. Also note that we’re defining this is an ApiController and we want to route to [controller]. What this means is, whatever you name your Controller file, whatever comes before the word “Controller” is going to be your route (example: this would be http://localhost/GetBlockchainInfo).

On this controller, we’re going to do exactly what we did in Postman. We’re going to create a new RavencoinRequest Object, give it some data, and then send that Object over to Ravencore.Connect and return the response to the browser/consumer.

using Microsoft.AspNetCore.Mvc;

namespace RavencoinApiExample.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class GetBlockchainInfoController
    {
        public string Get()
        {
            //Set up the Ravcencoin Object
            RavencoinRequest request = new RavencoinRequest()
            {
                reqid = "0",
                reqmethod = "getblockchaininfo",
                reqjsonrpc = "2.0"
            };

            //Send the Ravencoin Request Object to the Method that will call the node
            string response = Ravencore.Connect(request);

            return response;
        }
    }
}

This is the barebones of what we need to do to make this work. Lets test it out, shall we? Click the “Play” button and a browser will come up.

It may go to the default example url. We want to go to https://<hostname:port>/GetBlockchainInfo

If you got the blockchaininfo result, you were successful!! Good job.


You may have noticed, we didn’t put anything in the params. That’s because we don’t need to for getblockchaininfo, its a command that doesnt require any parameters.

So, lets make a controller that does require some parameters.

Let’s do that now. Right click your “Controllers” Directory, and go to Add->Class. (Or Shift-Alt-C). Call it GetAssetDataController.cs. We’re going to look up some assets.

using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;

namespace RavencoinApiExample.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class GetAssetDataController
    {
        public string Get(string asset)
        {
            //Set up any parameters we may need
            JObject parameters = new JObject();
            parameters.Add("asset_name", asset);

            //Set up the Ravencoin Object
            RavencoinRequest request = new RavencoinRequest()
            {
                reqid = "0",
                reqmethod = "getassetdata",
                reqparams = parameters,
                reqjsonrpc = "2.0"
            };

            //Send the Ravencoin Request Object to the Method that will call the node
            string response = Ravencore.Connect(request);

            return response;
        }
    }
}

You can see here we’re setting up a JObject with a parameter we’re getting from the querystring, adding those parameters to our Ravencoin object, and passing it off to Ravencore.Connect.

Start your application again, and when the browser comes up, lets look at a random asset. This time we want to go to https://<hostname:port>/GetAsetData?asset_name=TRASH

You should see this response. If you did, You now know how to pass parameters into your request! Good job.

OK, how about something a bit more challenging? I was figuring this one out on my own, and it drove me up the wall a bit. I started writing code to do “gettransaction”, and it worked fine on one of my own transactions – but failed when looking up someone else’s transaction. WHY? Well, according to the documentation “Get detailed information about in-wallet transaction <txid>” Well shit, that’s not very useful.

Well, we need to do two calls to get that information – one to “getrawtransaction” with the transaction ID as a parameter, which returns the hex string of the transaction, which then we’ll use as a parameter to call decoderawtransaction. FUN!

So, lets do this. Right click your “Controllers” Directory, and go to Add->Class. (Or Shift-Alt-C). Call it GetTransactionController.cs. and throw this code in there:

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace RavencoinApiExample.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class GetTransactionController : ControllerBase
    {
        [HttpGet]
        public string Get(string txid)
        {
            //Set up parameters to get the hex string of the transaction
            JObject rawtxparameters = new JObject(
                new JProperty("txid", txid)
            );
            //Set up the Ravcencoin Object
            RavencoinRequest rawtxrequest = new RavencoinRequest()
            {
                reqid = "0",
                reqmethod = "getrawtransaction",
                reqparams = rawtxparameters,
                reqjsonrpc = "2.0"
            };

            //Get the hex string of the transaction back from getrawtransaction, and then parse it to get just the raw hex string from result
            JObject rawtxresponse = JObject.Parse((Ravencore.Connect(rawtxrequest)));
            JToken hexstring = rawtxresponse["result"];

            //Add the hex string to the next call to decode the raw transaction
            JObject decodetxparameters = new JObject(
                new JProperty("hexstring", hexstring)
            );

            //Set up the Ravcencoin Object
            RavencoinRequest request = new RavencoinRequest()
            {
                reqid = "0",
                reqmethod = "decoderawtransaction",
                reqparams = decodetxparameters,
                reqjsonrpc = "2.0"
            };

            //Get the Raw Transaction details for the transaction ID from the server.
            string response = Ravencore.Connect(request);

            return response;
        }
    }
}

Can you see what I’m doing here? The response from the first call is going directly into a JObject, which then gets parsed out and used to the subsequent call to get the result we want.

Let’s test this. I’m going to pull a random transaction from the blockchain explorer of someone on the “rich list” for example (a16923c2dd1ed12f2c022437fe54a4d5222ed0f8dacecc9223c69efd27d32c61).

Click the play button again to start the application. This time, we want to go to https://<hostname:port>/GetTransaction?txid= a16923c2dd1ed12f2c022437fe54a4d5222ed0f8dacecc9223c69efd27d32c61

Ah, it feels so good when things just work…. (but for real, I refactored this code like 40 times, lol).

Did I help? If you’re feeling generous, buy me a coffee by sending RVN to RHEH92NguBjaxXQPsM1bedkqqTXKr9EZcM

Follow me on social media:

0 thoughts on “Intro to Ravencoin Development

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>