Quick Reference

Cheatsheet

Side-by-Side Syntax Comparison

01 Basic Contract Structure

Contract Template

Daml
template MyContract
  with
    owner : Party
    data : Text
  where
    signatory owner

    choice DoSomething : ContractId MyContract
      with param : Text
      controller owner
      do
        create this with data = param

Contract Structure

Rust
#[entry_point]
pub fn instantiate(
    deps: DepsMut,
    _env: Env,
    info: MessageInfo,
    msg: InstantiateMsg,
) -> StdResult<Response> {
    let state = State { owner: info.sender, data: msg.data };
    STATE.save(deps.storage, &state)?;
    Ok(Response::new())
}

#[entry_point]
pub fn execute(
    deps: DepsMut,
    _env: Env,
    info: MessageInfo,
    msg: ExecuteMsg,
) -> StdResult<Response> {
    match msg {
        ExecuteMsg::DoSomething { param } => { /* ... */ }
    }
}

Create Contract

Daml
-- In a choice or script
cid <- create MyContract with
  owner = party
  data = "hello"

Instantiate Contract

Rust
// Via CLI or another contract
let msg = WasmMsg::Instantiate {
    admin: Some(admin.to_string()),
    code_id,
    msg: to_json_binary(&InstantiateMsg { data: "hello".into() })?,
    funds: vec![],
    label: "my-contract".into(),
};
02 Data Types & Storage
Daml Types
Rust/CosmWasm Types
Party
Addr
ContractId a
Addr (contract address)
Text
String
Int
i64 / i128
Decimal
Decimal / Uint128
Bool
bool
Time
Timestamp
Date
Timestamp (seconds)
[a] (List)
Vec<T>
Optional a
Option<T>
Map k v
Map<K, V> (cw-storage-plus)

Custom Data Type

Daml
data Status
  = Pending
  | Active
  | Completed
  deriving (Eq, Show)

data Order = Order with
  id : Text
  amount : Decimal
  status : Status

Custom Data Type

Rust
#[derive(Serialize, Deserialize, Clone, PartialEq)]
pub enum Status {
    Pending,
    Active,
    Completed,
}

#[derive(Serialize, Deserialize, Clone)]
pub struct Order {
    pub id: String,
    pub amount: Uint128,
    pub status: Status,
}

Query Contract

Daml
-- Query by contract ID
Some contract <- queryContractId party cid

-- Query all contracts of a type
contracts <- query @MyContract party

-- Query with filter
results <- queryFilter @MyContract party
  (\c -> c.owner == party)

Query State

Rust
// Load single item
let state = STATE.load(deps.storage)?;

// Load from map
let order = ORDERS.load(deps.storage, &order_id)?;

// Optional load
let maybe = ORDERS.may_load(deps.storage, &id)?;

// Range query
let orders: Vec<_> = ORDERS
    .range(deps.storage, None, None, Order::Ascending)
    .take(10)
    .collect::<StdResult<_>>()?;
03 Common Patterns

Authorization Check

Daml
-- Built into controller declaration
choice Transfer : ContractId Asset
  with newOwner : Party
  controller owner  -- Only owner can call
  do
    create this with owner = newOwner

-- Additional runtime checks
choice Withdraw : ()
  with amount : Decimal
  controller owner
  do
    assertMsg "Insufficient balance" (amount <= balance)
    -- ...

Authorization Check

Rust
pub fn execute_transfer(
    deps: DepsMut,
    info: MessageInfo,
    new_owner: String,
) -> Result<Response, ContractError> {
    let state = STATE.load(deps.storage)?;

    // Manual authorization check
    if info.sender != state.owner {
        return Err(ContractError::Unauthorized {});
    }

    // Additional checks
    ensure!(
        amount <= state.balance,
        ContractError::InsufficientBalance {}
    );

    // ...
}

Time-Based Logic

Daml
template TimeLock
  with
    owner : Party
    unlockTime : Time
  where
    signatory owner

    choice Unlock : ()
      controller owner
      do
        now <- getTime
        assertMsg "Too early" (now >= unlockTime)

Time-Based Logic

