Introduction

Stratis empowers developers to build enterprise-grade blockchain solutions for current industries by utilizing their C# and .Net skill sets. Stratis Blockchain is open-source and provides templates for Visual Studio to develop the blockchain application using C# and .NET. In the previous article series, we have learned how to get started with smart contract in C# and write and deploy the smart contract in the Stratis Blockchain.

This article describes how to implement the Smart contract in ASP.Net core application using your C# and .NET skillset. We will be using the Smart Contract which we have already deployed in the previous article. Here we will use that contract address to interact from the ASP.Net Core application.

Source Code

Prerequisites

  • Visual Studio 2019 or later version
  • Smart Contract Address

Let’s create a .NET project.

Step 1

Open visual studio and create project.

Step 2

Select the ASP.Net Core MVC and click on Next.

Step 3

Give the project name and location of your project.

Step 4

Select Target Framework .NET 5.0.

Now, we have created ASP.Net Core application where we will call and implement the Smart Contract. We have already learned and deployed the contract in the previous part of the article series. In the previous article, we have deployed the contract which gives the address of the owner. We are going to call that contract through the .Net Application. In the previous article, we used the below API endpoint: /api/SmartContracts/local-call to call the contract from the postman. Hence, we will integrate this API endpoint in the .NET application.

So, let’s move for the development and follow below steps:

Step 1 – Create an entity Model to return the API response within it.

So, let’s create the Entities folder and under it add class APIRequestResponse.cs. Here we will return the Content and response success value of the API response.

Code of APIRequestResponse.cs

public class APIRequestResponse
    {
        public bool IsSuccess { get; set; }
        public dynamic Content { get; set; }
    }

API endpoint (/api/SmartContracts/local-call) is a POST method so we will add the API request service where we will create a method that will be common for all types of post methods.

Step 2 – Add ApiRequest Service Class

Right Click on the service folder and click new class and give the name of the class as CommonAPIRequestService. Then write the below code.

Code of CommonAPIRequestService.cs

public async Task<APIRequestResponse> GetRequestAsync(string apiendpoint, string path, string query = null)
        {           
            var restClient = new RestClient(BuildUri(apiendpoint, path, query));
            var restRequest = new RestRequest(Method.GET);
            IRestResponse restResponse = await restClient.ExecuteAsync(restRequest).ConfigureAwait(false);
            var isSuccess = restResponse.StatusCode.Equals(HttpStatusCode.OK);
            return new APIRequestResponse
            {
                IsSuccess = isSuccess,
                Content = JsonConvert.DeserializeObject(restResponse.Content)
            };
        }
public static Uri BuildUri(string endpoint, string path = null, string query = null) => new UriBuilder(endpoint)
        {
            Path = path,
            Query = query
        }.Uri;

BuildUri – This method builds the API based on the endpoint, path, and query.

GetRequestAsync-It’s a method for HTTP post request which we will use to call API endpoint. In this demo sample, we will use it for the contract call API endpoint.

There are two ways to call a contract: a local call and a contract call see Interacting with a contract in previous article. In this article, we will interact with a contract without broadcasting a transaction; we will use the local call.

As seen from the Swagger API endpoint, we need the following parameters to interact with the contract for a local call.

Hence, we will create a model for these parameters. Let’s add a model class under the Model folder with those parameters.

Right Click on Model folder and add class SmartContractLocalCallModel.cs.

Below is code of SmartContractLocalCallModel.cs.

public class SmartContractLocalCallModel
    {        
        public int Amount { get; set; }
        public int GasPrice { get; set; }
        public int GasLimit { get; set; }
        public string Sender { get; set; }
        public string ContractAddress { get; set; }
        public string MethodName { get; set; }
        public string[] Parameters { get; set; }
    }

Step 3 – Add Smart Contract service

Now, let’s add SmartContract Service under the Service folder.

