您当前位置: 首页> 资讯> EOS钱包开发之新建账号:设置多权限配置

热门标签

热门动态

EOS钱包开发之新建账号:设置多权限配置

作者:链大全 日期:2018-11-13 14:58:08


一、介绍说明

在开发账号模块之前,我们需要先用cleos工具帮我们创建一个账号,是什么原因需要它去创建和如何创建的请查看“使用cleos管理账号权限”章节的内容,这样我们才好使用开发的钱包项目查看账号详情以及创建账号。

创建账号属于一个交易,若使用RPC接口是非常的繁琐容易出错,这里我们使用eosjs库中封装的交易的接口,使用及其简单,eosjs的使用说明请查看“深入浅出EOSJS:连接到主网、测试网、交易”章节的内容。

本项目在配置eos对象时,获取了钱包里面所有的私钥进行配置,这样简化了用户每次交易都输入秘钥的操作,只需要输入钱包密码即可。

二、项目源码一:获取账号列表

账号模块的主要功能包括:

  • 账号列表
  • 通过私钥导入账号
  • 新建账号
  • 查看账号详情
    • 查询余额
    • 获取公私钥对
    • 查询权限配置

这部分源码先介绍获取账号列表的前后端实现。

1. web.js

编辑controllers文件夹下的web.js文件,实现后端返回给前端账号列表的页面。

module.exports = {
    ......

    getAccountHtml:async(ctx) => {
        await ctx.render("account.html")
    },
}

2. account.js

在controllers文件夹下新建account.js文件,后端实现获取账号列表的功能。

let httpRequest = require("../utils/httpRequest")
let config = require("../config/config")
let {success, fail} = require("../utils/myUtils")
let myUtils = require("../utils/myUtils")

