> ## Documentation Index
> Fetch the complete documentation index at: https://injectivelabs-docs-ai-sdk.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Token Factory

`tokenfactory` 模块允许任何账户创建名为 `factory/{creator address}/{subdenom}` 的新代币。由于代币按创建者地址命名空间化，这使得代币铸造无需许可，因为不需要解决名称冲突。

*注意：如果您希望您的 denom 在 Helix、Hub、Explorer 等产品上可见，使用下面解释的 `MsgSetDenomMetadata` 消息添加代币元数据信息非常重要。*

*注意 #2：建议将您的 admin 更改为零地址，以确保安全并防止供应量操纵。*

## 消息

让我们探索（并提供示例）TokenFactory 模块导出的消息，我们可以使用这些消息与 Injective 链交互。

### MsgCreateDenom

给定 denom 创建者地址和 subdenom，创建 `factory/{creator address}/{subdenom}` 的 denom。Subdenom 可以包含 \[a-zA-Z0-9./]。请记住，创建新代币时需要支付 `creation fee`。

请记住，代币的 `admin` 可以更改供应量（铸造或销毁新代币）。建议使用 `MsgChangeAdmin` 取消设置 `admin`，如下所述。

```ts theme={null}
import { Network } from "@injectivelabs/networks";
import { MsgCreateDenom } from "@injectivelabs/sdk-ts/core/modules";
import { MsgBroadcasterWithPk } from "@injectivelabs/sdk-ts/core/tx";

const injectiveAddress = "inj1...";
const privateKey = "0x...";
const subdenom = "inj-test";

const msg = MsgCreateDenom.fromJSON({
  subdenom,
  symbol: "InjTest",
  name: "Inj Testing",
  sender: injectiveAddress,
});

const txHash = await new MsgBroadcasterWithPk({
  privateKey,
  network: Network.Testnet,
}).broadcast({
  msgs: msg,
});

console.log(txHash);
```

### MsgMint

特定 denom 的铸造仅允许当前 admin 执行。注意，当前 admin 默认为 denom 的创建者。

```ts theme={null}
import { Network } from "@injectivelabs/networks";
import { MsgMint } from "@injectivelabs/sdk-ts/core/modules";
import { MsgBroadcasterWithPk } from "@injectivelabs/sdk-ts/core/tx";

const injectiveAddress = "inj1...";
const privateKey = "0x...";
const subdenom = "inj-test";
const amountToMint = 1_000_000_000;

const msg = MsgMint.fromJSON({
  sender: injectiveAddress,
  amount: {
    denom: `factory/${injectiveAddress}/${subdenom}`,
    amount: amountToMint,
  },
});

const txHash = await new MsgBroadcasterWithPk({
  privateKey,
  network: Network.Testnet,
}).broadcast({
  msgs: msg,
});

console.log(txHash);
```

### MsgBurn

admin 可以销毁 token factory 的供应量。其他人只能使用此消息销毁自己的资金。

```ts theme={null}
import { Network } from "@injectivelabs/networks";
import { MsgBurn } from "@injectivelabs/sdk-ts/core/modules";
import { MsgBroadcasterWithPk } from "@injectivelabs/sdk-ts/core/tx";

const injectiveAddress = "inj1...";
const privateKey = "0x...";
const subdenom = "inj-test";
const amountToBurn = 1_000_000_000;

const msg = MsgBurn.fromJSON({
  sender: injectiveAddress,
  amount: {
    denom: `factory/${injectiveAddress}/${subdenom}`,
    amount: amountToBurn,
  },
});

const txHash = await new MsgBroadcasterWithPk({
  privateKey,
  network: Network.Testnet,
}).broadcast({
  msgs: msg,
});

console.log(txHash);
```

### MsgSetDenomMetadata

为特定 denom 设置元数据仅允许 denom 的 admin 执行。它允许覆盖 bank 模块中的 denom 元数据。

