Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

哈哈笑417
307 0 0
自动分账是很多平台都会用到的支付功能。很多互联网内容售卖平台都会跟内容提供者分账。比如:Apple 的 App Store 跟 App 开发者三七分成。很多平台都使用了支付宝、微信支付作为支付手段,但是要同时实现给内容提供者分账,却是一件不太容易的事。使用 FIBOS 智能合约可以很容易实现这个需求。
4 A; s9 i  A! f, ]: y* `. ]5 J+ m& F3 h% ?) V- v
文中代码已在 GitHub 上开源。https://github.com/fengluo/fibos-subaccount
% X& z; b3 \$ q; b. X( I2 f1 P3 ~4 ~9 S# N
设计思路
! }! C- Q* ^9 z+ ^" N, i4 b. R
$ d# b! o. e. }4 J4 }" I在 FIBOS 转账是通过 token 合约的extransfer方法来实现的。extransfer方法在执行的时候会给转账方账户和入账方账户发送通知。所以用户给平台方账户转账的时候,平台账户就会收到通知。所以整体业务逻辑如下:
8 m2 x# E& [/ d" N$ h, i( l) S6 q! q% r
        quantity: 10 FO1 L: o+ d+ e. H" s1 T: \7 ~: R) v
- N; B- j) k3 Y4 f1 M6 G
        memo: 内容提供者账户           quantity: 8 FO+ T2 L1 ~. T/ c5 A+ |

7 k+ i; Z, _7 l$ Y1 I/ b: k* ~用户账户 -------------------> 平台账户 ----------------> 内容提供者账户
" C! K3 w2 x" |) n- B  u! Q
% t: b2 z7 f; `: `            extransfer      2/8 分成   extransfer
$ w9 P  T8 {( [7 `) ^
* i0 Q3 q, I( G4 L1.用户给平台方账户转账,memo 中填写内容提供者的账户名。
4 |: U$ I5 r1 X* T: O* r/ A4 f
: b% X. `5 L3 u4 ~* H2.平台方的账户合约监听 extransfer 方法的通知,然后做出分账计算,给对应内容提供者的账户转账对应金额。5 x4 ?3 y4 ?) t' M8 C

0 d7 M+ ~( G9 w整体逻辑很简单,整个合约代码逻辑差不多用20行就可以写完。
* @8 b4 ?3 n8 q, z/ N* R! [8 ?: w3 U% n; R: Q% u4 `( v
编写合约; D5 f0 ~( ^8 d6 W$ [) B  F9 @7 l$ D
: ?2 Z( |+ {1 K
FIBOS 的智能合约分为 ABI 文件和 JS 合约两部分。ABI 相当于合约接口,JS 合约则是功能实现。本案例目前没有接口设计需求,不过 ABI 文件还是合约不可缺少的部分。所以我们简单创建一下就好。4 r+ e* `6 |# b

9 |& ?+ F( F- K& X1 C) j我们先创建一个 contracts 文件夹,合约文件都会放在这里。然后在此文件夹下,创建 subaccount.abi 文件,内容为:6 b! y$ F2 K1 a- v: J9 ^9 A
0 w2 B* H, K7 U# h6 h
{
! ]/ }0 F9 s# q& o
3 s6 \) u6 V: X$ e4 h( T/ j, {    "version": "eosio::abi/1.0") ~. J$ J& D! p' I4 C! T& h; k
$ D# F2 Z9 t5 E6 i  c7 y/ T
}8 l) G' F3 o" y9 B
1 T7 ~# E2 Y2 {; r, a5 k- x# i3 f
JS 合约部分也没有太复杂。在 contracts 文件夹下创建 subaccount.js 文件,代码为:! I* l1 W* |% k8 L( l& W4 R

; c- D, p( c8 S% f' o6 E% @exports.on_extransfer = (from, to, quantity, memo) => {8 N& \0 R# P8 E) N% |; v
5 X: {  t3 K: U4 _+ W& X
    // 需要在开头做一些判断
9 |. {2 ?3 L+ B6 G6 {9 M7 z* Y/ x* S: o; W+ z- V
    if (to === action.receiver && action.is_account(memo)) {
, Q( J- e& X# H# L' Y0 v
" @. z5 I( V+ a: l        const num = parseInt(quantity.quantity.split(' ')[0]). }! s; z* A9 h  t2 s( E
0 u8 p; [( \- v" U* j4 y; z
        // 假设我们约定平台方跟内容提供者是2/8分成。7 ^/ R- J; g' o1 q
  W/ t& l  W2 E- c' U
        const subnum = (num * 0.8).toFixed(4);
9 l4 O; I1 s6 l& a. J
5 |! H0 I: C+ o7 Z. w        trans.send_inline('eosio.token', 'extransfer', {' n1 Y7 i& s: X! Q8 f
2 a/ O- s8 p* z. }8 D3 w
            from: to,- X8 V7 ], ?, }) P2 r# ?
1 G+ t5 ~1 o+ P7 O
            to: memo,! Y4 w$ r/ _. n% l& L8 S
5 V# n' h2 l4 e+ E0 F
            quantity: {
$ O* l5 k+ _, p8 t+ t
; r( a# {6 k6 O7 p9 i7 E                quantity: `${subnum} ${quantity.quantity.split(' ')[1]}`,
* b1 n, d" Z* \4 W. C; x
" a5 l, E- n% |' F                contract: quantity.contract
! R/ J; k0 E! I+ J$ u8 q
2 o$ f$ L5 K: v( C7 h9 A/ t4 F! \6 p            },# {9 P/ g8 j5 ?. Z' ]# n% s+ X

/ F# {! A- S2 n            memo: 'sub account'
0 e$ N/ S+ _% ~4 u, `  Y6 S
! w+ ^2 y' D' _# F( |. c- [( w        },
( a$ {, R" A3 a* a9 J$ t* }0 |! Q0 V* x0 K7 E8 D. m
        [0 I+ ?0 {- l7 U& S

+ Z% J' Y8 g+ p/ F* M* |5 [. q            {
. ]7 q" Q7 k6 g: G1 L4 R. E; h* j8 F) A. D  j8 x) w
                // 需要提供合约账户的 active 权限: A7 e, U2 ^8 |; M3 W$ q

( I; J9 ?3 A) j- N                actor: action.receiver,! s) y8 M2 W% ?" }' W, H
' g) g/ b3 [" A. z0 a, Q" C
                permission: 'active') H; v" o' F2 o$ X4 G6 ?- V
1 s1 ~( r0 @( \. y/ P0 P8 a8 k
            }4 G' \8 o2 L& T5 {0 I8 `

% Y. l8 f" r" l/ Y6 G. @. G' n        ]);
/ n9 Y; O( Q4 ~+ g( u
- `- P- \+ u( K    }
3 i/ H; M: B* n7 x5 ~3 ?! p- v& \2 ~9 \5 I2 T# s4 |
}! G6 R& K4 y. Z9 D+ ], k8 `

  R  C$ o  N% f$ X- a; O7 l5 N  T合约代码开头我们需要做一些验证。. T, W; G" Y! k: r! f
: L- a1 Y. f; n. |+ F; R
1.收款方的账户为合约账户,否则因为下面代码执行给内容提供者转账时,因为转帐方也是合约账号会再次收到通知,造成无限递归,超出最大 send_inline 层数而报错。
$ |1 z7 J3 {. |5 o! j% S  f
+ B0 N: d' o. V4 {2.我们用 memo 参数来放内容提供者的账户,所以我们需要对此参数校验一下该账户是否存在防止打错。
7 j' F( \; Q& K- E( k3 s5 |
6 H# M- @. M- X$ u; |0 ]合约代码中我们使用 send_inline 调用 eosio.token 合约来执行转帐操作。转帐操作需要对应账户的 active 权限才能执行。为了解决权限滥用问题,FIBOS 定义了一个特殊权限 eosio.code。我们需要在平台合约账户中配置权限,在 active 权限下添加该合约账户的 eosio.code 授权。具体的配置操作会在下面说明。
# y0 I+ S6 \; j8 S" C  K5 h
" M! a- c0 k$ v9 x; ?( y' l% \在 FIBOS TestNet 上注册账号4 r8 ?& }* x- t) t

9 i2 [8 I: m9 H( A8 j; A$ k为方便测试,我们在测试网 http://testnet.fibos.fo 上注册三个账户。
' N  S& z3 F; l  T0 w" j! u+ Y' |0 s* B0 \6 H9 v0 F/ u
用户账号 helloworld11
/ ^: g$ E' [, |1 Q5 Z0 W5 S/ J* M) o0 u' G
内容提供者账号 helloworld22
% ], I6 x6 }5 Z& h2 a- I
3 f& ?" @9 `6 ~& b$ R平台合约账号 helloworld33) |, d* [8 j5 m3 F

, V2 x( h6 @( n4 x我们需要记录这三个账号的账户名以及公私钥。以便下面的开发使用。创建一个统一的配置文件来记录这些数据:5 _- R7 G1 v0 M# |/ C% d
. j- S/ g$ C8 z+ _5 F1 c
const config = {+ A# K6 b0 R) C' L: O) f! r2 ]

3 T  B6 k, [7 G) c  K3 q5 ^$ s    // 平台合约账户的客户端配置
- Q5 ?; F( i2 u1 N
5 x2 @, y' m; n. N    client: {" d2 o4 P0 ~+ |: ?% H% H
* n" T4 J1 w# C  G% B
        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
1 ]# L. r5 c) f( b* r# ^
7 t! m" E! o/ F% e8 d        httpEndpoint: 'http://testnet.fibos.fo',# D- q- x9 q, H3 U+ H7 X
5 Y$ j& [) \+ @! |( N/ @, l2 b- y
        keyProvider: 'PRIVATE_KEY_OF_helloworld33'% n" U( m& J; s

$ C' q2 L" l8 X5 E    },
. f( b! s2 ?7 ]" n2 a6 v$ @
# E' E2 P1 d+ S) R    // 用户账户的客户端配置
% c. R: ]2 A3 m2 S' g4 r- `  C9 J: P7 p: v1 q
    callClient:{4 O4 c6 y; {+ z& X

8 e* L/ H' ]" t  j4 ?- i        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
; P0 j9 U. b$ u( C+ C2 o# X" k
% ~: _! l. f- {" L        httpEndpoint: 'http://testnet.fibos.fo',
& u) i4 |- y& f- T% Q: n1 S8 c( M- {* l/ L
        keyProvider: 'PRIVATE_KEY_OF_helloworld11'
1 n0 L1 ?# t$ L5 _* }) p
& c3 b5 i& D, p8 m5 d4 J    },
1 a8 {+ i0 @0 m' p6 e* [9 ?3 ^& q' P  D8 c% D( E
    // 平台合约账户信息
' z" \$ Z" D7 p: s( @1 L' N/ m
) {3 |- O6 d* ]$ J. W5 d1 `! B/ Z- m    contractAccount: {
$ a- c2 Z! b1 t$ b  n1 [
0 W3 g9 o+ Y) r6 w6 `$ C        name: 'helloworld33',. i" q* {( z* M9 g# b; F8 t
1 A0 r# q+ o* k& B2 l
        publicKey: 'PUBLIC_KEY_OF_helloworld33',7 C: u( o5 `  N9 y, V* m

4 z. Q4 h! J* Y1 g8 U        privateKey: 'PRIVATE_KEY_OF_helloworld33'
, Q) n, Z. Y9 f: Q% @: ~. B0 h/ T
    },
- z8 x! ^2 x" E  H, I- A
) P2 ]. u" J+ h* U7 @    // 用户账户信息
' Y: H& F: N8 Q7 L. P* G: x$ f9 X
$ E4 ~3 S- q, l+ J5 |' R! j) ]    account1: {" k5 E: V) x# r' T! }( c% z

  \( B: n6 A7 ~/ U8 k- K        name: 'helloworld11',
: M+ u% K$ L3 i7 g$ U7 f) X8 L& ]7 B. B) ?3 S9 s+ e3 v
        publicKey: 'PUBLIC_KEY_OF_helloworld11',
! ~) ]" E" r7 M7 g5 \' }
& I7 s; Q+ E: L' w! w; }, E9 S+ ~/ _" t6 t        privateKey: 'PRIVATE_KEY_OF_helloworld11'
" ~3 o/ K) C* `; H* o, m
, f0 u3 ^& n% _! }/ p3 b& s    },
$ G0 ~# O  U8 K: t* I  \8 A# u+ |
    // 内容提供者账户信息' K7 w. @0 l, F' h/ R* H

5 v+ G1 Z, i0 R* H1 c    account2: {) C' q( V/ f0 ~  R+ x! P& Q

* ^( O: J7 ?' k" w0 w8 c0 y# E1 h        name: 'helloworld22',
  Q. O1 O+ J/ ?! Q" Z
/ R3 O6 T( H8 C; {' \+ ^6 E        publicKey: 'PUBLIC_KEY_OF_helloworld22',
8 j; s1 N' U. J( t
% h  S$ u% g4 L( X2 }0 V        privateKey: 'PRIVATE_KEY_OF_helloworld22'& T( a! J) n9 P0 n/ t. p( f
; H6 b$ E# D! m$ F2 O- ?
    }
# ?& K. ~" Q+ }: c8 U5 Y) b+ \$ r7 l9 f9 r2 O
}- B+ G: ^/ y' d' W. F

/ {, D2 S+ u: H8 ^  ]* r6 p) Tmodule.exports = config
" Y2 c- k; D9 [- ]) w) Z" y
% x4 e  n0 f. }配置权限( k! R- a1 ]3 k+ e

+ x7 a; Z# \  z9 B! y' M在合约代码中,我们调用了 trans.send_inline 函数调用合约 eosio.token 来实现转帐操作,但是转帐操作是需要账户的 active 权限。所以我们需要更新一下合约账户的权限,需要添加调用者的 eosio.code 授权到它的 active 权限。这个调用者自然也是这个合约账户。; O* k0 r' s" l, F# }  ^7 \, t

" V3 `% J) `* w! x9 l7 k8 xconst FIBOS = require('fibos.js');- U& s2 X$ t/ ^8 s
" m8 H5 i$ n% r/ e! B% a
const config = require('./config');
. i/ C. l, ~% j( j( j9 S0 @
# L, Z/ t- {# U3 O1 X& Pconst fibosClient = FIBOS(config.client);
' p& j1 z& L4 N& |, O7 U! R7 b2 o7 P
let ctx = fibosClient.contractSync('eosio');
2 A0 y' O3 E# V  `+ }
2 E! j$ N! U4 ]% g" ?8 P- evar r = ctx.updateauthSync({% l5 d( D  }* G! J% J: V1 m  s0 Y
0 F5 Y( o, _8 ^2 j: E9 y: S
  account: config.contractAccount.name,/ {! Q. u9 l7 |" m

8 s* @4 U$ I; B" W  permission: 'active',
# r2 j. b" O. `, j: ]. m. D3 D: Y% A* q. l5 G! n0 H9 A
  parent: 'owner',
4 m* |. L( {/ H8 D: `+ i/ U9 G( o7 b, t6 t- L
  auth: {
) Z8 b, b& a7 q8 Y; {  Z3 S7 F1 a6 c5 y* x  U
    threshold: 1,1 ?! @4 d+ ]: ]

7 x8 b9 w( t" U7 n    keys: [{) G7 U/ ]" O* Z$ c* E8 [
7 T# l. K! c6 c+ \, n7 g4 J8 ]/ |: Y4 I. Z
      key: config.contractAccount.publicKey,$ T9 j+ A0 R& [$ z; s" [+ ?: a$ g# g
. ]  k$ ?, W, O% E; K
      weight: 1
3 S& P) v) ?( O* ^' m7 i  A& Z6 w. U$ ^" j
    }],0 W6 M1 s6 [" v* e, ~

7 l( s8 L: j3 }+ o    accounts: [{
' s' `: L! p+ B% b( r; m+ |( C/ @/ h1 @8 P$ ~
        permission: {
) o6 d& w6 |2 ?) j* g: w9 Q; V+ h! Y+ U/ B
            // 将调用者账号的 eosio.code 授权添加到它的 active 权限下。. S. }" @" K6 e5 [4 @
" W1 v1 M" U# o. W
            actor: config.contractAccount.name,1 x. e! Y. V. [  J3 ]5 d
+ Y/ ~" N2 F" Z& B
            permission: 'eosio.code'
$ m5 T$ i8 f7 b9 y; Z% B6 f* E
: ~# S2 n: T' T! |        },. z4 C6 a) o- N) D

, t7 `: W7 m/ a; H: m8 l        weight: 1
% t, i& L/ \* x  F1 J$ ~# f* ]. E: x6 w) k1 p! ?
    }]
7 ~0 a' {. s( s8 n2 n" P7 ]9 @, o6 Z8 C3 d
  }5 W3 b* |. m6 R, _1 J% {" D# _

5 I' ]; ?& y0 h. H( D( y% Y3 ~},{' Q- {, C$ S: ?! g# c9 ~
* S/ d2 H0 q  w# [' q& ~
    authorization: `${config.contractAccount.name}@owner` //更改账户权限需要使用 owner 权限
0 X- e  J  O: P' ]  [
$ P7 J( r. K$ p" `1 F; d2 C  x5 P( y});/ t6 {1 [! f, \& _: q

0 D* G% I; w+ Nconsole.log(r);( h5 E, N3 ~. [

4 a9 Z1 f' m' i0 t8 o部署合约: G) ~4 G) V/ M( G6 M/ R

3 M; v  ?  ^- Yconst FIBOS = require('fibos.js');/ i  T6 P( r0 y' x) U: l: W
. Q3 {6 T: q6 p2 r
const config = require('./config');
3 p6 w0 z: L5 X. \1 R( c
2 L+ o' W: _6 J3 I* [- Qconst fibosClient = FIBOS(config.client);
" L6 o! o4 w3 S
' b* [* C; j$ Z. `8 m% r! |  Oconst fs = require('fs');9 @1 I' ]/ P1 K1 A( g+ y! z4 S5 X
3 }% u1 V$ H4 ~5 q3 I
// setcode
  Q/ @$ r8 k  }; j; `, ^5 ~* v! h5 `8 T& n% g
const jsCode = fs.readTextFile(`${__dirname}/contracts/subaccount.js`);
  }9 U, w3 F$ ]- P" k7 z$ W7 |7 [
( u. ^3 Q4 W4 L9 ~/ u' HfibosClient.setcodeSync(config.contractAccount.name, 0, 0, fibosClient.compileCode(jsCode));
9 a0 |( I3 O: L4 c# L
- r0 B4 Y! ~0 |2 x// getcode
* M' s5 x" l8 V# W0 W5 P& p# z
7 u: t4 ?0 K' Y; qconst code = fibosClient.getCodeSync(config.contractAccount.name, true);0 |4 U0 ^3 O* x5 P3 D% j* O

1 ~0 ]5 r; Y/ Z; M* ^- Qconsole.log('code:', code);
* [6 L9 s0 W+ `; P
! r4 |* V! X  D) L5 J! k- h/ E2 v// setabi" g& @2 R# P# i. J8 Q3 J
( H9 g2 Y$ f. p/ l  K  ~
const abi = JSON.parse(fs.readTextFile(`${__dirname}/contracts/subaccount.abi`));
( y5 F  c; A) O4 l: Y4 {) X; M8 r
: W- n/ S" h* _: @! SfibosClient.setabiSync(config.contractAccount.name, abi);& _, t4 K# X. E7 {; {7 Z5 }

8 E; f7 N) o6 `转账测试% g" d1 i+ c+ b; M# a/ F; _! W; ]

9 i9 f& k& s8 J8 s. ]6 _' @我们先来写一个脚本 account.js 来查看三个账户的余额。& H% Q% ~* f, f# G( M
" _1 b5 l) p" D; G! p3 k
const FIBOS = require('fibos.js');
7 C& {1 E. v6 H: c# p  D& ]3 u* z7 ]: |7 y7 `) L* @$ t- V
const config = require('./config');
8 @9 P: I4 v- H' r$ e' S3 r; G' u. v8 j8 n1 m. z! R
const fibosClient = FIBOS(config.callClient);" T: ^9 m+ r$ a* x7 O
; d: K) ^, d, B. Z! P4 U; R" G
const account1 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account1.name, 'accounts');& X  c: n7 a' Z% K) N

+ ~3 Y/ M* w7 \8 q" Nconsole.log(config.account1.name);9 S! ]. O( r3 V  ]; m
5 b" k! Q  I5 D1 n1 N/ i' l
console.log(account1);6 T/ J$ I+ F. S) s. E5 C+ G
0 l5 j" v% F: Q
const account2 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account2.name, 'accounts');- w8 F* p% c+ J* C
& x( n5 M; [1 V; k  `3 t& g" G
console.log(config.account2.name);7 w, z9 W" R; a5 t$ ?* r  ]7 l

* `4 @* b! ]2 E6 \$ ?0 Y, A2 v( x2 Zconsole.log(account2);
1 s/ r/ ?/ J4 N' y+ B. I/ H5 ]1 T) S( \; z1 r
const contractAccount = fibosClient.getTableRowsSync(true, 'eosio.token', config.contractAccount.name, 'accounts');2 v' Z8 e3 V: q. p3 F1 x$ y* N

+ D, ]* T' ~# q* pconsole.log(config.contractAccount.name);
- L. F6 k3 v% z: a# I$ k# x$ @& y$ f% R2 S; Z7 R) e
console.log(contractAccount);0 f# E& `; _8 y4 Z, `/ `
) l* [7 X4 j; u$ I
执行 fibos account.js 来查看三个账户信息。 目前我们的账户还没有 FO,所以大致情况是这样的:
1 b+ g/ [) ~7 u/ t  t; C/ p. V- `% _
用户账户:helloworld11 金额:0.0000 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO
! ~  d2 H2 {3 J" h: M0 `8 I% W- _& y7 |7 d

4 Q9 a7 V8 o3 w. w& s" b+ {1 Z# ^; ^8 c, R. K+ q. L4 o
测试网会自动给每个账户发放10 EOS 的通证用以测试使用。账户中还并没有 FO 通证。所以我们再来写一个兑换脚本,用1 EOS 换一点 FO 通证。
% s+ }. x; B2 q) g, D1 u# I$ R9 ^5 w
5 g) B& k' G) O+ N+ H' j& E$ Yconst FIBOS = require('fibos.js');8 i  p. l- h! \
' w  `1 \( k% H# u2 a! n* m9 E
const config = require('./config');
* o2 }* v6 m! g5 n7 a% P, m0 s9 }. g8 J# l" _+ r
const fibosClient = FIBOS(config.callClient);
4 Y) _( K: B" i2 b" K0 c4 u2 H- y  c
let ctx = fibosClient.contractSync('eosio.token');# x3 _$ @- ?3 |$ I2 g( {1 }' ?5 e
+ j8 x2 L5 [- X& x7 W5 o) c
const r = ctx.exchangeSync(: P2 r, {' A7 j; r+ E, V; K: S

" p2 X+ j$ \( H0 ^$ W    config.account1.name,
  `7 g' ^( @3 W( s+ }+ o
, b' U' K5 v! ], O    '1.0000 EOS@eosio',% ^' t6 O; ~; X4 W- L1 M. n% M: P

% \' O: g6 [. t- m+ z    '0.0000 FO@eosio',
& d7 x, `8 I/ s6 k( |% x& T
5 B3 X$ b8 V7 {! L6 @, ~' R    'exchange FO to EOS',4 s: W& Z' O8 K. k

' c5 R3 y9 ]0 J! j' s9 R    {
, n" ^: B8 D4 Q. F
. s" K& s) Y% _8 M5 m' T        authorization: config.account1.name# G4 }* h! d4 p( o( p- w1 W2 X6 P

  ]& h6 r; F! n' J    }# |5 o9 J* B  y+ X9 d/ r- d- f) }

+ @: X, F3 g! J6 N3 T);7 r- c$ _0 G. i* T

0 Y0 ^; Z3 v$ z& A2 pconsole.log(r)
% c1 P0 }7 U. u+ Q- k" B6 r# j
8 E& F2 E) R4 k2 D/ U再次执行 fibos account.js 来查看账户信息。目前我们的账户金额大致是这样的:
5 F% k2 t1 _5 S  f( j7 n, e# X0 q7 M
用户账户:helloworld11 金额:146.4245 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO! y# `: V+ f: c( u* U
) G9 J* S4 t" c& r
下面写个脚本 transfer.js 来执行转帐操作。
6 Y+ z6 @7 L- K0 O, `5 P
5 Z/ U, F7 y) F6 D" Qconst FIBOS = require('fibos.js');
4 [6 K( q& j# W6 U* n/ `, H* g, }+ D+ s& r& j
const config = require('./config');
9 ?0 G' q& E2 y$ a7 `; j" G) h+ a% o4 g% i9 |2 R
const fibosClient = FIBOS(config.callClient);, t+ H( Y% Y2 y9 o7 Y

& A0 |3 ]0 B. U; J5 u8 plet ctx = fibosClient.contractSync('eosio.token');3 ^3 l2 Q) O' r5 i6 S" C
! K# ~% Y0 Y. y! K
const r = ctx.extransferSync(
+ t/ v4 X& b  G3 [' v9 n+ x0 _* C8 D; b& ~9 |' ]
    config.account1.name, // 用户账户
" f5 h' ?& S0 J
( ]9 V& v9 [* O5 \& q6 ]3 J3 Q# ]    config.contractAccount.name, // 平台合约账户
& g% b- u7 M: D- [. {; Y+ V) k) t
    '10.0000 FO@eosio', // 转帐金额. L3 E: w' O7 P8 ]& z  S3 ~
2 L7 w' ~4 `1 O6 R
    config.account2.name, // 附言填写内容提供者的账户名,平台合约会给它分账
4 E; q- e( n7 E1 e4 z3 W7 @# K8 ?6 d; R) [
    {" B  y7 X' _+ w4 y

# O" a7 b: V) ~( s% k+ }1 Y7 q        authorization: config.account1.name //提供用户账户的授权- N$ ^: l& P+ z' E; }2 q
# ~: h# s$ S9 p) H4 ]6 m% @
    }; }+ H3 U* \6 Z* M7 q. h+ c6 P7 \
; t4 e: f: a+ h: V
)0 B0 X) _7 X/ S

/ Q5 c2 V) h' B+ w6 ?6 Fconsole.log(r)
  y4 m+ O0 Z9 Z* Z( a0 @0 S
! O# d* I* ?# K4 w8 `5 n9 M& t6 G+ e$ C% `我们要从用户账户 account1 给平台合约账户 account3 转帐 10 FO。memo 参数为要分成的内容提供者账户 account2。根据合约中定的2/8分成,平台合约账户 account3 将会分得2 FO,而内容提供者账户 account2 将会获得8 FO。5 Z* _! a- d- {" w. ^$ v( Z& H

. S+ z) g6 w0 V9 k+ z使用命令 fibos transfer.js 执行该脚本完成转帐操作。5 E+ N, s, L+ v) W. W
1 H  t9 a) W- [- S, {1 T
下面我们再来看一下目前三个账户情况。执行命令 fibos account.js。三个账户金额大致如下。
/ z3 @* N& a' w  M# y" u+ t3 `; p% x7 y0 y1 i
用户账户:helloworld11 金额:136.4245 FO内容提供者账户:helloworld22 金额:8.0000 FO平台合约账户:helloworld33 金额:2.0000 FO0 X" U" z& ?, o' R
) K, f) y3 U7 n- }7 |  R
结果显示,分账账户和平台合约账户如预期那样获得8 FO 和2 FO。/ a. p$ {: M( U5 x6 c1 v3 V) M9 {
9 t. V& {# I/ w1 v1 [8 L

  }" Y6 O( l% m8 Y
: J7 N/ V2 j9 n" F* f' |综上,我们成功使用了智能合约实现了自动分账。平台方还可以继续根据自己业务需要定制自己的合约。
: E" m& |: Y6 R9 L0 |0 N
3 J4 `7 u; x# ]& a& k. R" |; J文中的代码请参考:https://github.com/fengluo/fibos-subaccount
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

哈哈笑417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11