Uniswap คืออะไร?

Moonbeam_Thailand
6 min readAug 31, 2021

--

คำเตือน : บทความนี้จัดทำขึ้นเพื่อการศึกษาเกี่ยวกับการทำงานของ Uniswap

ตั้งแต่ปี 2018 Uniswap ได้เป็นหนึ่งในผู้นำของตลาดการซื้อขายไร้ตัวกลาง (Decentralized Exchange, DEX) และ Automated Market Maker (AMM) หัวข้อเหล่านี้อาจมีความซับซ้อนอยู่บ้าง เราจึงเล็งเห็นถึงความสำคัญที่จะอธิบายการทำงานของ Uniswap

ในบทความนี้ เราจะอธิบายถึง Uniswap , ไปจนถึง Uniswap V2 ที่ถูกใช้งานกับ Moonbase Alpha TestNet (เพื่อเป็นเพียงตัวอย่างเท่านั้น ที่ยังไม่ได้ถูกเปิดให้ใช้งานจริง) หัวข้อจะแบ่งออกไปด้วย

1. Uniswap คืออะไร?: การรีวิวและอธิบายคำศัพท์เฉพาะที่ใช้ในระบบ Uniswap ก่อนที่จะลงลึกไปยังเนื้อหาทางเทคนิค
2.
Uniswap ใช้งานอย่างไร: จะกล่าวถึงการทำงานพื้นฐานของ smart contract หลัก ของ Uniswap
3.
การใช้ Uniswap V2 บน ระบบของ Moonbeam: กล่าวถึงวิธีการใช้งาน Uniswap V2 ที่ทำงานบน Moonbase Alpha เพื่อการสาธิตเป็นตัวอย่างเท่านั้น

เราจะยกตัวอย่างการใช้งานแอพพลิเคชันตัวอย่าง, Uniswap V2 บน Moonbase Alpha หรือ Moonbeam standalone node เราจะอัพเดตลิงค์เมื่อเราเปิดให้มันใช้งานจริง รวมถึงจะมี ERC20 token faucet บน Moonbase Alpha ที่คุณอาจจะต้องใช้

Uniswap คืออะไร ?

หลักการพื้นฐานของ Market Maker
ก่อนที่เราจะพูดถึง Uniswap เราควรทำความรู้จักกับ Market Maker เสียก่อน

โดยรวมๆแล้ว Market Makers (MM) จะเป็นตัวให้สภาพคล่องแก่ตลาดการซื้อขาย โดยจะตั้งการ “ซื้อ” และ “ขาย” ของสินทรัพย์แต่ละอย่าง ดังนั้นมันคือ “แหล่งกำเนิด” ของการค้นพบราคาตลาด เพื่อการแลกเปลี่ยน ถ้าหากในการเทรดครั้งหนึ่ง ราคาตั้งซื้อ ได้ถูกจับคู่กับราคาที่เสนอ จาก MM การแลกเปลี่ยนจะเป็นอันเสร็จสมบูรณ์ รายได้ของ Market Makers นั้นจะขึ้นกับ spread หรือ ความต่างระหว่างราคา “ซื้อ” และ “ขาย” โดยที่เมื่อ spread เพิ่มขึ้นรายได้ต่อการเทรดของ MM ก็จะเพิ่มขึ้น

Uniswap ทำงานอย่างไร?

Uniswap คือ Market Maker แบบอัตโนบัติ หรือ Automated MM (AMM) ที่จะขึ้นกับ smart contract ชุดหนึ่ง ที่อยู่บน Ethereum โดยจะเป็นกระบวนการจับคู่ราคา (หรือ ตั้งเป็นตัวกำหนดราคา) Uniswap จะให้ผู้ใช้งาน swap เหรียญ ไปยังอีกเหรียญ ผ่าน smart contract ซึ่งปราศจากตัวกลาง โดยที่ เหรียญ จะต้องเป็นเหรียญที่สามารถใช้งานบน ERC20 หรือ Eth ได้ (wrapped เพื่อให้อยู่บน ERC20 กับ WETH contract)

