# EVM/MoveVM Cheatsheet

### <mark style="color:red;">High-Level Overview</mark> <a href="#high-level-overview" id="high-level-overview"></a>

| Feature           | Ethereum                                 | Supra Move                                            |
| ----------------- | ---------------------------------------- | ----------------------------------------------------- |
| Smart Contracts   | Solidity, EVM                            | Move, MoveVM                                          |
| Benefits          | Mature, wide adoption                    | Scalability, low latency, Optimal fees                |
| Transaction Fees  | Variable, can be high                    | Lower and more predictable                            |
| Account Addresses | 160-bit                                  | 256-bit                                               |
| Account Structure | Balance in a single field, uses nonce    | Modules and resources, uses sequence number           |
| Data Storage      | Patricia Merkle Trees                    | Global storage with resources and modules             |
| Storage Mindset   | Contract-based storage                   | Account & Resources centric mindset for code and data |
| Parallelization   | Limited due to shared storage space      | Enhanced parallel execution due to resource model     |
| Type Safety       | Contract types provide basic type safety | Module structs and generics offer robust type safety  |
| Unique Features   | Wide ecosystem, EVM compatibility        | Native VRF, Automation, Oracle price feeds            |

### <mark style="color:red;">Comparing Token Standards</mark> <a href="#comparing-token-standards" id="comparing-token-standards"></a>

| Aspect             | Ethereum/Solidity                                          | Supra Move                                                        |
| ------------------ | ---------------------------------------------------------- | ----------------------------------------------------------------- |
| Token Structure    | Each token is its own contract                             | Every token uses typed Coin with single, reusable contract        |
| Token Standard     | Must conform to standards like ERC20; implementations vary | Uniform interface and implementation for all tokens               |
| Balance Storage    | Balances stored in contract using mapping structure        | Resource-Oriented: Balances stored as resource in user’s account  |
| Transfer Mechanism | Tokens can be transferred without receiver’s permission    | Tokens require receiver’s explicit consent for transfer           |
| Safety             | Depends on implementation quality                          | Resources cannot be arbitrarily created, ensuring token integrity |

### <mark style="color:red;">Comparing EVM and Move VM</mark> <a href="#comparing-evm-and-move-vm" id="comparing-evm-and-move-vm"></a>

| Aspect                      | EVM (Ethereum Virtual Machine)                   | Move VM (Supra Move Virtual Machine)                           |
| --------------------------- | ------------------------------------------------ | -------------------------------------------------------------- |
| Data Storage                | Data stored in smart contract’s storage space    | Data stored across smart contracts, user accounts, and objects |
| Parallelization             | Limited parallel execution due to shared storage | Enhanced parallel execution enabled by flexible split storage  |
| VM and Language Integration | Separate layers for EVM and languages (Solidity) | Seamless integration between VM layer and Move language        |
| Critical Network Operations | Complex implementation of network operations     | Critical operations natively implemented in Move               |
| Function Calling            | Dynamic dispatch allows arbitrary contract calls | Static dispatch focuses on security and predictable behavior   |
| Type Safety                 | Contract types provide basic type safety         | Module structs and generics offer robust type safety           |
| Transaction Safety          | Uses nonces for transaction ordering             | Uses sequence numbers for transaction ordering                 |
| Object Accessibility        | Objects bound to smart contract scope            | Guaranteed global accessibility of objects                     |

### <mark style="color:red;">Module Structure & Initialization</mark> <a href="#module-structure--initialization" id="module-structure--initialization"></a>

#### Ethereum (Solidity) <a href="#ethereum-solidity" id="ethereum-solidity"></a>

```
// SPDX-License-Identifier: MITpragma solidity ^0.8.0;
contract MyContract {    address public owner;    uint256 public value;
    constructor(uint256 _initialValue) {        owner = msg.sender;        value = _initialValue;    }
    modifier onlyOwner() {        require(msg.sender == owner, "Not owner");        _;    }}
```

#### Supra Move <a href="#supra-move" id="supra-move"></a>

```
module my_address::my_contract {    use supra_framework::signer;    use supra_framework::account;    use std::error;
    struct ContractData has key {        owner: address,        value: u64,    }
    const E_NOT_OWNER: u64 = 1;
    // Called once when module is published    fun init_module(account: &signer) {        let owner = signer::address_of(account);        move_to(account, ContractData {            owner,            value: 0,        });    }
    // Manual initialization function    public entry fun initialize(account: &signer, initial_value: u64) {        let addr = signer::address_of(account);        move_to(account, ContractData {            owner: addr,            value: initial_value,        });    }}
```

