How to Develop and Deploy an Avalanche Smart Contract

Build-dApp-on-Avalanche

The introduction of Bitcoin and its underlying technology, blockchain, was a breakthrough invention. Blockchain, a distributed ledger that has the potential to revamp healthcare, supply chain, financial infrastructure and the IT industry, was, however, introduced solely to create a new cryptocurrency. Satoshi Nakamoto introduced the world to the concept of Bitcoin, but developers discovered innovative blockchain use cases as they did not want it to be limited to cryptocurrencies.

Developers like Vitalik Buterin found the scope of creating decentralized platforms and applications that ensure autonomy and security through blockchain technology. From then onwards, blockchain is constantly evolving. Newly emerging blockchain platforms are more progressed and matured when compared to the initial Bitcoin blockchain. The bitcoin blockchain had several limitations like scalability problems, low transaction speed, interoperability, environmental issues etc., but the later introduced blockchain protocols addressed these shortcomings and brought in several beneficial features.

With noteworthy advanced features and impressive transaction speed, Avalanche is one of the latest additions to the blockchain networks. Launched in September 2020, Avalanche is an open-source, proof-of-stake protocol to build decentralized applications and enterprise blockchain deployments. The platform’s infrastructure resolves scalability issues and other limitations like slow transaction speed and security with its unique infrastructure.

Avalanche platform’s benefits make it a better ecosystem for developing customized DeFi apps, decentralized applications, and smart contracts. Through this article let us first learn about Avalanche before going through the steps to deploy smart contracts on Avalanche.

About Avalanche

Avalanche is a secure, flexible, and scalable ecosystem launched by the owner of Ava Labs and Cornell University computer science professor Emin Gün Sirer for decentralized applications development. It is one of the fastest, programmable and interoperable smart contracts platforms that permit anyone to make custom-made applications on the blockchain. AVAX is the native token of Avalanche.

Avalanche is a hybrid of three built-in blockchains suitable for three different purposes. They are:

  • Exchange Chain (X-Chain) – To create, trade and administer assets, and related transactions.
  • Platform Chain (P-Chain) – To coordinate validators, manage and create subnets
  • Contract Chain (C-Chain) – An instance of Ethereum Virtual Machine for creating smart contracts

Since this article deals with building Avalanche smart contracts, we have to understand about Contract (C) chain.

The Contract Chain allows the creation of Ethereum-compatible smart contracts and is the default smart contract blockchain on the Avalanche network. It is a instance of the Ethereum Virtual Machine. Avalanche claims that C-chain offers better throughput, higher speed, lower gas price and speedy transaction confirmation times because of its Proof-of-Stake consensus mechanism based on the Snowman consensus protocol.

Key features

  • Scalability – Avalanche is a massively scalable, robust and efficient blockchain protocol capable of 4500 transactions per second.
  • Speed – Avalanche claims to be the fastest smart contracts platform among other blockchain ecosystems, as measured by time-to-finality.
  • Secure – It is a powerful protocol that guarantees stronger security considerably larger than the 51% standard of other networks.
  • Interoperable and flexible – The infrastructure of Avalanche allows it to be a universal and flexible ecosystem for a multitude of blockchain or assets, where AVAX is used for security and as a unit of account for an exchange.
  • Sustainability – The use of a proof-of-stake consensus mechanism instead of proof-of-work, makes Avalanche a less energy-consuming, sustainable platform.

How to develop and deploy smart contracts on Avalanche?

Solidity is the programming language to develop and deploy an Avalanche smart contract.

You can build smart contracts on Avalanche using different tools like Hardhat, Truffle, Remix etc. However, in this tutorial, we will use Truffle with Avalanche’s C-chain blockchain. Truffle aids you in writing and compiling smart contracts, running migrations, building artifacts and interacting with already deployed contracts.

Dependencies

  • Avalanche Network Runner – It is a tool to run a local Avalanche network
  • NodeJS v8.9.4 or later
  • Truffle – Install it with “npm install -g truffle”

Step 1: Starting up a local Avalanche Network

With Avalanche Network Runner, you can run and interact with a local Avalanche network. First, start a local five node Avalanche network:

cd /path/to/avalanche-network-runner
# start a five node staking network
./go run examples/local/fivenodenetwork/main.go

A five-node Avalanche network will run until you press CTRL + C to exit.

Step 2: Creating Truffle directory and installing dependencies

Open a new terminal tab to create a “truffle” directory and install the dependencies. Use the following code to navigate to the directory where you plan to create your “truffle” working directory:

