Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

哈哈笑417
117 0 0
自动分账是很多平台都会用到的支付功能。很多互联网内容售卖平台都会跟内容提供者分账。比如:Apple 的 App Store 跟 App 开发者三七分成。很多平台都使用了支付宝、微信支付作为支付手段,但是要同时实现给内容提供者分账,却是一件不太容易的事。使用 FIBOS 智能合约可以很容易实现这个需求。8 P9 m9 X) R% G, o

. I/ t$ |4 r! ]) C# }% o, D文中代码已在 GitHub 上开源。https://github.com/fengluo/fibos-subaccount. M+ G2 |! |9 ]9 L( ~4 ^

* {7 o+ J$ Q9 ?. X! \; A( C设计思路
! G- c; y2 R3 b! M9 z$ t. H
4 X  [& p% [6 F- G) K  Z在 FIBOS 转账是通过 token 合约的extransfer方法来实现的。extransfer方法在执行的时候会给转账方账户和入账方账户发送通知。所以用户给平台方账户转账的时候,平台账户就会收到通知。所以整体业务逻辑如下:/ g9 d% V: }; O  r: d
- n5 B4 T# |( \
        quantity: 10 FO6 q0 H6 y+ k! [$ I
5 O6 y3 H$ X8 A7 o- J) ?5 f2 s
        memo: 内容提供者账户           quantity: 8 FO3 q5 h) j* K5 X* \0 q2 s' S& x
* N; R* o/ |9 `2 E1 i
用户账户 -------------------> 平台账户 ----------------> 内容提供者账户
* I- i0 L5 |: a/ `1 p+ ~" C5 O. m8 \+ P6 b' q$ M7 W8 Z3 ~, j  b; J
            extransfer      2/8 分成   extransfer
) h2 h3 P- D/ ~! r) P; V, T  e: }
1.用户给平台方账户转账,memo 中填写内容提供者的账户名。; E* N7 d2 a/ |$ |% V) M$ u
1 d8 K  t( A+ W4 D+ p5 y
2.平台方的账户合约监听 extransfer 方法的通知,然后做出分账计算,给对应内容提供者的账户转账对应金额。' C; O1 j- c! _" M7 b* ?: j$ m0 I- D
5 `3 e, j  s+ c8 ]
整体逻辑很简单,整个合约代码逻辑差不多用20行就可以写完。* V9 R' N& D  s5 ?: [7 G7 U

% _; L& g3 @. {3 }6 R" _9 f2 y( ]编写合约1 Z+ C! n4 O# `" s/ f

+ K. K5 }/ q1 ^FIBOS 的智能合约分为 ABI 文件和 JS 合约两部分。ABI 相当于合约接口,JS 合约则是功能实现。本案例目前没有接口设计需求,不过 ABI 文件还是合约不可缺少的部分。所以我们简单创建一下就好。
. `' f: e. v8 _* `
3 k8 _- X, F+ B8 d0 G我们先创建一个 contracts 文件夹,合约文件都会放在这里。然后在此文件夹下,创建 subaccount.abi 文件,内容为:
: L0 x+ @2 ~% Z, c8 D% u
' p& v& G8 y" o( v* ?{
/ u( E% g- L. b% N5 s; @" g0 k, Q3 i. b- p8 M# O/ L* F
    "version": "eosio::abi/1.0"+ W. f5 _/ [  J) |5 u+ g' O" p

% N  H% Q  p7 W! D* M. e# S}1 w3 P% V6 ~' p4 ^- Q- F

8 Z4 D2 ^: B4 y- R! g1 SJS 合约部分也没有太复杂。在 contracts 文件夹下创建 subaccount.js 文件,代码为:
6 V$ t8 N3 I1 u/ i( O0 @% m; B& Z3 h5 F
exports.on_extransfer = (from, to, quantity, memo) => {
4 Z6 h& j) n3 V3 V2 c, l6 X. H( U% d$ k' r0 j8 v. v
    // 需要在开头做一些判断, C: @- k! H& M2 }: z5 v' J& V

8 o6 x  |! Q  T; R$ D4 M! Z    if (to === action.receiver && action.is_account(memo)) {4 r! Y" {$ W/ z7 {

$ T+ |, o- l- Y        const num = parseInt(quantity.quantity.split(' ')[0])
- S8 C' {9 g9 K6 ~) d1 v& Y
  M* `+ l7 z! }; u        // 假设我们约定平台方跟内容提供者是2/8分成。
* \% e  n" u2 B2 t: z8 Q& M+ X  F2 f  j2 ?
        const subnum = (num * 0.8).toFixed(4);- {$ S# u9 Z( h

7 x, d1 |% z! x& r( S        trans.send_inline('eosio.token', 'extransfer', {
' \# ~) \% ^/ U! z9 a+ l; P+ ~
6 r; P$ ?3 R9 s1 h: Z- T: l            from: to,3 v9 R6 w0 a4 }2 D2 s; M: s
0 B: s1 f" [6 q# ^  I
            to: memo,
& B/ h$ O) |9 J# z# h+ q3 B% Q2 W3 P' J+ F" e: ]- I8 L& y4 W
            quantity: {$ a- i0 Q" |) m5 n. g  L% i
6 F8 f, K5 }4 B4 W
                quantity: `${subnum} ${quantity.quantity.split(' ')[1]}`,
4 A. r8 z3 k* l& V+ _3 h9 q+ ]% ]' _# x/ n" p
                contract: quantity.contract9 H. V0 p, G. C' w" R; r0 v

# \; H8 K3 u$ D; {- @2 K+ I  W            },
4 W3 t" A, K8 S6 Q  D# Y8 N/ S% b' c. o7 `
            memo: 'sub account'! w' s# H  I) `
7 i* y: O5 |* b) i* U% q
        },
: R# g1 y7 ^& [$ B
1 D' r8 T+ _! S, y( _6 E        [* i- P4 F' _, _# j7 L* _
( c& f1 `; z( \/ y
            {3 b/ q9 r' p# ~5 t7 B7 C% N4 V$ Q7 U

; x( l+ E- @5 Z7 R: c                // 需要提供合约账户的 active 权限
5 C% X1 u8 ?$ w1 `  {/ a2 Q9 i' Z) u  [
                actor: action.receiver," I; O& K  m! p# Y8 k; w! a4 S" i
& o6 \2 r  X7 X: B, z/ O
                permission: 'active'
* L( x) X) s5 ^- R, |( s9 K' e2 h5 u  c; o' E" n
            }
9 N7 ?. o6 s$ J8 [
" L7 t  Z( |) S        ]);
" s+ e- e8 N: \% c
1 g/ F; \3 \9 g- T' V7 @: s    }
$ d4 x' t9 p3 e3 e; W3 z+ O/ X5 E7 {# ~# C& B; d  Z
}7 N, n6 ]6 q% S; ^# M( p

0 d- Y6 ~/ z  l! ^$ _. X合约代码开头我们需要做一些验证。" e. Q6 t) V6 H

* f( B8 K1 r; I# P7 D- V( d1.收款方的账户为合约账户,否则因为下面代码执行给内容提供者转账时,因为转帐方也是合约账号会再次收到通知,造成无限递归,超出最大 send_inline 层数而报错。  A- ]  \. S8 G
/ l% y# X3 t& A; A2 d/ r' Y
2.我们用 memo 参数来放内容提供者的账户,所以我们需要对此参数校验一下该账户是否存在防止打错。, a: g+ N0 N. x2 t: H1 X

5 y8 |0 L5 b5 Y+ O$ ^/ E合约代码中我们使用 send_inline 调用 eosio.token 合约来执行转帐操作。转帐操作需要对应账户的 active 权限才能执行。为了解决权限滥用问题,FIBOS 定义了一个特殊权限 eosio.code。我们需要在平台合约账户中配置权限,在 active 权限下添加该合约账户的 eosio.code 授权。具体的配置操作会在下面说明。
+ Y) |* W# V! u4 M6 k& K% s; j
, ?( R5 Q  f1 Y) E, g* j$ l在 FIBOS TestNet 上注册账号
" q% G# e6 s, W  X1 Y7 v5 E. S* W
: W9 d9 w# e- \为方便测试,我们在测试网 http://testnet.fibos.fo 上注册三个账户。+ \' T7 d( Y+ O, K1 I
) d. g7 ]+ m+ ?! d  |1 j5 B
用户账号 helloworld11" P0 |/ c+ r2 A6 ]. _

