Calling function of another contract in current contract - General - Algorand

Calling function of another contract in current contract

post by salman.haider on Aug 10, 2022

I’m trying to call the function “Hello(firstName, lastName)” of another contract within my current contract, this is how I’m trying to achieve it:

                InnerTxnBuilder.Begin(),
                InnerTxnBuilder.SetFields({
                    TxnField.type_enum: TxnType.ApplicationCall,
                    TxnField.application_id: Int(104489178),
                    TxnField.on_completion: OnComplete.NoOp,
                    TxnField.application_args: [Bytes("Hello")],
                    TxnField.application_args: [firstName],
                    TxnField.application_args: [lastName],
                }),
                InnerTxnBuilder.Submit(),

However, it is giving me this error: logic eval error: TEAL runtime encountered err opcode. Details: pc=492, opcodes===

post by fabrice on Aug 11, 2022

Have you tried:

               InnerTxnBuilder.Begin(),
                InnerTxnBuilder.SetFields({
                    TxnField.type_enum: TxnType.ApplicationCall,
                    TxnField.application_id: Int(104489178),
                    TxnField.on_completion: OnComplete.NoOp,
                    TxnField.application_args: [Bytes("Hello"), firstName, lastName],
                }),
                InnerTxnBuilder.Submit(),

in Python is a dictionary. If you put twice the same key (here TxnField.application_args), only the last value is taken:

see on iPython:

In [1]: {"a": 5, "a": 7}
Out[1]: {'a': 7}

post by salman.haider on Aug 15, 2022

Hey,

I’m able to call other functions in other application, however, there is this one function that I’m trying to call many times but its always giving a different error, when I remove the args from this call and simply call the function by giving its name then it gave me the error "pushBytes “distribute-tax” etc

Received status 400: TransactionPool.Remember: transaction SSWTELQGZ3C42C3FQZZWKJLPS3Q6DQXYFTGFN4M2C4R6H77SL6JA: logic eval error: logic eval error: assert failed pc=541. Details: pc=541, opcodes=app_global_get
==
assert
. Details: pc=221, opcodes=load 1
itxn_field ApplicationArgs
itxn_submit

This is the error that I’m receiving whenever I call the distributeTax function of my TaxContract from the PrimaryContract.

Here is the code of my PrimaryContract

from pyteal import *

def approval_program():

@Subroutine(TealType.none)
    def call_tax(token):
        return Seq([\
                InnerTxnBuilder.Begin(),\
                InnerTxnBuilder.SetFields({\
                    TxnField.type_enum: TxnType.ApplicationCall,\
                    TxnField.application_id: Int(105162470),\
                    TxnField.on_completion: OnComplete.NoOp,\
                    TxnField.application_args: [Bytes("distribute-tax"), token],\
                }),\
                InnerTxnBuilder.Submit(),\
        ])

_token = Txn.application_args[1]
    on_call_tax = Seq([\
        call_tax(_token),\
        Approve(),\
    ])

on_call_method = Txn.application_args[0]
    on_call = Cond(
[on_call_method == Bytes("call-tax"), on_call_tax],
    )
    on_delete = Seq([\
        Approve(),\
    ])
    on_update = Seq([\
        Reject(),\
    ])

program = Cond(
        [Txn.application_id() == Int(0), on_creation],
        [Txn.on_completion() == OnComplete.NoOp, on_call],
        [Txn.on_completion() == OnComplete.UpdateApplication, on_update],
        [Txn.on_completion() == OnComplete.DeleteApplication, on_delete]
    )

return compileTeal(program, Mode.Application, version=6)

print(approval_program())

This is how my TaxContract looks like:

@Subroutine(TealType.none)
def distribute_tax(token, origin):
   return Seq([\
          // Transfer tokens to the some other account;\
   ])

_token = Btoi(Txn.application_args[1])
on_distribute_tax = Seq([\
        is_application_admin,\
        distribute_tax(_token, Txn.sender()),\
        Approve(),\
    ])

post by salman.haider on Aug 15, 2022

Now I’m facing this error if I try to call the same function, within my Taxfunction I’m checking the current balance of my Asset by using the holding function:

Error: Network request error. Received status 400: TransactionPool.Remember: transaction ITTVMG5OSBVBTVLHLGWSFSO5BAY4XRGSIE7GN5LKKXKSLU3WCY4A: logic eval error: logic eval error: invalid Asset reference 81317600. Details: pc=775, opcodes=global CurrentApplicationAddress
load 21
asset_holding_get AssetBalance
. Details: pc=239, opcodes=pushbytes 0x646973747269627574652d746178 // "distribute-tax"
itxn_field ApplicationArgs
itxn_submit

post by salman.haider on Aug 15, 2022

Could you please confirm if I want to perform some operations such as transferring tokens from ContractA to ContractB by calling ABC function of ContractB

Should I then pass the AppID of ContractB, FunctionName (ABC), arguments and also the Token ID? If Yes, how. can I pass the token ID within the pyTeal syntax while building the innerTxn?

post by fabrice on Aug 15, 2022

invalid Asset reference 81317600

most likely means you did not include the asset ID in the asset array of the transaction / inner transaction.

Assets ID specified in inner transactions must also be specified in parent transaction.

Concretely this means that 81317600 must be added to both the asset array of the parent transaction (using the SDK) AND of the inner transaction (TxnField.assets)

post by salman.haider on Aug 16, 2022

I have tried this way but it didn’t work, could you please write the accurate syntax of passing the asset within the innerTxn?

pyteal.TealInputError: inner transaction set array field TxnField.assets with non-array value
            InnerTxnBuilder.Begin(),
            InnerTxnBuilder.SetFields({
                TxnField.type_enum: TxnType.ApplicationCall,
                TxnField.application_id: Int(105169353),
                TxnField.assets: Int(81317600),
                TxnField.on_completion: OnComplete.NoOp,
                TxnField.application_args: [Bytes("distribute-tax")],
            }),
            InnerTxnBuilder.Submit(),

post by fabrice on Aug 16, 2022

                TxnField.assets: [Int(81317600)],

post by salman.haider on Aug 17, 2022

Thanks Fabrice, this helped! Just a little suggestion to ask, in Ethereum, we can simply send the tokens to zero_address to burn. Where should I send the tokens in Algorand when I want to burn them? Is there any zero address or blackhole?

I tried the one Global.zero_address but it didn’t work.

post by salman.haider on Aug 29, 2022

invalid : tx.Accounts too long, max number of accounts is 4

I’m restricted to only pass 4 addresses in accounts array but what If I want to pass 20+ addresses in accounts array?

post by TTogle on Aug 30, 2022

I believe you can only send a maximum of 8(?) arguments to a smart contract everything else needs to be hardcoded at the moment.

post by fabrice on Aug 31, 2022

Yes, you can only specify 4 accounts in the foreign accounts array of an application call:

If you need to access more of them, you’ll need to for example create a group of transactions and manually handle the situation. Remember you can communicate between application calls transactions using either scratch pads or logs.