Waffle: Deploy a Smart Contract with Waffle That’s Stored on IPFS
Learn how to deploy a smart contract with Waffle that's stored on IPFS.
Waffle is is a library comparable to Truffle that is used to write and test smart contracts. Waffle is compatible for use with ethers-js.
Read below to deploy a smart contract with Waffle that's stored on IPFS.
To do this, navigate to console.filebase.com. If you don’t have an account already, sign up, then log in.
Select ‘Create Bucket’ in the top right corner to create a new bucket.

Bucket names must be unique across all Filebase users, be between 3 and 63 characters long, and can contain only lowercase characters, numbers, and dashes.

Set up a credentials file for S3FS at
${HOME}/.passwd-s3fs
. You will need to save your Filebase Access and Secret keys to this file and give it owner permissions. You can do so with the following commands:echo ACCESS_KEY_ID:SECRET_ACCESS_KEY > ${HOME}/.passwd-s3fs
chmod 600 ${HOME}/.passwd-s3fs
ACCESS_KEY_ID is your Filebase Access key, and SECRET_ACCESS_KEY is your Filebase Secret key. For more information on Filebase access keys, see here.
You can mount a Filebase IPFS bucket with the command:
s3fs mybucket /path/to/mountpoint -o passwd_file=${HOME}/.passwd-s3fs -o url=https://s3.filebase.com
- mybucket: name of your Filebase bucket
- /path/to/mountpoint
cd /path/to/mounted/bucket
mkdir waffle-tutorial
cd waffle-tutorial
npm install --save-dev ethereum-waffle
npm install @openzeppelin/[email protected]^4.6.0 -D
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
// Example class - a mock class using delivering from ERC20
contract BasicToken is ERC20 {
constructor(uint256 initialBalance) ERC20("Basic", "BSC") {
_mint(msg.sender, initialBalance);
}
}
{
"scripts": {
"build": "waffle"
}
}
{
"compilerType": "solcjs",
"compilerVersion": "0.8.13",
"sourceDirectory": "./src",
"outputDirectory": "./build"
}
mkdir build
mkdir contracts
npm run build
npm install --save-dev mocha chai
import {expect, use} from 'chai';
import {Contract} from 'ethers';
import {deployContract, MockProvider, solidity} from 'ethereum-waffle';
import BasicToken from '../build/BasicToken.json';
use(solidity);
describe('BasicToken', () => {
const [wallet, walletTo] = new MockProvider().getWallets();
let token: Contract;
beforeEach(async () => {
token = await deployContract(wallet, BasicToken, [1000]);
});
it('Assigns initial balance', async () => {
expect(await token.balanceOf(wallet.address)).to.equal(1000);
});
it('Transfer adds amount to destination account', async () => {
await token.transfer(walletTo.address, 7);
expect(await token.balanceOf(walletTo.address)).to.equal(7);
});
it('Transfer emits event', async () => {
await expect(token.transfer(walletTo.address, 7))
.to.emit(token, 'Transfer')
.withArgs(wallet.address, walletTo.address, 7);
});
it('Can not transfer above the amount', async () => {
await expect(token.transfer(walletTo.address, 1007)).to.be.reverted;
});
it('Can not transfer from empty account', async () => {
const tokenFromOtherWallet = token.connect(walletTo);
await expect(tokenFromOtherWallet.transfer(wallet.address, 1))
.to.be.reverted;
});
it('Calls totalSupply on BasicToken contract', async () => {
await token.totalSupply();
expect('totalSupply').to.be.calledOnContract(token);
});
it('Calls balanceOf with sender address on BasicToken contract', async () => {
await token.balanceOf(wallet.address);
expect('balanceOf').to.be.calledOnContractWith(token, [wallet.address]);
});
});
{
"scripts": {
"build": "waffle",
"test": "NODE_ENV=test mocha",
}
}
{
"spec": "test/**/*.test.{js,ts}"
}
npm test
This test should return the following output:
BasicToken
✓ Assigns initial balance (84ms)
✓ Transfer adds amount to destination account (404ms)
✓ Transfer emits event (219ms)
✓ Can not transfer above the amount (32ms)
✓ Can not transfer from empty account (95ms)
✓ Calls totalSupply on BasicToken contract (67ms)
✓ Calls balanceOf with sender address on BasicToken contract (75ms)
7 passing (8s)
If you have any questions, please join our Discord server, or send us an email at [email protected]
Last modified 8mo ago