MCWrapper

A simple .NET Core wrapper aimed at supporting MultiChain Core blockchain networks

Download MCWrapper from GitHub or NuGet

Configure MCWrapper's RpcOptions, CliOptions and RuntimeParamOptions using environment variables. Alternately consumers may configure MCWrapper using the .NET Core Options pattern , or they may pass the necessary parameters explicitly to the MCWrapper extension methods.

The MCWrapper RPC, CLI, and Forge clients require certain values be available for use when interacting with a MultiChain Core blockchain node. We will discuss which values each client library requires and the different methods those value might be populated to one of the MCWrapper libraries.

Note: The MCWrapper Command Line Interface (CLI) and Forge clients interact directly with the MultiChain binary files so no RPC credentials are required. As indicated below, only the CliOptions are required for full CLI client functionality. Those properties are ChainName, ChainAdminAddress, ChainBinaryLocation, ChainDefaultLocation, and ChainDefaultColdNodeLocation. If no ChainBinaryLocation, ChainDefaultLocation, or ChainDefaultColdNodeLocation is offered during configuration then default values are used according to the operating system in use.

While, the CLI client library is a bit more secure than the RPC client library, since no RPC credentials are passed, it is slower. In testing, the quickest interaction we have observed is ~1 second per blockchain method call (due to loading the external MultiChain Core binary file during each transaction). Running a compiled instance of MCWrapper may be quicker, not much though. Obviously, there is a trade off, security for speed. The decision is yours.

RpcOptions class

Valid values required when using any IMultiChainRPC clients from MCWrapper.RPC

ChainName (string)

If a ChainName is not configured here it must be passed into RPC client methods explicitly.

ChainRpcPort (int?)

JSON-RPC Port number for the target node.

ChainUseSsl (bool?)

Only required if you want to use SSL-based HTTPS JSON-RPC connections.

ChainAdminAddress (string)

Required for performing administrator tasks (i.e. stream management, asset creation, setting permissions, etc...)

ChainHostname (string)

Generally is localhost. Can be 127.0.0.1, 0.0.0.0, or some other public IP address as well depending on the scenario.

ChainBurnAddress (string)

Node address used for burning assets.

ChainUsername (string)

'rpcusername' value located on the target node's multichain.conf file.

ChainPassword (string)

'rpcpassword' value located on the target node's multichain.conf file.

CliOptions class

Valid values required when using any IMultiChainCLI clients from MCWrapper.CLI

ChainName (string)

If a ChainName is not configured here it must be passed into CLI client methods explicitly.

ChainAdminAddress (string)

Required for performing administrator tasks (i.e. stream management, asset creation, setting permissions, etc...)

ChainBurnAddress (string)

Node address used for burning assets.

ChainBinaryLocation (string)

Location of MultiChain binary files.

ChainDefaultLocation (string)

Location of MultiChain hot nodes.

ChainDefaultColdNodeLocation (string)

Location of MultiChain cold nodes.

RuntimeParamOptions class

Values not required


BanTx (string)

Not required

LockBlock (string)

Not required

MaxShownData (string)

Not required

AutoSubscribe (string)

Not required

HandshakeLocal (string)

Not required

MiningTurnover (string)

Not required

MineEmptyRounds (string)

Not required

HideKnownOpDrops (string)

Not required

LockAdminMineRounds (string)

Not required

MiningRequiresPeers (string)

Not required

An example of using the parameterless extension method when adding MultiChainCoreServices to a .NET Core WebAPI Dependency Injection (DI) container via the Startup class.

When using the parameterless extension method environment variables representing RpcOptions and/or CliOptions properties must exist locally or in Visual Studio.

Environment variables representing RuntimeParamOptions properties are not required and may be treated as optional.

