$ cd myWallet
# 安装koa模板使用中间件
$ npm install --save koa-views
# 安装ejs模板引擎
$ npm install --save ejs
修改 myWallet/index.js
,加载模版引擎
const Koa = require('koa');
const routers = require('./routers/index')
const koaBody = require('koa-body');
const views = require('koa-views')
const path = require('path')
const app = new Koa();
// 引入 koa-body 中间件
app.use(koaBody({
multipart: true
}));
// 加载模板引擎
app.use(views(path.join(__dirname, './view'), {
map : {html:'ejs'}
}))
// 初始化路由中间件
app.use(routers.routes()).use(routers.allowedMethods())
app.listen(3000);
console.log('server is starting at port 3000')
进入项目目录,新建 view
文件夹,新建 account.html
$ cd myWallet
$ mkdir view
$ vi account.html
account.html
代码如下:
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>fujinliang.toptitle>
<meta name="viewport" content="width=device-width, initial-scale=1">
head>
<body>
account
body>
html>
修改 controllers/account.js
,调用 ctx.render("account")
实现页面的跳转
module.exports = {
async getAccountList (ctx) {
await ctx.render("account")
}
}
通过 node index.js
启动项目, 通过访问 http://localhost:3000 查看结果,页面显示如下:
account
进入 https://getbootstrap.com/ 下载 bootstrap
如何存放 bootstrap
的样式文件?
需要引入静态文件目录
$ cd myWallet
$ npm install koa-static
修改 index.js 引入koa-static
...
const static = require('koa-static')
const app = new Koa();
// 静态资源目录对于相对入口文件index.js的路径
const staticPath = './static'
app.use(static(
path.join( __dirname, staticPath)
))
...
用户创建的主要流程:通过 web3.eth.accounts.create()
创建用户,会得到 account 的 地址及私钥。通过 account.encrypt(pwd)
生成keystore 的内容,同时通过 fs.writeFile
方法将内容写入到文件之中。
async createAccount (ctx) {
let returnResult = {
code: 0,
msg: '成功!',
data: {}
}
let data = ctx.request.body
const pwd = data.pwd
// 调用 web3 创建账户
let account = await web3.eth.accounts.create();
// encrypt 返回一个JSON 对象
const keystoreJson = await account.encrypt(pwd)
// 将 JSON 对象转为字符串
const keystoreStr = JSON.stringify(keystoreJson)
// 生成随机文件存储 keystore 的字符串
const randFilename = "UTC--"+new Date().toISOString()+"--"+account.address
// 设置存储文件的目录
const filePath =path.join(__dirname,"../static/keystore/"+randFilename)
// 将 keystore 的内容写入文件中
await fileUtil.writeFile(filePath,keystoreStr)
// 将 用户地址、私钥、keystore 数据返回
const result = {"account":account.address,"privateKey":account.privateKey,"keystore": config.keystoreUrl+randFilename}
returnResult.data = result
ctx.body = returnResult
},
将 keystore 的内容写到文件之中。
const fs = require("fs")
module.exports = {
readFile(fPath) {
return new Promise(function (resolve, reject) {
fs.readFile(fPath, function(err, data) {
if (err) reject(err);
else resolve(data);
});
});
},
writeFile(fPath, content) {
return new Promise(function(resolve, reject) {
fs.writeFile(fPath, content, function(err, data) {
if (err) reject(err);
else resolve("Successed");
});
});
}
}
修改 routers/index.js
,添加如下代码:
router.post('/account/create',accountController.createAccount)
创建钱包的页面主要包含以下功能:
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>fujinliang.toptitle>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" media="screen" href="/css/bootstrap.min.css" />
<style>
.account {
margin-top: 100px;
text-align: center;
}
style>
head>
<body>
<div class="container">
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link active" href="#">添加账户a>
li>
ul>
<div id="create" class="account">
<p style="font-size: 30px">新建一个账户p>
<p>输入密码p>
<div style="padding: 50px 100px">
<input type="text" class="form-control" id="pwd" placeholder="输入密码" />
div>
<button type="button" class="btn btn-primary" onclick="createAccount()">创建账户button>
div>
<div id="download" class="account" style="display: none" >
<p style="font-size: 30px">保存你的<span style="color: red">Keystorespan> 文件p>
<a id="downloadUrl" class="btn btn-success" href="#" role="button">下载 Keystore 文件 (UTC / JSON)a>
<div style="margin-top:100px">
<button onclick="showKey()" type="button" class="btn btn-primary">下一步button>
div>
div>
<div id="privateKey" class="account" style="display: none">
<p style="font-size: 30px">保存你的<span style="color: red">私钥span>p>
<textarea class="form-control" id="prikey" rows="3" disabled>textarea>
div>
div>
body>
<script src="/js/jquery-3.3.1.min.js">script>
<script>
function createAccount(){
var pwd = $("#pwd").val()
if (pwd == "") {
alert("密码不能为空!");
return
}
$.post("/account/create","pwd="+pwd, function(result){
alert(result.data)
if (result.code == 0) {
$("#create").hide()
$("#download").show()
$("#downloadUrl").attr("href", result.data.keystore)
alert(result.data.privateKey)
$("#prikey").html(result.data.privateKey)
}
})
}
function showKey(){
$("#download").hide()
$("#privateKey").show()
}
script>
html>
使用 geth
启动私有网络
$ geth --datadir ~/privatechain/data0 --networkid 110 --rpc console
$ cd myWallet
$ node index.js
访问 http://localhost:3000 查看项目:
https://github.com/didianV5/web3EthWallet/tree/master/004_myWallet
关注公众号