The ICON Network is a decentralized blockchain project from South Korea with the goal of becoming a hub for interconnecting many other blockchains with its BTP technology, it currently hosts many Dapps (Decentralized Apps) ranging from NFT games and platforms ( like gangstabet, Craft Network, Project Nebula, etc) to DeFi platforms (like Balanced Network, OMM Finance and Optimus Finance) and even a fully decentralized casino running entirely on smart contracts (ICONBet).
This is the first article in a series dedicated to show how to interact with the ICON Network using nodejs. While the article is directed to people that have no prior knowledge of how to interact with smarts contracts on ICON or any other blockchain project, it is necessary to have a prior knowledge of coding with JavaScript (specially asynchronous programming with JavaScript) and nodejs (knowing how to use modules is necessary).
Understanding the JSON RPC API
All your interactions with the ICON Network and the different smart contracts in the chain are going to be done via a JSON RPC API.
The JSON RPC API is a remote procedure call encoded in JSON, to put it in simple terms, you are going to be sending data in a predefined schema or format to a smart contract in the ICON Network and if all goes well you'll be receiving a reply with the data you asked (if things don't go well you'll still receive an error reply too).
This is the description of the ICON JSON RPC API V3 and this is how a common call and response would look like.
// Request
{
"jsonrpc": "2.0",
"method": "$STRING1",
"id": $INT,
"params": {
"$KEY1": "$VALUE1",
"$KEY2": {
"method": "$STRING2",
"params": {
"$KEY3": "$VALUE3"
}
}
}
}
// Response - success
{
"jsonrpc": "2.0",
"id": $INT,
"result": "$STRING"
// or
"result": {
"$KEY1": "$VALUE1",
"$KEY2": "$VALUE2"
}
}
// Response - error
{
"jsonrpc": "2.0",
"id": $INT1,
"error": {
"code": $INT2,
"message": "$STRING"
}
}
The communication to the ICON Network is done from your code (any script or Dapp you build) to a citizen node (which is basically a full node with no governance participation in the network, a silent listener of the chain) an then to an active governance node (called Public Representatives or P-Reps) that is in charge to act up or process the interactions and/or transactions you are going to be making and then it propagates those changes to the entire network. The following diagram shows these interaction.
Image taken from the "ICON Deconstructed Part III" article on Medium
Things to know before talking to the chain, the https module and JS promises
As shown in the previous image there are several SDK in different languages that you can use but for the purpose of this article and because we are going to start with simple things we will be doing the communication directly via HTTPS requests.
Now that we know what is the language that we will be using to communicate to the ICON Network (JSON RPC API), there is one important piece of code that we need to write which will become our main module to talk to the ICON Network and that is an HTTPS request wrapped in a promise to allow for asynchronous interactions with the network.
Assuming that you already have nodejs installed in your computer, go and create a folder and then run npm init
to create a new project. The folder structure in the project is going to look like this:
dev.to-article/
├── httpsRequest.js
├── index.js
└── package.json
0 directories, 3 files
We are going to start working on the httpsRequest.js
file. The content is pretty straightforward we import the https
module, create an async function
wrap the https request
inside this function and execute it using await
to get the response from the network and then at the end we export the httpsRequest
async function as a module.
// httpsRequest.js
// This module is a https request wrapped in a promise design to be used
// to interact with the ICON Blockchain
//
// Imports
const https = require("https");
/**
* async https request wrapped in a promise
* @param {Object} param - params for the http request
* @param {string} param.hostname
* @param {string} param.ip
* @param {number} param.port
* @param {number} param.timeout
* @param {string} param.path
*/
async function httpsRequest(params, data = false) {
const promisifiedQuery = new Promise((resolve, reject) => {
const query = https.request(params, res => {
// Print status code on console
console.log("Status Code: " + res.statusCode);
// Process chunked data
let rawData = "";
res.on("data", chunk => {
rawData += chunk;
});
// when request completed, pass the data to the 'resolve' callback
res.on("end", () => {
let data = JSON.parse(rawData);
resolve(data);
});
// if error, print on console
res.on("error", err => {
console.log("Got error: ", +err.message);
});
});
// If request timeout destroy request
query.on("timeout", () => {
console.log("timeout. destroying query");
query.destroy();
});
// Handle query error
query.on("error", err => {
console.log("error running query, passing error to callback reject");
reject(err);
});
if (data != false) {
// If data param is passed into function we write the data
query.write(data);
}
// end request
query.end();
});
// wait for the response and return it
try {
return await promisifiedQuery;
} catch (err) {
console.log("error while running promisifiedQuery");
console.log(err);
}
}
module.exports = httpsRequest;
Talking to the governance smart contract on the ICON Network
On the index.js
file we are going to start by importing the httpsRequest.js
module and then start creating the JSON RPC formatted request we will be sending to the ICON network.
// index.js
const httpsRequest = require('./httpsRequest.js');
// These are the params of the https request
const PARAMS = {
hostname: 'api.icon.geometry.io', // This is a citizen node in the network
path: '/api/v3',
method: 'POST' // all https request to the network are POST requests
};
// This is the JSON RPC formatted call we are sending to the network
const DATA = JSON.stringify({
jsonrpc: '2.0',
method: 'icx_call',
id: 1,
params: {
to: 'cx0000000000000000000000000000000000000000',
dataType: 'call',
data: {
method: 'getPReps',
params: {
startRanking: '0x1',
endRanking: '0x16'
}
}
}
});
In this specific example we are interacting with the governance smart contract in the ICON Network (cx000...
) and calling the method getPReps
, this will allow us to get a list of the P-Reps (node validators) in the network, also since there are more than 100 P-Reps in the network we are passing a startRanking
and endRanking
values to get only the top 22 P-Reps by delegation in the network.
The final code in the index.js
file should look like this:
// index.js
const httpsRequest = require("./httpsRequest.js");
// These are the params of the https request
const PARAMS = {
hostname: "api.icon.geometry.io", // This is a citizen node in the network
path: "/api/v3",
method: "POST" // all https request to the network are POST requests
};
// This is the JSON RPC formatted call we are sending to the network
const DATA = JSON.stringify({
jsonrpc: "2.0",
method: "icx_call",
id: 1,
params: {
to: "cx0000000000000000000000000000000000000000",
dataType: "call",
data: {
method: "getPReps",
params: {
startRanking: "0x1",
endRanking: "0x16"
}
}
}
});
// Run async httpsRequest and print response on console
(async () => {
try {
let response = await httpsRequest(PARAMS, DATA);
console.log(response);
} catch (err) {
console.log("Error running httpsRequest");
console.log(err);
}
})();
After running node index.js
we are going to get a reply like this from the smart contract:
dev.to-article$ node index.js
Status Code: 200
{
jsonrpc: '2.0',
result: {
blockHeight: '0x2b924c6',
preps: [
[Object], [Object], [Object],
[Object], [Object], [Object],
[Object], [Object], [Object],
[Object], [Object], [Object],
[Object], [Object], [Object],
[Object], [Object], [Object],
[Object], [Object], [Object],
[Object]
],
startRanking: '0x1',
totalDelegated: '0x1205ef103fffce01d3dd1ff',
totalStake: '0x13f0b214efa073bac2d0d53'
},
id: 1
}
Congratulations! now you know how to interact with smart contracts on the ICON Network!, I invite you to join the community by visiting the forum and telegram channel for developers and keep learning so that you can also build amazing projects in the ICON Ecosystem, we have a decentralized funding program called CPS (Contribution Proposal System) that anyone can use to finance and build projects on the ICON Network so if you have a great idea please come and build with us!.
If you like this article please leave a comment and share it on social media, more articles will be coming explaining things about interacting with smart contracts on the ICON Network.
Thanks for reading!.
Top comments (0)