ในสาขาบล็อคเชน ออราเคิลเป็นระบบที่สามารถให้ข้อมูลภายนอกแก่สัญญาอัจฉริยะแบบออนเชนได้ เนื่องจากเป็นมิดเดิลแวร์ที่เชื่อมโยงสัญญาอัจฉริยะและโลกภายนอกบล็อคเชน ออราเคิลจึงมีบทบาทด้านโครงสร้างพื้นฐานที่สำคัญอย่างยิ่ง หน้าที่หลักของพวกเขาคือการจัดเตรียมข้อมูลสำหรับสัญญาอัจฉริยะในบล็อคเชน
ตัวอย่างเช่น หากเราสร้างสัญญาอัจฉริยะบนเครือข่าย Ethereum และสัญญานี้จำเป็นต้องเข้าถึงข้อมูลปริมาณการซื้อขายน้ำมันดิบในวันใดวันหนึ่ง อย่างไรก็ตาม สัญญาอัจฉริยะเองไม่สามารถรับข้อมูลนอกโลกแห่งความเป็นจริงได้ ดังนั้นจึงต้องนำไปใช้งานผ่านโอราเคิล ในกรณีนี้ สัญญาอัจฉริยะจะเขียนปริมาณการซื้อขายน้ำมันดิบในวันที่ต้องการลงในบันทึกเหตุการณ์ จากนั้นจะเริ่มกระบวนการแบบนอกเครือข่ายเพื่อตรวจสอบและสมัครใช้งานบันทึกเหตุการณ์นี้ เมื่อตรวจพบคำขอในการทำธุรกรรม กระบวนการจะส่งธุรกรรมบนเครือข่าย เรียกวิธีการที่เกี่ยวข้องของสัญญา และอัปโหลดข้อมูลปริมาณการซื้อขายน้ำมันดิบในวันที่ระบุไปยังสัญญาอัจฉริยะ
ข้อมูลจาก https://defillama.com/oracles
ลิงค์โซ่
ในบล็อคเชน Chainlink Oracle มีส่วนแบ่งการตลาดที่ใหญ่ที่สุด Chainlink คือโครงการออราเคิลแบบกระจายอำนาจที่มีบทบาทในการจัดเตรียมข้อมูลที่สร้างในโลกแห่งความเป็นจริงให้กับบล็อคเชนในวิธีที่ปลอดภัยที่สุด Chainlink ได้สร้างระบบนิเวศวงจรอันบริสุทธิ์ขึ้นรอบโทเค็น LINK โดยอาศัยแรงจูงใจทางเศรษฐกิจ โดยอิงตามการใช้งานหลักการออราเคิลขั้นพื้นฐาน Chainlink Oracle จำเป็นต้องได้รับการกระตุ้นโดยการโอนโทเค็น LINK LINK คือสัญญา ERC 677 บนเครือข่าย Ethereum ฟังก์ชันโอราเคิลที่ใช้โทเค็น LINK ERC 677 อยู่ในโหมดการร้องขอ/ตอบสนอง
transferAndCall ในโทเค็น ERC 677
โดยพื้นฐานแล้ว ออราเคิลคือฝ่ายที่เป็นผู้ให้บริการ เมื่อ ChainLink ออกแบบกรอบงาน Oracle สิ่งแรกที่นึกถึงคือผู้ใช้ Oracle จะสามารถชำระค่าธรรมเนียมบริการให้กับ Oracle ที่เป็นผู้ให้บริการได้อย่างไร อย่างไรก็ตาม เนื่องจากสัญญาโทเค็นที่เป็นเนื้อเดียวกันแบบมาตรฐาน ERC 20 ไม่สามารถตอบสนองความต้องการในการให้บริการหลังจากชำระเงินได้ ChainLink จึงได้เสนอมาตรฐานที่เหมาะสำหรับสถานการณ์บริการ Oracle - ERC 677
ตามที่คุณเห็นได้จากโค้ดด้านบน ERC 677 จริงๆ แล้วเพิ่มวิธีการ transferAndCall ตามมาตรฐาน ERC 20 วิธีการนี้จะรวมการชำระเงินและการร้องขอบริการเป็นหนึ่ง เพื่อตอบสนองความต้องการของสถานการณ์ทางธุรกิจของ Oracle
เมื่อผู้ใช้ดำเนินการ transferAndCall เพื่อโอนเงิน นอกเหนือจากการโอน ERC 20 แล้ว ระบบยังจะกำหนดด้วยว่าที่อยู่ปลายทางเป็นที่อยู่ตามสัญญาหรือไม่ หากเป็นเช่นนั้น ระบบจะเรียกวิธี onTokenTransfer ของที่อยู่ (ที่นี่ ตัวรับ ERC 677 มีเพียงวิธีเดียวเท่านั้น: onTokenTransfer)
เราสามารถไปที่ Etherscan เพื่อดูซอร์สโค้ดสัญญาของโทเค็น LINK ได้เช่นกัน: https://etherscan.io/address/0x514910771af9ca656af840dff83e8264ecf986ca#code
จะเห็นได้ว่านอกเหนือจากการตรวจสอบที่อยู่ _to หลายครั้งในระหว่างการนำไปใช้งานแล้ว LINK Token ยังสืบทอดวิธี transferAndCall ของ ERC 677 อีกด้วย หมายเหตุ: ก่อนที่จะร้องขอบริการ Oracle โปรดตรวจสอบให้แน่ใจว่า Oracle นั้นน่าเชื่อถือ เนื่องจาก Oracle ต้องการการชำระเงินก่อนที่จะให้บริการแก่ผู้บริโภค (ใครๆ ก็สามารถให้บริการออราเคิลได้)
การจำแนกประเภทความน่าเชื่อถือของ Oracle
คำขอออราเคิลแบบออนเชน
มาดูกันว่าวิธี onTokenTransfer ของสัญญา Oracle มีการใช้งานอย่างไร:
เมื่อผู้บริโภค Oracle ใช้เมธอด transferAndCall เพื่อชำระค่าธรรมเนียมและร้องขอบริการของ Oracle ที่อยู่ที่นี่คือที่อยู่ของ Oracle ที่ร้องขอ วิธี onTokenTransfer ใน Oracle จะตรวจสอบก่อนว่าการโอนเป็นโทเค็น LINK หรือไม่ (เฉพาะ LINK) ซึ่งจะเป็นการพิจารณาว่า msg.sender เป็นที่อยู่ของสัญญาโทเค็น Link หรือไม่ จากนั้นจะตรวจสอบว่าความยาวของ _data เกินขีดจำกัดสูงสุดหรือไม่ ในที่สุดมันจะกำหนดว่ามีตัวเลือกฟังก์ชันที่เริ่มต้นด้วย oracleRequest ใน _data หรือไม่ แน่นอนว่าตัวเลือกฟังก์ชันที่นี่สามารถปรับแต่งได้ตามบริการที่ Oracle ให้ไว้ ไม่จำเป็นต้องเป็น oracleRequest ขึ้นอยู่กับว่า Oracle เปิดเผยอินเทอร์เฟซประเภทใด
เมื่อส่งตัวปรับเปลี่ยนทั้งหมดเหล่านี้แล้ว ให้ตรวจสอบว่าตัวเรียกฟังก์ชันปัจจุบันและจำนวนการโอนเป็นแบบเดียวกันกับใน _data หรือไม่ หลังจากผ่านการตรวจสอบความปลอดภัยทั้งหมดแล้ว สัญญา Oracle ปัจจุบันจะถูกเรียกผ่าน Delegatecall แน่นอน เนื่องจากเราได้ตรวจสอบตัวเลือกฟังก์ชันใน _data แล้ว จริงๆ แล้ว ก็คือวิธี oracleRequest ที่ถูกเรียกใช้
ขั้นแรก ผู้ร้องขอ Oracle และ nonce ที่ส่งโดยผู้ร้องขอจะถูกเชื่อมโยงและแฮชเป็น requestId สำหรับคำขอนี้ จากนั้นจึงตรวจสอบการแมปการมุ่งมั่นเพื่อดูว่าเป็น ID ที่ไม่ซ้ำกันหรือไม่ หากทุกอย่างเรียบร้อยดี ให้ตั้งเวลาหมดอายุ เพิ่ม requestId ลงในข้อผูกพัน และเชื่อมโยง _payment, _callbackAddress, _callbackFunctionId และ expiration เป็นค่า ที่สำคัญที่สุด คือ มีการออกเหตุการณ์ OracleRequest ซึ่งประกอบด้วยข้อมูลคำขอ _data ซึ่งเป็นข้อมูล Concise Binary Object Representation (CBOR) รูปแบบการเข้ารหัสนี้มีน้ำหนักเบาและกระชับ และสามารถเข้าใจได้ง่ายว่าเป็นรูปแบบไบนารี JSON ข้อมูลนี้อาจอยู่ในรูปแบบต่างๆ ขึ้นอยู่กับการออกแบบโหนดนอกเครือข่าย
ตัวอย่างเช่น Chainlink: ETH/USD Aggregator มีธุรกรรมที่ประกอบด้วยเหตุการณ์ OracleRequest:
ตัวอย่างเหตุการณ์ OracleRequest
จากเหตุการณ์นี้ เราจะเห็นได้ว่าตัวรวบรวมราคา ETH/USD 0xF79D6aFBb6dA890132F9D7c355e3015f15F3406F เป็นผู้ส่งคำขอข้อมูลราคาไปยัง Oracle: 0x7e94a8a23687d8c7058ba5625db2ce358bcbd244 หาก Oracle ส่งคืนข้อมูลที่ร้องขอ คุณจะพบที่อยู่สัญญาที่ส่งคืนได้: 0xF79D6aFBb6dA890132F9D7c355e3015f15F3406F ID วิธีการที่ต้องเรียก: 6 A 9705 B 4 และเวลาหมดอายุ: 1618185924
การตอบสนองของโหนดนอกโซ่
3.1 เรียกการเติมเต็ม OracleRequest นอกเครือข่าย
การตรวจสอบครั้งแรก:
onlyAuthorizedNode: ผู้เรียกใช้ฟังก์ชัน (msg.sender) จะต้องเป็นเจ้าของสัญญาหรืออยู่ในรายการที่ได้รับอนุญาต
isValidRequest: ยังคงตรวจสอบว่า requestId มีอยู่ในแมปปิ้งการมุ่งมั่นหรือไม่
เชื่อมโยงการชำระเงิน, callbackAddress, _callbackFunctionId และวันหมดอายุ และตรวจสอบว่าเป็นค่าที่สอดคล้องกันของ requestId ในแผนผังการมุ่งมั่นหรือไม่
หากผ่านการตรวจสอบทั้งหมดนี้ ค่าใช้จ่ายของการร้องขอนี้จะถูกเพิ่มลงใน withdrawableTokens เพื่อบันทึกจำนวนเงินที่สามารถถอนได้ จากนั้น _requestId จะถูกลบออกจากแผนผังความมุ่งมั่น สุดท้าย ให้คำนวณปริมาณก๊าซที่เหลือเพื่อดูว่ามากกว่า MINIMUM_CONSUMER_GAS_LIMIT หรือไม่ ซึ่งเป็นปริมาณก๊าซขั้นต่ำที่จำเป็นในการดำเนินการฟังก์ชันการโทรกลับของสัญญาที่ออกคำขอ
หากผ่านการตรวจสอบทั้งหมดข้างต้นแล้ว ฟังก์ชันการโทรกลับของสัญญาผู้ร้องขอจะถูกเรียกอย่างเป็นทางการในรูปแบบการโทร
การตอบสนองต่อคำร้องขอควรจะรวดเร็วที่สุดเท่าที่จะเป็นไปได้ ดังนั้นจึงขอแนะนำให้ใช้บริการโหนดของ ZAN ( https://zan.top/home/node-service?chInfo=ch_WZ ) เพื่อปรับปรุงความเร็วในการตอบสนอง คุณสามารถค้นหาลิงก์ RPC ที่สอดคล้องกันในคอนโซลบริการโหนดเพื่อเพิ่มความเร็วในการส่งธุรกรรมนอกเครือข่าย
3.2 ฟังก์ชันการโทรกลับ
ก่อนหน้านี้เราได้เรียนรู้จาก oracleRequest ว่า ID ของฟังก์ชันคอลแบ็กคือ 6 A 9705 B 4 และวิธีการคือ chainlinkCallback (bytes 32, int 256
validateChainlinkCallback เป็นฟังก์ชันที่ปรับแต่งได้ นี่คือตัวปรับเปลี่ยน:
ตรวจสอบใน pendingRequests ว่า _requestId ตรงกับโอราเคิลที่ร้องขอหรือไม่ และปล่อยเหตุการณ์ ChainlinkFulfilled:
หากผ่านการตรวจสอบทั้งหมดแล้ว ก็สามารถประมวลผลการตอบกลับต่อไปได้ โดยที่การแมปคำตอบจะได้รับการอัปเดต หากเป็นออราเคิลราคา ข้อมูลราคาจะถูกกำหนดให้กับ currentPrice เพื่ออัปเดตราคาตามนั้น:
ข้างต้นเป็นกระบวนการทั้งหมดของบริการ Oracle ทั่วไป
มาลองใช้วิธี “requestEthereumPrice” ในสัญญา “TestnetConsumer” ที่ Chainlink จัดทำขึ้นเป็นตัวอย่างเพื่ออธิบายกระบวนการตอบสนองคำขอ Oracle ของราคาโดยย่อ ฟังก์ชันนี้ถูกกำหนดดังนี้:
ฟังก์ชันที่ใช้งานคือการรับราคาธุรกรรมของ ETH/USD จาก API ที่ระบุ (cryptocompare) พารามิเตอร์ที่ส่งผ่านเข้าสู่ฟังก์ชันคือที่อยู่โอราเคิลและ jobId ที่ระบุ หลังจากตั้งค่าพารามิเตอร์คำขอชุดหนึ่งแล้ว ให้เรียกใช้เมธอด sendChainlinkRequestTo เพื่อส่งคำขอ sendChainlinkRequestTo เป็นวิธีอินเทอร์เฟซที่กำหนดไว้ในไลบรารีที่จัดทำโดย Chainlink และกำหนดดังต่อไปนี้:
หลังจากได้รับการโอนแล้ว สัญญา Oracle จะทริกเกอร์วิธี onTokenTransfer ซึ่งจะตรวจสอบความถูกต้องของการโอนและบันทึกข้อมูลรายละเอียดมากขึ้นโดยออกเหตุการณ์ OracleRequest
บันทึกนี้จะพบได้ในบันทึกสัญญา Oracle โหนดภายใต้เครือข่ายจะสมัครใช้งานบันทึกของหัวข้อ หลังจากได้รับข้อมูลบันทึกที่บันทึกแล้ว โหนดจะวิเคราะห์ข้อมูลเฉพาะของคำขอและรับผลลัพธ์ของคำขอผ่านการเรียก API ของเครือข่าย หลังจากนั้น เมื่อส่งธุรกรรมแล้ว เรียกใช้เมธอด fulfillOracleRequest ในสัญญา Oracle เพื่อส่งข้อมูลไปยังเครือข่าย
หลังจากดำเนินการตรวจสอบชุดหนึ่งแล้ว วิธีนี้จะส่งผลลัพธ์กลับไปยังสัญญาผู้บริโภคผ่านทางที่อยู่การโทรกลับที่บันทึกไว้ก่อนหน้านี้และฟังก์ชันการโทรกลับ
ในฐานะนักพัฒนา ฉันเพียงอยากใช้ราคาคู่สกุลเงินที่มีอยู่โดยไม่จำเป็นต้องระบุ URL เหล่านี้เอง เป็นไปได้อย่างนั้นเหรอ?
คำตอบคือใช่ วิธีการใช้งานแรกมีดังนี้:
ประการแรก คู่การซื้อขายแต่ละคู่จะมี Price Feed แยกต่างหาก ซึ่งเรียกว่า Aggregator ซึ่งจริงๆ แล้วคือ AggregatorProxy ดังที่แสดงด้านล่าง:
การใช้งานเฉพาะของอินเทอร์เฟซนี้ค่อนข้างง่าย คุณสามารถดูคู่ AAVE/ETH ได้ที่: https://etherscan.io/address/0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012#code
วิธีการสอบถามข้อมูลมีทั้งหมด 5 วิธี:
decimals(): จำนวนหลักของความแม่นยำของข้อมูลราคาที่ส่งคืน โดยปกติคือ 8 หรือ 18
คำอธิบาย (description) : โดยปกติจะเป็นชื่อของคู่การซื้อขาย เช่น ETH / USD
เวอร์ชัน () : ส่วนใหญ่ใช้เพื่อระบุประเภทของ Aggregator ที่ Proxy ชี้ไป
getRoundData(_roundId): รับข้อมูลราคาปัจจุบันตาม ID รอบ
latestRoundData(): รับข้อมูลราคาล่าสุด
ในสถานการณ์การใช้งานส่วนใหญ่ สัญญาอาจต้องอ่านราคาล่าสุดเท่านั้น กล่าวคือ เรียกใช้วิธีการสุดท้าย และคำตอบในพารามิเตอร์ส่งคืนจะเป็นราคาล่าสุด
นอกจากนี้ แอปพลิเคชันส่วนใหญ่ใช้ USD เป็นหน่วยวัดในการอ่านโทเค็น หากเป็นเช่นนั้น คุณจะพบว่าความแม่นยำของคู่เงินที่กำหนดราคาเป็น USD มีความแม่นยำ 8 หลักเท่ากัน ดังนั้นโดยทั่วไปแล้วไม่จำเป็นต้องจัดการกับปัญหาความแม่นยำที่แตกต่างกันสำหรับโทเค็นที่แตกต่างกัน
บทความนี้เขียนโดย XiG (บัญชี X @SHXiGi ) ของทีม ZAN (บัญชี X @zan_team )