Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语3 B5 p% L- U/ Z& U
上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:
* p' M% H  x& v2 h% Q/ N同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:# N0 o9 w: ~; _7 U$ o" \: H( a
下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。) N) ?8 D3 J' z9 T
02 Native API 使用方法
1 A, S+ |. P6 f9 P3 Q7 M同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数
* ]- u9 ]/ ?: m- nfrom ontology.interop.Ontology.Native import Invoke
: J6 \- p! x  z% ^& O+ wfrom ontology.builtins import state9 O* d/ t) S& O
2.1 本体原生合约列表
0 v  `; p0 d% a4 o' O目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:1 F$ o- F% z/ e, O

1 A+ u* L3 S9 e* f' l在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。4 s/ D& @2 y( y6 ~  c/ d7 p, `* g
这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。
2 s& i8 B& ~. u" Z. \param = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额
, W6 G; N* b0 @0 \9 a; r9 ?res = Invoke(1, contract_address_ONT, 'transfer', [param])$ N6 G' }9 Y; B- }0 c& x. Z5 Z
2.2 转账合约代码
. I/ l; X6 m2 @下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:: x  [% r+ F5 Q, f
定义合约地址变量 contract_address_ONT,contract_address_ONG;! k( l( v, C; G
将转出地址和转入地址从 base58 格式转成 bytearray 格式;0 y) S. f8 d, E: v0 c
验签,确认转出地址与合约调用地址为同一地址;# v3 h8 x$ s3 R; _  f* `' {& g7 ^( |: j
state 函数封装转账相关参数;
' T- d# O+ U# |Invoke 函数调用 ONT Token 和 ONG Token 原生合约转账;* l$ |+ g8 |" H' \. D0 U
通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。. O. w) I' }, T8 e4 C8 l8 e
from ontology.interop.System.Runtime import Notify, CheckWitness
: u4 e, C7 K0 @" M! Yfrom ontology.interop.Ontology.Runtime import Base58ToAddress
; S- l9 s( D2 ~from ontology.interop.Ontology.Native import Invoke4 u5 K! H7 r: B* [% G
from ontology.builtins import state3 w2 y& j* ^6 T: \/ c3 p
# contract address
7 t! [: ^' h; ocontract_address_ONT = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')- ~& k1 a7 E, |5 b& ?/ k  h
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. d' j( L3 a, k/ L3 x% c
def Main(operation, args):3 j) ?" `& u4 |6 ?9 m  B5 \
    if operation == 'transfer':
4 N/ f7 ]6 g% X- p+ b( Y        from_acct = args[0]
  ]- E! \3 J2 P1 x        to_acct = args[1]
4 w8 \! z3 c$ e- k$ i7 n        ont_amount = args[2]
4 u: \- F  F3 Z. H* U6 K        ong_amount = args[3]0 n* ^# O4 L/ q: f! r2 b
        return transfer(from_acct,to_acct,ont_amount,ong_amount)( \; d6 ^! R3 e% L, T( }2 O% }$ E
   
4 Q/ r/ d% ~3 [7 @- G" l/ l    return False* K+ f( l4 c1 \7 v$ B- p9 _
def transfer(from_acct, to_acct, ont_amount, ong_amount):
( a1 c5 [8 V) H5 c" H! T    # 将base58地址转换成 bytearray格式地址
8 p4 X. Y! N* q6 r    from_acct=Base58ToAddress(from_acct)0 I. W' G" U9 e2 K1 {2 `  A+ ^
    to_acct=Base58ToAddress(to_acct)# D3 X" d  c5 V/ J
    # 验签,调用方必须与转出地址为同一地址' P6 K' s" c0 u6 V& r% F
    if CheckWitness(from_acct):
2 `, f9 [+ D% L: c6 o: L1 T        # ONT转账
8 ~/ o4 W. r% k* J8 H/ F; `        if ont_amount > 0:! Z, S: l9 u1 ]; j% w
            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数
  H) D" \! J6 u: S) x7 z4 u) [# j  [; ?            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账
0 f! |' n! K/ o6 D9 i0 q            if res and res == b'\x01':
: ~. E) l; Q0 |* O                Notify('transfer succeeded')0 }/ u# v  P  K5 u7 z7 i! l" t
            else:1 K, w9 W# e9 {* }" {$ o
                Notify('transfer failed')$ @$ Z8 L/ q# \$ Y7 _1 I
        # ONG转账,流程同上
/ k* S- v# C+ _9 a$ W+ \        if ong_amount > 0:( y0 M6 Q3 S5 R& d/ b/ D
            param = state(from_acct, to_acct, ong_amount)* ?! o, z3 f0 A( q9 m+ P3 h2 t2 A
            res = Invoke(1, contract_address_ONG, 'transfer', [param])
/ L8 J  d; K* o: u0 y            if res and res == b'\x01':
3 o5 Q$ a4 H. ]: ~- u                Notify('transfer succeeded')7 P! a/ V! \, o' t, L" i5 y
            else:
+ \8 j# {4 P2 l! ?' Q                Notify('transfer failed')) m7 D5 @3 g: l, P8 m
    else:
* y$ D6 r/ o& P# c  E9 C        Notify('CheckWitness failed')
9 k4 O# q4 l  b$ O
/ G3 ~' A" u. f( s7 v- Y03 SmartX 实践
" l7 d' G5 y. U( f1 k接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:
+ {0 n$ H6 V7 A4 r' @8 [
$ o. F  R8 o5 s1 q: }( ]编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。/ I2 ~3 U  s6 G+ Z
8 x3 Y6 F5 Z4 M. l/ e
; l8 P7 w) i- V/ E! H; E! G
部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:$ T& L0 r1 y4 Z( \& {, [
+ i: b( D! |7 C) O. X
# T/ k4 Y" z! D( }( A

' ~5 H, a& `+ {; ]' |执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:* V/ d" c  V% w. C
0 q' P& t/ Q9 K& f7 {6 {1 _

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

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8