มาทำความเข้าใจ Corda Blockchain กันดีกว่า Part 2

Apsa_sue
8 min readMar 15, 2019

ใครที่ยังไม่ได้อ่าน Part 1 คลิ๊กทีนี่

เอาหล่ะ มาต่อกันเลยดีกว่า หลังจากรอบที่แล้ว ผมได้พูดถึง Contract ไปแล้ว หลังจากนี้ผมจะไปพูดต่อในส่วนของ Transaction และ Flow ซึ่งถือว่าเป็นหัวใจหลักอีกส่วนหนึ่งเลยของ Corda

** Part นี้จะยามหน่อยนะครับ รายละเอียดค่อนข้างเยอะครับ **

Transactions

การทำงานของ Transaction นั้นใช้ระบบ UTXO Model(Unspent Transaction Output Model) เพราะ State เป็น Immutable Object ดังนั้นต้องใช้วิธี Update State แทน โดยอาศัย Transaction ในการ Update State บน Ledger

Corda เลือกใช้งาน UTXO Model เพราะถ้าใช้ระบบที่ดึง Current State มา Validate Transaction ก็จะต้องรอให้ Transaction อื่นทำการ Update State จนเสร็จก่อน จึงจะไปดึง Current State มาได้ ทำให้เกิดปัญหา Scalability (Transaction ค้างเยอะ จนการ Update State ทำงานช้า) ได้ ดังนั้น UTXO Model จะทำให้สามารถประมวลผล Transaction แบบ Parallel ได้

** Transaction เปรียบได้กับว่าเป็นข้อเสนอให้ Update State พร้อมกันทั้ง Party Node โดยจะทำงานแบบ Atomic คือ ถ้าทำงานได้ไม่เสร็จทั้งหมด ก็จะยกเลิกทิ้งทั้งหมดเลย **

โดยในการ Update State นั้นจะมี 2 ขั้นตอน ดังนี้

  1. นำ Input State มา Mark State ให้เป็น Consumed State
  2. ประมวลผล Output State ใหม่พร้อมกับ Mark State ให้เป็น Unconsumed State

Transaction ที่จะ Update State สามารถมีได้หลายแบบ ดังนี้

  • Transaction นั้นๆ สามารถเป็นได้หลาย Type เช่น จากภาพด้านล่าง จะมีส่วนที่ Cash State และ Bond State
  • Transaction สามารถมีหรือไม่มี Input State หรือ Output State ก็ได้
  • Transaction สามารถแยก State ออกจากกันได้ เช่น State บัญชียอดเงิน 100 บาท สามารถถูก Transaction แยก State ออกเป็น 50 บาท 2 บัญชีได้

เงื่อนไขในการสร้าง Transaction ที่สมบูรณ์ จะต้องมีเงื่อนไข ดังนี้

  1. Transaction นั้นจะต้องไม่เป็น Double-Spend Transaction
  2. ต้องผ่านการตรวจสอบและยืนยันความถูกต้องแล้วด้วย Contract
  3. ต้องถูก Signed รับรองทั้ง Party Node แล้ว

Transaction Chains

การอ้างอิงจะเกิดขึ้นต่อเนื่องเป็น Chain

ในขณะที่กำลังประมวลผล Transaction นั้น แน่นอนว่าจะยังไม่มี Output ออกมา เพราะมันกำลัง Process อยู่ แต่จะต้องใช้ Input ในการ Process จึงต้องมีการนำมา Output ของ Transaction ก่อนหน้ามาใช้ โดยจะมีตัวอ้างอิงไปยัง Transaction ก่อนหน้า ดังนี้

  1. Hash ของ Transaction ที่จะไปนำ Output มา
  2. Index ของ Output state ที่จะนำมาใช้อ้างอิง

Committing transactions

กระบวนการในการ Process ของ Transaction จนกระทั่งบันทึกลง Ledger มีขั้นตอนดังนี้

  1. เริ่มต้นด้วยการเป็น ข้อเสนอในการ Update State ก่อน โดยที่ Transaction นั้นๆ จะยังไม่ถูกบันทึกลงใน Ledger (Uncommit) ของทั้ง Party Node
Uncommited State

