mcpField
N
nft-blockchain

nft-blockchain

github.com/dcl-regenesislabs開発1741 回インストール21 週間前に更新
リポジトリ

nft-blockchain について

nft-blockchainは、NFT表示やEthereumのブロックチェーン機能を扱うDecentraland開発向けリファレンスです。ウォレット確認、署名付きリクエスト、スマートコントラクト、RPC呼び出し、Sepoliaでのテストを説明します。

主な機能

  1. 01ERC-721 NFTアートの表示
  2. 02プレイヤーのウォレットとゲスト状態の確認
  3. 03ウォレット署名付きバックエンドリクエスト
  4. 04eth-connectによるコントラクト操作
  5. 05独自のEthereum RPC呼び出し
  6. 06Sepoliaでのコントラクトテスト

活用シーン

  1. 01シーンに額装NFTアートを追加
  2. 02プレイヤーが取引に署名できるか確認
  3. 03ウォレット署名によるバックエンド認証
  4. 04スマートコントラクト連携の開発とテスト

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dcl-regenesislabs/opendcl --skill nft-blockchain

インストール後、Claude Code で/nft-blockchainを入力して読み込まれたか確認します。

詳細

Decentraland の NFT とブロックチェーン

NFT アートワークを表示する

NftShape は main-entities.ts でサポートされています。額装された NFT を直接宣言できます。ユーザーはビジュアルエディターでドラッグして移動できます。

// main-entities.ts
import type { Scene } from '@dcl/sdk/scene-types'

export const scene = {
  hero_nft: {
    components: {
      Transform: { position: { x: 8, y: 2, z: 8 } },
      NftShape: {
        urn: 'urn:decentraland:ethereum:erc721:0x06012c8cf97bead5deae237070f9587f8e7a266d:558536',
        color: { r: 1, g: 1, b: 1, a: 1 },
        style: 0  // NftFrameType.NFT_CLASSIC — enum values are integers in the literal
      }
    }
  }
} satisfies Scene

style フィールドは数値の列挙型です。AST ウォーカーが JSON 互換の式のみを受け付けるため、リテラルから NftFrameType.NFT_CLASSIC を直接参照することはできません。整数値(下の表を参照)を使い、コメントを残してください。

NFT URN の形式
urn:decentraland:ethereum:erc721:<contractAddress>:<tokenId>
  • Ethereum メインネット上のあらゆる ERC-721 NFT で動作します
  • 画像は NFT のメタデータから自動的に読み込まれます
使用可能なフレームスタイル
値列挙型の名前説明
0NFT_CLASSICシンプルなクラシックフレーム
1NFT_BAROQUE_ORNAMENT華やかなバロック調
2NFT_DIAMOND_ORNAMENTダイヤモンド柄
3NFT_MINIMAL_WIDEミニマルな幅広の縁
4NFT_MINIMAL_GREYミニマルなグレーの縁
5NFT_BLOCKYピクセル調/ブロック調
6NFT_GOLD_EDGES金色の縁取り
7NFT_GOLD_CARVED彫刻を施した金色
8NFT_GOLD_WIDE幅広の金色の縁
9NFT_GOLD_ROUNDED丸みを帯びた金色
10NFT_METAL_MEDIUM中程度の幅の金属製
11NFT_METAL_WIDE幅広の金属製
12NFT_METAL_SLIM細身の金属製
13NFT_METAL_ROUNDED丸みを帯びた金属製
14NFT_PINSピンで壁に固定
15NFT_MINIMAL_BLACKミニマルな黒
16NFT_MINIMAL_WHITEミニマルな白
17NFT_TAPEテープで壁に貼り付け
18NFT_WOOD_SLIM細身の木製
19NFT_WOOD_WIDE幅広の木製
20NFT_WOOD_TWIGS小枝/枝の木製
21NFT_CANVASキャンバススタイル
22NFT_NONEフレームなし

列挙型の識別子を使用できる src/index.ts では、NftFrameType.NFT_CLASSIC などを直接使用してください。

プレイヤーのウォレットを確認する

import { getPlayer } from '@dcl/sdk/src/players'

function checkWallet() {
  const player = getPlayer()
  if (player && !player.isGuest) {
    console.log('Player wallet address:', player.userId)
    // userId is the Ethereum wallet address
  } else {
    console.log('Player is guest (no wallet)')
  }
}

ブロックチェーンとのやり取りを行う前に、必ず isGuest を確認してください。ゲストプレイヤーはウォレットに接続されていません。

署名付きリクエスト

プレイヤーのウォレットで署名した、認証済みのリクエストをバックエンドに送信します。

import { signedFetch } from '~system/SignedFetch'

