1"use strict";(globalThis.webpackChunkdocs=globalThis.webpackChunkdocs||[]).push([[1186],{18206(e,n,r){r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"language/oracles","title":"Oracles","description":"Dive into how Noir supports Oracles via RPC calls, and learn how to declare an Oracle in Noir with our comprehensive guide.","source":"@site/versioned_docs/version-v1.0.0-rc.2/language/oracles.mdx","sourceDirName":"language","slug":"/language/oracles","permalink":"/docs/language/oracles","draft":false,"unlisted":false,"editUrl":"https://github.com/noir-lang/noir/edit/master/docs/versioned_docs/version-v1.0.0-rc.2/language/oracles.mdx","tags":[],"version":"v1.0.0-rc.2","frontMatter":{"title":"Oracles","description":"Dive into how Noir supports Oracles via RPC calls, and learn how to declare an Oracle in Noir with our comprehensive guide.","keywords":["Noir","Oracles","RPC Calls","Unconstrained Functions","Programming","Blockchain"]},"sidebar":"sidebar","previous":{"title":"Unconstrained Functions","permalink":"/docs/language/unconstrained"},"next":{"title":"Generics","permalink":"/docs/language/generics"}}');var t=r(74848),a=r(28453);const i={title:"Oracles",description:"Dive into how Noir supports Oracles via RPC calls, and learn how to declare an Oracle in Noir with our comprehensive guide.",keywords:["Noir","Oracles","RPC Calls","Unconstrained Functions","Programming","Blockchain"]},o=void 0,c={},l=[{value:"The <code>#[pure]</code> attribute",id:"the-pure-attribute",level:2},{value:"Restrictions",id:"restrictions",level:3}];function d(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"Noir has support for Oracles via RPC calls. This means Noir will make an RPC call and use the return value for proof generation."}),"\n",(0,t.jsxs)(n.p,{children:["Since Oracles are not resolved by Noir, they are ",(0,t.jsxs)(n.a,{href:"/docs/language/unconstrained",children:[(0,t.jsx)(n.code,{children:"unconstrained"})," functions"]})]}),"\n",(0,t.jsxs)(n.p,{children:["You can declare an Oracle through the ",(0,t.jsx)(n.code,{children:"#[oracle(<name>)]"})," flag. Example:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"#[oracle(get_number_sequence)]\nunconstrained fn get_number_sequence(_size: Field) -> [Field] {}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The timeout for when using an external RPC oracle resolver can be set with the ",(0,t.jsx)(n.code,{children:"NARGO_FOREIGN_CALL_TIMEOUT"})," environment variable. This timeout is in units of milliseconds."]}),"\n",(0,t.jsxs)(n.h2,{id:"the-pure-attribute",children:["The ",(0,t.jsx)(n.code,{children:"#[pure]"})," attribute"]}),"\n",(0,t.jsx)(n.p,{children:"By default, the compiler treats every oracle call as potentially impure: the return value\nmay depend on hidden state, the call may have side effects, and as such two calls with the same\narguments may produce different results. This forces the compiler to keep every oracle\ncall exactly as written."}),"\n",(0,t.jsxs)(n.p,{children:["When you know an oracle's return value is purely a function of its arguments and the call\nhas no observable effect on the program, you can mark the declaration with ",(0,t.jsx)(n.code,{children:"#[pure]"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"#[pure]\n#[oracle(field_inverse)]\nunconstrained fn field_inverse_oracle(x: Field) -> Field {}\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"#[pure]"})," is an unchecked assertion. If you mismark an oracle that secretly reads ambient state\nor has side effects, the optimizer can produce wrong circuits, so use it only when you are certain.\nHowever, ",(0,t.jsx)(n.code,{children:"#[pure]"})," is compatible with functions that can fail on some inputs (e.g division by zero)."]}),"\n",(0,t.jsx)(n.h3,{id:"restrictions",children:"Restrictions"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"#[pure]"})," is rejected on functions that are not ",(0,t.jsx)(n.code,{children:"#[oracle(...)]"}),", and on constrained\nfunctions."]}),"\n",(0,t.jsxs)(n.p,{children:["Do not use ",(0,t.jsx)(n.code,{children:"#[pure]"})," on oracles that read mutable external state (witness maps, RPC\nendpoints that change between calls, etc.) \u2014 those are inherently impure even if their\nsignatures look pure."]})]})}function u(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453(e,n,r){r.d(n,{R:()=>i,x:()=>o});var s=r(96540);const t={},a=s.createContext(t);function i(e){const n=s.useContext(a);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.