, Z( i7 I. w; N/ a' B2 A内容提供者账号 helloworld225 y; h# r- R) A* T; T

4 |" F7 Z& Z: C$ B- T8 q平台合约账号 helloworld338 I. V. R% k2 a* }( o: q* F
5 A: X: W# L8 o' V
我们需要记录这三个账号的账户名以及公私钥。以便下面的开发使用。创建一个统一的配置文件来记录这些数据:
# G1 D! O2 n3 N% ]* Y
1 ]+ H6 [4 s" N0 M3 D+ vconst config = {
5 ?. Y0 q& P" {; O4 _2 R8 E" _8 G1 R+ ^! K
    // 平台合约账户的客户端配置' _" D. Y: W2 h4 p8 I
  K) w; }7 @3 h
    client: {
3 R* M$ }3 ?# L/ _7 w
* V1 U) V3 Q, _2 w4 Q        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',; l8 r5 [# R8 s, J
' M9 @! l: u/ Y: j2 L
        httpEndpoint: 'http://testnet.fibos.fo',& H% J$ l0 V" S, E2 s" m$ I5 g
5 a. W$ ]: D0 M
        keyProvider: 'PRIVATE_KEY_OF_helloworld33'
# c( o9 F( \$ t9 r0 G+ ~
6 O; J3 N' s7 L2 r) C0 D    },
, _0 k4 v6 y4 @! Y
. v5 B5 J# T1 L9 l, ]    // 用户账户的客户端配置
" ~% S1 ?0 @6 ^! w7 R" K8 R/ i0 V' v( M0 z! S5 \6 \0 K
    callClient:{/ W( u/ o' D. G% _- c) \% Q, q; x
* H( B2 m% K% j
        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',3 G% @5 ?+ H9 [/ h& g) O* q& d
& l3 p5 N/ u6 J1 s* M6 K" Z
        httpEndpoint: 'http://testnet.fibos.fo',
1 r: Y9 E' T. J; D1 d5 Z( q% }
% ^/ q) i, T- e: R% _. l& A1 L        keyProvider: 'PRIVATE_KEY_OF_helloworld11'
3 Z. b' c* M8 \* ~- |$ \8 _6 C! O0 w0 i
    },3 ^* ]8 ], `7 d, Y% d: ?( C; u% I

3 w0 l$ o2 h$ [- m    // 平台合约账户信息8 `9 x) J. S0 _
) w2 P% J$ D) r2 ~0 z
    contractAccount: {, d' ?9 b' T; M% {' l6 P% [' i
* V  g- t; f( e$ D
        name: 'helloworld33',9 S5 u( ~3 ]" X$ U4 w
/ Y5 M; ]/ W5 |9 w! A
        publicKey: 'PUBLIC_KEY_OF_helloworld33',
) A- `: J5 }: x$ a. s8 p  `& p+ i6 W1 j
        privateKey: 'PRIVATE_KEY_OF_helloworld33'& _- \+ k7 z9 v+ H! S+ u
+ _, W; F. h# o, q
    },5 g# Q' z7 C3 G" f7 x

