โอนจากหลายกระเป๋าไปหลายกระเป๋าบน Solana
การโอนแบบจับคู่กระเป๋าเงินบน Solana ทำงานอย่างไร หนึ่งธุรกรรมต่อหนึ่งแถว ค่าธรรมเนียม 0.001 SOL ต่อการโอน และกฎ rent ที่ข้ามแถวแทนที่จะตัดยอดลง

บน Solana มีวิธีย้ายเงินจำนวนมากในคราวเดียวอยู่สามแบบ และคนมักสับสนระหว่างสามแบบนี้ เครื่องมือส่งหลายรายการจ่ายตามรายชื่อจากกระเป๋าเงินใบเดียว เครื่องมือรวบรวมแบบชุดดึงเงินจากกระเป๋าเงินหลายใบมารวมไว้ในใบเดียว แล้วยังเหลืออีกกรณีหนึ่งที่สองแบบแรกทำไม่ได้เลย
การโอนหลายกระเป๋าไปหลายกระเป๋าบน Solana เก็บผู้ส่งแต่ละรายไว้กับผู้รับของตัวเอง กระเป๋าเงินใบที่ 7 จ่ายให้ใบที่ 7 ใบที่แปดจ่ายให้ใบที่แปด และสองแถวนั้นไม่เกี่ยวข้องกันเลย
ฟังดูเหมือนรายละเอียดเล็กน้อย จริง ๆ แล้วมันคือความต่างระหว่างการมีแหล่งเงินเดียว กับการมีแหล่งเงินที่เป็นอิสระต่อกัน เช่นกระเป๋าเงินสี่สิบใบก็เท่ากับสี่สิบแหล่ง
- หนึ่งแถวคือหนึ่งธุรกรรม กระเป๋าเงินผู้ส่งของแถวนั้นจ่ายทุกอย่างที่อยู่บนแถวนั้น
- ค่าธรรมเนียมแพลตฟอร์ม 0.001 SOL ต่อการโอนหนึ่งครั้ง ค่าธรรมเนียมเครือข่าย 0.000005 SOL
- ในโหมดโทเคน ผู้รับที่ไม่เคยถือโทเคนตัวนี้มาก่อนต้องมีบัญชีโทเคนใหม่ ผู้ส่งจ่ายเงินมัดจำ rent เพิ่มอีก 0.00149 SOL
- แถวที่ผ่านการตรวจไม่ได้จะถูกข้ามทั้งแถว ไม่ใช่ถูกตัดยอดลง
สามรูปแบบของการโอนจำนวนมาก
เครื่องมือส่งหลายรายการคือหนึ่งไปหลาย กระเป๋าเงินใบเดียว รายชื่อผู้รับหนึ่งชุด ผู้จ่ายรายเดียว นี่คือรูปแบบที่ใช้กับการแจกโทเคน
เครื่องมือรวบรวมแบบชุดคือหลายไปหนึ่ง กระเป๋าเงินยี่สิบใบ ปลายทางเดียว และเมื่อจบงานทุกอย่างไปกองอยู่ที่เดียว
เครื่องมือหลายต่อหลายคือรูปแบบที่สาม และเป็นแบบเดียวที่รู้จักการจับคู่ นี่คือสิ่งที่เรียกว่าการโอนหลายกระเป๋าไปหลายกระเป๋า แถวแรกมีแหล่งเงินของแถวแรก แถวที่สองมีอีกแหล่งหนึ่ง ไม่มีกองกลาง และแถวหนึ่งไม่ช่วยจ่ายแทนอีกแถวหนึ่ง
หนึ่งแถวมีค่าใช้จ่ายเท่าไร
บนหนึ่งแถวอาจมีรายการค่าใช้จ่ายได้ถึงสามรายการ และกระเป๋าเงินผู้ส่งของแถวนั้นเป็นคนจ่ายทั้งสามรายการ ไม่มีบัญชีกลางที่คอยเติมเงินให้ ดังนั้นกระเป๋าเงินที่มีเงินไม่พอจ่ายค่าใช้จ่ายของแถวตัวเอง ก็ไม่ได้ยืมจากแถวที่อยู่ข้างบน รายการฝั่งเครือข่ายคือค่าธรรมเนียมพื้นฐาน 5000 lamport ต่อหนึ่งลายเซ็น ซึ่งเอกสารค่าธรรมเนียมของ Solana เองอธิบายที่มาไว้ครบ
| รายการ | โหมด SOL | โหมดโทเคน |
|---|---|---|
| ค่าธรรมเนียมแพลตฟอร์ม | 0.001 SOL | 0.001 SOL |
| ค่าธรรมเนียมเครือข่าย | 0.000005 SOL | 0.000005 SOL |
| บัญชีโทเคนของผู้รับ | ไม่เกี่ยวข้อง | 0.00149 SOL และเฉพาะเมื่อผู้รับรายนั้นไม่เคยถือโทเคนตัวนี้มาก่อน |
แถวที่สามควรอ่านซ้ำอีกรอบ เพราะนี่คือรายการที่ทำให้คนสะดุด การส่งโทเคน SPL ไปยังที่อยู่ที่ไม่เคยแตะโทเคนตัวนั้นมาก่อน แปลว่าต้องสร้างบัญชีขึ้นมาใหม่เพื่อเก็บมัน และ Solana เก็บเงินมัดจำ rent สำหรับบัญชีนั้น เงินมัดจำก้อนนี้สูงกว่าค่าธรรมเนียมเครือข่ายมาก
ถ้ามีผู้รับหน้าใหม่หนึ่งร้อยราย รายการนี้จะกินบิลไปราว 0.149 SOL ในขณะที่ค่าธรรมเนียมแพลตฟอร์มอยู่ที่ 0.1 SOL เงินมัดจำก้อนนี้ไม่ได้ถูกเผาทิ้ง มันค้างอยู่ในบัญชีโทเคนของผู้รับ และคืนให้กับใครก็ตามที่ปิดบัญชีนั้นในภายหลัง
แถวที่ถูกข้าม
ก่อนลงลายเซ็นจะมีการตรวจสองรอบ และทั้งสองรอบเลือกหยุดแถวนั้นไว้ แทนที่จะไปแก้ตัวเลขในแถว
รอบแรกเป็นเลขคณิตธรรมดา ถ้าเงินในกระเป๋าเงินผู้ส่งไม่พอจ่ายยอดของตัวเอง บวกค่าธรรมเนียม บวกบัญชีโทเคนที่อาจต้องเปิดใหม่ แถวนั้นจะถูกทำเครื่องหมายไว้และไม่ถูกส่ง ไม่มีอะไรออกไปแบบครึ่ง ๆ กลาง ๆ
รอบที่สองแปลกกว่าและควรทำความเข้าใจไว้ เพราะครั้งแรกที่เจอมันดูเหมือนบั๊ก ที่จริงคือ Solana ไม่ยอมให้เหลือบัญชีที่มียอดคงเหลือมากกว่าศูนย์ แต่ต่ำกว่าขั้นต่ำที่ได้รับยกเว้น rent สำหรับกระเป๋าเงินธรรมดา ขั้นต่ำนั้นคือ 0.00065 SOL และตัวเลขนี้ออกมาจากสูตรในเอกสารเรื่องบัญชีของ Solana
การเทบัญชีให้ว่างสนิททำได้ การทิ้งไว้ 0.00005 SOL ทำไม่ได้ แถวที่ผลักกระเป๋าเงินเข้าไปอยู่ในช่องว่างนั้นจะถูกติดป้ายว่า rent dust และค้างอยู่โดยไม่ถูกส่ง
ทำไมไม่ตัดยอดลงมาให้พอดี
ทางเลือกอีกทางคือค่อย ๆ เฉือนยอดลงจนกว่าจะพอดี และทางนั้นแย่กว่า ตัวเลขนั้นคุณเป็นคนกรอกเอง เครื่องมือที่ส่งตัวเลขอื่นออกไปเงียบ ๆ คือเครื่องมือที่หลังจากนั้นจะเทียบกับสเปรดชีตไหนก็กระทบยอดไม่ตรงอีกเลย
ให้ส่งยอดคงเหลือทั้งก้อนไปเลย หรือลดยอดลงจนส่วนที่เหลืออยู่เหนือขั้นต่ำ หน้าตัวอย่างบอกล่วงหน้าว่าแถวไหนโดนผลกระทบ และเครื่องมือจะตรวจบัญชีปลายทางทั้งหมดในการเรียกครั้งเดียวก่อนเซ็นอะไรทั้งสิ้น
หนึ่งธุรกรรมต่อหนึ่งแถว และทำไมเรื่องนี้ถึงสำคัญ
ในการโอนหลายกระเป๋าไปหลายกระเป๋า แต่ละแถวเป็นธุรกรรมของตัวเอง แถวที่ล้มจึงล้มอยู่แถวเดียว ถ้าเป็นชุดที่อัดทุกอย่างลงในธุรกรรมเดียว ความผิดพลาดที่แถวสามสิบจะลากยี่สิบเก้าแถวก่อนหน้าลงไปด้วย
เรื่องนี้มีราคาของมัน สี่สิบคู่แปลว่าลายเซ็นสี่สิบครั้ง และค่าธรรมเนียมเครือข่ายสี่สิบครั้ง ครั้งละ 0.000005 SOL ซึ่งไม่ใช่ส่วนของบิลที่ควรไปประหยัด สิ่งที่ได้กลับมาคือผลลัพธ์ที่อ่านได้ทีละแถว ใครอยากรู้ว่าธุรกรรมพวกนี้เข้าเร็วแค่ไหน ตัวเลขอยู่ในบทความค่าธรรมเนียมลำดับความสำคัญ
เมื่อไรการโอนหลายกระเป๋าไปหลายกระเป๋าบน Solana คือรูปแบบที่ใช่
กรณีที่คนใช้จริงมากที่สุดคือการหมุนกระเป๋าเงิน คุณมีกระเป๋าเงินชุดหนึ่งที่ติดประวัติซึ่งอยากทิ้งไว้ข้างหลัง จึงสร้างชุดใหม่ด้วยตัวสร้างกระเป๋าเงิน แล้วอยากให้กระเป๋าเงินเก่าใบที่ 7 เติมเงินให้กระเป๋าเงินใหม่ใบที่ 7 และไม่เกี่ยวกับใบอื่น
กรณีที่สองคือรายการจ่ายเงินที่ผู้จ่ายเปลี่ยนไปทีละแถว หลายโครงการ หลายกระเป๋าคลัง ตารางเดียว เครื่องมือส่งหลายรายการทำเรื่องนี้ไม่ได้เลย เพราะมันมีแหล่งเงินเพียงแหล่งเดียวเป๊ะ ๆ
กรณีที่สามคือการแบ่งใหม่หลังจากเก็บสแนปช็อต โดยผู้ถือแต่ละรายรับเงินจากกระเป๋าเงินที่กำหนดไว้ให้ล่วงหน้าแล้ว วิธีอ่านการกระจายตัวของผู้ถือก่อนจะแบ่ง อยู่ในคู่มืออ่านการกระจายตัวของผู้ถือ
เตรียมรายชื่ออย่างไร
ให้รันรอบแรกของการโอนหลายกระเป๋าไปหลายกระเป๋าด้วยสองแถวก่อน ตารางผลลัพธ์จะบอกว่าหนึ่งแถวใช้เงินไปจริงเท่าไร รวมเงินมัดจำบัญชีโทเคนเข้าไปด้วย ก่อนจะรันทั้งรายการ
ตรวจด้วยว่าผู้รับถือโทเคนตัวนั้นอยู่แล้วหรือยัง ในรายชื่อที่ครึ่งหนึ่งเป็นผู้ถือเดิม รายการเงินมัดจำจะหายไปครึ่งหนึ่ง และที่ขนาดหนึ่งร้อยแถว รายการนี้คือตัวเลขที่ใหญ่ที่สุดในบิลทั้งใบ
จดไว้ก่อนเริ่มด้วยว่ากระเป๋าเงินใบไหนจ่ายแถวไหน หลังรันไปแล้ว การไล่ย้อนหาว่าใบไหนจ่ายแถวไหนยากกว่าที่ฟังดูตอนนี้มาก โดยเฉพาะเมื่อกระเป๋าเงินผู้ส่งเพิ่งถูกสร้างขึ้นมาสด ๆ และยังไม่มีประวัติอะไรให้แยกแยะออกจากกัน
เรื่องยอดคงเหลืออีกข้อสุดท้าย กระเป๋าเงินผู้ส่งแต่ละใบต้องมีเงินพอจ่ายยอดกับค่าธรรมเนียม และส่วนที่เหลือหลังจ่ายต้องเป็นศูนย์พอดี หรือสูงกว่าขั้นต่ำ rent ถ้าเติมมาขาดไปนิดเดียว หรือเหลือเศษอยู่ระหว่างสองค่านั้น การตรวจจะเขี่ยแถวนั้นออกไป แล้วต้องกลับมาเติมเงินใหม่อีกรอบ ซึ่งช้ากว่าการเผื่อไว้ตั้งแต่แรก
อะไรเปลี่ยนไปเมื่อรายชื่อใหญ่ขึ้น
ที่สิบแถว ทุกอย่างข้างบนยังเป็นทฤษฎีที่สบาย ๆ พอถึงสองพันแถว มีสามเรื่องที่กลายเป็นงานจริง และทั้งสามเรื่องเป็นงานนอกตัวเครื่องมือ
เรื่องแรกคือการเติมเงิน กระเป๋าเงินผู้ส่งทุกใบต้องมียอดของตัวเองบวกค่าธรรมเนียมพร้อมอยู่ก่อนเริ่ม และไม่มีทางที่แถวหนึ่งจะช่วยจ่ายแทนอีกแถวหนึ่งได้ แปลว่าต้องมีรอบเติมเงินล่วงหน้าหนึ่งรอบ ปกติออกจากกระเป๋าคลังใบเดียว และควรเผื่อเงินไว้จนส่วนที่เหลือพ้นขั้นต่ำ rent แทนที่จะคำนวณมาพอดีเป๊ะ
เรื่องที่สองคือการกระทบยอดหลังจบงาน ที่สี่สิบแถว มองตารางก็จบแล้ว ที่สองพันแถว จะอยากส่งออกผลลัพธ์แล้วเทียบกับไฟล์ต้นทางทีละแถว เพราะแถวที่ถูกข้ามจะไม่โผล่บนเอ็กซ์พลอเรอร์เลยสักแถว มันไม่เคยมีตัวตนในฐานะธุรกรรม
ยังมีผลข้างเคียงข้อที่สามที่เห็นได้ยากกว่า ถ้าในรายชื่อมีทั้งผู้รับหน้าใหม่และผู้รับเดิมปนกัน ต้นทุนต่อแถวจะไม่คงที่ ค่าเฉลี่ยที่คำนวณจากสิบแถวแรกจะให้ตัวเลขที่ไม่เหมือนยอดรวมเลย ให้นับว่ามีผู้รับกี่รายที่ต้องเปิดบัญชีใหม่ แล้วคูณเฉพาะจำนวนนั้นด้วย 0.00149 SOL
เรื่องที่มักถูกมองข้ามตอนวางแผน
คนที่ทำงานสายนี้บ่อย ๆ มักสะดุดเรื่องเดียวกันสองสามข้อ ข้อแรกคือการคิดว่าเครื่องมือจะช่วยเติมเงินให้แถวที่ขาด มันไม่ทำ และเจตนาก็คือไม่ให้ทำ เพราะการหยิบเงินจากกระเป๋าเงินใบอื่นมาปิดแถวที่ขาด จะทำให้ความหมายของการจับคู่หายไปทันที
ข้อที่สองคือการวางแผนโดยดูแต่ยอดที่จะโอน แล้วลืมว่าค่าธรรมเนียมและเงินมัดจำก็ออกจากกระเป๋าเงินผู้ส่งใบเดียวกัน กระเป๋าเงินที่มีพอดีกับยอดโอนเป๊ะ ๆ จึงไม่พอเสมอ ส่วนต่างไม่มาก แต่มันเกิดกับทุกแถวพร้อมกัน
ข้อที่สามคือการอ่านผลลัพธ์ด้วยความคาดหวังผิด แถวที่ถูกข้ามไม่เคยถูกสร้างเป็นธุรกรรมตั้งแต่แรก ถ้าไปตามหาบนเอ็กซ์พลอเรอร์จะไม่เจออะไรเลย ซึ่งเป็นเรื่องปกติ ไม่ได้แปลว่ามีอะไรเสีย
คำถามที่พบบ่อยเกี่ยวกับการโอนแบบจับคู่
ต่างจากการรันเครื่องมือส่งหลายรายการหลายรอบอย่างไร?
เครื่องมือส่งหลายรายการมีแหล่งเงินหนึ่งแหล่งเป๊ะ ๆ ต่อการรันหนึ่งครั้ง สี่สิบแหล่งแปลว่ารันสี่สิบรอบ และสลับกระเป๋าเงินด้วยมืออีกสี่สิบครั้ง ส่วนหลายต่อหลายรันครั้งเดียวได้ครบสี่สิบแถว
แถวที่ล้มมีค่าใช้จ่ายไหม?
ขึ้นกับว่าล้มตอนไหน แถวที่ถูกปฏิเสธก่อนเซ็นไม่เสียอะไรเลย เพราะไม่มีธุรกรรมไปถึงเครือข่าย ส่วนแถวที่เซ็นและส่งแล้วไปล้มบนเชนจะเสียค่าธรรมเนียมเครือข่ายเหมือนธุรกรรม Solana ที่ล้มทุกรายการ ค่าธรรมเนียมแพลตฟอร์มเป็นคำสั่งหนึ่งในธุรกรรมเดียวกัน จึงไม่ถูกหักถ้าการโอนไม่สำเร็จ
ผู้ส่งกับผู้รับซ้อนทับกันได้ไหม?
ได้ กระเป๋าเงินหนึ่งใบส่งในแถวหนึ่งและรับในอีกแถวหนึ่งได้ แต่ละแถวเป็นธุรกรรมอิสระ ลำดับระหว่างแถวจึงไม่มีการรับประกัน ถ้าแถวที่ 2 ต้องใช้เงินที่แถวที่ 1 ส่งมา ให้แยกเป็นสองรอบ
ทำไมแถวของฉันถูกติดป้ายว่า rent dust?
เพราะยอดที่เหลือในกระเป๋าเงินผู้ส่งจะตกอยู่ระหว่างศูนย์กับ 0.00065 SOL ให้ส่งยอดทั้งก้อนไปจนกระเป๋าเงินเหลือศูนย์ หรือลดยอดลงจนส่วนที่เหลือสูงกว่าขั้นต่ำ
กระเป๋าเงินที่ส่งเฉพาะโทเคนต้องมี SOL ไหม?
ต้องมี ค่าธรรมเนียมเครือข่ายและค่าธรรมเนียมแพลตฟอร์มจ่ายด้วย SOL เสมอ บวกเงินมัดจำบัญชีโทเคนเมื่อผู้รับต้องใช้ ถึงแม้สิ่งที่ย้ายจะเป็นโทเคนก็ตาม
จำนวนคู่มีเพดานไหม?
ไม่มีเพดานตายตัว จะวางเป็นหลายพันคู่ก็ไม่มีอะไรมากั้น ระบบเซ็นและส่งเป็นชุดละหนึ่งร้อยคู่ แล้วยืนยันเป็นชุดละไม่เกิน 256 รายการ โดยรอผลแต่ละชุดได้นานสุด 90 วินาที รอบที่ยาวจึงใช้เวลาไม่กี่นาที ไม่ใช่ไม่กี่วินาที รอบที่เฝ้าดูได้คือรอบที่แก้ได้ ถ้ารายการยาวมาก แบ่งเป็นหลายรอบเล็ก ๆ จะจัดการง่ายกว่า ในทางปฏิบัติสิ่งที่จำกัดก่อนมักเป็นการเตรียมงาน เพราะกระเป๋าเงินผู้ส่งทุกใบต้องถูกเติมเงินไว้ล่วงหน้า
ตัดสินใจในบรรทัดเดียว
ถ้าตารางมีคอลัมน์ผู้จ่าย รูปแบบที่ต้องใช้คือการโอนหลายกระเป๋าไปหลายกระเป๋า ถ้าทุกแถวออกจากกระเป๋าเงินใบเดียวกัน ให้ใช้เครื่องมือส่งหลายรายการ ซึ่งตั้งค่าครั้งเดียวก็พอ และถ้าแถวหายไปหนึ่งแถว ให้ดูขั้นต่ำของ rent ก่อนจะสรุปว่าเป็นบั๊ก เรื่องขั้นต่ำนี้มีต่อในคำอธิบายข้อผิดพลาดยอดไม่พอสำหรับ rent


