วันนี้มีโอกาสได้ช่วยแก้ปัญหาการใช้งานวอลเล็ตให้กับชาวเราท่านหนึ่ง คิดว่าเป็นข้อผิดพลาดที่อาจจะเกิดขึ้นกับทุกคนได้ จึงขอนำเคสนี้และวิธีแก้ไขมาเล่าต่อครับ
—
TL;DR
ถ้าต้องการทำ watch-only wallet สำหรับ native segwit ต้องดูให้แน่ใจว่า Xpub ที่เอามาขึ้นต้นด้วย “zpub…” หรือถ้าต้องการใช้ nested segwit ต้องใช้ “ypub…” ไม่อย่างนั้นถ้าเอา “xpub…” มามันจะแผลงร่างไปเป็น legacy
หลังจาก import Xpub เข้า software wallet เพื่อทำ watch-only wallet แล้ว ก่อนจะโอนเงินเข้าโดยใช้ address จาก watch-only wallet นั้นให้เช็คก่อนว่าชุด address ที่ได้จาก watch-only wallet มันตรงกับ wallet ตัวต้นทางไหม
—
[[[ เริ่มเรื่อง ]]]
เรื่องเริ่มต้นจากเจ้าของเคส (จขค.) generate seed สร้าง wallet ใน sparrow desktop จากนั้นก็สแกน QR code ของ Xpub ด้วยแอป Trezor suit lite เพื่อสร้างเป็น watch-only wallet บนมือถือ
ปัญหาที่เกิดขึ้นก็คือ หากเช็คดู ณ จุดนี้ จะพบว่าชุดของ address ใน sparrow และ Trezor ไม่ตรงกัน!
https://image.nostr.build/1231055fcb7011bc820d76ddd242135ae558dcba565ffde4bd398e0f247d7461.png
https://image.nostr.build/88599ec5edba5496edd22cc7be3ff22adb8fce1c14de5072b29ad2bf66a8bca8.jpg
และความเสียหายจะไม่เกิดขึ้นเลยถ้าเราเช็คเสียก่อนว่าชุดของ address ตรงกันไหมก่อนที่จะโอนเงินเข้าไป (ดังนั้นเพื่อหลีกเลี่ยงปัญหาแต่แรก กรุณาทำตามข้อแนะนำในส่วน TL;DR)
ส่วนสิ่งที่เกิดขึ้นในเคสนี้คือ จขค. โอน BTC เข้าไปใน address ที่ได้จาก trezor และไม่สามารถเอาออกมาได้ เพราะ
trezor เป็น watch-only ไม่มี private key ไม่สามารถ sign ธุรกรรมได้
sparrow ไม่สามารถ sign ธุรกรรมได้ เพราะ address เป็นคนละชุดกัน มองไม่เห็นยอดเงินนั้น
—
[[[ สาเหตุ ]]]
อันที่จริงแล้วที่เราพูดกันว่า Xpub ซึ่งย่อมาจาก extended public key เนี่ย มันไม่ได้มีแค่ที่ขึ้นต้นด้วยอักษร “xpub…” เท่านั้น แต่ยังมี “ypub…” และ “zpub…” อีกด้วย
“xpub…” ไว้ใช้สำหรับ address ประเภท legacy (bip44 ขึ้นต้นด้วย 1…)
“ypub…” ไว้ใช้สำหรับ address ประเภท nested segwit (bip49 ขึ้นต้นด้วย 3…)
“zpub…” ไว้ใช้สำหรับ address ประเภท native segwit (bip84 ขึ้นต้นด้วย bc1q…)
ซึ่งด้วยเหตุผลใดในด้านการออกแบบที่ไม่ทราบได้ เมื่อ จขค. สร้างกระเป๋าแบบ native segwit ใน sparrow มันกลับแสดง Xpub ในรูปแบบ “xpub…” มาเป็นอันดับแรกแทนที่จะเป็น “zpub…” (คือ zpub… ก็สามารถเรียกให้แสดงขึ้นมาได้ แต่ต้องกดปุ่มลูกศรด้านขวาของช่องที่แสดง Xpub ก่อน)
https://image.nostr.build/1c40e7e258b6090e671e2ff33d8c4b61bd089a501e2c8e55bc95cd538bd198c4.png
ทีนี้ ในเมื่อสากลโลกเค้าเข้าใจตรงกันว่า “xpub…” ไว้ใช้สำหรับ legacy พอ จขค. ใช้ trezor สแกน “xpub…” แอป trezor ก็เข้าใจว่าต้องการใช้ address แบบ legacy จึงจัดแจงเอา “xpub…” นั้นไป derive ด้วยมาตรฐาน bip44 ได้ผลลัพธ์ออกมาเป็น address ประเภท legacy ทั้งเซ็ท
(ลองกับ Blue Wallet แล้วก็เป็นลักษณะเดียวกัน)
สรุปรวบรัดคือ ตอนนี้ trezor suit lite มันเอา Xpub ที่ได้จาก derivation path m/84’ ไปสร้าง address ด้วยมาตรฐาน bip44
และวิธีแก้คือ เราก็จะต้องบังคับให้ sparrow (ซึ่งเป็นที่ที่มี private key ของเราอยู่) ทำท่าพิสดารท่าเดียวกันนี้ เพื่อให้สามารถเซ็นธุรกรรมโอนเงินออกได้
—
[[[ ปัญหา ]]]
โดยปกติสำหรับ sparrow คุณจะต้องเลือกประเภท address ที่ต้องการจะใช้ (legacy / nested segwit / native segwit / taproot) ก่อนที่จะสร้าง seed, กรอก seed หรือ connect hardware wallet เพราะว่ามันจะไปดึงเอา Xpub ที่สอดคล้องกันมาทำกระเป๋าให้เรา
ถ้าเราบอกมันว่าอยากสร้างแบบ legacy มันจะไปดึง Xpub จาก derivation path m/44’ มา
ถ้าเราบอกมันว่าอยากสร้างแบบ nested segwit มันจะไปดึง Xpub จาก derivation path m/49’ มา
ถ้าเราบอกมันว่าอยากสร้างแบบ native segwit มันจะไปดึง Xpub จาก derivation path m/84’ มา
ถ้าเราบอกมันว่าอยากสร้างแบบ taproot มันจะไปดึง Xpub จาก derivation path m/86’ มา
ในกรณีของ จขค. sparrow ดึง Xpub จาก path m/84’ มาเพื่อเตรียมสร้างกระเป๋า native segwit ตามมาตรฐาน bip84
ถ้าเราพยายามจะเปลี่ยนไปใช้มาตรฐาน bip44 มันจะไล่เราให้ไป import keystore ใหม่ เพราะเอา Xpub อันที่ควรเป็นจาก path m/44’ มาใช้
การเอา Xpub จาก path หนึ่งไปสร้าง address ด้วยอีกมาตรฐานหนึ่งเป็นเรื่องผิดผี ไม่งาม ระบบตรวจสอบใน sparrow ไม่ยอมให้เราทำแบบนั้น (เราจะไม่สามารถกดปุ่ม apply ได้)
https://image.nostr.build/f59437b123457db7942aa5705e226359c8bcc44634d9c7415c9e626e869d0c6c.png
แต่เราดันทำแบบนั้นใน trezor ไปแล้วไง!!! เพราะฉะนั้นแกก็ต้องทำด้วย!!! ชั้นจะบีบคอให้แกทำ!!!
—
[[[ วิธีแก้ ]]]
ในการทำแบบนั้น เราจะต้องปิดระบบป้องกันการทำผิดผี (validate derivation) ของ sparrow โดยการเข้าไปที่เมนู file > preference > general แล้วติ๊กปิด toggle หลังคำว่า validate derivation (หลังจากนั้นเราอาจจะต้องปิดโปรแกรม sparrow และเปิดขึ้นมาให้เพื่อให้ setting ใหม่นี้มีผล)
https://image.nostr.build/7ddc2784757b650f9d17fdccdc4496200835c8360424b2810bf81dd350c24b9b.png
ในตอนนี้เราสามารถแก้ประเภทกระเป๋าจาก native segwit (bip84) เป็น legacy (bip44) ทั้งที่ยังใช้ Xpub เดิมจาก m/84’ ได้แล้ว สามารถกดปุ่ม apply ได้ เราควรจะพบชุด address เดียวกันกับใน trezor suit lite เห็นยอดเงิน และโอนออกได้ตามปกติ (และควรกลับไปเปิด validate derivation กลับมาด้วย เดี๋ยวจะทำพลาดแบบแปลกๆ อีก)
https://image.nostr.build/5d08f3e3c5d2484d5f8abe997af327f05c4fefa26e923983329451f7d0f4ffbc.png
https://image.nostr.build/6d0ba749c96c8d71efee0bf049516b5a36b27e7f099ae1030b92c4c2cfef97ea.png
เอวังด้วยประการฉะนี้ สวัสดีครับ
#Siamstr
#SparrowWallet
#TrezorSuitLite
#WatchOnlyWallet