Liquidity provider (LP) หรือ ผู้ให้สภาพคล่อง สามารถสร้างตลาดเหล่านี้ได้ (เรียกว่า pools) โดย ผ่านการใช้งาน Uniswap factory contract โดย เมื่อ pool หนึ่ง pool ได้ถูกสร้างขึ้น ทุกคนสามารถที่จะเป็นผู้ให้สภาพคล่องให้แก่ pool นั้นๆได้ ซึ่งผู้ให้สภาพคล่องนั้น จะได้รับรายได้จากค่าธรรมเนียมในอัตราคงที่ โดยขึ้นกับปริมาณเหรียญที่คนๆนั้นฝากบน pool ในส่วนของ Share ใน pool นั้นๆ จะคิดจาก การใช้งานของเหรียญ ใน Liquidity นั้นๆ (LP Token) ซึ่งมันคือ จำนวน share ที่คุณมี ใน pool นั้นๆ

การทำ AMM นั้นหมายถึงการที่ราคาได้ถูกตั้งมาจากสูตรทางคณิตศาสตร์ และไม่ได้ถูกตั้งขึ้นโดยตัวกลาง หรือคนใดคนหนึ่ง ในกรณีนี้ของ Uniswap เราจะใช้ XYK model ซึ่งจะเขียนเป็นสมการดังนี้

โดยที่ x คือปริมาณของเหรียญ (สมมติให้ชื่อเหรียญ X) และ y คือปริมาณของอีกเหรียญหนึ่ง (สมมติให้ชื่อเหรียญ Y), และ k คือค่าคงที่

ยกตัวอย่าง มี pool หนึ่ง ถูกสร้างขึ้นมาด้วย 1,000 เหรียญของ TokenX และ 1,000 เหรียญของ TokenY ดังนั้น ค่า k จะเท่ากับ 1,000,000 และราคาเริ่มต้นจะมีสัดส่วนคือ 1:1 โดยที่ค่า k จะคงที่เสมอ ดังนั้น หากมีผู้ใช้ต้องการอยากจะฝากเหรียญ 10 TokenX ปริมาณของ TokenY ที่ pool ต้องการ จะถูกคำนวณได้โดย

เมื่อ pool ได้ถูกสร้างขึ้น address ของ pool จะถูกจัดเก็บ ด้วย double mapping ที่จะใช้ address ของเหรียญทั้งสอง เป็น input (ไม่ว่าจะเป็นเหรียญอะไรขึ้นต้นก่อนก็ตาม)

การสร้าง pool เกิดขึ้นผ่าน บรรทัดต่อไปนี้ ที่เป็น ฟังก็ชัน creatPair

จากตาราง จะเห็นว่า ยิ่งปริมาณเหรียญมากขึ้นที่ถูกแลกเปลี่ยน จะทำให้ราคายิ่งต่ำลง มันจะแตกต่างออกไปจาก อัตราส่วนในทางอุดมคติ (ที่เป็นสัดส่วน 1:1) ซึ่งเป็นส่วนของการกำหนดราคาจาก AMM

แต่เดี๋ยวก่อน, สูตรคำนวณด้านบนจะทำ AMM ได้อย่างไร ? จำไว้ว่าการคำนวณนั้นจะเป็นตัวกำหนดราคาของการแลกเปลี่ยน และนี่คือการสร้างโอกาสของการทำ arbitrage (การทำกำไรบนส่วนต่างของราคาเหรียญจากตลาดหลายๆแห่ง) โดยผู้ใช้สามารถใช้ประโยชน์จากความไม่เท่ากันใน สัดส่วนของ TokenX/TokenY เพื่อได้ราคาเหรียญที่ต่ำกว่าปกติ ซึ่งสิ่งนี้จะทำให้ pool มีความ balance ตลอดเวลาโดยอัตโนมัติ

และนี่คือความรู้พื้นฐานของ Uniswap โดยมันได้ถูกประกาศ สร้างขึ้นบน Ethereum MainNet ใน พฤศจิกายน 2018 ตั้งแต่นั้นมา มันได้เติบโตเป็นโปรเจค DeFi ที่ใหญ่ที่สุดในโลกของ blockchain ที่มีปริมาณการซื้อขายกว่า 130 พันล้านดอลลาร์ของปริมาตรการซื้อขายตลอดเวลาในตอนที่บทความนี้ถูกเขียนขึ้น Uniswap มีสภาพคล่องถึง 4.56 พันล้านดอลลาร์ และ ใน 24 ชั่วโมง มีปริมาณเงินที่เทียบเท่ากับ 1.28พันล้านดอลลาร์ ซึ่งเป็นปริมาณที่มหาศาลมากๆ ที่จำนวนเงินหลักนี้จะถูกเก็บอยู่บน โค้ด smart contract, blockchain, และ ระบบการเงิน

