MongoDB的设置
// mongodb安装比较简单,这里就不介绍了, 大致上就是官网下载个安装包,双击运行
// https://docs.mongodb.com/manual/installation/
// 启动数据库 (窗口不能关)
// 启动mongodb的时候可能会遇到 /data/db/ 文件夹权限不够的情况,运行以下命令提权
// sudo chmod -R 0777 /data/db
$ mongod
// 开启另外一个命令行窗口,进入数据库
$ mongo
// 创建一个名为 faucet 的数据库
use faucet
// 创建一个名为 faucet 的集合
db.createCollection('faucet')
// 切换至admin数据库
use admin
// 创建admin数据库管理员,只是为了方便以后管理,不一定需要设置。
// 用户名tmd,密码123,权限:读写、用户管理
db.createUser({user:'tmd',pwd:'123',roles:[{role:'readWrite',db:'admin'},{role:'userAdminAnyDatabase',db:'admin'}]})
// 创建faucet数据库的可读写账号
// 要记住自己创建的用户与密码
db.createUser({user:'eos',pwd:'eos',roles:[{role:'readWrite',db:'faucet'}]})
到目前为止,数据库设置大致完成,现在需要把刚刚开启mongod 和 mongo 进程关闭,带认证参数重新启动一次
// --auth 参数是设置 (窗口不能关)
$ mongod --auth
// 如果是在linux环境下运行
// 编辑 /etc/mongod.conf文件,mongodb默认的配置文件
// 修改以下代码,设置成enabled。(这是3.0以上版的设置方式,旧版本就不介绍了)
security:
authorization: "enabled"
// linux环境下,在后台启动mongodb (窗口可以关)
$ sudo service mongod start
// 开启一个新命令行窗口进入数据库
$ mongo
// 进入数据库后,账号都需要进入admin数据库中进行验证,
use admin
// 这里输入刚才设置的用户名和密码,如果返回1表示认证通过
db.auth('eos','eos')
// 切换至faucet数据库
use faucet
// 展示集合,一切顺利的话会展示集合列表
show collections
mongodb数据库设置完成
附录
mongodb配置文件设置
https://docs.mongodb.com/manual/reference/configuration-options/
Express安装与项目初始化
// 全局安装一个 express-generator
$ npm install express-generator -g
// 初始化一个名为eos_faucet的项目
$ express eos_faucet
// 安装依赖包
$ cd eos_faucet
$ npm install eosjs@beta node-fetch text-encoding eosjs-ecc
- 编辑
/eos_faucet/app.js
文件,
// 在所有路由前面,设置允许跨域请求
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By",' 3.2.1');
res.header("Content-Type", "application/json;charset=utf-8");
next();
});
- 编辑
/eos_faucet/routes/index.js
文件
const express = require('express');
const router = express.Router();
const registerController = require('../controllers/register');
/* 保留get请求,测试服务器成功开启. */
router.get('/', function(req, res) {
res.send('you shall not pass')
});
// 增加一个post请求的路由,用于处理注册请求
router.post('/',registerController.register);
module.exports = router;
- 创建并编辑
/eos_faucet/controllers/register.js
文件 - 以下api调用涉及到eosjs库的调用,如果不熟悉请参考我的前一篇文章 NODE.JS 调用EOS API
const { Api, JsonRpc, JsSignatureProvider } = require('eosjs');
const fetch = require('node-fetch');
const { TextDecoder, TextEncoder } = require('text-encoding');
const registerModel = new require('../models/register');
// 设置一个账号,用于创建账号的,这个账号一定是存在并且有足够的EOS在里面的。
const admin = 'tmd555555555';
// 账号的私钥
const privateKey = "5KX4fnaQWhc6Coz9uqk9GWkjiA8q8R8ditSTDjKcHqsHCwnhJpR";
const signatureProvider = new JsSignatureProvider([privateKey]);
const rpc = new JsonRpc('http://junglehistory.cryptolions.io:18888', { fetch });
const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), textEncoder: new TextEncoder() });
exports.register = async (req, res) => {
try{
const result = await api.transact({
actions: [{
account: 'eosio',
name: 'newaccount',
authorization: [{
actor: admin,
permission: 'active',
}],
data: {
creator: admin,
name: req.body.username,
newact:req.body.username,
owner: {
threshold: 1,
keys: [{
key: req.body.publicKey,
weight: 1
}],
accounts: [],
waits: []
},
active: {
threshold: 1,
keys: [{
key: req.body.publicKey,
weight: 1
}],
accounts: [],
waits: []
},
},
}, {
account: 'eosio',
name: 'buyrambytes',
authorization: [{
actor: admin,
permission: 'active',
}],
data: {
payer: admin,
receiver: req.body.username,
bytes: 3000,
},
}, {
account: 'eosio',
name: 'delegatebw',
authorization: [{
actor: admin,
permission: 'active',
}],
data: {
from: admin,
receiver: req.body.username,
stake_net_quantity: '1.0000 EOS',
stake_cpu_quantity: '1.0000 EOS',
transfer: false,
}
}]
}, {
blocksBehind: 3,
expireSeconds: 30,
});
// 合约运行成功后把结果发给前端。
res.send(JSON.stringify(result))
}catch(err){
// 如果运行失败,把错误信息返回给前端。并且退出函数。
if(!!err.json){
res.send(JSON.stringify(err.json));
}else{
res.send(JSON.stringify(err));
}
return;
}
// 如果运行成功,把新用户信息存入数据库。运行失败的话,不会执行到这一步。
await registerModel.create({
username: req.body.username,
publicKey: req.body.publicKey,
creator: admin,
cost:'',
bytes:3000
});
};
- 创建并编辑
/eos_faucet/models/register.js
const mongoose = require('mongoose');
// 用账号和密码登录连接数据库,eos:eos这里的账号和密码都是eos,
// 地址127.0.0.1,mongodb默认设置了只能本地访问
// faucet,表示连接到faucet这个数据库
// 数据库的账号名是在admin数据库中建立的 所以需要添加 ?authSource=admin
mongoose.connect('mongodb://eos:eos@127.0.0.1/faucet?authSource=admin',{ useNewUrlParser: true } );
mongoose.Promise = global.Promise;
// 设置schema,虽然mongodb是非关系型数据库,但是一般都会给它设置模式
const registerSchema = new mongoose.Schema({
username:String,
publicKey:String,
creator: String,
cost:String,
bytes:Number,
// 创建日期,默认值写成当前时间
date:{type:Date, default:new Date()}
});
// 设置静态方法,给外外层调用
registerSchema.statics.save = async function({username, publicKey, creator, cost, bytes}){
return this.create({username, publicKey, creator, cost, bytes})
};
// 三个参数,第一个只是schema的名字,可以随便写,第二个是schema对象,第三个是数据库中集合的名字
module.exports = mongoose.model('register', registerSchema, 'faucet');
- 到目前Express设置完成,可以跑起来了
- 注意:服务器的端口可以在
./bin/www
设置,我把端口设置了5000
- 如果在产品环境运行,可以用
pm2
做进程守护,并且打开多线程模式,提高性能。
如果不了解,可以参考我这篇文章 部署node服务器到产品环境
// 只用于本地测试
$ npm start
// 产品环境开启进程守护和多线程
$ pm2 start ./bin/www -i max --env production
you shall not pass
在浏览器测试服务器是否开启成功,成功展示我们设置文本you shall not pass
,表示服务器已经正常开启
在postman测试一下请求,并收到成功的返回信息,表示流程没问题。
QQ20181101-164850@2x.pngmongo shell 中运行db.faucet.find({},{_id:0,__v:0}).sort({date:-1}).pretty()
查到最近一条记录是我刚刚在前端请求存入的信息,说明储存流程没问题。
网友评论