• 那是从何处传来的钟声呢?偶尔听到那钟声,平添一份喜悦与向往之情。

【以太坊开发重磅推荐】基于ethers.js库同时兼容实现MetaMask钱包和独立的HDWallet钱包代码总结(真比web3.js强大不知道多少倍)

编程 Nanait 3年前 (2021-05-26) 1947次浏览 已收录 0个评论 扫描二维码

 ethers.js官方推荐的MetaMask操作:https://docs.ethers.io/ethers.js/html/cookbook-providers.html?highlight=metamask#metamask

Providers.js(最终要选择MetaMask还是 ethers 选择的提供者)

//Providers.js(最终要选择<a href="http://jinwei.fun/mdzztag/metamask" title="查看更多关于 MetaMask 的文章" target="_blank">MetaMask</a>还是 ethers 选择的提供者)
 
import { ethers } from 'ethers';
 
export default class Providers {
 
    static is<a href="http://jinwei.fun/mdzztag/metamask" title="查看更多关于 MetaMask 的文章" target="_blank">MetaMask</a>Provider () {
        return Boolean( window.web3 && window.web3.currentProvider );
    }
 
    static createProvider () {
        if (Providers.is<a href="http://jinwei.fun/mdzztag/metamask" title="查看更多关于 MetaMask 的文章" target="_blank">MetaMask</a>Provider()) {
            // 基于浏览器插件<a href="http://jinwei.fun/mdzztag/metamask" title="查看更多关于 MetaMask 的文章" target="_blank">MetaMask</a>插件节点
            return new ethers.providers.Web3Provider( window.web3.currentProvider );
        } else {
            // InfuraProvider 基于 infura.io 账号链接后面的 Token 令牌和 network【ropsten 是 3】
            // return new ethers.providers.InfuraProvider(
            //     3, 'ea9fcb17397d4e2994424dcd677d2a2f' );
            // 基于 infura.io 平台的 ropsten 测试节点(链接必须是 https 开头,否则会链接失败)
            // JsonRpcProvider 是基于 url 来连接!
            return new ethers.providers.JsonRpcProvider(
                'https://ropsten.infura.io/v3/ea9fcb17397d4e2994424dcd677d2a2f');
        }
    }
}

 MetamaskWallet.js(MetaMask 浏览器钱包)

//MetamaskWallet.js(MetaMask 浏览器钱包)
 
import Providers from '@/modules/icowallet/Providers';
 
export default class MetamaskWallet {
    constructor () {
        this.initProvider();
        this.signer = this.provider.getSigner();
    }
 
    initProvider () {
        if (!Providers.isMetaMaskProvider()) {
            throw Error( '您正在使用当前离线钱包,暂时不能使用 MetaMask 钱包或先退出当前离线钱包!' );
        }
        this.provider = this.provider = Providers.createProvider();
        console.log( '您正在使用的是 MetaMask 浏览器钱包!!!' );
    }
}

EthersWallet.js(ethers.js创建或导入钱包) 

import { Wallet } from 'ethers';
import Providers from './Providers.js';
 
export default class EthersWallet {
    constructor () {
        this.initProvider();
    }
 
    initProvider () {
        if (Providers.isMetaMaskProvider()) {
            throw Error( '浏览器已经提供了 MetaMask 钱包,不能再创建其他离线钱包了!' );
        }
        this.provider = this.provider = Providers.createProvider();
        console.log( '您正在使用的是离线钱包!!!' );
    }
 
    // 私钥生成钱包!
    generate_private_key_wallet ( private_key ) {
        return new Wallet( private_key, this.provider );
    }
 
    // 助记词生成钱包!
    generate_mnemonric_wallet ( mnemonric, path = `m/44'/60'/0'/0/0` ) {
        // 必须连接 provider 才是活跃钱包
        return Wallet.fromMnemonic( mnemonric, path ).connect( this.provider );
    }
 
    // keystore.json 文件生成钱包
    async generate_keystore_wallet ( keystore_json_string, password, progressCallback = null ) {
        // 必须连接 provider 才是活跃钱包
        let off_wallet = await Wallet.fromEncryptedJson( keystore_json_string, password, progressCallback );
        return off_wallet.connect( this.provider );
    }
 
    // 随机创建一个钱包
    create_new_wallet () {
        return Wallet.createRandom().connect( this.provider );
    }
}

BassContract.js(所有的合约都继承于此,开始于合约交互) 

import EthersWallet from './EthersWallet';
import MetamaskWallet from './MetamaskWallet';
import Providers from '@/modules/icowallet/Providers';
import { ethers } from 'ethers';
 
export default class BassContract {
    constructor ( mnemonric ) {
        this.initWallet( mnemonric );
        // 务必注意:钱包是实现了 Signer 接口,所以 active_wallet 中的一些属性是 signer 没有的【比如 address 属性】
        // 所以在后续实例中,只能调用 Signer 共有的方法,以免出错!【获取地址用 getAddress()方法】
        this.active_WalletOrSigner = this.signer || this.active_wallet;
    }
 
    initWallet ( mnemonric ) {
        if (Providers.isMetaMaskProvider()) {
            // 确定是 MetaMask 钱包
            this.signer = new MetamaskWallet().signer;
            console.log( 'MetaMask 之 this.signer', this.signer );
        } else {
            // 确定是 Ethers 自己创建或助记词导入的钱包!
            this.active_wallet = new EthersWallet().generate_mnemonric_wallet( mnemonric );
            console.log( 'ethers 钱包之 active_wallet 接口', this.active_wallet );
        }
    }
 
    createContract ( abi_data, bytecode ) {
        return new ethers.ContractFactory( abi_data, bytecode, this.active_WalletOrSigner );
    }
 
    createContractInstance ( contract_address, abi_data ) {
        return new ethers.Contract( contract_address, abi_data, this.active_WalletOrSigner );
    }
}

最后:务必注意:this.active_WalletOrSigner 要么是基于 MetaMask 的签名,要么是自定义的钱包,二者的属性和方法共用了 Signer,也有不同之处,一定要注意!


何处钟 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:【以太坊开发重磅推荐】基于 ethers.js 库同时兼容实现 MetaMask 钱包和独立的 HDWallet 钱包代码总结(真比 web3.js 强大不知道多少倍)
喜欢 (2)
[15211539367@163.com]
分享 (0)

您必须 登录 才能发表评论!