What the f**k is Program Derived Address (PDA) in Solana really?
ช่วงนี้ได้หันมาลองเขียน contract บน Solana ดูครับ นอกจากจะงงชิบหายกับ Accounts (ใครมันตั้งชื่อ จะตามไปด่า) ยังมางงต่อกับ Program Derived Address อีก ว่ามันอะไรวะเนี่ยยย ต้องใช้ตอนไหน ใช้ยังไงฟะะ อันนี้ก็เป็นจดบันทึกสำหรับตัวเอง เผื่อวันหน้างงจะกลับมาดูใหม่
So what is PDA?
เดี๋ยวเอาจาก Solana Document มาแปะก่อน
An account whose owner is a program and thus is not controlled by a private key like other accounts.
ถ้าอ่านตามตรงเลยก็คือ Account ที่เจ้าของเป็นโปรแกรมแล้วก็ไม่ได้ถูกควบคุมด้วย Private Key เหมือน Account อื่น ๆ
ตอนอ่านครั้งแรกนี่คืองงไปเลยเหมือนกัน ว่ามันทำได้ไง ใช้อย่างไรวะเนี่ย ถ้าให้แปลให้มันเหมือนจะง่ายขึ้นอะนะ ก็คือ Public Key ที่ไม่มี Private Key แต่ว่าสามารถ *magically* sign ด้วย Program ได้ ช่วยไหม 555
วนกลับมาที่ Public Key, Private Key ใน Solana ก่อน
KeyPair บน Solana มีขนาด 64 bytes โดย 32 bytes แรกจะเป็น Private Key (บางก็เรียก Secret Key) และ 32 bytes หลังจะเป็น Public Key
โดย KeyPair พวกจะต้องอยู่บน Mathematic Curve โดย Solana ใช้ ed25519 curve โดย ณ จุดใดจุดหนึ่งถ้าอยู่บน Curve นี้จะมี KeyPair อยู่ตรงนั้นเสมอหรือคือมี (Private Key, Public Key) เสมอ โดยถ้าเราย้อนกลับไปดูคำที่เขานิยามของ PDA ใหม่
An account whose owner is a program and thus is not controlled by a private key like other accounts.
จะพบว่า PDA ก็คือ Public Key ที่ไม่มี Private Key ซึ่งก็คือจุดใด ๆ ที่ไม่ได้อยู่บน ed25519 curve นั่นแหละ เพราะจุดที่ไม่ได้ตกลงบน Curve จะไม่มี Private Key ที่สอดคล้องกับ Public Key มีแต่เพียง Public Key เท่านั้น นั่นแปลได้ว่าจะไม่มีใครสามารถ sign transaction ที่มันเข้ากับ Public Key นี้ได้ ยกเว้นแต่พลังแห่ง Solana Program เท่านั้น *MAGIC* 🧙♂️
โดยเราสามารถหา PDA ได้จากฟังก์ชัน
let (pda, pda_bump) = PublicKey::find_program_address([seeds], program_id)
โดยฟังก์ชันนี้จะทำ mapping จากจุด Program Id ที่อยู่บน Curve ไปยังอีกจุดหนึ่งซึ่งจะเป็นจุดที่อยู่หรือไม่อยู่บน Curve ก็ได้ และเพื่อให้มันการันตีว่าจะอยู่นอก Curve แน่ ๆ เลยมีการบวก Bump เข้าไปเพื่อให้มันหลุดออกจาก Curve แน่นอนหรือแปลว่าไม่มี Private Key ที่สอดคล้องกับ PDA อย่างแน่นอน นี่มันช่วยจริงหรือไม่ รู้สึกไม่มั่นใจเอาเสียเลย 5555
แล้ว PDA เอาไว้ทำอะไรกันแน่ฟะ
จริง ๆ ถ้าเราแอบแปลคำว่า Program Derived Address จะแปลว่า Address ที่จากมาจาก Program นั่นแล หมายความว่าถ้าเรามี Program Id เราจะสร้าง PDA กี่อันก็ได้ ด้วยการใส่ Seed ต่าง ๆ กันไปตามต้องการ
ประโยชน์ของมันจริง ๆ ก็เอาไว้ใช้ตอนที่ต้องการจะให้โปรแกรมถือ Accounts อะไรบางอย่าง ที่ควรจะต้อง Sign ได้ด้วยเช่น ถ้าเราต้องการให้ Program เราถือ TokenAccount ที่เอาไว้เก็บเหรียญ สมมติถ้าเราให้ Program เนี่ยถือ TokenAccount ตรง ๆ เลย เราจะไม่มีหนทางให้ตัว Program ทำการ sign transaction ได้ หรือแปลว่าเราจะไม่มีทางที่จะ Transfer Token ออกจาก Accounts นั้นได้เลย ถือไปตลอดกาล (อาจจะมีก็ได้แหละ แต่เท่าที่รู้ตอนนี้ยังไม่มี มีก็บอกด้วยนะครับ ขอบคุณครับ) แทนที่จะเป็นเช่นนั้นก็เลยให้ PDA เนี่ยเป็นคนถือ TokenAccounts แทน แล้วเวลาจะ Transfer ก็ทำการ sign transaction โดยให้ Solana มัน *magically* sign ให้ ตราบใดที่เรามี Seed, Bump เราก็จะให้ Program sign transaction ได้เสมอนั่นเอง
เอาจริง ๆ เขียนมาแล้วรู้สึกว่ามันไม่น่าจะมีใครอ่านรู้เรื่อง แต่ก็นั่นแหละ ตอนนี้เอาตัวเองอ่านรู้เรื่องก่อนแล้วก่อน กราบขออภัยถ้าใครเข้ามาอ่านแล้วมันไม่เข้าใจอะนะ
แหล่งอ้างอิง
- Solana Bootcamp Chicago — Day 2 — Lecture: Program derived addresses and cross program invocation — https://www.youtube.com/watch?v=iMWaQRyjpl4
- https://docs.solana.com/terminology#program-derived-account-pda