Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语9 F/ j3 `1 K/ c3 s* X
上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:
( K0 x- P! O* n9 f$ ]# }同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:
( A" T& \( B+ @4 o* x下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。: Z8 H; r& H. s. Q7 u! B
02 Native API 使用方法
  q% Q& M0 r3 l, ?) S( g; h同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数) z- r' z% p% @; X" T. \
from ontology.interop.Ontology.Native import Invoke
( \5 e0 G6 b# y( F! Mfrom ontology.builtins import state
+ e0 j! p* X/ Y5 B# \: o2.1 本体原生合约列表
" `3 t9 {9 B& N* Q2 K. Y: I: }目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:( @7 k6 r$ w% c5 e
# D0 B0 T- V: s) _; J: u
在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。
5 ]9 h- a# d7 R2 ?% X! Z这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。
3 y# ?* G- ~$ A2 f3 @9 t, D* eparam = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额
) ?4 Z) W: {& m- y' rres = Invoke(1, contract_address_ONT, 'transfer', [param])& C) G: B  m) `. h9 D% d$ i* N
2.2 转账合约代码! m9 @# j1 ]2 |% w0 e7 s* [+ o
下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:
3 G% j5 @! v0 n: H9 ~! h定义合约地址变量 contract_address_ONT,contract_address_ONG;
+ ]5 l  r, U: R- o/ ?. R2 S将转出地址和转入地址从 base58 格式转成 bytearray 格式;! H1 N4 n- Q7 f8 k2 }5 l
验签,确认转出地址与合约调用地址为同一地址;. n4 Z8 [6 P3 m* E: ^* n; o
state 函数封装转账相关参数;
( k. n: H5 b; V8 \; C2 v5 U# q; jInvoke 函数调用 ONT Token 和 ONG Token 原生合约转账;
( \* p* t' m; t4 r通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。
& H# J2 m5 K9 c2 [" z8 f' Cfrom ontology.interop.System.Runtime import Notify, CheckWitness
. H* u4 B1 X( o' P, d6 ?  jfrom ontology.interop.Ontology.Runtime import Base58ToAddress
0 Q# p' J/ w3 V6 Ifrom ontology.interop.Ontology.Native import Invoke$ b0 X: s, t5 Y! g: P
from ontology.builtins import state
# R$ |" \/ D( w& C4 \# contract address
, W6 @1 l3 E) rcontract_address_ONT = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')/ a& n& W1 B% b3 k3 `: x) f  L
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')1 L9 T/ c6 u; q2 f$ `
def Main(operation, args):
, N. i3 z! @0 N; C( F6 n6 N8 Z    if operation == 'transfer':! n* e# X# z$ R& B8 y% C
        from_acct = args[0]+ Q1 q9 N: c2 i8 E0 ]
        to_acct = args[1]5 q0 Y: t% N1 t! e
        ont_amount = args[2]
3 n4 w; k; D) A. {        ong_amount = args[3]
( s+ I- n8 ?" P# l        return transfer(from_acct,to_acct,ont_amount,ong_amount)$ @* z) e  H' k; G: M* r: J
    # @* i7 W- Q; e2 a+ q
    return False' g( s" s& Q2 ?# \/ m" m$ I
def transfer(from_acct, to_acct, ont_amount, ong_amount):
; X3 X0 s5 C- C) b    # 将base58地址转换成 bytearray格式地址 & _+ |, J$ }- I% {( `
    from_acct=Base58ToAddress(from_acct)6 ~6 B; q  b! d* V9 ]4 F
    to_acct=Base58ToAddress(to_acct)
4 @0 ?! J% V6 m  H# U/ n2 ?    # 验签,调用方必须与转出地址为同一地址
$ A( n3 B( U4 @7 E9 T: `3 s# k    if CheckWitness(from_acct):; L: o  n% [. d% I- W
        # ONT转账
$ \* k' p. r! H; r  k        if ont_amount > 0:
" B6 w& |" B  i% d2 _* H, Q            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数
. b0 u% C2 a2 P            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账
5 j3 c2 \; T1 L/ x            if res and res == b'\x01':
% M6 ?  N, O2 j1 w. r" {+ |                Notify('transfer succeeded')
% w/ F" N1 p0 U: X            else:
- k. p# v, ?- V, s$ h; R                Notify('transfer failed')
# {7 u2 |+ u& E) S6 m* G1 A1 F, i: D        # ONG转账,流程同上
( a/ Y# _9 T1 R3 V        if ong_amount > 0:
& Y1 p, ~9 |$ \- ]) u5 a            param = state(from_acct, to_acct, ong_amount)0 D% I0 U- k# i. j5 D5 K1 L
            res = Invoke(1, contract_address_ONG, 'transfer', [param])
6 m7 B/ m+ o# F/ u            if res and res == b'\x01':
$ |  K, R- _# ~: c+ N! Q" m9 g# P& J: q                Notify('transfer succeeded')0 B3 o% g' s7 o  h3 N
            else:: u1 @7 d+ a) R1 t( ]- _% w( n
                Notify('transfer failed')
( Q! u$ D: \+ c6 Z  Z    else:0 i2 Z! ?% z) |  s& J
        Notify('CheckWitness failed'): N6 V+ [, m6 \7 q$ G
1 @6 z. `  [9 ?, ~$ Q
03 SmartX 实践
/ e0 c: T" f1 F( i! ~; N3 P3 M1 _接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:9 k' ~+ A7 H3 H' K: w+ r

& q  G9 Z) R9 R, t- e% M编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。" M2 \8 p& t. l' a) b: o, w, D

  ~0 N; C: J4 q6 l+ d' b1 K+ K: q$ A0 ?  n) r6 p
部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:3 Z0 w% o/ Y* h

" `, r* |3 B8 Q9 N
5 j) i- }( E* J6 B2 [- O! b! z9 d& @5 S5 [
执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:
5 l: b3 V/ b( |3 S* F! e& S' f
2 V& B5 g8 _2 B( i. S2 l8 E2 p! b% Z& c: M6 A  ^
转账成功。当转帐参数设置正确时,执行 transfer 函数将转账成功。上面所填的接收地址中将显示出收到的代币:
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8