Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

哈哈笑417
157 0 0
自动分账是很多平台都会用到的支付功能。很多互联网内容售卖平台都会跟内容提供者分账。比如:Apple 的 App Store 跟 App 开发者三七分成。很多平台都使用了支付宝、微信支付作为支付手段,但是要同时实现给内容提供者分账,却是一件不太容易的事。使用 FIBOS 智能合约可以很容易实现这个需求。+ D' {" G1 b+ N# K' }1 r
) v) M* \0 Z1 c* ^" o
文中代码已在 GitHub 上开源。https://github.com/fengluo/fibos-subaccount0 p9 p/ P- o; o6 K$ a5 ~& e7 |& x
* m% {4 J6 W: `" ^
设计思路
5 x! X! ]4 ]) ?6 F8 q
( N) G9 e- H  q  w9 }9 w4 \( L在 FIBOS 转账是通过 token 合约的extransfer方法来实现的。extransfer方法在执行的时候会给转账方账户和入账方账户发送通知。所以用户给平台方账户转账的时候,平台账户就会收到通知。所以整体业务逻辑如下:7 U' A8 h' U: |) ?' n! o) i6 ?+ l
1 E; y0 D) u4 O
        quantity: 10 FO2 n5 n+ @) P/ t2 o
; N" I- K- {; O) e. i
        memo: 内容提供者账户           quantity: 8 FO
: F5 j0 z+ H' l/ e9 F9 R4 w. D7 i( c9 W
用户账户 -------------------> 平台账户 ----------------> 内容提供者账户
# y7 i& ]4 [9 l% I5 L$ V4 S. ]1 ?- K0 t+ Y
            extransfer      2/8 分成   extransfer
3 u" r7 V- Q3 E. M; `
" M5 S0 V3 S+ t1.用户给平台方账户转账,memo 中填写内容提供者的账户名。
& |  t  _7 Y3 E6 a  J& o% V. D5 M: \. y" a
2.平台方的账户合约监听 extransfer 方法的通知,然后做出分账计算,给对应内容提供者的账户转账对应金额。3 j4 j* ?. M9 q  Z* n4 B  X

# Q1 `' ], b8 _" {* f! K0 y整体逻辑很简单,整个合约代码逻辑差不多用20行就可以写完。
# D  n$ t; B- U$ `
# A# Z4 H& ?/ Q" H. x编写合约
. a  \; n: x- E6 w7 u! P/ q% n9 J6 b9 x3 ]6 _& z) V
FIBOS 的智能合约分为 ABI 文件和 JS 合约两部分。ABI 相当于合约接口,JS 合约则是功能实现。本案例目前没有接口设计需求,不过 ABI 文件还是合约不可缺少的部分。所以我们简单创建一下就好。
, b8 \8 e; M& t" \; P& T3 z( Q/ ?' E! T
% v1 u% M: o2 [我们先创建一个 contracts 文件夹,合约文件都会放在这里。然后在此文件夹下,创建 subaccount.abi 文件,内容为:7 R' h3 j7 M% }
) L7 N- K2 O* D  B( V) m2 l* A
{
& ~* w  H& }0 \$ I# E5 p1 O5 r" {. K4 |2 Q
    "version": "eosio::abi/1.0"$ H+ E% `$ J- |) A+ @9 ^; Z' B
4 [+ Q8 U! N8 L4 ~, Q
}
; g) w- v& O3 L2 \) g9 d) M1 ^9 r
& T' M  L( l4 E& R* W* `# u$ ^JS 合约部分也没有太复杂。在 contracts 文件夹下创建 subaccount.js 文件,代码为:
( e4 `+ E1 c# x2 [1 l4 T
3 }/ C  D  H9 t: F4 r* {$ Eexports.on_extransfer = (from, to, quantity, memo) => {. }" B: |" `: l- s) F* w! D
5 t, T, b* i* x! r2 t  [! m6 [' ?
    // 需要在开头做一些判断
' i! V1 n; y4 j$ F5 r' E- R* g
4 t0 g3 c" k3 d4 {. ], P. m' b: y    if (to === action.receiver && action.is_account(memo)) {
+ y" [9 Q+ E( K
$ a, p/ Z" p, V! R        const num = parseInt(quantity.quantity.split(' ')[0])! u3 y# B2 p6 i% {/ b
# Z$ |3 b6 W& p$ k3 c  K8 z: m
        // 假设我们约定平台方跟内容提供者是2/8分成。
$ }7 f: d+ N& q( I$ r8 {) p% T  Q) w, w0 e5 v& s1 {4 R8 s
        const subnum = (num * 0.8).toFixed(4);6 [# g% w" O5 e* _3 Y, c
% M3 g. }0 o: E
        trans.send_inline('eosio.token', 'extransfer', {7 b" y! a/ s7 |  r9 n; F

# f' E( G' X  G; w1 S6 v% p5 j            from: to,  ^% [/ G8 r5 n5 H0 L  @! o: \

2 W- G1 V  Q0 a! C1 e# N# o            to: memo,/ u5 K4 q3 j4 G/ l! v- c7 Z$ S9 @; E
  V* b/ [$ g( y8 v% o/ S
            quantity: {
$ e. Q* K3 g: W& P7 j& q1 c) }3 r0 ~- \! M* P3 I2 V1 i
                quantity: `${subnum} ${quantity.quantity.split(' ')[1]}`,
8 k4 f! K2 u7 S% T- B6 Z3 V, Q/ j8 B. K! \$ w
                contract: quantity.contract% Z+ o' G' I$ [, M' V  a9 F7 u9 U
  d( N& t& r1 g/ y8 ?
            },
4 U: }& L) b9 x
- D; q- t- Y3 O! y0 E            memo: 'sub account'
  l& ~& V, |: f+ |0 ~# q! U0 a3 Q# {
        },
+ P& U" }4 F3 @0 J1 S
* o% @; M! L. m8 k, L: Z, p        [% \1 ?3 x* h3 @' [& e
! M- A( w" V) T: z: T
            {
, o1 O9 Z" H: s4 w" N6 n
" w3 N# I/ t  Z- h                // 需要提供合约账户的 active 权限
+ L2 l, T. Q3 r' I$ r4 o
( C3 B7 |+ h3 j% p1 w                actor: action.receiver,
7 C% j( Z5 a; C) q- |- h/ r& l" W3 P; e
                permission: 'active'; Y. _" _" }) O9 _
. z4 L/ R3 d2 K& w/ I( T- M$ P  f
            }$ y; P+ h* V- p5 H! ]' O" k$ d5 P2 i
9 M' ?  U3 X( }+ [  ?- H
        ]);  I1 u# H" g) O/ o# Q2 d. v

) Q5 L$ P4 N* `& Y- S& X4 n4 S3 F3 j    }8 ?. Z5 e" r& q0 y$ K+ ]! L2 }: }

2 m0 L5 G3 p9 u- }& E}3 S$ Z. w: b# s: n+ G+ r

  K! M, q1 W# V  [; l) i合约代码开头我们需要做一些验证。. P8 }( j& A" {$ R. z; t

8 X# h( C+ ~- a0 g1.收款方的账户为合约账户,否则因为下面代码执行给内容提供者转账时,因为转帐方也是合约账号会再次收到通知,造成无限递归,超出最大 send_inline 层数而报错。- }$ p# a% b( L! Y2 |8 K

) E) Z2 c- [/ }( b. X7 H' t! U/ |9 j2.我们用 memo 参数来放内容提供者的账户,所以我们需要对此参数校验一下该账户是否存在防止打错。, w9 q8 X: {! ^2 K( ^( G6 u
& ]6 }' C. r2 Z2 K: k
合约代码中我们使用 send_inline 调用 eosio.token 合约来执行转帐操作。转帐操作需要对应账户的 active 权限才能执行。为了解决权限滥用问题,FIBOS 定义了一个特殊权限 eosio.code。我们需要在平台合约账户中配置权限,在 active 权限下添加该合约账户的 eosio.code 授权。具体的配置操作会在下面说明。
  U6 \* W. u3 Y9 g' e8 t
; `# p* [* ~1 v在 FIBOS TestNet 上注册账号
. x; P  U7 i# B0 ]* e- T/ S0 j0 N7 V: x5 }, R
为方便测试,我们在测试网 http://testnet.fibos.fo 上注册三个账户。8 T3 x4 O; Z+ u, n/ K
! z( t! R) B: ?$ s8 b! E
用户账号 helloworld11+ x; k6 H$ W4 G. D$ ]

