实例化链上方法
公司的项目全是区块链项目,最近这个项目是要构建一个链上的游戏社区,目前这个功能是用户可以质押NFT到游戏的链上,然后游戏那边就可以有人去参加竞赛,然后质押人可以赎回NFT。
MetaMask
浏览器插件用的是小狐狸MetaMask
网络用的是测试网络Rinkeby,记得切换网络,把设置 > 高级 > 显示测试网络 打开
let hexChainId = window.web3.utils.toHex(4) // 4就是Rinkeby测试网络 await window.ethereum.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: hexChainId }], })
首先要初始化web3
yarn add web3
import Web3 from 'web3' export const web3Init = () => { // web3初始化 let web3 = window.web3 if (typeof web3 !== 'undefined') { // web3.currentProvider web3 = new Web3(window.ethereum) // 取小狐狸的地址 } else { web3 = new Web3( new Web3.providers.HttpProvider(‘项目链接') ) } window.web3 = web3 // web3链接 }
现在就把web3挂载到window上了 链接小狐狸 await ethereum.request({ method: 'eth_requestAccounts' })
这一句代码就可以,返回的是钱包地址组成的字符串
实例化链
之后就是实例化链了,我是存在vuex里进项目第一步是初始化游戏链,游戏链是固定的
const texasPokerContract = new window.web3.eth.Contract( texasPokerJson, import.meta.env.VITE_TEXASPOKER_ADDRESS )
第一个参数就是链的ABI
第二个参数就是项目链上地址
还需要实例一个NFT,但是NFT是不固定的,我们操作哪个NFT就用哪个NFT的链上链接调用这个方法实例,把这两个都存在store里。
调用链上方法授权
export function approve(tokenId) { // 授权德州扑克链 return new Promise((resolve, reject) => { const texasPokerContract = store.state.texasPokerContract // 获取德州扑克合约 const nftContract = store.state.nftContract // 获取当前操作nft的合约 let optionsData = nftContract.methods.approve(texasPokerContract.options.address, tokenId).encodeABI() callContractMethod(optionsData, nftContract, 0, (res) => { resolve(res) }) }) } async function callContractMethod(optionsData, contractExample, values = 0, callback) { // 调用合约上的方法 /** * @param optionsData 发送方法的对象 * @param contractExample 要操作的合约实例 * @param values value值默认是0 * @param callback 回调函数 */ const account = store.state.persistence.assets // 当前钱包地址 if (!account) { return } const gasPrice = await window.web3.eth.getGasPrice() // 获取gas费 let options = { from: account, to: contractExample.options.address, value: values, data: optionsData, gasPrice: gasPrice, } window.web3.eth .sendTransaction(options) .on('error', function (error) { console.error('error', error) callback && callback(false) }) .then(function () { callback && callback(true) }) }
这段代码业务性很强,但是根本上也就是调用了window.web3.eth .sendTransaction(options)
这个方法
let options = { from: account, // 你的当前地址 to: contractExample.options.address, // 你要操作的链上地址 value: values, // 方法要带的参数,默认填0 data: optionsData, // *关键 要调用的方法nftContract.methods.approve(要带的参数).encodeABI() gasPrice: gasPrice, // 此次操作的gas费也就是手续费 }
不出意外就可以调起小狐狸进行授权了
调用游戏链上方法质押NFT
这一步跟上一步类似只是之前调用的是NFT链上的方法,现在调用的是我们自己游戏链上的方法
export function pledgeNFT(tokenId, amountp, timer) { // 质押NFT /** * @param tokenId tokenId * @param amountp 质押价格 * @param timer 质押天数的时间戳 */ return new Promise(async (resolve, reject) => { const texasPokerContract = store.state.texasPokerContract // 获取德州扑克合约 const getBlockTimes = await texasPokerContract.methods.getBlockTime().call() // 获取区块链时间 const nftContract = store.state.nftContract // 获取当前操作nft的合约 const token = nftContract.options.address const amount = window.web3.utils.toWei(amountp.toString(), 'ether') const unlockTime = Number(getBlockTimes) + Number(timer) let optionsData = texasPokerContract.methods.pledgeNFT(token, tokenId, amount, unlockTime).encodeABI() callContractMethod(optionsData, texasPokerContract, 0, (res) => { resolve(res) }) }) }
最后发送的时候记得把to改成对应的地址
在授权之前我们还需要判断这个NFT是否已经授权给了我们,不然用户将支付多份手续费
export async function getApproved(tokenId) { // 查询该NFT tokenId 是否已授权给Game合约 const nftContract = store.state.nftContract // 获取当前操作nft的合约 return await nftContract.methods.getApproved(tokenId).call() }
这次调用的是call方法,这个就相当于前端的get,是直接回调的,会返回这个NFT已经授权的链地址,我们直接进行判断就好
现在从查询,到授权,到质押NFT这一套流程就走完了,以上就是web3.js调用链上的方法操作NFT区块链MetaMask详解的详细内容,更多关于web3.js操作NFT区块链MetaMask的资料请关注阿兔在线工具其它相关文章!