Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语! U2 z5 j: `! d+ C0 f0 g
上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:
: j* B4 F' o* o/ y! }同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:" a( P* y5 T. Z: H# W3 O) c
下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。
8 d8 k& m  J& _" v02 Native API 使用方法, M: b5 q3 J7 N2 W
同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数/ n0 V$ O9 F0 q9 R6 l
from ontology.interop.Ontology.Native import Invoke4 p# ^- l! \" u) y
from ontology.builtins import state0 e' ]% ~/ _% B
2.1 本体原生合约列表
& U# c6 q1 G. \3 H目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:
- f; _1 e4 o- B- z! Y1 R. [: S6 e" F  O# i
在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。: x% C" `0 i" ?2 I
这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。2 W& \2 [( U5 X+ n" m; ?
param = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额: Y0 F! H8 g3 ?3 V: e9 z% l
res = Invoke(1, contract_address_ONT, 'transfer', [param])
1 V5 w" q% `' a# q3 W8 l2.2 转账合约代码9 q" R5 |6 b' F$ o1 w- E/ r
下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:! v9 b1 p" l' I
定义合约地址变量 contract_address_ONT,contract_address_ONG;$ p. m1 U, ^8 }; r" n4 ~9 V
将转出地址和转入地址从 base58 格式转成 bytearray 格式;7 H! U' \( E( `2 P; Z
验签,确认转出地址与合约调用地址为同一地址;
6 G* A6 j! w, w; {- r0 \; vstate 函数封装转账相关参数;, a; F  h( v. W
Invoke 函数调用 ONT Token 和 ONG Token 原生合约转账;! u: ?) _: X4 B$ W2 x* c1 I
通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。, L! k# M6 a9 O' F* c: J# \' z( C
from ontology.interop.System.Runtime import Notify, CheckWitness0 y1 N) w" _8 B# I; [3 Q/ _# A6 M
from ontology.interop.Ontology.Runtime import Base58ToAddress6 ^$ b0 o) d  v2 }! X3 f3 J
from ontology.interop.Ontology.Native import Invoke' }. J. z& u5 D/ P2 s
from ontology.builtins import state# z( ~; D! f$ ]/ |
# contract address * u. z2 p( a. G& m/ S5 s6 o
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')3 l8 W; J9 A' |) k- J+ X
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')  R. Q, Q0 ^7 j& c
def Main(operation, args):
$ m2 B6 U9 U$ O' Q7 Y- S8 Y    if operation == 'transfer':
  b$ \0 e$ l# S" |3 |  M! u        from_acct = args[0]! R; h, T* Y, J
        to_acct = args[1]
5 ?' L% e% e# |: b. N9 T        ont_amount = args[2]
1 u/ |# V5 ~; m; C. K  A" p7 @, o        ong_amount = args[3]
7 b; P8 L9 N  E: j1 ^        return transfer(from_acct,to_acct,ont_amount,ong_amount)
+ b/ _2 n2 U% ^    4 m6 ^/ D" P1 j. M% E, n
    return False- [: b( D  F6 ~; V- E
def transfer(from_acct, to_acct, ont_amount, ong_amount):
6 p( ?/ c3 z1 A5 Y% U6 U- H    # 将base58地址转换成 bytearray格式地址
% W* W( G  d0 s    from_acct=Base58ToAddress(from_acct)6 W5 G% L& ~0 _0 {- y, w/ R
    to_acct=Base58ToAddress(to_acct)3 N; X! K+ [9 Z, Y& {9 ^  E
    # 验签,调用方必须与转出地址为同一地址
$ ], H5 m# r, I# n7 \2 ]    if CheckWitness(from_acct):
! O+ Q& [3 ?" S! n5 v8 M5 }0 u) p        # ONT转账! `# s  d1 e1 n+ C6 h# t+ ~
        if ont_amount > 0:" e/ S: ^- R8 R# S: v2 L
            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数+ W! ~. A- q- v& {/ w) H. i
            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账! u% y1 _- H( x/ f
            if res and res == b'\x01':
' H' O. e4 }8 V$ F0 u+ j$ ]                Notify('transfer succeeded')
7 v& |/ ^  `4 S            else:
0 ?. [1 ^* o1 ~                Notify('transfer failed')
3 u# b' U' u% N+ w2 n        # ONG转账,流程同上; @* G5 W) K+ p! n0 j' V, k: L
        if ong_amount > 0:
# i/ U4 [, l( `  j3 t/ A            param = state(from_acct, to_acct, ong_amount)
* F0 c% V) b" a5 r$ S% G# J            res = Invoke(1, contract_address_ONG, 'transfer', [param])3 I& R7 q9 L/ M  D$ y
            if res and res == b'\x01':
1 b( {6 F3 }/ x1 a& ~% I                Notify('transfer succeeded')
$ L/ U$ f5 A) E. r/ F3 i6 q3 D            else:
) i' H: v& F/ i8 K) T) U; s% Z                Notify('transfer failed')- g2 O5 P! L! c' W0 q0 ]/ Q
    else:
- P4 Z+ S# F& y4 `% A& g1 W& p        Notify('CheckWitness failed')8 k4 [+ `( }/ v8 V1 Z/ j2 j9 a

2 |/ h# o  q9 W; p9 R03 SmartX 实践0 q# w+ H; f6 l% `
接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:  B3 z" w. ~# S; ^& _( X5 f- w! k: H$ B

) l0 T; n$ R( c: t: {/ Z& h; J编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。7 I. _% G) B7 k0 ~- o* h; {" C) i

0 U8 \8 ?3 Q  y0 E  n7 h2 Y
4 y. L/ f0 S# J# _部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:' ~; {* u1 J: p# [+ L  [& x

, Y1 [* X' ?3 ?9 e9 T8 R: R& |5 o( }2 a; ^1 S

6 b* w+ W% q: U' j2 L执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:
' L* z) X+ c  {: `
9 P9 z$ g! f7 x5 V7 l7 p1 F% D5 S: G3 T, K
转账成功。当转帐参数设置正确时,执行 transfer 函数将转账成功。上面所填的接收地址中将显示出收到的代币:
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8