2. เพื่อให้ Transaction นั้นๆ ถูกบันทึกลงบน Ledger อย่างสมบูรณ์จำเป็นจะต้องมีการ Signed จากทั้ง Party Node ก่อนที่เกี่ยวข้องตาม Command ที่กำหนดไว้ (เดี่ยวผมจะมาขยายความเรื่อง Command อีกที)

Require all signer in participant (Command)

3. หลังจากได้รับการ Signed ตามที่ต้องการแล้ว Transaction นั้นจึงจะสมบูรณ์และถูกบันทึกลง Ledger (Commit)

Commited Transaction

ซึ่งจะทำให้ Input State ถูกเปลี่ยนกลายเป็น Consumed State และไม่สามารถนำกลับมาใช้เป็น Unconsumed State ได้อีก และ Output State ก็จะกลายเป็น Unconsumed State หรือ Current State บน Ledger แทน

Transaction validity

โดยแต่ละโหนดที่จะ sign ยืนยันได้ว่า Transaction นั้นถูกต้องนั้น ก็จำเป็นจะต้องมีการตรวจสอบ โดยหลักๆ จะมีการตรวจสอบอยู่ 2 เงื่อนไข ดังนี้

  • Transaction validity = แต่ละโหนดที่รับ Transaction มาก็จะตรวจสอบย้อนหลัง Transaction ทั้งหมดว่าถูกต้องหรือไม่ และ Transaction นั้นๆ ผ่านข้อกำหนดต่างๆของ Contract ที่ใช้อ้างอิงบนโหนดตัวเองหรือเปล่า

ถ้าผ่าน ก็ถืิอว่า Transaction Valid แล้วในเงื่อนไขนี้ และก็ทำการตรวจสอบ

  • Transaction uniqueness = เป็นการตรวจสอบว่า Transaction นั้นๆ ยังไม่เคยถูกนำไปใช้ Commit ที่ไหนมาก่อน และยังไม่เคยถูกนำไปใช้ใน Transaction อื่น (Notary Node ของ Party Node นั้นๆ จะทำหน้าที่ตรวจสอบในส่วนนี้)

เอาหล่ะ หลังจากรู้ กระบวนการหลักๆ และโครงสร้างหลักๆของ Transaction แล้วคร่าวนี้ เราจะมาดูส่วนประกอบเพิ่มเติมภายใน Transaction นอกเหนือจาก Input State และ Output State กันบ้าง

  • Commands

เป็นส่วนของชุดคำสั่งที่ใช้กำหนด Output State จาก Input State โดย Command จะอาศัย Contract ในการ Validate ความถูกต้อง

ในบางกรณีเราจำเป็นจะต้องแยกเงื่อนไขการประมวลผล Transaction เป็นหลายกรณี ตามเงื่อนไขของ Transaction ตัวอย่างเช่น

Alice ซื้อคูปองจาก Bob โดย Bob จะต้องจ่ายเงินปันผลคืนให้ Alice ในฐานะที่ถือคูปองเอาไว้ ซึ่งจะแยก Command ออกได้เป็น 2 ชุด ดังนี้

(ตัวอย่างนี้เป็นตัวอย่างบน Document ของ Corda เอง แล้วมีการตัดช่วงซื้อคูปองออก ให้เข้าใจได้ง่าย จะพูดถึงแค่ส่วนหลังจาก Alice จ่ายเงินค่าซื้อคูปองแล้ว)

  1. เปลี่ยน State โดย Mark state ใหม่ให้ คูปองถูกจ่ายแล้วโดย Alice กรณีนี้จะมีแค่ Alice เท่านี้ที่เป็น Participant
  2. Bob โอนเงินเพื่อจ่ายเงินปันผลให้ Alice ในฐานะคนที่ซื้อคูปองไป กรณีนี้ Participant คือ Alice และ Bob
  • Attachments

ตรงตัวเลยครับ มันคือ ไฟล์แนบ Corda มีความสามารถในการใส่ไฟล์แนบเข้าไปใน Transaction ได้ โดยจะมีการอ้างอิงไฟล์แนบด้วย Hash โดยสามารถอัพโหลดได้แค่ไฟล์แบบ Zip / Jar เท่านั้นครับ โดยไฟล์แนบเหล่านี้อาจใช้เพื่อตรวจสอบความถูกต้องของ Transaction ด้วย ตัวอย่างไฟล์แนบเช่น เอกสารโฉนดที่ดิน หรือ สัญญาต่างๆ

  • Timestamps (Time-Windows)