& D  g  z) U( f6 a: Y8 g$ w内容提供者账号 helloworld22& D1 Z5 ^% f* @7 L) a1 g; i/ C5 F+ K% R
1 ?; _1 j+ U  o7 Y3 u
平台合约账号 helloworld33
( v. H, H) E, ~  `
! x0 [& B! K& J9 A, K+ `我们需要记录这三个账号的账户名以及公私钥。以便下面的开发使用。创建一个统一的配置文件来记录这些数据:% J/ Y/ r7 M" p% _: U7 ~

* e) U" N' o. z7 Iconst config = {& X7 I& @2 \: N+ W
5 r. @  R2 y+ n* K* T/ i" u
    // 平台合约账户的客户端配置
; g# v, ~* Z1 f. Q, H. G7 U1 }) L: i3 S( s
    client: {
0 I: ^0 y$ G) R% d0 T9 K' W- N7 K- ?( E& G
        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
: I; T# I& p& x0 _& ]# V) {- s3 J. g. l6 O0 d) h  v
        httpEndpoint: 'http://testnet.fibos.fo',
- w% n7 W# K/ K0 Z  S7 O8 \
" W6 T+ f5 v' H2 n% [! D        keyProvider: 'PRIVATE_KEY_OF_helloworld33'+ I% H% f' b  q4 V4 K$ f' o
! W) X; C" y/ o8 S) g1 Z; V
    },
