Chuỗi bài Oracle Chainlink (Phần 1)

avatar
ZAN Team
1tuần trước
Bài viết có khoảng 4131từ,đọc toàn bộ bài viết mất khoảng 6 phút
Trong lĩnh vực blockchain, oracle là hệ thống có thể cung cấp thông tin bên ngoài cho các hợp đồng thông minh trên chuỗi. Là phần mềm trung gian kết nối các hợp đồng thông minh và thế giới bên ngoài blockchain, oracle đóng vai trò cơ sở hạ tầng cực kỳ quan trọng. Chức năng chính của chúng là cung cấp dữ liệu cho các hợp đồng thông minh trong blockchain.

Trong lĩnh vực blockchain, oracle là hệ thống có thể cung cấp thông tin bên ngoài cho các hợp đồng thông minh trên chuỗi. Là phần mềm trung gian kết nối các hợp đồng thông minh và thế giới bên ngoài blockchain, oracle đóng vai trò cơ sở hạ tầng cực kỳ quan trọng. Chức năng chính của chúng là cung cấp dữ liệu cho các hợp đồng thông minh trong blockchain.

Ví dụ, nếu chúng ta tạo một hợp đồng thông minh trên mạng Ethereum và hợp đồng này cần truy cập vào dữ liệu khối lượng giao dịch dầu thô vào một ngày cụ thể. Tuy nhiên, bản thân các hợp đồng thông minh không thể thu thập được dữ liệu thực tế ngoài chuỗi này, do đó chúng cần được triển khai thông qua các oracle. Trong trường hợp này, hợp đồng thông minh sẽ ghi khối lượng giao dịch dầu thô vào ngày cần thiết vào nhật ký sự kiện. Sau đó, một quy trình sẽ được bắt đầu ngoài chuỗi để theo dõi và đăng ký nhật ký sự kiện này. Khi phát hiện yêu cầu trong giao dịch, quy trình sẽ gửi giao dịch trên chuỗi, gọi phương thức có liên quan của hợp đồng và tải thông tin khối lượng giao dịch dầu thô vào ngày đã chỉ định lên hợp đồng thông minh.

Chuỗi bài Oracle Chainlink (Phần 1)

Dữ liệu từ https://defillama.com/oracles

Liên kết chuỗi

Trong blockchain, Chainlink oracle chiếm thị phần lớn nhất. Chainlink là một dự án oracle phi tập trung có vai trò cung cấp dữ liệu được tạo ra trong thế giới thực cho blockchain theo cách an toàn nhất. Dựa trên việc triển khai các nguyên tắc cơ bản của oracle, Chainlink đã thiết lập một hệ sinh thái chu kỳ lành mạnh xung quanh token LINK thông qua các ưu đãi kinh tế. Oracle Chainlink cần được kích hoạt bằng cách chuyển token LINK. LINK là hợp đồng ERC 677 trên mạng Ethereum. Chức năng oracle dựa trên token LINK ERC 677 thuộc chế độ yêu cầu/phản hồi.

transferAndCall trong token ERC 677

Chuỗi bài Oracle Chainlink (Phần 1)

Về cơ bản, nhà tiên tri là bên cung cấp dịch vụ. Khi ChainLink thiết kế nền tảng oracle, điều đầu tiên họ nghĩ đến là làm sao để người dùng oracle có thể trả phí dịch vụ cho oracle cung cấp dịch vụ. Tuy nhiên, do hợp đồng mã thông báo đồng nhất chuẩn ERC 20 không đáp ứng được nhu cầu cung cấp dịch vụ sau khi thanh toán nên ChainLink đã đề xuất một tiêu chuẩn phù hợp với các tình huống dịch vụ oracle - ERC 677.

Như bạn có thể thấy từ đoạn mã trên, ERC 677 thực chất chỉ thêm phương thức transferAndCall dựa trên chuẩn ERC 20. Phương thức này kết hợp thanh toán và yêu cầu dịch vụ thành một, đáp ứng nhu cầu của các tình huống kinh doanh Oracle.

Chuỗi bài Oracle Chainlink (Phần 1)

