ethers.js官方推荐的MetaMask操作:https://docs.ethers.io/ethers.js/html/cookbook-providers.html?highlight=metamask#metamask
Providers.js(最终要选择MetaMask还是ethers选择的提供者)
//Providers.js(最终要选择MetaMask还是ethers选择的提供者)
import { ethers } from 'ethers';
export default class Providers {
static isMetaMaskProvider () {
return Boolean( window.web3 && window.web3.currentProvider );
}
static createProvider () {
if (Providers.isMetaMaskProvider()) {
// 基于浏览器插件MetaMask插件节点
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 );
}
}