摘要:編寫合約的智能合約分為文件和合約兩部分。相當于合約接口,合約則是功能實現。用戶賬戶金額內容提供者賬戶金額平臺合約賬戶金額結果顯示,分賬賬戶和平臺合約賬戶如預期那樣獲得和。綜上,我們成功使用了智能合約實現了自動分賬。
自動分賬是很多平臺都會用到的支付功能。很多互聯網內容售賣平臺都會跟內容提供者分賬。比如: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" } ]); } }
合約代碼開頭我們需要做一些驗證。
收款方的賬戶為合約賬戶,否則因為下面代碼執行給內容提供者轉賬時,因為轉帳方也是合約賬號會再次收到通知,造成無限遞歸,超出最大 send_inline 層數而報錯。
我們用 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...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108984.html
摘要:編寫合約的智能合約分為文件和合約兩部分。相當于合約接口,合約則是功能實現。用戶賬戶金額內容提供者賬戶金額平臺合約賬戶金額結果顯示,分賬賬戶和平臺合約賬戶如預期那樣獲得和。綜上,我們成功使用了智能合約實現了自動分賬。 自動分賬是很多平臺都會用到的支付功能。很多互聯網內容售賣平臺都會跟內容提供者分賬。比如:Apple 的 App Store 跟 App 開發者三七分成。很多平臺都使用了支付...
摘要:在協議結束時,智能合約被視為已履行并仍存儲在區塊鏈網絡中。這組條件和事件代表了最基本的一次性智能合約。智能合約用例智能合約越來越受歡迎,并已在各種區塊鏈項目中實施。 與區塊鏈技術一樣,智能合約在商業領域也非常有價值。 為了讓我們的讀者徹底了解智能合約是什么以及它們如何影響現代商業的交易方式,我們準備了本指南。 集中商業模式正在給去中心化的模式讓路 傳統的商業關系模型都是集中式的,始終存...
閱讀 1970·2021-11-23 10:03
閱讀 4129·2021-11-22 09:34
閱讀 2466·2021-10-08 10:05
閱讀 2245·2019-08-30 15:53
閱讀 1685·2019-08-30 13:56
閱讀 1149·2019-08-29 16:52
閱讀 1102·2019-08-26 13:31
閱讀 3345·2019-08-26 11:45