ข้ามไปยังเนื้อหา

วิธีกู้คืนช่องว่าง nonce ในวอลเล็ต

ค้นหา nonce แรกที่ขาดหายของบัญชี EVM ตัดสินใจว่าควรแทนที่หรือยกเลิก และป้องกันธุรกรรมค้างคิวระหว่างวอลเล็ตหรืออุปกรณ์

อัปเดต

เพื่อการศึกษาเท่านั้น ไม่ใช่คำแนะนำด้านการลงทุน การลงทุนอาจทำให้เกิดการสูญเสีย

คำตอบโดยตรง

บนเชนที่รองรับ EVM ธุรกรรมจากบัญชีที่บุคคลภายนอกเป็นเจ้าของ (EOA) จะทำงานตามลำดับ nonce หาก nonce ถัดไปที่ควรทำงานขาดหายหรือติดค้าง ธุรกรรมที่มี nonce สูงกว่าอาจยังอยู่ในคิวแม้ตั้งค่าธรรมเนียมสูง การกู้คืนต้องจัดการ nonce ต่ำสุดที่ยังไม่คลี่คลายก่อน โดยยืนยันเชนและผู้ส่ง เปรียบเทียบข้อมูล nonce ที่ยืนยันแล้วกับที่รอดำเนินการ แล้วแทนที่ธุรกรรมเดิมหรือส่งธุรกรรมยกเลิกที่ใช้ nonce เดียวกันมาแข่งขัน

การยกเลิกไม่ใช่การย้อนกลับในระดับโปรโตคอล โดยทั่วไปคือการโอน 0 ETH จากบัญชีกลับมาหาตัวเองโดยใช้ nonce เดียวกัน ธุรกรรมที่ถูกต้องซึ่งเข้าอยู่ในบล็อกก่อนจะชนะ และไม่สามารถใช้วิธีนี้ยกเลิกธุรกรรมที่ยืนยันแล้วได้

ขั้นตอนนี้ใช้กับธุรกรรม EOA ทั่วไปบน EVM สมาร์ตแอ็กเคานต์หรือการดำเนินการแบบ account abstraction อาจใช้รูปแบบ nonce ที่สัญญากำหนด ส่วนเครือข่าย UTXO ใช้โมเดลธุรกรรมต่างออกไป

เหตุใดช่องว่าง nonce จึงกีดขวางคิว

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

คิวไม่ได้เป็น mempool กลางเพียงแห่งเดียวที่มีอำนาจตัดสิน โหนด RPC แต่ละแห่งมองเห็นและเก็บชุดย่อยของธุรกรรม pending ต่างกัน ธุรกรรมอาจปรากฏในวอลเล็ตแต่ไม่อยู่ใน explorer หรือมองเห็นผ่าน RPC หนึ่งแต่ไม่เห็นผ่านอีกแห่ง ซึ่งอาจหมายความว่าไม่เคยกระจายธุรกรรม โหนดลบออกจาก pool หรือยังแพร่ไปไม่ถึงบริการที่สอบถาม

eth_getTransactionCount เมื่อใช้ latest จะคืนจำนวนตามสถานะบล็อกล่าสุด สำหรับ EOA ให้ตีความว่าเป็น nonce ถัดจากธุรกรรมที่ยืนยันแล้ว ส่วน pending จะสอบถามมุมมองสถานะรอดำเนินการของโหนดเดียว ความต่างบ่งชี้ว่าโหนดนั้นรู้จักธุรกรรม pending แต่ไม่ได้พิสูจน์ว่าโหนดสาธารณะทุกแห่งรู้จักด้วย

