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

ลายเซ็นข้อมูลแบบมีชนิด EIP-712: โดเมน ไดเจสต์ และการตรวจสอบอย่างปลอดภัย

EIP-712 ทำให้ข้อความแบบมีโครงสร้างของ Ethereum มีการเข้ารหัสที่แน่นอนและแสดงผลได้ แต่การลงนามอย่างปลอดภัยยังต้องตรวจสอบโดเมน ชนิด ค่า nonce กำหนดเวลา การดำเนินการ และนโยบายผู้ลงนาม

อัปเดต

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

คำตอบโดยตรง

EIP-712 กำหนดวิธีมาตรฐานที่แอป Ethereum ใช้อธิบาย ทำแฮช และขอลายเซ็นสำหรับข้อมูลแบบมีโครงสร้างและมีชนิด คำขอประกอบด้วย types primaryType domain และ message ส่วนไดเจสต์คือ keccak256("\x19\x01" || domainSeparator || hashStruct(message)) การเข้ารหัสจึงให้ผลแน่นอน และกระเป๋าที่รองรับสามารถแสดงแต่ละฟิลด์ได้ชัดกว่าแฮชที่อ่านความหมายไม่ได้

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

ลายเซ็นข้อมูลแบบมีชนิด EIP-712
0 / 5
0 ตรวจสอบรายการแล้ว; 5 รายการยังไม่ได้รับการแก้ไข

การเสร็จสิ้นการตรวจสอบนี้ไม่ได้พิสูจน์ว่าสินทรัพย์ ธุรกรรม หรือระบบมีความปลอดภัย

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

1. ระบุการกระทำและเส้นทางตรวจสอบ

พิจารณาว่าคำขอให้อำนาจเข้าสู่ระบบ ตั้งคำสั่ง โหวต ให้ allowance แก่โทเคน โอนสินทรัพย์ เรียกผ่าน relayer หรือทำอย่างอื่น จากนั้นหาคอดที่สร้างไดเจสต์ใหม่และใช้ลายเซ็น สำหรับบัญชีที่ควบคุมด้วยกุญแจภายนอก มักกู้ที่อยู่จากลายเซ็น ECDSA ส่วนบัญชีสัญญาอาจต้องเรียก ERC-1271 isValidSignature(hash, signature) และตรวจค่าความสำเร็จ 0x1626ba7e

2. ตรึงโดเมน

ตรวจชนิด EIP712Domain และค่าที่แท้จริง ฟิลด์มาตรฐานคือ name version chainId verifyingContract และ salt แต่มีเพียงฟิลด์ที่ใส่ไว้เท่านั้นที่ถูกแฮช ยืนยันเครือข่ายที่ใช้งาน คอดที่เผยแพร่ และสัญญาตรวจสอบจากแหล่งอิสระ ชื่อ สัญลักษณ์ ป้าย proxy หรือที่อยู่แบบ checksum ที่คุ้นเคยยังไม่เพียงพอ ERC-5267 eip712Domain() อาจเปิดเผยโดเมนได้ แต่การรองรับไม่บังคับและยังต้องตรวจพฤติกรรม proxy กับการอัปเกรด

3. สร้างกราฟชนิดข้อมูลใหม่

เริ่มจาก primaryType รักษาลำดับสมาชิก และรวบรวม struct ที่อ้างถึงแบบเวียนซ้ำ encodeType จะต่อท้ายคำจำกัดความเหล่านั้นโดยเรียงตามชื่อชนิด EIP-712 รองรับจำนวนเต็มความกว้างคงที่ address bool ตั้งแต่ bytes1 ถึง bytes32 รวมถึง bytes และ string แบบไดนามิก array และ struct แต่มาตรฐานไม่ได้กำหนดชื่อย่อ uint กับ int ชนิดเลขจุดคงที่ หรือค่าแบบวนรอบ

4. ถอดความทุกค่าและหน่วย