using MCWrapper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace MCWrapperWebAPI
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            
            // Add MCWrapper's MultiChain Core Services
            // When using the parameterless extension method the necessary environment
            // variables must be configured beforehand.
            //
            // Environment variables may exist in VisualStudio or the Operating System, 
            // one or the other is required.
            //
            // Environment variables representing RpcOptions and/or CliOptions properties
            // must exist.
            //
            // Environment variables representing RuntimeParamOptions properties are
            // not required and may be treated as optional.
            services.AddMultiChainCoreServices();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

An appsettings.json file should be populated with the necessary details before adding MultChainCoreServices to the Dependency Injection (DI) container.

{
    // - RpcOptions properties -
    // If RpcOptions properties are net set here in the appsettings.json
    // file they must be explicitly declared or present as environment variables when
    // adding MultiChainServices to the applications DI container.
    "ChainUseSsl": "",
    "ChainUsername": "",
    "ChainPassword": "",
    "ChainName": "",
    "ChainRpcPort": "",
    "ChainAdminAddress": "",
    "ChainHostname": "",
    "ChainBurnAddress": "",
    "ChainBinaryLocation": "",
    "ChainDefaultLocation": "",
    "ChainDefaultColdNodeLocation": "",

    // - CliOptions properties -
    // If CliOptions properties are net set here in the appsettings.json
    // file they must be explicitly declared or present as environment variables when
    // adding MultiChainServices to the applications DI container.
    "ChainName": "",
    "ChainAdminAddress": "",
    "ChainBurnAddress": "",
    "ChainBinaryLocation": "",
    "ChainDefaultLocation": "",
    "ChainDefaultColdNodeLocation": "",

    // - RuntimeParamOptions properties -
    // If RuntimeParamOptions properties are net set here in the appsettings.json
    // file they may be explicitly declared or present as environment variables when
    // adding MultiChainCoreServices to the applications DI container.
    "BanTx": "",
    "LockBlock": "",
    "MaxShownData": "",
    "AutoSubscribe": "",
    "HandshakeLocal": "",
    "MiningTurnover": "",
    "MineEmptyRounds": "",
    "HideKnownOpDrops": "",
    "LockAdminMineRounds": "",
    "MiningRequiresPeers": ""
}
An example of adding MultiChainCoreServices to a .NET Core WebAPI Dependency Injection (DI) container via the Startup class.
using MCWrapper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace MCWrapperWebAPI
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            
            // Add MCWrapper's MultiChain Core Services
            // Infers BlockchainProfileOptions and RuntimeParamOptions from IConfiguration
            services.AddMultiChainCoreServices(Configuration);
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

An example of explicitly adding MultiChainCoreServices to a .NET Core WebAPI Dependency Injection (DI) container via the Startup class.

using MCWrapper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace MCWrapperWebAPI
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            
            // Add MCWrapper's MultiChain Core Services
            // Explicitly configure the RpcOptions and CliOptions
            // before adding them to the DI container.
            // Obviously, the values need to be populated with a consumer's local values.
            services.AddMultiChainCoreServices(rpcOptions => 
            {
                rpcOptions.ChainName = "";
                rpcOptions.ChainHostname = "";
                rpcOptions.ChainRpcPort = null;
                rpcOptions.ChainUseSsl = null;
                rpcOptions.ChainUsername = "";
                rpcOptions.ChainPassword = "";
                rpcOptions.ChainAdminAddress = "";
                rpcOptions.ChainBurnAddress = "";
                rpcOptions.ChainBinaryLocation = "";
                rpcOptions.ChainDefaultLocation = "";
                rpcOptions.ChainDefaultColdNodeLocation = "";
            },
            cliOptions => 
            {
                rpcOptions.ChainName = "";
                rpcOptions.ChainAdminAddress = "";
                rpcOptions.ChainBurnAddress = "";
                rpcOptions.ChainBinaryLocation = "";
                rpcOptions.ChainDefaultLocation = "";
                rpcOptions.ChainDefaultColdNodeLocation = "";
            });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}