Rust
pub fn execute_unlock(
    deps: DepsMut,
    env: Env,
    info: MessageInfo,
) -> Result<Response, ContractError> {
    let lock = TIMELOCK.load(deps.storage)?;

    if env.block.time < lock.unlock_time {
        return Err(ContractError::TooEarly {
            unlock_time: lock.unlock_time,
        });
    }

    // Proceed with unlock...
}

Error Handling

Daml
-- Using assert
assertMsg "Amount must be positive" (amount > 0.0)

-- Using exceptions
exception InsufficientFunds with
    requested : Decimal
    available : Decimal
  where
    message "Insufficient funds"

-- Throwing
when (amount > balance) do
  throw InsufficientFunds with
    requested = amount
    available = balance

Error Handling

Rust
// Define errors
#[derive(Error, Debug)]
pub enum ContractError {
    #[error("{0}")]
    Std(#[from] StdError),

    #[error("Insufficient funds: need {requested}, have {available}")]
    InsufficientFunds { requested: Uint128, available: Uint128 },

    #[error("Unauthorized")]
    Unauthorized {},
}

// Use ensure! macro
ensure!(amount > Uint128::zero(), ContractError::InvalidAmount {});

// Or explicit return
if amount > balance {
    return Err(ContractError::InsufficientFunds { requested: amount, available: balance });
}
04 CLI Commands
Create Project daml new my-project
Create Project cargo generate --git cw-template
Build daml build
Build cargo wasm
Test daml test
Test cargo test
Start Local daml start
Optimize docker run cosmwasm/optimizer
Run Script daml script --dar app.dar --script-name Main:setup
Store Code wasmd tx wasm store contract.wasm
Generate Docs daml damlc docs
Instantiate wasmd tx wasm instantiate $CODE_ID '{}'

Canton Console

Scala
// Start Canton
bin/canton -c canton.conf

// Connect to domain
participant1.domains.connect_local(mydomain)

// Upload DAR
participant1.dars.upload("app.dar")

// List parties
participant1.parties.list()

// Health check
participant1.health.status()

wasmd CLI

Bash
# Query contract
wasmd query wasm contract-state smart $ADDR '{"get_count":{}}'

# Execute
wasmd tx wasm execute $ADDR '{"increment":{}}' --from wallet

# List contracts
wasmd query wasm list-contract-by-code $CODE_ID

# Get contract info
wasmd query wasm contract $ADDR

# Migrate contract
wasmd tx wasm migrate $ADDR $NEW_CODE '{}' --from admin
05 Quick Reference

Daml Keywords

Reference
template      -- Define contract type
with          -- Contract fields
where         -- Contract body
signatory     -- Required signers
observer      -- Can see contract
controller    -- Can exercise choice
choice        -- Define action
nonconsuming  -- Don't archive on exercise
preconsuming  -- Archive before exercise
postconsuming -- Archive after exercise
key           -- Unique contract key
maintainer    -- Key maintainer
ensure        -- Creation precondition
agreement     -- Human-readable text
create        -- Create new contract
exercise      -- Call a choice
fetch         -- Get contract data
archive       -- Archive contract
assertMsg     -- Runtime assertion
getTime       -- Current ledger time
forA          -- Loop with actions
foldlA        -- Fold with actions

CosmWasm Imports

Reference
// Core types
use cosmwasm_std::{
    entry_point,    // Mark entry points
    DepsMut, Deps,  // Storage access
    Env,            // Block info, contract addr
    MessageInfo,    // Sender, funds
    Response,       // Return type
    StdResult,      // Result alias
    StdError,       // Standard errors
    Addr,           // Validated address
    Uint128,        // 128-bit unsigned
    Decimal,        // Fixed-point decimal
    Coin, coins,    // Native tokens
    BankMsg,        // Send tokens
    WasmMsg,        // Call contracts
    to_json_binary, // Serialize
    from_json,      // Deserialize
};

// Storage
use cw_storage_plus::{
    Item,           // Single value
    Map,            // Key-value map
    IndexedMap,     // Map with indexes
};

// Standard interfaces
use cw2::set_contract_version;
use cw20::{Cw20ExecuteMsg, Cw20QueryMsg};