Khi người dùng thực hiện lệnh transferAndCall để chuyển tiền, ngoài việc chuyển tiền ERC 20, lệnh này cũng sẽ xác định xem địa chỉ chuyển tiền có phải là địa chỉ hợp đồng hay không. Nếu vậy, phương thức onTokenTransfer của địa chỉ đến sẽ được gọi. (Ở đây, ERC 677 Receiver chỉ có một phương thức: onTokenTransfer)

Chúng ta cũng có thể vào Etherscan để xem mã nguồn hợp đồng của token LINK: https://etherscan.io/address/0x514910771af9ca656af840dff83e8264ecf986ca#code

Chuỗi bài Oracle Chainlink (Phần 1)

Có thể thấy rằng ngoài nhiều lần xác minh địa chỉ _to trong quá trình triển khai, LINK Token thực sự kế thừa phương thức transferAndCall của ERC 677. Lưu ý: Trước khi yêu cầu dịch vụ oracle, hãy đảm bảo rằng oracle đó đáng tin cậy, vì oracle yêu cầu thanh toán trước khi cung cấp dịch vụ cho người dùng. (Bất kỳ ai cũng có thể cung cấp dịch vụ oracle)

Chuỗi bài Oracle Chainlink (Phần 1)

Phân loại độ tin cậy của Oracle

Yêu cầu oracle trên chuỗi

Chúng ta hãy xem phương thức onTokenTransfer của hợp đồng oracle được triển khai như thế nào:

Chuỗi bài Oracle Chainlink (Phần 1)

Khi người dùng oracle sử dụng phương thức transferAndCall để thanh toán phí và yêu cầu dịch vụ của oracle, thì địa chỉ ở đây là địa chỉ của oracle được yêu cầu. Phương thức onTokenTransfer trong oracle trước tiên sẽ xác minh xem giao dịch chuyển tiền có phải là mã thông báo LINK (chỉ LINK) hay không, trên thực tế là để xác định xem msg.sender có phải là địa chỉ của hợp đồng mã thông báo Link hay không. Sau đó, nó sẽ xác định xem độ dài của _data có vượt quá giới hạn tối đa hay không. Cuối cùng, nó sẽ xác định xem có bộ chọn hàm bắt đầu bằng oracleRequest trong _data hay không. Tất nhiên, bộ chọn chức năng ở đây có thể được tùy chỉnh theo các dịch vụ do oracle cung cấp. Không nhất thiết phải là oracleRequest. Điều này phụ thuộc vào loại giao diện mà oracle sử dụng.

Khi tất cả các trình sửa đổi này được thông qua, hãy kiểm tra xem trình gọi hàm hiện tại và số tiền chuyển có giống với những hàm trong _data hay không. Sau khi tất cả các bước kiểm tra bảo mật này được thông qua, hợp đồng oracle hiện tại sẽ được gọi thông qua lệnh delegatecall. Tất nhiên, vì chúng ta đã kiểm tra bộ chọn hàm trong _data, nên thực tế là phương thức oracleRequest được gọi.

Chuỗi bài Oracle Chainlink (Phần 1)

Đầu tiên, người yêu cầu oracle và nonce do người đó gửi được nối lại và băm thành requestId cho yêu cầu này, và ánh xạ cam kết được kiểm tra để xem liệu đó có phải là id duy nhất hay không. Nếu mọi thứ đều ổn, hãy đặt thời gian hết hạn, thêm requestId vào cam kết và nối _payment, _callbackAddress, _callbackFunctionId và expiration làm giá trị. Quan trọng nhất, sự kiện OracleRequest được phát hành, chứa dữ liệu yêu cầu _data, là dữ liệu Biểu diễn đối tượng nhị phân súc tích (CBOR). Định dạng mã hóa này nhẹ và ngắn gọn, có thể hiểu đơn giản là định dạng JSON nhị phân. Dữ liệu này có thể ở nhiều dạng khác nhau, tùy thuộc vào cách thiết kế các nút ngoài chuỗi.

Ví dụ: Chainlink: ETH/USD Aggregator có giao dịch chứa sự kiện OracleRequest:

Chuỗi bài Oracle Chainlink (Phần 1)

Ví dụ về sự kiện OracleRequest

