关于 nft-blockchain
面向 Decentraland 场景开发的 NFT 与区块链技能,介绍 NFT 展示和链上操作。内容涵盖钱包检查、签名后端请求、合约调用、代币门控及 MANA、代币、NFT 和市场操作。
主要功能
- 01以相框展示 NFT 艺术品
- 02检查玩家钱包与余额
- 03发送签名后端请求
- 04读写智能合约
- 05按 NFT 或余额进行代币门控
- 06MANA、代币、NFT 与市场操作
适用场景
- 01在场景中展示 NFT 艺术品
- 02按代币持有情况限制访问
- 03发送代币或转移 NFT
- 04在市场购买或挂牌 NFT
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ decentraland/ sdk-skills --skill nft-blockchain安装后在 Claude Code 中输入/nft-blockchain确认已加载。
附带文件references/blockchain-patterns.md
详细介绍
Decentraland 中的 NFT 和区块链
展示 NFT 艺术品
使用 NftShape 在装饰性画框中展示 NFT。提供 NFT URN 并选择画框样式。图像会自动从 NFT 的元数据中加载(通过 Decentraland 的 OpenSea 代理 opensea.decentraland.org 获取)——任何 OpenSea 支持的 NFT 都可以展示,且支持多个链。
NFT URN 格式: urn:decentraland:<chain>:<contractStandard>:<contractAddress>:<tokenId>
- 示例:
urn:decentraland:ethereum:erc721:0x06012c8cf97bead5deae237070f9587f8e7a266d:558536 <chain>支持的值(会原样转发至 OpenSea v2 API;无法识别的链会被拒绝):ethereum、matic、klaytn、bsc、arbitrum、arbitrum_nova、avalanche、optimism、solana、base、blast、zora。<contractStandard>通常为erc721。图像由 OpenSea 响应提供,因此 OpenSea 索引为erc1155的合约也能解析。
可用的画框样式
NftFrameType.NFT_CLASSIC // Simple classic frame
NftFrameType.NFT_BAROQUE_ORNAMENT // Ornate baroque
NftFrameType.NFT_DIAMOND_ORNAMENT // Diamond pattern
NftFrameType.NFT_MINIMAL_WIDE // Minimal wide border
NftFrameType.NFT_MINIMAL_GREY // Minimal grey border
NftFrameType.NFT_BLOCKY // Pixelated/blocky
NftFrameType.NFT_GOLD_EDGES // Gold edge trim
NftFrameType.NFT_GOLD_CARVED // Carved gold
NftFrameType.NFT_GOLD_WIDE // Wide gold border
NftFrameType.NFT_GOLD_ROUNDED // Rounded gold
NftFrameType.NFT_METAL_MEDIUM // Medium metal
NftFrameType.NFT_METAL_WIDE // Wide metal
NftFrameType.NFT_METAL_SLIM // Slim metal
NftFrameType.NFT_METAL_ROUNDED // Rounded metal
NftFrameType.NFT_PINS // Pinned to wall
NftFrameType.NFT_MINIMAL_BLACK // Minimal black
NftFrameType.NFT_MINIMAL_WHITE // Minimal white
NftFrameType.NFT_TAPE // Taped to wall
NftFrameType.NFT_WOOD_SLIM // Slim wood
NftFrameType.NFT_WOOD_WIDE // Wide wood
NftFrameType.NFT_WOOD_TWIGS // Twig/branch wood
NftFrameType.NFT_CANVAS // Canvas style
NftFrameType.NFT_NONE // No frame
检查玩家钱包
使用 @dcl/sdk/src/players 中的 getPlayer(),通过 player.userId 获取玩家的 Ethereum 地址。进行任何区块链交互之前,务必检查 isGuest——访客玩家没有已连接的钱包。
签名请求
使用 ~system/SignedFetch 中的 signedFetch 向后端发送经过身份验证的请求。它会自动注入经过签名的身份标头(ADR-44),供后端验证——你无需自行构建或传递这些标头。
- 签名:
signedFetch({ url, init: { method?, headers?, body? } })。 - 响应为
{ ok, status, statusText, headers, body };body是字符串——调用JSON.parse(response.body)(没有.json())。 - 它不需要玩家事先进行交互(与受限操作不同)。
- 如果只需要签名标头,以供自行执行请求的库使用,则可从同一模块使用
getHeaders({ url, init? })——它会返回{ headers }。
智能合约交互
若要直接调用智能合约,请将 eth-connect 与 @dcl/sdk/ethereum-provider 中的 createEthereumProvider 配合使用。将 ABI 存储在单独的文件中,通过 ContractFactory 创建合约实例,然后调用读取函数(无需 gas)或写入函数(需要 gas,并会提示用户签名)。
npm install eth-connect
读取操作(view/pure 函数)不需要 gas。写入操作会提示玩家签名,并需要 gas。
使用 executeTask(async () => { ... }) 包装所有异步区块链调用。妥善处理错误——区块链操作可能失败(用户拒绝、gas 不足、网络问题)。
Gas 价格和余额
使用 eth-connect 中的 requestManager.eth_gasPrice() 和 requestManager.eth_getBalance() 检查当前 gas 价格和账户的 ETH 余额。
自定义 RPC 调用
对于 eth-connect 辅助函数未涵盖的底层 Ethereum RPC 调用,请使用 ~system/EthereumController 中的 sendAsync。
打开外部 URL / NFT 对话框
使用 ~system/RestrictedActions 中的 openExternalUrl 和 openNftDialog 打开外部链接和 NFT 详情视图。
使用 Sepolia 测试
开发时请使用 Sepolia 测试网:将 MetaMask 设置为 Sepolia,从水龙头获取测试 ETH,并将合约部署到 Sepolia。主网和测试网的合约地址不同。
dcl-crypto-toolkit(更高级别的 API)
对于常见的区块链操作,请使用 dcl-crypto-toolkit,而不是原始的 eth-connect。它为最常用的任务提供了更简洁的 API。
npm install dcl-crypto-toolkit
导入:import * as crypto from 'dcl-crypto-toolkit'。模块包括:ethereum、mana、currency、nft、marketplace、services、wearable、contract。没有顶层的 crypto.signMessage。
功能:
- **MANA 操作:**发送、查询余额(
crypto.mana.send/.myBalance/.balance) - **ERC20 代币:**发送、查询余额、查询/设置额度(
crypto.currency.*) - **ERC721/NFT:**查询持有的代币(代币门控)、转移、管理授权(
crypto.nft.*) - **市场:**购买(
executeOrder)、出售(createOrder)、取消(cancelOrder)、查询授权(crypto.marketplace.*) - **签名消息:**使用玩家钱包为 EIP-712 类型化数据签名(
crypto.ethereum.signMessageAdvanced())
代币门控
**基于 NFT 所有权:**使用 crypto.nft.checkTokens(contractAddress, tokenIds?)——返回玩家是否持有该合约的代币。省略 tokenIds 可检查该合约的任意代币。根据结果授予或拒绝访问权限。
**基于 MANA 余额:**检查 crypto.mana.myBalance()(其他 ERC20 代币则使用 crypto.currency.balance(contractAddress, address)),根据持有量控制访问权限。
快速选择指南
| 任务 | 使用 |
|---|---|
| 发送 MANA | crypto.mana.send() |
| 查询自己的 MANA 余额 | crypto.mana.myBalance() |
| 查询任意地址的 MANA 余额 | crypto.mana.balance(address) |
| 发送任意 ERC20 代币 | crypto.currency.send() |
| 查询 ERC20 余额 | crypto.currency.balance(contract, address) |
| 转移 NFT | crypto.nft.transfer() |
| 查询 NFT 所有权/进行代币门控 | crypto.nft.checkTokens() |
| 从市场购买 | crypto.marketplace.executeOrder() |
| 上架出售 NFT | crypto.marketplace.createOrder() |
| 签名消息 | crypto.ethereum.signMessageAdvanced() |
| 自定义智能合约 | eth-connect(见上文) |
| 已验证身份的 API 调用 | signedFetch(见上文) |
示例场景
Engine 团队提供的测试场景,展示了这些 API 如何在真实运行时中运行:
- https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/5,90-scene-bounds-check — 使用实时的
urn:decentraland:ethereum:erc721:<contract>:<tokenId>URN 调用NftShape.create(),并将其安装在移动平台上,使其穿过地块边界(因此也展示了 NFT 框超出边界后被剔除的情况)。 - https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/80,-4-restricted-actions — 通过 React-ECS 按钮调用
openNftDialog({ urn })和openExternalUrl,并展示其他所有 RestrictedAction。请注意,该场景既未在requiredPermissions中声明OPEN_EXTERNAL_LINK,也未声明 NFT 权限,但两项功能仍可运行。 - https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/66,6-signed-fetch — 点击时调用
signedFetch;读取response.ok/.status/.body,并检查自动添加的签名标头;requiredPermissions为空。
完整代码示例和实现模式(包括 dcl-crypto-toolkit 库 API)请参见“{baseDir}/references/blockchain-patterns.md”。