**Key Differences:**

* **Supra Move**: Uses `init_module` for automatic initialization or explicit initialization functions
* **Ethereum**: Uses constructors that run once during deployment
* **Supra Move:** Resources are stored under user accounts, not contract addresses
* **Ethereum**: State stored in contract storage slots

### <mark style="color:red;">Functions</mark> <a href="#functions" id="functions"></a>

#### Ethereum (Solidity) <a href="#ethereum-solidity-1" id="ethereum-solidity-1"></a>

```
contract Functions {    uint256 private _value;
    // Public function (external callable)    function setValue(uint256 newValue) public {        _value = newValue;    }
    // View function (read-only)    function getValue() public view returns (uint256) {        return _value;    }
    // Pure function (no state access)    function add(uint256 a, uint256 b) public pure returns (uint256) {        return a + b;    }
    // Internal function    function _internalHelper() internal pure returns (uint256) {        return 42;    }
    // Payable function    function deposit() public payable {        // Function can receive Ether    }}
```

#### Supra Move <a href="#supra-move-1" id="supra-move-1"></a>

```
module my_address::functions {    use supra_framework::signer;
    struct Storage has key {        value: u64,    }
    // Public entry function (blockchain callable)    public entry fun set_value(account: &signer, new_value: u64) acquires Storage {        let addr = signer::address_of(account);        let storage = borrow_global_mut<Storage>(addr);        storage.value = new_value;    }
    // View function (read-only)    #[view]    public fun get_value(addr: address): u64 acquires Storage {        borrow_global<Storage>(addr).value    }
    // Public function (can be called by other modules)    public fun add(a: u64, b: u64): u64 {        a + b    }
    // Private function (module internal only)    fun internal_helper(): u64 {        42    }
    // Function that can receive coins    public entry fun deposit(account: &signer, amount: u64) {        // Use coin framework for transfers        // coin::transfer<SupraCoin>(account, target, amount);    }}
```

**Key Differences:**

* **Supra Move**: Uses `#[view]` for read-only functions, public entry for blockchain calls
* **Ethereum**: Uses view, pure, public, external modifiers
* **Supra Move**: acquires keyword, declares which resources the function accesses
* **Ethereum**: Automatic state access without declaration

### <mark style="color:red;">Basic Types</mark> <a href="#basic-types" id="basic-types"></a>

#### Ethereum (Solidity) <a href="#ethereum-solidity-2" id="ethereum-solidity-2"></a>

```
contract BasicTypes {    // Integers    uint8 smallNumber;      // 0 to 255    uint256 bigNumber;      // 0 to 2^256-1    int256 signedNumber;    // -2^255 to 2^255-1
    // Boolean    bool isActive;
    // Address    address userAddress;
    // Bytes    bytes32 hash;    bytes dynamicBytes;
    // String    string text;
    // Arrays    uint256[] dynamicArray;    uint256[5] fixedArray;
    // Mapping    mapping(address => uint256) balances;
    // Struct    struct User {        string name;        uint256 age;    }}
```

#### Supra Move <a href="#supra-move-2" id="supra-move-2"></a>

```
module my_address::basic_types {    use std::string::{Self, String};    use std::vector;    use aptos_std::table::{Self, Table};
    struct BasicTypes has key {        // Integers (unsigned only)        small_number: u8,       // 0 to 255        medium_number: u64,     // 0 to 2^64-1        big_number: u128,       // 0 to 2^128-1        huge_number: u256,      // 0 to 2^256-1
        // Boolean        is_active: bool,
        // Address        user_address: address,
        // Vector (dynamic array)        dynamic_array: vector<u64>,
        // String        text: String,
        // Table (like mapping)        balances: Table<address, u64>,    }
    // Struct    struct User has store, drop {        name: String,        age: u64,    }}
```

### <mark style="color:red;">Structs and Resources</mark> <a href="#structs-and-resources" id="structs-and-resources"></a>

#### Ethereum (Solidity) <a href="#ethereum-solidity-3" id="ethereum-solidity-3"></a>

