> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monad.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# 如何在 Monad 上使用 ERC-6551(代币绑定账户)构建

> 使用规范的 Tokenbound ERC-6551 部署,在 Monad 上为每个 NFT 提供其专属的智能合约钱包。

export const CopyToClipboard = ({value, children}) => {
  const [copied, setCopied] = useState(false);
  const handleCopy = async () => {
    try {
      await navigator.clipboard.writeText(value);
      setCopied(true);
      setTimeout(() => setCopied(false), 1000);
    } catch {
      const textarea = document.createElement("textarea");
      textarea.value = value;
      textarea.style.position = "fixed";
      textarea.style.opacity = "0";
      document.body.appendChild(textarea);
      textarea.select();
      document.execCommand("copy");
      document.body.removeChild(textarea);
      setCopied(true);
      setTimeout(() => setCopied(false), 1000);
    }
  };
  return <span style={{
    display: "inline",
    whiteSpace: "nowrap"
  }}>
      {children}
      <button onClick={handleCopy} title={copied ? "Copied!" : "Copy to clipboard"} style={{
    background: "none",
    border: "none",
    cursor: "pointer",
    padding: "2px",
    display: "inline-flex",
    alignItems: "center",
    verticalAlign: "middle",
    marginLeft: "4px",
    opacity: copied ? 1 : 0.4,
    transition: "opacity 0.15s"
  }} onMouseEnter={e => {
    if (!copied) e.currentTarget.style.opacity = "0.8";
  }} onMouseLeave={e => {
    if (!copied) e.currentTarget.style.opacity = "0.4";
  }}>
        {copied ? <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#22c55e" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
            <polyline points="20 6 9 17 4 12" />
          </svg> : <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
            <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
          </svg>}
      </button>
    </span>;
};

