本文介绍了如何使用 Safe 账户抽象 SDK 和 Gelato Relay Kit 实现 gasless 的 NFT minting。
对于新手来说,浏览大量的 dApp 可能会让人望而却步。链上操作过程通常充满了复杂的概念和步骤,这构成了一个阻碍大规模采用的障碍。
其中一个挑战是“gas”的概念——在不同链上执行交易所需的费用。
要获得支付 gas 费用的原生资产(如 ETH、MATIC 等),你必须在交易所创建一个帐户,经过可能漫长的验证过程,购买资产,然后将其转移到你的钱包。这个过程可能会让新用户感到害怕并产生摩擦。即使你已经克服了这个障碍并在你的钱包中有任何 ERC20 代币,但没有原生资产,进一步的挑战还在等着你。你无法移动或交换这些 ERC20 代币,因为你无法支付 gas 费用。你也无法将 USDC 兑换为原生资产(如 ETH),因为这本身也需要 gas。因此,你又回到了原点——需要原生代币才能执行任何操作。
Safe 正在朝着这个方向取得进展。Safe{Core} 账户抽象 SDK 为开发者提供了一个将账户抽象功能集成到其应用程序中的机会,从而促进更流畅的用户体验。
由 Gelato relay SDK 提供支持的 Safe 账户抽象 Relay kit 开创了一个用户友好的环境。它允许用户使用 ERC-20 代币支付 gas 费用,或者为提供无 gas 交易铺平道路。
在本节中,我们将引导你了解如何使用 Gelato 提供支持的 Safe Relay Kit 铸造 NFT,而无需承担任何 gas 成本。
首先,让我们看一下一个简单的 NFT 铸造合约。我们的目标是使该合约的 mintGelato
函数实现无 gas 化。
这是一个 NFT 铸造合约,实现了 ERC721 标准:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.14;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract GelatoNFT is ERC721, ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
string public constant gelatoInitialURI = "https://bafkreid6qtmeanbpfygu3e5bbw5fxfexas4dimaigsm6nbigji3naxtz74.ipfs.nftstorage.link/";
constructor() ERC721("GelatoNFT", "GNFT") {}
function mintGelato(address to) public {
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(to, newItemId);
_setTokenURI(newItemId, gelatoInitialURI);
}
function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) {
return super.tokenURI(tokenId);
}
function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721URIStorage) returns (bool) {
return super.supportsInterface(interfaceId);
}
}
现在让我们看看使 mintGelato
函数实现无 gas 化的分步指南 -
1. 创建一个 Safe
导航到 safe{Wallet} 网站并创建一个新的 safe。在本教程中,创建一个 1/1 safe。
2. 验证你的合约
复制你的新 safe 地址并将其粘贴到区块浏览器中以验证合约。转到区块浏览器中的合约标签,然后单击“Is this a proxy?”。
验证你的合约并保存它。验证步骤还将为你提供一个实现地址。此实现智能合约的 ABI 也可用于将此智能合约添加到 Gelato
3. 将资金存入 Gelato 1Balance
访问 Gelato 1Balance 并在 Polygon 上存入 USDC 以用于主网,或在 Goerli 上存入 geth 以用于测试网。Gelato 1Balance 允许你通过此存款支付跨多个链的 relay 成本。
4. 从 Gelato UI 创建你的 Relay 应用程序
在你的 Relay 应用程序 中,粘贴你的 safe 合约地址。这将显示所有可用的函数。启用 execTransaction
函数以使其无 gas 化。
5. 准备你的项目目录和依赖项
打开终端并运行以下命令:
mkdir gasless-nft-minting
cd gasless-nft-minting
yarn init -y
yarn add ethers @safe-global/relay-kit @safe-global/protocol-kit @safe-global/safe-core-sdk-types
6. 导入包并初始化交易设置
在你的项目中,导入必要的包:
import { ethers } from 'ethers'
import { GelatoRelayPack } from '@safe-global/relay-kit'
import Safe, { EthersAdapter, getSafeContract } from '@safe-global/protocol-kit'
import { MetaTransactionData, MetaTransactionOptions, OperationType } from '@safe-global/safe-core-sdk-types'
7. 创建交易对象
为 NFT 铸造合约创建一个交易对象。这包括 to 地址(NFT 铸造合约地址),数据,其中包括编码的函数数据以调用 NFT 合约中的 mintGelato
函数,以及设置为零的值,因为铸造 NFT 通常不需要发送以太币。该操作设置为 OperationType.Call,因为我们正在简单地调用 NFT 合约中的 mintGelato 函数。
选项对象指示交易是否被赞助。如果 sponsored 为 true
,则平台正在为用户支付 gas 费用,否则用户通过其 safe 中的任何原生或 ERC20 代币支付。
const : MetaTransactionData = {
to: targetAddress,
data: nftContract.interface.encodeFunctionData("mintGelato", [\
"0x68B38f944d2689537f8ed8A2F006b4597eE42218",\
]),
value: "0",
operation: OperationType.Call,
};
const options: MetaTransactionOptions = {
gasLimit,
isSponsored: true,
};
8. 创建 Protocol 和 Relay Kit 实例
const ethAdapter = new EthersAdapter({
ethers,
signerOrProvider: signer,
});
const safeSDK = await Safe.create({
ethAdapter,
safeAddress,
});
console.log(safeSDK);
const relayKit = new GelatoRelayPack(GELATO_RELAY_API_KEY);
9. 编码交易
在此,我们将编码 execTransaction
函数,该函数是 Gnosis Safe 合约的一部分。此函数采用多个参数,包括合约地址 (to)、要发送的以太币值 (value) 和其他操作参数。
const safeTransaction = await safeSDK.createTransaction({
safeTransactionData,
});
const signedSafeTx = await safeSDK.signTransaction(safeTransaction);
const safeSingletonContract = await getSafeContract({
ethAdapter,
safeVersion: await safeSDK.getContractVersion(),
});
const encodedTx = safeSingletonContract.encode("execTransaction", [\
signedSafeTx.data.to,\
signedSafeTx.data.value,\
signedSafeTx.data.data,\
signedSafeTx.data.operation,\
signedSafeTx.data.safeTxGas,\
signedSafeTx.data.baseGas,\
signedSafeTx.data.gasPrice,\
signedSafeTx.data.gasToken,\
signedSafeTx.data.refundReceiver,\
signedSafeTx.encodedSignatures(),\
]);
10. 将交易发送给 Relayer
上述编码的数据以及其他参数将根据选择的支付 gas 费用的逻辑(赞助或通过代币支付 gas 费用)发送到 Gelato Relay。
const relayTransaction: RelayTransaction = {
target: safeAddress,
encodedTransaction: encodedTx,
chainId: chainId,
options,
};
const response = await relayKit.relayTransaction(relayTransaction);
console.log(response);
console.log(
`Relay Transaction Task ID: https://relay.gelato.digital/tasks/status/${response.taskId}`
);
Safe 的账户抽象 SDK Relay Kit(由 Gelato Relay 提供支持)提供了一种创新的解决方案,可以促进无 gas 交易,从而使 dApp 交互更简单、更用户友好。通过启用简化的流程和更大的可访问性,这些工具具有巨大的潜力来促进区块链技术的大规模采用。
Gelato 在每一步都为你处理区块链的复杂性,从而实现安全的无 gas 交易,从而实现无缝的用户体验和链上操作。
查看 Relay 以及其他 Gelato 服务,例如 Web3 Functions、Automate 和 Account Abstraction SDK。
当你这样做时,请加入我们的社区和我们在 Discord 上的开发者讨论!
- 原文链接: gelato.cloud/blog/gasles...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!