Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语
2 a/ K$ w$ b4 I& ]+ B2 P) F上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:
* [. q0 V  D+ S0 b同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:
( j" V' g4 _  X* q' t下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。# P0 U. a- m) k( I; Q* `# Y4 t* O
02 Native API 使用方法) N  |- t( `2 K4 K
同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数
: ^6 J9 M5 V. M9 jfrom ontology.interop.Ontology.Native import Invoke
- e; X) B# T. V7 Bfrom ontology.builtins import state
) w, h8 b% A4 H2 A) }, K2.1 本体原生合约列表# h0 p( H, C5 P$ f
目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:
: Y1 f( W2 ?: c* x: \+ @. |4 ^1 _8 R' p) H* M
在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。9 {) C6 T0 I, W
这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。/ i, ~" p0 q0 }. l3 a; K
param = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额
& W$ f! C3 V% L; }% O  \res = Invoke(1, contract_address_ONT, 'transfer', [param])
9 E& j, G" O1 Q$ P2 l" r2.2 转账合约代码! @- E% R3 i5 @5 w. R' F
下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:0 e, j" w+ V+ ~
定义合约地址变量 contract_address_ONT,contract_address_ONG;
) g2 t8 D; k7 L9 e将转出地址和转入地址从 base58 格式转成 bytearray 格式;' O- a% S4 Z0 q' f7 G) e! P( q
验签,确认转出地址与合约调用地址为同一地址;: t# }8 P/ \$ @: O% f0 y# |
state 函数封装转账相关参数;  B' }! z' n9 t9 l9 X4 e- k2 D$ [
Invoke 函数调用 ONT Token 和 ONG Token 原生合约转账;0 l7 Q1 W4 Z: ^1 `, V
通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。& F; k( n. @6 G
from ontology.interop.System.Runtime import Notify, CheckWitness
/ n' m% ?& R/ Vfrom ontology.interop.Ontology.Runtime import Base58ToAddress
8 y& L+ W. g# w" G: d! Cfrom ontology.interop.Ontology.Native import Invoke) ?/ A% G# B& l( ^6 m
from ontology.builtins import state
  O, m4 l  x. z: s# contract address + ^0 B' x% H! q
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')( K: S) r+ G8 p( Z6 n
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')6 t7 Z% f: z* B0 A2 _* }
def Main(operation, args):
7 u. O" H: p' q3 {    if operation == 'transfer':
9 B: m$ q0 K" p        from_acct = args[0]6 y# |6 a; U, y
        to_acct = args[1]
. b3 ?" h/ |2 E# v; _/ v        ont_amount = args[2]
5 r# v, S+ }% Q8 E4 g+ g) D! U        ong_amount = args[3]- i! p( P/ z. G/ g0 j# R! b2 m
        return transfer(from_acct,to_acct,ont_amount,ong_amount)7 E2 [! M/ a$ S
    2 G! [# `( y7 _  Y/ w, U, D& w
    return False8 o3 G2 ]  s; z6 u, B  e' l: b: y
def transfer(from_acct, to_acct, ont_amount, ong_amount):
6 E1 A2 o/ B! p1 w    # 将base58地址转换成 bytearray格式地址
! v1 [3 L) K( g* V" d- W    from_acct=Base58ToAddress(from_acct)
; b7 I! k  e# y    to_acct=Base58ToAddress(to_acct)" |  x& y4 l6 }
    # 验签,调用方必须与转出地址为同一地址: B# w7 A% P7 [8 w
    if CheckWitness(from_acct):4 P& h" l, x* E
        # ONT转账& s1 C; B7 h* v9 W
        if ont_amount > 0:
& z" n% K; B- ]3 q; \            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数8 B! U. R5 s" J7 [& z1 p
            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账
- Y$ G# k) \' I4 z, ~+ W3 D; \            if res and res == b'\x01':
/ l7 Y$ @" S9 M! o( n, _  k                Notify('transfer succeeded')
' [5 g; a3 }7 R5 A9 i6 u  Q            else:
, [3 T/ v3 e' }& l% P6 a                Notify('transfer failed')8 ]' u/ |. \7 a8 K$ [
        # ONG转账,流程同上
; C, D; b. p# q; m) Q5 J# Q        if ong_amount > 0:4 A5 W) E# |. L9 Y3 `$ {
            param = state(from_acct, to_acct, ong_amount)/ C$ S. l, q' g: x$ H! A
            res = Invoke(1, contract_address_ONG, 'transfer', [param])
& E( @/ K: P/ T5 W' ?7 k. {            if res and res == b'\x01':
5 ]$ t) P: d8 k7 W' C5 t                Notify('transfer succeeded')
: k* [  A' x4 _5 `7 w9 `! e! n            else:; J& z3 D1 [7 M0 o2 L+ B& \
                Notify('transfer failed')
1 X5 h! H8 {# X  ^    else:/ A% {  U3 K3 w0 |5 V
        Notify('CheckWitness failed')7 ]3 R, G% p/ S0 U1 F
( y0 V- H/ D2 J, {+ f% `+ h1 U2 @
03 SmartX 实践& i" c" {0 P+ p' p# }' K$ W( p
接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:: [) U) H" r( e4 L$ y9 {
7 g% G. o# N$ c' y, ?
编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。7 J  T6 r, g! ^& D
  X% R8 o9 S; k- q. ~8 T
4 Y2 m$ W; e: C( W% y
部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:$ K$ D  y% Y8 X9 v* h, d
. U5 g: s/ P" ~$ ]% f: y. e
9 k4 {' J  U' ^7 p
3 B3 i. L0 g2 s
执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:$ S6 J8 C; |& Y+ s5 l) K

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

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8