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

สัญญาพร็อกซี

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

อัปเดต

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

คำตอบโดยตรง

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

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

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

วิธีการทำงาน

เมื่อการเรียกมาถึงพร็อกซี เส้นทาง fallback จะคัดลอกหรือส่งต่อข้อมูลการเรียกไปยังอิมพลีเมนเทชัน เมื่อใช้ delegatecall ค่า address(this) คือพร็อกซี การอ่านและเขียนพื้นที่จัดเก็บมีผลต่อพร็อกซี และค่าเดิมของ msg.sender กับ msg.value จะยังคงอยู่ จากนั้นพร็อกซีจะส่งคืนข้อมูลจากอิมพลีเมนเทชันหรือย้อนกลับพร้อมกัน

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

การออกแบบที่พบบ่อยวางอำนาจอัปเกรดไว้ต่างตำแหน่งกัน:

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

ตัวอย่าง

สมมติว่าพร็อกซีของห้องนิรภัยเก็บยอดคงเหลือของผู้ใช้และมอบหมายงานให้อิมพลีเมนเทชัน A ผู้ใช้ฝากผ่านที่อยู่พร็อกซี และโค้ดของอิมพลีเมนเทชัน A จะอัปเดตบันทึกยอดคงเหลือในพื้นที่จัดเก็บของพร็อกซี

ต่อมา ฝ่ายกำกับดูแลเปลี่ยนสล็อตอิมพลีเมนเทชัน ERC-1967 เป็นอิมพลีเมนเทชัน B ที่อยู่พร็อกซีและยอดคงเหลือที่บันทึกไว้ไม่ย้าย แต่การเรียกในอนาคตจะทำงานด้วยโค้ดของ B หาก B รักษาเค้าโครงพื้นที่จัดเก็บและใช้กฎตามที่ตั้งใจ ผู้ใช้จะเห็นพฤติกรรมใหม่ที่ที่อยู่เดิม

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

ความเสี่ยง

  • คีย์อัปเกรดถูกยึดครอง: ผู้ดูแลระบบ กระเป๋าหลายลายเซ็น หรือกระบวนการกำกับดูแลอาจติดตั้งโค้ดที่เป็นอันตรายหรือมีข้อบกพร่อง
  • เค้าโครงพื้นที่จัดเก็บไม่เข้ากัน: การเปลี่ยนลำดับ ชนิด หรือการสืบทอดของตัวแปรอาจทำให้โค้ดใหม่อ่านผิดหรือเขียนทับสถานะเดิม
  • การเริ่มต้นล้มเหลว: คอนสตรักเตอร์ไม่ได้เริ่มต้นพื้นที่จัดเก็บของพร็อกซี การป้องกันที่ขาดหายหรือเรียกซ้ำได้อาจเปิดให้อีกบัญชีเข้าครอบครองบทบาทพิเศษ
  • เส้นทางการเรียกที่ไม่คาดคิด: การชนกันของฟังก์ชันซีเล็กเตอร์ เส้นทางเฉพาะผู้ดูแลระบบ หรือบีคอนที่ไม่คาดคิดอาจทำให้เส้นทางที่ทำงานต่างจากอินเทอร์เฟซที่เห็น
  • ผลกระทบกว้างจากการอัปเกรดร่วม: การตัดสินใจเกี่ยวกับบีคอนหรืออิมพลีเมนเทชันครั้งเดียวอาจเปลี่ยนอินสแตนซ์สัญญาหลายรายการพร้อมกัน

ก่อนฝากสินทรัพย์หรือให้สิทธิ์อนุมัติ ให้ค้นหาอิมพลีเมนเทชันหรือบีคอนปัจจุบันบนเชน ระบุผู้มีอำนาจอัปเกรดและ timelock ตรวจสอบซอร์สโค้ดที่ยืนยันแล้วและความเข้ากันได้ของพื้นที่จัดเก็บ และดูอีเวนต์ล่าสุด Upgraded, BeaconUpgraded และ AdminChanged เมื่อเกี่ยวข้อง ยังต้องติดตามต่อหลังการตรวจสอบครั้งแรก เพราะเส้นทางการทำงานสามารถเปลี่ยนได้

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

  • “พร็อกซีไม่ได้เก็บสถานะที่มีความหมาย” เมื่อใช้ delegatecall สถานะของแอปพลิเคชันและโดยมากรวมถึงสินทรัพย์เป็นของพร็อกซี แม้ว่าลอจิกจะมาจากอีกที่อยู่หนึ่ง
  • “อิมพลีเมนเทชันที่ยืนยันแล้วทำให้ระบบไม่ต้องอาศัยความไว้วางใจ” คีย์อัปเกรด การกำกับดูแล บีคอน การเริ่มต้น และอิมพลีเมนเทชันในอนาคตยังเป็นส่วนหนึ่งของแบบจำลองความไว้วางใจ
  • “พร็อกซีทุกตัวอัปเกรดได้” โคลนและพร็อกซีแบบคงที่อื่นอาจมอบหมายงานอย่างถาวร ความสามารถในการอัปเกรดขึ้นอยู่กับการออกแบบและโค้ดอนุญาตเฉพาะ

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

แหล่งที่มา

การนำทาง

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