การทำลายการเปลี่ยนแปลงไม่ได้ของบล็อกเชน: โมเดลพร็อกซีสามารถบรรลุการอัปเกรดสัญญาอัจฉริยะได้อย่างไร

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

บทความนี้จะให้ภาพรวมของประเภทของสัญญาพร็อกซี เหตุการณ์และคำแนะนำด้านความปลอดภัยที่เกี่ยวข้อง และแนวทางปฏิบัติที่ดีที่สุดสำหรับการใช้สัญญาพร็อกซี

ข้อมูลเบื้องต้นเกี่ยวกับสัญญาที่อัปเกรดได้และโหมดพร็อกซี

เราทุกคนทราบดีถึงคุณสมบัติที่ "ไม่สามารถแก้ไขได้" ของบล็อกเชน และรหัสสัญญาอัจฉริยะจะไม่สามารถแก้ไขได้หลังจากปรับใช้บนบล็อกเชน

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

เพื่อแก้ปัญหานี้ คุณสามารถใช้โหมดพร็อกซี

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

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

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

โหมดพร็อกซีทั่วไปอีกสามโหมด ได้แก่ พร็อกซีโปร่งใส พร็อกซี UUPS และพร็อกซีบีคอน

พร็อกซี่โปร่งใส

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

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

พร็อกซี UUPS

ในโหมด UUPS (Universal Upgradeable Proxy Standard) ฟังก์ชันอัปเกรดสัญญาจะถูกนำไปใช้ในสัญญาลอจิก เนื่องจากกลไกการอัปเกรดถูกจัดเก็บไว้ในสัญญาลอจิก เวอร์ชันที่อัปเกรดสามารถลบลอจิกที่เกี่ยวข้องกับการอัปเกรดเพื่อห้ามการอัปเกรดในอนาคต ในโหมดนี้ การเรียกทั้งหมดไปยังสัญญาพร็อกซีจะถูกส่งต่อไปยังสัญญาการใช้งานลอจิก

บีคอนพร็อกซี

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

การใช้พร็อกซีในทางที่ผิดและเหตุการณ์ด้านความปลอดภัย

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

** การเปิดเผยคีย์ที่จัดการโดยพร็อกซี **

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

เมื่อวันที่ 5 มีนาคม 2021 PAID Network ประสบกับการโจมตีแบบ "minting" ซึ่งเกิดจากการจัดการคีย์ส่วนตัวที่ไม่ดี เครือข่าย PAID ถูกโจมตีโดยผู้โจมตีที่ขโมยคีย์ส่วนตัวของผู้ดูแลระบบพร็อกซีและเรียกใช้กลไกการอัปเกรดเพื่อเปลี่ยนสัญญาลอจิก

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

** การใช้งานพร็อกซี UUPS ที่ไม่ได้เตรียมใช้งาน **

สำหรับโหมดพร็อกซี UUPS ในระหว่างการเริ่มต้นของสัญญาพร็อกซี พารามิเตอร์เริ่มต้นจะถูกส่งผ่านไปยังสัญญาพร็อกซีโดยผู้เรียก จากนั้นสัญญาพร็อกซีจะเรียกใช้ฟังก์ชัน initialize() ในสัญญาลอจิกเพื่อให้เกิดการเริ่มต้น

ฟังก์ชัน initialize() มักจะป้องกันด้วยตัวดัดแปลง "initializer" เพื่อจำกัดฟังก์ชันให้เรียกใช้เพียงครั้งเดียว หลังจากเรียกใช้ฟังก์ชัน initialize() จากมุมมองของสัญญาพร็อกซี สัญญาลอจิกจะเริ่มต้น

อย่างไรก็ตาม จากมุมมองของสัญญาลอจิก สัญญาลอจิกจะไม่ถูกเตรียมใช้งาน เนื่องจาก initialize() ไม่ได้ถูกเรียกโดยตรงในสัญญาลอจิก เนื่องจากตัวสัญญาลอจิกไม่ได้เริ่มต้น ทุกคนสามารถเรียกใช้ฟังก์ชัน initialize() เพื่อเริ่มต้น ตั้งค่าตัวแปรสถานะเป็นค่าที่เป็นอันตราย และอาจเข้าควบคุมสัญญาลอจิก

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

กรณี

① Parity Multisig Freeze: สัญญาตรรกะไม่ได้เริ่มต้น ผู้โจมตีเรียกการเริ่มต้นของกระเป๋าเงินจำนวนมากและล็อคอีเทอร์ในสัญญาโดยเรียก selfdestruct()

