Waffle & Mars
Using Waffle & Mars to Deploy to Phron
Introduction
Waffle is a library for compiling and testing smart contracts, and Mars is a deployment manager. Together, Waffle and Mars can be used to write, compile, test, and deploy Ethereum smart contracts. Since Phron is Ethereum compatible, Waffle and Mars can be used to deploy smart contracts to a Phron development node or the Phron TestNet.
Waffle uses minimal dependencies, has syntax that is easy to learn and extend, and provides fast execution times when compiling and testing smart contracts. Furthermore, it is TypeScript compatible and uses Chai matchers to make tests easy to read and write.
Mars provides a simple, TypeScript compatible framework for creating advanced deployment scripts and staying in sync with state changes. Mars focuses on infrastructure-as-code, allowing developers to specify how their smart contracts should be deployed and then using those specifications to automatically handle state changes and deployments.
In this guide, you'll be creating a TypeScript project to write, compile, and test a smart contract using Waffle, then deploy it on to the Phron TestNet using Mars.
Checking Prerequisites
You will need to have the following:
MetaMask installed and connected to Phron
An account with funds. You can get DEV tokens for testing on Phron once every 24 hours from the Phron Faucet
To test out the examples in this guide on Phron, you will need to have your own endpoint and API key, which you can get from one of the supported Endpoint Providers
Once you've created an account you'll need to export the private key to be used in this guide.
Create a TypeScript Project with Waffle & Mars
To get started, you'll create a TypeScript project and install and configure a few dependencies.
Create the project directory and change to it:
Initialize the project. Which will create a
package.json
in the directory:Install the following dependencies:
Waffle - for writing, compiling, and testing smart contracts
Mars - for deploying smart contracts to Phron
Ethers - for interacting with Phron's Ethereum API
OpenZeppelin Contracts - the contract you'll be creating will use OpenZeppelin's ERC-20 base implementation
TypeScript - the project will be a TypeScript project
TS Node - for executing the deployment script you'll create later in this guide
Chai - an assertion library used alongside Waffle for writing tests
@types/chai - contains the type definitions for chai
Mocha - a testing framework for writing tests alongside Waffle
@types/mocha - contains the type definitions for mocha
Create a TypeScript configuration file:
Add a basic TypeScript configuration:
Now, you should have a basic TypeScript project with the necessary dependencies to get started building with Waffle and Mars.
Add a Contract
For this guide, you will create an ERC-20 contract that mints a specified amount of tokens to the contract creator. It's based on the OpenZeppelin ERC-20 template.
Create a directory to store your contracts and a file for the smart contract:
Add the following contract to
MyToken.sol
:
In this contract, you are creating an ERC-20 token called MyToken with the symbol MYTOK, that allows you, as the contract creator, to mint as many MYTOKs as desired.
Use Waffle to Compile and Test
Compile with Waffle
Now that you have written a smart contract, the next step is to use Waffle to compile it. Before diving into compiling your contract, you will need to configure Waffle:
Go back to the root project directory and create a
waffle.json
file to configure Waffle:Edit the
waffle.json
to specify compiler configurations, the directory containing your contracts, and more. For this example, we'll usesolcjs
and the Solidity version you used for the contract, which is0.8.0
:Add a script to run Waffle in the
package.json
:
That is all you need to do to configure Waffle, now you're all set to compile the MyToken
contract using the build
script:
After compiling your contracts, Waffle stores the JSON output in the build
directory. Since the contract in this guide is based on OpenZeppelin's ERC-20 template, relevant ERC-20 JSON files will appear in the build
directory too.
Test with Waffle
Before deploying your contract and sending it off into the wild, you should test it first. Waffle provides an advanced testing framework and has plenty of tools to help you with testing.
You'll be running tests against the Phron TestNet and will need the corresponding RPC URL to connect to it: https://testnet.phron.ai
.
To configure your project for Phron, you will need to have your own endpoint and API key, which you can get from one of the supported Endpoint Providers.
Since you will be running tests against the TestNet, it might take a couple minutes to run all of the tests. If you want a more efficient testing experience, you can spin up a Phron development node using instant seal
. Running a local Phron development node with the instant seal
feature is similar to the quick and iterative experience you would get with Hardhat Network.
Create a directory to contain your tests and a file to test your
MyToken
contract:Open the
MyToken.test.ts
file and setup your test file to use Waffle's Solidity plugin and use Ethers custom JSON-RPC provider to connect to Phron:Before each test is run, you'll want to create wallets and connect them to the provider, use the wallets to deploy an instance of the
MyToken
contract, and then call theinitialize
function once with an initial supply of 10 tokens:Now you can create your first test. The first test will check your initial balance to ensure you received the initial supply of 10 tokens. However, to follow good testing practices, write a failing test first:
Before you can run your first test, you'll need to go back to the root direction and add a
.mocharc.json
Mocha configuration file:Now edit the
.mocharc.json
file to configure Mocha:You'll also need to add a script in the
package.json
to run your tests:You're all set to run the tests, simply use the
test
script you just created and run:Please note that it could take a few minutes to process because the tests are running against Phron, but if all worked as expected, you should have one failing test.
Next, you can go back and edit the test to check for 10 tokens:
If you run the tests again, you should now see one passing test:
You've tested the ability to mint tokens, next you'll test the ability to transfer the minted tokens. If you want to write a failing test first again that is up to, however the final test should look like this:
Congratulations, you should now have two passing tests! Altogether, your test file should look like this:
If you want to write more tests on your own, you could consider testing transfers from accounts without any funds or transfers from accounts without enough funds.
Use Mars to Deploy to Phron
After you compile your contracts and before deployment, you will have to generate contract artifacts for Mars. Mars uses the contract artifacts for typechecks in deployments. Then you'll need to create a deployment script and deploy the MyToken
smart contract.
Remember, you will be deploying to Phron and will need to use the TestNet RPC URL:
To configure your project for Phron, you will need to have your own endpoint and API key, which you can get from one of the supported Endpoint Providers.
The deployment will be broken up into three sections: generate artifacts, create a deployment script, and deploy with Mars.
Generate Artifacts
Artifacts need to be generated for Mars so that typechecks are enabled within deployment scripts.
Update existing script to run Waffle in the
package.json
to include Mars:Generate the artifacts and create the
artifacts.ts
file needed for deployments:
If you open the build
directory, you should now see an artifacts.ts
file containing the artifact data needed for deployments. To continue on with the deployment process, you'll need to write a deployment script. The deployment script will be used to tell Mars which contract to deploy, to what network, and which account is to be used to trigger the deployment.
Create a Deployment Script
Now you need to configure the deployment for the MyToken
contract to the Phron TestNet.
In this step, you'll create the deployment script which will define how the contract should be deployed. Mars offers a deploy
function that you can pass options to such as the private key of the account to deploy the contract, the network to deploy to, and more. Inside of the deploy
function is where the contracts to be deployed are defined. Mars has a contract
function that accepts the name
, artifact
, and constructorArgs
. This function will be used to deploy the MyToken
contract with an initial supply of 10 MYTOKs.
Create a
src
directory to contain your deployment scripts and create the script to deploy theMyToken
contract:In
deploy.ts
, use Mars'deploy
function to create a script to deploy to Phron using your account's private key:Set up the
deploy
function to deploy theMyToken
contract created in the previous steps:Add a deploy script to the
scripts
object in thepackage.json
:
So far, you should have created a deployment script in deploy.ts
that will deploy the MyToken
contract to Phron, and added the ability to easily call the script and deploy the contract.
Deploy with Mars
You've configured the deployment, now it's time to actually deploy to Phron.
Deploy the contract using the script you just created:
In your Terminal, Mars will prompt you to press
ENTER
to send your transaction
If successful, you should see details about your transaction including it's hash, the block it was included in, and it's address.
Congratulations! You've deployed a contract to Phron using Waffle and Mars!
Example Project
If you want to see a completed example of a Waffle and Mars project on Phron, check out the phron-waffle-mars-example created by the team behind Waffle and Mars, EthWorks.
This tutorial is for educational purposes only. As such, any contracts or code created in this tutorial should not be used in production.The information presented herein has been provided by third parties and is made available solely for general information purposes. Phron does not endorse any project listed and described on the Phron Doc Website (https://docs.Phron.ai/). Phron does not warrant the accuracy, completeness or usefulness of this information. Any reliance you place on such information is strictly at your own risk. Phron disclaims all liability and responsibility arising from any reliance placed on this information by you or by anyone who may be informed of any of its contents. All statements and/or opinions expressed in these materials are solely the responsibility of the person or entity providing those materials and do not necessarily represent the opinion of Phron. The information should not be construed as professional or financial advice of any kind. Advice from a suitably qualified professional should always be sought in relation to any particular matter or circumstance. The information herein may link to or integrate with other websites operated or content provided by third parties, and such other websites may link to this website. Phron has no control over any such other websites or their content and will have no liability arising out of or related to such websites or their content. The existence of any such link does not constitute an endorsement of such websites, the content of the websites, or the operators of the websites. These links are being provided to you only as a convenience and you release and hold Phron harmless from any and all liability arising from your use of this information or the information provided by any third-party website or service.
Last updated