Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

哈哈笑417
310 0 0
自动分账是很多平台都会用到的支付功能。很多互联网内容售卖平台都会跟内容提供者分账。比如:Apple 的 App Store 跟 App 开发者三七分成。很多平台都使用了支付宝、微信支付作为支付手段,但是要同时实现给内容提供者分账,却是一件不太容易的事。使用 FIBOS 智能合约可以很容易实现这个需求。
" r& `2 o& j, A8 X6 y
2 `9 q% z, |) q+ T' {文中代码已在 GitHub 上开源。https://github.com/fengluo/fibos-subaccount
) P$ g, v" k# Y1 [: i
4 p5 B& |1 j6 O0 o# I5 }. B设计思路" g" ^, E& L6 D+ [5 J5 C
3 j. [. X% k) v- b6 w' D7 H5 w
在 FIBOS 转账是通过 token 合约的extransfer方法来实现的。extransfer方法在执行的时候会给转账方账户和入账方账户发送通知。所以用户给平台方账户转账的时候,平台账户就会收到通知。所以整体业务逻辑如下:+ Y9 o  r, S( n- t7 M
' X' z. c8 i5 |" p5 c
        quantity: 10 FO; Q) \% ]# F7 |

; b( t: G" ^7 [1 Q/ Z        memo: 内容提供者账户           quantity: 8 FO) h1 B* v, F) q7 D& R
7 l1 ]( _; M$ W" o; B1 b
用户账户 -------------------> 平台账户 ----------------> 内容提供者账户
8 d8 u0 u: Z2 V. h+ b$ G& M) ~! A# k6 J" K0 {0 [1 Z
            extransfer      2/8 分成   extransfer
) D4 S2 b: G4 }4 ?1 [; h8 m
5 c7 E8 r# i8 [1.用户给平台方账户转账,memo 中填写内容提供者的账户名。! O+ V( h# E( \" M% h% f
& ^! j' ?: x: o# u
2.平台方的账户合约监听 extransfer 方法的通知,然后做出分账计算,给对应内容提供者的账户转账对应金额。* h% u, L7 g  I. Q
/ [8 q+ K4 w* ^- N" @$ d
整体逻辑很简单,整个合约代码逻辑差不多用20行就可以写完。
+ Q' P! c- v0 \- c
7 M9 ?( V8 O* `( d# R; {: _  k3 z编写合约3 L& x7 w# O  Z- Z9 _

7 h' @' J5 s+ E: T+ S, ]$ G/ R! G& k" V, CFIBOS 的智能合约分为 ABI 文件和 JS 合约两部分。ABI 相当于合约接口,JS 合约则是功能实现。本案例目前没有接口设计需求,不过 ABI 文件还是合约不可缺少的部分。所以我们简单创建一下就好。  r; R( z! u! ^6 S( G7 R
; m- t* h) G- g# A
我们先创建一个 contracts 文件夹,合约文件都会放在这里。然后在此文件夹下,创建 subaccount.abi 文件,内容为:* {' g' t5 x+ t2 h& ~4 H
) B% n8 S! w1 }8 P" g$ l' D  p
{
7 T/ i+ j3 K  F0 R) S
9 w# s% m( T8 a  O0 Z3 C/ f- R    "version": "eosio::abi/1.0"7 J( I' f; l( d, f' I4 o
* U7 i) H' e( r! w  \( v/ I/ d" H
}
9 Y5 }% U6 L9 `' O
! U2 S' X+ f$ N) k; O! m9 U& yJS 合约部分也没有太复杂。在 contracts 文件夹下创建 subaccount.js 文件,代码为:' }! w: L; B5 ]0 |0 W+ }3 p* ^
; x( E+ f; ^" @4 y
exports.on_extransfer = (from, to, quantity, memo) => {
$ o! k+ \, d. \$ b# m- w3 I3 A- ]8 e
    // 需要在开头做一些判断: |' K1 l& }) L" a6 u& s& E3 j

8 ]- C* O8 R4 c5 @    if (to === action.receiver && action.is_account(memo)) {' Q- U) ^2 U1 _' E! \
, ?& Y# S! e* C  Y( c3 Q: P. ~& ~
        const num = parseInt(quantity.quantity.split(' ')[0])
% r( r# `! q; q( `7 S' I
2 V1 c- U9 [% T5 S, g# e8 j        // 假设我们约定平台方跟内容提供者是2/8分成。. `0 }1 L; E& H, \

* ]9 x3 @3 _# n  E, A) G        const subnum = (num * 0.8).toFixed(4);
5 ]* J9 x8 i) N# i$ y9 [
0 U/ x* t* Q: u! x        trans.send_inline('eosio.token', 'extransfer', {
6 V1 u- Q! L4 R$ q4 ?7 L1 N. q! ^& ~9 M
            from: to,
. S1 {% w. s$ X8 l) B+ d1 a5 A! f" v3 Y
            to: memo,
* u2 j! Q+ D! y- x1 O9 V- j: ]- ^; E" R  @: O2 |# S  b7 O
            quantity: {) b5 Z3 L$ U1 u1 E- |9 H

8 Q7 Y7 {0 u  s7 M                quantity: `${subnum} ${quantity.quantity.split(' ')[1]}`,+ N3 m- I, \0 x5 _

0 A1 r* K9 M% Q  `  {                contract: quantity.contract
" |7 z) y% C5 F+ l" Z: D! `+ M% q
* p6 l2 P1 ^3 X            },1 _" t, W& m7 p# ?5 }! u( D7 P' v
0 I# H8 r0 ~; k& Z/ `
            memo: 'sub account'
6 n! Q9 b3 T7 N: P' X& A2 w" [1 Y" K$ ~
        },
7 [& K  n0 V$ J9 S6 O6 F" @2 e! c; q5 z5 a
        [# f6 k6 R+ M+ T2 z8 J% ~

# X" X9 Z* H% O& n' e% A            {
; r. T: O. n8 S$ N! i0 F' @# p0 B- \$ K/ ]! d
                // 需要提供合约账户的 active 权限
" p/ J2 L5 e0 U: x; e- e
' X8 Q0 {" V: }- W: `) U, W                actor: action.receiver,  Y2 B9 c/ F2 I6 B6 I  V8 m
, X& \% n* G! o) h$ E5 m+ ^
                permission: 'active'7 n$ I' j( d! h9 @0 l  J

/ F3 ], q! w7 C3 T$ N            }
5 F: X* x6 y5 p3 z% V
2 z+ ~# Z+ E5 L' b        ]);
6 G2 t  Q& ]2 r" }0 ~" }3 e$ n5 N; ?1 _; X& r% Q4 z, U: ]
    }
* M; W- a6 h. j: j* I( z
  H- b6 r. ^4 V* P% N3 D5 ^- M}
$ a* \* v4 H# j* f9 W- j& o5 O$ I2 I1 O
合约代码开头我们需要做一些验证。
3 h# L' I0 u. W. V' ?9 r: I( L& U* o. y. K
1.收款方的账户为合约账户,否则因为下面代码执行给内容提供者转账时,因为转帐方也是合约账号会再次收到通知,造成无限递归,超出最大 send_inline 层数而报错。
2 ~5 A/ r" k+ L; ?2 ^
5 [3 A" W. T; l/ ~2.我们用 memo 参数来放内容提供者的账户,所以我们需要对此参数校验一下该账户是否存在防止打错。: F9 U: R' M. ]: X; e0 [
0 h0 }2 a; @. ]( s% Y+ R
合约代码中我们使用 send_inline 调用 eosio.token 合约来执行转帐操作。转帐操作需要对应账户的 active 权限才能执行。为了解决权限滥用问题,FIBOS 定义了一个特殊权限 eosio.code。我们需要在平台合约账户中配置权限,在 active 权限下添加该合约账户的 eosio.code 授权。具体的配置操作会在下面说明。
7 r' Q  G7 s/ v( a7 [% c: ~$ @# Q* G0 d  J) g! X
在 FIBOS TestNet 上注册账号9 [" R: F) ]$ W4 k

$ `6 _# ~1 Z& Y, O; `为方便测试,我们在测试网 http://testnet.fibos.fo 上注册三个账户。1 ?4 c; P% B# F* a; C* H' R6 d' k; m
5 v) T- ~  a8 i' ]7 I+ T2 {7 K7 t
用户账号 helloworld11$ e( b& Q" b3 ^* e
2 ?4 G: y1 b) a* y
内容提供者账号 helloworld22
* I# w$ D. [( @2 _; P3 X  ]7 I2 G
7 i8 }2 m4 t7 ?# g平台合约账号 helloworld33
% |4 @1 J6 t, ]$ E- T" k% }8 u- [- Q( n6 q; r& k
我们需要记录这三个账号的账户名以及公私钥。以便下面的开发使用。创建一个统一的配置文件来记录这些数据:
/ P5 s& ~2 w& t8 E
1 H, `' g& I. Bconst config = {% N8 ]9 u( p1 [7 H4 S

- l; O) A! V5 R/ g' S    // 平台合约账户的客户端配置
6 r6 U! v8 E, f; a+ p1 p* [7 A: f) O' C: l) c: x1 @+ _% \( n
    client: {
$ t2 i) A" @0 x/ p: h/ ?( H( O* M" ?
        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
6 s7 e5 s* F" O% U, m/ d
  u1 T2 N+ h  k8 [2 i' e7 c7 v        httpEndpoint: 'http://testnet.fibos.fo',2 {  d) r& l8 T; A( g+ G
% Y, @3 ]: j7 \: e- f2 q8 }) Z: @
        keyProvider: 'PRIVATE_KEY_OF_helloworld33'3 Q0 L) ?# q1 ~
2 j4 c( m0 c+ v
    },
9 `/ q; b3 M5 s" l. c; }/ a* F/ b9 V" ]) M2 K7 T# y( W
    // 用户账户的客户端配置4 D/ h7 S; A% i% L/ i8 h2 W

( P; \+ A+ G& Y% |1 f( z. t    callClient:{/ ~- k" M9 _# P' t, ]' ]3 N! w
) Z) U9 |4 h7 Z
        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
8 P2 O" L+ q, `! \( U3 o/ Y7 W% O( c# [% {1 t3 Z# U: C: \
        httpEndpoint: 'http://testnet.fibos.fo',9 ?) q4 W; K  f0 I
$ P+ S/ d& z0 v5 |' ]
        keyProvider: 'PRIVATE_KEY_OF_helloworld11'
4 G3 B- p/ ~/ ~1 d, p
$ V" N+ g. k. u9 M8 o. l    },. K7 M) F: _8 v$ C5 f  A3 c
( A2 [: f  B, V: d/ K# A  l
    // 平台合约账户信息; [) v- W1 {) G

/ a2 n2 I) O0 I; W, z    contractAccount: {
1 i  Q' j  z0 D9 r! j8 R: i
* z' G8 F: Q' T        name: 'helloworld33',2 f# Z: z$ u" w
+ p$ O' n" F+ q. M9 E! ?8 E
        publicKey: 'PUBLIC_KEY_OF_helloworld33',
7 F0 K" _" Y1 }) p; E, d
  f6 L# M5 D8 G0 W- \/ B        privateKey: 'PRIVATE_KEY_OF_helloworld33'4 O) r/ v' F9 v% T

# \. f1 X6 r2 Q- E' [    },
) L1 Y; ?9 X2 h0 q0 o* p( C' s2 t* K
3 r5 t6 Q7 q& U% w    // 用户账户信息! ]. ?; n  n/ V5 {0 L/ u

; a6 ~: T( ]) ~0 \    account1: {7 K4 Z7 P5 s8 G/ c1 m+ Z

5 g$ g  V, w0 R% D9 C        name: 'helloworld11',+ _. d. a# b5 V
) f! o% o& ?. ?2 z$ ?) r/ S
        publicKey: 'PUBLIC_KEY_OF_helloworld11',. _/ m3 B3 V8 ~, r4 G
% A- x$ W# T/ O5 k/ F9 u
        privateKey: 'PRIVATE_KEY_OF_helloworld11'
& o# v1 s- m: Q. ]* A
, `) @$ q" R9 ]; u+ }    },
" }" J1 y/ W1 Q- P! F- a! q
/ m* N6 Y5 J) r; A    // 内容提供者账户信息1 {+ ^. \/ }# M7 s/ O3 j8 Q

, Z* W3 q( `+ X4 {    account2: {
" J1 n/ F# `2 s2 F" E$ k% S7 d. I+ O- x
        name: 'helloworld22',! @- I) G4 z0 [5 w+ j; X

9 n, x* e  a5 ~( H2 `. h* l6 v        publicKey: 'PUBLIC_KEY_OF_helloworld22',' N' j. Z  z: O8 T( e1 ]# q! n- B) x
0 k% U4 ~/ h/ m; F& a: m; Z5 n
        privateKey: 'PRIVATE_KEY_OF_helloworld22'
/ Q+ l  U3 Y5 l- ?- t) p0 j1 P9 a- `$ c
    }- M& Y3 D+ U- i8 L  ?2 k" _$ `
1 o0 ]# u2 b& L% \9 p
}1 G! k6 ?/ G% h0 @& w& B! S

2 m  y; D2 G0 R6 ]1 t  e4 q3 Xmodule.exports = config
, i) ?6 \. o* }, \% H) `0 B+ p8 F6 `* i1 L
配置权限
+ t1 i7 H- O( M1 a, Q: @7 z3 H5 @% O5 A. k+ b1 X9 r, q
在合约代码中,我们调用了 trans.send_inline 函数调用合约 eosio.token 来实现转帐操作,但是转帐操作是需要账户的 active 权限。所以我们需要更新一下合约账户的权限,需要添加调用者的 eosio.code 授权到它的 active 权限。这个调用者自然也是这个合约账户。
) N: F0 @9 X. R( x/ L! B/ i/ C1 \" D0 d- E5 U
const FIBOS = require('fibos.js');6 ]/ I- N4 {/ {, J4 @, U. m! u

( Z8 Z8 L- z6 Y# q  _5 Mconst config = require('./config');
! `. X5 l0 x( I! i% _. N
" C  ]: q: N0 e8 A2 pconst fibosClient = FIBOS(config.client);
9 N/ z7 M. c6 W! I% i: p" t9 T8 _; P5 }: V
9 j, T+ n6 K1 ~& W$ llet ctx = fibosClient.contractSync('eosio');5 c$ |# `8 a) U: }- S- ?  n

& s3 q+ O( W" z3 g! t' Gvar r = ctx.updateauthSync({
, D& [- c& f$ r
5 s  F( A, B8 X+ D& N* `  B  account: config.contractAccount.name,
2 ?* n( c1 p  A, P" I  a/ k# n
& B8 B% o) C, h  permission: 'active',
9 N7 i- m* s6 o$ g6 g% L2 H% j% i
  parent: 'owner',
8 P3 x' W7 W. y) L# g/ Z1 c9 C; y1 J1 B) h$ o  k  u
  auth: {
- O# T6 m: T8 R$ F& w) X. W$ _+ m- M/ e8 B7 |
    threshold: 1,
$ D+ h& O3 i# T7 f% f
/ ?9 D: s. h! C. u8 f    keys: [{+ P2 L; _# W/ i5 A5 q  A8 ~' y
2 \. i) k& w3 T# Y8 d/ g
      key: config.contractAccount.publicKey,9 D5 `1 V1 Z/ t1 ^

6 ]* ^" x* @5 Y/ ~% I8 D      weight: 1, m6 l2 F: U! _/ {# o2 D
. [! T2 t. V0 D0 |
    }],3 h1 H+ T5 P6 x" I+ k* d  K3 A
' `5 |4 I' c  ^4 L, I+ y# j2 W
    accounts: [{
4 k3 Q! d$ z5 @$ J- k" _& j7 P" B6 M0 z3 [; I' x7 M7 W- ^& A
        permission: {0 l& p, Z0 R+ Q& y( A
- K) T& v$ z" I- Q4 r
            // 将调用者账号的 eosio.code 授权添加到它的 active 权限下。
1 p3 O8 D  D- V4 n) P" B0 K, [
- P. H% U7 k* r            actor: config.contractAccount.name,3 g3 N$ K9 F+ P3 \( `( a! u4 K

6 r4 l* r0 @6 _* `. {            permission: 'eosio.code'  L8 D( K+ o9 T
2 ~+ K  k! b2 e/ F
        },& \- x! @( M& q5 p/ Y
/ H) @6 r" _# R* l% F
        weight: 1* ^) v( R8 U0 V* @3 [5 G$ o
0 j! m+ W; G( Z
    }]' d8 x# h. D. F

* R$ g! V# ]! u& z3 i+ M  }
! W. \/ ]6 \: q3 [# @; @* N; {
) d0 N1 n1 J# M% L$ p# r+ B2 s},{
8 i9 P# x$ n3 `  h5 U4 \' T6 \9 ~' V
    authorization: `${config.contractAccount.name}@owner` //更改账户权限需要使用 owner 权限% |6 c0 J8 s5 o! z. {; e% B# V

3 x4 N; u/ ~' p. Q" e- L});
+ S# |9 [; m# t5 d% T' f9 F' d2 @5 {! @  X" n- j' a1 i9 L' |& p
console.log(r);, f2 M% q+ Y* v: S- P
' y1 s2 v# ]* k- R6 _1 d; m
部署合约
: P) ?5 ]8 X' n" n2 S) C( M
8 K6 I6 t1 y% Pconst FIBOS = require('fibos.js');
! D' n  A: d: E& i, P
, @# L+ u' i' J1 W' C* A  econst config = require('./config');: y! ~3 g0 b/ R- d

. I4 d1 \+ T4 l1 F7 [: ^% |3 N- rconst fibosClient = FIBOS(config.client);7 }! @; D- y" i( L3 U, r
$ K* J7 d' F8 Z! G
const fs = require('fs');
  [! I# ^2 _( e! u& n  T5 G$ \& ^, |; X6 ~; g! k( ~# V% z$ c3 z  m
// setcode
$ V) d9 N7 M' C/ j
0 |" j0 M( o, r& p, \5 yconst jsCode = fs.readTextFile(`${__dirname}/contracts/subaccount.js`);
% a+ w' o$ T8 ~! v9 m1 ]; W
. n. d' V6 W) l) \! j8 WfibosClient.setcodeSync(config.contractAccount.name, 0, 0, fibosClient.compileCode(jsCode));
. b: D5 [# n; i/ w# a! D+ {1 r( o' F4 d" M1 D
// getcode
  I! G+ H3 Y) o, j: L
  j& m5 Y# s' a) U4 T/ E' \const code = fibosClient.getCodeSync(config.contractAccount.name, true);8 i+ y2 m7 V2 ]: k' c) q; _: k$ @# O
: K7 a. J, |6 m( C0 q* P
console.log('code:', code);. a- R/ u' d: B1 V& m3 m* y

- u+ `3 H- N! b9 ]+ _5 c( s' n// setabi* Y1 Y9 ~' c3 z3 K
9 p5 o6 ]( w1 t9 Q7 B5 T  E/ L
const abi = JSON.parse(fs.readTextFile(`${__dirname}/contracts/subaccount.abi`));& i6 h; H" s& z* E8 Y7 I
9 J1 }$ ]  W9 h7 V5 J1 U  y6 n
fibosClient.setabiSync(config.contractAccount.name, abi);# W. w3 X& c' A% @

2 `) V6 h' F, Z7 P2 N; }' x# q转账测试
0 O8 n) |/ m/ f- i* s% ^9 f3 y( i8 L1 Q/ v
我们先来写一个脚本 account.js 来查看三个账户的余额。
. J( F: \+ P% C, y" e- [6 {0 L) d2 c% C0 ]
const FIBOS = require('fibos.js');
: K- u/ |% W  {8 b, n- p
4 Y5 |8 P3 K  tconst config = require('./config');
3 c6 q) M0 B$ N" v0 p
# U/ K& G$ [& T) z% Z- W1 M9 a8 P6 jconst fibosClient = FIBOS(config.callClient);
0 y- _) W( X* v8 q
1 v0 O; S) B9 H% s, f6 ^, y  uconst account1 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account1.name, 'accounts');
! T$ w+ N. ?+ t6 T
- A- z; \( X" z) ~7 |4 o: N8 tconsole.log(config.account1.name);
; O: I) o) j) k; [$ r3 t* w# D. ^: b; {+ l& ~' g; i0 i/ [
console.log(account1);
3 w  Q/ B! X: F$ z5 G
7 n2 W6 k4 S0 V6 E8 P6 _' t8 Y! G. iconst account2 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account2.name, 'accounts');
. X' I% j" q) ]. h4 P# C
' Q5 S  _* I) y2 v, tconsole.log(config.account2.name);
6 G" R" U6 C7 u8 `  m% b$ C; S) w  z% J. b: E/ H# ?1 m
console.log(account2);) y" o* v) @, k2 x/ ~
$ N# I* K3 |) j& a" X* N
const contractAccount = fibosClient.getTableRowsSync(true, 'eosio.token', config.contractAccount.name, 'accounts');  ]% [9 J+ K! ~! V0 T

; {5 C8 C& c7 B' P9 i8 Z+ Qconsole.log(config.contractAccount.name);
4 X) I' a: f9 S: C% j% ?1 f" s2 ~( L( F' [& S
console.log(contractAccount);; w" ?& _* ~; t4 f8 A; E8 O

+ N2 k4 E3 ^0 ?/ t* h执行 fibos account.js 来查看三个账户信息。 目前我们的账户还没有 FO,所以大致情况是这样的:: S# \' n- H/ o; f) o
, N+ y0 M# U9 J. ^
用户账户:helloworld11 金额:0.0000 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO
0 Q$ c* J4 B( O5 ~( s5 J9 I& m, H2 q) ^7 C2 ~2 C

4 p6 g1 W2 N4 }
: g9 E  d, ]  s9 |测试网会自动给每个账户发放10 EOS 的通证用以测试使用。账户中还并没有 FO 通证。所以我们再来写一个兑换脚本,用1 EOS 换一点 FO 通证。% R2 ?. U2 b( |5 Q% @" U4 w

3 T) U$ S. N/ Z/ r" F% \0 ^const FIBOS = require('fibos.js');( k2 A3 s9 p! ?
6 D: \( n8 W) }1 N
const config = require('./config');
* H" o4 e2 d. d: B( J0 p
5 {, d9 o+ y6 Dconst fibosClient = FIBOS(config.callClient);% q1 S# M+ v5 ^3 H
5 b! |7 x& h) B) F! n
let ctx = fibosClient.contractSync('eosio.token');2 s5 d( C3 b1 u
; q* z7 E  I# |/ E4 y$ C7 F
const r = ctx.exchangeSync(
& Y( e$ H! y) X/ L3 v
5 o! A  h: x3 }1 z    config.account1.name,
5 d1 q/ ~+ z& s# a3 b1 o& b5 @. N6 }$ S8 ]5 J  o: I! X2 x4 t# C" n' Y
    '1.0000 EOS@eosio',, o: Z, K4 [3 F; ^* R/ l
% s  y4 k; W0 m4 z' {/ @6 |1 s" w
    '0.0000 FO@eosio',, Q% f5 K/ N: z1 l6 f( K0 v

5 b- g  s- r: \9 G1 B! h+ \    'exchange FO to EOS',
( V9 u5 M9 p/ J/ ]4 a
9 L% E+ ~. `" `! l    {
/ n( z1 J& T0 w
5 D3 Z9 m( C& b  K* d- c        authorization: config.account1.name% K2 k' C; j. O2 H
- X. ~. {9 F0 c7 j, i. o' f2 z& x
    }" {# E. M- P9 B# R

$ ~& P+ s+ C8 J. f+ P& i);! m) B, u& |. v( N

& Z9 M# Q2 X  }" Xconsole.log(r)
# `& L5 b6 p  l; c1 w' s( z& H' \! Z0 s- q* t6 [; r. u3 ?1 s; j
再次执行 fibos account.js 来查看账户信息。目前我们的账户金额大致是这样的:
; Q* l' J/ u: A; F6 s. B
! S* ^0 r5 d& {; V2 {. u+ A用户账户:helloworld11 金额:146.4245 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO, A; x1 f4 `$ L, S, d5 n0 [5 K( a* Q; E

! f* D. C% v$ B6 i! v下面写个脚本 transfer.js 来执行转帐操作。- B2 w$ A/ o# e6 c3 `

( ?1 B; ]3 _% Q7 w- B0 lconst FIBOS = require('fibos.js');
& B) ]* d, B5 F+ \$ i" S7 C+ ^0 o" z! i5 {# ~5 R+ _6 y; b. o( K
const config = require('./config');% v9 _& l9 E! p( ^
( B9 a8 s9 c! p- c; ?
const fibosClient = FIBOS(config.callClient);
. U9 r6 {6 P& ?5 G% i/ s: A  [5 i0 X8 W" Q, |- ?
let ctx = fibosClient.contractSync('eosio.token');
& r# k( m+ {# G3 ^% Q% m2 e4 t+ c8 J% J- c9 h# Z, C' s
const r = ctx.extransferSync(1 Y9 J, ~$ O. {# G4 Y9 m
( B& e# j1 x7 W( J6 y% |9 Q
    config.account1.name, // 用户账户7 [3 |9 c- f: J9 r  }

3 C8 @: x6 y! ]5 b( t* I    config.contractAccount.name, // 平台合约账户
+ w* R+ k' Z) k# B
2 y* Z- K. c/ [. H0 S    '10.0000 FO@eosio', // 转帐金额
$ s' l  R+ b4 A3 @
+ I3 h0 I6 c) X( E    config.account2.name, // 附言填写内容提供者的账户名,平台合约会给它分账6 |, u& M" N. f8 o! ]# P

5 x: r& N* V6 c" F5 P    {. D& [: C: v0 @; q: F- Q# J  O

; R# [# b8 V7 f        authorization: config.account1.name //提供用户账户的授权7 J" w/ X" Y8 Q
4 [0 P% Z) Q$ j6 _% O/ n
    }
$ l' w1 G2 o, A. z4 _3 m* N% H( {; y% u% `3 w& L* X
)
: i' {9 H  e2 ^8 c" I4 o
) d% A2 L3 x0 p  }) Lconsole.log(r)4 Y$ d; p# E: K: U
! W) v7 h, H/ k$ _
我们要从用户账户 account1 给平台合约账户 account3 转帐 10 FO。memo 参数为要分成的内容提供者账户 account2。根据合约中定的2/8分成,平台合约账户 account3 将会分得2 FO,而内容提供者账户 account2 将会获得8 FO。" `  \9 L8 M. J( [
: q4 G2 ^. t9 G3 a
使用命令 fibos transfer.js 执行该脚本完成转帐操作。, r2 M' w% Q0 V
& Y: t2 T2 G# ?# n) L3 S' O- V
下面我们再来看一下目前三个账户情况。执行命令 fibos account.js。三个账户金额大致如下。* w$ v7 O! X% x: j5 u0 C1 K
# `+ R% n  q$ o4 y
用户账户:helloworld11 金额:136.4245 FO内容提供者账户:helloworld22 金额:8.0000 FO平台合约账户:helloworld33 金额:2.0000 FO! X1 p& ~' w& [; v0 B3 k* O& R
6 l' t: W; h; H6 X8 q
结果显示,分账账户和平台合约账户如预期那样获得8 FO 和2 FO。
3 j6 E5 A5 Z4 @0 N2 M7 l$ j+ {+ T: a2 c. A8 l  [& r
) e; X5 c, O. Q+ `! `

/ K, B' F" L+ n/ p: o3 n综上,我们成功使用了智能合约实现了自动分账。平台方还可以继续根据自己业务需要定制自己的合约。) e; |1 |* i. h9 U2 x# Q" q

2 m4 U7 d) ]3 H; o7 K! d# C文中的代码请参考:https://github.com/fengluo/fibos-subaccount
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

哈哈笑417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11