Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

哈哈笑417
309 0 0
自动分账是很多平台都会用到的支付功能。很多互联网内容售卖平台都会跟内容提供者分账。比如:Apple 的 App Store 跟 App 开发者三七分成。很多平台都使用了支付宝、微信支付作为支付手段,但是要同时实现给内容提供者分账,却是一件不太容易的事。使用 FIBOS 智能合约可以很容易实现这个需求。9 A2 u1 K2 c* i5 }* @  ~

- n' d( Z( h& m文中代码已在 GitHub 上开源。https://github.com/fengluo/fibos-subaccount: }2 v! C9 U& x$ j$ K  B) ~

* n/ x* S. F' b8 P, C! z$ f设计思路
/ o9 C/ [2 Y8 b7 l: M' c4 Q) ^- J& ^& A- O6 T' m1 [( H
在 FIBOS 转账是通过 token 合约的extransfer方法来实现的。extransfer方法在执行的时候会给转账方账户和入账方账户发送通知。所以用户给平台方账户转账的时候,平台账户就会收到通知。所以整体业务逻辑如下:$ ^) s0 ?9 D/ ]
" D2 X* q% N9 D; E2 P' n& l) Z" N: `' L% Y) u
        quantity: 10 FO
# {4 k! U* S: Y: Q: M6 D5 M8 A' S
        memo: 内容提供者账户           quantity: 8 FO
9 n+ }5 ?/ W& ]7 x
6 w& T4 Y$ W/ u% J0 u& P2 C9 U1 K( Q用户账户 -------------------> 平台账户 ----------------> 内容提供者账户
5 ]- b8 F/ `% }+ h8 K; c; t, d( C: c: u' H6 X, w
            extransfer      2/8 分成   extransfer
6 Q2 y5 q6 p5 }6 |# l4 Q1 c/ k6 N0 |4 U/ a" S0 H) F
1.用户给平台方账户转账,memo 中填写内容提供者的账户名。
1 X7 a$ ?; m4 m/ S# O+ e+ d
0 }6 c, m- M. Y/ [, Y2.平台方的账户合约监听 extransfer 方法的通知,然后做出分账计算,给对应内容提供者的账户转账对应金额。
& q4 F7 `' D2 G" j' C6 D# x* ?, ^6 I' W( o+ N/ L
整体逻辑很简单,整个合约代码逻辑差不多用20行就可以写完。
' i; a3 T4 \: U
$ n% S4 j2 F9 F4 ]5 g编写合约
' }5 n; w# a! ^/ u0 L  N2 Q6 w( F% ]* s7 o
FIBOS 的智能合约分为 ABI 文件和 JS 合约两部分。ABI 相当于合约接口,JS 合约则是功能实现。本案例目前没有接口设计需求,不过 ABI 文件还是合约不可缺少的部分。所以我们简单创建一下就好。
- o# W4 a& d2 C! r% b1 j, @6 ~0 d* V$ t1 i
我们先创建一个 contracts 文件夹,合约文件都会放在这里。然后在此文件夹下,创建 subaccount.abi 文件,内容为:
  u8 ]. W! D+ y5 l3 a+ G# T( C$ F  W5 l- _
{
0 y# A5 r# j( J$ P  X4 d: z5 t0 y* Y3 V1 Q+ F! N+ e/ R$ Z
    "version": "eosio::abi/1.0". s3 J( B) Q3 V

3 G, z/ T- l6 s  Z- Z}" _2 a/ N) e" W6 i% g; a  }
8 W$ F. F* l1 n, l
JS 合约部分也没有太复杂。在 contracts 文件夹下创建 subaccount.js 文件,代码为:& I- O" y, F0 ], O& o8 U$ n; L
% ]; u  @9 Q/ O6 S5 K1 N$ f# }. m0 T
exports.on_extransfer = (from, to, quantity, memo) => {
$ F) f7 n9 U; {  B9 U
  b4 K: t1 j  s' H* Q6 L7 d1 v    // 需要在开头做一些判断
5 k8 ~! q- u4 S, y
6 [2 }/ }) z' b9 R# N. ~( Y    if (to === action.receiver && action.is_account(memo)) {
# C2 W* z7 A6 v. M7 O. C0 m
7 _' Z7 m3 G# u% H4 b- F        const num = parseInt(quantity.quantity.split(' ')[0])# W5 d* A: R/ ^$ d1 G) |; D: t% \

# S/ H7 Y- W; i+ D; O  w        // 假设我们约定平台方跟内容提供者是2/8分成。7 O3 E, {: u: k0 j) P
+ B# N% D, h# e. D6 b9 z1 H: s
        const subnum = (num * 0.8).toFixed(4);
3 g; b# m( I' c5 Q6 |9 c, f1 S% x* R. B
        trans.send_inline('eosio.token', 'extransfer', {/ h2 m2 ?. q0 }9 c8 J
- u4 u2 |9 g$ g# |+ o3 T7 G/ Q
            from: to,
  T  y2 ^$ {. c* V% |! @5 B& Q3 ]. S
' P: T# C0 ^1 S7 b# R            to: memo,
. H3 A8 W2 d( d, ~0 ?9 x+ B) F' {0 S/ r% a& J6 [; o
            quantity: {/ z' }  F* |2 s7 U8 v
" T5 Z3 \) ~& m9 Y5 X( @
                quantity: `${subnum} ${quantity.quantity.split(' ')[1]}`,* u$ X  b+ z2 P# v7 m( S5 M

$ R5 T- {; E  @! {" {8 K+ x- z                contract: quantity.contract
; q  F( [7 z6 w( s! L) X; z+ v. o* r4 r. c% l) x3 C3 |
            },
3 |6 G' L3 j  _7 E7 D6 X. M5 \9 f* u8 g7 e/ V9 g" x  S+ ~* |6 V
            memo: 'sub account'9 H+ T: ~' R! T& ~& E# x
7 A6 `( _7 @4 K6 R2 \
        },
8 y3 `( ^6 Q: m" B7 A
4 s9 f3 }0 H8 z/ R" H6 U! ]5 z        [8 T# Z% W' j( \" e: _  g% ^4 E

8 E. H0 O% ]7 s$ ?2 i            {
2 Z, Z8 ^# B1 o) V
/ l: W) [$ p9 ?                // 需要提供合约账户的 active 权限/ |1 h! {) }; M0 F- t
4 d3 ~! }$ Z' i/ w+ S% {% h) P. P
                actor: action.receiver,2 ]6 M* f* Q! [. I8 \

" b/ F" d  M4 n! z% U; o                permission: 'active'
. y! }2 J: V' q3 Y) i3 Y. @/ _0 R* N1 E* Q4 ?; l, i: l
            }
1 D- P3 w0 h, ]4 _0 `- @$ d5 [1 ~. k+ N: W& a2 j' D
        ]);
4 j" j6 ~( }( g" n( V' ?' j+ G) x0 s, k' V- o& t0 W
    }
. ]$ \$ S  K8 E& j- \8 b& k# D! ^/ W1 j
}6 P9 Z8 h- l. P# Z

# o, O5 j$ J8 m- |! l  X合约代码开头我们需要做一些验证。* T, J3 H* f" l

% y7 x  ^! \/ q* i( u$ a1 s" h1.收款方的账户为合约账户,否则因为下面代码执行给内容提供者转账时,因为转帐方也是合约账号会再次收到通知,造成无限递归,超出最大 send_inline 层数而报错。
3 x( g  ~$ m- j3 ^8 H# {
& f" I/ `, g' J5 z+ I3 X1 `2.我们用 memo 参数来放内容提供者的账户,所以我们需要对此参数校验一下该账户是否存在防止打错。
% f4 d1 a( s7 X- N2 z6 ?# L; [* X; ?! V% l+ F" ^6 _" ?
合约代码中我们使用 send_inline 调用 eosio.token 合约来执行转帐操作。转帐操作需要对应账户的 active 权限才能执行。为了解决权限滥用问题,FIBOS 定义了一个特殊权限 eosio.code。我们需要在平台合约账户中配置权限,在 active 权限下添加该合约账户的 eosio.code 授权。具体的配置操作会在下面说明。/ ?3 O* j2 {3 P2 D2 C
5 A" P" l+ L% D% ~
在 FIBOS TestNet 上注册账号
, f0 W6 W8 E9 Y- d$ ?3 B0 R1 i- k. \
为方便测试,我们在测试网 http://testnet.fibos.fo 上注册三个账户。
- ]0 L0 y3 O, z  T& R
, `$ |3 v( o( t) W! s用户账号 helloworld11* I/ v0 S5 y# T& G) ?! z6 D4 n
! p1 N7 K) G- A" [2 l: z
内容提供者账号 helloworld22+ G4 i: M+ y5 k" ~7 Y! I/ N
$ [% J. w9 A. c; r& ?* B) b1 v
平台合约账号 helloworld33
0 |+ T6 H5 g6 {" q1 g$ g* h
$ C& ^, D9 x6 x( d我们需要记录这三个账号的账户名以及公私钥。以便下面的开发使用。创建一个统一的配置文件来记录这些数据:
9 @( K+ _) u8 x' [- c, X
8 R1 W7 i. z- F$ p9 [const config = {
" _) [9 h0 ?: Q+ L( |- V- O) E  o2 |0 K& i* z! c& P: k6 u
    // 平台合约账户的客户端配置
7 e9 v$ z" g( \( g* K: J0 ^) C+ `$ C9 {
    client: {
" }% q8 l  M2 i+ f
+ _1 B, Z! Q2 g3 z3 P: D        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',  m( z8 q0 D& p6 g/ S( H, |
' b* b5 P; W% |% a4 J
        httpEndpoint: 'http://testnet.fibos.fo',# ]( U4 g) ^+ N8 ?

5 d4 y4 `+ O# m* V2 R7 h5 Y        keyProvider: 'PRIVATE_KEY_OF_helloworld33': [( Y/ U0 e' ^/ [$ \

3 Z$ f/ h$ Y- k. o3 V    },2 I' w1 K) X. n' [/ g+ v3 R2 |) L
: F& ~' [" S$ W/ [& {
    // 用户账户的客户端配置
) s0 R2 U( X+ ^7 x( U6 A$ Z9 P
5 ^6 ]+ ~7 \3 E$ t    callClient:{$ {/ `) R4 y4 U+ b4 ~1 {0 }
7 d. c$ t, R& y" |9 O+ s
        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
% _- C/ ~! b( b4 Z' E! Y, T! u7 l  I! F
        httpEndpoint: 'http://testnet.fibos.fo',
4 X7 e, b. a9 l
, a  J: x" v& |        keyProvider: 'PRIVATE_KEY_OF_helloworld11'
, @0 J# A! R+ w9 K+ _, j/ b: r4 P& K" D3 u5 D% h) b, k
    },
8 m5 Y- n; B& j
2 ?5 M7 F. A0 R- R9 n# {" r: S9 i! ^    // 平台合约账户信息( J6 n/ \4 T. n  ^+ z# N1 k

/ X$ J: H7 n5 r/ q- N( a7 d    contractAccount: {
$ ^* z9 x* n7 T, A' A2 [6 Q; f: l7 k# h, U. n& x" n+ N$ B& a/ _- q
        name: 'helloworld33',0 F, [( h3 D- G( N

( t$ v4 E+ p+ x$ d/ {  Y0 @        publicKey: 'PUBLIC_KEY_OF_helloworld33',) g6 D3 w8 F0 K$ }& E3 p1 o. E

' V9 @" n# _# N        privateKey: 'PRIVATE_KEY_OF_helloworld33'
/ n  N9 U# Q0 }" H/ |
" I% u$ h' j" i  ]    },2 o1 r  S& u' {) z; v+ p# b' s5 V
3 W  W3 s7 [- L+ Z. |
    // 用户账户信息
( w+ Q0 F4 y/ ?+ j/ E- N$ B. l( v( B, H5 d' N, ~& f, g
    account1: {8 Q' n4 k' `0 ]9 H$ m

: @. ]8 V6 ~! T9 p7 ]$ b2 k7 Y        name: 'helloworld11',
" a! f+ W, q5 _2 o: J- r, P7 G2 V! N' p
        publicKey: 'PUBLIC_KEY_OF_helloworld11',
9 k: R/ f, C1 {6 k( A7 R
9 J3 |+ N5 P4 e) n        privateKey: 'PRIVATE_KEY_OF_helloworld11'+ k1 K/ U/ r9 K, I( j  O# V6 u

- g0 x8 g  P8 G/ o* n2 P+ a: ?$ {    },
* @' z! q  g- P0 D! ?* o9 ?  l0 I& t3 _3 z: j, G* R6 j
    // 内容提供者账户信息, N2 o- y; G% R0 {( ?. v- W; g

3 E) A  Q; z) `0 u% V3 G    account2: {& z, C2 |7 _8 h- g* w0 b

+ t' d) h$ t# H, {# b7 @" d        name: 'helloworld22',
4 w; o) o+ u4 n7 q& h/ R7 _! j- A9 v( N! u5 [% s
        publicKey: 'PUBLIC_KEY_OF_helloworld22',. Q9 _, d- N5 l& s9 Y
& @" {1 X2 N, N# U# a
        privateKey: 'PRIVATE_KEY_OF_helloworld22'& i( U$ V: e, u: C" {, r3 ?: C# A, G
" u9 o6 p3 j+ `  F$ z
    }5 l% E* J' |$ w! |: X# X$ N) \  l* |, f

; b0 C& Y8 G) s5 ]}
/ Y1 U" _9 U9 W, k0 ~/ e% G7 m; |* R. Q
module.exports = config9 b$ F, X( `" ?% [7 R

3 c5 o$ N3 }% o配置权限7 v1 }: e. ]& x- I8 F1 y0 A
/ Y. L0 \$ Y+ I! W9 y
在合约代码中,我们调用了 trans.send_inline 函数调用合约 eosio.token 来实现转帐操作,但是转帐操作是需要账户的 active 权限。所以我们需要更新一下合约账户的权限,需要添加调用者的 eosio.code 授权到它的 active 权限。这个调用者自然也是这个合约账户。" h2 p7 Y: Q3 p3 Z. ^4 }6 b# O
7 l; \/ p2 W; ~5 m* O; N' l0 r4 k/ Q
const FIBOS = require('fibos.js');
3 z7 v9 x9 ]6 H; ~
/ R( f7 L$ m! Y: P6 |# }const config = require('./config');
' c; Z# g+ |: ]9 o2 x3 l' \7 O( @( k. h4 p
const fibosClient = FIBOS(config.client);
$ _- w7 A& b* }) n9 C+ X
: i7 U0 m# Z' {' A8 b3 glet ctx = fibosClient.contractSync('eosio');9 z, U9 ~! j" n% W6 m0 q
/ J/ ]+ S* Y+ y) |: ]4 Z
var r = ctx.updateauthSync({
' `6 O2 N- n+ P: R0 ]1 I
7 W) {( U& B3 C* X4 a  account: config.contractAccount.name,  \+ {. i7 Y/ o' k) r; N
; n+ h/ v  V5 `( @
  permission: 'active',
/ d' G# n' F# q& S6 C- w/ ^" ]: @' Y3 ~# n7 Z. e- X7 g
  parent: 'owner',3 p" G9 ~; X; {
9 R% z& U4 ~2 n7 L  `7 y5 ]) ~
  auth: {, U9 K2 {2 Z/ ?5 _& N/ d0 `
- R- f1 u. h1 V, q3 k/ {( \' q. u* ?9 @
    threshold: 1,: y# m/ L' K6 H
0 ?% F& t! O8 d4 p
    keys: [{& Y$ H. c( y, F: }2 H) V* r+ P* U

, n9 q7 I% H, P      key: config.contractAccount.publicKey,- j) F# c) U% S. ?% o$ f  c/ g6 Y
$ W& U- |4 @6 y3 H( N7 h5 l
      weight: 1
- m/ [' y5 [: W' V1 Q6 x% q
6 s( m3 q# ]9 _    }],
+ l! Z# T2 U9 y5 g1 }
" v: z! L  k( o" p    accounts: [{& c& H1 W- \* v* _4 k# A$ g- n

8 k$ T) j+ C. m! i        permission: {
& q* d. k0 n$ D: H% @9 _
4 w6 B3 J  o# R1 K' |            // 将调用者账号的 eosio.code 授权添加到它的 active 权限下。
' T' H* i; z/ ~2 S$ ^& K3 f1 Q- X* E+ }8 T
            actor: config.contractAccount.name,, G) H% _, t6 L/ M

  i( l* ^9 @) F0 l0 Z1 k$ K            permission: 'eosio.code'
$ R: ]6 n5 b! x# V8 f) G% N  p- j$ S3 K+ i% H' z5 Z3 t- L
        },
; n9 W! ~: Z9 U" a  v9 e
" h6 o+ q: {7 h; u  z7 W        weight: 1
7 N# ^6 l) ~0 k5 I
+ n: G% ]( ^8 f- `    }]
1 V5 x" F5 B; p" n+ z4 s$ |6 h( ~7 f: ~# t
  }
& @3 {) P- o. m- V
* N" V. ]5 z0 q  m) t0 R},{! N/ Y: L# ?/ A/ L
" T. x; V* U2 [3 U
    authorization: `${config.contractAccount.name}@owner` //更改账户权限需要使用 owner 权限# S7 F- z6 }5 D6 b/ x

0 J) S9 h* I7 [6 I* u2 r});- T) f" K: h/ @2 H0 N. Y3 Y+ [; i
4 `3 ~8 I7 v2 |2 S# x* G" I) l- x
console.log(r);
1 ?  g1 k' I) u5 {# _9 m
# \2 |6 z4 c3 ^1 v( t部署合约2 s: w" D+ q& n$ P: h% [; Y0 c
2 n  X' I% i' A' D( g; u
const FIBOS = require('fibos.js');
$ m( |! N9 G  g/ F  Z7 Y
: K6 V% Y( T' F% Z6 ]5 cconst config = require('./config');4 ?* o  `# H" b$ V
# y; Q0 D7 o8 V
const fibosClient = FIBOS(config.client);& O/ Z$ e+ J" ~( ?/ r$ d
) E5 W! l: p: T# w8 ]/ q4 W
const fs = require('fs');
' y( Z( ]1 d" G% }8 {& ?( C6 V  E1 r  U: h( H
// setcode7 h; K8 X6 O, N9 k0 y

, [$ S2 [0 r* b$ G: `5 s: Iconst jsCode = fs.readTextFile(`${__dirname}/contracts/subaccount.js`);
4 |7 `: K& `7 c) I" l( D2 Y3 A+ U  J- D' z* {
fibosClient.setcodeSync(config.contractAccount.name, 0, 0, fibosClient.compileCode(jsCode));
8 y. M$ F; y# n3 E4 c, k1 v9 D. y
6 C2 y& N8 R! C" _// getcode/ M2 y' e8 n% g! G+ d

6 t0 H# n; C, v) ^8 Kconst code = fibosClient.getCodeSync(config.contractAccount.name, true);4 N( o$ ]8 S6 p7 t  a/ \

) ]( N! a8 F* A. a+ Zconsole.log('code:', code);
' ~0 _( b+ j* h; n/ \5 r! b! K$ i5 a
// setabi
1 ~- |# f# r" `6 @' r5 F  W$ J
+ W+ Z  O+ ~; a1 u0 Y! h: Econst abi = JSON.parse(fs.readTextFile(`${__dirname}/contracts/subaccount.abi`));6 Y7 Z: Z: l; R

9 M1 r% a7 n5 y4 S& q4 r' pfibosClient.setabiSync(config.contractAccount.name, abi);
' N6 q, ]$ ~+ b/ f. ]
$ O& E* S0 W  @% }转账测试, p2 U. }! q( Y* \" n
( S3 p* O1 @5 d, f) h* o4 ]/ [' B. O1 ]
我们先来写一个脚本 account.js 来查看三个账户的余额。
5 u$ B  C0 b6 {, v4 P( R/ J$ k
+ l9 [1 v" l# t5 X1 I6 Dconst FIBOS = require('fibos.js');' p# U; t+ y! V6 W; n) ~" r1 _

4 o0 d6 `. n; V2 B6 v" aconst config = require('./config');# N# _& `  ^6 v% c1 Y
# e. W0 H2 ]& S+ n3 f' u& W
const fibosClient = FIBOS(config.callClient);
3 j- l& x0 U) D! H+ L; h
; F7 h* O8 n) ^# M# K- lconst account1 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account1.name, 'accounts');! U- w  a) t5 Q$ ^" p- T% V+ l( Q1 `
0 G8 \8 |$ F7 {8 T( ~3 T% r( C
console.log(config.account1.name);% q3 c+ r5 W" q7 ~
: N7 F5 W( L7 x$ B
console.log(account1);
/ V& B8 Y; @( b4 F( V8 N, b' b* O* ^: [/ R
const account2 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account2.name, 'accounts');
' U5 `5 S" [6 k2 N/ {
: |# d, U1 C2 q6 sconsole.log(config.account2.name);
# y1 B9 X6 ?  a7 V1 u1 a4 O) e
$ M4 u2 G2 Z& ~- kconsole.log(account2);5 p- @4 X0 {4 Q5 p" [& n

1 G, U/ V5 I1 \$ Fconst contractAccount = fibosClient.getTableRowsSync(true, 'eosio.token', config.contractAccount.name, 'accounts');8 R' o3 m/ P; o
$ c0 l5 H2 w9 N9 C  F! ?8 @2 o, V
console.log(config.contractAccount.name);
( u+ A7 U7 ?. ]' ?: z8 n
% `2 E. i: q3 w3 A; Dconsole.log(contractAccount);7 R: h% k% V3 U4 }
$ e- h  Q( q6 G! d$ ~
执行 fibos account.js 来查看三个账户信息。 目前我们的账户还没有 FO,所以大致情况是这样的:
' |1 w9 J( S# j: t% l# |# q7 }2 L, U+ X! G2 f8 e4 g8 \( ~. J/ K
用户账户:helloworld11 金额:0.0000 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO
7 M  o: \7 ?/ S: _" v8 O
" E& U: n- f$ A  }: r

: o0 y( d! v/ h- Y1 z* O3 s/ M! d! a' s: v7 e( S( Y
测试网会自动给每个账户发放10 EOS 的通证用以测试使用。账户中还并没有 FO 通证。所以我们再来写一个兑换脚本,用1 EOS 换一点 FO 通证。, U; K; v4 y6 f; F6 c" _: C
1 X3 G. |- x6 T( x2 T+ E
const FIBOS = require('fibos.js');0 \7 \7 C! ^; T. G
; M% s6 C/ g% {* l2 s
const config = require('./config');6 G' g/ _8 b4 Z9 I0 |$ e: y& |
) J0 I! U+ p8 f; x7 s4 ~
const fibosClient = FIBOS(config.callClient);
8 F. v' r2 w: L* Z- j6 b: h3 e
. y9 j+ m% |5 X  G+ qlet ctx = fibosClient.contractSync('eosio.token');" K7 j  K* W5 O

% k- E, t6 Y3 `$ K2 A. rconst r = ctx.exchangeSync(
* h9 d; |7 ?* \' l( T+ |4 v! K; K9 z9 k0 _
    config.account1.name,
( q7 P4 B4 G% V. u4 ~
! a1 v& Q1 z& ]) u    '1.0000 EOS@eosio'," V2 [0 Y& c& S3 o) ^% M

9 ?3 o) @! R- }( ~% Z. d1 W& q8 n. P    '0.0000 FO@eosio',
4 i) Y" F' m0 m" w# x# {7 U0 d9 L: G9 P' G# W; ?9 @
    'exchange FO to EOS',
( h! ^8 M/ j. `. F. b) x
+ J) P4 P+ |9 _* z7 J# s* @    {
6 v) |" V9 s; ^6 n/ `& l! E; c' N( l0 E
        authorization: config.account1.name
' V, O" \! l2 T: W! o$ [! ]  _( {1 L; _" b& P1 \1 E& e. J% ]. O" A
    }5 L' m, V, w* W) I. Y- ]
3 ^1 p/ h9 B( d7 T/ `: R# T! ?
);& Q, r6 B1 }' }  J: R

/ E$ h5 c' ]- Q4 r1 C. Hconsole.log(r)
, T4 [9 N2 r2 s
7 Y. y- K6 w3 g4 B, A  v, `7 E再次执行 fibos account.js 来查看账户信息。目前我们的账户金额大致是这样的:% x" `# S+ S+ V1 p- r9 X
) ]/ u, ?* E4 y# {% d# }
用户账户:helloworld11 金额:146.4245 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO5 n! ]% z) b! G5 g

  q& j2 _0 k3 T7 U$ @) W下面写个脚本 transfer.js 来执行转帐操作。
3 Z; q) T0 O0 q4 b, Q1 I7 T3 z0 V/ d2 m, W3 ^1 q4 E
const FIBOS = require('fibos.js');2 R, i0 b+ N0 X0 Q- }

  p" u, n* K0 o, e9 Jconst config = require('./config');
- |) n$ {! r) A: }! M
4 |6 S+ _$ A# F+ A8 g" X  U; Qconst fibosClient = FIBOS(config.callClient);: `8 U3 A( L; Y! r) y' O
! Z" I: m* [+ e/ Y; d
let ctx = fibosClient.contractSync('eosio.token');  ^+ s7 O5 o& i4 m
; j; ?# F" ]7 V% j
const r = ctx.extransferSync(' P$ K. q6 F* a0 t: g

" ]! L, ~( W7 x. L( F    config.account1.name, // 用户账户( L; L+ b+ a  z  {( H

! x3 ^2 h) ]% D) U3 c) x8 z    config.contractAccount.name, // 平台合约账户
9 Z" @; G" l6 k( S! Z: c# B
8 r7 R/ @) g  k9 e9 Q/ p    '10.0000 FO@eosio', // 转帐金额- P- `+ Q1 g! T) G9 ~- k0 w

8 @7 y' N+ y- z$ `; k  m    config.account2.name, // 附言填写内容提供者的账户名,平台合约会给它分账
* x% ]* B( H) K% H& E3 L" K% U) @' M8 g* O4 T' r' U4 O3 Q
    {+ P) K& |# C( P* Z
8 ~4 m1 p# [% B, Q& F) K
        authorization: config.account1.name //提供用户账户的授权# [  i- K2 w0 X

+ h8 ?6 G/ t' h% _( ?    }( c4 l5 x4 W! O$ z7 Q

  g" H' O; O/ c+ X/ s)% m3 a3 R7 T+ c+ n1 z
! O3 H' W4 Y8 a1 w8 }* I
console.log(r)
$ z, A5 q( w6 V1 A& r( M5 H7 ~1 W( t" e8 L. z3 ?
我们要从用户账户 account1 给平台合约账户 account3 转帐 10 FO。memo 参数为要分成的内容提供者账户 account2。根据合约中定的2/8分成,平台合约账户 account3 将会分得2 FO,而内容提供者账户 account2 将会获得8 FO。
2 |4 B* o6 Y' K+ j
) T! c% F7 v, y0 @/ u. |% U' K使用命令 fibos transfer.js 执行该脚本完成转帐操作。
; a; c4 {$ Y& l+ e: y, |- a2 t- J, a" F1 I
下面我们再来看一下目前三个账户情况。执行命令 fibos account.js。三个账户金额大致如下。
4 S' p" l4 U% M1 L
1 a% e2 q; \$ h- I" C用户账户:helloworld11 金额:136.4245 FO内容提供者账户:helloworld22 金额:8.0000 FO平台合约账户:helloworld33 金额:2.0000 FO. o' @: O+ U" q: X8 u

0 V6 ]: `% ~) q( V1 Z& ?结果显示,分账账户和平台合约账户如预期那样获得8 FO 和2 FO。
1 ]; j  T& z8 j8 p% H! l3 ?" @# f2 m+ a

+ |+ L) j% Z- d4 E
: ~" A) R  m9 b综上,我们成功使用了智能合约实现了自动分账。平台方还可以继续根据自己业务需要定制自己的合约。
" C- K" {& I& Q$ e* t' {* i$ w8 w, v
文中的代码请参考:https://github.com/fengluo/fibos-subaccount
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

哈哈笑417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11