Smart Contractsintermediatearticle40 min read

Compact ngôn ngữ midnight: Hướng dẫn Smart Contract Quyền Riêng Tư | VCC

Học Compact — ngôn ngữ smart contract ưu tiên quyền riêng tư cho Midnight Network. Kiến trúc ledger/circuit/witness, ZK tự động, ví dụ voting bí mật. Dành cho dev Việt Nam.

Vietcardano teamTeam

Đội ngũ biên tập VietCardanoCommunity — các chuyên gia blockchain và Cardano, cung cấp nội dung giáo dục và nghiên cứu chuyên sâu cho cộng đồng.

Published 31 tháng 8, 2026Updated 30 tháng 8, 2026
Mục lục (48 mục)

Compact ngôn ngữ midnight là ngôn ngữ smart contract ưu tiên quyền riêng tư đầu tiên được thiết kế chuyên biệt cho Midnight Network — một partner chain của Cardano tập trung vào bảo vệ dữ liệu. Khác với Solidity hay Rust (Solana) nơi quyền riêng tư là suy nghĩ sau cùng (cần mixer, ZK-rollup riêng), Compact xây dựng privacy by design ngay tại tầng ngôn ngữ: bạn viết code TypeScript-like, compiler tự động tách thành ba phần — ledger công khai, circuit zero-knowledge, và witness cục bộ — khiến dữ liệu nhạy cảm không bao giờ chạm chuỗi khối trừ khi bạn tường minh cho phép.

Tóm tắt nhanh: Compact = TypeScript syntax + ZK tự động + 3 ngữ cảnh (ledger/circuit/witness) + compile-time privacy guard. Dành cho dev muốn xây dApp bảo mật (voting bí mật, sealed-bid auction, DeFi confidential) mà không cần học toán học ZK phức tạp.

Compact là gì? Ngôn ngữ smart contract ưu tiên quyền riêng tư cho Midnight

Midnight Network ra đời như một partner chain của Cardano, sử dụng consensus Kachina (dựa trên Ouroboros) và token ADA làm gas. Mục tiêu: cho phép các dApp xử lý dữ liệu nhạy cảm — y tế, tài chính, nhận dạng, bầu cử — trên chuỗi khối công khai mà không tiết lộ dữ liệu gốc.

Compact là ngôn ngữ lập trình trung tâm của Midnight. Đặc điểm nổi bật:

Đặc tínhMô tả
SyntaxTypeScript-like (cú pháp quen thuộc, dễ onboard)
Type systemStrong + static + bounded (kích thước cố định tại compile-time)
ZK generationTự động từ circuit code — không viết R1CS/Circom tay
Privacy model3 ngữ cảnh: ledger (public), circuit (ZK), witness (private/local)
Compile targetsJS/TS (TX construction), ZKIR (proving keys), JSON (contract interface)
Toolingcompact CLI, VS Code extension, Vim support, source maps

Midnight compact được phát triển dưới egida của Linux Foundation Decentralized Trust (LFDT-Minokawa) — repo chính tại github.com/LFDT-Minokawa/compact (1,035+ commits, Apache-2.0). Compiler viết bằng Chez Scheme (qua Nix), CLI bằng Rust, spec bằng Agda.


Kiến trúc ba ngữ cảnh độc đáo: Ledger — Circuit — Witness

Đây là cốt lõi khiến Compact khác biệt. Mọi hợp đồng Compact đều hoạt động song song trên ba "thế giới":

`mermaid graph TB subgraph "Người dùng (Local Machine)" W[Witness
TypeScript callback
Dữ liệu riêng tư
Không bao giờ on-chain] end subgraph "Zero-Knowledge Layer" C[Circuit
Mạch ZK bounded
Chứng minh tính đúng đắn
Compiler sinh tự động] end subgraph "Midnight Ledger (On-chain)" L[Ledger
Trạng thái công khai
Replicated across nodes
Ai cũng đọc được] end W -->|Private input| C C -->|ZK Proof + Public output| L L -->|Public state| C `

Diagram - Compact three-context architecture (ledger/circuit/witness)

1. Ledger (Sổ cái công khai) — "Database everyone can read"

  • Khai báo bằng export ledger fieldName: Type;
  • Các kiểu ledger-state: Counter, List, Map, các kiểu primitive
  • State được replicate trên tất cả node, bất biến, ai cũng query được
  • Ví dụ: export ledger authority: Bytes<32>; — public key của người nắm quyền

