Skip to content

Commit b3456f4

Browse files
committed
feat: each user can only create a wallet via POST /users/:id/wallet
1 parent 043b341 commit b3456f4

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

app/controller/user.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,22 @@ class UserController extends Controller {
2323

2424
const address = ctx.params.address;
2525
const updates = ctx.request.body;
26-
// TODO: 检查权限 只有本人 或者 管理员 才有权修改
26+
// TODO: 检查权限 只有本人 或者 管理员 才有权限
2727
// ctx.throw(403, '无权限修改用户信息', { code: 'FORBIDDEN_UPDATE_USER', error: { address } });
2828
const user = await ctx.service.user.updateByAddress(address, updates);
2929
ctx.body = user;
3030
}
3131

32+
async createWallet() {
33+
const ctx = this.ctx;
34+
const user_id = ctx.params.id;
35+
36+
// TODO: 检查权限 只有本人 或者 管理员 才有权限
37+
// ctx.throw(403, '无权限创建钱包', { code: 'FORBIDDEN_CREATE_WALLET', error: { user_id } });
38+
const { address } = await ctx.service.user.createWallet(user_id);
39+
ctx.body = { address };
40+
}
41+
3242
}
3343

3444
module.exports = UserController;

app/router.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ module.exports = app => {
3636
router.get('/user', isUser, controller.user.current);
3737
router.get('/users/:address', controller.user.getUser);
3838
router.patch('/users/:address', controller.user.updateUser);
39+
router.post('/users/:id/wallet', controller.user.createWallet);
3940

4041
router.get('/likes', controller.like.list);
4142
router.post('/likes', isUser, controller.like.create);

app/service/user.js

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
'use strict';
22

33
const Service = require('egg').Service;
4-
4+
const secp256k1 = require('secp256k1/elliptic');
5+
const createKeccakHash = require('keccak');
6+
const crypto = require('crypto');
57
class UserService extends Service {
68

79
async create(user) {
@@ -18,10 +20,8 @@ class UserService extends Service {
1820
}
1921

2022
const exist_user = await ctx.model.User.find({ where: { mobile } });
21-
console.log(exist_user);
2223
if (exist_user) return exist_user;
2324

24-
2525
return ctx.model.User.create({ mobile });
2626
}
2727

@@ -90,6 +90,43 @@ class UserService extends Service {
9090
return this.getByAddress(address);
9191
}
9292

93+
// 创建钱包
94+
async createWallet(user_id) {
95+
const ctx = this.ctx;
96+
97+
const user = await ctx.model.User.find({ where: { id: user_id } });
98+
if (!user) {
99+
ctx.throw(400, `用户(id: ${user_id})不存在`, { code: 'USER_NOT_FOUND', errors: { user_id } });
100+
}
101+
if (user.address) {
102+
ctx.throw(400, `用户(id: ${user_id})已有钱包,无法创建新的`, { code: 'USER_ALREADY_HAS_WALLET', errors: { user_id, address: user.address } });
103+
}
104+
105+
let private_key = crypto.randomBytes(32);
106+
const publicKey = secp256k1.publicKeyCreate(private_key, false).slice(1);
107+
let address = createKeccakHash('keccak256').update(publicKey).digest()
108+
.slice(-20);
109+
private_key = private_key.toString('hex').toLowerCase();
110+
address = '0x' + address.toString('hex').toLowerCase();
111+
112+
await ctx.model.User.update({
113+
address,
114+
private_key
115+
}, {
116+
where: {
117+
id: user_id,
118+
address: null, // 如果同一个用户高并发打过来,可能会被更新多次, 所以不要用user.updates({address,private_key})
119+
private_key: null,
120+
},
121+
returning: true,
122+
});
123+
124+
return {
125+
address,
126+
private_key
127+
};
128+
}
129+
93130
}
94131

95132
module.exports = UserService;

0 commit comments

Comments
 (0)