Build systems are the heart of every engineering team and become even more crucial when dealing with microservices and all the dependencies that come with them. When I joined Circle, my first task focused on improving our build systems for microservices connecting to EVM-compatible blockchains. We already had a fairly mature build system but felt we could get more out of it. To set consistent standards for us internally at Circle and simplify our Web3 development process, we created Contract-CLI – a configurable build tool for smart contracts.
Today, we are open-sourcing it. We also want to share our story about how Contract-CLI has helped us scale our blockchain engineering team from 3 to 40+ people, while delivering high-quality smart contracts that developers can trust and build upon.
Smart contract development was always hard
Before we had the right systems in place, our smart contract development process was rather inconsistent. Someone would write the contracts, then someone else would copy and compile them in the solidity terminal running on their local machine. We’d copy the output bytecode from the terminal into a file that we could check into source control.
Although this worked in the beginning, there are a lot of challenges with this system:
- Running the solidity terminal locally exposed us to lots of different versions which in turn led to instability.
- Dependencies weren’t strictly managed.
- It was impossible to audit what we compiled to review that it was correct and error-free.
- There was no natural place for automated testing as we couldn’t guarantee our local environments had the same configuration.
So, we built Contract-CLI to address these problems. Our first principles were 1) easy, 2) repeatable, 3) consistent, and 4) flexible.
Advantages of building with Contract-CLI
Contract-CLI makes smart contract development, testing, and deployment easier and more consistent by automating key stages of the build process.
With Contract-CLI, you can configure a series of “build steps” to be executed against your smart contracts. Underlying each step is a shell script defining how to install and execute the step. You can choose to leverage default steps we’ve included based on popular smart contract tools, or create custom steps which match your use case exactly.
Once you’ve specified the steps, they are executed serially inside a Docker container. This ensures the smart contract environment is the same every time, whether on a developer machine or inside your build system.
Prerequisites and installation
If you want to use Contract-CLI, the only prerequisites are Docker Engine (> 20.10.8) and NodeJS (> 16.16.0).
You can install Contract-CLI from npm as `npm i -g @circle-fin/contract-cli`
How to get started
If you’re ready to dive in right now, check out our Quick Usage documentation in GitHub, or keep reading for a walkthrough of how to get started.
To initialize Contract-CLI in your smart contract project, navigate to the root directory of your smart contracts using the terminal and run `contract-cli init`
This will initialize Contract-CLI with the default steps.
Alternatively, if you know exactly which steps you want, you can specify them in your command. For example, `contract-cli init --steps ganache --steps truffle`
This will initialize Contract-CLI with the steps you specified. You’ll find that a few new folders and files have been created.
│ ├── package.json
│ ├── install.sh
│ └── execute.sh
│ ├── package.json
│ ├── truffle-config.js
│ ├── install.sh
│ └── execute.sh
In particular, you’ll find a new config.json in your root directory. This specifies the overall function of Contract-CLI. You can use it to identify your contract and test locations and specify the different steps that will be executed.
For each step, there’s a directory created. Inside the directory are the shell scripts which will install and execute the step. These can easily be customized to fit your needs.
When you’re ready to see Contract-CLI in action, simply run `contract-cli execute`
This will start up your container and run the steps in order. The output will be piped to the terminal, and any files created are shared back to your local system.
From there, you’ve got the basics down. You can add more steps and customizations to improve your process further. I would also suggest committing your configuration and step directories to your source control so that others can pull them with your project. Then, if they want to build the contracts, they don’t even need to initialize Contract-CLI. Once it's installed, they can jump right to executing and get the same results as you.
Open-source and extensible
So far, we’ve focused on EVM-compatible tooling for Contract-CLI. Consider using Contract-CLI to level up your smart contract management on Ethereum, Avalanche, Polygon and more and give you confidence that what you’re deploying is 100% consistent, fully tested, and ready to go. With that said, Contract-CLI is highly configurable and can easily be extended to support non-EVM smart contract development as well.
If you’re wondering why we’re releasing this to the world now, we’ve been leveraging this tool internally for a while, and it's been incredibly helpful for developer productivity and smart contract quality. Over the summer, we open-sourced this tool to the Web3 developer community. We’re really excited to share this with you and hope it brings new and exciting smart contracts to the ecosystem and improves the quality of existing contracts.
Contract-CLI is free for anyone to use and build upon. We’re striving to help the next million developers start building on the blockchain. If you’re just starting out, Circle has a multitude of Web3 services that you can tap into. For example, if you're looking to manage smart contracts via API with more security, you might be interested in Circle's Programmable Wallets infrastructure to help you automate smart contracts with granular control.
Build with us!
If Contract-CLI or any other Circle offerings sound helpful and interesting, we’d love to hear from you. Find us on Discord and share what you’re building!