第1章 【EOS钱包开发 一】EOS不得不说的一些概念
第2章 【EOS钱包开发 二】EOS开发环境搭建
第3章 【EOS钱包开发 三】钱包项目整体架构设计
第4章 【EOS钱包开发 四】钱包模块:新建钱包、解锁钱包、导入账号
第5章 【EOS钱包开发 五】使用cleos工具管理账号权限
第6章 【EOS钱包开发 六】深入浅出EOSJS:连接到主网、测试网、交易
第7章 【EOS钱包开发 七】新建账号:设置多权限配置
第8章 【EOS钱包开发 八】EOS代币转账交易
第9章 【EOS钱包开发 九】基于测试网络进行开发
第10章 【EOS钱包开发 十】详解与获取RAM、NET、CPU资源数据
第11章 【EOS钱包开发 十一】买入卖出RAM
第12章 【EOS钱包开发 十二】抵押和赎回NET与CPU带宽
- 【EOS钱包开发 八】EOS代币转账交易
最后更新于 2021-01-14 12:01:21

一、使用Cleos在本地网络发布代币

发布代币后转账给钱包应用里的账号,接下来我们才能使用应用程序去进行转账交易。发布代币的过程这里使用Cleos命令行工具,咱们拓展钱包应用程序的时候也可以添加发布代币这样一个功能,这里就不做这个次要的功能了。

1. 部署eosio.token合约

这一步骤咱们在环境搭建章节已经完成,注意必须创建eosio.token这个账号,并使用eosio.token账号部署eosio.token合约。

2. 创建Token代币

contracts/eosio.token/eosio.token.hpp文件中可以查看到Token合约接口,如下

32A41D3B0DFBCA95B7761C2490703234

需要调用create()方法去创建Token合约。发行人可以对该Token合约执行一些特有的操作,例如冻结,召回和列入所有者白名单。

创建代币的cleos命令是cleos push action

lixu@ubuntu:~/Desktop/sourceeos/eos$ cleos push action
ERROR: RequiredError: account
Push a transaction with a single action
Usage: cleos push action [OPTIONS] account action data

Positionals:
 account TEXT                The account providing the contract to execute (required)
 action TEXT                 A JSON string or filename defining the action to execute on the contract (required)
 data TEXT                   The arguments to the contract (required)

Options:
......

其中的参数:

  • account TEXT(必传):执行合约的帐户名。
  • action TEXT (必传):JSON字符串或文件名,执行的是合约里的action,即方法名。
  • data TEXT(必传):执行的是合约方法的参数。

因此,创建EOS Token代币的完整命令如下:

cleos push action eosio.token create '[ "eosio", "1000000000.0000 EOS"]' -p eosio.token@active

或者调用create方法时指定参数

cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 EOS"}' -p eosio.token@active

executed transaction: b1a1f0a1471415170438ea609ed6586ec7d3965e9bcd4f92cb502364f877fa59  120 bytes  494 us
#   eosio.token <= eosio.token::create          {"issuer":"eosio","maximum_supply":"1000000000.0000 EOS"}

此命令是通过eosio.token账户创建了一个新的Token,发布者是eosio,Token名为EOS,其精度为4位小数,发布的总量是1000000000.0000 EOS。

3. 查询代币信息

根据命令cleos get currency stats可以查看查询代币命令的参数

lixu@ubuntu:~$ cleos get currency stats

ERROR: RequiredError: contract
Retrieve the stats of for a given currency
Usage: cleos get currency stats contract [symbol]

Positionals:
  contract TEXT               代币合约名称 ,此项必填
  symbol TEXT                 代币符号,例如 EOS ,此项必填

因此,可知查询账户余额的命令为 cleos get currency stats 合约名称 代币符号

lixu@ubuntu:~$ cleos get currency stats eosio.token EOS
{
  "EOS": {
    "supply": "0.0000 EOS",
    "max_supply": "1000000000.0000 EOS",
    "issuer": "eosio"
  }
}