จับคู่ทุกค่ากับชนิดที่ประกาศและความหมายในแอป ตรวจที่อยู่เต็ม หน่วยจำนวนเต็มดิบ เครื่องหมาย ลำดับ array ผู้รับ spender สินทรัพย์ จำนวน ค่าธรรมเนียม ขีดจำกัด ปลายทาง แฮช calldata และข้อความที่อ่านได้ ค่า bytes และ string แบบไดนามิกแสดงใน encodeData ด้วยแฮช Keccak-256 ของเนื้อหา ส่วน array ใช้แฮชของการเข้ารหัสสมาชิกที่ต่อกัน และ struct ซ้อนใช้ hashStruct ของตนเอง

5. คำนวณไดเจสต์ใหม่อย่างอิสระ

คำนวณ typeHash = keccak256(encodeType(primaryType)) แล้วคำนวณ hashStruct(message) = keccak256(typeHash || encodeData(message)) คำนวณตัวคั่นโดเมนด้วยวิธีเดียวกันและรวมกับไบต์เวอร์ชัน ERC-191 0x19 0x01 เปรียบเทียบผลจากหน้าแอป ไลบรารีลงนาม สัญญาตรวจสอบ และการคำนวณอิสระ JSON ที่ดูเหมือนกันไม่ได้พิสูจน์ว่าการเข้ารหัสแบบมีชนิดเหมือนกัน

6. ตรวจการใช้ซ้ำ เวลา และการดำเนินการ

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

7. ลงนามเท่าที่จำเป็นและกระทบยอดผล

ปฏิเสธฟิลด์ซ่อน ชนิดที่อธิบายไม่ได้ ค่าไม่จำกัด กำหนดเวลาที่ไกล สัญญาไม่รู้จัก chain ID ไม่ตรง หน้าจอ blind signing หรือบริบทการดำเนินการไม่ครบ เก็บ JSON แบบมีชนิดและไดเจสต์ที่ตรงทั้งหมด ใช้บัญชีจำกัดวัตถุประสงค์เมื่อทำได้ แล้วตรวจธุรกรรม ใบรับเหตุการณ์ ยอดคงเหลือ allowance nonce สถานะคำสั่ง และ finality การตัดการเชื่อมต่อเว็บไซต์ไม่เพิกถอนลายเซ็นที่ยังใช้ได้หรืออำนาจที่สร้างแล้ว

ตัวอย่างการคำนวณ

ตัวอย่าง 1: การสร้างชนิดและไดเจสต์

สำหรับ Order(address maker,address token,uint256 amount,uint256 nonce,uint256 deadline) ค่า typeHash คือแฮช Keccak-256 ของสตริงนี้ทุกตัวรวมลำดับฟิลด์ แฮชข้อความคือ keccak256(typeHash || maker || token || amount || nonce || deadline) และสมาชิกที่เข้ารหัสแต่ละตัวใช้ 32 ไบต์ ไดเจสต์สุดท้ายเพิ่ม 0x1901 ตัวคั่นโดเมน และแฮชข้อความ การเปลี่ยน amount จาก 250000000 เป็น 250000001 เปลี่ยนไดเจสต์และทำให้ลายเซ็นเดิมใช้ไม่ได้

ตัวอย่าง 2: หน่วยและกำหนดเวลา

จำนวน 250 USDC ของโทเคนทศนิยมหกตำแหน่งต้องเข้ารหัสเป็นค่าดิบ 250000000 ไม่ใช่ 250 หากเวลาปัจจุบันคือ 1727000000 และกำหนดหมดอายุคือ 1727000900 ช่วงเวลาคือ 900 seconds = 15 minutes การแสดงทศนิยมของกระเป๋าและนาฬิกาเครื่องเป็นเพียงตัวช่วย สัญญาตรวจสอบใช้จำนวนเต็มดิบและกฎเวลา on-chain ที่กำหนด

ตัวอย่าง 3: การควบคุม replay

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

ตัวอย่าง 4: ความถูกต้องของกระเป๋าสัญญา

