Skip to main content

Command Palette

Search for a command to run...

zkLogin ท่าไม้ตายสำหรับ Crypto Adoption

Updated
3 min read
zkLogin ท่าไม้ตายสำหรับ Crypto Adoption

สวัสดีครับ ปี 2026 แล้ว มีใครยังเจอกับปัญหาจดจำ Seed phase หรือ Private key อยู่บ้างไหมครับ นี้คือปัญหาในด้าน UX ที่ทำให้ผู้ใช้งานผลิตภัณฑ์ต่างๆของ Web 3.0 รู้สึกเข้าถึงยาก เพราะแค่เริ่มก็ต้องเจอกับอุปสรรคในการใช้งานแล้ว ในช่วงปีที่ผ่านมา เราจึงเห็นว่า Platform ต่างๆเริ่มมีวิธีการเเก้ไขปัญหาเหล่านี้มากขึ้น ผู้ใช้งานไม่จำเป็นจะต้องมีกระเป๋าของตัวเอง แต่สามารถเชื่อมต่อบัญชีเช่น X, Google เพื่อเข้าใช้งานได้ทันที ซึ่งเบื้องหลังการทำงานก็จะมีผู้ให้บริการคอยดูแลกระเป๋าเงินให้เรานั้นเอง เช่น Privy

ZKLogin บน Sui คือกลไกการล็อกอินที่ผสาน Zero-Knowledge Proof เข้ากับ OAuth (เช่น Google หรือ X) เพื่อให้ผู้ใช้เข้าใช้งาน Web 3.0 ได้โดยไม่ต้องสร้างหรือเก็บ Private key เอง ระบบจะพิสูจน์ตัวตนว่า ผู้ใช้ล็อกอินถูกต้อง โดยไม่เปิดเผยข้อมูลส่วนบุคคลบนบล็อกเชน และสร้างบัญชีที่ผูกกับ session ผลลัพธ์คือประสบการณ์ใช้งานที่ใกล้เคียง Web 2.0 แต่ยังคงคุณสมบัติด้านความเป็นส่วนตัวและความปลอดภัยแบบ Web 3.0 ลดปัญหาสำหรับผู้ใช้งานมือใหม่ และช่วยให้นักพัฒนาสร้าง dApp ที่ onboard คนได้ง่ายขึ้นเป็นอย่างมาก

เรามาดูวิธีการตัวอย่างการ Implement ZK Login กันดีกว่า


สิ่งต้องเตรียม

  • Node.js (เวอร์ชัน 18 ขึ้นไปแนะนำ)

  • Sui TypeScript SDK: @mysten/sui

  • Google Cloud Project: เพื่อเอา Client ID (เพราะเราจะจำลองการ Login ด้วย Google account)