Từ sự kiện này, chúng ta có thể thấy rằng bộ tổng hợp giá ETH/USD 0xF79D6aFBb6dA890132F9D7c355e3015f15F3406F là bộ gửi yêu cầu dữ liệu giá đến oracle: 0x7e94a8a23687d8c7058ba5625db2ce358bcbd244. Nếu oracle trả về dữ liệu được yêu cầu, bạn có thể tìm ra địa chỉ hợp đồng được trả về: 0xF79D6aFBb6dA890132F9D7c355e3015f15F3406F, ID phương thức cần gọi: 6 A 9705 B 4 và thời gian hết hạn: 1618185924.

Phản hồi nút ngoài chuỗi

3.1 Gọi fulfillmentOracleRequest ra khỏi chuỗi

Chuỗi bài Oracle Chainlink (Phần 1)

Kiểm tra đầu tiên:

  • onlyAuthorizedNode: Người gọi hàm (msg.sender) phải là chủ sở hữu của hợp đồng hoặc nằm trong danh sách được ủy quyền;

  • isValidRequest: vẫn kiểm tra xem requestId có tồn tại trong ánh xạ cam kết hay không;

  • Nối payment, callbackAddress, _callbackFunctionId và expiration và kiểm tra xem chúng có phải là giá trị tương ứng của requestId trong bản đồ cam kết hay không.

Nếu tất cả các bước kiểm tra này đều vượt qua, chi phí của yêu cầu này sẽ được cộng vào withdrawalableTokens để ghi lại số tiền có thể rút được. Sau đó, _requestId sẽ bị xóa khỏi bản đồ cam kết. Cuối cùng, hãy tính toán lượng gas còn lại để xem liệu nó có lớn hơn MINIMUM_CONSUMER_GAS_LIMIT hay không, đây là lượng gas tối thiểu cần thiết để thực hiện hàm gọi lại của hợp đồng đã phát hành yêu cầu.

Nếu tất cả các bước kiểm tra trên đều thành công, hàm gọi lại của hợp đồng người yêu cầu có thể được gọi chính thức dưới dạng lệnh gọi.

