Awesome
Solidity Template
This is a modern Solidity template for Ethereum smart contracts. It combines two extremely powerful frameworks:
- Foundry - for Unit tests written in Solidity (contracts/test/).
- Hardhat - for Integration tests written in Typescript (integration/).
This template optimizes and cleans up using these frameworks together (e.g. no remappings.txt
or /lib
submodules, using one foundry.toml as a source of truth for options). Dependencies are all managed through NPM.
Utilizing both frameworks allows you to comprehensively test every scenario, which should always be the case when planning to deploy immutable code. Both layers of testing also gives other developers a reference for how they should interact with your contracts:
-
On-chain developers writing contracts that call these contracts can refer to your Unit Test files to see the expected usage in Solidity.
-
Off-chain developers writing clients that call these contracts can refer to your Integration Test files to see the expected usage in JavaScript (TypeScript) and Ethers.js.
These frameworks also offer some advanced tools for contract debugging, deployment, gas measurements, etc.
Other features of this template are linting rules for Solidity and TypeScript, a developer guide for new contributors to your project, a LICENSE sample which can be changed, a sample CLI for contract deployment and interactions, documentation generation from NatSpec comments, and useful GitHub Actions already configured.
Template Usage
Go to the top right of this repository and click the big green "Use this template" button:
Alternatively, you can set this template up through Foundry:
forge init --template https://github.com/mattstam/solidity-template <project-name>
This will create a copy of this repository for your project. A sample contract already exists, Counter.sol, with its interface ICounter.sol, Unit Test file Counter.t.sol, and Integration Test file counter.test.ts.
Use this as the foundation for how to write and test your contracts. Replace these with the contracts you want to build.
GitHub Actions & Workflow Badges
This repository comes with GitHub Actions already configured. You can find them in the ./github/workflows directory. These will run the Unit Tests, Integration Tests, Lint Check, etc, during Pull Requests and merges to the master branch.
All that is required to get theses setup is to include your MNEMONIC
environmental variable in the settings. In your GitHub repository, go to the Settings
tab > Security
/Secrets
/Actions
> click the big green "New repository secret" button:
The Name should be MNEMONIC
and the Secret should be your BIP-39 compatible phrase. Afterward you should see:
If you would like to also get badges for your workflows shown on this README, just uncomment out the lines at the top of this README:
Cleanup
To make this specific to your project, just Find And Replace all the mentions of mattstam/solidity-template
, solidity-template
, and Solidity Template
with the name of your project name.
Clear out everything in the media directory, as these images were just use in this README. Use this directory for your own project content instead.
Lastly, delete this Template Usage block in this README. You probably want to keep everything else, but customize it to your needs.
Developer Guide
Directory Structure
integration/
|- counter.test.ts - "Integration tests with Hardhat"
scripts/
|- console.ts - "CLI for contracts"
|- deploy.ts - "Contract deployment functions"
contracts/
|- interfaces/
|--- ICounter.sol - "Interface contract"
|- test/
|--- Counter.t.sol - "Unit tests with Foundry"
|- Counter.sol - "Implementation contract"`
.env - "Real environment vars"
.env.example - "Example environment vars"
.eslintignore - "Ignore list for eslint"
.eslintrc - "Configure eslint"
.gitignore - "Ignore list for Git"
.solcover.js - "Configure coverage"
.solhint.json - "Configure Solidity linter"
.prettierignore - "Ignore list for Prettier"
.prettierrc.json - "Configure Prettier"
foundry.toml - "Configure Foundry"
hardhat.config.ts - "Configure Hardhat"
LICENSE - "Software license"
package.json - "Node dependencies"
slither.config.json - "Configure Slither"
tsconfig.json - "Configure Typescript"
--- (not an extensive list of all files) ---
Clone the repository
git clone https://github.com/mattstam/solidity-template.git && cd solidity-template
Install Node.js / NPM
npm install -g npm
Copy over a new .env
file
cp .env.example .env
Fill in at least your MNEMONIC
Install Node dependencies
npm i
Install Foundry
curl -L https://foundry.paradigm.xyz | bash
Then, in a new terminal session or after reloading your PATH
, run this to get
the latest forge
and cast
binaries:
foundryup
Do Things
Run the unit tests with Forge
forge test
This will run everything in contracts/test/, which utilizes Forge to test contract code.
Run the integration tests with Hardhat
npm run test
This will run everything in integration/, which utilizes Hardhat to tests for full usage scenarios.
Deploy to Goerli test network
Create a .env file matching the variables seen in .env.example.
Getting fully prepared may involve getting a INFURA_API_KEY
by signing up, and getting some test ETH on your target network via a facet.
Then run:
npm run deploy -- --network goerli
This will automatically update deployments.json, which gets exported with your NPM package. It will also become the default address to use when interacting with your contracts with the CLI.
Generate documentation
npm run doc
Sets up API docs from the NatSpec comments in your contract interfaces (ignoring implementations and libraries).
If desired, this can be updated to included all contract comments, and the path can be updated to a different location (such as if you want a seperate docs
repository for your project).
Foundry & Hardhat Info
Foundry
Foundry is a blazing fast, portable, and modular toolkit for Ethereum application development. It consists of:
- Forge: Framework for Unit / Fuzz testing written in Solidity.
- Cast: EVM interactions for contracts, transaction handling, and reading on-chain data.
- Anvil: A local testnet node with network forking capabilities.
Configuration details can be found in foundry.toml.
Hardhat
Hardhat is a complete Ethereum development environment. The integration tests run on the Hardhat network, with each test written in JavaScript (TypeScript), utilizing the Ethers.js library, and the Mocha testing framework.
Hardhat can also be extended (see the full plugin list). This project makes use of:
- Hardhat Waffle - test assertions with Chai matchers.
- Hardhat Ethers - integration with Ethers.js.
- Hardhat Solhint - integration with the Solidity language Solhint linter.
- Hardhat Gas Reporter - gas cost summary of contract calls.
- Hardhat Tracer - contract name tag for logs and advanced debugging.
- Hardhat Contract Sizer - show output size of contracts.
- Hardhat Etherscan - verify contract source code on Etherscan.
- Hardhat Dodoc - documentation generation from NatSpec.
Configuration details can be found in hardhat.config.ts, which inherits from foundry.toml.
Recommended VSCode Extensions
- Solidity Visual Developer
- Solidity Language & Themes (only)
- Solidity (by Hardhat authors)
- Solidity (by Juan Blanco)
- Prettier
Deployments
All contract addresses for each network are stored in deployments.json.
License
The code in this project is licensed under the MIT License.