การใช้งานของ Uniswap

หลักการพื้นฐานของ Uniswap V2 Contracts
ดังที่ได้กล่าวไปก่อนหน้านี้ Uniswap จะขึ้นอยู่กับ smart contract ชุด ชุดหนึ่ง ที่จะกำหนดกระบวนการ AMM โดยในบทความส่วนนี้ เราจะอธิบายหลักการโดยรวมของ contract หลักๆ ที่เป็นส่วนของกระบวนการ AMM

Uniswap V2 Factory
Uniswap V2 factory contract อาจเรียกได้ว่าเป็น contract สำคัญของ protocol เลยก็ว่าได้ ที่มีขึ้นมาเพื่อสร้าง pools (เรียกว่า pairs ใน contract) จะทำโดยการใช้ create2 opcode, ที่สามารถ deploy contracts กับ determistic address ซึ่งนี่เป็นส่วนที่เป็นประโยชน์ในการใช้คำนวณ address ของ pool ที่ประกอบไปด้วยคู่เหรียญ (แม้กระทั่ง off-chain) คุณสามารถอ่านเพิ่มเติมเกี่ยวกับ create2 ได้ในบทความนี้ โดยสรุป เพือที่จะหา address ของ pool ใหม่ (contract) เพื่อถูก deploy ตัว create2 จะใช้:

1. bytecode ของ contract สามารถถูกประกาศ (UniswapV2Pair)
2. ที่อยู่ ของ contract ที่ deploy(UniswapV2Factory)
3. A salt, ที่คำนวณมาจาก kecccak256 ของ address ของเหรียญ ERC20 ทั้งคู่เขียนติดกัน

เมื่อ pool ได้ถูกสร้างขึ้น address ของ pool จะถูกจัดเก็บ ด้วย double mapping ที่จะใช้ address ของเหรียญทั้งสอง เป็น input (ไม่ว่าจะเป็นเหรียญอะไรขึ้นต้นก่อนก็ตาม)

การสร้าง pool เกิดขึ้นผ่าน บรรทัดต่อไปนี้ ที่เป็น ฟังก็ชัน creatPair

Uniswap V2 Router 02
ตัวกระจาย router คือ smart contract ที่จะติดต่อกับ pool โดย router นั้นจะไม่มีการถือ token ไว้กับตัวเลย ดังนั้น router จะสามารถถูกแทนที่ อย่างปลอดภัย ด้วย router ที่มีประสิทธิภาพดีกว่าในอนาคต ยกตัวอย่างเช่น router ในตอนนี้ (02) ได้ถูกอัพเกรดมาจากเวอร์ชั่นก่อนหน้านี้ (01)

เอกสารฉบับนี้จะไม่ได้กล่าวถึง code แบบละเอียดในทุกฟังก์ชันที่อยู่ใน router contract แต่จะกล่าวถึงฟังก์ชันที่สำคัญ ที่ประกอบไปด้วย

1) Addliquidity (การเพิ่ม Liquidity): คือฟังก์ชันที่ใช้กับการสร้าง Liquidity หรือสภาพคล่องใน pool ที่ถูกสร้างไว้อยู่แล้ว มันจะถูกใช้งานผ่านการให้ input คือ
- address ของเหรียญทั้งสองเหรียญ
- ปริมาณ Liquidity ที่คุณอยากจะฝากไว้
- ปริมาณ Liquidity ขั้นต่ำที่คุณอยากจะฝากไว้
- ที่อยู่ของผู้รับของเหรียญ LP token
- deadline (ใน UNIX timestamp)
หลักจากการตรวจสอบ ฟังก์ชั่นจะคำนวณ ปริมาณ liquidity ที่ดีที่สุดของหนึ่งในสองเหรียญ ซึ่งถ้า ปริมาณอยู่สูงกว่า ค่า Liquidity ขั้นต่ำที่คุณกำหนดไว้ มันจะส่ง เหรียญนั้นไปยัง pool และสร้าง LP token ขึ้นมายัง address ที่ได้กำหนดไว้

