内容简介:自动分账是很多平台都会用到的支付功能。很多互联网内容售卖平台都会跟内容提供者分账。比如:Apple 的 App Store 跟 App 开发者三七分成。很多平台都使用了支付宝、微信支付作为支付手段,但是要同时实现给内容提供者分账,却是一件不太容易的事。使用 FIBOS 智能合约可以很容易实现这个需求。文中代码已在 GitHub 上开源。在 FIBOS 转账是通过 token 合约的
自动分账是很多平台都会用到的支付功能。很多互联网内容售卖平台都会跟内容提供者分账。比如:Apple 的 App Store 跟 App 开发者三七分成。很多平台都使用了支付宝、微信支付作为支付手段,但是要同时实现给内容提供者分账,却是一件不太容易的事。使用 FIBOS 智能合约可以很容易实现这个需求。
文中代码已在 GitHub 上开源。 https://github.com/fengluo/fi...
设计思路
在 FIBOS 转账是通过 token 合约的 extransfer
方法来实现的。 extransfer
方法在执行的时候会给转账方账户和入账方账户发送通知。所以用户给平台方账户转账的时候,平台账户就会收到通知。所以整体业务逻辑如下:
quantity: 10 FO
memo: 内容提供者账户 quantity: 8 FO
用户账户 -------------------> 平台账户 ----------------> 内容提供者账户
extransfer 2/8 分成 extransfer
memo extransfer
整体逻辑很简单,整个合约代码逻辑差不多用20行就可以写完。
编写合约
FIBOS 的智能合约分为 ABI 文件和 JS 合约两部分。ABI 相当于合约接口,JS 合约则是功能实现。本案例目前没有接口设计需求,不过 ABI 文件还是合约不可缺少的部分。所以我们简单创建一下就好。
我们先创建一个 contracts
文件夹,合约文件都会放在这里。然后在此文件夹下,创建 subaccount.abi
文件,内容为:
{
"version": "eosio::abi/1.0"
}
JS 合约部分也没有太复杂。在 contracts
文件夹下创建 subaccount.js
文件,代码为:
exports.on_extransfer = (from, to, quantity, memo) => {
// 需要在开头做一些判断
if (to === action.receiver && action.is_account(memo)) {
const num = parseInt(quantity.quantity.split(' ')[0])
// 假设我们约定平台方跟内容提供者是2/8分成。
const subnum = (num * 0.8).toFixed(4);
trans.send_inline('eosio.token', 'extransfer', {
from: to,
to: memo,
quantity: {
quantity: `${subnum} ${quantity.quantity.split(' ')[1]}`,
contract: quantity.contract
},
memo: 'sub account'
},
[
{
// 需要提供合约账户的 active 权限
actor: action.receiver,
permission: 'active'
}
]);
}
}
合约代码开头我们需要做一些验证。
memo
合约代码中我们使用 send_inline
调用 eosio.token
合约来执行转帐操作。转帐操作需要对应账户的 active
权限才能执行。为了解决权限滥用问题,FIBOS 定义了一个特殊权限 eosio.code
。我们需要在平台合约账户中配置权限,在 active
权限下添加该合约账户的 eosio.code
授权。具体的配置操作会在下面说明。
在 FIBOS TestNet 上注册账号
为方便测试,我们在测试网 http://testnet.fibos.fo 上注册三个账户。
helloworld11 helloworld22 helloworld33
我们需要记录这三个账号的账户名以及公私钥。以便下面的开发使用。创建一个统一的配置文件来记录这些数据:
const config = {
// 平台合约账户的客户端配置
client: {
chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
httpEndpoint: 'http://testnet.fibos.fo',
keyProvider: 'PRIVATE_KEY_OF_helloworld33'
},
// 用户账户的客户端配置
callClient:{
chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
httpEndpoint: 'http://testnet.fibos.fo',
keyProvider: 'PRIVATE_KEY_OF_helloworld11'
},
// 平台合约账户信息
contractAccount: {
name: 'helloworld33',
publicKey: 'PUBLIC_KEY_OF_helloworld33',
privateKey: 'PRIVATE_KEY_OF_helloworld33'
},
// 用户账户信息
account1: {
name: 'helloworld11',
publicKey: 'PUBLIC_KEY_OF_helloworld11',
privateKey: 'PRIVATE_KEY_OF_helloworld11'
},
// 内容提供者账户信息
account2: {
name: 'helloworld22',
publicKey: 'PUBLIC_KEY_OF_helloworld22',
privateKey: 'PRIVATE_KEY_OF_helloworld22'
}
}
module.exports = config
配置权限
在合约代码中,我们调用了 trans.send_inline
函数调用合约 eosio.token
来实现转帐操作,但是转帐操作是需要账户的 active
权限。所以我们需要更新一下合约账户的权限,需要添加调用者的 eosio.code
授权到它的 active
权限。这个调用者自然也是这个合约账户。
const FIBOS = require('fibos.js');
const config = require('./config');
const fibosClient = FIBOS(config.client);
let ctx = fibosClient.contractSync('eosio');
var r = ctx.updateauthSync({
account: config.contractAccount.name,
permission: 'active',
parent: 'owner',
auth: {
threshold: 1,
keys: [{
key: config.contractAccount.publicKey,
weight: 1
}],
accounts: [{
permission: {
// 将调用者账号的 eosio.code 授权添加到它的 active 权限下。
actor: config.contractAccount.name,
permission: 'eosio.code'
},
weight: 1
}]
}
},{
authorization: `${config.contractAccount.name}@owner` //更改账户权限需要使用 owner 权限
});
console.log(r);
部署合约
const FIBOS = require('fibos.js');
const config = require('./config');
const fibosClient = FIBOS(config.client);
const fs = require('fs');
// setcode
const jsCode = fs.readTextFile(`${__dirname}/contracts/subaccount.js`);
fibosClient.setcodeSync(config.contractAccount.name, 0, 0, fibosClient.compileCode(jsCode));
// getcode
const code = fibosClient.getCodeSync(config.contractAccount.name, true);
console.log('code:', code);
// setabi
const abi = JSON.parse(fs.readTextFile(`${__dirname}/contracts/subaccount.abi`));
fibosClient.setabiSync(config.contractAccount.name, abi);
转账测试
我们先来写一个脚本 account.js
来查看三个账户的余额。
const FIBOS = require('fibos.js');
const config = require('./config');
const fibosClient = FIBOS(config.callClient);
const account1 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account1.name, 'accounts');
console.log(config.account1.name);
console.log(account1);
const account2 = fibosClient.getTableRowsSync(true, 'eosio.token', config.account2.name, 'accounts');
console.log(config.account2.name);
console.log(account2);
const contractAccount = fibosClient.getTableRowsSync(true, 'eosio.token', config.contractAccount.name, 'accounts');
console.log(config.contractAccount.name);
console.log(contractAccount);
执行 fibos account.js
来查看三个账户信息。 目前我们的账户还没有 FO,所以大致情况是这样的:
-
用户账户:
helloworld11金额:0.0000 FO -
内容提供者账户:
helloworld22金额:0.0000 FO -
平台合约账户:
helloworld33金额:0.0000 FO
测试网会自动给每个账户发放10 EOS 的通证用以测试使用。账户中还并没有 FO 通证。所以我们再来写一个兑换脚本,用1 EOS 换一点 FO 通证。
const FIBOS = require('fibos.js');
const config = require('./config');
const fibosClient = FIBOS(config.callClient);
let ctx = fibosClient.contractSync('eosio.token');
const r = ctx.exchangeSync(
config.account1.name,
'1.0000 EOS@eosio',
'0.0000 FO@eosio',
'exchange FO to EOS',
{
authorization: config.account1.name
}
);
console.log(r)
再次执行 fibos account.js
来查看账户信息。目前我们的账户金额大致是这样的:
-
用户账户:
helloworld11金额:146.4245 FO -
内容提供者账户:
helloworld22金额:0.0000 FO -
平台合约账户:
helloworld33金额:0.0000 FO
下面写个脚本 transfer.js
来执行转帐操作。
const FIBOS = require('fibos.js');
const config = require('./config');
const fibosClient = FIBOS(config.callClient);
let ctx = fibosClient.contractSync('eosio.token');
const r = ctx.extransferSync(
config.account1.name, // 用户账户
config.contractAccount.name, // 平台合约账户
'10.0000 FO@eosio', // 转帐金额
config.account2.name, // 附言填写内容提供者的账户名,平台合约会给它分账
{
authorization: config.account1.name //提供用户账户的授权
}
)
console.log(r)
我们要从用户账户 account1
给平台合约账户 account3
转帐 10 FO。 memo
参数为要分成的内容提供者账户 account2
。根据合约中定的2/8分成,平台合约账户 account3
将会分得2 FO,而内容提供者账户 account2
将会获得8 FO。
使用命令 fibos transfer.js
执行该脚本完成转帐操作。
下面我们再来看一下目前三个账户情况。执行命令 fibos account.js
。三个账户金额大致如下。
-
用户账户:
helloworld11金额:136.4245 FO -
内容提供者账户:
helloworld22金额:8.0000 FO -
平台合约账户:
helloworld33金额:2.0000 FO
结果显示,分账账户和平台合约账户如预期那样获得 8 FO 和 2 FO 。
综上,我们成功使用了智能合约实现了自动分账。平台方还可以继续根据自己业务需要定制自己的合约。
文中的代码请参考: https://github.com/fengluo/fi...
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Head First JavaScript Programming
Eric T. Freeman、Elisabeth Robson / O'Reilly Media / 2014-4-10 / USD 49.99
This brain-friendly guide teaches you everything from JavaScript language fundamentals to advanced topics, including objects, functions, and the browser’s document object model. You won’t just be read......一起来看看 《Head First JavaScript Programming》 这本书的介绍吧!