手上有个项目需要接入metamask小狐狸钱包充值,之前一直没搞过区块链的开发,一点逻辑都不懂就上手搞了。
切换到币安对应的主网后,用 eth_sendTransaction 可以正常唤起metamask发起交易,但是币种是BNB,而项目需要使用USDT进行交易,接口参数里没有指定币种的地方,试了各种方式均未实现指定币种的效果。
后来发现使用智能合约可以进行指定币种的交易,但是为了这么一块小功能还要去学 solidity ,专门写这么一个合约吗?
仔细想了想,能写出以太坊的人,肯定不能每个人使用都需要自己写合约,应该是有公共的可以大家一起用的那种智能合约,只是我对这块不懂,没有找到,没有想明白,后来仔细搜了下,终于解决了,记录一下代码,免得以后忘记
实现
之前的发起默认币种交易代码
1const transactionParameters = {2 nonce: '0x00', // ignored by MetaMask3 // gasPrice: '0x09184e72a000', // customizable by user during MetaMask confirmation.4 // gas: '0x2710', // customizable by user during MetaMask confirmation.5 to: '0x0000000000000000000000000000000000000000', // Required except during contract publications.6 from: ethereum.selectedAddress, // must match user's active address.7 value: '0x00', // Only required to send ether to the recipient from the initiating external account.8 // data:9 // '0x7f7465737432000000000000000000000000000000000000000000000000000000600057', // Optional, but used for defining smart contract creation and interaction.10 chainId: '0x3', // Used to prevent transaction reuse across blockchains. Auto-filled by MetaMask.11};12
13// txHash is a hex string14// As with any RPC call, it may throw an error15const txHash = await ethereum.request({9 collapsed lines
16 method: 'eth_sendTransaction',17 params: [transactionParameters],18})19.then((result) => {20 console.log("txHash:" + result)21})22.catch((error) => {23 console.log("error:" + error.code)24});;发起指定币种交易 USDT
有意思的是,不知道是我搜索的方式不对还是什么,怎么都搜不到metamask如何发起指定币种交易的相关内容,最后无可奈何,把问题甩给了chatGPT,经过几次询问后,chatGPT 给了我一个带详细中文注释的代码,修改下参数,可以完美运行,真的是。。。
1// 假设你已经有了USDT合约的地址和ABI2const USDTContractAddress = "..."; // USDT合约地址3const USDTContractABI = [...]; // USDT合约ABI4const recipientAddress = "0x..."; // 接收地址5const amount = 100; // 要发送的代币数量,单位为wei6
7// 创建一个web3实例,连接到metamask提供的provider8const web3 = new Web3(window.ethereum);9
10// 获取当前用户的账户地址11const accounts = await ethereum.request({ method: 'eth_requestAccounts' });12const senderAddress = accounts[0];13
14// 创建一个USDT合约实例15const USDTContract = new web3.eth.Contract(USDTContractABI, USDTContractAddress);22 collapsed lines
16
17// 调用USDT合约的transfer方法,生成data字段18const data = USDTContract.methods.transfer(recipientAddress, amount).encodeABI();19
20// 构造交易参数对象21const txParams = {22 from: senderAddress,23 to: USDTContractAddress,24 value: "0x0", // 不发送以太币,只发送代币25 gas: web3.utils.toHex(21000), // 设置gas limit,可以根据实际情况调整26 gasPrice: web3.utils.toHex(web3.utils.toWei('10', 'gwei')), // 设置gas price,可以根据实际情况调整27 data: data // 填入之前生成的data字段28};29
30// 调用metamask的eth_sendTransaction方法,发送交易并获取交易哈希31const txHash = await ethereum.request({32 method: 'eth_sendTransaction',33 params: [txParams],34});35
36// 打印交易哈希或者做其他操作37console.log(txHash);(注意,这里用到了 web3.js)
币安USDT合约地址及ABI
有了发起指定币种交易的代码,就要找对应币种的合约地址和ABI,填充进去
币安的USDT合约页面:https://bscscan.com/token/0x55d398326f99059ff775485246999027b3197955#code
USDT合约地址:0x55d398326f99059fF775485246999027B3197955
上面的页面内就有ABI代码:
1[{"inputs":[],"payable":false,"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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"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"},{"constant":true,"inputs":[],"name":"_decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]参考
MetaMask Docs - Sending Transactions
ethereum JSON-RPC API - eth_sendTransaction
用 Web3 以太坊接口连接与操作 MetaMask 开发指南
Web3.0-使用metamask获取某个账号(钱包地址)的余额、交易回执
How to sign an ethereum transaction with metamask