Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

哈哈笑417
115 0 0
自动分账是很多平台都会用到的支付功能。很多互联网内容售卖平台都会跟内容提供者分账。比如:Apple 的 App Store 跟 App 开发者三七分成。很多平台都使用了支付宝、微信支付作为支付手段,但是要同时实现给内容提供者分账,却是一件不太容易的事。使用 FIBOS 智能合约可以很容易实现这个需求。+ Y# f  e6 l5 D8 j
5 |0 b9 n' d' W" q3 P6 |4 p: ]
文中代码已在 GitHub 上开源。https://github.com/fengluo/fibos-subaccount
* c: D7 c5 o3 e; i( L" L5 {0 ^# E( X1 r
设计思路
! c0 ?' D9 t- O  ?7 c9 N! C0 j+ X" \6 N8 `+ v
在 FIBOS 转账是通过 token 合约的extransfer方法来实现的。extransfer方法在执行的时候会给转账方账户和入账方账户发送通知。所以用户给平台方账户转账的时候,平台账户就会收到通知。所以整体业务逻辑如下:
# A  P% W9 Q2 n% m7 T0 H* E. @. m; V7 ]8 {
        quantity: 10 FO& z. S. s, c- X) H; J* h5 T

1 }& I' N5 a. a6 d! B        memo: 内容提供者账户           quantity: 8 FO9 r& U' m9 M$ v# x5 R8 p# c- n

' o) D/ A& z9 Y* h用户账户 -------------------> 平台账户 ----------------> 内容提供者账户9 b3 h, e% o9 T+ |( O
$ T% X  y+ E$ B4 g* `0 x0 u: ]& D
            extransfer      2/8 分成   extransfer, [+ j# Y( C2 E* \8 g+ G
5 {5 |' ]$ V3 y3 ~) J. v
1.用户给平台方账户转账,memo 中填写内容提供者的账户名。
$ p% T$ B% e" P/ m2 E+ B1 F
7 i5 L/ a! z7 ]; J0 ]" o4 w/ m2.平台方的账户合约监听 extransfer 方法的通知,然后做出分账计算,给对应内容提供者的账户转账对应金额。
1 W. U9 T0 n* P7 r! c
4 B! x* d  u% G5 l9 f1 m. |整体逻辑很简单,整个合约代码逻辑差不多用20行就可以写完。- |8 }, z& B, w1 U; w/ M; g) E

5 A" G- h4 u! P4 L4 g编写合约1 B0 b) o8 T; m  _8 M9 D

9 S7 x5 V3 J; A! G, YFIBOS 的智能合约分为 ABI 文件和 JS 合约两部分。ABI 相当于合约接口,JS 合约则是功能实现。本案例目前没有接口设计需求,不过 ABI 文件还是合约不可缺少的部分。所以我们简单创建一下就好。
- \4 W; D! b! A( f+ q) [- ?/ J- w, f
我们先创建一个 contracts 文件夹,合约文件都会放在这里。然后在此文件夹下,创建 subaccount.abi 文件,内容为:4 }, l1 V& B/ b0 `8 p; s
& p* H8 V& Z) b& E( A3 n' L8 r
{6 R/ D% N9 m% t# o& q

' W, R( C6 d% J% K8 O* m& Y    "version": "eosio::abi/1.0"# Z& l: l3 h' R) L" m  x

2 H3 Q5 a: _7 D+ F8 ~5 T8 D! i}
: W& r- z. E# D$ _9 d0 _" J3 ^/ M6 Y% O# N8 [1 v, q
JS 合约部分也没有太复杂。在 contracts 文件夹下创建 subaccount.js 文件,代码为:$ g4 \, ~3 s0 k' r! V$ r: Q

6 L/ V* u+ l: T" V/ M% V7 U2 vexports.on_extransfer = (from, to, quantity, memo) => {
  N4 g1 q9 E3 T6 Z6 a8 y$ K
