Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

使用智能合约实现自动分账

哈哈笑417
231 0 0
自动分账是很多平台都会用到的支付功能。很多互联网内容售卖平台都会跟内容提供者分账。比如:Apple 的 App Store 跟 App 开发者三七分成。很多平台都使用了支付宝、微信支付作为支付手段,但是要同时实现给内容提供者分账,却是一件不太容易的事。使用 FIBOS 智能合约可以很容易实现这个需求。
0 M7 E' L' _8 b+ R; p, B
: e6 m* t. w8 g: \文中代码已在 GitHub 上开源。https://github.com/fengluo/fibos-subaccount5 h6 e! v7 a7 U$ W7 n) @. \& r
  w) s1 K( w8 i& ]
设计思路4 H$ F$ [$ G9 M9 N, f
! ]' Z. Z$ X  {
在 FIBOS 转账是通过 token 合约的extransfer方法来实现的。extransfer方法在执行的时候会给转账方账户和入账方账户发送通知。所以用户给平台方账户转账的时候,平台账户就会收到通知。所以整体业务逻辑如下:
; B) w! w4 V% ]( U
( b! y3 f7 K! v' {7 @$ d) |        quantity: 10 FO
, A, K* ~6 o) V: x# P+ o' r: C4 a2 P  @5 \
        memo: 内容提供者账户           quantity: 8 FO
+ f. P7 A4 V3 r" A* y8 a8 U) J% V+ I6 G  Q
用户账户 -------------------> 平台账户 ----------------> 内容提供者账户' c$ i; T+ a. }( g" N
+ Y2 O- m" k( k4 V6 {1 W4 n
            extransfer      2/8 分成   extransfer, P! S6 a4 J; d# F+ B5 [

2 C. g6 ]3 N2 S1 l2 E' x1.用户给平台方账户转账,memo 中填写内容提供者的账户名。
; y& q; i8 X) @9 F+ m8 B1 I" P: N& G2 f% b' x& u1 y
2.平台方的账户合约监听 extransfer 方法的通知,然后做出分账计算,给对应内容提供者的账户转账对应金额。
! V; e4 i/ d3 c+ J
3 W/ Z1 j2 |9 n# k! }  m1 B整体逻辑很简单,整个合约代码逻辑差不多用20行就可以写完。* H9 f& _8 i& G7 L
! G# H% f* I- F9 g/ I
编写合约
% g: s+ @3 B4 f* A
  E# b$ }" @& {  S  r4 `6 pFIBOS 的智能合约分为 ABI 文件和 JS 合约两部分。ABI 相当于合约接口,JS 合约则是功能实现。本案例目前没有接口设计需求,不过 ABI 文件还是合约不可缺少的部分。所以我们简单创建一下就好。
( u  n# M" [* [6 T7 [) D' J
* F9 t" ^- b0 m' Q  g8 _! J我们先创建一个 contracts 文件夹,合约文件都会放在这里。然后在此文件夹下,创建 subaccount.abi 文件,内容为:: K- F, y/ a/ M9 L  r+ J6 ]$ g
0 |2 p8 {2 g6 J4 s; y: Q! I/ t
{% Y. B3 k- w! c2 j' @
* f; n0 ]) f) X: X* p! @
    "version": "eosio::abi/1.0"  j/ n6 T5 L6 ^1 Z1 ?
