美文网首页以太坊钱包
005 以太坊钱包开发-账户转账

005 以太坊钱包开发-账户转账

作者: 时光记忆forever | 来源:发表于2018-07-29 22:06 被阅读200次

    账户转账主要分为两部分:

    • 根据 privateKeykeystore 获取账户私钥及地址
    • 通过私钥签名交易实现转账

    通过 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 查看项目:

    image

    源码下载

    https://github.com/didianV5/web3EthWallet/tree/master/005_myWallet

    关注公众号


    关注公众号

    相关文章

      网友评论

        本文标题:005 以太坊钱包开发-账户转账

        本文链接:https://www.haomeiwen.com/subject/eabtvftx.html