② Harvest Finance, Teller, KeeperDAO และ Rivermen ล้วนใช้สัญญาตรรกะที่ไม่ได้กำหนดค่าเริ่มต้น ซึ่งจะทำให้ผู้โจมตีสามารถตั้งค่าพารามิเตอร์เริ่มต้นของสัญญาได้ตามอำเภอใจ และดำเนินการ selfdestruct() ระหว่าง delegatecall() เพื่อทำลายสัญญาตัวแทน

ความขัดแย้งในการจัดเก็บ

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

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

สัญญาพร็อกซีที่จัดทำโดยไลบรารี OpenZeppelin ไม่ได้ประกาศตัวแปรสถานะในสัญญา แต่ตามมาตรฐาน EIP 1967 จะบันทึกค่าที่ต้องจัดเก็บ (เช่น ที่อยู่การจัดการ) ในช่องจัดเก็บเฉพาะเพื่อป้องกันความขัดแย้ง

กรณี

เมื่อวันที่ 23 กรกฎาคม 2022 ตามเวลาปักกิ่ง Audius แพลตฟอร์มเพลงแบบกระจายศูนย์ถูกแฮ็ก เหตุการณ์นี้เกิดจากการนำตรรกะใหม่ในสัญญาพร็อกซีมาใช้ ส่งผลให้เกิดความขัดแย้งในการจัดเก็บ

สัญญาพร็อกซีประกาศตัวแปรสถานะที่อยู่ proxyAdmin และค่าของมันจะอ่านไม่ถูกต้องเมื่อมีการดำเนินการรหัสสัญญาลอจิก

ค่าของ proxyAdmin ที่ปรับแต่งโดยฝ่ายโครงการนั้นถูกมองว่าเป็นค่าของ initialized และ initialized ดังนั้นตัวแก้ไข initializer จึงส่งคืนผลลัพธ์ที่ไม่ถูกต้อง ซึ่งทำให้ผู้โจมตีสามารถเรียกฟังก์ชัน initialize() อีกครั้ง และให้สิทธิ์ตัวเองในการจัดการ สัญญา. จากนั้นผู้โจมตีเปลี่ยนพารามิเตอร์การลงคะแนนและส่งข้อเสนอที่เป็นอันตรายเพื่อขโมยทรัพย์สินของ Audius

โทร delegatecall() ในสัญญาลอจิกหรือสัญญาที่ไม่น่าเชื่อถือ

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

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

กรณี

การโจมตี Pickle Finance, Furucombo และ dYdX

ในเหตุการณ์เหล่านี้ สัญญาที่มีช่องโหว่ได้รับการอนุมัติโดยโทเค็นผู้ใช้ และมีการเรียก ()/delegatecall() ในสัญญาที่ผู้ใช้ให้ไว้เพื่อโทรไปยังที่อยู่และข้อมูลของสัญญา ผู้โจมตีจะสามารถโทรหา สัญญาฟังก์ชั่น TransferFrom() เพื่อถอนยอดคงเหลือของผู้ใช้ ในช่วงเหตุการณ์ dYdX dYdX ได้ทำการโจมตีแบบหมวกขาวเพื่อปกป้องเงินทุน

ปฏิบัติที่ดีที่สุด

โดยทั่วไป

(1) ใช้โหมดพร็อกซีเมื่อจำเป็นเท่านั้น

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

(2) อย่าแก้ไขไลบรารีพร็อกซี

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

ประเด็นสำคัญของการดำเนินการและบริหารสัญญาตัวแทน

(1) เริ่มต้นสัญญาตรรกะ

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

(2) ตรวจสอบความปลอดภัยของบัญชีการจัดการตัวแทน

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

(3) ใช้บัญชีแยกต่างหากสำหรับการจัดการพร็อกซีที่โปร่งใส

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

เกี่ยวข้องกับการจัดเก็บสัญญาพร็อกซี

(1) โปรดใช้ความระมัดระวังเมื่อประกาศตัวแปรสถานะในสัญญาตัวแทน

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

(2) รักษาลำดับการประกาศตัวแปรและประเภทของสัญญาลอจิก

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

(3) รวมช่องว่างในการจัดเก็บในสัญญาพื้นฐาน

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

(4) อย่ากำหนดค่าของตัวแปรสถานะในตัวสร้างหรือกระบวนการประกาศ

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

สัญญารับมรดก

(1) สัญญาที่อัปเกรดได้จะสืบทอดมาจากสัญญาที่อัปเกรดได้อื่นๆ เท่านั้น