กระเป๋าสัญญาแบบ 2-of-3 อนุมัติไดเจสต์ขณะที่ตั้งผู้ลงนาม A B และ C ลายเซ็นของ A กับ B อาจทำให้ ERC-1271 คืน 0x1626ba7e ในวันนี้ หากอัปเกรดโมดูลแล้วแทน B ด้วย D ไบต์ลายเซ็นเดิมอาจใช้ไม่ได้ เพราะความถูกต้องของ ERC-1271 ขึ้นกับสถานะ นโยบาย เวลา และการเรียกภายนอกปัจจุบันได้ การกู้ที่อยู่เพียงอย่างเดียวจึงตัดสินบัญชีสัญญาไม่ได้

ความเสี่ยง

  • chainId ผิดหรือขาดหาย
  • verifyingContract ปลอมหรือไม่ใช่สัญญาที่คาด
  • name หรือ version ของโดเมนทำให้เข้าใจผิด
  • implementation ของ proxy หรือโดเมนเปลี่ยนหลังอัปเกรด
  • primaryType ผิดหรือชนิดซ่อนที่มีป้ายคล้ายกัน
  • ลำดับสมาชิก ลำดับ dependency หรือ encoder ไม่ตรงกัน
  • ที่อยู่ถูกย่อ เปลี่ยน หรือใส่ป้ายหลอก
  • ทศนิยมโทเคนหรือจำนวนเต็มมีเครื่องหมายผิด
  • สมาชิก array, struct ซ้อน หรือ payload bytes ถูกซ่อน
  • จำนวนไม่จำกัด ขอบเขตกว้าง หรือผู้รับที่ผู้โจมตีควบคุม
  • nonce หาย เก่า ใช้ร่วม หรือถูกใช้ผิดวิธี
  • กำหนดเวลาหาย ไกล overflow หรือแปลความกำกวม
  • replay ข้ามเครือข่าย สัญญา บัญชี หรือการกระทำ
  • relayer กัก เซ็นเซอร์ แซงหน้า หรือเปลี่ยนเส้นทาง
  • ลายเซ็นเปลี่ยนรูปได้หรือการกู้ ECDSA ผ่อนปรนเกินไป
  • ผู้ลงนาม โมดูล threshold สถานะ หรือคอด ERC-1271 เปลี่ยน
  • การแสดงผลกระเป๋า blind signing หรือชนิดไม่รองรับล้มเหลว
  • JSON หน้าแอปต่างจากไดเจสต์ของสัญญาตรวจสอบ
  • การเพิกถอนหรือยกเลิกแพ้การแข่งขันลำดับธุรกรรม
  • เข้าใจผลหน้าลงนามผิดเป็นใบรับ การเปลี่ยนสถานะ หรือ finality

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

ความเข้าใจผิด 1: ลายเซ็น EIP-712 คือธุรกรรม

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

ความเข้าใจผิด 2: การแสดงแบบมีโครงสร้างหมายความว่าคำขอปลอดภัย

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

ความเข้าใจผิด 3: ตัวคั่นโดเมนป้องกัน replay ทุกแบบ

ตัวคั่นแยกเฉพาะโดเมนที่เข้ารหัส replay ภายในโดเมนเดิมยังต้องใช้ nonce กำหนดเวลา การยกเลิก การบันทึก fill หรือ idempotence และฟิลด์โดเมนที่ไม่ได้ใส่ไม่สร้างขอบเขตใด

ความเข้าใจผิด 4: กู้ที่อยู่ที่คาดได้ก็พิสูจน์อำนาจแล้ว

การกู้พิสูจน์เพียงลายเซ็นของ EOA เหนือไดเจสต์ ไม่ได้ตรวจความหมายของแอป บัญชีสัญญาต้องใช้กฎ ERC-1271 ของตนแทนการกู้ที่อยู่ทั่วไป

ความเข้าใจผิด 5: ปิดหน้าหรือตัดการเชื่อมต่อกระเป๋าจะยกเลิกลายเซ็น

ลายเซ็นที่ถูกคัดลอกยังใช้ได้จนกว่า nonce กำหนดเวลา การยกเลิก สถานะ หรือนโยบายของสัญญาตรวจสอบจะทำให้ใช้ไม่ได้ ต้องตรวจสถานะ on-chain ที่เกี่ยวข้อง ไม่ใช่สถานะเซสชัน

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

แหล่งอ้างอิง

การนำทาง

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