ซีรีส์ Web3 Security: เงินที่ถูกโอนไปยังบล็อคเชนอื่นโดยผิดพลาดสามารถกู้คืนได้หรือไม่?
ในโลกของคริปโต การคลิกผิดพลาดเพียงครั้งเดียวอาจนำไปสู่ "หายนะทางดิจิทัล" ได้ หนึ่งในฝันร้ายที่พบบ่อยที่สุดคือการส่งสินทรัพย์ไปยังบล็อกเชนที่ไม่ถูกต้อง ตัวอย่างเช่น คุณอาจตั้งใจจะส่ง ETH ไปยังที่อยู่บนเครือข่ายทดสอบ Ethereum Sepolia แต่กลับส่งไปยังที่อยู่บนเครือข่ายหลัก Ethereum โดยไม่ตั้งใจ ในกรณีนี้ เป็นไปได้หรือไม่ที่จะกู้คืนเงินที่โอนผิดพลาดจากเครือข่ายหลัก Ethereum การที่สินทรัพย์จะถูกกู้คืนได้หรือไม่นั้นขึ้นอยู่กับประเภทของที่อยู่ผู้รับ บทความนี้จะวิเคราะห์สถานการณ์ต่างๆ
1. สถานการณ์ที่ 1: ที่อยู่ผู้รับเป็น EOA
EOA (บัญชีที่เป็นเจ้าของจากภายนอก) คือสิ่งที่เราเรียกกันทั่วไปว่าที่อยู่กระเป๋าเงินปกติที่ได้รับการควบคุมโดยตรงด้วยคีย์ส่วนตัวหรือวลีช่วยจำ
ข้อกำหนดเบื้องต้นสำหรับการกู้คืนทรัพย์สิน:
- คุณได้โอนสินทรัพย์ของคุณไปยังที่อยู่ EOA แล้ว
- คุณมีคีย์ส่วนตัวหรือวลีช่วยจำสำหรับที่อยู่ EOA เป้าหมายนี้ (โดยปกติแล้วจะเป็นที่อยู่กระเป๋าเงินอื่นของคุณเองหรือที่อยู่ของเพื่อนที่พวกเขายินดีที่จะให้ความร่วมมือ)
- โซ่เป้าหมายเป็นโซ่ที่เข้ากันได้กับ EVM
วิธีการเรียกคืนทรัพย์สิน:
ผู้ถือคีย์ส่วนตัวสำหรับที่อยู่ EOA ที่รับสามารถถอนเงินจากบล็อคเชนเป้าหมายได้โดยตรง
2. สถานการณ์ที่ 2 : ที่อยู่ผู้รับคือสัญญา
นี่เป็นหนึ่งในสถานการณ์ที่สิ้นหวังที่สุด เนื่องจากที่อยู่ของสัญญาอัจฉริยะไม่ได้ถูกสร้างขึ้นโดยคีย์ส่วนตัว จึงไม่มีใครเป็นเจ้าของคีย์ส่วนตัวของสัญญาอัจฉริยะ ดังนั้นจึงไม่สามารถควบคุมสัญญาได้ในลักษณะเดียวกับที่ควบคุม EOA นอกจากนี้ หากสัญญาไม่มีฟังก์ชันการกู้คืนที่เขียนไว้ล่วงหน้าเพื่อจัดการกับ "สินทรัพย์ที่โอนโดยไม่ได้ตั้งใจ" เงินที่โอนโดยไม่ได้ตั้งใจอาจถูกล็อกไว้ในสัญญาอย่างถาวร และไม่มีใครสามารถกู้คืนได้
อย่างไรก็ตาม ในบางกรณี ก็มีความหวังริบหรี่อยู่บ้าง ต่อไป เราจะสร้างสถานการณ์ที่ ETH ถูกล็อกบนเครือข่ายหลัก Ethereum และอธิบายวิธีการกู้เงิน
2.1. บทนำฉาก
โดยสรุป สถานการณ์นี้เกี่ยวข้องกับผู้ใช้ที่ตั้งใจจะเรียกใช้สัญญาบนเครือข่ายทดสอบ Sepolia เพื่อโอน ETH เข้าสู่สัญญาสำหรับการสร้างโทเค็น อย่างไรก็ตาม ระหว่างการเริ่มต้นธุรกรรม มีการเชื่อมต่อที่ไม่ถูกต้องกับเมนเน็ต ส่งผลให้ ETH ถูกล็อกไว้ในสัญญาเมนเน็ต กระบวนการสร้างสถานการณ์เฉพาะมีดังนี้:

