How Pencils Can Change Lives

I always thought Architecture was about design. I thought it was about aesthetics. Design a unique looking building. Of course, beauty was supplemented with brawn; some structures were marvelous…

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




The Ultimate Guide to Test Your Smart Contract

Testing is one of the most important — yet overlooked — aspect of the development of smart contract. Whenever you create a smart contract you have to make sure that it’s working properly and testing is the best way for using the contract in different situations without any risk. In this guide, you’ll learn the steps that you need to take to make sure your contracts are safe via testing.

Here’s all that you’ll know after finishing this tutorial:

Note that you should have at least a medium level of javascript to write tests however you should be able to understand most of what’s going on.

There are lots of different ways to test a smart contract and truffle is the most popular tool for writing tests in javascript that can be executed any time you make a change. This is great when working in a team because you can’t possibly know if a new feature is breaking some existing code.

To start, download truffle with the command:

Then you can go to your project folder from the terminal and execute the command:

Which will initialize the main files required for your project. Here’s a breakdown of the things that truffle has created for you:

Now that you know what each of those folders and files is doing, you have to

move your smart contracts to the contracts/ folder because they will be used when testing.

After doing that, you’re ready to start testing the smart contracts.

Let’s start right away with the testing. I’ve prepared a sample “notes” contract which contains some general functions that I want to test. Here’s the code of the contract I’ll be using so you can follow along:

It’s just a contract which allows you to store decentralized strings of notes for having a to-do list of things to complete in a day and for keeping yourself accountable.

As you can see, there are 2 functions only: addTodo() and markTodoAsCompleted() . In most of the projects you’ll have dozens of functions to test which is simply a longer version of this tutorial.

Now I’ve moved this file to the contracts/ folder of my project. Note that I’ve named the file as TodoList.sol which is the name of the contract inside the file. This is important for keeping things simple and organized.

After that, go to the test/ folder and create a file called todoList.js note that the first letter is lowercase and that it is a javascript file. The name must be the same as the contract name that you want to test.

In this testing file, you start by importing the contract and the library for checking the testing conditions, in my case I’m using assert but you can use should or expect from chai which is a testing framework. Write this in your testing file:

The TodoList variable it just converting the code from the smart contract to use it here. assert is the nodejs library that allows you to check the conditions for each one of your tests.

Now I usually create a variable called contractInstance like so:

Below the assert initialization. The contract instance variable will contain the instance of the contract that you will use later on.

Create now the contract container where you’ll test will live:

The name TodoList is just the name of the contract, you can use whatever text you want because that’s just for you to know what is executing at that moment.

Add the beforeEach block:

The beforeEach function will be executed before each test and inside it we are just deploying a new TodoList contract with the method deployed() .

Now you can add your tests.

Each test should verify that a function is working under certain conditions. In this contract I have a function called addTodo that simply adds a string note to the array of notes. So a good starting test would be something like this:

There’s a lot going on but it’s quite simple, here’s the breakdown:

Congratulation! You just wrote a test for your smart contract. Let’s add another one for the remaining function of the contract:

That test is checking if one of the existing notes is being successfully marked as completed by first adding a note and then executing the markTodoAsCompleted() function.

It’s time to execute those tests to see if they are working or not.

The way you execute the tests is by creating a test blockchain which is just an empty virtual Ethereum blockchain created in node.js where you can do whatever you want without real costs and immediately, without waiting for the miners to process the transaction.

To do that, you have to install the testrpc module which has been renamed to ganache-cli from npm:

Note that the before the change, the plugin was called ethereumjs-testrpc, you may have seen that name before.

After installing the module, execute that test blockchain with:

You’ll see that a test blockchain has been created on localhost:8545 . Now you need to change the configuration of your truffle.js file to let him know that you want to use that localhost:8545 network for the tests.

Open your truffle.js file and type this content:

Open a new terminal, go to your project folder and execute the following for starting the tests:

The --development flag it’s telling truffle to use the development network that we just created in the truffle.js configuration file.

It’s highly probable that you get warnings because of some errors in your smart contract. Simply fix those and execute the command again.

If you did everything correctly you’ll see that your tests are compiling. Some of them will pass, some won’t. Your goal is to create good tests that don’t pass to detect possible vulnerabilities. In my case all of them are passing:

Great. You now know how to write tests, how to execute them and how to fix them. Go ahead and read the final section where you’ll learn the most important aspect of testing. What, when and how to test all your functions.

Most of the contracts have the same range of possible vulnerabilities. Here I want to tell you what to look for when testing. Where most of the problems are located.

1.- Always check for overflows and underflows. If you are making any sort of mathematical calculation, you have to make sure that you code is not overflowing or underflowing. Those words just mean that you exceed the capacity of a uint type of variable and thus the value of that variable resets and goes to 0 again after trying to store a gigantic number.

For instance. Let’s say that you have a smart contract with a similar function to this one:

That function is at risk of an overflow. You can execeed the maximum value of a uint256 type of variable if you try to sum 2 numbers that are bigger than 2²⁵⁶.

In that case you could write a test like this one where you are testing if the sum is overflowing by checking the final value:

2.- Check that the return values of your functions are always within the range of the expected values. For instance if you have a function that is expected to return numbers bigger than 0, make a test where you are forcing a 0 return to see if it’s rejecting that situation or not. Which brings us to the next point…

3.- Always test the limits of the functions. If a function is returning a number, write a test where you execute it with the biggest possible number, another test with the smallest possible number and another with a random value in the middle. You never know how your functions will react in unexpected situations.

4.- Make sure that the return values are properly formated. If you have a function that is supposed to return an array of numbers, check if there’s any case where that array returns empty. This is important because it could break the functionality of your decentralized application.

5.- If you have functions with parameters like this one:

Make sure that the string and the uint256 parameters are rejecting invalid values. Write a test where the string is empty, write another where the string is a massive text of 10 thousand words, write a test where the uint is zero, where it’s negative, where it’s a gigantic number and so on.

You have to make sure that your contract is ready for all the possible values of the parameters of your functions to avoid security risks.

Congratulations! You now know how to properly test a smart contract. You’ve become a better developer which makes you more valuable. Give yourself a hug for being such a great person! For real.

Now if you have any questions, if your tests are not working or if you just want to share the love, make sure to leave a comment with your problem and me or any other user will help you get out.

Did you learn something useful? Do you think this article is worth your time? If so, clap it 50 times and share it with your fellow developers on linkedin, twitter and facebook, they will thank you for that.

Thanks for your time.

Add a comment

Related posts:

Foundations of Engineering Management

Foundations of Engineering Management, a Medium series by Jack Dempsey