This service is added to write the logic related to the Smart Contract interaction. Thus, here we will write a method to call SmartContract.

Below is code of SmartContractService.cs class.

  public class SmartContractService
    {
        private readonly CommonAPIRequestService commonAPIRequestService;
        private string defaultEndPoint="http://localhost:38223";
        public SmartContractService(CommonAPIRequestService commonAPIRequestService)
        {
            this.commonAPIRequestService = commonAPIRequestService;
        }    
        
        public async Task<APIRequestResponse> GetOwnerSmartContractCall(string senderAddress)
        {
            string ownerContractAddress = "";
            try
            {                
                var smartContractLocalCall = new SmartContractLocalCallModel
                {
                    GasPrice = 100,
                    GasLimit = 50000,
                    Amount = 0,
                    MethodName = "GetOwner",
                    ContractAddress = "PNhr8Qo9tbmVXyzz38xnBVm9oceJqzD8Q5",
                    Sender =senderAddress,
                    Parameters =null, 
                    };

                    APIRequestResponse response = await commonAPIRequestService.PostRequestAsync(defaultEndPoint, "/api/SmartContracts/local-call", smartContractLocalCall).ConfigureAwait(false);

                    return response;                
            }
            catch (Exception ex)
            {
              
            }
            return null;
        }

    }

Here, all the default values to call contract are hardcoded, and also the Smart Contract Address that we received while deployed in the private network is also passed as the hardcoded value in the parameter. You can keep the contract address in the appsettings as well because it can be different if you deploy the contract in Testnet or in MainNet. The right way to keep the default/reusable value is in a managed way so that it can be accessed from any service or any class. You don’t need to change the hardcoded values in several places. For demo purposes, I have passed the default values as hardcode.

Step 4 – Add Model for Sender Address

In this demo contract call, we will pass the sender address from UI and then call the contract. For this, we need to add ViewModel. So add GetOwnerModel class under the Models folder. Below is the code of GetOwnerModel.

public class GetOwnerModel
    {
        public string SenderAddress;
    }

Step 5 – Create Action Method and View Page for Contract Call

Now, it’s time to add the Action method in Home Controller and Create a view to call the contract from the application interface.

For this, let’s add the Action method as below in the HomeController.

  public IActionResult GetOwnerAddress()
        {
            return View();
        }

Right-click on above GetOwnerAddress() method and add empty View.

Then write the below code in your GetOwnerAddress View.

@model SampleSmartContractCallApp.Models.GetOwnerModel

@{
    ViewData["Title"] = "GetOwnerAddress";
}

<h4>Get Owner Address</h4>
<div class="row">
    <div class="col-md-4">
        <form id="studenteForm" novalidate class="needs-validation">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="SenderAddress" class="control-label"></label>
                <input asp-for="SenderAddress" class="form-control" id="senderAddress" required />
                <span asp-validation-for="SenderAddress" class="text-danger"></span>
            </div>
            <div class="form-group">
                <button type="button" class="btn btn-primary" onclick="getOwnerAddress()">Get Owner </button>
            </div>
        </form>
    </div>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Here we have designed the Sender Address text field and button. On click event of this button, we will call the contract based on the address provided in the Text field.

Additionally, add this in your _Layout.cshtml so that you can directly click from the Home page and redirect to your Contract Call View page.

Then when you run the application your home page will look like as illustrated below.

GetOwnerAddress page view.

Step 6 -Add ContractCallController under the Controller Folder.

Right-click on Controller and add the ContractCallController. Once, the user clicks the button from the GerOwnerAddress View we will call the method from this Controller to call the Contract.

Below is the complete code of ContractCallController

