Technical Report · ECOSUS CO., LTD. · TR-2026-012 EN JP TH
TR-2026-012

gyotak-catch v3

GPS Hiding Commitment & Independent On-Chain Verification Hiding Commitment ของ GPS และการตรวจสอบอิสระบนเชน

From brute-forceable hash to hiding commitment — and an MCP tool that lets any AI verify it · Preprod · 2026-07 จากแฮชที่ถอดรหัสได้ด้วย brute force สู่ hiding commitment — และเครื่องมือ MCP ให้ AI ตรวจสอบอิสระ · Preprod · ก.ค. 2569
✓ Mainnet Deployed / Preprod VerifiedDeploy บน Mainnet แล้ว / ตรวจสอบบน Preprod แล้ว
Dateวันที่
2026-07-11
Layer
Catch Provenance (GPS Privacy)พิสูจน์แหล่งจับ (ความเป็นส่วนตัว GPS)
Statusสถานะ
Preprod verified · Mainnet deployedตรวจสอบบน Preprod แล้ว · Deploy บน Mainnet แล้ว
Classหมวดหมู่
Public Defensive Publicationการเผยแพร่เชิงป้องกัน
Contract (Preprod)คอนแทรกต์ (Preprod)
2e519c34…
Abstract / 要旨 / บทคัดย่อ
GYOTAK’s v2 catch contract stored GPS as persistentHash(GPS) — a bare hash with no nonce. Because GPS coordinates have finite precision, this hash is reversible by brute force. We confirmed the exposure: recomputing the hash from known coordinates matched the on-chain value for 64 of 66 mainnet records. v3 replaces the bare hash with a hiding commitment — persistentCommit(GPS, secret_nonce) — making GPS recovery computationally infeasible. The region is still provable via ZK range checks against a public bounding box. To let third parties verify without trusting GYOTAK, we deployed verify_catch as an MCP tool: it reads on-chain state directly from the Midnight indexer, returns raw bytes plus decoded fields, and never touches GYOTAK’s database. An end-to-end test from Claude Desktop confirmed that the AI recovered region and fish species from the chain, and correctly concluded that GPS is not recoverable.
สัญญาจับปลา v2 ของ GYOTAK เก็บ GPS เป็น persistentHash(GPS) — แฮชโดยไม่มี nonce เนื่องจากพิกัด GPS มีความแม่นยำจำกัด แฮชนี้สามารถย้อนกลับได้ด้วย brute force เรายืนยันการรั่วไหล: การคำนวณแฮชใหม่จากพิกัดที่รู้ตรงกับค่าบนเชนสำหรับ 64 จาก 66 รายการบน mainnet v3 แทนที่แฮชด้วย hiding commitment — persistentCommit(GPS, secret_nonce) — ทำให้การกู้คืน GPS เป็นไปไม่ได้ในเชิงการคำนวณ ภูมิภาคยังคงพิสูจน์ได้ผ่าน ZK range check กับ bounding box สาธารณะ เพื่อให้บุคคลที่สามตรวจสอบโดยไม่ต้องเชื่อถือ GYOTAK เราเปิดตัวเครื่องมือ MCP verify_catch: อ่าน state บนเชนจาก Midnight indexer โดยตรง ส่งคืนไบต์ดิบพร้อมฟิลด์ที่ถอดรหัสแล้ว และไม่เข้าถึงฐานข้อมูลของ GYOTAK การทดสอบจาก Claude Desktop ยืนยันว่า AI กู้คืนภูมิภาคและชนิดปลาจากเชน และสรุปอย่างถูกต้องว่า GPS ไม่สามารถกู้คืนได้

1. Background — Why v2 Was Superseded 1. ภูมิหลัง — ทำไม v2 ถูกแทนที่

gyotak-catch v2 stored the catch location as gpsHash = persistentHash(GPS), with no random nonce. Because GPS coordinates have finite precision (typically 7 decimal places ≈ 1 cm), a hash without a nonce can be reversed by brute force over the plausible coordinate space. gyotak-catch v2 เก็บตำแหน่งจับปลาเป็น gpsHash = persistentHash(GPS) โดยไม่มี random nonce เนื่องจากพิกัด GPS มีความแม่นยำจำกัด (ทศนิยม 7 ตำแหน่ง ≈ 1 ซม.) แฮชที่ไม่มี nonce สามารถถอดรหัสด้วย brute force ได้

