Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语) z% k9 j" R1 n; V0 k4 `! b
上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:
# w+ h! f4 M6 O" ]$ c9 m- {0 ^" U7 M同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:
) L6 b9 w* f' w2 ]下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。- d" d1 b7 v9 y# q
02 Native API 使用方法
' v/ f  H: J; p2 A同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数# U: I* w) _+ y; o; ?
from ontology.interop.Ontology.Native import Invoke. n+ P! x. q) x  j
from ontology.builtins import state! ^  ]6 o& J1 `, ~2 H. G
2.1 本体原生合约列表# G1 `: G# B8 a6 f! k1 v
目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:
" Q1 ^$ u, g  o
, s( M% k# i1 ^9 O) L! w在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。$ ?; @/ d* f" F; r1 `
这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。9 Z7 m( h2 W4 B/ A
param = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额
4 m! m9 E$ C; V" a0 q8 G! _  Ores = Invoke(1, contract_address_ONT, 'transfer', [param])
6 B5 J) n# T: B; w1 j0 m/ \# t2.2 转账合约代码
! K; B! k% u$ Z# A/ d1 O2 V# s下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:2 }( S  b, z& {5 Y
定义合约地址变量 contract_address_ONT,contract_address_ONG;8 _$ I% @% u0 O& L& R
将转出地址和转入地址从 base58 格式转成 bytearray 格式;
4 ^5 q+ H4 x, [' W" E" E8 b/ F验签,确认转出地址与合约调用地址为同一地址;
: @3 q; F8 }7 w! K6 R( `8 ?( Jstate 函数封装转账相关参数;
) M" |8 W# N: {3 y- h8 mInvoke 函数调用 ONT Token 和 ONG Token 原生合约转账;+ p1 e( ~( H; G& T& Y# Z
通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。
0 x; b0 p1 C5 Afrom ontology.interop.System.Runtime import Notify, CheckWitness
5 {) B) T5 i5 j) F8 D7 ]( Ifrom ontology.interop.Ontology.Runtime import Base58ToAddress
6 g# K* V7 f* s- q0 Efrom ontology.interop.Ontology.Native import Invoke
# }; c1 K$ V2 i' g5 g3 tfrom ontology.builtins import state
5 X- o9 l4 u9 @% y' W. R, e# contract address 6 v3 R% X* h/ }* t6 V" }4 I9 q
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')" V' Y; c& E- y0 B, m# A. 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')
7 v3 R- Q) a1 b$ O! Rdef Main(operation, args):
; _. F0 G2 h/ j4 q! _    if operation == 'transfer':
3 |& K  S/ k" a        from_acct = args[0]( V  G$ J% C1 \' T3 N6 W
        to_acct = args[1]
! x: W/ F  E) k        ont_amount = args[2]( k2 n. ?: j1 ^, h- d
        ong_amount = args[3]
! ^+ r8 G$ q, G        return transfer(from_acct,to_acct,ont_amount,ong_amount)' S+ v! h  B  R0 d: u$ ?
    . n+ J; i# V2 u* n7 l; j# t
    return False' _3 n4 ~5 q; c
def transfer(from_acct, to_acct, ont_amount, ong_amount):6 W% }; A% t$ r: ~
    # 将base58地址转换成 bytearray格式地址
" u1 A3 O7 n4 N    from_acct=Base58ToAddress(from_acct)
6 j6 n4 a. V8 b    to_acct=Base58ToAddress(to_acct)5 L4 _- G# z# p; Q9 W6 f$ A
    # 验签,调用方必须与转出地址为同一地址6 \9 {* P3 N" }( P4 ]0 Z
    if CheckWitness(from_acct):
7 O8 Q/ |8 }/ D, i4 b" o# @0 }        # ONT转账( ?4 T+ S4 r0 H3 Z8 W0 r
        if ont_amount > 0:
, @/ E: ^; E5 J1 [2 g( a( J            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数
0 b8 ^$ [  a  y7 d- p6 T$ c/ d            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账
7 z6 f! j6 G7 H1 m: G            if res and res == b'\x01':
6 k. y. W% m! ]6 u1 z" X                Notify('transfer succeeded')
' Y6 {2 S4 @7 Q- r  A            else:, j% y0 G2 C3 N0 t: L! b, ~
                Notify('transfer failed')7 I* ^/ X- S1 C) u3 O7 I5 o, s  q9 K
        # ONG转账,流程同上
2 S: @' p0 L2 C5 X0 I        if ong_amount > 0:9 y1 W) B, t; x/ L6 `
            param = state(from_acct, to_acct, ong_amount), y) \7 {; \% ?; {
            res = Invoke(1, contract_address_ONG, 'transfer', [param])
; `. [' o9 P: k. N( \% u            if res and res == b'\x01':
, J8 D1 B( U! f/ Z0 |                Notify('transfer succeeded')
3 h  Q3 z8 w$ K" z. ^            else:
1 E. F, K* z  L; R5 O                Notify('transfer failed')
! e, b# S; s! ~- i    else:; [8 ]+ I8 j% G0 s" A+ W
        Notify('CheckWitness failed')
3 i/ S) q/ Q  l& _( a1 K* s! k1 M9 J3 V7 y, T7 S
03 SmartX 实践/ B- y% E. p* y! ^6 G; M/ K
接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:8 j- H3 q7 c2 q  l, r* M$ r
' i" R- p# U8 @9 J& G! U
编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。
! _8 d" G: Y, H* j1 C6 V4 i. T6 ?1 M, E0 j
8 l  T5 w/ _& y
部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:, Z* X$ ~& u; o: x6 x4 Z+ l( T! X! L

6 V; c" U- a. }. |% r& V, Z* g: ~% z& d3 Z- Q- o1 v% u) b

8 C+ `; S" R* T  n1 M, H% o执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:
! T* s$ D, ]7 I  u& A3 V
4 _4 c' x9 }  N/ O# `
% C  p7 F: `* s# N! y9 I8 O转账成功。当转帐参数设置正确时,执行 transfer 函数将转账成功。上面所填的接收地址中将显示出收到的代币:
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8