如何在Algorand中创建带参数的子应用?
如何在Beaker中给预编译子应用的创建方法传递参数
我想基于Beaker的预编译子应用机制创建子应用,但需要让子应用的创建方法接收参数。目前的代码如下:
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()), )
我尝试用application_args传递参数,代码改成这样:
InnerTxnBuilder.Execute({ **self.child.get_create_config(), TxnField.application_args: [ Itob(42) ], })
但执行create_child时出现了错误:
TransactionPool.Remember: transaction RIOKX6SHD2QC4CW3ZDMVKEWDP7DISFXEGOMQEZOVQQDY6OMMAN6Q: logic eval error: err opcode executed. Details: pc=60, opcodes===\n' + 'bnz label4\n' + 'err\n' + 'label4:\n'
请问该如何正确给子应用的创建方法传递参数?
正确的参数传递方式
你之前的错误根源是:get_create_config()已经自动把create方法的选择器放到了application_args的第一个位置,但你手动覆盖后只传入了参数值,缺少方法选择器,导致子应用无法识别要执行的方法,触发了err指令。下面是两种可靠的解决方式:
方式1:用Beaker内置方法自动处理(推荐)
直接调用子应用预编译对象的create方法,Beaker会自动处理参数编码、方法选择器拼接和交易构建,不需要手动操作application_args:
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, foo: abi.Uint64, *, output: abi.Uint64): return Seq( # 直接调用子应用的create方法,自动处理所有参数逻辑 self.child.create(foo), output.set(InnerTxn.created_application_id()), )
方式2:手动追加参数(不推荐,仅作原理演示)
如果一定要手动处理application_args,需要保留原有的方法选择器,再追加编码后的参数:
@decorators.external def create_child(self, *, output: abi.Uint64): return Seq( InnerTxnBuilder.Execute({ **self.child.get_create_config(), # 保留原有的方法选择器,追加ABI编码后的参数 TxnField.application_args: Concat( self.child.get_create_config()[TxnField.application_args], [Itob(42)] ), }), output.set(InnerTxn.created_application_id()), )
注意:这里用Itob是因为参数是abi.Uint64,其ABI编码结果和Itob的输出一致;如果是其他ABI类型(比如字符串),需要用对应的ABI编码方法。
内容的提问来源于stack exchange,提问作者jeron-diovis
相关产品推荐
相关产品推荐