module.exports = {
    //通过钱包名称获取账号列表
    accountListForWallet: async (ctx) => {
        console.log(JSON.stringify(ctx.request.body))
        let { wallet, password } = ctx.request.body
        //获取钱包管理的所有公私钥对
        let res = await httpRequest.postRequest(config.walletGetKeys, [wallet, password])

        let accountList = []
        if (res.code == 0) {
            for (const index in res.data) {
                let keys = res.data[index]
                console.log(keys[0])
                //查询公钥关联的所有账号
                let resData = await httpRequest.postRequest(config.accountListForKey, { "public_key": keys[0] })
                if (resData.code == 0) {
                    resData.data.account_names.forEach(account => {
                        //去重
                        if (accountList.indexOf(account) 

3. router.js

将获取账号列表的接口绑定到路由。

......

let accountController = require("../controllers/account")

//账号
router.post("/account/listforwallet", accountController.accountListForWallet)

//页面
router.get("/account.html", webController.getAccountHtml)

4. account.html

在views文件夹下新建account.html文件,实现前端账号列表的页面。




    账号
    
    
    
    



    

    


5. account.js

在static/js文件夹下新建account.js文件,前端处理账号列表的网络请求与页面的渲染。

function accountInfo(acocunt) {
    localStorage.setItem("currentAccount", acocunt)
    window.location.href = "/accountinfo.html"
}

function goTransaction(account) {
    localStorage.setItem("currentAccount", account)
    window.location.href = "/transaction.html"
}

$(document).ready(function () {
    let currentwallet = localStorage.getItem("currentwallet")
    $("h1").text(currentwallet+" 钱包")
    if (!currentwallet) {
        return
    }
    let walletPassword = localStorage.getItem(currentwallet)
    $("input[name=wallet][hidden=hidden]").val(currentwallet)

    //获取账号列表
    let params = {"wallet":currentwallet, "password":walletPassword}
    $.post("/account/listforwallet", params, function (res, status) {
        console.log(status + JSON.stringify(res))
        if (res.code == 0) {
            let accountTable = $("#account-list-table")
            res.data.forEach(account => {
                let accountTr = `
                    
                    ${account}
                    
                    
                `
                accountTable.append(accountTr)
            });

            sessionStorage.setItem(`wallet-${currentwallet}-accounts`, JSON.stringify(res.data))
        }
    })

    //导入账户
    $("#account-import-form").validate({
        rules: {
            privatekey: {
                required: true,
            },
        },
        messages: {
            privatekey: {
                required: "请输入要导入的账号的私钥",
            },
        },
        submitHandler: function (form) {
            $(form).ajaxSubmit({
                url: "/wallet/importkey",
                type: "post",
                dataType: "json",
                success: function (res, status) {
                    console.log(status + JSON.stringify(res))
                    alert(JSON.stringify(res.data))
                    if (res.code == 0) {
                        window.location.reload()
                    }
                },
                error: function (res, status) {
                    console.log(status + JSON.stringify(res))
                }
            });
        }
    })
})

三、项目源码一:新建账号

1. web.js

编辑controllers文件夹下的web.js文件,实现后端返回给前端创建账号的页面。

module.exports = {
    ......

    getAccountCreateHtml:async(ctx) => {
        await ctx.render("accountNew.html")
    },
}

2. account.js

编辑controllers文件夹下的account.js文件,后端实现创建账号的功能。

module.exports = {
    ......

    //创建账号
    accountCreate: async (ctx) => {
        console.log(JSON.stringify(ctx.request.body))
        let {account, creator, wallet, password, activepubkey, ownerpubkey} = ctx.request.body

        //1.获取钱包里面所有的私钥
        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])
            }
            //2.设置创建账号默认的公钥
            let defaultKey = res.data[0][0]

            activepubkey = activepubkey || defaultKey
            ownerpubkey = ownerpubkey || defaultKey
        }

        console.log("privatekeyList:", privatekeyList)
        console.log("activepubkey:", activepubkey,"\n ownerpubkey:", ownerpubkey)

        //3.配置EOSJS
        eos = myUtils.getEOSJS(privatekeyList)

        //4.交易(创建账号)
        let data = await eos.transaction(tr => {
            tr.newaccount({
                creator: creator,
                name: account,
                owner: ownerpubkey,
                active: activepubkey
            })

            tr.buyrambytes({
                payer: creator,
                receiver: account,
                bytes: 8192
            })

            tr.delegatebw({
                from: creator,
                receiver: account,
                stake_net_quantity: '10.0000 EOS',
                stake_cpu_quantity: '10.0000 EOS',
                transfer: 0
            })
        })
        // console.log(JSON.stringify(data))

        //5.返回给前端执行的状态
        let resData
        if (data) {
            resData = success("创建账号成功")
        } else {
            resData = fail("创建账号失败")
        }
        ctx.body = resData
    },
}

3. router.js

将账号模块所有功能的接口绑定到路由。

......

//账号
router.post("/account/create", accountController.accountCreate)

//页面
router.get("/accountnew.html", webController.getAccountCreateHtml)

4. accountNew.html

在views文件夹下新建accountNew.html文件,实现前端创建账号的页面。




    新建账号
    
    
    
    



    

    

新建账号





以下内容可以选择填写




5. accountNew.js

在static/js文件夹下新建accountNew.js文件,前端处理新建账号的网络请求与页面的渲染。

function createKey() {
    let currentwallet = localStorage.getItem("currentwallet")
    let params = {"wallet": currentwallet, "type":"k1"}
    $.post("/wallet/createkey", params, function (res, status) {
        console.log(status, JSON.stringify(res))
        alert(res.data)
    })
}

$(document).ready(function () {
    let currentwallet = localStorage.getItem("currentwallet")
    $("h1").text(currentwallet+" 钱包")
    if (!currentwallet) {
        return
    }

    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 = $("#account-create-creator-select")
    for(let i = 0; accountList && i ${account}`
        accountSelectList.append(accountOption)
    }

    //新建账号
    $("#account-create-form").validate({
        rules: {
            name: {required: true,},
            creator: {required: true,},
        },
        messages: {
            name: {required: "请输入要新建的账号名称",},
            creator: {required: "该钱包没有可供新建账号的创者账号,可将该钱包的任意一个公钥发送给其它钱包新建该账号,或者导入其他账号的私钥到该钱包再进行新建账号"},
        },
        submitHandler: function (form) {
            $(form).ajaxSubmit({
                url: "/account/create",
                type: "post",
                dataType: "json",
                success: function (res, status) {
                    console.log(status + JSON.stringify(res))
                    if (res.code == 0) {
                        alert("账号新建成功")
                        window.location.href = history.go(-1);
                    } else {
                        alert("账号新建失败")
                    }
                },
                error: function (res, status) {
                    console.log(status + JSON.stringify(res))
                    alert(res.data)
                }
            });
        }
    })
})

四、项目源码一:查看账号详情

1. web.js

编辑controllers文件夹下的web.js文件,实现后端返回给前端账号详情的页面。

module.exports = {
    ......

    getAccountInfoHtml:async(ctx) => {
        await ctx.render("accountInfo.html")
    },
}

2. account.js

编辑controllers文件夹下的account.js文件,后端实现查看账号详情的功能。

module.exports = {
    ......

    accountBalance: async (ctx) => {
        let {code, account} = ctx.request.body
        let params = {"code":code,"account":account}
        let res = await httpRequest.postRequest(config.accountBalance, params)

        let currencyList = []
        if (res.code == 0) {
            for (const index in res.data) {
                let currency = res.data[index] //"9996.0000 EOS"
                let currencys = currency.split(" ")//currencys[0]=9996.0000, currencys[1]=EOS
                currencyList.push({
                    "symbol":currencys[1], 
                    "amount":currencys[0]
                })
            }
        }
        res.data = currencyList
        console.log("currencyList:", currencyList)
        res.data = currencyList
        ctx.body = res
    },

    accountInfo: async (ctx) =>{
        let {account} = ctx.request.body
        let res = await httpRequest.postRequest(config.accountInfo, {"account_name":account})
        ctx.body = res
    },
}

3. router.js

将查看账号详情的接口绑定到路由。

......

//账号
router.post("/account/balance", accountController.accountBalance)
router.post("/account/info", accountController.accountInfo)

//页面
router.get("/accountinfo.html", webController.getAccountInfoHtml)

4. accountInfo.html

在views文件夹下新建accountInfo.html文件,实现前端账号详情的页面。




    账号详情
    
    
    
    



    

    

代币 金额
权限 阈值 公钥 私钥 权重

5. accountInfo.js

在static/js文件夹下新建accountInfo.js文件,前端处理查看账号详情的网络请求与页面的渲染。

function getAccountPermissionPrivateKey(publicKey) {
    let currentwallet = localStorage.getItem("currentwallet")
    let currentPassword = localStorage.getItem(currentwallet)
    let params = {"wallet":currentwallet, "password":currentPassword, "publickey":publicKey}
    console.log(params)
    $.post("/wallet/privatekey", params, function (res, status) {
        console.log(status, JSON.stringify(res))
        alert(JSON.stringify(res.data))
    })
}

$(document).ready(function () {
    let currentAccount = localStorage.getItem("currentAccount")
    $("h1").text(currentAccount+" 账号")
    if (!currentAccount) {
        return
    }

    //账号金额
    let params = {"code":"eosio.token","account":currentAccount}
    $.post("/account/balance", params, function (res, status) {
        console.log(status + JSON.stringify(res))
        //后端返回的数据结构如下
        //[{"symbol":"EOS", "amout":100}, {"symbol":"SYS", "amount":200}]
        if (res.code == 0) {
            let balanceTable = $("#account-balance-table")
            res.data.forEach(balanceData => {
                let balanceTr = `
                    ${balanceData.symbol}
                    ${balanceData.amount}
                `
                balanceTable.append(balanceTr)
            });
        }
    })

    //账号权限详情
    $.post("/account/info", {"account":currentAccount}, function (res, status) {
        console.log(status + JSON.stringify(res))
        if (res.code == 0) {
            let permissionTable = $("#account-permission-table")
            for (const index in res.data.permissions) {
                let permission = res.data.permissions[index]
                let publicKey = permission.required_auth.keys[0].key
                let rowTr = `
                    ${permission.perm_name}
                    ${permission.required_auth.threshold}
                    ${publicKey}
                    
                    ${permission.required_auth.keys[0].weight}
                `
                permissionTable.append(rowTr)

                for(let i = 1; i 
                        
                        
                        ${keyData.key}
                        
                        ${keyData.weight}
                    `
                    permissionTable.append(rowTr)
                };
            };
        }
    })
})

五、项目运行效果

  1. 获取钱包mywallet1的账号列表如下

  1. 新建账号的效果如下在mywallet1钱包中使用账号lixu新建账号account1,控制的权限的两个公钥都是一样的,对应的私钥并且在mywallet2钱包中的,所以创建后将会在mywallet2钱包中看到该账号。

  1. 查看账号详情我们查看使用cleos配置的多个主体共同管理的账号lixu,为了简化前端的代码量,只显示了主体是公钥的数据,并没有显示主体是账号的数据,其中的一个公私钥主体无权获取私钥,因为它没有到当前钱包中。

项目源码Github地址

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

未经授权禁止转载、改编,转载请注明出处!

去新建账号

去新建账号

新建账号





以下内容可以选择填写




以下内容可以选择填写

代币 金额
权限 阈值 公钥 私钥 权重

未经授权禁止转载、改编,转载请注明出处!