摘要:編寫合約的智能合約分為文件和合約兩部分。相當(dāng)于合約接口,合約則是功能實(shí)現(xiàn)。用戶賬戶金額內(nèi)容提供者賬戶金額平臺(tái)合約賬戶金額結(jié)果顯示,分賬賬戶和平臺(tái)合約賬戶如預(yù)期那樣獲得和。綜上,我們成功使用了智能合約實(shí)現(xiàn)了自動(dòng)分賬。
自動(dòng)分賬是很多平臺(tái)都會(huì)用到的支付功能。很多互聯(lián)網(wǎng)內(nèi)容售賣平臺(tái)都會(huì)跟內(nèi)容提供者分賬。比如:Apple 的 App Store 跟 App 開發(fā)者三七分成。很多平臺(tái)都使用了支付寶、微信支付作為支付手段,但是要同時(shí)實(shí)現(xiàn)給內(nèi)容提供者分賬,卻是一件不太容易的事。使用 FIBOS 智能合約可以很容易實(shí)現(xiàn)這個(gè)需求。
文中代碼已在 GitHub 上開源。https://github.com/fengluo/fi...
設(shè)計(jì)思路在 FIBOS 轉(zhuǎn)賬是通過 token 合約的extransfer方法來實(shí)現(xiàn)的。extransfer方法在執(zhí)行的時(shí)候會(huì)給轉(zhuǎn)賬方賬戶和入賬方賬戶發(fā)送通知。所以用戶給平臺(tái)方賬戶轉(zhuǎn)賬的時(shí)候,平臺(tái)賬戶就會(huì)收到通知。所以整體業(yè)務(wù)邏輯如下:
quantity: 10 FO memo: 內(nèi)容提供者賬戶 quantity: 8 FO 用戶賬戶 -------------------> 平臺(tái)賬戶 ----------------> 內(nèi)容提供者賬戶 extransfer 2/8 分成 extransfer
用戶給平臺(tái)方賬戶轉(zhuǎn)賬,memo 中填寫內(nèi)容提供者的賬戶名。
平臺(tái)方的賬戶合約監(jiān)聽 extransfer 方法的通知,然后做出分賬計(jì)算,給對(duì)應(yīng)內(nèi)容提供者的賬戶轉(zhuǎn)賬對(duì)應(yīng)金額。
整體邏輯很簡單,整個(gè)合約代碼邏輯差不多用20行就可以寫完。
編寫合約FIBOS 的智能合約分為 ABI 文件和 JS 合約兩部分。ABI 相當(dāng)于合約接口,JS 合約則是功能實(shí)現(xiàn)。本案例目前沒有接口設(shè)計(jì)需求,不過 ABI 文件還是合約不可缺少的部分。所以我們簡單創(chuàng)建一下就好。
我們先創(chuàng)建一個(gè) contracts 文件夾,合約文件都會(huì)放在這里。然后在此文件夾下,創(chuàng)建 subaccount.abi 文件,內(nèi)容為:
{ "version": "eosio::abi/1.0" }
JS 合約部分也沒有太復(fù)雜。在 contracts 文件夾下創(chuàng)建 subaccount.js 文件,代碼為:
exports.on_extransfer = (from, to, quantity, memo) => { // 需要在開頭做一些判斷 if (to === action.receiver && action.is_account(memo)) { const num = parseInt(quantity.quantity.split(" ")[0]) // 假設(shè)我們約定平臺(tái)方跟內(nèi)容提供者是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 權(quán)限 actor: action.receiver, permission: "active" } ]); } }
合約代碼開頭我們需要做一些驗(yàn)證。
收款方的賬戶為合約賬戶,否則因?yàn)橄旅娲a執(zhí)行給內(nèi)容提供者轉(zhuǎn)賬時(shí),因?yàn)檗D(zhuǎn)帳方也是合約賬號(hào)會(huì)再次收到通知,造成無限遞歸,超出最大 send_inline 層數(shù)而報(bào)錯(cuò)。
我們用 memo 參數(shù)來放內(nèi)容提供者的賬戶,所以我們需要對(duì)此參數(shù)校驗(yàn)一下該賬戶是否存在防止打錯(cuò)。
合約代碼中我們使用 send_inline 調(diào)用 eosio.token 合約來執(zhí)行轉(zhuǎn)帳操作。轉(zhuǎn)帳操作需要對(duì)應(yīng)賬戶的 active 權(quán)限才能執(zhí)行。為了解決權(quán)限濫用問題,F(xiàn)IBOS 定義了一個(gè)特殊權(quán)限 eosio.code。我們需要在平臺(tái)合約賬戶中配置權(quán)限,在 active 權(quán)限下添加該合約賬戶的 eosio.code 授權(quán)。具體的配置操作會(huì)在下面說明。
在 FIBOS TestNet 上注冊賬號(hào)為方便測試,我們在測試網(wǎng) http://testnet.fibos.fo 上注冊三個(gè)賬戶。
用戶賬號(hào) helloworld11
內(nèi)容提供者賬號(hào) helloworld22
平臺(tái)合約賬號(hào) helloworld33
我們需要記錄這三個(gè)賬號(hào)的賬戶名以及公私鑰。以便下面的開發(fā)使用。創(chuàng)建一個(gè)統(tǒng)一的配置文件來記錄這些數(shù)據(jù):
const config = { // 平臺(tái)合約賬戶的客戶端配置 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" }, // 平臺(tái)合約賬戶信息 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" }, // 內(nèi)容提供者賬戶信息 account2: { name: "helloworld22", publicKey: "PUBLIC_KEY_OF_helloworld22", privateKey: "PRIVATE_KEY_OF_helloworld22" } } module.exports = config配置權(quán)限
在合約代碼中,我們調(diào)用了 trans.send_inline 函數(shù)調(diào)用合約 eosio.token 來實(shí)現(xiàn)轉(zhuǎn)帳操作,但是轉(zhuǎn)帳操作是需要賬戶的 active 權(quán)限。所以我們需要更新一下合約賬戶的權(quán)限,需要添加調(diào)用者的 eosio.code 授權(quán)到它的 active 權(quán)限。這個(gè)調(diào)用者自然也是這個(gè)合約賬戶。
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: { // 將調(diào)用者賬號(hào)的 eosio.code 授權(quán)添加到它的 active 權(quán)限下。 actor: config.contractAccount.name, permission: "eosio.code" }, weight: 1 }] } },{ authorization: `${config.contractAccount.name}@owner` //更改賬戶權(quán)限需要使用 owner 權(quán)限 }); 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);轉(zhuǎn)賬測試
我們先來寫一個(gè)腳本 account.js 來查看三個(gè)賬戶的余額。
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);
執(zhí)行 fibos account.js 來查看三個(gè)賬戶信息。 目前我們的賬戶還沒有 FO,所以大致情況是這樣的:
用戶賬戶:helloworld11 金額:0.0000 FO
內(nèi)容提供者賬戶:helloworld22 金額:0.0000 FO
平臺(tái)合約賬戶:helloworld33 金額:0.0000 FO
測試網(wǎng)會(huì)自動(dòng)給每個(gè)賬戶發(fā)放10 EOS 的通證用以測試使用。賬戶中還并沒有 FO 通證。所以我們再來寫一個(gè)兌換腳本,用1 EOS 換一點(diǎn) 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)
再次執(zhí)行 fibos account.js 來查看賬戶信息。目前我們的賬戶金額大致是這樣的:
用戶賬戶:helloworld11 金額:146.4245 FO
內(nèi)容提供者賬戶:helloworld22 金額:0.0000 FO
平臺(tái)合約賬戶:helloworld33 金額:0.0000 FO
下面寫個(gè)腳本 transfer.js 來執(zhí)行轉(zhuǎn)帳操作。
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, // 平臺(tái)合約賬戶 "10.0000 FO@eosio", // 轉(zhuǎn)帳金額 config.account2.name, // 附言填寫內(nèi)容提供者的賬戶名,平臺(tái)合約會(huì)給它分賬 { authorization: config.account1.name //提供用戶賬戶的授權(quán) } ) console.log(r)
我們要從用戶賬戶 account1 給平臺(tái)合約賬戶 account3 轉(zhuǎn)帳 10 FO。memo 參數(shù)為要分成的內(nèi)容提供者賬戶 account2。根據(jù)合約中定的2/8分成,平臺(tái)合約賬戶 account3 將會(huì)分得2 FO,而內(nèi)容提供者賬戶 account2 將會(huì)獲得8 FO。
使用命令 fibos transfer.js 執(zhí)行該腳本完成轉(zhuǎn)帳操作。
下面我們再來看一下目前三個(gè)賬戶情況。執(zhí)行命令 fibos account.js。三個(gè)賬戶金額大致如下。
用戶賬戶:helloworld11 金額:136.4245 FO
內(nèi)容提供者賬戶:helloworld22 金額:8.0000 FO
平臺(tái)合約賬戶:helloworld33 金額:2.0000 FO
結(jié)果顯示,分賬賬戶和平臺(tái)合約賬戶如預(yù)期那樣獲得8 FO 和2 FO。
綜上,我們成功使用了智能合約實(shí)現(xiàn)了自動(dòng)分賬。平臺(tái)方還可以繼續(xù)根據(jù)自己業(yè)務(wù)需要定制自己的合約。
文中的代碼請參考:https://github.com/fengluo/fi...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/108984.html
摘要:編寫合約的智能合約分為文件和合約兩部分。相當(dāng)于合約接口,合約則是功能實(shí)現(xiàn)。用戶賬戶金額內(nèi)容提供者賬戶金額平臺(tái)合約賬戶金額結(jié)果顯示,分賬賬戶和平臺(tái)合約賬戶如預(yù)期那樣獲得和。綜上,我們成功使用了智能合約實(shí)現(xiàn)了自動(dòng)分賬。 自動(dòng)分賬是很多平臺(tái)都會(huì)用到的支付功能。很多互聯(lián)網(wǎng)內(nèi)容售賣平臺(tái)都會(huì)跟內(nèi)容提供者分賬。比如:Apple 的 App Store 跟 App 開發(fā)者三七分成。很多平臺(tái)都使用了支付...
摘要:在協(xié)議結(jié)束時(shí),智能合約被視為已履行并仍存儲(chǔ)在區(qū)塊鏈網(wǎng)絡(luò)中。這組條件和事件代表了最基本的一次性智能合約。智能合約用例智能合約越來越受歡迎,并已在各種區(qū)塊鏈項(xiàng)目中實(shí)施。 與區(qū)塊鏈技術(shù)一樣,智能合約在商業(yè)領(lǐng)域也非常有價(jià)值。 為了讓我們的讀者徹底了解智能合約是什么以及它們?nèi)绾斡绊懍F(xiàn)代商業(yè)的交易方式,我們準(zhǔn)備了本指南。 集中商業(yè)模式正在給去中心化的模式讓路 傳統(tǒng)的商業(yè)關(guān)系模型都是集中式的,始終存...
摘要:在協(xié)議結(jié)束時(shí),智能合約被視為已履行并仍存儲(chǔ)在區(qū)塊鏈網(wǎng)絡(luò)中。這組條件和事件代表了最基本的一次性智能合約。智能合約用例智能合約越來越受歡迎,并已在各種區(qū)塊鏈項(xiàng)目中實(shí)施。 與區(qū)塊鏈技術(shù)一樣,智能合約在商業(yè)領(lǐng)域也非常有價(jià)值。 為了讓我們的讀者徹底了解智能合約是什么以及它們?nèi)绾斡绊懍F(xiàn)代商業(yè)的交易方式,我們準(zhǔn)備了本指南。 集中商業(yè)模式正在給去中心化的模式讓路 傳統(tǒng)的商業(yè)關(guān)系模型都是集中式的,始終存...
摘要:在協(xié)議結(jié)束時(shí),智能合約被視為已履行并仍存儲(chǔ)在區(qū)塊鏈網(wǎng)絡(luò)中。這組條件和事件代表了最基本的一次性智能合約。智能合約用例智能合約越來越受歡迎,并已在各種區(qū)塊鏈項(xiàng)目中實(shí)施。 與區(qū)塊鏈技術(shù)一樣,智能合約在商業(yè)領(lǐng)域也非常有價(jià)值。 為了讓我們的讀者徹底了解智能合約是什么以及它們?nèi)绾斡绊懍F(xiàn)代商業(yè)的交易方式,我們準(zhǔn)備了本指南。 集中商業(yè)模式正在給去中心化的模式讓路 傳統(tǒng)的商業(yè)關(guān)系模型都是集中式的,始終存...
摘要:在協(xié)議結(jié)束時(shí),智能合約被視為已履行并仍存儲(chǔ)在區(qū)塊鏈網(wǎng)絡(luò)中。這組條件和事件代表了最基本的一次性智能合約。智能合約用例智能合約越來越受歡迎,并已在各種區(qū)塊鏈項(xiàng)目中實(shí)施。 與區(qū)塊鏈技術(shù)一樣,智能合約在商業(yè)領(lǐng)域也非常有價(jià)值。 為了讓我們的讀者徹底了解智能合約是什么以及它們?nèi)绾斡绊懍F(xiàn)代商業(yè)的交易方式,我們準(zhǔn)備了本指南。 集中商業(yè)模式正在給去中心化的模式讓路 傳統(tǒng)的商業(yè)關(guān)系模型都是集中式的,始終存...
閱讀 1980·2021-11-23 10:03
閱讀 4178·2021-11-22 09:34
閱讀 2486·2021-10-08 10:05
閱讀 2254·2019-08-30 15:53
閱讀 1691·2019-08-30 13:56
閱讀 1160·2019-08-29 16:52
閱讀 1113·2019-08-26 13:31
閱讀 3351·2019-08-26 11:45