Blockchain EP.5 : Communicate in P2P Network

Anonymous
Nextzy
Published in
3 min readApr 17, 2018

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

ปัจจุบัน Blockchain ถูกนำมาทำเครือข่ายของระบบกระจายตัว ที่เข้ามาแก้ไขปัญหาในระบบหลายๆอย่าง ตัวอย่างที่เห็นชัดเลยคือ Bitcoin ที่ทุกคนเข้ามาเป็นคนเก็บข้อมูลการเงินในระบบคนละชุด ไม่ใช่ธนาคารที่เป็นตัวกลางเก็บข้อมูลอยู่ที่เดียว เป็นต้น

การติดต่อสื่อสารกันระหว่าง Node ที่รันตัว Blockchain นั้นสามารถทำได้หลายวิธี แต่ที่เป็นที่นิยมที่สุดคือ Peer-to-Peer Network หรือเรียกสั้นๆว่า P2P โดยในแต่ละ Node นั้นจะทำการติดต่อสื่อสารกันเองเป็นเครือข่าย โดยไม่จำเป็นต้องมี Server กลางคอยควมคุม

Create Transaction in Network

เมื่อทำการสร้าง Transaction ขึ้นมาเราจะทำการ Broadcast Transaction นั้นไปให้ Block อื่นเก็บไว้ด้วย เพื่อให้คนอื่นสามารถทำการขุด (Mining) เพื่อสร้าง Block ให้เราได้

Mining Block in Network

หลักจากที่มี Node ใดในระบบทำการสร้าง Block เสร็จเรียบร้อยแล้ว ก็จะทำการ Broadcast เพื่อบอกโหนดอื่นๆให้ทำการ Sync Block ใหม่ไปเก็บไว้ จากนั้น Node อื่นๆก็จะอัพเดต Transaction ที่ผ่านการ Confirm แล้วลงไปได้

Let’s Coding

ในบทความนี้เราจะยังไม่ไปถึงการตัดการการแตกสายของ Block นะครับ โดยจะเป็นตัวอย่างแบบง่ายๆในการติดต่อสื่อสารกันระหว่าง Node ผ่าน P2P Network เพื่อทำการ Sync Block / Transactions กัน จะไม่ลงรายละเอียดเชิงลึกอื่นๆ เช่น การ handle เมื่อมี Node อื่นๆขุดได้ Block ที่แตกต่างกัน เป็นต้น

P2P Network

ในการติดต่อสื่อสารกันแบบ P2P ระหว่างโหนดนั้น ผมเลือกใช้ js-libp2p ครับ โดยผมได้ทำการ Implement Library ครอบขึ้นมาอีกชั้นหนึ่ง เพื่อให้ง่ายต่อการใช้งานและความเข้าใจ โดยสามารถดูได้ที่ devsolate/p2p-connect

เริ่มต้นด้วยการลง p2p-connect มาก่อนนะครับ

npm install devsolate/p2p-connect#master — save

จากนั้นผมสร้างไฟล์ node.js สำหรับเป็นตัว config / event ของ P2P Node นะครับ โดยประกอบไปด้วยการดึง Blockchain และตัว Command Interface มารัน โดยหลังจากที่ P2P Node ตัวนั้นเริ่มทำงานแล้ว ก็จะเข้าสู่ CLI ของเราต่อไป

เมื่อเริ่ม Start P2P Node ตัวโหนดนั้นจะทำการ Broadcast ผ่าน TCP เพื่อค้นหาโหนดอื่นๆและทำการเชื่อมต่อ โดยไม่ต้องมีตัวกลางคอยควบคุมว่ามีโหนดไหนอยู่ในระบบบ้าง แต่ในการใช้งานจริง เราอาจจะต้องใช้ตัวกลางในการระบุว่าระบบมี Node ไหนเชื่อมต่ออยู่บ้าง เพื่อให้โหนดใหม่สามารถเรียกเพื่อเชื่อมต่อได้เลย โดยลักษณะก็จะคล้ายๆกับไฟล์ Torrent ที่เราดาวน์โหลดเป็นตัวตั้งต้นว่าเราจะเชื่อมต่อเพื่อดาวน์โหลดไฟล์จากที่ไหนนั่นเอง

Event Handling