executeTask(async () => {
  try {
    const response = await signedFetch({
      url: 'https://example.com/api/action',
      init: {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          action: 'claimReward',
          amount: 100
        })
      }
    })

    if (!response.ok) {
      console.error('HTTP error:', response.status)
      return
    }
    const result = JSON.parse(response.body)
    console.log('Result:', result)
  } catch (error) {
    console.log('Request failed:', error)
  }
})

signedFetch は、プレイヤーの本人確認を行う暗号署名を自動的に付加します。バックエンドでこの署名を検証してリクエストを認証できます。

スマートコントラクトとのやり取り

eth-connect パッケージが必要です。

npm install eth-connect
ABI を別のファイルに保存する
// contracts/myContract.ts
export default [
  {
    "constant": true,
    "inputs": [{ "name": "_owner", "type": "address" }],
    "name": "balanceOf",
    "outputs": [{ "name": "balance", "type": "uint256" }],
    "type": "function"
  }
  // ... rest of ABI
]
コントラクトインスタンスを作成する
import { RequestManager, ContractFactory } from 'eth-connect'
import { createEthereumProvider } from '@dcl/sdk/ethereum-provider'
import { abi } from '../contracts/myContract'

executeTask(async () => {
  try {
    // Create web3 provider
    const provider = createEthereumProvider()
    const requestManager = new RequestManager(provider)

    // Create contract at a specific address
    const factory = new ContractFactory(requestManager, abi)
    const contract = await factory.at('0x2a8fd99c19271f4f04b1b7b9c4f7cf264b626edb') as any

    // Read data (no gas required)
    const balance = await contract.balanceOf('0x123...abc')
    console.log('Balance:', balance)
  } catch (error) {
    console.log('Contract interaction failed:', error)
  }
})
書き込み操作(ガス代が必要)
executeTask(async () => {
  try {
    const userData = getPlayer()
    if (userData.isGuest) return

    // Write operation — prompts the player to sign the transaction
    const writeResult = await contract.transfer(
      '0xRecipientAddress',
      100,
      {
        from: userData.userId,
        gas: 100000,
        gasPrice: await requestManager.eth_gasPrice()
      }
    )
    console.log('Transaction hash:', writeResult)
  } catch (error) {
    console.log('Transaction failed:', error)
  }
})
ガス価格と残高の確認
import { RequestManager } from 'eth-connect'
import { createEthereumProvider } from '@dcl/sdk/ethereum-provider'

executeTask(async () => {
  const provider = createEthereumProvider()
  const requestManager = new RequestManager(provider)

  const gasPrice = await requestManager.eth_gasPrice()
  console.log('Current gas price:', gasPrice)

  const balance = await requestManager.eth_getBalance('0x123...abc', 'latest')
  console.log('Account balance:', balance)
})

Sepolia でテストする

開発時には、Sepolia テストネットを使用してください。

  1. MetaMask を Sepolia ネットワークに設定します
  2. Sepolia のフォーセットからテスト用 ETH を入手します
  3. コントラクトを Sepolia にデプロイします
  4. メインネットとテストネットではコントラクトアドレスが異なるため、環境を確認して使い分けます
カスタム RPC 呼び出し

eth-connect のヘルパーで対応できない低レベルの Ethereum RPC 呼び出しには、sendAsync を使用します。

import { sendAsync } from '~system/EthereumController'

const result = await sendAsync({ method: 'eth_blockNumber', params: [] })
console.log('Current block:', result.body)
URL と NFT ダイアログを開く

制限付きアクションを使用して、外部リンクや NFT の詳細表示を開きます。

import { openExternalUrl, openNftDialog } from '~system/RestrictedActions'

openExternalUrl({ url: 'https://opensea.io/collection/...' })
openNftDialog({ urn: 'urn:decentraland:ethereum:erc721:0x06012c8cf97BEaD5deAe237070F9587f8E7A266d:558536' })

ベストプラクティス

  • ブロックチェーンとのやり取りの前に必ず isGuest を確認してください。ゲストプレイヤーはトランザクションに署名できません
  • すべての非同期ブロックチェーン呼び出しには executeTask(async () => { ... }) を使用します
  • ABI ファイルは別の場所(例:contracts/)に保存し、大きな ABI をインラインで記述しないでください
  • エラーは適切に処理してください。ブロックチェーン操作は失敗することがあります(ユーザーによる拒否、ガス不足、ネットワークの問題など)
  • eth-connect は依存関係としてインストールする必要があります:npm install eth-connect
  • バックエンドの認証には生の fetch ではなく signedFetch を使用してください。プレイヤーの本人確認ができます
  • 読み取り操作(view/pure 関数)にはガス代は不要です。書き込み操作ではユーザーに署名が求められます
  • メインネットにデプロイする前に Sepolia でテストしてください
  • NFT URN は Ethereum メインネット上の ERC-721 トークンでのみ動作します

コメント