1. บนเครือข่ายทดสอบ Ethereum Sepolia ทีมโครงการ (EOA) ได้ปรับใช้สัญญาการใช้งาน สมมติว่าฟังก์ชันหลักของสัญญานี้คือการอนุญาตให้ผู้ใช้ฝาก ETH เพื่อสร้าง AToken ที่เกี่ยวข้อง โดยมีโค้ดคล้ายกับฟังก์ชัน "mintTokens" สมมติว่าที่อยู่การใช้งานคือ A โปรดทราบว่า ไม่มีฟังก์ชันใดใน A ที่อนุญาตให้ถอน ETH ได้โดยตรง

2. บนเครือข่ายทดสอบ Ethereum Sepolia ทีมโครงการ (EOA) ได้ปรับใช้สัญญาโรงงาน ฟังก์ชันของสัญญานี้คือการปรับใช้สัญญาพร็อกซีที่ชี้ไปยังสัญญาการใช้งาน (ดังที่แสดงในฟังก์ชัน "deployProxyByImplementation") โดยใช้สัญญาพร็อกซีขั้นต่ำ (โคลน) โดยอิงจากที่อยู่สัญญาการใช้งานและเกลือ สมมติว่าที่อยู่การใช้งานคือ B ในที่นี้ เราเรียกใช้ฟังก์ชัน "deployProxyByImplementation" โดยส่งที่อยู่สัญญาการใช้งาน A เป็น `_implementation` เพื่อ ปรับใช้สัญญาพร็อกซีที่ชี้ไปยัง A ที่ที่อยู่ C

3. ผู้ใช้ต้องการสร้างโทเคน ATokens บนเครือข่ายทดสอบ Sepolia โดยการโอน ETH ผู้ใช้เริ่มต้นการเรียกใช้งานสัญญาพร็อกซี C โดยปกติสัญญาพร็อกซี C จะเรียกใช้ฟังก์ชัน "mintTokens" ซึ่งใช้งานสัญญา A เพื่อดำเนินการให้เสร็จสมบูรณ์ อย่างไรก็ตาม ระหว่างการเรียกใช้งาน ผู้ใช้เชื่อมต่อกับเครือข่ายหลัก Ethereum อย่างไม่ถูกต้อง ส่งผลให้ผู้ใช้โอน ETH ไปยังที่อยู่ C บนเครือข่ายหลัก Ethereum โดยตรง ณ จุดนี้ จะไม่มีสัญญาใดๆ เกิดขึ้นบนที่อยู่ C บนเครือข่ายหลัก Ethereum และไม่มีใครเป็นเจ้าของคีย์ส่วนตัวของที่อยู่ C ดังนั้น เงินของผู้ใช้จึงถูกล็อกไว้ในที่อยู่ C บนเครือข่ายหลักชั่วคราว
2.2. ประเด็นความรู้ที่สำคัญ
ก่อนที่จะแนะนำแผนการกู้ภัยโดยเฉพาะ เรามาแนะนำจุดความรู้พื้นฐานบางประการที่จำเป็นสำหรับการกู้ภัยกันก่อน
2.2.1. สร้าง & สร้าง2
`create` และ `create2` เป็นสองวิธีทั่วไปในการปรับใช้สัญญาใน Solidity
- เมื่อมีการปรับใช้สัญญาโดยใช้ฟังก์ชัน `สร้าง` ที่อยู่ของสัญญาจะถูกกำหนดโดยที่อยู่ของผู้ริเริ่มธุรกรรมและจำนวนธุรกรรมของบัญชี (nonce) และไม่เกี่ยวข้องกับเนื้อหาของสัญญา
- เมื่อใช้การปรับใช้สัญญาโดยใช้ create2 การคำนวณที่อยู่ของสัญญาจะไม่ขึ้นอยู่กับ nonce ของผู้ริเริ่มธุรกรรมอีกต่อไป แต่จะเกี่ยวข้องกับพารามิเตอร์ทั้งสี่ตัวต่อไปนี้
- 0xff
- ที่อยู่สัญญาสำหรับการสร้างสัญญาใหม่
- ค่าความคลุมเครือ (เกลือ) ที่ใช้เป็นพารามิเตอร์
- ไบต์โค้ดการสร้าง (init_code) ของสัญญาที่จะสร้าง
2.2.2. สัญญาตัวแทนขั้นต่ำ (โคลน)
https://docs.openzeppelin.com/contracts/4.x/api/proxy#โคลน
สัญญาพร็อกซีขั้นต่ำ หรือที่รู้จักกันในชื่อสัญญาโคลน ตั้งอยู่บนแนวคิดของการปรับใช้สัญญาพร็อกซีที่มีต้นทุนต่ำมาก (Gas) ซึ่งชี้ไปยังสัญญาการใช้งานที่กำหนดไว้ ในสัญญาโคลน สัญญาพร็อกซีสามารถปรับใช้ได้โดยใช้เมธอด `create` หรือ `create2` ตัวอย่างเช่น การปรับใช้สัญญาพร็อกซีโดยใช้ฟังก์ชัน `cloneDeterministic` จะใช้เมธอด `create2`
ในฟังก์ชัน "cloneDeterministic" ไบต์โค้ดของสัญญาพร็อกซีที่สร้างขึ้นจะสั้นมาก ในรูปแบบ: "0x363d3d373d3d3d363d73<ที่อยู่สัญญาการใช้งาน>5af43d82803e903d91602b57fd5bf3" ที่อยู่ของสัญญาการใช้งานจะถูกฮาร์ดโค้ดลงในไบต์โค้ดโดยตรง และการเรียกใช้สัญญาพร็อกซีทั้งหมดจะถูกมอบหมายให้กับสัญญาการใช้งาน
ดังที่เห็นได้จากฟังก์ชัน "cloneDeterministic" ฟังก์ชันนี้ใช้เมธอด create2 เพื่อสร้างสัญญาพร็อกซี ที่ อยู่ของสัญญาพร็อกซีที่สร้างขึ้นจะสัมพันธ์กับที่อยู่ของผู้สร้างสัญญา, salt, ที่อยู่ของสัญญาที่นำไปใช้งาน และสตริงไบต์โค้ดคงที่ แต่จะไม่สัมพันธ์กับไบต์โค้ดของสัญญาที่นำไปใช้งาน