We confirmed the exposure against live mainnet data: recomputing persistentHash from the GPS coordinates stored in GYOTAK’s database reproduced the on-chain gpsHash for 64 of 66 records (the remaining 2 are early test records with no GPS). Because no nonce is present, a third party who does not hold the coordinates can also recover them by brute force — demonstrated on preprod, where a 10,201-point search over the district recovered the coordinates of one record. เรายืนยันการรั่วไหลกับข้อมูล mainnet จริง: คำนวณ persistentHash ใหม่จากพิกัด GPS ในฐานข้อมูล GYOTAK แล้วเทียบกับ gpsHash บนเชน ตรงกัน 64 จาก 66 รายการ (2 รายการที่เหลือเป็นรายการทดสอบเริ่มต้นที่ไม่มี GPS) เนื่องจากไม่มี nonce บุคคลที่สามที่ไม่มีพิกัดก็สามารถกู้คืนได้ด้วย brute force — สาธิตบน preprod โดยค้นหา 10,201 จุดทั่วอำเภอเพื่อกู้คืนพิกัดของหนึ่งรายการ

The problem:ปัญหา: The location of a fishing ground is a core business asset. A traceability system that silently leaks it defeats its own purpose. v2 leaked it. ตำแหน่งแหล่งจับปลาเป็นทรัพย์สินหลักของธุรกิจ ระบบตรวจสอบย้อนกลับที่แอบรั่วไหลข้อมูลนี้ทำลายจุดประสงค์ของตัวเอง v2 รั่วไหล

2. The v3 Design 2. การออกแบบ v3

v3 changes two things: v3 เปลี่ยนสองสิ่ง:

1. GPS is hidden with a commitment, not a bare hash:1. GPS ถูกซ่อนด้วย commitment ไม่ใช่แฮชเปล่า:

gpsCommitment = persistentCommit(GPS, secret_nonce)

The nonce is 32 random bytes, never written on-chain. Without it, the commitment reveals nothing about the coordinates. Nonce เป็น 32 ไบต์สุ่ม ไม่เคยเขียนบนเชน หากไม่มี nonce commitment จะไม่เปิดเผยอะไรเกี่ยวกับพิกัด

2. The region is proven, not asserted:2. ภูมิภาคถูกพิสูจน์ ไม่ใช่แค่ประกาศ:

assert gps.lat >= latMin    // south boundary
assert gps.lat <= latMax    // north boundary
assert gps.lon >= lonMin    // west boundary
assert gps.lon <= lonMax    // east boundary
gpsCommitment == persistentCommit(gps, nonce)

The bounding box (latMin..lonMax) is a public argument, taken verbatim from OpenStreetMap Nominatim administrative boundaries. regionLabel (e.g. “Pran Buri, Prachuap Khiri Khan”) is a display-only label; the circuit does not prove the label, it proves the coordinates lie inside the box. Bounding box (latMin..lonMax) เป็นอาร์กิวเมนต์สาธารณะ นำมาจากเขตแดนการปกครองของ OpenStreetMap Nominatim regionLabel (เช่น “Pran Buri, Prachuap Khiri Khan”) เป็นป้ายแสดงเท่านั้น วงจรไม่ได้พิสูจน์ป้าย แต่พิสูจน์ว่าพิกัดอยู่ภายในกล่อง

Preprod verification: ผลการตรวจสอบ Preprod:

Testทดสอบ Resultผลลัพธ์
GPS inside bounding boxGPS ภายในกล่อง PASS — record written on-chainบันทึกบนเชน
GPS in Tokyo against Pran Buri boxGPS ที่โตเกียว กับกล่อง Pran Buri REJECTED — “GPS latitude above maximum” at proof generation; tx never reaches chain“GPS latitude above maximum” ที่การสร้าง proof; tx ไม่ถึงเชน
Same GPS, two different noncesGPS เดียวกัน nonce ต่างกัน 2 ตัว PASS — two different commitments (hiding property confirmed)commitment ต่างกัน 2 ค่า (ยืนยัน hiding property)

3. Independent Verification via MCP 3. การตรวจสอบอิสระผ่าน MCP

3.1 Why a document alone is not enough 3.1 ทำไมเอกสารเพียงอย่างเดียวไม่เพียงพอ

