BOLT 12 กับ BOLT 11: เปลี่ยนอะไร และทำไมสำคัญ
Lightning Network ของ Bitcoin เดิมใช้ BOLT 11 สำหรับ invoice — string lnbc… ที่คุ้นเคยในกระเป๋า Lightning ส่วนใหญ่ BOLT 11 ใช้งานได้ดีกับการจ่ายเงินครั้งเดียว: ร้านค้าสร้าง invoice ลูกค้าจ่าย จบ แต่ BOLT 11 มีข้อจำกัดสำคัญที่ชัดเจนเมื่อใช้ระดับใหญ่
invoice BOLT 11 ใช้ได้ครั้งเดียว ทุกการจ่ายเงินต้องดึง invoice ใหม่จากผู้รับ ทำให้ลิงก์บริจาคแบบถาวรเป็นไปไม่ได้ — ถ้าคุณ publish invoice BOLT 11 แล้ว 100 คนพยายามจ่าย มีแค่คนแรกที่สำเร็จ ผู้จ่ายคนถัดไปทุกคนต้องดึง invoice ใหม่ก่อนจ่าย ซึ่งต้องให้ผู้รับ online อยู่
BOLT 11 รั่วข้อมูลโหนดของผู้รับ invoice encode node public key ของผู้รับสุดท้าย ใครก็ตามที่ถือ invoice ระบุโหนดปลายทางบนกราฟ Lightning Network ได้ ทำให้ทั้งการสอดส่องและ denial-of-service เป็นไปได้
BOLT 12 แก้ทั้ง 2 ปัญหา ด้วยการผสมระหว่าง reusable offers และ onion messages
Reusable offers
BOLT 12 offer (HRP: lno) คือคำเชิญจ่ายเงินแบบถาวรที่ใช้ซ้ำได้ เมื่อผู้จ่ายต้องการจ่าย offer จะส่ง invoice request (HRP: lnr) ไปที่ผู้ออก offer ผ่าน Lightning Network ด้วย onion messages ผู้ออกจะตอบกลับด้วย invoice สด (HRP: lni) ที่ทำเฉพาะผู้จ่ายคนนั้น จากนั้นการจ่ายเงินจริงก็ดำเนินตามปกติ
flow นี้ช่วยให้:
- string บริจาคแบบถาวร คุณ publish offer เส้นเดียว ใช้ได้กับทุกคนไม่จำกัด
- การสมัครสมาชิก ผู้จ่ายสามารถขอ invoice ซ้ำตามตาราง จ่าย offer เดียวกันได้เรื่อยๆ
- การคืนเงิน BOLT 12 offer รวม refund offer ได้ ทำให้ reverse payment แบบมีโครงสร้างได้
- ความยืดหยุ่นของสกุลเงิน offer ระบุจำนวนในสกุลเงินที่ไม่ใช่ Bitcoin ได้ แล้วค่อยแปลงตอนออก invoice
Onion messages
BOLT 12 อาศัย onion messages — กลไก routing message ใดๆ ผ่าน Lightning Network ด้วย onion routing เดียวกับที่ใช้จ่ายเงิน แต่ไม่ต้อง lock ทุนใดๆ ทำให้ handshake offer → invoice-request → invoice ทำได้โดยไม่ต้องให้ผู้รับเก็บ TCP connection ตรง
onion messages ยังรักษาความเป็นส่วนตัวของผู้รับ string offer มี blinded paths ได้ — route hint ที่เข้ารหัสไว้ล่วงหน้า ให้ผู้จ่ายเข้าถึงผู้รับได้โดยไม่เคยรู้ identity ของโหนดผู้รับ public key ของผู้รับถูกซ่อนอยู่ใน onion
3 ชนิดของ HRP
ทุก message BOLT 12 ถูก encode ด้วย bech32m โดยมี Human-Readable Part (HRP) เฉพาะที่บอกประเภทของ message:
-
lno1…— Offer คำเชิญจ่ายเงินแบบถาวรใช้ซ้ำได้ นี่คือสิ่งที่คุณ publish ออกสาธารณะ ประกอบด้วย: จำนวนที่ต้องจ่าย (หรือ placeholder สำหรับจำนวนตามใจ) คำอธิบาย สกุลเงินและอัตราแปลง (optional) และ blinded paths ไปถึงผู้รับ (optional) -
lnr1…— Invoice Request message จากผู้จ่ายไปผู้รับ ส่งเป็นการตอบสนองต่อ offer ประกอบด้วย: offer ID ที่กำลังตอบ public key ของผู้จ่าย (สำหรับ reply path) และ payer note หรือหลักฐานการจ่ายเงิน (optional) -
lni1…— Invoice invoice ใช้ครั้งเดียวที่สร้างตอบ invoice-request ประกอบด้วย: จำนวนเป็น millisatoshi, payment hash, เวลาหมดอายุ, routing hints (อาจ blinded), และ signature
สังเกตว่า invoice BOLT 12 แบบ lni ต่างจาก invoice BOLT 11 (lnbc…) — ใช้แทนกันไม่ได้ และต้องใช้กระเป๋าที่รองรับ BOLT 12 ในการจ่าย
bech32m กับ bech32
BOLT 11 ใช้ bech32 (encoding ของ SegWit ดั้งเดิม) BOLT 12 ใช้ bech32m เวอร์ชันที่ปรับเล็กน้อยเพื่อเพิ่มการตรวจจับ error สำหรับ string ยาวๆ polynomial ของ checksum ต่างกัน นั่นหมายความว่า string bech32 กับ bech32m ใช้แทนกันไม่ได้ และ decoder bech32 จะปฏิเสธ offer BOLT 12 อย่างถูกต้องว่า invalid
decoder นี้ใช้ bech32m variant ในการ validate และ decode string BOLT 12
สถานะการรองรับของกระเป๋า
BOLT 12 ยังเป็น specification ที่ค่อนข้างใหม่ที่ต้องเพิ่ม protocol สำคัญ (onion messages, blinded paths) ณ ปี 2026 การรองรับกำลังเติบโต:
- Core Lightning (CLN): implementation แบบเต็มรายแรก offer พร้อม production ตั้งแต่ CLN 22.11 BOLT 12 เป็น payment protocol พื้นเมืองของ CLN
- Phoenix Wallet: เพิ่มรองรับ BOLT 12 offer ในปี 2024 หนึ่งใน implementation BOLT 12 ที่ผู้ใช้เข้าถึงได้ง่ายที่สุด
- LDK (Lightning Development Kit): implementation BOLT 12 ที่แอ็กทีฟ ขับเคลื่อนหลายกระเป๋าที่ทยอยเพิ่มการรองรับ
- LNbits: เพิ่มการสร้าง BOLT 12 offer เป็น extension
- LND: รองรับ onion message และ BOLT 12 อยู่ใน active development ณ ปี 2026 — ยังไม่พร้อม production เต็มที่
- Eclair / Phoenix (server): รองรับ BOLT 12 ผ่าน implementation ของ Eclair
ecosystem กำลังเคลื่อนไหวเร็ว ดู release notes ล่าสุดของแต่ละกระเป๋าจะเชื่อถือได้ที่สุด
ความเป็นส่วนตัวและ flow การบริจาค
BOLT 12 เป็นการปรับปรุงความเป็นส่วนตัวที่สำคัญเหนือ BOLT 11 สำหรับการบริจาคและการจ่ายเงินประจำ:
- คุณ publish offer เดียว ไม่ใช่ invoice ต่อการจ่ายเงิน ไม่มีใครเดาได้ว่าคุณถูกจ่ายกี่ครั้งจาก offer แบบถาวรอย่างเดียว
- blinded paths ซ่อนโหนดของคุณ ถ้าคุณใส่ blinded path ใน offer ผู้จ่ายระบุโหนดของคุณบนกราฟเครือข่ายไม่ได้
- ไม่มีการใช้ payment hash ซ้ำ ทุก invoice ที่ออกจาก offer เดียวกันมี payment hash ไม่ซ้ำ ป้องกัน correlation ที่จะเกิดจากการใช้ invoice BOLT 11 ซ้ำแบบไร้เดียงสา
สำหรับนักพัฒนา Bitcoin ที่รับบริจาค offer BOLT 12 พร้อม blinded path เป็นส่วนตัวมากกว่า invoice BOLT 11 แบบถาวรเยอะ — และใช้งานได้ดีกว่า เพราะใช้ได้กับทุกผู้จ่ายโดยไม่ต้องใช้ action ฝั่ง server ต่อการจ่ายเงิน
ขอบเขตของ decoder ปัจจุบัน
decoder นี้ validate การเข้ารหัส bech32m และระบุประเภท HRP โชว์ raw payload เป็น hex สำหรับตรวจสอบ การ parse TLV (Type-Length-Value) stream แบบเต็ม — ซึ่งจะดึงจำนวน คำอธิบาย ชื่อผู้ออก blinded paths และ field ที่มีโครงสร้างอื่นๆ จาก payload — กำลังทำอยู่ รูปแบบ TLV ที่ BOLT 12 ใช้ถูกนิยามใน specification ของ BOLT 12 และต้องการการ parse แบบค่อยเป็นค่อยไปอย่างระมัดระวัง งานนั้นจะปรากฏใน update ถัดไปของเครื่องมือ
ในระหว่างนี้ มุมมอง envelope บอกคุณได้ว่า: string นี้ถูกสร้างเป็น bech32m ถูกต้องไหม เป็น message BOLT 12 ประเภทไหน และ payload มีกี่ bytes