🌱
Dev Compendium
  • Ethereum
    • Solidity
      • EVM
      • Architecture
      • Execution Context
      • Transactions
      • Gas
      • Calldata, Memory & Storage
      • Gas Optimisation
      • Function Declarations
      • receive() & fallback()
      • CALL vs. DELEGATE CALL
    • Yul
      • Introduction
      • Types
      • Basic Operations
      • Storage
      • Memory
        • Arrays
        • Structs
        • Tuples, revert, keccak256
        • Logs and Events
        • Gotchas
        • abi.encode
      • Calldata
        • External Calls
        • Dynamic Length Inputs
        • Transferring Value
        • Receiving Contract Calls
      • Contracts in Yul
      • Other Yul Functions
    • Foundry
    • Security
      • Common Vulnerabilities
      • Best Practices
      • Development Workflow
      • Contract Migration
    • Auditing Tools
      • Slither
      • Mythril
      • Fuzzing
    • Upgradable Contracts
      • Upgrade Patterns
      • ERC-1967 Implementation
      • Deployment
    • MEV
    • Tooling
      • Chainlink
      • IPFS
      • Radicle
    • Frontend
      • Contract Hooks
      • Wallet Connection
        • wagmi.sh
        • Rainbow Kit
      • thirdweb
    • Protocol Research
      • Uniswap v2
      • Uniswap v3
      • Curve
      • GMX
  • Starkware
    • Fundamentals
    • Account Abstraction
    • Universal Deployer
    • Cairo 1.0
    • starknet.js
    • Security Model
  • Zero Knowledge
    • Group Theory
    • ECDSA
  • Rust
    • Basic Operations
    • Set up
    • Primitives
    • Control Flow
    • Mutability & Shadowing
    • Adding Behavior
    • Lifetimes
    • Std Library
  • SUI
    • Architecture
    • Consensus Mechanism
    • Local Node Setup
    • Sui Client CLI
    • Move Contracts
      • Move
      • Move.toml
      • Move.lock
      • Accessing Time in Sui Move
      • Set up Development Framework
      • Debug & Publish
      • Package Upgrades
      • Sui Move Library
      • Difference from Core Move
    • Object Programming
      • Object Basics
      • Using Objects
      • Immutable Objects
      • Object Wrapping
      • Dynamic Fields
      • Collections
      • Unit Testing
      • Deployment with CLI
  • NEAR
    • Architecture
    • Contract Standards
      • Fungible Token (NEP-141)
      • Non-Fungible Token (NEP-171)
      • Storage Management (NEP-145)
      • Events (NEP-297)
      • Meta-Transactions
    • Rust Contracts
      • Development Workflow
      • Smart Contract Layout
      • Storage Management
      • Events & Meta-transactions
      • Method Types
      • Upgrading Contracts
      • Unit Testing
    • NEAR Libraries
    • Environment Variables
    • Serialisation
    • Security Concepts
    • Collections
    • JS SDK
Powered by GitBook
On this page
  1. SUI
  2. Move Contracts

Move

PreviousMove ContractsNextMove.toml

Last updated 1 year ago

Structs

struct Foo {
  x: u64,
  y: bool
}

In Move, modules have much more control over how their types can and can’t be used than conventional programming languages do. A struct defined as in the code snippet above will have the following restrictions:

  • It can only be instantiated (“packed”) and destroyed (“unpacked”) inside the module that defines the struct — i.e. you cannot instantiate or destroy a struct instance from inside any function in any other module

  • Fields of a struct instance can only be accessed (and therefore mutated) from its module

  • You cannot clone or duplicate a struct instance outside its module

  • You cannot store a struct instance in a field of some other struct instance

This means that if you’re handling an instance of this struct in a function in another module, you wouldn’t be able to mutate its fields, clone it, store it in a field in another struct, or drop it (you’d have to pass it on somewhere else via a function call). It may be the case that the struct’s module implements functions that do those things that can be called from our module, but otherwise we can’t do any of those things directly for an external type. This gives modules full control over how their types can and can’t be used.

Move allows us to loosen up some of these restrictions by adding capabilities to structs. There are four capabilities: key, store, copy, and drop. You can add any combination of these capabilities to a struct:

struct Foo has key, store, copy, drop {
  id: UID,
  x: u64,
  y: bool
}
  • key — this allows a struct to become an object (Sui specific, core Move is slightly different). As explained earlier, objects are persisted and, in the case of owned objects, require user signatures to be used in a smart contract call. When the key capability is used, the first field of the struct must be the ID of the object with the type . This will give it a globally unique ID that can be used to reference it.

  • store — this allows the struct to be embedded as a field in another struct

  • copy — this allows the struct to be copied/cloned arbitrarily from anywhere

  • drop — this allows the struct to be destroyed arbitrarily from anywhere

In essence, every struct in Move is a resource by default. Capabilities give us the power to granularly loosen up these restrictions and make them behave more like conventional structs.

UID