﻿---
title: "ภาวะแข่งขันในการอนุมัติ ERC-20"
description: "ผู้รับอนุญาตของ ERC-20 อาจใช้วงเงินเดิมก่อนที่การอนุมัติทดแทนจะได้รับการยืนยัน แล้วจึงใช้วงเงินใหม่ต่อ บทความนี้อธิบายกลไกของภาวะแข่งขันและวิธีเปลี่ยนหรือเพิกถอนการอนุมัติอย่างปลอดภัยยิ่งขึ้น"
image: "https://wiki.fcontext.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://wiki.fcontext.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ภาวะแข่งขันในการอนุมัติ ERC-20

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

<a id="answer"></a>

## คำตอบโดยตรง

ภาวะแข่งขันในการอนุมัติ ERC-20 อาจเกิดขึ้นเมื่อเจ้าของเรียก `approve(spender, newAmount)` เพื่อแทนที่วงเงินที่ไม่ใช่ศูนย์ด้วยวงเงินอื่นที่ไม่ใช่ศูนย์ ผู้รับอนุญาตอาจเห็นการเปลี่ยนแปลงที่รอดำเนินการ ใช้วงเงินเดิมก่อนด้วย `transferFrom` แล้วใช้วงเงินทดแทนหลังจากได้รับการยืนยัน

ดังนั้น ข้อกำหนด ERC-20 จึงแนะนำให้อินเทอร์เฟซฝั่งไคลเอนต์ตั้งวงเงินเป็น `0` ก่อนกำหนดค่าใหม่ให้ผู้รับอนุญาตรายเดิม ธุรกรรมแต่ละรายการต้องได้รับการยืนยันตามลำดับ หากโทเค็นรองรับ การเรียก `increaseAllowance` หรือ `decreaseAllowance` แบบอะตอมมิกจะช่วยหลีกเลี่ยงการแทนที่วงเงินที่ไม่ใช่ศูนย์โดยตรง

<a id="mechanism"></a>

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

ERC-20 กำหนดให้ `approve` เป็นการเขียนทับ กล่าวคือ `approve(spender, amount)` ที่สำเร็จจะตั้งวงเงินของผู้รับอนุญาตเป็น `amount` ส่วน `transferFrom(owner, recipient, amount)` เปิดให้ผู้รับอนุญาตรายนั้นโอนโทเค็นของเจ้าของ และโดยทั่วไปจะลดวงเงินที่เหลือ ธุรกรรมที่รอดำเนินการไม่ได้จองลำดับการดำเนินการไว้ ผู้รับอนุญาตจึงอาจส่งคำสั่งโอนที่ดำเนินการก่อนการเปลี่ยนแปลงการอนุมัติของเจ้าของได้

การเปลี่ยนผ่านที่มีความเสี่ยงคือ `N -> M` โดยที่ทั้ง `N > 0` และ `M > 0` หากผู้รับอนุญาตใช้ `N` หมดก่อนการอนุมัติทดแทนจะดำเนินการ การอนุมัติที่ตามมาจะกำหนดวงเงินใหม่เป็น `M` ดังนั้น ยอดใช้จ่ายสูงสุดตลอดลำดับนี้อาจเป็น `N + M` โดยขึ้นอยู่กับยอดคงเหลือโทเค็นของเจ้าของและการทำงานของโทเค็น

<a id="example"></a>

## ตัวอย่าง

Alice อนุมัติให้โปรโตคอลใช้โทเค็น `100` หน่วย เธอส่ง `approve(protocol, 50)` โดยตั้งใจลดวงเงินคงเหลือเป็น `50` ก่อนที่ธุรกรรมนั้นจะได้รับการยืนยัน ผู้รับอนุญาตของโปรโตคอลส่ง `transferFrom(Alice, recipient, 100)` และทำให้รายการนี้ดำเนินการก่อน จากนั้นการอนุมัติของ Alice จะตั้งวงเงินเป็น `50` ซึ่งผู้รับอนุญาตสามารถใช้ในการโอนอีกครั้งได้ การโอนทั้งสองครั้งรวมเป็นโทเค็น `150` หน่วย

ขั้นตอนทดแทนที่ปลอดภัยกว่าคือส่ง `approve(protocol, 0)` รอการยืนยัน ตรวจสอบวงเงินและยอดคงเหลือที่ได้ แล้วจึงส่ง `approve(protocol, 50)` เฉพาะเมื่อการอนุมัติใหม่ยังเหมาะสมอยู่ หากผู้รับอนุญาตใช้วงเงินเดิมก่อนที่ธุรกรรมตั้งวงเงินเป็นศูนย์จะได้รับการยืนยัน Alice จะเห็นยอดคงเหลือที่เปลี่ยนไปและหยุดได้ก่อนอนุมัติวงเงินใหม่ `50`

<a id="risks"></a>

## ความเสี่ยง

- การตั้งวงเงินเป็น `0` ไม่ได้เพิกถอนการใช้จ่ายที่ดำเนินการไปแล้ว และไม่สามารถป้องกันการใช้วงเงินเดิมก่อนที่ธุรกรรมตั้งวงเงินเป็นศูนย์จะได้รับการยืนยัน
- การส่งคำสั่งอนุมัติเพื่อตั้งวงเงินเป็นศูนย์และคำสั่งอนุมัติทดแทนพร้อมกันโดยไม่รอการยืนยันรายการแรก จะทำให้ความเสี่ยงด้านลำดับกลับมาอีกครั้ง
- `increaseAllowance` และ `decreaseAllowance` ไม่ได้เป็นส่วนหนึ่งของมาตรฐาน ERC-20 พื้นฐาน ให้ใช้เฉพาะเมื่อสัญญาโทเค็นที่ตรวจสอบแล้วรองรับ
- วงเงินแบบไม่จำกัดอาจทำให้ยอดคงเหลือโทเค็นทั้งหมดของเจ้าของมีความเสี่ยงตราบใดที่ยังเปิดใช้งานอยู่ ตรวจสอบเชน สัญญาโทเค็น ผู้รับอนุญาต และจำนวนเงินก่อนลงนาม
- โทเค็นบางรายการมีพฤติกรรมการอนุมัติที่ไม่เป็นมาตรฐาน อ่านผลจำลองของกระเป๋าเงินและ calldata ของธุรกรรม แล้วตรวจสอบวงเงินบนเชนหลังจากแต่ละขั้นตอน

<a id="misconceptions"></a>

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

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

<a id="related"></a>

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

- [วิธีแยกโทเค็นมาตรฐานออกจากโทเค็นแบบ wrapped](/th/crypto/canonical-vs-wrapped-token/)
- [Mempool](/th/crypto/mempool/)
- [ความเสี่ยงจากลายเซ็น Permit2](/th/crypto/permit2-signature-risk/)
- [คำสั่งแบบ Reduce-only](/th/crypto/reduce-only-order/)
- [การอนุมัติของกระเป๋าเงิน](/th/crypto/wallet-approval/)

<a id="sources"></a>

## แหล่งที่มา

- [ERC-20: Token Standard](https://eips.ethereum.org/EIPS/eip-20) - Ethereum Improvement Proposals (เข้าถึงเมื่อ: 2026-08-20)
- [ERC20 | OpenZeppelin Docs](https://docs.openzeppelin.com/contracts/4.x/api/token/erc20) - OpenZeppelin (เข้าถึงเมื่อ: 2026-08-20)

Source: https://wiki.fcontext.com/th/crypto/erc20-approval-race-condition/index.mdx
