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

สมาร์ตคอนแทรกต์ที่อัปเกรดได้

สมาร์ตคอนแทรกต์ที่อัปเกรดได้คงที่อยู่และสถานะของพร็อกซีไว้ขณะผู้มีอำนาจเปลี่ยน implementation ความยืดหยุ่นนี้เพิ่มความเสี่ยงด้าน storage การเริ่มต้น ธรรมาภิบาล และการติดตาม

อัปเดต

เพื่อการศึกษาเท่านั้น ไม่ใช่คำแนะนำด้านการลงทุนหรือความปลอดภัย สิทธิ์อัปเกรดอาจเปิดทางให้ผู้มีอำนาจเปลี่ยนพฤติกรรมของสัญญาและทำให้เกิดความเสียหาย

คำตอบโดยตรง

สมาร์ตคอนแทรกต์ที่อัปเกรดได้คือระบบที่เปลี่ยนตรรกะจริงได้โดยไม่ต้องย้ายผู้ใช้ไปยังที่อยู่ใหม่หรือทิ้งสถานะเดิม โดยทั่วไปพร็อกซีเก็บสถานะและส่งคำสั่งผ่าน delegatecall ไปยัง implementation การอัปเกรดเปลี่ยน implementation แต่คงที่อยู่ storage และยอดคงเหลือของพร็อกซี

ระบบไม่ได้เขียน bytecode ที่แก้ไขไม่ได้ใหม่ แต่เพิ่มชั้นอ้างอิงทางอ้อม จึงแก้บั๊กและเพิ่มฟังก์ชันได้ ขณะเดียวกันก็สร้างช่องทางพิเศษที่เปลี่ยนการถอน ค่าธรรมเนียม สิทธิ์ หรือบัญชีได้ ต้องประเมินทั้งโค้ดปัจจุบันและกติกาของโค้ดในอนาคต

ไม่ใช่ทุกพร็อกซีจะอัปเกรดได้ โครงการอาจย้ายสถานะไปสัญญาใหม่หรือปิดสิทธิ์อัปเกรดถาวร โครงสร้างและอำนาจบนเชนจริงสำคัญกว่าป้ายบนหน้าจอ

กลไกการทำงาน

พร็อกซีอ่านที่อยู่ implementation แล้วรันโค้ดในบริบท storage ของพร็อกซีด้วย delegatecall ERC-1967 กำหนด slot ของ implementation, Beacon และผู้ดูแล พร็อกซี Transparent แยกคำสั่งผู้ดูแล ส่วน UUPS วางตรรกะอัปเกรดใน implementation ตาม ERC-1822 และ Beacon เดียวอาจเปลี่ยนพร็อกซีหลายตัว

การเรียง ลบ หรือเปลี่ยนชนิดตัวแปร รวมถึงการเปลี่ยน inheritance อาจทำลายสถานะ การเพิ่มตัวแปรท้ายสุด ช่องสำรอง และ storage แบบ namespace ตาม ERC-7201 ช่วยได้ แต่ยังต้องตรวจความเข้ากันได้ทุกเวอร์ชัน

constructor ไม่เริ่มต้น storage ของพร็อกซี จึงต้องเรียก initialize หนึ่งครั้ง ล็อกการเริ่มต้น implementation โดยตรง และจำกัดการย้ายสถานะภายหลัง

ขั้นตอนที่ตรวจสอบได้คือ:

  1. ตรึง source, compiler, dependency, storage layout, ที่อยู่ และ bytecode ที่คาดหมายของทั้งสอง implementation
  2. ตรวจส่วนต่าง ความเข้ากันได้ การเริ่มต้นหรือย้ายสถานะ สิทธิ์ dependency และสมมติฐาน rollback พร้อมทดสอบธุรกรรมทั้งหมดบน fork
  3. เปิดเผยข้อเสนอและที่อยู่ แล้วใช้ multisig ธรรมาภิบาล และ timelock ตามที่ประกาศโดยไม่มีทางลับ
  4. หลังดำเนินการ ตรวจ slot ของ implementation หรือ Beacon, event, bytecode, สถานะเริ่มต้น บทบาท และ invariant ณ block ที่บันทึกไว้
  5. เฝ้าดู slot บทบาท และพารามิเตอร์ โดยไม่สมมติว่า rollback ปลอดภัยเสมอ

ตัวอย่าง

พร็อกซีของโปรโตคอลกู้ยืมใช้ implementation A ทีมติดตั้ง B หลังยืนยันว่าเพิ่ม storage ต่อท้ายเท่านั้น เผยแพร่ bytecode และตั้ง timelock 48 ชั่วโมง หลังอัปเกรด ที่อยู่เดิมใช้ B และยอดคงเหลือยังอยู่ในพร็อกซี

ผู้ใช้ควรตรวจว่า slot เปลี่ยนจาก A เป็น B การย้ายทำเพียงครั้งเดียว และบทบาทกับยอดคงเหลือถูกต้อง หากผู้พิทักษ์ข้าม timelock หรือผู้ลงนามแทน B ด้วยโค้ดใดก็ได้ อำนาจนั้นเป็นส่วนหนึ่งของแบบจำลองความไว้วางใจ

ความเสี่ยง

  • การแทนที่ด้วยสิทธิ์พิเศษ: ผู้ดูแล multisig ผู้ว่าการ หรือกุญแจที่รั่วอาจติดตั้งตรรกะอันตราย
  • storage เสียหาย: layout ที่ไม่เข้ากันอาจตีความยอดคงเหลือ เจ้าของ mapping หรือบัญชีผิด
  • การเริ่มต้นผิด: initializer ที่ขาด ซ้ำ หรือเปิดเผยอาจโอนอำนาจควบคุม
  • ความล้มเหลวเฉพาะรูปแบบ: Transparent, UUPS, Beacon และพร็อกซีเฉพาะพังต่างกัน
  • ธรรมาภิบาลฉากหน้า: อาจมีทางฉุกเฉิน เวลาสั้น อำนาจโหวตรวมศูนย์ หรือผู้ลงนามอ่อนแอ
  • การย้ายหรือ rollback ไม่ปลอดภัย: สถานะอาจเปลี่ยนย้อนกลับไม่ได้
  • ช่องว่างการยืนยัน: source ที่ยืนยันแล้วไม่พิสูจน์เป้าหมายพร็อกซี ผู้ดูแล หรือสถานะเริ่มต้น
  • ความเสี่ยงการติดตาม: บริการอาจตาม implementation เก่าหรือพลาดการเปลี่ยน Beacon

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

  • “สัญญาที่ที่อยู่นี้แก้ไม่ได้” bytecode ของพร็อกซีอาจคงที่ แต่ slot implementation หรือ Beacon เปลี่ยนพฤติกรรมได้
  • “multisig ทำให้การอัปเกรดกระจายศูนย์” ขึ้นกับความเป็นอิสระ เกณฑ์ การปฏิบัติงาน และกติกาเปลี่ยนผู้ลงนาม
  • “timelock ป้องกันการอัปเกรดอันตราย” เพียงให้เวลาสังเกตและออก ไม่ได้ทำให้โค้ดปลอดภัย
  • “ผ่านการตรวจ storage แปลว่าปลอดภัย” ไม่ครอบคลุมตรรกะ สิทธิ์ oracle การย้าย และเศรษฐศาสตร์
  • “สละสิทธิ์อัปเกรดแล้วไม่มีการควบคุมเสมอ” ต้องตรวจผู้ดูแล Beacon ผู้ว่าการ UUPS และเส้นทางอื่นบนเชน

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

แหล่งข้อมูล

การนำทาง

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