前言
之前我們使用Node.js+Web3.js
,創(chuàng)建錢包的時候,只返回了address
,privateKey
,keystore
,其實還應(yīng)該返回助記詞mnemonic
。助記詞,私鑰,公鑰,地址,密碼的關(guān)系,這里就不再解釋了,大家可以去自行了解。
老版本創(chuàng)建錢包代碼(不返回助記詞)
/**
* 創(chuàng)建錢包
*
* 參數(shù):1.password: 錢包密碼
*
* 返回:1.address: 賬號地址
* 2.privateKey: 私鑰
* 3.keystore: keystore
*
*/
router.get('/eth/account/createWallet', async(ctx, next) => {
if (typeof(ctx.request.query.password) == 'undefined' ||
ctx.request.query.password == '') {
ctx.body = await Promise.resolve({
code: 1,
data: {},
message: 'Missing parameter: password.',
})
return
}
try {
let account = web3.eth.accounts.create()
let response = web3.eth.accounts.encrypt(account.privateKey,
ctx.request.query.password)
ctx.body = await Promise.resolve({
code: 0,
address: account.address,
privateKey: account.privateKey.substr(2),
keystore: response,
message: 'Success',
})
} catch (error) {
ctx.body = await Promise.resolve({
code: 1,
data: {},
message: error.stack,
})
}
})
新版本創(chuàng)建錢包代碼(同時返回助記詞)
/**
* 創(chuàng)建錢包
*
* 參數(shù):1.password: 錢包密碼
*
* 返回:1.address: 地址
* 2.password: 錢包密碼
* 3.privateKey: 私鑰
* 4.publicKey: 公鑰
* 5.keystore: keystore
* 6.mnemonic:助記詞
*
*/
router.get('/eth/account/createWallet', async(ctx, next) => {
if (typeof(ctx.request.query.password) == 'undefined' ||
ctx.request.query.password == '') {
ctx.body = await Promise.resolve({
code: 1,
data: {},
message: 'Missing parameter: password.',
})
return
}
try {
// 1.生成助記詞
let mnemonic = bip39.generateMnemonic()
//2.將助記詞轉(zhuǎn)成seed
let seed = bip39.mnemonicToSeedSync(mnemonic)
//3.通過hdkey將seed生成HD Wallet
let hdWallet = hdkey.fromMasterSeed(seed)
//4.生成錢包中在m/44'/60'/0'/0/0路徑的keypair
let key = hdWallet.derivePath("m/44'/60'/0'/0/0")
//5.從keypair中獲取私鑰
let privateKey = util.bufferToHex(key._hdkey._privateKey)
//6.從keypair中獲取公鑰
let publicKey = util.bufferToHex(key._hdkey._publicKey)
//7.使用keypair中的公鑰生成地址
let address = util.pubToAddress(publicKey, true)
address = util.toChecksumAddress(address.toString('hex'))
//8.生成keystore
let keystore = web3.eth.accounts.encrypt(privateKey,
ctx.request.query.password)
ctx.body = await Promise.resolve({
code: 0,
address: address,
password: ctx.request.query.password,
privateKey: privateKey.substr(2),
publicKey: publicKey,
keystore: keystore,
mnemonic: mnemonic,
message: 'Success',
})
} catch (error) {
ctx.body = await Promise.resolve({
code: 1,
data: {},
message: error.stack,
})
}
})
需要使用三個新的包bip39
、ethereumjs-wallet/hdkey
、ethereumjs-util
。
首先安裝三個包:
npm install bip39
npm install ethereumjs-wallet
npm install ethereumjs-util
然后代碼里引用包:
var bip39 = require('bip39')
var hdkey = require('ethereumjs-wallet/hdkey')
var util = require('ethereumjs-util')
根據(jù)助記詞獲取錢包信息
/**
* 根據(jù)password和助記詞返回address, privateKey, publicKey, keystore
*
* 參數(shù):1.password: 錢包密碼
* 2.助記詞: 助記詞
*
* 返回:1.address: address
* 2.privateKey: privateKey
* 3.publicKey: publicKey
* 4.keystore: keystore
*
*/
router.get('/eth/account/getAccount', async(ctx, next) => {
let { password, mnemonic } = ctx.request.query
if (typeof(password) == 'undefined' ||
password == '') {
ctx.body = await Promise.resolve({
code: 1,
data: {},
message: 'Missing parameter: password.',
})
return
}
if (typeof(mnemonic) == 'undefined' ||
mnemonic == '') {
ctx.body = await Promise.resolve({
code: 1,
data: {},
message: 'Missing parameter: mnemonic.',
})
return
}
try {
//將助記詞轉(zhuǎn)成seed
let seed = bip39.mnemonicToSeedSync(mnemonic)
//通過hdkey將seed生成HDWallet
let hdWallet = hdkey.fromMasterSeed(seed)
//生成錢包中在m/44'/60'/0'/0/0路徑的keypair
let key = hdWallet.derivePath("m/44'/60'/0'/0/0")
//從keypair中獲取私鑰
let privateKey = util.bufferToHex(key._hdkey._privateKey)
//從keypair中獲取公鑰
let publicKey = util.bufferToHex(key._hdkey._publicKey)
//使用keypair中的公鑰生成地址
let address = util.pubToAddress(publicKey, true)
address = util.toChecksumAddress(address.toString('hex'))
//生成keystore
let keystore = web3.eth.accounts.encrypt(privateKey, password)
ctx.body = await Promise.resolve({
code: 0,
address: address,
privateKey: privateKey.substr(2),
publicKey: publicKey,
keystore: keystore,
message: 'Success',
})
} catch (error) {
ctx.body = await Promise.resolve({
code: 1,
data: {},
message: error.stack,
})
}
})