# SUI Object

วันนี้เรามาเริ่มขยับให้ลึกขึ้นไปอีกนิดนึง ซึ่งเรื่องนี้เป็นเรื่องสำคัญต่อนักพัฒนา dApp บน SUI network นั้นก็คือ Object นั้นเอง นี้คือเรื่องพื้นฐานที่สำคัญเลยเเหละ มาเริ่มกันเลยดีกว่า

ในโลกการเขียนโปรเเกรม Web 2.0 ที่เราคุ้นเคย ถ้าเราเป็น Web 2.0 Developer เวลาเก็บข้อมูลของผู้ใช้หรือระบบ เรามักจะเก็บเป็น Row ใน Database (เช่น PostgreSQL, MySQL, MongoDB)

* มี user\_id เป็น Primary Key
    
* เก็บข้อมูลเช่น username, email, balance
    
* เวลาแก้ไข เราแค่รัน UPDATE หรือ DELETE ตามสิทธิ์ที่ระบบกำหนด
    

คุณคือเจ้าของระบบและ Database ถ้าอยาก rollback หรือ migrate schema ก็ทำได้เองหมด

แต่เดียวก่อน ในจักรวาลของ SUI Network นั้น ทุกอย่างไม่ได้เก็บเป็นแค่ Row/Column แบบที่เราคุ้นเคยกัน แต่เก็บทั้งหมดอยู่ในรูปแบบ Object

* Object = Data + Owner + Version
    
* ทุกครั้งที่เปลี่ยนแปลง Object จะไม่ใช่การเขียนทับ แต่คือการสร้าง เวอร์ชันใหม่ของสถานะ (state) เพื่อรักษาความถูกต้องและป้องกัน conflict
    
* เจ้าของ Object (owner) มีสิทธิ์ควบคุมว่าจะโอน ยืมใช้ หรือแก้ไขได้หรือไม่
    

**SUI Object คือ**

หน่วยเก็บข้อมูล (data unit) พื้นฐานที่สุดที่ใช้แทนทุกสิ่ง ไม่ว่าจะเป็นโทเค็น, NFT, smart contract state หรือแม้กระทั่งข้อมูลทั่วไป ต่างจาก blockchain อื่นๆ (ที่เก็บข้อมูลในรูปแบบ account + balance หรือ key-value store) Sui ใช้ Object-Centric Model ทำให้แต่ละ Object มีตัวตนแยกชัดเจน (unique identity) และสิทธิ์การเป็นเจ้าของในตัวเอง

**คุณสมบัติคร่าวๆของ SUI Object จะมีดังนี้**

* มี ID ที่ไม่ซ้ำกัน (Object ID)
    
    ทุก Object จะมีรหัสเฉพาะ (32 bytes) เพื่อระบุว่าเป็น Object ไหน
    
* มีเจ้าของ (Ownership)
    
    Object จะกำหนดว่าใครเป็นเจ้าของหรือสามารถเข้าถึงได้ โดย ownership มีหลายรูปแบบ เช่น
    
    * Address-owned → เป็นของ address ใด address หนึ่ง นั้นคือมีเจ้าของชัดเจนนั้นเอง ใช้กับ NFT, Token, Item
        
    * Shared → ใช้ร่วมกันหลายคน เช่น DEX Pool, Counter
        
    * Immutable → อ่านได้อย่างเดียว เปลี่ยนแปลงไม่ได้ ใช้กับพวก Metadata หรือ Config
        
    * Wrapped → ถูกเก็บซ้อนอยู่ใน Object อื่น
        
    * Party → ใช้ร่วมกับ party ของผู้ที่เกี่ยวข้อง
        

**เปรียบเทียบกับ Database**

| Concept (Web2) | Database (SQL/NoSQL) | Sui Blockchain (Web3) |
| --- | --- | --- |
| Primary Key | user\_id (int/uuid) | Object ID (Global Unique) |
| Data | Row / Document | Object Fields (struct) |
| Permission | App Logic (ACL/Role) | Owner field ใน Object |
| Update | UPDATE row ... | สร้าง Object เวอร์ชันใหม่ |
| Delete | DELETE row ... | Object ถูกทำลาย (destroy) ด้วยฟังก์ชันใน Move ถ้า logic อนุญาต |

มาดูตัวอย่างกันดีกว่า

Web 2.0 (SQL)

```sql
INSERT INTO players (id, name, score) VALUES (1, 'Alice', 10); 
UPDATE players SET score = 20 WHERE id = 1;
```

SUI (Move)