มาเริ่มกัน

  1. ติดตั้ง SDK

     npm install @mysten/sui jwt-decode
    
  2. เตรียม Google OAuth (Client ID)

    เริ่มจากเราต้องไปที่ Google Cloud Console แล้วทำตามขั้นตอนดังนี้

    • เริ่มจากสร้าง Project ใหม่ ตรงนี้จะต้องกรอกข้อมูลพื้นฐาน เช่น ข้อมูลที่อยู่ออกบิล เเละข้อมูลบัตรเครติด ซึ่งเราไม่ต้องกังวลไปนะ เพราะเราจะใช้งานเเบบฟรี แถมได้เครติดฟรีด้วย

    • ไปที่ APIs & Services > Credentials (https://console.cloud.google.com/apis/credentials)

    • สร้าง OAuth client ID กรอกข้อมูลต่างตามตัวอย่างรูปข้างล่าง และตั้งค่า Authorized redirect URIs ให้ตรงกับหน้าเว็บของเรา (เช่น http://localhost:5173)

    • Copy Client ID เก็บไว้นะ เราต้องนำไปใช้งานต่อ

  3. เริ่มเขียนโค๊ดกัน

    ซึ่งการทำ ZK Login จะมี Flow หลักๆ ดังนี้

    • สร้างกุญแจชั่วคราว (Ephemeral Key)

    • สร้าง Nonce และส่ง User ไปล็อกอิน Google

    • รับ JWT Token จาก Google

    • สร้าง ZK Proof และส่ง Transaction

  • เริ่มจาก สร้าง Ephemeral Key และ URL สำหรับ Login

    อันดับแรก เราต้องสร้างกุญแจชั่วคราวก่อน เพื่อใช้เซ็นธุรกรรมแทน User ใน Session ที่ผู้ใช้งานได้เข้าสู่ระบบ

      import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
      import { generateNonce, generateRandomness } from '@mysten/sui/zklogin';
    
      // 1. สร้างกุญแจชั่วคราว (Ephemeral Key)
      const ephemeralKeyPair = new Ed25519Keypair();
    
      // 2. กำหนดค่าพื้นฐาน
      const maxEpoch = 100; // กำหนดอายุการใช้งานของ Key (เช็ค epoch ปัจจุบันจาก RPC ได้)
      const randomness = generateRandomness(); // ค่าสุ่มเพื่อความปลอดภัย
    
      // 3. สร้าง Nonce
      // Nonce นี้จะผูก Public Key ชั่วคราวของเราเข้ากับ Login Session ของ Google
      const nonce = generateNonce(
          ephemeralKeyPair.getPublicKey(), 
          maxEpoch, 
          randomness
      );
    
      // 4. สร้าง URL เพื่อส่ง User ไปหน้า Login Google
      const REDIRECT_URI = 'http://localhost:5173'; // URL หน้าเว็บของคุณ
      const CLIENT_ID = 'YOUR_GOOGLE_CLIENT_ID'; // ใส่ Client ID ที่ได้จาก Google
    
      const params = new URLSearchParams({
          client_id: CLIENT_ID,
          response_type: 'id_token',
          redirect_uri: REDIRECT_URI,
          scope: 'openid email', // ขอสิทธิ์ดู email
          nonce: nonce, // สำคัญมาก! ต้องส่ง nonce ไปด้วย
      });
    
      const loginURL = `https://accounts.google.com/o/oauth2/v2/auth?${params}`;
    
      console.log('Login Link:', loginURL);
      // ในเว็บจริง: window.location.href = loginURL;
    
  • รับ JWT และสร้าง Sui Address (หลัง User ล็อกอินเสร็จ)

    จากขั้นตอนแรกเราจะได้ Login Link ให้นำ URL ดังกล่าวไปเปิดผ่าน browser นะ และเมื่อผู้ใช้งานล็อกอินสำเร็จ Google จะ redirect กลับมาพร้อม id_token (JWT) ใน URL นั้นเอง และเมื่อเราได้ SUI address มาเเล้วอย่าลืมไปขอ Devent token นะ

      import { jwtToAddress } from '@mysten/sui/zklogin';
      import { jwtDecode } from 'jwt-decode';
    
      // สมมติว่าดึง id_token มาจาก URL แล้ว
      const idToken = '...JWT_TOKEN_FROM_GOOGLE_URL...'; 
    
      // ถอดรหัส JWT เพื่อดูข้อมูล (ไม่จำเป็นต้องใช้ private key)
      const decodedJwt = jwtDecode(idToken);
    
      // 5. กำหนด Salt (User Salt)
      // *สำคัญ* Salt ต้องเป็นความลับและ "เหมือนเดิมเสมอ" สำหรับ User คนเดิม
      // ในโปรดักชั่น ควรมี Salt Service แยกต่างหากเพื่อ Map User ID -> Salt
      const userSalt = '12345678901234567890'; // ตัวอย่าง (จริงๆ ต้องเป็น BigInt string)
    
      // 6. คำนวณหา Sui Address ของ User คนนี้
      const zkLoginAddress = jwtToAddress(idToken, userSalt);
    
      console.log('Sui Address ของ User คือ:', zkLoginAddress);
    
  • สร้าง Transaction และส่งขึ้นธุรกรรมขึ้น SUI network

    ขั้นตอนนี้ต้องใช้ Proving Service (บริการสร้าง Zero-Knowledge Proof) ซึ่งปกติ Mysten Labs มีให้ใช้ฟรีใน Devnet หรือเราจะรันเองใน Mainnet ก็ได้

      import { SuiClient } from '@mysten/sui/client';
      import { Transaction } from '@mysten/sui/transactions';
      import { genAddressSeed, getZkLoginSignature } from '@mysten/sui/zklogin';
    
      // เชื่อมต่อ SUI Network
      const client = new SuiClient({ url: 'https://fullnode.devnet.sui.io' });
    
      // --- (ส่วนนี้คือการขอ ZK Proof จาก Proving Service) ---
      // เราต้องส่ง JWT, Salt, Ephemeral Public Key, ฯลฯ ไปที่ Prover API
      // Devnet => https://prover-dev.mystenlabs.com/v1
      // สมมติว่าได้ proof กลับมาแล้วเก็บในตัวแปร `zkProof`
      // const zkProof = await fetchProverService(...); 
    
      // 7. สร้าง Transaction (ตัวอย่างส่งเหรียญ SUI)
      const tx = new Transaction();
      tx.setSender(zkLoginAddress);
      const [coin] = tx.splitCoins(tx.gas, [1000]); // ส่ง 1000 MIST
      tx.transferObjects([coin], '0xRECIPIENT_ADDRESS');
    
      // 8. เซ็น Transaction ด้วย Ephemeral Key (กุญแจชั่วคราว)
      const { bytes, signature: userSignature } = await tx.sign({
          client,
          signer: ephemeralKeyPair, // ใช้ Key ที่สร้างในขั้นตอนที่ 1
      });
    
      // 9. สร้าง Signature (รวม ZK Proof + Signature)
      const addressSeed = genAddressSeed(
          BigInt(userSalt), 
          'sub', 
          decodedJwt.sub, 
          decodedJwt.aud
      ).toString();
    
      const zkLoginSignature = getZkLoginSignature({
          inputs: {
              ...zkProof, // Proof ที่ได้จาก Prover
              addressSeed,
          },
          maxEpoch,
          userSignature, // Signature จาก Ephemeral Key
      });
    
      // 10. ส่ง Transaction ขึ้น SUI network
      const result = await client.executeTransactionBlock({
          transactionBlock: bytes,
          signature: zkLoginSignature,
      });
    
      console.log('Transaction Success:', result.digest);
    

เรียบร้อย พอจะเข้าในการทำงานในแต่ละขั้นตอนใช่ไหม ซึ่งเราสามารถนำความเข้าตรงนี้ไปพัฒนาต่อเป็น Web application (ดูตัวอย่างได้ที่นี้ https://github.com/jovicheng/sui-zklogin-demo) ให้ผู้ใช้งานสามารถสร้างกระเป๋าด้วยบัญชี Google ของเขาได้ทันที หรือ สามารถลองเล่นทีละขั้นตอนได้ที่นี้นะ https://sui-zklogin.vercel.app/ ซึ่งจะมีตัวอย่างให้เห็นอย่างชัดเจนว่าแต่ละขั้นตอนมีการเรียกใช้งานโค๊ดส่วนไหน ลองเอาไปใช้กันดูน๊า เเล้วลูกค้าจะรักในผลิตภัณฑ์เรามากยิ่งขึ้น