```ts theme={null}
import { Network } from "@injectivelabs/networks";
import { MsgSetDenomMetadata } from "@injectivelabs/sdk-ts/core/modules";
import { MsgBroadcasterWithPk } from "@injectivelabs/sdk-ts/core/tx";

const injectiveAddress = "inj1...";
const privateKey = "0x...";
const subdenom = 'inj-test'
const denom = `factory/${injectiveAddress}/${subdenom}`;

const denomUnitsIfTokenHas0Decimals = [
  {
    denom: denom,
    exponent: 0,
    aliases: [subdenom]
  },
]
const denomUnitsIfTokenHas6Decimals = [
  {
    denom: denom, /** 这里使用完整的 denom */
    exponent: 0,
    aliases: [subdenom]
  },
  {
    denom: subdenom,
    exponent: 6, /** 这里只使用 subdenom（如果您希望代币有 6 位小数） */
    aliases: []
  },
]

const msg = MsgSetDenomMetadata.fromJSON({
  sender: injectiveAddress,
  metadata: {
    base: denom, /** 基础 denom */
    description: '', /** 代币描述 */
    display: subdenom, /** 代币在 UI 上的显示别名（是具有最高小数位的单位的 denom） */
    name: '', /** 代币名称 */
    symbol: '', /** 代币符号 */
    uri: '' /** 代币 logo，应托管在 IPFS 上，应为小型 webp 图片 */
    denomUnits: denomUnitsIfTokenHas6Decimals  /** 选择代币是否有 6 或 0 位小数 */,
    decimals: 6 /** 选择代币是否有 6 或 0 位小数 */
  }
});

const txHash = await new MsgBroadcasterWithPk({
  privateKey,
  network: Network.Testnet
}).broadcast({
  msgs: msg
});

console.log(txHash);
```

### MsgChangeAdmin

denom 的 admin 可以铸造新供应量或销毁现有供应量。建议将 admin 更改为零地址，以不允许更改代币的供应量。

```ts theme={null}
import { Network } from "@injectivelabs/networks";
import { MsgChangeAdmin } from "@injectivelabs/sdk-ts/core/modules";
import { MsgBroadcasterWithPk } from "@injectivelabs/sdk-ts/core/tx";

const injectiveAddress = "inj1...";
const privateKey = "0x...";
const subdenom = "inj-test";
const denom = `factory/${injectiveAddress}/${subdenom}`;

const msg = MsgChangeAdmin.fromJSON({
  denom,
  sender: injectiveAddress,
  newAdmin:
    "inj1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqe2hm49" /** 设置为零地址 */,
});

const txHash = await new MsgBroadcasterWithPk({
  privateKey,
  network: Network.Testnet,
}).broadcast({
  msgs: msg,
});

console.log(txHash);
```

## 完整示例

以下是在 Injective 上创建新代币、铸造新代币和设置代币元数据的完整示例。

```ts theme={null}
import { Network } from "@injectivelabs/networks";
import { MsgBroadcasterWithPk } from "@injectivelabs/sdk-ts/core/tx";
import { MsgSetDenomMetadata, MsgCreateDenom, MsgMint, MsgChangeAdmin } from "@injectivelabs/sdk-ts/core/modules";

const injectiveAddress = "inj1...";
const privateKey = "0x...";
const subdenom = 'inj-test'
const denom = `factory/${injectiveAddress}/${subdenom}`;
const amount = 1_000_000_000

const msgCreateDenom = MsgCreateDenom.fromJSON({
  subdenom,
  sender: injectiveAddress,
});
const msgMint = MsgMint.fromJSON({
  sender: injectiveAddress,
  amount: {
    denom: `factory/${injectiveAddress}/${subdenom}`,
    amount: amount
  }
});
const msgChangeAdmin = MsgChangeAdmin.fromJSON({
  denom: `factory/${injectiveAddress}/${subdenom}`,
  sender: injectiveAddress,
  newAdmin: 'inj1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqe2hm49' /** 设置为零地址 */
});
const msgSetDenomMetadata = MsgSetDenomMetadata.fromJSON({
  sender: injectiveAddress,
  metadata: {
    base: denom, /** 基础 denom */
    description: '', /** 代币描述 */
    display: '', /** 代币在 UI 上的显示名称 */,
    name: '', /** 代币名称 */,
    symbol: '' /** 代币符号 */,
    uri: '' /** 代币 logo，应托管在 IPFS 上，应为小型 webp 图片 */
    denomUnits: [
      {
        denom: denom,
        exponent: 0,
        aliases: [subdenom]
      },
      {
        denom: subdenom,
        exponent: 6, /** 如果您希望代币有 6 位小数 */
        aliases: []
      },
    ]
  }
});

const txHash = await new MsgBroadcasterWithPk({
  privateKey,
  network: Network.Testnet
}).broadcast({
  msgs: [msgCreateDenom, msgMint, msgSetDenomMetadata, msgChangeAdmin]
});

console.log(txHash);
```
