账户转账主要分为两部分:
- 根据 privateKey 和 keystore 获取账户私钥及地址
- 通过私钥签名交易实现转账
通过 privateKey 获取账户私钥及地址
通过调用 web3.eth.accounts.privateKeyToAccount(privateKey)
就可以通过私钥获取相应的用户信息。
async getAccountByPrivatekey(ctx) {
let returnResult = {
code: 0,
msg: '成功!',
data: {}
}
const data = ctx.request.body
const privateKey = data.privateKey
// 根据私钥获取用户地址
const account = web3.eth.accounts.privateKeyToAccount(privateKey)
// 查询账户的余额
const balance = await web3.eth.getBalance(account.address)
const ethNum = web3.utils.fromWei(balance, 'ether')
returnResult.data.address = account.address
returnResult.data.privateKey = account.privateKey
returnResult.data.balance = ethNum
ctx.body = returnResult
},
通过 keystore 获取账户私钥及地址
通过读取 keystore 里面存储的JSON数据及密码,通过调用 web3.eth.accounts.decrypt(keystoreStr,password)
可以获取用户的私钥及地址。
async getAccountByKeystore(ctx) {
let returnResult = {
code: 0,
msg: '成功!',
data: {}
}
const data = ctx.request.body; // 获取上传文件
const keystoreFile = ctx.request.files.file
const filePath = keystoreFile.path
// 获取 keystore 里面的json字符串
const keystoreStr = await fileUtil.readFile(filePath)
// 获取账户的密码
const password = data.password
// 获取账户的信息地址及私钥
const account = web3.eth.accounts.decrypt(keystoreStr,password)
const balance = await web3.eth.getBalance(account.address)
const ethNum = web3.utils.fromWei(balance, 'ether')
returnResult.data.address = account.address
returnResult.data.privateKey = account.privateKey
returnResult.data.balance = ethNum
ctx.body = returnResult
}
获取 keystore 里面的json字符串,代码实现:
readFile(fPath) {
return new Promise(function (resolve, reject) {
fs.readFile(fPath, 'utf-8', function(err, data) {
if (err) reject(err);
else resolve(data);
});
});
}
上传keystore文件
页面通过 ajax 上传文件,需要构建 FormData
,页面上传文件的js 代码如下
function unlockByKeystore() {
var formData = new FormData();
formData.append('file', $('#file')[0].files[0]);
formData.append('password', $('#pwd').val());
$.ajax({
url: '/account/keystore',
type: 'POST',
cache: false,
data: formData,
processData: false,
contentType: false
}).done(function(res) {
console.log(res)
if (res.code == 0) {
const result = res.data
const address = result.address
const balance = result.balance
const privateKey = result.privateKey
$("#balanceDiv").html(balance+' ETH')
$("#addressDiv").html(address)
$("#currAccount").val(address)
$("#currAccountKey").val(privateKey)
}
}).fail(function(res) {});
}
发送交易
发送交易主要分为以下几点:
- 构建账单数据
- 用私钥对帐单数据进行签名
- 通过
web3.eth.sendSignedTransaction
发送签名的交易。
async sendTransaction (ctx) {
let returnResult = {
code: 0,
msg: '成功!',
data: {}
}
const data = ctx.request.body
const currentAccount = data.currAccount
const privateKey = data.privateKey
const reciptAccount = data.reciptAccount
const txValue = data.txValue
// 获取指定账户地址的交易数
let nonce = await web3.eth.getTransactionCount(currentAccount);
// 将 ether 转为 wei
let value = web3.utils.toWei(txValue,'ether');
// 获取当前gasprice
let gasPrice = await web3.eth.getGasPrice();
// 以太币转账参数
let txParms = {
from: currentAccount,
to: reciptAccount,
nonce: nonce,
gasPrice: gasPrice,
data: '0x00', // 当使用代币转账或者合约调用时
value: value // value 是转账金额
}
// 获取一下预估gas
let gas = await web3.eth.estimateGas(txParms);
txParms.gas = gas;
// 用密钥对账单进行签名
let signTx = await web3.eth.accounts.signTransaction(txParms,privateKey)
// 将签过名的账单进行发送
try {
await web3.eth.sendSignedTransaction(signTx.rawTransaction, function(error, hash){
if (!error) {
returnResult.data.hash = hash
} else {
returnResult.code = "101"
returnResult.msg = "失败!"
returnResult.data.error = error.message
}
})
} catch (error) {
console.log(error)
}
ctx.body = returnResult
}
修改路由文件
修改 routers/index.js
添加如下内容:
const transactionController = require("../controllers/transaction")
...
router.post('/account/privatekey',accountController.getAccountByPrivatekey)
router.post('/account/keystore',accountController.getAccountByKeystore)
router.get('/transaction', transactionController.transaction)
router.post('/transaction/send', transactionController.sendTransaction)
运行项目
启动私链网络
使用 geth
启动私有网络
$ geth --datadir ~/privatechain/data0 --networkid 110 --rpc console
开启本地挖矿
miner.start()
启动项目
$ cd myWallet
$ node index.js
访问 http://localhost:3000/transaction 查看项目:
源码下载
https://github.com/didianV5/web3EthWallet/tree/master/005_myWallet
关注公众号