Testing Smart Contracts with Ownable Inheritance in Typescript & Hardhat
Testing with ethers.js & Waffle & Typescript & Hardhat
Today, I will show you some testing examples of smart contracts with ownable inheritance from openzeppelin using Typescript and Hardhat. If you are new to hardhat, this tutorial might help!
A Simple Smart Contract
This is a simple smart contract with ownable inheritance from openzeppelin.
Contracts need the receive function (line 19~ 21) in order to receive ether.
If neither a receive Ether nor a payable fallback function is present, the contract cannot receive Ether through regular transactions and throws an exception.
The noReentrant modifier prevent the contract from a known re-entrancy attack. For more info, you can refer to this tutorial.
Let’s Test the Contact!
The example test for above contract is as follows:
Typechain
As I explained in the previous story, you can add typescript bindings for your smart contracts with typechain. This is pretty useful and all you have to do is to install the dependencies and import @typechain/hardhat at hardhat.config.ts. Then when you compile contracts, it will automatically create typescript bindings in typechain folder in the root directory.
ethers.js
You don’t have to import ethers.js because you can get it from hardhat runtime environment (line 3). This is something I like about hardhat😊
Also, if you want to send 1 ether, you do like this.
const transactionHash = await owner.sendTransaction({
to: base.address,
value: ethers.utils.parseEther("1.0"), // Sends exactly 1.0 ether
});
About sendTransaction (ethers.js)
Please make sure you always use BigNumber(data type) to specify the amount of ether in Typescript. Without this, it would return errors because of overflow.
const transactionHash = await owner.sendTransaction({
to: base.address,
value: 1.0 * 10**18, // Don't do this.
});
Sending Transactions from different accounts
Here is how you can call functions from different accounts. The withdraw function has onlyOwner modifier, so when addr1(non-owner) call this function, the transaction will fail.
await expect(base.connect(addr1).withdraw(owner.address, ethers.utils.parseEther("1.0")))
.to.be.reverted;
For more: hardhat tutorial
Hope this helps. Thank you for reading 😁