本体技术视点 | 听说Python的广告刷爆了你的朋友圈?

前几天,一条 Python 广告刷爆了小编的朋友圈。网友纷纷惊呼,“什么鬼?居然这么多人在学 Python?”而在日前 IEEE Spectrum 发布的第五届年度编程语言交互排行榜中,Python 不但雄踞第一,在综合指数、用户增速、就业优势和开源语言单项中,全部霸占榜首。
本体技术视点 | 听说Python的广告刷爆了你的朋友圈?_第1张图片

于是有网友开玩笑:“人生苦短,你还不用 Python 吗?”既然要用,何不来本体学学 Python 智能合约开发?言归正传,今天小编就教你点干货!
本体技术视点 | 听说Python的广告刷爆了你的朋友圈?_第2张图片
图 | 网络

01 导语

上一期我们介绍了跨合约静态调用,讲述了如何使用 RegisterAppCall API 进行静态调用其它合约的函数。本期我们将讨论如何跨合约动态调用。API只有一个,用法如下:

在这里插入图片描述

02 DynamicAppCall 使用方法

使用 DynamicAppCall 函数前需要将其引入。这可以通过下面的语句实现:


from ontology.interop.System.App import DynamicAppCall

2.1 DynamicAppCall API
DynamicAppCall API 有三个参数,分别对应被调用合约的哈希反序,被调用合约方法和被调用方法所需要的参数。我们准备两个智能合约,合约 A 与合约 B。接下来我们通过合约 A 来动态调用合约 B 的功能函数。

合约 A 的代码如下:
特别注意:获取合约 B 的合约哈希后,需要将其反序后再作为调用合约 A 时的参数传入。


from ontology.interop.System.App import DynamicAppCall
from ontology.interop.System.Runtime import Notify

def Main(operation, args):
    if operation == "DynamicCallContract":
        if len(args) != 3:
            return False
        revesedContractAddress = args[0]
        opt = args[1]
        params = args[2]
        return DynamicCallContract(revesedContractAddress, opt, params)

    return False

def DynamicCallContract(revesedContractAddress, operation, params):
    res = DynamicAppCall(revesedContractAddress, operation, [params])
    Notify(["the result of the DynamicCall is: ", res])
    return res

合约 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)

    return False

def Hello(msg):
    return msg

此外,我们推荐在合约 A 中预留接口,对 B 合约哈希的反序进行存储 (注意存储时,value 的类型应为 bytearray)。当我们通过合约 A 调用合约 B 时,可将被存储的 B 合约哈希取出填充到 DynamicAppCall() 中的第一个参数位置。

这样做的好处有:

  1. 不用每次调用方法时,传入 B 合约的哈希反序;

  2. 对于函数调用者而言,合约 B 的哈希是隐形的,可以预先在合约 A 中方便地进行设置,进而保留了动态调用的灵活性,同时也包含了 RegisterAppCall 接口传参的简洁性。

03 SmartX 示例

  1. 部署合约 B,得到其合约哈希为028de32923bcc21e8a5485e4b0e81eff2d9ba08e;
  2. 点击工具栏使用Hex String (Big-endian/Little-endian),将合约哈希反序得到8ea09b2dff1ee8b0e485548a1ec2bc2329e38d02;
  3. 部署合约 A;
  4. 在 SmartX 上选中合约 A 中的 DynamicCallContract 方法,并设置参数:
    本体技术视点 | 听说Python的广告刷爆了你的朋友圈?_第3张图片
  5. 点击「运行预执行」,返回68656c6c6f20776f726c64 (Hello World 十六进制字符串), 调用成功。

04 总结

这两期我们分别介绍了静态合约调用与动态合约调用。可以总结,二者的主要区别在于:
静态合约调用需要写死合约地址(作为参数写入 RegisterAppCall),也就是说静态调用只能调用某个特定合约。而动态合约调用可以将合约地址作为参数传入,意味着可以没有限制地调用任意非 Native 合约。

静态合约调用合约地址无需反序,而动态调用合约地址需要反序。

下一期我们将介绍本体 Python 智能合约语法的 Execution Engine API,也是本系列教程的最后一篇,记得搬好小板凳来听课哦~以下为本期教程的中文视频,欢迎小伙伴们观看学习,相信会对你有帮助!
点此观看视频教程

你可能感兴趣的:(开发者杂谈)