本指南展示如何使用规范的 [Tokenbound](https://tokenbound.org) ERC-6551 v3 部署,在 Monad 上为任何 NFT 提供其专属账户(钱包)。完整技术栈已在 Monad 主网和测试网上线,使用与以太坊和 Base 相同的规范地址,因此标准的 `@tokenbound/sdk` 无需任何自定义合约配置即可使用。

## 什么是 ERC-6551?

[ERC-6551](https://eips.ethereum.org/EIPS/eip-6551) 为每个 ERC-721 NFT 赋予其专属的智能合约账户 —— 即"代币绑定账户"(token-bound account,TBA)。该账户由当前持有该 NFT 的人拥有,因此该账户所拥有或可执行的任何内容,都会随着 NFT 的转移自动转移。

具体来说,代币绑定账户可以:

* 持有资产 —— ERC-20 代币、其他 NFT 以及原生 MON。
* 执行任意交易,由当前 NFT 持有者授权。
* 作为游戏、代理、会员资格和忠诚度计划的身份或库存。

由于账户是通过共享的、无需许可的注册表以确定性方式创建的,给定 NFT 的账户地址可以事先预知,并且在部署该标准的每条链上都是相同的。

### 主要优点

* **所有权跟随 NFT**:转移 NFT 后,其整个账户 —— 包括资产和权限 —— 会随之原子性地移动,无需任何迁移步骤。
* **确定性地址**:NFT 的账户地址由 `(chainId, tokenContract, tokenId, implementation, salt)` 计算得出,因此可以在账户尚未部署之前于链下推导出来。
* **钱包侧无需学习新标准**:TBA 是一种智能账户,与现有工具和 ERC-4337 账户抽象兼容。
* **开箱即用**:Monad 使用规范的 Tokenbound 合约,部署在其标准的跨链地址上,因此现有的 ERC-6551 应用和 Tokenbound SDK 只需修改配置即可指向 Monad。

## Monad 上的规范部署

Tokenbound ERC-6551 v3 技术栈以其规范的、确定性地址部署在 **Monad 主网(chain ID 143)** 和 **Monad 测试网(chain ID 10143)** 上。两个网络上的地址完全相同,并与以太坊/Base 部署一致。所有合约均已在 [Monadscan](https://monadscan.com) 和 [MonadVision](https://monadvision.com) 上完成源码验证。

<ul>
  <li>
    <strong>ERC-6551 Registry</strong>:

    <CopyToClipboard value="0x000000006551c19487814612e58FE06813775758">
      `0x000000006551c19487814612e58FE06813775758`
    </CopyToClipboard>

    <span>
      (
      <a href="https://monadscan.com/address/0x000000006551c19487814612e58FE06813775758">主网</a>

      {", "}

      <a href="https://testnet.monadscan.com/address/0x000000006551c19487814612e58FE06813775758">测试网</a>
      )
    </span>
  </li>

  <li>
    <strong>V3 Account Implementation</strong>:

    <CopyToClipboard value="0x41C8f39463A868d3A88af00cd0fe7102F30E44eC">
      `0x41C8f39463A868d3A88af00cd0fe7102F30E44eC`
    </CopyToClipboard>

    <span>
      (
      <a href="https://monadscan.com/address/0x41C8f39463A868d3A88af00cd0fe7102F30E44eC">主网</a>

      {", "}

      <a href="https://testnet.monadscan.com/address/0x41C8f39463A868d3A88af00cd0fe7102F30E44eC">测试网</a>
      )
    </span>
  </li>

  <li>
    <strong>V3 Account Proxy</strong>:

    <CopyToClipboard value="0x55266d75D1a14E4572138116aF39863Ed6596E7F">
      `0x55266d75D1a14E4572138116aF39863Ed6596E7F`
    </CopyToClipboard>

    <span>
      (
      <a href="https://monadscan.com/address/0x55266d75D1a14E4572138116aF39863Ed6596E7F">主网</a>

      {", "}

      <a href="https://testnet.monadscan.com/address/0x55266d75D1a14E4572138116aF39863Ed6596E7F">测试网</a>
      )
    </span>
  </li>

  <li>
    <strong>V3 Account Guardian</strong>:

    <CopyToClipboard value="0x2fe5CCB0d7Ea195FEB87987D3573f9FccE2b5d57">
      `0x2fe5CCB0d7Ea195FEB87987D3573f9FccE2b5d57`
    </CopyToClipboard>

    <span>
      (
      <a href="https://monadscan.com/address/0x2fe5CCB0d7Ea195FEB87987D3573f9FccE2b5d57">主网</a>

      {", "}

      <a href="https://testnet.monadscan.com/address/0x2fe5CCB0d7Ea195FEB87987D3573f9FccE2b5d57">测试网</a>
      )
    </span>
  </li>

  <li>
    <strong>Authenticated Multicall (Forwarder)</strong>:

    <CopyToClipboard value="0xcA1167915584462449EE5b4Ea51c37fE81eCDCCD">
      `0xcA1167915584462449EE5b4Ea51c37fE81eCDCCD`
    </CopyToClipboard>

    <span>
      (
      <a href="https://monadscan.com/address/0xcA1167915584462449EE5b4Ea51c37fE81eCDCCD">主网</a>

      {", "}

      <a href="https://testnet.monadscan.com/address/0xcA1167915584462449EE5b4Ea51c37fE81eCDCCD">测试网</a>
      )
    </span>
  </li>
</ul>

V3 账户实现已连接到 ERC-4337 EntryPoint v0.6,地址为 [`0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789`](https://monadscan.com/address/0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789)([测试网](https://testnet.monadscan.com/address/0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789)),该合约在 Monad 上也已上线。

## 使用 Tokenbound SDK 快速开始

安装 SDK 和 [viem](https://viem.sh):

```bash theme={null}
npm install @tokenbound/sdk viem@^2.40.0
```

将客户端指向 Monad。由于 Monad 的部署使用规范的 v3 地址,而这些地址正是 SDK 的默认值,因此您只需提供链信息 —— 无需任何自定义合约地址:

```ts theme={null}
import { TokenboundClient } from "@tokenbound/sdk"
import { createWalletClient, custom } from "viem"
import { monad } from "viem/chains" // chain 10143 使用 monadTestnet

const [account] = (await window.ethereum.request({
  method: "eth_requestAccounts",
})) as [`0x${string}`]

const walletClient = createWalletClient({
  account,
  chain: monad,
  transport: custom(window.ethereum),
})

const tokenboundClient = new TokenboundClient({
  walletClient,
  chain: monad,
})
```

<Note>
  请显式传递 viem 的 `chain` 对象(`monad` / `monadTestnet`)。仅通过 `chainId` 识别 Monad(例如 `chainId: 143`)需要将 Monad 注册到 SDK 内置的链列表中 —— 这项变更在 [tokenbound/sdk](https://github.com/tokenbound/sdk) 上游中被跟踪。要求 `viem` ≥ 2.40.0,这是首个导出 `monad` 主网链的版本。
</Note>

派生 NFT 的账户地址(具有确定性 —— 在账户部署之前即可推导),然后创建它:

```ts theme={null}
// NFT 合约 tokenId 1 的确定性账户地址
const account = tokenboundClient.getAccount({
  tokenContract: "0xYourNftContract",
  tokenId: "1",
})

// 在链上部署账户(幂等 —— 若已存在则可安全再次调用)
const { account: created, txHash } = await tokenboundClient.createAccount({
  tokenContract: "0xYourNftContract",
  tokenId: "1",
})
```

创建后,该账户由 NFT 的当前持有者控制。持有者可以通过它执行交易:

```ts theme={null}
const executedTxHash = await tokenboundClient.execute({
  account,
  to: "0xRecipient",
  value: 0n,
  data: "0x",
})
```

转移底层 NFT 后,账户的控制权 —— 以及它所持有的一切 —— 会自动转移给新所有者。无需任何进一步操作。

## 注意事项与限制

* **Monad 上未启用跨链执行。** 核心 TBA 技术栈已完整部署,但支持 Tokenbound 跨链调用的可选 LayerZero V2 executor 尚未部署。同链账户创建、所有权解析和执行均正常工作。

## 资源

* [ERC-6551 规范](https://eips.ethereum.org/EIPS/eip-6551)
* [Tokenbound 文档](https://docs.tokenbound.org)
* [Tokenbound SDK](https://github.com/tokenbound/sdk)
* [Tokenbound 合约](https://github.com/tokenbound/contracts)
* [Monad 开发者 Discord](https://discord.gg/monaddev)

## 需要帮助?

加入 [Monad 开发者 Discord](https://discord.gg/monaddev)。
