Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语
5 [# G6 Q9 ^5 N4 m! I: V4 a上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:
5 h4 F7 V$ w& Z8 @8 G同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:
' q) L2 `* B" `: U/ p% L% q下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。' I6 _0 n6 P' E* p9 n  l3 p
02 Native API 使用方法2 I3 w' {7 k4 W: C" R2 Y" w
同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数
( k* M& n7 }2 ?' s, {/ ^; sfrom ontology.interop.Ontology.Native import Invoke
! p0 j6 R& f& |6 v$ ]6 Ofrom ontology.builtins import state
: p9 C: @% r0 x' W% [  Z6 i2.1 本体原生合约列表
& m5 m* C2 E* T" g目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:
& v$ I, V' u6 d4 }$ e- K1 k* o4 l
- h8 @) U' I7 Z* h在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。
% a, q* ^  [1 g: d, q! N5 |这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。' S, U9 \( f3 h6 l
param = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额
+ o' `- U" q/ t+ l, P( U! G# rres = Invoke(1, contract_address_ONT, 'transfer', [param]). h2 c1 n2 Z% n/ _
2.2 转账合约代码5 x* r6 a. @" Y4 n! |  L2 X: w
下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:1 x+ j9 N, I' t7 k
定义合约地址变量 contract_address_ONT,contract_address_ONG;: Q0 o' B6 x  S8 ~  }) |; w
将转出地址和转入地址从 base58 格式转成 bytearray 格式;
, a( A0 \6 g' Q3 y: D- W, R验签,确认转出地址与合约调用地址为同一地址;
9 b; J1 j; a3 l& C4 Tstate 函数封装转账相关参数;
5 K/ h( Y% _- ~2 FInvoke 函数调用 ONT Token 和 ONG Token 原生合约转账;
: G& [' a8 W# a: @6 S. a通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。
% ^) z* y* c4 J$ _from ontology.interop.System.Runtime import Notify, CheckWitness
0 H0 h  `7 B  `1 M* Y0 ~from ontology.interop.Ontology.Runtime import Base58ToAddress( e  I, _" h- P- Y) ^- u3 `
from ontology.interop.Ontology.Native import Invoke9 L& I0 b- R( t. G# U
from ontology.builtins import state
9 |2 [9 ?& ]) `, h0 E# contract address * s# \& C8 Z  D$ G
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')% W6 B: `; `7 k9 ^, e
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')
# j5 _6 X6 m- W$ }. l- R: \2 u& ~def Main(operation, args):
. `4 }) f5 N4 K$ y- J8 k    if operation == 'transfer':$ h8 q% R" k4 `8 m5 |$ s) _6 }
        from_acct = args[0]* C9 P! u/ k" }( H5 i
        to_acct = args[1]
, _5 Q7 z+ x* o7 m1 T" B        ont_amount = args[2]  }- F! _* T; p  ]% z& Q$ n* o
        ong_amount = args[3]7 o5 m3 K' D7 ^' h
        return transfer(from_acct,to_acct,ont_amount,ong_amount)7 r0 G7 {$ w% R2 @  F* b
    * O7 M8 N; a2 ^4 w8 \
    return False
* Y" A( P& N2 w2 Odef transfer(from_acct, to_acct, ont_amount, ong_amount):
; N0 l9 O0 t. P! Q    # 将base58地址转换成 bytearray格式地址 8 D0 _4 U" D$ \4 n2 o
    from_acct=Base58ToAddress(from_acct). j8 n1 s8 O8 D
    to_acct=Base58ToAddress(to_acct)/ A0 z1 x: w, k; D; w5 z: `. e
    # 验签,调用方必须与转出地址为同一地址
& r* S0 J9 t: Y5 A$ I6 s1 T# o    if CheckWitness(from_acct):
  ?, s* q5 y5 [# _9 K/ M1 E        # ONT转账* _7 Z: H! T( Q7 d6 q: f
        if ont_amount > 0:
+ Z" Y( z0 I  S: `8 \  m! D            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数- U. G6 M/ m$ c# L
            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账8 Y! Y: V. b3 B( l2 B
            if res and res == b'\x01':
& _  }6 k. e! _+ Z                Notify('transfer succeeded')( U0 C. B! m( U3 J/ r( h
            else:& a- n8 L7 Z9 I/ V" P
                Notify('transfer failed')% k: g- g5 `  R  O# O4 Y
        # ONG转账,流程同上
: _. {2 O  \3 R8 o( O        if ong_amount > 0:1 V. P1 h8 W+ S" c: R8 }3 c' R
            param = state(from_acct, to_acct, ong_amount)
) f4 H& t$ e5 u( R6 N            res = Invoke(1, contract_address_ONG, 'transfer', [param])
% R0 y2 q, I7 W( j. j% A- ~            if res and res == b'\x01':
( B. F3 i$ m( ^% ]) f* J                Notify('transfer succeeded')( E( J8 U! ]7 h% M* _
            else:9 k$ ?3 J+ w9 I5 u  L+ j$ r" I+ s% r
                Notify('transfer failed')% a" v* \: x4 f  D; K9 M5 c
    else:7 v4 i3 U2 X2 f: B. h
        Notify('CheckWitness failed')
/ x! M$ z/ W0 u# f! w% }3 p1 q( Y$ H' e: R) }5 H' U* i+ M; F
03 SmartX 实践0 c5 w+ M* F: [7 q' M
接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:, c$ W( N6 S! ]: |% r$ Q; j7 Y; y: a

  V' V6 i6 x% z4 \4 F8 W编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。
5 r5 K8 ]( n! _( T# t7 m( ~6 l( z& W5 L  O! D0 w
& T& U% {# j5 N, H
部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:5 i& ^9 h' P, {: J
' e1 S; q4 p, Y
) t7 c- [% W; c

) `3 u) p! m' F/ k- T执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:- N- Q( H/ u5 b$ M
$ T  R" ]1 S: k/ _4 ^# p7 B1 b

/ D4 u9 c# i$ Z- k' P转账成功。当转帐参数设置正确时,执行 transfer 函数将转账成功。上面所填的接收地址中将显示出收到的代币:
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8