: ^3 ?7 n/ J. B: k
}
! \  }. N2 v* v" w9 s, m% C. l  _) p$ P- i7 Z  H8 F
JS 合约部分也没有太复杂。在 contracts 文件夹下创建 subaccount.js 文件,代码为:
' {7 @" Q* d2 N3 y! K% c& h! W  [# B- Y( N# J
exports.on_extransfer = (from, to, quantity, memo) => {
) e( K4 \5 u+ X' T2 J4 f/ N. a, L$ I* F' `
    // 需要在开头做一些判断
& v' R, p( k% T" A, Z; z! i0 x  I6 L9 |) e# x1 X: @& \
    if (to === action.receiver && action.is_account(memo)) {$ G6 C, `6 P5 p2 t4 T4 Y- [
& s, d  H8 w  C% ?2 B
        const num = parseInt(quantity.quantity.split(' ')[0])
( Q0 V+ i9 C& |0 t3 r) ~, m: \
5 [  O; i! x" U' A$ w9 a        // 假设我们约定平台方跟内容提供者是2/8分成。
+ C- ^: F8 ]1 z% d/ A6 Z
  w/ B* c6 x6 |9 s9 y& U        const subnum = (num * 0.8).toFixed(4);$ J: P* T# {( o$ d1 H
6 Y+ B3 h* i$ Q" G! A  c0 N. B
        trans.send_inline('eosio.token', 'extransfer', {
3 G+ ~3 b; v) m. O1 m. ^. c/ T8 I+ ^. K9 T0 G+ x  @
            from: to,6 A# O. e( ~% i+ y1 M4 M# C
; U* B9 g2 n  p$ m  L
            to: memo,8 v4 y4 }) v* t. ]3 D