A chat AI given only a decoding guide cannot verify anything, because it cannot issue the GraphQL query to fetch the on-chain state. In our test, one chat model, unable to fetch, produced a fabricated region and fish species (a hallucination). A verifier needs a way to actually read the chain. AI แชทที่ได้รับเฉพาะคู่มือถอดรหัสไม่สามารถตรวจสอบอะไรได้ เพราะไม่สามารถส่ง GraphQL query เพื่อดึง state บนเชน ในการทดสอบ โมเดลแชทหนึ่งที่ไม่สามารถดึงข้อมูลได้สร้างภูมิภาคและชนิดปลาปลอมขึ้นมา (hallucination) ผู้ตรวจสอบต้องมีวิธีอ่านเชนจริง ๆ

3.2 The verify_catch MCP tool 3.2 เครื่องมือ MCP verify_catch

GYOTAK added verify_catch to its existing MCP server (registered on Smithery). The tool: GYOTAK เพิ่ม verify_catch ในเซิร์ฟเวอร์ MCP ที่มีอยู่ (ลงทะเบียนบน Smithery) เครื่องมือนี้:

3.3 End-to-end demonstration (preprod) 3.3 การสาธิตจากต้นจนจบ (preprod)

A real transaction was recorded on preprod, then verified from Claude Desktop through the GYOTAK MCP server — without trusting GYOTAK’s database. ธุรกรรมจริงถูกบันทึกบน preprod จากนั้นตรวจสอบจาก Claude Desktop ผ่านเซิร์ฟเวอร์ GYOTAK MCP — โดยไม่เชื่อถือฐานข้อมูลของ GYOTAK

record:   CR-TESTV3-INSIDE-02
contract: 2e519c349331a6aaee82a7ed31aa5e39d6a3995f6cf85ec2256c97cda9a8c302
tx:       b32f3328a0e1ac73adf41ce3ac665626b7a98f9e921ce7885a52b83e83ad078a
block:    1602801
network:  preprod
Fieldฟิลด์ Resultผลลัพธ์
Region✓ Pran Buri, Prachuap Khiri Khan — recovered from on-chain stateกู้คืนจาก state บนเชน
Fish✓ Kuro-Aji-Modoki 1.28 kg, He-Dai 0.5 kg
Photo hash✓ 80938b94… — tamper check availableตรวจสอบการปลอมแปลงได้
GPS✗ Hidden as persistentCommit (f50ef64d…) — NOT recoverable. Only “within Pran Buri district” is provable.ซ่อนด้วย persistentCommit (f50ef64d…) — กู้คืนไม่ได้ พิสูจน์ได้เฉพาะ “ภายในอำเภอปราณบุรี”
The AI read the region and fish species directly from the Midnight chain, and correctly concluded that the exact GPS cannot be recovered. This is verification against on-chain fact, not against GYOTAK’s word. AI อ่านภูมิภาคและชนิดปลาจากเชน Midnight โดยตรง และสรุปอย่างถูกต้องว่า GPS ที่แน่นอนไม่สามารถกู้คืนได้ นี่คือการตรวจสอบกับข้อเท็จจริงบนเชน ไม่ใช่กับคำพูดของ GYOTAK

As of 2026-07-11, the v3 contract is also deployed and live on Midnight mainnet (contract: bc33d8c05852decd4ef183201a8a9f3c25eabaa46a81786f306b95397ed118ab). It currently holds no records; the first will be inscribed with the next real catch. The demonstration above was performed on preprod, where test records were freely created; mainnet carries no test records. ณ วันที่ 2026-07-11 สัญญา v3 ยังถูก deploy และใช้งานบน Midnight mainnet ด้วย (คอนแทรกต์: bc33d8c05852decd4ef183201a8a9f3c25eabaa46a81786f306b95397ed118ab) ปัจจุบันยังไม่มีรายการ รายการแรกจะถูกจารึกเมื่อจับปลาจริงครั้งถัดไป การสาธิตข้างต้นดำเนินการบน preprod ซึ่งสร้างรายการทดสอบได้อย่างอิสระ mainnet ไม่มีรายการทดสอบ

4. How to Verify Yourself 4. วิธีตรวจสอบด้วยตัวเอง

