layout: post title: “钱包项目整体架构设计” date: 2019-02-26 description: “以太坊钱包” tag: 以太坊,钱包 keywords: “钱包” —

本课程是以太坊钱包开发,后端使用的NodeJS搭建,客户端使用的web前端,VSCode开发工具,Ubuntu16.04开发环境,node v8.11.3,npm v5.6.0。 在Kovan测试网络上进行开发。

一、前端架构

咱们的开发重点是在后端实现上,因此为了让大家快速上手,web客户端没有使用其它流行的框架,这里只使用了jQuery框架简化代码,另外还有个jQuery Validate 插件简化了表单验证。

二、后端架构

这个钱包应用程序与以坊节点进行交互,使用web3.js库提供的jsAPI访问以太坊区块链数据,因此我们用NodeJS搭建后端服务,使用成熟的MVC架构,http框架是koa,需用到如下第三方库:

三、项目初始化

新建项目跟文件夹MyEtherWallet,然后按照如下步骤执行

lixu@ubuntu:~$ cd '/home/lixu/Documents/demo/MyEtherWallet' 
lixu@ubuntu:~/Documents/demo/MyEtherWallet$ npm init

然后不断回车初始化项目。然后后自动生成package.json文件,是项目包的配置文件,下面我们引入项目中需要用到的库,拷贝下面json到package.json文件的最后一个字段。

,
  "dependencies": {
    "bignumber": "^1.1.0",
    "ejs": "^2.6.1",
    "ethereumjs-tx": "^1.3.7",
    "koa": "^2.5.2",
    "koa-body": "^4.0.4",
    "koa-router": "^7.4.0",
    "koa-static": "^5.0.0",
    "koa-views": "^6.1.4",
    "web3": "^1.0.0-beta.35"
  }
  

项目的界面如下:

然后运行以下命令按照上面的依赖库。

npm install

下载完成后会将所有的依赖库下载到项目根目录自动新建的node_modules文件夹。

四、项目源码

按照如下结构搭建项目。

index.js

项目的入口文件。首先实例化koa对象,然后将koaBody、static、views、路由注册到中间件,服务绑定到3000端口。

let koa = require("koa")
//通过koa创建一个应用程序
let app = new koa()
//导入./router/route这个包,赋值给的router就是 ./router/router导出的数据
let router = require("./router/router")
let static = require("koa-static")
let path = require("path")
let views = require("koa-views")
let koaBody = require("koa-body")

app.use(async (ctx, next) => {
    console.log(`${ctx.method} ${ctx.url} ..........`)
    await next()
})

//针对于文件上传的时候,可以解析多个字段
app.use(koaBody({multipart:true}))
//注册静态文件的库到中间件
app.use(static(path.join(__dirname, "static")))
//注册模板引擎的库到中间件
app.use(views(path.join(__dirname, "views"), {extension:"ejs", map:{html:"ejs"}}))
app.use(router.routes())

console.log("正在监听3000端口")
app.listen(3000)

newaccount.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/wallet.js"></script>
    <link rel="stylesheet" href="/css/wallet.css">
</head>

<body>

    <%include block/nav.html%>

    <div id="main">
        创建账号
    </div>
</body>

</html>

前端的导航栏,使用$(“#nav”).load(“/html/nav.html”)方式载入。


<div id="nav">
    <div id="nav-center">
        <ul>
            <li><a href="http://www.kongyixueyuan.com">孔壹学院</a></li>
            <li><a href="/account/new.html">新建账户</a></li>
            <li><a href="/transaction.html">转账</a></li>
        </ul>
    </div>
</div>

myUtils.js

项目工具类,提供获取web3实例、返回给前端成功与失败的基本数据结构。

module.exports = {
    getweb3: () => {
        let Web3 = require("web3")
        var web3 = new Web3(Web3.givenProvider || 'https://kovan.infura.io/v3/bc76......ca805');

        return web3
    },

    success: (data) => {
        responseData = {
            code:0,
            status:"success",
            data:data
        }
        return responseData
    },

    fail: (msg) => {
        responseData = {
            code:1,
            status:"fail",
            msg:msg
        }
        return responseData
    }
}

wallet.js

前端唯一的js文件。

$(document).ready(function () {
    alert("welcome!")
})

wallet.css

前端唯一的css文件。

#main{
    /*background-color: #8bc34a;*/
    margin: 100px 50px 50px 50px;

}
.error{
    color: red;
}
a{
    color: black;
    text-decoration: none;
}
a:hover{
    color: #666;
}
body{
    margin: 0px;
}
.global-color{
    color: #0abc9c;
}
a[class=button]{
    background-color: beige;
    padding: 2px 10px;
    border: 1px solid gray;
}

/*导航-------------------------------------------------------------------------------------------------------*/
#nav{
    display: flex;
    justify-content: space-between;
    background-color: #0abc9c;
    position: fixed;
    top: 0px;
    left: 0px;
    right: 0px;
}
#nav li{
    display: inline-block;
    margin: 10px 2px;
}
#nav ul{
    padding: 0px;
}
#nav a{
    padding: 10px;
    font-size: 24px;
}
#nav-left{
    margin-left: 20px;
}
#nav-right{
    margin-right: 20px;
}

router.js

路由文件。

let router = require("koa-router")()

router.get("/", async (ctx) => {
    await ctx.render("newaccount.html")
})

module.exports = router

五、项目运行效果

参考资料

koa的github:https://github.com/koajs/koa

koa-views的github:https://github.com/queckezz/koa-views

koa-body的github:https://github.com/dlau/koa-body

koa-router的github:https://github.com/alexmingoia/koa-router

koa-static的github:https://github.com/koajs/static

ejs的github:https://github.com/tj/ejs

web3.js的github:https://github.com/ethereum/web3.js

ethereumjs-tx的github:https://github.com/ethereumjs/ethereumjs-tx

BIP39的github:https://github.com/bitcoinjs/bip39

ethereumjs-wallet的github:https://github.com/ethereumjs/ethereumjs-wallet

ethereumjs-util的github:https://github.com/ethereumjs/ethereumjs-util

项目源码Github地址

作者:李旭

来源:http://www.chaindesk.cn