Getting Data from another contract or running a function from another contract was something that took me some time to find information on originally. In this article I will walk you through what I think is the cleanest way to do this. I will also show you how to write very clean tests to explore these smart contracts.

If you get lost or simply don’t care to read all of this and want to just play with the code, you can find the complete repo along with tests here. Otherwise simply follow along.

Prerequisites:

Truffle installed (have the latest yarn global upgrade truffle ) Basic Experience with Smart Contracts Basic Experience with Truffle

Setup the Project

Let’s get the project setup. Open up your terminal and navigate to your working directory then run:

mkdir interactions

cd interactions

truffle init

We have just created a folder named interactions , moved into it, and initialized our project with some basic truffle files.

Creating the Initial Contracts

Open up the project and create the following two files in /contracts :

ExampleContract.sol

and

ExampleUser.sol

ExampleContract

Open up ExampleContract.sol and put in the following code:

This is just a simple contract for starters… we are just going to set a number and get that number from another contract.

ExampleUser

In ExampleUser.sol , add the following code:

So what have we done here in this contract? We have two contracts here. The first one, ExampleContractInterface is a more limited definition of the contract that we want to interact with. We do not need the full contract here! Our UserContract only needs to know about the parts that it will use.

Another thing to note here… Make sure that you use a unique name for this contract definition. If you name the contract interface in ExampleUser ExampleContract , it will be combined together with the actual contract we have created. This happens because of the way truffle is handling builds. MAKE SURE TO HAVE DIFFERENT NAMES!

The second contract is the main contract which will be using the definition at the top. We set a global variable in the contract named exampleContract with a type of ExampleContractInterface this is the definition of the contract we gave at the top. We then set the contract address in the constructor. We can now use this contract in any other functions we want.

Lastly, we create an addNumbers function which will use the other contract’s function and set the returned value on the UserContract .

Compile the Contracts

Before moving on make sure that your contracts compile by running:

truffle compile

You will probably get some warnings similar to this:

/Users/tovarishfin/dev/my-tutorials/interactions/contracts/ExampleUser.sol:5:23: Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.

function addNumbers(uint256 _number)

^-------------^

,/Users/tovarishfin/dev/my-tutorials/interactions/contracts/ExampleUser.sol:5:3: Warning: Function state mutability can be restricted to pure

function addNumbers(uint256 _number)

^ (Relevant source part starts here and spans across multiple lines).

This is fine! Truffle is treating this as a real contract when all we want is a limited definition that will allow us to run these functions.

Smart contracts are all about tests. Lets write some to see this contract in action!

Setup Tests

Create two new files in the test directory:

ExampleContract

and

ExampleUser

We will also need the Big Number library. Init yarn and add the package using yarn:

yarn init -y

yarn add bignumber.js@"4.1.0"

fun fact: older versions of web3 need this older version of bignumber.js Make sure to use this older version.

ExampleContract Tests

Put the following code as a starting point for your tests:

We are simply testing the two functions that we have in ExampleContract

run truffle test and you should see the following:

when using our beautiful example contract

Contract: ExampleContract

✓ should setNumber (67ms)

✓ should addNumbers 2 passing (156ms)

Hooray beautiful green checkmarks!

ExampleUser Tests

Use the following code to test what we have in ExampleUser :

In the above file we have setup a test which will instantiate both the ExampleContract and ExampleUser contracts before running the tests. This happens on lines 12–16. You can see that we are first creating an instance of ExampleContract named ec . We are then using this instance’s address to create a new instance of ExampleUser where we are giving it the ExampleContract address as a construction parameter. We are also setting a number for ExampleContract to use when running addNumbers .

Our single test (lines 18–35) calls the addNumbers function of ExampleUser and then test that this is the expected number by getting addedNumbers from ExampleUser .

Run truffle test again and you should now see more beautiful green checkmarks:

when using our beautiful example contract

Contract: ExampleContract

✓ should setNumber (62ms)

✓ should addNumbers when using our beautiful example user with example contract

Contract: ExampleContract/ExampleUser

✓ should addNumbers using ExampleContract (60ms) 3 passing (346ms)

hooray!

Gotchas

There are some issues that you will inevitably run into when trying to get certain types of data from other contracts. I will try to create another tutorial to address these… for now, know that one of the biggest ones is that you cannot send a string from one contract to another.

In my next tutorial, I will show you how access the following from one contract to another: