Polymarket Bot Tutorial · บทที่ 9 จาก 32

อ่าน Polymarket on-chain data โดยตรง: ยอดคงเหลือ USDC/pUSD, การอ่านสัญญา CTF สำหรับอุปทานของ outcome, UMA Optimistic Oracle proposed/disputed events และ Polygon transaction logs - พร้อม code.

บทนี้ครอบคลุมอะไรบ้าง

Polymarket's APIs สะดวก แต่ในที่สุดข้อมูลจะสอดคล้องตามเวลาแบบ eventual consistency. chain คือแหล่งอ้างอิงหลัก. บทนี้จะพาคุณอ่าน on-chain ที่ production bot ใช้เพื่อตรวจสอบบัญชีของตัวเอง: pUSD balances, outcome-token inventory, UMA dispute events และ CTF contract state. รูปแบบที่ production bots ส่วนใหญ่ลงเอยด้วยคือใช้ API เป็นหลักเพื่อความเร็ว พร้อมทำ on-chain reconciliation เป็นระยะเพื่อความถูกต้อง.

  • สิ่งที่อยู่ on-chain (vs in CLOB)
  • ที่อยู่ contract และ ABI ของ pUSD
  • Conditional Tokens Framework (CTF)
  • UMA Optimistic Oracle: proposed และ disputed events
  • การอ่าน Polygon event logs (web3.py / ethers)
  • เมื่อใดควรอ่าน on-chain vs เชื่อถือ API
  • Code: ตรวจจับ UMA dispute ผ่าน event subscription

สิ่งที่อยู่ on-chain (vs in CLOB)

สอง state machines สองความจริง.

On-chain (Polygon): ยอดคงเหลือ pUSD, outcome-token inventory (ERC-1155 supply ต่อ token), allowance approvals, UMA Optimistic Oracle proposals และ disputes, deposit และ withdrawal events. สุดท้ายจะถูกต้องตามจริง; latency คือ Polygon block หนึ่งบล็อก (~2 วินาที).

CLOB (Polymarket API): order book, recent trades, pending limit orders, match acknowledgments. แบบเรียลไทม์แต่ eventual consistent-match จะถูกยืนยันก่อนที่ ERC-1155 จะ settle ซึ่งก่อให้เกิดปัญหา phantom-fill ที่อธิบายในบทที่ 12.

ทั้งสองฝั่งควร converge เสมอ. เมื่อมัน diverge, chain คือแหล่งอ้างอิงหลัก. bot ที่เชื่อแต่ CLOB จะค่อย ๆ เพี้ยน; bot ที่เชื่อแต่ chain จะเทรดช้า. production code ใช้ทั้งสองอย่าง: CLOB สำหรับการตัดสินใจที่ต้องการความเร็ว และ chain สำหรับ reconciliation เป็นระยะ.

ที่อยู่ contract และ ABI ของ pUSD

pUSD คือ stablecoin wrapper ของ Polymarket ที่ใช้ตั้งแต่การ migration ไป V2 ในปี 2025. contract ที่ 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB บน Polygon mainnet เป็นมาตรฐาน ERC-20.

reads สำคัญ 3 รายการสำหรับ bot:

  • balanceOf(proxy)-pUSD ที่คุณใช้จ่ายได้จริง เปรียบเทียบกับมุมมองยอดคงเหลือของ CLOB ทุกครั้งที่รีสตาร์ต.
  • allowance(proxy, exchange_contract)-ตรวจสอบว่า contract ของ CTF/NegRisk exchange สามารถใช้ pUSD ของคุณได้หรือไม่. จำเป็นสำหรับการจับคู่คำสั่งซื้อขาย.
  • Transfer event subscription-ตรวจจับ deposit และ withdrawal โดยไม่ต้อง polling.

USDC (0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174) ยังคงเป็น pair สำหรับ off-ramp. bot ส่วนใหญ่ต้องอ่าน pUSD เท่านั้น; USDC มีความสำคัญเฉพาะช่วง deposit/withdrawal.

Conditional Tokens Framework (CTF)

Outcome shares คือ ERC-1155 tokens ที่ mint โดย Conditional Tokens Framework (CTF) ของ Gnosis. contract CTF บน Polygon ที่ 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045 ติดตาม supply แยกตาม position-id.

reads สามรายการ:

  • balanceOf(proxy, position_id)-คุณถือ outcome tokens ของ market+outcome นั้นจริง ๆ กี่ token.
  • getOutcomeSlotCount(condition_id)-จำนวน outcomes (2 สำหรับ binary, N สำหรับ multi-outcome).
  • payoutNumerators, payoutDenominator-ถูกตั้งค่าเมื่อ UMA resolve market. การอ่านค่านี้ช่วยบอกว่าฝั่งไหนชนะก่อนที่ UI ของ CLOB จะอัปเดต.

position_id คือ hash ของ (condition_id, outcome_index). คำนวณฝั่ง client ได้ผ่าน helper getPositionId ของ CTF หรือจะทำ keccak math เองใน stack ของคุณก็ได้.

UMA Optimistic Oracle: proposed และ disputed events

Optimistic Oracle (OO) ของ UMA จัดการการ resolve dispute ของ Polymarket ทั้งหมด. มี 2 events ที่ bot ของคุณอาจต้อง subscribe.

  • ProposePrice(requester, identifier, timestamp, ancillaryData, proposer, proposedPrice)-ถูกยิงเมื่อ Polymarket bot เสนอ outcome.
  • DisputePrice(requester, identifier, timestamp, ancillaryData, disputer)-ถูกยิงเมื่อมีคนคัดค้าน outcome ที่เสนอไว้.

OO contract address: 0xeE3Afe347D5C74317041E2618C49534dAf887c24. กรองตาม Polymarket's requester address.

ทำไมต้อง subscribe: dispute หมายความว่าการ resolve ถูกโต้แย้งแล้ว และจะต้องใช้เวลาโหวตบน UMA 24-72 ชั่วโมง. ระหว่างช่วงนั้น market อาจถูก pause สำหรับการเทรด. bot ที่ถือสถานะใน market ที่มี dispute ควรรู้ทันที.

การอ่าน Polygon event logs (web3.py / ethers)

สอง reference implementations.

Python (web3.py):

from web3 import Web3
w3 = Web3(Web3.HTTPProvider(POLYGON_RPC))
ctf = w3.eth.contract(address=CTF_ADDR, abi=CTF_ABI)
filter = ctf.events.PayoutRedemption.create_filter(fromBlock="latest")
for event in filter.get_new_entries():
    print(event["args"])

Node (ethers v6):

import { ethers } from "ethers";
const p = new ethers.JsonRpcProvider(POLYGON_RPC);
const ctf = new ethers.Contract(CTF_ADDR, CTF_ABI, p);
ctf.on("PayoutRedemption", (redeemer, collateral, parentId, conditionId) => {
  console.log("redemption", { redeemer, conditionId });
});

