Last modified: Mon Nov 04 2019 16:15:12 GMT+0000 (Coordinated Universal Time)
How to call a smart contract
There are multiple ways to call methods or send transactions to the Ethereum network. This tutorial will cover two basic approaches - from a browser using Metamask extension and using a Truffle console.
A bit of theory
The Ethereum network consists of independent servers called nodes
. You interact with
the network by interacting with one of the nodes. Put simply, you need to
- call a function to read data
- send a transaction to write data. To ensure the transaction gets mined, you need to pay using gas.
That means if you want to change data some ETH is needed to pay for gas. Luckily, on testnets you can get free ETHs from a faucet
Besides paying for a transaction, you need to know two things about the contract you are interacting with:
- the address
- the interface
The interface is very simple, it only consists of the method's name and its parameters types. This is saved in a JSON-based structure called ABI. Let's see this on an example.
Calling from a browser
The simplest way is to use an Etherscan read/write contract function. Unfortunately, it doesn't support Zos upgradable contracts we use for most of Winding Tree smart contracts. That is why we created a contract caller in our debugging tools suite. Let's try it out!
Metamask
First, you will need a browser (Chrome recommended) with Metamask extension installed.
After installing the extension, follow the guide Get started
to
Create a wallet
. Choose a password and mark the
seed phrase words for recovery. You don't need to worry much about this
if you only intend to use the wallet for testing but make sure the
wallet is properly secured when used in production! Best create a new
wallet once you decide to work with mainnet.
Once you have an identity you can interact with the network. Select
Ropsten Test Network
from the menu on top of the Metamask window.
Contract caller
Open up https://debugging-tools.windingtree.com/contract-caller.
By default the address and ABI of the current Ropsten testnet WindingTreeEntrypoint contract will be set.
Click the yellow button to open up a Metamask window and connect the application with your wallet.
Next, you will see a list of methods loaded from the ABI. Select
getSegmentsLength
and click Call
to call it.
A green window should pop up in the right corner. The number you are
looking for is the value for "0"
key. It should be 4 which - due to
the way arrays are used in the contract - means there are 3 segments.
(Let's not worry about that for now :-))
Info
See the Entrypoint code to understand how it works.
Let's move on to getSegmentName
method. Unlike getSegmentsLength
this one takes an argument. Call it with 1
, then 2
and then 3
.
You'll find out there are separate segments for hotels
, airlines
and
otas
. Let's work with the hotels segment for now.
To interact with hotels directory, we need its address. Select a
getSegment
method and call it with hotels
parameter. The result
should be an ethereum address (0x...
). Go ahead and copy it to the
address
field on the top of the page.
Now we need the ABI of the SegmentDirectory
contract. All we need to
do is select SegmentDirectory
from the contract
dropdown and the ABI
will get loaded. You'll notice the list of methods has changed.
Info
See the Segment Directory code to understand how it works.
Note
You can use the contract caller with any smart contract but you need to provide the ABI. It can usually be found in built .json files provided with the smart contract. Or you can get it by compiling the contracts on your own.
Now let's simply call getOrganizations
function to get a list of
addresses. All of these (except removed organizations that were replaced
by zero values (0x000..0)) are smart contracts implementing
OrganizationInterface.
Pick one of the addresses, copy it into the form, select Organization
form the contracts dropdown, call getOrgJsonUri
and voilà! You have
discovered an organization's ORG.ID you can work with.
Calling from a console
Calling methods from a browser is a good method to test it out manually. Once you want to run a script periodically or act programatically on the returned data, you need to do this in a script.
There are many bindings for favourite languages, like Node.js, Java, Python or C#.
We will work with a Truffle console written in Javascript.
Installing truffle
Basically just run
npm install -g truffle
Follow the instructions if you run into problems.
Working with any smart contracts
You can use truffle console to interact with any smart contract. The only thing you have to do is to give truffle their source code and/or their compiled form. You can configure it as you like, the only issue is if you work with contracts from multiple sources. Truffle does not support that.
Working with Winding Tree contracts
Clone wt-contracts repository, set up correct node version and install dependencies
git clone https://github.com/windingtree/wt-contracts.git && cd wt-contracts
nvm use && npm ci
Build contracts
npm run buildfornpm
Next follow the Local testing
part of wt-contracts
readme to deploy
the contracts. (Run local network, start a zos session, deploy contracts
and create proxies.) This is not interacting with any real Ethereum network.
Info
You can ignore the could not find ./keys.json
warnings for local testing.
Now you are ready to run the Truffle console.
./node_modules/.bin/truffle console --network development
Finish the testing according to the readme to insert an organization in
local development
network.
Interacting with the contracts on testnet
The local network is set up to automine blocks after each transaction.
On testnet (and mainnet) you need to pay gas
for the transaction to be
mined. See the first part of
How to get Lif token tutorial to
find out how to get ETH from a faucet and be able to send transactions.
You will also need to configure truffle to connect to an external network. For that you need a connected node and a little bit of configuration. You can check any tutorial on the internet or take some inspiration from our tutorial repository.