! z+ S! z7 T- D, R+ D4 [6 u9 N. |1 D    // 用户账户信息* ?4 T: k" h8 D: @8 b6 O" V7 c" {. q
6 S4 ?7 f1 h' E6 ?8 l! c
    account1: {4 H/ W5 V" ~  o4 g

% T8 d# A* b3 t& W6 [$ s& F        name: 'helloworld11',
5 z" J( i6 b! n, m# ~! u1 i
8 y$ X; @$ U5 w  B  u  p        publicKey: 'PUBLIC_KEY_OF_helloworld11',
3 U$ D* f, [0 ]7 m4 V
- R; Q8 R7 Y3 q1 ?; e( A5 @7 x        privateKey: 'PRIVATE_KEY_OF_helloworld11'3 `0 f. c. Z" P% i2 W

' T, U# M1 T) O* U  Q6 L6 r. p    },
( W6 W) F2 w& ^2 B4 ~3 t- ~7 E- d; y. @
    // 内容提供者账户信息
6 g9 W/ m% ]; s+ N  s3 T' c# W, ~5 j; }2 j" G% L
    account2: {
2 m8 a/ E8 s, B/ N  U6 ^$ I+ m* `. `5 l0 q/ U" u: d
        name: 'helloworld22',
! A# ?7 s! L1 j; f8 q! I6 @$ T! O# |% r, P$ D/ i
        publicKey: 'PUBLIC_KEY_OF_helloworld22',: x9 t9 `  G, A6 i6 W6 A

7 ^7 V; B! h0 k+ x& [        privateKey: 'PRIVATE_KEY_OF_helloworld22'
/ m9 ^3 w" j% d* N# A; v
) G$ W6 u; q, T# |* U- U* w* x/ c6 p1 n    }: b' S9 r) a" q7 @/ R+ P+ ]+ m
2 M/ ?& m- r$ s( u
}
* b# U0 @" X9 [' ~$ t* ?7 [. T' ^6 t3 m- j7 K: L  v' Q
module.exports = config
5 d3 h* v: r2 w- d  D9 f* _, Q4 B+ t1 E) d# P( @3 ^  P) K2 s7 k
配置权限  o* }% y* q* g% H% y8 Q
7 a/ I* O2 E$ d
在合约代码中,我们调用了 trans.send_inline 函数调用合约 eosio.token 来实现转帐操作,但是转帐操作是需要账户的 active 权限。所以我们需要更新一下合约账户的权限,需要添加调用者的 eosio.code 授权到它的 active 权限。这个调用者自然也是这个合约账户。
: m6 I" B3 ?: e# f  d6 c
  \4 D  l; H1 W7 Kconst FIBOS = require('fibos.js');- Y& `7 j* _/ K. L* a

8 Y4 f8 u6 [, H! R/ W5 vconst config = require('./config');& U7 c1 O1 T) @8 W4 ]* H( I2 s( }

: K1 _8 r2 b1 ]# f6 a2 zconst fibosClient = FIBOS(config.client);# @) h) u: J# z2 }1 f

5 ]) ?6 Y8 a8 s3 Z& V& r) ulet ctx = fibosClient.contractSync('eosio');, g: F2 q' }2 D* }& M; _

; Y5 [) ^5 c0 x% D! ovar r = ctx.updateauthSync({
( I* X$ Y: ^% C. y& ?9 ~* R, _' D3 _9 l
  account: config.contractAccount.name,
3 ?0 x# C' Z0 U9 A/ c; V0 U  g* F. S! j
  permission: 'active',/ e% a- h- l2 C1 t6 e

. M9 F6 L+ a7 b2 x: T  parent: 'owner',
) T' ?. V5 k: i3 S2 B" b0 B1 b0 C, Y5 s8 p8 |; l* T% I4 o$ v/ v: R- u
  auth: {
0 ]/ v, o) q2 ~: b$ \, W" M2 Q# j2 E/ G  B  x" R+ g
    threshold: 1,$ e5 P0 A( E9 S+ }  ?/ [
5 @' z9 R6 R5 T
    keys: [{
2 |$ M2 N3 B: S; y) m" i8 h6 S/ E0 [2 A
      key: config.contractAccount.publicKey,
/ b/ }+ b5 M$ n
  U+ _- Z( \2 Q4 A2 p7 J9 E- K      weight: 1
6 [& N: u9 o9 M) h- k, x9 S# ~* v4 v
    }],
8 x& \& T; r# s3 w- u
6 H0 x" K$ S5 [    accounts: [{1 x) G4 `9 c2 g( R; j, ^; w9 h
% [3 D7 _$ z, D7 Q) V9 L
        permission: {3 S4 d; \- V7 @4 m2 D/ x5 g1 I! i

* a" x+ ?, s  i            // 将调用者账号的 eosio.code 授权添加到它的 active 权限下。
4 H6 s. }' g. }/ O% h% q( @6 k  K5 p. \( f8 ]! ^+ @0 @, W  c; G
            actor: config.contractAccount.name,2 p( a/ K. c. B; \# _
' x' t* o# i# m  ?" A
            permission: 'eosio.code'
" u( [, @2 A3 a7 ?. Q
; X& L8 n( y1 d0 ]/ Y  @        },. h7 e' u7 Q. [+ n
1 w7 i1 g* |( n* w
        weight: 1
( g: Q& V) J' S, S
4 q  T  i, y2 h$ S) q# L& l' r( c/ Q    }]
5 a4 N4 p, W7 ~, H1 a8 n( m6 u7 m
7 r# r  ?: t  b  }
- x/ u# X9 V& T. n5 @2 n& k# J, u+ n0 J
},{
7 w8 ]; j2 J: }4 L* a$ d
+ q2 i1 r+ f5 W/ \! ~    authorization: `${config.contractAccount.name}@owner` //更改账户权限需要使用 owner 权限1 d' D! L3 f. l7 \
- ?) D+ G- z  T! y  ~( S2 f
});
. q7 K3 V- F2 U1 _
. }2 k+ X8 X' Y0 U5 K5 h) oconsole.log(r);  }9 E7 u0 z" g1 u  l, \
; i% J0 h: [" v, X$ o- A
部署合约
8 i  O! Z! ~5 f* u( v2 T- L5 g' y
const FIBOS = require('fibos.js');
+ b9 O- v/ w# {( \4 u/ p5 |/ k/ v: ?& t4 [
const config = require('./config');
" ?% I' B- V3 ^. K7 H# }6 `" g1 K4 i( }
const fibosClient = FIBOS(config.client);$ E% v9 k  x. u  c6 ^) ]0 S9 h
6 {3 L. Z, h7 J' s( J) |
const fs = require('fs');
4 R& b# L/ B' K* l
3 a! D: q) _" h' d* u$ u5 G) P// setcode. o5 y4 l- E) e3 F; o
4 _3 J8 S$ z- b
const jsCode = fs.readTextFile(`${__dirname}/contracts/subaccount.js`);) E* H* h( G% ~: l

" Y+ u( U; b  g' ^  VfibosClient.setcodeSync(config.contractAccount.name, 0, 0, fibosClient.compileCode(jsCode));
# c' l+ c' ~+ J
1 ]. U; h; v: D1 ~* F// getcode
$ ^2 h2 ~. x7 f( q
% N4 `& c" r3 l- Sconst code = fibosClient.getCodeSync(config.contractAccount.name, true);9 m) D, Q8 q0 V1 ]9 T! j5 d6 J# o

# h' c2 O) P3 u* ?console.log('code:', code);7 V# E0 w. x+ w4 K

0 a: |* g1 M  y( C1 u1 ?. p3 ^7 ^// setabi  y' s2 I9 \+ t0 @. |, g

. ]  j5 `; ~: z7 p# J+ iconst abi = JSON.parse(fs.readTextFile(`${__dirname}/contracts/subaccount.abi`));
  D% ~$ T7 @8 R3 w* t* A3 d1 k/ s( S: t2 \( j( ]; |8 a! o
fibosClient.setabiSync(config.contractAccount.name, abi);3 Y6 b. ?! y  W' ~$ j0 X1 `- S

4 d8 L% q6 O( A$ j* ~转账测试
8 {5 R5 \8 Q1 i0 P) t2 _& e  P
& d8 m' Z, ]* I7 z1 ?, d" c8 u$ B我们先来写一个脚本 account.js 来查看三个账户的余额。
- T6 j. u2 ?  A% b% d
9 O3 g* ?2 N$ K, @0 V5 h1 Lconst FIBOS = require('fibos.js');
8 x9 G# M# D- A% y+ A! E. R% h5 B6 t. }4 g
const config = require('./config');6 g  Y, z' ]4 I; D5 Y6 j0 ?  u

: ~7 m, k/ A/ E# cconst fibosClient = FIBOS(config.callClient);9 H" Q3 w6 ^" O" K7 }

% j: T* G- I  w4 O+ H- X8 ?; k. X+ `const account1 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account1.name, 'accounts');, L# @/ D7 @; M* Q. a

1 T) R$ y: G' {. sconsole.log(config.account1.name);4 D% {- a$ k: d0 V! d  z: a* p; w
+ z9 l( }* Q4 b, o9 Y9 ]' j
console.log(account1);; y8 e; a5 w* u1 E
9 t# M6 ~. a7 r# z# q/ m
const account2 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account2.name, 'accounts');
, c& Q- c1 Y- m) Z/ z! \# ?9 H- X6 d& T  l. I9 A+ M2 ^
console.log(config.account2.name);
. n* C. j: I3 L  e9 J" k
3 b0 q* ?1 I; a2 }2 mconsole.log(account2);
7 _7 `, S5 Z: |' d# v* t: s& v+ V0 c& L0 x4 d5 U
const contractAccount = fibosClient.getTableRowsSync(true, 'eosio.token', config.contractAccount.name, 'accounts');& M) q5 l4 M7 n. F( }/ `
) s$ S' N3 d, g/ b
console.log(config.contractAccount.name);+ w/ u; Q& N7 v% A6 b

0 A1 h, M% z  h: K9 Gconsole.log(contractAccount);
3 e  q2 i0 S6 N/ w6 W1 u6 t' |; V, f$ r3 ?* [9 {8 d
执行 fibos account.js 来查看三个账户信息。 目前我们的账户还没有 FO,所以大致情况是这样的:1 V9 c2 u* Z2 A1 f7 a" g+ ^0 N

* M1 E+ r$ j/ X6 e用户账户:helloworld11 金额:0.0000 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO) m* ^# Q; M3 ~, r
! u% ]# U3 S; A2 b

( P2 |0 j8 m, i5 }+ p3 Y
$ d9 ~8 |/ u( X/ a/ U& V测试网会自动给每个账户发放10 EOS 的通证用以测试使用。账户中还并没有 FO 通证。所以我们再来写一个兑换脚本,用1 EOS 换一点 FO 通证。
7 G9 E  h/ A6 `) S, J8 m
) _2 |. H+ h( U3 W( L  i1 Aconst FIBOS = require('fibos.js');1 _. m$ M4 `. h& \. A

5 h: a4 t6 b! d$ b& |; _0 w6 Aconst config = require('./config');5 w% J% T" g( l

$ b3 R  F5 D1 |" Yconst fibosClient = FIBOS(config.callClient);
8 ^) _( O2 l' S9 I/ z. Y4 n- f% L' {1 c% M. f, h+ `
let ctx = fibosClient.contractSync('eosio.token');% t7 Q! x' L5 s7 e' J
& P/ |1 h$ V3 L- h) D/ Y/ a3 s, T
const r = ctx.exchangeSync($ t9 g1 f1 r' W. l

# K" b( |/ h9 U: _- {8 U$ ~    config.account1.name,
, M: t' c0 g5 D  ?
' p0 o6 r7 t5 A- N! e' p    '1.0000 EOS@eosio',! @+ j7 n+ W+ W/ R( S: Z
3 |2 F% l' l, d$ Q/ G
    '0.0000 FO@eosio',
# U+ I  H- G4 Y. E; X
# T: ?  ?# w3 q% N- B. l    'exchange FO to EOS',5 K+ q4 l- n- {: O
6 F8 J1 f) e* C+ ^  J
    {8 H. o9 ]( }* R! L
  H# c$ a. [  v- P' s* Q
        authorization: config.account1.name
  g) U5 I  M6 V7 l0 @$ h1 M* }* s4 h7 B* a* N
    }
) S: p" X+ b" c% u- _5 \$ K3 ^
# A  w6 u+ {$ J);# Z  n# D4 a: }0 @9 F. i

) d, n8 n( o1 e/ n+ ?( W* E- kconsole.log(r), I! A% g& {, f% `
1 t) I6 j0 ^! m4 q% d) p% m6 S3 k
再次执行 fibos account.js 来查看账户信息。目前我们的账户金额大致是这样的:
) a9 e8 H/ \$ ^8 S
9 d+ f6 v, C7 q; f3 J用户账户:helloworld11 金额:146.4245 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO
8 [/ |; [8 ^3 G3 X: h6 U( Q& C7 A0 H" _
下面写个脚本 transfer.js 来执行转帐操作。
: l* A- ^8 z& Y' m
5 Z+ ]' e9 n; Vconst FIBOS = require('fibos.js');# y* o1 N) `, N2 t$ J, E1 Y9 r
" D# A. u$ L6 ~' ~& r
const config = require('./config');
4 A9 a2 B  L3 k) G& Y
# h! \; j# t0 kconst fibosClient = FIBOS(config.callClient);1 \- e' n' a3 |9 n
3 w& n% K: W- n' D4 l
let ctx = fibosClient.contractSync('eosio.token');
9 G& |  B3 P1 y) r% M: o9 p7 Q: x; r
& t+ D8 Q" m2 S+ d6 `% D& }const r = ctx.extransferSync() a9 N4 ?+ d% S  C3 h

9 ?2 X' G4 {: I7 x* B$ I    config.account1.name, // 用户账户7 y' @# q( V$ X& j8 [
9 ?$ R+ j+ o/ B! l3 j/ [6 u
    config.contractAccount.name, // 平台合约账户! j2 O& h# [2 b* g* i0 C4 z* `
+ G3 @% h) E) f4 e7 S# ?9 e
    '10.0000 FO@eosio', // 转帐金额
) s+ c" O/ L6 l6 t6 k# b" F3 Q% D' L' D9 F9 c
    config.account2.name, // 附言填写内容提供者的账户名,平台合约会给它分账$ ~- I, T: ^: E; v
