赞
踩
目录
本文记录Vue框架前端使用ethers.js开发web3钱包相关功能。主要是前端调用ethers.js的相关用法。
1.Provider 是一个连接以太坊网络的抽象,用与查询以太坊网络状态或者发送更改状态的交易。
2.Wallet 类管理着一个公私钥对用于在以太坊网络上密码签名交易以及所有权证明。
3.Signer 是一个抽象类,当需要签名器Signer 时就可以扩展实现它。主要用于对交易消息最新签名,发到后台需要验签。
4.Contracts 合约是在以太坊区块链上的可执行程序的抽象。合约具有代码 (称为字节代码) 以及分配的长期存储 (storage)。每个已部署的合约都有一个地址, 用它连接到合约, 可以向其发送消息来调用合约方法。
5.Utils 工具包提供了大量的通用实用函数去编写 dapps、处理用户输入和格式化数据等功能。
Provider | A Provider (in ethers) is a class which provides an abstraction for a connection to the Ethereum Network. It provides read-only access to the Blockchain and its status. | |
Signer | A Signer is a class which (usually) in some way directly or indirectly has access to a private key, which can sign messages and transactions to authorize the network to charge your account ether to perform operations. | |
Contract | A Contract is an abstraction which represents a connection to a specific contract on the Ethereum Network, so that applications can use it like a normal JavaScript object. |
Provider主要提供读属性,取得provider后可以查询账户信息及太坊状态。
- 1.连接以太坊:MetaMask
- //window.ethereum是一个以太坊对象,MetaMask会向网页注入一个全局的API变量window.ethereum
- //登录连接到MetaMask后可以获取provider
- const provider = new ethers.providers.Web3Provider(window.ethereum)
-
- 2.获取signer
- const signer = provider.getSigner();
- //调取MetaMask小狐狸钱包签名
- let msg = address+amount...;//约定好签名规则即可
- const signature = await signer.signMessage(msg);
-
- 3.获取账户余额
-
- provider.getBalance(address).then((balance) => {
-
- // 余额是 BigNumber (in wei); 格式化为 ether 字符串
- let etherString = ethers.utils.formatEther(balance);
-
- console.log("Balance: " + etherString);
- });
-
- 或者
- const balance = await provider.getBalance(address);
- // 余额是 BigNumber (in wei); 格式化为 ether 字符串,使用工具包格式化成字符串
- let balanceStr = ethers.utils.formatUnits(balance, 18);
-
- 4.获取交易数
-
- let address = "0x02F024e0882B310c6734703AB9066EdD3a10C6e0";
- provider.getTransactionCount(address).then((transactionCount) => {
- console.log("发送交易总数: " + transactionCount);
- });
-
- 5.获取当前状态
-
- //当前的区块号
- provider.getBlockNumber().then((blockNumber) => {
- console.log("Current block number: " + blockNumber);
- });
-
- //当前的gas费
- provider.getGasPrice().then((gasPrice) => {
- // gasPrice is a BigNumber; convert it to a decimal string
- gasPriceString = gasPrice.toString();
-
- console.log("Current gas price: " + gasPriceString);
- });
-
-
- 1.监听事件,监听小狐狸钱包余额变化
- let address = '';
- this.provider.on(address, (bal) => {});
-
- 2.监听区块
- provider.on("block", (blockNumber) => {
- // Emitted on every block change
- console.log("blockNumber: " + blockNumber);
- })
Wallet实现了Signer,所以交易时使用Wallet就行。
本人目前没有使用到wallet对象,目前使用的是后端开发的合约方式。
- 1.创建钱包-随机钱包
-
- //Wallet . createRandom ( [ options ] ) => Wallet
- //创建一个随机钱包实例。 确保钱包(私钥)存放在安全的位置,如果丢失了就没有办法找回钱包。
- let randomWallet = ethers.Wallet.createRandom();
-
- 2.创建钱包-加载JSON钱包文件
-
- let data = {
- id: "fb1280c0-d646-4e40-9550-7026b1be504a",
- address: "88a5c2d9919e46f883eb62f7b8dd9d0cc45bc290",
- Crypto: {
- kdfparams: {
- dklen: 32,
- p: 1,
- salt: "bbfa53547e3e3bfcc9786a2cbef8504a5031d82734ecef02153e29daeed658fd",
- r: 8,
- n: 262144
- },
- kdf: "scrypt",
- ciphertext: "10adcc8bcaf49474c6710460e0dc974331f71ee4c7baa7314b4a23d25fd6c406",
- mac: "1cf53b5ae8d75f8c037b453e7c3c61b010225d916768a6b145adf5cf9cb3a703",
- cipher: "aes-128-ctr",
- cipherparams: {
- iv: "1dcdf13e49cea706994ed38804f6d171"
- }
- },
- "version" : 3
- };
-
- let json = JSON.stringify(data);
- let password = "foo";
-
- ethers.Wallet.fromEncryptedJson(json, password).then(function(wallet) {
- console.log("Address: " + wallet.address);
- // "Address: 0x88a5C2d9919e46F883EB62F7b8Dd9d0CC45bc290"
- });
-
- 3.创建钱包-加载助记词
-
-
- let mnemonic = "radar blur cabbage chef fix engine embark joy scheme fiction master release";
- let mnemonicWallet = ethers.Wallet.fromMnemonic(mnemonic);
-
- // Load the second account from a mnemonic
- let path = "m/44'/60'/1'/0/0";
- let secondMnemonicWallet = ethers.Wallet.fromMnemonic(mnemonic, path);
-
- // Load using a non-english locale wordlist (the path "null" will use the default)
- let secondMnemonicWallet = ethers.Wallet.fromMnemonic(mnemonic, null, ethers.wordlists.ko);
-
- 4.从已有实例创建新的Wallet实例
-
- //privateKey是小狐狸钱包账户的私钥,可以在钱包处看到
- let privateKey = "0x0123456789012345678901234567890123456789012345678901234567890123";
- let wallet = new ethers.Wallet(privateKey);
-
- // Connect a wallet to mainnet
- let provider = ethers.getDefaultProvider();
- let walletWithProvider = new ethers.Wallet(privateKey, provider);
-
- 5.余额和交易数
- let balancePromise = wallet.getBalance();
-
- balancePromise.then((balance) => {
- console.log(balance);
- });
-
- let transactionCountPromise = wallet.getTransactionCount();
-
- transactionCountPromise.then((transactionCount) => {
- console.log(transactionCount);
- });
合约Contract对象是一个元类,它是一个在运行时定义类的类。 可以提供合约定义(称为应用程序二进制接口或ABI)以及可用的方法和事件可以动态添加到对象中。
创建和部署合约这块我前端没涉及,以后明白了再补偿。
我这里使用到连接已有合约并执行转账等操作。
- 1.连接已有合约
- // The Contract interface
- let abi = [
- "event ValueChanged(address indexed author, string oldValue, string newValue)",
- "constructor(string value)",
- "function getValue() view returns (string value)",
- "function setValue(string value)"
- ];
- //const abi= require("../config/constants/contract-abi.json");//将abi单独存放到json文件中
- // Connect to the network,查看provider获取连接provider对象
- let provider = new ethers.providers.Web3Provider(window.ethereum)
-
- // 地址来自上面部署的合约
- let contractAddress = "0x2bD9aAa2953F988153c8629926D22A6a5F69b14E";
-
- // 使用Provider 连接合约,将只有对合约的可读权限
- let daiContract = new ethers.Contract(contractAddress, abi, provider);
-
- 2.合约代币转账
-
- //合约使用signer签名,查询provider的用法
- let signer = provider.getSigner();
- const daiWithSigner = daiContract.connect(signer);
- const dai = ethers.utils.parseUnits(amount.toString(), 18);
- //执行转账动作,这里的transfer是部署的合约abi定义的转账方法
- daiWithSigner.transfer(to, dai).then((resp) => {})
- .catch((err) => {});
-
- 3.代币余额查询
- const balance = await daiContract.balanceOf(address);
- let balanceStr = ethers.utils.formatUnits(balance, 18);
- //contract-abi.json
-
- [
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "to",
- "type": "address"
- },
- {
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "transfer",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "account",
- "type": "address"
- }
- ],
- "name": "balanceOf",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": false,
- "internalType": "address",
- "name": "from",
- "type": "address"
- },
- {
- "indexed": false,
- "internalType": "uint256",
- "name": "fromBalance",
- "type": "uint256"
- },
- {
- "indexed": false,
- "internalType": "address",
- "name": "to",
- "type": "address"
- },
- {
- "indexed": false,
- "internalType": "uint256",
- "name": "toBalance",
- "type": "uint256"
- },
- {
- "indexed": false,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "TransferNew",
- "type": "event"
- }
- ]
- daiContract.on("TransferNew", (from, fromBalance,to,toBalance, amount, event) => {
- // let balanceStr = ethers.utils.formatUnits(fromBalance, 18);
- // console.log("fromBalance:::"+fromBalance);
- // this.$store.dispatch('SET_BALANCE', balanceStr);
- });
- import * as ethers from 'ethers';
-
- 1.BigNumber类型转成可读的字符串
- let balanceStr = ethers.utils.formatUnits(balance, 18);
-
- 2.字符串转成BigNumber
- let amount = 1000;
- let amountBig = ethers.utils.parseUnits(amount.toString(), 18);
-
- 3.校验是否为以太坊账户地址
- //返回true或者false
- let isAddress = ethers.utils.isAddress(address);
-
- 4.随机数
- let randomNumber = utils.bigNumberify(utils.randomBytes(32));
- // BigNumber { _hex: 0x617542634156966e0bbb6c673bf88015f542c96eb115186fd93881518f05f7ff }
1.连接MetaMask小狐狸钱包;
2.监听账户变化,即时更新页面信息;
2.链上转账(代币合约转账),唤起小狐狸钱包签名对转账消息签名;
3.代币余额查询,账户切换时即时刷新;
- //我们前面provider提到,MetaMask在安装后会发布一个全局的对象window.ethereum
- //参照小狐狸钱包的官方API:https://docs.metamask.io/guide/getting-started.html#basic-considerations
-
- //通过eth_requestAccounts获取连接的账户,未连接时弹出小狐狸钱包的连接页面
- const addressArray = await web3Provider.request({
- method: "eth_requestAccounts",
- });
-
- //通过eth_accounts获取当前连接的账户
- const addressArray = await web3Provider.request({
- method: "eth_accounts",
- });
具体代码
- //写在了store的action里
- //连接小狐狸钱包
- export const connectWallet= async ({ commit }) => {
- let web3Provider;
- if (window.ethereum) {
- web3Provider = window.ethereum;
- try {
-
- //通过
- const addressArray = await web3Provider.request({
- method: "eth_requestAccounts",
- });
-
- let address = addressArray[0];
- const obj = {
- status: "声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/453467推荐阅读
相关标签
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。