4. 发行者转代币给其它账户

现在我们已经创建了EOS代币,发行者可以调用issue方法向之前创建的帐户lixu发放Token。

cleos push action eosio.token issue '[ "user", "100.0000 EOS", "memo" ]' -p eosio@active

12354F66-D136-45BE-8B3F-4319BC0BC154

可以看到会通知资金的发送方和接收方,以便它们可以自动处理存款和取款。

5. 查询账户余额

根据命令cleos get currency balance可以查询账户余额。

$ cleos get currency balance

ERROR: RequiredError: contract
Retrieve the balance of an account for a given currency
Usage: cleos get currency balance contract account [symbol]

Positionals:
  contract TEXT               代币合约名称
  account TEXT                查询余额的账户
  symbol TEXT                 货币符号,例如 EOS ,此项非必须

因此,查询账户余额完整的命令为cleos get currency balance 合约名称 账户名称

lixu@ubuntu:~$ cleos get currency balance eosio.token lixu
100.0000 EOS

lixu@ubuntu:~$ cleos get currency balance eosio.token lixu EOS
100.0000 EOS

二、项目源码

对发布的代币如何进行转账交易,请查看“深入浅出EOSJS:连接到主网、测试网、交易”章节。

1. web.js

编辑controllers文件夹下的web.js文件,用于实现后端返回给前端转账交易的页面。

module.exports = { ...... getTransactionHtml:async(ctx) => { await ctx.render("transaction.html") }, }

2. transaction.js

在controllers文件夹下新建transaction.js文件,后端实现转账交易的功能。

