Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语9 i; R6 p$ Z& V9 p, |
上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:' G0 N% L9 F& @! J. g" z: r7 R$ t
同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:6 P$ S& S; ^1 [; a
下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。$ v- |! N9 Y: ?7 u
02 Native API 使用方法
$ s5 \& Y/ ~3 t0 e* F) k6 O同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数
1 s6 e# t5 V: ^: I  r, _% hfrom ontology.interop.Ontology.Native import Invoke+ \) u" F6 g0 l" s7 p. W
from ontology.builtins import state) |) x2 Z9 k. `2 H/ B% y+ I
2.1 本体原生合约列表
) i/ ]( y1 V/ @) P* S7 I! m% X! j目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:
7 d0 w- v: Q# d2 v; o
. ]; u7 @. _, L& {* c在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。
7 Q6 c" p( Q! K: H这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。
& B1 b7 W+ X; H5 C' {param = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额) b6 n- Q/ H3 x( `+ i2 w7 }7 r9 w
res = Invoke(1, contract_address_ONT, 'transfer', [param])
+ ^3 o" L8 _/ u" e( h2 D% M2.2 转账合约代码
1 c  _) y9 u4 C; @' H( M下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:
7 Z: C4 c# t: W- p; {定义合约地址变量 contract_address_ONT,contract_address_ONG;
" ?7 ]2 l. _$ i" ?/ B& b& }将转出地址和转入地址从 base58 格式转成 bytearray 格式;/ |# f4 S" G5 {/ |
验签,确认转出地址与合约调用地址为同一地址;: T# }  y* R) x
state 函数封装转账相关参数;
* f& Y+ i+ f0 M' \) jInvoke 函数调用 ONT Token 和 ONG Token 原生合约转账;& y" f, h5 p3 h5 C& }0 F
通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。: C+ v* @7 e+ K* X) l- S
from ontology.interop.System.Runtime import Notify, CheckWitness1 A* s$ z4 P: e/ Y. D  l
from ontology.interop.Ontology.Runtime import Base58ToAddress. Y0 n+ h/ M4 X: k) E# e
from ontology.interop.Ontology.Native import Invoke$ P# }9 W% J$ [7 a: e, {* I9 m4 ?
from ontology.builtins import state
' C, _* u. @  U# contract address 8 V- c5 C# S7 J5 s# l' o
contract_address_ONT = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')$ B3 W4 v& s- q& s
contract_address_ONG = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')
' F& g' r  _4 tdef Main(operation, args):
5 f+ E' j& y* J/ a    if operation == 'transfer':, Z! s0 A3 @3 X
        from_acct = args[0]
+ [# S; [% n8 ?& p" L        to_acct = args[1]3 D1 Q" h; M. A/ Y7 D& T
        ont_amount = args[2]' Y' L: H1 B; k3 x' m7 C& M; T  R
        ong_amount = args[3]
, Z- V' s" l+ h; M+ {        return transfer(from_acct,to_acct,ont_amount,ong_amount)
/ R3 P  K. m& g    * z3 _- i+ b* B+ u- I5 J$ W( j) @2 {
    return False
- N( c% z" f" t' x- s" w1 s, e4 I* Odef transfer(from_acct, to_acct, ont_amount, ong_amount):6 R& t) R* `$ i: |& J$ ^, c
    # 将base58地址转换成 bytearray格式地址 0 w8 R" Q/ u: j
    from_acct=Base58ToAddress(from_acct)" D9 A  |# x9 o7 b$ f4 z( B
    to_acct=Base58ToAddress(to_acct)
1 r5 E% [) s$ A; }2 K4 I2 b    # 验签,调用方必须与转出地址为同一地址% W! d4 q% B0 q% h- w
    if CheckWitness(from_acct):
  G8 ^6 i- ~8 I3 p, Q- X( [        # ONT转账
+ e% T8 [6 Q4 k, L" I  |" w( B% a        if ont_amount > 0:
) \2 U! H( ?( O* e            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数" H; }9 l* Y0 s* W2 D5 j' R8 Y
            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账& t  j8 x: _0 X, T1 N! w1 a
            if res and res == b'\x01':
4 @, y* k; }+ W0 ]% r. {* U0 U                Notify('transfer succeeded')
  n/ e! U! z! P$ F; D) u            else:& c  R4 ~0 K* O. q
                Notify('transfer failed')& i% s% f, ?+ [8 O4 [3 Q
        # ONG转账,流程同上
0 K1 c1 }9 |" F        if ong_amount > 0:8 v" ~  i$ z0 S" f8 F
            param = state(from_acct, to_acct, ong_amount)
& [2 a1 a0 o. K6 _1 `# x* t9 H            res = Invoke(1, contract_address_ONG, 'transfer', [param])
6 `4 C* G, G' M& c% v, x            if res and res == b'\x01':; J4 `9 o; T1 X4 ^' \5 `# H: C3 j
                Notify('transfer succeeded'); O. A! T0 @% H* l
            else:/ b! }2 q! u8 d% e* |. P
                Notify('transfer failed')( v0 Z" n/ C- Q2 S
    else:
# X1 K5 r9 j9 D        Notify('CheckWitness failed')
6 m. V) A, }3 U3 H, u# H. ~  D; j2 q: f" X, U
03 SmartX 实践
. e0 M/ F2 H/ g( G' \接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:! B, y6 N( k5 d/ n9 x9 z
4 `0 x! A' s5 {6 i/ X7 d7 m5 P
编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。7 j0 Q: l; `6 f- O1 ]
; N3 c1 G- f% m' [4 l4 _

! @4 J0 T3 J/ G5 {5 d部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:
- E# @" R. e8 i
# f; Z$ S  w' a5 w+ x5 t% Q! P6 D. V8 V* w& V1 ]
. c: O! H* g4 d& O6 `
执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:, |1 M+ U: M, o1 m. X, c% `% }6 ^6 G

$ C5 n3 w  g) {9 i4 d) I  m
  B0 g8 m6 D; [. s3 ^; E转账成功。当转帐参数设置正确时,执行 transfer 函数将转账成功。上面所填的接收地址中将显示出收到的代币:
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8