Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

哈哈笑417
118 0 0
自动分账是很多平台都会用到的支付功能。很多互联网内容售卖平台都会跟内容提供者分账。比如:Apple 的 App Store 跟 App 开发者三七分成。很多平台都使用了支付宝、微信支付作为支付手段,但是要同时实现给内容提供者分账,却是一件不太容易的事。使用 FIBOS 智能合约可以很容易实现这个需求。
  ?& P. }/ q, U! b; n/ |* J6 K/ T! }/ R& i% J. k
文中代码已在 GitHub 上开源。https://github.com/fengluo/fibos-subaccount: M6 o5 ?5 ^/ D3 D  y/ z/ l

0 w' ^' ]7 C" I$ v设计思路$ @9 J& T$ m% w; }& }+ F
( ^9 K5 L  B; p$ S
在 FIBOS 转账是通过 token 合约的extransfer方法来实现的。extransfer方法在执行的时候会给转账方账户和入账方账户发送通知。所以用户给平台方账户转账的时候,平台账户就会收到通知。所以整体业务逻辑如下:
+ N6 ^" S/ v8 d- f8 }. j' k  }0 \# u) l: }1 c8 `! `! v
        quantity: 10 FO* G3 |, p1 `! a$ u; x4 l

& t  u$ p/ @% l5 D' |: l1 T# H( d        memo: 内容提供者账户           quantity: 8 FO$ {, b3 K- q, o+ k" q5 y

& j0 p3 l* h7 Y' n# O用户账户 -------------------> 平台账户 ----------------> 内容提供者账户( }5 O* B; g+ [$ V

: W  k( ^8 P2 J            extransfer      2/8 分成   extransfer4 b; w+ \# w; K4 h; a
& l6 ?" P; T$ h1 m
1.用户给平台方账户转账,memo 中填写内容提供者的账户名。
/ [% P6 U1 i9 z
+ V0 N9 G& H1 y4 O* z2.平台方的账户合约监听 extransfer 方法的通知,然后做出分账计算,给对应内容提供者的账户转账对应金额。
2 H0 j) p( r  m+ A5 ?/ _$ I3 O5 y" x
整体逻辑很简单,整个合约代码逻辑差不多用20行就可以写完。
& E* J% v5 r$ x% f" {1 U! r, p6 u7 s0 N: |
编写合约: l4 L+ N4 Q5 S% Z, S

3 z1 l. k2 L3 d6 S' \2 I/ [FIBOS 的智能合约分为 ABI 文件和 JS 合约两部分。ABI 相当于合约接口,JS 合约则是功能实现。本案例目前没有接口设计需求,不过 ABI 文件还是合约不可缺少的部分。所以我们简单创建一下就好。
1 p& H: T( e' }) a6 g) w# x. w1 X2 U1 M' ^0 a3 k% E
我们先创建一个 contracts 文件夹,合约文件都会放在这里。然后在此文件夹下,创建 subaccount.abi 文件,内容为:; g) _4 _; n* V0 U3 [* \+ Q3 ?" X1 z1 |

0 w7 k8 V8 R0 ^1 Y% z{% G! H* h& D; D. U* x

8 R& V, Y( I" t! f* c7 P    "version": "eosio::abi/1.0"
( K/ Z1 P) ]2 v5 ~0 q* p0 V  ^# k9 I' Y0 y0 v: b. c
}, @- C5 S: {- {: b# }8 r

/ g8 ?4 @6 O/ O& J% x, DJS 合约部分也没有太复杂。在 contracts 文件夹下创建 subaccount.js 文件,代码为:7 ~/ ?( M+ R4 y2 K
8 r2 o5 g, W" D- d& O% W2 l# f
exports.on_extransfer = (from, to, quantity, memo) => {# B, H* ?5 ]# f" ^4 C( G

6 A% u! H, y1 g5 B" B: G3 M  |, h0 d    // 需要在开头做一些判断  j! {& @4 w. `! ?2 f# I
2 ^1 P/ N' s. X" ^+ \, S% {
    if (to === action.receiver && action.is_account(memo)) {  O7 M$ J/ _$ t8 b/ B, l' d" f
3 Y' C9 k- ?& H: P! J9 ^3 Y+ q) s3 H
        const num = parseInt(quantity.quantity.split(' ')[0])' o/ U* k# Z# o8 }

) t  l5 r6 T! y7 b; s' g' |: N/ i        // 假设我们约定平台方跟内容提供者是2/8分成。
4 [+ i7 F- k! h& S* ?' L% p
$ r5 D9 |. F, q% n8 L        const subnum = (num * 0.8).toFixed(4);4 R+ ?* G8 d8 r5 S
# i1 H) M3 x: M% G! C" a: Y# k8 s
        trans.send_inline('eosio.token', 'extransfer', {
# K, G3 m8 O5 n: T+ k% S4 G
# I. g1 O/ ]# S  Y, @            from: to,
$ Q/ D' T+ n) G7 d( ]1 A3 P) n8 G: k1 g* I) Y' U8 G
            to: memo,
& |+ n2 C1 n. _1 W8 |+ ?) Y# W. v1 T$ T- R' b
            quantity: {
3 f9 E! E" @4 W! H  g. l# g1 _/ t
4 ]7 e3 K7 [$ H7 `                quantity: `${subnum} ${quantity.quantity.split(' ')[1]}`,& [; B- \: u$ w5 H, G
  Y! Q6 ?1 N2 F3 ~# \3 D
                contract: quantity.contract9 @- @, ^" p/ Y! f: {* h
! M( h7 d! o' n0 M/ ?/ j
            },& g* r/ R$ X9 S4 L7 [" l( R

' C5 m  T3 l3 ~  L! h            memo: 'sub account'
: N$ T! }% Z- X9 ^8 e
3 P* l2 H* |5 Z$ x4 n6 R6 [        },
, Y4 E: k4 R2 U8 }! Y1 f4 {8 d3 d# A1 s9 T
        [
4 {3 t. E" W+ H3 p* Z: S  B
" O" ?- H) B% c3 |6 n# j  [8 [            {+ `( g5 `& K" x- t2 ]" q
; T% a6 B1 |6 a, s  c' [8 [1 \
                // 需要提供合约账户的 active 权限
/ X7 W9 ~+ k: ^0 m$ C0 `
: z1 g3 U6 l% @                actor: action.receiver,
8 p7 a! y/ v" K* f; _2 }2 q
) E6 ^0 E2 V7 Y0 j1 Q8 S9 q* y/ k                permission: 'active'3 C! t. K3 o- G; S2 Q) ?  {
5 r2 _* X% i! u# N6 h2 J+ w
            }  k4 b- U* k5 `2 r- A4 G2 o" Q

8 O8 X* W( [( z9 g# h5 Y        ]);4 d  t# ]1 ^! _9 R  N, K

$ N& z: q; I) R8 z+ [( o* c7 A7 o) _% N    }3 Q' Q& ^8 c$ n$ b5 |! F8 a* y6 U
$ R  ^& Y0 J& M( Y, \$ s
}' p2 d4 K9 T- T: t4 Y2 C

  C" E9 l* d* U; n* p合约代码开头我们需要做一些验证。1 L! {# h/ t6 _& Q

: `) A6 O, E/ [6 q& l1.收款方的账户为合约账户,否则因为下面代码执行给内容提供者转账时,因为转帐方也是合约账号会再次收到通知,造成无限递归,超出最大 send_inline 层数而报错。; x! z* W) a8 N" X: `
/ G6 ~% a6 d6 f
2.我们用 memo 参数来放内容提供者的账户,所以我们需要对此参数校验一下该账户是否存在防止打错。
$ {9 X/ c& o& |  u4 G1 t( R4 w+ U& u' m, g5 b( e6 t
合约代码中我们使用 send_inline 调用 eosio.token 合约来执行转帐操作。转帐操作需要对应账户的 active 权限才能执行。为了解决权限滥用问题,FIBOS 定义了一个特殊权限 eosio.code。我们需要在平台合约账户中配置权限,在 active 权限下添加该合约账户的 eosio.code 授权。具体的配置操作会在下面说明。4 ?5 N8 b3 }4 L! N4 H
" T7 F7 `% Y) O
在 FIBOS TestNet 上注册账号
: |' a+ E8 Q* G% B* t4 k* d" n
& \- K8 I/ b2 \3 D7 u' b为方便测试,我们在测试网 http://testnet.fibos.fo 上注册三个账户。" \% e5 l: \- C7 b) _4 {
2 r2 a& ~# y4 Q* I
用户账号 helloworld111 h9 [4 m2 K: D" z" r

% V! M6 a! F0 V) Q4 W内容提供者账号 helloworld22* I6 n7 l0 u" |: |5 y

7 u5 N- Y' G. d. z9 T: _+ [平台合约账号 helloworld331 B9 h! ]& }$ B9 s2 g/ q
: U1 m. j8 r1 O  d& _0 N
我们需要记录这三个账号的账户名以及公私钥。以便下面的开发使用。创建一个统一的配置文件来记录这些数据:) M( r. n& d' L4 D2 D2 G, ?0 z
" w5 i/ F  |% l+ x
const config = {8 f  l* y5 G- q! S, }- |$ O

" h& R9 ?. X# w/ W5 V    // 平台合约账户的客户端配置
7 g, _$ ]" a7 N; u( ]& o9 W& |$ `3 t
    client: {9 T9 Z( |2 ?: J/ w( z0 N* B

0 g1 V- w- F& K0 |' p        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',* e8 R1 i' D, {; K6 ~. R
' U& B6 P$ J/ X$ ]9 x$ u% J
        httpEndpoint: 'http://testnet.fibos.fo',, Y: v$ |* l! D+ `

$ L- K" d+ V. M( S        keyProvider: 'PRIVATE_KEY_OF_helloworld33'$ S. B3 m6 y' h' p
) z  v* C" F% T2 G+ s+ b) \
    },
; I5 ^3 E' u! _4 d( e) r, E2 o! g( ?4 @0 P7 u; M
    // 用户账户的客户端配置" L1 ?" B* Q1 v# h# q& Y

0 I& B& m2 C6 K+ |    callClient:{
. ?7 {5 ^0 V9 ?% k, F4 b- V* `
        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',# ], N8 _; h6 r, |

) Y. ~4 p; Q1 ?8 q        httpEndpoint: 'http://testnet.fibos.fo',# l8 f! `4 {8 N- z6 z5 @4 p5 z. H% O# |

% J! o: O# B0 ]# X% C        keyProvider: 'PRIVATE_KEY_OF_helloworld11'* u0 `: L# J, Z$ a" A

% Q+ l4 T: v. g% m- h' F* r    }," o/ J6 Y1 i, @2 y$ a' b

6 I/ Q9 S+ J1 f. N3 q9 T    // 平台合约账户信息
' b: ~- {. B; h; @$ f: W
0 f. n1 u( _* u0 d! M% j    contractAccount: {* d2 d3 X9 Z* m. f0 t' A: M0 r5 y

+ X; P, p; c2 A: Z, w        name: 'helloworld33',6 M  M6 |8 o  R/ P, k9 g7 z3 }

$ {4 p. q" Y& g; g, E9 m        publicKey: 'PUBLIC_KEY_OF_helloworld33',# v: H" O. s, }  e, O6 g

+ R+ B  m' q. N; ?( z! L. m        privateKey: 'PRIVATE_KEY_OF_helloworld33'
. U4 U: a$ Z, a3 k' G& f/ ?2 J9 V+ d( p, S) f: h: }
    },
8 H7 F3 _: I% P1 P1 j4 n5 a* {  Y  q" p) G
    // 用户账户信息
5 K  h. U' B; s: E0 |& ~9 N4 C4 n- [* [' j% V$ j, T
    account1: {
5 W1 s- u* [: j4 F8 ?
2 M) }# u7 D6 T# A3 R3 w( D. U        name: 'helloworld11',: V/ t$ j. R% i' y
. z! b  n  f+ M3 c. l
        publicKey: 'PUBLIC_KEY_OF_helloworld11',# m9 x9 o* P7 @3 u2 P" j0 S% @6 ~5 |
: {9 T$ t* K2 c  q# ~; z
        privateKey: 'PRIVATE_KEY_OF_helloworld11'& g- r1 P$ d5 H$ G& ?
7 w5 J, B2 D/ ]9 }; N  I# n8 x
    },
$ ?7 H2 s% C# ^( s. D8 }" C  Y( G: n% N. J1 C" t
    // 内容提供者账户信息
6 l& g' R8 J' g2 s3 O0 m: x) j. f# L/ o) c) }, |# d
    account2: {7 k! n9 X8 f4 ]+ n* M+ L

; _' d# k3 }/ T- ~2 Z        name: 'helloworld22',& m/ b2 ]4 p8 a7 V

7 j6 F) \, v3 E5 ~1 D7 J. t- I        publicKey: 'PUBLIC_KEY_OF_helloworld22',
4 g9 m% B* _' o/ M) C3 S- c
& p4 I$ V; x" o        privateKey: 'PRIVATE_KEY_OF_helloworld22'
, B. A2 U# u" ~( z
( }1 q: F7 k+ O# G% w    }
$ l* |+ L, l# T2 g+ l9 K8 p1 G
# Y" h$ b3 p2 I' v( i0 X0 A% g}+ J- ~% n4 R7 d& L$ T* S
7 L7 e1 d% E: [! D+ h( I
module.exports = config9 ~  S& p7 e9 O7 Z; N; \9 j4 o* d( s

  K! q6 `/ x  k9 o& _配置权限/ T5 @, l% Z$ w4 I7 [+ F

; @  ^; I$ i: W9 f5 E+ g3 K1 L# J4 h在合约代码中,我们调用了 trans.send_inline 函数调用合约 eosio.token 来实现转帐操作,但是转帐操作是需要账户的 active 权限。所以我们需要更新一下合约账户的权限,需要添加调用者的 eosio.code 授权到它的 active 权限。这个调用者自然也是这个合约账户。
; E* y" o2 Y6 v( I  ~% X1 Y, \- R$ j/ N( i
const FIBOS = require('fibos.js');
6 |5 g  p0 z$ m& `
5 e9 A! F# B$ ~5 i1 }2 tconst config = require('./config');/ x8 n! s2 B- [/ ?9 }$ R

! i, ?# ?& W6 S3 O* E6 G, econst fibosClient = FIBOS(config.client);
: {6 G" G' C9 k- @! v2 m9 l. i. E- G" Q; ]/ C
let ctx = fibosClient.contractSync('eosio');
; E- j& X( ^3 d/ p" r4 I: Q/ V  A, J- I
var r = ctx.updateauthSync({8 S2 @# y% T$ t. A

# U) y/ O1 O% h1 e  account: config.contractAccount.name,7 F* N4 P* p9 Y6 G
2 s, T/ F6 }' K( s
  permission: 'active',
& G5 K8 `$ U( x: j( G( q% o7 }  W$ T, p
  parent: 'owner',
  t4 o; {+ G' G; q" p' O8 P7 I, x( w) q( L
  auth: {
7 J5 h) _( I6 R) R' {' ^1 E7 ?1 O& D, }( t. X& V* P$ `
    threshold: 1,1 C# O" ]2 Z  s  d/ s+ c- _

" R0 k4 h/ \' q; u    keys: [{! E- W  b! _2 G

" X& f. f3 {9 F% Z      key: config.contractAccount.publicKey,9 t8 ?+ o# @* G

! B# [) h$ K$ t# W6 T- n( Z      weight: 1
, p- b8 D1 E! A' e3 n7 \( T7 ~$ \6 Y0 @" O$ J3 a9 ?& J, v; V
    }],: k& K0 F  Q* ]& @  R( D: g+ l5 p
$ {  P( ^5 f! ^# T, |; j
    accounts: [{( X3 G. e2 S/ q0 S
. `1 Z- v% }" M6 ~5 L: C
        permission: {: X; K/ u5 K4 V& t  N& x
. a# {9 h% e/ d6 Q( a# i
            // 将调用者账号的 eosio.code 授权添加到它的 active 权限下。8 s8 c, z- o& z( |' J& u

2 P( O4 e0 ?/ `# a1 s2 V+ Z+ S8 l            actor: config.contractAccount.name,0 T) H# B# c! r/ v
7 o: k' k; ]  n3 A& n- R( g1 n; v9 \
            permission: 'eosio.code'
3 ~( P7 K9 ?! |2 p
+ Z) [) U- W/ u1 O! ^        },) T' _2 d7 ~! C/ b5 f  k: j

4 `" y2 H6 S: k& U0 l" \5 D4 A3 b        weight: 1# G# v: y5 b& k

& G6 c. }" ~9 y9 `9 }* J    }]2 U8 s4 H# q9 c7 y# V% m
! J9 Q& O: i6 W; M& l5 E7 \1 X9 o3 [
  }
$ E5 @/ V( o6 j4 E
- T, b: z" y1 t2 S, n},{
6 n% m; g+ e0 @" J( ]$ `$ K6 |, j4 c/ G3 u
    authorization: `${config.contractAccount.name}@owner` //更改账户权限需要使用 owner 权限7 ~$ c4 {' G' K8 g) {* R

4 t7 m* l8 a& q6 i0 e});
7 \% G4 Q3 Y3 P) D! _5 F. J, h  j$ h$ V. Y* _' V7 S4 n* d8 E; L. \
console.log(r);
3 N5 Z$ N/ w; y3 J) l' Z, W5 z9 r- e. y* u- B# r+ p( a
部署合约1 c3 t4 i) |* ^) f; a! i* P
% {% P$ J9 r; A4 l& \) g0 |
const FIBOS = require('fibos.js');  g' u4 s$ w* s1 M: [1 _. q

