在上一节中我们讲到了了如何使用web3调来用以太坊API,学习了如何创建账户,使用私钥签名交易,查询余额,转账等操作。本节我们将创建一个可视化的界面,来完成创建账户,转账、查询余额等功能。
目录:
打开命令行工具,新建一个文件夹 EthWallet_web3
mkdir EthWallet_web3
进入到项目目录中,使用NPM初始化
cd EthWallet_web3
npm init -y
使用参数 -y
可以直接生产package.json
文件,避免了总是输入回车下一步的麻烦。这是可以看到项目目录下生成了package.json
。
我们使用express
来作为项目后端,通过它来为前端页面提供调用接口。
npm install --save express
--save
参数可以使项目依赖保存在package.json
文件中。
安装body-parser
,这个库是用来支持post请求的。
npm install --save body-parser
最后,最重要的,我们还要安装web3
npm install --save web3
在项目根目录中新建 getWeb3.js
代码:
var Web3 = require('web3');
var web3;
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
} else {
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}
module.exports = web3;
最后通过module.exports = web3;
把web3实例对象导出,方便其他文件调用。
前端页面我使用了Bootstrap框架,你可以去https://getbootstrap.com/(英文)或者 http://www.bootcss.com/(中文)下载 Bootstrap。
并且使用了jQuery(https://jquery.com/)来方便DOM操作和ajax。
新建public
目录,把Bootstrap和jQuery(如果你使用CDN则不需要)放到public
目录下,新建index.html
文件。现在项目目录结构如下:
注意:这里面有一个 .gitignore的文件,这是git仓库的忽略配置文件,用来在推送远程仓库的时候忽略仓库里的某些文件。
如果你没有使用git的话,可以忽略这个文件,当它不存在好了。
接下来编辑前端页面,代码如下
Document
以太坊钱包
在项目根目录下新建index.js
,使用express创建一个服务器
var express = require("express");
var app = express();
app.listen(8081,function(){
console.log('server start...@8081')
});
配置静态文件路径
var path = require('path');
app.use(express.static(path.join(__dirname, 'public')));
这不操作的目的是吧 public
设置问静态文件路径,这样再浏览器访问public目录下的文件的时候,可以不用添加 public,比如如果想访问index.html,就可以直接在地址栏输入http://localhost:8081/index.html
,同样的,如果你注意的话,会发现我们在index.html里引用的bootstrap和jQuery也是如此
使用body-parser
中间件支持post请求
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
接下来,我们先添加一个接口,用来访问index.html,在index.js添加如下代码:
app.get("/", function(req, res){
res.sendFile(__dirname + "/public/index.html");
})
__dirname
这是一个全局变量,用来获取当前文件的路劲,这里用它获取到的是index.js
的路劲,我们通过拼接就得到了index.html
的文件绝对路径了。
__dirname + "/public/index.html"
接下来启动服务器,在命令行(注意要在当前项目目录下)执行
node index.js
命令行显示
然后打开浏览器,输入http://localhost:8081/
,回车
接下来我们添加一个接口用来获取所有账户,在index.js
中添加如下代码
//获取所有用户
app.get('/accounts',function(req,res){
web3.eth.getAccounts(function(error, result){
res.send(result)
})
})
然后前端页面也要相应的调用这个接口,修改index.html
,添加一对标签,在其中添加:
var accounts = {};
function gtAccounts(){
$.get('http://localhost:8081/accounts',function(accs){
console.log(accs)
for(var i = 0;i < accs.length;i++){
accounts[accs[i]] = 0;
}
for( k in accounts){
getBalance(k)
}
})
}
gtAccounts()
这里使用get的方式请求http://localhost:8081/accounts
接口,获取所有的账户,展示在页面。
后端接口:
//注册用户
app.post("/register", function(req, res){
var password = req.body.password;
console.log('password:');
console.log(password);
web3.eth.personal.newAccount(password)
.then(function(addr){
console.log('新增账户:',addr)
res.send({address:addr,balance:0})
});
})
前端页面调用如下:
$("#addaccount").click(function(){
if($("#password").val() != ""){
$.post('http://localhost:8081/register/',
{password:$("#password").val()},
function(res){
console.log(res)
accounts[res.address] = res.balance;
showAccountList();
})
}
$("#password").val("")
})
后端代码:
//发送以太币
app.post("/sendcoin", function(req, res){
var address_from = req.body.address_from;
var address_to = req.body.address_to;
var trans_value = req.body.trans_value;
var password = req.body.trans_password;
web3.eth.personal.unlockAccount(address_from,password,9999,function(){
console.log('unlock accounts ok')
web3.eth.sendTransaction({
from: address_from,
to: address_to,
value: web3.utils.toWei(trans_value,"ether"),
},function(err,transactionHash){
if(!err){
console.log('transactionHash:',transactionHash)
res.send({msg:"ok",hash:transactionHash});
}else{
console.log('-------------error-----------')
console.log(err)
console.log('-------------error-----------')
}
})
});
})
前端调用代码:
$("#trans_btn").click(function(){
var address_from = $("#address_from").val();
var address_to = $("#address_to").val();
var trans_value = $("#trans_value").val();
var trans_password = $("#trans_password").val();
if(address_from != '' && address_to != '' && trans_value != "" && trans_password != ""){
$.post("http://localhost:8081/sendcoin/",
{
address_from,
address_to,
trans_value,
trans_password
},function(res){
if(res.msg == 'ok'){
accounts[address_to] = trans_value;
showAccountList();
// getBalance(address_from)
// getBalance(address_to)
}
})
}
// $("#address_from").val("");
$("#address_to").val("");
$("#trans_value").val("");
$("#trans_password").val("");
})
后端代码
var express = require("express");
var app = express();
var path = require('path');
var bodyParser = require('body-parser');
// var BigNumber = require('bignumber.js');
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
var web3 = require("./getWeb3");
app.get("/", function(req, res){
res.sendFile(__dirname + "/public/index.html");
})
//获取所有用户
app.get('/accounts',function(req,res){
web3.eth.getAccounts(function(error, result){
res.send(result)
})
})
//注册用户
app.post("/register", function(req, res){
var password = req.body.password;
console.log('password:');
console.log(password);
web3.eth.personal.newAccount(password)
.then(function(addr){
console.log('新增账户:',addr)
res.send({address:addr,balance:0})
});
})
//查询余额
app.get("/getBalance", function(req, res){
var address = req.query.address;
web3.eth.getBalance(address).then(function(balance){
var ether = web3.utils.fromWei(balance, 'ether');
res.send(ether);
})
})
//发送以太币
app.post("/sendcoin", function(req, res){
var address_from = req.body.address_from;
var address_to = req.body.address_to;
var trans_value = req.body.trans_value;
var password = req.body.trans_password;
web3.eth.personal.unlockAccount(address_from,password,9999,function(){
console.log('unlock accounts ok')
web3.eth.sendTransaction({
from: address_from,
to: address_to,
value: web3.utils.toWei(trans_value,"ether"),
},function(err,transactionHash){
if(!err){
console.log('transactionHash:',transactionHash)
res.send({msg:"ok",hash:transactionHash});
}else{
console.log('-------------error-----------')
console.log(err)
console.log('-------------error-----------')
}
})
});
})
app.listen(8081,function(){
console.log('server start...@8081')
});
前端代码
Document
以太坊钱包
完整项目案例可以从github上下载:https://github.com/cooleye/web3_wallet