Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语" J3 M0 m3 b+ @- t
上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:
: {  y2 |/ _! ^7 e同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:
# N/ x  K5 T$ g6 Y# b; \下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。
7 p6 B# y) C% d02 Native API 使用方法
/ K! z  _* z: B同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数; S) o3 C: c1 Z/ J6 D4 @8 W
from ontology.interop.Ontology.Native import Invoke
7 a+ w9 n7 A: Z" f' afrom ontology.builtins import state0 E3 m$ ~* P3 `
2.1 本体原生合约列表4 y3 P- A, k& G9 B
目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:) s) c; E. Q8 T

4 X. k' M3 k) `* L: U在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。) g. l. g5 k% }
这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。5 h; I4 K. m2 X
param = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额, L+ g, ?$ o/ E: r7 m. T
res = Invoke(1, contract_address_ONT, 'transfer', [param])
/ W% l$ G% H; q: g/ E7 n2.2 转账合约代码
/ R# S- f) N2 D/ N' H4 `; w下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:7 _! e6 _; u8 z% J% }
定义合约地址变量 contract_address_ONT,contract_address_ONG;
. H" i1 F. v2 g/ o. p% r" `将转出地址和转入地址从 base58 格式转成 bytearray 格式;& i- ~' _! L! {
验签,确认转出地址与合约调用地址为同一地址;$ I) r, _4 d- I0 e
state 函数封装转账相关参数;
; ]& r$ L$ b  \# ?3 mInvoke 函数调用 ONT Token 和 ONG Token 原生合约转账;9 N0 T5 p6 U, w; W! c
通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。# [& p: z& m6 W' A1 W
from ontology.interop.System.Runtime import Notify, CheckWitness* [, h, G# n1 j& `
from ontology.interop.Ontology.Runtime import Base58ToAddress
/ c: e- F( E( l" K! j% u7 Zfrom ontology.interop.Ontology.Native import Invoke
% ~5 k+ \+ o2 h" ~* Afrom ontology.builtins import state# p* X2 @+ z" T6 I$ C5 l1 ^' f' {
# contract address 5 ~! d, z& _0 z$ o& M) L
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')
5 N' H! z. T% b( c8 h& R3 Bcontract_address_ONG = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')
) f7 y- g4 V4 ddef Main(operation, args):: M- N( ?' a( o4 P
    if operation == 'transfer':9 L, W$ }- B- ^
        from_acct = args[0]
% @( c! J- {1 n! W' @% f6 q        to_acct = args[1]& _( ?- E+ |# m0 K4 q
        ont_amount = args[2]" _3 k9 ?8 r6 f
        ong_amount = args[3]3 O/ S& g! S7 s! B
        return transfer(from_acct,to_acct,ont_amount,ong_amount)
! K/ a) N; t+ k1 ]3 X/ _- B   
. D7 @3 Q  ]' ], F# e) G    return False
  P" J  L& A# ]" ^6 \def transfer(from_acct, to_acct, ont_amount, ong_amount):2 b2 Y( A9 ?% `7 B  H5 ?
    # 将base58地址转换成 bytearray格式地址
) w' G" t7 j; p    from_acct=Base58ToAddress(from_acct)
" P3 f3 j7 h/ t, n    to_acct=Base58ToAddress(to_acct)
2 _8 Q) o" f1 H. o) r" i; n    # 验签,调用方必须与转出地址为同一地址  I  T' E5 ?, P8 j6 t; V) P
    if CheckWitness(from_acct):
7 _  t2 y( f) W) _; @        # ONT转账( @+ u1 e9 x5 {( W$ i: @
        if ont_amount > 0:8 G% M2 K2 t- t/ t% m. Q! f
            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数
& v: l$ c. w5 _9 H' }* o# ]            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账
5 o: y$ H" d2 f; t8 B            if res and res == b'\x01':
8 j  S  s4 p* v2 _/ u# q                Notify('transfer succeeded')3 @5 Z' @4 e' K. O+ @9 F" J5 ?# Y
            else:: b/ S, d& N6 }3 w$ ^, @# K
                Notify('transfer failed')
$ t" s8 c1 d' A+ @; s        # ONG转账,流程同上7 o# |# w7 b# _; L' N1 \# J
        if ong_amount > 0:% }& E7 {; l5 {$ y1 z; w
            param = state(from_acct, to_acct, ong_amount)
2 n* X; K# e* A  C            res = Invoke(1, contract_address_ONG, 'transfer', [param])
+ n9 n, B2 a+ S7 q            if res and res == b'\x01':" K' _0 `2 u1 B( f5 T! ?
                Notify('transfer succeeded'); L2 Y# A% l) d2 T
            else:. C" Z% \+ z3 h6 m5 Z* w
                Notify('transfer failed')
" l) _6 w; S+ Q. A  A* Y    else:
* h) z( |5 V' l' m$ s        Notify('CheckWitness failed')8 D7 V: N; w, t9 B( A! O
8 ~) M7 R9 k5 u0 E' \
03 SmartX 实践
  r: Y0 j- ?9 e' q接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:0 c2 t; Q9 E) Y" s1 I4 |+ ~/ w$ n

) n/ O# ]3 O, M+ l& L* v& j编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。% B$ v8 S  \! L- u! s1 Z

* s  C  l( \/ O: U. x6 o4 p( l$ G# ^5 q% R  `. e2 p- w
部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:1 m7 W4 H4 x; {

4 z9 `' O' l- m9 {9 c1 ^( j# O7 O! C: {+ X7 ?% E+ ^( N
8 e. L% _/ _7 Y/ }
执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:
- t' J% `* _6 |; V0 V  ~" Y$ B8 |5 [$ L3 \/ n" p! y

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

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8