2.3. แผนการกู้ภัย
ต่อไป เราจะอธิบายวิธีการกู้คืน ETH ของผู้ใช้ที่อยู่ในที่อยู่ C ของเมนเน็ต แนวคิดหลักคือการนำโค้ดสัญญาไปใช้งานบนที่อยู่ C ของเมนเน็ต Ethereum เพื่อเข้าควบคุมที่อยู่และดึง ETH ออกมา ขั้นตอนเฉพาะมีดังนี้:

1. ปรับใช้สัญญาโรงงานบนเมนเน็ตด้วยแอดเดรส B เดียวกับบนเทสต์เน็ต เหตุผลที่ต้องใช้แอดเดรสสัญญาโรงงานเดียวกันคือ เมื่อเรียกใช้ "cloneDeterministic" เพื่อปรับใช้สัญญาพร็อกซีในภายหลัง การคำนวณแอดเดรสของสัญญาพร็อกซีจะสัมพันธ์กับแอดเดรสสัญญาโรงงาน โดยการตรวจสอบธุรกรรมที่ปรับใช้สัญญาโรงงานบนเทสเน็ต Sepolia จะได้รับค่า nonce ของผู้ปรับใช้ (แอดเดรสโครงการ) ในธุรกรรมนี้ บนเมนเน็ต ให้เลื่อนค่า nonce ของแอดเดรสเจ้าของโครงการ (EOA) ไปที่ค่า nonce ก่อนปรับใช้สัญญาโรงงาน จากนั้นจึงปรับใช้สัญญาโรงงานบนเมนเน็ต เนื่องจากแอดเดรสและ nonce ของผู้ปรับใช้ตรงกับธุรกรรมการปรับใช้บนเทสเน็ต ที่อยู่สัญญาโรงงานที่ปรับใช้บนเมนเน็ตจะเป็น B เช่นกัน
2. ปรับใช้สัญญาการใช้งานบนเมนเน็ตที่แอดเดรส A เดียวกับบนเทสต์เน็ต ดังที่ได้กล่าวไว้ในส่วน #สัญญาพร็อกซีขั้นต่ำ (โคลน)# การปรับใช้สัญญาพร็อกซีโดยใช้ฟังก์ชัน "cloneDeterministic" ของสัญญาโคลนจะคำนวณแอดเดรสสัญญาพร็อกซี แอดเดรสสัญญาพร็อกซีที่คำนวณได้จะขึ้นอยู่กับพารามิเตอร์อินพุต `salt` และแอดเดรสสัญญาการใช้งาน แต่จะไม่ขึ้นอยู่กับไบต์โค้ดของสัญญาการใช้งาน ดังนั้น เราจึงจำเป็นต้องปรับใช้สัญญาเพียงอันเดียวบนแอดเดรส A เนื้อหาเฉพาะของสัญญาจะไม่ส่งผลต่อการคำนวณแอดเดรสสัญญาพร็อกซี จากนั้นเราสามารถปรับใช้สัญญาที่มีฟังก์ชันการสกัด ETH บนแอดเดรส A ได้โดยตรง ดังที่แสดงในโค้ดด้านล่าง
บนเทสต์เน็ตเวิร์ก สัญญาการนำไปใช้งาน A จะถูกนำไปใช้งานโดยที่อยู่ของเจ้าของโครงการ (EOA) ดังนั้น ที่อยู่ของสัญญาการนำไปใช้งาน A จะเกี่ยวข้องกับผู้ริเริ่มธุรกรรมและค่า nonce เท่านั้น ดังนั้น โดยการสังเกตธุรกรรมที่นำสัญญาการนำไปใช้งาน A ไปใช้งานบนเทสต์เน็ตเวิร์ก ค้นหาค่า nonce ที่เกี่ยวข้อง ผลักที่อยู่ของเจ้าของโครงการ (EOA) บนเมนเน็ตไปยังค่า nonce ที่ระบุ แล้วจึงนำสัญญาการนำไปใช้งาน A ไปใช้งาน คุณจะสามารถดำเนินการต่อไปได้

