EOS錢包開發:抵押和贖回NET與CPU頻寬
目標
前言
現在我們能對RAM進行交易了,還差的NET、CPU交易將是本章重點。
同樣,交易NET、CPU貸款的前提是我們需要知道它的價格,即買1KB NET頻寬和1ms CPU頻寬需要抵押多少EOS,贖回1個EOS能獲得多少NET、CPU頻寬。這就需要我們去鏈上查詢資料庫獲取相應的實時的資料,再進行計算拿到價格。下面我們來一步步實現,最後展示在專案中的相應原始碼。
一、計算NET、CPU頻寬價格
RPC和eosjs都沒有提供API直接獲取價格,那我們如何獲取頻寬的價格呢?我們可以通過特定的規則去計算NET、CPU頻寬的價格。
1. 計算NET頻寬價格
在前面“詳解與獲取RAM、NET、CPU資源資料”章節的學習中我們已經可以獲取賬號的網路資源詳情了,包含NET寬頻抵押金額和NET寬頻總量。通過這個演算法(NET寬頻抵押金額 / NET寬頻總量)/ 3
即可獲取到NET寬頻價格了。
let httpRequest = require("../utils/httpRequest") let config = require("../config/config") async function testGetNetPrice() { let account = "lixutest1111" let res = await httpRequest.postRequest(config.accountInfo, { "account_name": account }) if (res.code == 0) { data = res.data //抵押NET的EOS數量 var netBalance = data.net_weight / 10000 //NET貸款的總量 var netTotal = data.net_limit.max / 1024 //(netBalance / netTotal)獲取到的是過去3天內的平均消耗量,除以3獲取每天的平均消耗量,即價格 netPrice = ((netBalance / netTotal) / 3).toFixed(4) console.log(netBalance, netTotal, netPrice) } } testGetNetPrice() 輸出如下
100 18680.2177734375 '0.00178442'
可以看到連線到的測試網路計算得到的NET價格為0.00178442,單位是EOS/KB/Day。
另外,修改config配置連線到主網後計算的價格是“0.0004887”左右。所以測試網路和主網的NET頻寬價格相差很大。
2. 計算CPU頻寬價格
計算CPU頻寬價格的方式與NET頻寬類似,我們直接看測程式碼。
let httpRequest = require("../utils/httpRequest") let config = require("../config/config") async function testGetCpuPrice() { let account = "lixutest1111" let res = await httpRequest.postRequest(config.accountInfo, { "account_name": account }) if (res.code == 0) { data = res.data //抵押CPU的EOS數量 var cpuBalance = data.cpu_weight / 10000 //CPU貸款的總量 var cpuTotal = data.cpu_limit.max / 1024 //(cpuBalance / cpuTotal)獲取到的是過去3天內的平均消耗量,除以3獲取每天的平均消耗量,即價格 cpuPrice = ((cpuBalance / cpuTotal) / 3).toFixed(4) console.log(cpuBalance, cpuTotal, cpuPrice) } } testGetCpuPrice() 輸出如下
100 3554.1171875 '0.0094'、
可以看到連線到的測試網路計算得到的CPU價格為0.0094,單位是EOS/ms/Day。
另外,修改config配置連線到主網後計算的價格是“0.2148”左右。所以測試網路和主網的CPU頻寬價格相差很大。
二、抵押EOS獲取NET、CPU頻寬
1. 抵押EOS獲取NET頻寬
抵押EOS獲取NET頻寬的API我們已經使用過了,在建立賬號的時候我們為別人建立的賬號就需要為它購買一定的NET頻寬,現在我們在來單獨呼叫抵押的API。由於現在需要交易,所以會使用資源,因此我們切換到測試網路進行測試。
let myUtils = require("../utils/myUtils") async function testBuyNet() { eos = myUtils.getEOSJS(["5HqCj7sg4K2xZ1KD5sSH38kuJkKGqfE1wSGiLL3M599ajacVmTs"]) let account = "lixutest1111" let data = await eos.transaction(tr => { tr.delegatebw({ from: account, receiver: account, stake_net_quantity: "1.0000 EOS", stake_cpu_quantity: "0.0000 EOS", transfer: 0 }) }) console.log(data) } testBuyNet()
特別注意:
- 若只買NET頻寬,那麼“stake_cpu_quantity”該欄位必須設定,且一樣須帶有四個小數位,即“0.0000 EOS”。
- 若只買CPU頻寬,那麼“stake_net_quantity”該欄位也必須設定,且一樣須帶有四個小數位,即“0.0000 EOS”。
在執行之前先記錄下來賬號“lixutest1111”的網路資源資料。
執行測試程式碼後檢視NET頻寬資料如下
可以看到EOS可用餘額減少了一個,NET頻寬抵押的EOS多了一個,總量從18280KB增加到了18867KB,增量是587KB。
剛才計算的每KB NET大約花費0.00178442個EOS,所以1個EOS大概能買到NET 1/0.00178442 = 560KB。這個計算的結果和鏈上獲取的結果587KB相差無幾。因為NET價格會隨著市場波動而變化,所以導致結果有一點點偏差,這是不可避免的。另外我們在購買NET的時候,需要輸入的是EOS數量,然後根據NET價格轉換成他當前能購買到多少KB RAM,再進行交易。
2. 抵押EOS獲取CPU頻寬
抵押EOS獲取CPU頻寬的方式與抵押EOS獲取NET頻寬一樣,下面我只給出程式碼,它的原理與獲取NET頻寬一樣。
let myUtils = require("../utils/myUtils") async function testBuyCpu() { eos = myUtils.getEOSJS(["5HqCj7sg4K2xZ1KD5sSH38kuJkKGqfE1wSGiLL3M599ajacVmTs"]) let account = "lixutest1111" let data = await eos.transaction(tr => { tr.delegatebw({ from: account, receiver: account, stake_net_quantity: "0.0000 EOS", stake_cpu_quantity: "1.0000 EOS", transfer: 0 }) }) console.log(data) } testBuyCpu()
3. 抵押EOS同時獲取NET與CPU頻寬
正常情況下我們都是一起購買NET與CPU頻寬的,需要前端同時傳來抵押EOS購買NET的量,與抵押EOS購買CPU的量,然後設定上stake_net_quantity與stake_cpu_quantity相應的值。
三、贖回NET頻寬與獲取贖回金額
1. 贖回NET頻寬
贖回需要用到另外一個APIundelegatebw
,它與抵押的API
delegatebw
相對應。傳遞的資料結構一樣。
async function testSellNet() { eos = myUtils.getEOSJS(["5HqCj7sg4K2xZ1KD5sSH38kuJkKGqfE1wSGiLL3M599ajacVmTs"]) let account = "lixutest1111" let data = await eos.transaction(tr => { tr.undelegatebw({ from: account, receiver: account, unstake_net_quantity: "1.0000 EOS", unstake_cpu_quantity: "0.0000 EOS" }) }) console.log(data) } testSellNet()
在執行之前先記錄下來賬號“lixutest1111”的網路資源資料。
執行測試程式碼後檢視NET頻寬資料如下
可以看到贖回NET頻寬後EOS可用餘額並沒有增加,而用於NET頻寬抵押的EOS的數量由101減少到了100,總量也由18877KB減少到了18680KB。那麼問題來了,NET寬頻資源已經被扣了,但是贖回的EOS沒有到賬,這是為什麼呢?
2. 獲取贖回期中的贖回金額
之前已經說過了,在贖回寬頻資源的時候,存在三天的贖回期,因此我們的贖回交易已經完成了,但是需要三天後EOS才會到賬。那麼我們需要將此資料顯示給使用者檢視。如何獲取贖回的金額資料呢?
再使用cleos工具檢視賬號“lixutest1111”的賬號資訊,如下
可以看到“refund_request”欄位資料中包含了“net_amount”欄位的資料有“1.0000 EOS”,這正是我們贖回的EOS。之前沒有贖回金額的時候,該欄位為null。
因此我們獲取該欄位資料返回給前端,用於顯示贖回金額。
let redeemBalance = 0 if (data.refund_request) { refundNetBalance = data.refund_request.net_amount.split(" ")[0] refundCpuBalance = data.refund_request.cpu_amount.split(" ")[0] redeemBalance = parseFloat(refundNetBalance) + parseFloat(refundCpuBalance) }
四、同時贖回NET與CPU頻寬
單獨贖回CPU頻寬也是可以的,與單獨贖回NET頻寬一樣。下面我們看看同時贖回NET與CPU頻寬的方式。
async function testSellNetAndCpu() { eos = myUtils.getEOSJS(["5HqCj7sg4K2xZ1KD5sSH38kuJkKGqfE1wSGiLL3M599ajacVmTs"]) let account = "lixutest1111" let data = await eos.transaction(tr => { tr.undelegatebw({ from: account, receiver: account, unstake_net_quantity: "1.0000 EOS", unstake_cpu_quantity: "1.0000 EOS" }) }) console.log(data) } testSellNetAndCpu()
執行測試程式碼後檢視寬頻資源資料如下
可以看到贖回NET、CPU頻寬後EOS可用餘額並沒有增加,而用於NET頻寬抵押的EOS的數量都減少了一個,寬頻資源也相應地減少了。
再來看看賬號“lixutest1111”贖回期中的贖回金額
五、專案原始碼
1. controllers/netResource.js
在controllers資料夾下編輯netResource.js檔案,實現獲取NET與CPU的價格、抵押和贖回NET與CPU頻寬的功能。
...... let httpRequest = require("../utils/httpRequest") let config = require("../config/config") module.exports = { ...... netResourceGetBandwidthPrice: async (ctx) => { console.log(ctx.request.body) let { account } = ctx.request.body let res = await httpRequest.postRequest(config.accountInfo, { "account_name": account }) if (res.code == 0) { data = res.data //1. 計算NET價格 //抵押NET的EOS數量 var netBalance = data.net_weight / 10000 //NET貸款的總量 var netTotal = data.net_limit.max / 1024 //(netBalance / netTotal)獲取到的是過去3天內的平均消耗量,除以3獲取每天的平均消耗量,即價格 netPrice = ((netBalance / netTotal) / 3).toFixed(4) console.log(netBalance, netTotal, netPrice) //1. 計算CPU價格 //抵押CPU的EOS數量 var cpuBalance = data.cpu_weight / 10000 //CPU貸款的總量 var cpuTotal = data.cpu_limit.max / 1024 //(cpuBalance / cpuTotal)獲取到的是過去3天內的平均消耗量,除以3獲取每天的平均消耗量,即價格 cpuPrice = ((cpuBalance / cpuTotal) / 3).toFixed(4) ctx.body = success({ netPrice: netPrice, cpuPrice: cpuPrice, }) } else { ctx.body = res } }, netResourceTransactionBandwidth: async (ctx) => { console.log(ctx.request.body) let { net_amount, cpu_amount, bandwidth_transaction_type, account, wallet, password } = ctx.request.body //獲取錢包裡面所有的私鑰配置EOSJS let privatekeyList = await walletModel.getWalletPrivatekeyList(wallet, password) eos = myUtils.getEOSJS(privatekeyList) let result if (bandwidth_transaction_type == '1') { //抵押EOS購買NET、CPU result = await eos.transaction(tr => { tr.delegatebw({ from: account, receiver: account, stake_net_quantity: parseFloat(net_amount).toFixed(4) + " EOS", stake_cpu_quantity: parseFloat(cpu_amount).toFixed(4) + " EOS", transfer: 0 }) }) } else { //從NET、CPU資源中贖回EOS result = await eos.transaction(tr => { tr.undelegatebw({ from: account, receiver: account, unstake_net_quantity: parseFloat(net_amount).toFixed(4) + " EOS", unstake_cpu_quantity: parseFloat(cpu_amount).toFixed(4) + " EOS", }) }) } console.log("data:", result) if (result.broadcast) { ctx.body = success("ok") } else { ctx.body = fail("error") } }, }
2. router/router.js
將獲取NET與CPU的價格、抵押和贖回NET與CPU頻寬的介面繫結到路由。
//網路資源 router.post("/net_resource/bandwidth/price", netresourceController.netResourceGetBandwidthPrice) router.post("/net_resource/bandwidth/transaction", netresourceController.netResourceTransactionBandwidth)
3. views/netResource.html
編輯views資料夾下的netResource.html檔案,實現NET與CPU抵押和贖回的表單顯示。
...... <div class="interactive"> <b>NET、CPU頻寬交易</b> <form id="bandwidth-transaction"> <input type="radio" id="bandwidth-transaction-buy" name="bandwidth_transaction_type" value="1" checked="checked"> <label for="bandwidth-transaction-buy">抵押</label> <input type="radio" id="bandwidth-transaction-sell" name="bandwidth_transaction_type" value="2" checked> <label for="bandwidth-transaction-sell">贖回</label> <br> <div>NET頻寬價格:<span id="net-price"></span> EOS/KB/Day</div> <label>數量:</label> <input type="text" name="net_amount" placeholder="請輸入購買NET所抵押的EOS數量"><br> <div>CPU頻寬價格:<span id="cpu-price"></span> EOS/ms/Day</div> <label>數量:</label> <input type="text" name="cpu_amount" placeholder="請輸入購買CPU所抵押的EOS數量"><br> <input type="text" name="account" hidden="hidden"> <input type="text" name="wallet" hidden="hidden"> <input type="text" name="password" hidden="hidden"> <button type="submit" id="bandwidth-transaction-button">抵押</button> </form> </div> ......
4. static/js/netResource.js
對NET與CPU的價格、抵押和贖回NET與CPU頻寬的表單進行網路請求處理與頁面渲染。
$(document).ready(function () { ...... $("input[name=bandwidth_transaction_type]").change(function () { if (this.value == 1) { $("#bandwidth-transaction-button").text("抵押") } else { $("#bandwidth-transaction-button").text("贖回") } }) //NET、CPU價格 $.post("/net_resource/bandwidth/price", { "account": currentAccount }, function (res, status) { console.log(status + JSON.stringify(res)) if (res.code == 0) { $("#net-price").text(res.data.netPrice) $("#cpu-price").text(res.data.cpuPrice) } }) //交易NET、CPU $("#bandwidth-transaction").validate({ rules: { net_amount: {required: true,}, cpu_amount: {required: true,}, }, messages: { net_amount: {required: "請輸入購買NET所抵押的EOS數量",}, cpu_amount: {required: "請輸入購買CPU所抵押的EOS數量",}, }, submitHandler: function (form) { $(form).ajaxSubmit({ url: "/net_resource/bandwidth/transaction", type: "post", dataType: "json", success: function (res, status) { console.log(status + JSON.stringify(res)) if (res.code == 0) { alert("交易成功") location.reload() } else { alert("交易失敗") } }, error: function (res, status) { console.log(status + JSON.stringify(res)) alert(res.data) } }); } }) })
六、專案效果

ofollow,noindex" target="_blank">專案原始碼Github地址
版權宣告:部落格中的文章版權歸博主所有,未經授權禁止轉載,轉載請聯絡作者(微信:lixu1770105)取得同意並註明出處。
未經授權禁止轉載、改編,轉載請註明出處!