let {success, fail} = require("../utils/myUtils") let myUtils = require("../utils/myUtils") let walletModel = require("../models/wallet") module.exports = { transactionSend: async (ctx) => { console.log(ctx.request.body) let { from, to, amount, symbol, memo, wallet, password } = ctx.request.body //1.获取钱包里面所有的私钥 let privatekeyList = await walletModel.getWalletPrivatekeyList(wallet, password) //2.配置EOSJS eos = myUtils.getEOSJS(privatekeyList) //3.发起转账交易 options = { authorization: `${from}@active`, broadcast: true, sign: true } let data = await eos.transaction(eos => { let stantardAmount = parseFloat(amount).toFixed(4) eos.transfer(from, to, `${stantardAmount} ${symbol}`, memo, options) }) console.log("data:", data) //4.返回给前端执行的状态 let resData if (data) { resData = success("转账成功") } else { resData = fail("转账失败") } ctx.body = resData }, }

3. wallet.js

在mdoels文件夹下新建wallet.js文件,实现根据钱包名和密码获取所有秘钥的功能。

let httpRequest = require("../utils/httpRequest") let config = require("../config/config") module.exports = { getWalletPrivatekeyList: async (wallet, password) => { let privatekeyList = [] let res = await httpRequest.postRequest(config.walletGetKeys, [wallet, password]) if (res.code == 0 && res.data.length > 0) { for (const index in res.data) { let keys = res.data[index] privatekeyList.push(keys[1]) } } return privatekeyList } }

3. router.js

将转账交易功能的接口绑定到路由。

...... let transactionController = require("../controllers/transaction") //转账交易 router.post("/transaction/send", transactionController.transactionSend) //页面 router.get("/transaction.html", webController.getTransactionHtml)

4. transaction.html

在views文件夹下新建transaction.html文件,实现前端转账交易的页面。

<html> <head> <title>转账</title> <script src="js/lib/jquery-3.3.1.min.js"></script> <script src="/js/lib/jquery.url.js"></script> <script src="js/transaction.js"></script> <link rel="stylesheet" href="css/eoswallet.css"> </head> <body> <%include block/nav.html%> <div id="main"> <h1></h1> <div class="row top"> <form id="transaction-send-form"  > <select name="from" id="transaction-send-account-select"> </select> <label>from账号名称</label> <br><br> <input type="text" name="to" placeholder="请输入对方账号名称"> <label>to账号名称</label> <br><br> <input type="text" name="amount" placeholder="请输入转账数量"> <select name="symbol" id="transaction-send-token-select"> </select> <label>金额</label> <br><br> <input type="text" name="memo" placeholder="请输入转账备注"> <label>memo备注</label> <br><br> <input type="text" name="wallet" hidden="hidden"> <input type="text" name="password" hidden="hidden"> <button type="submit">发送交易</button> </form> </div> <div class="row top"> <table> <tr> <th>代币</th> <th>金额</th> </tr> </table> <table id="transation-balance-table"> </table> </div> </div> </body> </html>

5. transaction.js

在static/js文件夹下新建transaction.js文件,前端处理钱包模块的网络请求与页面的渲染。

//账号金额 function updateAccountBalance(account) { let params = {"code":"eosio.token","account":account} $.post("/account/balance", params, function (res, status) { console.log(status + JSON.stringify(res)) if (res.code == 0) { let balanceTable = $("#transation-balance-table") balanceTable.empty() if (res.data && res.data.length > 0) { res.data.forEach(balanceData => { let balanceTr = `<tr> <td>${balanceData.symbol}</td> <td>${balanceData.amount}</td> </tr>` balanceTable.append(balanceTr) }); tokenSelectList(res.data) } else { let balanceTr = `<tr> <td>无存款</td> </tr>` balanceTable.append(balanceTr) tokenSelectList([]) } } }) } //选择Token列表 function tokenSelectList(tokenList) { let TokenSelectList = $("#transaction-send-token-select") TokenSelectList.empty() for(let i = 0; i < tokenList.length; i++) { let token = tokenList[i] let option = `<option value="${token.symbol}">${token.symbol}</option>` TokenSelectList.append(option) } } $(document).ready(function () { let currentwallet = localStorage.getItem("currentwallet") $("h1").text(currentwallet+" 钱包") if (!currentwallet) { return } let currentAccount = localStorage.getItem("currentAccount") let walletPassword = localStorage.getItem(currentwallet) $("input[name=wallet][hidden=hidden]").val(currentwallet) $("input[name=password][hidden=hidden]").val(walletPassword) //选择账号列表 let accountList = sessionStorage.getItem(`wallet-${currentwallet}-accounts`) accountList = JSON.parse(accountList) console.log("accountList",accountList) let accountSelectList = $("#transaction-send-account-select") for(let i = 0; accountList && i < accountList.length; i++) { let account = accountList[i] let accountOption if (account == currentAccount) { accountOption = `<option selected="selected" value="${account}">${account}</option>` } else { accountOption = `<option value="${account}">${account}</option>` } accountSelectList.append(accountOption) } //账号金额 updateAccountBalance(currentAccount) //选择不同的账号 accountSelectList.change(function() { console.log(this.value) localStorage.setItem("currentAccount", this.value) updateAccountBalance(this.value) }) //发送交易 $("#transaction-send-form").validate({ rules: { from: {required: true,}, to: {required: true,}, amount: {required: true,}, }, messages: { frmo: {required: "请选择转出的账号",}, to: {required: "请输入对方账号名称",}, amount: {required: "请输入转账的数量",}, }, submitHandler: function (form) { $(form).ajaxSubmit({ url: "/transaction/send", type: "post", dataType: "json", success: function (res, status) { console.log(status + JSON.stringify(res)) alert(JSON.stringify(res.data)) if (res.code == 0) { } }, error: function (res, status) { console.log(status + JSON.stringify(res)) alert(res.data) } }); } }) })

三、项目运行效果

前面通过cleos给账号lixu发行了100个EOS,现在通过他去转账。

![2018-10-12 18.11.58](http://img.kongyixueyuan.com/2018-10-12 18.11.58.gif)

项目源码Github地址

版权声明:博客中的文章版权归博主所有,未经授权禁止转载,转载请联系作者(微信:lixu1770105)取得同意并注明出处。

精选评论
欢迎在这里发表留言,经过筛选后可公开显示
评论
取消