3. ปรับใช้สัญญาพร็อกซีบนเมนเน็ตที่แอดเดรส C เดียวกับเทสต์เน็ต สังเกตธุรกรรมของสัญญาพร็อกซี C ที่ติดตั้งบนเทสต์เน็ต รับข้อมูล salt และเรียกใช้ฟังก์ชัน "deployProxyByImplementation" ของสัญญาโรงงาน B โดยส่งแอดเดรสของสัญญาการติดตั้ง A และ salt เป็นพารามิเตอร์ การดำเนินการนี้จะปรับใช้สัญญาพร็อกซีที่แอดเดรส C บนเมนเน็ต
4. สัญญาพร็อกซีเมนเน็ต C ถูกเรียกใช้เพื่อถอนเงิน ที่ อยู่โครงการ (EOA) เรียกใช้ฟังก์ชันถอนเงินของสัญญาพร็อกซี C ระบุผู้รับเงิน ถอน ETH ที่ถูกอายัดจากสัญญาพร็อกซี C สำเร็จ แล้วส่งคืนให้กับผู้ใช้ที่เกี่ยวข้อง
2.4. สรุป
ตามที่เห็นได้จากแผนการกู้ภัยข้างต้น เงินทุนสามารถกู้คืนได้ก็ต่อเมื่อมีการบรรลุเงื่อนไขหลายประการพร้อมๆ กัน เช่น ไม่มีการใช้ประโยชน์จากค่า nonce ที่เกี่ยวข้องของผู้วางสัญญาบนเชนเป้าหมาย สัญญาดักจับเงินทุนที่มีฟังก์ชันการถอน หรือสามารถวางฟังก์ชันการถอนได้หลายวิธี (สามารถอัปเกรดสัญญาหรือใช้พร็อกซี เช่น โคลน เป็นต้น)
ดังนั้น ทุกคนจึงต้องระมัดระวังอย่างยิ่งในการซื้อขาย โดยตรวจสอบธุรกรรมแต่ละรายการอย่างละเอียดถี่ถ้วนก่อนทำสัญญา ก่อนทำสัญญา คุณสามารถใช้เครื่องมือสแกนช่องโหว่ AI SCAN ของ ZAN เพื่อตรวจสอบความปลอดภัยได้ หากเงินของคุณถูกล็อกโดยไม่ได้ตั้งใจ ไม่ต้องกังวล คุณสามารถติดต่อทีมตรวจสอบความปลอดภัยสัญญาของ ZAN เพื่อขอความช่วยเหลือในการกู้คืนเงินของคุณได้
บทความนี้เขียนโดย Cara ( @Cara6289 ) จาก ZAN Team (บัญชี X @zan_team ) และ AntChain OpenLabs (บัญชี X @AntChainOpenLab )
- 核心观点:误转资产能否找回取决于地址类型。
- 关键要素:
- EOA地址需持有私钥可找回。
- 合约地址无救援函数则永久锁定。
- 特定条件下可通过部署合约救援。
- 市场影响:提升用户操作谨慎性与安全工具需求。
- 时效性标注:长期影响