cd /path/to/directory

Now, generate and enter a new directory and name it “truffle”:

mkdir truffle; cd truffle

Using “npm”, install web3.js, a library that allows you to communicate with Ethereum Virtual Machine(EVM) and AvalancheJS, used for cross-chain swaps.

npm install web3 avalanche -s

We will utilize web3 to create an HTTP provider that enables web3 to interact with the EVM. Finally, make a truffle boilerplate project.

truffle init

When the local development network is built, it pre-funds some static addresses. We will use @truffle/hdwallet-provider to create accounts with these pre-funded addresses:

npm install @truffle/hdwallet-provider

Step 3: Update truffle-config.js

When you run “truffle init”, one of the files generated is “truffle-config.js”. Add the below mentioned codes to “truffle-config.js”:

const Web3 = require("web3");
const HDWalletProvider = require("@truffle/hdwallet-provider");
const protocol = "http";
const ip = "localhost";
const port = 9650;
Web3.providers.HttpProvider.prototype.sendAsync = Web3.providers.HttpProvider.prototype.send;
const provider = new Web3.providers.HttpProvider(
${protocol}://${ip}:${port}/ext/bc/C/rpc
);
const privateKeys = [
"0x56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027",
"0x7b4198529994b0dc604278c99d153cfd069d594753d471171a1d102a10438e07",
"0x15614556be13730e9e8d6eacc1603143e7b96987429df8726384c2ec4502ef6e",
"0x31b571bf6894a248831ff937bb49f7754509fe93bbd2517c9c73c4144c0e97dc",
"0x6934bef917e01692b789da754a0eae31a8536eb465e7bff752ea291dad88c675",
"0xe700bdbdbc279b808b1ec45f8c2370e4616d3a02c336e68d85d4668e08f53cff",
"0xbbc2865b76ba28016bc2255c7504d000e046ae01934b04c694592a6276988630",
"0xcdbfd34f687ced8c6968854f8a99ae47712c4f4183b78dcc4a903d1bfe8cbf60",
"0x86f78c5416151fe3546dece84fda4b4b1e36089f2dbc48496faf3a950f16157c",
"0x750839e9dbbd2a0910efe40f50b2f3b2f2f59f5580bb4b83bd8c1201cf9a010a",
];
module.exports = {
networks: {
development: {
provider: () => {
return new HDWalletProvider({
privateKeys: privateKeys,
providerOrUrl: provider,
});
},
network_id: "*",
gas: 3000000,
gasPrice: 225000000000,
},
},
};

If you need to send API calls to a different AvalancheGo node, you can modify the “protocol”, “ip” and “port”. Also, note that the “gasPrice” and “gas” are set to the suitable values for the Avalanche C-chain.

Step 4: Add Storage.sol

Add the following codes to a new file called “Storage.sol” in the “contracts” directory:

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

/**
 * @title Storage
 * @dev Store & retrieve value in a variable
 */
contract Storage {

    uint256 number;

    /**
     * @dev Store value in variable
     * @param num value to store
     */
    function store(uint256 num) public {
        number = num;
    }

    /**
     * @dev Return value
     * @return value of 'number'
     */
    function retrieve() public view returns (uint256){
        return number;
    }
}

“Storage” is a solidity smart contract that allows us to write a number to a blockchain using a “store” function and subsequently recover the value using a “retrieve” function.

Step 5: Add new migration

Add the below-mentioned code to a new file named “2_deploy_contracts.js” in the “migrations” directory. This manages the “Storage” smart contract deployment to the blockchain:

const Storage = artifacts.require("Storage");

module.exports = function (deployer) {
  deployer.deploy(Storage);
};

Step 6: Compiling Contracts with Truffle

Whenever you edit “Storage.sol”, you have to run “truffle compile”.

truffle compile

Look into the following:

Compiling your contracts...
===========================
> Compiling ./contracts/Migrations.sol
> Compiling ./contracts/Storage.sol
> Artifacts written to /path/to/build/contracts
> Compiled successfully using:
   - solc: 0.5.16+commit.9c3226ce.Emscripten.clang

Step 7: Accounts on C-chain

Truffle will use the first accessible account offered by your C-chain client as the “from” address used during migrations when deploying smart contracts to the C-chain. The first available default account should have some pre-funded AVAX.

Truffle Accounts

With the truffle console, you can check imported accounts.

To access the truffle console:

