Calling function of another contract in current contract

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===

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}

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([
        # is_application_admin,
        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(
        # Application Creation Call would be routed here.
        [Txn.application_id() == Int(0), on_creation],

         # All General Application calls will be routed here.
        [Txn.on_completion() == OnComplete.NoOp, on_call],
        # Reject DELETE and UPDATE Application Calls.
        [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(),
    ])


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

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?

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)

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(),

I have also tried,
TxnField.assets : Txn.assets[0];

Please suggest the appropriate way of using this field. Thanks.

                TxnField.assets: [Int(81317600)],

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.

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?

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

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.