เป็นการกำหนดช่วงเวลาในการบอกว่า Transaction นั้นๆ จะถูกต้องในช่วงเวลาใดบ้าง เช่น กำหนดเวลาว่า การขายคูปองจะเกิดขึ้นในช่วงเวลาตั้งแต่ บ่ายโมงถึง

ซึ่งการกำหนดเวลาโดยอาศัยเวลาจริงนั้น ทำให้ Transaction สามารถนำมาประยุกต์ใช้ได้มากขึ้น และไม่มีข้อจำกัดเหมือน Blockchain บางแพลตฟอร์ม

โดย Notary node หรือ Participant Node จะคอยทำหน้าที่ตรวจสอบ Timestamp ของ Transaction ว่า Valid หรือไม่ โดย Initiator จะต้องกำหนดลงบน Transaction ตอนที่สร้าง

โดยจะแบ่งลักษณะการกำหนดเวลาได้เป็น 3 รูปแบบ

  1. กำหนดเวลาให้ Transaction จะ Valid จนกว่าจะถึงเวลาที่กำหนด

2. กำหนดเวลาให้ Transaction จะ Valid ในช่วงเวลาหนึ่งเท่านั้น

3. กำหนดเวลาให้ Transaction จะ Valid ตั้งแต่หลังจากช่วงเวลาที่กำหนด

อาจต้องใช้ นาฬิกาอะตอมเป็นมาตรฐานในการวัด เพื่อให้เวลาของโหนดเดินตรงกันให้มากที่สุด

ดังนั้นโครงสร้างแบบครบๆของ Transaction จะมีหน้าตาเป็นแบบนี้

Flows

เป็นขั้นตอนการส่ง Transaction กันระหว่างโหนดเพื่อ Verify (Signed transaction by participant) จากทั้ง Party Node และ Update Ledger กันภายใน Party Node

Flow เป็นการติดต่อระหว่างโหนดตั้งแต่ Verify Transaction ไปจนถึง Update Ledger ทั้ง Party Node

Corda มีรูปแบบการติดต่อระหว่างโหนดแบบ Point-to-Point ดังนั้นรูปแบบการส่งข้อมูลภายใน Party Node จึงแตกต่างจากแบบ Global broadcast

โดยขั้นตอนจะมีดังนี้

1. Alice (Transaction Builder) ทำการสร้าง Transaction ใหม่เพื่อร้องขอให้เกิดการ Update Ledger พร้อมกับ Sign transaction นั้น

Step 1
  1. Alice ส่ง Transaction ที่สร้างใหม่ พร้อมกับ Sign Transaction แล้วไปให้ Bob
Step 2

3. Bob ตรวจสอบ Transaction ที่ได้รับจาก Alice ถ้าถูกต้อง (Contract valid, Uniqueness Valid) Bob จะทำการ Sign Transaction นั้น

Step 3

4. Bob ทำการส่ง Transaction ที่ Bob ทำการ Signed Transaction แล้ว กลับไปให้ Alice

Step 4

5. เมื่อ Alice ได้รับ Transaction จาก Bob ก็จะทำการตรวจสอบ Transaction และเช็คว่า Bob ได้ทำการ Sign Transaction มาหรือเปล่า

Step 5

โดยโหนดอื่นๆภายในเครือข่าย จะไม่เห็น Transaction ระหว่าง Alice และ Bob เลย

Unknown

โดยถ้าเป็นกรณีที่มีหลายโหนดในเครือข่าย ก็จะมีลักษณะ ตามภาพนี้

นอกจากนี้ Flow ยังสามารถเรียก Flow ย่อยๆ ได้ เรียกว่า Subflow (Flow ย่อย) โดย Flow จะรอจนกว่า Subflow จะทำงานจนเสร็จก่อน (Return กลับมา) แล้ว Flow หลักจึงจำทำงานต่อได้

