Aller au contenu principal

Développement CosmWasm

QoreChain prend en charge les contrats intelligents CosmWasm, permettant aux développeurs d'écrire des programmes sécurisés et isolés (sandboxed) en Rust qui compilent vers WebAssembly. Les contrats CosmWasm s'exécutent aux côtés des programmes EVM et SVM au sein de l'architecture triple-VM de QoreChain.

remarque

Les commandes ci-dessous utilisent le mainnet qorechain-vladi, actif depuis le 7 juin 2026 et exécutant la version de chaîne v3.1.97. Remplacez par --chain-id qorechain-diana pour le testnet.

Le téléversement et l'instanciation de code nécessitent actuellement une permission explicite

Au moment de la rédaction, code_upload_access et instantiate_default_permission sont tous deux définis sur Nobody à la fois sur le mainnet et le testnet — ce qui signifie que MsgStoreCode et MsgInstantiateContract ne sont pas ouverts par défaut à des comptes arbitraires, suite à une alerte de sécurité CosmWasm à l'échelle de l'industrie. Vous devrez obtenir de la gouvernance qu'elle accorde à votre compte (ou à une liste d'adresses spécifique) la permission de téléversement/instanciation avant que les étapes ci-dessous ne puissent réussir — vérifiez d'abord les paramètres en vigueur, car c'est exactement le type de réglage que la gouvernance peut modifier :

qorechaind query wasm params
# or: curl -s https://api.qore.host/cosmwasm/wasm/v1/codes/params (substitute api-testnet.qore.host for testnet)

Cette restriction n'affecte pas les contrats déjà instanciés — execute et query sur un contrat existant fonctionnent normalement quel que soit ce réglage.


Prérequis​

DépendanceVersionObjectif
RustDernière stableCompilation du contrat
wasm32-unknown-unknowncibleCible de compilation WebAssembly
cargo-generateDernièreGénération de la structure du projet
cosmwasm-std1.5+Bibliothèque standard CosmWasm

Installez la cible Wasm :

rustup target add wasm32-unknown-unknown

Cycle de vie du contrat​

Les contrats CosmWasm suivent un cycle de vie en cinq étapes : Build (construire), Store (stocker), Instantiate (instancier), Execute (exécuter) et Query (interroger).

  1. Build — Compilez votre contrat en WebAssembly optimisé :

    cd my-contract

    # Standard build
    cargo build --release --target wasm32-unknown-unknown

    # Optimized build (recommended for deployment)
    docker run --rm -v "$(pwd)":/code \
    cosmwasm/rust-optimizer:0.15.0

    Le fichier .wasm optimisé se trouvera dans le répertoire artifacts/.

  2. Store — Téléversez le contrat compilé vers la chaîne :

    qorechaind tx wasm store contract.wasm \
    --from mykey \
    --gas auto \
    --gas-adjustment 1.3 \
    -y

    Une fois la transaction confirmée, interrogez l'ID de code stocké :

    qorechaind query wasm list-code
  3. Instantiate — Créez une nouvelle instance de contrat à partir d'un ID de code stocké :

    qorechaind tx wasm instantiate <code-id> \
    '{"count": 0, "owner": "qor1..."}' \
    --label "my-counter-contract" \
    --from mykey \
    --no-admin \
    --gas auto \
    --gas-adjustment 1.3 \
    -y
    FlagDescription
    <code-id>ID numérique renvoyé par la transaction de stockage
    --labelÉtiquette lisible pour cette instance
    --no-adminAucune adresse admin (le contrat est immuable)
    --admin <address>Définit un admin pouvant migrer le contrat

    Récupérez l'adresse du contrat :

    qorechaind query wasm list-contracts-by-code <code-id>
  4. Execute — Appelez le point d'entrée d'exécution d'un contrat pour modifier son état :

    qorechaind tx wasm execute <contract-addr> \
    '{"increment": {}}' \
    --from mykey \
    --gas auto \
    -y

    Exécution avec des fonds joints :

    qorechaind tx wasm execute <contract-addr> \
    '{"deposit": {}}' \
    --amount 1000000uqor \
    --from mykey \
    -y
  5. Query — Lisez l'état du contrat sans soumettre de transaction :

    qorechaind query wasm contract-state smart <contract-addr> \
    '{"get_count": {}}'

    Les réponses aux requêtes sont renvoyées au format JSON.


Requêtes utiles​

# List all stored code
qorechaind query wasm list-code

# List all instances of a specific code ID
qorechaind query wasm list-contracts-by-code <code-id>

# Get contract info (code ID, admin, label)
qorechaind query wasm contract <contract-addr>

# Get raw contract state by key
qorechaind query wasm contract-state raw <contract-addr> <key-hex>

# Get full contract state (all keys)
qorechaind query wasm contract-state all <contract-addr>

# Get contract history (instantiate/migrate events)
qorechaind query wasm contract-history <contract-addr>

Structure du contrat​

Un contrat CosmWasm typique possède trois points d'entrée :

use cosmwasm_std::{
entry_point, Binary, Deps, DepsMut, Env, MessageInfo,
Response, StdResult,
};

#[entry_point]
pub fn instantiate(
deps: DepsMut,
_env: Env,
info: MessageInfo,
msg: InstantiateMsg,
) -> StdResult<Response> {
// Initialize contract state
Ok(Response::new().add_attribute("method", "instantiate"))
}

#[entry_point]
pub fn execute(
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: ExecuteMsg,
) -> StdResult<Response> {
// Handle state-changing operations
Ok(Response::new().add_attribute("method", "execute"))
}

#[entry_point]
pub fn query(
deps: Deps,
_env: Env,
msg: QueryMsg,
) -> StdResult<Binary> {
// Handle read-only queries
Ok(Binary::default())
}

Appels inter-VM​

Les contrats CosmWasm peuvent interagir avec des contrats déployés sur l'EVM et la SVM via le module x/crossvm. Les appels inter-VM depuis CosmWasm utilisent le chemin de message asynchrone :

use cosmwasm_std::{CosmosMsg, CustomMsg};

// Call an EVM contract from CosmWasm
let cross_vm_msg = CosmosMsg::Custom(QoreChainMsg::CrossVMCall {
target_vm: "evm".to_string(),
target_contract: "0x1234...abcd".to_string(),
payload: hex::encode(abi_encoded_data),
funds: vec![],
});

Ok(Response::new().add_message(cross_vm_msg))

Le message est soumis à une file d'attente et traité par l'EndBlocker au bloc suivant. Consultez Interopérabilité inter-VM pour le cycle de vie complet du message.


Intégration des modules​

Les contrats CosmWasm peuvent interagir avec les modules du Cosmos SDK via la transmission de messages standard :

// Send native tokens via the bank module
let send_msg = BankMsg::Send {
to_address: "qor1recipient...".to_string(),
amount: vec![Coin {
denom: "uqor".to_string(),
amount: Uint128::new(1_000_000),
}],
};

// Delegate to a validator via the staking module
let delegate_msg = StakingMsg::Delegate {
validator: "qorvaloper1...".to_string(),
amount: Coin {
denom: "uqor".to_string(),
amount: Uint128::new(1_000_000),
},
};

Migration du contrat​

Si le contrat a été instancié avec une adresse --admin, l'admin peut le migrer vers un nouvel ID de code :

qorechaind tx wasm migrate <contract-addr> <new-code-id> \
'{"migrate_msg": {}}' \
--from admin-key \
-y

Cela appelle le point d'entrée migrate sur le nouveau code avec l'état existant du contrat.


Étapes suivantes​