วินิจฉัยก่อนลงนาม

  1. หยุดส่งจากที่อยู่ที่ได้รับผลกระทบบนอุปกรณ์และแอปพลิเคชันทั้งหมด บันทึกเครือข่าย chain ID ที่อยู่ผู้ส่ง แฮชธุรกรรม nonces ผู้รับ มูลค่า calldata gas limits และช่องค่าธรรมเนียม
  2. ตรวจว่าวอลเล็ต explorer และ RPC อ้างถึงเชนและผู้ส่งเดียวกัน Nonce เป็นของบัญชีบนเชนหนึ่ง ไม่ใช่ของการติดตั้งวอลเล็ต
  3. สอบถาม eth_getTransactionCount ทั้งแบบ latest และ pending ควรใช้ผู้ให้บริการ RPC อิสระสองราย มองผลต่างว่าเป็นหลักฐานของมุมมอง mempool ที่ต่างกัน ไม่ใช่ข้อพิสูจน์ว่าสถานะ on-chain ขัดแย้งกัน
  4. ตรวจธุรกรรมของผู้ส่งตาม nonce หากใช้ได้ API ของ transaction pool ของโหนดจะแยกรายการ pending ที่ทำงานได้จากรายการ queued สำหรับอนาคต ผู้ให้บริการ RPC สาธารณะมักปิด API ที่ไม่ใช่มาตรฐานนี้
  5. เริ่มจากค่า latest แล้วหา nonce แรกที่ไม่มีธุรกรรมยืนยัน ตรวจว่าธุรกรรมที่ทราบใน nonce นั้นยังมองเห็น ถูกลบ หรือสร้างไว้เฉพาะในเครื่อง

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

แทนที่หรือยกเลิก nonce แรกที่ยังไม่คลี่คลาย

หากต้องการคงการดำเนินการเดิม: ใช้ฟังก์ชันเร่งความเร็วของวอลเล็ต หรือกระจายธุรกรรมอีกครั้งโดยใช้ผู้ส่ง nonce ผู้รับ มูลค่า และ calldata เดิม แต่ตั้งค่าธรรมเนียมให้แข่งขันได้ ตรวจทุกช่องก่อนลงนาม เพราะการเปลี่ยน payload ทำให้เป็นอีกการดำเนินการหนึ่ง

หากต้องการละทิ้งการดำเนินการเดิม: ขณะที่ยังไม่ยืนยัน ให้ส่ง 0 ETH จากที่อยู่นั้นกลับมาหาตัวเองโดยใช้ nonce เดียวกันและค่าธรรมเนียมที่แข่งขันได้ วิธีนี้เพียงพยายามให้ธุรกรรมโอนหาตัวเองชนะ ธุรกรรมเดิมยังอาจยืนยันก่อน จึงอย่าถือว่ายกเลิกสำเร็จจนกว่าธุรกรรมแทนที่จะมีใบเสร็จและธุรกรรมเดิมยังไม่ยืนยัน

การรับธุรกรรมแทนที่เป็นนโยบายของโหนด ไม่ใช่เปอร์เซ็นต์สากล สำหรับธุรกรรม EIP-1559 อาจต้องเพิ่มทั้ง maxPriorityFeePerGas และ maxFeePerGas และ maxFeePerGas ต้องยังใช้ได้กับ base fee ปัจจุบัน ค่าประมาณของวอลเล็ตและกฎของไคลเอนต์ต่างกัน ข้อผิดพลาด replacement transaction underpriced หมายถึงโหนดผู้รับไม่ยอมรับธุรกรรมแทนที่ตามนโยบายปัจจุบัน

เมื่อ nonce ต่ำสุดยืนยันแล้ว ให้ตรวจใบเสร็จ latest ยอดคงเหลือ และธุรกรรม nonce ที่สูงกว่าทุกธุรกรรมอีกครั้ง ธุรกรรมในคิวอาจทำงานได้ทันที ส่วนธุรกรรมที่โหนดที่เกี่ยวข้องทั้งหมดลบแล้วอาจต้องตั้งใจกระจายใหม่ อย่าส่งซ้ำโดยไม่ตรวจสอบ ต้องยืนยันก่อนว่าสำเนาก่อนหน้าไม่ได้เข้าอยู่ในบล็อก

ตัวอย่าง

ที่อยู่หนึ่งมีธุรกรรมยืนยันถึง nonce 24 ดังนั้น latest คือ 25 RPC หนึ่งรายงาน pending เป็น 25 แต่วอลเล็ตแสดง nonce 26 และ nonce 27 อยู่ในคิว ไม่มีผู้ให้บริการรายใดพบธุรกรรมที่กระจายไว้ใน nonce 25

เจ้าของตรวจเชน ผู้ส่ง และ payloads ที่บันทึกไว้ก่อน หากมีธุรกรรมที่ต้องการใน nonce 25 ให้สร้างการดำเนินการนั้นใหม่และกระจายด้วย nonce 25 โดยใช้ค่าธรรมเนียมปัจจุบัน หากไม่มี อาจส่ง 0 ETH หาตัวเองที่ nonce 25 การเพิ่มเฉพาะค่าธรรมเนียมของ nonce 27 ปิดช่องว่างไม่ได้

