Inter-Contract Calling in SmartPy

Pawan Dhanwani
Tezos India
Published in
3 min readMay 25, 2020

Inter contract call is one of the most important and underused features of SmartPy.

They can be very useful when Oracles come into the picture and hence it is important to learn how to implement them.

In this article you will learn how to perform interact contract calling with SmartPy.

Please make sure you use SmartPy’s dev version because on demo version this may not work.

Before writing the contract lets understand how it works.

contractParams = sp.contract(sp.TRecord(ans = sp.TInt),"KT1-AAA",entry_point="addTwoandReturn").open_some()

First, we need to create a variable which holds details about what and where it will be sent.

Data to the target contract is sent in the form of a record. You need to specify the data types as well.

Then comes the address of the contract where data needs to be sent.

And at last the name of the entry point where data needs to be sent.

Please note when there is only one entry point in the target contract you shouldn’t provide the name of entry point then the variable will have only two-parameter. But generally, we have at least two entry points in our contract.

dataToBeSent = sp.record(ans = 6)

A record needs to be created having the data which needs to be sent, the structure of record should be the same as described in the previous line.

sp.transfer(dataToBeSent,sp.mutez(0),contractParams)

At last you send the data. The first parameter is a record that contains data. Then comes the amount which you need to send in Mutez and at last variable which contains details of the target contract.

Pro tip : Say for, a Caller contract sends the Target / Service contract some data and amount(Mutez) and now you want to return the processed data to same contract and with same amount which was sent to you. You can use sp.sender and sp.amount respectively.

Let's understand with an example

Target / Service contract

import smartpy as sp
class TargetContract(sp.Contract):

@sp.entry_point
def addTwoAndReturn(self,params):
contractParams = sp.contract(sp.TRecord(ans = sp.TInt),sp.sender,entry_point="recieveResponse").open_some()

dataToBeSent = sp.record(ans = params.num+2)
sp.transfer(dataToBeSent,sp.mutez(0),contractParams)

@sp.entry_point
def addThreeAndReturn(self,params):
contractParams = sp.contract(sp.TRecord(ans = sp.TInt),sp.sender,entry_point="recieveResponse").open_some()

dataToBeSent = sp.record(ans = params.num+3)
sp.transfer(dataToBeSent,sp.mutez(0),contractParams)

@sp.add_test(name="Inter contract calling test")
def test():
obj = TargetContract()
scenario = sp.test_scenario()
scenario+=obj
#scenario+=obj.addTwoAndReturn(num=4).run(sender=sp.address("KT1-AAA"),amount=sp.mutez(0))

Caller Contract

import smartpy as sp
class CallerContract(sp.Contract):
def __init__(self):
self.init(mynum = sp.int(0))

@sp.entry_point
def sendDataToTargetContract(self,params):
c = sp.contract(sp.TRecord(num = sp.TInt),params.targetContract,entry_point="addTwoAndReturn").open_some()
mydata = sp.record(num = params.num)
sp.transfer(mydata,sp.mutez(0),c)


@sp.entry_point
def recieveResponse(self,params):
self.data.mynum = params.ans


@sp.add_test(name="Inter contract calling test")
def test():
obj = CallerContract()
scenario = sp.test_scenario()
scenario += obj
#scenario+=obj.sendDataToTargetContract(num=2,targetContract=sp.address("KT1-AAA")).run(amount=sp.mutez(0))
#scenario+=obj.recieveResponse(ans=4)

How to play with this -

  1. Deploy both the contract and save the address.
  2. Once deployed open the explorer tab of SmartPy.
  3. Provide the caller contract address and hit the “explore on smartpy.io Nodes” button.
  4. Scroll down and select the “sendDataToTargetContract” option, then provide the address of Target Contract and number which you want to send to the target contract.
  5. Press “Build Message”.
  6. At last, send the transaction by pressing “Send the transaction”

For your convenience I have deployed the contracts already.

Smartpy Node - https://carthagenet.smartpy.ioTarget / Service Contract Address - KT1BFaqCe1U1gUcb47zQTD8U7Lh4tZvNNJYMCaller Contract Address - 
KT1AsXGv8cdS68axXwyEn6xRqSLJrKapPPcP

Extras: Say for example, you need to send some Tez to target contract from caller contract then, you need to provide Tez to caller contract at the time of deployment from the “amount” tab.

Please let us know if you get any doubts in the comments or you can ask directly in our Tezos India developers telegram channel.

--

--