BTC
ETH
HTX
SOL
BNB
ดูตลาด
简中
繁中
English
日本語
한국어
ภาษาไทย
Tiếng Việt

ไดอารี่การพัฒนาสัญญาสมาร์ทสนิม (6)

BlockSec
特邀专栏作者
2022-03-29 10:35
บทความนี้มีประมาณ 2976 คำ การอ่านทั้งหมดใช้เวลาประมาณ 5 นาที
การโจมตีแบบ Denial of Service หรือที่เรียกว่าการโจมตีแบบ DoS (Denial of Service) การโจมตีประเภทนี้จะทำให้ Smart Contract ไม่
สรุปโดย AI
ขยาย
การโจมตีแบบ Denial of Service หรือที่เรียกว่าการโจมตีแบบ DoS (Denial of Service) การโจมตีประเภทนี้จะทำให้ Smart Contract ไม่

บทความที่เกี่ยวข้อง:

การโจมตีแบบ Denial of Service หรือที่เรียกว่าการโจมตีแบบ DoS (Denial of Service) การโจมตีประเภทนี้จะทำให้ Smart Contract ไม่สามารถใช้งานได้ตามปกติโดยผู้ใช้เป็นระยะเวลาหนึ่ง (แม้จะเป็นการถาวรก็ตาม)

สาเหตุที่ทราบในปัจจุบันสามารถแบ่งออกเป็นสองประเภทต่อไปนี้:

  • ข้อบกพร่องบางประการในตรรกะของสัญญา เช่น ฟังก์ชันสาธารณะ การใช้งานไม่ได้คำนึงถึงความซับซ้อนในการคำนวณ เมื่อผู้ใช้เรียกใช้ฟังก์ชันนี้ ก๊าซที่ใช้จริงจะเกินก๊าซที่กำหนดไว้ในไฟล์การกำหนดค่าบล็อกการกำเนิดเชนสาธารณะ NEAR (genesis_config.json)"max_total_prepaid_gas": 300000000000000` (300TGas) ทำให้การทำธุรกรรมล้มเหลว

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

  • นอกเหนือจากข้อบกพร่องในตรรกะของสัญญาแล้ว สาเหตุของปรากฏการณ์ DoS ยังสามารถนำมาประกอบกับปัจจัยของมนุษย์ได้ ตัวอย่างทั่วไป: เจ้าของสัญญาทำคีย์ส่วนตัวหาย ดังนั้นฟังก์ชันพิเศษที่เรียกใช้ได้ของ only_owner ในสัญญาจึงไม่สามารถดำเนินการได้ เรียกว่าทำให้ค่าสถานะของระบบที่สำคัญบางค่าในสัญญาไม่สามารถอัพเดทได้ทัน ซึ่งอาจทำให้ Project เสียหายมากขึ้น


ชื่อเรื่องรอง

1. วนซ้ำโครงสร้างข้อมูลที่สามารถเปลี่ยนแปลงได้โดยการโทรจากภายนอก

ต่อไปนี้เป็นสัญญาอัจฉริยะอย่างง่ายสำหรับ "เงินปันผล" สำหรับผู้ใช้ที่ลงทะเบียนในสัญญา และข้อมูลสถานะมีดังนี้:

ผู้ใช้สามารถลงทะเบียนและเริ่มต้นได้โดยการเรียกใช้ฟังก์ชัน pub fn register_account()

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

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

ต่อไปนี้คือผลการทดสอบของสัญญาใน NEAR Localnet จริง

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

วิธีแก้ไขที่แนะนำ:

เนื่องจากข้อจำกัดของ Gas Limit จึงไม่แนะนำให้สำรวจโครงสร้างข้อมูลขนาดใหญ่ในระหว่างการดำเนินการตามวิธีสัญญา (ผู้ใช้ภายนอกสามารถจัดการขนาดของโครงสร้างข้อมูลได้) หากคุณต้องการสำรวจจริงๆ คุณต้องจำกัดขนาดของโครงสร้างข้อมูลด้วย และตรวจสอบให้แน่ใจว่าเมื่อขนาดของโครงสร้างข้อมูลถึงค่าสูงสุด จะไม่แตะขีดจำกัด Gas Limit

ชื่อเรื่องรอง

2. การพึ่งพาของรัฐระหว่างสัญญาข้ามนำไปสู่การปิดกั้นสัญญา

เมื่อสัญญาทำการโทรข้ามสัญญา อาจขึ้นอยู่กับสถานะของสัญญาภายนอก การพึ่งพาที่ไม่เหมาะสมจะทำให้สัญญาถูกปิดกั้น ซึ่งอาจทำให้เกิดการโจมตี DoS

ลองพิจารณาสถานการณ์ที่ใช้สัญญาอัจฉริยะสำหรับ "การเสนอราคา":

ผู้ใช้สามารถลงทะเบียนบัญชีโดยเรียกใช้เมธอดฟังก์ชัน pub fn register_account ใน "สัญญาการประมูล" เพื่อเตรียมพร้อมสำหรับการเข้าร่วมการประมูลครั้งต่อไป

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

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

เมื่อสัญญาการประมูลได้รับโทเค็น มันจะเรียกใช้ฟังก์ชันการประมูลต่อไปนี้ผ่านฟังก์ชัน ft_on_transfer

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

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

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

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

ในขณะนี้ การทดสอบจะจำลองผู้ใช้ที่เข้าร่วมของ "ระบบการเสนอราคา": user0, user1 และ user2

พวกเขาแต่ละคนมี 10,000 โทเค็นเริ่มต้น user0 เสนอราคาครั้งแรกที่ 1,000 ใน "ระบบการเสนอราคา" ในขณะนี้ ข้อความค้นหาแสดงว่า current_leader: user0.test.near maximum_bid: 1,000 จากนั้น user0 โอนโทเค็นที่เหลืออีก 9,000 รายการไปยัง user2 ทันทีและทำลายบัญชีโทเค็น

หลังจากนั้น เมื่อ user1 เสนอราคา 2000 ระบบจะวางแผนคืนค่า bid ก่อนหน้าของ user0 อย่างไรก็ตาม เนื่องจากบัญชีของ user0 ไม่มีอยู่ในขณะนี้ ระบบจะแจ้ง"Cannot Refund"สถานะการอัปเดตธุรกรรมที่ตามมาไม่สามารถทำให้เสร็จสมบูรณ์ได้

ณ จุดนี้ ผู้ประมูลรายที่สองต้องการเสนอราคา 2,000:

  • สารละลาย:

ชื่อเรื่องรอง

3. คีย์ส่วนตัวของเจ้าของสูญหาย

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

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

  • สารละลาย:

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

สัญญาที่ชาญฉลาด
ยินดีต้อนรับเข้าร่วมชุมชนทางการของ Odaily
กลุ่มสมาชิก
https://t.me/Odaily_News
กลุ่มสนทนา
https://t.me/Odaily_CryptoPunk
บัญชีทางการ
https://twitter.com/OdailyChina
กลุ่มสนทนา
https://t.me/Odaily_CryptoPunk
ค้นหา
สารบัญบทความ
คลังบทความของผู้เขียน
BlockSec
ดาวน์โหลดแอพ Odaily พลาเน็ตเดลี่
ให้คนบางกลุ่มเข้าใจ Web3.0 ก่อน
IOS
Android