Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

哈哈笑417
328 0 0
自动分账是很多平台都会用到的支付功能。很多互联网内容售卖平台都会跟内容提供者分账。比如:Apple 的 App Store 跟 App 开发者三七分成。很多平台都使用了支付宝、微信支付作为支付手段,但是要同时实现给内容提供者分账,却是一件不太容易的事。使用 FIBOS 智能合约可以很容易实现这个需求。
/ W+ @  [) l8 d8 s$ f* m
% `( g" A1 C1 a& C文中代码已在 GitHub 上开源。https://github.com/fengluo/fibos-subaccount
7 t! F" p* Y2 x5 s. x  _+ @8 V4 `; X) R5 n
设计思路
8 r( v) m4 G/ T* U
* H" F: l, O+ U8 n在 FIBOS 转账是通过 token 合约的extransfer方法来实现的。extransfer方法在执行的时候会给转账方账户和入账方账户发送通知。所以用户给平台方账户转账的时候,平台账户就会收到通知。所以整体业务逻辑如下:
/ c6 S; Q. x! j  L
- W, b' Z% a" J  w2 N! [0 y9 Z        quantity: 10 FO' G0 _- C3 i! ^$ s+ ~

3 [' S; W0 J. n4 j# K# E! n        memo: 内容提供者账户           quantity: 8 FO
" U+ a% a5 }8 J+ k
/ L1 q% o# y2 @. j1 \* ]% z用户账户 -------------------> 平台账户 ----------------> 内容提供者账户1 n9 b  i: w! U+ }3 Z4 D: l7 n. E0 O4 F
. A* J7 {% P* ]- b
            extransfer      2/8 分成   extransfer
4 ]; Q, i; E5 m  u+ p  [: N
* b2 b1 ^1 |# z8 \8 i) V1.用户给平台方账户转账,memo 中填写内容提供者的账户名。
% b7 E2 b, t- e9 @2 T/ {5 O
+ ~6 F2 D4 ^9 v  W+ X% P3 L5 [' }2.平台方的账户合约监听 extransfer 方法的通知,然后做出分账计算,给对应内容提供者的账户转账对应金额。* ~# V1 G) Z& a, |( ]0 |, ?9 g
( v9 y0 V# z- H
整体逻辑很简单,整个合约代码逻辑差不多用20行就可以写完。
4 s, r2 O0 c8 n" g! M" x8 S5 u/ J: K8 ~- y6 w( j4 W" S/ `2 Z% Y
编写合约/ A% |/ i0 Y* m" {2 A

( q9 N: S6 o  x! P' ?6 t( f. d! U' ^$ z( D; |FIBOS 的智能合约分为 ABI 文件和 JS 合约两部分。ABI 相当于合约接口,JS 合约则是功能实现。本案例目前没有接口设计需求,不过 ABI 文件还是合约不可缺少的部分。所以我们简单创建一下就好。( K* J7 B; ?. p% P* N3 s1 R0 t
' k, Z4 c) z% M3 R5 d# G, M
我们先创建一个 contracts 文件夹,合约文件都会放在这里。然后在此文件夹下,创建 subaccount.abi 文件,内容为:
, _0 e# O" y# A5 m6 ]; |
2 F( Z2 o- D' N5 f{
* x% ^; n9 a3 W! Z7 j4 D% r) P  @1 w7 G5 ?3 A6 g
    "version": "eosio::abi/1.0"
/ j- n/ Y& C9 i( f3 U) B. S0 s, l& j' o( @& Z: L) K) L
}  n6 p0 o6 @! [1 O6 y

! L; {; \6 z  z$ U, [# lJS 合约部分也没有太复杂。在 contracts 文件夹下创建 subaccount.js 文件,代码为:. d. F* k) h& Z. \, O$ C' P+ M

- y& H. w  W6 G- a7 W* ?- v! o" Wexports.on_extransfer = (from, to, quantity, memo) => {
1 r. S9 I9 `+ f( ^3 g* _4 j2 h( ^2 J8 K# _! k& b% c
    // 需要在开头做一些判断
7 d4 X* G) ]# T' c! b, v9 E  B4 j6 c. B
    if (to === action.receiver && action.is_account(memo)) {+ r8 H  s: u2 N( ?, _: x

/ J$ f0 g, `6 S7 P; E; ^        const num = parseInt(quantity.quantity.split(' ')[0])1 |! c- W3 g! i
7 i, [0 Z9 A7 i
        // 假设我们约定平台方跟内容提供者是2/8分成。
8 X8 u1 M' D8 _: F, X! l4 R, e- Q( v* o4 v( h! ~7 a
        const subnum = (num * 0.8).toFixed(4);4 R8 q- X7 ?& V! E& l
/ C  q& y' H- B9 j7 P: r  ]
        trans.send_inline('eosio.token', 'extransfer', {" ^& |5 I2 X1 f
6 x) `3 I. H. w( |7 I% Y% Y7 e' q
            from: to,& h$ Z; t! I2 V- J2 Z/ C6 K: y
; V8 _0 n4 f. N7 D2 B: M0 }( R
            to: memo,. o# r; W& {" [/ V7 @

2 u1 U& ~/ a0 E: h/ v            quantity: {& Z8 `8 c* e9 d4 q$ I  u: C

: u" S" j$ i- n9 c8 I. }                quantity: `${subnum} ${quantity.quantity.split(' ')[1]}`,
0 U1 i# U5 {* q5 z7 S- b' W' N1 B) q' a$ W; f% Y* m
                contract: quantity.contract7 T, K! L+ E* ]

: v$ Z: q* A. w            },
+ D: |/ R& D$ t9 k
3 G' [5 a( C; Q& ]% v! o% c            memo: 'sub account'$ L$ t) Q( F/ x* s4 K% {3 i! j4 z

6 q' l3 s4 g- ~+ c3 n+ U        },) L8 T+ Y/ j9 w# W! |

6 D) m4 m5 g/ W" O( ~4 w2 B        [
5 p: C5 T9 W  o1 A/ p' @0 r3 }" K; |! P
            {
& \( \) J% @+ c) H1 d2 X
2 y! Q  U) v( A! P0 a% S                // 需要提供合约账户的 active 权限4 k/ r! A* ]% H' Z* Y
& `7 x' e) \- S: w2 d) l' s% L
                actor: action.receiver,# C3 W: t7 E; j4 D# S1 o! e

! Z7 K! P$ F& \9 v6 O$ a                permission: 'active'/ _% o# }5 Q- Y; t' B. @" Q2 m3 V
# g/ Y- @3 O. j
            }4 h5 {8 t$ e4 q- A% v) K% u) q
2 L+ ^$ n! b0 T, j
        ]);6 [2 O2 V8 D6 A. M
% l6 G" }: [; \: Q8 @! U6 \! g
    }- p  R- Q& S' p0 ?5 F. U+ Q

) u# r8 h! s0 A9 \: q: w" A}
; K% I, M! o6 ~% }7 [  ]+ `7 i
4 ^6 k& }# A, j5 B7 r$ v) L合约代码开头我们需要做一些验证。
# O( j% R/ H1 H0 X! Z$ Q3 f7 W, E
1.收款方的账户为合约账户,否则因为下面代码执行给内容提供者转账时,因为转帐方也是合约账号会再次收到通知,造成无限递归,超出最大 send_inline 层数而报错。( I7 V1 w) U! C0 F, c" `( m+ e
* ?4 h* F# `+ m# ]. ?3 h
2.我们用 memo 参数来放内容提供者的账户,所以我们需要对此参数校验一下该账户是否存在防止打错。8 t# I1 g- ?$ r3 j6 ^5 c
' X( P! C' U' s1 h. h: v7 [
合约代码中我们使用 send_inline 调用 eosio.token 合约来执行转帐操作。转帐操作需要对应账户的 active 权限才能执行。为了解决权限滥用问题,FIBOS 定义了一个特殊权限 eosio.code。我们需要在平台合约账户中配置权限,在 active 权限下添加该合约账户的 eosio.code 授权。具体的配置操作会在下面说明。4 N3 V2 O5 _  f. [2 U0 B$ }: n

% {0 c& b9 _% R9 m7 s' N在 FIBOS TestNet 上注册账号
4 t8 Y7 p9 ^3 Q& Y4 ?7 j2 c* K3 L! O# _- ~; G3 N
为方便测试,我们在测试网 http://testnet.fibos.fo 上注册三个账户。: T( ~4 s5 K& a- Z$ e

* l: Y7 W, v8 X用户账号 helloworld119 v1 a1 C4 J- b: U/ i  _' Q

* |% Q: i( C) Q% m" o内容提供者账号 helloworld22
+ N: r& I$ Z  C2 l2 G) V. O- F
6 [. q. k2 R0 X& o- z% Q! D; t平台合约账号 helloworld33
3 r# i! o1 ~7 r9 I0 x/ L
7 }" c6 r1 P* u0 J/ \2 v% y  k( \6 F我们需要记录这三个账号的账户名以及公私钥。以便下面的开发使用。创建一个统一的配置文件来记录这些数据:: m/ ?3 k* c* w0 F! V2 Q
0 ?% g" Q1 i# M. a$ S2 c
const config = {
/ D3 Y+ g; ]" d; s) S
- C) ^+ A( Q4 f+ o) l( l, V    // 平台合约账户的客户端配置
5 q1 g( T4 ^" t5 R6 x" F  E' P2 \- [; o* H7 l
    client: {# f* E7 \% t; S( `& R& r
% p8 q1 k1 f% S0 ^6 E/ Z' e/ F7 P$ ^
        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
8 P# g" l) d! d5 F) b7 E* J& {+ x; h
        httpEndpoint: 'http://testnet.fibos.fo',) G) i4 T1 ]" k; S9 B) X/ E

- q1 M+ d9 l* U8 I$ q        keyProvider: 'PRIVATE_KEY_OF_helloworld33'" b! w$ S. I5 U' n/ V7 W1 a* S+ [4 P( C

4 U' M% [1 u3 a6 R8 v    },
/ Y# X7 y% w! D( w
  \; R2 _' q. o: V! K  @& e4 D+ ^# s( N    // 用户账户的客户端配置% ~" d9 W, J1 f! [4 |  i
/ h) Z& w# C. {/ [* Q
    callClient:{! |- A6 c1 e) o2 E8 z6 \. M+ ?
5 `5 M6 Z3 c! U( b) R* A
        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',+ P+ Z- v3 o0 M+ K

6 l8 b& z' I- S        httpEndpoint: 'http://testnet.fibos.fo',+ @3 a! ~0 E1 M! X) B" k
* P2 |9 `- M1 G( Q# D
        keyProvider: 'PRIVATE_KEY_OF_helloworld11'
, m' a! R1 ?! j# E& L+ R% d( q6 G- J# j$ y
    },! e" H! a7 e2 `& i! @6 \

6 c3 d# D6 N) R0 @! i1 D' M    // 平台合约账户信息
* {* Y. P8 N4 s6 x
9 ]% H' `% @" D4 a. w+ G    contractAccount: {4 H+ H$ k$ N/ B

' X6 O+ n, S' N* h$ a, @        name: 'helloworld33',
6 q- e2 ?, J0 S& {3 }" c) \' k2 E7 ^6 p( C" \& I, j& ?! e7 a
        publicKey: 'PUBLIC_KEY_OF_helloworld33',3 O) h3 J5 j8 L! u
* y! F5 c; e) W  s* j* v' e
        privateKey: 'PRIVATE_KEY_OF_helloworld33', U- h- M& S2 _: v. c6 Y

; J; }$ S7 w6 G9 u5 l6 }- C/ q    },
: _+ N( c" V# Y  C$ f. K- S6 ~" m; I: K/ w+ J) z* r5 z% _
    // 用户账户信息
