如何将 ethers.js 与元掩码连接起来?
Posted
技术标签:
【中文标题】如何将 ethers.js 与元掩码连接起来?【英文标题】:How to connect ethers.js with metamask? 【发布时间】:2020-07-02 06:25:21 【问题描述】:我正在使用 ethers.js 文档:https://docs.ethers.io/ethers.js/html/cookbook-providers.html。 设置提供程序时出现错误 -: Uncaught ReferenceError: web3 is not defined 我想将我的分散式应用程序与元掩码连接起来。 为此,我试图通过根据文档设置提供程序来将元掩码与 ethers.js 连接起来。 我使用了 provider = new ethers.providers.Web3Provider(web3.currentProvider)。但它会为代码中的 web3 对象抛出错误。此代码与文档完全相同。但还是不行。
//let provider = new ethers.getDefaultProvider('rinkeby');
let provider = new ethers.providers.Web3Provider(web3.currentProvider);
let contract;
let wallet;
let abi = [
"anonymous": false,
"inputs": [
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
,
"indexed": false,
"internalType": "string",
"name": "pwd",
"type": "string"
],
"name": "Pwd_Assigned",
"type": "event"
,
"inputs": [
"internalType": "string",
"name": "_passwd",
"type": "string"
],
"name": "setPwd",
"outputs": [
"internalType": "bool",
"name": "success",
"type": "bool"
],
"stateMutability": "nonpayable",
"type": "function"
,
"inputs": [
"internalType": "string",
"name": "_uname",
"type": "string"
],
"name": "setUname",
"outputs": [
"internalType": "bool",
"name": "success",
"type": "bool"
],
"stateMutability": "nonpayable",
"type": "function"
,
"inputs": [
"internalType": "string",
"name": "_uType",
"type": "string"
],
"name": "setUtype",
"outputs": [
"internalType": "bool",
"name": "success",
"type": "bool"
],
"stateMutability": "nonpayable",
"type": "function"
,
"anonymous": false,
"inputs": [
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
,
"indexed": false,
"internalType": "string",
"name": "utype",
"type": "string"
],
"name": "Type_Assigned",
"type": "event"
,
"anonymous": false,
"inputs": [
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
,
"indexed": false,
"internalType": "string",
"name": "uname",
"type": "string"
],
"name": "Username_Assigned",
"type": "event"
,
"inputs": [],
"name": "getContractName",
"outputs": [
"internalType": "string",
"name": "_name",
"type": "string"
],
"stateMutability": "view",
"type": "function"
,
"inputs": [],
"name": "name",
"outputs": [
"internalType": "string",
"name": "",
"type": "string"
],
"stateMutability": "view",
"type": "function"
,
"inputs": [
"internalType": "address",
"name": "",
"type": "address"
],
"name": "pwd",
"outputs": [
"internalType": "string",
"name": "",
"type": "string"
],
"stateMutability": "view",
"type": "function"
,
"inputs": [],
"name": "symbol",
"outputs": [
"internalType": "string",
"name": "",
"type": "string"
],
"stateMutability": "view",
"type": "function"
,
"inputs": [
"internalType": "address",
"name": "",
"type": "address"
],
"name": "uname",
"outputs": [
"internalType": "string",
"name": "",
"type": "string"
],
"stateMutability": "view",
"type": "function"
,
"inputs": [
"internalType": "address",
"name": "",
"type": "address"
],
"name": "uType",
"outputs": [
"internalType": "string",
"name": "",
"type": "string"
],
"stateMutability": "view",
"type": "function"
];
let contractAddress = "0xECFFa8439Fa4DC64388227fA43a420449E895c3f"; // for rinkeby
let AidTokenAbi = [
"inputs": [
"internalType": "uint256",
"name": "_initialSupply",
"type": "uint256"
],
"stateMutability": "nonpayable",
"type": "constructor"
,
"anonymous": false,
"inputs": [
"indexed": true,
"internalType": "address",
"name": "_owner",
"type": "address"
,
"indexed": true,
"internalType": "address",
"name": "_spender",
"type": "address"
,
"indexed": false,
"internalType": "uint256",
"name": "_value",
"type": "uint256"
],
"name": "Approval",
"type": "event"
,
"inputs": [
"internalType": "address",
"name": "_spender",
"type": "address"
,
"internalType": "uint256",
"name": "_value",
"type": "uint256"
],
"name": "approve",
"outputs": [
"internalType": "bool",
"name": "success",
"type": "bool"
],
"stateMutability": "payable",
"type": "function"
,
"inputs": [
"internalType": "address",
"name": "_to",
"type": "address"
,
"internalType": "uint256",
"name": "_value",
"type": "uint256"
],
"name": "transfer",
"outputs": [
"internalType": "bool",
"name": "success",
"type": "bool"
],
"stateMutability": "payable",
"type": "function"
,
"anonymous": false,
"inputs": [
"indexed": true,
"internalType": "address",
"name": "_from",
"type": "address"
,
"indexed": true,
"internalType": "address",
"name": "_to",
"type": "address"
,
"indexed": false,
"internalType": "uint256",
"name": "_value",
"type": "uint256"
],
"name": "Transfer",
"type": "event"
,
"inputs": [
"internalType": "address",
"name": "_from",
"type": "address"
,
"internalType": "address",
"name": "_to",
"type": "address"
,
"internalType": "uint256",
"name": "_value",
"type": "uint256"
],
"name": "transferFrom",
"outputs": [
"internalType": "bool",
"name": "success",
"type": "bool"
],
"stateMutability": "payable",
"type": "function"
,
"inputs": [
"internalType": "address",
"name": "",
"type": "address"
,
"internalType": "address",
"name": "",
"type": "address"
],
"name": "allowance",
"outputs": [
"internalType": "uint256",
"name": "",
"type": "uint256"
],
"stateMutability": "view",
"type": "function"
,
"inputs": [
"internalType": "address",
"name": "",
"type": "address"
],
"name": "balanceOf",
"outputs": [
"internalType": "uint256",
"name": "",
"type": "uint256"
],
"stateMutability": "view",
"type": "function"
,
"inputs": [],
"name": "name",
"outputs": [
"internalType": "string",
"name": "",
"type": "string"
],
"stateMutability": "view",
"type": "function"
,
"inputs": [],
"name": "standard",
"outputs": [
"internalType": "string",
"name": "",
"type": "string"
],
"stateMutability": "view",
"type": "function"
,
"inputs": [],
"name": "symbol",
"outputs": [
"internalType": "string",
"name": "",
"type": "string"
],
"stateMutability": "view",
"type": "function"
,
"inputs": [],
"name": "tokensSold",
"outputs": [
"internalType": "uint256",
"name": "",
"type": "uint256"
],
"stateMutability": "view",
"type": "function"
,
"inputs": [],
"name": "totalSupply",
"outputs": [
"internalType": "uint256",
"name": "",
"type": "uint256"
],
"stateMutability": "view",
"type": "function"
];
let AidtokenAddress = "0x17b0e97DF8217a984294De6bDbbb9D7020190479";
let AidTokenContract;
let signer = provider.getSigner();
let usr_account;
function loadWallet()
signer.getAddress().then(async(res)=>
usr_account = res;
await console.log(usr_account);
);
// async function setProvider()
// provider = await new ethers.providers.JsonRpcProvider('http://127.0.0.1:8545');
//
function getContract()
contract = new ethers.Contract(contractAddress,abi, signer);
console.log(contract.functions);
function getTokenContract()
AidTokenContract = new ethers.Contract(AidtokenAddress,AidTokenAbi, signer);
async function getName()
// var name = await contract.functions.getContractName();
// console.log(name);
await contract.name().then(async (res)=>
await console.log(res);
);
async function setInfo(event)
event.preventDefault();
loadWallet();
getContract();
var uname = document.getElementById('uname').value;
var pwd = document.getElementById('psw').value;
var utype = document.getElementById('utype').value;
await contract.functions.setUname(uname).then(async(res)=>
console.log(res);
);
await contract.functions.setUtype(utype).then(async(res)=>
console.log(res);
);
await contract.functions.setPwd(pwd).then(async(res)=>
console.log(res);
);
//getInfo();
async function getInfo(event)
event.preventDefault();
var uname;
var utype;
var pwd;
loadWallet();
getContract();
await contract.functions.uname(usr_account).then(async(res)=>
uname=res;
console.log(res);
);
await contract.functions.uType(usr_account).then(async(res)=>
utype = res;
console.log(res);
);
await contract.functions.pwd(usr_account).then(async(res)=>
pwd=res
console.log(res);
);
async function transfer(event)
event.preventDefault();
loadWallet();
getTokenContract();
await console.log(".....");
var numberOfTokens = document.getElementById('numberOfTokens').value;
await AidTokenContract.functions.transfer(numberOfTokens,
from: usr_account,
gasLimit: 500000
);
//setProvider();
loadWallet();
getContract();
//getName();
// setInfo();
//getInfo();
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcode-generator/1.4.3/qrcode.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<!-- <script src="js/web3.min.js"></script> -->
<script charset="utf-8"
src="https://cdn.ethers.io/scripts/ethers-v4.min.js" type="text/javascript">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.js"></script>
</head>
<body>
<form onsubmit="setInfo(event)">
<div>
<h1>Register</h1>
<p>Please fill in this form to create an account.</p>
<hr>
<br>
<label for="uname"><b>User Name</b></label>
<input type="text" placeholder="Enter Username" id="uname" required>
<br>
<label for="utype">Choose a User type:</label>
<select id="utype" name="utype">
<option value="Donor">Donor</option>
<option value="NGO">NGO</option>
<option value="Government">Government</option>
</select>
<br>
<label for="psw"><b>Password</b></label>
<input type="password" placeholder="Enter Password" id="psw" required>
<!-- <label for="psw-repeat"><b>Repeat Password</b></label>
<input type="password" placeholder="Repeat Password" name="psw-repeat" required>
<hr> -->
<p>By creating an account you agree to our <a href="#">Terms & Privacy</a>.</p>
<button type="submit" id="registerbtn">Register</button>
</div>
<div class="container signin">
<p>Already have an account? <a href="#">Sign in</a>.</p>
</div>
</form>
<br><br>
<form onsubmit="getInfo(event)">
<button type="submit" >Get Info</button>
</form>
<form onsubmit="transfer(event)">
<input id="numberOfTokens" type="number" name="number" value="1" min="1" pattern="[0-9]">
<button type="submit" >Donate</button>
</form>
<!-- <script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min.js"></script> -->
<script src="js/app.js"></script>
</body>
</html>
Getting this error while setting the provider-Uncaught ReferenceError: web3js is not defined
【问题讨论】:
【参考方案1】:使用 ethers.js 与 Metamask 交互
const provider = new ethers.providers.Web3Provider(window.ethereum, "any");
// Prompt user for account connections
await provider.send("eth_requestAccounts", []);
const signer = provider.getSigner();
console.log("Account:", await signer.getAddress());
【讨论】:
谢谢,你能分享一下文档网址吗? 注意,还需要调用window. ethereum.enable() 首先。 @whileone 为什么需要它? 根据eips.ethereum.org/EIPS/eip-1102,方法ethereum.enable()
代替.send('eth_requestAccounts')
已被弃用
Ethers docs for Metamask 应该更新【参考方案2】:
我也觉得这很令人困惑。根据ethers.js documentation for Metamask,需要以下内容:
const provider = new ethers.providers.Web3Provider(web3.currentProvider);
const signer = provider.getSigner();
但这会导致错误:特别是 web3.currentProvider
无法识别。
Ethers.js github 问题日志有一个similar complaint at Issue #433。因此,以此为指导,我使用window.ethereum
代替web3.currentProvider
,并且还预先包含了.enable()
:
await window.ethereum.enable()
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
或者(在异步函数之外):
let provider;
window.ethereum.enable().then(provider = new ethers.providers.Web3Provider(window.ethereum));
const signer = provider.getSigner();
这会清除错误,并确保 Metamask 在连接到浏览器/DApp 之前请求许可。
【讨论】:
方法“ethereum.enable()”现在已被弃用,代替了“ethereum.send('eth_requestAccounts')”。根据以下'eips.ethereum.org/EIPS/eip-1102'【参考方案3】:window.ethereum.enable()
已弃用。
你应该使用:
ethereum.request( method: 'eth_requestAccounts' )
【讨论】:
您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。以上是关于如何将 ethers.js 与元掩码连接起来?的主要内容,如果未能解决你的问题,请参考以下文章