Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语
/ N- K. t7 C, ^9 n上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:1 }# K1 B5 t( H  U; B+ h9 L+ p
同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:* N0 s/ }( t) a- w
下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。' ~4 X" x! d; Y  @
02 Native API 使用方法
: |+ @3 \1 X! g# o  ~同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数
, H4 Z7 o6 r5 A# bfrom ontology.interop.Ontology.Native import Invoke
) }/ P4 t' {1 F( hfrom ontology.builtins import state
& A! t% W% q" e2.1 本体原生合约列表
$ p' a" W& Y5 Q. J: q! D4 G目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:
6 N4 B; K0 Z" l; v
  f/ N, b- [7 \, r7 z1 }: D在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。7 @' e. ?5 ]6 O1 x9 J
这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。
7 l& C- W7 }+ [/ P& O* [param = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额
& B8 {0 b0 j/ q- g! {1 k$ Eres = Invoke(1, contract_address_ONT, 'transfer', [param])& z4 n; j- [3 x, w: k* w
2.2 转账合约代码
: t7 n' d! m3 |" W8 y下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:
) L" k' ]2 h, u- W定义合约地址变量 contract_address_ONT,contract_address_ONG;0 N: u( j! ]! q$ J
将转出地址和转入地址从 base58 格式转成 bytearray 格式;/ N: O# \4 J6 A7 Y% G, n
验签,确认转出地址与合约调用地址为同一地址;
7 C" G6 T6 n( O% Wstate 函数封装转账相关参数;
# ]" s7 Y9 m+ r$ v, `- T5 k7 rInvoke 函数调用 ONT Token 和 ONG Token 原生合约转账;
7 E: F  ^* n: \. A. U# k通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。
* u+ I8 E7 I0 _: G! Pfrom ontology.interop.System.Runtime import Notify, CheckWitness* e% D) ]! E- A
from ontology.interop.Ontology.Runtime import Base58ToAddress
0 _( E  D& b' J6 tfrom ontology.interop.Ontology.Native import Invoke
; j1 c9 E* a% I9 j, T% Mfrom ontology.builtins import state
: f; i1 K5 v# Z  m( x. @# contract address % @% F2 d& P2 T1 }
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')
/ u9 F- v8 w) Acontract_address_ONG = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')" j; a5 J! _6 Y5 E
def Main(operation, args):
; D+ g6 w/ R- R  `' t8 X    if operation == 'transfer':
4 I: F" [/ y' p% |: _        from_acct = args[0]
$ ]. {6 a  y8 o: h4 m. S        to_acct = args[1]
0 l" p8 R6 X% l" M2 E/ R        ont_amount = args[2]2 L! x, D1 b% p+ G4 s  p9 Y
        ong_amount = args[3]$ C5 s9 O$ W6 R  G
        return transfer(from_acct,to_acct,ont_amount,ong_amount)
$ b, y. E8 q  g$ v. W  w    ; E  Y% F7 s) {7 z. x; B
    return False
# ]7 `$ E6 ~* ?2 M& t* Cdef transfer(from_acct, to_acct, ont_amount, ong_amount):- Y9 x, z: l8 P7 m3 f3 d8 Z$ N
    # 将base58地址转换成 bytearray格式地址 5 u- [; D  b$ w  t. H
    from_acct=Base58ToAddress(from_acct)! m' x. P9 I& G- ~1 q: W
    to_acct=Base58ToAddress(to_acct)7 t4 C! P: K5 n- M( L" e1 m
    # 验签,调用方必须与转出地址为同一地址
/ z& T5 l3 g" j/ J5 n* h2 e2 ]    if CheckWitness(from_acct):4 P+ v  l+ i$ c7 _' c. u8 r
        # ONT转账
6 }# n- q6 _0 T        if ont_amount > 0:
" x9 n% E; E, z$ Y7 b$ B            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数' {. U% y8 z9 Q2 m
            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账
/ z' A; V) y7 _9 ~8 \            if res and res == b'\x01':
4 u% n! O0 O/ D) d' Y                Notify('transfer succeeded')
" r) m! z6 [+ y* r, _6 ]5 l* J6 m, n            else:# Y6 D1 o5 ?* `" n* n. }
                Notify('transfer failed')
% d, x) K4 [. E; T) M' {        # ONG转账,流程同上& w, v- n5 U8 @0 `# H
        if ong_amount > 0:
  Q5 C. S: S6 F* C- f& t7 U$ H, a            param = state(from_acct, to_acct, ong_amount)) ~8 L& R3 c" @7 c! n" Q! R7 n! O
            res = Invoke(1, contract_address_ONG, 'transfer', [param]). [( k- `: F0 k9 H: g2 a
            if res and res == b'\x01':* M& U6 s2 P5 i0 B8 H1 e; R
                Notify('transfer succeeded')
7 T( j/ ?4 C1 H8 ]8 _% `& d            else:
3 L# z4 Q' W( ~( i- M                Notify('transfer failed')
  Q; [# Y0 U9 n; V9 [# s    else:
* E+ L6 i! h! C        Notify('CheckWitness failed')
' H' t9 P+ e* Q
6 l  m3 m+ g$ s) I03 SmartX 实践+ K* C0 f* d5 u9 T3 T
接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:
0 O4 [* ?7 a0 S1 V/ U+ g: `: q, O* ^8 C6 i; ^& P/ D9 n+ A
编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。" s$ q! j8 Q8 D

+ H" \: Y) Y  P. D! @1 V: \7 E/ R4 p/ o! t( e: ]: d/ @
部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:
! L/ B& @' d- J6 H% j; [/ j
! B1 s; y  P: @4 {* }" a0 X4 @1 d0 C
* M3 p0 t* O4 ]! Z9 n6 `
执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:
7 t+ ^% T! M, E
% `1 U3 X7 ]: S+ Q: s* u' S2 B- i, M7 V: v
, J: N! G: G; `' E9 J转账成功。当转帐参数设置正确时,执行 transfer 函数将转账成功。上面所填的接收地址中将显示出收到的代币:
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8