Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语$ Z4 M- `) {0 h. |. r# ]
上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:
- I7 Q0 f! T1 S+ C2 [5 c+ l同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:- z1 C& n$ v1 V" `+ z
下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。+ o' [  `7 `9 a+ L  q, U9 Y& \
02 Native API 使用方法
" ^! {5 w5 O4 A! D2 \同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数: W1 |3 r  i- Y# n
from ontology.interop.Ontology.Native import Invoke9 S8 V" F4 I7 m2 @  u
from ontology.builtins import state8 G2 t% ?1 y& B6 b, T8 |4 W! I
2.1 本体原生合约列表
5 Q2 r7 |( v( H! a目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:
  n) R3 |8 s% f9 {
# b( F6 N1 i3 _' i. T# z在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。: Y5 m' ?6 g. c& @
这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。
5 c6 \1 Z5 y. s% a& ?param = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额+ y5 K: `$ o' d
res = Invoke(1, contract_address_ONT, 'transfer', [param])
) m" z5 e+ m+ g# T- o# N2.2 转账合约代码
' h, p5 {8 G1 W* b: \& p' ?下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:
: {7 l8 c( B! W; Q$ d4 a. G定义合约地址变量 contract_address_ONT,contract_address_ONG;$ U# B! U- P0 H" h' {+ y
将转出地址和转入地址从 base58 格式转成 bytearray 格式;8 ?5 N4 D( c. o1 n: f
验签,确认转出地址与合约调用地址为同一地址;6 b( l3 _( |+ y( }
state 函数封装转账相关参数;
, v9 j8 b' l. F. L* z% \4 M, H; x% w. kInvoke 函数调用 ONT Token 和 ONG Token 原生合约转账;
9 \+ N- ^  N  P- |/ x7 Q通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。. ?/ Q% q8 f- J- q
from ontology.interop.System.Runtime import Notify, CheckWitness
8 h1 F. t( N" s6 z8 o( z9 Afrom ontology.interop.Ontology.Runtime import Base58ToAddress
2 q6 U* o/ e+ [$ p+ o& ^from ontology.interop.Ontology.Native import Invoke+ F* s5 q5 m' n
from ontology.builtins import state
2 D0 ?  `" o+ {  i) d# contract address
9 ?/ Z  g3 b" [7 P3 |0 [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')# a( `' W/ T/ \0 k! r  j" U3 T
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'), a" X% V2 o( C1 s
def Main(operation, args):6 p5 \1 x) Z) r9 Q3 y9 q% }
    if operation == 'transfer':: {& t) I' H) g, j3 \. Q; t! T
        from_acct = args[0]
8 Q8 U6 \  f) n4 f0 A- |2 y% u        to_acct = args[1]$ R% v1 v/ Q% E. c$ G, M, ^
        ont_amount = args[2]
1 [# m* p4 O1 R/ V7 k5 j( N        ong_amount = args[3]
- @/ c! V5 |0 Q2 e0 H" t& _        return transfer(from_acct,to_acct,ont_amount,ong_amount)/ F, j: ~8 x. B) j0 }1 x
   
7 _9 j8 g% e% g# z+ p9 ~    return False1 c# y9 J0 C" E1 _$ z5 q4 ?
def transfer(from_acct, to_acct, ont_amount, ong_amount):
9 `" L3 y8 A9 G* r0 R- U( N    # 将base58地址转换成 bytearray格式地址
. Q3 a5 |0 i; x6 m+ l    from_acct=Base58ToAddress(from_acct)# v( K& i# p9 v" y
    to_acct=Base58ToAddress(to_acct)
# t# W9 b5 u( q7 g    # 验签,调用方必须与转出地址为同一地址
7 [6 E' T! ^" v- Q: W, A9 {    if CheckWitness(from_acct):
% i9 S  x: J/ u1 |5 t4 f+ t+ ~        # ONT转账: d' u/ o# W; z! z3 @
        if ont_amount > 0:
' z: j0 W, g0 W3 P) ~* @- C! w            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数
0 Q- c* L1 m3 f* c( }3 v            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账9 e, s' @7 [; b+ h  Q. P
            if res and res == b'\x01':
! m' B2 z% ?9 }5 m' S) `1 F                Notify('transfer succeeded')
8 w# o% K* a* z& H9 I. [; [- f: T            else:
" B4 W; D5 o! F$ [4 W- W, B" _                Notify('transfer failed')
, u5 t3 ~) ~9 G  [( W$ v        # ONG转账,流程同上, c) ?, a  D$ E( J' Y
        if ong_amount > 0:
: R- k3 |. s% ?- ~            param = state(from_acct, to_acct, ong_amount)
4 P" g6 K! L7 ?3 z! k            res = Invoke(1, contract_address_ONG, 'transfer', [param])) Y3 N! t" B# l
            if res and res == b'\x01':
$ J2 k& ?" d6 |                Notify('transfer succeeded')
; P6 `# t1 P( f/ p            else:7 J) V, K( [) a9 U% J) K
                Notify('transfer failed')# U7 i" u, a2 G; I# ?1 j* z
    else:
3 E2 n( r0 c/ [- O2 F4 W; U        Notify('CheckWitness failed')
3 w7 a( A  y$ |  o
4 t" m8 I& V; t4 D: g% T03 SmartX 实践
0 p* k# j- v) _( C+ }接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:
2 g3 I/ @& o/ m) \! O7 v" X% K4 \
- n- g7 D9 n. n7 s& J编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。
/ I7 Y$ \$ f9 G8 m9 M: ^" S
/ L6 h0 M! m9 R) g, g0 @$ h2 X* f$ Y* @$ L5 S
部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:$ s! U# ]7 v! I. L

2 L) ]& u" x2 r
! a. l" y# q+ m0 I  d3 D4 |# |$ ^$ Q+ Y3 q
执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:& h$ s: ]- ]$ a& b5 @( `
9 }- G( m8 L+ o* Q8 t- e

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

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8