- Chainlink Hardhat Starter Kit
- Getting Started
- Usage
- Test
- Interacting with Deployed Contracts
- View Contracts Size
- Linting
- Code Formating
- Estimaging Gas
- Code Coverage
- Fuzzing
- Contributing
- Thank You!
Implementation of the following 4 Chainlink features using the Hardhat development environment:
It's recommended that you've gone through the hardhat getting started documentation before proceeding here.
- git
- You'll know you did it right if you can run
git --version
and you see a response likegit version x.x.x
- You'll know you did it right if you can run
- Nodejs
- You'll know you've installed nodejs right if you can run:
node --version
and get an ouput like:vx.x.x
- You'll know you've installed nodejs right if you can run:
- Yarn instead of
npm
- You'll know you've installed yarn right if you can run:
yarn --version
And get an output like:x.x.x
- You might need to install it with npm
- You'll know you've installed yarn right if you can run:
If you're familiar with
npx
andnpm
instead ofyarn
, you can usenpx
for execution andnpm
for installing dependencies.
- Clone and install dependencies
After installing all the requirements, run the following:
git clone https://github.com/smartcontractkit/hardhat-starter-kit/
cd hardhat-starter-kit
git checkout typescript
Then:
yarn
or
npm i
- You can now do stuff!
yarn hardhat test
or
yarn hardhat test
If you run yarn hardhat --help
you'll get an output of all the tasks you can run.
yarn hardhat deploy
This will deploy your contracts to a local network. Additionally, if on a local network, it will deploy mock Chainlink contracts for you to interact with. If you'd like to interact with your deployed contracts, skip down to Interacting with Deployed Contracts.
One of the best ways to test and interact with smart contracts is with a local network. To run a local network with all your contracts in it, run the following:
yarn hardhat node
You'll get a local blockchain, private keys, contracts deployed (from the deploy
folder scripts), and an endpoint to potentially add to an EVM wallet.
In your hardhat.config.ts
you'll see section like:
const config: HardhatUserConfig = {
defaultNetwork: "hardhat",
networks: {
This section of the file is where you define which networks you want to interact with. You can read more about that whole file in the hardhat documentation.
To interact with a live or test network, you'll need:
- An rpc URL
- A Private Key
- ETH & LINK token (either testnet or real)
Let's look at an example of setting these up using the Goerli testnet.
First, we will need to set environment variables. We can do so by setting them in our .env
file (create it if it's not there). You can also read more about environment variables from the linked twilio blog. You'll find a sample of what this file will look like in .env.example
IMPORTANT: MAKE SURE YOU'D DONT EXPOSE THE KEYS YOU PUT IN THIS
.env
FILE. By that, I mean don't push them to a public repo, and please try to keep them keys you use in development not associated with any real funds.
- Set your
GOERLI_RPC_URL
environment variable.
You can get one for free from Alchmey, Infura, or Moralis. This is your connection to the blockchain.
- Set your
PRIVATE_KEY
environment variable.
This is your private key from your wallet, ie MetaMask. This is needed for deploying contracts to public networks. You can optionally set your MNEMONIC
environment variable instead with some changes to the hardhat.config.ts
.
When developing, it's best practice to use a Metamask that isn't associated with any real money. A good way to do this is to make a new browser profile (on Chrome, Brave, Firefox, etc) and install Metamask on that brower, and never send this wallet money.
Don't commit and push any changes to .env files that may contain sensitive information, such as a private key! If this information reaches a public GitHub repository, someone can use it to check if you have any Mainnet funds in that wallet address, and steal them!
.env
example:
GOERLI_RPC_URL='www.infura.io/asdfadsfafdadf'
PRIVATE_KEY='abcdef'
bash
example
export GOERLI_RPC_URL='www.infura.io/asdfadsfafdadf'
export PRIVATE_KEY='abcdef'
You can also use a
MNEMONIC
instead of aPRIVATE_KEY
environment variable by uncommenting the section in thehardhat.config.ts
, and commenting out thePRIVATE_KEY
line. However this is not recommended.
For other networks like mainnet and polygon, you can use different environment variables for your RPC URL and your private key. See the hardhat.config.ts
to learn more.
- Get some Goerli Testnet ETH and LINK
Head over to the Chainlink faucets and get some ETH and LINK. Please follow the chainlink documentation if unfamiliar.
- Create VRF V2 subscription
Head over to VRF Subscription Page and create the new subscription. Save your subscription ID and put it in .env
file as VRF_SUBSCRIPTION_ID
- Running commands
You should now be all setup! You can run any command and just pass the --network goerli
now!
To deploy contracts:
yarn hardhat deploy --network goerli
To run staging testnet tests
yarn hardhat test --network goerli
If you'd like to run tests or on a network that is a forked network
- Set a
MAINNET_RPC_URL
environment variable that connects to the mainnet. - Choose a block number to select a state of the network you are forking and set it as
FORKING_BLOCK_NUMBER
environment variable. If ignored, it will use the latest block each time which can lead to test inconsistency. - Set
enabled
flag totrue
/false
to enable/disable forking feature
forking: {
url: MAINNET_RPC_URL,
blockNumber: FORKING_BLOCK_NUMBER,
enabled: false,
}
This Starter Kit is configured by default to attempt to auto-fund any newly deployed contract that uses Any-API, to save having to manually fund them after each deployment. The amount in LINK to send as part of this process can be modified in the Starter Kit Config, and are configurable per network.
Parameter | Description | Default Value |
---|---|---|
fundAmount | Amount of LINK to transfer when funding contracts | 0.1 LINK |
If you wish to deploy the smart contracts without performing the auto-funding, add an AUTO_FUND
environment variable, and set it to false.
Tests are located in the test directory, and are split between unit tests and staging/testnet tests. Unit tests should only be run on local environments, and staging tests should only run on live environments.
To run unit tests:
yarn test
or
yarn hardhat test
To run integration tests:
yarn test-integration
or
yarn hardhat test --network goerli
Since all tests are written in a way to be independent from each other, you can save time by running them in parallel. Make sure that AUTO_FUND=false
inside .env
file. There are some limitations with parallel testing, read more about them here
To run tests in parallel:
yarn test --parallel
or
yarn hardhat test --parallel
or
yarn hardhat test
You can make Hardhat run faster 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:
TS_NODE_TRANSPILE_ONLY=1 yarn test
After deploying your contracts, the deployment output will give you the contract addresses as they are deployed. You can then use these contract addresses in conjunction with Hardhat tasks to perform operations on each contract.
The Price Feeds consumer contract has one task, to read the latest price of a specified price feed contract
yarn hardhat read-price-feed --contract insert-contract-address-here --network network
The APIConsumer contract has two tasks, one to request external data based on a set of parameters, and one to check to see what the result of the data request is. This contract needs to be funded with link first:
yarn hardhat fund-link --contract insert-contract-address-here --network network
Once it's funded, you can request external data by passing in a number of parameters to the request-data task. The contract parameter is mandatory, the rest are optional
yarn hardhat request-data --contract insert-contract-address-here --network network
Once you have successfully made a request for external data, you can see the result via the read-data task
yarn hardhat read-data --contract insert-contract-address-here --network network
The VRFConsumer contract has two tasks, one to request a random number, and one to read the result of the random number request. To start, go to VRF Subscription Page and create the new subscription. Save your subscription ID and put it in .env
file as VRF_SUBSCRIPTION_ID
:
VRF_SUBSCRIPTION_ID=subscription_id
Then, deploy your VRF V2 contract consumer to the network of your recent subscription using subscription id as constructor argument.
yarn hardhat deploy --network network
Finally, you need to go to your subscription page one more time and add the address of deployed contract as a new consumer. Once that's done, you can perform a VRF request with the request-random-number task:
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 read-random-number task:
yarn hardhat read-random-number --contract insert-contract-address-here --network network
The KeepersCounter contract is a simple Chainlink Keepers enabled contract that simply maintains a counter variable that gets incremented each time the performUpkeep task is performed by a Chainlink Keeper. Once the contract is deployed, you should head to https://keepers.chain.link/ to register it for upkeeps, then you can use the task below to view the counter variable that gets incremeneted by Chainlink Keepers
yarn hardhat read-keepers-counter --contract insert-contract-address-here --network network
You'll need an ETHERSCAN_API_KEY
environment variable. You can get one from the Etherscan API site.. If you have it set, your deploy script will try to verify them by default, but if you want to verify any manually, you can run: . If you have it set, your deploy script will try to verify them by default, but if you want to verify any manually, you can run:
yarn hardhat verify --network <NETWORK> <CONTRACT_ADDRESS> <CONSTRUCTOR_PARAMETERS>
example:
yarn hardhat verify --network goerli 0x9279791897f112a41FfDa267ff7DbBC46b96c296 "0x9326BFA02ADD2366b30bacB125260Af641031331"
yarn run hardhat size-contracts
This will lint your smart contracts.
yarn lint:fix
This will format both your typescript and solidity to look nicer.
yarn format
To estimate gas, just set a REPORT_GAS
environment variable to true, and then run:
yarn hardhat test
If you'd like to see the gas prices in USD or other currency, add a COINMARKETCAP_API_KEY
from Coinmarketcap.
To see a measure in percent of the degree to which the smart contract source code is executed when a particular test suite is run, type
yarn coverage
We are going to use Echidna as a Fuzz testing tool. You need to have Docker installed with at least 8GB virtual memory allocated (To update this parameter go to Settings->Resources->Advanced->Memory).
To start Echidna instance run
yarn fuzzing
If you are using it for the first time, you will need to wait for Docker to download eth-security-toolbox image for us.
To start Fuzzing run
echidna-test /src/contracts/test/fuzzing/KeepersCounterEchidnaTest.sol --contract KeepersCounterEchidnaTest --config /src/contracts/test/fuzzing/config.yaml
To exit Echidna type
exit
Contributions are always welcome! Open a PR or an issue!