2. Circuit (Mạch ZK) — "API endpoint có chứng minh toán học"

  • Khai báo bằng export circuit name(params): ReturnType { ... }
  • Entry points của smart contract — user gọi qua transaction
  • Bounded execution: mọi loop, recursion, allocation có giới hạn compile-time
  • Compiler tự động dịch sang ZKIR → proving key / verifier key
  • Có thể pure (chỉ đọc, không sửa ledger) hoặc stateful

3. Witness (Chứng nhân cục bộ) — "Secure enclave của user"

  • Khai báo bằng witness name(params): ReturnType; — chỉ signature, không body
  • Implementation nằm ở TypeScript DApp chạy trên máy user (browser, mobile, backend)
  • Dữ liệu witness không bao giờ rời thiết bị user — compiler enforce này
  • Mental model: async function mà ZK prover "await" — nhưng runtime là prover, không phải browser
Analogy cho dev VN:
- Ledger = PostgreSQL public replica
- Circuit = API endpoint + ZK proof (client không thể gian lận input)
- Witness = localStorage / Secure Enclave / YubiKey — private key không bao giờ lên server

Hệ thống kiểu dữ liệu bounded: An toàn tại compile-time

Compact không có any, không có dynamic allocation, không có recursion. Mọi kiểu đều có kích thước cố định — compiler bác bỏ code có thể gây unbounded computation (độ phức tạp không xác định), điều cần thiết cho ZK circuit.

Primitive Types

KiểuMô tảVí dụ
Booleantrue/falsetrue
FieldSố nguyên modulo prime field của ZK system123 as Field
UintUnsigned integer bounded [m, n)Uint<0..100>
UintSized unsigned integer (n bits)Uint<64> ≡ Uint<0..2^64>
BytesByte vector cố định n bytesBytes<32>
VectorTuple n phần tử cùng kiểu TVector<3, Field>
[T1, T2, ...]Tuple heterogeneous[Uint<32>, Boolean]
Opaque<"string"\"Uint8Array">Opaque value, hash trong ZK, raw trong ledgerOpaque<"string">

Program-Defined Types

`compact // Struct - nominal typing (tên quan trọng, không phải shape) struct UserProfile { id: Uint<64>; name: Bytes<64>; isActive: Boolean; }

// Enum - state machine rõ ràng enum ProposalState { DRAFT, ACTIVE, PASSED, REJECTED }

// Contract type - structural interface (duck typing cho cross-contract) contract TokenInterface { circuit transfer(to: Bytes<32>, amount: Uint<64>): Boolean; circuit balanceOf(account: Bytes<32>): Uint<64>; } contract implements TokenInterface; // Compiler verify `