* V9 ~- S* M; ^: s2 T# ?  V
6 \  h5 G- ^* V  r    account1: {) i4 D% `6 i7 F3 v( V

0 k6 i. w% h  N: c7 i  `7 T/ K        name: 'helloworld11',; q1 P2 f3 r$ P! X
5 ~: ]1 u3 d& \  Q' B
        publicKey: 'PUBLIC_KEY_OF_helloworld11',
( |+ T5 ^* k3 P
8 y! I- A! J! R, F0 F; L        privateKey: 'PRIVATE_KEY_OF_helloworld11'. J& p1 q! g% N( q

, n* \# m8 y$ `3 Q9 B8 \/ ^    },
( Y; L0 J$ s7 @' R" W" m; u* I8 E& ^& K# I. N$ k* }
    // 内容提供者账户信息
# L4 `) m2 Y1 q( Y$ y
  @) i; b# O$ }6 c* v' S# ]    account2: {
9 [' m5 S( u; S9 Y8 n9 W5 p
4 W0 K5 P- K# s; N/ y: z" S1 W: M        name: 'helloworld22',
9 `( ?) v9 M5 {+ J+ k1 B  b, e( ?7 i" Y. i" C# n
        publicKey: 'PUBLIC_KEY_OF_helloworld22',) U7 {; A( T" }4 S
- G# a5 q1 b# G# y! G
        privateKey: 'PRIVATE_KEY_OF_helloworld22'
; f& t. F) [9 W- I6 l8 S
4 }# A6 o' [6 }. a    }
# [9 |' \3 T. {; X
3 k' Q$ V: \: Z3 G- q7 I}
% {* l, F" O$ O1 ^3 W/ V/ q/ S2 \, Z9 b( _8 n. t1 w
module.exports = config! r. E: H5 }( w0 S3 s2 O6 t
" n2 @0 V+ U5 K+ o: _4 `0 @
配置权限
$ N( d* e+ [3 S6 d- Y$ i% X) [5 k, N) ]3 H
在合约代码中,我们调用了 trans.send_inline 函数调用合约 eosio.token 来实现转帐操作,但是转帐操作是需要账户的 active 权限。所以我们需要更新一下合约账户的权限,需要添加调用者的 eosio.code 授权到它的 active 权限。这个调用者自然也是这个合约账户。
  O5 w. G  ^+ `/ p' i& w& }; H7 k$ W' \1 i
const FIBOS = require('fibos.js');+ ~7 N' u2 v+ q/ T" P
8 M. g: G* C+ x$ R* {+ g- M" s
const config = require('./config');
/ Y6 B# r6 O/ x$ k- C& ~/ o- h1 x+ f8 C# M0 ?7 G
const fibosClient = FIBOS(config.client);
' u" J- S4 B, g% d* N' ~& G) O& K. w9 e. t
let ctx = fibosClient.contractSync('eosio');4 ?8 `# _4 Y; H8 c4 D

3 B. x* U2 C% V3 ~% jvar r = ctx.updateauthSync({2 H; ?( Q4 T2 P0 q% n
) t9 i3 @0 r3 Y" c; a5 `* V
  account: config.contractAccount.name,8 B& k5 C4 B  w7 j, V! U3 M1 k
( M/ x' A7 u+ U4 v$ `3 @* \
  permission: 'active',3 g6 {0 `6 r  a/ h" v

$ {  ?7 X4 }% @  parent: 'owner',
" m/ H7 k; G/ }1 v) B, a9 j" E: c; N7 M) Z0 F+ G5 P$ P
  auth: {
. o- X- Q$ F& g3 C5 b0 n. m3 m% `5 S2 |3 i1 G; w4 c
    threshold: 1,
. B0 ~0 ?& W# |5 y4 O% r9 @8 x" _9 C& J0 k" D6 j
    keys: [{/ j5 u$ G" ?# Y/ K5 A+ A
3 o/ r6 ?  r1 T  B: R
      key: config.contractAccount.publicKey,
  M  l' s5 S* @, g- o, `" ~# ~; N0 O$ [7 {, I3 T
      weight: 1: J' x* E3 @8 `, f, e. G

) x- G( ?: V5 ^% W6 h: J/ T& }6 L    }],; w  ^+ b, E4 Z. L

6 f& Y( U" [  l    accounts: [{* l" |  v  i6 V5 D

3 w7 l# v  F9 J, }        permission: {
3 O. r( I4 l* d. J( D) ]# R1 Z
( o9 M% @, b6 E. G% m! s9 W            // 将调用者账号的 eosio.code 授权添加到它的 active 权限下。
8 G# W  \9 Z0 g6 D/ v0 F% o1 H3 G
5 U+ a: g9 L- t2 k' F# Z            actor: config.contractAccount.name,
  e# W4 c0 r9 Q1 w8 z# u) p3 t6 c; ~) r) ^: M6 D+ y2 O
            permission: 'eosio.code'
$ C* E2 J" J  K+ U+ w2 t" _5 z9 ?- p
        },
  m! ]8 |6 f3 @" d8 g2 Z/ a  h3 |) q; H: r/ @
        weight: 1
) B! [% `. p  Q# H% ?! V$ M& v* x; k
    }]
+ {, w3 O1 n6 F5 A8 p( t2 C; r+ u3 v3 M/ B* V5 v& I6 G6 }& t
  }; K  S4 B* ]$ R  Z9 z6 N
" o8 u0 O; N" d* Y! h
},{
8 V, Y% i- B# T- d9 m& N' S* i1 h2 R& P
    authorization: `${config.contractAccount.name}@owner` //更改账户权限需要使用 owner 权限
5 q- _1 }: a* ], E
( W: |9 X; l& s4 h; L: o; A7 u});+ p# a* V' I/ D7 y( u, e
# m$ p3 _' Y2 W) e* K# Q
console.log(r);1 p2 \$ b- T* ?0 b. j# Q* p
3 O3 x* s) @& o1 ]' k7 E
部署合约3 G- e1 x7 [$ w4 z8 v
  V9 k8 F& T' B  g5 j* `4 Z, y
const FIBOS = require('fibos.js');: N5 E  J" N% \7 G$ o% D

4 C0 s" E1 B8 O4 F8 g7 `7 W/ kconst config = require('./config');
9 L  n9 u: Z, C. h  Z6 G9 `2 A" t; i% ^
const fibosClient = FIBOS(config.client);
& k' E* n9 s+ [6 ^+ I* R' B+ w% B; @3 ]( H! C/ S; f
const fs = require('fs');
  M3 s$ }1 K8 q/ x. M9 k2 v$ x) Q3 s
// setcode
! l, b( y' E8 z! r% W/ t( x! c: U, p& y1 C
const jsCode = fs.readTextFile(`${__dirname}/contracts/subaccount.js`);0 e* ^. N# F& w
; b4 ^9 G* q2 y0 R
fibosClient.setcodeSync(config.contractAccount.name, 0, 0, fibosClient.compileCode(jsCode));
+ i2 P# L( L9 \% J' S  c" y- Q
& r* ~/ ~8 y. l7 E+ O6 l// getcode
$ I/ p0 Y% n7 _- e0 h
" J% [) l/ i6 Z9 X, \3 \& Lconst code = fibosClient.getCodeSync(config.contractAccount.name, true);
6 I+ R9 e: t/ O5 T& L5 ^  \! c6 D
7 M2 f, U/ I6 t8 l  p8 c# {  R! K: Zconsole.log('code:', code);* Q, b. C2 Q! }9 A0 r7 ], D
6 u) H8 s, {/ \  n* o* f( [8 u
// setabi
' }" ?6 ?& {9 H' J8 T
; T- Q3 f" n6 f7 V3 fconst abi = JSON.parse(fs.readTextFile(`${__dirname}/contracts/subaccount.abi`));9 x& e& \& H4 D- |
) O6 u9 Q  W+ z( ]
fibosClient.setabiSync(config.contractAccount.name, abi);
/ Q8 [, i. H2 v5 v6 o" T3 \$ F3 G6 H) E2 C! a% @
转账测试
4 m, V7 K. O* `2 W: @/ Q- |- b, N: ?# q
我们先来写一个脚本 account.js 来查看三个账户的余额。, y+ y, @  `7 ?

* k# P  P/ J( E8 e* xconst FIBOS = require('fibos.js');
& R- {! S: K, c$ h0 X
( Y+ o& n  ^. `! w3 S! J, ]const config = require('./config');
, f# R, K8 v+ P" S
$ ?5 G8 }6 `  Y  X7 z4 dconst fibosClient = FIBOS(config.callClient);
! r* n! R- x( j7 R3 p& w! P* K. A1 X/ u
const account1 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account1.name, 'accounts');
4 m+ J, J& r0 w7 N: y) U4 x4 l; `9 P$ B# S' M4 L# R8 l
console.log(config.account1.name);9 b- R( G9 z+ v) S+ P3 D$ Z
( t4 J: I% L/ t
console.log(account1);
9 K- \4 ^( b2 w: w9 y
! ]1 f4 X8 o; U! E5 J9 {const account2 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account2.name, 'accounts');
9 u& L( D* ~! ?0 w* Q. u9 r  T0 i3 {- x% F1 F
console.log(config.account2.name);  u: P  A" G+ N6 ?  W1 i1 n1 g$ q
8 W& k. ]- ~% c( {
console.log(account2);
  U+ I& Y/ Y8 C- B' G( L% M; R- N  J- y0 Z
const contractAccount = fibosClient.getTableRowsSync(true, 'eosio.token', config.contractAccount.name, 'accounts');
: A: U6 o" h) F. W. g4 H2 e. Q: T3 ]0 C6 ^2 p* m9 G
console.log(config.contractAccount.name);
/ ?- `9 a: u2 N2 ]4 r, ]5 s) q
( m3 b0 Q' L/ Rconsole.log(contractAccount);- t7 }5 }7 E* g! O/ b- ]2 m) x

. Z$ ?9 p5 J7 a2 b' i执行 fibos account.js 来查看三个账户信息。 目前我们的账户还没有 FO,所以大致情况是这样的:
( r, i! A8 D* U9 @2 O
4 ~! g/ E9 @( T2 c! _2 A用户账户:helloworld11 金额:0.0000 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO1 k) T. D+ Y; [, d* a- n
' b  |9 b' g/ m; G3 e% H; P( [
9 {! y5 Y4 u5 p) R0 M
( z$ |& y" v* G8 O
测试网会自动给每个账户发放10 EOS 的通证用以测试使用。账户中还并没有 FO 通证。所以我们再来写一个兑换脚本,用1 EOS 换一点 FO 通证。1 |# z3 w) X. u5 B
4 D/ j5 O& r  C4 c0 q* R
const FIBOS = require('fibos.js');: s) l, Y- G; W: ^0 v0 m* I
. h4 U  c! K. I, G# r
const config = require('./config');
6 {: o, v6 r& ?  K+ v- ~9 `1 e. d; t5 {; M
const fibosClient = FIBOS(config.callClient);
6 R# S8 L3 |" ]% Q
$ v6 u5 \' j1 M/ I: u9 Y! }let ctx = fibosClient.contractSync('eosio.token');
/ Y4 o* ^* Q& V" ?- M; W' v- O3 K
5 X7 `/ p7 L  |0 M/ K/ T, nconst r = ctx.exchangeSync(- U# s9 X/ ?0 f2 J. `
: N: k7 B  N) J
    config.account1.name,  W& ^* |/ c' F4 B9 k( C! {% ^

& u& d: }0 Z, p) d6 S4 k: x7 y    '1.0000 EOS@eosio',
$ F  z% P# g8 d/ e* @  I6 \# l  u% e
    '0.0000 FO@eosio',
) e4 s+ w+ {9 A; K3 I2 ?# y9 o9 e2 N9 c9 q  u4 B' t
    'exchange FO to EOS',
8 i& N$ L3 Z( g: I6 H3 C7 d' H+ j' u
    {( o( v5 C& x: e! ?6 n! p( C

* }3 [$ }! ~$ v7 T1 q        authorization: config.account1.name
# ~+ J' M- f5 t6 O) e. x+ Y0 M7 ?, C# @5 V7 y
    }
4 z; c; ^: s9 ^# e& A3 K- n9 A* y0 r0 ]) @/ \7 ?
);' R+ M& v/ k9 `! M; z# z
/ w# W! C( Y/ E" J4 ^( ^# B9 R
console.log(r)' O' x/ P$ @1 a' a

1 j' J- C- q# B- v1 E4 J( g再次执行 fibos account.js 来查看账户信息。目前我们的账户金额大致是这样的:" l2 S- `# D& R" Y1 |0 a
' p! W7 m6 r1 B! M7 h4 D
用户账户:helloworld11 金额:146.4245 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO
" b4 g$ P  X* i& h2 a9 b6 ]) j7 {. r" ^
下面写个脚本 transfer.js 来执行转帐操作。
1 p& Q3 A3 w0 m! }; T( {9 Y# s4 Q  K/ N+ f1 `/ `
const FIBOS = require('fibos.js');/ u5 _( D; ]* |% y! y. n

% |5 a; P: }+ s) mconst config = require('./config');
, `& Y. d# H' c1 h3 z; t; h0 w; J* `" s$ P( f
const fibosClient = FIBOS(config.callClient);6 r- i+ E0 ~( u# D# q8 C4 B1 a
# f! E4 K( F4 M$ n8 M, C# Y6 Y
let ctx = fibosClient.contractSync('eosio.token');
- g, j  A. D6 c4 r
  S: O. Q/ m! B7 s. c% Qconst r = ctx.extransferSync(! C7 ]3 }' M3 p6 n1 b4 T) h

. {6 l1 f: V. L* R& T6 r9 Q( v    config.account1.name, // 用户账户2 E1 h' c+ Z8 K# y( c: H/ M

8 W" _* W% G3 x1 e1 G0 o    config.contractAccount.name, // 平台合约账户( k+ b" k5 S8 l' N

+ q, T8 b% Z. k$ h    '10.0000 FO@eosio', // 转帐金额
6 H6 I2 C' @) r& }( q6 T8 ~' D: P  C% _$ ~2 Q/ ]  [
    config.account2.name, // 附言填写内容提供者的账户名,平台合约会给它分账1 D2 p& b1 s; N3 P$ Q: \6 E/ M
' q- [. N& m1 [: l
    {
- q3 r( f" u) i3 c8 e1 V; P& h2 p# e  w1 y, X( v# l# f& @
        authorization: config.account1.name //提供用户账户的授权! ]/ P4 {: }  i8 ]  M8 W2 B0 q! B
3 v2 k. X6 y. u1 M; l- q
    }3 B1 p5 v- m' D& M6 Y0 l' ~0 v: t

0 N; N. c2 N- u6 u- J# h)
- E' U! C* n4 C$ V: p. _! J+ U4 {! I7 x; m0 _+ I0 i8 K
console.log(r)
6 c: Y- z( W: M' s) d' `! ?: V3 z3 H4 U7 o! v1 R5 {, r
我们要从用户账户 account1 给平台合约账户 account3 转帐 10 FO。memo 参数为要分成的内容提供者账户 account2。根据合约中定的2/8分成,平台合约账户 account3 将会分得2 FO,而内容提供者账户 account2 将会获得8 FO。5 R: D8 W& g2 U: @. t4 I& Q

2 y/ \  U1 O0 {7 g5 i8 w. F使用命令 fibos transfer.js 执行该脚本完成转帐操作。9 C, Q" P' ~# e9 |' t

3 L. W" J! {0 D& E9 h7 F下面我们再来看一下目前三个账户情况。执行命令 fibos account.js。三个账户金额大致如下。( {+ ]/ @, m2 _. Q, _7 @6 J
4 R$ l$ |9 @" @
用户账户:helloworld11 金额:136.4245 FO内容提供者账户:helloworld22 金额:8.0000 FO平台合约账户:helloworld33 金额:2.0000 FO
8 {" ~: W5 ~8 u+ \! m4 F* D- I$ l; w$ B+ K
结果显示,分账账户和平台合约账户如预期那样获得8 FO 和2 FO。
% E) _9 r4 i" Y& ^, i. R: {3 ?; q0 [3 r2 A$ p4 f

$ l& U7 g+ a8 d; i  b& v7 \# e$ b1 w8 j9 y% X
综上,我们成功使用了智能合约实现了自动分账。平台方还可以继续根据自己业务需要定制自己的合约。, `# x' T- |8 g8 z! b

$ O$ }+ ~9 ~) j; t# y# g/ G( g文中的代码请参考:https://github.com/fengluo/fibos-subaccount
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

哈哈笑417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11