สำหรับการ monitoring ต่อเนื่อง ให้ใช้ WebSocket transport (wss://...) แทน HTTP polling-requests น้อยลงและส่งข้อมูลได้เร็วขึ้น. ผู้ให้บริการ RPC แบบเสียเงินส่วนใหญ่มี WebSocket ในแพ็กเกจเริ่มต้น.

เมื่อใดควรอ่าน on-chain vs เชื่อถือ API

กฎเชิงปฏิบัติจาก production.

  • เชื่อถือ API สำหรับ: real-time order book, recent trades, pending orders ของคุณเอง, market metadata (slug, question, end date), event/market discovery.
  • เชื่อถือ chain สำหรับ: ยอดคงเหลือ pUSD ของคุณเอง, outcome-token inventory ของคุณเอง, การยืนยัน deposit และ withdrawal, resolution outcomes, dispute state.
  • ตรวจสอบทั้งสองฝั่ง สำหรับ: เรื่องการเงินใด ๆ ที่ bot บันทึกว่าเป็น fill-ให้ match "matched" event ของ API กับ CTF transfer บน chain เพื่อยืนยัน settlement.

กฎการรอ 5 วินาทีหลังซื้อ (บทที่ 12) คือความจริงของ on-chain ที่แทรกเข้ามาในเวลาแบบ API. GTC sell ที่ส่งทันทีหลัง market buy จะเห็น balance: 0 จากการตรวจ chain แม้ว่า CLOB จะ match ไปเมื่อสักครู่นี้แล้วก็ตาม.

Code: ตรวจจับ UMA dispute ผ่าน event subscription

Reference: เฝ้าดู UMA disputes ที่เกี่ยวข้องกับ Polymarket แบบเรียลไทม์.

from web3 import Web3
w3 = Web3(Web3.WebsocketProvider(POLYGON_WSS))
oo = w3.eth.contract(address=UMA_OO_ADDR, abi=UMA_ABI)
POLY_REQUESTER = "0x..."  # Polymarket's UMA requester address

def on_dispute(event):
    args = event["args"]
    if args["requester"].lower() != POLY_REQUESTER.lower(): return
    print(f"DISPUTE on Polymarket market: ancillary={args['ancillaryData'][:40]}...")
    # decode ancillaryData to recover the market question

event_filter = oo.events.DisputePrice.create_filter(fromBlock="latest")
while True:
    for ev in event_filter.get_new_entries():
        on_dispute(ev)
    time.sleep(2)

ฟิลด์ ancillaryData เป็นข้อความแบบ hex-encoded ที่มีลักษณะคล้าย JSON และเก็บ market question อยู่. การ decode มันจะให้ identifier ที่เทียบเท่า slug เพื่อใช้ cross-reference กับ open positions ของคุณ.

คำถามที่พบบ่อย

ฉันจะหา Polymarket pUSD contract ได้ที่ไหน?
pUSD อยู่ที่ 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB บน Polygon. มันแทนที่ USDC.e ในฐานะหลักประกัน canonical collateral ของ Polymarkets เมื่อวันที่ 28 เมษายน 2026. ลิงก์ Polygonscan: https://polygonscan.com/token/0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB.
CTF contract บน Polymarket คืออะไร?
CTF ย่อมาจาก Conditional Tokens Framework - contract ERC-1155 ที่สืบทอดมาจาก Gnosis ซึ่งออก outcome tokens (YES และ NO shares ที่คุณเทรด). แต่ละ Polymarket market คือ CTF position ที่ logic การ redeem ผูกกับการ resolve ของ UMA. bot แทบไม่ต้องโต้ตอบกับ CTF โดยตรง; SDK จัดการให้.
ฉันจะ subscribe UMA dispute events บน Polygon ได้อย่างไร?
Subscribe ไปที่ UMA Optimistic Oracle V2 contract`s "ProposePrice" และ "DisputePrice" events ผ่าน WebSocket ของ Polygon RPC provider ของคุณ. กรองด้วยฟิลด์ requesterAddress (oracle adapter ของ Polymarkets) เพื่อให้ได้เฉพาะ disputes ที่เกี่ยวกับ Polymarket. มี code samples อยู่ในบทนี้.
ฉันจำเป็นต้องอ่าน on-chain data ถ้าเชื่อ Polymarket API อยู่แล้วไหม?
สำหรับกลยุทธ์ส่วนใหญ่ ไม่จำเป็น. CLOB API คือแหล่งอ้างอิงหลักสำหรับ order book และ trade data และ gamma API คือแหล่งอ้างอิงหลักสำหรับ metadata. คุณจะอ่าน on-chain เมื่อจำเป็น เช่น (a) ต้องการ UMA dispute alerts เร็วกว่าที่ API แสดง, (b) ต้องการยืนยันว่า deposit มาถึงจริง, หรือ (c) ต้องการ custom analytics บน outcomes/positions.
latency ของ on-chain Polygon data เทียบกับ Polymarket API เป็นอย่างไร?
Polygon block time อยู่ที่ ~2 วินาที. โดยทั่วไป Polymarket API จะแสดงการเปลี่ยนแปลงของ order book ภายในหลักร้อยมิลลิวินาทีหลัง on-chain match. สำหรับสัญญาณส่วนใหญ่ API เร็วกว่าการอ่าน on-chain ของคุณเอง. UMA disputes เป็นข้อยกเว้น - event บน chain จะเกิดก่อนที่ UI จะแสดง dispute.
ฉันอ่าน Polymarket positions ได้โดยไม่ใช้ CLOB API ไหม?
ในทางเทคนิคได้ - อ่าน CTF balanceOf(walletAddress, positionId) สำหรับแต่ละ position. ในทางปฏิบัติ CLOB API /trade/positions endpoint เร็วกว่า มี pricing รวมอยู่ และรวม positions ทั้งหมดของคุณไว้ด้วย. ควร fallback ไปอ่าน on-chain เฉพาะเมื่อคุณต้องการ verification หรือ API ใช้งานไม่ได้.