ภาพรวมของการทำงานของ flow ตั้งแต่การการติดต่อระหว่างโหนดไปจนถึงการ Update Ledger ทั้ง Party Node ตามภาพด้านล่าง

ถ้าอ่านมาถึงตรงนี้แล้ว (รวมถึงจาก Part.1 ด้วย) ก็น่าจะพอมองเห็นภาพใหญ่ๆกันแล้วว่า เราจะมี Flow ในการทำงานหลักๆ ทั้งหมด ซึ่ง Flow จะทำหน้าที่รับข้อมูลจากภายนอก (รวมถึงการเข้าถึงจาก Hacker ด้วย) และมี Contract เอาไว้ตรวจสอบความถูกต้องของข้อมูลภายใน State (ทำงานบน Sandbox ปลอดภัยมากกว่า Flow เพราะไม่รับรู้ข้อมูลภายนอกเลย) เพราะบางครั้งถ้ามีการแอบสร้าง Fake Flow ขึ้นมา แล้ว Contract ไม่ตรวจสอบ ก็จะทำให้ Hacker เข้ามา Hack ระบบได้ แต่ถ้า Hacker แอบสร้าง Fake Contract ขึ้นแล้วแอบ Deploy ลงโหนดใน Party Node ก็จะตรวจสอบได้ทันทีว่ามีการแอบเปลี่ยน Contract เพราะเวอร์ชั่นของ Contract จะไม่ตรงกับโหนดอื่นๆ ซึ่งจะทำให้ Fake Contract นั้นใช้งานไม่ได้

โดย Corda มีการทำ Library ไว้ให้เรียกใช้งานเกี่ยวกับ Flow ไว้ให้แล้ว ตามนี้เลยครับ

https://docs.corda.net/flow-library.html

Consensus

ในหัวข้อนี้ เราจะพูดถึงการตรวจสอบความถูกต้องของ Transaction ที่แต่ละ Party Node ต้องทำ เรียกว่า Consensus (เอกฉันท์)

โดย Transaction จะ Valid และได้ Update Ledger ของทั้ง Party Node ได้นั้น Transaction จะต้องผ่าน Consensus ทั้ง 2 แบบนี้

  1. Validity consensus

ต้องผ่านเงื่อนไขของ Contract พร้อมกับได้รับการ Signed จากผู้ที่เกี่ยวข้องทั้งหมด ซึ่งจะตรวจสอบย้อนหลัง Transaction ทั้งหมด

2. Uniqueness consensus

เป็นการตรวจสอบกรณี เช่น นาย Alice มีเงินอยู่ 100 บาท แต่นาย Alice โอนเงินให้ นาง Bob 90 บาท และ นางสาว 50 บาท โดยประกาศ Transaction พร้อมกัน ซึ่งจะเห็นว่า นาย Alice ใช้เงินก้อนเดิม 2 ครั้ง เรียกว่า Double-Spend Transaction ซึ่งจำเป็นจะต้องมีการตรวจสอบในส่วนนี้ด้วย ซึ่ง Notary Node จะค่อยตรวจสอบส่วนนี้

Notaries

คร่าวนี้ เราจะมาลงลึกถึง Notary Node กันดีกว่า หลังจากที่พูดถึงไปในหลายๆ หัวข้อ โดยจากหัวข้อที่ผ่านมาๆ สามารถสรุปหน้าที่ของ Notary Node ได้ดังนี้

  • คอยตรวจสอบ Uniqueness Consensus เพื่อป้องกันการเกิด Double-spend
  • ทำหน้าที่เป็น Time-stamp Authority ในการตรวจสอบ Time-Window (ผมพูดถึงไปในส่วนของ Time ในหัวข้อ Transaction)

โดยถ้า Notary Node ตรวจพบว่า Transaction นั้นไม่ถูกต้องก็จะ Rejected Transaction นั้นทันที แต่ถ้าถูกต้อง Notary ก็จะ Signed เพื่อยืนยันความถูกต้องลงบน Transaction