คราวนี้เรามากำหนด Event ต่างๆที่จะเกิดขึ้นใน Node.js เรากัน โดยแบ่งเป็น 2 กลุ่มคือ Sync Event สำหรับดึงข้อมูลจาก Node อื่นๆ เมื่อเราทำการรัน Node นั้นใหม่เพื่อให้ข้อมูลอัพเดตล่าสุด และ Create Event สำหรับ Broadcast ไปให้ Node อื่นๆที่รันอยู่เมื่อทำการสร้าง Block หรือ Transaction เสร็จสิ้น

  • Sync Request สำหรับขอข้อมูล Block ถัดไป
  • Sync Block สำหรับรับข้อมูล Block ถัดไปจาก Node อื่น
  • Sync Transaction Request สำหรับขอข้อมูล Transaction ส่วนที่ยังติด Pending อยู่
  • Sync Transaction สำหรับรับข้อมูล Transaction ที่ยังติด Pending จาก Node อื่น
  • Created Transaction สำหรับรับข้อมูล Transaction ที่ถูกสร้างจาก Node อื่น
  • Created Block สำหรับรับข้อมูล Block ที่ถูกสร้างจาก Node อื่น

การรับส่งข้อมูลระหว่าง Node นั้น เราจะใช้ PubSub ซึ่งจะเป็นการ Broadcast ไปยังทุกๆ Node เมื่อมีการ Trigger Event ขึ้นมา

เริ่มแรกเมื่อ Node ได้ทำการต่อกับ Node อื่นๆ เราก็จะเริ่มทำการ Sync ข้อมูลกัน โดย Publish Event Sync Request และ Sync Transaction เพื่อขอข้อมูลจาก Node อื่นๆกันครับ โดยการ Sync Block จะส่ง Hash ล่าสุดของ Node นี้ที่เก็บไว้ไปด้วย เพื่อไปขอ Block ถัดไปมาเลย ไม่ต้องส่งมาใหม่ทั้งหมด

จากนั้นเราก็ทำการ Subscribe Event ต่างๆเพื่อทำงานต่างๆนะครั

  • Sync Request สำหรับขอข้อมูล Block ถัดไป เมื่อรับมาแล้วทำการค้นหา Block ใน Blockchain จาก Hash ที่ได้รับแล้ว แล้วทำส่งค่ากลับไปผ่าน Event Sync Block
  • Sync Block สำหรับรับข้อมูล Block ถัดไปจาก Node อื่น เมื่อรับค่ามาแล้วก็ทำการ Save ลง DB
  • Created Block สำหรับรับ Event เมื่อ Node อื่นทำการ Mining Block ใหม่ได้ Node ที่ไม่ได้ขุดก็จะขอ Request Block โดยผ่านฟังก์ชัน Sync เหมือนเดิม

สำหรับ Event ของ Transaction สามารถดูได้จาก Source Code ตัวเต็มเลยนะครับ จากนั้นเราแก้ไขไฟล์ index.js เรียกรัน P2PNode แทนการเรียก CLI ตรงๆเหมือนคราวก่อน

Testing

เริ่มรัน Node ที่ 1 เราก็ได้ ID ของ Node นั้นมา ซึ่ง ID ตัวนี้มาจาก js-libp2p นะครับ และรอรับการ Connect จาก Node อื่นๆต่อไป แล้วทำการ Init Blockchain และทดสอบการทำ Transaction ขึ้นมาครับ ได้มาแล้ว 2 Block

ตัดภาพที่ Node ที่ 2 เราทำการ Start มันจะทำการค้นหาและ Connect ไปยัง Node1 แล้วดึง Block มาเก็บไว้ที่ Node ตัวเองด้วยนะครับ ( โปรแกรมรันอยู่บนคนละโฟลเดอร์และ DB คนละตัว ) เมื่อเรารันคำสั่ง List ก็จะเจอ Block ที่ Sync มาจาก Node 1 นั่นเอง

มาลองให้ Node อื่นทำหน้าที่ขุดให้กันดีกว่าครับ เมื่อทำการสร้าง Transaction ใหม่ ตัวมันเองก็จะ Broadcast ไปให้ Node อื่นๆด้วย

  • Node 2 ทำการ Transaction
  • Node 1 ได้รับ Transaction แล้วก็ทำการขุด
  • กลับมา Node2 เมื่อได้รับ Event Created Block ก็จะทำการ Sync Block ใหม่มาเก็บไว้เรียบร้อย สามารถดึงมาดูได้เลย
Node 2

References

--

--