```rust
struct Player has key {
    id: UID,
    name: String,
    score: u64,
}

public entry fun new_player(name: String, ctx: &mut TxContext) {
    let player = Player {
        id: object::new(ctx),
        name,
        score: 0,
    };
    transfer::transfer(player, tx_context::sender(ctx));
}

public entry fun update_score(player: &mut Player, new_score: u64) {
    player.score = new_score;
}
```

**การ Upgrade ของ Object**

อีกสิ่งนึงที่น่าสนใจคือกรณีที่เราต้องการเเก้ไขข้อมูลของ SUI Object เพราะจริง ๆ แล้วผูกกับ แนวคิด Versioning ของ Object โดยตรง เพราะทุกครั้งที่มีการแก้ไข (mutate) หรือโอน (transfer) ตัว Object จะไม่ใช่การเขียนทับ แต่คือการสร้าง Version ใหม่ ของ Object นั้น

* Object Versioning
    
    * ทุกการเปลี่ยนแปลงของ Object = การสร้าง Version ใหม่
        
    * ระบบจะเก็บคู่ `ObjectID + Version` เพื่ออ้างอิงสถานะปัจจุบัน
        
    * ถ้า Transaction ใช้ Object version เก่า → จะล้มเหลวทันที (ป้องกัน conflict)
        
* Module Upgrade
    
    * Logic หรือฟังก์ชันการทำงานที่ผูกกับ Object อยู่ใน Move Package
        
    * เมื่อจะอัปเกรด logic → ไม่ได้แก้ package เดิม แต่ใช้การ Deploy Package ใหม่
        
    * กลไกนี้ช่วยให้ blockchain ยังคงรักษาความเป็น Immutable ของ code เดิมได้
        
* Migration Script
    
    * ใช้เพื่อ ย้ายข้อมูลจาก Object เดิมไปยัง Object ใหม่ ที่สร้างด้วย logic เวอร์ชันล่าสุด
        
    * เหมาะในกรณีที่โครงสร้างข้อมูล (struct) หรือ logic เปลี่ยนไปจนไม่สามารถใช้ Object เดิมได้
        
    * เป็นขั้นตอนสำคัญในการรักษาความต่อเนื่องของ state และ user experience
        

**ทำไม Sui Object สำคัญ?**

Sui Object เป็นหัวใจของการออกแบบ Sui blockchain เพราะมันทำให้เครือข่าย เร็วขึ้น, ปลอดภัยขึ้น, ยืดหยุ่นกว่า และพัฒนาได้ง่ายกว่า blockchain แบบ account-based เดิม ๆ โดยสามารถสรุปได้เป็น 4 แกนหลักดังนี้

* Scalable (รองรับการขยายตัวสูง)
    
    * เพราะ Object แยกออกจากกัน → ธุรกรรมที่แตะคนละ Object สามารถประมวลผล พร้อมกัน (parallel execution) ได้
        
    * ต่างจาก Ethereum ที่ต้องประมวลผลแบบ sequential ทีละธุรกรรม
        
    * ทำให้ Sui รองรับ throughput สูงและ latency ต่ำ เหมาะกับ dApp ขนาดใหญ่ เช่น DeFi และ GameFi
        
* Security (ปลอดภัยด้วยสิทธิการเข้าถึง)
    
    * ทุก Object มี owner ที่ชัดเจน (address, shared, immutable, party ฯลฯ)
        
    * สิทธิ์การเข้าถึงถูกควบคุมอย่างเข้มงวด → ป้องกันการใช้ object โดยไม่ได้รับอนุญาต
        
    * ระบบ versioning ทำให้มั่นใจได้ว่าธุรกรรมใช้ object เวอร์ชันล่าสุด ลดปัญหา conflict หรือ double spend
        
* Programmable Asset (ทรัพย์สินที่โปรแกรมได้)
    
    * บน Sui, Object ไม่ได้เป็นแค่ data แต่เป็น asset ที่มี logic ของตัวเอง ตัวอย่าง: Sword ในเกมไม่ใช่แค่ metadata ของ NFT แต่สามารถมี logic เช่น upgrade\_sword, transfer, หรือ equip อยู่ภายใน
        
    * เปิดโอกาสให้สร้างแอปที่ซับซ้อนขึ้นได้ โดยใช้ Object เป็น building block
        
* Upgradable (อัปเกรดได้ต่อเนื่อง)
    
    * Object Versioning → ทุกครั้งที่แก้ไข object จะสร้าง version ใหม่
        
    * Module Upgrade → logic เปลี่ยนได้ด้วยการ deploy package ใหม่
        
    * Migration Script → ย้ายข้อมูลจาก object เดิมไป object ใหม่ได้
        
    * ทำให้ทั้ง data และ logic สามารถพัฒนาและอัปเกรดได้โดยไม่สูญเสีย state เก่า
        