Generics: Type Params (T) + Numeric Params (#N)

`compact module M { export circuit process(data: T, arr: Vector): Vector { return map((x) => [x, data], arr); } } import M, 10>; // Specialize tại import `
  • #N prefix phân biệt numeric param vs type param
  • Phải fully specialize tại use site — generic type không phải valid type

Subtyping cho Uint

Uint<0..100> là subtype của Uint<0..1000> — an toàn widening, compiler cho phép implicit upcast. Downcast cần explicit check (runtime guard auto-generated).

Privacy by design: disclose(), witness, và round counter

Đây là nơi Compact thực sự phát huy sức mạnh — privacy không phải option, là default.

disclose(): Compile-time guard cho private → public

`compact witness secretKey(): Bytes<32>; // Private: chỉ user biết

circuit publicKey(round: Field, sk: Bytes<32>): Bytes<32> { return persistentHash>>( [pad(32, "midnight:examples:lock:pk"), round as Bytes<32>, sk]); }

export circuit set(v: Uint<64>): [] { const sk = secretKey(); // Fetch private key locally const pk = publicKey(round, sk); // Derive trong ZK proof authority = disclose(pk); // ✅ EXPLICIT: "Tôi CHỌN publish pk" value = disclose(v); // ✅ EXPLICIT: "Tôi CHỌN publish value" state = State.SET; } `

  • Bất kỳ giá trị nào derived từ witness không thể gán vào ledger trừ khi wrap disclose()
  • Compiler bác bỏ tại compile-time nếu bạn quên disclose() — không phải runtime bug
  • Giống strict: true trong TypeScript: bắt bạn tường minh intent, ngăn "accidental leak"

Witness Pattern: Private Input Không Bao Giờ On-Chain

`compact witness secretKey(): Bytes<32>; // Declaration only

// TypeScript DApp implements: const secretKey = async (): Promise => { // Có thể dùng: Web Crypto API, Secure Enclave, HSM, MPC, hardware wallet return await window.crypto.subtle.exportKey("raw", privateKey); }; `

  • Mỗi user có thể implement witness khác nhau — contract không trust witness output inherently
  • Circuit dùng assert() để verify witness output (vd: assert(authority == pk))

Round Counter: Phá Vỡ Linkability (Giống Rotating MAC / JWT Rotation)

`compact export ledger round: Counter; // Tăng 1 mỗi lần clear

export circuit clear(): [] { const sk = secretKey(); const pk = publicKey(round, sk); // Round nhập vào hash assert(authority == pk); state = State.UNSET; round.increment(1); // Next round → khác pk hoàn toàn } `

  • Không có round: cùng secretKey → cùng authority → observer link được transactions
  • Có round: mỗi clear → round++ → pk mới → unlinkable
  • Real-world analogy: MAC address randomization (WiFi), JWT refresh token rotation, Tor circuit rotation — cùng nguyên lý: thay đổi identifier định kỳ để ngăn correlation attack

Commitment Schemes: Sealed-Bid Auction / Hash-commit-reveal

`compact // CompactStandardLibrary cung cấp: circuit transientHash(value: T): Field; // Không lưu state circuit transientCommit(value: T, rand: Field): Field; circuit persistentHash(value: T): Bytes<32>; // Lưu được ledger circuit persistentCommit(value: T, rand: Bytes<32>): Bytes<32>; `
  • Commit phase: commit = persistentCommit(bid, nonce) → publish commit on ledger
  • Reveal phase: disclose bid + nonce → verifier check persistentCommit(bid, nonce) == commit
  • Nonce không được reuse — nếu reuse, attacker link được commitments cùng giá trị
Flowchart - Lock contract set/clear with witness

Vòng đời biên dịch: Từ .compact đến JavaScript + ZKIR + Contract Info

` ┌─────────────────┐ │ contract.compact │ └────────┬────────┘ │ compact compile [--skip-zk] output/ ▼ ┌────────────────────────────────────────────────────────────┐ │ COMPILER OUTPUT │ ├──────────────────┬──────────────────┬──────────────────────┤ │ .js / .d.ts │ *.zkir │ contract.json │ │ (TX construction│ (ZK Intermediate│ (Interface metadata)│ │ + type defs) │ Representation)│ │ └──────────────────┴──────────────────┴──────────────────────┘ `

Flowchart - Compact compilation pipeline

CLI Workflow Hàng Ngày

`bash curl --proto '=https' --tlsv1.2 -LsSf https://github.com/midnightntwrk/compact/releases/latest/download/compact-installer.sh | sh compact update # Latest compiler compact update 0.29.0 # Specific version compact list # Available versions compact compile --skip-zk examples/counter.compact output/ compact compile examples/counter.compact output/ `

Output Files

FileMục đích
contract.jsJS implementation: circuit functions, TX builders, type guards
contract.d.tsTypeScript definitions — type-safe call từ TS
contract.zkirZK intermediate representation → proving/verifier keys
contract.jsonContract info: exported circuits, types, version, metadata
contract.js.mapSource map — debug Compact source trong Chrome DevTools
Tip: Dùng --skip-zk khi dev (compile ~seconds vs minutes). Chỉ full compile khi testnet/mainnet deploy.

So sánh: Compact vs Solidity vs Rust (Solana) vs Circom vs Noir

FeatureCompactSolidityRust (Solana)CircomNoir
Privacy modelBuilt-in (3 contexts)External (mixers, Aztec)External (Elusiv, ZK)Manual circuitsBuilt-in (similar)
SyntaxTypeScript-likeJS-likeRustDSL (C-like)Rust-like
ZK generationTự động từ circuitManual (Solidity + Circom)Manual (Rust + RISC Zero)Manual R1CSTự động (Rust-like)
Type safetyStrong + boundedWeak (dynamic)StrongStrongStrong
Bounded executionEnforced compilerNo (gas limit runtime)No (compute budget)Manual constraintsEnforced
Private data guarddisclose() compile-timeNoNoManualSimilar
Vietnamese docsBài này (first!)Có nhiềuCóKhôngÍt
Learning curveThấp (nếu biết TS)ThấpTrung bình (Rust)Cao (math-heavy)Trung bình
Ecosystem maturityEarly (testnet)MatureMatureMature (tooling)Growing
Comparison - Compact vs Solidity vs Rust feature matrix

Khi nào chọn Compact?

  • Cần privacy native cho user data (y tế, tài chính, voting, identity)
  • Team đã biết TypeScript — onboard nhanh
  • Muốn ZK không viết circuit tay — focus business logic
  • Target Midnight/Cardano ecosystem — ADA gas, Kachina consensus

Khi nào KHÔNG chọn Compact?

  • Cần DeFi composability ngay hôm nay (Midnight testnet, TVL thấp)
  • Cần tooling mature (Hardhat, Foundry, Anchor equivalent chưa có)
  • Team chỉ biết Solidity/Rust, không muốn học paradigm mới


Bắt đầu nhanh: Cài đặt và hợp đồng Counter đầu tiên

1. Cài đặt

`bash curl --proto '=https' --tlsv1.2 -LsSf https://github.com/midnightntwrk/compact/releases/latest/download/compact-installer.sh | sh compact update # Cài latest toolchain `

2. Hello World: Counter Contract

Tạo file counter.compact: `compact pragma language_version 0.16;

import CompactStandardLibrary;

export ledger round: Counter;

export circuit increment(): [] { round.increment(1); } `

3. Biên dịch

`bash compact compile --skip-zk counter.compact output/ `

4. Gọi từ TypeScript

`typescript import { createCounterContract } from './output/counter.js'; import { MidnightProvider } from '@midnight-ntwrk/midnight-js-provider';

const provider = new MidnightProvider('wss://testnet.midnight.network'); const contract = createCounterContract(contractAddress, provider);

// Call circuit const tx = await contract.circuits.increment().proveAndSubmit(); console.log('Transaction submitted:', tx.hash); `

5. VS Code Extension

  • Cài từ marketplace: "Compact" (publisher: LFDT-Minokawa)
  • Syntax highlighting, hover types, go-to-definition, compile-on-save

Ví dụ thực tế: Private Voting (Bỏ phiếu bí mật) trên Midnight

Bài toán

DAO Việt Nam cần bầu cử hội đồng quản trị. Yêu cầu:
  • Tính bí mật: Không ai biết ai vote cho ai (không retaliation)
  • Tính minh bạch: Kết quả tally công khai, verifiable
  • Chống gian lận: Mỗi user vote 1 lần, không double-vote

Giải pháp Compact

`compact pragma language_version 0.16; import CompactStandardLibrary;

enum VoteChoice { YES, NO, ABSTAIN }

export ledger tallyYes: Uint<64>; export ledger tallyNo: Uint<64>; export ledger tallyAbstain: Uint<64>; export ledger voted: Map, Boolean>; // Nullifier set export ledger merkleRoot: Bytes<32>; // Merkle root của eligible voters

witness voteChoice(): VoteChoice; // Private: user chọn YES/NO/ABSTAIN witness voterNullifier(): Bytes<32>; // Private: unique per election per user witness merkleProof(): Vector<32, Bytes<32>>; // Private: Merkle proof of eligibility

circuit verifyMerkleProof(leaf: Bytes<32>, proof: Vector<32, Bytes<32>>, root: Bytes<32>): Boolean { // Verify Merkle proof trong ZK circuit // (Implementation dùng persistentHash iterative) }

export circuit vote(): [] { const choice = voteChoice(); const nullifier = voterNullifier(); const proof = merkleProof(); // 1. Check eligibility (ZK proof) assert(verifyMerkleProof(nullifier, proof, merkleRoot), "Not eligible"); // 2. Check nullifier chưa dùng (prevent double-vote) assert(!voted.get(nullifier).orElse(false), "Already voted"); // 3. Tally (private choice → public aggregate) if (choice == VoteChoice.YES) { tallyYes = tallyYes + 1; } else if (choice == VoteChoice.NO) { tallyNo = tallyNo + 1; } else { tallyAbstain = tallyAbstain + 1; } // 4. Mark nullifier used voted.set(nullifier, true); } `

Flowchart - Private voting dApp flow on Midnight

Luồng DApp (TypeScript)

`typescript // User side (browser) async function castVote(choice: VoteChoice) { // 1. Generate nullifier = hash(secretKey, electionId) const nullifier = await generateNullifier(userSecretKey, electionId); // 2. Get Merkle proof từ eligibility tree (off-chain service) const merkleProof = await fetchMerkleProof(nullifier); // 3. Call witness implementations const witnesses = { voteChoice: () => choice, voterNullifier: () => nullifier, merkleProof: () => merkleProof, }; // 4. Prove & submit (midnight-js handles ZK proving) const tx = await contract.circuits.vote(witnesses).proveAndSubmit(); return tx; } `

Ứng dụng thực tế tại Việt Nam

  • Bầu cử nội bộ công ty: Nhân viên vote kín đáo, kết quả透明
  • DAO quản trị quỹ cộng đồng: Thành viên vote phân bổ ngân sách không lo bị chèn ép
  • Hội đồng quản trị startup: Founders/Investors vote quyết định chiến lược bí mật
  • Thẩm định dự án công: Các chuyên gia chấm điểm ẩn danh, kết quả công khai

Các Pattern Thường Gặp và Best Practices

1. State Machine với Enum

`compact enum EscrowState { CREATED, FUNDED, RELEASED, REFUNDED, DISPUTED } export ledger state: EscrowState;

export circuit fund(): [] { assert(state == EscrowState.CREATED); state = EscrowState.FUNDED; } `

  • Tại sao: Enum forces exhaustive handling, compiler cảnh báo missing cases

2. Counter cho Replay Protection & Unlinkability

`compact export ledger nonce: Counter; // Mỗi circuit call: nonce.increment(1); // Dùng trong hash: persistentHash([data, nonce]) `
  • Ngăn replay attack (cùng input → khác output nhờ nonce)
  • Cùng secretKey → khác commitment mỗi lần (unlinkability)

3. Commitment Scheme cho Sealed-Bid Auction

`compact witness bidAmount(): Uint<64>; witness bidNonce(): Bytes<32>;

export ledger commitments: Map, Bytes<32>>; // bidder -> commit

export circuit commitBid(bidder: Bytes<32>): [] { const amount = bidAmount(); const nonce = bidNonce(); const commit = persistentCommit(amount, nonce); commitments.set(bidder, commit); }

export circuit revealBid(bidder: Bytes<32>): [] { const amount = bidAmount(); // Same witness, user reveals const nonce = bidNonce(); const commit = commitments.get(bidder).unwrap(); assert(persistentCommit(amount, nonce) == commit, "Invalid reveal"); // Process bid... } `

4. Contract Types cho Cross-Contract Calls (Limitations)

`compact contract Token { circuit transfer(to: Bytes<32>, amount: Uint<64>): Boolean; }

export ledger token: Token; // Reference to deployed contract

export circuit payToken(to: Bytes<32>, amount: Uint<64>): [] { // Current limitation: circuits calling witnesses CANNOT satisfy contract types // Workaround: separate pure view circuits for reads token.transfer(to, amount); } `

Lưu ý: Compiler hiện tại không cho phép circuit gọi witness satisfy contract type. Đọc doc/compact-reference.mdx section "Cross-contract calls" để biết chi tiết.

5. Error Messages Thân Thiện

`compact export circuit withdraw(amount: Uint<64>): [] { assert(balance >= amount, "Insufficient balance: requested ${amount}, available ${balance}"); assert(amount > 0, "Withdraw amount must be positive"); balance = balance - amount; } `
  • assert(condition, "message") → message xuất hiện trong TX failure log
  • Giúp user/debugger hiểu lỗi ngay lập tức

Hệ sinh thái công cụ và tài nguyên

Công cụLinkMô tả
Compact CLIgithub.com/midnightntwrk/compact/releasescompact update, compile, list, self update
VS Code ExtensionMarketplace / editor-support/vscSyntax highlight, type hover, compile task
Vim Supporteditor-support/vimSyntax, indent, compiler integration
CompactStandardLibrarydoc/compact-reference.mdx#standard-libraryHash, commitment, vector ops, math
Examplesgithub.com/LFDT-Minokawa/compact/tree/main/examplesCounter, Lock, Bulletin Board, Voting
Writing Guidedoc/writing.mdxWalkthrough từ zero đến full contract
Language Referencedoc/compact-reference.mdxSpec đầy đủ (3800+ lines)
Midnight Dev Docsdocs.midnight.networkNetwork info, deployment, midnight-js
Discord Communitydiscord.gg/midnightDev support, announcements
GitHub Discussionsgithub.com/LFDT-Minokawa/compact/discussionsQ&A, feature requests, RFC

Roadmap & Trạng Thái (2025)

  • Testnet: Active (faucet, explorer, RPC endpoints)
  • Mainnet: Roadmap Q4 2025
  • Compiler: Version 0.16+ (language_version pragma)
  • Breaking changes: Có thể xảy ra pre-1.0 — pin version trong CI/CD

FAQ

1. Compact khác gì so với Solidity?

Compact có privacy native (3 ngữ cảnh), ZK tự động, TypeScript syntax, bounded types. Solidity public-by-default, cần external tooling cho ZK (Circom, Noir), dynamic types, gas-based execution bounds.

2. Có cần biết toán học ZK không?

Không. Compiler xử lý R1CS/PLONK/Halo2 conversion. Bạn chỉ cần hiểu: witness = private input, circuit = logic cần chứng minh, ledger = public state, disclose() = opt-in publish.

3. Triển khai lên mainnet khi nào?

Midnight testnet đang active (2024-2025). Mainnet roadmap Q4 2025. Theo dõi midnight.network và Discord để cập nhật.

4. Tương tác với Cardano như thế nào?

Midnight là partner chain của Cardano:
  • Dùng ADA làm gas (bridge từ Cardano)
  • Consensus Kachina (dựa trên Ouroboros Praos)
  • Có thể read Cardano state qua cross-chain bridge (đang phát triển)

5. Học đường cong dốc không?

Dễ nếu biết TypeScript. Khái niệm mới chỉ 3: witness, disclose(), bounded types. Nếu biết Rust + Circom → dễ hơn. Nếu chỉ biết Solidity → cần shift mindset: "public by default" → "private by default".

6. Debug ZK circuit như thế nào?

  • Dùng --skip-zk cho logic testing (JS output chạy bình thường)
  • Source maps (contract.js.map) → debug Compact source trong Chrome DevTools
  • console.log trong witness implementation (TypeScript side)
  • Midnight-js tester: circuit.prove(witnesses) → inspect proof locally trước khi submit

7. Gas/Fees thế nào?

  • Dùng ADA (bridge từ Cardano)
  • Fee tính theo proof size + TX size (khác Ethereum gas model)
  • Testnet có faucet miễn phí

8. Có thể upgrade contract không?

Không trực tiếp (immutable deployment). Pattern: proxy contract + versioned logic (giống OpenZeppelin proxy) — deploy contract mới, migrate state qua admin circuit.

Kết luận

Compact ngôn ngữ midnight mang来了 một paradigm mới cho smart contract development: privacy không phải add-on, mà là default. Với TypeScript-like syntax, ZK generation tự động, và compile-time privacy guards (disclose()), Compact hạ thấp barrier entry cho ZK development xuống mức bất kỳ TypeScript developer nào cũng có thể onboard trong vài giờ.

Đối với lập trình viên Việt Nam — nơi TypeScript thống trị, nhạy cảm về privacy (luật bảo vệ dữ liệu 13/2023), và có truyền thống mạnh về outsourcing blockchain (Axie, Coin98, Kyber) — Compact là cơ hội lớn để dẫn đầu wave privacy-preserving dApps trên Cardano/Midnight ecosystem.

Bước tiếp theo:

  1. compact update và compile examples/counter.compact
  2. Đọc doc/writing.mdx end-to-end
  3. Tham gia Discord Midnight — hỏi trực tiếp core team
  4. Build một mini dApp: private voting, sealed-bid auction, hoặc confidential token transfer

Resources:
📖 [Writing a Contract](https://github.com/LFDT-Minokawa/compact/blob/main/doc/writing.mdx)
📚 [Language Reference](https://github.com/LFDT-Minokawa/compact/blob/main/doc/compact-reference.mdx)
💻 [Examples](https://github.com/LFDT-Minokawa/compact/tree/main/examples)
💬 [Discord](https://discord.gg/midnight)
🐙 [GitHub](https://github.com/LFDT-Minokawa/compact)

Bài viết này được tạo dựa trên tài liệu chính thức từ LFDT-Minokawa/compact (Apache-2.0), Midnight Foundation docs, và phân tích gốc của tác giả. Mã nguồn ví dụ lấy từ repo chính thức. Cập nhật: 2026-08-19.

Tags:

compact ngôn ngữ midnightsmart contract quyền riêng tưmidnight compact