天天看點

005 以太坊錢包開發-賬戶轉賬

賬戶轉賬主要分為兩部分:

* 根據 privateKey 和 keystore 擷取賬戶私鑰及位址

* 通過私鑰簽名交易實作轉賬

通過 privateKey 擷取賬戶私鑰及位址

通過調用

web3.eth.accounts.privateKeyToAccount(privateKey)

就可以通過私鑰擷取相應的使用者資訊。

async getAccountByPrivatekey(ctx) {

        let returnResult = {
            code: ,
            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: ,
            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')[].files[]);
        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 == ) {
                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: ,
            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

啟動私有網絡

開啟本地挖礦

啟動項目

$ cd myWallet
$ node index.js
           

通路 http://localhost:3000/transaction 檢視項目:

005 以太坊錢包開發-賬戶轉賬

源碼下載下傳

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

關注公衆号
005 以太坊錢包開發-賬戶轉賬

繼續閱讀