สัญญาที่อัปเกรดได้จะมีโครงสร้างที่แตกต่างจากสัญญาที่อัปเกรดไม่ได้ ตัวอย่างเช่น ตัวสร้างเข้ากันไม่ได้กับการเปลี่ยนสถานะตัวแทน จะใช้ฟังก์ชัน initialize() เพื่อตั้งค่าตัวแปรสถานะ

สัญญาใด ๆ ที่สืบทอดมาจากสัญญาอื่นจำเป็นต้องใช้ฟังก์ชัน initialize() ของสัญญาที่สืบทอดมาเพื่อกำหนดตัวแปรที่เกี่ยวข้อง เมื่อใช้ไลบรารี OpenZeppelin หรือเขียนโค้ดของคุณเอง ตรวจสอบให้แน่ใจว่าสัญญาที่อัปเกรดได้จะรับช่วงต่อสัญญาที่อัปเกรดได้อื่นๆ เท่านั้น

(2) อย่ายกตัวอย่างสัญญาใหม่ในสัญญาตรรกะ

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

(3) ความเสี่ยงในการเริ่มต้นสัญญาหลัก

เมื่อเริ่มต้นสัญญาหลัก ฟังก์ชัน __{ContractName}_init จะเริ่มต้นสัญญาหลัก การเรียก __{ContractName}_init หลายครั้งอาจส่งผลให้เกิดการเริ่มต้นครั้งที่สองของสัญญาหลัก โปรดทราบว่า __{ContractName}_init_unchained() จะเริ่มต้นเฉพาะพารามิเตอร์ของ {ContractName} เท่านั้น และจะไม่เรียกใช้ตัวเริ่มต้นของสัญญาหลัก

อย่างไรก็ตาม นี่ไม่ใช่แนวทางปฏิบัติที่แนะนำ เนื่องจากสัญญาหลักทั้งหมดจำเป็นต้องเริ่มต้น และการไม่เริ่มต้นสัญญาที่จำเป็นจะทำให้เกิดปัญหาในการดำเนินการในอนาคต

** การดำเนินการตามสัญญาตรรกะ **

หลีกเลี่ยง selfdestruct() หรือ selegatecall()/call() กับสัญญาที่ไม่น่าเชื่อถือ

หากมี selfdestruct() หรือ delegatecall() ในสัญญา ผู้โจมตีอาจใช้ฟังก์ชันเหล่านี้เพื่อทำลายการนำตรรกะไปใช้หรือดำเนินการตามตรรกะที่กำหนดเอง นักพัฒนาควรตรวจสอบข้อมูลที่ผู้ใช้ป้อนและไม่อนุญาตให้สัญญาดำเนินการเรียกผู้รับมอบสิทธิ์/การโทรไปยังสัญญาที่ไม่น่าเชื่อถือ นอกจากนี้ ไม่แนะนำให้ใช้ delegatecall() ในสัญญาแบบลอจิก เนื่องจากการจัดการเลย์เอาต์ที่เก็บข้อมูลในสายผู้รับมอบสิทธิ์ของสัญญาหลายฉบับจะยุ่งยาก

เขียนไว้ตอนท้าย

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

โดยรวมแล้ว แนวทางปฏิบัติที่ดีที่สุดคือการใช้โซลูชันที่เชื่อถือได้และผ่านการทดสอบอย่างครอบคลุม เนื่องจากโหมด Transparent, UUPS และ Beacon Proxy แต่ละโหมดมีกลไกการอัปเกรดที่พิสูจน์แล้วสำหรับกรณีการใช้งานที่เกี่ยวข้อง นอกจากนี้ บทบาทที่มีสิทธิพิเศษสำหรับเอเจนต์ที่ยกระดับควรได้รับการจัดการอย่างปลอดภัยด้วย เพื่อป้องกันผู้โจมตีจากการเปลี่ยนแปลงตรรกะของเอเจนต์

นอกจากนี้ สัญญาการใช้งานลอจิกควรระมัดระวังที่จะไม่ใช้ delegatecall() ซึ่งสามารถป้องกันผู้โจมตีจากการดำเนินการโค้ดที่เป็นอันตรายบางอย่าง เช่น selfdestruct()

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

ดูต้นฉบับ
เนื้อหานี้มีสำหรับการอ้างอิงเท่านั้น ไม่ใช่การชักชวนหรือข้อเสนอ ไม่มีคำแนะนำด้านการลงทุน ภาษี หรือกฎหมาย ดูข้อจำกัดความรับผิดชอบสำหรับการเปิดเผยความเสี่ยงเพิ่มเติม
  • รางวัล
  • แสดงความคิดเห็น
  • แชร์
แสดงความคิดเห็น
0/400
ไม่มีความคิดเห็น
  • ปักหมุด