Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语7 S, b. H8 d6 i; D
上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:
& c( E, M1 q4 b, ]1 {同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:$ V/ {$ A' b2 w- h
下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。
0 B, \; x; W+ i4 u- D& L* E02 Native API 使用方法, ^' A! @) E% o) g8 k9 q' K  ?
同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数( F  a& i2 J3 l; L! H; L6 v4 j, r
from ontology.interop.Ontology.Native import Invoke, E0 f3 x0 c% N$ f
from ontology.builtins import state  P5 j0 v3 w) I0 J+ o# q2 o
2.1 本体原生合约列表
3 B9 k" ?! l3 w) N: m目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:/ l% h- W3 M6 t9 g' D
9 r8 h5 P; ]9 M; U* l/ A. }
在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。: B! [) x% i+ z- g& v
这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。  {8 T* B! X$ c/ d
param = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额: k' w5 `0 K! L  J; b
res = Invoke(1, contract_address_ONT, 'transfer', [param])
6 f9 y6 g* ?. I" F, m, b2.2 转账合约代码+ l; m0 u( \" \2 ]  N! J4 c. g! k
下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:9 }$ i! c: N8 P+ K1 N. h
定义合约地址变量 contract_address_ONT,contract_address_ONG;
4 H8 M6 L: L/ J. z将转出地址和转入地址从 base58 格式转成 bytearray 格式;$ w/ [9 k) p" G% I
验签,确认转出地址与合约调用地址为同一地址;7 g* Y1 B5 `% g1 z" I
state 函数封装转账相关参数;
& e7 \1 z# C; U# o" Y" EInvoke 函数调用 ONT Token 和 ONG Token 原生合约转账;6 \5 z. X+ n: Q& V
通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。* T6 B2 A0 h2 }/ W2 l* A% Z
from ontology.interop.System.Runtime import Notify, CheckWitness
& d3 F  U/ p/ S$ Ofrom ontology.interop.Ontology.Runtime import Base58ToAddress
; q5 c4 l+ U' D) R1 M( H5 Jfrom ontology.interop.Ontology.Native import Invoke, `) C3 V6 q: e, N
from ontology.builtins import state
6 e2 {, h, U. T( L) f3 n# contract address % a- J2 u. T7 g: v) b
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')
8 S6 }; a, ]/ G: [) 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')
% U: S7 J# _8 `( L& _% Jdef Main(operation, args):
+ o& J4 U/ N! t# ?1 |3 T. [    if operation == 'transfer':
9 w! @4 C8 z* Z& D5 B) e" ~        from_acct = args[0]. D) H6 L: U, H" u6 A- v& |2 Y
        to_acct = args[1]" S& D$ G7 `3 @: v9 J
        ont_amount = args[2]
$ A5 ?0 W. D1 e7 a7 t2 q        ong_amount = args[3]% Y0 J* I5 Y2 a) h5 ]3 B& X
        return transfer(from_acct,to_acct,ont_amount,ong_amount)# J) }: O4 |! d5 l. `0 [4 c" \
    # s+ W/ E0 A5 w& A! S
    return False
! t/ n0 n. N/ ]7 odef transfer(from_acct, to_acct, ont_amount, ong_amount):2 Q7 O7 n) f& j+ a0 ^; \, p! ?
    # 将base58地址转换成 bytearray格式地址 " J6 B# y& ]# j- }# Y1 x
    from_acct=Base58ToAddress(from_acct)' j2 s- J7 D+ `" ]5 K( `
    to_acct=Base58ToAddress(to_acct)1 H2 D: `7 |# u, E" }
    # 验签,调用方必须与转出地址为同一地址
5 C9 [" j" }, ]    if CheckWitness(from_acct):0 `# N5 U4 n7 ?. a8 X
        # ONT转账
5 r2 g; P9 |  Q, p7 R, r$ Z1 M        if ont_amount > 0:6 x0 c, U! T3 O
            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数8 A5 ?4 ]: k3 c9 f$ q; _
            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账" |  @. G+ w* s& x7 ~1 Q
            if res and res == b'\x01':& U: l( ~) t1 Q
                Notify('transfer succeeded')) ?) U2 V7 `; F# G* n
            else:
( Z8 N0 ~6 ^4 {9 z- C                Notify('transfer failed')
, \- Z/ e9 ?1 V        # ONG转账,流程同上
( l; D6 B* v- E1 B# E1 t1 N0 W        if ong_amount > 0:4 G: J5 q5 P: z9 a
            param = state(from_acct, to_acct, ong_amount)- C+ x' @8 ~: ]
            res = Invoke(1, contract_address_ONG, 'transfer', [param])
3 _! e! Y+ ]/ Z( Z8 S            if res and res == b'\x01':) }  T; j/ n9 @5 [6 Z& }- W  \
                Notify('transfer succeeded')7 h& p% r2 E' H# U+ K
            else:
! C* d2 B4 Q& X7 J/ a                Notify('transfer failed')
4 k- T! K# m* Q* x- D. Z    else:
# ~3 Y. O' k0 G/ {        Notify('CheckWitness failed')
6 x( O* b; K; N" K2 P& s
6 k( P2 G, `4 v; C0 U03 SmartX 实践
' T; m( ]* |- @2 p接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:
+ e& F# E  ~! s8 h
* p* c7 R# l5 c9 N' B- n8 a编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。
+ M5 l9 D) G: k8 t. W! T8 j/ S/ q! V7 n: u1 d

4 o' _/ a6 H: g6 C# i部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:
- _$ Q0 Y: J$ ^8 m: X; n
& t( ^/ q3 _+ I7 s8 I+ {# Y( _" @* f) y  m8 L- f* _

" y  ?: n) R+ ~- C% F2 a8 K执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:% q' x% T" T: L/ ^

& b: C$ |. l/ `) X7 x5 v* y! I. g3 |& k# ], c0 ]' v- u
转账成功。当转帐参数设置正确时,执行 transfer 函数将转账成功。上面所填的接收地址中将显示出收到的代币:
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8