จัดทำขึ้นเพื่อการศึกษาเท่านั้น ไม่ใช่คำแนะนำการลงทุน การลงทุนอาจทำให้สูญเสียเงินลงทุนได้
คำตอบโดยตรง
Calldata คือชุดไบต์ที่เปลี่ยนแปลงไม่ได้ซึ่งส่งเป็นอินพุตให้ธุรกรรม Ethereum ระดับบนสุดหรือการเรียกข้อความภายใน การเรียกฟังก์ชัน Solidity ตามแบบแผนเริ่มด้วย selector ขนาด 4-byte ตามด้วยอาร์กิวเมนต์ที่เข้ารหัสด้วย ABI แต่ calldata ไม่ได้อธิบายตัวเอง ไบต์เดียวกันอาจมีความหมายต่างกันเมื่อใช้กับ runtime code การใช้งานพร็อกซี หรือสคีมาคนละชุด ฟังก์ชัน fallback, raw assembly และโปรโตคอลที่ไม่ได้เขียนด้วย Solidity ก็ไม่จำเป็นต้องทำตาม ABI ของฟังก์ชันตามแบบแผนเลย
ดังนั้นกระเป๋าเงินควรแสดงมากกว่าชื่อฟังก์ชันที่คาดเดา การตรวจสอบที่ปลอดภัยต้องผูกไบต์กับ chainId บล็อก from to value ดั้งเดิม codeHash ของ runtime การใช้งานที่ทำงานอยู่ และ ABI ที่เชื่อถือได้ ถอดรหัสทุกการเรียกซ้อนอย่างเคร่งครัด แยก calldata บนเชนออกจากลายเซ็น EIP-712 จำลองด้วยสถานะที่ระบุชัด และกระทบยอด receipt กับการเปลี่ยนแปลงสถานะจริงหลังธุรกรรมถูกรวมเข้าบล็อก
การเสร็จสิ้นการตรวจสอบนี้ไม่ได้พิสูจน์ว่าสินทรัพย์ ธุรกรรม หรือระบบมีความปลอดภัย
กลไกการทำงาน
- ตรึงซองข้อมูลที่จะลงนามและจุดสังเกต ได้แก่
chainIdหมายเลขและแฮชบล็อกfromtovalueดั้งเดิม ไบต์อินพุต nonce และฟิลด์ค่าธรรมเนียม เก็บแหล่งข้อมูลจากกระเป๋าเงินหรือ RPC ไว้ เพราะ payload ที่ถอดจากเชนหรือบล็อกอื่นไม่ใช่ข้ออ้างเดียวกัน - จำแนกวัตถุก่อนถอดรหัส ธุรกรรม คำขอ typed data แบบ EIP-712, permit แบบ ERC-2612, UserOperation แบบ ERC-4337 และข้อความ personal-sign ดิบ ใช้โดเมนและสคีมาต่างกัน อย่าบังคับให้ทั้งหมดผ่าน ABI ของธุรกรรม
- ระบุเป้าหมาย ณ บล็อกที่ตรึงไว้ อ่าน runtime bytecode และ
codeHashระบุพร็อกซี beacon หรือ implementation เมื่อเกี่ยวข้อง บันทึกสล็อต implementation และ admin แล้วใช้ ABI ที่ตรงกับโค้ดเวอร์ชันนั้นทุกประการ ฐานข้อมูล selector ให้ได้เพียงรายชื่อที่เป็นไปได้ ไม่ใช่หลักฐานชี้ขาด - ถอดรหัสอย่างเคร่งครัด selector คือ
4 bytesแรกของ Keccak-256 จากลายเซ็นฟังก์ชันมาตรฐานโดยไม่รวมชนิดค่าที่ส่งคืน ค่าคงที่ใช้คำขนาด32-byteส่วน head ของค่าไดนามิกเก็บออฟเซ็ตจากจุดเริ่มต้นของบล็อกอาร์กิวเมนต์หลัง selector ปฏิเสธข้อมูลที่ขาด ออฟเซ็ตนอกขอบเขต ความยาวที่เป็นไปไม่ได้ padding ที่ไม่ถูกต้อง และไบต์ส่วนท้ายที่อธิบายไม่ได้ - คลี่ multicall, calldata ที่ซ้อนกัน และการทำงานแบบมอบหมายสิทธิ์ซ้ำลงไปทุกระดับ สำหรับ child call แต่ละรายการ ให้แสดงเป้าหมาย มูลค่าดั้งเดิม selector อาร์กิวเมนต์ ชนิดการเรียก และ flag
allowFailureถ้ามี เมื่อใช้delegatecallโค้ด implementation จะทำงานในบริบทของที่อยู่ ยอดคงเหลือ และ storage ของผู้เรียก โดยคงmsg.senderและmsg.valueไว้ - สร้างบัญชีสิทธิ์และบัญชีมูลค่าแยกกัน แล้วจึงจำลอง บันทึกผู้รับ spender ผู้ดำเนินการ NFT หน่วยโทเค็นดิบ decimals เส้นตาย ขอบเขต slippage และมูลค่าดั้งเดิม จำลองด้วยบล็อก ผู้ส่ง และมูลค่าที่ตรงกัน แต่ถือผลลัพธ์เป็นภาพสถานะแบบมีเงื่อนไข เพราะสถานะ ราคา เวลา โค้ด และลำดับธุรกรรมอาจเปลี่ยนได้
- ยืนยันทุกฟิลด์ที่มีสาระสำคัญก่อนลงนาม หลังธุรกรรมถูกรวมเข้าบล็อก ให้ตรวจสถานะ receipt, log, trace หากมี และส่วนต่างของยอดคงเหลือ allowance และสถานะผู้ดำเนินการ แยกความล้มเหลวของ child call ที่โค้ดดักไว้จากความสำเร็จระดับบนสุด คิดค่า gas แม้ธุรกรรม revert รอ finality ตามที่กำหนด และหยุดแทนการลงนามซ้ำโดยไม่เข้าใจความล้มเหลว
ตัวอย่างคำนวณ
- การโอน ERC-20 แบบค่าคงที่
transfer(address,uint256)มักใช้ selector0xa9059cbbโดย selector หนึ่งชุดบวกคำ ABI สองคำมีขนาด4 + 2 * 32 = 68 bytesจำนวนดิบ1,500,000ของโทเค็นที่ตรวจสอบแยกต่างหากแล้วว่าใช้6 decimalsจะแสดงเป็น1.5 tokensค่า decimals เป็นข้อมูลเมตาภายนอกของสัญญา ไม่ได้เข้ารหัสอยู่ในอาร์กิวเมนต์เหล่านั้น และ selector เพียงอย่างเดียวระบุสัญญาหรือฟังก์ชันแบบไม่ซ้ำไม่ได้ - ออฟเซ็ตของไบต์ไดนามิก สำหรับ
f(address,bytes)ที่มี payload ขนาด3-byteส่วน head สองคำใช้64 bytesออฟเซ็ตไดนามิกคือ0x40โดยวัดจากจุดเริ่มต้นของบล็อกอาร์กิวเมนต์และไม่รวม selector ส่วน tail มีคำความยาว32-byteหนึ่งคำและคำข้อมูลที่เติม padding แล้วขนาด32-byteอีกหนึ่งคำ ดังนั้น calldata รวมมีขนาด4 + 64 + 32 + 32 = 132 bytesหากมองออฟเซ็ตเป็นตำแหน่งสัมบูรณ์จากไบต์ศูนย์ จะคลาดไปสี่ไบต์ - มูลค่าของแบตช์ขึ้นกับ implementation การเรียกภายนอกส่ง
1.00 ETHส่วน child call ที่ถอดรหัสแล้วสามรายการขอ0.20 ETH,0.30 ETHและ0.10 ETHรวมเป็น0.60 ETHโค้ดแบตช์อาจคืน เก็บ ส่งต่อ0.40 ETHที่เหลือ หรือ revert ขึ้นกับ implementation หาก child รายการที่สามล้มเหลวโดยมีallowFailure=trueรายการก่อนหน้าอาจยังคงถูกบันทึก ส่วน implementation แบบอะตอมิกอาจ revert ทั้งหมด - Permit ไม่ใช่ calldata ของ relayer ณ เวลาลงนาม เจ้าของที่มี
1,000 USDCลงนาม permit แบบ ERC-2612 มูลค่า300 USDCที่ nonce41ลายเซ็นอย่างเดียวไม่เปลี่ยนยอดคงเหลือหรือ allowance หลัง relayer ส่งสำเร็จ nonce จะเป็น42และ allowance เป็น300เมื่อ spender ใช้180ยอดคงเหลือจะเป็น820และ allowance ที่เหลือเป็น120การตัดการเชื่อมต่อเว็บไซต์ไม่ได้เพิกถอนสิทธิ์นี้
ความเสี่ยง
- ถอดรหัสโดยอ้างอิงเชน fork, block tag หรือซองธุรกรรมที่ผิด
- ลงนามให้โดเมน ที่อยู่เป้าหมาย หรือผู้รับที่ปลอมแปลง
- ถือว่า selector
4-byteไม่ซ้ำทั้งที่อาจชนกันได้ - ใช้ ABI ที่คาดเดา ล้าสมัย หรือตรวจสอบไม่ถูกต้อง
- เชื่อป้าย source ที่ยืนยันแล้วโดยไม่เทียบกับ
codeHashของ runtime ปัจจุบัน - พลาดการอัปเกรด implementation, beacon หรือ admin ระหว่างการตรวจสอบกับการทำงาน
- มองข้ามฟังก์ชันพร็อกซีที่มี selector ชนกับ implementation
- ลืมว่า
delegatecallเขียนในบริบท storage ของผู้เรียก - ยอมรับออฟเซ็ต ความยาว padding ไดนามิก หรือไบต์ส่วนท้ายที่ผิดรูป
- ไม่คลี่แบตช์ซ้อนที่ซ่อนเป้าหมาย มูลค่า หรือสิทธิ์
- สมมติว่าเป็นอะตอมิกทั้งที่ implementation ดักหรือยอมให้ child call ล้มเหลว
- มองข้าม
valueดั้งเดิมระดับบนสุดเพราะอาร์กิวเมนต์โทเค็นดูไม่เป็นอันตราย - ใช้ decimals ผิดหรือสมมติว่าโทเค็นแบบ fee-on-transfer และ rebasing เป็น ERC-20 มาตรฐาน
- ให้ allowance ERC-20 ไม่จำกัดหรือจัดการ race ของการเปลี่ยน allowance ผิด
- มองข้ามว่า
setApprovalForAllของ NFT ครอบคลุมทั้งคอลเลกชัน - เข้าใจ typed data แบบ EIP-712 หรือ permit แบบ ERC-2612 ผิดว่าเป็น calldata ของธุรกรรม
- พลาดขอบเขต nonce เส้นตาย verifying contract โดเมนเชน หรือการเล่นซ้ำ
- ถือว่าการจำลองคงที่ทั้งที่ oracle, timestamp, pending state, MEV หรือโค้ดเปลี่ยนได้
- ถือสถานะ receipt, log หรือ trace จากผู้ให้บริการเป็นหลักฐานสถานะทางเศรษฐกิจที่สมบูรณ์
- ลงนามซ้ำโดยไม่ตรวจสอบผ่าน UI ที่ถูกเจาะ หรือมองข้ามความเสี่ยงด้าน inclusion, reorg และ finality
ความเข้าใจผิดที่พบบ่อย
- selector ของฟังก์ชันระบุสิ่งที่สัญญาจะทำแบบไม่ซ้ำ
- สรุปจาก front-end ที่ยืนยันแล้วตรงกับไบต์และ implementation ปัจจุบันที่กำลังลงนามทุกประการ
- ธุรกรรมที่มี
value=0ไม่สามารถย้ายโทเค็น NFT หรือสินทรัพย์ที่มอบสิทธิ์ไว้ได้ - การจำลองหรือ receipt ที่สำเร็จพิสูจน์ความปลอดภัยและผลลัพธ์ทางเศรษฐกิจที่ตั้งใจไว้
- การตัดการเชื่อมต่อ dapp เพิกถอน approval, permit และสิทธิ์ผู้ดำเนินการ NFT
หัวข้อที่เกี่ยวข้อง
แหล่งข้อมูล
- Contract ABI Specification - Solidity Documentation (เข้าถึง: 2026-08-12)
- Introduction to Smart Contracts - Solidity Documentation (เข้าถึง: 2026-08-12)
- Transactions - Ethereum.org (เข้าถึง: 2026-08-12)
- ERC-20: Token Standard - Ethereum Improvement Proposals (เข้าถึง: 2026-08-12)
- EIP-712: Typed structured data hashing and signing - Ethereum Improvement Proposals (เข้าถึง: 2026-08-12)
- ERC-2612: Permit Extension for EIP-20 Signed Approvals - Ethereum Improvement Proposals (เข้าถึง: 2026-08-12)
- ERC-721: Non-Fungible Token Standard - Ethereum Improvement Proposals (เข้าถึง: 2026-08-12)
- ERC-1967: Proxy Storage Slots - Ethereum Improvement Proposals (เข้าถึง: 2026-08-12)