Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
01 导语4 C6 q! @: K' s5 I! W) x" V) d
上一期我们介绍了本体 Python 智能合约的合约执行 API,本期我们将讨论如何通过 Native API 来进行本体原生合约调用。原生合约调用最典型的功能就是合约转账,这也是整个智能合约最核心的部分。Native API 只有1个 API。用法如下:
8 q/ ]! A( z# h! h) s' z8 E同时,使用 Invoke 函数需要内建的 state 函数辅助来封装参数,用法如下:
" \: T# ?6 t' a下面我们具体讲述一下这两个 API 的使用方法。在这之前,小伙伴们可以在本体智能合约开发工具 SmartX 中新建一个合约,跟着我们进行操作。跟以前的API讲解一样,在文章最后我们将给出这次讲解的所有源代码以及视频讲解。
- m3 g; G9 B; V4 ]4 W9 J0 v* p6 w02 Native API 使用方法: Q$ r- H/ C4 G5 P
同样,使用这两个函数前需要引入。下面两条语句分别引入了这两个函数4 q- V3 b! i  s6 F. R# m8 s6 L
from ontology.interop.Ontology.Native import Invoke
1 D3 C7 Y' n$ i. P5 Dfrom ontology.builtins import state
) f# t( N. `! c/ X3 w2.1 本体原生合约列表
) A5 [. X7 m) k% B1 a: ~目前,本体可供使用的原生合约有六个。以下就是可以使用 Native API 调用的原生合约列表:
$ b2 D! v0 S7 a+ e9 f5 \. i/ X# R8 E  M4 G
在合约中,将合约地址转成 bytearray 形式传入 Invoke 即可。例如,需要调用 ONT Token 合约时,可以先将 ONT Token 合约对应的地址转成相应的 bytearray 形式,再进行相应的 Invoke 函数调用。在进行 Invoke 函数调用时,传入的参数分别为版本号,合约地址,调用的合约方法以及 state 函数封装的转账相关参数。
6 Z3 a6 b6 t4 U/ ]& L这里特别要注意的一点是,在进行 ONG 的合约转账时,所填数量是实际数量的10^9倍。 即,如果需要转10个 ONG,那么数量需要填为10^10。而在采用 ONTO 或者 Cyano 等钱包转账时,所填数量即为转账数量。
2 E9 |# z$ k5 F+ B6 B  Hparam = state(from_acct, to_acct, ont_amount) # 参数为转出地址,转入地址, 转账金额/ O: W# P1 P. T1 l/ r
res = Invoke(1, contract_address_ONT, 'transfer', [param])( m/ }/ T  ]% G
2.2 转账合约代码( X7 D' {) U0 v
下面我们给出一个完整的示例,演示如何使用 Python 语言来实现 ONT 以及 ONG 的转账功能。下述代码以传入的转出账户和转入地址参数类型为string为例实现该合约。另外,也可以以address为类型的账户参数进行传递,从而达到节省调用Gas费用的目的。该合约代码流程如下:& K7 e' E& A4 v+ r0 r5 r, y1 u
定义合约地址变量 contract_address_ONT,contract_address_ONG;
1 k" p8 H) h7 o4 Q. Z5 H将转出地址和转入地址从 base58 格式转成 bytearray 格式;6 @) r" g  _9 H* Y" @
验签,确认转出地址与合约调用地址为同一地址;0 d; ^4 q2 t* k0 n( m2 T$ U
state 函数封装转账相关参数;. L# q& C* I. y! N3 P% d2 [! P- ~% K
Invoke 函数调用 ONT Token 和 ONG Token 原生合约转账;9 B# D/ b& C; [1 {/ J
通过返回 res 判断转账是否成功。返回值 b’\x01’ 为成功,成功则推送事件“transfer succeed”。( _2 `/ P7 }; d
from ontology.interop.System.Runtime import Notify, CheckWitness
2 k7 d* R. H: O5 N! dfrom ontology.interop.Ontology.Runtime import Base58ToAddress
3 A2 G3 r+ H$ a0 b7 Wfrom ontology.interop.Ontology.Native import Invoke3 H/ e( d, f, U/ D
from ontology.builtins import state7 I1 V! u: {6 l" s. R$ `
# contract address
1 b. h4 f) x9 X: }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')
+ e5 n3 i" K$ b' Z, X0 R4 x0 Ccontract_address_ONG = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')" }# p5 z0 Y( ]9 p
def Main(operation, args):: Z/ v5 l: V; q% f+ _% m
    if operation == 'transfer':* P! e  m+ y# }3 E, m7 \# |
        from_acct = args[0]
