听说Python的广告刷爆了你的朋友圈
zmhg799417
发表于 2023-1-10 00:02:09
97
0
0
使用 DynamicAppCall 函数前需要将其引入。这可以通过下面的语句实现:1 Q- R) n s: E
from ontology.interop.System.App import DynamicAppCall: X+ A6 Y, i' U
2.1 DynamicAppCall API
DynamicAppCall API 有三个参数,分别对应被调用合约的哈希反序,被调用合约方法和被调用方法所需要的参数。我们准备两个智能合约,合约 A 与合约 B。接下来我们通过合约 A 来动态调用合约 B 的功能函数。+ M8 L6 @0 ^% y, f% n9 ~ Z4 X5 l
合约 A 的代码如下:
特别注意:获取合约 B 的合约哈希后,需要将其反序后再作为调用合约 A 时的参数传入。! T% _3 Y0 I& M2 y; k8 {
from ontology.interop.System.App import DynamicAppCall% A! _1 x+ F' \# {9 o1 l
from ontology.interop.System.Runtime import Notify
def Main(operation, args):" e! l' D) f2 Z W3 g
if operation == "DynamicCallContract":$ o( B" Q: L/ p
if len(args) != 3:
return False
revesedContractAddress = args[0]
opt = args[1]0 a' B+ \1 o% a& u+ k( ~' } |
params = args[2]
return DynamicCallContract(revesedContractAddress, opt, params)7 _* V' O2 {1 @
return False
def DynamicCallContract(revesedContractAddress, operation, params):
res = DynamicAppCall(revesedContractAddress, operation, [params])
Notify(["the result of the DynamicCall is: ", res])" W8 r) L, p2 ?: Y
return res! P" t" t1 W( D: y- q$ r
/ q% t8 k' {, X: x* s7 W) s. C: _
合约 B。也是最简单的 Hello World 合约。合约 A 将调用合约 B 中的 Hello 函数。
特别注意:需要先部署合约 B,获取合约 B 的合约哈希。
from ontology.interop.System.Runtime import Notify
def Main(operation, args):
if operation == 'Hello':
msg = args[0]
return Hello(msg): l. B! Q7 z" q! i! a; k+ D: a
return False( O6 r, O8 {) z! Z* n
def Hello(msg):' S' M& o6 V7 }# ^9 \
return msg
此外,我们推荐在合约 A 中预留接口,对 B 合约哈希的反序进行存储 (注意存储时,value 的类型应为 bytearray)。当我们通过合约 A 调用合约 B 时,可将被存储的 B 合约哈希取出填充到 DynamicAppCall() 中的第一个参数位置。 A L1 E; E: l- N2 y
这样做的好处有:; b6 _) P2 N3 [$ L6 b. y, k
' v$ Z2 E2 K# O) H* {5 L8 o
不用每次调用方法时,传入 B 合约的哈希反序;5 J1 _, W+ X/ C" f( c1 v5 r" c
对于函数调用者而言,合约 B 的哈希是隐形的,可以预先在合约 A 中方便地进行设置,进而保留了动态调用的灵活性,同时也包含了 RegisterAppCall 接口传参的简洁性。# [1 ^, V) P$ ^) s- \4 u6 R N
; n. v5 i6 ?% J9 @9 I+ `( A
03 SmartX 示例
部署合约 B,得到其合约哈希为028de32923bcc21e8a5485e4b0e81eff2d9ba08e;点击工具栏使用Hex String (Big-endian/Little-endian),将合约哈希反序得到8ea09b2dff1ee8b0e485548a1ec2bc2329e38d02;部署合约 A;在 SmartX 上选中合约 A 中的 DynamicCallContract 方法,并设置参数: J$ P& B. n4 G; U" Y- T" ^
点击「运行预执行」,返回68656c6c6f20776f726c64 (Hello World 十六进制字符串), 调用成功。
04 总结
这两期我们分别介绍了静态合约调用与动态合约调用。可以总结,二者的主要区别在于:
静态合约调用需要写死合约地址(作为参数写入 RegisterAppCall),也就是说静态调用只能调用某个特定合约。而动态合约调用可以将合约地址作为参数传入,意味着可以没有限制地调用任意非 Native 合约。
静态合约调用合约地址无需反序,而动态调用合约地址需要反序。
成为第一个吐槽的人