# I( e$ i% m. @0 l$ E' M  K+ [5 t    // 需要在开头做一些判断
! x2 r6 D7 L  J7 \2 \$ I- I! C( M4 a' r+ t9 Z& r9 w
    if (to === action.receiver && action.is_account(memo)) {
& b, Y6 j4 n: q8 h3 k
* F' S  j7 G' j2 H# i        const num = parseInt(quantity.quantity.split(' ')[0]), B7 p* r# K9 u+ ~

, h; g" V, w" ^% f        // 假设我们约定平台方跟内容提供者是2/8分成。
8 K+ o% M# T. w$ o+ ?+ v! z; i7 s" z  r' r3 H- r- _, E# Z
        const subnum = (num * 0.8).toFixed(4);4 ?& ?1 H1 B# r2 h! E0 O" Q
" U4 \8 X- X! g; R6 [' f7 f
        trans.send_inline('eosio.token', 'extransfer', {
4 o' f, W1 A$ L, j* i. p4 n( [* F) H
            from: to,! w9 N  t4 W! C% M' M2 {% a/ \5 \
& j' X+ l( `4 D
            to: memo,  C- T3 Z! P! P; k. F

* ]  B' F* E+ C. Z: m            quantity: {+ _" k; b  a; L% D% H8 A2 P
2 w( `0 q# ^7 K$ ~* ?! f
                quantity: `${subnum} ${quantity.quantity.split(' ')[1]}`,1 Q! a. v+ O: F+ N- m/ y
  h2 I) h- M1 ^/ I8 M
                contract: quantity.contract
  ^1 `0 v. v% {% {  t5 B0 p
9 w+ y0 n, n! y0 C9 |            },2 ?& p2 p( t* n1 u( l
" m! G7 n6 C5 C
            memo: 'sub account'
; |# H: r! I! {4 Z
0 J7 F! G- k/ T        },
" B( f5 B, x! e7 C7 O# l, g/ ^" V' y  h% O
        [* |. H( W/ N# x/ k

# n! d$ |: r+ y% Y6 h# K            {3 ?! W! z4 w' z% I/ L* R' b' z- {

9 f5 ~  a6 D# J8 S" m6 Q6 \7 r" m9 p                // 需要提供合约账户的 active 权限
; z( J$ A8 [7 Y$ f4 @4 V/ E4 h& t7 d. z
                actor: action.receiver,
% c8 o3 F5 l# N
4 I9 K8 q6 S6 u% ^: g6 k, e                permission: 'active'0 ^. E- ?' |1 G1 Y! ?: v/ L

9 N/ H2 j# B* B$ ?' Y            }$ [6 S: K- A' X8 t1 E$ ~0 O

' r8 b* e6 o0 L; g( ?8 D8 q        ]);
$ [  s! X7 h, Z1 s( C- I+ k3 G2 t0 x% r% V. X1 J" L9 N1 O9 u
    }/ K  a: |! e- I$ a
* X. v) w! _7 @/ Z" _$ k) F
}9 q6 b: h$ e8 ~* r

6 t5 k! o" [& n% m合约代码开头我们需要做一些验证。
3 L& K, c* w, M: L: n
; P% N/ M3 M* @+ R# p; e, y1.收款方的账户为合约账户,否则因为下面代码执行给内容提供者转账时,因为转帐方也是合约账号会再次收到通知,造成无限递归,超出最大 send_inline 层数而报错。, r7 }* D! N8 J) `" R

- f! T) J0 }& u3 I- P2.我们用 memo 参数来放内容提供者的账户,所以我们需要对此参数校验一下该账户是否存在防止打错。$ H* [$ Q* O$ Y4 }5 R7 K
; f7 m; D( I5 @
合约代码中我们使用 send_inline 调用 eosio.token 合约来执行转帐操作。转帐操作需要对应账户的 active 权限才能执行。为了解决权限滥用问题,FIBOS 定义了一个特殊权限 eosio.code。我们需要在平台合约账户中配置权限,在 active 权限下添加该合约账户的 eosio.code 授权。具体的配置操作会在下面说明。
& q# K) I. R  e" B! v4 z; f( e" m8 p( [7 ^5 Y( q
在 FIBOS TestNet 上注册账号3 z: k3 l' P0 S( q
/ a' B  L) Z3 }5 p5 W
为方便测试,我们在测试网 http://testnet.fibos.fo 上注册三个账户。% O- ~) h0 c/ @  l* G2 f

: b! C! X& d4 R  f用户账号 helloworld11
) i( G+ x' e# t/ ]1 v8 [! k6 l8 F8 S4 v5 V2 P4 T
内容提供者账号 helloworld22
+ _1 X3 f2 P) A; j
2 \# ^% o  q4 ]$ o9 ?( R平台合约账号 helloworld33
' y! U- Z% N& X% L
. N5 W9 ?% b) T+ Y4 T我们需要记录这三个账号的账户名以及公私钥。以便下面的开发使用。创建一个统一的配置文件来记录这些数据:6 E/ M3 U4 o& g7 p* q8 O, X4 D
  ]  \2 t7 P* r6 P
