How to create a child app with parameters in Algorand?

173 views Asked by At

I want to create a child app as described here, but make it to accept parameters on creation:

    from pyteal import *
    from beaker import Application, ApplicationStateValue, decorators

    class ChildApp(Application):
      foo = ApplicationStateValue(
        stack_type=TealType.uint64,
      )
    
      @decorators.create
      def create(self, foo: abi.Uint64):
        return Seq(
          self.foo.set(foo.get()),
        )

    class ParentApp(Application):
      child: AppPrecompile = AppPrecompile(ChildApp())
      
      @decorators.external
      def create_child(self, *, output: abi.Uint64):
        return Seq(
          InnerTxnBuilder.Execute({
            **self.child.get_create_config(),
            # ???
          }),
          output.set(InnerTxn.created_application_id()),
        )

The question is – how do I pass those parameters to a child?

From what I see, the only thing that looks suitable, is application_args:

InnerTxnBuilder.Execute({
  **self.child.get_create_config(),
  TxnField.application_args: [ Itob(42) ],
})

I have to use Itob in this case, because application_args only accepts Bytes values.

This is weird already, but anyway it doesn't work: on attempt to call create_child method I get this:

TransactionPool.Remember: transaction RIOKX6SHD2QC4CW3ZDMVKEWDP7DISFXEGOMQEZOVQQDY6OMMAN6Q: 
logic eval error: err opcode executed. Details: pc=60, opcodes===\n' +
        'bnz label4\n' +
        'err\n' +
        'label4:\n'

Which is not helpful at all. I don't understand what am I doing wrong.

So how do I properly pass params to a child app?

1

There are 1 answers

1
GaryLu On BEST ANSWER

Firstly, thank you for trying out Beaker even though it is still in early development! Please don't be afraid to share your feedback on it through it's GitHub repository or Beaker channel on the Algorand Discord server.

From ARC 4 which details the ABI standard:

The method selector must be the first Application call argument (index 0), accessible as txna ApplicationArgs 0 from TEAL (except for bare Application calls, which use zero application call arguments).

Your TxnField.application_args should therefore look something like the following so that your child contract knows which method it should route to upon creation:

TxnField.application_args: [
    Bytes(get_method_spec(ChildApp.create).get_selector()),
    Itob(Int(42)),
],

Also note that the number 42 must first be wrapped with Int to convert it to a teal type.

You will likely want to pass an argument from the parent to the child on creation. If so, then it'd look more like the following assuming your parent receives an abi.Uint64 argument called my_int_arg:

TxnField.application_args: [
    Bytes(get_method_spec(ChildApp.create).get_selector()),
    my_int_arg.encode(),
],

You may read more about ARC 4 here.