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

# 在 CosmWasm 中使用 Injective 模块和查询

本指南全面概述了如何使用 `Any` 消息和查询在 CosmWasm 中与 Injective 的模块和查询进行交互。旧的 [injective-cosmwasm](https://github.com/InjectiveLabs/cw-injective/tree/dev/packages/injective-cosmwasm) 包依赖于 JSON 编码的消息，已不再维护，可能会过时。本指南重点介绍使用 protobuf 编码的 `Any` 消息和查询的推荐方法，这种方法更高效，并且符合现代 CosmWasm 标准。

## CosmWasm 中的 `Any` 消息是什么？

在 CosmWasm 中，`Any` 消息是 `CosmosMsg` 枚举的一部分，允许你发送包装在链支持的 protobuf `Any` 类型中的消息。它们取代了已弃用的 `Stargate` 消息（在 `stargate` 功能标志下仍然可用），具有改进的命名和语法。`Any` 消息使用 `cosmwasm_2_0` 功能门控，这意味着它们需要运行 CosmWasm 2.0 的链，Injective 支持这一点。以下是 `CosmosMsg` 定义的片段：

```rust theme={null}
pub enum CosmosMsg<T = Empty> {
    // ...
    #[cfg(feature = "cosmwasm_2_0")]
    Any(AnyMsg),
    // ...
}

pub struct AnyMsg {
    pub type_url: String,
    pub value: Binary,
}
```

`type_url` 指定 protobuf 消息类型，`value` 包含序列化的消息数据。

## 为什么使用这种方法？

`injective-cosmwasm` 包使用基于 JSON 的消息，效率较低，可能无法与未来的更新保持兼容。新的 `Any` 消息方法使用 protobuf 编码，提供更好的性能、类型安全性和与 CosmWasm 2.0+ 的兼容性。这现在是与 Injective 模块和查询交互的推荐方法。

## 发送消息

要发送消息，你需要创建一个 protobuf 消息，对其进行编码，并将其包装在 `Any` 消息中。以下是在 Injective 的 exchange 模块上创建现货市价单的示例。

### 示例：创建现货市价单

```rust theme={null}
use cosmwasm_std::{AnyMsg, CosmosMsg, StdResult};
use injective_cosmwasm::{InjectiveMsgWrapper, OrderType, SpotMarket};
use injective_math::{round_to_min_tick, round_to_nearest_tick, FPDecimal};
use injective_std::types::injective::exchange::v1beta1 as Exchange;
use prost::Message;

pub fn create_spot_market_order_message(
    price: FPDecimal,
    quantity: FPDecimal,
    order_type: OrderType,
    sender: &str,
    subaccount_id: &str,
    fee_recipient: &str,
    market: &SpotMarket,
) -> StdResult<CosmosMsg<InjectiveMsgWrapper>> {
    let msg = create_spot_market_order(price, quantity, order_type, sender, subaccount_id, fee_recipient, market);

    let mut order_bytes = vec![];
    Exchange::MsgCreateSpotMarketOrder::encode(&msg, &mut order_bytes).unwrap();

    Ok(CosmosMsg::Any(AnyMsg {
        type_url: Exchange::MsgCreateSpotMarketOrder::TYPE_URL.to_string(),
        value: order_bytes.into(),
    }))
}

fn create_spot_market_order(
    price: FPDecimal,
    quantity: FPDecimal,
    order_type: OrderType,
    sender: &str,
    subaccount_id: &str,
    fee_recipient: &str,
    market: &SpotMarket,
) -> Exchange::MsgCreateSpotMarketOrder {
    let rounded_quantity = round_to_min_tick(quantity, market.min_quantity_tick_size);
    let rounded_price = round_to_nearest_tick(price, market.min_price_tick_size);

    Exchange::MsgCreateSpotMarketOrder {
        sender: sender.to_string(),
        order: Some(Exchange::SpotOrder {
            market_id: market.market_id.as_str().into(),
            order_info: Some(Exchange::OrderInfo {
                subaccount_id: subaccount_id.to_string(),
                fee_recipient: fee_recipient.to_string(),
                price: rounded_price.to_string(),
                quantity: rounded_quantity.to_string(),
                cid: "".to_string(),
            }),
            order_type: order_type as i32,
            trigger_price: "".to_string(),
        }),
    }
}
```

**步骤：**

1. 使用订单详细信息构造 `MsgCreateSpotMarketOrder` protobuf 消息。
2. 使用 `prost::Message::encode` 将其编码为字节。
3. 使用正确的 `type_url` 将其包装在 `AnyMsg` 中。
4. 将其作为 `CosmosMsg::Any` 返回。

这种方法可以通过使用适当的 protobuf 消息和 `type_url` 适用于其他模块（例如 auction、tokenfactory）。

## 执行查询

查询使用带有 `InjectiveQueryWrapper` 的 `QuerierWrapper` 执行。你可以使用 `injective_std` 中的预构建查询器或发送原始查询。以下是涵盖不同模块的示例。

### 示例：查询现货市场（Exchange 模块）

```rust theme={null}
use cosmwasm_std::{to_json_binary, Binary, Deps, StdResult};
use injective_cosmwasm::InjectiveQueryWrapper;
use injective_std::types::injective::exchange::v1beta1::ExchangeQuerier;

pub fn handle_query_spot_market(deps: Deps<InjectiveQueryWrapper>, market_id: &str) -> StdResult<Binary> {
    let querier = ExchangeQuerier::new(&deps.querier);
    to_json_binary(&querier.spot_market(market_id.to_string())?)
}
```

**步骤：**

1. 从 `deps.querier` 创建 `ExchangeQuerier`。
2. 使用 `market_id` 调用 `spot_market`。
3. 将响应序列化为 JSON 并作为 `Binary` 返回。

### 示例：查询 Bank 参数（Bank 模块）

```rust theme={null}
use cosmwasm_std::{to_json_binary, Binary, Deps, StdResult};
use injective_cosmwasm::InjectiveQueryWrapper;
use injective_std::types::cosmos::bank::v1beta1::BankQuerier;

pub fn handle_query_bank_params(deps: Deps<InjectiveQueryWrapper>) -> StdResult<Binary> {
    let querier = BankQuerier::new(&deps.querier);
    to_json_binary(&querier.params()?)
}
```

**步骤：**

1. 从 `deps.querier` 创建 `BankQuerier`。
2. 调用 `params` 获取 bank 模块参数。
3. 序列化并返回结果。

## 使用其他模块

相同的原则适用于其他 Injective 模块，如 auction、insurance、oracle、permissions 和 tokenfactory，以及 Cosmos 原生模块。例如：

* **Auction 模块**：使用 `AuctionQuerier` 进行查询或将 `MsgBid` 编码为 `Any` 消息。
* **Tokenfactory 模块**：编码 `MsgCreateDenom` 或使用 `TokenFactoryQuerier`。

有关特定消息类型和查询器，请参阅 [injective\_std](https://github.com/InjectiveLabs/injective-rust/tree/dev/packages/injective-std)。