เมื่อ nonce 25 อยู่ในบล็อกแล้ว เจ้าของตรวจใบเสร็จก่อนแตะ nonce 26 หรือ nonce 27 จากนั้นตรวจแต่ละธุรกรรมแยกกัน เพราะอาจถูกลบไปแล้วหรืออาจทำงานอย่างรวดเร็วหลังปิดช่องว่าง

ความเสี่ยงและเงื่อนไขที่ควรหยุด

  • ธุรกรรมแทนที่อาจแข่งกับธุรกรรมเดิม จนกว่าจะมีหลักฐาน on-chain ให้ถือว่าผู้รับ มูลค่า และการเรียกสัญญาเดิมยังอาจทำงานได้
  • ยืนยันที่อยู่ผู้ส่งเต็ม chain ID nonce และ calldata บนหน้าจอที่เชื่อถือได้ มัลแวร์หรือเว็บไซต์ “กู้คืน” ที่ไม่น่าเชื่อถืออาจสับเปลี่ยนเป็นการโอนหรือการอนุมัติ
  • เก็บสกุลเงินดั้งเดิมให้เพียงพอสำหรับค่าธรรมเนียมแทนที่ ธุรกรรมที่เข้าอยู่ในบล็อกจะเสีย gas แม้การเรียกสัญญาจะ revert ภายหลัง
  • อย่าเปิดเผย seed phrase หรือ private key เพื่อกู้ช่องว่าง nonce RPC explorer หรือเจ้าหน้าที่สนับสนุนที่ถูกต้องไม่จำเป็นต้องใช้
  • หากที่อยู่ถูกบุกรุก การส่งธุรกรรมแทนที่สาธารณะซ้ำอาจกลายเป็นการแข่งขันค่าธรรมเนียมกับผู้โจมตี หยุดใช้อุปกรณ์ที่ถูกบุกรุกและทำตามแผนรับมือเหตุการณ์
  • หากผู้ให้บริการ RPC ให้ผลต่างกัน ไม่ทราบผู้รับเดิม สร้าง payload ใหม่ไม่ได้ หรือมีการโต้ตอบสัญญามูลค่าสูง ให้หยุดและขอความช่วยเหลือจากผู้เชี่ยวชาญก่อนลงนาม

สำหรับการใช้ซ้ำข้ามอุปกรณ์หรือผู้ลงนามอัตโนมัติ ให้ป้องกันการเกิดซ้ำด้วยตัวจัดสรร nonce เดียวต่อบัญชีและเชน ลงนามตามลำดับ เก็บบันทึก nonces และแฮชที่จองไว้อย่างถาวร และกระทบยอดกับทั้งสถานะยืนยันและ pending pool ของโหนดผู้กระจาย การรีเซ็ตประวัติกิจกรรมในเครื่องของวอลเล็ตไม่เปลี่ยนสถานะ on-chain หรือ mempools ของโหนดอื่น

ความเข้าใจผิดที่พบบ่อย

  • “ค่าธรรมเนียมสูงขึ้นใน nonce 27 ทำให้ข้าม nonce 25 ได้” อาจเพิ่มลำดับความสำคัญหลัง nonce ก่อนหน้าทำงานได้เท่านั้น แต่ไม่ซ่อมช่องว่าง
  • “หาไม่พบหมายถึงยกเลิกแล้ว” โหนดหนึ่งอาจลบธุรกรรม แต่อีกโหนด builder หรือคู่สัญญายังมีอยู่ ธุรกรรมที่ลงนามแล้วสามารถถูกกระจายซ้ำ
  • “การโอน 0 ETH หาตัวเองย้อนธุรกรรมเดิม” เพียงแข่งขันใน nonce เดียวกันและไม่มีผลหลังธุรกรรมเดิมยืนยัน
  • pending คือคำตอบสุดท้ายของเครือข่าย” เป็นมุมมองสถานะรอดำเนินการของโหนดที่สอบถามและอาจต่างกันในแต่ละผู้ให้บริการ

หัวข้อที่เกี่ยวข้อง

แหล่งข้อมูล

การนำทาง

ค้นหาในวิกิ...