2) RemoveLiquidity (การนำ Liquidity ออก): ฟังก์ชั่นนี้จะคล้ายกับ AddLiquidity แต่จะมีความแตกต่างที่จะ ใช้กับการนำ liquidity ออกมาจาก pool ที่มีอยู่แล้ว โดยการกำหนด input จะประกอบไปด้วย
- address ของเหรียญทั้งของ
- ปริมาณของ LP token ที่ึคุณอยากทำลาย (burn)
- ปริมาณขั้นต่ำที่คุณอยากได้รับ
- address ของผู้รับและผู้ถอน
- deadline (ใน UNIX timestamp)
หลังจากการตรวจสอง ฟังก์ชั่นจะคืน LP token ให้กับ pool (เพื่อจะนำไป burn ต่อ) และ เคลื่อนย้าย เหรียญใน pool ไปยัง address ที่กำหนด

3) SwapExactTokensForTokens (การ Swap token): ฟังก์ชั่นนี้มีขึ้นเพื่อตามชื่อของมัน คือการ swap token โดยจะคำนวณ และ ถอน จำนวนเหรียญ ตาม input ที่ใส่ ยกตัวอย่างเช่น pool หนึ่ง ประกอบไปด้วย tokenA และ tokenB สูตรคือ tokenA * tokenB = k ปริมาณ tokenB ที่ผู้ใช้งานอยากจะถอนออกจาก pool (tokensBout) เพื่อแลกกับ tokenAที่เข้ามา จะถูกคำนวณได้จากสมการดังต่อไปนี้

4) SwapTokensForExactTokens (การ Swaptoken เพื่อการฝาก): ฟังก์ชั่นนี้จะคำนวณปริมาณเหรียญที่ต้องฝากเข้าไปเพื่อถอนเหรียญจำนวนหนึ่งออกมา ตัวอย่างเช่น pool หนึ่ง ประกอบไปด้วย tokenA และ tokenB สูตรคือ tokenA * tokenB = k ปริมาณ tokenA ที่ผู้ใช้จะต้องฝากเข้ามายัง pool (tokensAin) เพื่อการถอน tokenB ออก (tokensBout) จะถูกคำนวณด้วยสมการดังนี้

ฟังก์ชั่นที่ได้กล่าวไปด้านบน จะมี ฟังก์ชั่นอื่นๆที่ใกล้เคียงกันอยู่ แต่ใน pool ที่มีเหรียญ ETH เป็นหนึ่งใน 2 เหรียญ (ที่ถูก wrapped เป็น WETH) จะต้องให้ผู้ใช้ ทำการส่งเหรียญ ETH และ contract จะดำเนินการต่อกับ WETH smart contract ผ่านการ สร้างเหรียญ (minting) ทำลายเหรียญ (burining) หรือการเคลื่อนย้ายเหรียญ (transferring)

Uniswap V2 Pair
จะเป็นตัวแทน liquidity pool ด้วยตัวมันเอง และคุณสามารถหามันเจอผ่านลิงค์ด้านล่าง มันจะถือเหรียญ ERC20, รวมถึงการ mint หรือ burn เหรียญ liquidity หรือสรุปสั้นๆคือทำจะจัดการกับทุกกระบวนการใน liquidity pool

เพื่อยกตัวอย่างการประกาศการใช้งาน แอพพลิเคชั่นที่เป็น Ethereum-based ไปยัง Moonbeam และ การระหว่างที่เรากำลังสร้าง tutorial เพื่ออธิบายมัน เราได้ให้ตัวอย่างของ การใช้ Uniswap บน Moonbean Alpha หรือ Moonbeam TestNet

การนำ Uniswap V2 ไปยัง Moonbeam จะประกอบไปด้วย 3 ขั้นตอน คือ การประกาศ contract, การสร้างหน้า interface, และการปรับแต่ง SDK

