Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语
, V% Q& `. P! n1 l2 Z, @上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:
3 d, Z" P% ~. v同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:8 }! m# [0 \( x6 K
下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。
* w, p* a! ^" ?02 Native API 使用方法
! a# f/ ^1 }# k! V! }同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数, Y0 Y3 M. f: x' @5 |- z
from ontology.interop.Ontology.Native import Invoke; _" R& f5 h- u7 H( g% r$ P$ M
from ontology.builtins import state" N% C3 C* d8 }, ^$ @/ d- u9 O
2.1 本体原生合约列表! {. r( u, M$ Z6 g  l* b
目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:
8 B5 \" d; n' m( s; m9 ~3 M
- h5 e$ A+ f2 t/ l  K" O- c& u在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。) [) |  v+ Y& S4 s) f! ]. z9 ]7 c
这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。
4 c9 I# ]' l+ N# K) v" d  Pparam = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额
6 @, C( A, |3 A, i0 V+ g3 nres = Invoke(1, contract_address_ONT, 'transfer', [param])
: l) x8 L  @  H2 w( ^2.2 转账合约代码: S1 n% L2 y5 G. b
下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:
, H2 L0 X( q+ V3 ^5 ?7 v定义合约地址变量 contract_address_ONT,contract_address_ONG;4 V) P8 b4 l% c1 N  E$ ]# k
将转出地址和转入地址从 base58 格式转成 bytearray 格式;
4 G) q  n7 C; @  H, A4 R验签,确认转出地址与合约调用地址为同一地址;7 p4 V  J8 ^: H2 s7 S  A# |8 ~
state 函数封装转账相关参数;, K. J2 g: \2 E+ C; E8 V
Invoke 函数调用 ONT Token 和 ONG Token 原生合约转账;
/ k+ x8 Q4 ?$ F7 O6 Z通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。, Q, z% B( ^) T2 J; Y9 T
from ontology.interop.System.Runtime import Notify, CheckWitness
+ Z' K; `) d! e; s- \9 nfrom ontology.interop.Ontology.Runtime import Base58ToAddress6 K3 j$ _6 P' F6 @. w
from ontology.interop.Ontology.Native import Invoke6 z6 i. R7 f3 d4 }2 B2 v) S" [
from ontology.builtins import state
9 T* ~2 w2 `) J# contract address
+ B; J% T# @7 E- dcontract_address_ONT = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
/ ~) v, I# X0 _! k5 l8 xcontract_address_ONG = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')
3 k1 r" L) ]8 m! Hdef Main(operation, args):
# @9 Z/ w9 ~4 v1 X# k  G& j    if operation == 'transfer':
+ k4 s% u" J* U1 j4 j% i$ Z        from_acct = args[0]
7 L! M( x( o: X        to_acct = args[1]% L+ s2 E2 Y; E8 J
        ont_amount = args[2]) A; [% {" m- m( ^
        ong_amount = args[3]
8 n0 d( s0 c7 S/ Q5 I5 o        return transfer(from_acct,to_acct,ont_amount,ong_amount)
& C4 }: Y9 \0 r, |" m1 B    % i. ?6 [- P: G
    return False$ V' ?9 C" V6 c+ A7 B
def transfer(from_acct, to_acct, ont_amount, ong_amount):- b! q0 g$ D4 b! I; Y
    # 将base58地址转换成 bytearray格式地址
! L0 u+ j7 M" p/ B7 x& V    from_acct=Base58ToAddress(from_acct)% G2 }4 c6 E2 N: g  r+ c( I! v# ?
    to_acct=Base58ToAddress(to_acct)- |# d$ }5 |: Y" Y! ~
    # 验签,调用方必须与转出地址为同一地址
8 O* [6 ]8 X# g% o- X  n    if CheckWitness(from_acct):; Z% S7 m7 u; L! c
        # ONT转账
4 ~" G$ v0 J  B9 U        if ont_amount > 0:% L( _6 ?7 P( x+ \. n# ~& J
            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数% G2 @7 p# l* w) b1 \4 C# m/ }9 t5 O
            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账/ i4 J5 i6 ?4 @! m2 ~; w# n) c# I, S
            if res and res == b'\x01':6 S3 x; W; K* C8 \2 q6 H  f
                Notify('transfer succeeded')# L2 }4 h: M: r1 f
            else:
- z1 f" x6 P- P2 }3 p; x, ?                Notify('transfer failed')# O. U1 @7 M' G/ W6 u# K# j
        # ONG转账,流程同上
5 ^9 ]8 J5 {1 @# b$ L. V. f  o* E        if ong_amount > 0:
9 l0 d4 U+ x3 n" @( i% a; v; W7 a2 S            param = state(from_acct, to_acct, ong_amount)( c  m! o4 }4 x. w- v* [* U+ v
            res = Invoke(1, contract_address_ONG, 'transfer', [param])% ~, z* f; G  `1 N2 U) z
            if res and res == b'\x01':: a+ R. P( d1 R( q( W5 J) R
                Notify('transfer succeeded')2 M  ?' W- C  b
            else:
+ y! p" e5 h: M1 C1 y& g                Notify('transfer failed')! D3 Z# F# O  P. q% {3 v+ ?# m
    else:7 q+ n' s7 I  o& K# J
        Notify('CheckWitness failed')
. u, q0 Z4 a) X2 X& e/ }+ c' K+ ~0 L# L; U3 [
03 SmartX 实践% X0 O/ t' i8 `
接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:
7 E  |. Q1 h9 @2 L3 V4 T9 H: s4 b* R' S7 {6 M, d" i
编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。, x) h2 v* k/ |

8 q$ ]6 |: t6 c: J4 Q; Z6 a5 D! b8 i& c# i0 `! q4 _8 ?
部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:/ i. t$ c. K2 y6 |+ ?

+ t# F" N, D. m6 a* S& e/ z' Z; x+ {" R

$ X# @, [' e: Y$ S执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:5 {$ S# D1 F7 D. g! c( \
$ p  h5 ]2 R/ _# \1 `& ^

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

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8