Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语" l0 N# T* D8 ?+ f3 [% e3 L
上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:3 D0 s' y6 h1 }+ s. u" K
同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:
' F( f7 ]5 R* X下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。
+ M0 o- X) s* x02 Native API 使用方法
6 d5 F3 u" W2 S! g同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数& j- y& q# Q6 \+ N* w0 ]/ I
from ontology.interop.Ontology.Native import Invoke' A. P! ~. c% Z5 w
from ontology.builtins import state
& N- Z# o/ r0 {( `2.1 本体原生合约列表
# W3 q/ p5 s" W: C: n' M目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:) g  C& F8 i0 W

6 J. J1 h' w; W在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。0 W0 H; C$ h$ F0 F9 b, R2 I& _
这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。
+ `  M) z* i  n5 }5 B" D  \& O: E. w# `param = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额
5 v7 `/ a% p6 Cres = Invoke(1, contract_address_ONT, 'transfer', [param])
3 k/ _3 E( q% f9 }  y: y2.2 转账合约代码: Z3 f* W  b$ g0 o, R- C* w5 D
下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:
$ c# f8 H; p! z定义合约地址变量 contract_address_ONT,contract_address_ONG;/ B5 D- W1 o) m, o$ d* u1 B7 x) v
将转出地址和转入地址从 base58 格式转成 bytearray 格式;/ j+ Q8 N! z+ s( Q" @
验签,确认转出地址与合约调用地址为同一地址;4 z+ p: i8 ~. ]+ _+ G1 g
state 函数封装转账相关参数;' d( \) d# u+ ]% X
Invoke 函数调用 ONT Token 和 ONG Token 原生合约转账;( @/ [, J# \' x8 \+ i; l9 F
通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。
! o& U3 E+ g! O/ X; G$ Bfrom ontology.interop.System.Runtime import Notify, CheckWitness' w! C5 c6 l5 ]
from ontology.interop.Ontology.Runtime import Base58ToAddress# F0 ], x4 [+ q) e9 W' s- o6 j8 d
from ontology.interop.Ontology.Native import Invoke
) Y9 g; I" R) [1 Afrom ontology.builtins import state; @' X! P  Z6 H0 D6 D  t
# contract address
1 U+ ~) Z. b2 X* N; M" p2 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')2 A' p# C! b% x' {% ], \
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')+ R$ N8 O& W% j" P' B
def Main(operation, args):
' t* v& U$ F3 P# h    if operation == 'transfer':
0 \- r0 E5 a6 J        from_acct = args[0]
6 U% p6 X) P% R1 [0 m) ?2 I        to_acct = args[1]7 {% {; t8 e2 c- N) ]' p: t
        ont_amount = args[2]
2 i5 O7 K( z- Z        ong_amount = args[3]) [% j# K1 a6 C- n
        return transfer(from_acct,to_acct,ont_amount,ong_amount)
: @: k" n" V' t' {    ! i. Q1 U# H5 }$ a" {
    return False& k9 j: O9 l1 A  b$ K$ A2 _* \, m0 y
def transfer(from_acct, to_acct, ont_amount, ong_amount):
9 u( S" x1 m& x+ e2 M    # 将base58地址转换成 bytearray格式地址
. }* Y/ Q8 S; Y9 d* x" Q' n) L    from_acct=Base58ToAddress(from_acct)3 Q+ n6 n" a4 b  c" D
    to_acct=Base58ToAddress(to_acct)
0 Y( P0 @8 `1 E' L$ q' [  ?    # 验签,调用方必须与转出地址为同一地址7 B. @5 Y1 V, H' v
    if CheckWitness(from_acct):
* t3 a( D- z# W9 R; |  z# q        # ONT转账& M" f8 A- j0 z, d  R' l- r- ~
        if ont_amount > 0:1 S/ y, C8 \% S6 c) g
            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数
- X( A9 H! ~: M9 v5 f            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账( R! y1 C5 N9 `% ^$ q$ ^( _
            if res and res == b'\x01':. f* i% R& G% m( M
                Notify('transfer succeeded')
- m! C  T2 R, ~7 D$ I/ _            else:
9 p; n. c( G+ q1 b/ x                Notify('transfer failed')+ O9 y& u" R# s/ y( f3 u
        # ONG转账,流程同上
% o2 M# t- n0 m% y* Q. g        if ong_amount > 0:9 \+ f3 y& M1 |+ Y1 ~* U: m
            param = state(from_acct, to_acct, ong_amount)# U8 n" J! \7 \' Q
            res = Invoke(1, contract_address_ONG, 'transfer', [param])
  h  ^) ~# \, J) P$ ]  _+ w; z            if res and res == b'\x01':
8 ~; n3 j* B5 E* D                Notify('transfer succeeded')
- B# o# C% [. _            else:
/ a! a3 z* H( a0 }4 a) R7 s/ G7 m                Notify('transfer failed')* e. \( ?$ I6 g) [) L& R7 g9 u; E
    else:
( s# a+ C+ X6 T" w2 |        Notify('CheckWitness failed')+ U( @4 u; g) M; \! g5 f9 V3 h) o
( x( {3 J9 n# t( K1 N
03 SmartX 实践
. C2 z  r: O& O! ~; x' L接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:4 O' z$ R7 ?' P4 f0 O
7 x0 L# ^: R! t+ i9 A0 V$ ~/ C6 W
编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。- `( y! h+ ~+ V7 U6 g+ x

- x% B$ x, y5 g; x
; |" P! B3 n2 S' i" D& T4 o8 e# W部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:4 T! `$ Y' Y. [+ g! F: V6 ?5 r
, G7 O& d" p, ]+ s4 E; L6 g9 R+ n& l

* C8 [5 F- I6 a8 V# W- J, n# G2 W6 d; M
执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:6 i9 ], ?- q' Y
* M) e  I% J8 `9 W% a% c
' ?7 j0 e8 F* ^. \  F
转账成功。当转帐参数设置正确时,执行 transfer 函数将转账成功。上面所填的接收地址中将显示出收到的代币:
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8