文章目录

记一下node环境使用ethers.js的一个坑

由 Rorical 发布

在用electron写项目,需要用到以太坊的公私钥签名,就导入了ethers.js

但是使用wallet.encrypt报错

WARNING: Missing strong random number source
(node:9688) UnhandledPromiseRejectionWarning: Error: no secure random source avaialble (operation="crypto.getRandomValues", code=UNSUPPORTED_OPERATION, version=random/5.3.0)

没有足够随机的熵源。。
找了半天,终于在ethers的库里面发现了random.js
@ethersproject\random\lib.esm 下面

const logger = new Logger(version);
let anyGlobal = null;
try {
    anyGlobal = window;
    if (anyGlobal == null) {
        throw new Error("try next");
    }
}
catch (error) {
    try {
        anyGlobal = global;
        if (anyGlobal == null) {
            throw new Error("try next");
        }
    }
    catch (error) {
        anyGlobal = {};
    }
}
let crypto = anyGlobal.crypto || anyGlobal.msCrypto;
if (!crypto || !crypto.getRandomValues) {
    logger.warn("WARNING: Missing strong random number source");
    crypto = {
        getRandomValues: function (buffer) {
            return logger.throwError("no secure random source avaialble", Logger.errors.UNSUPPORTED_OPERATION, {
                operation: "crypto.getRandomValues"
            });
        }
    };
}
export function randomBytes(length) {
    if (length <= 0 || length > 1024 || (length % 1)) {
        logger.throwArgumentError("invalid length", "length", length);
    }
    const result = new Uint8Array(length);
    crypto.getRandomValues(result);
    return arrayify(result);
}

看来它是会分别在windows和global下寻找一次crypto,并且使用getRandomValues生成随机数。既然如此我们就给他定义一下

import Crypto from 'crypto'
global.crypto = {
    getRandomValues: (array) => {
        let length = array.length
        let random = Crypto.randomBytes(length)
        random.forEach((value, index) => {
            array[index] = value
        })
    }
}

这段代码放在引入ethers库的前面,然后

const { ethers } = require("ethers")

注意不要使用静态型import导入,用require才会分执行顺序


暂无评论

发表评论