เราสามารถกำหนด Structure และ Consensus Algorithms ของ Notary Node ได้ เพื่อให้เราสามารถควบคุมทั้งความเร็วและความปลอดภัยภายในเครือข่ายได้

  • Structure คือ การออกแบบว่า จะให้มี Notary Node ภายในเครือข่ายกี่โหนด โดยจะมีแค่โหนดเดียวก็ได้ หรือ หลายโหนดก็ได้ แถมยังสามารถปรับแต่งได้ด้วยว่า จะให้แต่ละโหนดไว้ใจกันหรือไม่ โดยถ้าให้แต่ละโหนดไว้ใจกัน ก็จะสามารถหาตัวแทนของ Notary Node ในการตรวจสอบได้ ซึ่งจะทำให้การตรวจสอบทำงานได้เร็วขึ้น แต่ก็จะปลอดภัยน้อยลง เพราะเชื่อโหนดแค่โหนดเดียว แต่ถ้าให้แต่ละโหนดไม่ไว้ใจกัน แต่ละ Notary Node เมื่อตรวจสอบเสร็จ ก็จะส่งให้อีก Notary Node ตรวจสอบใหม่อีกครั้งจนครบทุกโหนด ซึ่งก็จะทำให้การประมวลผลช้า แต่จะปลอดภัยมากยิ่งขึ้น
  • Consensus Algorithms คือ เราสามารถเลือกได้ว่าจะให้แต่โหนดคุยกันในลักษณะใด จะใช้ RAFT Consensus (เร็ว แต่ต้องเชื่อโหนดอื่น) หรือ BFT (ช้าเพราะไม่เชื่อโหนดอื่น)

อยากเข้าใจ RAFT Consensus ให้มากขึ้น

แต่ละ Notary Node สามารถมี Consensus Algorithms ได้

Validation

ในการ Validate ของ Notary Node นั้น Corda ได้ยอมให้มีการเลือกรูปแบบการตรวจสอบของ Notary Node ได้ ว่าจะให้ Notary Node สามารถมองเห็นข้อมูลได้มากแค่ไหน เพื่อในกรณีเครือข่ายที่ต้องการความเป็นส่วนตัวสูง โดยจะแบ่งได้เป็น

  1. Non-Validating Notary Node = เป็น Notary Node ที่จะมองเห็นข้อมูลเพียงบางส่วนเท่านั้น และตรวจสอบ Input State ได้แค่การ Reference ย้อนหลังของ Consumed State ภายใน Vault ได้เท่านั้น (เห็นข้อมูลใน Vault แค่ที่จำเป็นเท่านั้น) และ Notary Node ลักษณะนี้จะไม่เห็นตัวคนสร้าง Transaction ด้วย ทำให้เกิดความเสี่ยงที่จะถูกโจมตีโดย “Denial of state” Attacks ได้ แต่ก็จะได้ความเป็นส่วนตัวของข้อมูลสูง
  2. Validating Notary Node = เป็น Notary Node ที่จะมองเห็นข้อมูลทั้งหมดตั้งแต่ Input State, Output State รวมถึง Signature ภายใน Transaction ซึ่งจะทำให้ Notary Node ลักษณะนี้ ตรวจสอบข้อมูลได้ทั่วถึงและมีความปลอดภัยสูง แต่ก็ต้องแลกมาด้วย ความเป็นส่วนตัวของข้อมูลที่ค่อนข้างต่ำ เพราะโหนดจะเห็นข้อมูลทั้งหมด

จะเห็นว่า เราจำเป็นจะต้อง Tradeoff ว่าระบบควรจะเป็นอย่างไร ระหว่าง ปลอดภัยสูง ความเป็นส่วนตัวต่ำ หรือ ปลอดภัยต่ำ ความเป็นส่วนตัวสูง คล้ายๆกับ ปัญหาที่เจอในโลกของ Blockchain ในปัจจุบัน

ตารางนี้จะระบุว่า Notary Node ทั้ง 2 แบบ จะมีขอบเขตการมองเห็นข้อมูลมากน้อยแค่ไหน (Data visibility)

Multiple notaries

