Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语
4 G/ s/ }- Q  [/ U6 q. k+ Q& M9 F上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:
1 D/ @7 `3 U) m同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:
; r. d( K, @( U' {% D  f6 y3 y下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。
+ @! j) g2 n, X7 F! B" g02 Native API 使用方法
% @" j/ d$ i& m+ Y$ |  h5 Q7 v同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数5 G. M' F0 X7 F4 ^
from ontology.interop.Ontology.Native import Invoke
2 Z8 O2 S, o" Q; M: C2 cfrom ontology.builtins import state
! _7 \, ~) R9 o5 t; W% a2.1 本体原生合约列表2 q, u% y0 s  c; }) a) |$ l9 r' p' B
目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:6 U% G5 t. o/ f& Z

5 m* Y# R9 @) s) W: j4 ?在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。. q0 A' f+ B) \4 G+ A1 _" \
这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。. K, ~! ^+ Q% e# {' H# C4 ^+ Z& ~
param = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额; g2 k6 B1 i& D9 Q& c
res = Invoke(1, contract_address_ONT, 'transfer', [param])% E. Y  _& x4 }7 a2 u8 Z+ S, `' i) @
2.2 转账合约代码
6 G1 C7 o2 }) M' G2 c  L. B下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:2 G2 d" q/ p( A2 N* i4 P
定义合约地址变量 contract_address_ONT,contract_address_ONG;
4 h2 a" \& R( D6 G% s: ~4 q8 _将转出地址和转入地址从 base58 格式转成 bytearray 格式;
  z0 U& X/ j1 q2 O7 L3 [验签,确认转出地址与合约调用地址为同一地址;4 D9 z' J2 f+ \/ j
state 函数封装转账相关参数;  g4 ?: e/ U) Q
Invoke 函数调用 ONT Token 和 ONG Token 原生合约转账;9 s% y$ V, {0 P# M1 h; O
通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。& H8 N9 A7 u0 [+ N
from ontology.interop.System.Runtime import Notify, CheckWitness
8 A* P) J1 h* H7 \from ontology.interop.Ontology.Runtime import Base58ToAddress# L/ Y5 f) P! V# f9 v8 ], h
from ontology.interop.Ontology.Native import Invoke' y3 }0 F  Z: Q6 ^9 o% L3 F
from ontology.builtins import state8 q: d6 a  X0 [0 K9 `1 M
# contract address * K1 X+ ~6 E; E
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')
+ ]: q8 Z8 J1 k5 ]+ @# x1 Dcontract_address_ONG = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')
! Y2 @- O! V" I/ z1 }# P6 n/ Fdef Main(operation, args):
, j+ x; c; }* k* l+ G" v: m/ F5 x" r    if operation == 'transfer':/ B( @9 `" D3 U
        from_acct = args[0]6 A; L1 [0 F& t
        to_acct = args[1]
* P" ?6 ^8 L' d        ont_amount = args[2]' I$ r5 ?- s/ l; c! Y5 h) W/ a
        ong_amount = args[3]  l6 I, \8 m5 Y* ~4 a
        return transfer(from_acct,to_acct,ont_amount,ong_amount)$ t9 f$ l8 O5 J9 u
    : E: U1 K* k4 _! {- x7 j; x
    return False$ d- ~8 o9 C* z4 ~$ Y
def transfer(from_acct, to_acct, ont_amount, ong_amount):2 D6 [6 K" t, F2 {- G
    # 将base58地址转换成 bytearray格式地址 , @3 I+ _$ s6 F; r. R+ e4 q
    from_acct=Base58ToAddress(from_acct)
  F" m( p0 K. L/ _    to_acct=Base58ToAddress(to_acct)
1 G$ x4 N( w' A, Z4 Q    # 验签,调用方必须与转出地址为同一地址
1 X& G1 R7 I5 B7 b9 k" p" i    if CheckWitness(from_acct):. o& i; [# d3 W; J9 c6 g# e6 d
        # ONT转账/ _+ G* {) I3 f6 G5 q& b" \7 A* J4 g
        if ont_amount > 0:3 p0 Z$ l9 F: ~6 i, \6 o
            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数7 d2 F% P7 q$ S7 c+ N$ n4 o3 W
            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账
# ^: P0 j# S7 I* t$ m# m. e            if res and res == b'\x01':
+ N2 S  {. U; v- A                Notify('transfer succeeded')
  u. l3 E3 B. L' ?/ x            else:
, F: K" @* ~" p% \, ]) p( w                Notify('transfer failed')
8 c  C5 M7 @$ n( y- h* w2 A7 j; B        # ONG转账,流程同上$ c: x: p% j& L
        if ong_amount > 0:
! R) L$ w; S- {9 a8 D) P) E& f            param = state(from_acct, to_acct, ong_amount)
# ^) [0 E% \/ Q+ C1 @* `5 ~9 n2 i            res = Invoke(1, contract_address_ONG, 'transfer', [param]), @" g, D9 O* g2 Q; Y  H0 w* o9 }
            if res and res == b'\x01':$ p3 I. c5 t0 O8 d4 J' v6 _( C
                Notify('transfer succeeded')# s7 w& v( r0 `/ J9 l
            else:
. V+ h! ~6 n: F1 I. }6 ^7 L                Notify('transfer failed')0 j& }% e* X4 d. o
    else:
' T1 x+ [. {- {! Q0 g        Notify('CheckWitness failed')
) t$ Q. C& B7 ^, \5 j: L
) y4 h1 Z- W' V  P: W) f" `03 SmartX 实践
( A! Q: w; i. ~+ r% e" ]. i接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:
; q- G2 E9 A9 m& k4 q' r% Y0 X, W+ o; s7 E
编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。" z- d8 j' F" d) p3 e( @0 j  j
  G) q/ p+ z+ T7 D  n

$ S, d% H7 B' L. h3 \+ A* U: }, j; ]2 H& X部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:8 D* [4 U  x; Q2 ~- {5 E# p% z

8 H# \$ A% z2 n  {: W' B- ^$ ]. k) L7 {# `1 c6 f8 j& `

% a) [1 s, Q; T- R$ s9 j执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:6 n5 N! T( q! r. m5 ?( y$ J( L
3 \+ }4 @* U! e

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

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8