Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语+ y1 Z( L0 E. W: J' I) [* P
上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:
; s1 R8 G; I. j3 d  g同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:
3 I' B6 m8 k7 S5 d7 T下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。
' {! {! p- D8 h3 I/ ?! A02 Native API 使用方法
, `- a/ M% D* y: v同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数, \$ l) a$ Z) W+ S
from ontology.interop.Ontology.Native import Invoke2 K1 Y, ]6 z- A1 G" h
from ontology.builtins import state* s' R& p$ s: y& c( B* @' C; l: }, f
2.1 本体原生合约列表
4 X% W7 t8 u& o5 F3 r7 g- q- i目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:' s# U2 [/ Q! ]8 @; |

5 L( ]6 |+ q7 z& m( o2 E在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。! F& Q% t/ B2 y
这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。
2 s. s/ Y7 t' fparam = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额
0 i/ t6 U: ?8 I7 X% U  Yres = Invoke(1, contract_address_ONT, 'transfer', [param])) x: g+ R. z2 O
2.2 转账合约代码) U7 @8 k8 a2 X/ _4 x! N
下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:
( l% M& p6 _' K) Z, b定义合约地址变量 contract_address_ONT,contract_address_ONG;
5 P/ M3 O, `& e" c* i+ N7 T; G' N将转出地址和转入地址从 base58 格式转成 bytearray 格式;
3 E! x% ]5 Z; R, t验签,确认转出地址与合约调用地址为同一地址;5 F' E- F2 N+ y8 e
state 函数封装转账相关参数;
: R! ?" ]8 P; [Invoke 函数调用 ONT Token 和 ONG Token 原生合约转账;# q$ R, K5 x( Q
通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。- ^; a' W& V& j- c* v
from ontology.interop.System.Runtime import Notify, CheckWitness" d- d9 N1 w# y& n( \& E" ^# }& I
from ontology.interop.Ontology.Runtime import Base58ToAddress
6 N" A0 }  N# y3 P1 Zfrom ontology.interop.Ontology.Native import Invoke
" s) ]* i5 N& ~  Z& J' K* Ofrom ontology.builtins import state% ?0 U% a0 g( m
# contract address
* D& H3 x0 V/ w$ Vcontract_address_ONT = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
8 c/ u" n& K3 |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')3 a2 V6 j- ?# [* j/ _! z
def Main(operation, args):
# S* G+ i) P% l9 H+ W    if operation == 'transfer':
) z& r5 X0 c0 E6 X        from_acct = args[0]* J) o& E+ p7 j% d& ^8 \
        to_acct = args[1]. v8 t( _+ Z7 j
        ont_amount = args[2]
+ [4 b( d) p) f5 ~1 _        ong_amount = args[3]5 P0 L( y4 J. O9 a
        return transfer(from_acct,to_acct,ont_amount,ong_amount)$ R8 k4 p* T& C# S" a4 f
   
7 Q5 t7 Q% x8 G7 ~3 o# W! K    return False7 a& c3 Y5 n( t) h/ J/ N
def transfer(from_acct, to_acct, ont_amount, ong_amount):
% y$ Z$ p& }( Y    # 将base58地址转换成 bytearray格式地址
- `" k6 e: c$ Z    from_acct=Base58ToAddress(from_acct)
# s- x" s' Y$ a9 j5 e% n    to_acct=Base58ToAddress(to_acct)$ c! `3 U) d* M! L; I& q+ ^
    # 验签,调用方必须与转出地址为同一地址
' \8 _9 j" a3 F6 D% C! S    if CheckWitness(from_acct):
+ u& |* u% [; v        # ONT转账* q- d8 U. G) I9 \$ g1 s2 S  b% S
        if ont_amount > 0:
9 `0 E" ~% W' n            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数( J  |/ E7 y8 z- d* K
            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账) p6 O% D  G* V) o
            if res and res == b'\x01':
' l; e7 a( T/ y. y5 Y# E                Notify('transfer succeeded')
, N+ E/ U( }: f7 G            else:5 K9 ?3 w4 d- l. p) G: r
                Notify('transfer failed')! a# {: M  b; Z; t1 v7 G
        # ONG转账,流程同上
% |* }  g+ V9 U% `& a& p        if ong_amount > 0:
7 E! I& o2 Z& b) ]+ Q+ s            param = state(from_acct, to_acct, ong_amount)5 D) D3 J8 j2 G, m6 d' N/ v
            res = Invoke(1, contract_address_ONG, 'transfer', [param])
5 B4 g, T4 E+ }7 U            if res and res == b'\x01':+ L7 o# B/ a* t4 f5 S8 q0 L
                Notify('transfer succeeded')
7 R- U5 a3 Z& \1 z' g            else:
2 Q6 V2 P+ e# Z/ u- J, u% T$ ]0 o0 R                Notify('transfer failed'): E) W$ i( H/ b/ r1 i7 ]
    else:& t3 r7 v7 M# X; N3 V
        Notify('CheckWitness failed')" n+ R/ O4 J9 F& l! l7 a, ^, |

3 |7 R( ^* B, Y7 Y, W03 SmartX 实践9 x2 d0 Q( q( V* L; ~2 `1 \+ J( b) T
接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:$ {6 {- h" }7 A) R3 M
: T. j9 z, Z  j+ y/ Z/ P2 W* C
编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。9 l4 r) O- S4 }8 k8 F, @4 ^$ E& j

% ^  V2 G9 u% X1 k8 S/ ^
6 b, |" V+ T- w0 G, l部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:
+ c; L# j4 H! N- \5 o9 H6 G/ d" f# x' A" _& a

, k1 n; L/ S8 Q  g; g* o
- w" P+ v5 C0 a) e执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:
+ j6 B0 X2 e* W2 p! h3 J. z, ?2 Y6 F( x( x

* M. X# M4 e2 s$ `2 l; z5 e! F5 h2 G% R转账成功。当转帐参数设置正确时,执行 transfer 函数将转账成功。上面所填的接收地址中将显示出收到的代币:
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8