3 s' \' S" w" Z5 Y8 R+ P
    {2 C" n' Z: Z8 E
8 S) X: _6 Y; I- D" X
        authorization: config.account1.name //提供用户账户的授权7 u8 a/ C' f: p. N

# ], r6 ~9 u6 ]9 ^$ f: g. S    }
) p7 N! [2 h6 _1 M4 V
" s' N) g, Z& o. w)3 @2 c: y, m/ }% q

6 N$ ^+ a3 c/ Z8 i' Yconsole.log(r)
+ z" S9 R9 t) g- c) U6 X4 \0 C3 q: Y% c* D7 N/ \$ j
我们要从用户账户 account1 给平台合约账户 account3 转帐 10 FO。memo 参数为要分成的内容提供者账户 account2。根据合约中定的2/8分成,平台合约账户 account3 将会分得2 FO,而内容提供者账户 account2 将会获得8 FO。- S" r5 X9 M! y9 t3 o

- U: a) _. [/ g6 N# A% p使用命令 fibos transfer.js 执行该脚本完成转帐操作。$ Z0 ]6 e3 I. i5 j. L2 l
7 t$ }0 B! s( H* m7 Y: t" z3 U
下面我们再来看一下目前三个账户情况。执行命令 fibos account.js。三个账户金额大致如下。3 u' G& r. |0 X9 ~* ?
6 Z* H, z+ T2 f) t. G( }7 r8 S
用户账户:helloworld11 金额:136.4245 FO内容提供者账户:helloworld22 金额:8.0000 FO平台合约账户:helloworld33 金额:2.0000 FO
0 r1 J3 n! m7 G" n- m  m
$ l( K- A' z* N! H6 I- y1 _结果显示,分账账户和平台合约账户如预期那样获得8 FO 和2 FO。
! L! i8 n) ]- b# R( c* E: F: x/ U) v( q' z6 G" f

1 q: F: {3 P, N8 S+ l
2 t* q* `6 |0 q: K0 M0 @3 h4 w4 o综上,我们成功使用了智能合约实现了自动分账。平台方还可以继续根据自己业务需要定制自己的合约。- v6 F* @+ @  [* T1 h% m9 @! j
$ }* ^+ g' |3 w; a: ]9 S
文中的代码请参考:https://github.com/fengluo/fibos-subaccount
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

哈哈笑417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11