การประกาศ contract จะเป็นอะไรที่ตรงไปตรงมา โดยไม่ต้องมีการปรับแต่งอะไรเลยในของ protocol แต่อย่างไรก็ตาม เพราะว่า create2 opcode (ดูตัวอย่างก่อนหน้า) และไม่ใช่ Moonbeam เอง การเปลี่ยนแปลงเล็กน้อยยังจำเป็นจะต้องถูกทำ (อ่านรายละเอียดเพิ่มเติมตาม blog post นี้)

หน้า interface และ SDK ถูกทำขึ้นเพื่อสนับสนุน chain ID ของ Moonbeam standalone node และ Moonbeam Alpha TestNet รวมถึง contract address ใหม่จะต้องถูกใส่ลงไปใน code

เวอร์ชั่นของ interface ที่ถูกใช้งานจะถูกแสดงที่ลิ้งค์นี้ ในหน้า interface นั้น จะใช้งานกับ Moonbase Alpha และ standalone node ผ่าน MetaMask (อ่านใน section ถัดไปเกี่ยวกับ standalone node)

หาก “Moonbeam-swap” ถูกต่อเข้ากับ network ที่ถูกต้อง (ในกรณีนี้คือ standalone node) ผ่าน MetaMask คุณจะเห็นหน้าจอดังต่อไปนี้

หากคุณเคยใช้งาน Uniswap V2 เวอร์ชั่น classic หน้าจอต่อไปนี้จะมีความคล้ายกัน จากนี้ต่อไป เราจะสามารถ swap tokens, สร้าง pools, และ เพิ่ม/ลด liquidity จาก pool ที่มีอยู่แล้ว ซึ่งในกรณีนี้มาลองเริ่มสร้าง pool ใหม่ ที่ประกอบไปด้วยเหรียญ ERC20 สองเหรียญ” Token1 และ Token2

ไปยัง “Pool” menu และ คลิกที่ปุ่ม “Add Liquidity” โดยคุณจะสร้างรายชื่อของ เหรียญ (ลิสสำหรับ standalone node) แต่ถ้าหากเหรียญของคุณไม่ได้ถูกลิส คุณจะใส่มันเข้าไปผ่านการ paste address ที่คุณสามารถไปคัดลอกมาได้ ผ่าน search bar ด้านบน

เมื่อคุณเลือกเหรียญเสร็จแล้ว ให้ใส่จำนวณเหรียญที่คุณอยากใส่เข้าไป เพื่อเป็น Liquidity ขั้นต้น (จำไว้ว่า สิ่งนี้จะ set ราคาการซื้อขาย)

ถัดไป คุณจะต้องกด approve Router V2 เพื่อเป็นตัวใช้งานเหรียญ ERC20 ซึ่งจะทำผ่าน transaction เมื่อคุณกดปุ่ม “Approve” ของแต่ละเหรียญ โดย Transaction จะถูก signed ด้วย MetaMask

เมื่อ การบวนการ การ Approve ได้ถูก verify ผ่านทั้งสองเหรียญ ปุ่ม “Supply” จะถูก Enable ให้ใช้งานได้ ให้กดปุ่มนี้และ ยืนยัน ว่ารายละเอียดของ pool นั้นถูกต้อง และเลือก “Creat Pool & Supply” จากนั้นให้กดยืนยัน transaction

เมื่อ transaction ถูกคอนเฟิร์ม pool ของคุณจะถูกแสดงขึ้นมา ในแถบ “Pools” โดยถ้า กดที่มัน จะทำให้รายละเอียดถูกแสดงขึ้นมา และมีปุ่ม เพิ่ม หรือ ลด liquidity ถ้าหาก pool ไม่แสดงขึ้นมา ให้กด refresh และ รอประมาณ 1 นาที ก่อนจะกดอีกครั้ง คุณสามารถใช้ตัวเลือก “import pool” ที่ส่วนด้านล่างของแถบ “Pool”

เมื่อ pool ได้ถูก set เรียบร้อยแล้ว คุณสามารถที่จะเริ่ม swap token และ ลองใช้งาน interface นี้ได้

ขั้นตอนดังต่อไปนี้ สามารถที่จะทำได้ใน Moonbase Alpha แต่ก่อนอื่นจะต้อง deploy เหรียญ ERC20 token ของคุณก่อน

--

--

No responses yet