8 stable releases (3 major)
4.3.0 | Sep 27, 2024 |
---|---|
4.2.0 | Mar 26, 2024 |
4.1.0 | Jan 26, 2024 |
3.2.0 | Nov 23, 2023 |
1.0.0 | May 8, 2023 |
#7 in #off-chain
104 downloads per month
255KB
4K
SLoC
Concordium Smart Contract Testing
A library that supports writing integration tests in Rust for Concordium smart contracts.
This is a companion to concordium-std which is used to write smart contracts in Rust.
Documentation
MSRV
The minimum supported Rust version can be found in the Cargo.toml
manifest
file. Changes in MSRV will be accompanied by at least a minor version bump.
lib.rs
:
Concordium Smart Contract Testing
This library supports writing integration tests in Rust for Concordium smart contracts.
To use the library, you must add it to your Cargo.toml
file under the
[dev-dependencies]
section. The library requries the rust edition 2021
or greater.
[package]
# ...
edition = "2021"
[dev-dependencies]
concordium-smart-contract-testing = "4.0"
Basic usage
use concordium_smart_contract_testing::*;
// Create a "chain" with default parameters.
let mut chain = Chain::new();
// Define an account address to be used.
const ACC: AccountAddress = AccountAddress([0;32]);
// Create an account with 10000 CCD in balance.
chain.create_account(Account::new(ACC, Amount::from_ccd(1000)));
// Deploy a smart contract module (built with [Cargo Concordium](https://developer.concordium.software/en/mainnet/smart-contracts/guides/setup-tools.html#cargo-concordium)).
let deployment = chain
.module_deploy_v1(
Signer::with_one_key(),
ACC,
module_load_v1("path/to/contract.wasm.v1").unwrap())
.unwrap();
// Initialize a smart contract from the deployed module.
let initialization = chain
.contract_init(
Signer::with_one_key(), // Used for specifying the number of signatures.
ACC, // Invoker account.
Energy::from(10000), // Maximum energy allowed for initializing.
InitContractPayload {
mod_ref: deployment.module_reference, // Module to initialize from.
init_name: OwnedContractName::new_unchecked("init_my_contract".into()), // Contract to init.
param: OwnedParameter::from_serial(&"my_param").unwrap(), // Any type implementing [`Serial`] can be used.
amount: Amount::zero(), // CCD to send the contract.
}
)
.unwrap();
// Update the initialized contract.
let update = chain
.contract_update(
Signer::with_one_key(), // Used for specifying the number of signatures.
ACC, // Invoker account.
Address::Account(ACC), // Sender (can also be a contract).
Energy::from(10000), // Maximum energy allowed for the update.
UpdateContractPayload {
address: initialization.contract_address, // The contract to update.
receive_name: OwnedReceiveName::new_unchecked("my_contract.my_entrypoint".into()), // The receive function to call.
message: OwnedParameter::from_serial(&42u8).unwrap(), // The parameter sent to the contract.
amount: Amount::from_ccd(100), // Sending the contract 100 CCD.
}
)
.unwrap();
// Check the trace elements produced (updates, interrupts, resumes, transfers, etc.).
assert!(matches!(update.effective_trace_elements().collect::<Vec<_>>()[..], [ContractTraceElement::Updated{..}]));
// Check the return value.
assert_eq!(update.return_value, to_bytes(&84u8));
// Check the balances of both contracts and accounts.
assert_eq!(chain.contract_balance(initialization.contract_address), Some(Amount::from_ccd(100)));
assert_eq!(chain.account_balance_available(ACC), Some(
Amount::from_ccd(1000)
- Amount::from_ccd(100) // Amount sent to contract.
- deployment.transaction_fee
- initialization.transaction_fee
- update.transaction_fee));
Dependencies
~26–37MB
~540K SLoC