We’re excited to announce a new version of our most popular developer starter kit: the Chainlink Hardhat Starter Kit now supports Typescript! Keep reading for a breakdown of all of the new features.
A Refresher—The Chainlink Hardhat Starter Kit
git clone https://github.com/smartcontractkit/hardhat-starter-kit.git
To switch to the TypeScript version, you need to checkout to the
git checkout typescript
Testing has truly been leveled up with this new edition. Test files are divided into two separate categories—unit tests and staging tests. Each test listens for a specific event when waiting for a callback from the oracle network.
Each unit test is independent and callback responses from the oracle network are mocked using a wide pallet of test contracts and helpers from the official Chainlink repository. This means you can save time by running them in parallel using the following command:
yarn test --parallel
Staging tests, on the other hand, use already deployed instances of contracts on various test networks while listening for the events. There are no mocked contracts or simulated callbacks. You can speed Hardhat up by preventing ts-node from recompiling and type-checking your project on every run by setting the
TS_NODE_TRANSPILE_ONLY env variable to 1.
Additionally, in tests, you can fork mainnet in a concrete block by uncommenting the “forking” property in a Hardhat config file and setting “enabled” to true. You will need an archival node or JSON RPC provider like Alchemy for this.
Ethereum Natural Language Specification Format, or NatSpec for short, is a form for comments meant to provide rich documentation to Solidity smart contracts. These comments use tags such as
@return, etc., and can be used to describe pretty much anything from contracts themselves to functions, including variables, events, or even modifiers. But not just that, the messages generated by NatSpec are directly meant to be displayed to the end-users when they are interacting with your contract functions, i.e., signing a transaction.
In smart contract development, understanding code coverage is an underrated skill, especially if you practice test-driven development. It is a measure in percent of the degree to which the smart contract source code is executed when a particular test suite is run. A project with high test coverage has a lower chance of containing undetected bugs compared to a project with low test coverage. To develop secure dApps, you should reach at least 90 percent of code coverage. However, don’t try to chase 100 percent coverage at all costs because this can result in unexpected side effects.
To run it, enter:
Some Solidity files, like mock contracts whose only purpose is to serve as test helpers, will display low coverage percentages. To exclude them from checks, update the “.solcover.js” file.
Programming smart contracts for EVM-compatible chains means programming with limited resources. For this reason, developers tend to optimize their code as much as possible. Gas optimizations can be tricky, a Mocha reporter has been added to the test suites that displays gas usage per unit test and various metrics for method calls and deployments.
To estimate gas, just set a
REPORT_GAS environment variable to true, and then run:
yarn hardhat test
The output will be stored in a “gas-report.txt” file. If you’d like to see the gas prices in USD or another currency, add a
COINMARKETCAP_API_KEY from Coinmarketcap.
View Contracts Size
Ever spent weeks building a smart contract only to encounter the “max code size exceeded” error during the deployment process? This means that you hit the smart contract code size limit (24,576 bytes for Ethereum testnets) and that you’ll need to reduce the size of the contract before deploying, or split it into several smaller contracts and libraries. To avoid massive refactoring at the end of the development process, a simple command to display the size of each smart contract in the project has been added so you can be aware of this limitation way earlier and act accordingly.
To view contract size, run:
yarn run hardhat size-contracts
Due to the immutable nature of smart contracts, you always want to be sure to test every possible scenario before deployment on the blockchain. That’s why the TypeScript edition of the Chainlink Hardhat Starter Kit comes with a fuzzer to find edge cases that couldn’t be found using the unit or staging tests. Fuzz testing is a technique that generates a massive number of random scenarios to uncover values that produce unexpected results.
Echidna has been included as a fuzz testing tool in this starter kit. You need to have Docker installed with at least 8GB of virtual memory allocated. To update this parameter go to Settings -> Resources -> Advanced -> Memory.
You can also run Echidna from the source. For more information, visit the Echidna public repository.
To start the Echidna instance, run the following command from the project root directory
If you are using it for the first time, you will need to wait for Docker to download the eth-security-toolbox image. This may take a while. The previous command will copy the content of the project directory into the “/src” directory inside the Docker container.
Fuzz testing has only been implemented for the Keeper-compatible smart contract example, but feel free to experiment with it and add more. The main focus of this test is to implement the fuzzing of block timestamps. The idea is that, no matter what, the
performUpkeep function can’t update the
counter state variable before the set interval of time.
To start fuzzing, run
echidna-test /src/contracts/test/fuzzing/KeepersCounterEchidnaTest.sol --contract KeepersCounterEchidnaTest --config /src/contracts/test/fuzzing/config.yaml
After a couple of minutes you will see the test results in the console. To exit Echidna, type
The final addition is, of course, the new version of Chainlink Verifiable Random Function! Chainlink VRF v2 includes several improvements to the way you fund and request randomness for your smart contracts. You’ll find a complete walkthrough of how to write VRF v2 compatible contracts, how to deploy them, how subscription management works, and how to properly test and use them.
To start, navigate to the VRF Subscription Page, select network, connect your wallet, and click “Create subscription”. Then save your “subscriptionId” as the
VRF_SUBSCRIPTION_ID environment variable. After deployment, head back to the VRF subscription page, navigate to your subscription, click the “Add consumer” button, and paste the address of the recently deployed VRF consumer contract. Once that’s done, you can perform a VRF request with the
yarn hardhat request-random-number --contract insert-contract-address-here --network network
Once you have successfully made a request for a random number, you can see the result via the
yarn hardhat read-random-number --contract insert-contract-address-here --network network
If you encounter an error, check on the VRF subscription page to see if the request has been fulfilled and try again.
Learn more about Chainlink by visiting chain.link or reading the documentation at docs.chain.link. To discuss an integration, reach out to an expert.