Variables

The most important variables are those that are persisted in state and retain their value between contract executions. They must be defined in the scope of the contract like contractVar1.

Persisting data in state costs gas. The contract must pay rent periodically from its balance. State storage is expensive, about 4 TON per MB per year. If the contract runs out of balance, the data will be deleted. If you need to store large amounts of data, like images, a service like TON Storage would be more suitable.

Persistent state variables can only change in receivers by sending messages as transactions. Sending these transactions will cost gas to users.

Executing getters is read-only, they can access all variables, but cannot change state variables. They are free to execute and don't cost any gas.

Local variables like localVar1 are temporary. They're not persisted to state. You can define them in any function and they will only exist in run-time during the execution of the function. You can change their value in getters too.

All Examples
import "@stdlib/deploy";

message TransferEvent {
    amount: Int as coins;
    recipient: Address;
}

message StakeEvent {
    amount: Int as coins;
}

contract Emit with Deployable {

    init() {}

    receive("action") {
        // handle action here
        // ...
        // emit log that the action was handled
        emit("Action handled".asComment());
    }

    receive("transfer") {
        // handle transfer here
        // ...
        // emit log that the transfer happened
        emit(TransferEvent{amount: ton("1.25"), recipient: sender()}.toCell());
    }

    receive("stake") {
        // handle stake here
        // ...
        // emit log that stake happened
        emit(StakeEvent{amount: ton("0.007")}.toCell());
    }
}