```
contract StructsExample {    struct Token {        string name;        uint256 totalSupply;        mapping(address => uint256) balances;    }
    Token public token;
    constructor() {        token.name = "MyToken";        token.totalSupply = 1000000;    }
    function transfer(address to, uint256 amount) public {        require(token.balances[msg.sender] >= amount, "Insufficient balance");        token.balances[msg.sender] -= amount;        token.balances[to] += amount;    }}
```

#### Supra Move <a href="#supra-move-3" id="supra-move-3"></a>

```
module my_address::token {    use supra_framework::signer;    use aptos_std::table::{Self, Table};    use std::string::String;    use std::error;
    // Resource stored under account    struct Token has key {        name: String,        total_supply: u64,        balances: Table<address, u64>,    }
    const E_INSUFFICIENT_BALANCE: u64 = 1;
    public entry fun initialize(account: &signer, name: String, total_supply: u64) {        move_to(account, Token {            name,            total_supply,            balances: table::new(),        });    }
    public entry fun transfer(        account: &signer,        to: address,        amount: u64    ) acquires Token {        let from = signer::address_of(account);        let token = borrow_global_mut<Token>(@my_address);
        let from_balance = table::borrow_mut(&mut token.balances, from);        assert!(*from_balance >= amount, error::invalid_argument(E_INSUFFICIENT_BALANCE));
        *from_balance = *from_balance - amount;
        if (table::contains(&token.balances, to)) {            let to_balance = table::borrow_mut(&mut token.balances, to);            *to_balance = *to_balance + amount;        } else {            table::add(&mut token.balances, to, amount);        };    }}
```

**Key Differences:**

* **Supra Move**: Resources have abilities (`key, store, drop, copy`)
* **Ethereum**: Structs are simple data containers
* **Supra Move**: Resources ensure linear type safety
* **Ethereum**: No built-in protection against double-spending

### <mark style="color:red;">Events</mark> <a href="#events" id="events"></a>

#### Ethereum (Solidity) <a href="#ethereum-solidity-4" id="ethereum-solidity-4"></a>

```
contract Events {    event Transfer(        address indexed from,        address indexed to,        uint256 value    );
    event Approval(        address indexed owner,        address indexed spender,        uint256 value    );
    function transfer(address to, uint256 amount) public {        // Transfer logic...
        emit Transfer(msg.sender, to, amount);    }}
```

#### Supra Move <a href="#supra-move-4" id="supra-move-4"></a>

```
module my_address::events {    use supra_framework::event;    use supra_framework::signer;
    #[event]    struct TransferEvent has drop, store {        from: address,        to: address,        value: u64,    }
    #[event]    struct ApprovalEvent has drop, store {        owner: address,        spender: address,        value: u64,    }
    public entry fun transfer(account: &signer, to: address, amount: u64) {        let from = signer::address_of(account);
        // Transfer logic...
        event::emit(TransferEvent {            from,            to,            value: amount,        });    }}
```

**Key Differences:**

* **Supra Move**: Events are structs with `#[event]` attribute
* **Ethereum**: Events are declared with `event` keyword
* **Supra Move**: Uses `event::emit()` to emit events
* **Ethereum**: Uses `emit` keyword
* **Supra Move**: No indexed parameters concept
* **Ethereum**: Supports indexed parameters for filtering

### <mark style="color:red;">Storage & State Management</mark> <a href="#storage--state-management" id="storage--state-management"></a>

#### Ethereum (Solidity) <a href="#ethereum-solidity-5" id="ethereum-solidity-5"></a>

```
contract Storage {    // State variables stored in contract storage    uint256 private _totalSupply;    mapping(address => uint256) private _balances;
    function updateBalance(address user, uint256 amount) internal {        _balances[user] = amount;    }
    function getBalance(address user) public view returns (uint256) {        return _balances[user];    }}
```

#### Supra Move <a href="#supra-move-5" id="supra-move-5"></a>

```
module my_address::storage {    use supra_framework::signer;    use aptos_std::table::{Self, Table};
    struct TokenStorage has key {        total_supply: u64,        balances: Table<address, u64>,    }
    public entry fun initialize(account: &signer) {        move_to(account, TokenStorage {            total_supply: 0,            balances: table::new(),        });    }
    fun update_balance(storage: &mut TokenStorage, user: address, amount: u64) {        if (table::contains(&storage.balances, user)) {            *table::borrow_mut(&mut storage.balances, user) = amount;        } else {            table::add(&mut storage.balances, user, amount);        };    }
    #[view]    public fun get_balance(addr: address, user: address): u64 acquires TokenStorage {        let storage = borrow_global<TokenStorage>(addr);        if (table::contains(&storage.balances, user)) {            *table::borrow(&storage.balances, user)        } else {            0        }    }}
```