Corda ยอมให้แต่ละ Notary Node มี Consensus Algorithm ที่แตกต่างกันได้ ซึ่งช่วยให้มีข้อดี ดังนี้

  • Privacy : เนื่องจากพอมีหลาย Notary Node อาจเลือกให้มีทั้ง Non-Validating Notary Node และ Validating Notary Node อยู่ภายในเครือข่ายเดียวกันได้ แถมยังใช้ Consensus Algorithms ที่แตกต่างกันได้ ซึ่งช่วยให้สามารถเลือก Notary Node มาตรวจสอบแต่ละ Transaction ตามความเป็นส่วนตัวของข้อมูลได้ด้วย จึงให้ช่วยเพิ่มประสิทธิภาพด้านความเป็นส่วนตัวมากยิ่งขึ้น
  • Load balancing : พอมีหลาย Notary Node ก็แปลว่า สามารถกระจายการตรวจสอบไปยังหลายๆ โหนดพร้อมกันได้ ซึ่งจะช่วยเพิ่ม ปริมาณ Transaction ที่จะประมวลผลให้ได้มากยิ่งขึ้น ทำให้ระบบเร็วยิ่งขึ้น
  • Low latency : พอมี Notary Node เยอะ ก็สามารถเลือก Notary Node ที่อยู่ใกล้กับ Party Node มากที่สุดมาประมวลผลได้ ก็จะช่วยให้มี latency ที่ต่ำ

Changing notaries

เนื่องจาก Notary Node จะทำหน้าที่แค่ Sign Transaction เท่านั้น โดยที่การตรวจสอบ Input State จะใช้ Notary Node เดิมเสมอในการตรวจสอบ แต่ในบางกรณีที่เราต้องการเปลี่ยน Notary Node ที่อ้างอิงไปยัง State นั้นๆ ก็สามารถทำได้ โดยการสร้าง Flow เพื่อเปลี่ยนมัน

Oracles

มาถึงหัวข้อ ที่ทิ้งค้างไว้นาน ตั้งแต่ Part.1 ที่ผมเคยบอกไว้ว่า Services หลักๆ ใน Corda จะแบ่งได้เป็น 2 แบบ คือ Notary Services และ Oracle Services และที่ผ่านๆ มาผมได้อธิบายถึง Notary Services ไปค่อนข้างเยอะแล้ว (ถ้าไม่รู้ตัวว่า ผมพูดถึงตอนไหน ลองอ่านบทความทั้ง 2 Part วนซ้ำใหม่อีกครั้ง) แต่ยังแทบไม่ได้พูดถึง Oracle กันเลย เอาหล่ะ Oracle มันคืออะไร มาดูกัน

Oracles เข้ามาตอบโจทย์ในการ Validate Transaction กับปัญหาที่ว่า ในบางครั้งในการ Validate จำเป็นจะต้องใช้ข้อมูลจากภายนอกเข้ามาตรวจสอบด้วย เช่น ราคาเหรียญ Bitcoin ณ ปัจจุบัน Corda เรียกข้อมูลภายนอกเหล่านี้ว่า Fact

ซึ่งถ้าเราปล่อยให้โหนดแต่ละโหนด ดึง Fact มา Validate กันเอง ก็อาจจะเจอปัญหาที่ บางครั้งแต่ละโหนดดึงข้อมูลมาได้ไม่ตรงกันบ้าง ข้อมูลผิดบ้าง หรือ มีการแอบโกงข้อมูลก็เป็นไปได้ ซึ่งสิ่งที่จะเข้ามาแก้ปัญหาเหล่านี้ก็คือ คนกลางในการดึงข้อมูลที่เรียกว่า Oracle Node

Oracle Node เข้ามาทำหน้าที่ในการ Sign เพื่อยืนยันความถูกต้องของข้อมูลที่อยู่ใน Transaction เช่น Oracle ทำการดึงข้อมูล ราคาเหรียญ Bitcoin ล่าสุด เข้ามา และตรวจสอบว่า Transaction นั้นๆ มีข้อมูลเดียวกันหรือไม่ ถ้าตรงกันก็จะ​ Signed ว่า Transaction นั้นถูกต้อง

โดยถ้า Transaction ใดๆ ต้องการยืนยันความถูกต้องของข้อมูลจาก Oracle ก็จะต้องเรียกดึงข้อมูลผ่านทาง Flow โดยส่ง Require command ไปหา Oracle และ Oracle จะเข้ามายืนยันว่า Fact นั้นถูกต้อง (เดี่ยวเราไปลงลึกอีกครั้งในบทความการพัฒนา CorDApp)

