0

I have two contracts , contract A and Contract B. This is my contract B where I have defined a callback function that will return sp.some("test") when called.

import smartpy as sp


t_balance_of_params = sp.TRecord(
    callback=sp.TContract(sp.TOption(sp.TString)),
    requests=sp.TString,
).layout(("requests", "callback"))

class ContractB(sp.Contract):
    def __init__(self, value):
        self.init()


    @sp.entry_point
    def get_String(self, params):
        sp.set_type(params, t_balance_of_params)
        sp.transfer(
           sp.some("test"), sp.mutez(0), params.callback
        )

Here is the contract A, where I am trying to access the contract B callback function and update my contract A initial storage value,

class ContractA(sp.Contract):
    def __init__(self, value):
        self.init(updated_balance = value, 
                 str_test = sp.some(sp.string("initial")))

    @sp.entry_point
    def getBalance(self, contract_address):
        fa2_contract = sp.contract(
            sp.TRecord(
                callback=sp.TContract(sp.TString),
                requests=sp.TString,
            ).layout(("callback", "requests"))
        , contract_address, entry_point="get_String").open_some()

        x  = sp.transfer(sp.record(callback=sp.self_entry_point("test_balance"), 
                               requests= "Nooo"),
                    sp.tez(0),
                    fa2_contract)

    @sp.entry_point
    def test_balance(self, balance):
        sp.set_type(balance, sp.TString)
        self.data.str_test = sp.some(balance)

Here both of the contracts are being compiled and deployed but somehow when i do the transaction on contract A getBalance function , my assumptions was it should have saved sp.some("test") on self.data.str_test , but the transaction is giving error. What am i doing wrong here ?

1
  • Please can you improve post a minimal code (removing the unused code like the contractB __init__ or the contractA __init__ parameter and also provide a scenario that can be copy pasted and executed?
    – Jordan_tez
    Apr 27, 2023 at 8:04

1 Answer 1

0

get_String is returning an option of string: sp.some("...").

So test_balance is receiving an option of string, not a string.

You can return a string or change the set_balance entrypoint parameter type to be an option.

import smartpy as sp

t_balance_of_params = sp.TRecord(
    callback=sp.TContract(sp.TOption(sp.TString)),
    requests=sp.TString,
).layout(("requests", "callback"))

class ContractA(sp.Contract):
    def __init__(self):
        self.init(str_test = sp.none)

    @sp.entry_point
    def getBalance(self, contract_address):
        fa2_contract = sp.contract(t_balance_of_params, contract_address, entry_point="get_String").open_some()
        sp.transfer(
            sp.record(callback=sp.self_entry_point("test_balance"), requests= "Nooo"),
            sp.tez(0),
            fa2_contract)

    @sp.entry_point
    def test_balance(self, balance):
        sp.set_type(balance, sp.TOption(sp.TString))
        self.data.str_test = balance

class ContractB(sp.Contract):
    @sp.entry_point
    def get_String(self, params):
        sp.set_type(params, t_balance_of_params)
        sp.transfer(
           sp.some("test"), sp.mutez(0), params.callback
        )

if "templates" not in __name__:
    @sp.add_test(name="MyContract")
    def test():
        sc = sp.test_scenario()
        c1 = ContractA()
        sc += c1
        c2 = ContractB()
        sc += c2
        c1.getBalance(c2.address)
        sc.verify(c1.data.str_test == sp.some("test"))

Another remark: always check that the callback sp.sender is the good one.

You can see examples here: https://smartpy.io/ide?template=inter_contract_calls.py

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.