Appearance
S1C10: Give 1 Get 1
1. 問題
S1C1 と S1C9 の NFT を同時に保持し、flag と交換するために1つの NFT をチャレンジコントラクトに転送する必要があります。
2. 原因
チャレンジは ERC-721 の safeTransferFrom を使用して「物々交換」メカニズムを実装しています — 特定の NFT をコントラクトに転送し、コントラクトが検証した後に S1C10 flag を mint します。
3. 解法
- S1C1 と S1C9 の NFT tokenId を保持していることを確認します
- チャレンジコントラクトの交換関数を呼び出し、指定された NFT をコントラクトに転送します
- コントラクトが検証した後、自動的に S1C10 flag が mint されます
4. 遭遇した落とし穴
NFT 所有権の確認: 自分の tokenId を見つける必要があります(S1 NFTFlags は ERC721Enumerable を実装していません)。
5. 落とし穴の原因
Season1NFTFlags は ERC721 のみを継承しており、tokenOfOwnerByIndex を含まないため、列挙による保有者のクエリができません。tokenId の範囲をスキャンして所有者を見つける必要があります。
6. 解決方法
ownerOf(tokenId) を使用して tokenId の範囲をスキャンし、自分のアドレスに属する token を見つけます:
bash
for tid in $(seq 1 100); do
owner=$(cast call $NFT_FLAGS "ownerOf(uint256)(address)" $tid)
if [ "$owner" = "$MY_ADDRESS" ]; then echo "My token: $tid"; fi
done
7. 技術的ポイント
| ポイント | 説明 |
|---|---|
| ERC-721 transfer | safeTransferFrom は onERC721Received コールバックをトリガーします |
| ERC721 vs ERC721Enumerable | 非 Enumerable バージョンは token リストを保持せず、インデックスによるクエリができません |
| Token 所有権スキャン | tokenId の範囲をブルートフォーススキャンして所属する token を見つけます |