Dapp开发

Web3.js的decrypt接口报错问题

2018-06-15  本文已影响105人  yuyangray

decrypt方法英文文档
http://web3js.readthedocs.io/en/1.0/web3-eth-accounts.html#decrypt

使用此接口,传入账户的keyStore和password,可以获取到账户的地址和私钥:

web3.eth.accounts.decrypt({
    version: 3,
    id: '04e9bcbb-96fa-497b-94d1-14df4cd20af6',
    address: '2c7536e3605d9c16a7a3d7b1898e529396a65c23',
    crypto: {
        ciphertext: 'a1c25da3ecde4e6a24f3697251dd15d6208520efc84ad97397e906e6df24d251',
        cipherparams: { iv: '2885df2b63f7ef247d753c82fa20038a' },
        cipher: 'aes-128-ctr',
        kdf: 'scrypt',
        kdfparams: {
            dklen: 32,
            salt: '4531b3c174cc3ff32a6a7a85d6761b410db674807b2d216d022318ceee50be10',
            n: 262144,
            r: 8,
            p: 1
        },
        mac: 'b8b010fff37f9ae5559a352a185e86f9b9c1d7f7a9f1bd4e82a5dd35468fc7f6'
    }
}, 'test!');
> {
    address: "0x2c7536E3605D9C16a7a3D7b1898e529396a65c23",
    privateKey: "0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318",
    signTransaction: function(tx){...},
    sign: function(data){...},
    encrypt: function(password){...}
}

现在有个需求,就是将此方法封装为接口使用:

/**
 * ETH根据keystore和密码返回账户密钥
 * @param {string} keystore 账户keystore
 * @param {string} password 账户password
 * @return {json}  账户信息
 */
// http://127.0.0.1:8084/eth/accounts/decrypt?keystore=keystore&password=password
router.get('/eth/accounts/decrypt', function(req, res) {
    // 表单验证
    if (typeof req.query.keystore !== 'string') {
        res.json({
            code: 20001,
            data: {},
            message: 'keystore 参数必须是一个字符串',
        })
    }
    if (typeof req.query.password !== 'string') {
        res.json({
            code: 20001,
            data: {},
            message: 'password 参数必须是一个字符串',
        })
    }

    // 执行逻辑
    let data = web3.eth.accounts.decrypt(req.query.keystore, req.query.password)


    // 返回结果
    res.json({
        code: 10000,
        message: 'ok',
        info: data,
    })
})

调用此方法报错:

TypeError: Cannot read property 'kdf' of undefined
    at Accounts.decrypt (/Users/yuyang/web3/node_modules/web3-eth-accounts/src/index.js:306:21)
    at /Users/yuyang/web3/index.js:183:34
    at Layer.handle [as handle_request] (/Users/yuyang/web3/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/yuyang/web3/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/yuyang/web3/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/yuyang/web3/node_modules/express/lib/router/layer.js:95:5)
    at /Users/yuyang/web3/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/Users/yuyang/web3/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/yuyang/web3/node_modules/express/lib/router/index.js:275:10)
    at Function.handle (/Users/yuyang/web3/node_modules/express/lib/router/index.js:174:3)
    at router (/Users/yuyang/web3/node_modules/express/lib/router/index.js:47:12)
    at Layer.handle [as handle_request] (/Users/yuyang/web3/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/Users/yuyang/web3/node_modules/express/lib/router/index.js:317:13)
    at /Users/yuyang/web3/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/Users/yuyang/web3/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/yuyang/web3/node_modules/express/lib/router/index.js:275:10)
    at expressInit (/Users/yuyang/web3/node_modules/express/lib/middleware/init.js:40:5)
    at Layer.handle [as handle_request] (/Users/yuyang/web3/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/Users/yuyang/web3/node_modules/express/lib/router/index.js:317:13)
    at /Users/yuyang/web3/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/Users/yuyang/web3/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/yuyang/web3/node_modules/express/lib/router/index.js:275:10)

可以在keystore文件中看到,kdfkeystore文件中的属性,在Crypto下,按理说有此属性是不会报错的。

根据报错信息,去/Users/yuyang/web3/node_modules/web3-eth-accounts/src/index.js306行查看,是这样写的:

 if (json.crypto.kdf === 'scrypt') 

keystore文件中的CryptoC是大写的

回去处理下代码,转换为小写:

/**
 * ETH根据keystore和密码返回账户密钥
 * @param {string} keystore 账户keystore
 * @param {string} password 账户password
 * @return {json}  账户信息
 */
// http://127.0.0.1:8084/eth/accounts/decrypt?keystore=keystore&password=password
router.get('/eth/accounts/decrypt', function(req, res) {
    // 表单验证
    if (typeof req.query.keystore !== 'string') {
        res.json({
            code: 20001,
            data: {},
            message: 'keystore 参数必须是一个字符串',
        })
    }
    if (typeof req.query.password !== 'string') {
        res.json({
            code: 20001,
            data: {},
            message: 'password 参数必须是一个字符串',
        })
    }

    // 执行逻辑
    let data = web3.eth.accounts.decrypt(req.query.keystore.toLowerCase(), req.query.password)


    // 返回结果
    res.json({
        code: 10000,
        message: 'ok',
        info: data
    })
})

再次调用就正常了

另外此方法返回的privateKey带了0x,直接使用进行签署交易会失败。这里同时处理一下,修改下代码,去掉前缀0x

/**
 * ETH根据keystore和密码返回账户密钥
 * @param {string} keystore 账户keystore
 * @param {string} password 账户password
 * @return {json}  账户信息
 */
// http://127.0.0.1:8084/eth/accounts/decrypt?keystore=keystore&password=password
router.get('/eth/accounts/decrypt', function(req, res) {
    // 表单验证
    if (typeof req.query.keystore !== 'string') {
        res.json({
            code: 20001,
            data: {},
            message: 'keystore 参数必须是一个字符串',
        })
    }
    if (typeof req.query.password !== 'string') {
        res.json({
            code: 20001,
            data: {},
            message: 'password 参数必须是一个字符串',
        })
    }

    // 执行逻辑
    let data = web3.eth.accounts.decrypt(req.query.keystore.toLowerCase(), req.query.password)


    // 返回结果
    res.json({
        code: 10000,
        message: 'ok',
        info: {
            address: data.address,
            privateKey: data.privateKey.substr(2),
        },
    })
})
上一篇 下一篇

猜你喜欢

热点阅读