I suggest you start by understanding how to call one contract from another. You can refer to this resource for more details: Call one contract from another.
In SmartPy, you have the ability to call a method in another contract by using sp.transfer
.
c1.transfer
is restrained to test scenario.
Here's the syntax for sp.transfer
:
sp.transfer(argument: t, amount: sp.mutez, destination: sp.contract[t])
:
argument
is the same argument as c1.transfer
amount
is an amount of tez (most of the time sp.tez(0)
)
destination
is the destination contract, obtained by calling sp.contract(t, address: sp.address, entrypoint="transfer")
and .unwrap_some()
.
Below is an example where I use these concepts. Note that I use t.transfer_params
from the fa2_lib
, but you can specify the full type directly:
list[sp.record(
from_=sp.address,
txs=list[sp.record(
to_=sp.address,
token_id=sp.nat,
amount=sp.nat,
).layout(("to_", ("token_id", "amount")))],
).layout(("from_", "txs"))]
Here is a full example:
import smartpy as sp
from templates import fa2_lib
# Accessing transfer_params from fa2_lib
t, main = fa2_lib.t, fa2_lib.main
@sp.module
def m():
class MyContract(sp.Contract):
def __init__(self):
pass
@sp.entrypoint
def call_transfer(self, fa2_address, args):
# Get contract from the address
fa2_contract = sp.contract(t.transfer_params, fa2_address, entrypoint="transfer")
# Call the transfer entrypoint in the FA2 contract
sp.transfer(args, sp.tez(0), fa2_contract.unwrap_some(error="Contract not found"))
if "templates" not in __name__:
@sp.add_test(name="MyContract")
def test():
sc = sp.test_scenario([t, main, m])
c1 = m.MyContract()
sc += c1
fa2 = main.Fungible(sp.big_map(), {}, [])
sc += fa2
# Here we give the args
# They can also be created inside the entrypoint.
c1.call_transfer(sp.record(
fa2_address=fa2.address,
args=[]))