ยาวหน่อยนะ เเต่ SUI Object เป็นพื้นฐานที่ต้องเข้าใจจริงๆ ก่อนที่จะเริ่มพัฒนา dApp บน SUI Network ซึ่งจากข้อมูลข้างบนจะเริ่มมีเเตะๆโค๊ดบ้างแล้วเเหละ สำหรับใครที่อยากจะเริ่มสามารถดูคอร์ดเรียนเบื้องต้นภาษาไทยได้จากที่นี้นะ

[https://github.com/Contribution-DAO/sui-move-intro-course-thai](https://github.com/Contribution-DAO/sui-move-intro-course-thai)

โดยในบทเรียนที่ 1 จะสอนเกี่ยวกับการติดตั้งค่า เเละบทเรียนที่ 2 จะสอนเกี่ยวกับ SUI Object นั้นเอง

---

ของเเถม จริงๆรายละเอียดเบื้องต้นเกี่ยวกับ SUI Object จบไปละ เเต่เนื้อหาข้างล่างเเถมให้

**เปรียบเทียบกับ EVM chain**

มาดูคำนิยามกันก่อนว่า EVM คืออะไร

* EVM (Ethereum Virtual Machine)
    
    Smart Contract ที่ deploy แล้ว immutable (เปลี่ยนไม่ได้) ถ้าอยาก upgrade ต้องใช้ Proxy Pattern หรือ deploy contract ใหม่
    
* Sui Move
    
    Package (smart contract logic) ถูก deploy ได้ทั้งแบบ immutable และ upgradable และ Object ที่ถูกสร้างจาก package เก่า สามารถ migrate ไปใช้ logic ใหม่ได้
    

ตัวอย่าง EVM ก็เช่น Ethereum หรือ Layer 2 network อาทิเช่น Arbitrum Optimism เป็นต้น

ตารางเปรียบเทียบมัดต่อมัด

| เรื่อง | EVM (Ethereum, Layer 2 network etc.) | Sui |
| --- | --- | --- |
| Default Contract | Immutable (แก้ไขไม่ได้หลัง deploy) | Immutable หรือ Upgradable (เลือกได้) |
| การเเก้ไข Logic | ใช้ Proxy Pattern เช่น Transparent Proxy, UUPS (delegate call ไป logic ใหม่) | Publish Package เวอร์ชันใหม่ (upgradeable package) |
| การเก็บข้อมูล | เก็บใน Storage Slot ของ Proxy | เก็บใน Object (มี owner, version) |
| การเเก้ไขข้อมูล | ต้องเขียน Migration Function ใน logic ใหม่ | ใช้ Migration Script: โอนค่าจาก Object เก่า → Object ใหม่ |
| Ownership ของ Logic | Admin Proxy สามารถเปลี่ยน Implementation | Upgrade Cap สามารถกำหนดสิทธิ์ว่าใคร upgrade package ได้ |
| ความซับซ้อน | Proxy ต้อง handle storage layout compatibility | Sui handle object versioning โดยตรง, migration explicit |
| ความเสี่ยง | Storage collision, delegatecall bug | ต้องระวังการ migrate object ให้ถูกต้อง |

ตัวอย่างการอัพเดต

EVM (UUPS Proxy)

```solidity
contract Proxy {
    address public implementation;

    function upgrade(address newImpl) external onlyAdmin {
        implementation = newImpl;
    }

    fallback() external payable {
        (bool success, ) = implementation.delegatecall(msg.data);
        require(success);
    }
}
```

Sui (Upgrade Package + Migration)

```rust
// Package V1
struct Player has key {
    id: UID,
    name: String,
    score: u64,
}

// Package V2 (เพิ่ม avatar_url)
struct PlayerV2 has key {
    id: UID,
    name: String,
    score: u64,
    avatar_url: String,
}

public entry fun migrate(old: Player, ctx: &mut TxContext) {
    let new_player = PlayerV2 {
        id: object::new(ctx),
        name: old.name,
        score: old.score,
        avatar_url: String::utf8(b"default.png"),
    };
    transfer::transfer(new_player, tx_context::sender(ctx));
    object::delete(old);
}
```

จบจริงๆละ รอบหน้าตัดเล็บรอได้เลย เพราะเราจะเริ่มลงมือเขียนโค๊ดกันละ ส่วนข้อมูลฉบับเต็มสามารถดูได้จากเอกสาร [https://docs.sui.io/concepts/object-model](https://docs.sui.io/concepts/object-model)

*By Gang|ContributionDAO*