4 _$ Y$ ?$ z1 |+ }4 z
            quantity: {
- h1 {" e) W& J9 e9 G- f
6 G( U  z. |8 M% F6 p4 Q1 G( Z# c/ s                quantity: `${subnum} ${quantity.quantity.split(' ')[1]}`,6 ^. B8 Q- Z# @

; A) e. k0 p. c0 U; t- l                contract: quantity.contract+ C$ r1 ?7 q* k3 e8 I& x
3 y+ F9 d( x: E
            },
2 \% n; q9 k* {( ?0 v, `1 F; q6 F5 B+ z) Q2 p" P
            memo: 'sub account'
6 ^$ [+ v/ ]( q0 I9 R- A
9 b3 O1 z( e5 ?. s) @4 z+ y! t6 u        },2 U2 O- D2 H; s( H7 B- b* W/ E
3 d2 J% Y" Q" n3 D9 {
        [
8 Z7 {# Y3 {# @5 n0 ~. M& e+ Q0 ^7 K  S' c
            {
1 B; a; C+ A6 W  C! t0 D8 {. m3 ?1 R& s- V2 p. A! D; C: \3 B
                // 需要提供合约账户的 active 权限
# z4 {6 Z8 j4 p1 b" P# d/ b6 C: ]+ ]' S  R$ I- W2 V* p
                actor: action.receiver,( ]7 _# \+ b/ F* }
* Q( G; y# X4 m' p% ?6 t
                permission: 'active'
6 u, y7 o! S1 G% F7 d% h
; R8 x6 O6 E) j9 `( _            }
+ j& I' S- h4 h2 R$ P2 X1 B
' Q0 H; F; W+ q0 X/ P: g1 P/ Y5 p) }        ]);% b( {, @, T! H
( H0 C$ Y8 @3 Q: y$ X" W
    }+ w( B9 I9 {; w$ u/ l

3 f7 k2 r' `7 v+ I. W: I# Q% k}
' {5 R$ m- g) V5 T8 s+ A. \; W# H1 D# I% e8 M5 Y' }7 k# v9 O
合约代码开头我们需要做一些验证。
* L2 u3 V! _8 I/ C8 R7 L7 p- k& c' k7 Q- K# {1 ?
1.收款方的账户为合约账户,否则因为下面代码执行给内容提供者转账时,因为转帐方也是合约账号会再次收到通知,造成无限递归,超出最大 send_inline 层数而报错。- M7 Y/ u4 ^# g
& N  Y- v3 |1 A
2.我们用 memo 参数来放内容提供者的账户,所以我们需要对此参数校验一下该账户是否存在防止打错。$ d, w+ h: e$ c6 X7 N
% b8 H/ O0 {6 U7 O0 Q  Y5 c
合约代码中我们使用 send_inline 调用 eosio.token 合约来执行转帐操作。转帐操作需要对应账户的 active 权限才能执行。为了解决权限滥用问题,FIBOS 定义了一个特殊权限 eosio.code。我们需要在平台合约账户中配置权限,在 active 权限下添加该合约账户的 eosio.code 授权。具体的配置操作会在下面说明。
4 `: k( t$ l  N: O+ X. m
% j  o* z- [+ X5 c在 FIBOS TestNet 上注册账号
, S, F! Z, F" x- h; j, W6 a5 Z8 [; ~- {! F0 v& w
为方便测试,我们在测试网 http://testnet.fibos.fo 上注册三个账户。& `$ j/ z4 x2 P# ~& z
& l! [2 X, A% i$ D
用户账号 helloworld11
# q; O; }! _8 b, f7 F; t- M
  p6 u9 d5 u4 {内容提供者账号 helloworld22
, p8 A6 D, R0 a/ y8 c
0 W3 o6 X5 ~; m平台合约账号 helloworld33
1 n$ T6 k- Z* w3 G$ u
/ H( K3 ^5 {, X" K) H1 W! U5 }我们需要记录这三个账号的账户名以及公私钥。以便下面的开发使用。创建一个统一的配置文件来记录这些数据:
3 N% C) P4 l1 [; ~/ U+ ?; M8 A3 z; a4 A6 l# z7 N5 g; t( R  s
const config = {
+ W+ L( {* `" L* ^
: b: y3 K+ l' a. i; {3 E    // 平台合约账户的客户端配置: q) _% B7 _* o: i; x
- v+ Q0 m& A- E: E
    client: {
+ h5 ^' Y1 @, C; ?% n
5 m* }. S+ T" f1 _/ s1 T8 f        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
& Z& L5 v2 M  g" f, F1 N. q* ?; f6 T7 Z9 |' U
        httpEndpoint: 'http://testnet.fibos.fo',
1 i2 |  P+ {/ P2 X1 ~$ S+ W0 K: |" B) K8 `# W$ F* d
        keyProvider: 'PRIVATE_KEY_OF_helloworld33'8 ?9 g( B% s  u- X- ~5 Q

; c2 }* d: u+ F    },
3 U$ H) @+ [8 y* Y
2 q& f3 J1 R1 k! g    // 用户账户的客户端配置
4 m+ Y" b2 [! u" B# k6 m: O* W# s* v
    callClient:{
+ d7 x) }* M3 @. N# g6 v" J( }' t6 j. M5 l/ u
        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',% h! R. N; k" y! U' T
; N) ]: C: I0 J: J; Q
        httpEndpoint: 'http://testnet.fibos.fo',
$ X) ^: w" L! {* n
- i2 u' s* |9 A  C7 x        keyProvider: 'PRIVATE_KEY_OF_helloworld11'8 W% m+ f8 G: g% Y5 D

% x% B. H3 d8 Y% D2 |1 j( @    },
$ l. U" r, H- N# G( C$ N/ i/ _
$ Y+ p" K0 ]# n2 U& }; z) g    // 平台合约账户信息
; z# u4 x7 `# U9 B
; q  L: j' g3 S3 x, A6 y# w8 F    contractAccount: {
1 z9 B, z; ^9 d6 }' x* r/ u& g$ H) c% T+ J5 L1 G
        name: 'helloworld33',/ }0 X2 {# l5 _$ u* y- z8 @

% i: {1 H, }$ Q7 H" j; z# ]        publicKey: 'PUBLIC_KEY_OF_helloworld33',
5 Y7 n2 ^+ o" E+ m; M/ D2 g! \' L. j( d5 P$ {
        privateKey: 'PRIVATE_KEY_OF_helloworld33'
+ ^5 F! O/ {+ {! K; ^) v4 ?3 u/ K( t1 I) `* \5 c3 t
    },
) r' K7 E) H- P/ k. n* N, m3 R0 m- d# M1 I4 [/ G9 _# F: {4 h6 [" e
    // 用户账户信息
/ |" M. V& `# H$ a0 [! m
9 p& c$ T$ D. e- q0 s) x    account1: {
9 ~: N3 d) O' _% F+ r  ^3 D) e( m( {" ^& o6 k7 {8 Q
        name: 'helloworld11',  p- U4 b- H: {
! t5 f+ P: V& I/ |2 N9 Y
        publicKey: 'PUBLIC_KEY_OF_helloworld11',* ^) F; t6 h' D
1 W, ^" x0 v( W. a9 H5 t& o
        privateKey: 'PRIVATE_KEY_OF_helloworld11'5 i/ D9 e! C, d6 `$ c1 u/ O

- f+ d, T6 W9 a$ R- ?# `2 C    },
2 e" y8 j+ J6 @! _$ |) W
% e% B9 f- `  S! ~    // 内容提供者账户信息
0 W5 f( a& z  T* h8 ]! c+ l- S; |$ q$ e" M/ v' k
    account2: {+ Z- N" J/ ]1 \3 Y; G3 q- S, j

" G# R$ l( A0 c/ W        name: 'helloworld22',
) ?9 |6 }5 f/ f
4 }7 n" H5 Y9 b7 C8 _        publicKey: 'PUBLIC_KEY_OF_helloworld22',
5 G' Y  U1 k6 o3 v
6 f# \) Z. z8 {) ]' _) K' O/ G        privateKey: 'PRIVATE_KEY_OF_helloworld22'" u7 d7 m" y* s- b8 L
. E" @- s3 S, J$ H/ [( a9 d+ Y' Z
    }8 e& b) g! f- [1 a
; O# y5 _6 l9 p" b) j7 P+ n* Z
}& [2 C; X  [3 U- ^& K$ e! r4 D" a

3 E- X  I5 G, H$ Zmodule.exports = config5 }5 \8 U1 X6 p" f& G( l, b

' y/ e: L9 Q# Z' N% Q& |" C/ s  Y配置权限5 B4 [) R# m8 z5 [2 f

) f: c7 J5 h. h: U% q7 W& ^在合约代码中,我们调用了 trans.send_inline 函数调用合约 eosio.token 来实现转帐操作,但是转帐操作是需要账户的 active 权限。所以我们需要更新一下合约账户的权限,需要添加调用者的 eosio.code 授权到它的 active 权限。这个调用者自然也是这个合约账户。
0 }' m% T% b% W5 |
0 g. J/ X+ N7 C, S3 G$ v* Dconst FIBOS = require('fibos.js');% o6 y! l3 I/ ~. b; `8 A
  ]3 ?: g; J9 e: L! s, Y$ o5 {
const config = require('./config');8 d/ ^- S7 J$ R9 I. \
) {3 h+ |' M0 u
const fibosClient = FIBOS(config.client);
3 d5 z. S9 d1 j3 l' u1 D2 t- u( r+ y% x: \  K' h
let ctx = fibosClient.contractSync('eosio');7 ]; ]7 a  @% m( x- r
4 F" p  C7 p5 p& i. I
var r = ctx.updateauthSync({
- W  n4 A8 J# Z& {3 f) d# Q: _! G9 n+ p* |% E$ O+ |% T* ~& q
  account: config.contractAccount.name,
: P- \9 }. B# Q/ s  ?& J
' m* i% d+ E2 A9 i3 w  permission: 'active',4 f2 }/ D! z' R  J, E) X1 q

4 P% Y% ^# T7 L+ z# l2 _  parent: 'owner',) Q  C* Y* }1 ~& o* L( w5 o

$ K5 z% S+ I3 u" E3 h  auth: {
2 t6 A& E! R- Y) s. i5 |; {+ ]" A. u
- p) z" \0 r- b. g$ m    threshold: 1,8 a; {; h1 U- H2 k+ z$ n
+ d2 `( d  y# g+ o+ c1 u, g9 Z
    keys: [{; F% y% Z4 N' T' L& q! _' ?

/ c. j8 _! n+ Y, o. I4 g( h      key: config.contractAccount.publicKey,+ ~9 a# W, j) I* W

$ u& O  ^# H! t' C/ `5 @      weight: 16 r9 N. j+ K8 R! v2 Z6 S- j
& Z& I! D- e# N5 W7 q
    }],1 ^" V6 G0 i: e: O, z

. p. x: r; ~, R2 M, W+ A    accounts: [{
# R1 G, i3 ]# \9 X) N. X  h2 T0 O! o" [
        permission: {
6 K5 P2 J9 X- G& q' U0 p: V7 Q% ~, E! D! o7 o! D! A8 l$ Q( [
            // 将调用者账号的 eosio.code 授权添加到它的 active 权限下。5 V6 j5 L- s: l) @6 ~% S

, T( q9 u+ i+ u            actor: config.contractAccount.name,2 L( M# j" t2 C: P( ]: W; E3 ]) }
. Z# m( y$ b2 N) e
            permission: 'eosio.code'
6 l( I+ Q) N' H
6 S  U; ?$ \8 i& l1 \        },
- A: @0 c+ u$ m6 e' i, n! N& \8 _7 P" y9 K% E6 Q
        weight: 1  ~# o% L" Q' ]  ~7 Z1 G

; ]6 v- F- ?1 b- D2 C    }]  S% \% G7 m5 G/ @& v

: h' y- {& v* ~+ j, D9 v# [) L  }8 t  W( {# T9 U+ i

) J2 L1 z  i6 q  K+ ^},{+ H5 J5 j$ s1 o: E) W+ L8 y

9 t% W' o( Y5 z' W: P. f% {    authorization: `${config.contractAccount.name}@owner` //更改账户权限需要使用 owner 权限
9 F& Y/ y+ E! F3 o) W3 a( M
! `/ e6 r5 _6 c* ^, q});/ x: D& U* E/ G. W
) Y/ e# E7 H+ k6 P
console.log(r);
2 h6 w9 \% H- M$ H' o7 K& @' w. W
, t3 Z: T) N( [# U' [3 I' u部署合约/ M; a* C  C" M5 t. @
: Y& |3 y3 j2 s! b- ]* j
const FIBOS = require('fibos.js');: [# m, _$ P5 ~7 Q
. G# p$ n0 }9 O& d+ h4 u3 k9 _
const config = require('./config');5 j8 o* O3 q1 U

9 ]: c7 I! G8 Y1 f4 h/ p' Fconst fibosClient = FIBOS(config.client);% k# j. N3 T! s3 q" \

  A2 z- [0 c$ G+ E! L% aconst fs = require('fs');
% |# O3 Q! s* e( y- [) n
4 {9 g* ^: W1 g' F& A( o1 s// setcode
7 J  y* f& f" N# e
. K* A* a  h- xconst jsCode = fs.readTextFile(`${__dirname}/contracts/subaccount.js`);
2 l' R, z/ S1 ~* B( l4 Z  }5 M' _0 [2 c' |; R& r5 F
fibosClient.setcodeSync(config.contractAccount.name, 0, 0, fibosClient.compileCode(jsCode));
' O2 f) E  t( a5 b; [8 P% Q0 T3 Z! `" o# h
// getcode
  A0 v* u6 ?- {" W$ s, |
7 O  t& e8 B) R: C9 T) {6 \const code = fibosClient.getCodeSync(config.contractAccount.name, true);# a3 v: N- B( m3 i
' S! N) I/ J7 t2 n
console.log('code:', code);. V) _$ R  _% m' K& {9 O% Z. {
, q6 t1 [2 ?! g2 _7 Q# O6 {( J
// setabi5 x! o' j, b5 ~. H( W6 h5 Q
" ~  E* H1 d! U: W) M: O+ ^2 Y- r
const abi = JSON.parse(fs.readTextFile(`${__dirname}/contracts/subaccount.abi`));
. Q3 R6 {/ ~7 w& a6 ]+ H
4 P8 z+ K8 m: A8 I: Q% N1 rfibosClient.setabiSync(config.contractAccount.name, abi);
4 x  v; [3 E8 V: X* r; c9 W2 o% F% B( j& O
转账测试
4 E- _1 b6 V( {$ i" ]/ s  \  X
( W2 @- L5 s9 b" C/ k. x我们先来写一个脚本 account.js 来查看三个账户的余额。- s, ^2 N3 b% P5 K7 i

3 h! V! L+ E( V$ n/ S! ]  mconst FIBOS = require('fibos.js');
1 W0 q1 ^6 c* D, w
& [" Q- V# H* \1 h2 [const config = require('./config');' b0 r7 D* I2 |4 Y1 Z' m

2 }+ H" @- v  u% @9 D9 X1 U) Nconst fibosClient = FIBOS(config.callClient);
1 A- m' a$ E: M0 A& k, H9 {& B7 p1 x8 J* s0 u& o# q
const account1 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account1.name, 'accounts');) W# G$ ~( T, D/ I
) ^4 m* [' V8 F+ u- Q
console.log(config.account1.name);
! V* F* Y6 e  T! M  W( D. u
$ C" V/ K3 U3 C7 x$ _- Qconsole.log(account1);& i/ c$ h8 `5 k7 V( N) V+ U
% _1 G/ a$ k- [! |
const account2 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account2.name, 'accounts');2 w5 `- L: O% t. Q; U" Z
. M. L; q8 S9 B
console.log(config.account2.name);
  K0 ]/ a. H' V7 C' s# I$ R6 [6 v/ e9 d
console.log(account2);
/ S- g( p: k. [( ]: ]9 E, l# P( w/ J. |$ {# X
const contractAccount = fibosClient.getTableRowsSync(true, 'eosio.token', config.contractAccount.name, 'accounts');
' v$ \8 o2 V! ], V' P& S
6 ]5 S% ?1 r7 v% h/ o1 oconsole.log(config.contractAccount.name);' c7 ]8 q/ B/ I

' G) l. t7 O' i7 A2 _8 n) b) iconsole.log(contractAccount);
; M7 R' i  K. c% {2 M& g7 ?9 ?) U/ T- x8 X
执行 fibos account.js 来查看三个账户信息。 目前我们的账户还没有 FO,所以大致情况是这样的:
+ g# ?7 \) _5 ^% t* A: P7 Y' P" h
用户账户:helloworld11 金额:0.0000 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO4 W& a) n6 M  M

; Y; L6 t- J; P) O4 A% P( p9 U

; J- e0 J2 g5 f, f
4 j& R# ]4 ?1 I, O  H! ~5 `测试网会自动给每个账户发放10 EOS 的通证用以测试使用。账户中还并没有 FO 通证。所以我们再来写一个兑换脚本,用1 EOS 换一点 FO 通证。4 `4 V5 K5 l0 T3 j# I# z) Q
7 X8 V- Q8 d1 P: e. \% }% a
const FIBOS = require('fibos.js');
8 q  B3 ?! Y$ b8 D( y! f* G5 {$ H$ h% {) [" M
const config = require('./config');
% X( n! l0 N9 {. C9 w* K
- F4 F( G$ X! ?. {const fibosClient = FIBOS(config.callClient);
8 W9 C1 ~0 ]+ \! i: i7 {; Z* D+ q& k
let ctx = fibosClient.contractSync('eosio.token');
& x& X9 ?& S5 }4 a3 H! N0 @, Q* {$ C, d" G* S1 Z
const r = ctx.exchangeSync(5 h9 Y0 E/ X3 U

) `( O; s' k* F8 a( ^    config.account1.name,
1 W+ M+ }5 V. n
5 v9 {: q0 l, A, @6 @& D! ?8 t    '1.0000 EOS@eosio',& s' B" t( d( \% r/ F$ i5 ]4 t
; u4 j2 e. T: W  b9 G" A% |
    '0.0000 FO@eosio',
  Y7 W2 X3 K8 t$ N& j* U3 k. O. z% v- ~0 J- x( C
    'exchange FO to EOS',. |/ F$ R6 Z* _7 B) O. [2 q6 r
: K# _  F3 u  t  h9 [6 `* o1 D
    {
) z9 l! h* h8 a. E2 y/ E0 X$ a9 P3 N" c5 C0 a, B7 c
        authorization: config.account1.name
* m6 b5 p3 K# j) m. E! v9 w9 C
/ _$ m- e, f" K    }( Y" P2 x+ S: H9 V

- [/ N% T7 @" i/ P" j8 U) P& T);2 e% M5 u4 n/ P# c7 w
! L- `  B4 @3 q% I- A2 t
console.log(r)
  K  w; _3 f5 z; q8 a
% ^/ ?5 J! W& D8 B* X  R再次执行 fibos account.js 来查看账户信息。目前我们的账户金额大致是这样的:, x( G& g0 h6 u

% q" l0 o6 `9 O, {2 A# b用户账户:helloworld11 金额:146.4245 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO( E* w* j& s2 L8 r$ Z, r6 f4 ^- w, m, t

) a4 T; n* W4 b- O; u; I下面写个脚本 transfer.js 来执行转帐操作。
* G) i! D9 v) I7 z6 |3 k9 W+ f# k( S0 }4 j! }/ D/ C2 B
const FIBOS = require('fibos.js');/ G/ A$ e9 P5 l* U# \4 q

8 q3 W4 `' R5 }6 ~+ P* Oconst config = require('./config');2 u. ]: \$ A& D9 a/ {9 S% y

" I* N+ ?0 e' a' dconst fibosClient = FIBOS(config.callClient);8 Y' m: F; G; }# Z5 x
  y8 l9 ~9 r; }. G9 }4 Q7 k
let ctx = fibosClient.contractSync('eosio.token');
3 x$ n7 ~1 D% L6 B
1 x& A, X6 o: Mconst r = ctx.extransferSync(, P8 H7 \, ~* Z0 E. ]2 q1 B

  `/ v. Q! F4 [; S: I3 e3 B    config.account1.name, // 用户账户
# F  `# K. M" v# @/ \, [5 O! h  m/ M" G6 Z- n0 `
    config.contractAccount.name, // 平台合约账户5 K' e9 T* K1 b, [* F7 @) i0 V

& _$ g9 w  L" t    '10.0000 FO@eosio', // 转帐金额+ L$ I: T. k% }  v  U  V2 ~

% x- v( ?3 [" s& ?* ~    config.account2.name, // 附言填写内容提供者的账户名,平台合约会给它分账) Z6 M; s& E) p/ C% c# i- [5 d# q8 |
% w( N" H7 C6 c% m" `  @# S
    {9 w; K4 X0 e# n1 `* d

6 Y5 U" Y6 O$ _        authorization: config.account1.name //提供用户账户的授权
9 t7 H$ {% B: n* W7 D, }2 r( n( e( q6 ?0 A; O' x0 c, n
    }
* }' _0 S* p- ~: x- h$ d  x
: L. |4 [1 Y5 W' g7 |)& ~* }# S; L( h# h  u
, Z' x. p2 B% |% [
console.log(r)% n% `$ G2 @- c9 X1 }
% Q- M1 y+ _+ T9 M
我们要从用户账户 account1 给平台合约账户 account3 转帐 10 FO。memo 参数为要分成的内容提供者账户 account2。根据合约中定的2/8分成,平台合约账户 account3 将会分得2 FO,而内容提供者账户 account2 将会获得8 FO。  }  h6 f) s# v: p' s. s

7 W. U$ F& ^7 P1 k: ]0 Y; H使用命令 fibos transfer.js 执行该脚本完成转帐操作。2 i6 [/ s8 }( z* J6 N6 B7 e4 c
0 a9 R7 j+ J6 o, P" V
下面我们再来看一下目前三个账户情况。执行命令 fibos account.js。三个账户金额大致如下。$ d& v. A+ e4 r! f9 S6 G
4 A# ~& T" D! Q/ }' \3 g$ z6 D
用户账户:helloworld11 金额:136.4245 FO内容提供者账户:helloworld22 金额:8.0000 FO平台合约账户:helloworld33 金额:2.0000 FO
7 ~% @* }. E! a* O9 \: c) A+ z) r6 \# s! A/ `% ~
结果显示,分账账户和平台合约账户如预期那样获得8 FO 和2 FO。  g) U( e- s) K2 t4 ?/ M: \
; l  P* t% ~  Z* w3 T& z* @

" l+ p' N! i: U% u0 U5 v" f
, m. P1 D7 G2 c9 h综上,我们成功使用了智能合约实现了自动分账。平台方还可以继续根据自己业务需要定制自己的合约。) k) X' f7 f3 R+ f
1 H8 L, ?0 C8 Z( e' v! G! H
文中的代码请参考:https://github.com/fengluo/fibos-subaccount
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

哈哈笑417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11