0 ]6 ]0 ^% ?, a/ mconst config = require('./config');# x+ S8 \" V0 ?  V1 |5 d2 ]) B
; Z! o2 k6 r- V- F6 k! x6 o
const fibosClient = FIBOS(config.client);7 ~, l! u% g+ @7 d' P  n

3 q% b) C8 s3 Z8 D3 hconst fs = require('fs');! i4 B2 {! E* [1 P3 B
, z8 P; N; Q- e  J8 E
// setcode& t& W  U5 P$ z
! A8 w# e0 G: c! O7 q
const jsCode = fs.readTextFile(`${__dirname}/contracts/subaccount.js`);$ D: x4 b4 N% T, |6 p

, `" f# z# q: v& O; ~fibosClient.setcodeSync(config.contractAccount.name, 0, 0, fibosClient.compileCode(jsCode));
) |5 N3 [- g  [* l% U- l
* s2 C3 Z' ~) v9 N2 z. T/ _, _// getcode
# P* ^# f. g7 B+ L' Q& j$ F% u, N
const code = fibosClient.getCodeSync(config.contractAccount.name, true);6 }3 j! @( t* L) g4 C+ e% w! X; Z

5 `- Y6 K( s8 Y& r, sconsole.log('code:', code);
; R9 j# E6 C/ }2 |) B: M6 d+ ~: q+ w8 M( u1 Z# Q
// setabi) x2 B6 w$ L2 k2 H9 d# U
* ^& N- J& C' q: f
const abi = JSON.parse(fs.readTextFile(`${__dirname}/contracts/subaccount.abi`));
+ `% ~- x, a& e# @  T3 l  c' [7 L: m- P' L1 Q; z& s% C
fibosClient.setabiSync(config.contractAccount.name, abi);
- p% l( a0 k  F" ~6 h1 y) I
' `) V1 d' {; F  L$ n转账测试
% q' x# \$ i: l1 u" e: k/ w9 l; V+ j) S% g% _, o0 D
我们先来写一个脚本 account.js 来查看三个账户的余额。9 P; ~- J$ D# w! ^# k2 O

7 Y* z) f# s0 W) ?) |& g# ]const FIBOS = require('fibos.js');1 f0 t0 i3 ^, V
$ Y1 y8 M& @$ H3 ^
const config = require('./config');
. O  \+ n7 C% n4 h& H/ Z! b" \( g# m  ]4 l( \. l
const fibosClient = FIBOS(config.callClient);9 z! w5 [+ w9 v3 w. E4 r8 c1 j4 e
- t! |+ T8 F! Y: b
const account1 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account1.name, 'accounts');
( a& g, [1 @- |$ e$ {
! D" D& J+ X' m/ jconsole.log(config.account1.name);! `/ I0 l2 [+ N; ^; |1 f- ?8 [4 B

/ Q& y; G% \8 Lconsole.log(account1);
/ w: W7 u) w& Y  [/ n6 s3 \; g8 a( _% `) f
const account2 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account2.name, 'accounts');
3 r5 h) n+ l, o8 I( {* l
# u8 H! t% E- Uconsole.log(config.account2.name);
5 ]  k  _4 q$ y1 g
$ q, ]2 ~; L, @) j# ~console.log(account2);
, V3 x7 b9 k/ x' e, ^
" ?! `( ]/ v- t$ j' Iconst contractAccount = fibosClient.getTableRowsSync(true, 'eosio.token', config.contractAccount.name, 'accounts');
, H$ x, N/ _. S0 p1 l2 L5 L% S1 i* V$ W& v& r/ o8 f
console.log(config.contractAccount.name);& I) k+ z- I+ q& p
- j" }/ N6 k3 f: X
console.log(contractAccount);
4 J% _0 d4 l9 k1 F' Q
# Y5 [. o# `$ o" i+ M7 Y执行 fibos account.js 来查看三个账户信息。 目前我们的账户还没有 FO,所以大致情况是这样的:: q+ u9 P2 V0 n2 R( K1 S5 ]
3 ~2 T& r. j+ u' u& c& o
用户账户:helloworld11 金额:0.0000 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO. o* b& n- F5 \5 I( O2 d/ \( P
; ~- R8 v0 [# F7 Y& Y- W
* p* l6 ?  y; v4 r) F" U4 b: [

/ ^6 w* H9 Z+ r6 D测试网会自动给每个账户发放10 EOS 的通证用以测试使用。账户中还并没有 FO 通证。所以我们再来写一个兑换脚本,用1 EOS 换一点 FO 通证。0 Q& g2 ~8 N, b4 I3 M+ P
3 W0 ?, V+ k& k: Z
const FIBOS = require('fibos.js');
  Q8 }7 c3 ~' l2 b: f* {1 C+ L& K) Y2 W
const config = require('./config');% W4 f0 F# \( {6 d8 ]9 _; c

! K6 K, I5 _, [: M! ~. j7 g! p8 aconst fibosClient = FIBOS(config.callClient);# W4 d3 Y" `5 N& Z8 o* |; N) o
/ c5 [$ X- V, j
let ctx = fibosClient.contractSync('eosio.token');4 x0 h2 e7 Q' L1 o( P2 O7 H; M
- @) r: E7 X5 g- f9 ]
const r = ctx.exchangeSync(; a$ P, l( G' ^$ f: R

' |  H# z+ u' I5 A    config.account1.name,+ z7 g2 c5 N8 A4 X" D: y

" u8 }* H* Z4 ?$ ]7 q* U6 u% B3 a    '1.0000 EOS@eosio',
$ Y1 S2 q* p( ]: A
8 J( G. G* ^5 z# q) c6 ]; T    '0.0000 FO@eosio',! I5 J+ z$ L  e9 V, I
; E1 ?5 o& u- s. _4 l" _
    'exchange FO to EOS',
" r# }2 {4 D* S1 S6 v
2 C0 Q. w+ {! C% t& G    {
6 k5 ]3 L# o  B* |8 h' \" z, {5 U2 }+ e
        authorization: config.account1.name
( [9 X& C: j0 H0 ~
/ `0 l, S! s9 w" {1 X    }" G1 ]( _9 k0 k& n, D6 ?
% @; B: ]/ H# q; y
);, ]1 D" J9 H! X- D6 ?. b
5 A- y2 N: A( S  K6 _1 ^
console.log(r)
9 A2 r$ P: L8 s: D3 k
* s5 V! {5 u2 u, V再次执行 fibos account.js 来查看账户信息。目前我们的账户金额大致是这样的:
4 K/ y- k1 m' ?' U' a7 t% r2 c
用户账户:helloworld11 金额:146.4245 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO& `+ t4 e: G. O' R- h7 e4 Y- p

1 U1 G$ `0 ~6 d1 V下面写个脚本 transfer.js 来执行转帐操作。
2 ?; k& s  Q6 B% z8 `4 N4 c
: \7 n1 U- k  k4 j* p7 m) dconst FIBOS = require('fibos.js');
& S5 ^% z  ?; V2 n' i4 l3 Q
8 ?/ H0 {& ~/ S: \4 F' I8 P' }. @const config = require('./config');& l  Q+ C4 k3 e. x! O8 n9 R

. |6 g: u+ _8 x* [% Gconst fibosClient = FIBOS(config.callClient);- G+ t0 J1 e, X. ]' p: k, S
( s+ K8 n, ?/ V
let ctx = fibosClient.contractSync('eosio.token');
, L# ]% G3 t, F7 K+ `" \9 L+ V! ~
! ?% Q+ H) v0 X2 ^* H3 Jconst r = ctx.extransferSync(% B1 f7 M4 q" ]: ?. i& w+ H" V

/ w. g4 H5 {  o6 @7 E  n! \    config.account1.name, // 用户账户* R( l' s4 w5 Q7 n+ K  f
* O- V( m! u, u/ q' `( ]
    config.contractAccount.name, // 平台合约账户" h! m6 m$ ^! Y9 I3 O! c: I

# p8 M8 M) R" P9 G, h+ S    '10.0000 FO@eosio', // 转帐金额; H( W. Q, @9 K- x# O! i; J9 C

6 g. m& R( n: E: L4 i; j2 Z    config.account2.name, // 附言填写内容提供者的账户名,平台合约会给它分账( b$ r. Y, p  S

# K3 F% n3 H1 _% r    {
# a# K) l! J) Q: O# w! \! }: V
+ N$ O& k; {* a: G; B* k% Y+ ]( K        authorization: config.account1.name //提供用户账户的授权
$ f0 D! G# N  n
# Y. x: {+ g6 e; j    }2 N8 m+ B% G; G! F
* W, X, [6 q7 S) c: \8 p5 t  \
)0 j5 n  j: \5 ^8 M4 e

8 C! G& _- P' p7 P6 b6 d& econsole.log(r)
3 ~8 ?( y9 d2 P; E
5 G5 ~1 w. s& C# j. U3 y我们要从用户账户 account1 给平台合约账户 account3 转帐 10 FO。memo 参数为要分成的内容提供者账户 account2。根据合约中定的2/8分成,平台合约账户 account3 将会分得2 FO,而内容提供者账户 account2 将会获得8 FO。
' N  U8 F! M3 S0 G' W: Q& h# P- X1 `' r7 H& e% i- z% [2 u* U2 h
使用命令 fibos transfer.js 执行该脚本完成转帐操作。
6 v% s) b5 }, ?; j2 B9 ?- M6 `4 _
5 W5 g+ A4 K- q$ |下面我们再来看一下目前三个账户情况。执行命令 fibos account.js。三个账户金额大致如下。
# [, U: P$ Y/ C  p5 L2 V; O* f$ B8 a% }
' t+ o1 t( b$ e6 {8 Y# h用户账户:helloworld11 金额:136.4245 FO内容提供者账户:helloworld22 金额:8.0000 FO平台合约账户:helloworld33 金额:2.0000 FO; I. X( k' i# _* b5 S7 A9 [
0 r; w7 H& [8 G! K6 v% ]2 j
结果显示,分账账户和平台合约账户如预期那样获得8 FO 和2 FO。. ?6 v- C. p9 _% f9 J7 T7 A

5 A# g" u9 x2 y% D+ c0 ^4 e( g

; o' |/ q8 Y/ S. c
: R4 m3 @; P& E1 M5 [综上,我们成功使用了智能合约实现了自动分账。平台方还可以继续根据自己业务需要定制自己的合约。
/ d0 i% X, D4 l7 f. O; `
6 Q7 p/ c8 w5 [) ^) u4 ~/ \2 A' A文中的代码请参考:https://github.com/fengluo/fibos-subaccount
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

哈哈笑417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11