truffle console --network development

Note: If “Error: Invalid JSON RPC response: “API call rejected because the chain is not done bootstrapping” “appears, you must wait until the network has been bootstrapped and is ready to use. It would not take much time.

Inside truffle console:

truffle(development)> accounts
[
  '0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC',
  '0x9632a79656af553F58738B0FB750320158495942',
  '0x55ee05dF718f1a5C1441e76190EB1a19eE2C9430',
  '0x4Cf2eD3665F6bFA95cE6A11CFDb7A2EF5FC1C7E4',
  '0x0B891dB1901D4875056896f28B6665083935C7A8',
  '0x01F253bE2EBF0bd64649FA468bF7b95ca933BDe2',
  '0x78A23300E04FB5d5D2820E23cc679738982e1fd5',
  '0x3C7daE394BBf8e9EE1359ad14C1C47003bD06293',
  '0x61e0B3CD93F36847Abbd5d40d6F00a8eC6f3cfFB',
  '0x0Fa8EA536Be85F32724D57A37758761B86416123'
]

If you want to see the balance, enter:

truffle(development)> await web3.eth.getBalance(accounts[0])
'50000000000000000000000000'

truffle(development)> await web3.eth.getBalance(accounts[1])
'0'

Remember that “accounts[0]” (default account) has some balance, but “accounts[1]” have no balance.

Scripting account funding

A convenient script that funds the “accounts” list is available. However, you can also download it using the following command:

wget -nd -m https://raw.githubusercontent.com/ava-labs/avalanche-docs/master/scripts/fund-cchain-addresses.js

Use the below-mentioned code to run the script:

truffle exec fund-cchain-addresses.js --network development

The script will deposit 1000 AVAX into each of the “accounts”. After you successfully run the script, check the balances with:

truffle(development)> await web3.eth.getBalance(accounts[0]);
'50000001000000000000000000'
truffle(development)> await web3.eth.getBalance(accounts[1]);
'1000000000000000000'

Personal APIs

Node accounts connect with personal APIs. “Web3” has some functions that uses this API, such as “web3.eth.personal.newAccount”, “web3.eth.personal.unlockAccount” etc. However, this API is turned off by default, which can be activated with “C-chain”/”Coreth” configs. The Avalanche Network Runner presently does not enable activating this API. So, you can access these features only if you run your network manually with “internal-private-personal” API enabled through the “eth-apis” flag.

Step 8: Run migrations

With everything set up, you can now run migrations and deploy the “Storage” contract:

truffle(development)> migrate --network development

Now, you can see the following:

Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.

Migrations dry-run (simulation)
===============================
> Network name:    'development-fork'
> Network id:      1
> Block gas limit: 99804786 (0x5f2e672)


1_initial_migration.js
======================

   Deploying 'Migrations'
   ----------------------
   > block number:        4
   > block timestamp:     1607734632
   > account:             0x34Cb796d4D6A3e7F41c4465C65b9056Fe2D3B8fD
   > balance:             1000.91683679
   > gas used:            176943 (0x2b32f)
   > gas price:           225 gwei
   > value sent:          0 ETH
   > total cost:          0.08316321 ETH

   -------------------------------------
   > Total cost:          0.08316321 ETH

2_deploy_contracts.js
=====================

   Deploying 'Storage'
   -------------------
   > block number:        6
   > block timestamp:     1607734633
   > account:             0x34Cb796d4D6A3e7F41c4465C65b9056Fe2D3B8fD
   > balance:             1000.8587791
   > gas used:            96189 (0x177bd)
   > gas price:           225 gwei
   > value sent:          0 ETH
   > total cost:          0.04520883 ETH

   -------------------------------------
   > Total cost:          0.04520883 ETH

Summary
=======
> Total deployments:   2
> Final cost:          0.13542204 ETH

Not creating an account on the C-chain will show you this error:

Error: Expected parameter 'from' not passed to function.

Also, you can see the following error if you did not fund the account:

Error:  *** Deployment Failed ***

"Migrations" could not deploy due to insufficient funds
   * Account:  0x090172CD36e9f4906Af17B2C36D662E69f162282
   * Balance:  0 wei
   * Message:  sender doesn't have enough funds to send tx. The upfront cost is: 1410000000000000000 and the sender's account only has: 0
   * Try:
      + Using an adequately funded account

Step 9: Interacting with your contract

Now that the “Storage” contract is deployed let us note down a number to the blockchain and then read it back. For this, go to the truffle console:

Acquire an instance of the deployed “Storage” contract:

truffle(development)> let instance = await Storage.deployed()

This results in:

undefined

Writing a number to the blockchain

Once you get an instance of the “Storage” contract, call its “store” method and hand in a number to write to the blockchain.

truffle(development)> instance.store(1234)

You can see codes similar to this:

{
  tx: '0x10afbc5e0b9fa0c1ef1d9ec3cdd673e7947bd8760b22b8cdfe08f27f3a93ef1e',
  receipt: {
    blockHash: '0x8bacbce7c9d835db524bb856288e3a73a6afbe49ab34abd8cd8826db0240eb21',
    blockNumber: 9,
    contractAddress: null,
    cumulativeGasUsed: 26458,
    from: '0x34cb796d4d6a3e7f41c4465c65b9056fe2d3b8fd',
    gasUsed: 26458,
    logs: [],
    logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
    status: true,
    to: '0x0d507b0467baef742f9cc0e671eddbdf6df41d33',
    transactionHash: '0x10afbc5e0b9fa0c1ef1d9ec3cdd673e7947bd8760b22b8cdfe08f27f3a93ef1e',
    transactionIndex: 0,
    rawLogs: []
  },
  logs: []
}

Reading a number from the blockchain

Connect with the “retrieve” method of the “Storage” contract instance to read the number from the blockchain.

truffle(development)> let i = await instance.retrieve()

This shows the following:

undefined

The call to “retrieve” results in a “BN”(big number). To see the value, call its “.toNumber” method:

truffle(development)> i.toNumber()

Now, you would be able to see the number you stored.

1234

Avalanche development services at LeewayHertz

LeewayHertz offers a broad range of blockchain development services to help firms and startups better adopt the technology for business growth opportunities. Our developers can provide you with the quality development services and use-cases you aim for in any advanced blockchain protocol, including Avalanche. We offer the following Avalanche development services:

dApps Development

Our developers specialize in building DeFi dApps compatible with Ethereum. The technical expertise of our team can provide you with refined dApps that support the trading of equities, commodities, alternative assets and more.

Solidity-based smart contracts creation

Our team constantly researches and keeps track of even the nuances of Avalanche upgradations and new adoptions. We create and deploy solidity-based smart contracts on Avalanche and offer services that include architecture, designing, auditing, and implementing smart contracts.

NFT Solutions

Blockchain developers of LeewayHertz are proficient in creating NFT solutions like NFT marketplace development, NFT storage solution, UI design, wallet integration, feature integrations, etc. for blockchain-focused businesses. We build and deploy reliable NFT solutions leveraging advanced blockchain technologies, including Avalanche.

Wallet development

Our team of developers can create a customized, user-friendly and secure Avalanche wallet to transfer, receive, and swap assets on the network.

Custom blockchain development

We use virtual machines in Avalanche subnets to develop private and public custom blockchains including running a node on the primary network, API calls, subnet development, virtual machine development and adding a validator.

Conclusion

Avalanche is a “blazing fast, low cost and eco-friendly” protocol gaining popularity in the blockchain space. The infrastructure of Avalanche is open-source and fully programmable, allowing blockchain developers worldwide to build dApps, solidity-based smart contracts, NFT solutions, etc. Avalanche smart contracts are inexpensive and offer support for tools like Remix, Truffle, etc., for developers’ convenience.

For consultancy and development services related to dApps, smart contracts and custom blockchains development on Avalanche blockchain, please connect with our blockchain experts.

Webinar Details

Author’s Bio

Akash Takyar
Akash Takyar
CEO LeewayHertz
Akash Takyar is the founder and CEO at LeewayHertz. The experience of building over 100+ platforms for startups and enterprises allows Akash to rapidly architect and design solutions that are scalable and beautiful.
Akash's ability to build enterprise-grade technology solutions has attracted over 30 Fortune 500 companies, including Siemens, 3M, P&G and Hershey’s. Akash is an early adopter of new technology, a passionate technology enthusiast, and an investor in AI and IoT startups.

Start a conversation by filling the form

Once you let us know your requirement, our technical expert will schedule a call and discuss your idea in detail post sign of an NDA.

All information will be kept confidential.

 Send me the signed Non-Disclosure Agreement (NDA)

Insights

The seven layers of the metaverse

The seven layers of the metaverse

A great way to understand the metaverse is by understanding the seven layers that make it up. Every layer is important and represents a key aspect of the metaverse.

read more