Quick Start using Hardhat

This tutorial will guide you how to deploy a contract on Base Sepolia that leverage Inco's functionality such as random number generator and encrypted types in order to generate a random hidden card.

Project Setup

First you need Node.js installed on your system. We recommend to install NVM (Node Version Manager) first and install Node with nvm. The official Linux version can be found here. If you're on Windows, you can use this unofficial distribution here. To make things easier, here is how to set up nvm:

For Linux, follow this tutorial. For Windows, just follow the Readme guide.

We'll also need pnpm which can be installed with the following command:

npm install -g pnpm

Now that you have NVM, Node.js and PNPM installed, clone this repo and install dependencies with the following command:

git clone https://github.com/Inco-fhevm/hardhat-inco-bridge-template.git
cd hardhat-inco-bridge-template
pnpm install

Once completed, you'll be able to deploy contracts and use Inco's full confidentiality suite. The project comes with two sample contracts that show how to generate a hidden random card, reveal it and send it back to Base.

Feel free to familiarize yourself with how contracts are structured. To tell hardhat which contracts to deploy to which chain, we have written both contract names inside hardhat.config.ts at the very bottom:

The first one will be deployed on Inco, while the second one will be deployed on your chain of choice. For now we only support the following chains:

  • Base Sepolia (Testnet)

  • Edgeless (Testnet)

Deploying to Base Sepolia

Deploying both contracts to both chains is relatively easy. First you need a private key to a wallet that has both Inco as well as Base Sepolia test tokens. To get Inco Testnet tokens, you can use our faucet. Once you have that, just copy .env.example to .env

cp .env.example .env

and replace PRIVATE_KEY environment variable inside .env file with your own private key. Then run:

npx hardhat crossdeploy --network baseSepolia

If everything went correctly, you should see the following output:

Congratulations, you have successfully deployed a contract on Base that bridges to Inco. To test it out and see that it actually worked, open CardExampleBaseContractExecuteAPI.sol contract inside Remix, connect your Metamask and switch to Base Sepolia testnet:

Then go back to our terminal and copy the last address which is address of a contract deployed on Base:

and then paste it in Remix and press "At Address" button to connect to the deployed contract:

At the bottom you should see the following:

Press the dropdown button and then copy any ethereum address and paste it as an argument to CardGet function before calling it.

Once called, the transaction will relay a message through our bridge by calling returnCard() function on Inco, return value of which will be passed to the callback function cardReceive(uint256 user, uint8 _card). After pressing the CardGet() button we wait 10-15 seconds before calling CardView and using the same address to confirm:

The resulting number should be a number between 1 - 52 which represents a full range of cards in a deck of 52 cards. If you're receiving 0 keep pressing "CardView" button to fetch the value from Base.

One thing to keep in mind as a developer is that as soon as you decrypt something on Inco - the plaintext value is already known to the public before the transaction happens on Base. Make sure your smart contract logic takes that into account to prevent from frontrunning.

That is all for this tutorial. We won't touch on security best practices as this was meant as an introduction to bridging between Inco and Base, but feel free to tinker around with the smart contracts themselves and use them as a template for your next cool project.

Last updated