Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

哈哈笑417
113 0 0
自动分账是很多平台都会用到的支付功能。很多互联网内容售卖平台都会跟内容提供者分账。比如:Apple 的 App Store 跟 App 开发者三七分成。很多平台都使用了支付宝、微信支付作为支付手段,但是要同时实现给内容提供者分账,却是一件不太容易的事。使用 FIBOS 智能合约可以很容易实现这个需求。! J8 g% G2 @9 R# _; j2 w) l+ m

: i1 G% B! [1 b& r; ?1 H文中代码已在 GitHub 上开源。https://github.com/fengluo/fibos-subaccount7 {- \# s* Q# @( N! A& G6 r
; [; B4 P+ T# Q* W4 x
设计思路
, @/ Z/ F" L4 s
' T) f2 y* H% v1 T$ c! B4 T在 FIBOS 转账是通过 token 合约的extransfer方法来实现的。extransfer方法在执行的时候会给转账方账户和入账方账户发送通知。所以用户给平台方账户转账的时候,平台账户就会收到通知。所以整体业务逻辑如下:0 z! u% L) a6 M2 P) t% m8 c
$ ?  D2 ]4 K% q
        quantity: 10 FO
& @, k% q( N5 ~' M/ t% `# T' H9 o5 L& c4 ^; D
        memo: 内容提供者账户           quantity: 8 FO0 t$ A5 L5 L  E% Q. o% E
3 s2 b% x! K5 a  N2 V( c! D
用户账户 -------------------> 平台账户 ----------------> 内容提供者账户
. p1 v+ h8 Q* u$ q  S2 b  V
6 d! }6 j* O$ o  I            extransfer      2/8 分成   extransfer7 P! O( v6 i& U5 b9 b( N8 X
: [' e9 i( |, v% }
1.用户给平台方账户转账,memo 中填写内容提供者的账户名。4 ^( x6 ]* i1 Q, X

/ ]/ s, A+ a# n8 v2.平台方的账户合约监听 extransfer 方法的通知,然后做出分账计算,给对应内容提供者的账户转账对应金额。& i0 N6 l3 H$ X6 g: i

4 d2 u, I0 m- |" p) m8 h整体逻辑很简单,整个合约代码逻辑差不多用20行就可以写完。
' C) I3 h0 J) r3 |) O4 o. J5 w% {) y0 E* W9 t+ N
编写合约1 ]% B; y3 e0 I

5 _8 s( k! P5 L- B5 ?FIBOS 的智能合约分为 ABI 文件和 JS 合约两部分。ABI 相当于合约接口,JS 合约则是功能实现。本案例目前没有接口设计需求,不过 ABI 文件还是合约不可缺少的部分。所以我们简单创建一下就好。
; z+ J. v9 h: d. n3 x+ X& Q
; Y* u) Q# h  ~6 t; N  O我们先创建一个 contracts 文件夹,合约文件都会放在这里。然后在此文件夹下,创建 subaccount.abi 文件,内容为:
0 d' E/ M; ^: O
! G% {' ^1 q, {7 [4 p" h{9 x4 w4 ?+ b0 E7 q# W
" x% }( o/ m; d* d7 c) [: O
    "version": "eosio::abi/1.0"
1 _' _$ k& E6 s+ H' c
4 z+ m# S2 ]9 F) |}
1 Q5 J! e+ E$ k- |8 _+ S/ h4 E9 C6 C' h" K1 i, b
JS 合约部分也没有太复杂。在 contracts 文件夹下创建 subaccount.js 文件,代码为:
& A2 W: j! y6 ?! v8 f/ \& U( A) b: m- \& ~% F/ ^
exports.on_extransfer = (from, to, quantity, memo) => {3 h4 @* p) @/ s$ s' \' d
' R$ F5 [5 s) f2 w: {. B
    // 需要在开头做一些判断) D/ X2 f( [$ E+ W8 Q- c6 Y

- ?$ Q8 y' K6 P! e5 b    if (to === action.receiver && action.is_account(memo)) {9 A* _! W( i0 `

# G/ I( _, m7 h5 u8 a% [$ T        const num = parseInt(quantity.quantity.split(' ')[0]). O. @8 {1 B; M& D' c
2 o. e" C$ ^& W7 A  q. W1 {$ p) ]% q- j
        // 假设我们约定平台方跟内容提供者是2/8分成。; S  X! M8 d& A; }; U
( Q6 i9 @0 G9 ]8 I
        const subnum = (num * 0.8).toFixed(4);) l( w" y* o: x; H; c
, a- H$ P! \9 O3 Q
        trans.send_inline('eosio.token', 'extransfer', {
+ U# W4 }! F  k2 E4 p! t0 k! V6 x5 u1 Q" {% N, K9 e
            from: to,
* B; s: b1 I% I2 Y! Q3 d
8 {2 ]& }) M8 ?8 O- k/ R            to: memo,
3 k3 f: N) G% ]6 R' ?# \3 T# U" e9 _1 u
            quantity: {- E/ y8 x! |7 m& N
9 ]* L% |0 U! N; H6 E2 K9 A
                quantity: `${subnum} ${quantity.quantity.split(' ')[1]}`,
. \( s8 r( p" o( }- u, {5 o) q" V# O# |1 H( q9 K6 ?+ k% ]
                contract: quantity.contract
2 }& i. [/ l( v" k9 q  }# B! O. f# ]
+ w& ~4 d1 r( R            },
6 d, b# R+ r* \) M" \* C. B4 L
# q9 K9 c( p8 |            memo: 'sub account'" ?0 R. W# ^, J/ t6 h. m* w
5 Y: M  `- V& U6 N/ y  W
        },
1 M" b5 q( A) @7 s  n1 G. M5 w# k3 ]
        [
8 Z( n$ O) a6 R8 r$ [! b! k
3 k: g9 C0 ]1 i7 \& Q            {, k( v6 @. `; r% `2 q' x1 G5 a2 h
% Y: Z+ a0 l4 x; o1 f1 l, Q( p3 i
                // 需要提供合约账户的 active 权限
& N/ f* {' i( P) k# ^3 G; Q* Z
9 z8 f- g  J" r                actor: action.receiver,5 D9 j8 M7 D# b) c& n0 P' H

2 d/ |. [$ U) c8 D4 S# N                permission: 'active'1 Y5 _# J4 S8 v0 Q' W, R8 c1 v
5 _: m8 b1 j) O! l/ `( o
            }/ b8 n. y& U( ^7 d; R

3 b" q9 Q' Q6 q1 l9 d5 C        ]);
' K/ L  [$ d+ G& F+ v) M9 p4 v, r) p6 q& ^$ ?3 Q2 X
    }- J9 I$ Q0 p+ X6 Y+ o* U! @
' ]; L/ `4 W2 @. q
}+ r# c2 O) j6 h4 M# L! W

* {4 r' P- I7 }) R) i- X合约代码开头我们需要做一些验证。: X6 z6 r& S/ g; ]5 L

# J( M3 Y3 X" W+ |" w8 k4 ^# c1.收款方的账户为合约账户,否则因为下面代码执行给内容提供者转账时,因为转帐方也是合约账号会再次收到通知,造成无限递归,超出最大 send_inline 层数而报错。. B1 E$ U; e! R

" y' P9 W, v: f2.我们用 memo 参数来放内容提供者的账户,所以我们需要对此参数校验一下该账户是否存在防止打错。
7 v! s5 Z$ Q+ f$ v! X5 x
9 a! n6 U$ S5 @8 M) o, ?: w合约代码中我们使用 send_inline 调用 eosio.token 合约来执行转帐操作。转帐操作需要对应账户的 active 权限才能执行。为了解决权限滥用问题,FIBOS 定义了一个特殊权限 eosio.code。我们需要在平台合约账户中配置权限,在 active 权限下添加该合约账户的 eosio.code 授权。具体的配置操作会在下面说明。8 y+ h$ b8 n# [; G3 L6 @7 O! c
% R5 a9 R0 t8 p: _1 K6 D
在 FIBOS TestNet 上注册账号8 t) G5 M) U  N; s9 e

7 b0 Q9 Z8 N! I: d: h+ a- h! |为方便测试,我们在测试网 http://testnet.fibos.fo 上注册三个账户。9 e7 l* W' k8 w3 k: p+ D
" q" }1 B2 l, k" s+ L& W
用户账号 helloworld110 f4 [% Z+ m& a+ p) Z9 C  `: y/ ]
4 P, Z) \' g, b
内容提供者账号 helloworld227 [8 c! \6 ]+ e9 w2 G
: y2 m+ I6 I9 d9 w' x# Y' `
平台合约账号 helloworld33# R. y" Z- H1 j; r. R5 G! J
2 u" v- X7 i7 M  a: `
我们需要记录这三个账号的账户名以及公私钥。以便下面的开发使用。创建一个统一的配置文件来记录这些数据:$ H+ Y4 c& W0 c* Q! l
* W  X1 ~. ~* k1 h
const config = {7 R1 L6 e  D* L, ]
' j4 B7 }9 u2 ]; }1 S- ?
    // 平台合约账户的客户端配置
- y+ l8 Z: s  d" P! g$ Q  h
% ~$ y. h; P* ^! l# `    client: {0 b+ T0 U8 B# B- s, W+ ?

" p+ a1 _# U: i        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
! ?# v. \3 l0 G* ~/ E( p6 b, [  V8 q4 D3 {- x5 D1 ~
        httpEndpoint: 'http://testnet.fibos.fo',; N2 ]2 D- ]$ R% w

