Smart Contract: decentralize application

A smart contract after deployed to blockchain can be understood as an application. It can be used with multiple purpose. Like other types of application, smart contract needs to be deployed to be used. In our case, we will deploy the smart contract to KardiaChain

Initialize a smart contract instance

import KardiaClient from 'kardia-js-sdk';
const RPC_ENDPOINT = 'YOUR_RPC_ENDPOINT';

const kardiaClient = new KardiaClient({ endpoint: RPC_ENDPOINT });

const contractInstance = kardiaClient.contract;

Deploy a smart contract

contractInstance.updateAbi(ABI);
contractInstance.updateByteCode(BYTECODES);

const preDeploy = myContract.deploy({
    params: PARAMS_TO_DEPLOY,
});

const defaultPayload = preDeploy.getDefaultTxPayload();
const estimatedGas = await preDeploy.estimateGas(defaultPayload);

const smcData = await preDeploy.send(PRIVATE_KEY, {
    gas: estimatedGas,
}, true);

// Get the deployed contract address by smcData.contractAddress

Every interaction with smart contract can be categorized into 2 type:

  • Call interaction

  • Send interaction

Call a smart contract function

Will call a “constant” method and execute its smart contract method in the KVM without sending any transaction. Note calling cannot alter the smart contract state

contractInstance.updateAbi(ABI);
const invocation = contractInstance.invokeContract(FUNCTION_NAME, FUNCTION_PARAMS);
const result = await invocation.call(SMC_ADDRESS);

Send a transaction to smart contract

Will send a transaction to the smart contract and execute its method. Note this can alter the smart contract state.

contractInstance.updateAbi(ABI);
const invocation = contractInstance.invokeContract(FUNCTION_NAME, FUNCTION_PARAMS);
const txHash = await invocation.send(PRIVATE_KEY, SMC_ADDRESS);

// Custom payload in case you don't want to use default payload
const txPayload = {
    gasPrice: YOUR_GAS_PRICE,
    gas: YOUR_GAS_LIMIT
}

// Or if you want to wait for transaction receipt
const txReceipt = await invocation.send(
    PRIVATE_KEY, 
    SMC_ADDRESS,
    txPayload , // if you want to use default payload, use {}
    true // Flag to indicate if waiting for tx receipt. It will wait for 300000
);

Listen for smart contract's event

Smart contract's events can be listened using filter. But before creating filter, topics must be defined. Topics are created by using keccak256 hash function. For example:

import keccak256 from 'keccak256'

// A topic for event Delegate(address,uint256)
// The result should be 0xb0d234274aef7a61aa5a2eb44c23881ebf46a068cccbd413c978bcbd555fe17f
const delegateTopic = keccak256('Delegate(address,uint256)')

After that, a filter can be created using those topics

import KardiaClient from 'kardia-js-sdk';
import keccak256 from 'keccak256'

// A topic for event Delegate(address,uint256)
// The result should be 0xb0d234274aef7a61aa5a2eb44c23881ebf46a068cccbd413c978bcbd555fe17f
const delegateTopic = keccak256('Delegate(address,uint256)')

const RPC_ENDPOINT = 'YOUR_RPC_ENDPOINT';

const kardiaClient = new KardiaClient({ endpoint: RPC_ENDPOINT });

const filterID = kardiaClient.kaiChain.newFilter({
    fromBLock: 123,
    toBlock: 'latest',
    address: 'CONTRACT_ADDRESS',
    topics: [delegateTopic]
});
// FilterID response will be something like 0xd4d6cab8e6de13d09eec61c681f3039f

FilterID can be used in getFilterLogs or getFilterChanges function

// Get all logs matching filter
const logs = await kardiaClient.kaiChain.getFilterLogs(filterID)

// Or if you want to get an array of logs which occurred since last poll
const newLogs = await kardiaClient.kaiChain.getFilterChanges(filterID)

// Sample response
// [
//   {
//     "address": "0xf35a869a0f96dfd6bce6d57ecf9ef5a883b59c61",
//     "topics": [
//         "0xb0d234274aef7a61aa5a2eb44c23881ebf46a068cccbd413c978bcbd555fe17f"
//     ],
//     "data": "0x000000000000000000000000c1fe56e3f58d3244f606306611a5d10c8333f1f600000000000000000000000000000000000000000000054b40b1f852bda00000",
//     "blockHeight": 5,
//     "transactionHash": "0x8d8d38bf099ec1a3b5bcc4dbc091dc62020236023863f7afb6f852a9d4828a0b",
//     "transactionIndex": 0,
//     "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
//     "logIndex": 1,
//     "removed": false
// }, {
//     ...
// }]

Remember to always remove a filter after used. A filter can be removed using uninstallFilter function

await kardiaClient.kaiChain.uninstallFilter(filterID)

Last updated