**Key Differences:**

* Supra Move: Resources stored under specific account addresses
* Ethereum: State stored in contract’s storage slots
* Supra Move: Must explicitly declare resource access with `acquires`
* Ethereum: Automatic state access

### <mark style="color:red;">Testing</mark> <a href="#testing" id="testing"></a>

#### Ethereum (Solidity with Hardhat) <a href="#ethereum-solidity-with-hardhat" id="ethereum-solidity-with-hardhat"></a>

```
const { expect } = require("chai");
describe("Token", function () {    it("Should transfer tokens correctly", async function () {        const Token = await ethers.getContractFactory("Token");        const token = await Token.deploy();
        await token.transfer(addr1.address, 100);        expect(await token.balanceOf(addr1.address)).to.equal(100);    });});
```

#### Supra Move <a href="#supra-move-6" id="supra-move-6"></a>

```
#[test_only]module my_address::token_tests {    use my_address::token;    use supra_framework::account;    use std::signer;
    #[test(account = @0x123)]    public entry fun test_transfer(account: signer) {        let addr = signer::address_of(&account);        account::create_account_for_test(addr);
        token::initialize(&account, string::utf8(b"Test"), 1000);        token::transfer(&account, @0x456, 100);
        assert!(token::get_balance(addr, @0x456) == 100, 1);    }}
```

### <mark style="color:red;">Deployment</mark> <a href="#deployment" id="deployment"></a>

#### Ethereum <a href="#ethereum" id="ethereum"></a>

```
# Using Hardhatnpx hardhat compilenpx hardhat run scripts/deploy.js --network mainnet
```

#### Supra Move <a href="#supra-move-7" id="supra-move-7"></a>

```
# Compile and publish modulesupra move tool publish \  --package-dir /path/to/project \  --rpc-url https://rpc-testnet.supra.com
```

### <mark style="color:red;">Account Structure & Transaction Model</mark> <a href="#account-structure--transaction-model" id="account-structure--transaction-model"></a>

#### Ethereum Account Model <a href="#ethereum-account-model" id="ethereum-account-model"></a>

```
// Ethereum accounts have:// - Address (160-bit)// - Balance (single ETH balance)// - Nonce (for transaction ordering)// - Contract code (for contract accounts)// - Storage (key-value store)
contract Example {    mapping(address => uint256) balances;
    function transfer(address to, uint256 amount) public {        require(balances[msg.sender] >= amount);        balances[msg.sender] -= amount;        balances[to] += amount;    }}
```

#### Supra Move Account Model <a href="#supra-move-account-model" id="supra-move-account-model"></a>

```
// Supra accounts have:// - Address (256-bit)// - Sequence number (for transaction ordering)// - Resources (typed data structures)// - Modules (code)
module my_address::example {    use supra_framework::coin;    use supra_framework::supra_coin::SupraCoin;
    // Each account can hold resources directly    public entry fun transfer(from: &signer, to: address, amount: u64) {        coin::transfer<SupraCoin>(from, to, amount);    }}
```

### <mark style="color:red;">Recap</mark> <a href="#recap" id="recap"></a>

| **Feature**         | **Ethereum/Solidity**          | **Supra Move**                     |
| ------------------- | ------------------------------ | ---------------------------------- |
| Type System         | Dynamic typing, runtime checks | Static typing, compile-time safety |
| Resource Management | Manual memory management       | Automatic resource lifecycle       |
| Upgrades            | Proxy patterns, complex        | Module upgrades, simpler           |
| State Storage       | Contract storage               | Account resources                  |
| Safety              | Runtime safety                 | Compile-time + runtime safety      |
| Arrays              | Fixed/dynamic arrays           | Vectors                            |
| Mappings            | Built-in mappings              | Table data structure               |
| Events              | Built-in event system          | Struct-based events                |
| Testing             | External frameworks            | Built-in testing                   |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://supraoracles.gitbook.io/supra/network/evm/overview/supraevm-resources/evm-movevm-cheatsheet.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