0 H7 u7 L; N& U: p9 d, u8 x8 u. K        to_acct = args[1]* Y# |4 e% _& x1 D" W, q1 C& d. f
        ont_amount = args[2]
: j8 x0 A8 c: A+ I. l        ong_amount = args[3]5 U' m1 z5 a+ D" @( P1 b
        return transfer(from_acct,to_acct,ont_amount,ong_amount)3 z) {. f3 v) j
   
" n" o% ?9 n3 o    return False# z$ I% x6 J9 p. [* m, S
def transfer(from_acct, to_acct, ont_amount, ong_amount):3 F* U4 l( a  j* D
    # 将base58地址转换成 bytearray格式地址
+ u" o$ N' P* {" ~    from_acct=Base58ToAddress(from_acct)% W1 {0 f. u) Q
    to_acct=Base58ToAddress(to_acct)" _& m) i" M8 f+ a8 U# s
    # 验签,调用方必须与转出地址为同一地址! X) E0 |/ [6 ~0 j$ P2 i; V
    if CheckWitness(from_acct):
" {+ a2 L+ i9 r# t4 u        # ONT转账
+ w: L0 j7 u* A& ~6 }+ q4 L+ i        if ont_amount > 0:0 h" d( B& P" w, N5 q
            param = state(from_acct, to_acct, ont_amount) # state函数用于封装转账相关参数" s. U2 _0 v) K1 h2 ?0 `1 D+ C
            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke调用ONT token原生合约转账
. b5 X3 _# S- j8 J. E/ m4 P            if res and res == b'\x01':
; u5 g( O% f& X3 e+ k                Notify('transfer succeeded')
. f# k$ y# j* K7 A; z1 @            else:
$ A5 q3 b- m+ c4 s                Notify('transfer failed')( u- q( p! I2 q9 S' R. p5 `
        # ONG转账,流程同上' T' P, C% ?' k0 X2 z
        if ong_amount > 0:$ z/ x2 u7 R7 e, r  F  z" B
            param = state(from_acct, to_acct, ong_amount). `( z2 t+ C6 u, r3 ~& d
            res = Invoke(1, contract_address_ONG, 'transfer', [param]): ]1 K9 Z  p0 B) ?& E9 I) Y
            if res and res == b'\x01':# a) k  K8 q2 c% j! {+ d+ [" k
                Notify('transfer succeeded')7 ~9 a* z+ H& K( u) o! t1 s
            else:# J3 F) x0 U' ~
                Notify('transfer failed')8 I  E+ n* S7 r" e& f; W( Q3 F' W6 y
    else:. q- L% B+ ^$ t' s6 t' T
        Notify('CheckWitness failed')
  B' e1 _4 q, G! [( b" I  _2 d
, o( p1 k7 C# K  e$ f6 Z& p: [03 SmartX 实践( I  e2 }) |4 M; p
接下来,小伙伴们可以在 SmartX 上进行操作,动手编译和运行上述提供的合约示例代码。具体步骤如下:/ l5 V& o, h. |2 ]0 T6 S* ~

# G. y& e, O4 z; U, j$ ^( i  a# z编译合约。首先在 SmartX 中新建一个合约项目,并将代码放入该项目中进行编译。
; ]7 k$ W8 L5 r+ X- q  ]9 f4 R9 C& z& T/ D5 o( K
+ g. H" C- q& C- }5 C. C1 A* \$ G
部署合约。部署过程中如需申请测试币,申请地址为https://developer.ont.io/applyOng。部署结果示意如下:
1 t) y8 v1 ^( @, n( _5 h
$ ~2 A+ w2 Q( q' J
, b+ q, A. g. O  l8 x2 W& G& o
: b; r# |- n- a& F3 B+ Q执行转账。执行 transfer 函数进行转账前需要进行相关参数设置。在该示例中,需要填入发送地址、接收地址、代转账的 ONT 数量以及 ONG 数量:% a5 ]/ x1 u2 }' x* Q' L6 g3 S6 D
+ z2 u5 E! u$ m8 f4 F. A; W$ g! C

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

本版积分规则

成为第一个吐槽的人

放弃六月们 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    8