Phản hồi cho yêu cầu phải nhanh nhất có thể, vì vậy bạn nên sử dụng dịch vụ nút của ZAN ( https://zan.top/home/node-service?chInfo=ch_WZ ) để cải thiện tốc độ phản hồi. Bạn có thể tìm liên kết RPC tương ứng trong bảng điều khiển dịch vụ nút để tăng tốc độ gửi giao dịch ra khỏi chuỗi.

Chuỗi bài Oracle Chainlink (Phần 1)

3.2 Hàm gọi lại

Trước đó chúng ta đã biết từ oracleRequest rằng hàm gọi lại id là 6 A 9705 B 4 và phương thức là chainlinkCallback(bytes 32, int 256

Chuỗi bài Oracle Chainlink (Phần 1)

Chuỗi bài Oracle Chainlink (Phần 1)

validateChainlinkCallback là một hàm có thể tùy chỉnh, sau đây là một trình sửa đổi:

Chuỗi bài Oracle Chainlink (Phần 1)

Kiểm tra trong pendingRequests xem _requestId có khớp với oracle được yêu cầu hay không. Và phát ra sự kiện ChainlinkFulfilled:

Chuỗi bài Oracle Chainlink (Phần 1)

Nếu tất cả các bước kiểm tra đều đạt, các phản hồi có thể được xử lý thêm, trong đó bản đồ câu trả lời được cập nhật. Nếu là một oracle về giá, dữ liệu giá sẽ được gán cho currentPrice để cập nhật giá cho phù hợp:

Chuỗi bài Oracle Chainlink (Phần 1)

Trên đây là toàn bộ quy trình của dịch vụ oracle nói chung.

Chúng ta hãy lấy phương thức “requestEthereumPrice” trong hợp đồng “TestnetConsumer” do Chainlink cung cấp làm ví dụ để giải thích ngắn gọn về quy trình phản hồi yêu cầu của price oracle. Hàm này được định nghĩa như sau:

Chuỗi bài Oracle Chainlink (Phần 1)

Chức năng mà nó thực hiện là lấy giá giao dịch của ETH/USD từ API được chỉ định (cryptocompare). Các tham số được truyền vào hàm là địa chỉ oracle và jobId được chỉ định. Sau khi thiết lập một loạt các tham số yêu cầu, hãy gọi phương thức sendChainlinkRequestTo để gửi yêu cầu. sendChainlinkRequestTo là một phương thức giao diện được định nghĩa trong thư viện do Chainlink cung cấp và được định nghĩa như sau:

Chuỗi bài Oracle Chainlink (Phần 1)

Sau khi nhận được lệnh chuyển, hợp đồng Oracle sẽ kích hoạt phương thức onTokenTransfer để kiểm tra tính hợp lệ của lệnh chuyển và ghi lại thông tin dữ liệu chi tiết hơn bằng cách phát hành sự kiện OracleRequest.

Nhật ký này có thể được tìm thấy trong nhật ký của hợp đồng oracle. Các nút trong chuỗi sẽ đăng ký nhật ký của chủ đề. Sau khi có được thông tin nhật ký đã ghi lại, các nút sẽ phân tích thông tin cụ thể của yêu cầu và lấy kết quả của yêu cầu thông qua lệnh gọi API mạng. Sau đó, bằng cách gửi giao dịch, hãy gọi phương thức fulfillOracleRequest trong hợp đồng Oracle để gửi dữ liệu tới chuỗi.

Sau khi thực hiện một loạt kiểm tra, phương pháp này sẽ trả kết quả về hợp đồng người tiêu dùng thông qua địa chỉ gọi lại và hàm gọi lại đã ghi lại trước đó.

Là một nhà phát triển, tôi chỉ muốn sử dụng giá cặp tiền tệ hiện có mà không cần tự mình chỉ định các URL này. Có thể như vậy được không?

Câu trả lời là có. Cách đầu tiên để sử dụng như sau:

Chuỗi bài Oracle Chainlink (Phần 1)

Đầu tiên, mỗi cặp giao dịch có một Nguồn cấp giá riêng, còn gọi là Aggregator, thực chất là AggregatorProxy, như được hiển thị bên dưới:

Chuỗi bài Oracle Chainlink (Phần 1)

Việc triển khai cụ thể của giao diện này tương đối đơn giản, bạn có thể tham khảo cặp AAVE/ETH: https://etherscan.io/address/0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012#code

Tổng cộng có 5 phương pháp truy vấn:

  • decimals(): Số chữ số có độ chính xác của dữ liệu giá được trả về, thường là 8 hoặc 18

  • description(): thường là tên của cặp giao dịch, chẳng hạn như ETH/USD

  • version(): Chủ yếu được sử dụng để xác định loại Aggregator mà Proxy trỏ tới

  • getRoundData(_roundId): Lấy dữ liệu giá hiện tại dựa trên ID vòng

  • latestRoundData(): Lấy dữ liệu giá mới nhất

Trong hầu hết các tình huống ứng dụng, hợp đồng có thể chỉ cần đọc giá mới nhất, nghĩa là gọi phương thức cuối cùng và câu trả lời trong tham số trả về là giá mới nhất.

Ngoài ra, hầu hết các ứng dụng đều sử dụng USD làm đơn vị đo lường để đọc mã thông báo. Nếu vậy, bạn sẽ thấy rằng độ chính xác của cặp tiền được định giá bằng USD đều là 8 chữ số, do đó nhìn chung không cần phải xử lý các vấn đề về độ chính xác khác nhau cho các mã thông báo khác nhau.

Bài viết này được viết bởi XiG (tài khoản X @SHXiGi ) của ZAN Team (tài khoản X @zan_team ).

Bài viết gốc, tác giả:ZAN Team。Tuyển dụng: Nhân viên kinh doanh phần mềm theo dự án report@odaily.email;Vi phạm quy định của pháp luật.

Odaily nhắc nhở, mời đông đảo độc giả xây dựng quan niệm đúng đắn về tiền tệ và khái niệm đầu tư, nhìn nhận hợp lý về blockchain, nâng cao nhận thức về rủi ro; Đối với manh mối phạm tội phát hiện, có thể tích cực tố cáo phản ánh với cơ quan hữu quan.

Đọc nhiều nhất
Lựa chọn của người biên tập