แต่ก็อย่างที่รู้ว่า Corda ถูกออกแบบให้ใช้เพื่อความเป็นส่วนตัวของข้อมูลสูง ซึ่งถ้าจะเปิดเผยข้อมูลใน Transaction ให้ Oracle รู้หมด (เพื่อตรวจสอบความถูกต้อง) ก็จะทำให้ ข้อมูลไม่เป็นส่วนตัว Corda จึงแก้ปัญหานี้ด้วยการทำ Transaction tear-offs

Transaction tear-offs

ด้วยวิธีการนี้ จะทำให้ Oracle Node / Non-Validating Notary Node เข้ามาดูข้อมูลได้แค่ส่วนที่ต้องมองเห็นเท่านั้น และทำ Sign ลงใน Transaction ได้ในส่วนที่ Signed ได้เท่านั้นด้วยการใช้ Merkle Tree ซึ่งเป็นเทคนิคที่ถูกใช้บ่อยในระบบแบบ Peer-to-Peer Networks

โดย Transaction จะถูก tear off หรือ ตัดออกให้เหลือแค่ส่วนที่ Oracle จำเป็นต้องเห็น โดยการใช้ SHA256 (การทำ SHA256 แทนด้วย H และ + คือการต่อ String ตามภาพด้านล่าง) กับข้อมูลส่วนที่ต้องการปกปิดไว้

โดยขั้นตอนการทำงานของ Transaction Merkle Tree จะทำอย่างโดย

  1. ทำการแยกข้อมูลภายใน Transaction ออกเป็นส่วนย่อยๆ
  2. นำข้อมูลที่แบ่งแล้ว มาทำ SHA256 function
  3. นำผลลัพต์จากการทำ SHA256 ของข้อมูลแต่ละชุด มาต่อกัน ตามลำดับ Merkle Tree (ตามภาพด้านบน) และ นำมาทำ SHA256 function อีกครั้ง ทำแบบนี้วนซ้ำจนกว่าจะถึง Merkle Root

โดยถ้ามีการแก้ไขข้อมูลส่วนที่ไม่ควรแก้ไข ก็จะทำให้ผลลัพต์ของการทำ SHA256 ที่ Merkle Root เปลี่ยนไปจากเดิม ทำให้รู้ได้ทันทีว่า ข้อมูลถูกเปลี่ยน และจากภาพด้านบนจะเห็นว่า มีแค่ข้อมูลส่วนด้านขวาเท่านั้น ที่ Oracle Node หรือ Non-Validating Notary Node จะเห็นได้ และเมื่อตรวจสอบเสร็จก็จะ Signed Transaction

** มีการเปิด Oracle Node ในเชิงพาณิชย์ให้เราเข้าไปใช้บริการด้วยนะ แต่ก็ไม่ฟรีนะ 555 **

Nodes

แต่ละโหนดจะใช้ JVM run-time แบบ unique network identity ในการรัน Corda Software (Corda services และ CorDApps) โดยจะแบ่ง interface ออกเป็น 2 ส่วน

  • ส่วน Network layer สำหรับใช้ติดต่อกับโหนดอื่น
  • ส่วน RPC สำหรับให้เจ้าของโหนดเข้าไปเชื่อมต่อ

โดยส่วนประกอบสำคัญภายในโหนด มีดังนี้

  1. Persistence layer : เป็นส่วนของการเก็บข้อมูล โดยจะแบ่งเป็น 2 ส่วน ดังนี้
  • The vault = ส่วนที่จัดเก็บ Current State รวมถึง Consumed State ด้วย
  • The storage service = ส่วนที่จัดเก็บ Transaction, ไฟล์แนบ (Attachments) และ Flow Checkpoints (เมื่อมีการใช้ @Suspendable บนส่วนหัวของ function)

2. Network interface : เป็นส่วนที่ใช้ในการติดต่อกับโหนดอื่นๆ โดยจะต้องสื่อสารผ่าน Flow เท่านั้น แต่ละโหนดคุยกันตรงๆไม่ได้

