Submensajes

Los mensajes se utilizan para interactuar tanto con los módulos SDK como con los contratos inteligentes CW. Dado que los mensajes se ejecutan en forma de "configurar y olvidar", no recibirá una respuesta sobre si la llamada fue exitosa o no.

Sin embargo, obtener el resultado de tu llamada puede resultar muy útil en los siguientes casos:

  • Crear una instancia de un nuevo contrato y obtener la dirección del contrato

  • Ejecutar una acción y afirmar que el resultado fue exitoso (por ejemplo, asegurarse de que se haya transferido una determinada cantidad simbólica a su contrato)

  • Manejar el error de su llamada entre contratos en lugar de revertir la transacción

Para obtener el resultado del mensaje enviado desde su contrato inteligente, deberá enviar un submensaje. Puede leer más sobre la semántica de los submensajes y cómo se ordena la ejecución de los submensajes aquí.

Creando un submensaje

Un submensaje envuelve un CosmosMsg en una estructura SubMsg:

pub struct SubMsg<T> {
    pub id: u64,                // reply_id that will be used to handle the reply
    pub msg: CosmosMsg<T>,      // message to be sent
    pub gas_limit: Option<u64>, // gas limit for the submessage
    pub reply_on: ReplyOn,      // a flag to determine when the reply should be sent
}

Puede encontrar el código fuente de la estructura SubMsg aquí.

Ahora, veamos un ejemplo de cómo crear una instancia de un token cw20 usando un submensaje:

const INSTANTIATE_REPLY_ID = 1u64;
// Creating a message to create a new cw20 token
let instantiate_tx = WasmMsg::Instantiate {
    admin: None,
    code_id: msg.cw20_code_id,
    msg: to_binary(&Cw20InstantiateMsg {
        name: "new token".to_string(),
        symbol: "nToken".to_string(),
        decimals: 6,
        initial_balances: vec![],
        mint: Some(MinterResponse {
            minter: env.contract.address.to_string(),
            cap: None,
        }),
    })?,
    funds: vec![],
    label: "".to_string(),
};
// Creating a submessage that wraps the message above
let submessage = SubMsg::reply_on_success(instantiate_tx.into(), INSTANTIATE_REPLY_ID);
// Creating a response with the submessage
let response = Response::new().add_submessage(submessage);

Estrategias de respuesta

Los submensajes ofrecen cuatro opciones de respuesta diferentes para que las proporcione el otro contrato:

Tenga en cuenta que anteriormente creamos el submensaje usando la abreviatura SubMsg::reply_on_success. Sin embargo, también podemos crear un submensaje y especificar explícitamente la estrategia de respuesta.

Manejando una respuesta

Para manejar la respuesta del otro contrato, el contrato que llama debe implementar un nuevo punto de entrada. Aquí hay dos ejemplos de cómo manejar las respuestas:

Crear una instancia de un nuevo contrato

Manejo de una respuesta de una transferencia de token

Progagacion de contexto entre contratos.

Para detener los ataques de reentrada, CosmWasm no permite que se almacene el contexto en la memoria del contrato. Hay dos formas de propagar el estado entre contratos:

  • Todos los eventos devueltos por el submensaje se pueden leer en el mensaje de respuesta.

  • Almacenar un estado temporal usando cw_storage_plus::Item y cargarlo en el controlador de respuesta

Last updated