const config = {
3 Y! |' C6 L/ a+ v: v2 T; j
7 C2 A/ p& J; l( ]; s& `% c( _' v    // 平台合约账户的客户端配置* f- I7 `: q* T
2 K( k3 y5 H2 Q3 b
    client: {8 R# D4 [6 S: c( C

: \9 P& R; Z7 H3 P. B        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
( v1 k7 e& k$ |+ X3 e- ^4 q4 j. J2 q  z
        httpEndpoint: 'http://testnet.fibos.fo',% A" `+ U3 K! h/ l: U' u, f, A( W
8 z! T8 i" H2 u' F+ S: w
        keyProvider: 'PRIVATE_KEY_OF_helloworld33'5 Z9 g! L# }2 I/ b4 k
* E; K) u& }6 K* P; t0 [! U& L/ v& m
    },
8 i& w% l$ L' m+ m  B
4 D7 M9 a. g' v    // 用户账户的客户端配置
4 H) H/ X6 m; ], _& H+ S( o9 L2 J; ?; {2 i2 }
    callClient:{! A2 a# T5 p/ S- p0 l
0 Y& V0 T5 m& Q% T* `7 s
        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
; W& [0 L# a1 G0 \. R$ H: C: S
$ P  w7 j  q/ T. \6 @4 B5 S        httpEndpoint: 'http://testnet.fibos.fo',) B1 p( k2 q# Y1 |3 x

% Y9 l) H3 i+ D+ O7 X        keyProvider: 'PRIVATE_KEY_OF_helloworld11'% h" F0 t* u' r6 e7 {" ~

' k4 t( |- T$ b. Q/ W/ J" t- l2 X    },0 F4 g" \( r. R+ F0 Z/ b# s

  L5 `$ @5 I# k5 [3 Q5 ]' v5 s    // 平台合约账户信息
; F+ T& R$ \* [3 [; r; Q4 @
+ t/ z# i! Z$ b4 @. S' q/ |- l' S    contractAccount: {
9 @7 b3 {( f4 u% E8 ], i4 g: b+ v+ c/ m" p
        name: 'helloworld33',8 V# j& h. F5 m. @! Y

% `2 e3 q/ k, ~- H* L% v8 M, ^; h        publicKey: 'PUBLIC_KEY_OF_helloworld33',0 V# g3 l' {5 b1 ^1 K* y# ^3 X

" @& T# p. f4 V) _  Y5 N7 m1 d        privateKey: 'PRIVATE_KEY_OF_helloworld33'" h4 C& J9 T" L! H1 x5 |

4 L% @' U7 U; _# O  t! s    },
; s! [& @1 E" [; U; O, j; l( y" Q+ R$ S3 q. [8 c4 H
    // 用户账户信息0 z. J' v, f/ C) N$ G
: A0 r5 ~' F, M6 `' W
    account1: {
# G2 ~) P+ i* N
/ {4 _! [5 u5 V        name: 'helloworld11',
3 m6 ]6 k$ d' e* e& o- z! B- l  ^( v% D- L& C% X# z" X
        publicKey: 'PUBLIC_KEY_OF_helloworld11',+ p/ U5 ]( G" ^

' v+ u0 ]0 l! X4 `1 x        privateKey: 'PRIVATE_KEY_OF_helloworld11'! B6 X. L8 M" Q0 F

. i# f; s' E$ b- g    },
/ V; ]& A7 Z5 [' V" @) x' x# i$ H) h; Q' M& l1 I6 l* g
    // 内容提供者账户信息6 k6 F  _7 d- Z9 X$ _! |
" F1 \/ M8 J/ \
    account2: {
9 }& i5 \  [, h/ P7 ?
- c: i; E% \& \/ g6 ~        name: 'helloworld22',. r% F/ |, h5 O* u# J: V

6 m8 U2 e! e2 e% t        publicKey: 'PUBLIC_KEY_OF_helloworld22',) T" h8 f: [2 O+ C/ o

7 v$ O3 v2 u' c# {! ?" u. R        privateKey: 'PRIVATE_KEY_OF_helloworld22'# k1 w- }7 m3 A, t3 ]2 i
8 S: a+ p; W, U$ H7 |. T% W
    }
, P- G- [4 t  T4 A- p6 j$ {) J
- d1 v* D+ w4 l' i: X}
0 N  ?  c  Z; h7 \5 ]6 u- @& e1 Y( ?6 o$ m& N' c. |) l; ~. s0 B
module.exports = config; ^6 K7 }2 L: Z8 z$ {; m

8 }' H: d4 ?7 |. B- l4 g4 o' b1 r$ m配置权限
9 m  s( C7 O: ?0 V" E7 h- L: d6 g  }7 c7 j. N8 z6 L
在合约代码中,我们调用了 trans.send_inline 函数调用合约 eosio.token 来实现转帐操作,但是转帐操作是需要账户的 active 权限。所以我们需要更新一下合约账户的权限,需要添加调用者的 eosio.code 授权到它的 active 权限。这个调用者自然也是这个合约账户。: G% Q1 \2 s+ V9 O

' }: \8 g, ?! w3 k- D+ i  Econst FIBOS = require('fibos.js');
! `6 w" [" f+ V. ~0 z' ^# P- c
8 x9 G( k" J$ E8 x) uconst config = require('./config');$ b* B, @7 b! ]2 Z8 p
, Y* _8 o+ o! F$ y6 K. u
const fibosClient = FIBOS(config.client);5 a5 e3 ]! p- y+ D) h; U) U

- W6 Y( z& m' r, u1 }let ctx = fibosClient.contractSync('eosio');
4 q7 y0 c# \1 ?- u1 a. |0 f* K5 s/ k! Q$ C( u2 L
var r = ctx.updateauthSync({
& X+ N+ h+ F) A6 r( L9 H% f+ y7 k! ]
+ o9 y) \6 s- O/ ]  account: config.contractAccount.name,! `* @" Y/ \+ {3 i; N- b9 ^, y
! y: z# B4 b! |0 Y  [2 |
  permission: 'active',
1 {# f1 E! P  C7 h
: A, i0 p/ q: B( n) _& T! v, j7 A  parent: 'owner',
+ S9 \0 B4 u) I* E5 h% n2 d/ l! Z# p, y
  auth: {
5 Y+ k, Q, c' t0 `* R0 r) }' d* ^2 B5 [: d& d0 Y" x  Y, w
    threshold: 1,
: ]/ F' s- ~" H' L* q: [- q; b% S  v( M" e2 U& q* L% C# d  }& Q! k
    keys: [{
7 p' ^$ L" u* I1 G9 M" C/ u0 P! c
      key: config.contractAccount.publicKey,5 J" A( x( B. S/ U6 T6 z2 N- R: t

7 [( j0 q# T0 f" I' {6 C& u      weight: 18 I% y" y1 B6 [2 D4 @6 @* H, M

! a/ X- V. r( s    }],% Q4 n# ~/ o+ W3 P' _  X- S  `
* `1 c4 g- |3 y" o1 Y
    accounts: [{
0 ]; l# ?! y' [" U! f: ^9 t  J7 Y: Z7 Y
        permission: {
1 s, U2 G7 m5 Y' \3 t/ e  u! f, ~5 [+ Q) |
            // 将调用者账号的 eosio.code 授权添加到它的 active 权限下。
5 k" v2 v7 x" C8 M0 o
, X$ Q2 }+ s, A; n! N. h! t1 Y4 O8 S            actor: config.contractAccount.name,$ A. n  f8 }* {5 _6 b0 ?8 x
, ]% a( @5 @. m# ~" g. n
            permission: 'eosio.code'
# f! l; r# Q. B- A5 ]! i. `( F/ I, k
; D- s& j8 d$ z2 N4 r, h/ ]6 m$ S        },
& w4 X" Z  z9 e8 R% J
# \( O# V2 M5 F7 {, h        weight: 1
3 u5 _: z. J, E! w
* N8 i1 t) u6 Y4 |    }]( p2 o3 N% A& o& C1 o, U
" E2 U5 d5 e  X" P4 _7 z  ^
  }0 K+ F. }0 j. v  c. n- e% f

; k7 Y- K0 Q% E; j% L# A2 ?},{  R8 {( e0 i1 b0 T

  M- `: o; D" P1 R8 |    authorization: `${config.contractAccount.name}@owner` //更改账户权限需要使用 owner 权限
. c% F- E, m) |* \/ f3 Y0 E+ w/ {& ~
});
* f9 w: M2 _' V4 `. f5 r+ m4 H( U- e! M
console.log(r);0 y! `% r' }5 d* K) B; a3 _% `
( C9 M! R: ^0 V$ I( m) X
部署合约; E2 c% Q9 g$ X$ w
4 b4 v% M( i) Z5 Q7 c6 ~
const FIBOS = require('fibos.js');, x4 ~9 f7 O  M, \

! F) o& z1 h) Econst config = require('./config');/ q( d9 H' X4 A. n$ Z
; u% ~# D$ D5 Z: H$ v
const fibosClient = FIBOS(config.client);5 R  i9 J: F2 o3 _% y9 @$ p6 ^/ e

. R5 B" C1 {: B* W; r" Lconst fs = require('fs');/ d8 f2 T& U/ s& d. Y7 v( T  O

1 U1 Z7 g# ~. D// setcode+ Y- D7 y4 ~( Z1 A; w
& C# @: p) ]6 P/ L$ ]
const jsCode = fs.readTextFile(`${__dirname}/contracts/subaccount.js`);
+ v  n3 O6 `9 D$ ~; W2 o" x8 j8 B/ i( {
fibosClient.setcodeSync(config.contractAccount.name, 0, 0, fibosClient.compileCode(jsCode));
# s* O5 e( V' L) r3 g; D" p* K9 D, t4 L& _- [( X3 g7 E
// getcode; z$ D9 s' ^" H; Y9 \8 _. F% r

7 i/ ~) t5 W: ]const code = fibosClient.getCodeSync(config.contractAccount.name, true);
6 q; y! Y# {/ d. L- T7 V; e( v* B% x9 H/ L' a1 }
console.log('code:', code);6 f; B" n: x: q3 M# Y. f

, Z. L$ l6 `3 n% c5 s2 k% o2 B2 W// setabi
0 x% a; \0 d$ ~0 s( c9 w( I: W3 Z
+ Y5 Z" ^9 H- }0 E1 q4 Dconst abi = JSON.parse(fs.readTextFile(`${__dirname}/contracts/subaccount.abi`));- J2 b$ N# _1 [

' X+ z8 Z& n% q3 l0 [( v2 f& ?/ `fibosClient.setabiSync(config.contractAccount.name, abi);( U9 t: y& q9 K& Y. c
  }5 `# z% z) }1 S2 Y
转账测试" ]" o/ N& Q5 h$ z' v3 w: m! M
- M; S! n+ {+ P: c
我们先来写一个脚本 account.js 来查看三个账户的余额。: @, a; b& k* l* T5 w7 `. ^
/ s" N3 N! ]/ i/ g! D
const FIBOS = require('fibos.js');
' m4 F: c4 |' Y
8 V+ d+ y1 Z7 u3 N9 Q, Vconst config = require('./config');4 t0 V7 b' e( O, e! i8 h8 q0 [
9 q3 ?7 a1 b- B+ j
const fibosClient = FIBOS(config.callClient);
) F! @, |" V1 y9 k
0 X* o: o/ Q1 w, W/ bconst account1 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account1.name, 'accounts');8 n" ~9 N: y' h  W! m( I, S

+ W& {2 ^# s; {' e# Q1 Aconsole.log(config.account1.name);
! ?6 x  f+ ~/ k1 A' a+ E. x
1 F2 p! i- J5 k& @; |$ hconsole.log(account1);
" M, }1 i' N' J$ |0 z
% j6 Z5 F! F; w% econst account2 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account2.name, 'accounts');
* M' ]& c8 _- |# t$ D' ?# Z/ p# ]1 H/ [2 C) W0 H
console.log(config.account2.name);# k% e  b5 _. l* o* m+ s

; G5 k2 M& z( b0 y, _) M8 K+ Wconsole.log(account2);
9 M$ H# ]! K( Y# ~
( s2 D$ x1 ^3 wconst contractAccount = fibosClient.getTableRowsSync(true, 'eosio.token', config.contractAccount.name, 'accounts');
- |! n+ ]$ }6 V8 X" e; _
+ e% i9 r: L2 i; q" s3 ?console.log(config.contractAccount.name);; J2 r4 x3 o) d" Y
, B/ z: @0 F$ N7 r, W9 [: s( s
console.log(contractAccount);
6 a6 S* f" U$ I6 c6 d& c
/ W1 j+ r4 f, `5 P8 |) G! \执行 fibos account.js 来查看三个账户信息。 目前我们的账户还没有 FO,所以大致情况是这样的:
6 ?1 X, O( O  L' c# X4 o" ~; s% a1 k0 z! m. B; j$ d
用户账户:helloworld11 金额:0.0000 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO
3 A2 y: c: b( q% W" T) K# D, @1 n7 ~2 f* I6 I2 k) y

( w+ I& T" D9 b- j% @  M2 p  |
% p) q, @" U4 {. ]测试网会自动给每个账户发放10 EOS 的通证用以测试使用。账户中还并没有 FO 通证。所以我们再来写一个兑换脚本,用1 EOS 换一点 FO 通证。+ [# M( \/ P- b0 s3 ^; h8 @6 {* i/ [

  G$ z  G, s8 @0 L4 m4 Q: l% y4 tconst FIBOS = require('fibos.js');7 m2 B& b! a" o% v/ X: v

) j( Z" }1 X9 q) f/ ]: e" Hconst config = require('./config');
2 G* D* q; S# s% ^5 c+ r/ B8 _) t! `5 ?+ p# ~+ _* Y3 u( B7 ?. \9 A
const fibosClient = FIBOS(config.callClient);5 z/ |1 P* j/ ?. o  k3 O) r% ]

( X+ Z# u! w% {/ D: p( u2 D$ C  Ulet ctx = fibosClient.contractSync('eosio.token');
) P( Q9 R9 k" `) g, Y6 O
+ Y/ i+ h" ?- z3 \3 g. K! r1 iconst r = ctx.exchangeSync(  E+ h! |/ f" u+ J  g
6 z) F9 x. s3 \; B" L
    config.account1.name,
/ r7 y% E9 S& U4 K( r4 h6 T7 l! V
    '1.0000 EOS@eosio',
) J7 N7 I: z$ J" t( d0 h3 {5 W2 R# z! u& W* ?# ~
    '0.0000 FO@eosio',% F; h- l( h: Q! G
5 k6 k# [6 S: f
    'exchange FO to EOS',
5 @6 ^3 W  g3 R5 }6 k) V  L4 u% A& G) L5 Q
    {
% I9 p9 D# U9 O3 |9 N+ A: x2 s; o/ p# N) _+ g% y, L4 b& n
        authorization: config.account1.name5 b$ f$ [7 F6 u
( q1 v+ O( d: K" l
    }
, i5 w, |$ ~! M3 Q
- q& D  |7 a2 `: z7 {0 ^# ^5 Q);% w+ d" j% q3 F. t* M
1 }4 f7 n! j" j4 z* |7 f
console.log(r)7 k0 O$ J- Y. O' u1 X. X

% T' t  D7 A5 n' i# @再次执行 fibos account.js 来查看账户信息。目前我们的账户金额大致是这样的:
: Z, U, b' b9 ?3 C5 j8 ?0 v0 [
+ M% T# r7 E$ B, r+ `' T0 r用户账户:helloworld11 金额:146.4245 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO) P+ m+ S' g; S: k6 K

+ [( K/ J% M, }9 W# Z下面写个脚本 transfer.js 来执行转帐操作。
: O6 [3 r6 _/ ~+ p( K8 n. B1 L! I5 w6 F$ a& h2 Z; X# y6 U
const FIBOS = require('fibos.js');
# \, H4 g7 p8 U1 o2 L' r: x/ f8 g$ k8 m3 d  m/ Y, Y
const config = require('./config');! g: l& Y& N2 t% K0 Z

. r9 @# m7 F3 \2 Dconst fibosClient = FIBOS(config.callClient);5 Q! H4 d: N9 ~( J* S8 H9 c8 v2 e
+ W# ?' |( Z$ h# d, h6 o: W/ C
let ctx = fibosClient.contractSync('eosio.token');, _7 _1 I( }6 P1 Y+ b( P! Q
; W3 M9 g/ L6 a
const r = ctx.extransferSync(! F, H3 i+ n9 Q7 h

6 Z  u# E1 f( F    config.account1.name, // 用户账户  V0 Y: Q- y5 \0 j8 w, d- ]
/ W$ B. A2 B/ @( s' Q) Z
    config.contractAccount.name, // 平台合约账户
  y& v* R- }9 X
9 f) a; \3 q: Z/ s- R4 N6 m! F    '10.0000 FO@eosio', // 转帐金额0 s% I) d1 m2 T

4 z) Q' U9 `: n+ \+ v" \0 |, \    config.account2.name, // 附言填写内容提供者的账户名,平台合约会给它分账
+ e% C, ~3 A; [. g, N& d" s8 {, R( R4 j: |# W! P! `9 G
    {  f+ B4 W! H0 R/ R) l8 v
& \5 }7 d& Q9 X( T' Y
        authorization: config.account1.name //提供用户账户的授权8 C! v9 e" n1 T) d
9 L) Y6 i$ F- _' ^  t2 @
    }
' p6 ]' r% K/ X) D7 r' E  S  B6 g0 l1 M% n! `0 s
)
& b- W8 d2 C3 }' S8 }" {+ f* A
& c; m9 z* q' |/ v2 L9 `' @console.log(r)
* k9 @" q- |& c1 O8 x6 e" P9 F0 D% Z( E: t& j
我们要从用户账户 account1 给平台合约账户 account3 转帐 10 FO。memo 参数为要分成的内容提供者账户 account2。根据合约中定的2/8分成,平台合约账户 account3 将会分得2 FO,而内容提供者账户 account2 将会获得8 FO。9 B& G4 A; |6 x
5 l) j/ O& ~' r7 @8 Y# v7 j
使用命令 fibos transfer.js 执行该脚本完成转帐操作。3 z9 f9 {# k' Y& Y( y1 L4 Y- i5 i

: W/ U, m. b, \: V# d+ y3 R下面我们再来看一下目前三个账户情况。执行命令 fibos account.js。三个账户金额大致如下。
1 \5 a1 ]& L7 L# `0 d
6 d* Q, [) T, y2 q用户账户:helloworld11 金额:136.4245 FO内容提供者账户:helloworld22 金额:8.0000 FO平台合约账户:helloworld33 金额:2.0000 FO
; u1 `& d- @7 d) W" b! b' r! U+ E" I8 M- U( m8 B
结果显示,分账账户和平台合约账户如预期那样获得8 FO 和2 FO。8 v, |" a: ~0 ?& T) y. |
" x! H' X# s: z5 H2 }) @, e) o
' S3 f9 T4 `, s

1 G+ O8 |+ O) f0 _2 P2 F综上,我们成功使用了智能合约实现了自动分账。平台方还可以继续根据自己业务需要定制自己的合约。
9 ^+ X, _5 E. y" \2 e( B
4 X6 i0 M  d# D5 i" S文中的代码请参考:https://github.com/fengluo/fibos-subaccount
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

哈哈笑417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11