Child application deployment from parent application - General - Algorand
Child application deployment from parent application
post by elia on Oct 29, 2022
Hi everyone, I’m struggling a little with a problem regarding the creation of a child application from the parent application.
I’m currently using beaker and pyteal for my project.
Inside the application call transaction ParentApp.parent_app_call() I’m trying to deploy a child application with an InnerTxn.
The definition of the parent_app_call is the following:
@external(authorize=Authorize.only(Global.creator_address()))
def parent_app_call(self,
parent_arg1: abi.Uint64,
parent_arg2: abi.String,
parent_arg3: abi.Uint64,
*,
output: abi.Uint64 # child_app_id
):
return Seq(
Assert(self.parent_state.get() == Int(1), comment="must be in ## state"),
InnerTxnBuilder.Begin(),
InnerTxnBuilder.SetFields(
{
TxnField.type_enum: TxnType.ApplicationCall,
TxnField.approval_program: self.child_app.approval.binary,
TxnField.clear_state_program: self.child_app.clear.binary,
TxnField.fee: Int(0),
TxnField.application_args: [
Global.creator_address(),
Global.current_application_address(),
Itob(parent_arg1.get()),
Itob(parent_arg3.get()),
parent_arg2.get()
],
}
),
InnerTxnBuilder.Submit(),
self.parent_state.set(Int(2)), # in ## phase
output.set(InnerTxn.created_application_id())
)
From the main I call parent_app_call as follows:
sp = creator_app_client.client.suggested_params()
sp.fee = sp.min_fee * 2
sp.flat_fee = True
result = creator_app_client.call(
ParentApp.parent_app_call,
parent_arg1=1,
parent_arg2="string",
parent_arg3=10,
suggested_params=sp
)
The main executes without problems deploying the ParentApp and calling its methods, but parent_app_call is raising an error.
Traceback (most recent call last):
File "/Users/usr1/Projects/Blockchain/Algorand/PyTealLearning/project/venv/lib/python3.10/site-packages/algosdk/v2client/algod.py", line 78, in algod_request
resp = urlopen(req)
...
algosdk.error.AlgodHTTPError: TransactionPool.Remember: transaction JL5X7K4ELISIYP5AJYFBU6F5JFMIDANL5NSSHSRQUJMD45JJ7OUQ: logic eval error: logic eval error: err opcode executed. Details: pc=186, opcodes===
bnz label3
err
label3:
. Details: pc=1337, opcodes=extract 2 0
itxn_field ApplicationArgs
itxn_submit
During handling of the above exception,...
goal app method --app-id 1 --method "parent_app_call(uint64,string,uint64)uint64" \
--from $ADDR --arg 1 --arg '"string"' --arg 10 \
--fee 2000 --dryrun-dump -o test.dr
Do you have any suggestions on how to tackle this problem? What am I missing?
post by fabrice on Nov 2, 2022
Have you tried to call directly the child application from the SDK/goal?
Does it work? Note also that if you’re using ABI for the inputs of the child application call, then:
InnerTxnBuilder.SetFields(
{
TxnField.type_enum: TxnType.ApplicationCall,
TxnField.approval_program: self.child_app.approval.binary,
TxnField.clear_state_program: self.child_app.clear.binary,
TxnField.fee: Int(0),
TxnField.application_args: [
Global.creator_address(),
Global.current_application_address(),
Itob(parent_arg1.get()),
Itob(parent_arg3.get()),
parent_arg2.get()
],
}
),
is most likely incorrect: arguments are most likely not encoded as expected.
post by elia on Nov 3, 2022
Thanks for your answer @fabrice.
The child application is correctly deployed as a standalone using its create method. I also think encoding the arguments on the inner transaction could be the problem.
What would be the correct way to invoke the create method using InnerTxnBuilder.MethodCall?
InnerTxnBuilder.Begin(),
InnerTxnBuilder.MethodCall(
app_id=Int(0),
method_signature="create(address,address,uint64,uint64,string)void",
args=[
Global.creator_address(),
Global.current_application_address(),
parent_arg1,
parent_arg3,
parent_arg2
],
extra_fields={
TxnField.approval_program: self.child_app.approval.binary,
TxnField.clear_state_program: self.child_app.clear.binary,
TxnField.fee: Int(0)
}
),
InnerTxnBuilder.Submit(),
but app_id=Int(0) is not an acceptable app reference:
beaker.client.logic_error.LogicException: Txn XSZKJYKCHVXFOPSWUPNWDOAUXC3Z4A3BP6SQ56VTJFUGZ2E6A5MA had error 'invalid App reference 0' at PC 858 and Source Line 418:
assert
itxn_begin
pushint 6 // appl
itxn_field TypeEnum
intc_0 // 0
itxn_field ApplicationID <-- Error
post by Ben on Nov 3, 2022
The MethodCall function will try to submit an app call to the app id passed. Since 0 is not a valid app id its failing here. You’ll have to use the normal way of executing inner transactions with SetField or Execute to call an ABI method during create until something is changed in pyteal.
post by Ben on Nov 4, 2022
Great! In the latest beaker you can get most of those fields from the Precompile object itself.