* k3 i4 D/ _2 M; i( K/ x        keyProvider: 'PRIVATE_KEY_OF_helloworld33'; }& P2 C( K- Z/ b' ]) Z
$ m) u: [+ M: k
    },
; C5 M+ m$ U, R1 H2 W4 s
3 R' o! A6 ~. G) f    // 用户账户的客户端配置
6 J0 Y( ]7 N. k2 B, U6 v, S, ], q" S6 \. B( N2 W: k- L% S% a; P
    callClient:{, o( D0 a1 ~1 ~& u
. f3 ^. s" i  ^' q
        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
% w; `% y* P. v% D! ]
4 u$ D# c" j, h& J5 m  V- [        httpEndpoint: 'http://testnet.fibos.fo',
- J' l7 x" K1 I" y& n+ K1 ^8 b. {9 J9 l/ p
        keyProvider: 'PRIVATE_KEY_OF_helloworld11'
! X0 H- o6 U. J& g4 b; P1 _/ I' u- C
    },
! }6 O) i% p" i) H2 j0 l
  `- E8 X7 J9 x; n    // 平台合约账户信息. k5 H. Z& D4 A$ U/ P/ k& X6 _

/ Z* u$ G6 a( l" w9 w    contractAccount: {# k6 y8 R+ }! x
" h% [, C4 I7 C/ U( {6 y4 E. g, s
        name: 'helloworld33',
1 ?+ f3 x' ^7 I( `
2 |' }! D- O6 K1 @9 @5 \$ a        publicKey: 'PUBLIC_KEY_OF_helloworld33',
# S# o9 }  _# ~3 b3 t! M
% f$ j3 n8 |/ d8 N        privateKey: 'PRIVATE_KEY_OF_helloworld33'* y% N! `- F- A' ^7 f2 V

9 E) A7 A" R! g1 [. O    },- }) s! J' Z' w
  o- L# Q7 c2 t: H" I+ j2 Z
    // 用户账户信息4 Y6 E. b: o  N

' A/ ]8 f5 @8 R0 B: q    account1: {" O% @: Y, e9 ~0 f
, q; d/ {- [. ~3 K- N' P- P! n
        name: 'helloworld11',
; ^  t8 e; ~6 t* p) \
( ^/ x/ V* [2 p4 d8 W6 W5 i        publicKey: 'PUBLIC_KEY_OF_helloworld11',: [2 {; z0 i3 c; n# K5 k; k  d
( Z1 F# X4 a) h! {/ }5 j3 L6 w
        privateKey: 'PRIVATE_KEY_OF_helloworld11'
" |, v2 }3 {# v" A/ g$ g  v+ e
1 n) e* V. x* q8 ], ]    },
* y, Z" u8 ^5 i# ?3 n
9 E( }* O3 B- v+ x/ T% ^# |0 }% c    // 内容提供者账户信息
  N+ F: p" s$ E+ d  \& M7 `2 G9 g
" U$ T6 S6 P$ M( M    account2: {3 V( A" g! i' Y: M: \% h

9 ~" x( L; F" d1 a' Q7 j        name: 'helloworld22',
4 b. W0 x& F9 d- ~$ l4 I( W6 D& _7 h& _' }
        publicKey: 'PUBLIC_KEY_OF_helloworld22',
4 S3 M- Y4 z1 j! R- Y1 U/ h# k  e5 [5 D/ O) u; k
        privateKey: 'PRIVATE_KEY_OF_helloworld22'
6 A* q( l, g4 s4 M7 O% x) m2 ?+ ^# Z5 ^# W
    }# m# Y9 B2 i9 L

  V% {5 o% v! W5 O7 N8 ]) C6 s9 p% L}
* e0 w! K% J' _, G# ]8 T  v+ H2 J) k
module.exports = config( C4 Y5 q( {, ?  x+ g

, @9 ~  Y: C$ b/ u/ O配置权限
! [9 U7 u/ c7 h6 \4 m. [* Z( g7 Z. D* l
在合约代码中,我们调用了 trans.send_inline 函数调用合约 eosio.token 来实现转帐操作,但是转帐操作是需要账户的 active 权限。所以我们需要更新一下合约账户的权限,需要添加调用者的 eosio.code 授权到它的 active 权限。这个调用者自然也是这个合约账户。$ p. p- n, e' C" C. i, Z

" p* J/ I9 e5 s' W4 b7 yconst FIBOS = require('fibos.js');
/ Z) o& K, k8 r2 S# c: O7 }
8 @, E/ B1 }) ?0 tconst config = require('./config');( m+ U+ b1 n( ?+ I- r! L& Y
: M7 ?+ D# n3 y: e
const fibosClient = FIBOS(config.client);
5 _* u% I2 R& n3 S* f! ^8 z7 [3 Q4 L* Q% B9 `! m% u
let ctx = fibosClient.contractSync('eosio');9 ~! A* s1 j/ W

$ {% M9 N6 \$ avar r = ctx.updateauthSync({
9 b# \/ k8 ^; ~- V. r$ k  n0 M  d0 {
6 V5 |6 Y2 D7 d4 @! t" i( @* e  account: config.contractAccount.name,7 y0 p0 D* ?% q/ I. \

( q: J" ^& o$ @  permission: 'active',
9 \& c4 ]) L6 Z2 W0 ?6 F+ f9 R- t& @7 W
  parent: 'owner',
5 k8 `. J( X6 c1 C/ i4 v
' O) u1 d5 e( c5 H" m  auth: {
! _9 C0 `6 `+ G% J; q3 F7 {5 m! u$ O6 {9 ~
    threshold: 1,' m% R7 Z9 [8 r& Q4 L) V4 z7 S

, `1 x% c* @9 M2 @0 q, g    keys: [{9 U  H7 Q1 X6 P( C# Q6 r9 }

- X% l% G6 C3 |      key: config.contractAccount.publicKey,7 I6 n! M1 k  `9 P0 y' }8 V

0 I6 A0 ~, n" {; k& H) L0 K      weight: 1# Y8 i) u& Z2 x6 ]6 K4 U) t1 E% _: y
% E8 ~+ P0 q! Y; Q  m1 [: C1 k! `
    }],
* I- A( \; ~6 H# a2 u5 X% m- C2 |$ Q0 g! E/ n
    accounts: [{2 @9 f/ I, d. J( c/ o3 [
  h. s+ i4 T; ?2 N) ^
        permission: {
  r7 P& E+ v3 M. R, f; [
, B# W/ Z' G- q9 C1 a# B! W3 a            // 将调用者账号的 eosio.code 授权添加到它的 active 权限下。0 a0 j" n0 h5 o

7 O: L5 u. G/ j) @3 [/ Q            actor: config.contractAccount.name,1 a" \  B8 E" u) u4 s$ b% \

, n# o% Y& q' T            permission: 'eosio.code'. @: }; a, V2 V- m# k* ]

% C, @0 T# q4 P. C0 q$ h- ~/ |$ H        },
) }1 g0 K' M0 s" Y4 l' p' C& b
        weight: 13 q: m! W* a" l( Y, i0 M3 F) ^5 g

: I% b( _) w& c: Z' K    }]
! k7 i4 K6 \$ s. I9 W6 e! h
* Q' ]7 \1 m/ g3 e3 [' Z9 T9 P2 B  }
/ ~$ v3 f) [1 g, n+ r; |. @) J
  P/ m7 S% L0 T1 @7 E},{* ~* z; g# I. ]! W
0 A/ m5 p9 k) i. N
    authorization: `${config.contractAccount.name}@owner` //更改账户权限需要使用 owner 权限2 L2 }5 i5 W) p$ W8 X2 |, G
* ^: I) w, \, v: B: e  j1 B# N
});
# U  v7 i5 I% r" V' |
0 B  \0 q5 p7 X  Yconsole.log(r);! L: J  ^2 e/ W- {3 ~: W& w

% K6 g: W0 x# P) E8 a# \部署合约! b; j" O  s+ l! y$ }; g

& B9 ]4 J) P7 m9 M; N% Sconst FIBOS = require('fibos.js');% _. |* g5 h$ ~8 m* f  O5 ?' A
+ Z# L9 q& |# w: I/ i7 F. X, D
const config = require('./config');* ?  z" B0 a! y1 n

  E, L& ~1 j. Mconst fibosClient = FIBOS(config.client);- @) C# C" J( M' j& u, d
6 t8 v2 m/ Q: o
const fs = require('fs');
) I7 r3 D4 _# i% Q# v0 X8 d! F" Z+ P, g- a9 B( U
// setcode9 ]% M3 b% m; k- B
7 I9 `  {: H: W+ M7 w$ R( P
const jsCode = fs.readTextFile(`${__dirname}/contracts/subaccount.js`);
8 M3 B  W5 u' ?5 t) [: J8 F7 X0 A! z; d2 O
fibosClient.setcodeSync(config.contractAccount.name, 0, 0, fibosClient.compileCode(jsCode));
) ^: H6 m5 _1 P. G; ^7 {2 |1 u5 C4 M" b" l; [0 x
// getcode
% J  W3 K# r4 @$ a
' i# Z5 O1 i9 f3 F; _const code = fibosClient.getCodeSync(config.contractAccount.name, true);* O& ?' q3 s9 }- l4 F5 H

8 F9 K( B3 i( R# k0 u! oconsole.log('code:', code);
) y0 H4 |- I5 d9 `8 F. T
  a; q! v% j5 I, @4 y+ b& t/ z// setabi% H+ Q+ X3 d& K+ E5 M" e3 O; a
3 {7 R6 t2 k7 m/ X7 h! _
const abi = JSON.parse(fs.readTextFile(`${__dirname}/contracts/subaccount.abi`));
0 J; D9 p9 V+ Q8 \! Q5 h1 Z0 q
; G$ D5 n5 B( _5 KfibosClient.setabiSync(config.contractAccount.name, abi);
+ G: ^# f& E* f$ e0 c
, Q, D0 C4 |. U" H转账测试
; X- s! B) }( |, b
2 p2 R, i$ k* O1 o$ G4 D. c我们先来写一个脚本 account.js 来查看三个账户的余额。
% r& @/ h- L8 Q0 b& ~4 {
4 [0 `: R. L$ Econst FIBOS = require('fibos.js');
0 Q6 V7 d3 f8 O6 y( C8 v1 J1 N- H7 i$ J: V# t
const config = require('./config');
7 x9 ~4 w* W+ h# L9 [, r# p) _0 E5 i. P$ M4 K) H7 H9 ~& }
const fibosClient = FIBOS(config.callClient);
0 _/ h3 ]9 G- n+ U8 Y) u' ~; W
" c7 B" Q; v  q) w& ]3 M9 c3 L/ \const account1 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account1.name, 'accounts');
; [% ]5 q) r1 F$ z5 ]4 l% U+ a7 ^! T. P' O: z& G; N
console.log(config.account1.name);
2 G# Y4 k- d& P* L0 z: A3 c/ M7 ^& b- [& O/ U2 I" I- O+ `  B
console.log(account1);/ @( I! X6 N7 l- Y! j

$ B# g1 s- c/ I: p: _0 S7 I1 Yconst account2 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account2.name, 'accounts');
7 _8 P  R" l* e& A3 u; C# Q0 |. X, Q, e2 `+ \( [3 p
console.log(config.account2.name);
. Q- G5 q' r% f8 [: I! Q4 M- H; z+ m% z
console.log(account2);0 i" k/ R$ S8 n/ H& s

7 G# _8 l; T+ Z/ ]9 Fconst contractAccount = fibosClient.getTableRowsSync(true, 'eosio.token', config.contractAccount.name, 'accounts');
0 O' a. L2 |$ _6 e  o) N. \+ r" f
console.log(config.contractAccount.name);
) v% @9 w$ U. s' b3 W% L( Q# |  z0 g9 ~
  |1 w6 U6 e) b+ L0 q/ I3 i3 Lconsole.log(contractAccount);' i) ?1 m% O: P

& w1 t2 G9 @% \7 ^8 h" g  s9 S执行 fibos account.js 来查看三个账户信息。 目前我们的账户还没有 FO,所以大致情况是这样的:+ Z- D4 p& Z/ J: C; O

4 I( p. G" L8 v! i用户账户:helloworld11 金额:0.0000 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO) A% U9 l/ [1 m/ U

1 \- s6 |2 t+ w, v9 J. {% p

) l; G" o1 r0 [: R. D0 ]
+ o$ r& w- @) W  Y测试网会自动给每个账户发放10 EOS 的通证用以测试使用。账户中还并没有 FO 通证。所以我们再来写一个兑换脚本,用1 EOS 换一点 FO 通证。1 O0 _+ G- j9 f' c5 v! Q
7 D. M8 ~2 K( O/ Z0 E
const FIBOS = require('fibos.js');
7 R% d! `8 R9 ?, \# E
8 b! m- r$ }( b1 |% E4 Sconst config = require('./config');
' a* `) Z) c9 m4 g: j+ M) X
" Y$ o3 J2 h# G: ]; i: y5 ~8 C) v) iconst fibosClient = FIBOS(config.callClient);
( v' x2 n% c1 Z/ J
" D' Z, U% C, ~6 M4 ]let ctx = fibosClient.contractSync('eosio.token');! |% x! S6 D9 u3 t3 p% ?. U0 ^

- O& Q; C  h! r. w* sconst r = ctx.exchangeSync(/ e7 v, Q- ~* N: A0 k5 T. O
- s9 c/ d9 j! V* \7 b
    config.account1.name,
- e! D* a7 N# |) y# T; {5 t
& r9 l! a7 Z7 F! g6 W/ a" z    '1.0000 EOS@eosio',5 A  f! A) }2 e2 o6 Z$ @+ P
' V2 G- e5 K( v% c$ i
    '0.0000 FO@eosio',3 N% U- I/ a4 |& a

2 {! T* X; I2 [$ F0 K    'exchange FO to EOS',
. T3 T2 a4 S1 t3 l" o( ^2 U
& j. f6 q6 y8 Z+ T7 P    {
$ A9 W/ |- C+ \- K. ?6 d% ^1 d. j. i* @4 {/ Y
        authorization: config.account1.name
$ c9 j2 }7 w6 ^1 H4 {
; c9 Y1 B8 `7 X1 E    }
) D7 \) o! [' C1 G: Z, Q' a+ Y' |2 W2 a7 R/ ~3 g
);' H' L$ e6 f+ Q  J( r1 c

( U( M# G. k4 s. Dconsole.log(r)3 a& ^/ S9 s8 b' C  \
5 L" w% }! y" L. j# Q) f, S' X
再次执行 fibos account.js 来查看账户信息。目前我们的账户金额大致是这样的:
  F4 v, o1 n7 _% l7 O7 K. r6 T
" W( B- t9 X% J, s: {) `# g" r用户账户:helloworld11 金额:146.4245 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO: e9 G7 v" H4 Z- ?0 c
2 {% w) }" [; x! A# L9 A3 O' ?. q
下面写个脚本 transfer.js 来执行转帐操作。5 N3 ~; k4 ]7 r( a
* f/ X0 C, E; B5 L8 B+ I
const FIBOS = require('fibos.js');: q1 Y5 Q4 U! x7 P
" |- ?- K9 L1 W7 O
const config = require('./config');) H& u8 L8 ?/ {, r7 r# R4 z8 S
1 Y' H1 a5 m! y: ]7 {3 A* c4 L( m% `
const fibosClient = FIBOS(config.callClient);) o  y+ g* M$ o2 x( E; M) J

5 }8 _* r) A% q0 K! B: Dlet ctx = fibosClient.contractSync('eosio.token');
1 {. h  @9 F. b$ I& p. O8 P2 g( ]" Y% m- A0 E& v( U/ K
const r = ctx.extransferSync(
" d1 M# e  Y6 e, y8 p: w7 K* j4 k: y6 h( {1 A7 \) \
    config.account1.name, // 用户账户) _9 a) m" m2 p* [# y* g3 R) J6 J

7 S+ b: ^& |. u8 D4 B4 f! X. t    config.contractAccount.name, // 平台合约账户$ r; g4 a  t& i+ \

2 r" K  I& \6 @    '10.0000 FO@eosio', // 转帐金额
' }# Y3 Y7 [8 D. F8 G$ e
+ l4 r$ E$ t0 P  \8 |( ?    config.account2.name, // 附言填写内容提供者的账户名,平台合约会给它分账
( N- v7 I1 w2 Q7 i+ F+ ]- {6 t+ ^0 ?# ~0 H
    {. N. k7 R0 o- r" v# l/ y" X8 i3 E
: S. k9 P% a4 w7 ~, b
        authorization: config.account1.name //提供用户账户的授权$ B* T% P# }% j4 G/ H
! y7 n6 F3 D/ Q, k+ l
    }
. p' s1 O+ R. A3 ~% u
- B, F, u. h! d# X)
) v7 G2 A  K7 }* U. o2 Z7 a# a. G: ?
! v7 V9 l3 t( Q4 Bconsole.log(r)* c) S. C! T5 h0 s. h8 C

. g4 T9 ~' D0 P" Y7 E我们要从用户账户 account1 给平台合约账户 account3 转帐 10 FO。memo 参数为要分成的内容提供者账户 account2。根据合约中定的2/8分成,平台合约账户 account3 将会分得2 FO,而内容提供者账户 account2 将会获得8 FO。! N' k; `) w8 V

" A' U# E1 J9 O, d使用命令 fibos transfer.js 执行该脚本完成转帐操作。5 L; H+ a4 h0 M% W/ q, D. R( N% \
' d  s9 v, s6 ]% I3 c/ c' Q/ i
下面我们再来看一下目前三个账户情况。执行命令 fibos account.js。三个账户金额大致如下。
4 R8 k" T: ~2 }2 D+ Y0 o$ J+ W; ~# L* ?, Z
用户账户:helloworld11 金额:136.4245 FO内容提供者账户:helloworld22 金额:8.0000 FO平台合约账户:helloworld33 金额:2.0000 FO
6 z7 m1 L- e4 ]  J2 O
/ x( G4 k# o) L6 T% O8 g' h结果显示,分账账户和平台合约账户如预期那样获得8 FO 和2 FO。
+ d4 j; m9 {$ |3 [; M# x7 B2 V  k' g7 ?

8 Y/ |! g( T6 ]. Q
- [+ h6 R" M& y综上,我们成功使用了智能合约实现了自动分账。平台方还可以继续根据自己业务需要定制自己的合约。
4 d- {7 ^2 v/ S& [
0 h4 `) m# S) D文中的代码请参考:https://github.com/fengluo/fibos-subaccount
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

哈哈笑417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11