public class ContractCallController : Controller
    {
        private readonly SmartContractService smartContractService;
        public ContractCallController(SmartContractService smartContractService)
        {
            this.smartContractService = smartContractService;
        }

        [HttpPost]
        [Route("getowneraddress")]
        public async Task<IActionResult> OwnerAddress([FromBody] string senderAddress)
        {
            if (string.IsNullOrEmpty(senderAddress))
                return this.BadRequest("Please provide Sender Address!!");

            APIRequestResponse response = await this.smartContractService.GetOwnerSmartContractCall(senderAddress);
            if (response.IsSuccess)
            {
                return this.Ok(response.Content.ToString());
            }

            if (response.Content?.errors != null)
                return this.BadRequest($"An error occurred trying to get owner address: {response.Content?.errors[0].message}");

            return this.BadRequest($"An error occurred trying to get owner address: {response.Content}");
        }

    }

Step 7 – Button click Event using Ajax Post

Now, we will write the below code for form data submit using Ajax Post method in Get Owner Button click event.

You can visit previous article for form data Submit using Ajax Post for detailed understanding of it.

Note: If your Contract Method needs more parameters, you can add more properties in your view model and also add those in your design page, ContractCallService as well.

Ajax Post Code:

<script type="text/javascript">
    function getOwnerAddress() {
        var senderAddress = $("#senderAddress").val()
        console.log(senderAddress);
        $.ajax({
            type: 'POST',
             url: '/contractCall/getowneraddress',
            contentType: 'application/json; charset=utf-8',
            data: JSON.stringify(senderAddress),
            success: function (result) {
                alert('successful' + result);
                console.log(result);
            },
            error: function () {
                alert('Failed to get owner's address');
                console.log('Failed ');
            }
        })
    }
</script>

Complete code of GetOwnerAddress.cshtml page.

@model SampleSmartContractCallApp.Models.GetOwnerModel

@{
    ViewData["Title"] = "GetOwnerAddress";
}
<script type="text/javascript">
    function getOwnerAddress() {
        var senderAddress = $("#senderAddress").val()
        console.log(senderAddress);
        $.ajax({
            type: 'POST',
             url: '/contractCall/getowneraddress',
            contentType: 'application/json; charset=utf-8',
            data: JSON.stringify(senderAddress),
            success: function (result) {
                alert('success receive the Data' + result);
                console.log(result);
            },
            error: function () {
                alert('Failed to receive the Data');
                console.log('Failed ');
            }
        })
    }
</script>
<h4>Get Owner Address</h4>
<div class="row">
    <div class="col-md-4">
        <form id="studenteForm" novalidate class="needs-validation">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="SenderAddress" class="control-label"></label>
                <input asp-for="SenderAddress" class="form-control" id="senderAddress" required />
                <span asp-validation-for="SenderAddress" class="text-danger"></span>
            </div>
            <div class="form-group">
                <button type="button" class="btn btn-primary" onclick="getOwnerAddress()">Get Owner </button>
            </div>
        </form>
    </div>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Testing Contract Call

To test it, your blockchain network must be running. So run the FullNode in your machine. To run it, you can refer to the previous article.

Now, to test the contract call you need to use one of the addresses from your address list then it will show you the Owner’s address in the return value as depicted below.

In this article, I have just shown the contract call return result in the view as alert, however; you can get the return of your Contract Call and utilize your logic based on your application requirement.

Note: The way of implementing contract call in the application which builds transaction to call contract and also broadcast the transaction in the network such as API endpoint; /api/SmartContracts/build-and-send-call is also similar to the demonstrated example in this article. The difference is only you need more parameters to call contract for example Wallet Name, Password, and so on. Additionally, note that the required parameters to pass depend upon your method. If your contract call method needs some parameters then you must supply them while calling the contract.

Summary

In a nutshell, the article has described steps to create an ASP.NET Core application and demonstrated how to call a contract from the application with all steps. Additionally, we have learned to get the response from the API post method as well as explained in detail to post data from the user interface to the backend and get the response result from the smart contract which was deployed on the Stratis blockchain. I hope, the article has provided insight into Smart Contract use in your custom application.

Leave a Reply

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