3. RPC interface : เป็นส่วนที่เราใช้ในการติดต่อกับโหนด เพื่อควบคุมโหนด

โดยการใช้ RPC (Remote Procedure Calls) สามารถดู command ต่างๆ ได้เลย คลิกที่นี่

4. Service hub : เป็นส่วนที่ช่วยให้ Flow สามารถเข้าถึง Services ต่างๆของ Corda

โดยในการเรียกใช้งาน Services ต่างๆของ Flow จะเรียกผ่าน serviceHub (เราจะไปลงลึกในบทความการพัฒนา CorDApp อีกครั้งครับ)

โดย Services สำคัญที่ มีให้ :

  • ข้อมูลของโหนดอื่นๆ ภายในเครือข่ายและ service ที่โหนดอื่นมีให้ใช้งาน
  • การเก็บข้อมูล และ การเรียกใช้งานข้อมูลภายใน Vault
  • การเข้าถึงและการสร้าง Public key และ Private key
  • ข้อมูลของโหนดตัวเอง
  • เวลาปัจจุบัน (ใช้กรณี Time-Windows)

5. CorDApp interface และ Provider เป็นส่วนที่ใช้ในการติดตั้ง CorDApp และ Implement Code ไปยังโหนด โดยในทุกๆ CorDApp จะมีการติดตั้ง default ไว้ประกอบด้วย

  • ส่วนการรับ Transaction และไฟล์แนบต่างๆ จากโหนดอื่นๆ ที่เกี่ยวข้อง (ภายใน Party Node)
  • ส่วนการ Upgrade contracts
  • ส่วนที่ใช้ในการ Broadcast เพื่อยืนยันให้ภายใน Party Node ทำการ Update Ledger ของตัวเอง

** ถ้างงส่วนนี้ เดี่ยวจะได้เข้าใจตอนบทความการ Setup Corda Node ครับ **

Draining mode (โหมดท่อระบาย Flow ทิ้ง)

โดยในการจะ Shutdown หรือ Clean โหนดนั้น เราจำเป็นจะต้องแน่ใจว่า จะไม่มีการค้างการทำงานของ Flow อยู่ในโหนด โดยเราสามารถเปิด draining mode ได้ โดยเมื่อเปิดแล้ว

  1. เมื่อมี Command ต้องการจะเริ่ม Flow ใหม่ Flow นั้นจะถูก Reject ทิ้ง
  2. Flow ที่ถูกกำหนดเวลาไว้ จะถูกยกเลิก
  3. การเชื่อมต่อระหว่างโหนดทั้งหมดจะหยุดการทำงาน หมายความว่าโหนดที่ต้องการจะเชื่อมต่อเพื่อสร้าง Flow ใหม่ จะทำไม่ได้
  4. กิจกรรมทั้งหมดที่กำลังทำอยู่จะยังคงทำงานตามปกติ เพื่อให้งานทั้งหมดค้างอยู่ ทำงานจนเสร็จ แต่ก็จะไม่มีกิจกรรมใหม่ๆ เกิดขึ้นแล้ว (เพราะ 3 ข้อด้านบน)

โดยเมื่อกิจกรรมทั้งหมดภายในโหนดทำงานเสร็จจนหมดแล้ว ก็จะสามารถปิดโหนดได้อย่างปลอดภัย

และแล้วก็จบกันไปแล้ว สำหรับส่วนเนื้อหาของ Corda นะครับ ในบทความต่อๆไป ผมจะลงลึก วิธีการติดตั้ง และ พัฒนาตัว CorDApp กันต่อนะครับ รอติดตามครับ

คำศัพท์เพิ่มเติม

  • Double-Spend Transaction = การพยายามทำธุรกรรมทางการเงินสองครั้ง โดยใช้เงินก้อนเดียวกัน ปัญหาที่มักจะเกิดขึ้นกับระบบแบบกระจายศูนย์กลาง เพราะแต่ละคนมีการรับข้อมูลไม่พร้อมกัน ตัวอย่างเช่น นาย Alice มีเงิน 100 แต่ใช้เงิน 100 บาทนี้โอนไปให้ Bob และ Carl พร้อมกันเพื่อจะใช้จ่ายค่าสินค้า

--

--