1 ?  E" F9 n& @. A: h( A/ p: H# @6 J2 M1 O6 ^1 P  i  l1 i
    // 用户账户的客户端配置3 s# b9 N& ~$ T

7 g/ J/ [: ^& \- ?; s7 p5 h    callClient:{1 n7 q5 h. @, F3 E! F  G" r

. F, K9 M: f2 K* M        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
( l7 T0 a- l, U9 E7 X* s4 l1 c2 t2 U3 `1 e# V* o, }
        httpEndpoint: 'http://testnet.fibos.fo',$ M- E' u7 c2 Z7 H( A) c/ R# V" O
% u$ P' I: J8 X5 N
        keyProvider: 'PRIVATE_KEY_OF_helloworld11'
' O* m; i# l: X/ H+ ~' E' u, O2 L; H! F6 q0 h0 d% _
    },2 L. G2 u% E7 c) Z) l- E
& U/ ^7 r- q! }
    // 平台合约账户信息. h# S7 @9 _' s/ n% H( E6 k; w5 K

1 W& x+ g/ b% s- i( R    contractAccount: {. f# @" @. z) ~5 J, ?
' m, u: `; u; f: M* ?
        name: 'helloworld33',
, n1 [4 z2 q( u' g
- T! ], _; h. @8 \( v! @! B        publicKey: 'PUBLIC_KEY_OF_helloworld33',2 S( r: t  V2 P7 `, q) [

+ n$ J/ H+ j$ c" `9 G* f' \        privateKey: 'PRIVATE_KEY_OF_helloworld33'
$ y1 t* F  U4 H: t  T; U9 F. L* E6 w# Q$ b3 y* \* }
    },
+ Y$ p4 Q1 O. I  F/ ]: D# {& v8 }" y$ h% Q* n! j! P1 j" D; A6 z
    // 用户账户信息2 J, D& n4 }9 C
* \  Y# _. z- w$ J5 \8 u
    account1: {6 }8 A: n+ J' Z2 T$ f

4 Q/ `5 |) q9 ]        name: 'helloworld11',) t: o1 y4 g/ z! @1 [$ M
5 ~3 [1 Y% W1 z; X: h! s( z
        publicKey: 'PUBLIC_KEY_OF_helloworld11',
8 ~  D+ z+ r5 i1 r& G% C- G/ ?( j( _4 d
        privateKey: 'PRIVATE_KEY_OF_helloworld11'5 y; l, v! \" _8 t3 R6 ^; J
* ^3 v! ]" N/ Z; D* Y
    },
0 q) z: w* k. Z. z2 e; ^# T0 r1 X( l
    // 内容提供者账户信息, E( U- _3 ~8 |. Z
' v  [* J+ t+ g: t
    account2: {: h2 M7 j" j" y" ?& B' `

% j! S$ p  C& Q$ h: O3 b9 E6 c3 A5 t        name: 'helloworld22',4 [& W2 \) Z. O( C! ^5 b, D' z( Y

; h' ~+ B/ }( k* Y        publicKey: 'PUBLIC_KEY_OF_helloworld22',& B) _3 Z2 _3 z" P$ l" x$ p

- y- T) w' ?! n8 b2 U  V        privateKey: 'PRIVATE_KEY_OF_helloworld22'2 m, T0 w0 g9 ]  y7 d! h5 |

4 b  q5 R( s9 M  y0 Q5 |4 p    }
3 K9 [: J, `! E
8 R* N0 h# j" Y& |, e2 ?+ f  ]}
- e3 O$ T2 }8 M" N4 u
8 s' W4 _1 X8 ]module.exports = config: m+ r7 w8 |. H5 Y  T6 ]# E

5 N0 M: w  _+ ?) a9 N& M1 P% R2 y' n配置权限
7 n; ?9 B. ]+ N, I8 a
0 h$ i! p6 i7 o2 ]' h. e在合约代码中,我们调用了 trans.send_inline 函数调用合约 eosio.token 来实现转帐操作,但是转帐操作是需要账户的 active 权限。所以我们需要更新一下合约账户的权限,需要添加调用者的 eosio.code 授权到它的 active 权限。这个调用者自然也是这个合约账户。
. }& M0 a# \( ?8 V4 f9 I- r1 [2 U' Y# }: D* a6 [
const FIBOS = require('fibos.js');! _- v4 {. M4 g: E/ \

" N( u1 l3 i3 q. r: Cconst config = require('./config');
: E) y) Z0 R! @+ U) z7 d7 H; N( t6 O0 P" o5 e0 A
const fibosClient = FIBOS(config.client);% H9 o. c! q5 S0 U, ^6 o* k

+ g7 [% E# ^/ d6 R' h3 Ilet ctx = fibosClient.contractSync('eosio');$ A7 H6 U2 t8 H
+ b( E9 D/ C- Z
var r = ctx.updateauthSync({
, p3 G7 ~/ X- i' r3 J) c- X2 x4 s& d' W6 N4 U+ e
  account: config.contractAccount.name,
1 i0 R, v8 J6 B0 u5 r4 S! g: F0 L0 J
  permission: 'active',; b( V, M( n; m9 G
, }4 U- ]4 ^6 L2 Z  M
  parent: 'owner',% B8 d) E6 j0 o6 S" y

9 v! n% \' p. R  auth: {
3 W( B. W) `8 U: u6 O4 M+ a. d+ ^* R2 K( u. F; x% f  ?
    threshold: 1,/ Q* I" x' K' J6 U5 B

: Y1 W* N$ Y0 X- t3 N& `; \    keys: [{- y1 K; n# r2 U( e8 s7 d% Z9 y
$ g& F$ `# j" ^8 O( C9 L, i
      key: config.contractAccount.publicKey,
' O% g$ E3 K& Y/ C% A+ W+ ]9 t" u7 [# \: f3 H$ t9 P5 M8 G
      weight: 1( d0 y; s, N9 U( c( T* {
1 X) t2 z, Q& y! V5 E
    }],
% q' D& m, @4 y. q) F% U( A$ m" _8 g9 ^* @! O
    accounts: [{4 f. a! `; _" [: `3 g

. x% d) G2 ]! v; G  q7 D: E; H1 K        permission: {
$ n" ^8 h. u3 W! ^5 q. p! H  k
. M: t  g# L) z. B% f            // 将调用者账号的 eosio.code 授权添加到它的 active 权限下。7 G" y' ^; Q. u; p- j2 r, M' I
4 w6 J6 G( M8 d& T
            actor: config.contractAccount.name,  C: b7 Q0 h6 A

0 {" x2 r( P: E- h. T6 ]8 F            permission: 'eosio.code'
, H: }: `* n% R5 G3 e! g7 M/ k& y, S) J: f
        },
! a6 M  l( e$ K, O
2 p1 ^8 J/ D9 c3 z) ^9 T0 z6 [* R% x        weight: 1! j3 M5 k+ Z2 r) C- S' V

% w7 c- `4 u5 k( V1 [    }]3 _9 A4 m5 Y# m1 |  J

4 R9 ~) M; x) ~% x  }1 Y, g8 C' w4 e1 {0 I

/ g; V  }" q! ~: }},{
& |; F" B3 ^$ T7 B2 M" E5 ~% R' S( J
    authorization: `${config.contractAccount.name}@owner` //更改账户权限需要使用 owner 权限( ]& h# _: g! d( p0 v6 ~) x& O

! b! N7 b5 O( n( s! `9 x% g});
2 C" O$ U" F# T  R3 i5 M  ~
, a. o1 z! M. F( A  ]2 k* Pconsole.log(r);9 ?+ U$ l. ?4 }, V3 r- I5 X

& Z* [% M# T( ]! |3 W8 R. Q部署合约
8 r! ?" v2 p8 S3 O
7 N2 a8 |' d, q; b6 f$ P1 S9 {+ q/ zconst FIBOS = require('fibos.js');7 H. l& {( O  s' L6 H" C
) G% v) s6 ^( ?7 Z
const config = require('./config');% |5 R' E2 Y# y! Q9 U8 O' o/ V- x
+ f: H( f' O* s6 Y, V$ ^
const fibosClient = FIBOS(config.client);$ ?8 S  Z3 q2 N( w
7 R' \! m" q9 I8 k) ?! F; B1 Y
const fs = require('fs');
: F& r' G) F8 z% ]. ^8 A2 u0 j4 g8 j6 g: y
// setcode
9 V' ]! |( w) d4 d% x6 j+ `7 [( A, T/ T* t% s8 _- \- o9 u5 w4 D0 Y
const jsCode = fs.readTextFile(`${__dirname}/contracts/subaccount.js`);0 P$ I- R7 |2 }; @5 S  Q7 j
6 u( L. K# Y% F' ?
fibosClient.setcodeSync(config.contractAccount.name, 0, 0, fibosClient.compileCode(jsCode));
: y7 F9 }8 e5 M" Q9 b- \' H
- L+ k3 K! `5 D$ P// getcode, N/ O0 {+ I; S0 |3 I+ N

, u2 Y7 b- U0 o  m; _( Y, g5 v4 oconst code = fibosClient.getCodeSync(config.contractAccount.name, true);
  m3 L8 ?( w0 Y& J$ r( g0 `+ Y8 p7 s9 H  P8 o1 q' S! H  Q
console.log('code:', code);
, F4 o- A- m) M7 D; i2 c$ o0 Z4 a3 J
// setabi
% Q4 F: K5 D$ ?8 Y& d0 O
( {: F8 y* Q2 V! K% l( `. sconst abi = JSON.parse(fs.readTextFile(`${__dirname}/contracts/subaccount.abi`));. ^( h; u. ~+ q
) W; k' W/ i/ K( v/ Q$ k2 C
fibosClient.setabiSync(config.contractAccount.name, abi);
) q8 `" W  a- o! s! G0 h& |( R: s8 @( S0 x6 h
转账测试
* A. n" I  ]* c  P' B6 T/ A5 S5 n; \( S9 r' D# e
我们先来写一个脚本 account.js 来查看三个账户的余额。9 m5 \3 T0 |9 o! v4 T! d

' R! \& y" w  `9 J( q4 K8 O8 tconst FIBOS = require('fibos.js');
; F" q& b/ G/ h9 n2 |9 P
) m# F7 K4 h  D; I3 z7 K* I- wconst config = require('./config');; k8 q6 K3 A9 O0 P
  ~; ]- a' f9 S2 V$ q1 P' Y' M
const fibosClient = FIBOS(config.callClient);; J7 o1 n# ?- b4 y

, _% V) N/ K% Q5 a8 i' econst account1 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account1.name, 'accounts');
( l* ]+ U2 w/ e7 f: B1 Q0 X8 q& F7 ^, F9 J. I8 Z- {
console.log(config.account1.name);
; b) D& _2 g  P! n6 P2 _" C7 J. i+ D6 `
console.log(account1);' i+ g/ p# W/ c! _6 d+ C
0 P2 \8 e' a) F2 Y$ f; n7 y" ~$ D
const account2 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account2.name, 'accounts');1 I. E4 A3 [/ p8 p6 ?
7 @% C% g% d% G
console.log(config.account2.name);
: t) N- J! L+ B2 |7 R& i! c; \* ~8 J: m7 K6 ~
console.log(account2);
9 {; E; S/ J. n6 t8 g$ j  ?* S0 J, w9 _% F  B/ j
const contractAccount = fibosClient.getTableRowsSync(true, 'eosio.token', config.contractAccount.name, 'accounts');( G+ V* s' X; [0 j

# |* |( E! J. lconsole.log(config.contractAccount.name);" Z9 S* ]0 a2 }6 M& V

' O1 j( b9 S; l4 uconsole.log(contractAccount);
  d2 S$ n8 i; I- q  d4 N4 s, Z% }; h% |: ^
执行 fibos account.js 来查看三个账户信息。 目前我们的账户还没有 FO,所以大致情况是这样的:: m" B9 V% O5 H2 V2 n( U: O; I' n9 g
0 J0 s4 H! v% p* T8 V2 @0 y) M
用户账户:helloworld11 金额:0.0000 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO
: g' J& F! \5 D- ?* v& a7 |0 f  N) j3 {6 [
$ A5 h& x4 [5 H& l& ^1 L# m' d

3 P6 l) Y! X0 i/ D' X- v: ^测试网会自动给每个账户发放10 EOS 的通证用以测试使用。账户中还并没有 FO 通证。所以我们再来写一个兑换脚本,用1 EOS 换一点 FO 通证。- f  t5 `8 }( Q% K: C
, p% f" ~, e) J" b3 a9 m
const FIBOS = require('fibos.js');) e- ~( r5 m3 v8 k
0 \! u. g+ {+ z, ?
const config = require('./config');5 y2 [! p: X( W6 ?1 a" g
6 m; G/ |  m8 W, Q
const fibosClient = FIBOS(config.callClient);
- t4 ?6 C! [5 o* A: }! b# ~; n: b! i2 d  ^; A( m4 O
let ctx = fibosClient.contractSync('eosio.token');( {4 x) m: o% E, \
5 u5 T8 C3 w/ g- d9 f2 u
const r = ctx.exchangeSync(
; T" c# T2 m% Q9 P. {& ~5 q
3 q: _) m+ P  x- `    config.account1.name,
7 ~9 N5 j( O1 J) F1 d9 n3 y8 Y# o
9 M7 F5 ?# |( r! |    '1.0000 EOS@eosio',
4 r1 M# e' p5 h4 j! ?+ U. o; a% k  H# C/ k# H
    '0.0000 FO@eosio',
2 u! o, y3 J8 g/ v2 ]: l4 Z% _( p; @6 x; O
    'exchange FO to EOS',9 X0 I' d# C& `5 {

* o6 w% q/ B% q9 `    {$ e7 h; w7 S6 z# K

$ i$ ?1 V$ F7 s        authorization: config.account1.name
: A) z2 t8 }! e1 b' u6 ]
: l% _) ^! O* R3 [% \, Q9 R7 R1 ^    }# G, \  x  j2 ]' n7 O
* {) P% b1 q+ @  H
);* `, \. Q7 F7 R6 ]& n1 g

& k+ o9 S# a  T8 z1 s. @. ~4 oconsole.log(r)
" O$ v: S" E- W, r! [# J+ L* N# R8 y1 l* r( b* z+ E/ E/ x
再次执行 fibos account.js 来查看账户信息。目前我们的账户金额大致是这样的:
8 f( M* b$ Y. z: C  d& t0 |3 i9 o3 t( G& ~
用户账户:helloworld11 金额:146.4245 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO1 b- `  G/ T0 [+ R. }$ T
0 m# l6 D7 t, |, l& D
下面写个脚本 transfer.js 来执行转帐操作。
3 y" p! k0 {! ^
/ i3 o! l6 _8 G$ R! Cconst FIBOS = require('fibos.js');6 T2 M  m5 U' X  F/ L0 u' l
4 Z& S) W/ j+ u) {6 _
const config = require('./config');+ N$ }# \* k7 Z/ U
0 L  H) C* V$ W
const fibosClient = FIBOS(config.callClient);
0 h2 G$ J6 N9 R/ K$ G8 W+ {( F& p( d7 \, _9 s+ ^8 a# }: v3 S
let ctx = fibosClient.contractSync('eosio.token');
0 R" I% X  ~, X* J: W# r: z+ q) s/ Y' i0 V0 H
const r = ctx.extransferSync(
0 R; v. N$ ?* b2 N( I* m
: P8 e* ^9 J: `) ?  W4 I6 y    config.account1.name, // 用户账户, @! I  J$ \: n1 G& y4 s+ P; g4 }

5 L) W' @) s9 u+ X    config.contractAccount.name, // 平台合约账户
7 E$ g# r" e4 G& n0 ~
" _  c) c* f7 u& V8 _1 u1 A    '10.0000 FO@eosio', // 转帐金额! Q9 _' ~" @. e" o( I
0 s! l( o( |, ?* C6 a
    config.account2.name, // 附言填写内容提供者的账户名,平台合约会给它分账
5 M6 G- t* @  E0 c
  U$ @, G9 C; X8 [& K* ~    {
) M* b- s- n  @% ]0 G) e$ w7 o1 A) q9 H3 a& A! z
        authorization: config.account1.name //提供用户账户的授权+ r: O6 F/ ^: W0 h1 Z

/ ^/ s5 s; d  D0 ^    }
% P( r3 H, q0 L" ~- P4 q  Y. e
2 a# e. W3 I$ M. e5 @)+ _2 x3 y$ f/ s) z6 d. D& `

' u9 L4 u0 @1 Z9 y. i- f- W$ @+ dconsole.log(r)
: X. p7 a1 U- b. E2 e! q
5 y2 X, m0 Z! V  S' @; y我们要从用户账户 account1 给平台合约账户 account3 转帐 10 FO。memo 参数为要分成的内容提供者账户 account2。根据合约中定的2/8分成,平台合约账户 account3 将会分得2 FO,而内容提供者账户 account2 将会获得8 FO。/ @3 O/ \) V# D" ]4 }8 H6 ?

# I# M7 D+ m  h使用命令 fibos transfer.js 执行该脚本完成转帐操作。$ }  ^, @* U/ @% y5 H5 D  M: T8 O
- L( c8 `) X: L
下面我们再来看一下目前三个账户情况。执行命令 fibos account.js。三个账户金额大致如下。' ~4 A/ W* r. ?/ [" }* i& v. O" s

0 Z6 C3 f7 r" H用户账户:helloworld11 金额:136.4245 FO内容提供者账户:helloworld22 金额:8.0000 FO平台合约账户:helloworld33 金额:2.0000 FO- p# _4 K' m; ~: W/ ]; o6 l

5 a5 ]3 j5 z' x3 s) a结果显示,分账账户和平台合约账户如预期那样获得8 FO 和2 FO。" o! ^* r8 x$ ^+ ?, ^

4 F( }* i. d- J

6 ]: C0 Y$ U3 t$ e; E
' _7 H% s8 O6 ?* d4 H" ^0 L/ h综上,我们成功使用了智能合约实现了自动分账。平台方还可以继续根据自己业务需要定制自己的合约。/ [6 r, t! W( a. u  l8 `/ H
* {+ ~: z1 t. {6 m
文中的代码请参考:https://github.com/fengluo/fibos-subaccount
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

哈哈笑417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11