Path A — MCP-capable AI agent (recommended) Path A — AI agent ที่รองรับ MCP (แนะนำ)

  1. Connect the GYOTAK MCP server (Smithery: gyotak-fish-market, or https://line-harness.gyotak.workers.dev/mcp)
  2. Ask: “verify catch record CR-TESTV3-INSIDE-02”
  3. The agent calls verify_catch, fetches on-chain state, and reports region / fish / whether GPS is recoverable.
  1. GYOTAK MCPサーバーに接続する(Smithery: gyotak-fish-market、または https://line-harness.gyotak.workers.dev/mcp)
  2. 質問: 「catch record CR-TESTV3-INSIDE-02 を検証して」
  3. エージェントが verify_catch を呼び、オンチェーンstateを取得し、地域・魚種・GPSが復元可能かを報告する。
  1. เชื่อมต่อเซิร์ฟเวอร์ GYOTAK MCP (Smithery: gyotak-fish-market หรือ https://line-harness.gyotak.workers.dev/mcp)
  2. ถาม: “verify catch record CR-TESTV3-INSIDE-02”
  3. Agent เรียก verify_catch ดึง state บนเชน และรายงานภูมิภาค / ปลา / GPS กู้คืนได้หรือไม่

Path B — Manual GraphQL + state decode Path B — GraphQL ด้วยตนเอง + ถอดรหัส state

  1. Query the Midnight indexer:
    preprod: https://indexer.preprod.midnight.network/api/v4/graphql
    mainnet: https://indexer.mainnet.midnight.network/api/v4/graphql
    query { contractAction(address:"<contract>") { state } }
  2. Decode the state bytes: scan for the 0x01 separator between 32-byte gpsCommitment and 32-byte photoHash. After photoHash, read length-prefixed strings: regionLabel, catchDate, fishSpecies, fishManifest (10 slots).
  3. GPS cannot be recovered from gpsCommitment without the secret nonce.
  1. Midnight indexerにクエリ:
    preprod: https://indexer.preprod.midnight.network/api/v4/graphql
    mainnet: https://indexer.mainnet.midnight.network/api/v4/graphql
    query { contractAction(address:"<contract>") { state } }
  2. stateバイトをデコード: 32バイトの gpsCommitment と32バイトの photoHash の間の 0x01 セパレータをスキャンする。photoHash以降は長さプレフィクス付き文字列: regionLabel, catchDate, fishSpecies, fishManifest(10スロット)を読む。
  3. 秘密ノンスなしでは gpsCommitment からGPSを復元できない。
  1. Query Midnight indexer:
    preprod: https://indexer.preprod.midnight.network/api/v4/graphql
    mainnet: https://indexer.mainnet.midnight.network/api/v4/graphql
    query { contractAction(address:"<contract>") { state } }
  2. ถอดรหัสไบต์ state: สแกนหา separator 0x01 ระหว่าง gpsCommitment 32 ไบต์ และ photoHash 32 ไบต์ หลัง photoHash อ่านสตริงที่มี length prefix: regionLabel, catchDate, fishSpecies, fishManifest (10 สล็อต)
  3. ไม่สามารถกู้คืน GPS จาก gpsCommitment ได้หากไม่มี secret nonce
Note:หมายเหตุ: Handing a chat AI only these steps will not work — it cannot fetch the state. Use an MCP-capable agent (Path A) or a tool that can actually issue the query. การให้ AI แชทเฉพาะขั้นตอนเหล่านี้จะไม่ทำงาน — มันไม่สามารถดึง state ได้ ใช้ agent ที่รองรับ MCP (Path A) หรือเครื่องมือที่สามารถส่ง query ได้จริง

5. Scope & Limitations 5. ขอบเขตและข้อจำกัด

6. Archive Metadata 6. Metadata

Fieldฟิลด์ Valueค่า
Document IDECOSUS-TR-2026-012
Publisherผู้เผยแพร่ ECOSUS CO., LTD. · 0205562030631 · Pranburi, Thailand
Classหมวดหมู่ Public Defensive Publication
Licenseใบอนุญาต CC BY 4.0
Dateวันที่ 2026-07-11
Prior Reportรายงานก่อน TR-2026-011 · gyotak-temp-log Cold-Chain ZKP
Relatedที่เกี่ยวข้อง MCP Server · Smithery · Endpoint
Authorผู้เขียน Takuya Ogura, Chairman, ECOSUS CO., LTD.
Archiveจัดเก็บ (Perma.cc — assigned at publication)(Perma.cc — กำหนดเมื่อเผยแพร่)