=0?t:t+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each((function(){null!=this.parentNode&&this.parentNode.removeChild(this)}))},each:function(t){return a.every.call(this,(function(e,n){return!1!==t.call(e,n,e)})),this},filter:function(t){return P(t)?this.not(this.not(t)):i(c.call(this,(function(e){return O.matches(e,t)})))},add:function(t,e){return i(o(this.concat(i(t,e))))},is:function(t){return this.length>0&&O.matches(this[0],t)},not:function(t){var n=[];if(P(t)&&t.call!==e)this.each((function(e){t.call(this,e)||n.push(this)}));else{var s="string"==typeof t?this.filter(t):q(t)&&P(t.item)?l.call(t):i(t);this.forEach((function(t){s.indexOf(t)<0&&n.push(t)}))}return i(n)},has:function(t){return this.filter((function(){return F(t)?i.contains(this,t):i(this).find(t).size()}))},eq:function(t){return-1===t?this.slice(t):this.slice(t,+t+1)},first:function(){var t=this[0];return t&&!F(t)?t:i(t)},last:function(){var t=this[this.length-1];return t&&!F(t)?t:i(t)},find:function(t){var e=this;return t?"object"==typeof t?i(t).filter((function(){var t=this;return a.some.call(e,(function(e){return i.contains(e,t)}))})):1==this.length?i(O.qsa(this[0],t)):this.map((function(){return O.qsa(this,t)})):i()},closest:function(t,e){var n=[],s="object"==typeof t&&i(t);return this.each((function(i,r){for(;r&&!(s?s.indexOf(r)>=0:O.matches(r,t));)r=r!==e&&!M(r)&&r.parentNode;r&&n.indexOf(r)<0&&n.push(r)})),i(n)},parents:function(t){for(var e=[],n=this;n.length>0;)n=i.map(n,(function(t){if((t=t.parentNode)&&!M(t)&&e.indexOf(t)<0)return e.push(t),t}));return Z(e,t)},parent:function(t){return Z(o(this.pluck("parentNode")),t)},children:function(t){return Z(this.map((function(){return U(this)})),t)},contents:function(){return this.map((function(){return this.contentDocument||l.call(this.childNodes)}))},siblings:function(t){return Z(this.map((function(t,e){return c.call(U(e.parentNode),(function(t){return t!==e}))})),t)},empty:function(){return this.each((function(){this.innerHTML=""}))},pluck:function(t){return i.map(this,(function(e){return e[t]}))},show:function(){return this.each((function(){"none"==this.style.display&&(this.style.display=""),"none"==getComputedStyle(this,"").getPropertyValue("display")&&(this.style.display=z(this.nodeName))}))},replaceWith:function(t){return this.before(t).remove()},wrap:function(t){var e=P(t);if(this[0]&&!e)var n=i(t).get(0),s=n.parentNode||this.length>1;return this.each((function(r){i(this).wrapAll(e?t.call(this,r):s?n.cloneNode(!0):n)}))},wrapAll:function(t){if(this[0]){var e;for(i(this[0]).before(t=i(t));(e=t.children()).length;)t=e.first();i(t).append(this)}return this},wrapInner:function(t){var e=P(t);return this.each((function(n){var s=i(this),r=s.contents(),o=e?t.call(this,n):t;r.length?r.wrapAll(o):s.append(o)}))},unwrap:function(){return this.parent().each((function(){i(this).replaceWith(i(this).children())})),this},clone:function(){return this.map((function(){return this.cloneNode(!0)}))},hide:function(){return this.css("display","none")},toggle:function(t){return this.each((function(){var n=i(this);(t===e?"none"==n.css("display"):t)?n.show():n.hide()}))},prev:function(t){return i(this.pluck("previousElementSibling")).filter(t||"*")},next:function(t){return i(this.pluck("nextElementSibling")).filter(t||"*")},html:function(t){return 0 in arguments?this.each((function(e){var n=this.innerHTML;i(this).empty().append(X(this,t,e,n))})):0 in this?this[0].innerHTML:null},text:function(t){return 0 in arguments?this.each((function(e){var n=X(this,t,e,this.textContent);this.textContent=null==n?"":""+n})):0 in this?this.pluck("textContent").join(""):null},attr:function(t,i){var s;return"string"!=typeof t||1 in arguments?this.each((function(e){if(1===this.nodeType)if(F(t))for(n in t)G(this,n,t[n]);else G(this,t,X(this,i,e,this.getAttribute(t)))})):0 in this&&1==this[0].nodeType&&null!=(s=this[0].getAttribute(t))?s:e},removeAttr:function(t){return this.each((function(){1===this.nodeType&&t.split(" ").forEach((function(t){G(this,t)}),this)}))},prop:function(t,e){return t=N[t]||t,1 in arguments?this.each((function(n){this[t]=X(this,e,n,this[t])})):this[0]&&this[0][t]},removeProp:function(t){return t=N[t]||t,this.each((function(){delete this[t]}))},data:function(t,n){var i="data-"+t.replace(w,"-$1").toLowerCase(),s=1 in arguments?this.attr(i,n):this.attr(i);return null!==s?Y(s):e},val:function(t){return 0 in arguments?(null==t&&(t=""),this.each((function(e){this.value=X(this,t,e,this.value)}))):this[0]&&(this[0].multiple?i(this[0]).find("option").filter((function(){return this.selected})).pluck("value"):this[0].value)},offset:function(e){if(e)return this.each((function(t){var n=i(this),s=X(this,e,t,n.offset()),r=n.offsetParent().offset(),o={top:s.top-r.top,left:s.left-r.left};"static"==n.css("position")&&(o.position="relative"),n.css(o)}));if(!this.length)return null;if(h.documentElement!==this[0]&&!i.contains(h.documentElement,this[0]))return{top:0,left:0};var n=this[0].getBoundingClientRect();return{left:n.left+t.pageXOffset,top:n.top+t.pageYOffset,width:Math.round(n.width),height:Math.round(n.height)}},css:function(t,e){if(arguments.length<2){var s=this[0];if("string"==typeof t){if(!s)return;return s.style[r(t)]||getComputedStyle(s,"").getPropertyValue(t)}if(k(t)){if(!s)return;var o={},a=getComputedStyle(s,"");return i.each(t,(function(t,e){o[e]=s.style[r(e)]||a.getPropertyValue(e)})),o}}var u="";if("string"==I(t))e||0===e?u=B(t)+":"+j(t,e):this.each((function(){this.style.removeProperty(B(t))}));else for(n in t)t[n]||0===t[n]?u+=B(n)+":"+j(n,t[n])+";":this.each((function(){this.style.removeProperty(B(n))}));return this.each((function(){this.style.cssText+=";"+u}))},index:function(t){return t?this.indexOf(i(t)[0]):this.parent().children().indexOf(this[0])},hasClass:function(t){return!!t&&a.some.call(this,(function(t){return this.test(J(t))}),K(t))},addClass:function(t){return t?this.each((function(e){if("className"in this){s=[];var n=J(this);X(this,t,e,n).split(/\s+/g).forEach((function(t){i(this).hasClass(t)||s.push(t)}),this),s.length&&J(this,n+(n?" ":"")+s.join(" "))}})):this},removeClass:function(t){return this.each((function(n){if("className"in this){if(t===e)return J(this,"");s=J(this),X(this,t,n,s).split(/\s+/g).forEach((function(t){s=s.replace(K(t)," ")})),J(this,s.trim())}}))},toggleClass:function(t,n){return t?this.each((function(s){var r=i(this);X(this,t,s,J(this)).split(/\s+/g).forEach((function(t){(n===e?!r.hasClass(t):n)?r.addClass(t):r.removeClass(t)}))})):this},scrollTop:function(t){if(this.length){var n="scrollTop"in this[0];return t===e?n?this[0].scrollTop:this[0].pageYOffset:this.each(n?function(){this.scrollTop=t}:function(){this.scrollTo(this.scrollX,t)})}},scrollLeft:function(t){if(this.length){var n="scrollLeft"in this[0];return t===e?n?this[0].scrollLeft:this[0].pageXOffset:this.each(n?function(){this.scrollLeft=t}:function(){this.scrollTo(t,this.scrollY)})}},position:function(){if(this.length){var t=this[0],e=this.offsetParent(),n=this.offset(),s=y.test(e[0].nodeName)?{top:0,left:0}:e.offset();return n.top-=parseFloat(i(t).css("margin-top"))||0,n.left-=parseFloat(i(t).css("margin-left"))||0,s.top+=parseFloat(i(e[0]).css("border-top-width"))||0,s.left+=parseFloat(i(e[0]).css("border-left-width"))||0,{top:n.top-s.top,left:n.left-s.left}}},offsetParent:function(){return this.map((function(){for(var t=this.offsetParent||h.body;t&&!y.test(t.nodeName)&&"static"==i(t).css("position");)t=t.offsetParent;return t}))}},i.fn.detach=i.fn.remove,["width","height"].forEach((function(t){var n=t.replace(/./,(function(t){return t[0].toUpperCase()}));i.fn[t]=function(s){var r,o=this[0];return s===e?L(o)?o["inner"+n]:M(o)?o.documentElement["scroll"+n]:(r=this.offset())&&r[t]:this.each((function(e){(o=i(this)).css(t,X(this,s,e,o[t]()))}))}})),C.forEach((function(n,s){var r=s%2;i.fn[n]=function(){var n,o,a=i.map(arguments,(function(t){var s=[];return"array"==(n=I(t))?(t.forEach((function(t){return t.nodeType!==e?s.push(t):i.zepto.isZ(t)?s=s.concat(t.get()):void(s=s.concat(O.fragment(t)))})),s):"object"==n||null==t?t:O.fragment(t)})),u=this.length>1;return a.length<1?this:this.each((function(e,n){o=r?n:n.parentNode,n=0==s?n.nextSibling:1==s?n.firstChild:2==s?n:null;var c=i.contains(h.documentElement,o);a.forEach((function(e){if(u)e=e.cloneNode(!0);else if(!o)return i(e).remove();o.insertBefore(e,n),c&&tt(e,(function(e){if(!(null==e.nodeName||"SCRIPT"!==e.nodeName.toUpperCase()||e.type&&"text/javascript"!==e.type||e.src)){var n=e.ownerDocument?e.ownerDocument.defaultView:t;n.eval.call(n,e.innerHTML)}}))}))}))},i.fn[r?n+"To":"insert"+(s?"Before":"After")]=function(t){return i(t)[n](this),this}})),O.Z.prototype=Q.prototype=i.fn,O.uniq=o,O.deserializeValue=Y,i.zepto=O,i}();return function(e){var n,i=1,s=Array.prototype.slice,r=e.isFunction,o=function(t){return"string"==typeof t},a={},u={},c="onfocusin"in t,l={focus:"focusin",blur:"focusout"},h={mouseenter:"mouseover",mouseleave:"mouseout"};function p(t){return t._zid||(t._zid=i++)}function f(t,e,n,i){if((e=d(e)).ns)var s=g(e.ns);return(a[p(t)]||[]).filter((function(t){return t&&(!e.e||t.e==e.e)&&(!e.ns||s.test(t.ns))&&(!n||p(t.fn)===p(n))&&(!i||t.sel==i)}))}function d(t){var e=(""+t).split(".");return{e:e[0],ns:e.slice(1).sort().join(" ")}}function g(t){return new RegExp("(?:^| )"+t.replace(" "," .* ?")+"(?: |$)")}function m(t,e){return t.del&&!c&&t.e in l||!!e}function v(t){return h[t]||c&&l[t]||t}function y(t,i,s,r,o,u,c){var l=p(t),f=a[l]||(a[l]=[]);i.split(/\s/).forEach((function(i){if("ready"==i)return e(document).ready(s);var a=d(i);a.fn=s,a.sel=o,a.e in h&&(s=function(t){var n=t.relatedTarget;if(!n||n!==this&&!e.contains(this,n))return a.fn.apply(this,arguments)}),a.del=u;var l=u||s;a.proxy=function(e){if(!(e=S(e)).isImmediatePropagationStopped()){try{var i=Object.getOwnPropertyDescriptor(e,"data");i&&!i.writable||(e.data=r)}catch(e){}var s=l.apply(t,e._args==n?[e]:[e].concat(e._args));return!1===s&&(e.preventDefault(),e.stopPropagation()),s}},a.i=f.length,f.push(a),"addEventListener"in t&&t.addEventListener(v(a.e),a.proxy,m(a,c))}))}function w(t,e,n,i,s){var r=p(t);(e||"").split(/\s/).forEach((function(e){f(t,e,n,i).forEach((function(e){delete a[r][e.i],"removeEventListener"in t&&t.removeEventListener(v(e.e),e.proxy,m(e,s))}))}))}u.click=u.mousedown=u.mouseup=u.mousemove="MouseEvents",e.event={add:y,remove:w},e.proxy=function(t,n){var i=2 in arguments&&s.call(arguments,2);if(r(t)){var a=function(){return t.apply(n,i?i.concat(s.call(arguments)):arguments)};return a._zid=p(t),a}if(o(n))return i?(i.unshift(t[n],t),e.proxy.apply(null,i)):e.proxy(t[n],t);throw new TypeError("expected function")},e.fn.bind=function(t,e,n){return this.on(t,e,n)},e.fn.unbind=function(t,e){return this.off(t,e)},e.fn.one=function(t,e,n,i){return this.on(t,e,n,i,1)};var b=function(){return!0},C=function(){return!1},x=/^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/,_={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"};function S(t,i){if(i||!t.isDefaultPrevented){i||(i=t),e.each(_,(function(e,n){var s=i[e];t[e]=function(){return this[n]=b,s&&s.apply(i,arguments)},t[n]=C}));try{t.timeStamp||(t.timeStamp=Date.now())}catch(s){}(i.defaultPrevented!==n?i.defaultPrevented:"returnValue"in i?!1===i.returnValue:i.getPreventDefault&&i.getPreventDefault())&&(t.isDefaultPrevented=b)}return t}function E(t){var e,i={originalEvent:t};for(e in t)x.test(e)||t[e]===n||(i[e]=t[e]);return S(i,t)}e.fn.delegate=function(t,e,n){return this.on(e,t,n)},e.fn.undelegate=function(t,e,n){return this.off(e,t,n)},e.fn.live=function(t,n){return e(document.body).delegate(this.selector,t,n),this},e.fn.die=function(t,n){return e(document.body).undelegate(this.selector,t,n),this},e.fn.on=function(t,i,a,u,c){var l,h,p=this;return t&&!o(t)?(e.each(t,(function(t,e){p.on(t,i,a,e,c)})),p):(o(i)||r(u)||!1===u||(u=a,a=i,i=n),u!==n&&!1!==a||(u=a,a=n),!1===u&&(u=C),p.each((function(n,r){c&&(l=function(t){return w(r,t.type,u),u.apply(this,arguments)}),i&&(h=function(t){var n,o=e(t.target).closest(i,r).get(0);if(o&&o!==r)return n=e.extend(E(t),{currentTarget:o,liveFired:r}),(l||u).apply(o,[n].concat(s.call(arguments,1)))}),y(r,t,u,a,i,h||l)})))},e.fn.off=function(t,i,s){var a=this;return t&&!o(t)?(e.each(t,(function(t,e){a.off(t,i,e)})),a):(o(i)||r(s)||!1===s||(s=i,i=n),!1===s&&(s=C),a.each((function(){w(this,t,s,i)})))},e.fn.trigger=function(t,n){return(t=o(t)||e.isPlainObject(t)?e.Event(t):S(t))._args=n,this.each((function(){t.type in l&&"function"==typeof this[t.type]?this[t.type]():"dispatchEvent"in this?this.dispatchEvent(t):e(this).triggerHandler(t,n)}))},e.fn.triggerHandler=function(t,n){var i,s;return this.each((function(r,a){(i=E(o(t)?e.Event(t):t))._args=n,i.target=a,e.each(f(a,t.type||t),(function(t,e){if(s=e.proxy(i),i.isImmediatePropagationStopped())return!1}))})),s},"focusin focusout focus blur load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error".split(" ").forEach((function(t){e.fn[t]=function(e){return 0 in arguments?this.bind(t,e):this.trigger(t)}})),e.Event=function(t,e){o(t)||(t=(e=t).type);var n=document.createEvent(u[t]||"Events"),i=!0;if(e)for(var s in e)"bubbles"==s?i=!!e[s]:n[s]=e[s];return n.initEvent(t,i,!0),S(n)}}(i),n=[],i.fn.remove=function(){return this.each((function(){this.parentNode&&("IMG"===this.tagName&&(n.push(this),this.src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=",e&&clearTimeout(e),e=setTimeout((function(){n=[]}),6e4)),this.parentNode.removeChild(this))}))},function(t){var e={},n=t.fn.data,i=t.camelCase,s=t.expando="Zepto"+ +new Date,r=[];function o(r,o){var u=r[s],c=u&&e[u];if(void 0===o)return c||a(r);if(c){if(o in c)return c[o];var l=i(o);if(l in c)return c[l]}return n.call(t(r),o)}function a(n,r,o){var a=n[s]||(n[s]=++t.uuid),c=e[a]||(e[a]=u(n));return void 0!==r&&(c[i(r)]=o),c}function u(e){var n={};return t.each(e.attributes||r,(function(e,s){0==s.name.indexOf("data-")&&(n[i(s.name.replace("data-",""))]=t.zepto.deserializeValue(s.value))})),n}t.fn.data=function(e,n){return void 0===n?t.isPlainObject(e)?this.each((function(n,i){t.each(e,(function(t,e){a(i,t,e)}))})):0 in this?o(this[0],e):void 0:this.each((function(){a(this,e,n)}))},t.data=function(e,n,i){return t(e).data(n,i)},t.hasData=function(n){var i=n[s],r=i&&e[i];return!!r&&!t.isEmptyObject(r)},t.fn.removeData=function(n){return"string"==typeof n&&(n=n.split(/\s+/)),this.each((function(){var r=this[s],o=r&&e[r];o&&t.each(n||o,(function(t){delete o[n?i(this):t]}))}))},["remove","empty"].forEach((function(e){var n=t.fn[e];t.fn[e]=function(){var t=this.find("*");return"remove"===e&&(t=t.add(this)),t.removeData(),n.call(this)}}))}(i),i}(e)},8937:t=>{"use strict";var e={}.hasOwnProperty,n=/[ -,\.\/:-@\[-\^`\{-~]/,i=/[ -,\.\/:-@\[\]\^`\{-~]/,s=/(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g,r=function t(r,o){"single"!=(o=function(t,n){if(!t)return n;var i={};for(var s in n)i[s]=e.call(t,s)?t[s]:n[s];return i}(o,t.options)).quotes&&"double"!=o.quotes&&(o.quotes="single");for(var a="double"==o.quotes?'"':"'",u=o.isIdentifier,c=r.charAt(0),l="",h=0,p=r.length;h126){if(d>=55296&&d<=56319&&h
{"use strict";var i,s,r,o=[n(5741),n(1856),n(1015),n(6486),n(5723),n(6345)],a=-1,u=[],c=!1;function l(){i&&s&&(i=!1,s.length?u=s.concat(u):a=-1,u.length&&h())}function h(){if(!i){c=!1,i=!0;for(var t=u.length,e=setTimeout(l);t;){for(s=u,u=[];s&&++a1)for(var n=1;n{"use strict";e.test=function(){return!n.g.setImmediate&&void 0!==n.g.MessageChannel},e.install=function(t){var e=new n.g.MessageChannel;return e.port1.onmessage=t,function(){e.port2.postMessage(0)}}},1015:(t,e,n)=>{"use strict";var i=n.g.MutationObserver||n.g.WebKitMutationObserver;e.test=function(){return i},e.install=function(t){var e=0,s=new i(t),r=n.g.document.createTextNode("");return s.observe(r,{characterData:!0}),function(){r.data=e=++e%2}}},1856:(t,e,n)=>{"use strict";e.test=function(){return"function"==typeof n.g.queueMicrotask},e.install=function(t){return function(){n.g.queueMicrotask(t)}}},5723:(t,e,n)=>{"use strict";e.test=function(){return"document"in n.g&&"onreadystatechange"in n.g.document.createElement("script")},e.install=function(t){return function(){var e=n.g.document.createElement("script");return e.onreadystatechange=function(){t(),e.onreadystatechange=null,e.parentNode.removeChild(e),e=null},n.g.document.documentElement.appendChild(e),t}}},6345:(t,e)=>{"use strict";e.test=function(){return!0},e.install=function(t){return function(){setTimeout(t,0)}}}}]);
\ No newline at end of file
diff --git a/assets/js/489.8e09de33.js.LICENSE.txt b/assets/js/489.8e09de33.js.LICENSE.txt
new file mode 100644
index 0000000000..4f7ccd8a76
--- /dev/null
+++ b/assets/js/489.8e09de33.js.LICENSE.txt
@@ -0,0 +1 @@
+/*! https://mths.be/cssesc v3.0.0 by @mathias */
diff --git a/assets/js/4a27219a.734861b4.js b/assets/js/4a27219a.734861b4.js
new file mode 100644
index 0000000000..ab721b60ea
--- /dev/null
+++ b/assets/js/4a27219a.734861b4.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[3746],{9214:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>a});var i=t(4848),r=t(8453);const o={},d="Refreshing Node Certificates",s={id:"node/run-your-node/maintenance/refreshing-certificates",title:"Refreshing Node Certificates",description:"Refreshing Sentry Client TLS Certificate on the Validator Node",source:"@site/docs/node/run-your-node/maintenance/refreshing-certificates.md",sourceDirName:"node/run-your-node/maintenance",slug:"/node/run-your-node/maintenance/refreshing-certificates",permalink:"/node/run-your-node/maintenance/refreshing-certificates",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/node/run-your-node/maintenance/refreshing-certificates.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"operators",previous:{title:"Adding or Removing Nodes",permalink:"/node/run-your-node/maintenance/adding-or-removing-nodes"},next:{title:"Shutting Down a Node",permalink:"/node/run-your-node/maintenance/shutting-down-a-node"}},c={},a=[{value:"Refreshing Sentry Client TLS Certificate on the Validator Node",id:"refreshing-sentry-client-tls-certificate-on-the-validator-node",level:2},{value:"Steps on the Validator Node",id:"steps-on-the-validator-node",level:3},{value:"Steps on the Sentry Node",id:"steps-on-the-sentry-node",level:3},{value:"Refreshing TLS Certificate on the Sentry Node",id:"refreshing-tls-certificate-on-the-sentry-node",level:2},{value:"Steps on the Sentry Node",id:"steps-on-the-sentry-node-1",level:3},{value:"Steps on the Validator Node",id:"steps-on-the-validator-node-1",level:3}];function l(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"refreshing-node-certificates",children:"Refreshing Node Certificates"}),"\n",(0,i.jsx)(n.h2,{id:"refreshing-sentry-client-tls-certificate-on-the-validator-node",children:"Refreshing Sentry Client TLS Certificate on the Validator Node"}),"\n",(0,i.jsx)(n.h3,{id:"steps-on-the-validator-node",children:"Steps on the Validator Node"}),"\n",(0,i.jsxs)(n.p,{children:["Go to your validator node's data directory, e.g. ",(0,i.jsx)(n.code,{children:"/node/data"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"cd \n"})}),"\n",(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsxs)(n.p,{children:["We recommend backing up your validator's private and public keys (i.e. all ",(0,i.jsx)(n.code,{children:"*.pem"})," files) in your node's data directory before continuing."]})}),"\n",(0,i.jsx)(n.p,{children:"Remove the validator's current sentry client TLS private key and certificate by running:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"rm sentry_client_tls_identity.pem sentry_client_tls_identity_cert.pem\n"})}),"\n",(0,i.jsx)(n.p,{children:"Re-generate node's keys by running:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"oasis-node identity init --datadir ./\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["This should keep all your other node's keys (i.e. ",(0,i.jsx)(n.code,{children:"beacon.pem"}),", ",(0,i.jsx)(n.code,{children:"consensus.pem"}),", ",(0,i.jsx)(n.code,{children:"consensus_pub.pem"}),", ",(0,i.jsx)(n.code,{children:"identity.pem"}),", ",(0,i.jsx)(n.code,{children:"identity_pub.pem"}),", ...) intact."]})}),"\n",(0,i.jsx)(n.p,{children:"Then run:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"oasis-node identity show-sentry-client-pubkey --datadir ./\n"})}),"\n",(0,i.jsxs)(n.p,{children:["to obtain the value of the validator's new sentry client TLS public key in Base64-encoding that can be put in sentry node's configuration under ",(0,i.jsx)(n.code,{children:"control.authorized_pubkey"})," list."]}),"\n",(0,i.jsx)(n.p,{children:"Restart your validator node."}),"\n",(0,i.jsx)(n.h3,{id:"steps-on-the-sentry-node",children:"Steps on the Sentry Node"}),"\n",(0,i.jsx)(n.p,{children:"After generating a new sentry client TLS private key and certificate on the validator node, set the new client TLS public key in your sentry node's configuration."}),"\n",(0,i.jsx)(n.p,{children:"Before using the below sentry node configuration snippet, replace the following variables:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"{{ validator_sentry_client_grpc_public_key }}"}),": The validator node's new sentry client TLS public key encoded in Base64-encoding (e.g. ",(0,i.jsx)(n.code,{children:"KjVEdeGbtdxffQaSxIkLE+kW0sINI5/5YR/lgUkuEcw="}),")."]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"... trimmed ...\n\n# Worker configuration.\nworker:\n sentry:\n # Enable sentry node.\n enabled: true\n # Port used by validator nodes to query sentry node for registry\n # information.\n # IMPORTANT: Only validator nodes protected by the sentry node should have\n # access to this port. This port should not be exposed on the public\n # network.\n control:\n port: 9009\n authorized_pubkey:\n - {{ validator_sentry_client_grpc_public_key }}\n\n... trimmed ...\n"})}),"\n",(0,i.jsx)(n.p,{children:"Restart your sentry node."}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsx)(n.p,{children:"The validator node will re-register itself automatically once it's connected to the network through the sentry again."})}),"\n",(0,i.jsx)(n.h2,{id:"refreshing-tls-certificate-on-the-sentry-node",children:"Refreshing TLS Certificate on the Sentry Node"}),"\n",(0,i.jsx)(n.h3,{id:"steps-on-the-sentry-node-1",children:"Steps on the Sentry Node"}),"\n",(0,i.jsxs)(n.p,{children:["Go to your sentry node's data directory, e.g. ",(0,i.jsx)(n.code,{children:"/node/data"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"cd \n"})}),"\n",(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsxs)(n.p,{children:["We recommend backing up your sentry's private and public keys (i.e. all ",(0,i.jsx)(n.code,{children:"*.pem"})," files) in your node's data directory before continuing."]})}),"\n",(0,i.jsx)(n.p,{children:"Remove the sentry's current TLS private key and certificate by running:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"rm tls_identity.pem tls_identity_cert.pem\n"})}),"\n",(0,i.jsx)(n.p,{children:"Re-generate node's keys by running:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"oasis-node identity init --datadir ./\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["This should keep all your other node's keys (i.e. ",(0,i.jsx)(n.code,{children:"beacon.pem"}),", ",(0,i.jsx)(n.code,{children:"consensus.pem"}),", ",(0,i.jsx)(n.code,{children:"consensus_pub.pem"}),", ",(0,i.jsx)(n.code,{children:"identity.pem"}),", ",(0,i.jsx)(n.code,{children:"identity_pub.pem"}),", ...) intact."]})}),"\n",(0,i.jsx)(n.p,{children:"Then run:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"oasis-node identity show-tls-pubkey --datadir ./\n"})}),"\n",(0,i.jsxs)(n.p,{children:["to obtain the value of the sentry's new TLS public key in Base64-encoding that can be put in validator node's configuration under ",(0,i.jsx)(n.code,{children:"worker.sentry.address"})," list."]}),"\n",(0,i.jsx)(n.p,{children:"Restart your sentry node."}),"\n",(0,i.jsx)(n.h3,{id:"steps-on-the-validator-node-1",children:"Steps on the Validator Node"}),"\n",(0,i.jsx)(n.p,{children:"After generating a new TLS private key and certificate on the sentry node, set the new TLS public key in your validator node's configuration."}),"\n",(0,i.jsx)(n.p,{children:"Before using the below validator node configuration snippet, replace the following variables:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"{{ sentry_node_grpc_public_key }}"}),": The sentry node's new TLS public key encoded in Base64-encoding (e.g. ",(0,i.jsx)(n.code,{children:"1dA4/NuYPSWXYaKpLhaofrZscIb2FDKtJclCMnVC0Xc="}),")."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"{{ sentry_node_private_ip }}"}),": The private IP address of the sentry node over which sentry node should be accessible to the validator."]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'... trimmed ...\n\nworker:\n registration:\n # In order for the node to register itself the entity.json of the entity\n # used to provision the node must be available on the node.\n entity: /node/etc/entity.json\n sentry:\n address:\n - "{{ sentry_node_grpc_public_key }}@{{ sentry_node_private_ip }}:9009"\n\n... trimmed ...\n'})}),"\n",(0,i.jsx)(n.p,{children:"Restart your validator node."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>s});var i=t(6540);const r={},o=i.createContext(r);function d(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/4ae0b297.3bf39688.js b/assets/js/4ae0b297.3bf39688.js
new file mode 100644
index 0000000000..b0b1b2f4e7
--- /dev/null
+++ b/assets/js/4ae0b297.3bf39688.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[8121],{4695:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var o=t(4848),s=t(8453);const r={},i="Hello World",a={id:"dapp/cipher/hello-world",title:"Hello World",description:"This chapter will show you how to quickly create, build and test a minimal",source:"@site/docs/dapp/cipher/hello-world.md",sourceDirName:"dapp/cipher",slug:"/dapp/cipher/hello-world",permalink:"/dapp/cipher/hello-world",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/oasis-sdk/edit/main/docs/contract/hello-world.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"developers",previous:{title:"Prerequisites",permalink:"/dapp/cipher/prerequisites"},next:{title:"Confidential Hello World",permalink:"/dapp/cipher/confidential-smart-contract"}},l={},c=[{value:"Repository Structure and Dependencies",id:"repository-structure-and-dependencies",level:2},{value:"Smart Contract Definition",id:"smart-contract-definition",level:2},{value:"Testing",id:"testing",level:2},{value:"Building for Deployment",id:"building-for-deployment",level:2},{value:"Deploying the Contract",id:"deploying-the-contract",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"hello-world",children:"Hello World"}),"\n",(0,o.jsx)(n.p,{children:"This chapter will show you how to quickly create, build and test a minimal\nOasis WebAssembly smart contract."}),"\n",(0,o.jsx)(n.h2,{id:"repository-structure-and-dependencies",children:"Repository Structure and Dependencies"}),"\n",(0,o.jsxs)(n.p,{children:["First we create the basic directory structure for the hello world contract using\nRust's ",(0,o.jsx)(n.a,{href:"https://doc.rust-lang.org/cargo",children:(0,o.jsx)(n.code,{children:"cargo"})}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"cargo init --lib hello-world\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This will create the ",(0,o.jsx)(n.code,{children:"hello-world"})," directory and populate it with some\nboilerplate needed to describe a Rust application. It will also set up the\ndirectory for version control using Git. The rest of the guide assumes that you\nare executing commands from within this directory."]}),"\n",(0,o.jsxs)(n.p,{children:["Since the Contract SDK requires a nightly version of the Rust toolchain, you\nneed to specify a version to use by creating a special file called\n",(0,o.jsx)(n.code,{children:"rust-toolchain"})," containing the following information:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'[toolchain]\nchannel = "nightly-2024-07-09"\ncomponents = [ "rustfmt", "clippy" ]\ntargets = [ "x86_64-fortanix-unknown-sgx", "wasm32-unknown-unknown" ]\nprofile = "minimal"\n'})}),"\n",(0,o.jsx)(n.p,{children:"After you complete this guide, the minimal runtime directory structure will look\nas follows:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"hello-world\n\u251c\u2500\u2500 Cargo.lock # Dependency tree checksums (generated on first compilation).\n\u251c\u2500\u2500 Cargo.toml # Rust crate definition.\n\u251c\u2500\u2500 rust-toolchain.toml # Rust toolchain version configuration.\n\u2514\u2500\u2500 src\n \u2514\u2500\u2500 lib.rs # Smart contract source code.\n"})}),"\n",(0,o.jsx)(n.h2,{id:"smart-contract-definition",children:"Smart Contract Definition"}),"\n",(0,o.jsxs)(n.p,{children:["First you need to declare some dependencies in order to be able to use the smart\ncontract SDK. Additionally, you will want to specify some optimization flags in\norder to make the compiled smart contract as small as possible. To do this, edit\nyour ",(0,o.jsx)(n.code,{children:"Cargo.toml"})," to look like the following:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",metastring:'title="Cargo.toml"',children:'[package]\nname = "hello-world"\nversion = "0.0.0"\nedition = "2021"\nlicense = "Apache-2.0"\n\n[lib]\ncrate-type = ["cdylib"]\n\n[dependencies]\ncbor = { version = "0.5.1", package = "oasis-cbor" }\noasis-contract-sdk = { git = "https://github.com/oasisprotocol/oasis-sdk", tag = "contract-sdk/v0.3.0" }\noasis-contract-sdk-storage = { git = "https://github.com/oasisprotocol/oasis-sdk", tag = "contract-sdk/v0.3.0" }\n\n# Third party.\nthiserror = "1.0.30"\n\n[profile.release]\nopt-level = 3\ndebug = false\nrpath = false\nlto = true\ndebug-assertions = false\ncodegen-units = 1\npanic = "abort"\nincremental = false\noverflow-checks = true\nstrip = true\n'})}),"\n",(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsx)(n.p,{children:"We are using Git tags for releases instead of releasing Rust packages on\ncrates.io."})}),"\n",(0,o.jsxs)(n.p,{children:["After you have updated your ",(0,o.jsx)(n.code,{children:"Cargo.toml"})," the next thing is to define the hello\nworld smart contract. To do this, edit ",(0,o.jsx)(n.code,{children:"src/lib.rs"})," with the following\ncontent:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",metastring:'title="src/lib.rs"',children:'//! A minimal hello world smart contract.\nextern crate alloc;\n\nuse oasis_contract_sdk as sdk;\nuse oasis_contract_sdk_storage::cell::PublicCell;\n\n/// All possible errors that can be returned by the contract.\n///\n/// Each error is a triplet of (module, code, message) which allows it to be both easily\n/// human readable and also identifyable programmatically.\n#[derive(Debug, thiserror::Error, sdk::Error)]\npub enum Error {\n #[error("bad request")]\n #[sdk_error(code = 1)]\n BadRequest,\n}\n\n/// All possible requests that the contract can handle.\n///\n/// This includes both calls and queries.\n#[derive(Clone, Debug, cbor::Encode, cbor::Decode)]\npub enum Request {\n #[cbor(rename = "instantiate")]\n Instantiate { initial_counter: u64 },\n\n #[cbor(rename = "say_hello")]\n SayHello { who: String },\n}\n\n/// All possible responses that the contract can return.\n///\n/// This includes both calls and queries.\n#[derive(Clone, Debug, Eq, PartialEq, cbor::Encode, cbor::Decode)]\npub enum Response {\n #[cbor(rename = "hello")]\n Hello { greeting: String },\n\n #[cbor(rename = "empty")]\n Empty,\n}\n\n/// The contract type.\npub struct HelloWorld;\n\n/// Storage cell for the counter.\nconst COUNTER: PublicCell = PublicCell::new(b"counter");\n\nimpl HelloWorld {\n /// Increment the counter and return the previous value.\n fn increment_counter(ctx: &mut C) -> u64 {\n let counter = COUNTER.get(ctx.public_store()).unwrap_or_default();\n COUNTER.set(ctx.public_store(), counter + 1);\n\n counter\n }\n}\n\n// Implementation of the sdk::Contract trait is required in order for the type to be a contract.\nimpl sdk::Contract for HelloWorld {\n type Request = Request;\n type Response = Response;\n type Error = Error;\n\n fn instantiate(ctx: &mut C, request: Request) -> Result<(), Error> {\n // This method is called during the contracts.Instantiate call when the contract is first\n // instantiated. It can be used to initialize the contract state.\n match request {\n // We require the caller to always pass the Instantiate request.\n Request::Instantiate { initial_counter } => {\n // Initialize counter to specified value.\n COUNTER.set(ctx.public_store(), initial_counter);\n\n Ok(())\n }\n _ => Err(Error::BadRequest),\n }\n }\n\n fn call(ctx: &mut C, request: Request) -> Result {\n // This method is called for each contracts.Call call. It is supposed to handle the request\n // and return a response.\n match request {\n Request::SayHello { who } => {\n // Increment the counter and retrieve the previous value.\n let counter = Self::increment_counter(ctx);\n\n // Return the greeting as a response.\n Ok(Response::Hello {\n greeting: format!("hello {who} ({counter})"),\n })\n }\n _ => Err(Error::BadRequest),\n }\n }\n\n fn query(_ctx: &mut C, _request: Request) -> Result {\n // This method is called for each contracts.Query query. It is supposed to handle the\n // request and return a response.\n Err(Error::BadRequest)\n }\n}\n\n// Create the required Wasm exports required for the contract to be runnable.\nsdk::create_contract!(HelloWorld);\n\n// We define some simple contract tests below.\n#[cfg(test)]\nmod test {\n use oasis_contract_sdk::{testing::MockContext, types::ExecutionContext, Contract};\n\n use super::*;\n\n #[test]\n fn test_hello() {\n // Create a mock execution context with default values.\n let mut ctx: MockContext = ExecutionContext::default().into();\n\n // Instantiate the contract.\n HelloWorld::instantiate(\n &mut ctx,\n Request::Instantiate {\n initial_counter: 11,\n },\n )\n .expect("instantiation should work");\n\n // Dispatch the SayHello message.\n let rsp = HelloWorld::call(\n &mut ctx,\n Request::SayHello {\n who: "unit test".to_string(),\n },\n )\n .expect("SayHello call should work");\n\n // Make sure the greeting is correct.\n assert_eq!(\n rsp,\n Response::Hello {\n greeting: "hello unit test (11)".to_string()\n }\n );\n\n // Dispatch another SayHello message.\n let rsp = HelloWorld::call(\n &mut ctx,\n Request::SayHello {\n who: "second call".to_string(),\n },\n )\n .expect("SayHello call should work");\n\n // Make sure the greeting is correct.\n assert_eq!(\n rsp,\n Response::Hello {\n greeting: "hello second call (12)".to_string()\n }\n );\n }\n}\n'})}),"\n",(0,o.jsxs)(n.p,{children:["This is it! You now have a simple hello world smart contract with included unit\ntests for its functionality. You can also look at other smart contract handles\nsupported by the ",(0,o.jsx)(n.a,{href:"https://github.com/oasisprotocol/oasis-sdk/blob/main/contract-sdk/src/contract.rs",children:"Oasis Contract SDK"}),"."]}),"\n",(0,o.jsx)(n.admonition,{title:"PublicCell object",type:"tip",children:(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"PublicCell"})," can use any type ",(0,o.jsx)(n.code,{children:"T"})," which implements ",(0,o.jsx)(n.code,{children:"oasis_cbor::Encode"})," and\n",(0,o.jsx)(n.code,{children:"oasis_cbor::Decode"}),"."]})}),"\n",(0,o.jsx)(n.admonition,{title:"Context object",type:"tip",children:(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"ctx"})," argument contains the contract context analogous to ",(0,o.jsx)(n.code,{children:"msg"})," and ",(0,o.jsx)(n.code,{children:"this"}),"\nin the EVM world. To learn more head to the ",(0,o.jsx)(n.a,{href:"https://api.docs.oasis.io/oasis-sdk/oasis_contract_sdk/context/trait.Context.html",children:"Context"})," trait in our Rust API."]})}),"\n",(0,o.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,o.jsx)(n.p,{children:"To run unit tests type:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:'RUSTFLAGS="-C target-feature=+aes,+ssse3" cargo test\n'})}),"\n",(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsx)(n.p,{children:"Running unit tests locally requires a physical or virtualized Intel-compatible\nCPU with AES and SSSE3 instruction sets."})}),"\n",(0,o.jsx)(n.h2,{id:"building-for-deployment",children:"Building for Deployment"}),"\n",(0,o.jsx)(n.p,{children:"In order to build the smart contract before it can be uploaded to the target\nchain, run:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"cargo build --target wasm32-unknown-unknown --release\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This will generate a binary file called ",(0,o.jsx)(n.code,{children:"hello_world.wasm"})," under\n",(0,o.jsx)(n.code,{children:"target/wasm32-unknown-unknown/release"})," which contains the smart contract\ncompiled into WebAssembly. This file can be directly deployed on chain."]}),"\n",(0,o.jsx)(n.h2,{id:"deploying-the-contract",children:"Deploying the Contract"}),"\n",(0,o.jsx)(n.p,{children:"Deploying the contract we just built is simple using the Oasis CLI. This section\nassumes that you already have an instance of the CLI set up and that you will\nbe deploying contracts on the existing Testnet where you already have some\nTEST tokens to cover transaction fees."}),"\n",(0,o.jsx)(n.p,{children:"First, switch the default network to Cipher Testnet to avoid the need to pass\nit to every following invocation."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"oasis network set-default testnet\noasis paratime set-default testnet cipher\n"})}),"\n",(0,o.jsx)(n.p,{children:"The first deployment step that needs to be performed only once for the given\nbinary is uploading the Wasm binary."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"oasis contract upload hello_world.wasm\n"})}),"\n",(0,o.jsx)(n.p,{children:"After successful execution it will show the code ID that you need to use for any\nsubsequent instantiation of the same contract. Next, create an instance of the\ncontract by loading the code and calling its constructor with some dummy\narguments. Note that the arguments depend on the contract that is being deployed\nand in our hello world case we are simply taking the initial counter value."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"oasis contract instantiate CODEID '{instantiate: {initial_counter: 42}}'\n"})}),"\n",(0,o.jsx)(n.p,{children:"After successful execution it shows the instance ID that you need for calling\nthe instantiated contract. Next, you can test calling the contract."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"oasis contract call INSTANCEID '{say_hello: {who: \"me\"}}'\n"})}),"\n",(0,o.jsx)(n.admonition,{title:"Example",type:"info",children:(0,o.jsxs)(n.p,{children:["You can view and download a ",(0,o.jsx)(n.a,{href:"https://github.com/oasisprotocol/oasis-sdk/tree/main/examples/contract-sdk/hello-world",children:"complete example"})," from the Oasis SDK repository."]})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var o=t(6540);const s={},r=o.createContext(s);function i(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/4c52944b.9d7e2641.js b/assets/js/4c52944b.9d7e2641.js
new file mode 100644
index 0000000000..f109e968af
--- /dev/null
+++ b/assets/js/4c52944b.9d7e2641.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[2792],{647:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>r,default:()=>c,frontMatter:()=>o,metadata:()=>l,toc:()=>h});var i=t(4848),n=t(8453);const o={description:"How to build your first runtime"},r="Prerequisites",l={id:"paratime/prerequisites",title:"Prerequisites",description:"How to build your first runtime",source:"@site/docs/paratime/prerequisites.md",sourceDirName:"paratime",slug:"/paratime/prerequisites",permalink:"/paratime/prerequisites",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/oasis-sdk/edit/main/docs/runtime/prerequisites.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{description:"How to build your first runtime"},sidebar:"paratime",previous:{title:"Overview",permalink:"/paratime/"},next:{title:"Minimal Runtime",permalink:"/paratime/minimal-runtime"}},a={},h=[{value:"Environment Setup",id:"environment-setup",level:2},{value:"Rust",id:"rust",level:3},{value:"Rust Toolchain Version",id:"rust-toolchain-version",level:4},{value:"(OPTIONAL) Go",id:"optional-go",level:3},{value:"Oasis Core Installation",id:"oasis-core-installation",level:2},{value:"Oasis CLI Installation",id:"oasis-cli-installation",level:2}];function d(e){const s={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,n.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.h1,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsx)(s.p,{children:"This chapter will show you how to install the software required for developing\na runtime and client using the Oasis SDK. After successfully completing all the\ndescribed steps you will be able to start building your first runtime!"}),"\n",(0,i.jsxs)(s.p,{children:["If you already have everything set up, feel free to skip to the ",(0,i.jsx)(s.a,{href:"/paratime/minimal-runtime",children:"next chapter"}),"."]}),"\n",(0,i.jsx)(s.h2,{id:"environment-setup",children:"Environment Setup"}),"\n",(0,i.jsx)(s.p,{children:"The following is a list of prerequisites required to start developing using the\nOasis SDK:"}),"\n",(0,i.jsx)(s.h3,{id:"rust",children:(0,i.jsx)(s.a,{href:"https://www.rust-lang.org/",children:"Rust"})}),"\n",(0,i.jsxs)(s.p,{children:["We follow ",(0,i.jsx)(s.a,{href:"https://www.rust-lang.org/tools/install",children:"Rust upstream's recommendation"})," on using\n",(0,i.jsx)(s.a,{href:"https://rustup.rs/",children:"rustup"})," to install and manage Rust versions."]}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"rustup cannot be installed alongside a distribution packaged Rust version. You\nwill need to remove it (if it's present) before you can start using rustup."})}),"\n",(0,i.jsx)(s.p,{children:"Install it by running:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-bash",children:"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n"})}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsxs)(s.p,{children:["If you want to avoid directly executing a shell script fetched the\ninternet, you can also ",(0,i.jsxs)(s.a,{href:"https://rust-lang.github.io/rustup/installation/other.html",children:["download ",(0,i.jsx)(s.code,{children:"rustup-init"})," executable for your platform"]}),"\nand run it manually."]})}),"\n",(0,i.jsxs)(s.p,{children:["This will run ",(0,i.jsx)(s.code,{children:"rustup-init"})," which will download and install the latest stable\nversion of Rust on your system."]}),"\n",(0,i.jsx)(s.h4,{id:"rust-toolchain-version",children:"Rust Toolchain Version"}),"\n",(0,i.jsxs)(s.p,{children:["The version of the Rust toolchain we use in the Oasis SDK is specified in the\n",(0,i.jsx)(s.a,{href:"https://github.com/oasisprotocol/oasis-sdk/tree/main/rust-toolchain.toml",children:(0,i.jsx)(s.code,{children:"rust-toolchain.toml"})})," file."]}),"\n",(0,i.jsxs)(s.p,{children:["The rustup-installed versions of ",(0,i.jsx)(s.code,{children:"cargo"}),", ",(0,i.jsx)(s.code,{children:"rustc"})," and other tools will\n",(0,i.jsx)(s.a,{href:"https://github.com/rust-lang/rustup/blob/master/README.md#override-precedence",children:"automatically detect this file and use the appropriate version of the Rust\ntoolchain"}),". When you are building applications that\nuse the SDK, it is recommended that you copy the same ",(0,i.jsx)(s.a,{href:"https://github.com/oasisprotocol/oasis-sdk/tree/main/rust-toolchain.toml",children:(0,i.jsx)(s.code,{children:"rust-toolchain.toml"})}),"\nfile to your project's top-level directory as well."]}),"\n",(0,i.jsx)(s.p,{children:"To install the appropriate version of the Rust toolchain, make sure you are\nin the project directory and run:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"rustup show\n"})}),"\n",(0,i.jsx)(s.p,{children:"This will automatically install the appropriate Rust toolchain (if not\npresent) and output something similar to:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"...\n\nactive toolchain\n----------------\n\nnightly-2022-08-22-x86_64-unknown-linux-gnu (overridden by '/code/rust-toolchain')\nrustc 1.65.0-nightly (c0941dfb5 2022-08-21)\n"})}),"\n",(0,i.jsxs)(s.h3,{id:"optional-go",children:["(OPTIONAL) ",(0,i.jsx)(s.a,{href:"https://golang.org",children:"Go"})]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.em,{children:"Required if you want to use the Go Client SDK."})}),"\n",(0,i.jsxs)(s.p,{children:["At least version ",(0,i.jsx)(s.strong,{children:"1.22.5"})," is required. If your distribution provides a\nnew-enough version of Go, just use that."]}),"\n",(0,i.jsx)(s.p,{children:"Otherwise:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"install the Go version provided by your distribution,"}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:[(0,i.jsxs)(s.a,{href:"https://tip.golang.org/doc/code.html#GOPATH",children:["ensure ",(0,i.jsx)(s.code,{children:"$GOPATH/bin"})," is in your ",(0,i.jsx)(s.code,{children:"PATH"})]}),","]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:[(0,i.jsx)(s.a,{href:"https://golang.org/doc/install#extra_versions",children:"install the desired version of Go"}),", e.g. 1.22.5, with:"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"go get golang.org/dl/go1.22.5\ngo1.22.5 download\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"oasis-core-installation",children:"Oasis Core Installation"}),"\n",(0,i.jsxs)(s.p,{children:["The SDK requires utilities provided by ",(0,i.jsx)(s.a,{href:"https://github.com/oasisprotocol/oasis-core",children:"Oasis Core"})," in order to be able to run\na local test network for development purposes."]}),"\n",(0,i.jsxs)(s.p,{children:["The recommended way is to download a pre-built release (at least version\n24.2) from the ",(0,i.jsx)(s.a,{href:"https://github.com/oasisprotocol/oasis-core/releases",children:"Oasis Core releases"})," page. After downloading the binary\nrelease (e.g. into ",(0,i.jsx)(s.code,{children:"~/Downloads/oasis_core_24.2_linux_amd64.tar.gz"}),"), unpack\nit as follows:"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-bash",children:"cd ~/Downloads\ntar xf ~/Downloads/oasis_core_24.2_linux_amd64.tar.gz --strip-components=1\n\n# This environment variable will be used throughout this guide.\nexport OASIS_CORE_PATH=~/Downloads/oasis_core_24.2_linux_amd64\n"})}),"\n",(0,i.jsx)(s.h2,{id:"oasis-cli-installation",children:"Oasis CLI Installation"}),"\n",(0,i.jsxs)(s.p,{children:["The rest of the guide uses the Oasis CLI as an easy way to interact with the\nParaTime. You can use ",(0,i.jsx)(s.a,{href:"https://github.com/oasisprotocol/cli/releases",children:"one of the binary releases"})," or ",(0,i.jsx)(s.a,{href:"https://github.com/oasisprotocol/cli/blob/master/README.md",children:"compile it yourself"}),"."]})]})}function c(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>l});var i=t(6540);const n={},o=i.createContext(n);function r(e){const s=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:r(e.components),i.createElement(o.Provider,{value:s},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/4c58f4a9.755b5ccb.js b/assets/js/4c58f4a9.755b5ccb.js
new file mode 100644
index 0000000000..65bd8f6ddb
--- /dev/null
+++ b/assets/js/4c58f4a9.755b5ccb.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[1139],{2945:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>u,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var a=t(4848),r=t(8453),s=t(1470),o=t(9365);const i={description:"Secure dApps: Recipes for Confidentiality"},l="Security",c={id:"dapp/sapphire/security",title:"Security",description:"Secure dApps: Recipes for Confidentiality",source:"@site/docs/dapp/sapphire/security.md",sourceDirName:"dapp/sapphire",slug:"/dapp/sapphire/security",permalink:"/dapp/sapphire/security",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/sapphire-paratime/edit/main/docs/security.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{description:"Secure dApps: Recipes for Confidentiality"},sidebar:"developers",previous:{title:"Deployment Patterns",permalink:"/dapp/sapphire/deployment"},next:{title:"Oasis Privacy Layer",permalink:"/dapp/opl/"}},u={},d=[{value:"Storage Access Patterns",id:"storage-access-patterns",level:2},{value:"Order of Operations",id:"order-of-operations",level:2},{value:"Speed Bump",id:"speed-bump",level:2},{value:"Gas Padding",id:"gas-padding",level:2}];function p(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h1,{id:"security",children:"Security"}),"\n",(0,a.jsx)(n.p,{children:"This page is an ongoing work in progress to support confidential smart contract\ndevelopment. At the moment we address safeguarding storage variable access\npatterns and provide best practices for more secure orderings of error checking\nto prevent leaking contract state."}),"\n",(0,a.jsx)(n.h2,{id:"storage-access-patterns",children:"Storage Access Patterns"}),"\n",(0,a.jsxs)(n.p,{children:["You can use a tool such as ",(0,a.jsx)(n.a,{href:"https://www.npmjs.com/package/hardhat-tracer",children:"hardhat-tracer"})," to examine the base EVM state\ntransitions under the hood."]}),"\n",(0,a.jsxs)(s.A,{groupId:"npm2yarn",children:[(0,a.jsx)(o.A,{value:"npm",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"npm install -D hardhat-tracer\n"})})}),(0,a.jsx)(o.A,{value:"pnpm",label:"pnpm",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"pnpm add -D hardhat-tracer\n"})})}),(0,a.jsx)(o.A,{value:"yarn",label:"Yarn",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"yarn add --dev hardhat-tracer\n"})})})]}),"\n",(0,a.jsxs)(n.p,{children:["and add ",(0,a.jsx)(n.code,{children:"hardhat-tracer"})," to your ",(0,a.jsx)(n.code,{children:"config.ts"})," file,"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-typescript",children:'import "hardhat-tracer"\n'})}),"\n",(0,a.jsx)(n.p,{children:"in order to test and show call traces."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"npx hardhat test --vvv --opcodes SSTORE,SLOAD\n"})}),"\n",(0,a.jsx)(n.p,{children:"You can also trace a particular transaction, once you know its hash."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"npx hardhat trace --hash 0xTransactionHash\n"})}),"\n",(0,a.jsxs)(n.p,{children:["For both ",(0,a.jsx)(n.a,{href:"https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html",children:"gas"})," usage and confidentiality purposes, we ",(0,a.jsx)(n.strong,{children:"recommend using\nnon-unique data size"}),". E.g. 64-byte value will still be distinct from a\n128-byte value."]}),"\n",(0,a.jsx)(n.admonition,{title:"Inference based on access patterns",type:"caution",children:(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"SSTORE"})," keys from one transaction may be linked to ",(0,a.jsx)(n.code,{children:"SLOAD"})," keys of another\ntransaction."]})}),"\n",(0,a.jsx)(n.h2,{id:"order-of-operations",children:"Order of Operations"}),"\n",(0,a.jsxs)(n.p,{children:["When handling errors, gas usage patterns not only can reveal the code path\ntaken, ",(0,a.jsx)(n.strong,{children:"but sometimes the balance of a user as well"})," (in the case of a diligent\nattacker using binary search)."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-solidity",children:"function transferFrom(address who, address to, uint amount)\n external\n{\n require( balances[who] >= amount );\n require( allowances[who][msg.sender] >= amount );\n // ...\n}\n"})}),"\n",(0,a.jsx)(n.p,{children:"Modifying the order of error checking can prevent the accidental disclosure of\nbalance information in the example above."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-solidity",children:"function transferFrom(address who, address to, uint amount)\n external\n{\n require( allowances[who][msg.sender] >= amount );\n require( balances[who] >= amount );\n // ...\n}\n"})}),"\n",(0,a.jsx)(n.h2,{id:"speed-bump",children:"Speed Bump"}),"\n",(0,a.jsx)(n.p,{children:"If we would like to prevent off-chain calls from being chained together, we can\nensure that the block has been finalized."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-solidity",children:'contract Secret {\n uint256 private _height;\n bytes private _secret;\n address private _buyer;\n\n constructor(bytes memory _text) {\n _secret = _text;\n }\n\n function recordPayment() external payable {\n require(msg.value == 1 ether);\n // set and lock buyer\n _height = block.number;\n _buyer = msg.sender;\n }\n\n /// @notice Reveals the secret.\n function revealSecret() view external returns (bytes memory) {\n require(block.number > _height, "not settled");\n require(_buyer != address(0), "no recorded buyer");\n // TODO: optionally authenticate call from buyer\n return _secret;\n }\n}\n'})}),"\n",(0,a.jsx)(n.h2,{id:"gas-padding",children:"Gas Padding"}),"\n",(0,a.jsxs)(n.p,{children:["To prevent leaking information about a particular transaction, Sapphire\nprovides a ",(0,a.jsx)(n.a,{href:"https://api.docs.oasis.io/sol/sapphire-contracts/contracts/Sapphire.sol/library.Sapphire.html#padgas",children:"precompile"})," for dApp developers to ",(0,a.jsx)(n.strong,{children:"pad the amount of gas used\nin a transaction"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-solidity",children:"contract GasExample {\n bytes32 tmp;\n\n function constantMath(bool doMath, uint128 padGasAmount) external {\n if (doMath) {\n bytes32 x;\n\n for (uint256 i = 0; i < 100; i++) {\n x = keccak256(abi.encodePacked(x, tmp));\n }\n\n tmp = x;\n }\n\n Sapphire.padGas(padGasAmount);\n }\n}\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Both contract calls below should use the same amount of gas. Sapphire also\nprovides the precompile to return the gas ",(0,a.jsx)(n.a,{href:"https://api.docs.oasis.io/sol/sapphire-contracts/contracts/Sapphire.sol/library.Sapphire.html#gasused",children:"used"})," by the current transaction."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-typescript",children:"await contract.constantMath(true, 100000);\nawait contract.constantMath(false, 100000);\n"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(p,{...e})}):p(e)}},9365:(e,n,t)=>{t.d(n,{A:()=>o});t(6540);var a=t(4164);const r={tabItem:"tabItem_Ymn6"};var s=t(4848);function o(e){let{children:n,hidden:t,className:o}=e;return(0,s.jsx)("div",{role:"tabpanel",className:(0,a.A)(r.tabItem,o),hidden:t,children:n})}},1470:(e,n,t)=>{t.d(n,{A:()=>w});var a=t(6540),r=t(4164),s=t(3104),o=t(6347),i=t(205),l=t(7485),c=t(1682),u=t(9466);function d(e){return a.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:n,children:t}=e;return(0,a.useMemo)((()=>{const e=n??function(e){return d(e).map((e=>{let{props:{value:n,label:t,attributes:a,default:r}}=e;return{value:n,label:t,attributes:a,default:r}}))}(t);return function(e){const n=(0,c.X)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,t])}function h(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:t}=e;const r=(0,o.W6)(),s=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,l.aZ)(s),(0,a.useCallback)((e=>{if(!s)return;const n=new URLSearchParams(r.location.search);n.set(s,e),r.replace({...r.location,search:n.toString()})}),[s,r])]}function f(e){const{defaultValue:n,queryString:t=!1,groupId:r}=e,s=p(e),[o,l]=(0,a.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!h({value:n,tabValues:t}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const a=t.find((e=>e.default))??t[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:n,tabValues:s}))),[c,d]=m({queryString:t,groupId:r}),[f,g]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[r,s]=(0,u.Dv)(t);return[r,(0,a.useCallback)((e=>{t&&s.set(e)}),[t,s])]}({groupId:r}),b=(()=>{const e=c??f;return h({value:e,tabValues:s})?e:null})();(0,i.A)((()=>{b&&l(b)}),[b]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!h({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);l(e),d(e),g(e)}),[d,g,s]),tabValues:s}}var g=t(2303);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var x=t(4848);function v(e){let{className:n,block:t,selectedValue:a,selectValue:o,tabValues:i}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,s.a_)(),u=e=>{const n=e.currentTarget,t=l.indexOf(n),r=i[t].value;r!==a&&(c(n),o(r))},d=e=>{let n=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const t=l.indexOf(e.currentTarget)+1;n=l[t]??l[0];break}case"ArrowLeft":{const t=l.indexOf(e.currentTarget)-1;n=l[t]??l[l.length-1];break}}n?.focus()};return(0,x.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.A)("tabs",{"tabs--block":t},n),children:i.map((e=>{let{value:n,label:t,attributes:s}=e;return(0,x.jsx)("li",{role:"tab",tabIndex:a===n?0:-1,"aria-selected":a===n,ref:e=>l.push(e),onKeyDown:d,onClick:u,...s,className:(0,r.A)("tabs__item",b.tabItem,s?.className,{"tabs__item--active":a===n}),children:t??n},n)}))})}function y(e){let{lazy:n,children:t,selectedValue:r}=e;const s=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=s.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return(0,x.jsx)("div",{className:"margin-top--md",children:s.map(((e,n)=>(0,a.cloneElement)(e,{key:n,hidden:e.props.value!==r})))})}function j(e){const n=f(e);return(0,x.jsxs)("div",{className:(0,r.A)("tabs-container",b.tabList),children:[(0,x.jsx)(v,{...n,...e}),(0,x.jsx)(y,{...n,...e})]})}function w(e){const n=(0,g.A)();return(0,x.jsx)(j,{...e,children:d(e.children)},String(n))}},8453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>i});var a=t(6540);const r={},s=a.createContext(r);function o(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/4daae886.d552a7b3.js b/assets/js/4daae886.d552a7b3.js
new file mode 100644
index 0000000000..40399a684b
--- /dev/null
+++ b/assets/js/4daae886.d552a7b3.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[5456],{1494:(e,i,s)=>{s.r(i),s.d(i,{assets:()=>c,contentTitle:()=>r,default:()=>l,frontMatter:()=>t,metadata:()=>d,toc:()=>o});var a=s(4848),n=s(8453);const t={},r="ADR 0008: Standard Account Key Generation",d={id:"adrs/0008-standard-account-key-generation",title:"ADR 0008: Standard Account Key Generation",description:"Component",source:"@site/docs/adrs/0008-standard-account-key-generation.md",sourceDirName:"adrs",slug:"/adrs/0008-standard-account-key-generation",permalink:"/adrs/0008-standard-account-key-generation",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/adrs/edit/main/0008-standard-account-key-generation.md",tags:[],version:"current",lastUpdatedAt:1710755515e3,frontMatter:{},sidebar:"adrs",previous:{title:"ADR 0007: Improved Random Beacon",permalink:"/adrs/0007-improved-random-beacon"},next:{title:"ADR 0009: Ed25519 Signature Verification Semantics",permalink:"/adrs/0009-ed25519-semantics"}},c={},o=[{value:"Component",id:"component",level:2},{value:"Changelog",id:"changelog",level:2},{value:"Status",id:"status",level:2},{value:"Context",id:"context",level:2},{value:"Decision",id:"decision",level:2},{value:"Mnemonic Codes for Master Key Derivation",id:"mnemonic-codes-for-master-key-derivation",level:3},{value:"Hierarchical Key Derivation Scheme",id:"hierarchical-key-derivation-scheme",level:3},{value:"Key Derivation Paths",id:"key-derivation-paths",level:3},{value:"Rationale",id:"rationale",level:2},{value:"SLIP-0010 for Hierarchical Key Derivation Scheme",id:"slip-0010-for-hierarchical-key-derivation-scheme",level:3},{value:"Adoption",id:"adoption",level:4},{value:"Difficulties in Adapting BIP-0032 to edwards25519 Curve",id:"difficulties-in-adapting-bip-0032-to-edwards25519-curve",level:4},{value:"Shorter Key Derivation Paths",id:"shorter-key-derivation-paths",level:3},{value:"Test Vectors",id:"test-vectors",level:2},{value:"Implementation",id:"implementation",level:2},{value:"Alternatives",id:"alternatives",level:2},{value:"BIP32-Ed25519 for Hierarchical Key Derivation",id:"bip32-ed25519-for-hierarchical-key-derivation",level:3},{value:"Adoption",id:"adoption-1",level:4},{value:"Security Concerns",id:"security-concerns",level:4},{value:"Implementation Issues",id:"implementation-issues",level:4},{value:"Tor's Next Generation Hidden Service Keys for Hierarchical Key Derivation",id:"tors-next-generation-hidden-service-keys-for-hierarchical-key-derivation",level:3},{value:"Consequences",id:"consequences",level:2},{value:"Positive",id:"positive",level:3},{value:"Negative",id:"negative",level:3},{value:"Neutral",id:"neutral",level:3},{value:"References",id:"references",level:2}];function h(e){const i={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,n.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(i.h1,{id:"adr-0008-standard-account-key-generation",children:"ADR 0008: Standard Account Key Generation"}),"\n",(0,a.jsx)(i.h2,{id:"component",children:"Component"}),"\n",(0,a.jsx)(i.p,{children:"Oasis Core"}),"\n",(0,a.jsx)(i.h2,{id:"changelog",children:"Changelog"}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsx)(i.li,{children:"2021-05-07: Add test vectors and reference implementation, extend Consequences\nsection"}),"\n",(0,a.jsx)(i.li,{children:"2021-04-19: Switch from BIP32-Ed25519 to SLIP-0010 for hierarchical key\nderivation scheme"}),"\n",(0,a.jsx)(i.li,{children:"2021-01-27: Initial draft"}),"\n"]}),"\n",(0,a.jsx)(i.h2,{id:"status",children:"Status"}),"\n",(0,a.jsx)(i.p,{children:"Accepted"}),"\n",(0,a.jsx)(i.h2,{id:"context",children:"Context"}),"\n",(0,a.jsx)(i.p,{children:"Currently, each application interacting with the Oasis Network defines its own\nmethod of generating an account's private/public key pair."}),"\n",(0,a.jsxs)(i.p,{children:[(0,a.jsx)(i.a,{href:"/core/consensus/services/staking#accounts",children:"Account"}),"'s public key is in turn used to derive the account's address of the\nform ",(0,a.jsx)(i.code,{children:"oasis1 ... 40 characters ..."})," which is used to for a variety of operations\n(i.e. token transfers, delegations/undelegations, ...) on the network."]}),"\n",(0,a.jsx)(i.p,{children:"The blockchain ecosystem has developed many standards for generating keys which\nimprove key storage and interoperability between different applications."}),"\n",(0,a.jsx)(i.p,{children:"Adopting these standards will allow the Oasis ecosystem to:"}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsx)(i.li,{children:"Make key derivation the same across different applications (i.e. wallets)."}),"\n",(0,a.jsx)(i.li,{children:"Allow users to hold keys in hardware wallets."}),"\n",(0,a.jsx)(i.li,{children:"Allow users to hold keys in cold storage more reliably (i.e. using the\nfamiliar 24 word mnemonics)."}),"\n",(0,a.jsx)(i.li,{children:"Define how users can generate multiple keys from a single seed (i.e.\nthe 24 or 12 word mnemonic)."}),"\n"]}),"\n",(0,a.jsx)(i.h2,{id:"decision",children:"Decision"}),"\n",(0,a.jsx)(i.h3,{id:"mnemonic-codes-for-master-key-derivation",children:"Mnemonic Codes for Master Key Derivation"}),"\n",(0,a.jsxs)(i.p,{children:["We use Bitcoin's ",(0,a.jsx)(i.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki",children:"BIP-0039"}),": ",(0,a.jsx)(i.em,{children:"Mnemonic code for generating deterministic keys"}),"\nto derivate a binary seed from a mnemonic code."]}),"\n",(0,a.jsxs)(i.p,{children:["The binary seed is in turn used to derive the ",(0,a.jsx)(i.em,{children:"master key"}),", the root key from\nwhich a hierarchy of deterministic keys is derived, as described in\n",(0,a.jsx)(i.a,{href:"#hierarchical-key-derivation-scheme",children:"Hierarchical Key Derivation Scheme"}),"."]}),"\n",(0,a.jsx)(i.p,{children:"We strongly recommend using 24 word mnemonics which correspond to 256 bits of\nentropy."}),"\n",(0,a.jsx)(i.h3,{id:"hierarchical-key-derivation-scheme",children:"Hierarchical Key Derivation Scheme"}),"\n",(0,a.jsxs)(i.p,{children:["We use Sathoshi Labs' ",(0,a.jsx)(i.a,{href:"https://github.com/satoshilabs/slips/blob/master/slip-0010.md",children:"SLIP-0010"}),": ",(0,a.jsx)(i.em,{children:"Universal private key derivation from master\nprivate key"}),", which is a superset of\nBitcoin's ",(0,a.jsx)(i.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki",children:"BIP-0032"}),": ",(0,a.jsx)(i.em,{children:"Hierarchical Deterministic Wallets"})," derivation algorithm,\nextended to work on other curves."]}),"\n",(0,a.jsxs)(i.p,{children:["Account keys use the ",(0,a.jsx)(i.a,{href:"https://tools.ietf.org/html/rfc8032#section-5",children:"edwards25519 curve"})," from the Ed25519 signature scheme\nspecified in ",(0,a.jsx)(i.a,{href:"https://tools.ietf.org/html/rfc8032",children:"RFC 8032"}),"."]}),"\n",(0,a.jsx)(i.h3,{id:"key-derivation-paths",children:"Key Derivation Paths"}),"\n",(0,a.jsxs)(i.p,{children:["We adapt ",(0,a.jsx)(i.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki",children:"BIP-0044"}),": ",(0,a.jsx)(i.em,{children:"Multi-Account Hierarchy for Deterministic Wallets"})," for\ngenerating deterministic keys where ",(0,a.jsx)(i.code,{children:"coin_type"})," equals 474, as assigned to the\nOasis Network by ",(0,a.jsx)(i.a,{href:"https://github.com/satoshilabs/slips/blob/master/slip-0044.md",children:"SLIP-0044"}),"."]}),"\n",(0,a.jsxs)(i.p,{children:["The following ",(0,a.jsx)(i.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki",children:"BIP-0032"})," path should be used to generate keys:"]}),"\n",(0,a.jsx)(i.pre,{children:(0,a.jsx)(i.code,{children:"m/44'/474'/x'\n"})}),"\n",(0,a.jsxs)(i.p,{children:["where ",(0,a.jsx)(i.code,{children:"x"})," represents the key number."]}),"\n",(0,a.jsxs)(i.p,{children:["Note that all path levels are ",(0,a.jsx)(i.em,{children:"hardened"}),", e.g. ",(0,a.jsx)(i.code,{children:"44'"})," is ",(0,a.jsx)(i.code,{children:"44 | 0x8000000"})," or\n",(0,a.jsx)(i.code,{children:"44 + 2^31"}),"."]}),"\n",(0,a.jsxs)(i.p,{children:["The key corresponding to key number 0 (i.e. ",(0,a.jsx)(i.code,{children:"m/44'/474'/0'"}),") is called the\n",(0,a.jsx)(i.em,{children:"primary key"}),"."]}),"\n",(0,a.jsxs)(i.p,{children:["The account corresponding to the ",(0,a.jsx)(i.em,{children:"primary key"})," is called the ",(0,a.jsx)(i.em,{children:"primary account"}),".\nApplications (i.e. wallets) should use this account as a user's default Oasis\naccount."]}),"\n",(0,a.jsx)(i.h2,{id:"rationale",children:"Rationale"}),"\n",(0,a.jsx)(i.p,{children:"BIPs and SLIPs are industry standards used by a majority of blockchain projects\nand software/hardware wallets."}),"\n",(0,a.jsx)(i.h3,{id:"slip-0010-for-hierarchical-key-derivation-scheme",children:"SLIP-0010 for Hierarchical Key Derivation Scheme"}),"\n",(0,a.jsxs)(i.p,{children:[(0,a.jsx)(i.a,{href:"https://github.com/satoshilabs/slips/blob/master/slip-0010.md",children:"SLIP-0010"})," defines a hierarchical key derivation scheme which is a superset of\n",(0,a.jsx)(i.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki",children:"BIP-0032"})," derivation algorithm extended to work on other curves."]}),"\n",(0,a.jsxs)(i.p,{children:["In particular, we use their adaptation for the ",(0,a.jsx)(i.a,{href:"https://tools.ietf.org/html/rfc8032#section-5",children:"edwards25519 curve"}),"."]}),"\n",(0,a.jsx)(i.h4,{id:"adoption",children:"Adoption"}),"\n",(0,a.jsxs)(i.p,{children:["It is used by Stellar (",(0,a.jsx)(i.a,{href:"https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0005.md",children:"SEP-0005"}),")."]}),"\n",(0,a.jsxs)(i.p,{children:["It is supported by ",(0,a.jsx)(i.a,{href:"https://www.ledger.com/",children:"Ledger"})," and ",(0,a.jsx)(i.a,{href:"https://trezor.io/",children:"Trezor"})," hardware wallets."]}),"\n",(0,a.jsx)(i.p,{children:"It is commonly used by Ledger applications, including:"}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsxs)(i.li,{children:[(0,a.jsx)(i.a,{href:"https://github.com/LedgerHQ/app-stellar/blob/fc4ec38d9abcae9bd47c95ef93feb5e1ff25961f/src/stellar.c#L42-L49",children:"Stellar's Ledger app"}),","]}),"\n",(0,a.jsxs)(i.li,{children:[(0,a.jsx)(i.a,{href:"https://github.com/LedgerHQ/app-solana/blob/1c72216edf4e5358f719b164a8d1b6100988b34d/src/utils.c#L42-L51",children:"Solana's Ledger app"}),","]}),"\n",(0,a.jsxs)(i.li,{children:[(0,a.jsx)(i.a,{href:"https://github.com/LedgerHQ/app-near/blob/40ea52a0de81d65b993a49ac705e7edad8efff0e/workdir/app-near/src/crypto/ledger_crypto.c#L24",children:"NEAR Protocol's Ledger app"}),","]}),"\n",(0,a.jsxs)(i.li,{children:[(0,a.jsx)(i.a,{href:"https://github.com/LedgerHQ/app-sia/blob/d4dbb5a9cae2e2389d6b6a44701069e234f0f392/src/sia.c#L14",children:"Siacoin's Ledger app"}),","]}),"\n",(0,a.jsxs)(i.li,{children:[(0,a.jsx)(i.a,{href:"https://github.com/LedgerHQ/app-hedera/blob/47066dcfa02379a48a65c33efb1484bb744a30a5/src/hedera.c#L21-L30",children:"Hedera Hashgraph's Ledger app"}),"."]}),"\n"]}),"\n",(0,a.jsx)(i.h4,{id:"difficulties-in-adapting-bip-0032-to-edwards25519-curve",children:"Difficulties in Adapting BIP-0032 to edwards25519 Curve"}),"\n",(0,a.jsxs)(i.p,{children:["Creating a hierarchical key derivation scheme for the ",(0,a.jsx)(i.a,{href:"https://tools.ietf.org/html/rfc8032#section-5",children:"edwards25519 curve"}),'\nproved to be very challenging due to edwards25519\'s small cofactor and bit\n"clamping".']}),"\n",(0,a.jsxs)(i.p,{children:[(0,a.jsx)(i.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki",children:"BIP-0032"})," was designed for the ",(0,a.jsx)(i.a,{href:"https://en.bitcoin.it/wiki/Secp256k1",children:"secp256k1"})," elliptic curve with a prime-order\ngroup. For performance reasons, edwards25519 doesn't provide a prime-order group\nand provides a group of order ",(0,a.jsx)(i.em,{children:"h"})," * ",(0,a.jsx)(i.em,{children:"l"})," instead, where ",(0,a.jsx)(i.em,{children:"h"})," is a small co-factor\n(8) and ",(0,a.jsx)(i.em,{children:"l"})," is a 252-bit prime."]}),"\n",(0,a.jsxs)(i.p,{children:["While using a co-factor offers better performance, it has proven to be a source\nof issues and vulnerabilities in higher-layer protocol implementations as\n",(0,a.jsx)(i.a,{href:"https://ristretto.group/why_ristretto.html#pitfalls-of-a-cofactor",children:"described by Risretto authors"}),"."]}),"\n",(0,a.jsxs)(i.p,{children:['Additionally, edwards25519 curve employs bit "clamping". As ',(0,a.jsx)(i.a,{href:"https://moderncrypto.org/mail-archive/curves/2017/000874.html",children:"described by Trevor\nPerrin"}),', low bits are "clamped" to deal with\nsmall-subgroup attacks and high bits are "clamped" so that:']}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsx)(i.li,{children:"the scalar is smaller than the subgroup order, and"}),"\n",(0,a.jsx)(i.li,{children:"the highest bit set is constant in case the scalar is used with a\nnon-constant-time scalar multiplication algorithm that leaks based on the\nhighest set bit."}),"\n"]}),"\n",(0,a.jsxs)(i.p,{children:["These issues were discussed on ",(0,a.jsx)(i.a,{href:"https://moderncrypto.org/",children:"modern crypto"}),"'s mailing list ",(0,a.jsx)(i.a,{href:"https://moderncrypto.org/mail-archive/curves/2017/000858.html",children:"[1]"}),", ",(0,a.jsx)(i.a,{href:"https://moderncrypto.org/mail-archive/curves/2017/000866.html",children:"[2]"}),"."]}),"\n",(0,a.jsxs)(i.p,{children:[(0,a.jsx)(i.a,{href:"https://github.com/satoshilabs/slips/blob/master/slip-0010.md",children:"SLIP-0010"})," avoids these issues because it doesn't try to support non-hardened\nparent public key to child public key derivation and only supports hardened\nprivate parent key to private child key derivation when used with the\nedwards25519 curve."]}),"\n",(0,a.jsx)(i.h3,{id:"shorter-key-derivation-paths",children:"Shorter Key Derivation Paths"}),"\n",(0,a.jsxs)(i.p,{children:["Similar to Stellar's ",(0,a.jsx)(i.a,{href:"https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0005.md",children:"SEP-0005"}),", we decided not to use the full ",(0,a.jsx)(i.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki",children:"BIP-0032"}),"\nderivation path specified by ",(0,a.jsx)(i.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki",children:"BIP-0044"})," because ",(0,a.jsx)(i.a,{href:"https://github.com/satoshilabs/slips/blob/master/slip-0010.md",children:"SLIP-0010"}),"'s scheme for\n",(0,a.jsx)(i.a,{href:"https://tools.ietf.org/html/rfc8032#section-5",children:"edwards25519 curve"})," only supports hardened private parent key to private child\nkey derivation and additionally, the Oasis Network is account-based rather than\n",(0,a.jsx)(i.a,{href:"https://en.wikipedia.org/wiki/Unspent_transaction_output",children:"UTXO"}),"-based."]}),"\n",(0,a.jsxs)(i.p,{children:[(0,a.jsx)(i.a,{href:"https://trezor.io/",children:"Trezor"})," follows the same scheme for account-based blockchain networks as\ndescribed in their ",(0,a.jsx)(i.a,{href:"https://github.com/trezor/trezor-firmware/blob/master/docs/misc/coins-bip44-paths.md",children:"BIP-44 derivation paths"})," document."]}),"\n",(0,a.jsx)(i.h2,{id:"test-vectors",children:"Test Vectors"}),"\n",(0,a.jsx)(i.pre,{children:(0,a.jsx)(i.code,{className:"language-json",children:'[\n {\n "kind": "standard account key generation",\n "bip39_mnemonic": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",\n "bip39_passphrase": "",\n "bip39_seed": "5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4",\n "oasis_accounts": [\n {\n "bip32_path": "m/44\'/474\'/0\'",\n "private_key": "fb181e94e95cc6bedd2da03e6c4aca9951053f3e9865945dbc8975a6afd217c3ad55bbb7c192b8ecfeb6ad18bbd7681c0923f472d5b0c212fbde33008005ad61",\n "public_key": "ad55bbb7c192b8ecfeb6ad18bbd7681c0923f472d5b0c212fbde33008005ad61",\n "address": "oasis1qqx0wgxjwlw3jwatuwqj6582hdm9rjs4pcnvzz66"\n },\n {\n "bip32_path": "m/44\'/474\'/1\'",\n "private_key": "1792482bcb001f45bc8ab15436e62d60fe3eb8c86e8944bfc12da4dc67a5c89b73fd7c51a0f059ea34d8dca305e0fdb21134ca32216ca1681ae1d12b3d350e16",\n "public_key": "73fd7c51a0f059ea34d8dca305e0fdb21134ca32216ca1681ae1d12b3d350e16",\n "address": "oasis1qr4xfjmmfx7zuyvskjw9jl3nxcp6a48e8v5e27ty"\n },\n {\n "bip32_path": "m/44\'/474\'/2\'",\n "private_key": "765be01f40c1b78dd807e03a5099220c851cfe55870ab082be2345d63ffb9aa40f85ea84b81abded443be6ab3e16434cdddebca6e12ea27560a6ed65ff1998e0",\n "public_key": "0f85ea84b81abded443be6ab3e16434cdddebca6e12ea27560a6ed65ff1998e0",\n "address": "oasis1qqtdpw7jez243dnvmzfrhvgkm8zpndssvuwm346d"\n },\n {\n "bip32_path": "m/44\'/474\'/3\'",\n "private_key": "759b3c2af3d7129072666677b37e9e7b6d22c8bbf634816627e1704f596f60c411ebdac05bfa37b746692733f15a02be9842b29088272354012417a215666b0e",\n "public_key": "11ebdac05bfa37b746692733f15a02be9842b29088272354012417a215666b0e",\n "address": "oasis1qqs7wl20gfppe2krdy3tm4298yt9gftxpc9j27z2"\n },\n {\n "bip32_path": "m/44\'/474\'/4\'",\n "private_key": "db77a8a8508fd77083ba63f31b0a348441d4823e6ba73b65f354a93cf789358d8753c5da6085e6dbf5969773d27b08ee05eddcb3e11d570aaadf0f42036e69b1",\n "public_key": "8753c5da6085e6dbf5969773d27b08ee05eddcb3e11d570aaadf0f42036e69b1",\n "address": "oasis1qq8neyfkydj874tvs6ksljlmtxgw3plkkgf69j4w"\n },\n {\n "bip32_path": "m/44\'/474\'/5\'",\n "private_key": "318e1fba7d83ca3ea57b0f45377e77391479ec38bfb2236a2842fe1b7a624e8800e1a8016629f2882bca2174f29033ec2a57747cd9d3c27f49cc6e11e38ee7bc",\n "public_key": "00e1a8016629f2882bca2174f29033ec2a57747cd9d3c27f49cc6e11e38ee7bc",\n "address": "oasis1qrdjslqdum7wwehz3uaw6t6xkpth0a9n8clsu6xq"\n },\n {\n "bip32_path": "m/44\'/474\'/6\'",\n "private_key": "63a7f716e1994f7a8ab80f8acfae4c28c21af6b2f3084756b09651f4f4ee38606b85d0a8a9747faac85233ad5e4501b2a6862a4c02a46a0b7ea699cf2bd38f98",\n "public_key": "6b85d0a8a9747faac85233ad5e4501b2a6862a4c02a46a0b7ea699cf2bd38f98",\n "address": "oasis1qzlt62g85303qcrlm7s2wx2z8mxkr5v0yg5me0z3"\n },\n {\n "bip32_path": "m/44\'/474\'/7\'",\n "private_key": "34af69924c04d75c79bd120e03d667ff6287ab602f9285bb323667ddf9f25c974f49a7672eeadbf78f910928e3d592d17f1e14964693cfa2afd94b79f0d49f48",\n "public_key": "4f49a7672eeadbf78f910928e3d592d17f1e14964693cfa2afd94b79f0d49f48",\n "address": "oasis1qzw2gd3qq8nse6648df32zxvsryvljeyyyl3cxma"\n },\n {\n "bip32_path": "m/44\'/474\'/8\'",\n "private_key": "aa5242e7efe8dee05c21192766a11c46531f500ff7c0cc29ed59523c5e618792c0a24bf07953520f21c1c25882d9dbf00d24d0499be443fdcf07f2da9601d3e5",\n "public_key": "c0a24bf07953520f21c1c25882d9dbf00d24d0499be443fdcf07f2da9601d3e5",\n "address": "oasis1qqzjkx9u549r87ctv7x7t0un29vww6k6hckeuvtm"\n },\n {\n "bip32_path": "m/44\'/474\'/9\'",\n "private_key": "b661567dcb9b5290889e110b0e9814e72d347c3a3bad2bafe2969637541451e5da8c9830655103c726ff80a4ac2f05a7e0b948a1986734a4f63b3e658da76c66",\n "public_key": "da8c9830655103c726ff80a4ac2f05a7e0b948a1986734a4f63b3e658da76c66",\n "address": "oasis1qpawhwugutd48zu4rzjdcgarcucxydedgq0uljkj"\n },\n {\n "bip32_path": "m/44\'/474\'/2147483647\'",\n "private_key": "cc05cca118f3f26f05a0ff8e2bf5e232eede9978b7736ba10c3265870229efb19e7c2b2d03265ce4ea175e3664a678182548a7fc6db04801513cff7c98c8f151",\n "public_key": "9e7c2b2d03265ce4ea175e3664a678182548a7fc6db04801513cff7c98c8f151",\n "address": "oasis1qq7895v02vh40yc2dqfxhldww7wxsky0wgfdenrv"\n }\n ]\n },\n {\n "kind": "standard account key generation",\n "bip39_mnemonic": "equip will roof matter pink blind book anxiety banner elbow sun young",\n "bip39_passphrase": "",\n "bip39_seed": "ed2f664e65b5ef0dd907ae15a2788cfc98e41970bc9fcb46f5900f6919862075e721f37212304a56505dab99b001cc8907ef093b7c5016a46b50c01cc3ec1cac",\n "oasis_accounts": [\n {\n "bip32_path": "m/44\'/474\'/0\'",\n "private_key": "4e9ca1a4c2ed90c90da93ea181557ef9f465f444c0b7de35daeb218f9390d98545601f761af17dba50243529e629732f1c58d08ffddaa8491238540475729d85",\n "public_key": "45601f761af17dba50243529e629732f1c58d08ffddaa8491238540475729d85",\n "address": "oasis1qqjkrr643qv7yzem6g4m8rrtceh42n46usfscpcf"\n },\n {\n "bip32_path": "m/44\'/474\'/1\'",\n "private_key": "2d0d2e75a13fd9dc423a2db8dfc1db6ebacd53f22c8a7eeb269086ec3b443eb627ed04a3c0dcec6591c001e4ea307d65cbd712cb90d85ab7703c35eee07a77dd",\n "public_key": "27ed04a3c0dcec6591c001e4ea307d65cbd712cb90d85ab7703c35eee07a77dd",\n "address": "oasis1qp42qp8d5k8pgekvzz0ld47k8ewvppjtmqg7t5kz"\n },\n {\n "bip32_path": "m/44\'/474\'/2\'",\n "private_key": "351749392b02c6b7a5053bc678e71009b4fb07c37a67b44558064dc63b2efd9219456a3f0cf3f4cc5e6ce52def57d92bb3c5a651fa9626b246cfec07abc28724",\n "public_key": "19456a3f0cf3f4cc5e6ce52def57d92bb3c5a651fa9626b246cfec07abc28724",\n "address": "oasis1qqnwwhj4qvtap422ck7qjxf7wm89tgjhwczpu0f3"\n },\n {\n "bip32_path": "m/44\'/474\'/3\'",\n "private_key": "ebc13ccb62142ed5b600f398270801f8f80131b225feb278d42982ce314f896292549046214fdb4729bf7a6ee4a3bbd0f463c476acc933b2c7cce084509abee4",\n "public_key": "92549046214fdb4729bf7a6ee4a3bbd0f463c476acc933b2c7cce084509abee4",\n "address": "oasis1qp36crawwyk0gnfyf0epcsngnpuwrz0mtu8qzu2f"\n },\n {\n "bip32_path": "m/44\'/474\'/4\'",\n "private_key": "664b95ad8582831fb787afefd0febdddcf03343cc1ca5aa86057477e0f22c93b331288192d442d3a32e239515b4c019071c57ee89f91942923dd4c1535db096c",\n "public_key": "331288192d442d3a32e239515b4c019071c57ee89f91942923dd4c1535db096c",\n "address": "oasis1qz8d2zptvf44y049g9dtyqya4g0jcqxmjsf9pqa3"\n },\n {\n "bip32_path": "m/44\'/474\'/5\'",\n "private_key": "257600bfccc21e0bc772f4d1dcfb2834805e07959ad7bd586e7deec4a320bfcecbbfef21f0833744b3504a9860b42cb0bb11e2eb042a8b83e3ceb91fe0fca096",\n "public_key": "cbbfef21f0833744b3504a9860b42cb0bb11e2eb042a8b83e3ceb91fe0fca096",\n "address": "oasis1qz0cxkl3mftumy9l4g663fmwg69vmtc675xh8exw"\n },\n {\n "bip32_path": "m/44\'/474\'/6\'",\n "private_key": "10d224fbbac9d6e3084dff75ed1d3ae2ce52bce3345a48bf68d1552ed7d89594defb924439e0c93f3b14f25b3cb4044f9bc9055fa4a14d89f711528e6760133b",\n "public_key": "defb924439e0c93f3b14f25b3cb4044f9bc9055fa4a14d89f711528e6760133b",\n "address": "oasis1qz3pjvqnkyj42d0mllgcjd66fkavzywu4y4uhak7"\n },\n {\n "bip32_path": "m/44\'/474\'/7\'",\n "private_key": "517bcc41be16928d32c462ee2a38981ed15b784028eb0914cfe84acf475be342102ad25ab9e1707c477e39da2184f915669791a3a7b87df8fd433f15c926ede2",\n "public_key": "102ad25ab9e1707c477e39da2184f915669791a3a7b87df8fd433f15c926ede2",\n "address": "oasis1qr8zs06qtew5gefgs4608a4dzychwkm0ayz36jqg"\n },\n {\n "bip32_path": "m/44\'/474\'/8\'",\n "private_key": "ee7577c5cef5714ba6738635c6d9851c43428ff3f1e8db2fe7f45fb8d8be7c55a6ec8903ca9062910cc780c9b209c7767c2e57d646bbe06901d090ad81dabe8b",\n "public_key": "a6ec8903ca9062910cc780c9b209c7767c2e57d646bbe06901d090ad81dabe8b",\n "address": "oasis1qp7w82tmm6srgxqqzragdt3269334pjtlu44qpeu"\n },\n {\n "bip32_path": "m/44\'/474\'/9\'",\n "private_key": "5257b10a5fcfd008824e2216be17be6e47b9db74018f63bb55de4d747cae6d7bba734348f3ec7af939269f62828416091c0d89e14c813ebf5e64e24d6d37e7ab",\n "public_key": "ba734348f3ec7af939269f62828416091c0d89e14c813ebf5e64e24d6d37e7ab",\n "address": "oasis1qp9t7zerat3lh2f7xzc58ahqzta5kj4u3gupgxfk"\n },\n {\n "bip32_path": "m/44\'/474\'/2147483647\'",\n "private_key": "e7152f1b69ad6edfc05dccf67dad5305edb224669025c809d89de7e56b2cabe58c348f412819da57361cdbd7dfbe695a05dba7f24b8e7328ff991ffadab6c4d2",\n "public_key": "8c348f412819da57361cdbd7dfbe695a05dba7f24b8e7328ff991ffadab6c4d2",\n "address": "oasis1qzajez400yvnzcv8x8gtcxt4z5mkfchuh5ca05hq"\n }\n ]\n }\n]\n'})}),"\n",(0,a.jsx)(i.p,{children:"To generate these test vectors yourself, run:"}),"\n",(0,a.jsx)(i.pre,{children:(0,a.jsx)(i.code,{children:"make -C go staking/gen_account_vectors\n"})}),"\n",(0,a.jsx)(i.p,{children:"We also provide more extensive test vectors. To generate them, run:"}),"\n",(0,a.jsx)(i.pre,{children:(0,a.jsx)(i.code,{children:"make -C go staking/gen_account_vectors_extended\n"})}),"\n",(0,a.jsx)(i.h2,{id:"implementation",children:"Implementation"}),"\n",(0,a.jsxs)(i.p,{children:["Reference implementation is in Oasis Core's ",(0,a.jsxs)(i.a,{href:"https://pkg.go.dev/github.com/oasisprotocol/oasis-core/go/common/crypto/sakg",children:[(0,a.jsx)(i.code,{children:"go/common/crypto/sakg"})," package"]}),"."]}),"\n",(0,a.jsx)(i.h2,{id:"alternatives",children:"Alternatives"}),"\n",(0,a.jsx)(i.h3,{id:"bip32-ed25519-for-hierarchical-key-derivation",children:"BIP32-Ed25519 for Hierarchical Key Derivation"}),"\n",(0,a.jsxs)(i.p,{children:["The ",(0,a.jsx)(i.a,{href:"https://github.com/WebOfTrustInfo/rwot3-sf/blob/master/topics-and-advance-readings/HDKeys-Ed25519.pdf",children:"BIP32-Ed25519"})," (also sometimes referred to as ",(0,a.jsxs)(i.em,{children:["Ed25519 and BIP32\nbased on ",(0,a.jsx)(i.a,{href:"https://en.wikipedia.org/wiki/Dmitry_Khovratovich",children:"Khovratovich"})]}),") is a key derivation scheme that also adapts\n",(0,a.jsx)(i.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki",children:"BIP-0032"}),"'s hierarchical derivation scheme for the ",(0,a.jsx)(i.a,{href:"https://tools.ietf.org/html/rfc8032#section-5",children:"edwards25519 curve"})," from\nthe Ed25519 signature scheme specified in ",(0,a.jsx)(i.a,{href:"https://tools.ietf.org/html/rfc8032",children:"RFC 8032"}),"."]}),"\n",(0,a.jsx)(i.h4,{id:"adoption-1",children:"Adoption"}),"\n",(0,a.jsxs)(i.p,{children:["It is used by Cardano (",(0,a.jsx)(i.a,{href:"https://cips.cardano.org/cips/cip3/",children:"CIP 3"}),") and Tezos (dubbed ",(0,a.jsx)(i.a,{href:"https://medium.com/@obsidian.systems/v2-2-0-of-tezos-ledger-apps-babylon-support-and-more-e8df0e4ea161",children:"bip25519 derivation scheme"}),")."]}),"\n",(0,a.jsxs)(i.p,{children:["It is supported by ",(0,a.jsx)(i.a,{href:"https://www.ledger.com/",children:"Ledger"})," and ",(0,a.jsx)(i.a,{href:"https://trezor.io/",children:"Trezor"})," hardware wallets."]}),"\n",(0,a.jsx)(i.p,{children:"It is commonly used by Ledger applications, including:"}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsxs)(i.li,{children:[(0,a.jsx)(i.a,{href:"https://github.com/Zondax/ledger-polkadot/blob/7c3841a96caa5af6b78d49aac52b1373f10e3773/app/src/crypto.c#L44-L52",children:"Polkadot's Ledger app"}),","]}),"\n",(0,a.jsxs)(i.li,{children:[(0,a.jsx)(i.a,{href:"https://github.com/Zondax/ledger-kusama/blob/90593207558ed82ad97123b730b07bcc33aeabf2/app/src/crypto.c#L44-L52",children:"Kusama's Ledger app"}),","]}),"\n",(0,a.jsxs)(i.li,{children:[(0,a.jsx)(i.a,{href:"https://github.com/Zondax/ledger-zcash/blob/61fe324e567af59d39c609b84b591e28997c1a61/app/src/crypto.c#L173-L178",children:"Zcash's Ledger app"}),","]}),"\n",(0,a.jsxs)(i.li,{children:[(0,a.jsx)(i.a,{href:"https://github.com/Zondax/ledger-polymesh/blob/6228950a76c945fb0b5d7fc19fa475eccdf4160d/app/src/crypto.c#L44-L52",children:"Polymath's Ledger app"}),"."]}),"\n"]}),"\n",(0,a.jsx)(i.h4,{id:"security-concerns",children:"Security Concerns"}),"\n",(0,a.jsxs)(i.p,{children:["Its advantage is that it supports non-hardened parent public key to child public\nkey derivation which enables certain use cases described in ",(0,a.jsx)(i.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#use-cases",children:"BIP-0032"})," (i.e. audits, insecure money receiver, ...)."]}),"\n",(0,a.jsxs)(i.p,{children:["At the same time, allowing non-hardened parent public key to child public key\nderivation presents a serious security concern due to ",(0,a.jsx)(i.a,{href:"#difficulties-in-adapting-bip-0032-to-edwards25519-curve",children:"edwards25519's co-factor\nissues"}),"."]}),"\n",(0,a.jsxs)(i.p,{children:[(0,a.jsx)(i.a,{href:"https://github.com/burdges",children:"Jeff Burdges (Web3 Foundation)"})," warned about a potential ",(0,a.jsx)(i.a,{href:"https://web.archive.org/web/20210513183118/https://forum.w3f.community/t/key-recovery-attack-on-bip32-ed25519/44",children:"key recovery attack\non the BIP32-Ed25519 scheme"})," which could occur under the\nfollowing two assumptions:"]}),"\n",(0,a.jsxs)(i.ol,{children:["\n",(0,a.jsx)(i.li,{children:"The Ed25519 library used in BIP-Ed25519 derivation scheme does clamping\nimmediately before signing."}),"\n",(0,a.jsx)(i.li,{children:"Adversary has the power to make numerous small payments in deep hierarchies\nof key derivations, observe if the victim can cash out each payment, and\nadaptively continue this process."}),"\n"]}),"\n",(0,a.jsxs)(i.p,{children:["The first assumption is very reasonable since the ",(0,a.jsx)(i.a,{href:"https://github.com/WebOfTrustInfo/rwot3-sf/blob/master/topics-and-advance-readings/HDKeys-Ed25519.pdf",children:"BIP32-Ed25519"})," paper makes\nsupporting this part of their specification."]}),"\n",(0,a.jsxs)(i.p,{children:["The second assumption is a bit more controversial.\nThe ",(0,a.jsx)(i.a,{href:"https://github.com/WebOfTrustInfo/rwot3-sf/blob/master/topics-and-advance-readings/HDKeys-Ed25519.pdf",children:"BIP32-Ed25519"})," paper's specification limits the ",(0,a.jsx)(i.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki",children:"BIP-0032"})," path length\n(i.e. the number of levels in the tree) to 2",(0,a.jsx)("sup",{children:"20"}),".\nBut in practice, no implementation checks that and the issue is that path length\nis not an explicit part of the BIP32-Ed25519 algorithm. That means that one\ndoesn't know how deep in the tree the current parent/child node is. Hence, it\nwould be very hard to enforce the 2",(0,a.jsx)("sup",{children:"20"})," path length limit."]}),"\n",(0,a.jsx)(i.h4,{id:"implementation-issues",children:"Implementation Issues"}),"\n",(0,a.jsxs)(i.p,{children:["One practical issue with ",(0,a.jsx)(i.a,{href:"https://github.com/WebOfTrustInfo/rwot3-sf/blob/master/topics-and-advance-readings/HDKeys-Ed25519.pdf",children:"BIP32-Ed25519"})," is that its authors didn't provide a\nreference implementation and accompanying test vectors."]}),"\n",(0,a.jsx)(i.p,{children:"This has led to a number of incompatible BIP32-Ed25519 implementations."}),"\n",(0,a.jsxs)(i.p,{children:["For example, ",(0,a.jsx)(i.a,{href:"https://github.com/vbmithr/ocaml-bip32-ed25519",children:"Vincent Bernardoff's OCaml implementation"}),"\nand ",(0,a.jsx)(i.a,{href:"https://github.com/islishude/bip32",children:"Shude Li's Go implementation"})," follow ",(0,a.jsx)(i.a,{href:"https://github.com/WebOfTrustInfo/rwot3-sf/blob/master/topics-and-advance-readings/HDKeys-Ed25519.pdf",children:"BIP32-Ed25519"}),"'s\noriginal master (i.e. root) key derivation specification and use SHA512 and\nSHA256 for deriving the private key ",(0,a.jsx)(i.em,{children:"k"})," and chain code ",(0,a.jsx)(i.em,{children:"c"})," (respectively) from\nthe seed (i.e. master secret)."]}),"\n",(0,a.jsxs)(i.p,{children:["On the other hand, Ledger's ",(0,a.jsx)(i.a,{href:"https://github.com/LedgerHQ/orakolo/blob/0b2d5e669ec61df9a824df9fa1a363060116b490/src/python/orakolo/HDEd25519.py",children:"Python implementation in orakolo repository"})," and ",(0,a.jsx)(i.a,{href:"https://github.com/LedgerHQ/speculos/blob/dce04843ad7d4edbcd399391b3c39d30b37de3cd/src/bolos/os_bip32.c",children:"C implementation for their Speculos emulator"})," (variant with ",(0,a.jsx)(i.code,{children:"curve"})," equal to ",(0,a.jsx)(i.code,{children:"CX_CURVE_Ed25519"})," and\n",(0,a.jsx)(i.code,{children:"mode"})," equal to ",(0,a.jsx)(i.code,{children:"HDW_NORMAL"}),") use HMAC-SHA512 and HMAC-SHA256 for deriving the\nprivate key ",(0,a.jsx)(i.em,{children:"k"})," and chain code ",(0,a.jsx)(i.em,{children:"c"})," (respectively) from the seed."]}),"\n",(0,a.jsxs)(i.p,{children:["Furthermore, ",(0,a.jsx)(i.a,{href:"https://github.com/vbmithr/ocaml-bip32-ed25519/blob/461e6a301996d41755acd35d82cd7ab6e30a8437/src/bip32_ed25519.ml#L120-L128",children:"Vincent Bernardoff's OCaml implementation"})," follows ",(0,a.jsx)(i.a,{href:"https://github.com/WebOfTrustInfo/rwot3-sf/blob/master/topics-and-advance-readings/HDKeys-Ed25519.pdf",children:"BIP32-Ed25519"})," paper's instructions\nto discard the seed (i.e. master secret) if the master key's third highest bit\nof the last byte of ",(0,a.jsxs)(i.em,{children:["k",(0,a.jsx)("sub",{children:"L"})]})," is not zero."]}),"\n",(0,a.jsxs)(i.p,{children:["On the other hand, ",(0,a.jsx)(i.a,{href:"https://github.com/islishude/bip32/blob/72b7efc571fdb69a3f0ce4caf7078e5466b9273d/xprv.go#L51-L53",children:"Shude Li's Go implementation"}),"\njust clears the master key's third highest bit\nand ",(0,a.jsx)(i.a,{href:"https://github.com/LedgerHQ/orakolo/blob/0b2d5e669ec61df9a824df9fa1a363060116b490/src/python/orakolo/HDEd25519.py#L130-L133",children:"Ledger's implementations"})," repeatedly set\nthe seed to the master key and restart the derivation process until a master key\nwith the desired property is found."]}),"\n",(0,a.jsxs)(i.p,{children:["Cardano uses its own variants of ",(0,a.jsx)(i.a,{href:"https://github.com/WebOfTrustInfo/rwot3-sf/blob/master/topics-and-advance-readings/HDKeys-Ed25519.pdf",children:"BIP32-Ed25519"})," described in ",(0,a.jsx)(i.a,{href:"https://cips.cardano.org/cips/cip3/",children:"CIP 3"}),". In\nparticular, they define different variants of master key derivation from the\nseed described in ",(0,a.jsx)(i.a,{href:"https://github.com/satoshilabs/slips/blob/master/slip-0023.md",children:"SLIP-0023"}),"."]}),"\n",(0,a.jsxs)(i.p,{children:["Lastly, some implementations, notably ",(0,a.jsx)(i.a,{href:"https://github.com/LedgerHQ/app-oasis",children:"Oasis' Ledger app"}),",\ndon't use use ",(0,a.jsx)(i.a,{href:"https://github.com/WebOfTrustInfo/rwot3-sf/blob/master/topics-and-advance-readings/HDKeys-Ed25519.pdf",children:"BIP32-Ed25519"}),"'s private and public key directly but use the\nobtained ",(0,a.jsxs)(i.em,{children:["k",(0,a.jsx)("sub",{children:"L"})]})," (first 32 bytes) of the 64 byte BIP32-Ed25519 derived\nprivate key as Ed25519's seed (i.e. non-extended private key). For more details,\nsee ",(0,a.jsx)(i.a,{href:"https://github.com/Zondax/ledger-oasis/issues/84#issuecomment-827017112",children:"Zondax/ledger-oasis#84"}),"."]}),"\n",(0,a.jsx)(i.h3,{id:"tors-next-generation-hidden-service-keys-for-hierarchical-key-derivation",children:"Tor's Next Generation Hidden Service Keys for Hierarchical Key Derivation"}),"\n",(0,a.jsxs)(i.p,{children:["The ",(0,a.jsx)(i.a,{href:"https://gitweb.torproject.org/torspec.git/tree/proposals/224-rend-spec-ng.txt",children:"Next-Generation Hidden Services in Tor"})," specification defines a\n",(0,a.jsx)(i.a,{href:"https://gitweb.torproject.org/torspec.git/tree/proposals/224-rend-spec-ng.txt#n2135",children:"hierarchical key derivation scheme for Tor's keys"})," which employs\nmultiplicative blinding instead of an additive one use by ",(0,a.jsx)(i.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki",children:"BIP-0032"}),"."]}),"\n",(0,a.jsxs)(i.p,{children:[(0,a.jsx)(i.a,{href:"https://github.com/burdges",children:"Jeff Burdges (Web3 Foundation)"}),"'s post on potential ",(0,a.jsx)(i.a,{href:"https://web.archive.org/web/20210513183118/https://forum.w3f.community/t/key-recovery-attack-on-bip32-ed25519/44",children:"key recovery\nattack on the BIP32-Ed25519 scheme"})," mentions there is\nnothing wrong with this proposed scheme.\nLikewise, ",(0,a.jsx)(i.a,{href:"https://github.com/jstarry",children:"Justin Starry (Solana)"}),"'s ",(0,a.jsx)(i.a,{href:"https://github.com/solana-labs/solana/issues/6301#issuecomment-551184457",children:"summary of approaches to adopting BIP-0032\nfor Ed25519"})," recommends this scheme as one of the possible\napproaches to adapt BIP-0032 for ",(0,a.jsx)(i.a,{href:"https://tools.ietf.org/html/rfc8032#section-5",children:"edwards25519 curve"}),"."]}),"\n",(0,a.jsxs)(i.p,{children:["One practical issue with using this scheme would be the absence of support by\nthe ",(0,a.jsx)(i.a,{href:"https://www.ledger.com/",children:"Ledger"})," and ",(0,a.jsx)(i.a,{href:"https://trezor.io/",children:"Trezor"})," hardware wallets."]}),"\n",(0,a.jsx)(i.h2,{id:"consequences",children:"Consequences"}),"\n",(0,a.jsx)(i.h3,{id:"positive",children:"Positive"}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsxs)(i.li,{children:["\n",(0,a.jsxs)(i.p,{children:["Different applications interacting with the Oasis Network will use a\n",(0,a.jsx)(i.em,{children:"standards-compliant"})," (",(0,a.jsx)(i.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki",children:"BIP-0039"}),", ",(0,a.jsx)(i.a,{href:"https://github.com/satoshilabs/slips/blob/master/slip-0010.md",children:"SLIP-0010"}),", ",(0,a.jsx)(i.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki",children:"BIP-0044"}),") and\n",(0,a.jsx)(i.em,{children:"interoperable"})," account key generation process."]}),"\n",(0,a.jsx)(i.p,{children:"Hence, there will be no vendor lock-in and users will have the option to\neasily switch between standards-compliant applications (e.g. different\nwallets)."}),"\n"]}),"\n",(0,a.jsxs)(i.li,{children:["\n",(0,a.jsxs)(i.p,{children:["Using ",(0,a.jsx)(i.a,{href:"https://github.com/satoshilabs/slips/blob/master/slip-0010.md",children:"SLIP-0010"})," avoids a spectrum of issues when trying to support\nnon-hardened public parent key to public child key derivation with the\n",(0,a.jsx)(i.a,{href:"https://tools.ietf.org/html/rfc8032#section-5",children:"edwards25519 curve"}),".\nNon-hardened key derivation is practically impossible to implement securely\ndue to ",(0,a.jsx)(i.a,{href:"#difficulties-in-adapting-bip-0032-to-edwards25519-curve",children:"edwards25519 curve's co-factor issues"}),"."]}),"\n",(0,a.jsxs)(i.p,{children:["This is achieved by ",(0,a.jsx)(i.a,{href:"https://github.com/satoshilabs/slips/blob/master/slip-0010.md",children:"SLIP-0010"})," explicitly disallowing non-hardened public\nparent key to public child key derivation with the edwards25519 curve."]}),"\n"]}),"\n",(0,a.jsxs)(i.li,{children:["\n",(0,a.jsxs)(i.p,{children:["Using a ",(0,a.jsx)(i.a,{href:"#key-derivation-paths",children:"3-level BIP-0032 path"})," (i.e. ",(0,a.jsx)(i.code,{children:"m/44'/474'/x'"}),")\nallows ",(0,a.jsx)(i.a,{href:"https://github.com/LedgerHQ/app-oasis",children:"Oasis' Ledger app"})," to implement automatic switching\nbetween existing (legacy) account key generation and the standard account key\ngeneration proposed in this ADR."]}),"\n",(0,a.jsxs)(i.p,{children:["Since the existing (legacy) account key generation used in\n",(0,a.jsx)(i.a,{href:"https://github.com/LedgerHQ/app-oasis",children:"Oasis' Ledger app"})," uses a 5-level ",(0,a.jsx)(i.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki",children:"BIP-0032"})," path, the\nOasis' Ledger app will be able to automatically switch between standard and\nexisting (legacy) account key generation just based on the number of levels of\nthe given BIP-0032 path."]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(i.h3,{id:"negative",children:"Negative"}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsxs)(i.li,{children:["\n",(0,a.jsx)(i.p,{children:"The account key generation proposed in this ADR is incompatible with two\nexisting account key generation schemes deployed in the field:"}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsxs)(i.li,{children:[(0,a.jsx)(i.a,{href:"https://github.com/LedgerHQ/app-oasis",children:"Oasis' Ledger app"}),","]}),"\n",(0,a.jsxs)(i.li,{children:[(0,a.jsx)(i.a,{href:"/general/manage-tokens/faq",children:"Bitpie mobile wallet"}),"."]}),"\n"]}),"\n",(0,a.jsx)(i.p,{children:"That means that these two applications will need to support two account key\ngenerations schemes simultaneously to allow existing users to access their\n(old) accounts generated via the existing (legacy) account key generation\nscheme."}),"\n"]}),"\n",(0,a.jsxs)(i.li,{children:["\n",(0,a.jsxs)(i.p,{children:[(0,a.jsx)(i.a,{href:"https://github.com/satoshilabs/slips/blob/master/slip-0010.md",children:"SLIP-0010"}),"'s scheme for ",(0,a.jsx)(i.a,{href:"https://tools.ietf.org/html/rfc8032#section-5",children:"edwards25519 curve"})," only supports hardened private\nparent key to private child key derivation."]}),"\n",(0,a.jsx)(i.p,{children:"That means it will not be possible to implement wallet features that require\nnon-hardened key derivation, e.g. watch-only feature where one is able to\nmonitor a hierarchical wallet's accounts just by knowing the root public key\nand deriving all accounts' public keys from that."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(i.h3,{id:"neutral",children:"Neutral"}),"\n",(0,a.jsx)(i.h2,{id:"references",children:"References"}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsx)(i.li,{children:(0,a.jsx)(i.a,{href:"https://github.com/satoshilabs/slips/blob/master/slip-0010.md",children:"SLIP-0010"})}),"\n",(0,a.jsxs)(i.li,{children:["Stellar's ",(0,a.jsx)(i.a,{href:"https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0005.md",children:"SEP-0005"})]}),"\n",(0,a.jsxs)(i.li,{children:[(0,a.jsx)(i.a,{href:"https://github.com/jstarry",children:"Justin Starry (Solana)"}),"'s ",(0,a.jsx)(i.a,{href:"https://github.com/solana-labs/solana/issues/6301#issuecomment-551184457",children:"summary of approaches to adopting BIP-0032 for\nEd25519"})]}),"\n",(0,a.jsxs)(i.li,{children:[(0,a.jsx)(i.a,{href:"https://github.com/andrewkozlik",children:"Andrew Kozlik (SatoshiLabs)"}),"'s\n",(0,a.jsx)(i.a,{href:"https://github.com/satoshilabs/slips/issues/703#issuecomment-515213584",children:"comments on BIP32-Ed25519, SLIP-0010 and SLIP-0023"})]}),"\n"]})]})}function l(e={}){const{wrapper:i}={...(0,n.R)(),...e.components};return i?(0,a.jsx)(i,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},8453:(e,i,s)=>{s.d(i,{R:()=>r,x:()=>d});var a=s(6540);const n={},t=a.createContext(n);function r(e){const i=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function d(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:r(e.components),a.createElement(t.Provider,{value:i},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/527e04fa.9e57a7e4.js b/assets/js/527e04fa.9e57a7e4.js
new file mode 100644
index 0000000000..bed970deea
--- /dev/null
+++ b/assets/js/527e04fa.9e57a7e4.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[8905],{3963:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>o,default:()=>l,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var s=n(4848),i=n(8453);const r={},o="Runtime IDs",c={id:"core/runtime/identifiers",title:"Runtime IDs",description:"Identifiers for runtimes are represented by the [common.Namespace] type.",source:"@site/docs/core/runtime/identifiers.md",sourceDirName:"core/runtime",slug:"/core/runtime/identifiers",permalink:"/core/runtime/identifiers",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/oasis-core/edit/stable/22.2.x/docs/runtime/identifiers.md",tags:[],version:"current",lastUpdatedAt:1715584634e3,frontMatter:{},sidebar:"oasisCore",previous:{title:"Runtime Host Protocol",permalink:"/core/runtime/runtime-host-protocol"},next:{title:"Runtime Messages",permalink:"/core/runtime/messages"}},a={},d=[];function u(e){const t={a:"a",code:"code",h1:"h1",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"runtime-ids",children:"Runtime IDs"}),"\n",(0,s.jsxs)(t.p,{children:["Identifiers for runtimes are represented by the ",(0,s.jsx)(t.a,{href:"https://pkg.go.dev/github.com/oasisprotocol/oasis-core/go/common?tab=doc#Namespace",children:(0,s.jsx)(t.code,{children:"common.Namespace"})})," type."]}),"\n",(0,s.jsx)(t.p,{children:"The first 64 bits are reserved for specifying flags expressing various\nproperties of the runtime, and the last 192 bits are used as the runtime\nidentifier."}),"\n",(0,s.jsx)(t.p,{children:"Currently the following flags are defined (bit positions assume the flags\nvector is interpreted as an unsigned 64 bit big endian integer):"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Bit 63: The runtime is a test runtime and not for production networks."}),"\n",(0,s.jsx)(t.li,{children:"Bit 62: The runtime is a key manager runtime."}),"\n",(0,s.jsx)(t.li,{children:"Bits 61-0: Reserved for future expansion and MUST be set to 0."}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["Note: Unless the registry consensus parameter ",(0,s.jsx)(t.code,{children:"DebugAllowTestRuntimes"})," is\nset, attempts to register a test runtime will be rejected."]})]})}function l(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>c});var s=n(6540);const i={},r=s.createContext(i);function o(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/52c9072e.e69f3274.js b/assets/js/52c9072e.e69f3274.js
new file mode 100644
index 0000000000..7a670f9f71
--- /dev/null
+++ b/assets/js/52c9072e.e69f3274.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[4166],{9250:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Build Environment Setup and Building","slug":"core/development-setup/build-environment-setup-and-building","permalink":"/core/development-setup/build-environment-setup-and-building","sidebar":"oasisCore","navigation":{"previous":{"title":"Development Setup","permalink":"/core/development-setup"},"next":{"title":"Prerequisites","permalink":"/core/development-setup/prerequisites"}}}}')}}]);
\ No newline at end of file
diff --git a/assets/js/5334ec61.0ffd7d74.js b/assets/js/5334ec61.0ffd7d74.js
new file mode 100644
index 0000000000..7bc79f9bcc
--- /dev/null
+++ b/assets/js/5334ec61.0ffd7d74.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[8025],{8316:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>a});var t=i(4848),s=i(8453);const r={},o="Building",l={id:"core/development-setup/building",title:"Building",description:"This chapter contains a description of steps required to build Oasis Core.",source:"@site/docs/core/development-setup/building.md",sourceDirName:"core/development-setup",slug:"/core/development-setup/building",permalink:"/core/development-setup/building",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/oasis-core/edit/stable/22.2.x/docs/development-setup/building.md",tags:[],version:"current",lastUpdatedAt:1715584634e3,frontMatter:{},sidebar:"oasisCore",previous:{title:"Prerequisites",permalink:"/core/development-setup/prerequisites"},next:{title:"Running Tests and Development Networks",permalink:"/core/development-setup/running-tests-and-development-networks"}},d={},a=[{value:"Unsafe Non-SGX Environment",id:"unsafe-non-sgx-environment",level:2},{value:"SGX Environment",id:"sgx-environment",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"building",children:"Building"}),"\n",(0,t.jsxs)(n.p,{children:["This chapter contains a description of steps required to build Oasis Core.\nBefore proceeding, make sure to look at the ",(0,t.jsx)(n.a,{href:"/core/development-setup/prerequisites",children:"prerequisites"})," required for running\nan Oasis Core environment."]}),"\n",(0,t.jsx)(n.h2,{id:"unsafe-non-sgx-environment",children:"Unsafe Non-SGX Environment"}),"\n",(0,t.jsx)(n.p,{children:"To build everything required for running an Oasis node locally, simply execute\nthe following in the top-level directory:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'export OASIS_UNSAFE_SKIP_AVR_VERIFY="1"\nexport OASIS_UNSAFE_SKIP_KM_POLICY="1"\nexport OASIS_UNSAFE_ALLOW_DEBUG_ENCLAVES="1"\nmake\n'})}),"\n",(0,t.jsxs)(n.p,{children:["To build BadgerDB without ",(0,t.jsx)(n.code,{children:"jemalloc"})," support (and avoid installing ",(0,t.jsx)(n.code,{children:"jemalloc"}),"\non your system), set"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'export OASIS_BADGER_NO_JEMALLOC="1"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Not using ",(0,t.jsx)(n.code,{children:"jemalloc"})," is fine for development purposes."]}),"\n",(0,t.jsx)(n.p,{children:"This will build all the required parts (build tools, Oasis node, runtime\nlibraries, runtime loader, key manager and test runtimes). The AVR and KM flags\nare supported on production SGX systems only and these features must be disabled\nin our environment."}),"\n",(0,t.jsx)(n.h2,{id:"sgx-environment",children:"SGX Environment"}),"\n",(0,t.jsx)(n.p,{children:"Compilation procedure under SGX environment is similar to the non-SGX with\nslightly different environmental variables set:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'export OASIS_UNSAFE_SKIP_AVR_VERIFY="1"\nexport OASIS_UNSAFE_ALLOW_DEBUG_ENCLAVES="1"\nmake\n'})}),"\n",(0,t.jsx)(n.p,{children:"The AVR flag is there because we are running the node in a local development\nenvironment and we will not do any attestation with Intel's remote servers. The\ndebug enclaves flag allows enclaves in debug mode to be used."}),"\n",(0,t.jsx)(n.p,{children:"To run an Oasis node under SGX make sure:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Your hardware has SGX support."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["You either explicitly enabled SGX in BIOS or made a\n",(0,t.jsx)(n.code,{children:"sgx_cap_enable_device()"})," system call, if SGX is in software controlled state."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["You installed ",(0,t.jsx)(n.a,{href:"https://github.com/intel/linux-sgx-driver",children:"Intel's SGX driver"})," (check that ",(0,t.jsx)(n.code,{children:"/dev/isgx"})," exists)."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"You have the AESM daemon running. The easiest way is to just run it in a\nDocker container by doing (this will keep the container running and it will\nbe automatically started on boot):"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"docker run \\\n --detach \\\n --restart always \\\n --device /dev/isgx \\\n --volume /var/run/aesmd:/var/run/aesmd \\\n --name aesmd \\\n ghcr.io/oasisprotocol/aesmd:master\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Run ",(0,t.jsx)(n.code,{children:"sgx-detect"})," (part of fortanix rust tools) to verify that everything is\nconfigured correctly."]})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>l});var t=i(6540);const s={},r=t.createContext(s);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/533aa3d4.1cbac429.js b/assets/js/533aa3d4.1cbac429.js
new file mode 100644
index 0000000000..a0119d6819
--- /dev/null
+++ b/assets/js/533aa3d4.1cbac429.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[319],{3010:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>t,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var i=s(4848),r=s(8453);const o={},t="Damask Upgrade",a={id:"node/mainnet/previous-upgrades/damask-upgrade",title:"Damask Upgrade",description:"This document provides an overview of the changes for the Damask Mainnet",source:"@site/docs/node/mainnet/previous-upgrades/damask-upgrade.md",sourceDirName:"node/mainnet/previous-upgrades",slug:"/node/mainnet/previous-upgrades/damask-upgrade",permalink:"/node/mainnet/previous-upgrades/damask-upgrade",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/node/mainnet/previous-upgrades/damask-upgrade.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"operators",previous:{title:"Previous Upgrades",permalink:"/node/mainnet/previous-upgrades"},next:{title:"Cobalt Upgrade",permalink:"/node/mainnet/previous-upgrades/cobalt-upgrade"}},d={},l=[{value:"Major Features",id:"major-features",level:2},{value:"Mechanics of the Upgrade",id:"mechanics-of-the-upgrade",level:2},{value:"Proposed State Changes",id:"proposed-state-changes",level:2},{value:"General",id:"general",level:3},{value:"Registry",id:"registry",level:3},{value:"Root Hash",id:"root-hash",level:3},{value:"Staking",id:"staking",level:3},{value:"Committee Scheduler",id:"committee-scheduler",level:3},{value:"Random Beacon",id:"random-beacon",level:3},{value:"Governance",id:"governance",level:3},{value:"Consensus",id:"consensus",level:3},{value:"Other",id:"other",level:3},{value:"Launch Support",id:"launch-support",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"damask-upgrade",children:"Damask Upgrade"}),"\n",(0,i.jsx)(n.p,{children:"This document provides an overview of the changes for the Damask Mainnet\nupgrade."}),"\n",(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsxs)(n.p,{children:["The Damask upgrade on Mainnet is scheduled at epoch ",(0,i.jsx)(n.strong,{children:"13402"})," which will happen\naround ",(0,i.jsx)(n.strong,{children:"Apr 11, 2022 at 8:30 UTC"}),"."]})}),"\n",(0,i.jsx)(n.h2,{id:"major-features",children:"Major Features"}),"\n",(0,i.jsxs)(n.p,{children:["All features for the Damask upgrade are implemented as part of\n",(0,i.jsx)(n.strong,{children:"Oasis Core 22.1.x"})," release series which is a consensus protocol-breaking\nrelease."]}),"\n",(0,i.jsx)(n.p,{children:"Summary of the major features is as follows:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Random Beacon"}),": The random beacon is used by the consensus layer for\nParaTime committee elections and is a critical component in providing\nsecurity for ParaTimes with an open admission policy.\nTo make the random beacon more performant and scalable, the upgrade\ntransitions the election procedure to one that is based on cryptographic\nsortition of Verifiable Random Function (VRF) outputs.\nFor more details, see ",(0,i.jsx)(n.a,{href:"/adrs/0010-vrf-elections",children:"ADR 0010"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"On-Chain Governance"}),": The upgrade simplifies the governance by replacing\nseparate quorum and threshold parameters with a single unified stake threshold\nparameter that represents the percentage of ",(0,i.jsx)(n.em,{children:"yes"})," votes in terms of total\nvoting power for a governance proposal to pass."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"ParaTime Performance"}),": By simplifying the protocol (executor and storage\ncommittees are merged into a single committee) the upgrade improves ParaTime\ncommittee performance and opens the way for even more improvements on the\nParaTime side. It also leads to simplified configuration of ParaTime nodes."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"ParaTime Upgrades"}),": After the Damask upgrade, runtime descriptors will\ninclude information regarding supported versions, and the epoch from which\nthey are valid, which will allow ParaTime upgrades to happen without incurring\ndowntime by having upgrades and the descriptor changes pre-staged well in\nadvance of the upgrade epoch.\nFor more details, see ",(0,i.jsx)(n.a,{href:"/adrs/0013-runtime-upgrades",children:"ADR 0013"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"ParaTime Packaging"}),": This upgrade changes runtime bundles to be unified\nacross all supported TEE types and self describing so that configuring\nParaTimes is only a matter of passing in the runtime bundle file."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Consensus and ParaTime Communication"}),": The upgrade adds support for\nincoming runtime messages where consensus layer transactions can trigger\nactions inside ParaTimes.\nFor more details, see ",(0,i.jsx)(n.a,{href:"/adrs/0011-incoming-runtime-messages",children:"ADR 0011"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The upgrade also adds support for runtime message results which extends the\nresults of the emitted runtime messages with relevant information beyond\nindicating whether the message execution was successful or not.\nFor more details, see ",(0,i.jsx)(n.a,{href:"/adrs/0012-runtime-message-results",children:"ADR 0012"}),"."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["In addition to the specified additional features, we also propose the\n",(0,i.jsx)(n.strong,{children:"validator set size"})," to be ",(0,i.jsx)(n.strong,{children:"increased from"})," the current ",(0,i.jsx)(n.strong,{children:"110 to 120"})," as\ndiscussed in the\n",(0,i.jsx)(n.a,{href:"https://oasiscommunity.slack.com/archives/CMUSJCRFA/p1647881564057319?thread_ts=1647448573.197229&cid=CMUSJCRFA",children:"Oasis Community Slack #nodeoperators channel"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"This upgrade marks an important milestone for the Oasis Network, as it sets the\nfoundation for unlocking the network's full capabilities."}),"\n",(0,i.jsx)(n.h2,{id:"mechanics-of-the-upgrade",children:"Mechanics of the Upgrade"}),"\n",(0,i.jsxs)(n.p,{children:["On Mar 24, 2022, the Oasis Protocol Foundation submitted the upgrade governance\nproposal with id of ",(0,i.jsx)(n.code,{children:"2"})," which proposed upgrading the network at epoch 13402."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["In addition to submitting the actual governance proposal to the network, Oasis\nProtocol Foundation also published the ",(0,i.jsx)(n.a,{href:"https://github.com/oasisprotocol/community/discussions/30",children:"Damask Upgrade Proposal discussion"})," to\nthe ",(0,i.jsx)(n.a,{href:"https://github.com/oasisprotocol/community",children:"Oasis Community Forum on GitHub"}),"."]})}),"\n",(0,i.jsx)(n.p,{children:"Node operators which had an active validator node in the validator set had 1\nweek to cast their vote."}),"\n",(0,i.jsxs)(n.p,{children:["Validators representing more than 88% of the total stake in the consensus\ncommittee participated in the vote, and 100% of them voted ",(0,i.jsx)(n.em,{children:"yes"})," for the proposal."]}),"\n",(0,i.jsxs)(n.p,{children:["The upgrade will be performed by exporting the network's state at the upgrade\nepoch, updating the ",(0,i.jsx)(n.a,{href:"/node/genesis-doc#parameters",children:"genesis document"}),", upgrading the Oasis Node\nand the ParaTime binaries and starting a new network from the new genesis file."]}),"\n",(0,i.jsx)(n.p,{children:"This will require coordination between node operators and the Oasis Protocol\nFoundation.\nAll nodes will need to configure the new genesis file that they can generate or\nverify independently and reset/archive any existing state from Mainnet."}),"\n",(0,i.jsx)(n.p,{children:"Once enough nodes (representing 2/3+ of stake) have taken this step, the\nupgraded network will start."}),"\n",(0,i.jsxs)(n.p,{children:["For the actual steps that node operators need to make on their nodes, see the\n",(0,i.jsx)(n.a,{href:"/node/mainnet/upgrade-log#damask-upgrade",children:"Upgrade Log"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"proposed-state-changes",children:"Proposed State Changes"}),"\n",(0,i.jsx)(n.p,{children:"The following parts of the genesis document will be updated:"}),"\n",(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsx)(n.p,{children:"This section will be updated with the exact details as we get closer to the\nupgrade."})}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["For a more detailed explanation of the parameters below, see the\n",(0,i.jsx)(n.a,{href:"/node/genesis-doc#parameters",children:"Genesis Document"})," docs."]})}),"\n",(0,i.jsx)(n.h3,{id:"general",children:(0,i.jsx)(n.strong,{children:"General"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"height"})})," will be set to the height of the Mainnet state dump + 1,\n",(0,i.jsx)(n.code,{children:"8048956"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"genesis_time"})})," will be set to",(0,i.jsx)(n.code,{children:"2022-04-11T09:30:00Z"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"chain_id"})})," will be set to ",(0,i.jsx)(n.code,{children:"oasis-3"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"halt_epoch"})})," will be bumped by ",(0,i.jsx)(n.code,{children:"10000"})," (a little more than a year) to\n",(0,i.jsx)(n.code,{children:"23807"}),"."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"registry",children:(0,i.jsx)(n.strong,{children:"Registry"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"registry.runtimes"})})," list contains the registered runtimes' descriptors.\nIn this upgrade, all runtime descriptors will be migrated from version ",(0,i.jsx)(n.code,{children:"2"})," to\nversion ",(0,i.jsx)(n.code,{children:"3"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The migration will be done automatically with the\n",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"})," command."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"registry.runtimes.[id=000000000000000000000000000000000000000000000000e2eaa99fc008f87f].deployments.version"})}),"\nspecifies Emerald ParaTime's version on Mainnet."]}),"\n",(0,i.jsx)(n.p,{children:"It will be upgraded from version 7.1.0 to 8.2.0 and hence the configuration\nneeds to be manually updated to:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'"version": {\n "major": 8,\n "minor": 2\n},\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"registry.runtimes.[id=000000000000000000000000000000000000000000000000e199119c992377cb].deployments"})}),"\nspecifies Cipher ParaTime's version and TEE identity on Mainnet."]}),"\n",(0,i.jsx)(n.p,{children:"It will be upgraded from version 1.0.0 to 1.1.0 and hence the configuration\nneeds to be manually updated to:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'"version": {\n "major": 1,\n "minor": 1\n},\n"valid_from": 0,\n"tee": "oWhlbmNsYXZlc4GiaW1yX3NpZ25lclggQCXat+vaH77MTjY3YG4CEhTQ9BxtBCL9N4sqi4iBhFlqbXJfZW5jbGF2ZVggoiJgre0cDF5arUk9wh0X9eGWr5cHb8LY0A3/msmznHc="\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"registry.suspended_runtimes"})})," list contains the suspended registered\nruntimes' descriptors. In this upgrade, all runtime descriptors for suspended\nruntimes will be migrated from version ",(0,i.jsx)(n.code,{children:"2"})," to version ",(0,i.jsx)(n.code,{children:"3"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The migration will be done automatically with the\n",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"})," command."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Inactive registered entities in ",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"registry.entities"})})," (and their\ncorresponding nodes in ",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"registry.nodes"})}),") that don't pass the\n",(0,i.jsx)(n.a,{href:"/node/genesis-doc#staking-thresholds",children:"minimum staking thresholds"})," will be removed."]}),"\n",(0,i.jsxs)(n.p,{children:["The removal will be done automatically with the ",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"}),"\ncommand."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"root-hash",children:(0,i.jsx)(n.strong,{children:"Root Hash"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"roothash.params.gas_costs.submit_msg"})})," is a new parameter that specifies\nthe cost for a submit message transaction. It will be set to ",(0,i.jsx)(n.code,{children:"1000"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This will be done automatically with the ",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"}),"\ncommand."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"roothash.params.max_in_runtime_messages"})})," is a new parameter that\nspecifies the maximum number of incoming messages that can be queued for\nprocessing by a runtime. It will be set to ",(0,i.jsx)(n.code,{children:"128"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This will be done automatically with the ",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"}),"\ncommand."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"roothash.runtime_state"})})," contains the state roots of the runtimes.\nEmpty fields will be omitted."]}),"\n",(0,i.jsxs)(n.p,{children:["This will be done automatically with the ",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"}),"\ncommand."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"staking",children:(0,i.jsx)(n.strong,{children:"Staking"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"staking.params.thresholds"})})," specifies the minimum number of tokens that\nneed to be staked in order for a particular entity or a particular type of\nnode to participate in the network."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"node-storage"})," key is removed since Oasis Core 22.0+ removes separate\nstorage nodes.\nFor more details, see: ",(0,i.jsx)(n.a,{href:"https://github.com/oasisprotocol/oasis-core/pull/4308",children:"Oasis Core #4308"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This will be done automatically with the ",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"}),"\ncommand."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"staking.params.min_transfer"})})," is a new parameter that specifies the\nminimum number of tokens one can transfer.\nIt will be set to 10,000,000 base units, or 0.01 ROSE tokens."]}),"\n",(0,i.jsxs)(n.p,{children:["This will be done automatically with the ",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"}),"\ncommand."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"staking.params.min_transact_balance"})})," is a new parameter that specifies\nthe minimum general balance an account must have to be able to perform\ntransactions on the network.\nIt will be set to 0 base units, meaning this requirement is currently not\nenforced."]}),"\n",(0,i.jsxs)(n.p,{children:["This will be done automatically with the ",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"}),"\ncommand."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"committee-scheduler",children:(0,i.jsx)(n.strong,{children:"Committee Scheduler"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"scheduler.params.min_validators"})})," is the minimum size of the consensus\ncommittee (i.e. the validator set). It will be increased from ",(0,i.jsx)(n.code,{children:"15"})," to ",(0,i.jsx)(n.code,{children:"30"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"scheduler.params.max_validators"})})," is the maximum size of the consensus\ncommittee (i.e. the validator set). It will be increased from ",(0,i.jsx)(n.code,{children:"110"})," to ",(0,i.jsx)(n.code,{children:"120"}),"."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"random-beacon",children:(0,i.jsx)(n.strong,{children:"Random Beacon"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"beacon"})})," object contains parameters controlling the new\n",(0,i.jsx)(n.a,{href:"/adrs/0010-vrf-elections",children:"improved VRF-based random beacon"})," introduced in the Damask upgrade."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"beacon.base"})})," is the network's starting epoch. It will be set to the epoch\nof Mainnet's state dump + 1, ",(0,i.jsx)(n.code,{children:"13402"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"beacon.params.backend"})})," configures the random beacon backend to use.\nIt will be set to ",(0,i.jsx)(n.code,{children:'"vrf"'})," indicating that the beacon implementing\n",(0,i.jsx)(n.a,{href:"/adrs/0010-vrf-elections",children:"VRF-based random beacon"})," should be used."]}),"\n",(0,i.jsxs)(n.p,{children:["This will be done automatically with the ",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"}),"\ncommand."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"beacon.params.vrf_parameters"})})," control the behavior of the new\n",(0,i.jsx)(n.a,{href:"/adrs/0010-vrf-elections",children:"VRF-based random beacon"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"beacon.params.vrf_parameters.alpha_hq_threshold"})})," is minimal number of\nnodes that need to contribute a VRF proof for the beacon's output to be valid.\nIt will be set to ",(0,i.jsx)(n.code,{children:"20"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This will be done automatically with the ",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"}),"\ncommand."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"beacon.params.vrf_parameters.interval"})})," is the duration of an epoch.\nIt will be set to ",(0,i.jsx)(n.code,{children:"600"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This will be done automatically with the ",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"}),"\ncommand."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"beacon.params.vrf_parameters.proof_delay"})})," is number of blocks since the\nbeginning of an epoch after a node can still submit its VRF proof.\nIt will be set to ",(0,i.jsx)(n.code,{children:"400"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This will be done automatically with the ",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"}),"\ncommand."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"beacon.params.vrf_parameters.gas_costs.vrf_prove"})})," specifies the cost for\na VRF prove transaction.\nIt will be set to ",(0,i.jsx)(n.code,{children:"1000"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This will be done automatically with the ",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"}),"\ncommand."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"beacon.params.pvss_parameters"})})," control the behavior of the\n",(0,i.jsx)(n.a,{href:"/adrs/0007-improved-random-beacon",children:"previous random beacon implementing a PVSS scheme"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Since PVSS is no longer supported, all its configuration options are removed\nas well."}),"\n",(0,i.jsx)(n.h3,{id:"governance",children:(0,i.jsx)(n.strong,{children:"Governance"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"governance.params.stake_threshold"})})," is a new parameter specifying the\nsingle unified stake threshold representing the percentage of ",(0,i.jsx)(n.code,{children:"VoteYes"})," votes\nin terms of total voting power for a governance proposal to pass.\nIt will be set to ",(0,i.jsx)(n.code,{children:"68"})," (i.e. 68%)."]}),"\n",(0,i.jsxs)(n.p,{children:["This will be done automatically with the ",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"}),"\ncommand."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"governance.params.quorum"})})," is the minimum percentage of voting power that\nneeds to be cast on a proposal for the result to be valid."]}),"\n",(0,i.jsxs)(n.p,{children:["It will be removed since it is being replaced by the single\n",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"governance.params.staking_threshold"})})," parameter."]}),"\n",(0,i.jsxs)(n.p,{children:["This will be done automatically with the ",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"}),"\ncommand."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"governance.params.threshold"})})," is the minimum percentage of ",(0,i.jsx)(n.code,{children:"VoteYes"})," votes\nin order for a proposal to be accepted."]}),"\n",(0,i.jsxs)(n.p,{children:["It will be removed since it is being replaced by the single\n",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"governance.params.staking_threshold"})})," parameter."]}),"\n",(0,i.jsxs)(n.p,{children:["This will be done automatically with the ",(0,i.jsx)(n.code,{children:"oasis-node debug fix-genesis"}),"\ncommand."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"consensus",children:(0,i.jsx)(n.strong,{children:"Consensus"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"consensus.params.state_checkpoint_interval"})})," parameter controls the\ninterval (in blocks) on which state checkpoints should be taken. It will be\nincreased from ",(0,i.jsx)(n.code,{children:"10000"})," to ",(0,i.jsx)(n.code,{children:"100000"})," to improve nodes' performance since\ncomputing checkpoints is I/O intensive."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"other",children:"Other"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"extra_data"})})," will be set back to the value in the ",(0,i.jsx)(n.a,{href:"https://github.com/oasisprotocol/mainnet-artifacts/releases/tag/2020-11-18",children:"Mainnet genesis file"}),"\nto include the Oasis Network's genesis quote:"]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.em,{children:"\u201d"}),(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Quis_custodiet_ipsos_custodes%3F",children:(0,i.jsx)(n.em,{children:"Quis custodiet ipsos custodes?"})}),(0,i.jsx)(n.em,{children:"\u201d [submitted by Oasis\nCommunity Member Daniyar Borangaziyev]:"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'"extra_data": {\n "quote": "UXVpcyBjdXN0b2RpZXQgaXBzb3MgY3VzdG9kZXM/IFtzdWJtaXR0ZWQgYnkgT2FzaXMgQ29tbXVuaXR5IE1lbWJlciBEYW5peWFyIEJvcmFuZ2F6aXlldl0="\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"launch-support",children:"Launch Support"}),"\n",(0,i.jsx)(n.p,{children:"The Oasis team will be offering live video support during the Damask upgrade.\nVideo call link and calendar details will be shared with node operators via\nemail and Slack."}),"\n",(0,i.jsxs)(n.p,{children:["For any additional support, please reach out via the\n",(0,i.jsxs)(n.a,{href:"/get-involved/",children:[(0,i.jsx)(n.strong,{children:"#nodeoperators"})," Oasis Community Slack channel"]})," with\nyour questions, comments, and feedback related to Damask upgrade."]}),"\n",(0,i.jsxs)(n.p,{children:["To follow the network, please use one of the many\n",(0,i.jsx)(n.a,{href:"https://github.com/oasisprotocol/docs/blob/0aeeb93a6e7c9001925923661e4eb3340ec4fb4b/docs/general/community-resources/community-made-resources.md#block-explorers--validator-leaderboards-block-explorers-validator-leaderboards",children:"community block explorers"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>a});var i=s(6540);const r={},o=i.createContext(r);function t(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:t(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/5583c17b.466febe7.js b/assets/js/5583c17b.466febe7.js
new file mode 100644
index 0000000000..fe11552347
--- /dev/null
+++ b/assets/js/5583c17b.466febe7.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[7513],{2991:(e,q,n)=>{n.r(q),n.d(q,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>A,metadata:()=>o,toc:()=>c});var t=n(4848),a=n(8453),r=n(1470),s=n(9365);const A={description:"Writing Sapphire dApp for browser and Metamask"},i="Browser Support",o={id:"dapp/sapphire/browser",title:"Browser Support",description:"Writing Sapphire dApp for browser and Metamask",source:"@site/docs/dapp/sapphire/browser.md",sourceDirName:"dapp/sapphire",slug:"/dapp/sapphire/browser",permalink:"/dapp/sapphire/browser",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/sapphire-paratime/edit/main/docs/browser.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{description:"Writing Sapphire dApp for browser and Metamask"},sidebar:"developers",previous:{title:"Guide",permalink:"/dapp/sapphire/guide"},next:{title:"View-Call Authentication",permalink:"/dapp/sapphire/authentication"}},l={},c=[{value:"Signing Sapphire Calls and Transactions in Browser",id:"signing-sapphire-calls-and-transactions-in-browser",level:2},{value:"Trying it",id:"trying-it",level:2}];function d(e){const q={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(q.h1,{id:"browser-support",children:"Browser Support"}),"\n",(0,t.jsx)(q.p,{children:"Confidential Sapphire dApps work in web browsers by wrapping the\nEthereum provider such as Metamask to enable signing and encrypting\ncalls and transactions."}),"\n",(0,t.jsxs)(q.p,{children:["Let's begin with the ",(0,t.jsx)(q.a,{href:"https://hardhat.org/tutorial/boilerplate-project",children:"Hardhat boilerplate"}),". As mentioned on their website\nthe boilerplate provides the following:"]}),"\n",(0,t.jsxs)(q.ul,{children:["\n",(0,t.jsx)(q.li,{children:"The Solidity contract implementing an ERC-20 token"}),"\n",(0,t.jsx)(q.li,{children:"Tests for the entire functionality of the contract"}),"\n",(0,t.jsx)(q.li,{children:"A minimal React front-end to interact with the contract using ethers.js"}),"\n"]}),"\n",(0,t.jsxs)(q.p,{children:["Go ahead and clone the original ",(0,t.jsx)(q.a,{href:"https://github.com/NomicFoundation/hardhat-boilerplate",children:"Hardhat boilerplate repo"}),". Move to the checked\nout folder and ",(0,t.jsx)(q.strong,{children:"apply the Sapphire-specific changes"})," to ",(0,t.jsx)(q.code,{children:"hardhat.config.js"}),"\nas ",(0,t.jsx)(q.a,{href:"/dapp/sapphire/quickstart#add-the-sapphire-testnet-to-hardhat",children:"described in the quickstart"}),"."]}),"\n",(0,t.jsxs)(q.p,{children:["Next, install dependencies. The boilerplate project uses\n",(0,t.jsx)(q.a,{href:"https://pnpm.io",children:"pnpm"}),", but ",(0,t.jsx)(q.code,{children:"yarn"})," and ",(0,t.jsx)(q.code,{children:"npm"})," will also work with some modifications\naround workspaces:"]}),"\n",(0,t.jsxs)(r.A,{groupId:"npm2yarn",children:[(0,t.jsx)(s.A,{value:"npm",children:(0,t.jsx)(q.pre,{children:(0,t.jsx)(q.code,{className:"language-shell",children:"npm install\nnpm install -D @oasisprotocol/sapphire-paratime\n"})})}),(0,t.jsx)(s.A,{value:"pnpm",label:"pnpm",children:(0,t.jsx)(q.pre,{children:(0,t.jsx)(q.code,{className:"language-shell",children:"pnpm install\npnpm add -D @oasisprotocol/sapphire-paratime\n"})})}),(0,t.jsx)(s.A,{value:"yarn",label:"Yarn",children:(0,t.jsx)(q.pre,{children:(0,t.jsx)(q.code,{className:"language-shell",children:"yarn install\nyarn add --dev @oasisprotocol/sapphire-paratime\n"})})})]}),"\n",(0,t.jsxs)(q.p,{children:["Now, you can deploy the contract on the Testnet with the private key of the\naccount holding some ",(0,t.jsx)(q.a,{href:"/dapp/sapphire/quickstart#get-some-sapphire-testnet-tokens",children:"TEST tokens"}),":"]}),"\n",(0,t.jsx)(q.pre,{children:(0,t.jsx)(q.code,{className:"language-shell",children:'PRIVATE_KEY="0x..." npx hardhat run scripts/deploy.js --network sapphire-testnet\n'})}),"\n",(0,t.jsxs)(q.p,{children:["This will compile the contract and deploy it on the Testnet. In addition\nto the quickstart steps, ",(0,t.jsxs)(q.strong,{children:["the contract address and ABI will also automatically\nbe copied over to the ",(0,t.jsx)(q.code,{children:"frontend/src/contracts"})," folder so that the frontend can\naccess them!"]})]}),"\n",(0,t.jsx)(q.admonition,{type:"warning",children:(0,t.jsxs)(q.p,{children:["The contract in the Hardhat boilerplate is ERC-20-compatible and emits the\n",(0,t.jsx)(q.code,{children:"transfer"})," event. If your wish to preserve confidentiality, you can comment\nout ",(0,t.jsx)(q.a,{href:"https://github.com/NomicFoundation/hardhat-boilerplate/blob/13bd712c1285b2de572f14d20e6a750ae08565c0/contracts/Token.sol#L66",children:"line 66"}),". Read ",(0,t.jsx)(q.a,{href:"/dapp/sapphire/guide#contract-logs",children:"the guide"})," to learn more."]})}),"\n",(0,t.jsx)(q.h2,{id:"signing-sapphire-calls-and-transactions-in-browser",children:"Signing Sapphire Calls and Transactions in Browser"}),"\n",(0,t.jsxs)(q.p,{children:["Now, let's explore the frontend of our dApp. Begin by moving into the\n",(0,t.jsx)(q.code,{children:"frontend"})," folder and install dependencies:"]}),"\n",(0,t.jsxs)(r.A,{groupId:"npm2yarn",children:[(0,t.jsx)(s.A,{value:"npm",children:(0,t.jsx)(q.pre,{children:(0,t.jsx)(q.code,{className:"language-shell",children:"npm install\nnpm install -D @oasisprotocol/sapphire-paratime\n"})})}),(0,t.jsx)(s.A,{value:"pnpm",label:"pnpm",children:(0,t.jsx)(q.pre,{children:(0,t.jsx)(q.code,{className:"language-shell",children:"pnpm install\npnpm add -D @oasisprotocol/sapphire-paratime\n"})})}),(0,t.jsx)(s.A,{value:"yarn",label:"Yarn",children:(0,t.jsx)(q.pre,{children:(0,t.jsx)(q.code,{className:"language-shell",children:"yarn install\nyarn add --dev @oasisprotocol/sapphire-paratime\n"})})})]}),"\n",(0,t.jsxs)(q.p,{children:["The main frontend logic is stored in ",(0,t.jsx)(q.code,{children:"frontend/src/components/Dapp.js"}),". Apply\nthe following changes:"]}),"\n",(0,t.jsx)(q.pre,{children:(0,t.jsx)(q.code,{className:"language-diff",metastring:'title="frontend/src/components/Dapp.js"',children:"--- a/hardhat-boilerplate/frontend/src/components/Dapp.js\n+++ b/hardhat-boilerplate/frontend/src/components/Dapp.js\n@@ -2,6 +2,7 @@\n\n // We'll use ethers to interact with the Ethereum network and our contract\n import { ethers } from \"ethers\";\n+import * as sapphire from '@oasisprotocol/sapphire-paratime';\n\n // We import the contract's artifacts and address here, as we are going to be\n // using them with ethers\n@@ -22,7 +23,7 @@\n // This is the Hardhat Network id that we set in our hardhat.config.js.\n // Here's a list of network ids https://docs.metamask.io/guide/ethereum-provider.html#properties\n // to use when deploying to other networks.\n-const HARDHAT_NETWORK_ID = '1337';\n+const HARDHAT_NETWORK_ID = '23295'; // Sapphire Testnet\n\n // This is an error code that indicates that the user canceled a transaction\n const ERROR_CODE_TX_REJECTED_BY_USER = 4001;\n@@ -225,14 +226,20 @@\n\n async _initializeEthers() {\n // We first initialize ethers by creating a provider using window.ethereum\n- this._provider = new ethers.providers.Web3Provider(window.ethereum);\n+ this._provider = sapphire.wrap(new ethers.providers.Web3Provider(window.ethereum));\n\n- // Then, we initialize the contract using that provider and the token's\n- // artifact. You can do this same thing with your contracts.\n+ // Then, we initialize two contract instances:\n+ // - _token: Used for eth_calls (e.g. balanceOf, name, symbol)\n+ // - _tokenWrite: Used for on-chain transactions (e.g. transfer)\n this._token = new ethers.Contract(\n contractAddress.Token,\n TokenArtifact.abi,\n- this._provider.getSigner(0)\n+ this._provider,\n+ );\n+ this._tokenWrite = new ethers.Contract(\n+ contractAddress.Token,\n+ TokenArtifact.abi,\n+ this._provider.getSigner()\n );\n }\n\n@@ -294,7 +301,7 @@\n\n // We send the transaction, and save its hash in the Dapp's state. This\n // way we can indicate that we are waiting for it to be mined.\n- const tx = await this._token.transfer(to, amount);\n+ const tx = await this._tokenWrite.transfer(to, amount);\n this.setState({ txBeingSent: tx.hash });\n\n // We use .wait() to wait for the transaction to be mined. This method\n@@ -360,8 +367,8 @@\n return true;\n }\n\n- this.setState({\n- networkError: 'Please connect Metamask to Localhost:8545'\n+ this.setState({\n+ networkError: 'Please connect to Sapphire ParaTime Testnet'\n });\n\n return false;\n"})}),"\n",(0,t.jsxs)(q.p,{children:["Beside the obvious change to the chain ID and wrapping ethers.js objects with the\nSapphire wrapper you can notice that we initialized ",(0,t.jsx)(q.strong,{children:"two"})," contract\ninstances:"]}),"\n",(0,t.jsxs)(q.ul,{children:["\n",(0,t.jsxs)(q.li,{children:[(0,t.jsx)(q.code,{children:"this._token"})," object will be used for unsigned eth calls. This is the\nHardhat method of ",(0,t.jsxs)(q.a,{href:"/dapp/sapphire/guide#transactions--calls",children:["setting ",(0,t.jsx)(q.code,{children:"from"})," transaction field to all\nzeros"]})," in order to avoid Metamask signature popups.\nAlthough the call is unsigned, ",(0,t.jsx)(q.strong,{children:"it is still encrypted"})," with the\ncorresponding runtime key to preserve confidentiality."]}),"\n",(0,t.jsxs)(q.li,{children:[(0,t.jsx)(q.code,{children:"this._tokenWrite"})," object will be used for signed calls and transactions. The\nuser will be prompted by Metamask for the signature. Both \u2014 calls and\ntransactions \u2014 will be encrypted."]}),"\n"]}),"\n",(0,t.jsx)(q.h2,{id:"trying-it",children:"Trying it"}),"\n",(0,t.jsx)(q.p,{children:"Start the frontend by typing:"}),"\n",(0,t.jsxs)(r.A,{groupId:"npm2yarn",children:[(0,t.jsx)(s.A,{value:"npm",children:(0,t.jsx)(q.pre,{children:(0,t.jsx)(q.code,{className:"language-shell",children:"npm run start\n"})})}),(0,t.jsx)(s.A,{value:"pnpm",label:"pnpm",children:(0,t.jsx)(q.pre,{children:(0,t.jsx)(q.code,{className:"language-shell",children:"pnpm run start\n"})})}),(0,t.jsx)(s.A,{value:"yarn",label:"Yarn",children:(0,t.jsx)(q.pre,{children:(0,t.jsx)(q.code,{className:"language-shell",children:"yarn run start\n"})})})]}),"\n",(0,t.jsxs)(q.p,{children:["If all goes well the web server will spin up and your browser should\nautomatically open ",(0,t.jsx)(q.code,{children:"http://localhost:3000"}),"."]}),"\n",(0,t.jsx)(q.p,{children:(0,t.jsx)(q.img,{alt:"Hardhat boilerplate frontend",src:n(8496).A+"",width:"1489",height:"979"})}),"\n",(0,t.jsxs)(q.p,{children:["Go ahead and connect the wallet. If you haven't done it yet, you will have\nto add the ",(0,t.jsx)(q.a,{href:"/dapp/sapphire/#testnet",children:"Sapphire ParaTime Testnet network to your\nMetamask"}),". Once connected, the frontend will make an unsigned\ncall to the ",(0,t.jsx)(q.code,{children:"balanceOf"})," view and show you the amount of ",(0,t.jsx)(q.code,{children:"MHT"}),"s in your selected\nMetamask account."]}),"\n",(0,t.jsx)(q.p,{children:(0,t.jsx)(q.img,{alt:"MHT balance of your account",src:n(3899).A+"",width:"1489",height:"979"})}),"\n",(0,t.jsxs)(q.p,{children:["Next, let's transfer some ",(0,t.jsx)(q.code,{children:"MHT"}),"s. Fill in the amount, the address and hit the\n",(0,t.jsx)(q.em,{children:"Transfer"})," button. Metamask will show you the popup to sign and submit the\ntransfer transaction. Once confirmed, Metamask will both ",(0,t.jsx)(q.strong,{children:"sign and encrypt"})," the transaction."]}),"\n",(0,t.jsx)(q.p,{children:(0,t.jsx)(q.img,{alt:"Sign and encrypt the transfer transaction",src:n(242).A+"",width:"360",height:"635"})}),"\n",(0,t.jsx)(q.p,{children:"Once the transaction is processed, you will get a notification from Metamask\nand the balance in the dApp will be updated."}),"\n",(0,t.jsx)(q.admonition,{type:"tip",children:(0,t.jsxs)(q.p,{children:["If you commented out ",(0,t.jsx)(q.code,{children:"emit Transfer(...)"}),", the transfer of ",(0,t.jsx)(q.code,{children:"MHT"}),"s would have\nbeen completely confidential. In the example above, the ",(0,t.jsx)(q.a,{href:"https://explorer.oasis.io/testnet/sapphire/tx/0x3303dea5d48291d1564cad573f21fc71fcbdc2b862e17e056287fd9207e3bc53",children:"following\ntransaction"})," was generated. Go ahead and check your transaction\non the block explorer too, to make sure no sensitive data was leaked!"]})}),"\n",(0,t.jsx)(q.p,{children:"Congratulations, you successfully implemented your first truly confidential\ndApp which runs in the browser and wraps Metamask to both sign and encrypt the\ntransactions!"}),"\n",(0,t.jsxs)(q.p,{children:["Should you have any questions or ideas to share, feel free to reach out to us\non ",(0,t.jsx)(q.a,{href:"/get-involved/#social-media-channels",children:"discord and other social media channels"}),"."]}),"\n",(0,t.jsx)(q.admonition,{title:"Example",type:"info",children:(0,t.jsxs)(q.p,{children:["You can download a full working example from the ",(0,t.jsx)(q.a,{href:"https://github.com/oasisprotocol/sapphire-paratime/tree/main/examples/hardhat-boilerplate",children:"Sapphire ParaTime examples"}),"\nrepository."]})}),"\n",(0,t.jsx)(q.admonition,{title:"Example",type:"info",children:(0,t.jsxs)(q.p,{children:["If your project involves building both a contract backend and a web frontend,\nwe recommend that you check out the official ",(0,t.jsx)(q.a,{href:"https://github.com/oasisprotocol/demo-starter",children:"Oasis starter"})," files."]})})]})}function h(e={}){const{wrapper:q}={...(0,a.R)(),...e.components};return q?(0,t.jsx)(q,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},9365:(e,q,n)=>{n.d(q,{A:()=>s});n(6540);var t=n(4164);const a={tabItem:"tabItem_Ymn6"};var r=n(4848);function s(e){let{children:q,hidden:n,className:s}=e;return(0,r.jsx)("div",{role:"tabpanel",className:(0,t.A)(a.tabItem,s),hidden:n,children:q})}},1470:(e,q,n)=>{n.d(q,{A:()=>v});var t=n(6540),a=n(4164),r=n(3104),s=n(6347),A=n(205),i=n(7485),o=n(1682),l=n(9466);function c(e){return t.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,t.isValidElement)(e)&&function(e){const{props:q}=e;return!!q&&"object"==typeof q&&"value"in q}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function d(e){const{values:q,children:n}=e;return(0,t.useMemo)((()=>{const e=q??function(e){return c(e).map((e=>{let{props:{value:q,label:n,attributes:t,default:a}}=e;return{value:q,label:n,attributes:t,default:a}}))}(n);return function(e){const q=(0,o.X)(e,((e,q)=>e.value===q.value));if(q.length>0)throw new Error(`Docusaurus error: Duplicate values "${q.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[q,n])}function h(e){let{value:q,tabValues:n}=e;return n.some((e=>e.value===q))}function p(e){let{queryString:q=!1,groupId:n}=e;const a=(0,s.W6)(),r=function(e){let{queryString:q=!1,groupId:n}=e;if("string"==typeof q)return q;if(!1===q)return null;if(!0===q&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:q,groupId:n});return[(0,i.aZ)(r),(0,t.useCallback)((e=>{if(!r)return;const q=new URLSearchParams(a.location.search);q.set(r,e),a.replace({...a.location,search:q.toString()})}),[r,a])]}function u(e){const{defaultValue:q,queryString:n=!1,groupId:a}=e,r=d(e),[s,i]=(0,t.useState)((()=>function(e){let{defaultValue:q,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(q){if(!h({value:q,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${q}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return q}const t=n.find((e=>e.default))??n[0];if(!t)throw new Error("Unexpected error: 0 tabValues");return t.value}({defaultValue:q,tabValues:r}))),[o,c]=p({queryString:n,groupId:a}),[u,m]=function(e){let{groupId:q}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(q),[a,r]=(0,l.Dv)(n);return[a,(0,t.useCallback)((e=>{n&&r.set(e)}),[n,r])]}({groupId:a}),f=(()=>{const e=o??u;return h({value:e,tabValues:r})?e:null})();(0,A.A)((()=>{f&&i(f)}),[f]);return{selectedValue:s,selectValue:(0,t.useCallback)((e=>{if(!h({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);i(e),c(e),m(e)}),[c,m,r]),tabValues:r}}var m=n(2303);const f={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var b=n(4848);function g(e){let{className:q,block:n,selectedValue:t,selectValue:s,tabValues:A}=e;const i=[],{blockElementScrollPositionUntilNextRender:o}=(0,r.a_)(),l=e=>{const q=e.currentTarget,n=i.indexOf(q),a=A[n].value;a!==t&&(o(q),s(a))},c=e=>{let q=null;switch(e.key){case"Enter":l(e);break;case"ArrowRight":{const n=i.indexOf(e.currentTarget)+1;q=i[n]??i[0];break}case"ArrowLeft":{const n=i.indexOf(e.currentTarget)-1;q=i[n]??i[i.length-1];break}}q?.focus()};return(0,b.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.A)("tabs",{"tabs--block":n},q),children:A.map((e=>{let{value:q,label:n,attributes:r}=e;return(0,b.jsx)("li",{role:"tab",tabIndex:t===q?0:-1,"aria-selected":t===q,ref:e=>i.push(e),onKeyDown:c,onClick:l,...r,className:(0,a.A)("tabs__item",f.tabItem,r?.className,{"tabs__item--active":t===q}),children:n??q},q)}))})}function x(e){let{lazy:q,children:n,selectedValue:a}=e;const r=(Array.isArray(n)?n:[n]).filter(Boolean);if(q){const e=r.find((e=>e.props.value===a));return e?(0,t.cloneElement)(e,{className:"margin-top--md"}):null}return(0,b.jsx)("div",{className:"margin-top--md",children:r.map(((e,q)=>(0,t.cloneElement)(e,{key:q,hidden:e.props.value!==a})))})}function j(e){const q=u(e);return(0,b.jsxs)("div",{className:(0,a.A)("tabs-container",f.tabList),children:[(0,b.jsx)(g,{...q,...e}),(0,b.jsx)(x,{...q,...e})]})}function v(e){const q=(0,m.A)();return(0,b.jsx)(j,{...e,children:c(e.children)},String(q))}},8496:(e,q,n)=>{n.d(q,{A:()=>t});const t="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABdEAAAPTCAMAAABok7AJAAABX1BMVEX////+/v77+/v39/fy8/P/88zv7/Dt7u7p6erm5ufj4+Tf4ODa29zX19jV1tbR0tPQ0dLOz9DJysv/yCLExcb/xh3AwcL/wQj/wQe9vsD+wAb8vga6u7z6vQa2t7n1uQfxtgjttAmvsLLmrwqpq63fqgump6nXpAygoqOdn6HRoA3Qnw2Zm53Kmw6WmJqUlpjDlg+SlJaPkZO+khCMjpC5jxC0jBGGiIqthxKphBOAgoWkgRSefRR5e32aehV1eHqWdxZydHeTdRaQcxdvcXRsb3GKbxdoa22FahllaGt+ZhliZWdeYWR4Yhp3YRtbXmFxXRtYW15VWFtpWB1TVllQVFdkVB5OUVReUB5KTlFWSh9GSU1DRklQRiBNRCFAQ0dLQiE8QENEPiI5PEA9OSM1ODw5NiQwNDg2NCQ0MiUyMSUtMDQuLiYoLDArLCYmKi4mKSckKCwiJikhJSkhJSifXin8AAAN6UlEQVR42uzY0UvybBjH8Z9ONKdlRgSCeDAkGkhRCEIgIfQg4kCMQsRAZIgHQ8a8/394t+kzi07fDh78fg5U8LrunX3RWwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAvy2UffvERAHDCuiYWLnuW6uZCv6gy0d5NX/+T0NV9oNjxZAA4YV3jum7n1Qx+u+huqL2R91tFj08GgBPWNUq8RCWKDgD/tkPRHVNLi14dB8GgJOU6izAYV6Wz4Wb7diXpZhb6TzntnXvB+qWYjG+CP2XJXbSX4fxaGvV763Bsf51vzbarh9y9MaatmBd/sLPFxHwsyQruVOz7Yfysw7+F9ZNqxtlsbElNE78+py8zFZ79aN0vZEXPdZbhovX3ZAA4WV1zeEt/o5c3i5azmuV1H3Wu2+upNJk1b7ygqJvdsNHZPitlBx8tZ+2pGrzH46ui3HB+VfU2lkbhn/P6aqzjfMsMGp3ovtgNqwXFypO3aj5bTLhRSWpFJWvht5uTqP616Ou7B8UKUVuaG0daPsnznevH6Ckrem/Xazyb1v5kAcDJ6hrbti/utl7a0efgTKrsHL10JXV2uaSaOuvZms9yUntXViweK0jNZel1bUmV6FFuvKuaudJok5c6Uf44P59K6o2/37pki4lSdCuNxrpNDsl/Tr4W/VF704GKu3lftqkX3pqSxtND0eP1nqTBklsXAKeua1IzO+3o3MvHPl8klertibE0CQdOUSqah/iLM+Mo8TFSyu8r9jaRG7dfZdPQaCrJMVY2bxn35z36cTGW1rkYtpIox7ph7kvRG9q799X0O5+63eQk2dfu8uNv0ZumHj/KMWWKDuDEdU2z2bypSGnRfZMa6/zdhPOpsVTs+SYaWBWz11Fi2Vdq21VsOEtyfSi6lxa9kM2XjfOz6MfFVMuUbwNL4zfF7oz1peiX2js3lefXuikNB1JrZYLpIit62+xdUnQAJ65rlDgUfTGuJSr51ewyn8RVsfOeeSiZp1riTInZSJJ1U/T7ir17P4uezReMK6l8lf9W9Gwxld/ceX1lv9FVNzVJ26ToNR34t/Pb/La1cXQeDSo5DbOit0yzlihQdAAn7nvR+74lWV7bNm1JI2Od+Q1Jq74+h5IuphfHe/SGqaTX4Xb0+LPox/nFRFLPz92F2ht6Ura41/8Ir3S8R6+apnRpvhX9ZRxVNXnfldT+j127fUoqDeM4fvdcU9u6ZutPDVGJxcnc0SUYHxgy3SmWFqPFNaJahQDFDnD07v+fPSfkjK6z7jiFrvX9vLpgzg3vvsPcXP5Cy6VaUPQbu5PGmPvPL5lnFB3AN+1w0W96OyhDLz/culh71d//2NprZq18f2DBDphR+3hoovz20v6uy9q9iffPzK2mt7Ky8f7a0aIHz/vDjw/bk96bs9912rw1ebV7MPjq8gWv0m+9XZffd/vNhfLGxE/l2qGij9qtC2bWrhlz2z7pG/rDvukW3Sw0ZwceNh93Prnv+Q8GAL5Nh4ruL5o3P7zo8168atZ+G/ASff3XWvv1hJ/U1+3ak+um4/aLZm3hsjF9L5pb3lr50aIfeH70TXtj0pjLa+2fO2fL7f7uwa6tR8Zz/clW82W/N/T92X47+vJQ0a/uPjOm3856o7f6Xl6Y3L3aLfrF2XK7/Ohi55OH7D0DADgzffamAQCcf9//svHcAAC+Av0fXt0wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7blbuDOkuDd68YAMAXcGVQZ22QpAPAl3BHZ++OAQB8vkGdvUEDAPh8+j8wAACKDgCg6ADwtdHxKDoAnBs6HkUHgHNDx6PoAHBu6HgUHQDODR2PogPAuaEvYvikz1N0AOh10cefVtx6PqqTSafki9k5SaGW9c9P2bi63JSWHCkwk6PoANDjokfrTnZxpd6a0ok4S/IN72QlTe85i5LSbvhfi75epOgA0Nuij2xWI5LGq5WTF91X2JS0srle8OeSKDoAnCYdNGOT8iWzYwqlK25lXpKTKrScXOjAMJbbcUsxP/2rDacYk2ttVb7FvbBUyqScEamxorFs3W3kwkHRh9NVt5KUitbaCEUHgF4WPeMVuWvVXY5nbVpy3KVo0j0wjJScVKLoRBTabCzG322PRVuZqDzDUTutsBuP2Sn5Y7E+N7O8txIU/eleJp79mFCkWIqGKDoA9LLohbq6on7MtdoKy1mXtF5SMCRsXApVc94wLY1XZ4JbFzWWFHfD2l7WXCsULiUkFUvdoo+7GUn5KrcuAND7oucb6pq3EUkzdlrOiqTVdwqGbCvkyVWVcdQRFL2wrmxJype0WpQnMpOqvusWPWGnvXNJG6HoANDzoj/dv3UJR5W2IUkxG+/kevUvBUPefuIqV/1n0Rd3VFmW5txQJS0lqrZVqgRFn7cdUxQdAE7tn9F5O939jT51tOjZxoNP9n+jz0QUFD1qp7wTitj4x5hibj46rEJQ9KRNPPCFKToAnNr2Yr0y3L1HDx0tetLGJGUz+/fo7qJ2lrRvO++MSKoUdkY0b6NSeDsoemQvJWl+PawCRQfwNzt30NlAEAZgOD3kF1TsR4X0UDlUCVESiaqWqNAIpYdQoiJqRS3N/9dpKqewl4jt6vNcZoyxx/ey4+PERY9unj+NJvlnN2K+e+tyH4dFby/Xo970a5A2H8P+YtWJ1dsgfs2Ll0imP0t3O7/uL7bv+6Kn08feXTGLmOXjjqIDnLTocfW8Kla7KQDtyXr3Hv2w6HE5y4vlINJmvtm8psvDzaa9/6E6iuR2twzTt6bjorMv+sVDOpikm911caPoAH9yUlc5sxcBFB0ARQf4f6KcogPURpRTdIDaiHKKDlAbUU7RAWojyik6QG1EOUUHqI0sqpc1ADjeeVTvvAHA8ZpZVC1rNgA43lmzlUWVspagAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDNHhwIAAAAAAD5vzaCqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqoKe3AgAAAAAADk/9oIqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqoq7MGBAAAAAACQ/2sjqKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqtAeHBAAAAACC/r92hgUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4BdH5jrGCCBdOAAAAAElFTkSuQmCC"},3899:(e,q,n)=>{n.d(q,{A:()=>t});const t=n.p+"assets/images/hardhat-boilerplate-frontend2-6d2fe4701649136e7c90270f572a86be.png"},242:(e,q,n)=>{n.d(q,{A:()=>t});const t=n.p+"assets/images/hardhat-boilerplate-frontend3-727893cadf6a2874b868f655cb84d059.png"},8453:(e,q,n)=>{n.d(q,{R:()=>s,x:()=>A});var t=n(6540);const a={},r=t.createContext(a);function s(e){const q=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(q):{...q,...e}}),[q,e])}function A(e){let q;return q=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),t.createElement(r.Provider,{value:q},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/562f786c.adfd2990.js b/assets/js/562f786c.adfd2990.js
new file mode 100644
index 0000000000..e2ad9d69d3
--- /dev/null
+++ b/assets/js/562f786c.adfd2990.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[7386],{4753:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>l,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var n=o(4848),s=o(8453);const r={},i="Consensus Trust Root",a={id:"rofl/trust-root",title:"Consensus Trust Root",description:"The [ROFL app example] already contains an embedded root of trust called the",source:"@site/docs/rofl/trust-root.md",sourceDirName:"rofl",slug:"/rofl/trust-root",permalink:"/rofl/trust-root",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/oasis-sdk/edit/main/docs/rofl/trust-root.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"rofl",previous:{title:"Application",permalink:"/rofl/app"}},c={},d=[{value:"The Root of Trust",id:"the-root-of-trust",level:2},{value:"Embedding the Root",id:"embedding-the-root",level:2}];function u(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"consensus-trust-root",children:"Consensus Trust Root"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.a,{href:"/rofl/app",children:"ROFL app example"})," already contains an embedded root of trust called the\n",(0,n.jsx)(t.em,{children:"consensus trust root"}),". The preconfigured trust root is valid for the current\ndeployment of Sapphire Testnet. This chapter briefly describes what the trust\nroot is, how it can be securely derived and configured in your ROFL app."]}),"\n",(0,n.jsx)(t.h2,{id:"the-root-of-trust",children:"The Root of Trust"}),"\n",(0,n.jsx)(t.p,{children:"In order to ensure that the ROFL app can securely authenticate it is talking to\nthe actual consensus layer and not a fork, you need to configure it with a\nsuitable consensus trust root. The trust root is a well-known consensus block\nheader that is used to bootstrap the light client which verifies everything\nelse."}),"\n",(0,n.jsx)(t.p,{children:"Having a correct trust root configured makes it impossible even for the node\noperator who is running your ROFL app to forge any queries as integrity of all\nresults is verified against the consensus layer trust root. One should try to\nuse a somewhat recent trust root which can be refreshed during application\nupgrades."}),"\n",(0,n.jsx)(t.admonition,{type:"caution",children:(0,n.jsx)(t.p,{children:"The consensus trust root represents the root of security for the ROFL app. Not\nconfiguring it makes your application vulnerable to man-in-the-middle attacks by\nthe node operator."})}),"\n",(0,n.jsx)(t.h2,{id:"embedding-the-root",children:"Embedding the Root"}),"\n",(0,n.jsxs)(t.p,{children:["In order to obtain a suitable consensus trust root you can leverage the Oasis\nCLI as follows (note the correct ",(0,n.jsx)(t.em,{children:"network"})," and ",(0,n.jsx)(t.em,{children:"paratime"}),"). Note that you should\nuse a node you trust to query this information (the example below uses the\ndefault public gRPC endpoints)."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"oasis rofl trust-root --network testnet --paratime sapphire\n"})}),"\n",(0,n.jsx)(t.p,{children:"Which should output something like the following:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:'TrustRoot {\n height: 22110615,\n hash: "95d1501f9cb88619050a5b422270929164ce739c5d803ed9500285b3b040985e".into(),\n runtime_id: "000000000000000000000000000000000000000000000000a6d1e3ebf60dff6c".into(),\n chain_context: "0b91b8e4e44b2003a7c5e23ddadb5e14ef5345c0ebcb3ddcae07fa2f244cab76".to_string(),\n}\n'})}),"\n",(0,n.jsxs)(t.p,{children:["You can then use this in your ROFL app definition by adding the following method\nto your ",(0,n.jsx)(t.code,{children:"App"})," trait implementation."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:'fn consensus_trust_root() -> Option {\n Some(TrustRoot {\n height: 22110615,\n hash: "95d1501f9cb88619050a5b422270929164ce739c5d803ed9500285b3b040985e".into(),\n runtime_id: "000000000000000000000000000000000000000000000000a6d1e3ebf60dff6c".into(),\n chain_context: "0b91b8e4e44b2003a7c5e23ddadb5e14ef5345c0ebcb3ddcae07fa2f244cab76"\n .to_string(),\n })\n}\n'})})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},8453:(e,t,o)=>{o.d(t,{R:()=>i,x:()=>a});var n=o(6540);const s={},r=n.createContext(s);function i(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/5741.8206d17e.js b/assets/js/5741.8206d17e.js
new file mode 100644
index 0000000000..088bde4311
--- /dev/null
+++ b/assets/js/5741.8206d17e.js
@@ -0,0 +1 @@
+(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[5741],{5741:()=>{}}]);
\ No newline at end of file
diff --git a/assets/js/59b1a96c.827e3a10.js b/assets/js/59b1a96c.827e3a10.js
new file mode 100644
index 0000000000..5bc5cc35a7
--- /dev/null
+++ b/assets/js/59b1a96c.827e3a10.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[4485],{3398:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>c,default:()=>m,frontMatter:()=>l,metadata:()=>d,toc:()=>h});var s=n(4848),r=n(8453),o=n(5965),i=n(2550),a=n(6116);const l={},c="Getting Started",d={id:"README",title:"Getting Started",description:"Use Oasis",source:"@site/docs/README.mdx",sourceDirName:".",slug:"/",permalink:"/",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/README.mdx",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{}},u={},h=[{value:"Use Oasis",id:"use-oasis",level:2},{value:"Create dApp",id:"create-dapp",level:2},{value:"Build ROFL",id:"build-rofl",level:2},{value:"Get Involved",id:"get-involved",level:2},{value:"Run Node",id:"run-node",level:2},{value:"Build ParaTimes",id:"build-paratimes",level:2},{value:"Develop Core",id:"develop-core",level:2}];function p(e){const t={a:"a",h1:"h1",h2:"h2",p:"p",strong:"strong",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"getting-started",children:"Getting Started"}),"\n",(0,s.jsx)(t.h2,{id:"use-oasis",children:"Use Oasis"}),"\n",(0,s.jsx)(t.p,{children:"This introductory part contains general overview of the Oasis Network such as\nthe distinction between the consensus layer and different ParaTimes. It\nalso covers wallets and other tools for managing your assets across the Oasis\nchains and how to use unique Oasis features."}),"\n",(0,s.jsx)(i.A,{items:[(0,a.$)("/general/oasis-network/"),(0,a.$)("/general/manage-tokens/"),(0,a.$)("/general/manage-tokens/cli/")]}),"\n",(0,s.jsx)(t.h2,{id:"create-dapp",children:"Create dApp"}),"\n",(0,s.jsxs)(t.p,{children:["Contains learning material for the smart contract developers. Since the Oasis\nplatform is best known for confidentiality, the most notable ParaTime is\n",(0,s.jsx)(t.a,{href:"/dapp/sapphire/",children:"Oasis Sapphire"}),", an ",(0,s.jsx)(t.strong,{children:"EVM-compatible"})," ParaTime with ",(0,s.jsx)(t.strong,{children:"built-in contract state\nencryption"}),". The Oasis team also prepared a set of libraries called the\n",(0,s.jsx)(t.a,{href:"/dapp/opl/",children:"Oasis Privacy Layer"})," to ",(0,s.jsx)(t.strong,{children:"bridge existing dApps running on other chains"})," to\nuse the unique Sapphire's confidentiality."]}),"\n",(0,s.jsxs)(t.p,{children:["The part also covers other ParaTimes such as the non-confidential\n",(0,s.jsx)(t.a,{href:"/dapp/emerald/",children:"Oasis Emerald"})," and Wasm-compatible, confidential ",(0,s.jsx)(t.a,{href:"/dapp/emerald/",children:"Oasis Cipher"}),"."]}),"\n",(0,s.jsx)(i.A,{items:[(0,a.$)("/dapp/sapphire/"),(0,a.$)("/dapp/opl/"),(0,a.$)("/dapp/emerald/"),(0,a.$)("/dapp/cipher/")]}),"\n",(0,s.jsx)(t.h2,{id:"build-rofl",children:"Build ROFL"}),"\n",(0,s.jsx)(t.p,{children:"Runtime OFfchain Logic (ROFL) enables you to build secure applications running\noffchain in a trusted environment (TEE) and that seamlessly communicate with\nOasis Sapphire. This is ideal for trusted oracles, compute-expensive tasks\nin AI or as a backend for interactive games."}),"\n",(0,s.jsx)(o.A,{item:(0,a.$)("/rofl/")}),"\n",(0,s.jsx)(t.h2,{id:"get-involved",children:"Get Involved"}),"\n",(0,s.jsx)(t.p,{children:"Contains information on official channels to get in touch with the Oasis Network\ndevelopers and how to contribute to the network."}),"\n",(0,s.jsx)(i.A,{items:[(0,a.$)("/get-involved/"),(0,a.$)("https://oasisrose.garden"),(0,a.$)("/get-involved/run-node"),(0,a.$)("/get-involved/oasis-core")]}),"\n",(0,s.jsx)(t.h2,{id:"run-node",children:"Run Node"}),"\n",(0,s.jsx)(t.p,{children:"If you want to run your own Oasis node, this part will provide you\nwith guides on the current Mainnet and Testnet network parameters and how to\nset up your node, let it be a validator node, perhaps running a ParaTime or\njust a simple client node for your server to submit transactions and perform\nqueries on the network."}),"\n",(0,s.jsx)(i.A,{items:[(0,a.$)("/node/"),(0,a.$)("/node/mainnet/"),(0,a.$)("/node/testnet/"),(0,a.$)("/node/run-your-node/")]}),"\n",(0,s.jsx)(t.h2,{id:"build-paratimes",children:"Build ParaTimes"}),"\n",(0,s.jsx)(t.p,{children:"Apart from the Sapphire, Emerald, Cipher and the Key manager ParaTimes,\nyou can also write, compile, sign and deploy your own ParaTime on the Oasis\nNetwork. This part describes the knobs you need to use to do so."}),"\n",(0,s.jsx)(o.A,{item:(0,a.$)("/paratime/")}),"\n",(0,s.jsx)(t.h2,{id:"develop-core",children:"Develop Core"}),"\n",(0,s.jsx)(t.p,{children:"Whether you want to contribute your code to the core components of the Oasis\nNetwork or just learn more about the Oasis consensus layer and other core\ncomponents, this is the part for you."}),"\n",(0,s.jsx)(o.A,{item:(0,a.$)("/core/")}),"\n",(0,s.jsx)(t.p,{children:"Additions or changes to the interoperable Oasis network components are always\nmade with consensus. Similar to the Ethereum's ERC/EIP mechanism Oasis follows\nformal Architectural Decision Records (ADRs) which are first proposed, voted on\nand finally implemented, if accepted."}),"\n",(0,s.jsx)(o.A,{item:(0,a.$)("/adrs")})]})}function m(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},5965:(e,t,n)=>{n.d(t,{A:()=>g});n(6540);var s=n(4164),r=n(8774),o=n(4142),i=n(5846),a=n(6654),l=n(1312),c=n(1107);const d={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var u=n(4848);function h(e){let{href:t,children:n}=e;return(0,u.jsx)(r.A,{href:t,className:(0,s.A)("card padding--lg",d.cardContainer),children:n})}function p(e){let{href:t,icon:n,title:r,description:o}=e;return(0,u.jsxs)(h,{href:t,children:[(0,u.jsxs)(c.A,{as:"h2",className:(0,s.A)("text--truncate",d.cardTitle),title:r,children:[n," ",r]}),o&&(0,u.jsx)("p",{className:(0,s.A)("text--truncate",d.cardDescription),title:o,children:o})]})}function m(e){let{item:t}=e;const n=(0,o.Nr)(t),s=function(){const{selectMessage:e}=(0,i.W)();return t=>e(t,(0,l.T)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,u.jsx)(p,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??s(t.items.length)}):null}function f(e){let{item:t}=e;const n=(0,a.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",s=(0,o.cC)(t.docId??void 0);return(0,u.jsx)(p,{href:t.href,icon:n,title:t.label,description:t.description??s?.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return(0,u.jsx)(f,{item:t});case"category":return(0,u.jsx)(m,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}},2550:(e,t,n)=>{n.d(t,{A:()=>l});n(6540);var s=n(4164),r=n(4142),o=n(5965),i=n(4848);function a(e){let{className:t}=e;const n=(0,r.$S)();return(0,i.jsx)(l,{items:n.items,className:t})}function l(e){const{items:t,className:n}=e;if(!t)return(0,i.jsx)(a,{...e});const l=(0,r.d1)(t);return(0,i.jsx)("section",{className:(0,s.A)("row",n),children:l.map(((e,t)=>(0,i.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,i.jsx)(o.A,{item:e})},t)))})}},5846:(e,t,n)=>{n.d(t,{W:()=>c});var s=n(6540),r=n(4586);const o=["zero","one","two","few","many","other"];function i(e){return o.filter((t=>e.includes(t)))}const a={locale:"en",pluralForms:i(["one","other"]),select:e=>1===e?"one":"other"};function l(){const{i18n:{currentLocale:e}}=(0,r.A)();return(0,s.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:i(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),a}}),[e])}function c(){const e=l();return{selectMessage:(t,n)=>function(e,t,n){const s=e.split("|");if(1===s.length)return s[0];s.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${s.length}: ${e}`);const r=n.select(t),o=n.pluralForms.indexOf(r);return s[Math.min(o,s.length-1)]}(n,t,e)}}},6116:(e,t,n)=>{n.d(t,{$:()=>o});var s=n(2252);function r(e){for(const t of e){const e=t.href;e&&void 0===globalThis.sidebarItemsMap[e]&&(globalThis.sidebarItemsMap[e]=t),"category"===t.type&&r(t.items)}}function o(e){const t=(0,s.r)();if(!t)throw new Error("Unexpected: cant find docsVersion in current context");if(void 0===globalThis.sidebarItemsMap){globalThis.sidebarItemsMap={};for(const e in t.docsSidebars)r(t.docsSidebars[e])}if(void 0===globalThis.sidebarItemsMap[e])throw console.log("Registered sidebar items:"),console.log(globalThis.sidebarItemsMap),new Error("Unexpected: sidebar item with href "+e+" does not exist.");return globalThis.sidebarItemsMap[e]}},8453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var s=n(6540);const r={},o=s.createContext(r);function i(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/5a14fd4c.4416ac9f.js b/assets/js/5a14fd4c.4416ac9f.js
new file mode 100644
index 0000000000..e472224173
--- /dev/null
+++ b/assets/js/5a14fd4c.4416ac9f.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[9555],{9138:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var i=t(4848),s=t(8453);const o={},r="ADR 0010: VRF-based Committee Elections",a={id:"adrs/0010-vrf-elections",title:"ADR 0010: VRF-based Committee Elections",description:"Component",source:"@site/docs/adrs/0010-vrf-elections.md",sourceDirName:"adrs",slug:"/adrs/0010-vrf-elections",permalink:"/adrs/0010-vrf-elections",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/adrs/edit/main/0010-vrf-elections.md",tags:[],version:"current",lastUpdatedAt:1710755515e3,frontMatter:{},sidebar:"adrs",previous:{title:"ADR 0009: Ed25519 Signature Verification Semantics",permalink:"/adrs/0009-ed25519-semantics"},next:{title:"ADR 0011: Incoming Runtime Messages",permalink:"/adrs/0011-incoming-runtime-messages"}},l={},h=[{value:"Component",id:"component",level:2},{value:"Changelog",id:"changelog",level:2},{value:"Status",id:"status",level:2},{value:"Context",id:"context",level:2},{value:"Decision",id:"decision",level:2},{value:"Cryptographic Primitives",id:"cryptographic-primitives",level:3},{value:"Node Descriptor Changes",id:"node-descriptor-changes",level:3},{value:"Consensus Parameters",id:"consensus-parameters",level:3},{value:"Consensus State, Events, and Transactions",id:"consensus-state-events-and-transactions",level:3},{value:"VRF Operation",id:"vrf-operation",level:3},{value:"VRF Committee Elections",id:"vrf-committee-elections",level:3},{value:"VRF Validator Elections",id:"vrf-validator-elections",level:3},{value:"Timekeeping Changes",id:"timekeeping-changes",level:3},{value:"Consequences",id:"consequences",level:2},{value:"Positive",id:"positive",level:3},{value:"Negative",id:"negative",level:3},{value:"Neutral",id:"neutral",level:3},{value:"References",id:"references",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"adr-0010-vrf-based-committee-elections",children:"ADR 0010: VRF-based Committee Elections"}),"\n",(0,i.jsx)(n.h2,{id:"component",children:"Component"}),"\n",(0,i.jsx)(n.p,{children:"Oasis Core"}),"\n",(0,i.jsx)(n.h2,{id:"changelog",children:"Changelog"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"2021-05-10: Initial version"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"status",children:"Status"}),"\n",(0,i.jsx)(n.p,{children:"Accepted"}),"\n",(0,i.jsx)(n.h2,{id:"context",children:"Context"}),"\n",(0,i.jsx)(n.p,{children:"While functional, the current PVSS-based random beacon is neither all that\nperformant, nor all that scalable. To address both concerns, this ADR\nproposes transitioning the election procedure to one that is based on\ncryptographic sortition of Verifiable Random Function (VRF) outputs."}),"\n",(0,i.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,i.jsx)(n.h3,{id:"cryptographic-primitives",children:"Cryptographic Primitives"}),"\n",(0,i.jsxs)(n.p,{children:["Let the VRF to be used across the system be ECVRF-EDWARDS25519-SHA512-ELL2\nfrom the ",(0,i.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/draft-irtf-cfrg-vrf/",children:"Verifiable Random Functions (VRFs) draft (v10)"}),", with the\nfollowing additions and extra clarifications:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'All public keys MUST be validated via the "ECVRF Validate Key" procedure\nas specified in section 5.6.1 (Small order public keys MUST be\nrejected).'}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"The string_to_point routine MUST reject non-canonically encoded points\nas specified in RFC 8032. Many ed25519 implementations are lax about\nenforcing this when decoding."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"When decoding s in the ECVRF_verify routine, the s scalar MUST fall\nwithin the range 0 \u2264 i < L. This change will make proofs\nnon-malleable. Note that this check is unneeded for the c scalar\nas it is 128-bits, and thus will always lie within the valid range.\nThis check was not present in the IETF draft prior to version 10."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Implementations MAY choose to incorporate additional randomness into\nthe ECVRF_nonce_generation_RFC8032 function. Note that proofs (pi_string)\nare not guaranteed to be unique or deterministic even without this\nextension (the signer can use any arbitrary value for the nonce and\nproduce a valid proof, without altering beta_string)."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Let the tuple oriented cryptographic hash function be TupleHash256 from\n",(0,i.jsx)(n.a,{href:"https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf",children:"NIST SP 800-185"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"node-descriptor-changes",children:"Node Descriptor Changes"}),"\n",(0,i.jsx)(n.p,{children:"The node descriptor of each node will be extended to include the following\ndatastructure."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-golang",children:'type Node struct {\n // ... existing fields omitted ...\n\n // VRF is the public key used by the node to generate VRF proofs.\n VRF *VRFInfo `json:"vrf,omitempty"`\n}\n\ntype VRFInfo struct {\n // ID is the unique identifier of the node used to generate VRF proofs.\n ID signature.PublicKey `json:"id"`\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:"The VRF public key shall be a long-term Ed25519 public key, that is distinct\nfrom every other key used by the node. The key MUST not be small order."}),"\n",(0,i.jsxs)(n.p,{children:["The existing ",(0,i.jsx)(n.code,{children:"Beacon"})," member of the node descriptor is considered deprecated\nand will first be ignored by the consensus layer, and then removed in a\nsubsequent version following a transitionary period."]}),"\n",(0,i.jsx)(n.h3,{id:"consensus-parameters",children:"Consensus Parameters"}),"\n",(0,i.jsx)(n.p,{children:"The scheduler module will have the following additional consensus parameters\nthat control behavior."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-golang",children:'type ConsensusParameters struct {\n // ... existing fields omitted ...\n\n // VRFParameters is the paramenters for the VRF-based cryptographic\n // sortition based election system.\n VRFParameters *VRFParameters `json:"vrf_params"`\n}\n\n// VRFParameters are the VRF scheduler parameters.\ntype VRFParameters struct {\n // AlphaHighQualityThreshold is the minimum number of proofs (Pi)\n // that must be received for the next input (Alpha) to be considered\n // high quality. If the VRF input is not high quality, runtimes will\n // be disabled for the next epoch.\n AlphaHighQualityThreshold uint64 `json:"alpha_hq_threshold,omitempty"`\n\n // Interval is the epoch interval (in blocks).\n Interval int64 `json:"interval,omitempty"`\n\n // ProofSubmissionDelay is the wait peroid in blocks after an epoch\n // transition that nodes MUST wait before attempting to submit a\n // VRF proof for the next epoch\'s elections.\n ProofSubmissionDelay int64 `json:"proof_delay,omitempty"`\n\n // PrevState is the VRF state from the previous epoch, for the\n // current epoch\'s elections.\n PrevState *PrevVRFState `json:"prev_state,omitempty"`\n}\n\n// PrevVRFState is the previous epoch\'s VRF state that is to be used for\n// elections.\ntype PrevVRFState struct {\n // Pi is the accumulated pi_string (VRF proof) outputs for the\n // previous epoch.\n Pi map[signature.PublicKey]*signature.Proof `json:"pi.omitempty"`\n\n // CanElectCommittees is true iff the previous alpha was generated\n // from high quality input such that committee elections are possible.\n CanElectCommittees bool `json:"can_elect,omitempty"`\n}\n\n'})}),"\n",(0,i.jsx)(n.h3,{id:"consensus-state-events-and-transactions",children:"Consensus State, Events, and Transactions"}),"\n",(0,i.jsx)(n.p,{children:"The scheduler component will maintain and make available the following additonal\nconsensus state."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-golang",children:'// VRFState is the VRF scheduler state.\ntype VRFState struct {\n // Epoch is the epoch for which this alpha is valid.\n Epoch EpochTime `json:"epoch"`\n\n // Alpha is the active VRF alpha_string input.\n Alpha []byte `json:"alpha"`\n\n // Pi is the accumulated pi_string (VRF proof) outputs.\n Pi map[signature.PublicKey]*signature.Proof `json:"pi,omitempty"`\n\n // AlphaIsHighQuality is true iff the alpha was generated from\n // high quality input such that elections will be possible.\n AlphaIsHighQuality bool `json:"alpha_hq"`\n\n // SubmitAfter is the block height after which nodes may submit\n // VRF proofs for the current epoch.\n SubmitAfter int64 `json:"submit_after"`\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:"Implementations MAY cache the beta_string values that are generated from valid\npi_strings for performance reasons, however as this is trivial to recalculate,\nit does not need to be explicitly exposed."}),"\n",(0,i.jsx)(n.p,{children:"Upon epoch transition, the scheduler will emit the following event."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-golang",children:'// VRFEvent is the VRF scheduler event.\ntype VRFEvent struct {\n // Epoch is the epoch that Alpha is valid for.\n Epoch EpochTime `json:"epoch,omitempty"`\n\n // Alpha is the active VRF alpha_string input.\n Alpha []byte `json:"alpha,omitempty"`\n\n // SubmitAfter is the block height after which nodes may submit\n // VRF proofs for the current epoch.\n SubmitAfter int64 `json:"submit_after"`\n}\n\n'})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-golang",children:'type VRFProve struct {\n // Epoch is the epoch that this VRF proof is for.\n Epoch epochtime.EpochTime `json:"epoch"`\n\n // Pi is the VRF proof for the current epoch.\n Pi []byte `json:"pi"`\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"vrf-operation",children:"VRF Operation"}),"\n",(0,i.jsx)(n.p,{children:"For the genesis epoch, let the VRF alpha_string input be derived as:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:'TupleHash256((chain_context, I2OSP(epoch,8)), 256, "oasis-core:vrf/alpha")'})}),"\n",(0,i.jsx)(n.p,{children:"For every subsequent epoch, let alpha_string be derived as:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:'TupleHash256((chain_context, I2OSP(epoch, 8), beta_0, ... beta_n), 256, "oasis-core:vrf/alpha")'})}),"\n",(0,i.jsx)(n.p,{children:'where beta_0 through beta_n are the beta_string outputs gathered from\nall valid pi_strings submitted during the previous epoch (after the\non-transition culling is complete), in ascending lexographic order by\nVRF key. If the number of beta values incorporated into the TupleHash\ncomputation is greater than or equal to AlphaHighQuality threshold,\nthe alpha is considered "strong", and committee elections are allowed\nbased on the proofs generated with this alpha. If the alpha value is\nweak (insufficient nodes submitted proofs), only validator elections\nare allowed.'}),"\n",(0,i.jsxs)(n.p,{children:["Upon receiving a VRFEvent, all eligible nodes MUST wait a minimum of\nProofSubmissionDelay blocks, and then submit a VRFProve transaction,\nwith the Proof field set to the output of\n",(0,i.jsx)(n.code,{children:"ECVRF_prove(VRFKey_private, alpha_string)"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Upon receiving a VRFProve transaction, the scheduler does the following:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Rejects the transaction if less than ProofSubmissionDelay blocks\nhave elapsed since the transition into the current epoch."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Checks to see if the node tentatively eligible to be included in\nthe next election according to the following criteria:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Not frozen."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Has registered the VRF.ID used to generate the proof prior\nto the transition into the current epoch (May slash)."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Has not already submitted a proof for the current epoch\n(May slash if proof is different)."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Validates the proof, and if valid, stores the VRF.ID + pi_string\nin the consensus state."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"vrf-committee-elections",children:"VRF Committee Elections"}),"\n",(0,i.jsx)(n.p,{children:"The following changes are made to the committee election process."}),"\n",(0,i.jsx)(n.p,{children:"On epoch transition, as long as the alpha used to generate the proofs\nis considered strong re-validate node eligibility for all nodes that\nsubmitted a VRF proof (Not frozen, VRF.ID has not changed), and cull\nproofs from nodes that are now ineligible."}),"\n",(0,i.jsx)(n.p,{children:"If the alpha value is considered weak, no commitee elections are allowed."}),"\n",(0,i.jsx)(n.p,{children:"For each committee:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Filter the node list based on the current stake/eligibility criteria,\nand additionally filter out nodes that have not submitted a valid\nVRF proof."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"For each eligible (node, commitee kind, committe role) tuple, derive\na sortition string as:"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:'s_n = TupleHash256((chain_context, I2OSP(epoch, 8), runtime_id, I2OSP(kind, 1), I2OSP(role, 1), beta_n), 256, "oasis-core:vrf/committee")'})}),"\n",(0,i.jsxs)(n.ol,{start:"3",children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Sort s_0 ... s_n in ascending lexographical order."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Select the requisite nodes that produced the sortition strings\nstarting from the head of the sorted list as the committee."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Committee elections MUST be skipped for the genesis and subsequent epoch,\nas the genesis epoch has no VRF proofs, and proofs submitted during the\ngenesis epoch are based on the bootstrap alpha_string."}),"\n",(0,i.jsx)(n.h3,{id:"vrf-validator-elections",children:"VRF Validator Elections"}),"\n",(0,i.jsx)(n.p,{children:"The only place where the beacon is currently used in the validator selection\nprocess is to pick a single node out of multiple eligible nodes controlled by\nthe same entity to become a validator."}),"\n",(0,i.jsx)(n.p,{children:"When this situation occurs the validator is selected as follows:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"For all validator-eligible nodes controlled by the given entity,\nderive a sortition string as:"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:'s_n = TupleHash256((chain_context, I2OSP(epoch, 8), beta_n), 256, "oasis-core:vrf/validator")'})}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Sort s_0 ... s_n, in ascending lexographic order."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Select the node that produced the 0th sortition string in the sorted\nlist as the validator."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"This is safe to do with beta values generated via the bootstrap alpha string\nas it is up to the entity running the nodes in question as to which ones\nare a validator anyway."}),"\n",(0,i.jsx)(n.p,{children:"As a concession for the transition process, if the number of validators\nthat submit proofs is less than the minimum number of validators configured\nin the scheduler, validator tie-breaks (and only validator tie-breaks)\nwill be done by permuting the node list (as in the current PVSS beacon),\nusing entropy from the block hash."}),"\n",(0,i.jsx)(n.p,{children:"As nodes are required to submit a VRF public key as part of non-genesis\nregistrations, and each node will attempt to submit a VRF proof, this\nbackward compatibility hack should only be triggered on the genesis\nepoch, and can be removed on the next major upgrade."}),"\n",(0,i.jsx)(n.h3,{id:"timekeeping-changes",children:"Timekeeping Changes"}),"\n",(0,i.jsx)(n.p,{children:"Timekeeping will go back to a fixed-interval epoch transition mechanism, with\nall of the beacon related facilities removed. As this is primarily a module\nrename and code removal, the exact details are left unspecified."}),"\n",(0,i.jsx)(n.h2,{id:"consequences",children:"Consequences"}),"\n",(0,i.jsx)(n.h3,{id:"positive",children:"Positive"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"This is significantly simpler from a design standpoint."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"This is significantly faster and scales significantly better."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"It is possible to go back to fixed-length epochs again."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"negative",children:"Negative"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"The system loses a way to generate entropy at the consensus layer."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"The simple design involves an additional 1-epoch period after network\ninitialization where elections are not available."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"neutral",children:"Neutral"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"I need to implement TupleHash256."}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"references",children:"References"})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(6540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/5da91464.fb8e830b.js b/assets/js/5da91464.fb8e830b.js
new file mode 100644
index 0000000000..a7e5095282
--- /dev/null
+++ b/assets/js/5da91464.fb8e830b.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[4839],{4129:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>d,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var i=o(4848),s=o(8453);const r={description:"This page describes how to run an archive node on the Oasis Network."},t="Archive Node",a={id:"node/run-your-node/archive-node",title:"Archive Node",description:"This page describes how to run an archive node on the Oasis Network.",source:"@site/docs/node/run-your-node/archive-node.md",sourceDirName:"node/run-your-node",slug:"/node/run-your-node/archive-node",permalink:"/node/run-your-node/archive-node",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/node/run-your-node/archive-node.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{description:"This page describes how to run an archive node on the Oasis Network."},sidebar:"operators",previous:{title:"Seed Node",permalink:"/node/run-your-node/seed-node"},next:{title:"ParaTime Node",permalink:"/node/run-your-node/paratime-node"}},d={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Configuration (Oasis Core 23 and later)",id:"configuration-oasis-core-23-and-later",level:2},{value:"Configuration (Oasis Core 22 and earlier)",id:"configuration-oasis-core-22-and-earlier",level:2},{value:"Damask",id:"damask",level:4},{value:"Cobalt",id:"cobalt",level:4},{value:"Starting the Oasis Node",id:"starting-the-oasis-node",level:2},{value:"Archive node status",id:"archive-node-status",level:3},{value:"See also",id:"see-also",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",div:"div",h1:"h1",h2:"h2",h3:"h3",h4:"h4",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"archive-node",children:"Archive Node"}),"\n",(0,i.jsx)(n.p,{children:"This guide will cover setting up an archive node for the Oasis Network. Node\nstarted in archive mode only serves existing consensus and runtime states.\nThe node has all unneeded consensus and P2P functionality disabled, therefore\nit will not participate in the network. Archive nodes can be used to access\nhistoric state which is pruned in dump-restore network upgrades."}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.p,{children:["Running an archive node requires a pre-existing ",(0,i.jsx)(n.code,{children:"oasis-node"})," state. If you don't have one,\nyou can download a snapshot of a specific network state ",(0,i.jsx)(n.a,{href:"https://snapshots.oasis.io",children:"here"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"configuration-oasis-core-23-and-later",children:"Configuration (Oasis Core 23 and later)"}),"\n",(0,i.jsxs)(n.p,{children:["Starting from the Oasis Core version 23, the configuration for enabling archive mode has changed.\nUse the ",(0,i.jsx)(n.code,{children:"mode"})," setting:"]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsx)(n.p,{children:"This setting configures the node to act as an archive node."})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"mode: archive\ncommon:\n data_dir: /node/data\n log:\n format: JSON\n level:\n cometbft: info\n cometbft/context: error\n default: info\ngenesis:\n file: /node/etc/genesis.json\nruntime:\n # Paths to ParaTime bundles for all of the supported ParaTimes.\n paths:\n - {{ runtime_orc_path }}\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsx)(n.p,{children:"Keep all other settings the same as those for a full client node. For example, to serve archived runtime\nstate, the node needs to have the runtime configured and the state present."})}),"\n",(0,i.jsx)(n.h2,{id:"configuration-oasis-core-22-and-earlier",children:"Configuration (Oasis Core 22 and earlier)"}),"\n",(0,i.jsxs)(n.p,{children:["For all pre-Eden networks, such as Damask, the configuration remains the same but requires the\nappropriate version of ",(0,i.jsx)(n.code,{children:"oasis-node"})," and the node state."]}),"\n",(0,i.jsx)(n.h4,{id:"damask",children:"Damask"}),"\n",(0,i.jsxs)(n.p,{children:["To run an archive node for Damask, use ",(0,i.jsx)(n.a,{href:"https://github.com/oasisprotocol/oasis-core/releases/tag/v22.2.12",children:"Oasis Core v22.2.12"})," and the following\nconfiguration:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'datadir: /node/data\n\nlog:\n level:\n default: info\n tendermint: info\n tendermint/context: error\n format: JSON\n\ngenesis:\n file: /node/etc/genesis.json\n\nconsensus:\n tendermint:\n mode: archive\n\nruntime:\n mode: client\n paths:\n # Paths to ParaTime bundles for all of the supported ParaTimes.\n - "{{ runtime_orc_path }}"\n'})}),"\n",(0,i.jsx)(n.h4,{id:"cobalt",children:"Cobalt"}),"\n",(0,i.jsxs)(n.p,{children:["To run an archive node for Cobalt, use ",(0,i.jsx)(n.a,{href:"https://github.com/oasisprotocol/oasis-core/releases/tag/v21.3.14",children:"Oasis Core v21.3.14"})," and the following configuration:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'log:\n level:\n default: info\n tendermint: info\n tendermint/context: error\n format: JSON\n\ngenesis:\n file: /node/etc/genesis.json\n\nconsensus:\n tendermint:\n mode: archive\n\nruntime:\n supported:\n - "{{ runtime_id }}"\n\n paths:\n "{{ runtime_id }}": {{ paratime_binary_path }}\n\nworker:\n storage:\n enabled: true\n'})}),"\n",(0,i.jsx)(n.div,{children:(0,i.jsx)(n.p,{children:"Ensure you are using the correct version of oasis-node and the pre-existing state for your specific pre-Eden network."})}),"\n",(0,i.jsx)(n.h2,{id:"starting-the-oasis-node",children:"Starting the Oasis Node"}),"\n",(0,i.jsx)(n.p,{children:"You can start the node by running the following command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"oasis-node --config /node/etc/config.yml\n"})}),"\n",(0,i.jsx)(n.h3,{id:"archive-node-status",children:"Archive node status"}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsx)(n.p,{children:"The mode field is currently unavailable in the control status output. It will\nbe included in an upcoming release."})}),"\n",(0,i.jsx)(n.p,{children:"To ensure the node is running in archive mode, run the following command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"oasis-node control status -a unix:/node/data/internal.sock\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Output should report ",(0,i.jsx)(n.code,{children:"archive"})," consensus mode status:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n // other fields omitted ...\n "mode": "archive",\n // ...\n}\n'})}),"\n",(0,i.jsx)(n.h2,{id:"see-also",children:"See also"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"/node/web3#archive-web3-gateway",children:"Archive Web3 Gateway"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},8453:(e,n,o)=>{o.d(n,{R:()=>t,x:()=>a});var i=o(6540);const s={},r=i.createContext(s);function t(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/5e95c892.f27fa3ac.js b/assets/js/5e95c892.f27fa3ac.js
new file mode 100644
index 0000000000..bfcd74cad4
--- /dev/null
+++ b/assets/js/5e95c892.f27fa3ac.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[9647],{7121:(s,e,r)=>{r.r(e),r.d(e,{default:()=>n});r(6540);var a=r(4164),c=r(1003),o=r(7559),u=r(2831),i=r(5476),d=r(4848);function n(s){return(0,d.jsx)(c.e3,{className:(0,a.A)(o.G.wrapper.docsPages),children:(0,d.jsx)(i.A,{children:(0,u.v)(s.route.routes)})})}}}]);
\ No newline at end of file
diff --git a/assets/js/60d875af.68802beb.js b/assets/js/60d875af.68802beb.js
new file mode 100644
index 0000000000..9ea2201d84
--- /dev/null
+++ b/assets/js/60d875af.68802beb.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[436],{6502:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>u,frontMatter:()=>a,metadata:()=>d,toc:()=>h});var i=t(4848),s=t(8453),r=t(6116),o=t(2550);const a={},c="Run your node",d={id:"node/run-your-node/README",title:"Run your node",description:"The Oasis Network consists of several types of nodes, each serving distinct",source:"@site/docs/node/run-your-node/README.mdx",sourceDirName:"node/run-your-node",slug:"/node/run-your-node/",permalink:"/node/run-your-node/",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/node/run-your-node/README.mdx",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"operators",previous:{title:"Genesis Document",permalink:"/node/genesis-doc"},next:{title:"Prerequisites",permalink:"/node/run-your-node/prerequisites"}},l={},h=[{value:"Validator Node",id:"validator-node",level:2},{value:"Compute Nodes",id:"compute-nodes",level:2},{value:"Client Nodes",id:"client-nodes",level:2},{value:"Archive Node",id:"archive-node",level:2},{value:"Seed Node",id:"seed-node",level:2},{value:"Key Manager Node",id:"key-manager-node",level:2},{value:"Services",id:"services",level:2},{value:"Rosetta Gateway",id:"rosetta-gateway",level:3},{value:"Public gRPC",id:"public-grpc",level:3},{value:"Web3 Gateway",id:"web3-gateway",level:3},{value:"See also",id:"see-also",level:2}];function p(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"run-your-node",children:"Run your node"}),"\n",(0,i.jsx)(n.p,{children:"The Oasis Network consists of several types of nodes, each serving distinct\nroles to maintain the functionality, security, and decentralization of the\nnetwork. In this section you can find descriptions of the main types of nodes\nwithin the Oasis Network."}),"\n",(0,i.jsx)(n.h2,{id:"validator-node",children:"Validator Node"}),"\n",(0,i.jsxs)(n.p,{children:["A ",(0,i.jsx)(n.a,{href:"/node/run-your-node/validator-node",children:"Validator Node"})," is an essential component, as Oasis Network uses\nproof-of-stake (PoS) consensus mechanisms. It is responsible for verifying transactions and proposing new blocks to be added to the blockchain. Validator\nnodes operate on the consensus layer by staking the network's tokens, which\ngrants them the right to participate in the consensus process. This process\ninvolves validating transactions, signing blocks, and ensuring the integrity of\nthe blockchain."]}),"\n",(0,i.jsx)(n.h2,{id:"compute-nodes",children:"Compute Nodes"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"/node/run-your-node/paratime-node",children:"Compute Nodes"})," are responsible for executing smart contracts and processing\ntransactions within a specific ParaTime (Parallel Runtime). These nodes handle\nthe actual computation tasks, such as running decentralized applications\n(dApps), performing data processing, and executing privacy-preserving smart\ncontracts."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Sapphire Compute Node"})," is responsible for executing EVM-compatible\nprivacy-preserving smart contracts and processing transactions within the\nSapphire ParaTime. These nodes validate and execute transactions while\nmaintaining the confidentiality of sensitive data, which is a crucial aspect\nof applications that handle private information or require enhanced security.\nThis is achieved through trusted execution environments (TEEs) that ensure\ndata remains encrypted and confidential, even while being processed."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Cipher Compute Node"})," is responsible for executing privacy-preserving smart\ncontracts written in Oasis Wasm and processing transactions within the Cipher\nParaTime. These nodes validate and execute transactions while maintaining the\nconfidentiality of sensitive data, which is a crucial aspect of applications\nthat handle private information or require enhanced security. This is achieved\nthrough trusted execution environments (TEEs) that ensure data remains\nencrypted and confidential, even while being processed."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Emerald Compute Node"})," is responsible for executing EVM-compatible smart\ncontracts and processing transactions within the Emerald ParaTime. It performs\ntasks such as validating transactions, running EVM-based smart contracts, and\nensuring that the operations within the Emerald ParaTime are carried out\nefficiently."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"client-nodes",children:"Client Nodes"}),"\n",(0,i.jsx)(n.p,{children:"A Client Node is a type of node within the Oasis Network that serves as\nan interface for users or other applications to interact with the blockchain.\nUnlike compute nodes, which handle transaction processing and smart contract\nexecution, client nodes are primarily responsible for tasks such as querying\nthe blockchain, submitting transactions, and retrieving other data from the\nnetwork."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.a,{href:"/node/run-your-node/non-validator-node",children:"Non-Validator Node"})})," is a type of node in the Oasis Network that does not\nparticipate in the consensus process of validating and proposing new blocks.\nInstead, it has client node functions that support the network's operations and\ndecentralization."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.a,{href:"/node/run-your-node/paratime-client-node",children:"Sapphire Client Node"})})," is a specific type of client node within the Oasis\nNetwork that interacts with the Sapphire ParaTime. The Sapphire ParaTime is\ndesigned to support EVM-compatible confidential smart contracts and\nprivacy-preserving decentralized applications (dApps) with strong privacy\nfeatures and high performance."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.a,{href:"/node/run-your-node/paratime-client-node",children:"Cipher Client Node"})})," is a type of node within the Oasis Network designed\nto interact specifically with the Cipher ParaTime. The Cipher ParaTime is known\nfor its strong privacy features, allowing for the execution of confidential\nsmart contracts and the development of privacy-preserving decentralized\napplications (dApps)."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.a,{href:"/node/run-your-node/paratime-client-node",children:"Emerald Client Node"})})," is a specific type of client node within the Oasis\nNetwork, designed to interact with the Emerald ParaTime. The Emerald ParaTime is\nan Ethereum-compatible environment on the Oasis Network, allowing developers\nto deploy and manage decentralized applications (dApps) that utilize the\nEthereum Virtual Machine (EVM)."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"archive-node",children:"Archive Node"}),"\n",(0,i.jsxs)(n.p,{children:["An ",(0,i.jsx)(n.a,{href:"/node/run-your-node/archive-node",children:"Archive Node"})," is a specialized node within the Oasis Network that stores the\nentire blockchain history, making it a crucial tool for in-depth analysis,\ndevelopment, and ensuring that the network's past states remain accessible."]}),"\n",(0,i.jsx)(n.h2,{id:"seed-node",children:"Seed Node"}),"\n",(0,i.jsxs)(n.p,{children:["A ",(0,i.jsx)(n.a,{href:"/node/run-your-node/seed-node",children:"Seed Node"})," is a type of node in the Oasis Network that serves a critical role\nin helping other nodes discover peers and join the network (",(0,i.jsx)(n.em,{children:"address book"}),").\nUnlike validator nodes, which participate in the consensus process, Seed Nodes\ndo not play a direct role in consensus."]}),"\n",(0,i.jsx)(n.h2,{id:"key-manager-node",children:"Key Manager Node"}),"\n",(0,i.jsxs)(n.p,{children:["A ",(0,i.jsx)(n.a,{href:"/node/run-your-node/keymanager-node/",children:"Key Manager Node"})," is a specialized node in the Oasis Network responsible for\nsecurely managing cryptographic keys used in confidential computing. These nodes\nare crucial for the network's privacy-preserving features, enabling secure\nencryption and decryption of data processed within Trusted Execution\nEnvironments (TEEs). They play a vital role in enabling the Oasis Network's\nsecure, decentralized, and privacy-focused operations."]}),"\n",(0,i.jsx)(n.h2,{id:"services",children:"Services"}),"\n",(0,i.jsx)(n.h3,{id:"rosetta-gateway",children:"Rosetta Gateway"}),"\n",(0,i.jsxs)(n.p,{children:["A ",(0,i.jsx)(n.a,{href:"https://github.com/oasisprotocol/oasis-rosetta-gateway",children:"Rosetta Gateway"})," service is a specialized service within the Oasis Network\nthat implements the ",(0,i.jsx)(n.a,{href:"https://docs.cdp.coinbase.com/mesh/docs/api-reference",children:"Rosetta API"})," to provide a standardized and simplified\ninterface for interacting with the blockchain. This service is crucial for\nenabling seamless integration between the Oasis Network and various external\nplatforms, such as exchanges, wallets, custodians, and blockchain-based\napplications. The Rosetta Gateway connects to a ",(0,i.jsx)(n.a,{href:"#client-nodes",children:"non-validator"}),"\nnode."]}),"\n",(0,i.jsx)(n.h3,{id:"public-grpc",children:"Public gRPC"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/node/grpc",children:"Oasis gRPC protocol"})," is an efficient, real-time, and cross-platform\ncommunication protocol that allows developers to both manage the Oasis node and communicate with the Oasis network. While each Oasis node opens a gRPC socket,\nthe public endpoints run a proxy and expose only a small, safe subset of the\nAPI calls publicly."]}),"\n",(0,i.jsx)(n.h3,{id:"web3-gateway",children:"Web3 Gateway"}),"\n",(0,i.jsxs)(n.p,{children:["A ",(0,i.jsx)(n.a,{href:"/node/web3",children:"Web3 Gateway"})," enables interaction with the Oasis Network using standard\nWeb3 protocol, which is widely used in the Ethereum ecosystem. It acts as a\nbridge between Web3-based applications and the Oasis Network, allowing\ndevelopers to leverage the tools, libraries, and practices familiar in\nEthereum development while benefiting from the unique features of the Oasis\nNetwork, such as privacy and confidentiality. The Web3 gateway connects to a\n",(0,i.jsx)(n.a,{href:"#compute-nodes",children:"compute"})," or a ",(0,i.jsx)(n.a,{href:"#client-nodes",children:"client"})," Sapphire or Emerald node."]}),"\n",(0,i.jsx)(n.h2,{id:"see-also",children:"See also"}),"\n",(0,i.jsx)(o.A,{items:[(0,r.$)("/node/run-your-node/maintenance"),(0,r.$)("/node/run-your-node/advanced"),(0,r.$)("/node/run-your-node/troubleshooting")]})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(p,{...e})}):p(e)}},5965:(e,n,t)=>{t.d(n,{A:()=>g});t(6540);var i=t(4164),s=t(8774),r=t(4142),o=t(5846),a=t(6654),c=t(1312),d=t(1107);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var h=t(4848);function p(e){let{href:n,children:t}=e;return(0,h.jsx)(s.A,{href:n,className:(0,i.A)("card padding--lg",l.cardContainer),children:t})}function u(e){let{href:n,icon:t,title:s,description:r}=e;return(0,h.jsxs)(p,{href:n,children:[(0,h.jsxs)(d.A,{as:"h2",className:(0,i.A)("text--truncate",l.cardTitle),title:s,children:[t," ",s]}),r&&(0,h.jsx)("p",{className:(0,i.A)("text--truncate",l.cardDescription),title:r,children:r})]})}function m(e){let{item:n}=e;const t=(0,r.Nr)(n),i=function(){const{selectMessage:e}=(0,o.W)();return n=>e(n,(0,c.T)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:n}))}();return t?(0,h.jsx)(u,{href:t,icon:"\ud83d\uddc3\ufe0f",title:n.label,description:n.description??i(n.items.length)}):null}function f(e){let{item:n}=e;const t=(0,a.A)(n.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",i=(0,r.cC)(n.docId??void 0);return(0,h.jsx)(u,{href:n.href,icon:t,title:n.label,description:n.description??i?.description})}function g(e){let{item:n}=e;switch(n.type){case"link":return(0,h.jsx)(f,{item:n});case"category":return(0,h.jsx)(m,{item:n});default:throw new Error(`unknown item type ${JSON.stringify(n)}`)}}},2550:(e,n,t)=>{t.d(n,{A:()=>c});t(6540);var i=t(4164),s=t(4142),r=t(5965),o=t(4848);function a(e){let{className:n}=e;const t=(0,s.$S)();return(0,o.jsx)(c,{items:t.items,className:n})}function c(e){const{items:n,className:t}=e;if(!n)return(0,o.jsx)(a,{...e});const c=(0,s.d1)(n);return(0,o.jsx)("section",{className:(0,i.A)("row",t),children:c.map(((e,n)=>(0,o.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,o.jsx)(r.A,{item:e})},n)))})}},5846:(e,n,t)=>{t.d(n,{W:()=>d});var i=t(6540),s=t(4586);const r=["zero","one","two","few","many","other"];function o(e){return r.filter((n=>e.includes(n)))}const a={locale:"en",pluralForms:o(["one","other"]),select:e=>1===e?"one":"other"};function c(){const{i18n:{currentLocale:e}}=(0,s.A)();return(0,i.useMemo)((()=>{try{return function(e){const n=new Intl.PluralRules(e);return{locale:e,pluralForms:o(n.resolvedOptions().pluralCategories),select:e=>n.select(e)}}(e)}catch(n){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${n.message}\n`),a}}),[e])}function d(){const e=c();return{selectMessage:(n,t)=>function(e,n,t){const i=e.split("|");if(1===i.length)return i[0];i.length>t.pluralForms.length&&console.error(`For locale=${t.locale}, a maximum of ${t.pluralForms.length} plural forms are expected (${t.pluralForms.join(",")}), but the message contains ${i.length}: ${e}`);const s=t.select(n),r=t.pluralForms.indexOf(s);return i[Math.min(r,i.length-1)]}(t,n,e)}}},6116:(e,n,t)=>{t.d(n,{$:()=>r});var i=t(2252);function s(e){for(const n of e){const e=n.href;e&&void 0===globalThis.sidebarItemsMap[e]&&(globalThis.sidebarItemsMap[e]=n),"category"===n.type&&s(n.items)}}function r(e){const n=(0,i.r)();if(!n)throw new Error("Unexpected: cant find docsVersion in current context");if(void 0===globalThis.sidebarItemsMap){globalThis.sidebarItemsMap={};for(const e in n.docsSidebars)s(n.docsSidebars[e])}if(void 0===globalThis.sidebarItemsMap[e])throw console.log("Registered sidebar items:"),console.log(globalThis.sidebarItemsMap),new Error("Unexpected: sidebar item with href "+e+" does not exist.");return globalThis.sidebarItemsMap[e]}},8453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var i=t(6540);const s={},r=i.createContext(s);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/6602e166.d3e7dc73.js b/assets/js/6602e166.d3e7dc73.js
new file mode 100644
index 0000000000..6132ec36b2
--- /dev/null
+++ b/assets/js/6602e166.d3e7dc73.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[8063],{7435:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Run a Node","slug":"get-involved/run-node","permalink":"/get-involved/run-node","sidebar":"getInvolved","navigation":{"previous":{"title":"Join our Community","permalink":"/get-involved/"},"next":{"title":"Consensus Validator Node","permalink":"/get-involved/run-node/validator-node"}}}}')}}]);
\ No newline at end of file
diff --git a/assets/js/6629c45f.f05c5041.js b/assets/js/6629c45f.f05c5041.js
new file mode 100644
index 0000000000..54216d60d5
--- /dev/null
+++ b/assets/js/6629c45f.f05c5041.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[5820],{7691:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"adrs":[{"type":"category","label":"Architectural Decision Records","items":[{"type":"link","label":"ADR 0001: Multiple Roots Under the Tendermint Application Hash","href":"/adrs/0001-tm-multi-root-apphash","docId":"adrs/0001-tm-multi-root-apphash","unlisted":false},{"type":"link","label":"ADR 0002: Go Modules Compatible Git Tags","href":"/adrs/0002-go-modules-compatible-git-tags","docId":"adrs/0002-go-modules-compatible-git-tags","unlisted":false},{"type":"link","label":"ADR 0003: Consensus/Runtime Token Transfer","href":"/adrs/0003-consensus-runtime-token-transfer","docId":"adrs/0003-consensus-runtime-token-transfer","unlisted":false},{"type":"link","label":"ADR 0004: Runtime Governance","href":"/adrs/0004-runtime-governance","docId":"adrs/0004-runtime-governance","unlisted":false},{"type":"link","label":"ADR 0005: Runtime Compute Node Slashing","href":"/adrs/0005-runtime-compute-slashing","docId":"adrs/0005-runtime-compute-slashing","unlisted":false},{"type":"link","label":"ADR 0006: Consensus Governance","href":"/adrs/0006-consensus-governance","docId":"adrs/0006-consensus-governance","unlisted":false},{"type":"link","label":"ADR 0007: Improved Random Beacon","href":"/adrs/0007-improved-random-beacon","docId":"adrs/0007-improved-random-beacon","unlisted":false},{"type":"link","label":"ADR 0008: Standard Account Key Generation","href":"/adrs/0008-standard-account-key-generation","docId":"adrs/0008-standard-account-key-generation","unlisted":false},{"type":"link","label":"ADR 0009: Ed25519 Signature Verification Semantics","href":"/adrs/0009-ed25519-semantics","docId":"adrs/0009-ed25519-semantics","unlisted":false},{"type":"link","label":"ADR 0010: VRF-based Committee Elections","href":"/adrs/0010-vrf-elections","docId":"adrs/0010-vrf-elections","unlisted":false},{"type":"link","label":"ADR 0011: Incoming Runtime Messages","href":"/adrs/0011-incoming-runtime-messages","docId":"adrs/0011-incoming-runtime-messages","unlisted":false},{"type":"link","label":"ADR 0012: Runtime Message Results","href":"/adrs/0012-runtime-message-results","docId":"adrs/0012-runtime-message-results","unlisted":false},{"type":"link","label":"ADR 0013: Runtime Upgrade Improvements","href":"/adrs/0013-runtime-upgrades","docId":"adrs/0013-runtime-upgrades","unlisted":false},{"type":"link","label":"ADR 0014: Signing Runtime Transactions with Hardware Wallet","href":"/adrs/0014-runtime-signing-tx-with-hardware-wallet","docId":"adrs/0014-runtime-signing-tx-with-hardware-wallet","unlisted":false},{"type":"link","label":"ADR 0015: Randomized Paratime Proposer Selection","href":"/adrs/0015-vrf-per-block-entropy","docId":"adrs/0015-vrf-per-block-entropy","unlisted":false},{"type":"link","label":"ADR 0016: Consensus Parameters Change Proposal","href":"/adrs/0016-consensus-parameters-change-proposal","docId":"adrs/0016-consensus-parameters-change-proposal","unlisted":false},{"type":"link","label":"ADR 0017: ParaTime Application Standard Proposal Process","href":"/adrs/0017-app-standards","docId":"adrs/0017-app-standards","unlisted":false},{"type":"link","label":"ADR 0020: Governance Support for Delegator Votes","href":"/adrs/0020-governance-delegator-votes","docId":"adrs/0020-governance-delegator-votes","unlisted":false},{"type":"link","label":"ADR 0021: Forward-Secret Ephemeral Secrets","href":"/adrs/0021-keymanager-ephemeral-secrets","docId":"adrs/0021-keymanager-ephemeral-secrets","unlisted":false},{"type":"link","label":"ADR 0022: Forward-Secret Master Secrets","href":"/adrs/0022-keymanager-master-secrets","docId":"adrs/0022-keymanager-master-secrets","unlisted":false},{"type":"link","label":"ADR 0024: Runtime Off-chain Logic (ROFL)","href":"/adrs/0024-off-chain-runtime-logic","docId":"adrs/0024-off-chain-runtime-logic","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/adrs"}],"oasisCore":[{"type":"link","label":"Overview","href":"/core/","docId":"core/README","unlisted":false},{"type":"category","label":"Development Setup","collapsible":false,"items":[{"type":"category","label":"Build Environment Setup and Building","items":[{"type":"link","label":"Prerequisites","href":"/core/development-setup/prerequisites","docId":"core/development-setup/prerequisites","unlisted":false},{"type":"link","label":"Building","href":"/core/development-setup/building","docId":"core/development-setup/building","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/core/development-setup/build-environment-setup-and-building"},{"type":"category","label":"Running Tests and Development Networks","items":[{"type":"link","label":"Running Tests","href":"/core/development-setup/running-tests","docId":"core/development-setup/running-tests","unlisted":false},{"type":"link","label":"Local Network Runner","href":"/core/development-setup/oasis-net-runner","docId":"core/development-setup/oasis-net-runner","unlisted":false},{"type":"link","label":"Single Validator Node Network","href":"/core/development-setup/single-validator-node-network","docId":"core/development-setup/single-validator-node-network","unlisted":false},{"type":"link","label":"Deploying a Runtime","href":"/core/development-setup/deploying-a-runtime","docId":"core/development-setup/deploying-a-runtime","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/core/development-setup/running-tests-and-development-networks"}],"collapsed":false,"href":"/core/development-setup"},{"type":"category","label":"High-Level Components","collapsible":false,"items":[{"type":"category","label":"Consensus Layer","items":[{"type":"link","label":"Transactions","href":"/core/consensus/transactions","docId":"core/consensus/transactions","unlisted":false},{"type":"category","label":"Services","items":[{"type":"link","label":"Epoch Time","href":"/core/consensus/services/epochtime","docId":"core/consensus/services/epochtime","unlisted":false},{"type":"link","label":"Random Beacon","href":"/core/consensus/services/beacon","docId":"core/consensus/services/beacon","unlisted":false},{"type":"link","label":"Staking","href":"/core/consensus/services/staking","docId":"core/consensus/services/staking","unlisted":false},{"type":"link","label":"Registry","href":"/core/consensus/services/registry","docId":"core/consensus/services/registry","unlisted":false},{"type":"link","label":"Committee Scheduler","href":"/core/consensus/services/scheduler","docId":"core/consensus/services/scheduler","unlisted":false},{"type":"link","label":"Governance","href":"/core/consensus/services/governance","docId":"core/consensus/services/governance","unlisted":false},{"type":"link","label":"Root Hash","href":"/core/consensus/services/roothash","docId":"core/consensus/services/roothash","unlisted":false},{"type":"link","label":"Key Manager","href":"/core/consensus/services/keymanager","docId":"core/consensus/services/keymanager","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/core/consensus/services"},{"type":"link","label":"Genesis Document","href":"/core/consensus/genesis","docId":"core/consensus/genesis","unlisted":false},{"type":"link","label":"Transaction Test Vectors","href":"/core/consensus/test-vectors","docId":"core/consensus/test-vectors","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/core/consensus/"},{"type":"category","label":"Runtime Layer","items":[{"type":"link","label":"Runtime Host Protocol","href":"/core/runtime/runtime-host-protocol","docId":"core/runtime/runtime-host-protocol","unlisted":false},{"type":"link","label":"Runtime IDs","href":"/core/runtime/identifiers","docId":"core/runtime/identifiers","unlisted":false},{"type":"link","label":"Runtime Messages","href":"/core/runtime/messages","docId":"core/runtime/messages","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/core/runtime/"},{"type":"category","label":"Oasis Node","items":[{"type":"link","label":"RPC","href":"/core/oasis-node/rpc","docId":"core/oasis-node/rpc","unlisted":false},{"type":"link","label":"Metrics","href":"/core/oasis-node/metrics","docId":"core/oasis-node/metrics","unlisted":false},{"type":"link","label":"oasis-node CLI","href":"/core/oasis-node/cli","docId":"core/oasis-node/cli","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/core/oasis-node"}],"collapsed":false,"href":"/core/high-level-components"},{"type":"category","label":"Common Functionality","collapsible":false,"items":[{"type":"link","label":"Encoding","href":"/core/encoding","docId":"core/encoding","unlisted":false},{"type":"link","label":"Cryptography","href":"/core/crypto","docId":"core/crypto","unlisted":false},{"type":"category","label":"Protocols","items":[{"type":"link","label":"Authenticated gRPC","href":"/core/authenticated-grpc","docId":"core/authenticated-grpc","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Merklized Key-Value Store (MKVS)","href":"/core/mkvs","docId":"core/mkvs","unlisted":false}],"collapsed":false,"href":"/core/common-functionality"},{"type":"category","label":"Processes","collapsible":false,"items":[{"type":"link","label":"Release Process","href":"/core/release-process","docId":"core/release-process","unlisted":false},{"type":"link","label":"Versioning","href":"/core/versioning","docId":"core/versioning","unlisted":false},{"type":"link","label":"Security","href":"/core/SECURITY","docId":"core/SECURITY","unlisted":false}],"collapsed":false,"href":"/core/processes"},{"type":"link","label":"ADRs","href":"/adrs"},{"type":"link","label":"Core Client TypeScript API","href":"https://api.docs.oasis.io/js/client"},{"type":"link","label":"Core Client Go API","href":"https://pkg.go.dev/github.com/oasisprotocol/oasis-core/go"}],"developers":[{"type":"link","label":"Overview","href":"/dapp/","docId":"dapp/README","unlisted":false},{"type":"category","label":"Sapphire","items":[{"type":"link","label":"Quickstart","href":"/dapp/sapphire/quickstart","docId":"dapp/sapphire/quickstart","unlisted":false},{"type":"link","label":"Guide","href":"/dapp/sapphire/guide","docId":"dapp/sapphire/guide","unlisted":false},{"type":"link","label":"Browser Support","href":"/dapp/sapphire/browser","docId":"dapp/sapphire/browser","unlisted":false},{"type":"link","label":"View-Call Authentication","href":"/dapp/sapphire/authentication","docId":"dapp/sapphire/authentication","unlisted":false},{"type":"link","label":"Gasless Transactions","href":"/dapp/sapphire/gasless","docId":"dapp/sapphire/gasless","unlisted":false},{"type":"link","label":"Contract Addresses and Deployments","href":"/dapp/sapphire/addresses","docId":"dapp/sapphire/addresses","unlisted":false},{"type":"link","label":"Deployment Patterns","href":"/dapp/sapphire/deployment","docId":"dapp/sapphire/deployment","unlisted":false},{"type":"link","label":"Security","href":"/dapp/sapphire/security","docId":"dapp/sapphire/security","unlisted":false},{"type":"link","label":"TypeScript API","href":"https://api.docs.oasis.io/js/sapphire-paratime"},{"type":"link","label":"Solidity API","href":"https://api.docs.oasis.io/sol/sapphire-contracts"}],"collapsed":true,"collapsible":true,"href":"/dapp/sapphire/"},{"type":"category","label":"Oasis Privacy Layer","items":[{"type":"link","label":"Overview","href":"/dapp/opl/introduction","docId":"dapp/opl/introduction","unlisted":false},{"type":"link","label":"Setup","href":"/dapp/opl/setup","docId":"dapp/opl/setup","unlisted":false},{"type":"link","label":"DAO Contract","href":"/dapp/opl/host","docId":"dapp/opl/host","unlisted":false},{"type":"link","label":"Ballot Contract","href":"/dapp/opl/enclave","docId":"dapp/opl/enclave","unlisted":false},{"type":"link","label":"Build","href":"/dapp/opl/build","docId":"dapp/opl/build","unlisted":false},{"type":"link","label":"Frontend Application","href":"/dapp/opl/frontend","docId":"dapp/opl/frontend","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/dapp/opl/"},{"type":"category","label":"Cipher","items":[{"type":"link","label":"Prerequisites","href":"/dapp/cipher/prerequisites","docId":"dapp/cipher/prerequisites","unlisted":false},{"type":"link","label":"Hello World","href":"/dapp/cipher/hello-world","docId":"dapp/cipher/hello-world","unlisted":false},{"type":"link","label":"Confidential Hello World","href":"/dapp/cipher/confidential-smart-contract","docId":"dapp/cipher/confidential-smart-contract","unlisted":false},{"type":"link","label":"Rust API","href":"https://api.docs.oasis.io/rust/oasis_contract_sdk"}],"collapsed":true,"collapsible":true,"href":"/dapp/cipher/"},{"type":"category","label":"Emerald","items":[{"type":"link","label":"Writing dApps on Emerald","href":"/dapp/emerald/writing-dapps-on-emerald","docId":"dapp/emerald/writing-dapps-on-emerald","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/dapp/emerald/"},{"type":"category","label":"Tools & Services","items":[{"type":"link","label":"Integrating BAND Oracle","href":"/dapp/tools/band","docId":"dapp/tools/band","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/dapp/tools/"}],"general":[{"type":"link","label":"Overview","href":"/general/","docId":"general/README","unlisted":false},{"type":"category","label":"Oasis Network","collapsible":false,"items":[{"type":"link","label":"Why Oasis?","href":"/general/oasis-network/why-oasis","docId":"general/oasis-network/why-oasis","unlisted":false},{"type":"link","label":"Token Metrics and Distribution","href":"/general/oasis-network/token-metrics-and-distribution","docId":"general/oasis-network/token-metrics-and-distribution","unlisted":false},{"type":"link","label":"Papers","href":"https://oasisprotocol.org/papers"},{"type":"link","label":"Frequently Asked Questions","href":"/general/oasis-network/faq","docId":"general/oasis-network/faq","unlisted":false}],"collapsed":false,"href":"/general/oasis-network/"},{"type":"category","label":"Manage your Tokens","collapsible":false,"items":[{"type":"link","label":"Terminology","href":"/general/manage-tokens/terminology","docId":"general/manage-tokens/terminology","unlisted":false},{"type":"link","label":"Staking and Delegating","href":"/general/manage-tokens/staking-and-delegating","docId":"general/manage-tokens/staking-and-delegating","unlisted":false},{"type":"category","label":"ROSE Wallet","items":[{"type":"link","label":"Web","href":"/general/manage-tokens/oasis-wallets/web","docId":"general/manage-tokens/oasis-wallets/web","unlisted":false},{"type":"link","label":"Browser Extension","href":"/general/manage-tokens/oasis-wallets/browser-extension","docId":"general/manage-tokens/oasis-wallets/browser-extension","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/general/manage-tokens/oasis-wallets"},{"type":"category","label":"3rd Party Wallets and Services","items":[{"type":"link","label":"Custody Providers & Protocols","href":"/general/manage-tokens/holding-rose-tokens/custody-providers","docId":"general/manage-tokens/holding-rose-tokens/custody-providers","unlisted":false},{"type":"link","label":"Ledger Hardware Wallet","href":"/general/manage-tokens/holding-rose-tokens/ledger-wallet","docId":"general/manage-tokens/holding-rose-tokens/ledger-wallet","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/general/manage-tokens/holding-rose-tokens"},{"type":"link","label":"How to Transfer ETH/ERC20 to Emerald ParaTime","href":"/general/manage-tokens/how-to-transfer-eth-erc20-to-emerald-paratime","docId":"general/manage-tokens/how-to-transfer-eth-erc20-to-emerald-paratime","unlisted":false},{"type":"category","label":"Oasis CLI","items":[{"type":"link","label":"Setup","href":"/general/manage-tokens/cli/setup","docId":"general/manage-tokens/cli/setup","unlisted":false},{"type":"link","label":"Network","href":"/general/manage-tokens/cli/network","docId":"general/manage-tokens/cli/network","unlisted":false},{"type":"link","label":"ParaTime","href":"/general/manage-tokens/cli/paratime","docId":"general/manage-tokens/cli/paratime","unlisted":false},{"type":"link","label":"Wallet","href":"/general/manage-tokens/cli/wallet","docId":"general/manage-tokens/cli/wallet","unlisted":false},{"type":"link","label":"Account","href":"/general/manage-tokens/cli/account","docId":"general/manage-tokens/cli/account","unlisted":false},{"type":"link","label":"Transaction","href":"/general/manage-tokens/cli/transaction","docId":"general/manage-tokens/cli/transaction","unlisted":false},{"type":"link","label":"Address book","href":"/general/manage-tokens/cli/addressbook","docId":"general/manage-tokens/cli/addressbook","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/general/manage-tokens/cli/"},{"type":"link","label":"Frequently Asked Questions","href":"/general/manage-tokens/faq","docId":"general/manage-tokens/faq","unlisted":false}],"collapsed":false,"href":"/general/manage-tokens/"}],"getInvolved":[{"type":"link","label":"Join our Community","href":"/get-involved/","docId":"get-involved/README","unlisted":false},{"type":"link","label":"Become our Ambassador","href":"https://oasisprotocol.org/ambassador-program"},{"type":"link","label":"Become our Influencer","href":"https://oasisprotocol.org/influencer"},{"type":"link","label":"Apply for Grant","href":"https://oasisprotocol.org/grant-programs"},{"type":"link","label":"Join our University Program","href":"https://oasisprotocol.org/university-program"},{"type":"link","label":"Follow Community Portal","href":"https://oasisrose.garden"},{"type":"category","label":"Run a Node","collapsible":false,"items":[{"type":"link","label":"Consensus Validator Node","href":"/get-involved/run-node/validator-node","docId":"get-involved/run-node/validator-node","unlisted":false},{"type":"link","label":"ParaTime Node","href":"/get-involved/run-node/paratime-node","docId":"get-involved/run-node/paratime-node","unlisted":false}],"collapsed":false,"href":"/get-involved/run-node"},{"type":"link","label":"Develop Oasis Core","href":"/get-involved/oasis-core","docId":"get-involved/oasis-core","unlisted":false},{"type":"link","label":"Network Governance","href":"/get-involved/network-governance","docId":"get-involved/network-governance","unlisted":false},{"type":"link","label":"Delegation Policy","href":"/get-involved/delegation-policy","docId":"get-involved/delegation-policy","unlisted":false},{"type":"link","label":"Token Delivery & KYC Guide","href":"/get-involved/token-delivery-and-kyc","docId":"get-involved/token-delivery-and-kyc","unlisted":false}],"operators":[{"type":"link","label":"Overview","href":"/node/","docId":"node/README","unlisted":false},{"type":"category","label":"Mainnet","collapsible":false,"items":[{"type":"link","label":"Eden Upgrade","href":"/node/mainnet/eden-upgrade","docId":"node/mainnet/eden-upgrade","unlisted":false},{"type":"category","label":"Previous Upgrades","items":[{"type":"link","label":"Damask Upgrade","href":"/node/mainnet/previous-upgrades/damask-upgrade","docId":"node/mainnet/previous-upgrades/damask-upgrade","unlisted":false},{"type":"link","label":"Cobalt Upgrade","href":"/node/mainnet/previous-upgrades/cobalt-upgrade","docId":"node/mainnet/previous-upgrades/cobalt-upgrade","unlisted":false},{"type":"link","label":"Upgrade to Mainnet","href":"/node/mainnet/previous-upgrades/mainnet-upgrade","docId":"node/mainnet/previous-upgrades/mainnet-upgrade","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/node/mainnet/previous-upgrades"},{"type":"link","label":"Upgrade Log","href":"/node/mainnet/upgrade-log","docId":"node/mainnet/upgrade-log","unlisted":false}],"collapsed":false,"href":"/node/mainnet/"},{"type":"category","label":"Testnet","collapsible":false,"items":[{"type":"link","label":"Upgrade Log","href":"/node/testnet/upgrade-log","docId":"node/testnet/upgrade-log","unlisted":false}],"collapsed":false,"href":"/node/testnet/"},{"type":"link","label":"Genesis Document","href":"/node/genesis-doc","docId":"node/genesis-doc","unlisted":false},{"type":"category","label":"Run Your Node","collapsible":false,"items":[{"type":"category","label":"Prerequisites","items":[{"type":"link","label":"Hardware Requirements","href":"/node/run-your-node/prerequisites/hardware-recommendations","docId":"node/run-your-node/prerequisites/hardware-recommendations","unlisted":false},{"type":"link","label":"Stake Requirements","href":"/node/run-your-node/prerequisites/stake-requirements","docId":"node/run-your-node/prerequisites/stake-requirements","unlisted":false},{"type":"link","label":"Install the Oasis Node","href":"/node/run-your-node/prerequisites/oasis-node","docId":"node/run-your-node/prerequisites/oasis-node","unlisted":false},{"type":"link","label":"System Configuration","href":"/node/run-your-node/prerequisites/system-configuration","docId":"node/run-your-node/prerequisites/system-configuration","unlisted":false},{"type":"link","label":"Set up Trusted Execution Environment (TEE)","href":"/node/run-your-node/prerequisites/set-up-trusted-execution-environment-tee","docId":"node/run-your-node/prerequisites/set-up-trusted-execution-environment-tee","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/node/run-your-node/prerequisites"},{"type":"link","label":"Validator Node","href":"/node/run-your-node/validator-node","docId":"node/run-your-node/validator-node","unlisted":false},{"type":"link","label":"Non-validator Node","href":"/node/run-your-node/non-validator-node","docId":"node/run-your-node/non-validator-node","unlisted":false},{"type":"link","label":"Seed Node","href":"/node/run-your-node/seed-node","docId":"node/run-your-node/seed-node","unlisted":false},{"type":"link","label":"Archive Node","href":"/node/run-your-node/archive-node","docId":"node/run-your-node/archive-node","unlisted":false},{"type":"link","label":"ParaTime Node","href":"/node/run-your-node/paratime-node","docId":"node/run-your-node/paratime-node","unlisted":false},{"type":"link","label":"ParaTime Client Node","href":"/node/run-your-node/paratime-client-node","docId":"node/run-your-node/paratime-client-node","unlisted":false},{"type":"category","label":"Key Manager Node","items":[{"type":"link","label":"Signing Key Manager Policy","href":"/node/run-your-node/keymanager-node/signing-key-manager-policy","docId":"node/run-your-node/keymanager-node/signing-key-manager-policy","unlisted":false},{"type":"link","label":"Upgrading Key Managers","href":"/node/run-your-node/keymanager-node/key-manager-upgrade","docId":"node/run-your-node/keymanager-node/key-manager-upgrade","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/node/run-your-node/keymanager-node/"},{"type":"link","label":"IAS Proxy","href":"/node/run-your-node/ias-proxy","docId":"node/run-your-node/ias-proxy","unlisted":false},{"type":"link","label":"Sentry Node","href":"/node/run-your-node/sentry-node","docId":"node/run-your-node/sentry-node","unlisted":false},{"type":"category","label":"Maintenance","items":[{"type":"link","label":"Wiping Node State","href":"/node/run-your-node/maintenance/wiping-node-state","docId":"node/run-your-node/maintenance/wiping-node-state","unlisted":false},{"type":"link","label":"Handling Network Upgrades","href":"/node/run-your-node/maintenance/handling-network-upgrades","docId":"node/run-your-node/maintenance/handling-network-upgrades","unlisted":false},{"type":"link","label":"Adding or Removing Nodes","href":"/node/run-your-node/maintenance/adding-or-removing-nodes","docId":"node/run-your-node/maintenance/adding-or-removing-nodes","unlisted":false},{"type":"link","label":"Refreshing Node Certificates","href":"/node/run-your-node/maintenance/refreshing-certificates","docId":"node/run-your-node/maintenance/refreshing-certificates","unlisted":false},{"type":"link","label":"Shutting Down a Node","href":"/node/run-your-node/maintenance/shutting-down-a-node","docId":"node/run-your-node/maintenance/shutting-down-a-node","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/node/run-your-node/maintenance"},{"type":"category","label":"Advanced","items":[{"type":"link","label":"Using State Sync for Quick Bootstraping","href":"/node/run-your-node/advanced/sync-node-using-state-sync","docId":"node/run-your-node/advanced/sync-node-using-state-sync","unlisted":false},{"type":"link","label":"Copy State from One Node to the Other","href":"/node/run-your-node/advanced/copy-state-from-one-node-to-the-other","docId":"node/run-your-node/advanced/copy-state-from-one-node-to-the-other","unlisted":false},{"type":"link","label":"Remote Signer for Oasis Node Keys","href":"/node/run-your-node/advanced/remote-signer","docId":"node/run-your-node/advanced/remote-signer","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/node/run-your-node/advanced"},{"type":"link","label":"Troubleshooting","href":"/node/run-your-node/troubleshooting","docId":"node/run-your-node/troubleshooting","unlisted":false}],"collapsed":false,"href":"/node/run-your-node/"},{"type":"link","label":"Web3 Gateway","href":"/node/web3","docId":"node/web3","unlisted":false},{"type":"link","label":"gRPC Proxy","href":"/node/grpc","docId":"node/grpc","unlisted":false}],"paratime":[{"type":"link","label":"Overview","href":"/paratime/","docId":"paratime/README","unlisted":false},{"type":"link","label":"Prerequisites","href":"/paratime/prerequisites","docId":"paratime/prerequisites","unlisted":false},{"type":"link","label":"Minimal Runtime","href":"/paratime/minimal-runtime","docId":"paratime/minimal-runtime","unlisted":false},{"type":"link","label":"Modules","href":"/paratime/modules","docId":"paratime/modules","unlisted":false},{"type":"link","label":"Reproducibility","href":"/paratime/reproducibility","docId":"paratime/reproducibility","unlisted":false},{"type":"link","label":"ParaTime Client TypeScript API","href":"https://api.docs.oasis.io/js/client-rt"},{"type":"link","label":"ParaTime Client Go API","href":"https://pkg.go.dev/github.com/oasisprotocol/oasis-sdk/client-sdk/go/client"},{"type":"link","label":"ParaTime SDK Rust API","href":"https://api.docs.oasis.io/rust/oasis_runtime_sdk"}],"rofl":[{"type":"link","label":"Overview","href":"/rofl/","docId":"rofl/README","unlisted":false},{"type":"link","label":"Prerequisites","href":"/rofl/prerequisites","docId":"rofl/prerequisites","unlisted":false},{"type":"link","label":"Application","href":"/rofl/app","docId":"rofl/app","unlisted":false},{"type":"link","label":"Consensus Trust Root","href":"/rofl/trust-root","docId":"rofl/trust-root","unlisted":false}]},"docs":{"adrs/0001-tm-multi-root-apphash":{"id":"adrs/0001-tm-multi-root-apphash","title":"ADR 0001: Multiple Roots Under the Tendermint Application Hash","description":"Component","sidebar":"adrs"},"adrs/0002-go-modules-compatible-git-tags":{"id":"adrs/0002-go-modules-compatible-git-tags","title":"ADR 0002: Go Modules Compatible Git Tags","description":"Component","sidebar":"adrs"},"adrs/0003-consensus-runtime-token-transfer":{"id":"adrs/0003-consensus-runtime-token-transfer","title":"ADR 0003: Consensus/Runtime Token Transfer","description":"Component","sidebar":"adrs"},"adrs/0004-runtime-governance":{"id":"adrs/0004-runtime-governance","title":"ADR 0004: Runtime Governance","description":"Component","sidebar":"adrs"},"adrs/0005-runtime-compute-slashing":{"id":"adrs/0005-runtime-compute-slashing","title":"ADR 0005: Runtime Compute Node Slashing","description":"Component","sidebar":"adrs"},"adrs/0006-consensus-governance":{"id":"adrs/0006-consensus-governance","title":"ADR 0006: Consensus Governance","description":"Component","sidebar":"adrs"},"adrs/0007-improved-random-beacon":{"id":"adrs/0007-improved-random-beacon","title":"ADR 0007: Improved Random Beacon","description":"Component","sidebar":"adrs"},"adrs/0008-standard-account-key-generation":{"id":"adrs/0008-standard-account-key-generation","title":"ADR 0008: Standard Account Key Generation","description":"Component","sidebar":"adrs"},"adrs/0009-ed25519-semantics":{"id":"adrs/0009-ed25519-semantics","title":"ADR 0009: Ed25519 Signature Verification Semantics","description":"Component","sidebar":"adrs"},"adrs/0010-vrf-elections":{"id":"adrs/0010-vrf-elections","title":"ADR 0010: VRF-based Committee Elections","description":"Component","sidebar":"adrs"},"adrs/0011-incoming-runtime-messages":{"id":"adrs/0011-incoming-runtime-messages","title":"ADR 0011: Incoming Runtime Messages","description":"Component","sidebar":"adrs"},"adrs/0012-runtime-message-results":{"id":"adrs/0012-runtime-message-results","title":"ADR 0012: Runtime Message Results","description":"Component","sidebar":"adrs"},"adrs/0013-runtime-upgrades":{"id":"adrs/0013-runtime-upgrades","title":"ADR 0013: Runtime Upgrade Improvements","description":"Component","sidebar":"adrs"},"adrs/0014-runtime-signing-tx-with-hardware-wallet":{"id":"adrs/0014-runtime-signing-tx-with-hardware-wallet","title":"ADR 0014: Signing Runtime Transactions with Hardware Wallet","description":"Component","sidebar":"adrs"},"adrs/0015-vrf-per-block-entropy":{"id":"adrs/0015-vrf-per-block-entropy","title":"ADR 0015: Randomized Paratime Proposer Selection","description":"Component","sidebar":"adrs"},"adrs/0016-consensus-parameters-change-proposal":{"id":"adrs/0016-consensus-parameters-change-proposal","title":"ADR 0016: Consensus Parameters Change Proposal","description":"Component","sidebar":"adrs"},"adrs/0017-app-standards":{"id":"adrs/0017-app-standards","title":"ADR 0017: ParaTime Application Standard Proposal Process","description":"Component","sidebar":"adrs"},"adrs/0020-governance-delegator-votes":{"id":"adrs/0020-governance-delegator-votes","title":"ADR 0020: Governance Support for Delegator Votes","description":"Component","sidebar":"adrs"},"adrs/0021-keymanager-ephemeral-secrets":{"id":"adrs/0021-keymanager-ephemeral-secrets","title":"ADR 0021: Forward-Secret Ephemeral Secrets","description":"Component","sidebar":"adrs"},"adrs/0022-keymanager-master-secrets":{"id":"adrs/0022-keymanager-master-secrets","title":"ADR 0022: Forward-Secret Master Secrets","description":"Component","sidebar":"adrs"},"adrs/0024-off-chain-runtime-logic":{"id":"adrs/0024-off-chain-runtime-logic","title":"ADR 0024: Runtime Off-chain Logic (ROFL)","description":"Component","sidebar":"adrs"},"core/authenticated-grpc":{"id":"core/authenticated-grpc","title":"Authenticated gRPC","description":"Oasis Core nodes communicate between themselves over various protocols. One of","sidebar":"oasisCore"},"core/bigint":{"id":"core/bigint","title":"Big Integer Quantities","description":"Arbitrary-precision positive integer quantities are represented by the"},"core/consensus/genesis":{"id":"core/consensus/genesis","title":"Genesis Document","description":"The genesis document contains a set of parameters that outline the initial state","sidebar":"oasisCore"},"core/consensus/README":{"id":"core/consensus/README","title":"Consensus Layer","description":"Oasis Core is designed around the principle of modularity. The consensus layer","sidebar":"oasisCore"},"core/consensus/services/beacon":{"id":"core/consensus/services/beacon","title":"Random Beacon","description":"The random beacon service is responsible for providing a source of unbiased","sidebar":"oasisCore"},"core/consensus/services/epochtime":{"id":"core/consensus/services/epochtime","title":"Epoch Time","description":"","sidebar":"oasisCore"},"core/consensus/services/governance":{"id":"core/consensus/services/governance","title":"Governance","description":"The governance service is responsible for providing an on-chain governance","sidebar":"oasisCore"},"core/consensus/services/keymanager":{"id":"core/consensus/services/keymanager","title":"Key Manager","description":"The key manager service is responsible for coordinating the SGX-based key","sidebar":"oasisCore"},"core/consensus/services/registry":{"id":"core/consensus/services/registry","title":"Registry","description":"The registry service is responsible for managing a registry of runtime, entity","sidebar":"oasisCore"},"core/consensus/services/roothash":{"id":"core/consensus/services/roothash","title":"Root Hash","description":"The roothash service is responsible for runtime commitment processing and","sidebar":"oasisCore"},"core/consensus/services/scheduler":{"id":"core/consensus/services/scheduler","title":"Committee Scheduler","description":"The committee scheduler service is responsible for periodically scheduling all","sidebar":"oasisCore"},"core/consensus/services/staking":{"id":"core/consensus/services/staking","title":"Staking","description":"The staking service is responsible for managing the staking ledger in the","sidebar":"oasisCore"},"core/consensus/test-vectors":{"id":"core/consensus/test-vectors","title":"Transaction Test Vectors","description":"In order to test transaction generation, parsing and signing, we provide a set","sidebar":"oasisCore"},"core/consensus/transactions":{"id":"core/consensus/transactions","title":"Transactions","description":"The consensus layer uses a common transaction format for all transactions. As","sidebar":"oasisCore"},"core/crypto":{"id":"core/crypto","title":"Cryptography","description":"Hash Functions","sidebar":"oasisCore"},"core/development-setup/building":{"id":"core/development-setup/building","title":"Building","description":"This chapter contains a description of steps required to build Oasis Core.","sidebar":"oasisCore"},"core/development-setup/deploying-a-runtime":{"id":"core/development-setup/deploying-a-runtime","title":"Deploying a Runtime","description":"Before proceeding, make sure to look at the [prerequisites] required for running","sidebar":"oasisCore"},"core/development-setup/oasis-net-runner":{"id":"core/development-setup/oasis-net-runner","title":"Local Network Runner","description":"In order to make development easier (and also to facilitate automated E2E","sidebar":"oasisCore"},"core/development-setup/prerequisites":{"id":"core/development-setup/prerequisites","title":"Prerequisites","description":"The following is a list of prerequisites required to start developing on Oasis","sidebar":"oasisCore"},"core/development-setup/running-tests":{"id":"core/development-setup/running-tests","title":"Running Tests","description":"Before proceeding, make sure to look at the [prerequisites] required for running","sidebar":"oasisCore"},"core/development-setup/single-validator-node-network":{"id":"core/development-setup/single-validator-node-network","title":"Single Validator Node Network","description":"It is possible to provision a local \\"network\\" consisting of a single validator","sidebar":"oasisCore"},"core/encoding":{"id":"core/encoding","title":"Encoding","description":"All messages exchanged by different components in Oasis Core are encoded using","sidebar":"oasisCore"},"core/mkvs":{"id":"core/mkvs","title":"Merklized Key-Value Store (MKVS)","description":"For all places that require an [authenticated data structure (ADS)] we provide","sidebar":"oasisCore"},"core/oasis-node/cli":{"id":"core/oasis-node/cli","title":"oasis-node CLI","description":"control","sidebar":"oasisCore"},"core/oasis-node/metrics":{"id":"core/oasis-node/metrics","title":"Metrics","description":"oasis-node can report a number of metrics to Prometheus server. By default,","sidebar":"oasisCore"},"core/oasis-node/rpc":{"id":"core/oasis-node/rpc","title":"RPC","description":"Oasis Node exposes an RPC interface to enable external applications to query","sidebar":"oasisCore"},"core/README":{"id":"core/README","title":"Oasis Core Developer Documentation","description":"Architecture","sidebar":"oasisCore"},"core/release-process":{"id":"core/release-process","title":"Release Process","description":"The following steps should be followed when preparing a release.","sidebar":"oasisCore"},"core/runtime/identifiers":{"id":"core/runtime/identifiers","title":"Runtime IDs","description":"Identifiers for runtimes are represented by the [common.Namespace] type.","sidebar":"oasisCore"},"core/runtime/messages":{"id":"core/runtime/messages","title":"Runtime Messages","description":"In order to enable runtimes to perform actions in the consensus layer on their","sidebar":"oasisCore"},"core/runtime/README":{"id":"core/runtime/README","title":"Runtime Layer","description":"Runtime Layer","sidebar":"oasisCore"},"core/runtime/runtime-host-protocol":{"id":"core/runtime/runtime-host-protocol","title":"Runtime Host Protocol","description":"The Runtime Host Protocol (RHP) is a simple RPC protocol which is used to","sidebar":"oasisCore"},"core/SECURITY":{"id":"core/SECURITY","title":"Security","description":"At [Oasis Foundation], we take security very seriously and we deeply appreciate","sidebar":"oasisCore"},"core/versioning":{"id":"core/versioning","title":"Versioning","description":"Oasis Core","sidebar":"oasisCore"},"dapp/cipher/confidential-smart-contract":{"id":"dapp/cipher/confidential-smart-contract","title":"Confidential Hello World","description":"Confidential smart contract execution on Oasis is assured by three mechanisms:","sidebar":"developers"},"dapp/cipher/hello-world":{"id":"dapp/cipher/hello-world","title":"Hello World","description":"This chapter will show you how to quickly create, build and test a minimal","sidebar":"developers"},"dapp/cipher/prerequisites":{"id":"dapp/cipher/prerequisites","title":"Prerequisites","description":"How to build your first smart contract on Oasis","sidebar":"developers"},"dapp/cipher/README":{"id":"dapp/cipher/README","title":"Cipher ParaTime","description":"Cipher is a confidential ParaTime for executing Wasm smart contracts.","sidebar":"developers"},"dapp/emerald/README":{"id":"dapp/emerald/README","title":"Emerald ParaTime","description":"Emerald is our official ParaTime which executes smart contracts inside the","sidebar":"developers"},"dapp/emerald/writing-dapps-on-emerald":{"id":"dapp/emerald/writing-dapps-on-emerald","title":"Writing dApps on Emerald","description":"This tutorial will show you how to set up dApp development environment for","sidebar":"developers"},"dapp/opl/build":{"id":"dapp/opl/build","title":"Build","description":"Now that we have written our two smart contracts, let\'s compile and deploy them!","sidebar":"developers"},"dapp/opl/enclave":{"id":"dapp/opl/enclave","title":"Ballot Contract","description":"Next, we will write a smart contract that holds private data. This smart","sidebar":"developers"},"dapp/opl/frontend":{"id":"dapp/opl/frontend","title":"Frontend Application","description":"We will need a Pinata development API","sidebar":"developers"},"dapp/opl/host":{"id":"dapp/opl/host","title":"DAO Contract","description":"Let\'s start with a smart contract that describes a basic DAO, DAOV1.sol, with a","sidebar":"developers"},"dapp/opl/introduction":{"id":"dapp/opl/introduction","title":"Overview","description":"How to build your first dApp on OPL","sidebar":"developers"},"dapp/opl/README":{"id":"dapp/opl/README","title":"Oasis Privacy Layer","description":"The Oasis Privacy Layer (OPL) is an EVM-compatible privacy solution that","sidebar":"developers"},"dapp/opl/setup":{"id":"dapp/opl/setup","title":"Setup","description":"Let\'s get started and make our new project. You will need Node.js","sidebar":"developers"},"dapp/README":{"id":"dapp/README","title":"Create dApp","description":"Home of the Oasis dApp developer resources","sidebar":"developers"},"dapp/sapphire/addresses":{"id":"dapp/sapphire/addresses","title":"Contract Addresses and Deployments","description":"List of Standard Contract Addresses","sidebar":"developers"},"dapp/sapphire/authentication":{"id":"dapp/sapphire/authentication","title":"View-Call Authentication","description":"Authenticate users with your confidential contracts","sidebar":"developers"},"dapp/sapphire/browser":{"id":"dapp/sapphire/browser","title":"Browser Support","description":"Writing Sapphire dApp for browser and Metamask","sidebar":"developers"},"dapp/sapphire/deployment":{"id":"dapp/sapphire/deployment","title":"Deployment Patterns","description":"Deploying upgradable and deterministic contracts","sidebar":"developers"},"dapp/sapphire/gasless":{"id":"dapp/sapphire/gasless","title":"Gasless Transactions","description":"Submitting transactions without paying for fees","sidebar":"developers"},"dapp/sapphire/guide":{"id":"dapp/sapphire/guide","title":"Guide","description":"Guide to creating secure dApps on Sapphire","sidebar":"developers"},"dapp/sapphire/quickstart":{"id":"dapp/sapphire/quickstart","title":"Quickstart","description":"In this tutorial, you will build and deploy a unique dApp that requires","sidebar":"developers"},"dapp/sapphire/README":{"id":"dapp/sapphire/README","title":"Sapphire ParaTime","description":"Sapphire is our official confidential ParaTime providing a smart contract","sidebar":"developers"},"dapp/sapphire/security":{"id":"dapp/sapphire/security","title":"Security","description":"Secure dApps: Recipes for Confidentiality","sidebar":"developers"},"dapp/tools/band":{"id":"dapp/tools/band","title":"Integrating BAND Oracle","description":"This guide will explain how to query the Band Protocol reference data smart","sidebar":"developers"},"dapp/tools/README":{"id":"dapp/tools/README","title":"Tools & Services","description":"Oasis integrates with a number of services and provides tooling support for","sidebar":"developers"},"general/manage-tokens/cli/account":{"id":"general/manage-tokens/cli/account","title":"Account","description":"Using CLI for performing account-related tasks","sidebar":"general"},"general/manage-tokens/cli/addressbook":{"id":"general/manage-tokens/cli/addressbook","title":"Address book","description":"Storing your blockchain contacts for future use","sidebar":"general"},"general/manage-tokens/cli/network":{"id":"general/manage-tokens/cli/network","title":"Network","description":"Managing Mainnet, Testnet or Localnet endpoints","sidebar":"general"},"general/manage-tokens/cli/paratime":{"id":"general/manage-tokens/cli/paratime","title":"ParaTime","description":"Managing ParaTimes","sidebar":"general"},"general/manage-tokens/cli/README":{"id":"general/manage-tokens/cli/README","title":"Oasis CLI","description":"Powerful CLI for managing Oasis networks, nodes, tokens and dApps","sidebar":"general"},"general/manage-tokens/cli/setup":{"id":"general/manage-tokens/cli/setup","title":"Setup","description":"Download and Run","sidebar":"general"},"general/manage-tokens/cli/transaction":{"id":"general/manage-tokens/cli/transaction","title":"Transaction","description":"Use CLI to decode, verify, sign and submit a transaction","sidebar":"general"},"general/manage-tokens/cli/wallet":{"id":"general/manage-tokens/cli/wallet","title":"Wallet","description":"Manage accounts in your CLI wallet","sidebar":"general"},"general/manage-tokens/faq":{"id":"general/manage-tokens/faq","title":"Frequently Asked Questions","description":"This documents answers frequently asked questions about the official Oasis and","sidebar":"general"},"general/manage-tokens/holding-rose-tokens/custody-providers":{"id":"general/manage-tokens/holding-rose-tokens/custody-providers","title":"Custody Providers & Protocols","description":"Not comfortable keeping the keys on your own?","sidebar":"general"},"general/manage-tokens/holding-rose-tokens/ledger-wallet":{"id":"general/manage-tokens/holding-rose-tokens/ledger-wallet","title":"Ledger Hardware Wallet","description":"How to setup your Ledger hardware wallet","sidebar":"general"},"general/manage-tokens/how-to-transfer-eth-erc20-to-emerald-paratime":{"id":"general/manage-tokens/how-to-transfer-eth-erc20-to-emerald-paratime","title":"How to Transfer ETH/ERC20 to Emerald ParaTime","description":"This guide will walk you through bringing your assets, i.e. ETH, USDC, USDT,","sidebar":"general"},"general/manage-tokens/oasis-wallets/browser-extension":{"id":"general/manage-tokens/oasis-wallets/browser-extension","title":"ROSE Wallet - Browser Extension","description":"The Oasis Foundation-managed non-custodial browser extension wallet","sidebar":"general"},"general/manage-tokens/oasis-wallets/web":{"id":"general/manage-tokens/oasis-wallets/web","title":"ROSE Wallet - Web","description":"The Oasis Foundation-managed non-custodial web wallet","sidebar":"general"},"general/manage-tokens/README":{"id":"general/manage-tokens/README","title":"Manage your Tokens","description":"Transfer, deposit, withdraw and delegate your ROSE","sidebar":"general"},"general/manage-tokens/staking-and-delegating":{"id":"general/manage-tokens/staking-and-delegating","title":"Staking and Delegating","description":"The Oasis Network is a proof-of-stake network. This means that the voting","sidebar":"general"},"general/manage-tokens/terminology":{"id":"general/manage-tokens/terminology","title":"Terminology","description":"Account","sidebar":"general"},"general/oasis-network/faq":{"id":"general/oasis-network/faq","title":"Frequently Asked Questions","description":"This page tries to answer some of the most frequently asked questions about the","sidebar":"general"},"general/oasis-network/README":{"id":"general/oasis-network/README","title":"Oasis Network","description":"The Oasis Network is a Layer 1 decentralized blockchain network designed to be uniquely scalable, privacy-first and versatile.","sidebar":"general"},"general/oasis-network/token-metrics-and-distribution":{"id":"general/oasis-network/token-metrics-and-distribution","title":"Token Metrics and Distribution","description":"Background illustration","sidebar":"general"},"general/oasis-network/why-oasis":{"id":"general/oasis-network/why-oasis","title":"Why Oasis?","description":"Network Overview","sidebar":"general"},"general/README":{"id":"general/README","title":"Use Oasis","description":"This chapter provides general overview of the Oasis Network and introduces","sidebar":"general"},"get-involved/delegation-policy":{"id":"get-involved/delegation-policy","title":"Delegation Policy","description":"Oasis Protocol Foundation delegates ROSE tokens to node operators based on their","sidebar":"getInvolved"},"get-involved/network-governance":{"id":"get-involved/network-governance","title":"Network Governance","description":"If you have a general question on how to use and deploy our software, please","sidebar":"getInvolved"},"get-involved/oasis-core":{"id":"get-involved/oasis-core","title":"Develop Oasis Core","description":"This document outlines our guidelines for contributing to the Oasis Network\'s","sidebar":"getInvolved"},"get-involved/README":{"id":"get-involved/README","title":"Join our Community","description":"Welcome to the Oasis Community","sidebar":"getInvolved"},"get-involved/run-node/paratime-node":{"id":"get-involved/run-node/paratime-node","title":"ParaTime Node","description":"This guide provides an overview of the requirements to become a compute node for","sidebar":"getInvolved"},"get-involved/run-node/validator-node":{"id":"get-involved/run-node/validator-node","title":"Consensus Validator Node","description":"This guide provides an overview of the technical setup and stake requirements to","sidebar":"getInvolved"},"get-involved/token-delivery-and-kyc":{"id":"get-involved/token-delivery-and-kyc","title":"Token Delivery & KYC Guide","description":"If you\'re visiting this page, you may have recently earned ROSE tokens via the Community Cup program, the Ambassador Rewards program, or a recent hackathon. Congratulations!","sidebar":"getInvolved"},"node/genesis-doc":{"id":"node/genesis-doc","title":"Genesis Document","description":"A genesis document contains the initial state of an Oasis Network, and all the","sidebar":"operators"},"node/grpc":{"id":"node/grpc","title":"gRPC proxy for your Oasis node","description":"gRPC proxy for Oasis node","sidebar":"operators"},"node/mainnet/eden-upgrade":{"id":"node/mainnet/eden-upgrade","title":"Eden Upgrade","description":"This document provides an overview of the changes for the Eden Mainnet","sidebar":"operators"},"node/mainnet/previous-upgrades/cobalt-upgrade":{"id":"node/mainnet/previous-upgrades/cobalt-upgrade","title":"Cobalt Upgrade","description":"This document provides an overview of the proposed criteria and changes for the Cobalt Mainnet upgrade. This has been reviewed and approved by community members and validators of the Oasis Network and is being reproduced and summarized here for easy access.","sidebar":"operators"},"node/mainnet/previous-upgrades/damask-upgrade":{"id":"node/mainnet/previous-upgrades/damask-upgrade","title":"Damask Upgrade","description":"This document provides an overview of the changes for the Damask Mainnet","sidebar":"operators"},"node/mainnet/previous-upgrades/mainnet-upgrade":{"id":"node/mainnet/previous-upgrades/mainnet-upgrade","title":"Upgrade to Mainnet","description":"This document provides an overview of the proposed criteria and changes to upgrade from Mainnet Beta to Mainnet. This has been reviewed and approved by community members and validators of the Oasis Network and is being reproduced and summarized here for easy access.","sidebar":"operators"},"node/mainnet/README":{"id":"node/mainnet/README","title":"Mainnet","description":"Network Parameters","sidebar":"operators"},"node/mainnet/upgrade-log":{"id":"node/mainnet/upgrade-log","title":"Upgrade Log","description":"For each upgrade of the Oasis Network, we are tracking important changes for","sidebar":"operators"},"node/README":{"id":"node/README","title":"Run Node","description":"Welcome! This documentation is designed to provide you with a comprehensive","sidebar":"operators"},"node/run-your-node/advanced/copy-state-from-one-node-to-the-other":{"id":"node/run-your-node/advanced/copy-state-from-one-node-to-the-other","title":"Copy State from One Node to the Other","description":"A network that\'s been running for some time can accrue significant amount of","sidebar":"operators"},"node/run-your-node/advanced/remote-signer":{"id":"node/run-your-node/advanced/remote-signer","title":"Remote Signer for Oasis Node Keys","description":"The Oasis remote signer is an application that","sidebar":"operators"},"node/run-your-node/advanced/sync-node-using-state-sync":{"id":"node/run-your-node/advanced/sync-node-using-state-sync","title":"Using State Sync for Quick Bootstraping","description":"The State Sync is a way to quickly bootstrap a full Oasis node (either a","sidebar":"operators"},"node/run-your-node/archive-node":{"id":"node/run-your-node/archive-node","title":"Archive Node","description":"This page describes how to run an archive node on the Oasis Network.","sidebar":"operators"},"node/run-your-node/ias-proxy":{"id":"node/run-your-node/ias-proxy","title":"IAS Proxy","description":"This guide will cover setting up an Intel Attestation Service (IAS)","sidebar":"operators"},"node/run-your-node/keymanager-node/key-manager-upgrade":{"id":"node/run-your-node/keymanager-node/key-manager-upgrade","title":"Upgrading Key Managers","description":"This guide will describe how to upgrade a key manager node.","sidebar":"operators"},"node/run-your-node/keymanager-node/README":{"id":"node/run-your-node/keymanager-node/README","title":"Key Manager Node","description":"These instructions are for setting up a key manager node. Key manager nodes run a special runtime that provides confidentiality to other ParaTimes. If you want to run a validator node instead, see the instructions for running a validator node. Similarly, if you want to run a ParaTime node instead, see the instructions for running a ParaTime node.","sidebar":"operators"},"node/run-your-node/keymanager-node/signing-key-manager-policy":{"id":"node/run-your-node/keymanager-node/signing-key-manager-policy","title":"Signing Key Manager Policy","description":"This guide will describe how to print and sign an Oasis [key manager policy].","sidebar":"operators"},"node/run-your-node/maintenance/adding-or-removing-nodes":{"id":"node/run-your-node/maintenance/adding-or-removing-nodes","title":"Adding or Removing Nodes","description":"At some point you may wish to add or remove nodes from your entity. In order to","sidebar":"operators"},"node/run-your-node/maintenance/handling-network-upgrades":{"id":"node/run-your-node/maintenance/handling-network-upgrades","title":"Handling Network Upgrades","description":"Changes between the major consensus network versions are backward and forward","sidebar":"operators"},"node/run-your-node/maintenance/refreshing-certificates":{"id":"node/run-your-node/maintenance/refreshing-certificates","title":"Refreshing Node Certificates","description":"Refreshing Sentry Client TLS Certificate on the Validator Node","sidebar":"operators"},"node/run-your-node/maintenance/shutting-down-a-node":{"id":"node/run-your-node/maintenance/shutting-down-a-node","title":"Shutting Down a Node","description":"When a node registers for an epoch, it is committing to being available","sidebar":"operators"},"node/run-your-node/maintenance/wiping-node-state":{"id":"node/run-your-node/maintenance/wiping-node-state","title":"Wiping Node State","description":"In certain situations, you may need to do a complete node redeployment with a","sidebar":"operators"},"node/run-your-node/non-validator-node":{"id":"node/run-your-node/non-validator-node","title":"Non-validator Node","description":"These instructions are for setting up a non-validator node. If you want to run a validator node instead, see the instructions for running a validator node. Similarly, if you want to run a ParaTime node instead, see the instructions for running a ParaTime node.","sidebar":"operators"},"node/run-your-node/paratime-client-node":{"id":"node/run-your-node/paratime-client-node","title":"ParaTime Client Node","description":"These instructions are for setting up a ParaTime client node which only observes ParaTime activity and can submit transactions. If you want to run a ParaTime node instead, see the instructions for running a ParaTime node. Similarly, if you want to run a validator or a non-validator node instead, see the instructions for running a validator node or instructions for running a non-validator node.","sidebar":"operators"},"node/run-your-node/paratime-node":{"id":"node/run-your-node/paratime-node","title":"ParaTime Node","description":"These instructions are for setting up a ParaTime node which participates in one or more ParaTime compute committees. If you want to run a ParaTime client node instead, see the instructions for running a ParaTime client node. If you want to run a validator node instead, see the instructions for running a validator node. Similarly, if you want to run a non-validator node instead, see the instructions for running a non-validator node.","sidebar":"operators"},"node/run-your-node/prerequisites/hardware-recommendations":{"id":"node/run-your-node/prerequisites/hardware-recommendations","title":"Hardware Requirements","description":"The Oasis Network is composed of multiple classes of nodes and services such","sidebar":"operators"},"node/run-your-node/prerequisites/oasis-node":{"id":"node/run-your-node/prerequisites/oasis-node","title":"Install the Oasis Node","description":"The Oasis node is a binary that is created from the [Oasis Core] repository\'s","sidebar":"operators"},"node/run-your-node/prerequisites/set-up-trusted-execution-environment-tee":{"id":"node/run-your-node/prerequisites/set-up-trusted-execution-environment-tee","title":"Set up Trusted Execution Environment (TEE)","description":"In case the ParaTime you want to run does not require the use of a TEE (e.g.","sidebar":"operators"},"node/run-your-node/prerequisites/stake-requirements":{"id":"node/run-your-node/prerequisites/stake-requirements","title":"Stake Requirements","description":"This page provides an overview of the stake requirements to become a validator","sidebar":"operators"},"node/run-your-node/prerequisites/system-configuration":{"id":"node/run-your-node/prerequisites/system-configuration","title":"System Configuration","description":"This page outlines the modifications necessary that should be made to the","sidebar":"operators"},"node/run-your-node/README":{"id":"node/run-your-node/README","title":"Run your node","description":"The Oasis Network consists of several types of nodes, each serving distinct","sidebar":"operators"},"node/run-your-node/seed-node":{"id":"node/run-your-node/seed-node","title":"Seed Node","description":"This guide will cover setting up a seed node for the Oasis Network. This guide assumes some basic knowledge on the use of command line tools.","sidebar":"operators"},"node/run-your-node/sentry-node":{"id":"node/run-your-node/sentry-node","title":"Sentry Node","description":"This guide provides instructions for a deployment using the Sentry node architecture to protect validator nodes from being directly exposed on the public network.","sidebar":"operators"},"node/run-your-node/troubleshooting":{"id":"node/run-your-node/troubleshooting","title":"Troubleshooting","description":"Before you begin troubleshooting we suggest you check all of the following:","sidebar":"operators"},"node/run-your-node/validator-node":{"id":"node/run-your-node/validator-node","title":"Validator Node","description":"This guide will walk you through the process of setting up your validator","sidebar":"operators"},"node/testnet/README":{"id":"node/testnet/README","title":"Testnet","description":"These are the current parameters for the Testnet, a test-only network for","sidebar":"operators"},"node/testnet/upgrade-log":{"id":"node/testnet/upgrade-log","title":"Upgrade Log","description":"For each upgrade of the Testnet network, we are tracking important changes for","sidebar":"operators"},"node/web3":{"id":"node/web3","title":"Oasis Web3 Gateway for your EVM ParaTime","description":"Web3 gateway for Emerald and Sapphire ParaTimes","sidebar":"operators"},"paratime/minimal-runtime":{"id":"paratime/minimal-runtime","title":"Minimal Runtime","description":"This chapter will show you how to quickly create, build and test a minimal","sidebar":"paratime"},"paratime/modules":{"id":"paratime/modules","title":"Modules","description":"As we saw in the [minimal runtime example], creating an Oasis runtime is very","sidebar":"paratime"},"paratime/prerequisites":{"id":"paratime/prerequisites","title":"Prerequisites","description":"How to build your first runtime","sidebar":"paratime"},"paratime/README":{"id":"paratime/README","title":"Build ParaTime","description":"Build your own ParaTime using Oasis Runtime SDK","sidebar":"paratime"},"paratime/reproducibility":{"id":"paratime/reproducibility","title":"Reproducibility","description":"If you wish to build paratime binaries yourself, you can use the","sidebar":"paratime"},"README":{"id":"README","title":"Getting Started","description":"Use Oasis"},"rofl/app":{"id":"rofl/app","title":"Application","description":"This chapter will show you how to quickly create, build and test a minimal","sidebar":"rofl"},"rofl/prerequisites":{"id":"rofl/prerequisites","title":"Prerequisites","description":"How to build your first ROFL app","sidebar":"rofl"},"rofl/README":{"id":"rofl/README","title":"Build ROFL App","description":"Build your own ROFL app","sidebar":"rofl"},"rofl/trust-root":{"id":"rofl/trust-root","title":"Consensus Trust Root","description":"The [ROFL app example] already contains an embedded root of trust called the","sidebar":"rofl"}}}}')}}]);
\ No newline at end of file
diff --git a/assets/js/6ac8b2ab.8af26dc9.js b/assets/js/6ac8b2ab.8af26dc9.js
new file mode 100644
index 0000000000..1183581108
--- /dev/null
+++ b/assets/js/6ac8b2ab.8af26dc9.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[3132],{2082:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var t=i(4848),s=i(8453);const o={},r="ADR 0009: Ed25519 Signature Verification Semantics",a={id:"adrs/0009-ed25519-semantics",title:"ADR 0009: Ed25519 Signature Verification Semantics",description:"Component",source:"@site/docs/adrs/0009-ed25519-semantics.md",sourceDirName:"adrs",slug:"/adrs/0009-ed25519-semantics",permalink:"/adrs/0009-ed25519-semantics",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/adrs/edit/main/0009-ed25519-semantics.md",tags:[],version:"current",lastUpdatedAt:1710755515e3,frontMatter:{},sidebar:"adrs",previous:{title:"ADR 0008: Standard Account Key Generation",permalink:"/adrs/0008-standard-account-key-generation"},next:{title:"ADR 0010: VRF-based Committee Elections",permalink:"/adrs/0010-vrf-elections"}},c={},l=[{value:"Component",id:"component",level:2},{value:"Changelog",id:"changelog",level:2},{value:"Status",id:"status",level:2},{value:"Context",id:"context",level:2},{value:"Decision",id:"decision",level:2},{value:"Reject Non-canonical s",id:"reject-non-canonical-s",level:3},{value:"Reject Small Order A/R",id:"reject-small-order-ar",level:3},{value:"Accept Non-canonical A/R",id:"accept-non-canonical-ar",level:3},{value:"Cofactored Verification Equation",id:"cofactored-verification-equation",level:3},{value:"Accept A/R With Non-zero Torsion",id:"accept-ar-with-non-zero-torsion",level:3},{value:"Consequences",id:"consequences",level:2},{value:"Positive",id:"positive",level:3},{value:"Negative",id:"negative",level:3},{value:"Neutral",id:"neutral",level:3},{value:"Future Improvements",id:"future-improvements",level:3},{value:"Recomendations For Future Projects",id:"recomendations-for-future-projects",level:2},{value:"References",id:"references",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"adr-0009-ed25519-signature-verification-semantics",children:"ADR 0009: Ed25519 Signature Verification Semantics"}),"\n",(0,t.jsx)(n.h2,{id:"component",children:"Component"}),"\n",(0,t.jsx)(n.p,{children:"Oasis Core"}),"\n",(0,t.jsx)(n.h2,{id:"changelog",children:"Changelog"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"2021-05-10: Initial version"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"status",children:"Status"}),"\n",(0,t.jsx)(n.p,{children:"Informative"}),"\n",(0,t.jsx)(n.h2,{id:"context",children:"Context"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"In programming, it's often the buts in the specification that kill you."}),"\n",(0,t.jsx)(n.p,{children:"-- Boris Beizer"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:'For a large host of reasons, mostly historical, there are numerous definitions\nof "Ed25519 signature validation" in the wild, which have the potential to\nbe mutually incompatible. This ADR serves to provide a rough high-level\noverview of the issue, and to document the current definition of "Ed25519\nsignature verification" as used by Oasis Core.'}),"\n",(0,t.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,t.jsx)(n.p,{children:"The Oasis Core consensus layer (and all of the Go components) currently uses\nthe following Ed25519 verification semantics."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Non-canonical s is rejected (MUST enforce ",(0,t.jsx)(n.code,{children:"s < L"}),")"]}),"\n",(0,t.jsx)(n.li,{children:"Small order A/R are rejected"}),"\n",(0,t.jsx)(n.li,{children:"Non-canonical A/R are accepted"}),"\n",(0,t.jsxs)(n.li,{children:["The cofactored verification equation MUST be used (",(0,t.jsx)(n.code,{children:"[8][S]B = [8]R + [8][k]A"}),")"]}),"\n",(0,t.jsx)(n.li,{children:"A/R may have a non-zero torsion component."}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"reject-non-canonical-s",children:"Reject Non-canonical s"}),"\n",(0,t.jsxs)(n.p,{children:["Ed25519 signatures are trivially malleable unless the scalar component is\nconstrained to ",(0,t.jsx)(n.code,{children:"0 <= s < L"}),", as is possible to create valid signatures\nfrom an existing public key/message/signature tuple by adding L to s."]}),"\n",(0,t.jsx)(n.p,{children:"This check is mandated in all recent formulations of Ed25519 including\nbut not limited to RFC 8032 and FIPS 186-5, and most modern implementations\nwill include this check."}),"\n",(0,t.jsxs)(n.p,{children:["Note: Only asserting that ",(0,t.jsx)(n.code,{children:"s[31] & 224 == 0"})," as done in older implementations\nis insufficient."]}),"\n",(0,t.jsx)(n.h3,{id:"reject-small-order-ar",children:"Reject Small Order A/R"}),"\n",(0,t.jsx)(n.p,{children:"Rejecting small order A is required to make the signature scheme strongly\nbinding (resilience to key/message substitution attacks)."}),"\n",(0,t.jsx)(n.p,{children:"Rejecting (or accepting) small order R is not believed to have a security\nimpact."}),"\n",(0,t.jsx)(n.h3,{id:"accept-non-canonical-ar",children:"Accept Non-canonical A/R"}),"\n",(0,t.jsx)(n.p,{children:"The discrete logarithm of the Ed25519 points that have a valid non-canonical\nencoding and are not small order is unknown, and accepting them is not\nbelieved to have a security impact."}),"\n",(0,t.jsx)(n.p,{children:"Note: RFC 8032 and FIPS 186-5 require rejecting non-canonically encoded\npoints."}),"\n",(0,t.jsx)(n.h3,{id:"cofactored-verification-equation",children:"Cofactored Verification Equation"}),"\n",(0,t.jsxs)(n.p,{children:["There are two forms of the Ed25519 verification equation commonly in use,\n",(0,t.jsx)(n.code,{children:"[S]B = R + [k]A"})," (cofactor-less), and ",(0,t.jsx)(n.code,{children:"[8][S]B = [8]R + [8][k]A"}),"\n(cofactored), which are mutually incompatible in that it is possible\nto produce signatures that pass with one and fail with the other."]}),"\n",(0,t.jsx)(n.p,{children:"The cofactored verification equation is explicitly required by FIPS 186-5,\nand is the only equation that is compatible with batch signature verification.\nAdditionally, the more modern lattice-reduction based technique for fast\nsignature verification is incompatible with existing implementations unless\ncofactored."}),"\n",(0,t.jsx)(n.h3,{id:"accept-ar-with-non-zero-torsion",children:"Accept A/R With Non-zero Torsion"}),"\n",(0,t.jsx)(n.p,{children:"No other library enforces this, the check is extremely expensive, and\nwith how Oasis Core currently uses Ed25519 signatures, this has no security\nimpact. In the event that Oasis Core does exotic things that, for example,\nrequire that the public key is in the prime-order subgroup, this must be\nchanged."}),"\n",(0,t.jsx)(n.h2,{id:"consequences",children:"Consequences"}),"\n",(0,t.jsx)(n.h3,{id:"positive",children:"Positive"}),"\n",(0,t.jsx)(n.p,{children:"The verification semantics in use by Oasis Core provides the following\nproperties:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"SUF-CMA security"}),"\n",(0,t.jsx)(n.li,{children:"Non-repudiation (strong binding)"}),"\n",(0,t.jsx)(n.li,{children:"Compatibility with batch and lattice reduction based verification."}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"negative",children:"Negative"}),"\n",(0,t.jsx)(n.p,{children:'The combination of "reject small order A/R" and "accept non-canonical A/R"\nis difficult to test as it is not easily possible to generate valid\nsignatures that meet both conditions.'}),"\n",(0,t.jsx)(n.h3,{id:"neutral",children:"Neutral"}),"\n",(0,t.jsx)(n.h3,{id:"future-improvements",children:"Future Improvements"}),"\n",(0,t.jsx)(n.p,{children:"WARNING: Any changes to verification semantics are consensus breaking."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'Consider switching to the "Algorithm 2" definition, for ease of testing\nand because it is the default behavior provided by curve25519-voi.'}),"\n",(0,t.jsx)(n.li,{children:"Consider switching to ZIP-215 semantics, to be inline with other projects,\nmore library support (Give up on strong binding)."}),"\n",(0,t.jsx)(n.li,{children:"Switching to ristretto255 (sr25519) eliminates these problems entirely."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"recomendations-for-future-projects",children:"Recomendations For Future Projects"}),"\n",(0,t.jsx)(n.p,{children:"The definition used in Oasis Core is partly historical. New code should\nstrongly consider using one of FIPS 186-5, Algorithm 2, or ZIP-215 semantics."}),"\n",(0,t.jsx)(n.h2,{id:"references",children:"References"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://eprint.iacr.org/2020/1244.pdf",children:"Taming the many EdDSAs"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://zips.z.cash/zip-0215",children:"Explicitly Defining and Modifying Ed25519 Validation Rules"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>a});var t=i(6540);const s={},o=t.createContext(s);function r(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/6b19e4d7.7c8b354c.js b/assets/js/6b19e4d7.7c8b354c.js
new file mode 100644
index 0000000000..55630899b4
--- /dev/null
+++ b/assets/js/6b19e4d7.7c8b354c.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[9589],{3076:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>h,contentTitle:()=>d,default:()=>m,frontMatter:()=>c,metadata:()=>l,toc:()=>p});var n=t(4848),i=t(8453),r=t(2550),a=t(6116),o=t(1766);const c={},d="Sapphire ParaTime",l={id:"dapp/sapphire/README",title:"Sapphire ParaTime",description:"Sapphire is our official confidential ParaTime providing a smart contract",source:"@site/docs/dapp/sapphire/README.mdx",sourceDirName:"dapp/sapphire",slug:"/dapp/sapphire/",permalink:"/dapp/sapphire/",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/dapp/sapphire/README.mdx",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"developers",previous:{title:"Overview",permalink:"/dapp/"},next:{title:"Quickstart",permalink:"/dapp/sapphire/quickstart"}},h={},p=[{value:"Chain Information",id:"chain-information",level:2},{value:"Mainnet",id:"mainnet",level:3},{value:"Testnet",id:"testnet",level:3},{value:"RPC Endpoints",id:"rpc-endpoints",level:2},{value:"Block Explorers",id:"block-explorers",level:2},{value:"Indexers",id:"indexers",level:2},{value:"See also",id:"see-also",level:2}];function x(e){const s={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"sapphire-paratime",children:"Sapphire ParaTime"}),"\n",(0,n.jsxs)(s.p,{children:["Sapphire is our official confidential ParaTime providing a smart contract\ndevelopment environment with ",(0,n.jsx)(s.a,{href:"https://ethereum.org/en/developers/docs/evm/",children:"Ethereum Virtual Machine (EVM)"})," compatibility."]}),"\n",(0,n.jsx)(s.p,{children:"As the official confidential EVM-compatible ParaTime on the Oasis Network,\nSapphire allows for:"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:"Confidential state, end-to-end encryption, confidential randomness"}),"\n",(0,n.jsx)(s.li,{children:"EVM compatibility"}),"\n",(0,n.jsx)(s.li,{children:"Easy integration with EVM-based dApps, such as DeFi, NFT, Metaverse and\ncrypto gaming"}),"\n",(0,n.jsx)(s.li,{children:"Scalability: increased throughput of transactions"}),"\n",(0,n.jsx)(s.li,{children:"Low-cost: 99%+ lower fees than Ethereum"}),"\n",(0,n.jsx)(s.li,{children:"6 second finality (1 block)"}),"\n",(0,n.jsx)(s.li,{children:"Cross-chain bridge to enable cross-chain interoperability (upcoming)"}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["If you are not bound to EVM and you wish to develop dApps with more\nfine-grained confidentiality, check out the\n",(0,n.jsx)(s.a,{href:"/dapp/cipher/",children:"Cipher ParaTime"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"chain-information",children:"Chain Information"}),"\n",(0,n.jsx)(s.h3,{id:"mainnet",children:"Mainnet"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["Network name: ",(0,n.jsx)(s.code,{children:"sapphire"})]}),"\n",(0,n.jsxs)(s.li,{children:["Long network name: ",(0,n.jsx)(s.code,{children:"Oasis Sapphire"})]}),"\n",(0,n.jsxs)(s.li,{children:["Chain ID:","\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["Hex: ",(0,n.jsx)(s.code,{children:"0x5afe"})]}),"\n",(0,n.jsxs)(s.li,{children:["Decimal: ",(0,n.jsx)(s.code,{children:"23294"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"testnet",children:"Testnet"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["Network name: ",(0,n.jsx)(s.code,{children:"sapphire-testnet"})]}),"\n",(0,n.jsxs)(s.li,{children:["Long network name: ",(0,n.jsx)(s.code,{children:"Oasis Sapphire Testnet"})]}),"\n",(0,n.jsxs)(s.li,{children:["Chain ID:","\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["Hex: ",(0,n.jsx)(s.code,{children:"0x5aff"})]}),"\n",(0,n.jsxs)(s.li,{children:["Decimal: ",(0,n.jsx)(s.code,{children:"23295"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"rpc-endpoints",children:"RPC Endpoints"}),"\n",(0,n.jsx)(s.admonition,{type:"danger",children:(0,n.jsxs)(s.p,{children:["The RPC endpoint is a ",(0,n.jsx)(s.em,{children:"point of trust"}),". Beside traffic rate limiting, it can\nalso perform censorship or even a man-in-the-middle attack. If you have security\nconsiderations, we strongly recommend that you set up your own ",(0,n.jsx)(s.a,{href:"/node/run-your-node/paratime-client-node",children:"ParaTime client\nnode"})," and the ",(0,n.jsx)(s.a,{href:"/node/web3",children:"Web3-compatible gateway"}),"."]})}),"\n",(0,n.jsx)(s.p,{children:"You can connect to one of the public Web3 gateways below (in alphabetic order):"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Provider"}),(0,n.jsx)(s.th,{children:"Mainnet RPC URLs"}),(0,n.jsx)(s.th,{children:"Testnet RPC URLs"}),(0,n.jsx)(s.th,{children:"Supports Confidential Queries"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://www.1rpc.io/",children:"1RPC"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(o.KT,{rpcs:["https://1rpc.io/oasis/sapphire"]})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.em,{children:"N/A"})}),(0,n.jsx)(s.td,{children:"Yes"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://oasisprotocol.org",children:"Oasis Protocol Foundation"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(o.KT,{rpcs:["https://sapphire.oasis.io","wss://sapphire.oasis.io/ws"]})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(o.XV,{rpcs:["https://testnet.sapphire.oasis.io","wss://testnet.sapphire.oasis.io/ws"]})}),(0,n.jsx)(s.td,{children:"Yes"})]})]})]}),"\n",(0,n.jsx)(s.p,{children:"Public RPCs may have rate limits or traffic restrictions. For professional,\ndedicated RPC endpoints, consider the following providers (in alphabetic order):"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Provider"}),(0,n.jsx)(s.th,{children:"Instructions"}),(0,n.jsx)(s.th,{children:"Pricing"}),(0,n.jsx)(s.th,{children:"Supports Confidential Queries"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://www.1rpc.io/",children:"1RPC"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://docs.1rpc.io/guide/how-to-use-1rpc",children:"docs.1rpc.io"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://www.1rpc.io/#pricing",children:"Pricing"})}),(0,n.jsx)(s.td,{children:"Yes"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://chainstack.com/build-better-with-oasis-sapphire/",children:"Chainstack"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://docs.chainstack.com/docs/oasis-sapphire-tooling",children:"docs.chainstack.com"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://chainstack.com/pricing/",children:"Pricing"})}),(0,n.jsx)(s.td,{children:"Yes"})]})]})]}),"\n",(0,n.jsx)(s.h2,{id:"block-explorers",children:"Block Explorers"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Name (Provider)"}),(0,n.jsx)(s.th,{children:"Mainnet URL"}),(0,n.jsx)(s.th,{children:"Testnet URL"}),(0,n.jsx)(s.th,{children:"EIP-3091 compatible"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsxs)(s.td,{children:["Oasis Explorer (",(0,n.jsx)(s.a,{href:"https://oasisprotocol.org",children:"Oasis Protocol Foundation"}),")"]}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://explorer.oasis.io/mainnet/sapphire",children:"https://explorer.oasis.io/mainnet/sapphire"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://explorer.oasis.io/testnet/sapphire",children:"https://explorer.oasis.io/testnet/sapphire"})}),(0,n.jsx)(s.td,{children:"Yes"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsxs)(s.td,{children:["Oasis Scan (",(0,n.jsx)(s.a,{href:"https://www.bitcat365.com/",children:"Bit Cat"}),")"]}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://www.oasisscan.com/paratimes/000000000000000000000000000000000000000000000000f80306c9858e7279",children:"https://www.oasisscan.com/paratimes/000\u2026279"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://testnet.oasisscan.com/paratimes/000000000000000000000000000000000000000000000000a6d1e3ebf60dff6c",children:"https://testnet.oasisscan.com/paratimes/000\u2026f6c"})}),(0,n.jsx)(s.td,{children:"No"})]})]})]}),"\n",(0,n.jsx)(s.h2,{id:"indexers",children:"Indexers"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Name (Provider)"}),(0,n.jsx)(s.th,{children:"Mainnet URL"}),(0,n.jsx)(s.th,{children:"Testnet URL"}),(0,n.jsx)(s.th,{children:"Documentation"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://www.covalenthq.com/",children:"Covalent"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"https://api.covalenthq.com/v1/oasis-sapphire-mainnet"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"https://api.covalenthq.com/v1/oasis-sapphire-testnet"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://www.covalenthq.com/docs/unified-api/",children:"Unified API docs"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://goldsky.com",children:"Goldsky Subgraph"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.em,{children:"N/A"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.em,{children:"N/A"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://docs.goldsky.com/subgraphs/deploying-subgraphs",children:"Documentation site"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsxs)(s.td,{children:["Oasis Nexus (",(0,n.jsx)(s.a,{href:"https://oasisprotocol.org",children:"Oasis Protocol Foundation"}),")"]}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"https://nexus.oasis.io/v1/"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"https://testnet.nexus.oasis.io/v1/"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://nexus.oasis.io/v1/spec/v1.html",children:"API"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsxs)(s.td,{children:["Oasis Scan (",(0,n.jsx)(s.a,{href:"https://www.bitcat365.com/",children:"Bit Cat"}),")"]}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"https://api.oasisscan.com/mainnet/v2"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"https://api.oasisscan.com/testnet/v2"})}),(0,n.jsxs)(s.td,{children:[(0,n.jsx)(s.a,{href:"https://api.oasisscan.com/mainnet/swagger-ui/#/runtime-controller",children:"Mainnet Runtime API"}),", ",(0,n.jsx)(s.a,{href:"https://api.oasisscan.com/testnet/swagger-ui/#/runtime-controller",children:"Testnet Runtime API"})]})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://subquery.network",children:"SubQuery Network"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.em,{children:"N/A"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.em,{children:"N/A"})}),(0,n.jsxs)(s.td,{children:[(0,n.jsx)(s.a,{href:"https://academy.subquery.network/",children:"SubQuery Academy"}),", ",(0,n.jsx)(s.a,{href:"https://academy.subquery.network/quickstart/quickstart.html",children:"QuickStart"}),", ",(0,n.jsx)(s.a,{href:"https://github.com/subquery/ethereum-subql-starter/tree/main/Oasis/oasis-sapphire-starter",children:"Starter project"})]})]})]})]}),"\n",(0,n.jsx)(s.admonition,{type:"note",children:(0,n.jsxs)(s.p,{children:["If you are running your own Sapphire endpoint, a block explorer, or an indexer\nand wish to be added to these docs, open an issue at\n",(0,n.jsx)(s.a,{href:"https://github.com/oasisprotocol/docs",children:"github.com/oasisprotocol/docs"}),"."]})}),"\n",(0,n.jsx)(s.h2,{id:"see-also",children:"See also"}),"\n",(0,n.jsx)(r.A,{items:[(0,a.$)("/general/manage-tokens/"),(0,a.$)("/node/run-your-node/paratime-node"),(0,a.$)("/node/run-your-node/paratime-client-node"),(0,a.$)("/node/web3"),(0,a.$)("/dapp/emerald/"),(0,a.$)("/dapp/cipher/")]})]})}function m(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(x,{...e})}):x(e)}},5965:(e,s,t)=>{t.d(s,{A:()=>j});t(6540);var n=t(4164),i=t(8774),r=t(4142),a=t(5846),o=t(6654),c=t(1312),d=t(1107);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var h=t(4848);function p(e){let{href:s,children:t}=e;return(0,h.jsx)(i.A,{href:s,className:(0,n.A)("card padding--lg",l.cardContainer),children:t})}function x(e){let{href:s,icon:t,title:i,description:r}=e;return(0,h.jsxs)(p,{href:s,children:[(0,h.jsxs)(d.A,{as:"h2",className:(0,n.A)("text--truncate",l.cardTitle),title:i,children:[t," ",i]}),r&&(0,h.jsx)("p",{className:(0,n.A)("text--truncate",l.cardDescription),title:r,children:r})]})}function m(e){let{item:s}=e;const t=(0,r.Nr)(s),n=function(){const{selectMessage:e}=(0,a.W)();return s=>e(s,(0,c.T)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:s}))}();return t?(0,h.jsx)(x,{href:t,icon:"\ud83d\uddc3\ufe0f",title:s.label,description:s.description??n(s.items.length)}):null}function u(e){let{item:s}=e;const t=(0,o.A)(s.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",n=(0,r.cC)(s.docId??void 0);return(0,h.jsx)(x,{href:s.href,icon:t,title:s.label,description:s.description??n?.description})}function j(e){let{item:s}=e;switch(s.type){case"link":return(0,h.jsx)(u,{item:s});case"category":return(0,h.jsx)(m,{item:s});default:throw new Error(`unknown item type ${JSON.stringify(s)}`)}}},2550:(e,s,t)=>{t.d(s,{A:()=>c});t(6540);var n=t(4164),i=t(4142),r=t(5965),a=t(4848);function o(e){let{className:s}=e;const t=(0,i.$S)();return(0,a.jsx)(c,{items:t.items,className:s})}function c(e){const{items:s,className:t}=e;if(!s)return(0,a.jsx)(o,{...e});const c=(0,i.d1)(s);return(0,a.jsx)("section",{className:(0,n.A)("row",t),children:c.map(((e,s)=>(0,a.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,a.jsx)(r.A,{item:e})},s)))})}},5846:(e,s,t)=>{t.d(s,{W:()=>d});var n=t(6540),i=t(4586);const r=["zero","one","two","few","many","other"];function a(e){return r.filter((s=>e.includes(s)))}const o={locale:"en",pluralForms:a(["one","other"]),select:e=>1===e?"one":"other"};function c(){const{i18n:{currentLocale:e}}=(0,i.A)();return(0,n.useMemo)((()=>{try{return function(e){const s=new Intl.PluralRules(e);return{locale:e,pluralForms:a(s.resolvedOptions().pluralCategories),select:e=>s.select(e)}}(e)}catch(s){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${s.message}\n`),o}}),[e])}function d(){const e=c();return{selectMessage:(s,t)=>function(e,s,t){const n=e.split("|");if(1===n.length)return n[0];n.length>t.pluralForms.length&&console.error(`For locale=${t.locale}, a maximum of ${t.pluralForms.length} plural forms are expected (${t.pluralForms.join(",")}), but the message contains ${n.length}: ${e}`);const i=t.select(s),r=t.pluralForms.indexOf(i);return n[Math.min(r,n.length-1)]}(t,s,e)}}},1766:(e,s,t)=>{t.d(s,{KT:()=>r,XV:()=>a,YH:()=>o,fm:()=>c});t(6540);var n=t(4848);const i=e=>(0,n.jsxs)("span",{children:[e.rpcs.map((e=>(0,n.jsxs)("code",{children:[e,(0,n.jsx)("br",{})]},e))),(0,n.jsx)("button",{className:"button button--primary margin-top--md",onClick:()=>{if(!window.ethereum?.request)return alert("Have you installed MetaMask yet? If not, please do so.\n\nComputer: Once it is installed, you will be able to add the ParaTime to your MetaMask.\n\nPhone: Open the website through your MetaMask Browser to add the ParaTime.");const s=Date.now();window.ethereum.request({method:"wallet_addEthereumChain",params:[{chainId:e.chainId,chainName:e.name,nativeCurrency:{name:e.token,symbol:e.token,decimals:18},rpcUrls:e.rpcs,blockExplorerUrls:e.be}]}).then((t=>{const n=Date.now()-s<100;null===t&&n&&alert(`The ${e.name} RPC already added.`)}))},children:"Add to MetaMask"})]}),r=e=>i({name:"Oasis Sapphire",chainId:"0x5afe",token:"ROSE",rpcs:e.rpcs,be:["https://explorer.oasis.io/mainnet/sapphire"]}),a=e=>i({name:"Oasis Sapphire Testnet",chainId:"0x5aff",token:"TEST",rpcs:e.rpcs,be:["https://explorer.oasis.io/testnet/sapphire"]}),o=e=>i({name:"Oasis Emerald",chainId:"0xa516",token:"ROSE",rpcs:e.rpcs,be:["https://explorer.oasis.io/mainnet/emerald"]}),c=e=>i({name:"Oasis Emerald Testnet",chainId:"0xa515",token:"TEST",rpcs:e.rpcs,be:["https://explorer.oasis.io/testnet/emerald"]})},6116:(e,s,t)=>{t.d(s,{$:()=>r});var n=t(2252);function i(e){for(const s of e){const e=s.href;e&&void 0===globalThis.sidebarItemsMap[e]&&(globalThis.sidebarItemsMap[e]=s),"category"===s.type&&i(s.items)}}function r(e){const s=(0,n.r)();if(!s)throw new Error("Unexpected: cant find docsVersion in current context");if(void 0===globalThis.sidebarItemsMap){globalThis.sidebarItemsMap={};for(const e in s.docsSidebars)i(s.docsSidebars[e])}if(void 0===globalThis.sidebarItemsMap[e])throw console.log("Registered sidebar items:"),console.log(globalThis.sidebarItemsMap),new Error("Unexpected: sidebar item with href "+e+" does not exist.");return globalThis.sidebarItemsMap[e]}},8453:(e,s,t)=>{t.d(s,{R:()=>a,x:()=>o});var n=t(6540);const i={},r=n.createContext(i);function a(e){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/6de7ad9b.f0b69df3.js b/assets/js/6de7ad9b.f0b69df3.js
new file mode 100644
index 0000000000..92616be16e
--- /dev/null
+++ b/assets/js/6de7ad9b.f0b69df3.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[87],{9972:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>u});var t=a(4848),l=a(8453),r=a(1470),s=a(9365);const o={},i="Frontend Application",c={id:"dapp/opl/frontend",title:"Frontend Application",description:"We will need a Pinata development API",source:"@site/docs/dapp/opl/frontend.md",sourceDirName:"dapp/opl",slug:"/dapp/opl/frontend",permalink:"/dapp/opl/frontend",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/dapp/opl/frontend.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"developers",previous:{title:"Build",permalink:"/dapp/opl/build"},next:{title:"Cipher ParaTime",permalink:"/dapp/cipher/"}},d={},u=[{value:"VueJS",id:"vuejs",level:3},{value:"Pinata",id:"pinata",level:3},{value:"Start",id:"start",level:3},{value:"MetaMask",id:"metamask",level:3},{value:"Localhost",id:"localhost",level:4},{value:"Example",id:"example",level:2}];function p(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,l.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"frontend-application",children:"Frontend Application"}),"\n",(0,t.jsxs)(n.p,{children:["We will need a ",(0,t.jsx)(n.a,{href:"https://www.pinata.cloud",children:"Pinata"})," development API\n",(0,t.jsx)(n.a,{href:"https://docs.pinata.cloud/docs/getting-started#2-generate-your-api-keys",children:"key"}),"\nand JWT with the ",(0,t.jsx)(n.code,{children:"pinFileToIPFS"})," permission. Let's obtain that first."]}),"\n",(0,t.jsx)(n.h3,{id:"vuejs",children:"VueJS"}),"\n",(0,t.jsxs)(n.p,{children:["We will take a shortcut and bypass developing a VueJS app. Instead, we will\nsimply apply a sparse checkout of the complete frontend repo. Inside your\n",(0,t.jsx)(n.code,{children:"opl-secret-ballot"})," directory run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"git init .\ngit remote add -f demo-opl-secret-ballot https://github.com/oasisprotocol/demo-opl-secret-ballot\ngit checkout demo-opl-secret-ballot/main frontend\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Next, update the ",(0,t.jsx)(n.code,{children:"@oasislabs/secret-ballot-backend"})," package name in\n",(0,t.jsx)(n.code,{children:"frontend/package.json"})," to match your ",(0,t.jsx)(n.code,{children:"backend/package.json"})," project name."]}),"\n",(0,t.jsxs)(n.p,{children:["We recommend using ",(0,t.jsx)(n.a,{href:"https://pnpm.io",children:"pnpm"})," to install dependencies, but ",(0,t.jsx)(n.code,{children:"yarn"}),"\nand ",(0,t.jsx)(n.code,{children:"npm"})," will work with some modifications around workspaces."]}),"\n",(0,t.jsxs)(r.A,{groupId:"npm2yarn",children:[(0,t.jsx)(s.A,{value:"npm",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"npm install\n"})})}),(0,t.jsx)(s.A,{value:"pnpm",label:"pnpm",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"pnpm install\n"})})}),(0,t.jsx)(s.A,{value:"yarn",label:"Yarn",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"yarn install\n"})})})]}),"\n",(0,t.jsx)(n.p,{children:"Compile and Hot-Reload for Development"}),"\n",(0,t.jsxs)(r.A,{groupId:"npm2yarn",children:[(0,t.jsx)(s.A,{value:"npm",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"npm run dev\n"})})}),(0,t.jsx)(s.A,{value:"pnpm",label:"pnpm",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"pnpm run dev\n"})})}),(0,t.jsx)(s.A,{value:"yarn",label:"Yarn",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"yarn dev\n"})})})]}),"\n",(0,t.jsx)(n.p,{children:"Build assets for deployment"}),"\n",(0,t.jsxs)(r.A,{groupId:"npm2yarn",children:[(0,t.jsx)(s.A,{value:"npm",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"npm run build\n"})})}),(0,t.jsx)(s.A,{value:"pnpm",label:"pnpm",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"pnpm run build\n"})})}),(0,t.jsx)(s.A,{value:"yarn",label:"Yarn",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"yarn build\n"})})})]}),"\n",(0,t.jsx)(n.p,{children:"We can now reference the deployed contracts in our frontend Vue app."}),"\n",(0,t.jsxs)(n.p,{children:["Modify the ",(0,t.jsx)(n.code,{children:".env.development"})," file with the appropriate addresses:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"VITE_BALLOT_BOX_V1_ADDR=0xFb40591a8df155da291A4B52E4Df9901a95b7C06\n"})}),"\n",(0,t.jsx)(n.p,{children:"and"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"VITE_DAO_V1_ADDR=0xFBcb580DD6D64fbF7caF57FB0439502412324179\n"})}),"\n",(0,t.jsx)(n.h3,{id:"pinata",children:"Pinata"}),"\n",(0,t.jsxs)(n.p,{children:["Additionally, we will need a ",(0,t.jsx)(n.a,{href:"https://www.pinata.cloud",children:"Pinata"})," JWT\n",(0,t.jsx)(n.a,{href:"https://docs.pinata.cloud/reference/datatestauthentication",children:"key"})," to access the\npinning service with which we store our ballots as JSON."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"VITE_PINATA_JWT=\n"})}),"\n",(0,t.jsx)(n.h3,{id:"start",children:"Start"}),"\n",(0,t.jsx)(n.p,{children:"Start Vue app"}),"\n",(0,t.jsxs)(r.A,{groupId:"npm2yarn",children:[(0,t.jsx)(s.A,{value:"npm",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"npm run dev\n"})})}),(0,t.jsx)(s.A,{value:"pnpm",label:"pnpm",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"pnpm run dev\n"})})}),(0,t.jsx)(s.A,{value:"yarn",label:"Yarn",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"yarn dev\n"})})})]}),"\n",(0,t.jsx)(n.h3,{id:"metamask",children:"MetaMask"}),"\n",(0,t.jsxs)(n.p,{children:["You can use one of the deployed test accounts and associated private key with\n",(0,t.jsx)(n.a,{href:"https://metamask.io",children:"MetaMask"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"If you have not added a local network to MetaMask already, you can use this\nconfiguration."}),"\n",(0,t.jsx)(n.h4,{id:"localhost",children:"Localhost"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["RPC HTTP endpoint: ",(0,t.jsx)(n.code,{children:"http://127.0.0.1:8545/"})]}),"\n",(0,t.jsxs)(n.li,{children:["Chain ID:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Decimal: 1337"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,t.jsxs)(n.p,{children:["You should be able to navigate to\n",(0,t.jsx)(n.a,{href:"http://localhost:5173",children:"http://localhost:5173"})," and create a new poll."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Create a poll",src:a(8661).A+"",width:"2880",height:"1800"})}),"\n",(0,t.jsx)(n.p,{children:"Confirm and sign a transaction to create a new poll (issues a request against\nthe Host contract)."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Confirm new poll",src:a(8342).A+"",width:"2880",height:"1800"})}),"\n",(0,t.jsxs)(n.p,{children:["Voting on a ballot issues a request to the ",(0,t.jsx)(n.em,{children:"enclave"})," contract."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Vote on ballot",src:a(5730).A+"",width:"2880",height:"1800"})}),"\n",(0,t.jsx)(n.p,{children:"You should be able to see results from past polls."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"See past proposals",src:a(6274).A+"",width:"2880",height:"1800"})}),"\n",(0,t.jsx)(n.p,{children:"If you were able to get to this point, congrats! You have created an OPL dApp!"}),"\n",(0,t.jsx)(n.admonition,{title:"Example",type:"info",children:(0,t.jsxs)(n.p,{children:["You can try out and download a frontend of the secret ballot Dapp from the\n",(0,t.jsx)(n.a,{href:"https://github.com/oasisprotocol/demo-opl-secret-ballot/tree/main/frontend",children:"Oasis Playground repository"}),"."]})})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},9365:(e,n,a)=>{a.d(n,{A:()=>s});a(6540);var t=a(4164);const l={tabItem:"tabItem_Ymn6"};var r=a(4848);function s(e){let{children:n,hidden:a,className:s}=e;return(0,r.jsx)("div",{role:"tabpanel",className:(0,t.A)(l.tabItem,s),hidden:a,children:n})}},1470:(e,n,a)=>{a.d(n,{A:()=>w});var t=a(6540),l=a(4164),r=a(3104),s=a(6347),o=a(205),i=a(7485),c=a(1682),d=a(9466);function u(e){return t.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,t.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:n,children:a}=e;return(0,t.useMemo)((()=>{const e=n??function(e){return u(e).map((e=>{let{props:{value:n,label:a,attributes:t,default:l}}=e;return{value:n,label:a,attributes:t,default:l}}))}(a);return function(e){const n=(0,c.X)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,a])}function h(e){let{value:n,tabValues:a}=e;return a.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:a}=e;const l=(0,s.W6)(),r=function(e){let{queryString:n=!1,groupId:a}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!a)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return a??null}({queryString:n,groupId:a});return[(0,i.aZ)(r),(0,t.useCallback)((e=>{if(!r)return;const n=new URLSearchParams(l.location.search);n.set(r,e),l.replace({...l.location,search:n.toString()})}),[r,l])]}function x(e){const{defaultValue:n,queryString:a=!1,groupId:l}=e,r=p(e),[s,i]=(0,t.useState)((()=>function(e){let{defaultValue:n,tabValues:a}=e;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!h({value:n,tabValues:a}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${a.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const t=a.find((e=>e.default))??a[0];if(!t)throw new Error("Unexpected error: 0 tabValues");return t.value}({defaultValue:n,tabValues:r}))),[c,u]=m({queryString:a,groupId:l}),[x,j]=function(e){let{groupId:n}=e;const a=function(e){return e?`docusaurus.tab.${e}`:null}(n),[l,r]=(0,d.Dv)(a);return[l,(0,t.useCallback)((e=>{a&&r.set(e)}),[a,r])]}({groupId:l}),f=(()=>{const e=c??x;return h({value:e,tabValues:r})?e:null})();(0,o.A)((()=>{f&&i(f)}),[f]);return{selectedValue:s,selectValue:(0,t.useCallback)((e=>{if(!h({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);i(e),u(e),j(e)}),[u,j,r]),tabValues:r}}var j=a(2303);const f={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var b=a(4848);function g(e){let{className:n,block:a,selectedValue:t,selectValue:s,tabValues:o}=e;const i=[],{blockElementScrollPositionUntilNextRender:c}=(0,r.a_)(),d=e=>{const n=e.currentTarget,a=i.indexOf(n),l=o[a].value;l!==t&&(c(n),s(l))},u=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const a=i.indexOf(e.currentTarget)+1;n=i[a]??i[0];break}case"ArrowLeft":{const a=i.indexOf(e.currentTarget)-1;n=i[a]??i[i.length-1];break}}n?.focus()};return(0,b.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.A)("tabs",{"tabs--block":a},n),children:o.map((e=>{let{value:n,label:a,attributes:r}=e;return(0,b.jsx)("li",{role:"tab",tabIndex:t===n?0:-1,"aria-selected":t===n,ref:e=>i.push(e),onKeyDown:u,onClick:d,...r,className:(0,l.A)("tabs__item",f.tabItem,r?.className,{"tabs__item--active":t===n}),children:a??n},n)}))})}function v(e){let{lazy:n,children:a,selectedValue:l}=e;const r=(Array.isArray(a)?a:[a]).filter(Boolean);if(n){const e=r.find((e=>e.props.value===l));return e?(0,t.cloneElement)(e,{className:"margin-top--md"}):null}return(0,b.jsx)("div",{className:"margin-top--md",children:r.map(((e,n)=>(0,t.cloneElement)(e,{key:n,hidden:e.props.value!==l})))})}function y(e){const n=x(e);return(0,b.jsxs)("div",{className:(0,l.A)("tabs-container",f.tabList),children:[(0,b.jsx)(g,{...n,...e}),(0,b.jsx)(v,{...n,...e})]})}function w(e){const n=(0,j.A)();return(0,b.jsx)(y,{...e,children:u(e.children)},String(n))}},8342:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/confirm-new-poll-44de684bfe667f9b7c51358f6e374bc9.png"},8661:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/create-poll-07bde4932eab22772d5d7e193cbc0255.png"},6274:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/past-dao-proposals-fd0f3f96be29751307e0850e034593c3.png"},5730:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/vote-on-ballot-1a35d67b60f5531fd4b91a1633030ee2.png"},8453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>o});var t=a(6540);const l={},r=t.createContext(l);function s(e){const n=t.useContext(r);return t.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(l):e.components||l:s(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/6e63ac1c.385d397a.js b/assets/js/6e63ac1c.385d397a.js
new file mode 100644
index 0000000000..f35745d148
--- /dev/null
+++ b/assets/js/6e63ac1c.385d397a.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[7189],{536:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var a=n(4848),s=n(8453);const i={description:"Deploying upgradable and deterministic contracts"},r="Deployment Patterns",o={id:"dapp/sapphire/deployment",title:"Deployment Patterns",description:"Deploying upgradable and deterministic contracts",source:"@site/docs/dapp/sapphire/deployment.md",sourceDirName:"dapp/sapphire",slug:"/dapp/sapphire/deployment",permalink:"/dapp/sapphire/deployment",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/sapphire-paratime/edit/main/docs/deployment.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{description:"Deploying upgradable and deterministic contracts"},sidebar:"developers",previous:{title:"Contract Addresses and Deployments",permalink:"/dapp/sapphire/addresses"},next:{title:"Security",permalink:"/dapp/sapphire/security"}},c={},d=[{value:"Implementing Proxy contracts on Oasis Sapphire",id:"implementing-proxy-contracts-on-oasis-sapphire",level:2},{value:"What are Upgradable Contracts?",id:"what-are-upgradable-contracts",level:3},{value:"EIP-1822: Universal Upgradeable Proxy Standard (UUPS)",id:"eip-1822-universal-upgradeable-proxy-standard-uups",level:4},{value:"EIP-1967: Standard Proxy Storage Slots",id:"eip-1967-standard-proxy-storage-slots",level:4},{value:"The Impact of Confidential EVM on Tooling Compatibility",id:"the-impact-of-confidential-evm-on-tooling-compatibility",level:3},{value:"Solutions for Using UUPS Proxies on Oasis Sapphire",id:"solutions-for-using-uups-proxies-on-oasis-sapphire",level:3},{value:"1. Directly Implement EIP-1822",id:"1-directly-implement-eip-1822",level:4},{value:"2. Modify Deployment Scripts",id:"2-modify-deployment-scripts",level:4},{value:"Solution for Using Deterministic Proxies on Oasis Sapphire",id:"solution-for-using-deterministic-proxies-on-oasis-sapphire",level:3},{value:"Caution Against Using eth_getStorageAt
",id:"caution-against-using-eth_getstorageat",level:3},{value:"EIP-7201: Namespaced Storage for Delegatecall Contracts",id:"eip-7201-namespaced-storage-for-delegatecall-contracts",level:3},{value:"Benefits of Namespacing over Direct Storage Access",id:"benefits-of-namespacing-over-direct-storage-access",level:3}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h1,{id:"deployment-patterns",children:"Deployment Patterns"}),"\n",(0,a.jsx)(t.h2,{id:"implementing-proxy-contracts-on-oasis-sapphire",children:"Implementing Proxy contracts on Oasis Sapphire"}),"\n",(0,a.jsx)(t.p,{children:"As a confidential Ethereum Virtual Machine (EVM), Oasis prevents external\naccess to contract storage or runtime states in order to keep your secrets\nprivate. This unique feature affects how developers interact with and manage\nsmart contracts, particularly when using common Ethereum development tools."}),"\n",(0,a.jsx)(t.h3,{id:"what-are-upgradable-contracts",children:"What are Upgradable Contracts?"}),"\n",(0,a.jsx)(t.p,{children:"Upgradable contracts are smart contracts designed to allow developers to update\nfunctionality even after being deployed to a blockchain. This is particularly\nuseful for fixing bugs or adding new features without losing the existing state\nor having to deploy a new contract. Upgradability is achieved through proxy\npatterns, where a proxy contract directs calls to an underlying logic contract\nwhich developers can swap out without affecting the state stored in the proxy."}),"\n",(0,a.jsxs)(t.h4,{id:"eip-1822-universal-upgradeable-proxy-standard-uups",children:[(0,a.jsx)(t.a,{href:"https://eips.ethereum.org/EIPS/eip-1822",children:"EIP-1822"}),": Universal Upgradeable Proxy Standard (UUPS)"]}),"\n",(0,a.jsx)(t.p,{children:"EIP-1822 introduces a method for creating upgradable contracts using a proxy\npattern and specifies a mechanism where the proxy contract itself contains the\nupgrade logic. This design reduces the complexity and potential for errors\ncompared to other proxy patterns because it consolidates upgrade functionality\nwithin the proxy and eliminates the need for additional external management."}),"\n",(0,a.jsxs)(t.h4,{id:"eip-1967-standard-proxy-storage-slots",children:[(0,a.jsx)(t.a,{href:"https://eips.ethereum.org/EIPS/eip-1967",children:"EIP-1967"}),": Standard Proxy Storage Slots"]}),"\n",(0,a.jsx)(t.p,{children:"EIP-1967 defines standard storage slots to be used by all proxy contracts for\nconsistent and predictable storage access. This standard helps prevent storage\ncollisions and enhances security by outlining specific locations in a proxy\ncontract for storing the address of the logic contract and other administrative\ninformation. Using these predetermined slots makes managing and auditing proxy\ncontracts easier."}),"\n",(0,a.jsx)(t.h3,{id:"the-impact-of-confidential-evm-on-tooling-compatibility",children:"The Impact of Confidential EVM on Tooling Compatibility"}),"\n",(0,a.jsxs)(t.p,{children:["While the underlying proxy implementations in EIP-1822 work perfectly in\nfacilitating smart contract upgrades, the tools typically used to manage these\nproxies may not function as expected on Oasis Sapphire.\nFor example, the ",(0,a.jsx)(t.a,{href:"https://github.com/OpenZeppelin/openzeppelin-upgrades",children:"openzeppelin-upgrades"})," library, which relies on the EIP-1967\nstandard, uses ",(0,a.jsx)(t.a,{href:"https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getstorageat",children:"eth_getStorageAt"})," to access contract storage. This function\ndoes not work in a confidential environment which forbids direct storage\naccess."]}),"\n",(0,a.jsxs)(t.p,{children:["Additionally, Sapphire natively protects against replay and currently does not\nallow an empty chain ID \xe0 la pre ",(0,a.jsx)(t.a,{href:"https://eips.ethereum.org/EIPS/eip-155",children:"EIP-155"})," transactions."]}),"\n",(0,a.jsx)(t.h3,{id:"solutions-for-using-uups-proxies-on-oasis-sapphire",children:"Solutions for Using UUPS Proxies on Oasis Sapphire"}),"\n",(0,a.jsx)(t.p,{children:"Developers looking to use UUPS proxies on Oasis Sapphire have two primary\noptions:"}),"\n",(0,a.jsx)(t.h4,{id:"1-directly-implement-eip-1822",children:"1. Directly Implement EIP-1822"}),"\n",(0,a.jsxs)(t.p,{children:["Avoid using ",(0,a.jsx)(t.a,{href:"https://github.com/OpenZeppelin/openzeppelin-upgrades",children:"openzeppelin-upgrades"})," and manually handle the proxy setup and\nupgrades with your own scripts, such as by calling the ",(0,a.jsx)(t.code,{children:"updateCodeAddress"}),"\nmethod directly."]}),"\n",(0,a.jsx)(t.h4,{id:"2-modify-deployment-scripts",children:"2. Modify Deployment Scripts"}),"\n",(0,a.jsxs)(t.p,{children:["Change deployment scripts to avoid ",(0,a.jsx)(t.code,{children:"eth_getStorageAt"}),". Alternative methods\nlike calling ",(0,a.jsx)(t.code,{children:"owner()"})," which do not require direct storage access.\n",(0,a.jsx)(t.a,{href:"https://github.com/wighawag/hardhat-deploy",children:"hardhat-deploy"})," as of ",(0,a.jsx)(t.code,{children:"0.12.4"})," supports this approach with a default proxy\nthat includes an ",(0,a.jsx)(t.code,{children:"owner()"})," function when deploying with a configuration that\nspecifies ",(0,a.jsx)(t.code,{children:"proxy: true"}),"."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-typescript",children:"module.exports = async ({getNamedAccounts, deployments, getChainId}) => {\n const {deploy} = deployments;\n const {deployer} = await getNamedAccounts();\n await deploy('Greeter', {\n from: deployer,\n proxy: true,\n });\n};\n"})}),"\n",(0,a.jsx)(t.h3,{id:"solution-for-using-deterministic-proxies-on-oasis-sapphire",children:"Solution for Using Deterministic Proxies on Oasis Sapphire"}),"\n",(0,a.jsx)(t.p,{children:"We suggest that developers interested in deterministic proxies on Oasis\nSapphire use a contract that supports replay protection."}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.code,{children:"hardhat-deploy"})," supports using the ",(0,a.jsx)(t.a,{href:"https://github.com/safe-global/safe-singleton-factory",children:"Safe Singleton factory"})," deployed on\nthe Sapphire ",(0,a.jsx)(t.a,{href:"https://explorer.oasis.io/mainnet/sapphire/address/0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7",children:"Mainnet"})," and ",(0,a.jsx)(t.a,{href:"https://explorer.oasis.io/testnet/sapphire/address/0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7",children:"Testnet"})," when ",(0,a.jsx)(t.code,{children:"deterministicDeployment"})," is ",(0,a.jsx)(t.code,{children:"true"}),"."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-typescript",children:"module.exports = async ({getNamedAccounts, deployments, getChainId}) => {\n const {deploy} = deployments;\n const {deployer} = await getNamedAccounts();\n await deploy('Greeter', {\n from: deployer,\n deterministicDeployment: true,\n });\n};\n"})}),"\n",(0,a.jsxs)(t.p,{children:["Next, in your ",(0,a.jsx)(t.code,{children:"hardhat.config.ts"})," file, specify the address of the Safe\nSingleton factory:"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-typescript",children:" deterministicDeployment: {\n \"97\": {\n factory: '0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7',\n deployer: '0xE1CB04A0fA36DdD16a06ea828007E35e1a3cBC37',\n funding: '2000000',\n signedTx: '',\n },\n \"23295\": {\n factory: '0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7',\n deployer: '0xE1CB04A0fA36DdD16a06ea828007E35e1a3cBC37',\n funding: '2000000',\n signedTx: '',\n }\n },\n"})}),"\n",(0,a.jsxs)(t.h3,{id:"caution-against-using-eth_getstorageat",children:["Caution Against Using ",(0,a.jsx)(t.code,{children:"eth_getStorageAt"})]}),"\n",(0,a.jsxs)(t.p,{children:["Direct storage access, such as with ",(0,a.jsx)(t.code,{children:"eth_getStorageAt"}),", is generally\ndiscouraged. It reduces contract flexibility and deviates from common practice\nwhich advocates for a standardized Solidity compatible API to both facilitate\ninteractions between contracts and allow popular libraries such as ",(0,a.jsx)(t.a,{href:"https://abitype.dev/",children:"ABIType"}),"\nand ",(0,a.jsx)(t.a,{href:"https://www.npmjs.com/package/typechain",children:"TypeChain"})," to automatically generate client bindings. Direct storage\naccess makes contracts less adaptable and complicates on-chain automation; it\ncan even complicate the use of multisig wallets.\nFor contracts aiming to maintain a standard interface and ensure future\nupgradeability, we advise sticking to ERC-defined Solidity compatible APIs and\navoiding directly interacting with contract storage."]}),"\n",(0,a.jsxs)(t.h3,{id:"eip-7201-namespaced-storage-for-delegatecall-contracts",children:[(0,a.jsx)(t.a,{href:"https://eips.ethereum.org/EIPS/eip-7201",children:"EIP-7201"}),": Namespaced Storage for Delegatecall Contracts"]}),"\n",(0,a.jsxs)(t.p,{children:["ERC-7201 proposes a structured approach to storage in smart contracts that\nutilize ",(0,a.jsx)(t.code,{children:"delegatecall"})," which is often employed in proxy contracts for\nupgradability. This standard recommends namespacing storage to mitigate the\nrisk of storage collisions \u2014 a common issue when multiple contracts share the\nsame storage space in a ",(0,a.jsx)(t.code,{children:"delegatecall"})," context."]}),"\n",(0,a.jsx)(t.h3,{id:"benefits-of-namespacing-over-direct-storage-access",children:"Benefits of Namespacing over Direct Storage Access"}),"\n",(0,a.jsxs)(t.p,{children:["Contracts using ",(0,a.jsx)(t.code,{children:"delegatecall"}),", such as upgradable proxies, can benefit from\nnamespacing their storage through more efficient data organization which\nenhances security. This approach isolates different variables and sections of\na contract\u2019s storage under distinct namespaces, ensuring that each segment is\ndistinct and does not interfere with others. Namespacing is generally more\nrobust and preferable to using ",(0,a.jsx)(t.code,{children:"eth_getStorageAt"}),"."]}),"\n",(0,a.jsxs)(t.p,{children:["See example ERC-7201 implementation and usage:\n",(0,a.jsx)(t.a,{href:"https://gist.github.com/CedarMist/4cfb8f967714aa6862dd062742acbc7b",children:"https://gist.github.com/CedarMist/4cfb8f967714aa6862dd062742acbc7b"})]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-solidity",children:'// SPDX-License-Identifier: Apache-2.0\n\npragma solidity ^0.8.0;\n\ncontract Example7201 {\n /// @custom:storage-location erc7201:Example7201.state\n struct State {\n uint256 counter;\n }\n\n function _stateStorageSlot()\n private pure\n returns (bytes32)\n {\n return keccak256(abi.encode(uint256(keccak256("Example7201.state")) - 1)) & ~bytes32(uint256(0xff));\n }\n\n function _getState()\n private pure\n returns (State storage state)\n {\n bytes32 slot = _stateStorageSlot();\n assembly {\n state.slot := slot\n }\n }\n\n function increment()\n public\n {\n State storage state = _getState();\n\n state.counter += 1;\n }\n\n function get()\n public view\n returns (uint256)\n {\n State storage state = _getState();\n\n return state.counter;\n }\n}\n\ncontract ExampleCaller {\n Example7201 private example;\n\n constructor () {\n example = new Example7201();\n }\n function get()\n external\n returns (uint256 counter)\n {\n (bool success, bytes memory result ) = address(example).delegatecall(abi.encodeCall(example.get, ()));\n require(success);\n counter = abi.decode(result, (uint256));\n }\n\n function increment()\n external\n {\n (bool success, ) = address(example).delegatecall(abi.encodeCall(example.increment, ()));\n require(success);\n }\n}\n'})})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var a=n(6540);const s={},i=a.createContext(s);function r(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/6ea13540.c7c72dc1.js b/assets/js/6ea13540.c7c72dc1.js
new file mode 100644
index 0000000000..ba212da6ac
--- /dev/null
+++ b/assets/js/6ea13540.c7c72dc1.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[8186],{6743:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>r,toc:()=>a});var i=t(4848),s=t(8453);const o={},l="ADR 0001: Multiple Roots Under the Tendermint Application Hash",r={id:"adrs/0001-tm-multi-root-apphash",title:"ADR 0001: Multiple Roots Under the Tendermint Application Hash",description:"Component",source:"@site/docs/adrs/0001-tm-multi-root-apphash.md",sourceDirName:"adrs",slug:"/adrs/0001-tm-multi-root-apphash",permalink:"/adrs/0001-tm-multi-root-apphash",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/adrs/edit/main/0001-tm-multi-root-apphash.md",tags:[],version:"current",lastUpdatedAt:1710755515e3,frontMatter:{},sidebar:"adrs",previous:{title:"Architectural Decision Records",permalink:"/adrs"},next:{title:"ADR 0002: Go Modules Compatible Git Tags",permalink:"/adrs/0002-go-modules-compatible-git-tags"}},d={},a=[{value:"Component",id:"component",level:2},{value:"Changelog",id:"changelog",level:2},{value:"Status",id:"status",level:2},{value:"Context",id:"context",level:2},{value:"Decision",id:"decision",level:2},{value:"Alternatives",id:"alternatives",level:2},{value:"Consequences",id:"consequences",level:2},{value:"Positive",id:"positive",level:3},{value:"Negative",id:"negative",level:3},{value:"Neutral",id:"neutral",level:3},{value:"References",id:"references",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"adr-0001-multiple-roots-under-the-tendermint-application-hash",children:"ADR 0001: Multiple Roots Under the Tendermint Application Hash"}),"\n",(0,i.jsx)(n.h2,{id:"component",children:"Component"}),"\n",(0,i.jsx)(n.p,{children:"Oasis Core"}),"\n",(0,i.jsx)(n.h2,{id:"changelog",children:"Changelog"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"2020-08-06: Added consequence for state checkpoints"}),"\n",(0,i.jsx)(n.li,{children:"2020-07-28: Initial version"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"status",children:"Status"}),"\n",(0,i.jsx)(n.p,{children:"Accepted"}),"\n",(0,i.jsx)(n.h2,{id:"context",children:"Context"}),"\n",(0,i.jsx)(n.p,{children:"Currently the Tendermint ABCI application hash is equal to the consensus state\nroot for a specific height. In order to allow additional uses, like proving to\nlight clients that specific events have been emitted in a block, we should make\nthe application hash be derivable from potentially different kinds of roots."}),"\n",(0,i.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,i.jsx)(n.p,{children:"The proposed design is to derive the Tendermint ABCI application hash by hashing\nall the different roots as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"AppHash := H(Context || Root_0 || ... || Root_n)\n"})}),"\n",(0,i.jsx)(n.p,{children:"Where:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"H"})," is the SHA-512/256 hash function."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Context"})," is the string ",(0,i.jsx)(n.code,{children:"oasis-core/tendermint: roots"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Root_i"})," is the fixed-size SHA-512/256 root hash of the specified root."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Currently, the only root would be the existing consensus state root at index 0."}),"\n",(0,i.jsx)(n.p,{children:"To implement this change the following modifications would be required:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Update the ABCI multiplexer's ",(0,i.jsx)(n.code,{children:"Commit"})," method to calculate and return the\napplication hash using the scheme specified above."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Update the consensus API ",(0,i.jsx)(n.code,{children:"SignedHeader"})," response to include the\n",(0,i.jsx)(n.code,{children:"UntrustedStateRoot"})," (the untrusted prefix denotes that the user must verify\nthat the state root corresponds to ",(0,i.jsx)(n.code,{children:"AppHash"})," provided in the signed header in\n",(0,i.jsx)(n.code,{children:"Meta"}),")."]}),"\n",(0,i.jsxs)(n.p,{children:["When new roots will be added in the future, both ",(0,i.jsx)(n.code,{children:"Block"})," and ",(0,i.jsx)(n.code,{children:"SignedHeader"}),"\nwill need to include them all."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"alternatives",children:"Alternatives"}),"\n",(0,i.jsx)(n.p,{children:"The proposed design is simple and assumes that the number of additional roots is\nsmall and thus can always be included in signed headers. An alternative scheme\nwould be to Merkelize the roots in a binary Merkle tree (like the one used for\nour MKVS), but this would add complexity and likely require more round trips for\ncommon use cases."}),"\n",(0,i.jsx)(n.h2,{id:"consequences",children:"Consequences"}),"\n",(0,i.jsx)(n.h3,{id:"positive",children:"Positive"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"This would open the path to including different kinds of provable data (e.g.,\nin addition to state) as part of any consensus-layer block."}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"negative",children:"Negative"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"As this changes the application hash, this would be a breaking change for the\nconsensus layer."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Since we are simply hashing all the roots together, all of them need to be\nincluded in the signed headers returned to light clients."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"neutral",children:"Neutral"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Consensus state checkpoints will need to contain data for multiple roots."}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"references",children:"References"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://github.com/tendermint/tendermint/pull/5134",children:"tendermint#5134"})}),"\n"]})]})}function c(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>l,x:()=>r});var i=t(6540);const s={},o=i.createContext(s);function l(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/714fd338.c767d0fe.js b/assets/js/714fd338.c767d0fe.js
new file mode 100644
index 0000000000..7386145137
--- /dev/null
+++ b/assets/js/714fd338.c767d0fe.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[3343],{5416:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>d});var t=s(4848),i=s(8453);const o={},r="Set up Trusted Execution Environment (TEE)",l={id:"node/run-your-node/prerequisites/set-up-trusted-execution-environment-tee",title:"Set up Trusted Execution Environment (TEE)",description:"In case the ParaTime you want to run does not require the use of a TEE (e.g.",source:"@site/docs/node/run-your-node/prerequisites/set-up-trusted-execution-environment-tee.md",sourceDirName:"node/run-your-node/prerequisites",slug:"/node/run-your-node/prerequisites/set-up-trusted-execution-environment-tee",permalink:"/node/run-your-node/prerequisites/set-up-trusted-execution-environment-tee",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/node/run-your-node/prerequisites/set-up-trusted-execution-environment-tee.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"operators",previous:{title:"System Configuration",permalink:"/node/run-your-node/prerequisites/system-configuration"},next:{title:"Validator Node",permalink:"/node/run-your-node/validator-node"}},a={},d=[{value:"BIOS Configuration",id:"bios-configuration",level:2},{value:"Ensure Clock Synchronization",id:"ensure-clock-synchronization",level:2},{value:"Ensure Proper SGX Device Permissions",id:"ensure-proper-sgx-device-permissions",level:2},{value:"AESM Service",id:"aesm-service",level:2},{value:"DCAP Attestation",id:"dcap-attestation",level:2},{value:"Ubuntu 22.04",id:"ubuntu-2204",level:3},{value:"Configuring the Quote Provider",id:"configuring-the-quote-provider",level:3},{value:"Intel PCS",id:"intel-pcs",level:4},{value:"Cloud Service Provider's PCCS",id:"cloud-service-providers-pccs",level:4},{value:"Own PCCS",id:"own-pccs",level:4},{value:"DCAP Attestation Docker",id:"dcap-attestation-docker",level:3},{value:"Multi-socket Systems",id:"multi-socket-systems",level:3},{value:"Ubuntu 22.04",id:"ubuntu-2204-1",level:4},{value:"VMware vSphere 8.0+",id:"vmware-vsphere-80",level:4},{value:"Migrate from EPID Attestation to DCAP Attestation",id:"migrate-from-epid-attestation-to-dcap-attestation",level:2},{value:"Check SGX Setup",id:"check-sgx-setup",level:2},{value:"Install Dependencies",id:"install-dependencies",level:3},{value:"Install Rust",id:"install-rust",level:3},{value:"Build and Install sgxs-tools",id:"build-and-install-sgxs-tools",level:3},{value:"Run sgx-detect
Tool",id:"run-sgx-detect-tool",level:3},{value:"Oasis Attestation tool",id:"oasis-attestation-tool",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"AESM could not be contacted",id:"aesm-could-not-be-contacted",level:3},{value:"AESM: error 30",id:"aesm-error-30",level:3},{value:"Permission Denied When Accessing SGX Kernel Device",id:"permission-denied-when-accessing-sgx-kernel-device",level:3},{value:"Error Opening SGX Kernel Device",id:"error-opening-sgx-kernel-device",level:3},{value:"Ensure /dev
is NOT Mounted with the noexec
Option",id:"ensure-dev-is-not-mounted-with-the-noexec-option",level:4},{value:"Unable to Launch Enclaves: Operation not permitted",id:"unable-to-launch-enclaves-operation-not-permitted",level:3},{value:"Unable to Launch Enclaves: Invalid argument",id:"unable-to-launch-enclaves-invalid-argument",level:3},{value:"Couldn't find the platform library",id:"couldnt-find-the-platform-library",level:3}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"set-up-trusted-execution-environment-tee",children:"Set up Trusted Execution Environment (TEE)"}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsx)(n.p,{children:"In case the ParaTime you want to run does not require the use of a TEE (e.g.\nIntel SGX), you can skip setting up a TEE."})}),"\n",(0,t.jsxs)(n.p,{children:["If the ParaTime is configured to run in a TEE (currently only ",(0,t.jsx)(n.a,{href:"https://www.intel.com/content/www/us/en/architecture-and-technology/software-guard-extensions.html",children:"Intel SGX"}),"), you\nmust make sure that your system supports running SGX enclaves. This requires\nthat your hardware has SGX support, that SGX support is enabled and that the\nadditional driver and software components are properly installed and running."]}),"\n",(0,t.jsx)(n.h2,{id:"bios-configuration",children:"BIOS Configuration"}),"\n",(0,t.jsxs)(n.p,{children:["To enable Intel SGX on your hardware, you also need to configure the BIOS.\nFirst, ",(0,t.jsx)(n.strong,{children:"update the BIOS to the latest version with the latest microcode"})," and\nthen proceed with BIOS configuration as shown below. Note that some settings may\nnot apply to your BIOS. In that case, configure only the relevant ones. Please\nset the BIOS settings as follows:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"SGX"}),": ENABLE"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Hyper-Threading"}),": DISABLE"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Intel SpeedStep"}),": DISABLE"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"SecureBoot"}),": DISABLE (not necessary for recent kernels)"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"All Internal Graphics"}),": DISABLE"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Turbo Mode"}),": DISABLE"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"CPU AES"}),": ENABLE"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"ensure-clock-synchronization",children:"Ensure Clock Synchronization"}),"\n",(0,t.jsx)(n.p,{children:"Due to additional sanity checks within runtime enclaves, you should ensure that\nthe node's local clock is synchronized (e.g. using NTP). If it is off by more\nthan half a second you may experience unexpected runtime aborts."}),"\n",(0,t.jsx)(n.h2,{id:"ensure-proper-sgx-device-permissions",children:"Ensure Proper SGX Device Permissions"}),"\n",(0,t.jsxs)(n.p,{children:["Make sure that the user that is running the Oasis Node binary has access to the\nSGX device (e.g. ",(0,t.jsx)(n.code,{children:"/dev/sgx_enclave"}),"). This can usually be achieved by adding\nthe user into the right group, for example in case the permissions of the SGX\ndevice are as follows:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"crw-rw---- 1 root sgx 10, 125 Oct 28 09:28 /dev/sgx_enclave\n"})}),"\n",(0,t.jsxs)(n.p,{children:["and the user running Oasis Node is ",(0,t.jsx)(n.code,{children:"oasis"}),", you can do:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo adduser oasis sgx\n"})}),"\n",(0,t.jsx)(n.p,{children:"Failure to do so may result in permission denied errors during runtime startup."}),"\n",(0,t.jsx)(n.h2,{id:"aesm-service",children:"AESM Service"}),"\n",(0,t.jsxs)(n.p,{children:["To allow execution of SGX enclaves, several ",(0,t.jsx)(n.strong,{children:"Architectural Enclaves (AE)"})," are\ninvolved (i.e. Launch Enclave, Provisioning Enclave, Provisioning Certificate\nEnclave, Quoting Enclave, Platform Services Enclaves)."]}),"\n",(0,t.jsxs)(n.p,{children:["Communication between application-spawned SGX enclaves and Intel-provided\nArchitectural Enclaves is through ",(0,t.jsx)(n.strong,{children:"Application Enclave Service Manager\n(AESM)"}),". AESM runs as a daemon and provides a socket through which applications\ncan facilitate various SGX services such as launch approval, remote attestation\nquote signing, etc."]}),"\n",(0,t.jsx)(n.p,{children:"Oasis node requires the use of DCAP attestation. To see if your system supports\nit, run the following:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:' cpuid -1 | grep "SGX"\n'})}),"\n",(0,t.jsx)(n.p,{children:"and look for the following line:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:" SGX_LC: SGX launch config supported = true\n"})}),"\n",(0,t.jsx)(n.h2,{id:"dcap-attestation",children:"DCAP Attestation"}),"\n",(0,t.jsx)(n.h3,{id:"ubuntu-2204",children:"Ubuntu 22.04"}),"\n",(0,t.jsxs)(n.p,{children:["A convenient way to install the AESM service on Ubuntu 22.04 systems\nis to use the Intel's ",(0,t.jsx)(n.a,{href:"https://download.01.org/intel-sgx/sgx_repo/",children:"official Intel SGX APT repository"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"First add Intel SGX APT repository to your system:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'curl -fsSL https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | sudo gpg --dearmor -o /usr/share/keyrings/intel-sgx-deb.gpg\necho "deb [arch=amd64 signed-by=/usr/share/keyrings/intel-sgx-deb.gpg] https://download.01.org/intel-sgx/sgx_repo/ubuntu $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/intel-sgx.list > /dev/null\n'})}),"\n",(0,t.jsxs)(n.p,{children:["And then install the ",(0,t.jsx)(n.code,{children:"sgx-aesm-service"}),", ",(0,t.jsx)(n.code,{children:"libsgx-aesm-ecdsa-plugin"}),", ",(0,t.jsx)(n.code,{children:"libsgx-aesm-quote-ex-plugin"})," and ",(0,t.jsx)(n.code,{children:"libsgx-dcap-default-qpl"})," packages:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt update\nsudo apt install sgx-aesm-service libsgx-aesm-ecdsa-plugin libsgx-aesm-quote-ex-plugin libsgx-dcap-default-qpl\n"})}),"\n",(0,t.jsx)(n.p,{children:"The AESM service should be up and running. To confirm that, use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl status aesmd.service\n"})}),"\n",(0,t.jsx)(n.h3,{id:"configuring-the-quote-provider",children:"Configuring the Quote Provider"}),"\n",(0,t.jsxs)(n.p,{children:["The Intel Quote Provider (",(0,t.jsx)(n.code,{children:"libsgx-dcap-default-qpl"}),") needs to be configured in\norder to use either the Intel PCS, the PCCS of your cloud service provider, or\nyour own PCCS. The configuration file is located at ",(0,t.jsx)(n.code,{children:"/etc/sgx_default_qcnl.conf"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Make sure to always restart the ",(0,t.jsx)(n.code,{children:"aesmd.service"})," after updating the\nconfiguration, via:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl restart aesmd.service\n"})}),"\n",(0,t.jsx)(n.h4,{id:"intel-pcs",children:"Intel PCS"}),"\n",(0,t.jsxs)(n.p,{children:["Using the Intel PCS is the simplest and most generic way, but it may be less\nreliable than using your own PCCS. Some cloud providers (see the ",(0,t.jsx)(n.a,{href:"#cloud-service-providers-pccs",children:"following section"}),")\nalso require you to use their PCCS."]}),"\n",(0,t.jsxs)(n.p,{children:["To use Intel PCS update the ",(0,t.jsx)(n.code,{children:"pccs_url"})," value in ",(0,t.jsx)(n.code,{children:"/etc/sgx_default_qcnl.conf"}),"\nto the Intel PCS API URL:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:' //PCCS server address\n "pccs_url": "https://api.trustedservices.intel.com/sgx/certification/v4/"\n'})}),"\n",(0,t.jsxs)(n.admonition,{type:"tip",children:[(0,t.jsx)(n.p,{children:"In case there is an error in the QPL configuration file, attestation will refuse\nto work and the AESM service may produce unhelpful errors like the following:"}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"Couldn't find the platform library. (null)\n"})}),(0,t.jsxs)(n.p,{children:["The only thing that needs to be changed is the ",(0,t.jsx)(n.code,{children:"pccs_url"})," value above. ",(0,t.jsx)(n.strong,{children:"Do not\nadd any comments and/or modify punctuation as these could make the configuration\nfile invalid."})]})]}),"\n",(0,t.jsx)(n.h4,{id:"cloud-service-providers-pccs",children:"Cloud Service Provider's PCCS"}),"\n",(0,t.jsx)(n.p,{children:"Some cloud providers require you to use their PCCS."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Azure: See the ",(0,t.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/security/fundamentals/trusted-hardware-identity-management#how-do-i-use-intel-qpl-with-trusted-hardware-identity-management",children:"Azure documentation"})," for details on configuring the quote provider. The documentation\ncontains an example of an Intel QPL configuration file that can be used."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Alibaba Cloud: See the ",(0,t.jsx)(n.a,{href:"https://www.alibabacloud.com/help/en/ecs/user-guide/build-an-sgx-encrypted-computing-environment",children:"Alibaba Cloud documentation"})," for details on configuring the quote provider. The\ndocumentation shows the required ",(0,t.jsx)(n.code,{children:"sgx_default_qcnl.conf"})," changes."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Other cloud providers: If you are using a different cloud service provider, consult their\nspecific documentation for the appropriate PCCS configuration and guidance on configuring the quote provider, or\nuse one of the other PCCS options."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"own-pccs",children:"Own PCCS"}),"\n",(0,t.jsxs)(n.p,{children:["It is also possible to run PCCS yourself. Follow ",(0,t.jsx)(n.a,{href:"https://www.intel.com/content/www/us/en/developer/articles/guide/intel-software-guard-extensions-data-center-attestation-primitives-quick-install-guide.html",children:"official Intel instructions"})," on how to setup your own PCCS."]}),"\n",(0,t.jsx)(n.h3,{id:"dcap-attestation-docker",children:"DCAP Attestation Docker"}),"\n",(0,t.jsxs)(n.p,{children:["Alternatively, an easy way to install and run the AESM service on a ",(0,t.jsx)(n.a,{href:"https://docs.docker.com/engine/",children:"Docker"}),"-enabled\nsystem is to use ",(0,t.jsx)(n.a,{href:"https://github.com/oasisprotocol/oasis-core/pkgs/container/aesmd",children:"our AESM container image"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Executing the following command should (always) pull the latest version of our\nAESMD Docker container, map the SGX devices and ",(0,t.jsx)(n.code,{children:"/var/run/aesmd"})," directory\nand ensure AESM is running in the background (also automatically started on boot):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"docker run \\\n --pull always \\\n --detach \\\n --restart always \\\n --device /dev/sgx_enclave \\\n --device /dev/sgx_provision \\\n --volume /var/run/aesmd:/var/run/aesmd \\\n --name aesmd \\\n ghcr.io/oasisprotocol/aesmd-dcap:master\n"})}),"\n",(0,t.jsxs)(n.p,{children:["By default, the Intel Quote Provider in the docker container is configured to use the Intel PCS endpoint.\nTo override the Intel Quote Provider configuration within the container mount your own custom configuration using\nthe ",(0,t.jsx)(n.code,{children:"volume"})," flag."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"docker run \\\n --pull always \\\n --detach \\\n --restart always \\\n --device /dev/sgx_enclave \\\n --device /dev/sgx_provision \\\n --volume /var/run/aesmd:/var/run/aesmd \\\n --volume /etc/sgx_default_qcnl.conf:/etc/sgx_default_qcnl.conf \\\n --name aesmd \\\n ghcr.io/oasisprotocol/aesmd-dcap:master\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The default Intel Quote Provider config is available in ",(0,t.jsx)(n.a,{href:"https://github.com/intel/SGXDataCenterAttestationPrimitives/blob/master/QuoteGeneration/qcnl/linux/sgx_default_qcnl.conf",children:"Intel SGX Github repository"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"multi-socket-systems",children:"Multi-socket Systems"}),"\n",(0,t.jsx)(n.p,{children:"Note that platform provisioning for multi-socket systems (e.g. systems with\nmultiple CPUs) is more complex, especially if one is using a hypervisor and\nrunning SGX workloads inside guest VMs. In this case additional provisioning may\nbe required to be performed on the host."}),"\n",(0,t.jsx)(n.p,{children:"Note that the system must be booted in UEFI mode for provisioning to work as the\nprovisioning process uses UEFI variables to communicate with the BIOS."}),"\n",(0,t.jsx)(n.h4,{id:"ubuntu-2204-1",children:"Ubuntu 22.04"}),"\n",(0,t.jsx)(n.p,{children:"To provision and register your multi-socket system you need to install the Intel\nSGX Multi-Package Registration Agent Service as follows (assuming Intel's SGX\napt repository has been added as discussed above):"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"sudo apt install sgx-ra-service\n"})}),"\n",(0,t.jsx)(n.h4,{id:"vmware-vsphere-80",children:"VMware vSphere 8.0+"}),"\n",(0,t.jsxs)(n.p,{children:["In order to enable SGX remote attestation on VMware vSphere-based systems,\nplease follow ",(0,t.jsx)(n.a,{href:"https://docs.vmware.com/en/VMware-vSphere/8.0/vsphere-vcenter-esxi-management/GUID-F16476FD-3B66-462F-B7FB-A456BEDC3549.html",children:"the vSphere guide"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"migrate-from-epid-attestation-to-dcap-attestation",children:"Migrate from EPID Attestation to DCAP Attestation"}),"\n",(0,t.jsx)(n.p,{children:"EPID attestation will be discontinued in 2025 and will no longer be available on\nany processors. All nodes using EPID attestation must migrate to DCAP\nattestation."}),"\n",(0,t.jsx)(n.p,{children:"For transitioning to the DCAP attestation, follow these steps:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["See if your system ",(0,t.jsx)(n.a,{href:"#aesm-service",children:"supports DCAP attestation"}),". If your hardware does not\nsupport DCAP attestation, you'll need to migrate your node to newer hardware."]}),"\n",(0,t.jsx)(n.li,{children:"Transition to DCAP attestation:"}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["In case you are running AESM service on Docker follow ",(0,t.jsx)(n.a,{href:"#dcap-attestation-docker",children:"these instructions"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Otherwise manually configure AESM service to use DCAP attestation:","\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Remove any leftover EPID attestation packages. If running on Ubuntu 22.04 run\nthe following command:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:" sudo apt remove libsgx-aesm-launch-plugin libsgx-aesm-epid-plugin\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["Configure AESM service to use ",(0,t.jsx)(n.a,{href:"#dcap-attestation",children:"DCAP attestation"})]}),"\n",(0,t.jsx)(n.li,{children:"Restart the AESM service. If running on Ubuntu 22.04 run the following\ncommand:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl restart aesmd.service\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"#configuring-the-quote-provider",children:"Configure the Quote Provider"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Use the ",(0,t.jsx)(n.a,{href:"#oasis-attestation-tool",children:"attestation tool"})," to test if your settings are correct."]}),"\n",(0,t.jsxs)(n.li,{children:["Restart your compute node and verify that node is ",(0,t.jsx)(n.code,{children:"ready"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"check-sgx-setup",children:"Check SGX Setup"}),"\n",(0,t.jsxs)(n.p,{children:["In order to make sure that your SGX setup is working, you can use the\n",(0,t.jsx)(n.code,{children:"sgx-detect"})," tool from the ",(0,t.jsx)(n.a,{href:"https://lib.rs/crates/sgxs-tools",children:"sgxs-tools"})," Rust\npackage."]}),"\n",(0,t.jsx)(n.p,{children:"There are no pre-built packages for it, so you will need to compile it yourself."}),"\n",(0,t.jsx)(n.h3,{id:"install-dependencies",children:"Install Dependencies"}),"\n",(0,t.jsx)(n.p,{children:"Make sure you have the following installed on your system:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://gcc.gnu.org",children:"GCC"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://github.com/protocolbuffers/protobuf",children:"Protobuf"})," compiler."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://www.freedesktop.org/wiki/Software/pkg-config",children:"pkg-config"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://www.openssl.org",children:"OpenSSL"})," development package."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"On Fedora, you can install all the above with:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"sudo dnf install gcc protobuf-compiler pkg-config openssl-devel\n"})}),"\n",(0,t.jsx)(n.p,{children:"On Ubuntu, you can install all the above with:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"sudo apt install gcc protobuf-compiler pkg-config libssl-dev\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"install-rust",children:["Install ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org",children:"Rust"})]}),"\n",(0,t.jsxs)(n.p,{children:["We follow ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org/tools/install",children:"Rust upstream's recommendation"}),"\non using ",(0,t.jsx)(n.a,{href:"https://rustup.rs",children:"rustup"})," to install and manage Rust versions."]}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"rustup cannot be installed alongside a distribution packaged Rust version. You\nwill need to remove it (if it's present) before you can start using rustup."})}),"\n",(0,t.jsx)(n.p,{children:"Install rustup by running:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["If you want to avoid directly executing a shell script fetched the internet, you\ncan also ",(0,t.jsxs)(n.a,{href:"https://rust-lang.github.io/rustup/installation/other.html",children:["download ",(0,t.jsx)(n.code,{children:"rustup-init"})," executable for your platform"]}),"\nand run it manually. This will run ",(0,t.jsx)(n.code,{children:"rustup-init"})," which will download and install\nthe latest stable version of Rust on your system."]})}),"\n",(0,t.jsx)(n.h3,{id:"build-and-install-sgxs-tools",children:"Build and Install sgxs-tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo install sgxs-tools\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"run-sgx-detect-tool",children:["Run ",(0,t.jsx)(n.code,{children:"sgx-detect"})," Tool"]}),"\n",(0,t.jsxs)(n.p,{children:["After the installation completes, run ",(0,t.jsx)(n.code,{children:"sgx-detect"})," to make sure that everything\nis set up correctly:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"sudo $(which sgx-detect)\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["If you don't run the ",(0,t.jsx)(n.code,{children:"sgx-detect"})," tool as ",(0,t.jsx)(n.code,{children:"root"}),", it might not have the\nnecessary permissions to access the SGX kernel device."]})}),"\n",(0,t.jsx)(n.p,{children:"When everything works, you should get output similar to the following (some\nthings depend on hardware features so your output may differ):"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"Detecting SGX, this may take a minute...\n\u2714 SGX instruction set\n \u2714 CPU support\n \u2714 CPU configuration\n \u2714 Enclave attributes\n \u2714 Enclave Page Cache\n SGX features\n \u2714 SGX2 \u2714 EXINFO \u2714 ENCLV \u2714 OVERSUB \u2714 KSS\n Total EPC size: 92.8MiB\n\u2718 Flexible launch control\n \u2714 CPU support\n \uff1f CPU configuration\n \u2718 Able to launch production mode enclave\n\u2714 SGX system software\n \u2714 SGX kernel device (/dev/sgx_enclave)\n \u2718 libsgx_enclave_common\n \u2714 AESM service\n \u2714 Able to launch enclaves\n \u2714 Debug mode\n \u2718 Production mode\n \u2714 Production mode (Intel whitelisted)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The important part is the checkbox under ",(0,t.jsx)(n.em,{children:"Able to launch enclaves"})," in both\n",(0,t.jsx)(n.em,{children:"Debug mode"})," and ",(0,t.jsx)(n.em,{children:"Production mode (Intel whitelisted)"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["In case you encounter errors, see the ",(0,t.jsx)(n.a,{href:"https://edp.fortanix.com/docs/installation/help/",children:"list of common SGX installation issues"}),"\nfor help."]}),"\n",(0,t.jsx)(n.h3,{id:"oasis-attestation-tool",children:"Oasis Attestation tool"}),"\n",(0,t.jsxs)(n.p,{children:["To test if your settings are correct, you may use the ",(0,t.jsx)(n.a,{href:"#oasis-attestation-tool",children:"attestation tool"}),"\n(",(0,t.jsx)(n.a,{href:"https://github.com/oasisprotocol/tools/releases",children:"binary"}),") for testing remote attestation against Intel SGX's\ndevelopment server."]}),"\n",(0,t.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,t.jsxs)(n.p,{children:["See ",(0,t.jsx)(n.a,{href:"/node/run-your-node/troubleshooting",children:"the general troubleshooting section"}),", before\nproceeding with ParaTime node-specific troubleshooting."]}),"\n",(0,t.jsx)(n.h3,{id:"aesm-could-not-be-contacted",children:"AESM could not be contacted"}),"\n",(0,t.jsxs)(n.p,{children:["If running ",(0,t.jsx)(n.code,{children:"sgx-detect --verbose"})," reports:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"\ud83d\udd6e SGX system software > AESM service\nAESM could not be contacted. AESM is needed for launching enclaves and generating attestations.\n\nPlease check your AESM installation.\n\ndebug: error communicating with aesm\ndebug: cause: Connection refused (os error 111)\n\nMore information: https://edp.fortanix.com/docs/installation/help/#aesm-service\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Ensure you have completed all the necessary installation steps outlined in\n",(0,t.jsx)(n.a,{href:"#dcap-attestation",children:"DCAP Attestation"})," section."]}),"\n",(0,t.jsx)(n.h3,{id:"aesm-error-30",children:"AESM: error 30"}),"\n",(0,t.jsx)(n.p,{children:"If you are encountering the following error message in your node's logs:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"failed to initialize TEE: error while getting quote info from AESMD: aesm: error 30\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Ensure you have all required SGX driver libraries installed as listed in\n",(0,t.jsx)(n.a,{href:"#dcap-attestation",children:"DCAP Attestation"})," section."]}),"\n",(0,t.jsx)(n.h3,{id:"permission-denied-when-accessing-sgx-kernel-device",children:"Permission Denied When Accessing SGX Kernel Device"}),"\n",(0,t.jsxs)(n.p,{children:["If running ",(0,t.jsx)(n.code,{children:"sgx-detect --verbose"})," reports:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"\ud83d\udd6e SGX system software > SGX kernel device\nPermission denied while opening the SGX device (/dev/sgx/enclave, /dev/sgx or\n/dev/isgx). Make sure you have the necessary permissions to create SGX enclaves.\nIf you are running in a container, make sure the device permissions are\ncorrectly set on the container.\n\ndebug: Error opening device: Permission denied (os error 13)\ndebug: cause: Permission denied (os error 13)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Ensure you are running the ",(0,t.jsx)(n.code,{children:"sgx-detect"})," tool as ",(0,t.jsx)(n.code,{children:"root"})," via:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"sudo $(which sgx-detect) --verbose\n"})}),"\n",(0,t.jsx)(n.h3,{id:"error-opening-sgx-kernel-device",children:"Error Opening SGX Kernel Device"}),"\n",(0,t.jsxs)(n.p,{children:["If running ",(0,t.jsx)(n.code,{children:"sgx-detect --verbose"})," reports:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'\ud83d\udd6e SGX system software > SGX kernel device\nThe SGX device (/dev/sgx/enclave, /dev/sgx or /dev/isgx) could not be opened:\n"/dev" mounted with `noexec` option.\n\ndebug: Error opening device: "/dev" mounted with `noexec` option\ndebug: cause: "/dev" mounted with `noexec` option\n'})}),"\n",(0,t.jsxs)(n.h4,{id:"ensure-dev-is-not-mounted-with-the-noexec-option",children:["Ensure ",(0,t.jsx)(n.code,{children:"/dev"})," is NOT Mounted with the ",(0,t.jsx)(n.code,{children:"noexec"})," Option"]}),"\n",(0,t.jsxs)(n.p,{children:["Some Linux distributions mount ",(0,t.jsx)(n.code,{children:"/dev"})," with the ",(0,t.jsx)(n.code,{children:"noexec"})," mount option. If that is\nthe case, it will prevent the enclave loader from mapping executable pages."]}),"\n",(0,t.jsxs)(n.p,{children:["Ensure your ",(0,t.jsx)(n.code,{children:"/dev"})," (i.e. ",(0,t.jsx)(n.code,{children:"devtmpfs"}),") is not mounted with the ",(0,t.jsx)(n.code,{children:"noexec"})," option.\nTo check that, use:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"cat /proc/mounts | grep devtmpfs\n"})}),"\n",(0,t.jsxs)(n.p,{children:["To temporarily remove the ",(0,t.jsx)(n.code,{children:"noexec"})," mount option for ",(0,t.jsx)(n.code,{children:"/dev"}),", run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"sudo mount -o remount,exec /dev\n"})}),"\n",(0,t.jsxs)(n.p,{children:["To permanently remove the ",(0,t.jsx)(n.code,{children:"noexec"})," mount option for ",(0,t.jsx)(n.code,{children:"/dev"}),", add the following to\nthe system's ",(0,t.jsx)(n.code,{children:"/etc/fstab"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"devtmpfs /dev devtmpfs defaults,exec 0 0\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsxs)(n.p,{children:["This is the recommended way to modify mount options for virtual (i.e. API) file\nsystem as described in ",(0,t.jsx)(n.a,{href:"https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems/",children:"systemd's API File Systems"}),"\ndocumentation."]})}),"\n",(0,t.jsx)(n.h3,{id:"unable-to-launch-enclaves-operation-not-permitted",children:"Unable to Launch Enclaves: Operation not permitted"}),"\n",(0,t.jsxs)(n.p,{children:["If running ",(0,t.jsx)(n.code,{children:"sgx-detect --verbose"})," reports:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"\ud83d\udd6e SGX system software > Able to launch enclaves > Debug mode\nThe enclave could not be launched.\n\ndebug: failed to load report enclave\ndebug: cause: failed to load report enclave\ndebug: cause: Failed to map enclave into memory.\ndebug: cause: Operation not permitted (os error 1)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Ensure your system's ",(0,t.jsxs)(n.a,{href:"#ensure-dev-is-not-mounted-with-the-noexec-option",children:[(0,t.jsx)(n.code,{children:"/dev"})," is NOT mounted with the ",(0,t.jsx)(n.code,{children:"noexec"})," mount option"]}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"unable-to-launch-enclaves-invalid-argument",children:"Unable to Launch Enclaves: Invalid argument"}),"\n",(0,t.jsxs)(n.p,{children:["If running ",(0,t.jsx)(n.code,{children:"sgx-detect --verbose"})," reports:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"\ud83d\udd6e SGX system software > Able to launch enclaves > Debug mode\nThe enclave could not be launched.\n\ndebug: failed to load report enclave\ndebug: cause: Failed to call EINIT.\ndebug: cause: I/O ctl failed.\ndebug: cause: Invalid argument (os error 22)\n"})}),"\n",(0,t.jsx)(n.p,{children:"This may be related to a bug in the Linux kernel when attempting to run enclaves\non certain hardware configurations. Upgrading the Linux kernel to a version\nequal to or greater than 6.5.0 may solve the issue."}),"\n",(0,t.jsx)(n.h3,{id:"couldnt-find-the-platform-library",children:"Couldn't find the platform library"}),"\n",(0,t.jsx)(n.p,{children:"If AESMD service log reports:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"[read_persistent_data ../qe_logic.cpp:1084] Couldn't find the platform library. (null)\n[get_platform_quote_cert_data ../qe_logic.cpp:438] Couldn't load the platform library. (null)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["It may be that the ",(0,t.jsx)(n.a,{href:"#configuring-the-quote-provider",children:"DCAP quote provider"})," is misconfigured or the configuration\nfile is not a valid JSON file but is malformed. Double-check that its\nconfiguration file (e.g. ",(0,t.jsx)(n.code,{children:"/etc/sgx_default_qcnl.conf"}),") is correct."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>l});var t=s(6540);const i={},o=t.createContext(i);function r(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/71d6bec9.bebaaf63.js b/assets/js/71d6bec9.bebaaf63.js
new file mode 100644
index 0000000000..3a3e70eb51
--- /dev/null
+++ b/assets/js/71d6bec9.bebaaf63.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[1894],{5381:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>r,contentTitle:()=>c,default:()=>s,frontMatter:()=>a,metadata:()=>i,toc:()=>g});var d=n(4848),l=n(8453);const a={},c="Integrating BAND Oracle",i={id:"dapp/tools/band",title:"Integrating BAND Oracle",description:"This guide will explain how to query the Band Protocol reference data smart",source:"@site/docs/dapp/tools/band.md",sourceDirName:"dapp/tools",slug:"/dapp/tools/band",permalink:"/dapp/tools/band",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/dapp/tools/band.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"developers",previous:{title:"Tools & Services",permalink:"/dapp/tools/"}},r={},g=[{value:"What is the Band Protocol?",id:"what-is-the-band-protocol",level:3},{value:"Deploy Oracle",id:"deploy-oracle",level:3},{value:"Get Rates",id:"get-rates",level:3},{value:"Mainnet Reference Data Contract",id:"mainnet-reference-data-contract",level:3},{value:"Available Reference Data",id:"available-reference-data",level:3},{value:"Example of DemoOracle.sol contract",id:"example-of-demooraclesol-contract",level:3},{value:"Bandchain.js",id:"bandchain",level:3}];function o(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",...(0,l.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(t.h1,{id:"integrating-band-oracle",children:"Integrating BAND Oracle"}),"\n",(0,d.jsx)("p",{style:{width:"100%"},children:(0,d.jsx)("iframe",{style:{margin:"auto",display:"block"},width:"560",height:"315",src:"https://www.youtube.com/embed/cwe6P5MvIfk?si=4QFRA8yJ2PCZB5fq",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:!0})}),"\n",(0,d.jsxs)(t.p,{children:["This guide will explain how to query the Band Protocol reference data smart\ncontract from another Solidity smart contract on Oasis Sapphire, a confidential\nEVM-compatible ",(0,d.jsx)(t.a,{href:"/general/oasis-network/faq#how-is-a-paratime-different-from-a-parachain",children:"Paratime"}),"."]}),"\n",(0,d.jsx)(t.admonition,{type:"tip",children:(0,d.jsxs)(t.p,{children:["You can follow the same steps to integrate with Band on Oasis ",(0,d.jsx)(t.a,{href:"/dapp/emerald",children:"Emerald"}),"\n, a non-confidential EVM. See Band ",(0,d.jsx)(t.a,{href:"https://docs.bandchain.org/develop/supported-blockchains",children:"documentation"}),"\nfor full list of deployed contract addresses."]})}),"\n",(0,d.jsx)(t.h3,{id:"what-is-the-band-protocol",children:"What is the Band Protocol?"}),"\n",(0,d.jsxs)(t.p,{children:[(0,d.jsx)(t.a,{href:"https://bandprotocol.com",children:"Band Protocol"})," is a cross-chain data oracle\nplatform that aggregates and connects real-world data and APIs to smart\ncontracts. You can read more about details of the protocol\n",(0,d.jsx)(t.a,{href:"https://docs.bandchain.org",children:"here"}),"."]}),"\n",(0,d.jsx)(t.h3,{id:"deploy-oracle",children:"Deploy Oracle"}),"\n",(0,d.jsxs)(t.ol,{children:["\n",(0,d.jsxs)(t.li,{children:["Follow ",(0,d.jsx)(t.a,{href:"https://remix.ethereum.org/?#code=cHJhZ21hIHNvbGlkaXR5IDAuNi4xMTsKcHJhZ21hIGV4cGVyaW1lbnRhbCBBQklFbmNvZGVyVjI7CgppbnRlcmZhY2UgSVN0ZFJlZmVyZW5jZSB7CiAgICAvLy8gQSBzdHJ1Y3R1cmUgcmV0dXJuZWQgd2hlbmV2ZXIgc29tZW9uZSByZXF1ZXN0cyBmb3Igc3RhbmRhcmQgcmVmZXJlbmNlIGRhdGEuCiAgICBzdHJ1Y3QgUmVmZXJlbmNlRGF0YSB7CiAgICAgICAgdWludDI1NiByYXRlOyAvLyBiYXNlL3F1b3RlIGV4Y2hhbmdlIHJhdGUsIG11bHRpcGxpZWQgYnkgMWUxOC4KICAgICAgICB1aW50MjU2IGxhc3RVcGRhdGVkQmFzZTsgLy8gVU5JWCBlcG9jaCBvZiB0aGUgbGFzdCB0aW1lIHdoZW4gYmFzZSBwcmljZSBnZXRzIHVwZGF0ZWQuCiAgICAgICAgdWludDI1NiBsYXN0VXBkYXRlZFF1b3RlOyAvLyBVTklYIGVwb2NoIG9mIHRoZSBsYXN0IHRpbWUgd2hlbiBxdW90ZSBwcmljZSBnZXRzIHVwZGF0ZWQuCiAgICB9CgogICAgLy8vIFJldHVybnMgdGhlIHByaWNlIGRhdGEgZm9yIHRoZSBnaXZlbiBiYXNlL3F1b3RlIHBhaXIuIFJldmVydCBpZiBub3QgYXZhaWxhYmxlLgogICAgZnVuY3Rpb24gZ2V0UmVmZXJlbmNlRGF0YShzdHJpbmcgbWVtb3J5IF9iYXNlLCBzdHJpbmcgbWVtb3J5IF9xdW90ZSkKICAgICAgICBleHRlcm5hbAogICAgICAgIHZpZXcKICAgICAgICByZXR1cm5zIChSZWZlcmVuY2VEYXRhIG1lbW9yeSk7CgogICAgLy8vIFNpbWlsYXIgdG8gZ2V0UmVmZXJlbmNlRGF0YSwgYnV0IHdpdGggbXVsdGlwbGUgYmFzZS9xdW90ZSBwYWlycyBhdCBvbmNlLgogICAgZnVuY3Rpb24gZ2V0UmVmZXJlbmNlRGF0YUJ1bGsoc3RyaW5nW10gbWVtb3J5IF9iYXNlcywgc3RyaW5nW10gbWVtb3J5IF9xdW90ZXMpCiAgICAgICAgZXh0ZXJuYWwKICAgICAgICB2aWV3CiAgICAgICAgcmV0dXJucyAoUmVmZXJlbmNlRGF0YVtdIG1lbW9yeSk7Cn0KCmNvbnRyYWN0IERlbW9PcmFjbGUgewogICAgSVN0ZFJlZmVyZW5jZSByZWY7CgogICAgdWludDI1NiBwdWJsaWMgcHJpY2U7CgogICAgY29uc3RydWN0b3IoSVN0ZFJlZmVyZW5jZSBfcmVmKSBwdWJsaWMgewogICAgICAgIHJlZiA9IF9yZWY7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0UHJpY2UoKSBleHRlcm5hbCB2aWV3IHJldHVybnMgKHVpbnQyNTYpewogICAgICAgIElTdGRSZWZlcmVuY2UuUmVmZXJlbmNlRGF0YSBtZW1vcnkgZGF0YSA9IHJlZi5nZXRSZWZlcmVuY2VEYXRhKCJXQlRDIiwiVVNEIik7CiAgICAgICAgcmV0dXJuIGRhdGEucmF0ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRNdWx0aVByaWNlcygpIGV4dGVybmFsIHZpZXcgcmV0dXJucyAodWludDI1NltdIG1lbW9yeSl7CiAgICAgICAgc3RyaW5nW10gbWVtb3J5IGJhc2VTeW1ib2xzID0gbmV3IHN0cmluZ1tdKDIpOwogICAgICAgIGJhc2VTeW1ib2xzWzBdID0gIldCVEMiOwogICAgICAgIGJhc2VTeW1ib2xzWzFdID0gIkVUSCI7CgogICAgICAgIHN0cmluZ1tdIG1lbW9yeSBxdW90ZVN5bWJvbHMgPSBuZXcgc3RyaW5nW10oMik7CiAgICAgICAgcXVvdGVTeW1ib2xzWzBdID0gIlVTRCI7CiAgICAgICAgcXVvdGVTeW1ib2xzWzFdID0gIlVTRCI7CiAgICAgICAgSVN0ZFJlZmVyZW5jZS5SZWZlcmVuY2VEYXRhW10gbWVtb3J5IGRhdGEgPSByZWYuZ2V0UmVmZXJlbmNlRGF0YUJ1bGsoYmFzZVN5bWJvbHMscXVvdGVTeW1ib2xzKTsKCiAgICAgICAgdWludDI1NltdIG1lbW9yeSBwcmljZXMgPSBuZXcgdWludDI1NltdKDIpOwogICAgICAgIHByaWNlc1swXSA9IGRhdGFbMF0ucmF0ZTsKICAgICAgICBwcmljZXNbMV0gPSBkYXRhWzFdLnJhdGU7CgogICAgICAgIHJldHVybiBwcmljZXM7CiAgICB9CgogICAgZnVuY3Rpb24gc2F2ZVByaWNlKHN0cmluZyBtZW1vcnkgYmFzZSwgc3RyaW5nIG1lbW9yeSBxdW90ZSkgZXh0ZXJuYWwgewogICAgICAgIElTdGRSZWZlcmVuY2UuUmVmZXJlbmNlRGF0YSBtZW1vcnkgZGF0YSA9IHJlZi5nZXRSZWZlcmVuY2VEYXRhKGJhc2UscXVvdGUpOwogICAgICAgIHByaWNlID0gZGF0YS5yYXRlOwogICAgfQp9Cg==",children:"this link"})," to Remix. The link contains an encoded\nexample ",(0,d.jsx)(t.code,{children:"DemoOracle.sol"})," contract."]}),"\n",(0,d.jsxs)(t.li,{children:["Compile the contract with compiler version ",(0,d.jsx)(t.code,{children:"0.6.11"}),"."]}),"\n",(0,d.jsxs)(t.li,{children:["Switch to the Deploy tab of Remix.","\n",(0,d.jsxs)(t.ol,{children:["\n",(0,d.jsx)(t.li,{children:'Select "Injected Web3" in the Environment dropdown in the top left to\nconnect Metamask.'}),"\n",(0,d.jsxs)(t.li,{children:["Make sure that Metamask is connected to the Sapphire Paratime\n(Testnet/Mainnet) network. You can read about adding a network to Metamask ",(0,d.jsx)(t.a,{href:"../../general/manage-tokens/#metamask",children:"here"}),"."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,d.jsx)(t.p,{children:(0,d.jsx)(t.img,{alt:"Setting up the environment in Remix",src:n(1078).A+"",width:"756",height:"558"})}),"\n",(0,d.jsxs)(t.ol,{start:"4",children:["\n",(0,d.jsxs)(t.li,{children:["Enter the Testnet Band reference data aggregator contract address\n(",(0,d.jsx)(t.code,{children:"0x61704EFB8b8120c03C210cAC5f5193BF8c80852a"}),") to the ",(0,d.jsx)(t.code,{children:"DemoOracle"})," constructor\nand deploy the contract. You can access the reference data aggregator contract\non the Sapphire Mainnet at ",(0,d.jsx)(t.code,{children:"0xDA7a001b254CD22e46d3eAB04d937489c93174C3"}),"."]}),"\n"]}),"\n",(0,d.jsx)(t.p,{children:(0,d.jsx)(t.img,{alt:"Deploying DemoOracle",src:n(766).A+"",width:"1314",height:"1439"})}),"\n",(0,d.jsx)(t.p,{children:"An interface to interact with the contract will appear in the bottom left\ncorner of Remix."}),"\n",(0,d.jsx)(t.h3,{id:"get-rates",children:"Get Rates"}),"\n",(0,d.jsxs)(t.p,{children:["Clicking the ",(0,d.jsx)(t.code,{children:"getPrice"})," button will return the current price of WBTC in USD.\nThis function calls ",(0,d.jsx)(t.code,{children:"getReferenceData(string memory _base, string memory _quote)"}),'\non the Band reference data contract, passing "WBTC" and "USD", indicating WBTC\nas the base and USD as the quote. The rate returned is base/quote multiplied by\n1e18.']}),"\n",(0,d.jsx)(t.p,{children:(0,d.jsx)(t.img,{alt:"Get Rates",src:n(4841).A+"",width:"1690",height:"1234"})}),"\n",(0,d.jsxs)(t.p,{children:["Note that the ",(0,d.jsx)(t.code,{children:"DemoOracle"})," contract only returns the latest rate, but the\nreference contract also returns values of the last time the base and quote\nreferences were updated."]}),"\n",(0,d.jsxs)(t.p,{children:["The price is offset by 1e18. The returned value at the time of testing is\n",(0,d.jsx)(t.code,{children:"39567000000000000000000"}),". Multiplying by 1e-18 gives the current USD price\ngiven by the reference contract, 39567.00 WBTC/USD."]}),"\n",(0,d.jsxs)(t.p,{children:["Clicking the ",(0,d.jsx)(t.code,{children:"getMultiPrices"})," button returns multiple quotes in the same call,\nWBTC/USD and ETH/USD in this case. This function calls\n",(0,d.jsx)(t.code,{children:"getReferenceDataBulk(string[] memory _bases, string[] memory _quotes)"}),' on the\nBand reference data contract, passing "WBTC" and "ETH" as the base and "USD"\nfor the quote. This will return the current WBTC and ETH prices in USD, as an\narray of integers. The call also returns just the exchange rates (multipilied\nby 1e18), but can be modified to return the last updated times for the bases\nand quotes.']}),"\n",(0,d.jsxs)(t.p,{children:["The ",(0,d.jsx)(t.code,{children:"savePrice"})," function will save any base/quote rate that is passed to it in\nthe storage variable named ",(0,d.jsx)(t.code,{children:"price"}),". This storage data will only be updated when\nthe \u201csavePrice\u201d function is called, so the saved ",(0,d.jsx)(t.code,{children:"price"})," value will go stale\nunless this function is called repeatedly."]}),"\n",(0,d.jsx)(t.p,{children:(0,d.jsx)(t.img,{alt:"Save Price",src:n(6211).A+"",width:"343",height:"447"})}),"\n",(0,d.jsx)(t.h3,{id:"mainnet-reference-data-contract",children:"Mainnet Reference Data Contract"}),"\n",(0,d.jsxs)(t.p,{children:["You can access the reference data aggregator contract on the Sapphire Mainnet\nat ",(0,d.jsx)(t.a,{href:"https://explorer.oasis.io/mainnet/sapphire/address/0xDA7a001b254CD22e46d3eAB04d937489c93174C3",children:"0xDA7a001b254CD22e46d3eAB04d937489c93174C3"}),"."]}),"\n",(0,d.jsx)(t.h3,{id:"available-reference-data",children:"Available Reference Data"}),"\n",(0,d.jsxs)(t.p,{children:["You can view the available reference data on the ",(0,d.jsx)(t.a,{href:"https://data.bandprotocol.com/",children:"Band Standard Dataset site here"}),"."]}),"\n",(0,d.jsx)(t.h3,{id:"example-of-demooraclesol-contract",children:"Example of DemoOracle.sol contract"}),"\n",(0,d.jsx)(t.p,{children:(0,d.jsx)(t.a,{href:"https://remix.ethereum.org/?#code=cHJhZ21hIHNvbGlkaXR5IDAuNi4xMTsKcHJhZ21hIGV4cGVyaW1lbnRhbCBBQklFbmNvZGVyVjI7CgppbnRlcmZhY2UgSVN0ZFJlZmVyZW5jZSB7CiAgICAvLy8gQSBzdHJ1Y3R1cmUgcmV0dXJuZWQgd2hlbmV2ZXIgc29tZW9uZSByZXF1ZXN0cyBmb3Igc3RhbmRhcmQgcmVmZXJlbmNlIGRhdGEuCiAgICBzdHJ1Y3QgUmVmZXJlbmNlRGF0YSB7CiAgICAgICAgdWludDI1NiByYXRlOyAvLyBiYXNlL3F1b3RlIGV4Y2hhbmdlIHJhdGUsIG11bHRpcGxpZWQgYnkgMWUxOC4KICAgICAgICB1aW50MjU2IGxhc3RVcGRhdGVkQmFzZTsgLy8gVU5JWCBlcG9jaCBvZiB0aGUgbGFzdCB0aW1lIHdoZW4gYmFzZSBwcmljZSBnZXRzIHVwZGF0ZWQuCiAgICAgICAgdWludDI1NiBsYXN0VXBkYXRlZFF1b3RlOyAvLyBVTklYIGVwb2NoIG9mIHRoZSBsYXN0IHRpbWUgd2hlbiBxdW90ZSBwcmljZSBnZXRzIHVwZGF0ZWQuCiAgICB9CgogICAgLy8vIFJldHVybnMgdGhlIHByaWNlIGRhdGEgZm9yIHRoZSBnaXZlbiBiYXNlL3F1b3RlIHBhaXIuIFJldmVydCBpZiBub3QgYXZhaWxhYmxlLgogICAgZnVuY3Rpb24gZ2V0UmVmZXJlbmNlRGF0YShzdHJpbmcgbWVtb3J5IF9iYXNlLCBzdHJpbmcgbWVtb3J5IF9xdW90ZSkKICAgICAgICBleHRlcm5hbAogICAgICAgIHZpZXcKICAgICAgICByZXR1cm5zIChSZWZlcmVuY2VEYXRhIG1lbW9yeSk7CgogICAgLy8vIFNpbWlsYXIgdG8gZ2V0UmVmZXJlbmNlRGF0YSwgYnV0IHdpdGggbXVsdGlwbGUgYmFzZS9xdW90ZSBwYWlycyBhdCBvbmNlLgogICAgZnVuY3Rpb24gZ2V0UmVmZXJlbmNlRGF0YUJ1bGsoc3RyaW5nW10gbWVtb3J5IF9iYXNlcywgc3RyaW5nW10gbWVtb3J5IF9xdW90ZXMpCiAgICAgICAgZXh0ZXJuYWwKICAgICAgICB2aWV3CiAgICAgICAgcmV0dXJucyAoUmVmZXJlbmNlRGF0YVtdIG1lbW9yeSk7Cn0KCmNvbnRyYWN0IERlbW9PcmFjbGUgewogICAgSVN0ZFJlZmVyZW5jZSByZWY7CgogICAgdWludDI1NiBwdWJsaWMgcHJpY2U7CgogICAgY29uc3RydWN0b3IoSVN0ZFJlZmVyZW5jZSBfcmVmKSBwdWJsaWMgewogICAgICAgIHJlZiA9IF9yZWY7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0UHJpY2UoKSBleHRlcm5hbCB2aWV3IHJldHVybnMgKHVpbnQyNTYpewogICAgICAgIElTdGRSZWZlcmVuY2UuUmVmZXJlbmNlRGF0YSBtZW1vcnkgZGF0YSA9IHJlZi5nZXRSZWZlcmVuY2VEYXRhKCJXQlRDIiwiVVNEIik7CiAgICAgICAgcmV0dXJuIGRhdGEucmF0ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRNdWx0aVByaWNlcygpIGV4dGVybmFsIHZpZXcgcmV0dXJucyAodWludDI1NltdIG1lbW9yeSl7CiAgICAgICAgc3RyaW5nW10gbWVtb3J5IGJhc2VTeW1ib2xzID0gbmV3IHN0cmluZ1tdKDIpOwogICAgICAgIGJhc2VTeW1ib2xzWzBdID0gIldCVEMiOwogICAgICAgIGJhc2VTeW1ib2xzWzFdID0gIkVUSCI7CgogICAgICAgIHN0cmluZ1tdIG1lbW9yeSBxdW90ZVN5bWJvbHMgPSBuZXcgc3RyaW5nW10oMik7CiAgICAgICAgcXVvdGVTeW1ib2xzWzBdID0gIlVTRCI7CiAgICAgICAgcXVvdGVTeW1ib2xzWzFdID0gIlVTRCI7CiAgICAgICAgSVN0ZFJlZmVyZW5jZS5SZWZlcmVuY2VEYXRhW10gbWVtb3J5IGRhdGEgPSByZWYuZ2V0UmVmZXJlbmNlRGF0YUJ1bGsoYmFzZVN5bWJvbHMscXVvdGVTeW1ib2xzKTsKCiAgICAgICAgdWludDI1NltdIG1lbW9yeSBwcmljZXMgPSBuZXcgdWludDI1NltdKDIpOwogICAgICAgIHByaWNlc1swXSA9IGRhdGFbMF0ucmF0ZTsKICAgICAgICBwcmljZXNbMV0gPSBkYXRhWzFdLnJhdGU7CgogICAgICAgIHJldHVybiBwcmljZXM7CiAgICB9CgogICAgZnVuY3Rpb24gc2F2ZVByaWNlKHN0cmluZyBtZW1vcnkgYmFzZSwgc3RyaW5nIG1lbW9yeSBxdW90ZSkgZXh0ZXJuYWwgewogICAgICAgIElTdGRSZWZlcmVuY2UuUmVmZXJlbmNlRGF0YSBtZW1vcnkgZGF0YSA9IHJlZi5nZXRSZWZlcmVuY2VEYXRhKGJhc2UscXVvdGUpOwogICAgICAgIHByaWNlID0gZGF0YS5yYXRlOwogICAgfQp9Cg==",children:"DemoOracle.sol contract example in Remix"})}),"\n",(0,d.jsx)(t.h3,{id:"bandchain",children:"Bandchain.js"}),"\n",(0,d.jsxs)(t.p,{children:["Band also has a JavaScript library that makes it easy to interact with BandChain\ndirectly from JavaScript or TypeScript applications. The library provides\nclasses and methods for convenient to send transactions, query data,\nOBI encoding, and wallet management. You can read more about it ",(0,d.jsx)(t.a,{href:"https://docs.bandchain.org/develop/developer-tools/bandchain.js/getting-started",children:"here"}),"."]})]})}function s(e={}){const{wrapper:t}={...(0,l.R)(),...e.components};return t?(0,d.jsx)(t,{...e,children:(0,d.jsx)(o,{...e})}):o(e)}},1078:(e,t,n)=>{n.d(t,{A:()=>d});const d=n.p+"assets/images/band_demooracle_smartcontract-33de5c1550770b2f65357831fc13c6e1.png"},766:(e,t,n)=>{n.d(t,{A:()=>d});const d=n.p+"assets/images/band_deploy_demooracle_smartcontact-bcfd8510f590412a0eb3af8025b8a9dc.png"},4841:(e,t,n)=>{n.d(t,{A:()=>d});const d=n.p+"assets/images/band_get_rates-1172d264b2dcff4f0841da0e3f8a9d53.png"},6211:(e,t,n)=>{n.d(t,{A:()=>d});const d="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVcAAAG/CAMAAADb+GTFAAAC9FBMVEX////+/v/9/f38+/v9+ff6+fv4+Pr89vT29vj19fj68ezx8/bz8vTv8PP47OTs7vLs6+7n6/D2593p6Ov149ng5uzk4+fy283b4eje3+ng3+PY3+bc3OPZ2uXb2t7S2+Lu0b7V1uHV1dnrzLbL1N3Q0dzR0dbpx63MzdjE0NnMy9G8ytXGxs/mvJ+6yNPBws7Cwce0xNDitJO8vMSsvcu3t8Gzs7zdqIGjtsSvr7jaoXedscCrq7OXrb2lprCVq7zXmWuioquQp7meoK7UkWGNpLaenqibm6bTjVqIobSamqSVmq2UmazRiVaTmKuTl6qXlqGDnbCRlqnQh1GQlKePlKfPhE2Ok6aSkp1+ma2KkrCNkqWMkaTOgEiLkKOKj6KOjpmGjqyKjqGJjaCNjJd3k6iIjJ+Hi57Lej6Fi52EipyHiZmIiZSBiaWCh5rJdTh+hqKBhpiFhZBujKLGcziAhJd+g5V9gpTBcTiBgYx7gZR3gJxoh596gJN5f5G7bjh4fpFkhZy3bTl3fI96eoezazl1eo12eYlfgZlxeJRzeIt1doRydoludZBvdIdzc4CpZTlvc4dYe5RucoWkYzlub3xpb4lrboJTd5FqbYBmbIebXzpoa31ma35panhlan1lanxiaYNMcY1jaHthZ4BiZnpiZnllZXRhZXmOWjpgY3ddYntfYnVhYXBEa4heYXSHVjpaX3hAaIVbXnFaXW+BUztbXWtWXHRYXG5VXHNVW3NWWm15UDtVWWo6YoFUV2tTVWo2X35UVGNSVGg0Xn1QU2Y0XXtPUmROUWRrSTtLUGROT19LT2JJTWFJTWBkRTxKS1xIS19hRDxGSV1HSVlFSFtbQjxGRldERllCRFtCRFgwSmVDQ1RBQ1dBQ1Y/Q1RQPT0+QVQ9QFJMOz47PlI6PU84O083OU04OUpCNj43OUs1N0s1N0o0NkkzNUcyNEY3Mj8wMkUvMUQuL0MxLj8tLkIsLUErKz8pKz8oKT0kJDgiIzaxBVQFAAAeS0lEQVR42uzYb0gbZxzA8ecSLlxBIXCQF0HyIi/yQvpCCApCKPjGFxqSECyVq2y1lRaLFSt04krLoFJopx0isUxat7CVjpYwSosdQnGkFEudYNHRP9iJYkxomxwazntyvzf73V2txfSP6xJIyvMF77x77nmSfDgOEkK3WwLW/2iJvhNhrsy1tGOuzLWcYq7MtZxirsy1nPo814lYbFqDvFJx+GBaPLN11fc4t+zTHk1OJgvtSiw8RxwzsKOQDT4c3wF68QrCE1tkx+C9GOSX689CyTZ6OhptTxba9QcEEq3yf3dd4asyoHobdgxWuyC/NJmB0mw5OiYNRaM9p6M3C+4KWd6L80O+OEDHTG/99TeuT5oaZiDeCgCLjZoWqT+kASRC+xZMV59VBSO5yzcOMN0V39evQa+9sjESGY948co6XAi03rrWOR+pa8zqK+SgxFrrGZ00OlEEV3A7YMIiurgY2HjBQXyG63Wu0k764yQGUG0Hj9UjVOFNyjutnOHqcoNRSuCdxAshjq/iRagTeE/IbeXcry0Oj7UeQCRVlU43cXrSTmGv3Q2l1tCs9gzkJPSsFsG1pgJED+5qwGYH8HGa7iq68IwNRDcoXNc4WYR1TvbyGvQTw7VyLxjVGqeWQug/TmTjOeC2ZNEboLESR+L4r/4c0MgAQBpKraHZDQkmo8VxdTnBIojiHgFs9QAzJK67cq0AESL3c5kmXvMRURS5DocbIGferx4XGJmnekM8gEomTFd9qNXtECxQZ3v7fK3mnE0l9xwoqusK5wOrd2FhYRFse3XMFd2VR+JDRNNs+yrrocEyh+NZtwOvJoZrA5cCTDNPRXCG6epEV6QeJ4emGywQ4nTKDInjNt4guKDUKpZrvzzXYavIgVuYgFgH2PjrK04BYmQGPEJ8zi4C+CxcGmZI/bpav97EDcjVpqtSWRHJxJzeVv2URd1yDVkXc7prL1lM2S2wQLxyvBdstZrakINaAUqtYrliQk0WIO0knKUJbC4LEe4BOEit4iTEntBvNg8AdFkJEZegmiNOvgv0Ui6ecI4FqOGIbRy2XGWR7NFdVVyvyoK+eJEPmnjSJHIWYQBKrUK75pdDQ7C1Qgb0MiraKIBNkLjpqBpXrcN2CQ0wLQPvJqtgtP5mn9L0a1I4NQWl19AsJEHNFs8VM1135hbhC27sQtSoPV1U14En+adK9btSQdqYmjSaZ79n7agkf89iMdedMddyjrky13KKuTLXcoq5Mtdyirky13Jq165ajrI+WE77XFfG+nHYz3WlrI/GXJlrOcVcmWs5xVyZaznFXJlrOcVcd9mopNceVeinY667blkau3VrTBqShnYBy1x33TPpmbG5L92in4y57v4ZYLjiTdtzgX6yAri+2t4ZvQwGg4dHNig9HMSWhy9TLBGkNHvpQODkPB781R04OLJJp3C4+w+KXTxPMWW4zd82RQdvU8ycTM25K/Rx0EgfWjvqb/tHPf4LTui8oR+3JOkxY9CcJFOzwSA2vfptsO0KvuR+/0mZKoMt4fOyuQLVWz5CD4fDLRcTdOoc1btxxH/UeJH8Z8CY7ppsR9/3uz66jxv17osCud6UblLsrvQrNVvzb8r3vjm4QcPGUueaX+K2r5mqnWdeKn8G5+nD4ANl7dRJerubbs4Hn1OaDgSTFMdPrWYfD9Kz1yhmTjaBwsiuKD9+pygqHn516fXP4c3VwAN6tlM/PtacwFFlzb9Mw8/pduY6x4c3EvsfpQN3kn199Grna7lv5M0KFOu7QsPLNDPSrb8Z7HLbi82nB67RZDjvGWD8GV14r+srSbpL1VHpRIFcT0sIi6xSz1tXirX9ju/YcD2Kd8Lzr5vpbFD/KFeO0yO/4T7rf2p8lLb7+GkGR4YpnQ0o2x7GZLP1wGogg/ur5h2VDOBm/9/0gX8wrJ/+6WwgYdzzZ3DSizzXU5fpesvDO/hS6WZ6o1NRzwxvrYD5V+m/7NxPSBtZHAfw6UYI5DAHEUIOgYRQ9KAIljbUgxQUKjuzeWUatdQ/CwrZxFKnQqtQ0F0IWLCtsHgosi0IhdItQg4R1kVKBRF70AUJAVewRakGfLGShJjfcX8vY6Z142ICydbB94WZ0Zn3h/fh8UtyGTbR64DmmpLY6iMyIHSxrqxU/IHHnyVyjd1DWGS9u3vMdWwClM7e3gAEQ20fIbAsQbgPMAttQFYA0/k23PF6ekBJQZrs7pEkhHu/9tA6s7wMwviLL65RL9ujCwBPpHUA2PAmsq4xJAKly+d7qLt6fT7f/o5MpAeZF6zQSAfpLtmjfNZHgISUBqXH55U2NdcdKZO9+3lksnjXDKIiLZTAVYfVWXXXkWegzEUiUQiG5wZWekGCZQ8wnQD0sKp4KEfC3l+H5H3AJaVSQ2+057qr1hmTUdZTH8ih7rqpsOq7DCmvBzd5quMvyLoG2VMlvLoa1V3HV1dX08OB+Zdk7dUoziilQ95QuOtFbgRckox95qNLg0d1IClt4TkqZSYGi3eF9N3bt59CyVwRVmfVXQ+Vd7k6EIYOsoqucekDAAQmIDiI14iUZEsZHwLokGRZ9uLz9ZPqwAJ7Ks3prvtSCoB8gPHAjhyBabm/X/Ktwyd5F06sAzKiTzx56wPY9kB/CGC5MzcCYC9toriUyrqCl5WoqR6Yk7/9fmWwyHrMdX+k7fCL69IwoCsMPkjhpvwIUc8aJPpHgS1lX95caQNM5xIMDBzA1ti/XfvmGW6X7gq9b2BBgfdyDEJKYmtxcVEO7cPDMci57kUgsocnbZy+WUj/NHUgb8D4KEwGMzAZOBoBk5YS2YnCSkZzfdW2C5+8YfisfPP6ypJMwFfKEvGQkTiA4iGEbKMrhrkmh4mn6z1T6iTklzTMsqVMDg68BsxMIPucvIRRyePxzGmdAdZZCYAMieium15C1g7ILAAMsFusDmzJe7prmAAJ4UlzXfuRkOEkzHo8PXsQ7yck8FEbAVhIFBSikMAKzLJZx+CZQrzTALCd56r93mK5+7TM3weKT0K/npwDKCQHRc+pX9LpYyNMTP5X83xX3JBa7v19+vfXc/57a6cLCkleDTg159wVUlBI8mrAqTnvroUlrwacGu5abLjrqeGuRgx35a5GCnflrkYKd+WuRgp35a5GCnflrkYKd+WuRgp35a5GCnflrkYKd+WuRgp35a5GCnflrkYKd+WuRgp35a5GCnflrkYKd+WuRgp35a5GCnflrkZKCVx/u6+WO8k4PYOJJ8vp+vvPatlzJlkRtpyu99Xyh57RlNNV5a7clbtyV+7KXbkrd+WuZ8S1ymQyVbpVFrODu5bMVRSvNVqFdhVT11hi19gGPTFRWvLorvrl/3JtES9UuP1VJqFKNbtwn1pvWgTzNVWsVNVWwW1xmK2WarWhQrC0us2C2F2Y6/X6mjv11yldsy1T2lf73OZ0Ou802+02u71psxbPj1gLrd2TGuzQfIXewNvNtAYb1S7S2lu2SOlc89/RWH7XSktrg1u1uhsFt7VCbUdKscVaqYqWumqLSTUL1a1YB0xio+OHC9YWJC7I9c7l+kfBi8hla6K0Zvg5/jlni1Fqo/hv/Xs685i10Nodua7bFunGEK15RJeu2D9dGrLHSuea/47G8rtaBVcLbs06l8nRIjRWm/xClct6QRWFigrrNdVcxepro9Cqqm7B4RLFwlyf32gOx2xL1PnASSO2XXTdGbTTrOu27V2uhXY+ct20TVEMutId2+PvX12ipXPNf0dj+V39LotQ1y6IDpNDtVjNLnR1OBx+sTL3mYVHg9DOXPF+XRH19XLTvJM6w9cvUVYHbM2a6wweXyeeqwPDTnv9TNaVXrxV2vqa/47G8ru6u9VKETdkq+BQGwQEFCu7uxvUY643BYe/wf9dtb/FXYTrtPNqE22+enGK/sOuHYW0ccdxAP/nsssswYbAAoYQ8pI+OFiGI4NsWZsRJkMScijKkLoJFafzwSFBfMlkItQwSsD0YQ46lJTtYYwTMh8EIRr6TzeKLcgQxNIFi42wGEMqxt/j/v/cCSZrKdJEvPL7gob7+Tvu7uPx4y78+RzY4gPTym/G5eq2JTv/H3D17Of2Pe761Hq7zq4qLGc9vzkgvPXx8GWiZ/frsMA0P71MCJuv75xy/fY9geg/++BtQl4xX6tjt/6VX7cyNu66bc0o8/Xd9zP5X2fyLOubShsbqfbMo/F8ftGaY66rH9qf1d2VwzLW83Ll+fLk10mGh1/edBbXTxhn/spH7M7lzwPqHMhn+fPArcosvZbnmbliZ3/M8CeBAeV5IJNvgCs8L73h71t7WeXz2oxaeKqUt17c/ka9F5zHe+zOmbrR9WIFXdEVXdEVXdEVXdEVXbXniuuIcN3by3IR173hOk1cV/y/XOR1xRh0PRV01WLQFV21FHRFVy2lDq6P79OG5v5j0F5e35WzImz9XRlrw2FBc3l9V3oOAc0FXdFVS0FXdNVS0BVdtZSGuiZkSh0tlCWsn1NKnWKlHBc6pvR6vdEl86JXSKLrGVyNrZRayCCl1ETiSqmdVMqyOx4hnRG/2MqLU+4Uur7CtVUQHc00YdI1RUyECFGLaOR3KYk7bZSKHcyVlyNCOMKpW5o7DW7iF2myRRDcaYcg+mjULIid6Eqr0k7cfsFATeaowzLVZAunLE7Rn27ykLjDTKnOz1x5WSaDEeK+6tR52om510+oR/B2elxi+KqetpjmfOha4+psotRhSBFbm1NIV+aA0yt6muRTrpSVk9xVNJi8qXYyR1nRzMdwc3NbGwk7dW1RnAO1rgbumtTZXC5XSnFNG4gvWXFNkSrXuDpw+c8lR8WV7RVNtZmIF11pVTqIy6szUItFln3UZkqyOUD95jRzdesTbJJGSJiX5VpXhziV6HUb4mlvulemLRZ0pdVxX2q2NdGIRUcsdFAkPubKwlznjMRI2qmJ+FjZW+sqmwhplR0CuZRw6gTDILrSqsieVMLYyiVTlCVBTyWpdKR5uTbqDinek5bxOavWNWokOjO/EfF9q46uPKkUpeiK3w+gq5aCruiqpaArumop6IquWgquI7qorrjuDddpVuWiu2LQ9VTQVYtBV3TVUtAVXbUUdEVXLQVd0VVLQVdNuJZWlgpQk7FVUFI4hNKtLmnyAJ5ILItwPCuFpovQ3/1Tt6Tu9vBGsH8ZYP16cGQfYEGSZgFgbywGAL/1S+NP4HeJJQsPRkJDaycNh5Oh7hW2U09wrHiykfs62PdP/RpAPXX1+MrJqNfReNdyn8SFqvPnLigZugc7dwoH47dhq7tcLgPMju4XF55BVxYgqO41v3H0IFgsBteKPwxApntju28RikPffA+wKWWPfrkB89N818PQWnkjdKA2xEZ210I7hdDS3sSEugFfxfYXusp1awD11JXjqyejXkfjXVeDpfIXd45yyrGOJYDlaRhf3xwaDX33fCQQlIAlFoOtntK9fxnm/qONMqiuOSkHlfwdPNoOsY/A/uRdgJURALjLXLOhAiz2w/zNXKYEID2EnWBJbejaBrj589IoQCGgbuyFAKBns24NSmIx5fjqyajX0XjXHwcAJic2A7uKa+AY/hhnt+lGYLFw/T/2ziAkjisO46PFYAml9BAI5OolFAKBHAo9CEIO5T3m4TKyiIuFlQR2D4IEDQSVhgUJIkKyh0kgYkhJECkIcQ+CJBpcUYIVZBEWwUhC1gVxHSbLzn7HOs6/1alMwcxYZtr3gbj/N9/y3vzQcf4y+75l2L+4QFktosg6EmzN4OkE7wNxNXQDAF7E2RwsVS+meTE9D2x0EVeMMsGKmFQTQuxhmcXYFMjAKoA+OjECgBlOsakBhxMGZgAtneZ3FkPncf5cx/qBh2mzUIObqwDGsocvANR6ssCnkSqyqQM2DoO/J65wVFrLqgfY6NamY6W+HPCum7h+4BML/WksTaLe8wTa6GJWmGRQy0B2/OUwYLGaU2zHACRXAjOAlk7zO4uh8zh/rhNxoC8DgLhaeHnENQFks87P6910nf5CxcCXgZ8Xj7mSEq8BoMJrIzrwWx9xnbwHmMwAgOzwpgDQvUiGjnVgYOr1beCjSkWFVQHxPjADQEt35qfF0HmcO9cttrypzh/MmU6pFWo9J7hmdEDvMm3fC6ua6cPdodoHtktcq2tVAHoJZV40dKueGcaqZtQSOeK6Fv+MNW7mVlBJTBlqCRVeIEO2HyW+a/AtjA5TgeQ0FmMIzFDYo6U789Ni6DzOnSt0xoYtur7Cvie5PXDMtRATm4wLIfApxXliF3tJzl+CuO4evWtCVWM6jH7O0wfAmKoOWdgWnIl1jIhYYgHv4pwP1DCtxTQdZDBSqjoF5FS1ew9UbGtCbARnELPG0dJpfloMncf5c4VVdVU1uGQcHzFhy6wDxNXtqVVPfiM57/lcO+0z62SgInDD8BZIND85LTO8/ZYWe6KxCkKtPZxBIeH6X5Tk+r/iOqvtA+UUT2wCwK5WRlYcKkNNu6uRp4IaeR8G3wo91xdDrAwks2aOH9hdDyvBqtWqXTPUtLsaeSqokfdh8KvwcwV4GeA7qPE5YHJYLQHAYsyipt3VyFPhNPJ+DP4VDa69fVvj6jNsaabDNT4LatpdjTwVTiPvxwDfigbX/bQYvTdbja/jiOucVgc17a5GngqnkfdjgG9Fg6utrvVnPJ1mt4uwtHmAmnZXI0+F08j7MfhXNLjqB8jF8GFpaYnPVDATB0BNu6uRp4IaeR8G/wo71yHB1F7oqtqxBVtqCZZYBKhpdzXyVFAj78fgW6HnCpKJ0zJOHHJ39bWqH0OACj3X6EpylVyjJMlVco2SJFfJNUqSXCXXKElyDS1X+fnYv0t+njvEXOX+A6ck98uQXCMmyVVyjZIkV8k1SpJcJdco6d/k+upxPu9OhZFcg+DaruTz7lQYyfVLud6/2HC5+Wb+RlNjy08NSuMVSoX5/tKV5vam/INvGi50HqXCSK5n4/r1xc4rSustpe1O4+AN5c4jSoVpUVoGbyr5y83tP3QepcJIrmfi+kppzT9XWq9+df1683X7OkCpMC1NdhrEm8Yf/0qFkVy/iOth8Et7u/I2TykbLd/aXO2jf6bCSK5nug5cbL55SWm9r9zKdz54rLS/cXHNN3/3fPCBkwojuZ6J66NLzVcb2vLXmpSvOvNXlGY318ELSkObkwojuZ6Ja9v9t62Kfbtqf+Vfue5YKS3GToWR91ln5HqtUWm6Yb+Q/RYpCK6UYiS5yv8PSK6hluQquUZJkqvkGiVJrmHlKp8jks+9uRRyrvI5Tflc8UlJrlGU5Cq5RkmSq+QaJUmukmuUJLlKrlGS5Cq5RkmSayS4ns6HefIQjgwD+L2HJ+cATQiRAXIdPPURgFcsTCGx4BEL47WTK40FZQgN19P5MChuwpE+dpT+ss4N8D3LqmNFe19dWAbgEQtTSHXkPGJhPHdypbGgDGHh6sqH6d3Abhy/6hDjamrnKWfCRmwyE3x/dQfond9ZNvFPsTC9OY9YGM+dXGksKENYuLryYZKrKKnQx8Aylcy4/cLWWB/AtR6mIz4Q0zTvWBji6hEL47GTK40FZQgL1+N8GBfXj1jqIa5L6j4w9AlrzIp3Az1TcHQ6Foa4esTCeOzkSmNBGcLC1ZUPk1zBtsPVxGrS4bqlrtOVmJXT48DDMZBOxcIQV49YGI+dXGksKENYuLryYTJPkT3BNZcCyiIHoDpuYFbFTMeBEZ/1jIUhrh6xMB47udJYUIawcHXlwxQ0kRbHXI1uMTPKhBCT5gjn4h1qv3A+ZHnHwkwLxkUd3rEw23+wdzehiaNxHMefJ5IQqVJLqAe3dMCD0BdKF2tZqQRcGMv01LlZTw50brOX7kn2tOChpYfCgtBTocNCD0N72IM3y6xkWBgvwhamh1mEQnoQV8mI2d9xow1U+wK7mEIy/L+Q1NSQBz4ENfKo97/J1f6fUzu4xnX092EMjNS5e7M3tPP//1mY+9/k6vAOLrouoMiVXD0YuZKrlyJXcvVS5EquXopcXetK84ppHvxwLnelz23Q54xGIldyJVdyJVdyJVdy/dpc5TlytXPUde01udqN7/pS/EaY+FmbXJh4NrmivZB48HBrgk+dket4rs/Z9MuJCc3PVw79S5o4/XruUJjbDX5HruO6/qKtsXP/M03zL/3IDjVtiy19OzVFruO6vrWW3/wLfVdro++6sLRE5+vYrktn06J24/qWzZ0/PxdWzne3yHVc10kmbFmmWn9ZE5i4+/0E4yvkOq6rdqYNdTZY/U6vs8Z0fcE1K7reAl3HkqsLI1dy9VLkSq5eilzJ1UuRq1tdaR4RzXsbyeWuNE+T5hUPR65ejFzJ1UuRK7l6KXIlVy9FruTqpciVXL0UuZKrlyJXcvVS5EquXopc3eraoOh8Hcnd5ytFrsORqxcjV3J1cW0MR64OdZz76QtuI1dn+pLL5T7iNnJ1qL3cq79xG7k6lPlnB0ORqzP99f79RwzljOtpE49lnJh4qKsK+jUb+K8Zlz24tr1cLuf88xYr4rFq7BIPtS6hX5wDdvs1PNplEdhnJbi2d6/c5frHAWAnp/FoeRHQ96/h3vae0LVbXC10UCgBjYwJ7BzBdm29WS2ivAmgnjHN/dVsF7ZrJY/KdiX1pttL+2bTFVysJ8tAtpJVUVaTNQBVNXl6FOPpbCvdtkdopS8yGR3oWUcy4I6e0NWc4REhZCwHgCQros0Ltqse8McEtcyOgMUQor6YHLFd+3/WuRgRlW5UCEZLp4Iyw08g+aTVIp+dYSUUmRzlqsKiy9aR7BFqTFIC3EBEXpychTt6Qtd9VoHONiusioAYRVY0bdeEDBSCUKJoC9slVkeT60Ou7AQH7BpyGlBiwPIiJMVETwdmFhGIAJ+RFwdHskeosSS6fMdkBeAKrujDD7ncr//gNgddkxKA0DyC8TIvciO8CNs17AuFQqyxw/WMaCaZtcHzQ64i0GanA1dBDoX8MiQVaCdmFDEMvg4r29UeocaqQCCFGI9kXPI4sJcbfUHgpOs67wFyHKq8OAspw8o3rnVElJpV15RSgSRUoWpttIZcJaBjufpTgC9u3VeHtAEkpGJ1NgwpMXAVBq72CNatgSvKqjwDV/Th+Pj4nfPn63aj0biqstXWJjuAzngRcR5Evy7PYJMVehcpICVwHdZezXayecSqd1yjStOIyic4yg5c5wNGRQgjJpV6aqvGioalaY9guxqqgYQMt+aEaz8JeZH5VAAR0bT4VAyKc8VaOI8Ben+FvI8x5QJhlgCwIWHDdi35WewqwriQgbQJVGXuC0fQjjAWrGOes1N2aY9Qv3H9pHBBLsCtOXkde4X7tXXA/GQOH6kDK72DOzV6gPH59mAm+hnXg7X+wAiGS5617kfvD5CrxyJXcvVS5EquXopcydVLkSu5eilyJdd/27WD16bBMI7jf+BCC7t4KQoehHlYEaJ78RIJxMMYo8JuxdPwEE+BLTBYwKPmMIuCZRehs3MQN9jrmub9bSe77HWbcxTbROkbf9/Dy/vw3D6UQuA1KbrS1aRKcB2+aFiNNwC2GhmA+3u4Ouv1xrMD6N3Let5+PlS84q5q4fH+4MMKgMb8NoD5z7g6dwc7q7U9vVPD4cLmcHgxVLzirju1IfLeN97d06K/nCtPL3d4uAU9VLzirhv39WVxE3c+3eK6fVfvtKseql1x17c15O3Xvw9eP7nFdeOB3mlXPVS74q5Hc7s4b3nOsqy5g99dl5ahd7mrHmb5udVMuGJx8Rh7z4+tb+e4qzddB6+srz93uevlUOlKcD1Zqtfq6+uPAOCLNZi3arXagT5Hx8IuLncj12tDlSvoqjsG4/fWRXQ1MbrS1aToSleToitdTYqudDWp4q4nR4emdXSCQDTLTgSluprHOoINfImyk35QpuuhiQmJ8pPiv3dt4m/UpCtd6WpQdKWrSdGVriZF13/pGom8BONLJV0nclVZttbJMoXxRQFdJ3DNW+sAbV/EgRAh+q01u50idoU/ututPpKW7QV2U/TpOrlry00QSylkrxlLryttmXaQdFXkw/dlL4kCxd/rNK4xILux+7EngCBUdtgH0OsErhIJ/wemd+0is4NzVw8IQySh20bkRqGjmnQt5JrYKrW1a5YgbabtCKEDL1JSdlp0ndJVtR3H066J67kBesJtOUgc4fRST8R0nfK7IFU37iq9uOeHoiu/t/LoSle60pWudKUrXelKV7oa+I6I79500g/4TnP232ky8L32tehqYnSlq0nRla4mRVe6mhRd6WpSdKWrSdGVriZFV7qaFF3palJ0patJ0ZWuJkVXupoUXelqUnSdLddTsDGdTut6RthxrGd/7somaZzrD8oBAMffjbluAAAAAElFTkSuQmCC"},8453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>i});var d=n(6540);const l={},a=d.createContext(l);function c(e){const t=d.useContext(a);return d.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:c(e.components),d.createElement(a.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/72e396cc.6d65511b.js b/assets/js/72e396cc.6d65511b.js
new file mode 100644
index 0000000000..e9b4da7560
--- /dev/null
+++ b/assets/js/72e396cc.6d65511b.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[9743],{5700:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>t,metadata:()=>d,toc:()=>l});var i=s(4848),o=s(8453);const t={},r="Sentry Node",d={id:"node/run-your-node/sentry-node",title:"Sentry Node",description:"This guide provides instructions for a deployment using the Sentry node architecture to protect validator nodes from being directly exposed on the public network.",source:"@site/docs/node/run-your-node/sentry-node.md",sourceDirName:"node/run-your-node",slug:"/node/run-your-node/sentry-node",permalink:"/node/run-your-node/sentry-node",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/node/run-your-node/sentry-node.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"operators",previous:{title:"IAS Proxy",permalink:"/node/run-your-node/ias-proxy"},next:{title:"Maintenance",permalink:"/node/run-your-node/maintenance"}},a={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Configuring the Oasis Sentry Node",id:"configuring-the-oasis-sentry-node",level:2},{value:"Initializing Sentry Node",id:"initializing-sentry-node",level:3},{value:"Configuring Sentry Node",id:"configuring-sentry-node",level:3},{value:"Configuring the Oasis Validator Node",id:"configuring-the-oasis-validator-node",level:2},{value:"Initializing Validator Node",id:"initializing-validator-node",level:3},{value:"Configuring the Validator Node",id:"configuring-the-validator-node",level:3}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"sentry-node",children:"Sentry Node"}),"\n",(0,i.jsx)(n.p,{children:"This guide provides instructions for a deployment using the Sentry node architecture to protect validator nodes from being directly exposed on the public network."}),"\n",(0,i.jsxs)(n.p,{children:["This guide assumes a setup where an Oasis validator node is only accessible over a private network, with sentry nodes having access to it. The guide does not cover setting this infrastructure up. Knowledge of ",(0,i.jsx)(n.a,{href:"https://forum.cosmos.network/t/sentry-node-architecture-overview/454",children:"Tendermint's Sentry Node architecture"})," is assumed as well."]}),"\n",(0,i.jsx)(n.admonition,{type:"danger",children:(0,i.jsx)(n.p,{children:"This is only an example of a Sentry node deployment, and we take no responsibility for mistakes contained therein. Make sure you understand what you are doing."})}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.p,{children:["Before following this guide, make sure you've read the ",(0,i.jsx)(n.a,{href:"/node/run-your-node/prerequisites/oasis-node",children:"Prerequisites"})," and ",(0,i.jsx)(n.a,{href:"/node/run-your-node/validator-node",children:"Running a Node on the Network"})," guides and created your Entity."]}),"\n",(0,i.jsx)(n.h2,{id:"configuring-the-oasis-sentry-node",children:"Configuring the Oasis Sentry Node"}),"\n",(0,i.jsx)(n.h3,{id:"initializing-sentry-node",children:"Initializing Sentry Node"}),"\n",(0,i.jsx)(n.p,{children:"Sentry node identity keys can be initialized with:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"oasis-node identity init --datadir /node/data\n"})}),"\n",(0,i.jsx)(n.h3,{id:"configuring-sentry-node",children:"Configuring Sentry Node"}),"\n",(0,i.jsxs)(n.p,{children:["An Oasis node can be configured to run as a sentry node by setting the ",(0,i.jsx)(n.code,{children:"worker.sentry.enabled"})," flag. The ",(0,i.jsx)(n.code,{children:"tendermint.sentry.upstream_address"})," flag can be used to configure a list of nodes that will be protected by the sentry node."]}),"\n",(0,i.jsxs)(n.p,{children:["An example of full ",(0,i.jsx)(n.code,{children:"YAML"})," configuration of a sentry node is below."]}),"\n",(0,i.jsx)(n.p,{children:"Before using this configuration you should collect the following information to replace the variables present in the configuration file:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"{{ external_address }}"}),": This is the external IP on which sentry node will be reachable."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"{{ seed_node_address }}"}),": This the seed node address of the form ",(0,i.jsx)(n.code,{children:"ID@IP:port"}),". You can find the current Oasis Seed Node address in the Network Parameters page (",(0,i.jsx)(n.a,{href:"/node/mainnet/",children:"Mainnet"}),", ",(0,i.jsx)(n.a,{href:"/node/testnet/",children:"Testnet"}),")."]}),"\n"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"{{ validator_tendermint_id }}"}),": This is the Tendermint ID (address) of the Oasis validator node that will be protected by the sentry node. This address can be obtained by running:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"oasis-node identity tendermint show-node-address --datadir /node/data\n"})}),"\n",(0,i.jsx)(n.p,{children:"on the validator node."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"{{ validator_private_address }}"}),": This is the (presumably) private address on which validator should be reachable from the sentry node."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"{{ validator_sentry_client_grpc_public_key }}"}),": This is the public TLS key of the Oasis validator node that will be protected by the sentry node. This public key can be obtained by running:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:" oasis-node identity show-sentry-client-pubkey --datadir /node/data\n"})}),"\n",(0,i.jsxs)(n.p,{children:["on the validator node. Note that the above command is only available in ",(0,i.jsx)(n.code,{children:"oasis-node"})," from version 20.8.1 onward."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'mode: client\ncommon:\n data_dir: /node/data\n log:\n format: JSON\n level:\n cometbft: warn\n cometbft/context: error\n # Per-module log levels. Longest prefix match will be taken. Fallback to\n # "default", if no match.\n default: debug\n # By default logs are output to stdout. If you\'re running this in docker \n # keep the default\n #file: /var/log/oasis-node.log\nconsensus:\n external_address: tcp://{{ external_address }}:26656\n listen_address: tcp://0.0.0.0:26656\n sentry_upstream_addresses:\n - {{ validator_tendermint_id }}@{{ validator_private_address }}:26656\ngenesis:\n # Path to the genesis file for the current version of the network.\n file: /node/etc/genesis.json\np2p:\n seeds:\n # List of seed nodes to connect to.\n # NOTE: You can add additional seed nodes to this list if you want.\n - {{ seed_node_address }}\nsentry:\n # Port used by validator nodes to query sentry node for registry\n # information.\n # IMPORTANT: Only validator nodes protected by the sentry node should have\n # access to this port. This port should not be exposed on the public\n # network.\n control:\n authorized_pubkeys:\n - {{ validator_sentry_client_grpc_public_key }}\n port: 9009\n enabled: true\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsx)(n.p,{children:"Multiple sentry nodes can be provisioned following the above steps."})}),"\n",(0,i.jsx)(n.h2,{id:"configuring-the-oasis-validator-node",children:"Configuring the Oasis Validator Node"}),"\n",(0,i.jsx)(n.p,{children:"In this setup the Oasis validator node should not be exposed directly on the public network. The Oasis validator only needs to be able to connect to its sentry nodes, preferably via a private network."}),"\n",(0,i.jsx)(n.h3,{id:"initializing-validator-node",children:"Initializing Validator Node"}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsx)(n.p,{children:"If your validator node is already registered and running in a non-sentry setup, this step can be skipped as the Oasis validator will update its address in the Registry automatically once we redeploy it with new configuration."})}),"\n",(0,i.jsxs)(n.p,{children:["When you are ",(0,i.jsx)(n.a,{href:"/node/run-your-node/validator-node#configuration",children:"initializing a validator node"}),", you should use the sentry node's external address and Consensus ID in the ",(0,i.jsx)(n.code,{children:"node.consensus_address"})," flag. If you are running multiple sentry nodes, you can specify the ",(0,i.jsx)(n.code,{children:"node.consensus_address"})," flag multiple times."]}),"\n",(0,i.jsxs)(n.p,{children:["To initialize a validator node with 2 sentry nodes, run the following commands from the ",(0,i.jsx)(n.code,{children:"/localhostdir/node"})," directory:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"export SENTRY1_CONSENSUS_ID=\nexport SENTRY1_STATIC_IP=\nexport SENTRY2_CONSENSUS_ID=\nexport SENTRY2_STATIC_IP=\noasis-node registry node init \\\n --signer.backend file \\\n --signer.dir /localhostdir/entity \\\n --node.consensus_address $SENTRY1_CONSENSUS_ID@$SENTRY1_STATIC_IP:26656 \\\n --node.consensus_address $SENTRY2_CONSENSUS_ID@$SENTRY2_STATIC_IP:26656 \\\n --node.is_self_signed \\\n --node.role validator\n"})}),"\n",(0,i.jsxs)(n.admonition,{type:"info",children:[(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"SENTRY_CONSENSUS_ID"}),": This is the Consensus ID of the sentry node in base64 format. This ID can be obtained from ",(0,i.jsx)(n.code,{children:"consensus_pub.pem"}),":"]}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sed -n 2p /node/data/consensus_pub.pem\n"})}),(0,i.jsx)(n.p,{children:"on the sentry node."})]}),"\n",(0,i.jsx)(n.h3,{id:"configuring-the-validator-node",children:"Configuring the Validator Node"}),"\n",(0,i.jsx)(n.p,{children:"There are some configuration changes needed for the Oasis validator node to enable proxying through its sentry node. Most of these flags should be familiar from the Tendermint sentry node architecture."}),"\n",(0,i.jsxs)(n.p,{children:["Since the validator node will not have an external address, the ",(0,i.jsx)(n.code,{children:"consensus.tendermint.core.external_address"})," flag should be skipped. Similarly, the ",(0,i.jsx)(n.code,{children:"consensus.tendermint.p2p.seed"})," flag can be skipped, as the ",(0,i.jsx)(n.code,{children:"oasis-node"})," won't be directly connecting to any of the seed nodes."]}),"\n",(0,i.jsxs)(n.p,{children:["Tendermint Peer Exchange should be disabled on the validator with the ",(0,i.jsx)(n.code,{children:"consensus.tendermint.p2p.disable_peer_exchange"})," flag."]}),"\n",(0,i.jsxs)(n.p,{children:["Sentry nodes can also be configured as Tendermint Persistent-Peers with the ",(0,i.jsx)(n.code,{children:"consensus.tendermint.p2p.persistent_peer"})," flag."]}),"\n",(0,i.jsxs)(n.p,{children:["In addition to the familiar Tendermint setup above, the node needs to be configured to query sentry nodes for external addresses every time the validator preforms a re-registration. This is configured with the ",(0,i.jsx)(n.code,{children:"worker.sentry.address"})," flag."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"worker.sentry.address"})," flag is of format: ",(0,i.jsx)(n.code,{children:"@ip:port"})," where:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:""}),": Is the sentry node's TLS public key."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"ip:port"}),": Is the (private) address of the sentry node's control endpoint."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Putting it all together, an example configuration of a validator node in the sentry node architecture is given below."}),"\n",(0,i.jsxs)(n.p,{children:["Before using this configuration you should collect the following information to replace the ",(0,i.jsx)(n.code,{children:"{{ var_name }}"})," variables present in the configuration file:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"{{ sentry_node_private_ip }}"}),": This is the private IP address of the sentry node over which sentry node should be accessible to the validator."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"{{ sentry_node_grpc_public_key }}"}),": This is the sentry node's control endpoint TLS public key. This ID can be obtained by running:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:" oasis-node identity show-tls-pubkey --datadir /node/data\n"})}),"\n",(0,i.jsxs)(n.p,{children:["on the sentry node. Note that the above command is only available in ",(0,i.jsx)(n.code,{children:"oasis-node"})," from version 20.8.1 onward."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"{{ sentry_node_tendermint_id }}"}),": This is the Tendermint ID (address) of the sentry node that will be configured as a Persistent Peer. This ID can be obtained by running:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"oasis-node identity tendermint show-node-address --datadir /node/data\n"})}),"\n",(0,i.jsx)(n.p,{children:"on the sentry node."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'mode: validator\ncommon:\n data_dir: /node/data\n log:\n format: JSON\n level:\n cometbft: warn\n cometbft/context: error\n # Per-module log levels. Longest prefix match will be taken.\n # Fallback to "default", if no match.\n default: debug\n # By default logs are output to stdout. If you\'re running this in docker keep\n # the default\n #file: /var/log/oasis-node.log\n\nconsensus:\n listen_address: tcp://0.0.0.0:26656\n p2p:\n disable_peer_exchange: true\n persistent_peers:\n - {{ sentry_node_tendermint_id }}@{{ sentry_node_private_ip }}:26656\n\ngenesis:\n # Path to the genesis file for the current version of the network.\n file: /node/etc/genesis.json\n\nregistration:\n # In order for the node to register itself the entity.json of the entity\n # used to provision the node must be available on the node.\n entity: /node/etc/entity.json\n\nsentry:\n address:\n - {{ sentry_node_grpc_public_key }}@{{ sentry_node_private_ip }}:9009\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsxs)(n.p,{children:["Make sure the ",(0,i.jsx)(n.code,{children:"consensus"})," port (default: ",(0,i.jsx)(n.code,{children:"26656"}),") and ",(0,i.jsx)(n.code,{children:"p2p.port"})," (default: ",(0,i.jsx)(n.code,{children:"9200"}),") are exposed and publicly\naccessible on the internet (for ",(0,i.jsx)(n.code,{children:"TCP"})," and ",(0,i.jsx)(n.code,{children:"UDP"})," traffic)."]})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>d});var i=s(6540);const o={},t=i.createContext(o);function r(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/72efe815.dd30683c.js b/assets/js/72efe815.dd30683c.js
new file mode 100644
index 0000000000..694a220046
--- /dev/null
+++ b/assets/js/72efe815.dd30683c.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[5028],{7004:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>s,default:()=>h,frontMatter:()=>t,metadata:()=>a,toc:()=>l});var o=i(4848),r=i(8453);const t={},s="IAS Proxy",a={id:"node/run-your-node/ias-proxy",title:"IAS Proxy",description:"This guide will cover setting up an Intel Attestation Service (IAS)",source:"@site/docs/node/run-your-node/ias-proxy.md",sourceDirName:"node/run-your-node",slug:"/node/run-your-node/ias-proxy",permalink:"/node/run-your-node/ias-proxy",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/node/run-your-node/ias-proxy.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"operators",previous:{title:"Upgrading Key Managers",permalink:"/node/run-your-node/keymanager-node/key-manager-upgrade"},next:{title:"Sentry Node",permalink:"/node/run-your-node/sentry-node"}},d={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Obtaining IAS Service Provider ID (SPID) and API Key",id:"obtaining-ias-service-provider-id-spid-and-api-key",level:3},{value:"Creating a Working Directory",id:"creating-a-working-directory",level:3},{value:"Configuration",id:"configuration",level:2},{value:"Starting the IAS Proxy",id:"starting-the-ias-proxy",level:2},{value:"IAS Proxy Public Key",id:"ias-proxy-public-key",level:2},{value:"Share IAS Proxy address ",id:"share-ias-proxy-address-",level:3}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"ias-proxy",children:"IAS Proxy"}),"\n",(0,o.jsxs)(n.p,{children:["This guide will cover setting up an ",(0,o.jsx)(n.a,{href:"https://software.intel.com/content/www/us/en/develop/download/intel-sgx-intel-epid-provisioning-and-attestation-services.html",children:"Intel Attestation Service (IAS)"}),"\nProxy node for the Oasis Network. This guide assumes some basic knowledge on the\nuse of command line tools."]}),"\n",(0,o.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,o.jsxs)(n.p,{children:["Before following this guide, make sure you've followed the\n",(0,o.jsx)(n.a,{href:"prerequisites",children:"Prerequisites"})," section and have the Oasis Node binary installed\non your system. The IAS Proxy connects to an Oasis Node, so make sure you have a\nrunning node first. For more details, see the instructions on how to\n",(0,o.jsx)(n.a,{href:"/node/run-your-node/non-validator-node#configuration",children:"Run a Non-validator Node"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"obtaining-ias-service-provider-id-spid-and-api-key",children:"Obtaining IAS Service Provider ID (SPID) and API Key"}),"\n",(0,o.jsxs)(n.p,{children:["Running the ",(0,o.jsx)(n.a,{href:"https://software.intel.com/content/www/us/en/develop/download/intel-sgx-intel-epid-provisioning-and-attestation-services.html",children:"Intel Attestation Service (IAS)"}),"\nProxy requires access to the IAS API. Go to ",(0,o.jsx)(n.a,{href:"https://api.portal.trustedservices.intel.com/EPID-attestation",children:"IAS Enhanced Privacy ID (EPID) attestation"}),"\npage and signup for the ",(0,o.jsx)(n.em,{children:"Production Access"}),". As a service provider, you will\nregister your TLS certificate and obtain your Service Provider ID (SPID) and API\nkey. The SPID and API key will be used by the IAS Proxy to communicate with the\nIAS."]}),"\n",(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsxs)(n.p,{children:["Basic understanding of SGX Remote attestation is recommended. See Intel's\n",(0,o.jsx)(n.a,{href:"https://software.intel.com/content/www/us/en/develop/articles/code-sample-intel-software-guard-extensions-remote-attestation-end-to-end-example.html",children:"Remote Attestation End-to-End Example"}),"\nfor a short practical introduction."]})}),"\n",(0,o.jsx)(n.h3,{id:"creating-a-working-directory",children:"Creating a Working Directory"}),"\n",(0,o.jsxs)(n.p,{children:["We will be using the following working directory ",(0,o.jsx)(n.code,{children:"/node/ias"})," (feel free to name\nyour directory however you wish)."]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The directory permissions should be ",(0,o.jsx)(n.code,{children:"rwx------"}),"."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"To create the directory, use the following command:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-text",children:"mkdir -m700 -p /node/ias\n"})}),"\n",(0,o.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,o.jsx)(n.p,{children:"To avoid specifying the IAS Service Provider ID (SPID) and API key in the Oasis\nNode configuration directly, IAS Proxy supports reading the SPID and API key\nfrom environment variables. Make sure you have the following environment\nvariables set:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-text",children:'OASIS_IAS_SPID=""\nOASIS_IAS_APIKEY=""\n'})}),"\n",(0,o.jsxs)(n.p,{children:["In order to configure the IAS proxy create the ",(0,o.jsx)(n.code,{children:"/node/ias/config.yml"})," file with\nthe following content:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"common:\n data_dir: /node/ias\n log:\n format: JSON\n level:\n default: info\n"})}),"\n",(0,o.jsx)(n.h2,{id:"starting-the-ias-proxy",children:"Starting the IAS Proxy"}),"\n",(0,o.jsx)(n.p,{children:"You can start the IAS Proxy using the following command:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"oasis-node ias proxy \\\n --config /node/ias/config.yml \\\n --address unix:{{ oasis_node_socket }} \\\n --ias.production true \\\n --grpc.port 8650\n"})}),"\n",(0,o.jsx)(n.p,{children:"Before using this configuration you should collect the following information to\nreplace the variables present in the invocation command:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"{{ oasis_node_socket }}"}),": Path to a running client Oasis Node socket."]}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"ias-proxy-public-key",children:"IAS Proxy Public Key"}),"\n",(0,o.jsx)(n.p,{children:"The TLS public key required for connecting to the IAS Proxy can be found in the\nprocess logs where it is output on startup as following:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"caller":"proxy.go:111","level":"info","module":"cmd/ias/proxy","msg":"loaded/generated IAS TLS certificate","public_key":"tnTwXvGbbxqlFoirBDj63xWtZHS20Lb3fCURv0YDtYw=","ts":"2023-06-20T09:43:39.592787275Z"}\n'})}),"\n",(0,o.jsxs)(n.p,{children:["The relevant item is the ",(0,o.jsx)(n.code,{children:"public_key"})," which in the above case is\n",(0,o.jsx)(n.code,{children:"tnTwXvGbbxqlFoirBDj63xWtZHS20Lb3fCURv0YDtYw="}),"."]}),"\n",(0,o.jsxs)(n.h3,{id:"share-ias-proxy-address-",children:["Share IAS Proxy address ",(0,o.jsx)("a",{id:"share-seed-node-address"})]}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/node/run-your-node/paratime-node",children:"ParaTime nodes"})," can now use your IAS Proxy by specifying it\nin configuration, e.g.:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'ias:\n proxy:\n address:\n - "@:8650"\n'})}),"\n",(0,o.jsx)(n.p,{children:"Note that you can list multiple IAS proxy addresses."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>s,x:()=>a});var o=i(6540);const r={},t=o.createContext(r);function s(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/72f44a45.57701f10.js b/assets/js/72f44a45.57701f10.js
new file mode 100644
index 0000000000..636e0cbd7d
--- /dev/null
+++ b/assets/js/72f44a45.57701f10.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[3902],{8700:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>h,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>r,toc:()=>c});var i=t(4848),s=t(8453);const a={},o="Frequently Asked Questions",r={id:"general/oasis-network/faq",title:"Frequently Asked Questions",description:"This page tries to answer some of the most frequently asked questions about the",source:"@site/docs/general/oasis-network/faq.md",sourceDirName:"general/oasis-network",slug:"/general/oasis-network/faq",permalink:"/general/oasis-network/faq",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/general/oasis-network/faq.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"general",previous:{title:"Token Metrics and Distribution",permalink:"/general/oasis-network/token-metrics-and-distribution"},next:{title:"Manage your Tokens",permalink:"/general/manage-tokens/"}},h={},c=[{value:"Overview",id:"overview",level:2},{value:"Why Oasis?",id:"why-oasis",level:3},{value:"Is the Oasis Protocol Foundation still taking grant applications for projects that are building new dApps?",id:"is-the-oasis-protocol-foundation-still-taking-grant-applications-for-projects-that-are-building-new-dapps",level:3},{value:"Architecture",id:"architecture",level:2},{value:"What kind of blockchain is the Oasis Network? Does it use sidechains?",id:"what-kind-of-blockchain-is-the-oasis-network-does-it-use-sidechains",level:3},{value:"What does the Oasis Network\u2019s architecture look like?",id:"what-does-the-oasis-networks-architecture-look-like",level:3},{value:"How is a ParaTime different from a Parachain?",id:"how-is-a-paratime-different-from-a-parachain",level:3},{value:"Who will be running all of these ParaTimes? Can anyone run a ParaTime?",id:"who-will-be-running-all-of-these-paratimes-can-anyone-run-a-paratime",level:3},{value:"What consensus mechanism are you running? Is it BFT?",id:"what-consensus-mechanism-are-you-running-is-it-bft",level:3},{value:"Why doesn\u2019t the Oasis Network do sharding? Does that mean it\u2019s slow?",id:"why-doesnt-the-oasis-network-do-sharding-does-that-mean-its-slow",level:3},{value:"How does storage work on the Oasis Network? Do you use IPFS?",id:"how-does-storage-work-on-the-oasis-network-do-you-use-ipfs",level:3},{value:"Open Finance & DeFi",id:"open-finance--defi",level:2},{value:"Does the Oasis Network have a vision for DeFi? Is it different from the mainstream view of DeFi?",id:"does-the-oasis-network-have-a-vision-for-defi-is-it-different-from-the-mainstream-view-of-defi",level:3},{value:"I\u2019ve seen Oasis use both the terms \u201cOpen Finance\u201d and \u201cDeFi\u201d? What\u2019s the difference?",id:"ive-seen-oasis-use-both-the-terms-open-finance-and-defi-whats-the-difference",level:3},{value:"Will Oasis provide oracle solutions for use in DeFi applications?",id:"will-oasis-provide-oracle-solutions-for-use-in-defi-applications",level:3},{value:"What aspects of DeFi require privacy? How can the Oasis Network\u2019s focus on privacy help with DeFi applications?",id:"what-aspects-of-defi-require-privacy-how-can-the-oasis-networks-focus-on-privacy-help-with-defi-applications",level:3},{value:"How does privacy help create a new system of Open Finance?",id:"how-does-privacy-help-create-a-new-system-of-open-finance",level:3},{value:"Why would anyone choose to build a DeFi project on Oasis over Ethereum?",id:"why-would-anyone-choose-to-build-a-defi-project-on-oasis-over-ethereum",level:3},{value:"Token",id:"token",level:2},{value:"How will the Oasis Network\u2019s token be used in the network when it launches?",id:"how-will-the-oasis-networks-token-be-used-in-the-network-when-it-launches",level:3},{value:"Privacy",id:"privacy",level:2},{value:"How does the Oasis Network achieve privacy and confidentiality? Is it through homomorphic encryption?",id:"how-does-the-oasis-network-achieve-privacy-and-confidentiality-is-it-through-homomorphic-encryption",level:3},{value:"Interoperability",id:"interoperability",level:2},{value:"Can you run Ethereum smart contracts on the Oasis Network? Or if not directly run smart contracts, could you access a bridge between Ethereum ERC20 assets and Oasis?",id:"can-you-run-ethereum-smart-contracts-on-the-oasis-network-or-if-not-directly-run-smart-contracts-could-you-access-a-bridge-between-ethereum-erc20-assets-and-oasis",level:3}];function l(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"frequently-asked-questions",children:"Frequently Asked Questions"}),"\n",(0,i.jsx)(n.p,{children:"This page tries to answer some of the most frequently asked questions about the\nOasis Network."}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsx)(n.p,{children:"This page will constantly be updated with new questions and responses."})}),"\n",(0,i.jsx)(n.h2,{id:"overview",children:(0,i.jsx)(n.strong,{children:"Overview"})}),"\n",(0,i.jsx)(n.h3,{id:"why-oasis",children:(0,i.jsx)(n.strong,{children:"Why Oasis?"})}),"\n",(0,i.jsx)(n.p,{children:"Designed for the next generation of blockchain, the Oasis Network is the first privacy-enabled blockchain platform for open finance and a responsible data economy. Combined with its high throughput and secure architecture, the Oasis Network is able to power private, scalable DeFi, revolutionizing Open Finance and expanding it beyond traders and early adopters to a mass market. Its unique privacy features can not only redefine DeFi, but also create a new type of digital asset called Tokenized Data that can enable users to take control of the data they generate and earn rewards for staking it with applications \u2014 creating the first ever responsible data economy."}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"First Privacy-Enabled Blockchain:"})," The Oasis Network is the world\u2019s first scalable, privacy-enabled blockchain. ParaTimes on the Oasis Network can leverage confidential computing technology such as secure enclaves to keep data confidential \u2014 unlocking new use cases and applications for blockchain."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Scalable, Private DeFi:"})," The Oasis Network\u2019s privacy-first design can expand DeFi beyond traders and early adopters \u2014 unlocking a new mainstream market. Plus its innovative scalability design brings fast speeds and high-throughput to DeFi transactions."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"First to Enable Data Tokenization:"})," The Oasis Network can ",(0,i.jsx)(n.strong,{children:"Tokenize Data"}),", unlocking game changing use cases for blockchain, and an entirely new ecosystem of apps and projects on the network \u2014 powering the next generation of privacy-first applications."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Rapidly Growing Community:"})," The Oasis Network has a thriving community of close to a thousand node operators, developers, enterprise partners, ambassadors, and nearly ten thousand community members engaged in global social channels."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Top-Tier Team:"})," The Oasis Team is made up of top talent from around the world with backgrounds from Apple, Google, Amazon, Goldman Sachs, UC Berkeley, Carnegie Mellon, Stanford, Harvard and more \u2014 all committed to growing and expanding the impact of the Oasis Network."]}),"\n",(0,i.jsx)(n.h3,{id:"is-the-oasis-protocol-foundation-still-taking-grant-applications-for-projects-that-are-building-new-dapps",children:(0,i.jsx)(n.strong,{children:"Is the Oasis Protocol Foundation still taking grant applications for projects that are building new dApps?"})}),"\n",(0,i.jsxs)(n.p,{children:["Yes! We are still taking grant applications. You can apply any time ",(0,i.jsx)(n.a,{href:"https://medium.com/oasis-protocol-project/oasis-foundation-grant-wishlist-3ad73b723d7",children:"here"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"architecture",children:(0,i.jsx)(n.strong,{children:"Architecture"})}),"\n",(0,i.jsx)(n.h3,{id:"what-kind-of-blockchain-is-the-oasis-network-does-it-use-sidechains",children:(0,i.jsx)(n.strong,{children:"What kind of blockchain is the Oasis Network? Does it use sidechains?"})}),"\n",(0,i.jsxs)(n.p,{children:["The Oasis Network is a Layer 1 blockchain protocol using a BFT, proof-of-stake consensus system. The network\u2019s innovative ParaTime architecture enables us to scale without using sidechains. For more information please refer to our ",(0,i.jsx)(n.a,{href:"https://docsend.com/view/aq86q2pckrut2yvq",children:"platform whitepaper"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"what-does-the-oasis-networks-architecture-look-like",children:(0,i.jsx)(n.strong,{children:"What does the Oasis Network\u2019s architecture look like?"})}),"\n",(0,i.jsx)(n.p,{children:"The Oasis Network is a Layer 1, proof-of-stake, decentralized network. It has two main components, the consensus layer and the ParaTime layer."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["The ",(0,i.jsx)(n.strong,{children:"consensus layer"})," is a scalable, high-throughput, secure, proof-of-stake consensus run by a decentralized set of validator nodes."]}),"\n",(0,i.jsxs)(n.li,{children:["The ",(0,i.jsx)(n.strong,{children:"ParaTime layer"})," hosts many parallel runtimes (ParaTimes), each representing a replicated compute environment with shared state."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Paratime Communication",src:t(3048).A+"",width:"1600",height:"940"})}),"\n",(0,i.jsx)(n.h3,{id:"how-is-a-paratime-different-from-a-parachain",children:(0,i.jsx)(n.strong,{children:"How is a ParaTime different from a Parachain?"})}),"\n",(0,i.jsx)(n.p,{children:"Unlike a Parachain, a ParaTime does not need to do consensus itself, making them simpler to develop and more integrated into the network as a whole. ParaTimes take care of compute and discrepancy detection is used to ensure correctness and integrity of execution, making ParaTimes more efficient than Parachains and other chain designs that rely on sharding."}),"\n",(0,i.jsx)(n.h3,{id:"who-will-be-running-all-of-these-paratimes-can-anyone-run-a-paratime",children:(0,i.jsx)(n.strong,{children:"Who will be running all of these ParaTimes? Can anyone run a ParaTime?"})}),"\n",(0,i.jsxs)(n.p,{children:["The network is agnostic in this regard. Anyone can run a ParaTime. It is completely left up to the devs and users to see which ones provide the functionality that they need. Examples of ParaTimes in development include the Oasis Labs Data Sovereignty ParaTime and the ",(0,i.jsx)(n.a,{href:"https://medium.com/oasis-protocol-project/ethereum-support-on-the-oasis-blockchain-3add9e13556?source=collection_home---4------0-----------------------",children:"Second State Virtual Machine"}),", an EVM compatible Runtime."]}),"\n",(0,i.jsx)(n.h3,{id:"what-consensus-mechanism-are-you-running-is-it-bft",children:(0,i.jsx)(n.strong,{children:"What consensus mechanism are you running? Is it BFT?"})}),"\n",(0,i.jsx)(n.p,{children:"The Oasis Network uses Tendermint as its BFT consensus protocol. Given that the consensus layer uses a BFT protocol, the Oasis Network offers instant finality, meaning that once a block is finalized, it cannot be reverted (at least not for full nodes). A ParaTime commitment goes into a block and as such the ParaTime state is also finalized and cannot be reverted once a block is finalized."}),"\n",(0,i.jsx)(n.h3,{id:"why-doesnt-the-oasis-network-do-sharding-does-that-mean-its-slow",children:(0,i.jsx)(n.strong,{children:"Why doesn\u2019t the Oasis Network do sharding? Does that mean it\u2019s slow?"})}),"\n",(0,i.jsx)(n.p,{children:"The Oasis Network does not use sharding. Instead, Oasis leverages a discrepancy detection model leading up to roothash updates, giving the network the same scalability benefits that sharding offers but with added benefits that come from a design that is much simpler to implement in practice. Sharding is a nice idea in theory but comes with a lot of complexity and costs that make it harder to implement in practice. From a security perspective, the complexity of sharding also makes it harder to audit and inherently more vulnerable to security breaches The Oasis Network\u2019s discrepancy detection-based approach provides the same benefits as sharding through a cleaner, simpler, more efficient implementation. Ultimately, the Oasis Network\u2019s unique scalability mechanism ensures that the network is not only fast (like sharding networks purport to be) but also versatile and secure enough to support a wide range of real-world workloads."}),"\n",(0,i.jsx)(n.h3,{id:"how-does-storage-work-on-the-oasis-network-do-you-use-ipfs",children:(0,i.jsx)(n.strong,{children:"How does storage work on the Oasis Network? Do you use IPFS?"})}),"\n",(0,i.jsx)(n.p,{children:"Storage on the Oasis Network is determined by each ParaTime. There is a clear separation of concerns between the consensus layer and the runtime layer. The ParaTimes that make up the runtime layer have a lot of flexibility in how they choose to manage storage. For instance, the ParaTime being developed by Oasis Labs can support IPFS as its storage solution. Other ParaTime developers could opt to implement different storage mechanisms based on their own unique storage needs."}),"\n",(0,i.jsx)(n.h2,{id:"open-finance--defi",children:(0,i.jsx)(n.strong,{children:"Open Finance & DeFi"})}),"\n",(0,i.jsx)(n.h3,{id:"does-the-oasis-network-have-a-vision-for-defi-is-it-different-from-the-mainstream-view-of-defi",children:(0,i.jsx)(n.strong,{children:"Does the Oasis Network have a vision for DeFi? Is it different from the mainstream view of DeFi?"})}),"\n",(0,i.jsx)(n.p,{children:"The first generation of DeFi dApps has provided the market with a huge number of protocols and primitives that are meant to serve as the foundation for the specific components of a new financial system. Despite the current focus on short-term returns, we at Oasis believe the goal of DeFi applications should be to give rise to a new financial system that removes subjectivity, bias, and inefficiencies by leveraging programmable parameters instead of status, wealth, and geography. Oasis aims to support the next wave of DeFi applications by offering better privacy and scalability features than other Layer 1 networks."}),"\n",(0,i.jsx)(n.h3,{id:"ive-seen-oasis-use-both-the-terms-open-finance-and-defi-whats-the-difference",children:(0,i.jsx)(n.strong,{children:"I\u2019ve seen Oasis use both the terms \u201cOpen Finance\u201d and \u201cDeFi\u201d? What\u2019s the difference?"})}),"\n",(0,i.jsx)(n.p,{children:"The terms \u201cOpen Finance\u201d and \u201cDeFi\u201d are interchangeable. However, we believe that \u201cOpen Finance\u201d better represents the idea that the new financial system should be accessible to everyone who operates within the bounds of specific programmable parameters, regardless of their status, wealth, or geography**.**"}),"\n",(0,i.jsx)(n.h3,{id:"will-oasis-provide-oracle-solutions-for-use-in-defi-applications",children:(0,i.jsx)(n.strong,{children:"Will Oasis provide oracle solutions for use in DeFi applications?"})}),"\n",(0,i.jsxs)(n.p,{children:["Oasis recently announced a partnership with ",(0,i.jsx)(n.a,{href:"https://medium.com/oasis-protocol-project/oasis-network-chainlink-integrating-secure-and-reliable-oracles-for-access-to-off-chain-data-5d31e6e4591c?source=collection_home---4------1-----------------------",children:"Chainlink"})," as the preferred oracle provider of the Oasis Network. This integration is ongoing."]}),"\n",(0,i.jsx)(n.h3,{id:"what-aspects-of-defi-require-privacy-how-can-the-oasis-networks-focus-on-privacy-help-with-defi-applications",children:(0,i.jsx)(n.strong,{children:"What aspects of DeFi require privacy? How can the Oasis Network\u2019s focus on privacy help with DeFi applications?"})}),"\n",(0,i.jsx)(n.p,{children:"In the current generation of DeFi, some miners and traders are leveraging the inefficiencies of Ethereum to stack mining fees and interest rates, while preventing many more people from participating in the industry. Privacy can play a strong role in making the network function properly by reducing these inefficiencies. At the application level, privacy is an enabler. For instance, strong privacy guarantees can encourage established institutions to participate in the system because these institutions would be able to protect their interests and relationships. Additionally, privacy features can serve as the foundation for a reputation system, thereby unlocking the full potential of undercollateralized lending. We keep hearing that privacy is the next big thing in DeFi, and we look forward to empowering developers to build the next generation of DeFi applications."}),"\n",(0,i.jsx)(n.h3,{id:"how-does-privacy-help-create-a-new-system-of-open-finance",children:(0,i.jsx)(n.strong,{children:"How does privacy help create a new system of Open Finance?"})}),"\n",(0,i.jsx)(n.p,{children:"Existing financial systems and data systems are not open at all. They are only accessible to a select few. Privacy has a much broader meaning than just keeping something private. Thanks to privacy-preserving computation, users can retain ownership of their information and grant others access to compute on their data without actually revealing (or transferring) their data. This will enable users to accrue data yields by essentially staking their data on the blockchain, unlocking a wide range of new financial opportunities."}),"\n",(0,i.jsx)(n.p,{children:"Open Finance refers to the idea that status, wealth, and geography won't block you from accessing a certain financial product. Adherence to a programmable set of parameters will determine whether someone can participate or not, making new financial opportunities open to more people around the world. For example, services such as lending protocols could offer different interest rates depending on the history of that user. What's game changing for the world of finance is that companies would not have to rely on a centralized score such as FICO - they would be able to build their own models."}),"\n",(0,i.jsx)(n.h3,{id:"why-would-anyone-choose-to-build-a-defi-project-on-oasis-over-ethereum",children:(0,i.jsx)(n.strong,{children:"Why would anyone choose to build a DeFi project on Oasis over Ethereum?"})}),"\n",(0,i.jsx)(n.p,{children:"The network\u2019s cutting-edge scalable features can help unblock DeFi as it works today, fixing the high-transaction fees and slow throughput currently plaguing other Layer 1 networks. Combined, Oasis\u2019 unique ability to provide scalable, private DeFi is expected to make it the leading platform for unlocking the next generation of DeFi markets and use cases."}),"\n",(0,i.jsx)(n.h2,{id:"token",children:(0,i.jsx)(n.strong,{children:"Token"})}),"\n",(0,i.jsx)(n.h3,{id:"how-will-the-oasis-networks-token-be-used-in-the-network-when-it-launches",children:(0,i.jsx)(n.strong,{children:"How will the Oasis Network\u2019s token be used in the network when it launches?"})}),"\n",(0,i.jsx)(n.p,{children:"The ROSE token will be used for transaction fees, staking, and delegation at the consensus layer."}),"\n",(0,i.jsx)(n.h2,{id:"privacy",children:(0,i.jsx)(n.strong,{children:"Privacy"})}),"\n",(0,i.jsx)(n.h3,{id:"how-does-the-oasis-network-achieve-privacy-and-confidentiality-is-it-through-homomorphic-encryption",children:(0,i.jsx)(n.strong,{children:"How does the Oasis Network achieve privacy and confidentiality? Is it through homomorphic encryption?"})}),"\n",(0,i.jsx)(n.p,{children:"There are many ways to achieve confidentiality. Using a trusted execution environments (TEEs) is one way. This is what we do. In effect, we provide end-to-end confidentiality for transactions where state and payload are encrypted at rest, in motion, and, more importantly, in compute. homomorphic encryption is another technique for confidentiality. At this time, anyone can build a ParaTime on the Oasis Network that uses homomorphic encryption to provide confidentiality. We are not prescriptive about what approach developers should take."}),"\n",(0,i.jsx)(n.p,{children:"Something worth noting is that privacy and confidentiality are not equivalent. Privacy implies confidentiality but not the other way around. For privacy, there are techniques such as differential privacy that can be implemented."}),"\n",(0,i.jsx)(n.h2,{id:"interoperability",children:(0,i.jsx)(n.strong,{children:"Interoperability"})}),"\n",(0,i.jsx)(n.h3,{id:"can-you-run-ethereum-smart-contracts-on-the-oasis-network-or-if-not-directly-run-smart-contracts-could-you-access-a-bridge-between-ethereum-erc20-assets-and-oasis",children:(0,i.jsx)(n.strong,{children:"Can you run Ethereum smart contracts on the Oasis Network? Or if not directly run smart contracts, could you access a bridge between Ethereum ERC20 assets and Oasis?"})}),"\n",(0,i.jsx)(n.p,{children:"In short, yes! The Oasis Network supports EVM-compatible ParaTimes which will support a wide range of applications."})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},3048:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/consensus_paratime_communication-9e496f13908c8e30ad6e63e6da9f5fa3.png"},8453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var i=t(6540);const s={},a=i.createContext(s);function o(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/7327d54c.87942bc5.js b/assets/js/7327d54c.87942bc5.js
new file mode 100644
index 0000000000..98fce211d3
--- /dev/null
+++ b/assets/js/7327d54c.87942bc5.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[622],{5330:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var t=n(4848),s=n(8453);const i={},r="Network Governance",a={id:"get-involved/network-governance",title:"Network Governance",description:"If you have a general question on how to use and deploy our software, please",source:"@site/docs/get-involved/network-governance.md",sourceDirName:"get-involved",slug:"/get-involved/network-governance",permalink:"/get-involved/network-governance",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/get-involved/network-governance.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"getInvolved",previous:{title:"Develop Oasis Core",permalink:"/get-involved/oasis-core"},next:{title:"Delegation Policy",permalink:"/get-involved/delegation-policy"}},c={},l=[{value:"Governance Model Overview",id:"governance-model-overview",level:3},{value:"Decision Making Process",id:"decision-making-process",level:3},{value:"Minor Feature Requests",id:"minor-feature-requests",level:3},{value:"Major Feature Requests",id:"major-feature-requests",level:3},{value:"Urgent Bug Fixes",id:"urgent-bug-fixes",level:3},{value:"Contributing to the Network",id:"contributing-to-the-network",level:3}];function d(e){const o={a:"a",admonition:"admonition",h1:"h1",h3:"h3",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.h1,{id:"network-governance",children:"Network Governance"}),"\n",(0,t.jsxs)(o.admonition,{type:"info",children:[(0,t.jsxs)(o.p,{children:["If you have a general question on how to use and deploy our software, please\nread our ",(0,t.jsx)(o.a,{href:"/node/",children:"Run a Node"})," section or join our\n",(0,t.jsx)(o.a,{href:"/get-involved/",children:"community Discord"}),"."]}),(0,t.jsxs)(o.p,{children:["All community members are welcome and encouraged to commit code, documentation\nand enhancement proposals to the platform. Contribution guidelines can be found\n",(0,t.jsx)(o.a,{href:"/get-involved/oasis-core",children:"here"}),"."]})]}),"\n",(0,t.jsx)(o.h3,{id:"governance-model-overview",children:"Governance Model Overview"}),"\n",(0,t.jsx)(o.p,{children:"The Oasis Protocol Foundation proposes a representative democracy governance\nmodel based on a combination of off-chain and on-chain processes for the\ncontinued development of the Oasis Network. The Oasis Protocol Foundation will\nbe tasked with guiding the long-term development of the platform and\ncoordinating the community of development and network operations, with input\ncollected from community members and changes to the network being voted on by\nnode operators, with voting power based proportionally on staked and delegated\ntokens. We propose this model because we think it will provide a balanced voice\nto all engaged community members -- from developers of all sizes, to node\nowners, to token holders -- while at the same time still facilitating the swift\ndeployment of network updates, new features, critical bug fixes."}),"\n",(0,t.jsx)(o.p,{children:"In order for the community to balance distributed ownership and participation\nwith speed and quality of platform development, we propose a hybrid model of\noff- and on-chain mechanisms, organized around the following key components:"}),"\n",(0,t.jsxs)(o.ol,{children:["\n",(0,t.jsx)(o.li,{children:"Minor Feature Requests"}),"\n",(0,t.jsx)(o.li,{children:"Major Feature Requests"}),"\n",(0,t.jsx)(o.li,{children:"Bug Fixes"}),"\n"]}),"\n",(0,t.jsx)(o.h3,{id:"decision-making-process",children:"Decision Making Process"}),"\n",(0,t.jsx)(o.p,{children:"Moving forward, our proposed process for reviewing and approving major protocol\nupdates is:"}),"\n",(0,t.jsxs)(o.ul,{children:["\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsxs)(o.p,{children:[(0,t.jsx)(o.strong,{children:"Proposals."})," for features and roadmap updates can come from anyone in the\ncommunity in the form of issues\n(",(0,t.jsx)(o.a,{href:"/get-involved/network-governance#minor-feature-requests",children:"for minor features"}),") or\n",(0,t.jsx)(o.a,{href:"../../adrs",children:"Architectural Decision Records"})," (ADRs,\n",(0,t.jsx)(o.a,{href:"/get-involved/network-governance#major-feature-requests",children:"for major features"}),")."]}),"\n"]}),"\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsxs)(o.p,{children:[(0,t.jsx)(o.strong,{children:"Review and discussion of the proposals."})," Decisions about the future of the\nproject are made through discussion with all members of the community, from\nthe newest user to the most experienced. All non-sensitive project management\ndiscussion takes place in the Oasis Protocol GitHub via issues\n(",(0,t.jsx)(o.a,{href:"/get-involved/network-governance#minor-feature-requests",children:"for minor features"}),") and ADRs\n(",(0,t.jsx)(o.a,{href:"/get-involved/network-governance#major-feature-requests",children:"for major features"}),")."]}),"\n"]}),"\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsxs)(o.p,{children:[(0,t.jsx)(o.strong,{children:"Decision making process."})," In order to ensure that the project is not\nbogged down by endless discussion and continual voting, the project operates\na policy of lazy consensus. This allows the majority of decisions to be made\nwithout resorting to a formal vote."]}),"\n",(0,t.jsx)(o.p,{children:"In general, as long as nobody explicitly opposes a proposal or patch, it is\nrecognised as having the support of the community. For lazy consensus to be\neffective, it is necessary to allow at least 72 hours before assuming that\nthere are no objections to the proposal. This requirement ensures that\neveryone is given enough time to read, digest and respond to the proposal."}),"\n",(0,t.jsxs)(o.p,{children:["In case consensus is not reached through discussion, the\n",(0,t.jsx)(o.a,{href:"https://github.com/oasisprotocol/oasis-core/blob/master/GOVERNANCE.md#committers",children:"project committers"}),"\nmay vote to either accept the proposal or reject it. Votes are cast using\ncomments in the proposal pull request. The proposal is accepted by a simple\nmajority vote."]}),"\n"]}),"\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsxs)(o.p,{children:[(0,t.jsx)(o.strong,{children:"Final vote for approval."})," Once built, the community votes to approve each\nupgrade and the corresponding features that are included in the proposal.\nThis voting process may initially be done off-chain but will eventually\nbecome an on-chain process. Entities holding stake will vote to approve\nchanges, with each entity's voting power being proportional to their share of\ntokens staked relative to the total tokens staked."]}),"\n"]}),"\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsxs)(o.p,{children:[(0,t.jsx)(o.strong,{children:"Upgrade."})," Node operators autonomously upgrade their system to run the new\nversion of the software."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(o.h3,{id:"minor-feature-requests",children:"Minor Feature Requests"}),"\n",(0,t.jsx)(o.p,{children:"To request new functionality, there are two primary approaches that will be\nmost effective at receiving input and making progress."}),"\n",(0,t.jsxs)(o.p,{children:["If the feature is small - a change to a single piece of functionality, or an\naddition that can be expressed clearly and succinctly in a few sentences,\nthen the most appropriate place to\n",(0,t.jsx)(o.a,{href:"https://github.com/oasisprotocol/oasis-core/issues/new?template=feature_request.md",children:"propose it is as a new feature request"}),"\nin the Oasis Core repository."]}),"\n",(0,t.jsx)(o.h3,{id:"major-feature-requests",children:"Major Feature Requests"}),"\n",(0,t.jsxs)(o.p,{children:["If the feature is more complicated, involves protocol changes, or has potential\nsafety or performance implications, then consider\n",(0,t.jsx)(o.a,{href:"../../adrs",children:"proposing an Architectural Decision Record (ADR)"})," and submit it as\na pull request to the Oasis Core repository. This will allow a structured\nreview and commenting of the proposed changes. You should aim to get the ADR\naccepted and merged before starting on implementation. Please keep in mind that\nthe project's committers still have the final word on what is accepted into the\nproject."]}),"\n",(0,t.jsx)(o.admonition,{type:"info",children:(0,t.jsx)(o.p,{children:"We recommend that major protocol updates including a need to hard fork, roadmap\nand feature planning be conducted with recommendations from the Oasis Protocol\nFoundation and its technical advisory committee."})}),"\n",(0,t.jsx)(o.h3,{id:"urgent-bug-fixes",children:"Urgent Bug Fixes"}),"\n",(0,t.jsx)(o.p,{children:"Urgent bug fixes will primarily be coordinated off-chain to optimize for speed\nin addressing any issues that are critical to the immediate health of the\nnetwork. The Oasis Network community as a whole is collectively responsible for\nidentifying and addressing bugs. As bugs are identified, the Oasis Protocol\nFoundation can serve as a line of first defense to triage these bugs and\ncoordinate security patches for quick release."}),"\n",(0,t.jsx)(o.p,{children:"Bugs are a reality for any software project. We can't fix what we don't know\nabout!"}),"\n",(0,t.jsxs)(o.p,{children:["If you believe a bug report presents a security risk, please follow\n",(0,t.jsx)(o.a,{href:"https://en.wikipedia.org/wiki/Responsible_disclosure",children:"responsible disclosure"}),"\nand report it by following the\n",(0,t.jsx)(o.a,{href:"https://oasisprotocol.org/security",children:"security disclosure information"})," instead\nof filing a public issue or posting it to a public forum."]}),"\n",(0,t.jsx)(o.p,{children:"We will get back to you promptly."}),"\n",(0,t.jsxs)(o.p,{children:["Otherwise, please, first search between\n",(0,t.jsx)(o.a,{href:"https://github.com/oasisprotocol/oasis-core/issues",children:"existing issues in our repository"}),"\nand if the issue is not reported yet,\n",(0,t.jsx)(o.a,{href:"https://github.com/oasisprotocol/oasis-core/issues/new?template=bug_report.md",children:"file a new one"}),"."]}),"\n",(0,t.jsx)(o.h3,{id:"contributing-to-the-network",children:"Contributing to the Network"}),"\n",(0,t.jsxs)(o.p,{children:["If you are interested in contributing to the Oasis Network's codebase or\ndocumentation, please\n",(0,t.jsx)(o.a,{href:"/get-involved/oasis-core",children:"review our contribution guidelines here."}),"."]})]})}function h(e={}){const{wrapper:o}={...(0,s.R)(),...e.components};return o?(0,t.jsx)(o,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},8453:(e,o,n)=>{n.d(o,{R:()=>r,x:()=>a});var t=n(6540);const s={},i=t.createContext(s);function r(e){const o=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function a(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(i.Provider,{value:o},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/736ce571.e13e5850.js b/assets/js/736ce571.e13e5850.js
new file mode 100644
index 0000000000..f9130f5748
--- /dev/null
+++ b/assets/js/736ce571.e13e5850.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[210],{9817:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>t,metadata:()=>a,toc:()=>c});var r=i(4848),s=i(8453);const t={},o="Hardware Requirements",a={id:"node/run-your-node/prerequisites/hardware-recommendations",title:"Hardware Requirements",description:"The Oasis Network is composed of multiple classes of nodes and services such",source:"@site/docs/node/run-your-node/prerequisites/hardware-recommendations.md",sourceDirName:"node/run-your-node/prerequisites",slug:"/node/run-your-node/prerequisites/hardware-recommendations",permalink:"/node/run-your-node/prerequisites/hardware-recommendations",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/node/run-your-node/prerequisites/hardware-recommendations.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"operators",previous:{title:"Prerequisites",permalink:"/node/run-your-node/prerequisites"},next:{title:"Stake Requirements",permalink:"/node/run-your-node/prerequisites/stake-requirements"}},d={},c=[{value:"CPU",id:"suggested-minimum-configurations",level:3},{value:"Memory",id:"memory",level:3},{value:"Storage",id:"storage",level:3},{value:"Network",id:"network",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h3:"h3",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"hardware-requirements",children:"Hardware Requirements"}),"\n",(0,r.jsx)(n.p,{children:"The Oasis Network is composed of multiple classes of nodes and services such\nas:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Consensus validator or non-validator node"}),"\n",(0,r.jsx)(n.li,{children:"Sapphire ParaTime compute or client node"}),"\n",(0,r.jsx)(n.li,{children:"Emerald ParaTime compute or client node"}),"\n",(0,r.jsx)(n.li,{children:"Cipher ParaTime compute or client node"}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"info",children:(0,r.jsxs)(n.p,{children:["Hardware requirements for running the Oasis Web3 gateway can be found\n",(0,r.jsx)(n.a,{href:"/node/web3#hardware",children:"here"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This page describes the ",(0,r.jsx)(n.strong,{children:"minimum"})," and ",(0,r.jsx)(n.strong,{children:"recommended"})," system hardware\nrequirements for running different types of nodes on the Oasis Network. If you\nare running more than one ParaTime on a single node, you will require more\nresources."]}),"\n",(0,r.jsxs)(n.admonition,{type:"caution",children:[(0,r.jsx)(n.p,{children:"If you configure a system with slower resources than the recommended values, you\nrun the risk of being underprovisioned, causing proposer node timeouts and\nsynchronization delays. This could result in losing stake and not participating\nin committees."}),(0,r.jsx)(n.p,{children:"If you run out of memory or storage, the Oasis node process will be forcefully\nkilled. This could lead to state corruption, losing stake and not participating\nin committees."})]}),"\n",(0,r.jsx)(n.h3,{id:"suggested-minimum-configurations",children:"CPU"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Consensus validator or non-validator node:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Minimum: 2.0 GHz x86-64 CPU with ",(0,r.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/AES_instruction_set",children:"AES instruction set"})," support"]}),"\n",(0,r.jsxs)(n.li,{children:["Recommended: 2.0 GHz x86-64 CPU with 2 cores/vCPUs with\n",(0,r.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/AES_instruction_set",children:"AES instruction set"})," and ",(0,r.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#Advanced_Vector_Extensions_2",children:"AVX2"})," support"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Emerald ParaTime compute node and all ParaTime client nodes:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Minimum: 2.0 GHz x86-64 CPU with ",(0,r.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/AES_instruction_set",children:"AES instruction set"})," support"]}),"\n",(0,r.jsxs)(n.li,{children:["Recommended: 2.0 GHz x86-64 CPU with 4 cores/vCPUs with\n",(0,r.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/AES_instruction_set",children:"AES instruction set"})," and ",(0,r.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#Advanced_Vector_Extensions_2",children:"AVX2"})," support"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Sapphire and Cipher ParaTime compute node:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Minimum: 2.0 GHz x86-64 CPU with ",(0,r.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/AES_instruction_set",children:"AES instruction set"})," and ",(0,r.jsx)(n.a,{href:"https://www.intel.com/content/www/us/en/architecture-and-technology/software-guard-extensions.html",children:"Intel SGX"})," support"]}),"\n",(0,r.jsxs)(n.li,{children:["Recommended: 2.0 GHz x86-64 CPU with 2 cores/vCPUs with\n",(0,r.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/AES_instruction_set",children:"AES instruction set"}),", ",(0,r.jsx)(n.a,{href:"https://www.intel.com/content/www/us/en/architecture-and-technology/software-guard-extensions.html",children:"Intel SGX"})," and ",(0,r.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#Advanced_Vector_Extensions_2",children:"AVX2"})," support"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.admonition,{type:"info",children:[(0,r.jsx)(n.p,{children:"During regular workload your node will operate with the minimal CPU resources.\nHowever, if put under heavy load it might require more cores/vCPUs (e.g. an\nEmerald ParaTime client node behind a public Emerald Web3 gateway)."}),(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/AES_instruction_set",children:"AES instruction set"})," support is required by ",(0,r.jsx)(n.a,{href:"https://sites.google.com/view/deoxyscipher",children:"Deoxys-II-256-128"}),", a\nMisuse-Resistant Authenticated Encryption (MRAE) algorithm, which is used for\nencrypting ParaTime's state."]}),(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#Advanced_Vector_Extensions_2",children:"Advanced Vector Extensions 2 (AVX2)"})," support enables faster Ed25519\nsignature verification which in turn makes a node sync faster."]}),(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"https://www.intel.com/content/www/us/en/architecture-and-technology/software-guard-extensions.html",children:"Intel SGX"})," support is required if you want to run Paratime compute nodes\nthat use a trusted execution environment (TEE)."]})]}),"\n",(0,r.jsx)(n.h3,{id:"memory",children:"Memory"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Consensus validator or non-validator node:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Minimum: 6 GB of ECC RAM"}),"\n",(0,r.jsx)(n.li,{children:"Recommended: 8 GB of ECC RAM"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Each Emerald, Sapphire, Cipher compute or client node:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Minimum: 12 GB of ECC RAM"}),"\n",(0,r.jsx)(n.li,{children:"Recommended: 20 GB of ECC RAM"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"info",children:(0,r.jsx)(n.p,{children:"During regular workload your node will operate with less than the minimum amount\nof memory. However, at certain time points, it will absolutely require more\nmemory. Examples of such more resource intensive time points are the initial\nstate sync, BadgerDB migration when upgrading a node to a new major version of\nthe Oasis Core, generating storage checkpoints with BadgerDB, periodic BadgerDB\ncompactions..."})}),"\n",(0,r.jsx)(n.h3,{id:"storage",children:"Storage"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Consensus validator or non-validator node:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Minimum: 400 GB of SSD or NVMe fast storage"}),"\n",(0,r.jsx)(n.li,{children:"Recommended: 700 GB of SSD or NVMe fast storage"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Emerald ParaTime compute or client node (in addition to the consensus storage requirements):"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Minimum: 400 GB of SSD or NVMe fast storage"}),"\n",(0,r.jsx)(n.li,{children:"Recommended: 700 GB of SSD or NVMe fast storage"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Sapphire and Cipher ParaTime compute or client node (in addition to the consensus storage requirements):"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Minimum: 200 GB of SSD or NVMe fast storage"}),"\n",(0,r.jsx)(n.li,{children:"Recommended: 300 GB of SSD or NVMe fast storage"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"caution",children:(0,r.jsxs)(n.p,{children:["Consensus and ParaTime state is stored in an embedded ",(0,r.jsx)(n.a,{href:"https://dgraph.io/docs/badger/",children:"BadgerDB"})," database which\nwas ",(0,r.jsx)(n.a,{href:"https://dgraph.io/docs/badger/design/",children:"designed to run on SSDs"}),". Hence, we ",(0,r.jsx)(n.strong,{children:"strongly discourage"}),"\ntrying to run a node that stores data ",(0,r.jsx)(n.strong,{children:"on classical HDDs"}),"."]})}),"\n",(0,r.jsxs)(n.admonition,{type:"info",children:[(0,r.jsx)(n.p,{children:"The consensus layer and ParaTimes accumulate state over time. The speed at which\nthe state grows depends on the number of transactions on the network and\nParaTimes."}),(0,r.jsx)(n.p,{children:"For example, a consensus non-validator node on the Mainnet accumulated:"}),(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["280 GB of consensus state in ~1 year between Apr 28, 2021 and Apr 11, 2022 (since the ",(0,r.jsx)(n.a,{href:"/node/mainnet/previous-upgrades/cobalt-upgrade",children:"Cobalt upgrade"}),")"]}),"\n",(0,r.jsxs)(n.li,{children:["32 GB of consensus state in ~1 month since the ",(0,r.jsx)(n.a,{href:"/node/mainnet/previous-upgrades/damask-upgrade",children:"Damask upgrade"})]}),"\n"]}),(0,r.jsx)(n.p,{children:"For example, an Emerald client node on the Mainnet additionally accumulated:"}),(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["260 GB of Emerald ParaTime state in ~5 months between Nov 18, 2021 and Apr 11, 2022 (since the ",(0,r.jsx)(n.a,{href:"https://medium.com/oasis-protocol-project/oasis-emerald-evm-paratime-is-live-on-mainnet-13afe953a4c9",children:"Emerald Mainnet launch"}),")"]}),"\n",(0,r.jsxs)(n.li,{children:["25 GB of Emerald ParaTime state in ~1 month since the ",(0,r.jsx)(n.a,{href:"/node/mainnet/previous-upgrades/damask-upgrade",children:"Damask upgrade"})]}),"\n"]})]}),"\n",(0,r.jsx)(n.admonition,{type:"tip",children:(0,r.jsxs)(n.p,{children:["Dump & restore upgrades (e.g. ",(0,r.jsx)(n.a,{href:"/node/mainnet/previous-upgrades/damask-upgrade",children:"Damask upgrade"}),", ",(0,r.jsx)(n.a,{href:"/node/mainnet/previous-upgrades/cobalt-upgrade",children:"Cobalt upgrade"}),") include state\nwipes which will free the node storage. Historical state can be accessed by\nrunning a separate archive node."]})}),"\n",(0,r.jsxs)(n.admonition,{type:"info",children:[(0,r.jsxs)(n.p,{children:["You can configure your node ",(0,r.jsx)(n.em,{children:"not to"})," keep a complete state from the genesis\nonward. This will reduce the amount of storage required for the consensus and\nParaTime state."]}),(0,r.jsxs)(n.p,{children:["To enable pruning of the consensus state set the\n",(0,r.jsx)(n.code,{children:"consensus.prune.strategy"})," and\n",(0,r.jsx)(n.code,{children:"consensus.prune.num_kept"})," parameters appropriately in your\n",(0,r.jsx)(n.a,{href:"/node/run-your-node/validator-node#configuration",children:"node's configuration"}),"."]}),(0,r.jsxs)(n.p,{children:["To enable pruning of the ParaTime state set the\n",(0,r.jsx)(n.code,{children:"runtime.prune.strategy"})," and ",(0,r.jsx)(n.code,{children:"runtime.prune.num_kept"}),"\nparameters appropriately in your ",(0,r.jsx)(n.a,{href:"/node/run-your-node/validator-node#configuration",children:"node's configuration"}),"."]})]}),"\n",(0,r.jsx)(n.h3,{id:"network",children:"Network"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Consensus validator node and all ParaTime compute nodes:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Minimum: 200 Mbps internet connection with low latency"}),"\n",(0,r.jsx)(n.li,{children:"Recommended: 1 Gbps internet connection with low latency"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"info",children:(0,r.jsx)(n.p,{children:"During regular workload your node will receive much less network traffic.\nHowever, at certain time points when huge bursts of transactions arrive, you\nneed to assure that it doesn't timeout."})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>a});var r=i(6540);const s={},t=r.createContext(s);function o(e){const n=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/74cc02ce.bcf65a71.js b/assets/js/74cc02ce.bcf65a71.js
new file mode 100644
index 0000000000..d9c8c6f915
--- /dev/null
+++ b/assets/js/74cc02ce.bcf65a71.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[6350],{7725:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>u});var r=n(4848),s=n(8453),o=n(2550),i=n(6116);const a={},c="Use Oasis",l={id:"general/README",title:"Use Oasis",description:"This chapter provides general overview of the Oasis Network and introduces",source:"@site/docs/general/README.mdx",sourceDirName:"general",slug:"/general/",permalink:"/general/",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/general/README.mdx",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"general",next:{title:"Oasis Network",permalink:"/general/oasis-network/"}},d={},u=[];function m(e){const t={h1:"h1",p:"p",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h1,{id:"use-oasis",children:"Use Oasis"}),"\n",(0,r.jsx)(t.p,{children:"This chapter provides general overview of the Oasis Network and introduces\nbasic tools for you to get started."}),"\n",(0,r.jsx)(o.A,{items:[(0,i.$)("/general/oasis-network/"),(0,i.$)("/general/manage-tokens/"),(0,i.$)("/general/manage-tokens/cli/")]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(m,{...e})}):m(e)}},5965:(e,t,n)=>{n.d(t,{A:()=>g});n(6540);var r=n(4164),s=n(8774),o=n(4142),i=n(5846),a=n(6654),c=n(1312),l=n(1107);const d={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var u=n(4848);function m(e){let{href:t,children:n}=e;return(0,u.jsx)(s.A,{href:t,className:(0,r.A)("card padding--lg",d.cardContainer),children:n})}function h(e){let{href:t,icon:n,title:s,description:o}=e;return(0,u.jsxs)(m,{href:t,children:[(0,u.jsxs)(l.A,{as:"h2",className:(0,r.A)("text--truncate",d.cardTitle),title:s,children:[n," ",s]}),o&&(0,u.jsx)("p",{className:(0,r.A)("text--truncate",d.cardDescription),title:o,children:o})]})}function p(e){let{item:t}=e;const n=(0,o.Nr)(t),r=function(){const{selectMessage:e}=(0,i.W)();return t=>e(t,(0,c.T)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,u.jsx)(h,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??r(t.items.length)}):null}function f(e){let{item:t}=e;const n=(0,a.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,o.cC)(t.docId??void 0);return(0,u.jsx)(h,{href:t.href,icon:n,title:t.label,description:t.description??r?.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return(0,u.jsx)(f,{item:t});case"category":return(0,u.jsx)(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}},2550:(e,t,n)=>{n.d(t,{A:()=>c});n(6540);var r=n(4164),s=n(4142),o=n(5965),i=n(4848);function a(e){let{className:t}=e;const n=(0,s.$S)();return(0,i.jsx)(c,{items:n.items,className:t})}function c(e){const{items:t,className:n}=e;if(!t)return(0,i.jsx)(a,{...e});const c=(0,s.d1)(t);return(0,i.jsx)("section",{className:(0,r.A)("row",n),children:c.map(((e,t)=>(0,i.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,i.jsx)(o.A,{item:e})},t)))})}},5846:(e,t,n)=>{n.d(t,{W:()=>l});var r=n(6540),s=n(4586);const o=["zero","one","two","few","many","other"];function i(e){return o.filter((t=>e.includes(t)))}const a={locale:"en",pluralForms:i(["one","other"]),select:e=>1===e?"one":"other"};function c(){const{i18n:{currentLocale:e}}=(0,s.A)();return(0,r.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:i(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),a}}),[e])}function l(){const e=c();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const s=n.select(t),o=n.pluralForms.indexOf(s);return r[Math.min(o,r.length-1)]}(n,t,e)}}},6116:(e,t,n)=>{n.d(t,{$:()=>o});var r=n(2252);function s(e){for(const t of e){const e=t.href;e&&void 0===globalThis.sidebarItemsMap[e]&&(globalThis.sidebarItemsMap[e]=t),"category"===t.type&&s(t.items)}}function o(e){const t=(0,r.r)();if(!t)throw new Error("Unexpected: cant find docsVersion in current context");if(void 0===globalThis.sidebarItemsMap){globalThis.sidebarItemsMap={};for(const e in t.docsSidebars)s(t.docsSidebars[e])}if(void 0===globalThis.sidebarItemsMap[e])throw console.log("Registered sidebar items:"),console.log(globalThis.sidebarItemsMap),new Error("Unexpected: sidebar item with href "+e+" does not exist.");return globalThis.sidebarItemsMap[e]}},8453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var r=n(6540);const s={},o=r.createContext(s);function i(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/767aa429.5de976b1.js b/assets/js/767aa429.5de976b1.js
new file mode 100644
index 0000000000..89a842b291
--- /dev/null
+++ b/assets/js/767aa429.5de976b1.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[472],{7978:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>t,metadata:()=>i,toc:()=>o});var a=s(4848),r=s(8453);const t={title:"Wallet",description:"Manage accounts in your CLI wallet"},l="Managing Accounts in Your Wallet",i={id:"general/manage-tokens/cli/wallet",title:"Wallet",description:"Manage accounts in your CLI wallet",source:"@site/docs/general/manage-tokens/cli/wallet.md",sourceDirName:"general/manage-tokens/cli",slug:"/general/manage-tokens/cli/wallet",permalink:"/general/manage-tokens/cli/wallet",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/cli/edit/master/docs/wallet.md",tags:[],version:"current",lastUpdatedAt:1715850376e3,frontMatter:{title:"Wallet",description:"Manage accounts in your CLI wallet"},sidebar:"general",previous:{title:"ParaTime",permalink:"/general/manage-tokens/cli/paratime"},next:{title:"Account",permalink:"/general/manage-tokens/cli/account"}},c={},o=[{value:"Create an Account",id:"create",level:2},{value:"Import an Existing Keypair or a Mnemonic",id:"import",level:2},{value:"List Accounts Stored in Your Wallet",id:"list",level:2},{value:"Show Account Configuration Details",id:"show",level:2},{value:"Export the Account's Secret",id:"export",level:2},{value:"Renaming the Account",id:"rename",level:2},{value:"Deleting an Account",id:"remove",level:2},{value:"Set Default Account",id:"set-default",level:2},{value:"Advanced",id:"advanced",level:2},{value:"Import an Existing Keypair from PEM file",id:"import-file",level:3},{value:"Remote Signer for oasis-node
",id:"remote-signer",level:3},{value:"Test Accounts",id:"test-accounts",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h1,{id:"managing-accounts-in-your-wallet",children:"Managing Accounts in Your Wallet"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"wallet"})," command is used to manage accounts in your wallet. The wallet\ncan contain file-based accounts which are stored along your Oasis CLI\nconfiguration, or a reference to an account stored on your hardware wallet."]}),"\n",(0,a.jsx)(n.p,{children:"The following encryption algorithms and derivation paths are supported by the\nOasis CLI for your accounts:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"ed25519-adr8"}),": ",(0,a.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/EdDSA",children:"Ed25519"})," keypair using the ",(0,a.jsx)(n.a,{href:"/adrs/0008-standard-account-key-generation",children:"ADR-8"})," derivation path in order\nto obtain a private key from the mnemonic. This is the default setting\nsuitable for accounts on the Oasis consensus layer and Cipher."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"secp256k1-bip44"}),": ",(0,a.jsx)(n.a,{href:"https://en.bitcoin.it/wiki/Secp256k1",children:"Secp256k1"})," Ethereum-compatible keypair using ",(0,a.jsx)(n.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki",children:"BIP-44"}),"\nwith ETH coin type to derive a private key. This setting is\nused for accounts living on EVM-compatible ParaTimes such as Sapphire or\nEmerald. The same account can be imported into Metamask and other Ethereum\nwallets."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"ed25519-raw"}),": ",(0,a.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/EdDSA",children:"Ed25519"})," keypair imported directly from the Base64-encoded\nprivate key. No key derivation is involved. This setting is primarily used by\nthe network validators to sign the governance and other consensus-layer\ntransactions."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"ed25519-legacy"}),": ",(0,a.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/EdDSA",children:"Ed25519"})," keypair using a legacy 5-component derivation\npath. This is the preferred setting for Oasis accounts stored on a hardware\nwallet like Ledger. It is called legacy, because it was first implemented\nbefore the ",(0,a.jsx)(n.a,{href:"/adrs/0008-standard-account-key-generation",children:"ADR-8"})," was standardized."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"sr25519-adr8"}),": ",(0,a.jsx)(n.a,{href:"https://wiki.polkadot.network/docs/learn-cryptography",children:"Sr25519"})," keypair using the ",(0,a.jsx)(n.a,{href:"/adrs/0008-standard-account-key-generation",children:"ADR-8"})," derivation path. This is\nan alternative signature scheme for signing ParaTime transactions."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"secp256k1-raw"})," and ",(0,a.jsx)(n.code,{children:"sr25519-raw"}),": Respective Secp256k1 and Sr25519 keypairs\nimported directly from the Hex- or Base64-encoded private key. No key\nderivation is involved."]}),"\n"]}),"\n",(0,a.jsxs)(n.admonition,{type:"tip",children:[(0,a.jsxs)(n.p,{children:["For compatibility with Ethereum, each ",(0,a.jsx)(n.code,{children:"secp256k1"})," account corresponds to two\naddresses:"]}),(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["20-byte hex-encoded Ethereum-compatible address, e.g.\n",(0,a.jsx)(n.code,{children:"0xDCbF59bbcC0B297F1729adB23d7a5D721B481BA9"})]}),"\n",(0,a.jsxs)(n.li,{children:["Bech32-encoded Oasis native address, e.g.\n",(0,a.jsx)(n.code,{children:"oasis1qq3agel5x07pxz08ns3d2y7sjrr3xf9paquhhhzl"}),"."]}),"\n"]}),(0,a.jsxs)(n.p,{children:["There exists a ",(0,a.jsx)(n.a,{href:"https://github.com/oasisprotocol/oasis-sdk/blob/c36a7ee194abf4ca28fdac0edbefe3843b39bf69/client-sdk/go/types/address.go#L135-L142",children:"mapping"})," from the Ethereum address\nto the native Oasis address as in the example above, but ",(0,a.jsx)(n.strong,{children:"there is no reverse\nmapping"}),"."]})]}),"\n",(0,a.jsx)(n.h2,{id:"create",children:"Create an Account"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"wallet create "})," command is used add a new account into your Oasis\nCLI wallet by:"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"generating a new mnemonic and storing it into a file-based wallet, or"}),"\n",(0,a.jsx)(n.li,{children:"creating a reference to an account stored on your hardware wallet."}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"By default, a password-encrypted file-based wallet will be used for storing the\nprivate key. You will have to enter the password for this account each time to\naccess use it for signing the transactions (e.g. to send tokens). The account\naddress is public and can be accessed without entering the passphrase."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet create oscar\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"? Choose a new passphrase:\n? Repeat passphrase:\n"})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:["The first account you create or import will become your ",(0,a.jsx)(n.strong,{children:"default account"}),".\nThis means it will automatically be selected as a source for sending funds or\ncalling smart contracts unless specified otherwise by using ",(0,a.jsx)(n.code,{children:"--account "}),"\nflag. You can always ",(0,a.jsx)(n.a,{href:"#set-default",children:"change the default account"})," later."]})}),"\n",(0,a.jsxs)(n.p,{children:["To use your hardware wallet, add ",(0,a.jsx)(n.code,{children:"--kind ledger"})," parameter and Oasis CLI will\nstore a reference to an account on your hardware wallet:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet create logan --kind ledger\n"})}),"\n",(0,a.jsxs)(n.p,{children:["A specific account kind (",(0,a.jsx)(n.code,{children:"ed25519-adr8"}),", ",(0,a.jsx)(n.code,{children:"secp256k1-bip44"}),") and the derivation\npath number can be passed with ",(0,a.jsx)(n.code,{children:"--file.algorithm"})," and ",(0,a.jsx)(n.code,{children:"--file.number"})," or\n",(0,a.jsx)(n.code,{children:"--ledger.algorithm"})," and ",(0,a.jsx)(n.code,{children:"--ledger.number"})," respectively. For example:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet create logan --kind ledger\n"})}),"\n",(0,a.jsxs)(n.admonition,{type:"tip",children:[(0,a.jsx)(n.p,{children:"When creating a hardware wallet account, Oasis CLI will:"}),(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"obtain the public key of the account from your hardware wallet,"}),"\n",(0,a.jsx)(n.li,{children:"compute the corresponding native address, and"}),"\n",(0,a.jsx)(n.li,{children:"store the Oasis native address into the Oasis CLI."}),"\n"]}),(0,a.jsx)(n.p,{children:"If you try to open the same account with a different Ledger device or\nreset your Ledger with a new mnemonic, Oasis CLI will abort because the address\nof the account obtained from the new device will not match the one stored in\nyour config."}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet show logan\n"})}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"Error: address mismatch after loading account (expected: oasis1qpl4axynedmdrrgrg7dpw3yxc4a8crevr5dkuksl got: oasis1qzdyu09x7hs5nqa0sjgy5jtmz3j5f99ccq0aezjk)\n"})})]}),"\n",(0,a.jsx)(n.h2,{id:"import",children:"Import an Existing Keypair or a Mnemonic"}),"\n",(0,a.jsxs)(n.p,{children:["If you already have a mnemonic or a raw private key, you can import it\nas a new account by invoking ",(0,a.jsx)(n.code,{children:"wallet import"}),". You will be asked\ninteractively to select an account kind (",(0,a.jsx)(n.code,{children:"mnemonic"})," or ",(0,a.jsx)(n.code,{children:"private key"}),"),\nencryption algorithm (",(0,a.jsx)(n.code,{children:"ed25519"})," or ",(0,a.jsx)(n.code,{children:"secp256k1"}),") and then provide either the\nmnemonic with the derivation number, or the raw private key in the corresponding\nformat."]}),"\n",(0,a.jsx)(n.p,{children:"Importing an account with a mnemonic looks like this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet import eugene\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"? Kind: mnemonic\n? Algorithm: secp256k1-bip44\n? Key number: 0\n? Mnemonic: [Enter 2 empty lines to finish]man ankle mystery favorite tone number ice west spare marriage control lucky life together neither\n\n? Mnemonic:\nman ankle mystery favorite tone number ice west spare marriage control lucky life together neither\n? Choose a new passphrase:\n? Repeat passphrase:\n"})}),"\n",(0,a.jsx)(n.p,{children:"Let's make another Secp256k1 account and entering a hex-encoded raw private key:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet import emma\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"oasis wallet import emma\n? Kind: private key\n? Algorithm: secp256k1-raw\n? Private key (hex-encoded): [Enter 2 empty lines to finish]4811ebbe4f29f32a758f6f7bad39deb97ea67f07350637e31c75795dc679262a\n\n? Private key (hex-encoded):\n4811ebbe4f29f32a758f6f7bad39deb97ea67f07350637e31c75795dc679262a\n? Choose a new passphrase:\n? Repeat passphrase:\n"})}),"\n",(0,a.jsx)(n.h2,{id:"list",children:"List Accounts Stored in Your Wallet"}),"\n",(0,a.jsxs)(n.p,{children:["You can list all available accounts in your wallet with ",(0,a.jsx)(n.code,{children:"wallet list"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet list\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"ACCOUNT \tKIND \tADDRESS \nemma \tfile (secp256k1-raw) \toasis1qph93wnfw8shu04pqyarvtjy4lytz3hp0c7tqnqh\t\neugene \tfile (secp256k1-bip44:0) \toasis1qrvzxld9rz83wv92lvnkpmr30c77kj2tvg0pednz\t\nlenny \tledger (secp256k1-bip44:3)\toasis1qrmw4rhvp8ksj3yx6p2ftnkz864muc3re5jlgall\t\nlogan \tledger (ed25519-legacy:0) \toasis1qpl4axynedmdrrgrg7dpw3yxc4a8crevr5dkuksl\t\noscar (*)\tfile (ed25519-adr8:0) \toasis1qp87hflmelnpqhzcqcw8rhzakq4elj7jzv090p3e\t\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Above, you can see the native Oasis addresses of all local accounts. The\n",(0,a.jsx)(n.a,{href:"#set-default",children:"default account"})," has a special ",(0,a.jsx)(n.code,{children:"(*)"})," sign next to its name."]}),"\n",(0,a.jsx)(n.h2,{id:"show",children:"Show Account Configuration Details"}),"\n",(0,a.jsxs)(n.p,{children:["To verify whether an account exists in your wallet, use ",(0,a.jsx)(n.code,{children:"wallet show "}),".\nThis will print the account's native address and the public key which requires\nentering your account's password."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet show oscar\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"Unlock your account.\n? Passphrase:\nName: oscar\nKind: file (ed25519-adr8:0)\nPublic Key: Bx6gOixnxy15tCs09ua5DcKyX9uo2Forb32O6Hyjoc8=\nNative address: oasis1qp87hflmelnpqhzcqcw8rhzakq4elj7jzv090p3e\n"})}),"\n",(0,a.jsxs)(n.p,{children:["For ",(0,a.jsx)(n.code,{children:"secp256k1"})," accounts Ethereum's hex-encoded address will also be printed."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet show eugene\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"Unlock your account.\n? Passphrase:\nName: eugene\nKind: file (secp256k1-bip44:0)\nPublic Key: ArEjDxsPfDvfeLlity4mjGzy8E/nI4umiC8vYQh+eh/c\nEthereum address: 0xBd16C6bF701a01DF1B5C11B14860b6bDbE776669\nNative address: oasis1qrvzxld9rz83wv92lvnkpmr30c77kj2tvg0pednz\n"})}),"\n",(0,a.jsx)(n.p,{children:"Showing an account stored on your hardware wallet will require connecting it to\nyour computer:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet show logan\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"Name: logan\nKind: ledger (ed25519-legacy:0)\nPublic Key: l+cuboPsOeuY1+kYlROrpmKgiiELmXSw9xl0WEg8cWE=\nNative address: oasis1qpl4axynedmdrrgrg7dpw3yxc4a8crevr5dkuksl\n"})}),"\n",(0,a.jsx)(n.h2,{id:"export",children:"Export the Account's Secret"}),"\n",(0,a.jsxs)(n.p,{children:["You can obtain the secret material of a file-based account such as the mnemonic\nor the private key by running ",(0,a.jsx)(n.code,{children:"wallet export "}),"."]}),"\n",(0,a.jsx)(n.p,{children:"For example:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet export oscar\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"WARNING: Exporting the account will expose secret key material!\nUnlock your account.\n? Passphrase:\nName: oscar\nKind: file (ed25519-adr8:0)\nPublic Key: Bx6gOixnxy15tCs09ua5DcKyX9uo2Forb32O6Hyjoc8=\nNative address: oasis1qp87hflmelnpqhzcqcw8rhzakq4elj7jzv090p3e\nSecret mnemonic:\npromote easily runway junior saddle gold flip believe wet example amount believe habit mixed pistol lemon increase moon rail mail fiction miss clip asset\nDerived secret key for account number 0:\nLHOUUJgVquTdi/3DVsS4caW4jQcvuFgl1Oag6BwlNvwHHqA6LGfHLXm0KzT25rkNwrJf26jYWitvfY7ofKOhzw==\n"})}),"\n",(0,a.jsx)(n.p,{children:"The same goes for your Secp256k1 accounts:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet export eugene\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"WARNING: Exporting the account will expose secret key material!\nUnlock your account.\n? Passphrase:\nName: eugene\nKind: file (secp256k1-bip44:0)\nPublic Key: ArEjDxsPfDvfeLlity4mjGzy8E/nI4umiC8vYQh+eh/c\nEthereum address: 0xBd16C6bF701a01DF1B5C11B14860b6bDbE776669\nNative address: oasis1qrvzxld9rz83wv92lvnkpmr30c77kj2tvg0pednz\nSecret mnemonic:\nman ankle mystery favorite tone number ice west spare marriage control lucky life together neither\nDerived secret key for account number 0:\nc559cad1e71e0db1b3a657f47ca7a618bfb6a51a7294df72bcfca57aded5377e\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet export emma\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"WARNING: Exporting the account will expose secret key material!\nUnlock your account.\n? Passphrase:\nName: emma\nKind: file (secp256k1-raw)\nPublic Key: Az8B2UpSUET0E3n9XMzr+HBvviQKcRvz6C6bJtRFWNYG\nEthereum address: 0xeEbE22411f579682F6f9D68f4C19B3581bCb576b\nNative address: oasis1qph93wnfw8shu04pqyarvtjy4lytz3hp0c7tqnqh\nSecret key:\n4811ebbe4f29f32a758f6f7bad39deb97ea67f07350637e31c75795dc679262a\n"})}),"\n",(0,a.jsx)(n.p,{children:"Trying to export an account stored on your hardware wallet will only\nexport its public key:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet export lenny\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"WARNING: Exporting the account will expose secret key material!\nName: lenny\nKind: ledger (secp256k1-bip44:3)\nPublic Key: AhhT2TUkEZ7rMasLBvHcsGj4SUO7Iw36ELEpL0evZDV1\nEthereum address: 0x95e5e3C1BDD92cd4A0c14c62480DB5867946281D\nNative address: oasis1qrmw4rhvp8ksj3yx6p2ftnkz864muc3re5jlgall\n"})}),"\n",(0,a.jsx)(n.h2,{id:"rename",children:"Renaming the Account"}),"\n",(0,a.jsxs)(n.p,{children:["To rename an account, run ",(0,a.jsx)(n.code,{children:"wallet rename "}),"."]}),"\n",(0,a.jsx)(n.p,{children:"For example:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet list\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"ACCOUNT \tKIND \tADDRESS \nemma \tfile (secp256k1-raw) \toasis1qph93wnfw8shu04pqyarvtjy4lytz3hp0c7tqnqh\t\neugene \tfile (secp256k1-bip44:0) \toasis1qrvzxld9rz83wv92lvnkpmr30c77kj2tvg0pednz\t\nlenny \tledger (secp256k1-bip44:3)\toasis1qrmw4rhvp8ksj3yx6p2ftnkz864muc3re5jlgall\t\nlogan \tledger (ed25519-legacy:0) \toasis1qpl4axynedmdrrgrg7dpw3yxc4a8crevr5dkuksl\t\noscar (*)\tfile (ed25519-adr8:0) \toasis1qp87hflmelnpqhzcqcw8rhzakq4elj7jzv090p3e\t\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet rename lenny lester\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet list\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"ACCOUNT \tKIND \tADDRESS \nemma \tfile (secp256k1-raw) \toasis1qph93wnfw8shu04pqyarvtjy4lytz3hp0c7tqnqh\t\neugene \tfile (secp256k1-bip44:0) \toasis1qrvzxld9rz83wv92lvnkpmr30c77kj2tvg0pednz\t\nlester \tledger (secp256k1-bip44:3)\toasis1qrmw4rhvp8ksj3yx6p2ftnkz864muc3re5jlgall\t\nlogan \tledger (ed25519-legacy:0) \toasis1qpl4axynedmdrrgrg7dpw3yxc4a8crevr5dkuksl\t\noscar (*)\tfile (ed25519-adr8:0) \toasis1qp87hflmelnpqhzcqcw8rhzakq4elj7jzv090p3e\t\n"})}),"\n",(0,a.jsx)(n.h2,{id:"remove",children:"Deleting an Account"}),"\n",(0,a.jsxs)(n.p,{children:["To irreversibly delete the accounts from your wallet use\n",(0,a.jsx)(n.code,{children:"wallet remove [names]"}),". For file-based accounts this will delete the file\ncontaining the private key from your disk. For hardware wallet accounts this\nwill delete the Oasis CLI reference, but the private keys will remain intact on\nyour hardware wallet."]}),"\n",(0,a.jsxs)(n.p,{children:["For example, let's delete ",(0,a.jsx)(n.code,{children:"lenny"})," account:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet list\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"ACCOUNT \tKIND \tADDRESS \nemma \tfile (secp256k1-raw) \toasis1qph93wnfw8shu04pqyarvtjy4lytz3hp0c7tqnqh\t\neugene \tfile (secp256k1-bip44:0) \toasis1qrvzxld9rz83wv92lvnkpmr30c77kj2tvg0pednz\t\nlenny \tledger (secp256k1-bip44:3)\toasis1qrmw4rhvp8ksj3yx6p2ftnkz864muc3re5jlgall\t\nlogan \tledger (ed25519-legacy:0) \toasis1qpl4axynedmdrrgrg7dpw3yxc4a8crevr5dkuksl\t\noscar (*)\tfile (ed25519-adr8:0) \toasis1qp87hflmelnpqhzcqcw8rhzakq4elj7jzv090p3e\t\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet remove lenny\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"WARNING: Removing the account will ERASE secret key material!\nWARNING: THIS ACTION IS IRREVERSIBLE!\n? Enter 'I really want to remove account lenny' (without quotes) to confirm removal: I really want to remove account lenny\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet list\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"ACCOUNT KIND ADDRESS \nemma file (secp256k1-raw) oasis1qph93wnfw8shu04pqyarvtjy4lytz3hp0c7tqnqh\neugene file (secp256k1-bip44:0) oasis1qrvzxld9rz83wv92lvnkpmr30c77kj2tvg0pednz\nlogan ledger (ed25519-legacy:0) oasis1qpl4axynedmdrrgrg7dpw3yxc4a8crevr5dkuksl\noscar (*) file (ed25519-raw) oasis1qp87hflmelnpqhzcqcw8rhzakq4elj7jzv090p3e\n"})}),"\n",(0,a.jsxs)(n.p,{children:["You can also delete accounct in non-interactive mode format by passing the\n",(0,a.jsx)(n.code,{children:"-y"})," parameter:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet remove lenny -y\n"})}),"\n",(0,a.jsx)(n.h2,{id:"set-default",children:"Set Default Account"}),"\n",(0,a.jsxs)(n.p,{children:["To change your default account, use ",(0,a.jsx)(n.code,{children:"wallet set-default "})," and the\nname of the desired default account."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet list\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"ACCOUNT \tKIND \tADDRESS \nemma \tfile (secp256k1-raw) \toasis1qph93wnfw8shu04pqyarvtjy4lytz3hp0c7tqnqh\t\neugene \tfile (secp256k1-bip44:0) \toasis1qrvzxld9rz83wv92lvnkpmr30c77kj2tvg0pednz\t\nlenny \tledger (secp256k1-bip44:3)\toasis1qrmw4rhvp8ksj3yx6p2ftnkz864muc3re5jlgall\t\nlogan \tledger (ed25519-legacy:0) \toasis1qpl4axynedmdrrgrg7dpw3yxc4a8crevr5dkuksl\t\noscar (*)\tfile (ed25519-adr8:0) \toasis1qp87hflmelnpqhzcqcw8rhzakq4elj7jzv090p3e\t\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet set-default lenny\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet list\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"ACCOUNT \tKIND \tADDRESS \nemma \tfile (secp256k1-raw) \toasis1qph93wnfw8shu04pqyarvtjy4lytz3hp0c7tqnqh\t\neugene \tfile (secp256k1-bip44:0) \toasis1qrvzxld9rz83wv92lvnkpmr30c77kj2tvg0pednz\t\nlenny (*)\tledger (secp256k1-bip44:3)\toasis1qrmw4rhvp8ksj3yx6p2ftnkz864muc3re5jlgall\t\nlogan \tledger (ed25519-legacy:0) \toasis1qpl4axynedmdrrgrg7dpw3yxc4a8crevr5dkuksl\t\noscar \tfile (ed25519-adr8:0) \toasis1qp87hflmelnpqhzcqcw8rhzakq4elj7jzv090p3e\t\n"})}),"\n",(0,a.jsx)(n.h2,{id:"advanced",children:"Advanced"}),"\n",(0,a.jsx)(n.h3,{id:"import-file",children:"Import an Existing Keypair from PEM file"}),"\n",(0,a.jsxs)(n.p,{children:["Existing node operators may already use their Ed25519 private key for running\ntheir nodes stored in a PEM-encoded file typically named ",(0,a.jsx)(n.code,{children:"entity.pem"}),". In order\nto submit their governance transaction, for example to vote on the network\nupgrade using the Oasis CLI, they need to import the key into the Oasis CLI\nwallet:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet import-file my_entity entity.pem\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"? Choose a new passphrase:\n? Repeat passphrase:\n"})}),"\n",(0,a.jsx)(n.p,{children:"The key is now safely stored and encrypted inside the Oasis CLI."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet list\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"ACCOUNT KIND ADDRESS \nmy_entity file (ed25519-raw) oasis1qpe0vnm0ahczgc353vytvtz9r829le4pjux8lc5z\n"})}),"\n",(0,a.jsxs)(n.h3,{id:"remote-signer",children:["Remote Signer for ",(0,a.jsx)(n.code,{children:"oasis-node"})]}),"\n",(0,a.jsxs)(n.p,{children:["You can bind the account in your Oasis CLI wallet with a local instance of\n",(0,a.jsx)(n.code,{children:"oasis-node"}),". To do this, use\n",(0,a.jsx)(n.code,{children:"wallet remote-signer "}),", pick the account you wish\nto expose and provide a path to the new unix socket:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"oasis wallet remote-signer oscar /datadir/oasis-oscar.socket\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"Unlock your account.\n? Passphrase:\nAddress: oasis1qp87hflmelnpqhzcqcw8rhzakq4elj7jzv090p3e\nNode Args:\n --signer.backend=remote \\\n --signer.remote.address=unix:/datadir/oasis-oscar.socket\n\n*** REMOTE SIGNER READY ***\n"})}),"\n",(0,a.jsx)(n.h3,{id:"test-accounts",children:"Test Accounts"}),"\n",(0,a.jsx)(n.p,{children:"Oasis CLI comes with the following hardcoded test accounts:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"test:alice"}),": Ed25519 test account used by Oasis core tests"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"test:bob"}),": Ed25519 test account used by Oasis core tests"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"test:charlie"}),": Secp256k1 test account"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"test:cory"}),": Ed25519 account used by ",(0,a.jsx)(n.code,{children:"oasis-net-runner"})]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"test:dave"}),": Secp256k1 test account"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"test:erin"}),": Sr25519 test account"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"test:frank"}),": Sr25519 test account"]}),"\n"]}),"\n",(0,a.jsx)(n.admonition,{title:"Do not use these accounts on public networks",type:"danger",children:(0,a.jsx)(n.p,{children:"Private keys for these accounts are well-known. Do not fund them on public\nnetworks, because anyone can drain them!"})}),"\n",(0,a.jsxs)(n.p,{children:["We suggest that you use these accounts for Localnet development or for\nreproducibility when you report bugs to the Oasis core team. You can access the\nprivate key of a test account the same way as you would for ordinary accounts\nby invoking the ",(0,a.jsx)(n.a,{href:"#export",children:(0,a.jsx)(n.code,{children:"oasis wallet export"})})," command."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>i});var a=s(6540);const r={},t=a.createContext(r);function l(e){const n=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),a.createElement(t.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/7687a514.1e7aebe8.js b/assets/js/7687a514.1e7aebe8.js
new file mode 100644
index 0000000000..4448c4135a
--- /dev/null
+++ b/assets/js/7687a514.1e7aebe8.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[1538],{8542:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>h,contentTitle:()=>l,default:()=>u,frontMatter:()=>c,metadata:()=>d,toc:()=>p});var r=n(4848),i=n(8453),s=n(5965),o=n(2550),a=n(6116);const c={},l="Cipher ParaTime",d={id:"dapp/cipher/README",title:"Cipher ParaTime",description:"Cipher is a confidential ParaTime for executing Wasm smart contracts.",source:"@site/docs/dapp/cipher/README.mdx",sourceDirName:"dapp/cipher",slug:"/dapp/cipher/",permalink:"/dapp/cipher/",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/dapp/cipher/README.mdx",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"developers",previous:{title:"Frontend Application",permalink:"/dapp/opl/frontend"},next:{title:"Prerequisites",permalink:"/dapp/cipher/prerequisites"}},h={},p=[{value:"Smart Contract Development",id:"smart-contract-development",level:2},{value:"RPC Endpoints",id:"rpc-endpoints",level:2},{value:"Block Explorers",id:"block-explorers",level:2},{value:"Indexers",id:"indexers",level:2},{value:"See also",id:"see-also",level:2}];function m(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h1,{id:"cipher-paratime",children:"Cipher ParaTime"}),"\n",(0,r.jsx)(t.p,{children:"Cipher is a confidential ParaTime for executing Wasm smart contracts."}),"\n",(0,r.jsx)(t.p,{children:"As the officially supported ParaTime by the Oasis Protocol Foundation, Cipher\nallows for:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Flexibility: developer can define which data to store in a public\nand which data in the (more expensive) confidential storage"}),"\n",(0,r.jsxs)(t.li,{children:["Security: the ",(0,r.jsx)(t.a,{href:"https://www.rust-lang.org/",children:"rust language"})," primarily used for writing Wasm smart contracts\nis known for its strict memory management and was developed specifically to\navoid memory leaks"]}),"\n",(0,r.jsx)(t.li,{children:"Scalability: increased throughput of transactions"}),"\n",(0,r.jsx)(t.li,{children:"Low-cost: 99%+ lower fees than Ethereum"}),"\n",(0,r.jsx)(t.li,{children:"6 second finality (1 block)"}),"\n",(0,r.jsx)(t.li,{children:"Cross-chain bridge to enable cross-chain interoperability (upcoming)"}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["If you're looking for EVM-compatible ParaTimes, check out the\n",(0,r.jsx)(t.a,{href:"/dapp/emerald/",children:"Emerald"})," and the confidential\n",(0,r.jsx)(t.a,{href:"/dapp/sapphire/",children:"Sapphire"})," paratimes."]}),"\n",(0,r.jsx)(t.h2,{id:"smart-contract-development",children:"Smart Contract Development"}),"\n",(0,r.jsxs)(t.p,{children:["Cipher implements the ",(0,r.jsx)(t.a,{href:"https://github.com/oasisprotocol/oasis-sdk/tree/main/contract-sdk",children:"Oasis Contract SDK"})," API. To learn how to write a\nconfidential smart contract in Rust and deploy it on Cipher, read the related\nOasis Contract SDK chapters:"]}),"\n",(0,r.jsx)(s.A,{item:(0,a.$)("/dapp/cipher/prerequisites")}),"\n",(0,r.jsx)(s.A,{item:(0,a.$)("/dapp/cipher/hello-world")}),"\n",(0,r.jsx)(s.A,{item:(0,a.$)("/dapp/cipher/confidential-smart-contract")}),"\n",(0,r.jsx)(t.h2,{id:"rpc-endpoints",children:"RPC Endpoints"}),"\n",(0,r.jsx)(t.admonition,{type:"danger",children:(0,r.jsxs)(t.p,{children:["The RPC endpoint is a ",(0,r.jsx)(t.em,{children:"point of trust"}),". Beside traffic rate limiting, it can\nalso perform censorship or even a man-in-the-middle attack. If you have security\nconsiderations, we strongly recommend that you set up your own ",(0,r.jsx)(t.a,{href:"/node/run-your-node/paratime-client-node",children:"ParaTime client\nnode"}),"."]})}),"\n",(0,r.jsx)(t.p,{children:"Cipher endpoints share the gRPC protocol with the Oasis Core. You can connect to\none of the public endpoints below (in alphabetic order):"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Provider"}),(0,r.jsx)(t.th,{children:"Mainnet RPC URLs"}),(0,r.jsx)(t.th,{children:"Testnet RPC URLs"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://oasisprotocol.org",children:"Oasis Protocol Foundation"})}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.code,{children:"grpc.oasis.io:443"})}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.code,{children:"testnet.grpc.oasis.io:443"})})]})})]}),"\n",(0,r.jsx)(t.h2,{id:"block-explorers",children:"Block Explorers"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Name/Provider"}),(0,r.jsx)(t.th,{children:"Mainnet URL"}),(0,r.jsx)(t.th,{children:"Testnet URL"}),(0,r.jsx)(t.th,{children:"EIP-3091 compatible"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:["Oasis Scan (",(0,r.jsx)(t.a,{href:"https://www.bitcat365.com/",children:"Bit Cat"}),")"]}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://www.oasisscan.com/paratimes/000000000000000000000000000000000000000000000000e199119c992377cb",children:"https://www.oasisscan.com/paratimes/000\u20267cb"})}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://testnet.oasisscan.com/paratimes/0000000000000000000000000000000000000000000000000000000000000000",children:"https://testnet.oasisscan.com/paratimes/000\u2026000"})}),(0,r.jsx)(t.td,{children:"No"})]})})]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["Only rudimentary block explorer features exist for Cipher. Consider debugging\nthe Cipher transactions using the ",(0,r.jsx)(t.a,{href:"/general/manage-tokens/cli/paratime#show",children:(0,r.jsx)(t.code,{children:"oasis paratime show"})})," command part of the\n",(0,r.jsx)(t.a,{href:"/general/manage-tokens/cli/",children:"Oasis CLI"}),"."]})}),"\n",(0,r.jsx)(t.h2,{id:"indexers",children:"Indexers"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Name (Provider)"}),(0,r.jsx)(t.th,{children:"Mainnet URL"}),(0,r.jsx)(t.th,{children:"Testnet URL"}),(0,r.jsx)(t.th,{children:"Documentation"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:["Oasis Scan (",(0,r.jsx)(t.a,{href:"https://www.bitcat365.com/",children:"Bit Cat"}),")"]}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.code,{children:"https://api.oasisscan.com/mainnet/v2"})}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.code,{children:"https://api.oasisscan.com/testnet/v2"})}),(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.a,{href:"https://api.oasisscan.com/mainnet/swagger-ui/#/runtime-controller",children:"Mainnet Runtime API"}),", ",(0,r.jsx)(t.a,{href:"https://api.oasisscan.com/testnet/swagger-ui/#/runtime-controller",children:"Testnet Runtime API"})]})]})})]}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsxs)(t.p,{children:["If you are running your own Cipher endpoint, a block explorer, or an indexer\nand wish to be added to these docs, open an issue at\n",(0,r.jsx)(t.a,{href:"https://github.com/oasisprotocol/docs",children:"github.com/oasisprotocol/docs"}),"."]})}),"\n",(0,r.jsx)(t.h2,{id:"see-also",children:"See also"}),"\n",(0,r.jsx)(o.A,{items:[(0,a.$)("/general/manage-tokens/"),(0,a.$)("/node/run-your-node/paratime-node"),(0,a.$)("/node/run-your-node/paratime-client-node"),(0,a.$)("/dapp/emerald/"),(0,a.$)("/dapp/sapphire/")]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(m,{...e})}):m(e)}},5965:(e,t,n)=>{n.d(t,{A:()=>f});n(6540);var r=n(4164),i=n(8774),s=n(4142),o=n(5846),a=n(6654),c=n(1312),l=n(1107);const d={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var h=n(4848);function p(e){let{href:t,children:n}=e;return(0,h.jsx)(i.A,{href:t,className:(0,r.A)("card padding--lg",d.cardContainer),children:n})}function m(e){let{href:t,icon:n,title:i,description:s}=e;return(0,h.jsxs)(p,{href:t,children:[(0,h.jsxs)(l.A,{as:"h2",className:(0,r.A)("text--truncate",d.cardTitle),title:i,children:[n," ",i]}),s&&(0,h.jsx)("p",{className:(0,r.A)("text--truncate",d.cardDescription),title:s,children:s})]})}function u(e){let{item:t}=e;const n=(0,s.Nr)(t),r=function(){const{selectMessage:e}=(0,o.W)();return t=>e(t,(0,c.T)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,h.jsx)(m,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??r(t.items.length)}):null}function x(e){let{item:t}=e;const n=(0,a.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,s.cC)(t.docId??void 0);return(0,h.jsx)(m,{href:t.href,icon:n,title:t.label,description:t.description??r?.description})}function f(e){let{item:t}=e;switch(t.type){case"link":return(0,h.jsx)(x,{item:t});case"category":return(0,h.jsx)(u,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}},2550:(e,t,n)=>{n.d(t,{A:()=>c});n(6540);var r=n(4164),i=n(4142),s=n(5965),o=n(4848);function a(e){let{className:t}=e;const n=(0,i.$S)();return(0,o.jsx)(c,{items:n.items,className:t})}function c(e){const{items:t,className:n}=e;if(!t)return(0,o.jsx)(a,{...e});const c=(0,i.d1)(t);return(0,o.jsx)("section",{className:(0,r.A)("row",n),children:c.map(((e,t)=>(0,o.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,o.jsx)(s.A,{item:e})},t)))})}},5846:(e,t,n)=>{n.d(t,{W:()=>l});var r=n(6540),i=n(4586);const s=["zero","one","two","few","many","other"];function o(e){return s.filter((t=>e.includes(t)))}const a={locale:"en",pluralForms:o(["one","other"]),select:e=>1===e?"one":"other"};function c(){const{i18n:{currentLocale:e}}=(0,i.A)();return(0,r.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:o(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),a}}),[e])}function l(){const e=c();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const i=n.select(t),s=n.pluralForms.indexOf(i);return r[Math.min(s,r.length-1)]}(n,t,e)}}},6116:(e,t,n)=>{n.d(t,{$:()=>s});var r=n(2252);function i(e){for(const t of e){const e=t.href;e&&void 0===globalThis.sidebarItemsMap[e]&&(globalThis.sidebarItemsMap[e]=t),"category"===t.type&&i(t.items)}}function s(e){const t=(0,r.r)();if(!t)throw new Error("Unexpected: cant find docsVersion in current context");if(void 0===globalThis.sidebarItemsMap){globalThis.sidebarItemsMap={};for(const e in t.docsSidebars)i(t.docsSidebars[e])}if(void 0===globalThis.sidebarItemsMap[e])throw console.log("Registered sidebar items:"),console.log(globalThis.sidebarItemsMap),new Error("Unexpected: sidebar item with href "+e+" does not exist.");return globalThis.sidebarItemsMap[e]}},8453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var r=n(6540);const i={},s=r.createContext(i);function o(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/777245c5.bb091a8d.js b/assets/js/777245c5.bb091a8d.js
new file mode 100644
index 0000000000..a600881b9b
--- /dev/null
+++ b/assets/js/777245c5.bb091a8d.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[4551],{6661:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>p,frontMatter:()=>t,metadata:()=>c,toc:()=>l});var o=s(4848),r=s(8453);const t={},i="Governance",c={id:"core/consensus/services/governance",title:"Governance",description:"The governance service is responsible for providing an on-chain governance",source:"@site/docs/core/consensus/services/governance.md",sourceDirName:"core/consensus/services",slug:"/core/consensus/services/governance",permalink:"/core/consensus/services/governance",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/oasis-core/edit/stable/22.2.x/docs/consensus/services/governance.md",tags:[],version:"current",lastUpdatedAt:1715584634e3,frontMatter:{},sidebar:"oasisCore",previous:{title:"Committee Scheduler",permalink:"/core/consensus/services/scheduler"},next:{title:"Root Hash",permalink:"/core/consensus/services/roothash"}},a={},l=[{value:"Methods",id:"methods",level:2},{value:"Submit Proposal",id:"submit-proposal",level:3},{value:"Vote",id:"vote",level:3},{value:"Events",id:"events",level:2},{value:"Proposal Submitted Event",id:"proposal-submitted-event",level:3},{value:"Proposal Finalized Event",id:"proposal-finalized-event",level:3},{value:"Proposal Executed Event",id:"proposal-executed-event",level:3},{value:"Vote Event",id:"vote-event",level:3},{value:"Consensus Parameters",id:"consensus-parameters",level:2},{value:"Test Vectors",id:"test-vectors",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"governance",children:"Governance"}),"\n",(0,o.jsx)(n.p,{children:"The governance service is responsible for providing an on-chain governance\nmechanism."}),"\n",(0,o.jsxs)(n.p,{children:["The service interface definition lives in ",(0,o.jsx)(n.a,{href:"https://github.com/oasisprotocol/oasis-core/tree/master/go/governance/api",children:(0,o.jsx)(n.code,{children:"go/governance/api"})}),". It defines the\nsupported queries and transactions. For more information you can also check out\nthe ",(0,o.jsx)(n.a,{href:"https://pkg.go.dev/github.com/oasisprotocol/oasis-core/go/governance/api?tab=doc",children:"consensus service API documentation"})," and the ",(0,o.jsx)(n.a,{href:"/adrs/0006-consensus-governance",children:"governance ADR\nspecification"}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"methods",children:"Methods"}),"\n",(0,o.jsx)(n.p,{children:"The following sections describe the methods supported by the consensus\ngovernance service."}),"\n",(0,o.jsx)(n.h3,{id:"submit-proposal",children:"Submit Proposal"}),"\n",(0,o.jsx)(n.p,{children:"Proposal submission enables a new consensus layer governance proposal to be\ncreated."}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Method name:"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"governance.SubmitProposal\n"})}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Body:"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-golang",children:'// ProposalContent is a consensus layer governance proposal content.\ntype ProposalContent struct {\n Upgrade *UpgradeProposal `json:"upgrade,omitempty"`\n CancelUpgrade *CancelUpgradeProposal `json:"cancel_upgrade,omitempty"`\n}\n\n// UpgradeProposal is an upgrade proposal.\ntype UpgradeProposal struct {\n upgrade.Descriptor\n}\n\n// CancelUpgradeProposal is an upgrade cancellation proposal.\ntype CancelUpgradeProposal struct {\n // ProposalID is the identifier of the pending upgrade proposal.\n ProposalID uint64 `json:"proposal_id"`\n}\n'})}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Fields:"})}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"upgrade"})," (optional) specifies an upgrade proposal."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"cancel_upgrade"})," (optional) specifies an upgrade cancellation proposal."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"Exactly one of the proposal kind fields needs to be non-nil, otherwise the\nproposal is considered malformed."}),"\n",(0,o.jsx)(n.h3,{id:"vote",children:"Vote"}),"\n",(0,o.jsx)(n.p,{children:"Voting for submitted consensus layer governance proposals."}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Method name:"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"governance.CastVote\n"})}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Body:"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-golang",children:'type ProposalVote struct {\n // ID is the unique identifier of a proposal.\n ID uint64 `json:"id"`\n // Vote is the vote.\n Vote Vote `json:"vote"`\n}\n'})}),"\n",(0,o.jsx)(n.h2,{id:"events",children:"Events"}),"\n",(0,o.jsx)(n.h3,{id:"proposal-submitted-event",children:"Proposal Submitted Event"}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Body:"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-golang",children:'type ProposalSubmittedEvent {\n // ID is the unique identifier of a proposal.\n ID uint64 `json:"id"`\n // Submitter is the staking account address of the submitter.\n Submitter staking.Address `json:"submitter"`\n}\n'})}),"\n",(0,o.jsx)(n.p,{children:"Emitted for every submitted proposal."}),"\n",(0,o.jsx)(n.h3,{id:"proposal-finalized-event",children:"Proposal Finalized Event"}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Body:"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-golang",children:'type ProposalFinalizedEvent struct {\n // ID is the unique identifier of a proposal.\n ID uint64 `json:"id"`\n // State is the new proposal state.\n State ProposalState `json:"state"`\n}\n'})}),"\n",(0,o.jsx)(n.p,{children:"Emitted when a proposal is finalized."}),"\n",(0,o.jsx)(n.h3,{id:"proposal-executed-event",children:"Proposal Executed Event"}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Body:"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-golang",children:'type ProposalExecutedEvent {\n // ID is the unique identifier of a proposal.\n ID uint64 `json:"id"`\n}\n'})}),"\n",(0,o.jsx)(n.p,{children:"Emitted when a passed proposal is executed."}),"\n",(0,o.jsx)(n.h3,{id:"vote-event",children:"Vote Event"}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Body:"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-golang",children:'type VoteEvent {\n // ID is the unique identifier of a proposal.\n ID uint64 `json:"id"`\n // Submitter is the staking account address of the vote submitter.\n Submitter staking.Address `json:"submitter"`\n // Vote is the cast vote.\n Vote Vote `json:"vote"`\n}\n'})}),"\n",(0,o.jsx)(n.p,{children:"Emitted when a vote is cast."}),"\n",(0,o.jsx)(n.h2,{id:"consensus-parameters",children:"Consensus Parameters"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"gas_costs"})," (transaction.Costs) are the governance transaction gas costs."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"min_proposal_deposit"})," (base units) specifies the number of base units that\nare deposited when creating a new proposal."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"voting_period"})," (epochs) specifies the number of epochs after which the voting\nfor a proposal is closed and the votes are tallied."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"quorum"})," (uint8: [0,100]) specifies the minimum percentage of voting power\nthat needs to be cast on a proposal for the result to be valid."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"threshold"})," (uint8: [0,100]) specifies the minimum percentage of ",(0,o.jsx)(n.code,{children:"VoteYes"}),"\nvotes in order for a proposal to be accepted."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"upgrade_min_epoch_diff"})," (epochs) specifies the minimum number of epochs\nbetween the current epoch and the proposed upgrade epoch for the upgrade\nproposal to be valid. Additionally specifies the minimum number of epochs\nbetween two consecutive pending upgrades."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"upgrade_cancel_min_epoch_diff"})," (epochs) specifies the minimum number of\nepochs between the current epoch and the proposed upgrade epoch for the\nupgrade cancellation proposal to be valid."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"test-vectors",children:"Test Vectors"}),"\n",(0,o.jsxs)(n.p,{children:["To generate test vectors for various governance ",(0,o.jsx)(n.a,{href:"/core/consensus/transactions",children:"transactions"}),", run:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"make -C go governance/gen_vectors\n"})}),"\n",(0,o.jsxs)(n.p,{children:["For more information about the structure of the test vectors see the section\non ",(0,o.jsx)(n.a,{href:"/core/consensus/test-vectors",children:"Transaction Test Vectors"}),"."]})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var o=s(6540);const r={},t=o.createContext(r);function i(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/79102774.aa997a44.js b/assets/js/79102774.aa997a44.js
new file mode 100644
index 0000000000..6433e2dd80
--- /dev/null
+++ b/assets/js/79102774.aa997a44.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[3684],{2383:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>p,frontMatter:()=>a,metadata:()=>l,toc:()=>h});var i=t(4848),s=t(8453),o=t(2550),r=t(6116);const a={},d="Validator Node",l={id:"node/run-your-node/validator-node",title:"Validator Node",description:"This guide will walk you through the process of setting up your validator",source:"@site/docs/node/run-your-node/validator-node.mdx",sourceDirName:"node/run-your-node",slug:"/node/run-your-node/validator-node",permalink:"/node/run-your-node/validator-node",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/node/run-your-node/validator-node.mdx",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"operators",previous:{title:"Set up Trusted Execution Environment (TEE)",permalink:"/node/run-your-node/prerequisites/set-up-trusted-execution-environment-tee"},next:{title:"Non-validator Node",permalink:"/node/run-your-node/non-validator-node"}},c={},h=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Initialize Entity",id:"initialize-entity",level:2},{value:"Add Entity Account to Oasis CLI",id:"add-entity-account-to-oasis-cli",level:3},{value:"Write the Entity Descriptor File",id:"write-the-entity-descriptor-file",level:3},{value:"Copy the Public Entity File Descriptor to server
",id:"copy-the-public-entity-file-descriptor-to-server",level:3},{value:"Configuration",id:"configuration",level:2},{value:"Starting the Oasis Node",id:"starting-the-oasis-node",level:2},{value:"Node Keys",id:"node-keys",level:3},{value:"Ensuring Proper Permissions",id:"ensuring-proper-permissions",level:3},{value:"Obtain the Node ID",id:"obtain-the-node-id",level:3},{value:"Check that your Node is Synced",id:"check-that-your-node-is-synced",level:3},{value:"Staking and Registering",id:"staking-and-registering",level:2},{value:"Staking (Escrow) Transaction",id:"staking-escrow-transaction",level:3},{value:"Add your Node ID to the Entity Descriptor",id:"add-your-node-id-to-the-entity-descriptor",level:3},{value:"Entity Registration",id:"entity-registration",level:3},{value:"Check that Your Node is Properly Registered",id:"check-that-your-node-is-properly-registered",level:3},{value:"Oasis Metadata Registry",id:"oasis-metadata-registry",level:2}];function u(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"validator-node",children:"Validator Node"}),"\n",(0,i.jsxs)(n.p,{children:["This guide will walk you through the process of setting up your ",(0,i.jsx)(n.strong,{children:"validator\nnode"})," for the Oasis Network either on Mainnet or Testnet. It is designed for\nindividuals who have basic understanding of the command line environment."]}),"\n",(0,i.jsx)(n.p,{children:"We will be using two separate physical machines for deployment:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["your local system, referred to as ",(0,i.jsx)(n.code,{children:"localhost"}),","]}),"\n",(0,i.jsxs)(n.li,{children:["a remote ",(0,i.jsx)(n.code,{children:"server"})," which will function as an Oasis node."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The guide consists of the following steps:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["On the ",(0,i.jsx)(n.code,{children:"localhost"}),", we will use ",(0,i.jsx)(n.a,{href:"/general/manage-tokens/cli/",children:"Oasis CLI"})," to ",(0,i.jsx)(n.a,{href:"#initialize-entity",children:"Initialize your\nEntity"})," which is essential for deploying nodes on the\nnetwork. To ensure the security of these private keys, we strongly recommend\nto either isolate the ",(0,i.jsx)(n.code,{children:"localhost"})," from any network or internet connectivity, or\nuse a ",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Hardware_security_module",children:"hardware wallet"})," as a secure storage, such as ",(0,i.jsx)(n.a,{href:"../../../general/manage-tokens/holding-rose-tokens/ledger-wallet",children:"Ledger"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["After the entity has been created, we will move over to the ",(0,i.jsx)(n.code,{children:"server"})," and\n",(0,i.jsx)(n.a,{href:"#starting-the-oasis-node",children:"Start the Oasis Node"}),". The server needs to meet\nthe hardware requirements and have access to the internet."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Finally, we will ",(0,i.jsx)(n.a,{href:"#staking-and-registering",children:"stake assets to your entity, register it on the network,\nand attach the unique ID"})," of the\nOasis Node instance running on your server."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.p,{children:["Before proceeding with this guide, ensure that you have completed the steps\noutlined in the ",(0,i.jsx)(n.a,{href:"prerequisites/",children:"Prerequisites"})," chapter so that:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["your system meets the ",(0,i.jsx)(n.a,{href:"/node/run-your-node/prerequisites/hardware-recommendations",children:"hardware requirements"}),","]}),"\n",(0,i.jsxs)(n.li,{children:["you have the ",(0,i.jsx)(n.a,{href:"/general/manage-tokens/cli/",children:"Oasis CLI"})," installed on your ",(0,i.jsx)(n.code,{children:"localhost"}),","]}),"\n",(0,i.jsxs)(n.li,{children:["you have the ",(0,i.jsx)(n.a,{href:"/node/run-your-node/prerequisites/oasis-node",children:"Oasis Node binary"})," installed on your ",(0,i.jsx)(n.code,{children:"server"}),","]}),"\n",(0,i.jsxs)(n.li,{children:["you understand what are ",(0,i.jsx)(n.a,{href:"/node/run-your-node/prerequisites/stake-requirements",children:"Stake requirements"})," to become a validator on the\nOasis Network."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"initialize-entity",children:"Initialize Entity"}),"\n",(0,i.jsx)(n.admonition,{type:"danger",children:(0,i.jsxs)(n.p,{children:["Everything in this section should be done on the ",(0,i.jsx)(n.code,{children:"localhost"})," as there are\nsensitive items that will be created."]})}),"\n",(0,i.jsx)(n.p,{children:"During the entity initialization process, you will generate essential components\nsuch as keys and other crucial artifacts that are necessary for the deployment\nof nodes on the network. This guide has been designed with a particular file\nstructure in mind. Nonetheless, feel free to reorganize and rename directories\nas needed to accommodate your preferences."}),"\n",(0,i.jsx)(n.h3,{id:"add-entity-account-to-oasis-cli",children:"Add Entity Account to Oasis CLI"}),"\n",(0,i.jsxs)(n.p,{children:["An entity is critical to operating nodes on the network as it controls the stake\nattached to a given individual or organization on the network. The entity is\nrepresented as a consensus-layer account using the Ed25519 signature scheme.\nTo protect your entity private key, we strongly recommend using a ",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Hardware_security_module",children:"hardware\nwallet"})," such as ",(0,i.jsx)(n.a,{href:"../../../general/manage-tokens/holding-rose-tokens/ledger-wallet",children:"Ledger"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["We will be using ",(0,i.jsx)(n.a,{href:"/general/manage-tokens/cli/",children:"Oasis CLI"})," to initialize the entity and later stake our assets\nand register the entity on the network. If you haven't already, go ahead and\ninstall it."]}),"\n",(0,i.jsx)(n.p,{children:"Oasis CLI stores either your entity private key encrypted inside a file or a\nreference to an account whose keypair is stored on your hardware wallet."}),"\n",(0,i.jsx)(n.admonition,{type:"danger",children:(0,i.jsxs)(n.p,{children:["If you really need to use the file-based wallet using another\n",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Air_gap_(networking)",children:"offline/air-gapped machine"})," for this purpose is highly recommended. Gaining\naccess to the entity private key can compromise your tokens and the network\nsecurity through proposing and signing malicious governance transactions."]})}),"\n",(0,i.jsxs)(n.p,{children:["On the ",(0,i.jsx)(n.code,{children:"localhost"})," add a new entity account to Oasis CLI. This can be done in\none of the following ways:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Create an account entry in Oasis CLI, but use your Ledger device to store\nthe actual keypair to sign the transactions by executing\n",(0,i.jsx)(n.a,{href:"/general/manage-tokens/cli/wallet#create",children:(0,i.jsx)(n.code,{children:"oasis wallet create"})})," and passing the ",(0,i.jsx)(n.code,{children:"--kind ledger"})," flag. For example:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"oasis wallet create my_entity --kind ledger\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Import your existing ",(0,i.jsx)(n.code,{children:"entity.pem"})," into Oasis CLI by executing\n",(0,i.jsx)(n.a,{href:"/general/manage-tokens/cli/wallet#import-file",children:(0,i.jsx)(n.code,{children:"oasis wallet import-file"})})," command, for example:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"oasis wallet import-file my_entity entity.pem\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Generate a new keypair and store the private key in the encrypted file by\nexecuting ",(0,i.jsx)(n.a,{href:"/general/manage-tokens/cli/wallet#create",children:(0,i.jsx)(n.code,{children:"oasis wallet create"})}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"oasis wallet create my_entity\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Similar to the examples above we will assume that you named your entity account\nas ",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"my_entity"})})," in the remainder of this chapter."]}),"\n",(0,i.jsx)(n.h3,{id:"write-the-entity-descriptor-file",children:"Write the Entity Descriptor File"}),"\n",(0,i.jsxs)(n.p,{children:["On the ",(0,i.jsx)(n.code,{children:"localhost"})," we begin by creating a directory named ",(0,i.jsx)(n.code,{children:"/localhostdir"})," with\nthe ",(0,i.jsx)(n.code,{children:"entity"})," subdirectory that will contain the entity file descriptor."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"mkdir -p /localhostdir/entity\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Create a JSON file containing the ",(0,i.jsx)(n.strong,{children:"public key"})," of your entity by executing\n",(0,i.jsx)(n.a,{href:"/general/manage-tokens/cli/account#entity-init",children:(0,i.jsx)(n.code,{children:"oasis account entity init"})})," and store it as ",(0,i.jsx)(n.code,{children:"entity.json"}),", for example:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"oasis account entity init -o /localhostdir/entity/entity.json --account my_entity\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Now, we can move on to configuring our Oasis node with the freshly generated\n",(0,i.jsx)(n.code,{children:"entity.json"}),"."]}),"\n",(0,i.jsxs)(n.h3,{id:"copy-the-public-entity-file-descriptor-to-server",children:["Copy the Public Entity File Descriptor to ",(0,i.jsx)(n.code,{children:"server"})]}),"\n",(0,i.jsxs)(n.p,{children:["The Oasis node needs access to the public key of your entity. Copy your\n",(0,i.jsx)(n.code,{children:"entity.json"})," to ",(0,i.jsx)(n.code,{children:"/node/etc/entity.json"})," on the ",(0,i.jsx)(n.code,{children:"server"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,i.jsx)(n.p,{children:"There are a variety of options available when running an Oasis node. The\nfollowing YAML file is a basic configuration for a validator node on the\nnetwork."}),"\n",(0,i.jsx)(n.p,{children:"Before using this configuration you should collect the following information to\nreplace the variables present in the configuration file:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"{{ external_ip }}"}),": The external/public IP address you used when registering\nthis node."]}),"\n"]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["If you are using a ",(0,i.jsx)(n.a,{href:"/node/run-your-node/sentry-node",children:"Sentry Node"}),", you should use the public IP\nof that machine."]})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"{{ seed_node_address }}"}),": The seed node address in the form ",(0,i.jsx)(n.code,{children:"ID@IP:port"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["You can find the current Oasis Seed Node address in the Network Parameters\npage (",(0,i.jsx)(n.a,{href:"/node/mainnet/",children:"Mainnet"}),", ",(0,i.jsx)(n.a,{href:"/node/testnet/",children:"Testnet"}),")."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["To use this configuration, save it in the ",(0,i.jsx)(n.code,{children:"/node/etc/config.yml"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="/node/etc/config.yml"',children:'mode: validator\ncommon:\n # Set this to where you wish to store node data. The node\'s artifacts\n # should also be located in this directory.\n data_dir: /node/data\n # Logging.\n #\n # Per-module log levels are defined below. If you prefer just one unified\n # log level, you can use:\n #\n # log:\n # level: debug\n log:\n level:\n cometbft: warn\n cometbft/context: error\n # Per-module log levels. Longest prefix match will be taken.\n # Fallback to "default", if no match.\n default: debug\n format: JSON\n # By default logs are output to stdout. If you would like to output\n # logs to a file, you can use:\n #\n # file: /var/log/oasis-node.log\n\nconsensus:\n # The external IP that is used when registering this node to the network.\n # NOTE: If you are using the Sentry node setup, this option should be\n # omitted.\n external_address: tcp://{{ external_ip }}:26656\n listen_address: tcp://0.0.0.0:26656\n\ngenesis:\n # Path to the genesis file for the current version of the network.\n file: /node/etc/genesis.json\n\np2p:\n port: 9200\n registration:\n addresses:\n - {{ external_ip }}:9200\n seeds:\n # List of seed nodes to connect to.\n # NOTE: You can add additional seed nodes to this list if you want.\n - {{ seed_node_address }}\n\nregistration:\n # In order for the node to register itself, the entity.json of the entity\n # used to provision the node must be available on the node.\n entity: /node/etc/entity.json\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsxs)(n.p,{children:["Make sure the ",(0,i.jsx)(n.code,{children:"consensus"})," port (default: ",(0,i.jsx)(n.code,{children:"26656"}),") and ",(0,i.jsx)(n.code,{children:"p2p.port"})," (default: ",(0,i.jsx)(n.code,{children:"9200"}),") are exposed and publicly\naccessible on the internet (for ",(0,i.jsx)(n.code,{children:"TCP"})," and ",(0,i.jsx)(n.code,{children:"UDP"})," traffic)."]})}),"\n",(0,i.jsx)(n.h2,{id:"starting-the-oasis-node",children:"Starting the Oasis Node"}),"\n",(0,i.jsx)(n.p,{children:"You can start the node by simply running the command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"oasis-node --config /node/etc/config.yml\n"})}),"\n",(0,i.jsxs)(n.admonition,{type:"tip",children:[(0,i.jsx)(n.p,{children:"The Oasis node is configured to run in the foreground by default."}),(0,i.jsxs)(n.p,{children:["We recommend that you configure and use it with a process manager like\n",(0,i.jsx)(n.a,{href:"https://github.com/systemd/systemd",children:"systemd"})," or\n",(0,i.jsx)(n.a,{href:"http://supervisord.org",children:"Supervisor"}),". Check out the ",(0,i.jsx)(n.a,{href:"/node/run-your-node/prerequisites/system-configuration#create-a-user",children:"System Configuration"}),"\npage for examples."]})]}),"\n",(0,i.jsx)(n.h3,{id:"node-keys",children:"Node Keys"}),"\n",(0,i.jsxs)(n.p,{children:["The Oasis node requires ",(0,i.jsx)(n.strong,{children:"node keys"})," in order to register itself and to\nsecurely communicate with other nodes in the peer-to-peer network. The following\nkeys will automatically be generated and stored in your ",(0,i.jsx)(n.code,{children:"/node/data"})," folder\nas ",(0,i.jsx)(n.code,{children:".pem"})," files:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"consensus.pem"}),": The node's consensus private key. ",(0,i.jsx)(n.strong,{children:"DO NOT SHARE"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"consensus_pub.pem"}),": The node's consensus public key."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"identity.pem"}),": The node's identity private key. ",(0,i.jsx)(n.strong,{children:"DO NOT SHARE"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"identity_pub.pem"}),": The node's identity public key."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"p2p.pem"}),": The node's private key for libp2p. ",(0,i.jsx)(n.strong,{children:"DO NOT SHARE"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"p2p_pub.pem"}),": The node's public key for libp2p."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sentry_client_tls_identity.pem"}),": The node's TLS private key for communicating\nwith sentry nodes. ",(0,i.jsx)(n.strong,{children:"DO NOT SHARE"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sentry_client_tls_identity_cert.pem"}),": The node's TLS certificate for\ncommunicating with sentry nodes."]}),"\n"]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsx)(n.p,{children:"If the node keys do not exist, they will be automatically generated when you\nlaunch the Oasis node. Otherwise, the existing ones will be used."})}),"\n",(0,i.jsxs)(n.admonition,{type:"caution",children:[(0,i.jsxs)(n.p,{children:["You may have noticed that some files above are listed as ",(0,i.jsx)(n.strong,{children:"DO NOT SHARE"}),"."]}),(0,i.jsxs)(n.p,{children:["Ideally, the node keys should be stored on a separate device such as a\n",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Hardware_security_module",children:"hardware wallet"})," or a ",(0,i.jsx)(n.a,{href:"/node/run-your-node/advanced/remote-signer",children:"remote signer"}),". However, until the support is\nfully implemented, keep the keys on the ",(0,i.jsx)(n.code,{children:"server"})," as secure as possible."]})]}),"\n",(0,i.jsx)(n.h3,{id:"ensuring-proper-permissions",children:"Ensuring Proper Permissions"}),"\n",(0,i.jsxs)(n.p,{children:["Only the owner of the process that runs the Oasis node should have access to the\nfiles in the ",(0,i.jsx)(n.code,{children:"/node/data"})," directory. The ",(0,i.jsx)(n.code,{children:"oasis-node"})," binary ensures that\nthe files used by the node are as least privileged as possible so that you don't\naccidentally shoot yourself in the foot while operating a node."]}),"\n",(0,i.jsxs)(n.p,{children:["If you followed the steps described in the\n",(0,i.jsx)(n.a,{href:"/node/run-your-node/prerequisites/oasis-node",children:"Install the Oasis Node"})," chapter, then the proper permissions\nare already set:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"700"})," for the ",(0,i.jsx)(n.code,{children:"/node/data"})," directory"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"700"})," for the ",(0,i.jsx)(n.code,{children:"/node/etc"})," directory"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"700"})," for the ",(0,i.jsx)(n.code,{children:"/node/runtimes"})," directory"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"600"})," for all ",(0,i.jsx)(n.code,{children:"/node/data/*.pem"})," files"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Otherwise, run the following to remove all non-owner read/write/execute\npermissions:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"chmod -R go-r,go-w,go-x /node\n"})}),"\n",(0,i.jsx)(n.h3,{id:"obtain-the-node-id",children:"Obtain the Node ID"}),"\n",(0,i.jsx)(n.p,{children:"Now that the Oasis node is running, you can obtain your unique node ID which is\nneeded in order to associate your node with your entity in the network registry."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"oasis-node control status -a unix:/node/data/internal.sock | jq .identity.node\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'"5MsgQwijUlpH9+0Hbyors5jwmx7tTmKMA4c9leV3prI="\n'})}),"\n",(0,i.jsx)(n.h3,{id:"check-that-your-node-is-synced",children:"Check that your Node is Synced"}),"\n",(0,i.jsx)(n.p,{children:"Before you can become a validator, you will have to make sure that your node is\nsynced. To do so call this command on the server:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"oasis-node control is-synced -a unix:/node/data/internal.sock\n"})}),"\n",(0,i.jsx)(n.p,{children:"If your node is synced, the above command should output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'"ready"\n'})}),"\n",(0,i.jsx)(n.p,{children:"If your node is not yet synced, you will need to wait before you can move\nforward."}),"\n",(0,i.jsx)(n.h2,{id:"staking-and-registering",children:"Staking and Registering"}),"\n",(0,i.jsx)(n.p,{children:"Once you have been funded, you can complete the process of connecting your node\nto the network by registering both your entity and your node, as described\nbelow."}),"\n",(0,i.jsx)(n.h3,{id:"staking-escrow-transaction",children:"Staking (Escrow) Transaction"}),"\n",(0,i.jsxs)(n.p,{children:["The current minimum stake required to register an entity and register a node as\na validator is 200 tokens. We will submit the escrow transaction that\ndelegates 200 tokens from your entity account on the consensus layer to itself\nby invoking the ",(0,i.jsx)(n.a,{href:"/general/manage-tokens/cli/account#delegate",children:(0,i.jsx)(n.code,{children:"oasis account delegate"})})," command."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"oasis account delegate 200 my_entity --no-paratime --account my_entity\n"})}),"\n",(0,i.jsxs)(n.p,{children:["You can also fund your entity account from a different one. If you haven't yet\ninvoke the ",(0,i.jsx)(n.a,{href:"/general/manage-tokens/cli/wallet#import",children:(0,i.jsx)(n.code,{children:"oasis wallet import"})})," command to import the private key of the\nfunding account to the Oasis CLI and follow the instructions."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"oasis wallet import my_funding_account\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Then, invoke the ",(0,i.jsx)(n.a,{href:"/general/manage-tokens/cli/account#delegate",children:(0,i.jsx)(n.code,{children:"oasis account delegate"})})," passing the new account name with\nthe ",(0,i.jsx)(n.code,{children:"--account"})," parameter. For example:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"oasis account delegate 200 my_entity --no-paratime --account my_funding_account\n"})}),"\n",(0,i.jsx)(n.h3,{id:"add-your-node-id-to-the-entity-descriptor",children:"Add your Node ID to the Entity Descriptor"}),"\n",(0,i.jsxs)(n.p,{children:["Now we can register our entity on the network and associate it with the node ID\nobtained in the ",(0,i.jsx)(n.a,{href:"#obtain-the-node-id",children:"section above"}),". Open the ",(0,i.jsx)(n.code,{children:"entity.json"}),"\nfile we initially generated and add the ID inside the ",(0,i.jsx)(n.code,{children:"nodes"})," block. Your\nentity descriptor file should now look like this:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "id": "Bx6gOixnxy15tCs09ua5DcKyX9uo2Forb32O6Hyjoc8=",\n "nodes": [\n "5MsgQwijUlpH9+0Hbyors5jwmx7tTmKMA4c9leV3prI="\n ],\n "v": 2\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"entity-registration",children:"Entity Registration"}),"\n",(0,i.jsxs)(n.p,{children:["We can submit the fresh entity file descriptor by invoking the\n",(0,i.jsx)(n.a,{href:"/general/manage-tokens/cli/account#entity-register",children:(0,i.jsx)(n.code,{children:"oasis account entity register"})})," command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"oasis account entity register entity.json --account my_entity\n"})}),"\n",(0,i.jsx)(n.h3,{id:"check-that-your-node-is-properly-registered",children:"Check that Your Node is Properly Registered"}),"\n",(0,i.jsxs)(n.p,{children:["To ensure that your node is properly connected as a validator on the network,\ninvoke the following command on your ",(0,i.jsx)(n.code,{children:"server"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"oasis-node control status -a unix:/node/data/internal.sock | jq .consensus.is_validator\n"})}),"\n",(0,i.jsx)(n.p,{children:"If your node is registered and became a validator, the above command should\noutput:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"true\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsx)(n.p,{children:"Nodes are only elected into the validator set at epoch transitions, so you may\nneed to wait for up to an epoch before being considered."})}),"\n",(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsxs)(n.p,{children:["In order to be elected in the validator set you ",(0,i.jsx)(n.strong,{children:"need to have enough\nstake to be in the top K entities"})," (where K is a network-specific parameter\nspecified by the ",(0,i.jsx)(n.a,{href:"/node/genesis-doc#consensus",children:(0,i.jsx)(n.code,{children:"scheduler.max_validators"})})," field in the genesis document)."]})}),"\n",(0,i.jsx)(n.p,{children:"Congratulations, if you made it this far, you've properly connected your node\nto the network and became a validator on the Oasis Network."}),"\n",(0,i.jsx)(n.h2,{id:"oasis-metadata-registry",children:"Oasis Metadata Registry"}),"\n",(0,i.jsxs)(n.p,{children:["For the final touch, you can add some metadata about your entity to the\n",(0,i.jsx)(n.a,{href:"https://github.com/oasisprotocol/metadata-registry",children:"Metadata Registry"}),". The Metadata Registry is the same for Mainnet and\nthe Testnet. The metadata consists of your entity name, email, Keybase handle,\nTwitter handle, etc. This information is also used by various applications.\nFor example the ",(0,i.jsx)(n.a,{href:"https://wallet.oasisprotocol.org",children:"ROSE Wallet - Web"})," and the ",(0,i.jsx)(n.a,{href:"https://www.oasisscan.com/validators",children:"Oasis Scan"})," will fetch and show\nthe node operator's name and the avatar."]}),"\n",(0,i.jsx)(n.h1,{id:"see-also",children:"See also"}),"\n",(0,i.jsx)(o.A,{items:[(0,r.$)("/general/manage-tokens/cli/"),(0,r.$)("/core/oasis-node/cli"),(0,r.$)("/node/grpc")]})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},5965:(e,n,t)=>{t.d(n,{A:()=>x});t(6540);var i=t(4164),s=t(8774),o=t(4142),r=t(5846),a=t(6654),d=t(1312),l=t(1107);const c={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var h=t(4848);function u(e){let{href:n,children:t}=e;return(0,h.jsx)(s.A,{href:n,className:(0,i.A)("card padding--lg",c.cardContainer),children:t})}function p(e){let{href:n,icon:t,title:s,description:o}=e;return(0,h.jsxs)(u,{href:n,children:[(0,h.jsxs)(l.A,{as:"h2",className:(0,i.A)("text--truncate",c.cardTitle),title:s,children:[t," ",s]}),o&&(0,h.jsx)("p",{className:(0,i.A)("text--truncate",c.cardDescription),title:o,children:o})]})}function y(e){let{item:n}=e;const t=(0,o.Nr)(n),i=function(){const{selectMessage:e}=(0,r.W)();return n=>e(n,(0,d.T)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:n}))}();return t?(0,h.jsx)(p,{href:t,icon:"\ud83d\uddc3\ufe0f",title:n.label,description:n.description??i(n.items.length)}):null}function g(e){let{item:n}=e;const t=(0,a.A)(n.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",i=(0,o.cC)(n.docId??void 0);return(0,h.jsx)(p,{href:n.href,icon:t,title:n.label,description:n.description??i?.description})}function x(e){let{item:n}=e;switch(n.type){case"link":return(0,h.jsx)(g,{item:n});case"category":return(0,h.jsx)(y,{item:n});default:throw new Error(`unknown item type ${JSON.stringify(n)}`)}}},2550:(e,n,t)=>{t.d(n,{A:()=>d});t(6540);var i=t(4164),s=t(4142),o=t(5965),r=t(4848);function a(e){let{className:n}=e;const t=(0,s.$S)();return(0,r.jsx)(d,{items:t.items,className:n})}function d(e){const{items:n,className:t}=e;if(!n)return(0,r.jsx)(a,{...e});const d=(0,s.d1)(n);return(0,r.jsx)("section",{className:(0,i.A)("row",t),children:d.map(((e,n)=>(0,r.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,r.jsx)(o.A,{item:e})},n)))})}},5846:(e,n,t)=>{t.d(n,{W:()=>l});var i=t(6540),s=t(4586);const o=["zero","one","two","few","many","other"];function r(e){return o.filter((n=>e.includes(n)))}const a={locale:"en",pluralForms:r(["one","other"]),select:e=>1===e?"one":"other"};function d(){const{i18n:{currentLocale:e}}=(0,s.A)();return(0,i.useMemo)((()=>{try{return function(e){const n=new Intl.PluralRules(e);return{locale:e,pluralForms:r(n.resolvedOptions().pluralCategories),select:e=>n.select(e)}}(e)}catch(n){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${n.message}\n`),a}}),[e])}function l(){const e=d();return{selectMessage:(n,t)=>function(e,n,t){const i=e.split("|");if(1===i.length)return i[0];i.length>t.pluralForms.length&&console.error(`For locale=${t.locale}, a maximum of ${t.pluralForms.length} plural forms are expected (${t.pluralForms.join(",")}), but the message contains ${i.length}: ${e}`);const s=t.select(n),o=t.pluralForms.indexOf(s);return i[Math.min(o,i.length-1)]}(t,n,e)}}},6116:(e,n,t)=>{t.d(n,{$:()=>o});var i=t(2252);function s(e){for(const n of e){const e=n.href;e&&void 0===globalThis.sidebarItemsMap[e]&&(globalThis.sidebarItemsMap[e]=n),"category"===n.type&&s(n.items)}}function o(e){const n=(0,i.r)();if(!n)throw new Error("Unexpected: cant find docsVersion in current context");if(void 0===globalThis.sidebarItemsMap){globalThis.sidebarItemsMap={};for(const e in n.docsSidebars)s(n.docsSidebars[e])}if(void 0===globalThis.sidebarItemsMap[e])throw console.log("Registered sidebar items:"),console.log(globalThis.sidebarItemsMap),new Error("Unexpected: sidebar item with href "+e+" does not exist.");return globalThis.sidebarItemsMap[e]}},8453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(6540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/7b1f3817.f32ce934.js b/assets/js/7b1f3817.f32ce934.js
new file mode 100644
index 0000000000..64d18924c6
--- /dev/null
+++ b/assets/js/7b1f3817.f32ce934.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[7532],{100:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>x,frontMatter:()=>r,metadata:()=>d,toc:()=>c});var t=s(4848),i=s(8453);const r={},l="ADR 0002: Go Modules Compatible Git Tags",d={id:"adrs/0002-go-modules-compatible-git-tags",title:"ADR 0002: Go Modules Compatible Git Tags",description:"Component",source:"@site/docs/adrs/0002-go-modules-compatible-git-tags.md",sourceDirName:"adrs",slug:"/adrs/0002-go-modules-compatible-git-tags",permalink:"/adrs/0002-go-modules-compatible-git-tags",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/adrs/edit/main/0002-go-modules-compatible-git-tags.md",tags:[],version:"current",lastUpdatedAt:1710755515e3,frontMatter:{},sidebar:"adrs",previous:{title:"ADR 0001: Multiple Roots Under the Tendermint Application Hash",permalink:"/adrs/0001-tm-multi-root-apphash"},next:{title:"ADR 0003: Consensus/Runtime Token Transfer",permalink:"/adrs/0003-consensus-runtime-token-transfer"}},o={},c=[{value:"Component",id:"component",level:2},{value:"Changelog",id:"changelog",level:2},{value:"Status",id:"status",level:2},{value:"Context",id:"context",level:2},{value:"Decision",id:"decision",level:2},{value:"Alternatives",id:"alternatives",level:2},{value:"Consequences",id:"consequences",level:2},{value:"Positive",id:"positive",level:3},{value:"Negative",id:"negative",level:3},{value:"References",id:"references",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"adr-0002-go-modules-compatible-git-tags",children:"ADR 0002: Go Modules Compatible Git Tags"}),"\n",(0,t.jsx)(n.h2,{id:"component",children:"Component"}),"\n",(0,t.jsx)(n.p,{children:"Oasis Core"}),"\n",(0,t.jsx)(n.h2,{id:"changelog",children:"Changelog"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"2020-09-04: Initial version"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"status",children:"Status"}),"\n",(0,t.jsx)(n.p,{children:"Accepted"}),"\n",(0,t.jsx)(n.h2,{id:"context",children:"Context"}),"\n",(0,t.jsxs)(n.p,{children:["Projects that depend on ",(0,t.jsx)(n.a,{href:"https://pkg.go.dev/mod/github.com/oasisprotocol/oasis-core/go",children:"Oasis Core's Go module"}),", i.e.\n",(0,t.jsx)(n.code,{children:"github.com/oasisprotocol/oasis-core/go"}),", need a way to depend on its particular\nversion."]}),"\n",(0,t.jsxs)(n.p,{children:["Go Modules only allow ",(0,t.jsx)(n.a,{href:"https://semver.org/spec/v2.0.0.html",children:"Semantic Versioning 2.0.0"})," for\n",(0,t.jsx)(n.a,{href:"https://golang.org/ref/mod#versions",children:"versioning of the modules"})," which makes it hard to work\nwith ",(0,t.jsx)(n.a,{href:"/core/versioning",children:"Oasis Core's CalVer (calendar versioning) scheme"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The currently used scheme for Go Modules compatible Git tags is:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"go/v0.YY.MINOR[.MICRO]\n"})}),"\n",(0,t.jsx)(n.p,{children:"where:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"YY"})," represents the short year (e.g. ",(0,t.jsx)(n.code,{children:"19"}),", ",(0,t.jsx)(n.code,{children:"20"}),", ",(0,t.jsx)(n.code,{children:"21"}),", ...),"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"MINOR"})," represents the minor version starting with zero (e.g. ",(0,t.jsx)(n.code,{children:"0"}),", ",(0,t.jsx)(n.code,{children:"1"}),", ",(0,t.jsx)(n.code,{children:"2"}),",\n",(0,t.jsx)(n.code,{children:"3"}),", ...),"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"MICRO"}),' represents the final number in the version (sometimes referred to as\nthe "patch" segment) (e.g. ',(0,t.jsx)(n.code,{children:"0"}),", ",(0,t.jsx)(n.code,{children:"1"}),", ",(0,t.jsx)(n.code,{children:"2"}),", ",(0,t.jsx)(n.code,{children:"3"}),", ...)."]}),"\n",(0,t.jsxs)(n.p,{children:["If the ",(0,t.jsx)(n.code,{children:"MICRO"})," version is ",(0,t.jsx)(n.code,{children:"0"}),", it is omitted."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["It turns out this only works for Oasis Core versions with the ",(0,t.jsx)(n.code,{children:"MICRO"})," version\nof ",(0,t.jsx)(n.code,{children:"0"})," since the Go Modules compatible Git tag omits the ",(0,t.jsx)(n.code,{children:".MICRO"})," part and is\nthus compatible with ",(0,t.jsx)(n.a,{href:"https://golang.org/ref/mod#versions",children:"Go Modules versioning requirements"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,t.jsx)(n.p,{children:"The proposed design is to tag Oasis Core releases with the following Go Modules\ncompatible Git tags (in addition to the ordinary Git tags):"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"go/v0.YY0MINOR.MICRO\n"})}),"\n",(0,t.jsx)(n.p,{children:"where:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"YY"})," represents the short year (e.g. ",(0,t.jsx)(n.code,{children:"19"}),", ",(0,t.jsx)(n.code,{children:"20"}),", ",(0,t.jsx)(n.code,{children:"21"}),", ...),"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"0MINOR"})," represents the zero-padded minor version starting with zero (e.g.\n",(0,t.jsx)(n.code,{children:"00"}),", ",(0,t.jsx)(n.code,{children:"01"}),", ",(0,t.jsx)(n.code,{children:"02"}),", ..., ",(0,t.jsx)(n.code,{children:"10"}),", ",(0,t.jsx)(n.code,{children:"11"}),", ...),"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"MICRO"}),' represents the final number in the version (sometimes referred to as\nthe "patch" segment) (e.g. ',(0,t.jsx)(n.code,{children:"0"}),", ",(0,t.jsx)(n.code,{children:"1"}),", ",(0,t.jsx)(n.code,{children:"2"}),", ",(0,t.jsx)(n.code,{children:"3"}),", ...)."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here are some examples of how the ordinary and the corresponding Go Modules\ncompatible Git tags would look like:"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{style:{textAlign:"center"},children:"Version"}),(0,t.jsx)(n.th,{style:{textAlign:"center"},children:"Ordinary Git tag"}),(0,t.jsx)(n.th,{style:{textAlign:"center"},children:"Go Modules compatible Git tag"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"20.9"}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"v20.9"})}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"go/v0.2009.0"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"20.9.1"}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"v20.9.1"})}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"go/v0.2009.1"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"20.9.2"}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"v20.9.2"})}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"go/v0.2009.2"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"20.10"}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"v20.10"})}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"go/v0.2010.0"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"20.10.1"}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"v20.10.1"})}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"go/v0.2010.1"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"20.10.2"}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"v20.10.2"})}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"go/v0.2010.2"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"..."}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"..."}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"..."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"21.0"}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"v21.0"})}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"go/v0.2100.0"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"21.0.1"}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"v21.0.1"})}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"go/v0.2100.1"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"21.0.2"}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"v21.0.2"})}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"go/v0.2100.2"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"21.1"}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"v21.1"})}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"go/v0.2101.0"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"21.1.1"}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"v21.1.1"})}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"go/v0.2101.1"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"21.1.2"}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"v21.1.2"})}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:(0,t.jsx)(n.code,{children:"go/v0.2101.2"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"..."}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"..."}),(0,t.jsx)(n.td,{style:{textAlign:"center"},children:"..."})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Using such a scheme makes the version of the Oasis Core Go module fully\ncompatible with the ",(0,t.jsx)(n.a,{href:"https://golang.org/ref/mod#versions",children:"Go Modules versioning requirements"})," and thus\nenables users to use the familiar Go tools to check for new module versions,\ni.e. ",(0,t.jsx)(n.code,{children:"go list -m -u all"}),", or to obtain and require a module, i.e.\n",(0,t.jsx)(n.code,{children:"go get github.com/oasisprotocol/oasis-core/go@latest"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"alternatives",children:"Alternatives"}),"\n",(0,t.jsx)(n.p,{children:"An alternative scheme would be to use the following Go Modules compatible Git\ntags:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"go/v0.YY.MINOR-MICRO\n"})}),"\n",(0,t.jsx)(n.p,{children:"where:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"YY"})," represents the short year (e.g. ",(0,t.jsx)(n.code,{children:"19"}),", ",(0,t.jsx)(n.code,{children:"20"}),", ",(0,t.jsx)(n.code,{children:"21"}),", ...),"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"MINOR"})," represents the minor version starting with zero (e.g. ",(0,t.jsx)(n.code,{children:"0"}),", ",(0,t.jsx)(n.code,{children:"1"}),", ",(0,t.jsx)(n.code,{children:"2"}),",\n",(0,t.jsx)(n.code,{children:"3"}),", ...),"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"MICRO"}),' represents the final number in the version (sometimes referred to as\nthe "patch" segment) (e.g. ',(0,t.jsx)(n.code,{children:"0"}),", ",(0,t.jsx)(n.code,{children:"1"}),", ",(0,t.jsx)(n.code,{children:"2"}),", ",(0,t.jsx)(n.code,{children:"3"}),", ...)."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Using the ",(0,t.jsx)(n.code,{children:"-MICRO"})," suffix would make Go treat all such versions as a\n",(0,t.jsx)(n.a,{href:"https://golang.org/ref/mod#glos-pre-release-version",children:"Go Modules pre-release version"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The consequence of that would be that all Go tools would treat such versions as\npre-releases."}),"\n",(0,t.jsx)(n.p,{children:"For example, let's say the Oasis Core Go module would have the following Go\nversion tags:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"go/v0.20.9"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"go/v0.20.10-0"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"go/v0.20.10-1"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["and a module that depends on the Oasis Core Go module would currently require\nversion ",(0,t.jsx)(n.code,{children:"v0.20.9"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["One downside would be that the ",(0,t.jsx)(n.code,{children:"go list -m -u all"})," command would not notify a\nuser that an update, i.e. version ",(0,t.jsx)(n.code,{children:"v0.20.10-1"}),", is available."]}),"\n",(0,t.jsxs)(n.p,{children:["The second downside would be that using the\n",(0,t.jsx)(n.code,{children:"go get github.com/oasisprotocol/oasis-core/go@latest"})," command would treat\nversion ",(0,t.jsx)(n.code,{children:"v0.20.9"})," as the latest version and download and require this version of\nthe Oasis Core Go module instead of the real latest version, ",(0,t.jsx)(n.code,{children:"v0.20.10-1"})," in\nthis example."]}),"\n",(0,t.jsx)(n.h2,{id:"consequences",children:"Consequences"}),"\n",(0,t.jsx)(n.h3,{id:"positive",children:"Positive"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["This allow users to depend on a bugfix/patch release of the Oasis Core Go\nmodule in a ",(0,t.jsx)(n.a,{href:"https://golang.org/ref/mod#versions",children:"Go Modules versioning requirements"})," compatible way,\ni.e. without having to resort to pinning the requirement to a particular\nOasis Core commit."]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"negative",children:"Negative"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"The connection between an ordinary Git tag and a Go Modules compatible Git tag\nis not very obvious."}),"\n",(0,t.jsxs)(n.p,{children:["For example, it might not be immediately obvious that ",(0,t.jsx)(n.code,{children:"v21.0"})," and\n",(0,t.jsx)(n.code,{children:"go/v0.2100.0"})," refer to the same thing."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Using a zero-padded minor version fixed to two characters would limit the\nnumber of releases in a year to 100 releases."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"references",children:"References"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://github.com/dgraph-io/badger",children:"BadgerDB"})," uses a ",(0,t.jsx)(n.a,{href:"https://github.com/dgraph-io/badger/releases",children:"similar scheme for tagging Go Modules compatible Git tags"}),"\nfor their CalVer versioning scheme."]}),"\n"]})]})}function x(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>d});var t=s(6540);const i={},r=t.createContext(i);function l(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/7bee5ea1.88163222.js b/assets/js/7bee5ea1.88163222.js
new file mode 100644
index 0000000000..9713ec79aa
--- /dev/null
+++ b/assets/js/7bee5ea1.88163222.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[4938],{6557:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var o=s(4848),t=s(8453);const i={},r="Terminology",a={id:"general/manage-tokens/terminology",title:"Terminology",description:"Account",source:"@site/docs/general/manage-tokens/terminology.md",sourceDirName:"general/manage-tokens",slug:"/general/manage-tokens/terminology",permalink:"/general/manage-tokens/terminology",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/general/manage-tokens/terminology.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"general",previous:{title:"Manage your Tokens",permalink:"/general/manage-tokens/"},next:{title:"Staking and Delegating",permalink:"/general/manage-tokens/staking-and-delegating"}},c={},d=[{value:"Account",id:"account",level:2},{value:"Address",id:"address",level:2},{value:"Delegation",id:"delegation",level:2},{value:"Staking",id:"staking",level:2},{value:"Rewards",id:"rewards",level:2},{value:"Commission",id:"commission",level:2},{value:"Slashing",id:"slashing",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"terminology",children:"Terminology"}),"\n",(0,o.jsx)(n.h2,{id:"account",children:"Account"}),"\n",(0,o.jsxs)(n.p,{children:["A staking ",(0,o.jsx)(n.strong,{children:"account"})," is an entry in the staking ledger."]}),"\n",(0,o.jsx)(n.p,{children:"It has two (sub)accounts:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"General account"})}),"\n",(0,o.jsx)(n.p,{children:"It is used to keep the funds that are freely available to the account owner\nto transfer, delegate/stake, pay gas fees, etc."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Escrow account"})}),"\n",(0,o.jsx)(n.p,{children:"It is used to keep the funds needed for specific consensus-layer operations\n(e.g. registering and running nodes, staking and delegation of tokens, ...)."}),"\n",(0,o.jsx)(n.p,{children:"To simplify accounting, each escrow results in the source account being\nissued shares which can be converted back into staking tokens during the\nreclaim escrow operation. Reclaiming escrow does not complete immediately,\nbut may be subject to a debonding period during which the tokens still remain\nescrowed."}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"address",children:"Address"}),"\n",(0,o.jsxs)(n.p,{children:["A staking account ",(0,o.jsx)(n.strong,{children:"address"})," is represented by a truncated hash of a\ncorresponding entity's public key, prefixed by a 1 byte address version."]}),"\n",(0,o.jsxs)(n.p,{children:["It uses ",(0,o.jsx)(n.a,{href:"https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32",children:"Bech32 encoding"})," for text serialization with ",(0,o.jsx)(n.code,{children:"oasis"})," as its human\nreadable part (HRP) prefix."]}),"\n",(0,o.jsxs)(n.p,{children:["EVM-compatible ParaTimes running on the Oasis compute layer ",(0,o.jsx)(n.strong,{children:"may use"}),"\nEVM-compatible 20-byte addresses in hex format (starting with ",(0,o.jsx)(n.code,{children:"0x"}),")."]}),"\n",(0,o.jsx)(n.h2,{id:"delegation",children:"Delegation"}),"\n",(0,o.jsxs)(n.p,{children:["You can ",(0,o.jsx)(n.strong,{children:"delegate"})," your tokens by submitting an ",(0,o.jsx)(n.strong,{children:"escrow"})," transaction that\ndeposits a specific number of tokens into someone else\u2019s escrow account (as\nopposed to ",(0,o.jsx)(n.strong,{children:"staking"})," tokens, which usually refers to depositing tokens into\nyour own escrow account)."]}),"\n",(0,o.jsx)(n.p,{children:"In other words, delegating your tokens is equivalent to staking your tokens in\nsomeone else's validator node. Delegating your tokens can give you the\nopportunity to participate in the Oasis Network's proof-of-stake consensus\nsystem and earn rewards via someone else's validator node."}),"\n",(0,o.jsx)(n.h2,{id:"staking",children:"Staking"}),"\n",(0,o.jsxs)(n.p,{children:["You can stake your tokens by submitting an ",(0,o.jsx)(n.strong,{children:"escrow"})," transaction that deposits\na specific number of tokens into your escrow account."]}),"\n",(0,o.jsx)(n.h2,{id:"rewards",children:"Rewards"}),"\n",(0,o.jsx)(n.p,{children:"By delegating your tokens to someone else's node, you can earn a portion of the\nrewards earned by that node through its participation in the Oasis Network."}),"\n",(0,o.jsx)(n.h2,{id:"commission",children:"Commission"}),"\n",(0,o.jsxs)(n.p,{children:["Node operators collect ",(0,o.jsx)(n.strong,{children:"commissions"})," when their node earns a\n",(0,o.jsx)(n.strong,{children:"staking reward"})," for delegators. A validator node earns a staking reward for\nparticipating in the consensus protocol each epoch. The ",(0,o.jsx)(n.strong,{children:"commission rate"})," is\na fraction of the staking reward."]}),"\n",(0,o.jsx)(n.p,{children:"For example, if our validator node earns a reward of 0.007 tokens, 0.0035\ntokens are added to the escrow pool (increasing the value of our escrow pool\nshares uniformly), and 0.0035 tokens are given to us (issuing us new shares as\nif we manually deposited them)."}),"\n",(0,o.jsx)(n.h2,{id:"slashing",children:"Slashing"}),"\n",(0,o.jsxs)(n.p,{children:["A portion of your delegated tokens can be ",(0,o.jsx)(n.strong,{children:"slashed"})," (seized) by the network,\nif the node that you delegated your tokens to gets slashed, e.g. as a penalty\nfor equivocating in the protocol by signing diverging blocks for the same\nheight."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>a});var o=s(6540);const t={},i=o.createContext(t);function r(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/7ca72da4.271d128a.js b/assets/js/7ca72da4.271d128a.js
new file mode 100644
index 0000000000..cfdbb74072
--- /dev/null
+++ b/assets/js/7ca72da4.271d128a.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[8660],{3873:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>s,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>a});var i=n(4848),r=n(8453);const o={},s="Big Integer Quantities",c={id:"core/bigint",title:"Big Integer Quantities",description:"Arbitrary-precision positive integer quantities are represented by the",source:"@site/docs/core/bigint.md",sourceDirName:"core",slug:"/core/bigint",permalink:"/core/bigint",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/oasis-core/edit/stable/22.2.x/docs/bigint.md",tags:[],version:"current",lastUpdatedAt:1715584634e3,frontMatter:{}},d={},a=[{value:"Encoding",id:"encoding",level:2}];function u(e){const t={code:"code",h1:"h1",h2:"h2",p:"p",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"big-integer-quantities",children:"Big Integer Quantities"}),"\n",(0,i.jsxs)(t.p,{children:["Arbitrary-precision positive integer quantities are represented by the\n",(0,i.jsx)(t.code,{children:"quantity.Quantity"})," type."]}),"\n",(0,i.jsx)(t.h2,{id:"encoding",children:"Encoding"}),"\n",(0,i.jsx)(t.p,{children:"When encoded it uses the big-endian byte order."})]})}function p(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var i=n(6540);const r={},o=i.createContext(r);function s(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/7da689db.27e05283.js b/assets/js/7da689db.27e05283.js
new file mode 100644
index 0000000000..e15b964b52
--- /dev/null
+++ b/assets/js/7da689db.27e05283.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[1420],{5754:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>o,metadata:()=>d,toc:()=>u});var t=r(4848),i=r(8453),a=r(1470),s=r(9365);const o={},l="ParaTime Node",d={id:"get-involved/run-node/paratime-node",title:"ParaTime Node",description:"This guide provides an overview of the requirements to become a compute node for",source:"@site/docs/get-involved/run-node/paratime-node.mdx",sourceDirName:"get-involved/run-node",slug:"/get-involved/run-node/paratime-node",permalink:"/get-involved/run-node/paratime-node",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/docs/edit/main/docs/get-involved/run-node/paratime-node.mdx",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{},sidebar:"getInvolved",previous:{title:"Consensus Validator Node",permalink:"/get-involved/run-node/validator-node"},next:{title:"Develop Oasis Core",permalink:"/get-involved/oasis-core"}},c={},u=[{value:"About Oasis Network",id:"about-oasis-network",level:2},{value:"Operating ParaTimes",id:"operating-paratimes",level:2},{value:"Sapphire ParaTime",id:"sapphire-paratime",level:3},{value:"Overview",id:"overview",level:3},{value:"Features",id:"features",level:3},{value:"Mainnet Requirements",id:"mainnet-requirements",level:3},{value:"Cipher ParaTime",id:"cipher-paratime",level:3},{value:"Overview",id:"overview-1",level:3},{value:"Features",id:"features-1",level:3},{value:"Mainnet Requirements",id:"mainnet-requirements-1",level:3},{value:"Emerald ParaTime",id:"emerald-paratime",level:3},{value:"Overview",id:"overview-2",level:3},{value:"Features",id:"features-2",level:3},{value:"Mainnet Requirements",id:"mainnet-requirements-2",level:3}];function h(e){const n={a:"a",h1:"h1",h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"paratime-node",children:"ParaTime Node"}),"\n",(0,t.jsx)(n.p,{children:"This guide provides an overview of the requirements to become a compute node for\na ParaTime connected to the Oasis Network."}),"\n",(0,t.jsx)(n.h2,{id:"about-oasis-network",children:"About Oasis Network"}),"\n",(0,t.jsx)(n.p,{children:"The Oasis Network has two main components, the consensus layer and the ParaTime\nLayer."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.strong,{children:"consensus layer"})," is a scalable, high-throughput, secure,\nproof-of-stake consensus run by a decentralized set of validator nodes."]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.strong,{children:"ParaTime layer"})," hosts many parallel runtimes (ParaTimes), each\nrepresenting a replicated compute environment with shared state."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Oasis architectural design including ParaTime and consensus layers",src:r(141).A+"",width:"1523",height:"718"})}),"\n",(0,t.jsx)(n.h2,{id:"operating-paratimes",children:"Operating ParaTimes"}),"\n",(0,t.jsx)(n.p,{children:"Operating a ParaTime requires the participation of node operators who\ncontribute nodes to the committee in exchange for rewards.\nParaTimes can be operated by anyone, and have their own reward system,\nparticipation requirements, and structure."}),"\n",(0,t.jsxs)(n.p,{children:["As a node operator you can participate in any number of ParaTimes.\nWhile there are a number of ParaTimes under development, below are a few key\nParaTimes that you can get involved in today.\nFor operational documentation on running a ParaTime, please see the section on\n",(0,t.jsx)(n.a,{href:"/node/run-your-node/paratime-node",children:"running a ParaTime node for node operators"}),"."]}),"\n",(0,t.jsxs)(a.A,{children:[(0,t.jsxs)(s.A,{value:"Sapphire ParaTime",children:[(0,t.jsx)(n.h3,{id:"sapphire-paratime",children:"Sapphire ParaTime"}),(0,t.jsx)(n.p,{children:"A confidential EVM-compatible Oasis Foundation developed ParaTime that enables\nthe use of EVM smart contracts on the Oasis network."}),(0,t.jsx)(n.h3,{id:"overview",children:"Overview"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Leading Developer:"})," ",(0,t.jsx)(n.a,{href:"http://oasisprotocol.org",children:"Oasis Protocol Foundation"}),", with contributions from\ncommunity developers"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Status:"})," Deployed on Mainnet and Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Testnet Launch Date:"})," July 2022"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Mainnet Launch Date:"})," Dec 2022"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Discord Channel:"})," ",(0,t.jsx)(n.a,{href:"/get-involved/",children:"#node-operators"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Requires SGX:"})," Yes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Parameters:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/node/mainnet/#sapphire",children:"Mainnet"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/node/testnet/#sapphire",children:"Testnet"})}),"\n"]}),"\n"]}),"\n"]}),(0,t.jsx)(n.h3,{id:"features",children:"Features"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Fully decentralized with node operators distributed across the world."}),"\n",(0,t.jsxs)(n.li,{children:["Oasis ",(0,t.jsx)(n.strong,{children:"ROSE"})," tokens are the native token used in the ParaTime for gas fees."]}),"\n",(0,t.jsx)(n.li,{children:"Support for EVM smart contracts."}),"\n",(0,t.jsx)(n.li,{children:"Support for confidential compute."}),"\n"]}),(0,t.jsx)(n.h3,{id:"mainnet-requirements",children:"Mainnet Requirements"}),(0,t.jsx)(n.p,{children:"For your Sapphire ParaTime node to be eligible to be elected into the Sapphire\ncommittee on Mainnet, your entity needs to:"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Have a validator in the ",(0,t.jsx)(n.strong,{children:"validator set"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Have at least ",(0,t.jsx)(n.strong,{children:"5,000,000.00 ROSE staked/delegated"})," to it."]}),"\n"]})]}),(0,t.jsxs)(s.A,{value:"Cipher ParaTime",children:[(0,t.jsx)(n.h3,{id:"cipher-paratime",children:"Cipher ParaTime"}),(0,t.jsx)(n.p,{children:"An Oasis Foundation developed ParaTime that enables WebAssembly-based\nconfidential smart contracts."}),(0,t.jsx)(n.h3,{id:"overview-1",children:"Overview"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Leading Developer:"})," ",(0,t.jsx)(n.a,{href:"http://oasisprotocol.org",children:"Oasis Protocol Foundation"}),", with contributions from\ncommunity developers"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Status:"})," Deployed on Mainnet and Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Testnet Launch Date:"})," June 2021"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Mainnet Launch Date:"})," October 2021"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Discord Channel:"})," ",(0,t.jsx)(n.a,{href:"/get-involved/",children:"#node-operators"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Requires SGX:"})," Yes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Parameters:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/node/mainnet/#cipher",children:"Mainnet"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/node/testnet/#cipher",children:"Testnet"})}),"\n"]}),"\n"]}),"\n"]}),(0,t.jsx)(n.h3,{id:"features-1",children:"Features"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Fully decentralized with node operators distributed across the world."}),"\n",(0,t.jsxs)(n.li,{children:["Oasis ",(0,t.jsx)(n.strong,{children:"ROSE"})," tokens are the native token used in the ParaTime for gas fees."]}),"\n",(0,t.jsx)(n.li,{children:"Support for WebAssembly smart contracts."}),"\n",(0,t.jsx)(n.li,{children:"Support for confidential compute."}),"\n"]}),(0,t.jsx)(n.h3,{id:"mainnet-requirements-1",children:"Mainnet Requirements"}),(0,t.jsx)(n.p,{children:"For your Cipher ParaTime node to be eligible to be elected into the Cipher\ncommittee on Mainnet, your entity needs to:"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Have a validator in the ",(0,t.jsx)(n.strong,{children:"validator set"}),"."]}),"\n"]})]}),(0,t.jsxs)(s.A,{value:"Emerald ParaTime",children:[(0,t.jsx)(n.h3,{id:"emerald-paratime",children:"Emerald ParaTime"}),(0,t.jsx)(n.p,{children:"An EVM-compatible Oasis Foundation developed ParaTime that enables the use of\nEVM smart contracts on the Oasis network."}),(0,t.jsx)(n.h3,{id:"overview-2",children:"Overview"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Leading Developer:"})," ",(0,t.jsx)(n.a,{href:"http://oasisprotocol.org",children:"Oasis Protocol Foundation"}),", with contributions from\ncommunity developers"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Status:"})," Deployed on Mainnet and Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Testnet Launch Date:"})," October 2021"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Mainnet Launch Date:"})," November 2021"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Discord Channel:"})," ",(0,t.jsx)(n.a,{href:"/get-involved/",children:"#node-operators"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Requires SGX:"})," No"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Parameters:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/node/mainnet/#emerald",children:"Mainnet"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/node/testnet/#emerald",children:"Testnet"})}),"\n"]}),"\n"]}),"\n"]}),(0,t.jsx)(n.h3,{id:"features-2",children:"Features"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Fully decentralized with node operators distributed across the world."}),"\n",(0,t.jsxs)(n.li,{children:["Oasis ",(0,t.jsx)(n.strong,{children:"ROSE"})," tokens are the native token used in the ParaTime for gas fees."]}),"\n"]}),(0,t.jsx)(n.h3,{id:"mainnet-requirements-2",children:"Mainnet Requirements"}),(0,t.jsx)(n.p,{children:"For your Emerald ParaTime node to be eligible to be elected into the Emerald\ncommittee on Mainnet, your entity needs to:"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Have a validator in the ",(0,t.jsx)(n.strong,{children:"validator set"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Have at least ",(0,t.jsx)(n.strong,{children:"5,000,000.00 ROSE staked/delegated"})," to it."]}),"\n"]})]})]})]})}function m(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},9365:(e,n,r)=>{r.d(n,{A:()=>s});r(6540);var t=r(4164);const i={tabItem:"tabItem_Ymn6"};var a=r(4848);function s(e){let{children:n,hidden:r,className:s}=e;return(0,a.jsx)("div",{role:"tabpanel",className:(0,t.A)(i.tabItem,s),hidden:r,children:n})}},1470:(e,n,r)=>{r.d(n,{A:()=>T});var t=r(6540),i=r(4164),a=r(3104),s=r(6347),o=r(205),l=r(7485),d=r(1682),c=r(9466);function u(e){return t.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,t.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function h(e){const{values:n,children:r}=e;return(0,t.useMemo)((()=>{const e=n??function(e){return u(e).map((e=>{let{props:{value:n,label:r,attributes:t,default:i}}=e;return{value:n,label:r,attributes:t,default:i}}))}(r);return function(e){const n=(0,d.X)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,r])}function m(e){let{value:n,tabValues:r}=e;return r.some((e=>e.value===n))}function p(e){let{queryString:n=!1,groupId:r}=e;const i=(0,s.W6)(),a=function(e){let{queryString:n=!1,groupId:r}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!r)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:n,groupId:r});return[(0,l.aZ)(a),(0,t.useCallback)((e=>{if(!a)return;const n=new URLSearchParams(i.location.search);n.set(a,e),i.replace({...i.location,search:n.toString()})}),[a,i])]}function v(e){const{defaultValue:n,queryString:r=!1,groupId:i}=e,a=h(e),[s,l]=(0,t.useState)((()=>function(e){let{defaultValue:n,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({value:n,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const t=r.find((e=>e.default))??r[0];if(!t)throw new Error("Unexpected error: 0 tabValues");return t.value}({defaultValue:n,tabValues:a}))),[d,u]=p({queryString:r,groupId:i}),[v,x]=function(e){let{groupId:n}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(n),[i,a]=(0,c.Dv)(r);return[i,(0,t.useCallback)((e=>{r&&a.set(e)}),[r,a])]}({groupId:i}),j=(()=>{const e=d??v;return m({value:e,tabValues:a})?e:null})();(0,o.A)((()=>{j&&l(j)}),[j]);return{selectedValue:s,selectValue:(0,t.useCallback)((e=>{if(!m({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);l(e),u(e),x(e)}),[u,x,a]),tabValues:a}}var x=r(2303);const j={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var f=r(4848);function g(e){let{className:n,block:r,selectedValue:t,selectValue:s,tabValues:o}=e;const l=[],{blockElementScrollPositionUntilNextRender:d}=(0,a.a_)(),c=e=>{const n=e.currentTarget,r=l.indexOf(n),i=o[r].value;i!==t&&(d(n),s(i))},u=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const r=l.indexOf(e.currentTarget)+1;n=l[r]??l[0];break}case"ArrowLeft":{const r=l.indexOf(e.currentTarget)-1;n=l[r]??l[l.length-1];break}}n?.focus()};return(0,f.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.A)("tabs",{"tabs--block":r},n),children:o.map((e=>{let{value:n,label:r,attributes:a}=e;return(0,f.jsx)("li",{role:"tab",tabIndex:t===n?0:-1,"aria-selected":t===n,ref:e=>l.push(e),onKeyDown:u,onClick:c,...a,className:(0,i.A)("tabs__item",j.tabItem,a?.className,{"tabs__item--active":t===n}),children:r??n},n)}))})}function b(e){let{lazy:n,children:r,selectedValue:i}=e;const a=(Array.isArray(r)?r:[r]).filter(Boolean);if(n){const e=a.find((e=>e.props.value===i));return e?(0,t.cloneElement)(e,{className:"margin-top--md"}):null}return(0,f.jsx)("div",{className:"margin-top--md",children:a.map(((e,n)=>(0,t.cloneElement)(e,{key:n,hidden:e.props.value!==i})))})}function y(e){const n=v(e);return(0,f.jsxs)("div",{className:(0,i.A)("tabs-container",j.tabList),children:[(0,f.jsx)(g,{...n,...e}),(0,f.jsx)(b,{...n,...e})]})}function T(e){const n=(0,x.A)();return(0,f.jsx)(y,{...e,children:u(e.children)},String(n))}},141:(e,n,r)=>{r.d(n,{A:()=>t});const t=r.p+"assets/images/technology_scalability-37484303b278abc340a74baee5027d33.svg"},8453:(e,n,r)=>{r.d(n,{R:()=>s,x:()=>o});var t=r(6540);const i={},a=t.createContext(i);function s(e){const n=t.useContext(a);return t.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(i):e.components||i:s(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/82c34158.6d656fb2.js b/assets/js/82c34158.6d656fb2.js
new file mode 100644
index 0000000000..893708308d
--- /dev/null
+++ b/assets/js/82c34158.6d656fb2.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[9737],{4271:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>d});var i=t(4848),a=t(8453);const s={description:"Authenticate users with your confidential contracts"},r="View-Call Authentication",c={id:"dapp/sapphire/authentication",title:"View-Call Authentication",description:"Authenticate users with your confidential contracts",source:"@site/docs/dapp/sapphire/authentication.md",sourceDirName:"dapp/sapphire",slug:"/dapp/sapphire/authentication",permalink:"/dapp/sapphire/authentication",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/sapphire-paratime/edit/main/docs/authentication.md",tags:[],version:"current",lastUpdatedAt:172612742e4,frontMatter:{description:"Authenticate users with your confidential contracts"},sidebar:"developers",previous:{title:"Browser Support",permalink:"/dapp/sapphire/browser"},next:{title:"Gasless Transactions",permalink:"/dapp/sapphire/gasless"}},o={},d=[{value:"Sapphire Wrapper",id:"sapphire-wrapper",level:2},{value:"Caching Signed Queries",id:"caching-signed-queries",level:2},{value:"Daily Sign-In with EIP-712",id:"daily-sign-in-with-eip-712",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"view-call-authentication",children:"View-Call Authentication"}),"\n",(0,i.jsxs)(n.p,{children:['User impersonation on Ethereum and other "Transparent EVMs" isn\'t a problem\nbecause ',(0,i.jsx)(n.strong,{children:"everybody"})," can see ",(0,i.jsx)(n.strong,{children:"all"})," data however the Sapphire confidential\nEVM prevents contracts from revealing confidential information to the wrong\nparty (account or contract) - for this reason we cannot allow arbitrary\nimpersonation of any ",(0,i.jsx)(n.code,{children:"msg.sender"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"In Sapphire, there are four types of contract calls:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Contract to contract calls (also known as ",(0,i.jsx)(n.em,{children:"internal calls"}),")"]}),"\n",(0,i.jsxs)(n.li,{children:["Unauthenticted view calls (queries using ",(0,i.jsx)(n.code,{children:"eth_call"}),")"]}),"\n",(0,i.jsx)(n.li,{children:"Authenticated view calls (signed queries)"}),"\n",(0,i.jsx)(n.li,{children:"Transactions (authenticated by signature)"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Intra-contract calls always set ",(0,i.jsx)(n.code,{children:"msg.sender"})," appropriately, if a contract calls\nanother contract in a way which could reveal sensitive information, the calling\ncontract must implement access control or authentication."]}),"\n",(0,i.jsxs)(n.p,{children:["By default all ",(0,i.jsx)(n.code,{children:"eth_call"})," queries used to invoke contract functions have the\n",(0,i.jsx)(n.code,{children:"msg.sender"})," parameter set to ",(0,i.jsx)(n.code,{children:"address(0x0)"}),". In contrast, authenticated calls are\nsigned by a keypair and will have the ",(0,i.jsx)(n.code,{children:"msg.sender"})," parameter correctly initialized\n(more on that later). Also, when a transaction is\nsubmitted it is signed by a keypair (thus costs gas and can make state updates)\nand the ",(0,i.jsx)(n.code,{children:"msg.sender"})," will be set to the signing account."]}),"\n",(0,i.jsx)(n.h2,{id:"sapphire-wrapper",children:"Sapphire Wrapper"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"https://www.npmjs.com/package/@oasisprotocol/sapphire-paratime",children:"@oasisprotocol/sapphire-paratime"})," Ethereum provider wrapper\n",(0,i.jsx)(n.code,{children:"sapphire.wrap"})," function will ",(0,i.jsx)(n.strong,{children:"automatically end-to-end encrypt calldata"})," when\ninteracting with contracts on Sapphire, this is an easy way to ensure the\ncalldata of your dApp transactions remain confidential - although the ",(0,i.jsx)(n.code,{children:"from"}),",\n",(0,i.jsx)(n.code,{children:"to"}),", and ",(0,i.jsx)(n.code,{children:"gasprice"})," parameters are not encrypted."]}),"\n",(0,i.jsx)(n.admonition,{title:"Unauthenticated calls and Encryption",type:"tip",children:(0,i.jsx)(n.p,{children:"Although the calls may be unauthenticated, they can still be encrypted!"})}),"\n",(0,i.jsxs)(n.p,{children:["However, if the Sapphire wrapper has been attached to a signer then subsequent\nview calls via ",(0,i.jsx)(n.code,{children:"eth_call"})," will request that the user sign them (e.g. a\nMetaMask popup), these are called ",(0,i.jsx)(n.strong,{children:"signed queries"})," meaning ",(0,i.jsx)(n.code,{children:"msg.sender"})," will be\nset to the signing account and can be used for authentication or to implement\naccess control. This may add friction to the end-user experience and can result\nin frequent pop-ups requesting they sign queries which wouldn't normally require\nany interaction on Transparent EVMs."]}),"\n",(0,i.jsx)(n.p,{children:"Let's see how Sapphire interprets different contract calls. Suppose the\nfollowing solidity code:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-solidity",children:"contract Example {\n address owner;\n constructor () {\n owner = msg.sender;\n }\n function isOwner () public view returns (bool) {\n return msg.sender == owner;\n }\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["In the sample above, assuming we're calling from the same contract or account\nwhich created the contract, calling ",(0,i.jsx)(n.code,{children:"isOwner"})," will return:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"false"}),", for ",(0,i.jsx)(n.code,{children:"eth_call"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"false"}),", with ",(0,i.jsx)(n.code,{children:"sapphire.wrap"})," but without an attached signer"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"true"}),", with ",(0,i.jsx)(n.code,{children:"sapphire.wrap"})," and an attached signer"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"true"}),", if called via the contract which created it"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"true"}),", if called via transaction"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"caching-signed-queries",children:"Caching Signed Queries"}),"\n",(0,i.jsx)(n.p,{children:"When using signed queries the blockchain will be queried each time, however\nthe Sapphire wrapper will cache signatures for signed queries with the same\nparameters to avoid asking the user to sign the same thing multiple times."}),"\n",(0,i.jsxs)(n.p,{children:['Behind the scenes the signed queries use a "leash" to specify validity conditions\nso the query can only be performed within a block and account ',(0,i.jsx)(n.code,{children:"nonce"})," range.\nThese parameters are visible in the EIP-712 popup signed by the user. Queries\nwith the same parameters will use the same leash."]}),"\n",(0,i.jsx)(n.h2,{id:"daily-sign-in-with-eip-712",children:"Daily Sign-In with EIP-712"}),"\n",(0,i.jsxs)(n.p,{children:["One strategy which can be used to reduce the number of transaction signing\nprompts when a user interacts with contracts via a dApp is to use\n",(0,i.jsx)(n.a,{href:"https://eips.ethereum.org/EIPS/eip-712",children:"EIP-712"}),' to "sign-in" once per day (or per-session), in combination\nwith using two wrapped providers:']}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Provider to perform encrypted but unauthenticated view calls"}),"\n",(0,i.jsxs)(n.li,{children:["Another provider to perform encrypted and authenticated transactions (or view calls)","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The user will be prompted to sign each action."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The two-provider pattern, in conjunction with a daily EIP-712 sign-in prompt\nensures all transactions are end-to-end encrypted and the contract can\nauthenticate users in view calls without frequent annoying popups."}),"\n",(0,i.jsxs)(n.p,{children:["The code sample below uses an ",(0,i.jsx)(n.code,{children:"authenticated"})," modifier to verify the sign-in:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-solidity",children:'// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nstruct SignatureRSV {\n bytes32 r;\n bytes32 s;\n uint256 v;\n}\n\ncontract SignInExample {\n bytes32 public constant EIP712_DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");\n string public constant SIGNIN_TYPE = "SignIn(address user,uint32 time)";\n bytes32 public constant SIGNIN_TYPEHASH = keccak256(bytes(SIGNIN_TYPE));\n bytes32 public immutable DOMAIN_SEPARATOR;\n\n constructor () {\n DOMAIN_SEPARATOR = keccak256(abi.encode(\n EIP712_DOMAIN_TYPEHASH,\n keccak256("SignInExample.SignIn"),\n keccak256("1"),\n block.chainid,\n address(this)\n ));\n }\n\n struct SignIn {\n address user;\n uint32 time;\n SignatureRSV rsv;\n }\n\n modifier authenticated(SignIn calldata auth)\n {\n // Must be signed within 24 hours ago.\n require( auth.time > (block.timestamp - (60*60*24)) );\n\n // Validate EIP-712 sign-in authentication.\n bytes32 authdataDigest = keccak256(abi.encodePacked(\n "\\x19\\x01",\n DOMAIN_SEPARATOR,\n keccak256(abi.encode(\n SIGNIN_TYPEHASH,\n auth.user,\n auth.time\n ))\n ));\n\n address recovered_address = ecrecover(\n authdataDigest, uint8(auth.rsv.v), auth.rsv.r, auth.rsv.s);\n\n require( auth.user == recovered_address, "Invalid Sign-In" );\n\n _;\n }\n\n function authenticatedViewCall(\n SignIn calldata auth,\n ... args\n )\n external view\n authenticated(auth)\n returns (bytes memory output)\n {\n // Use `auth.user` instead of `msg.sender`!\n }\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:"With the above contract code deployed, let's look at the frontend dApp and how\nit can request the user to sign-in using EIP-712. You may wish to add additional\nparameters which are authenticated such as the domain name. The following code\nexample uses Ethers:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:'const time = new Date().getTime();\nconst user = await eth.signer.getAddress();\n\n// Ask user to "Sign-In" every 24 hours.\nconst signature = await eth.signer.signTypedData({\n name: "SignInExample.SignIn",\n version: "1",\n chainId: import.meta.env.CHAINID,\n verifyingContract: await contract.getAddress()\n}, {\n SignIn: [\n { name: \'user\', type: "address" },\n { name: \'time\', type: \'uint32\' },\n ]\n}, {\n user,\n time: time\n});\nconst rsv = ethers.Signature.from(signature);\nconst auth = {user, time, rsv};\n// The `auth` variable can then be cached.\n\n// Then in the future, authenticated view calls can be performed by\n// passing auth without further user interaction authenticated data.\nawait contract.authenticatedViewCall(auth, ...args);\n'})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>c});var i=t(6540);const a={},s=i.createContext(a);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/85011861.ba4e738a.js b/assets/js/85011861.ba4e738a.js
new file mode 100644
index 0000000000..8d5b1ae8a9
--- /dev/null
+++ b/assets/js/85011861.ba4e738a.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[5403],{6995:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var s=t(4848),a=t(8453);const i={title:"Transaction",description:"Use CLI to decode, verify, sign and submit a transaction"},o="Transaction Tools",r={id:"general/manage-tokens/cli/transaction",title:"Transaction",description:"Use CLI to decode, verify, sign and submit a transaction",source:"@site/docs/general/manage-tokens/cli/transaction.md",sourceDirName:"general/manage-tokens/cli",slug:"/general/manage-tokens/cli/transaction",permalink:"/general/manage-tokens/cli/transaction",draft:!1,unlisted:!1,editUrl:"https://github.com/oasisprotocol/cli/edit/master/docs/transaction.md",tags:[],version:"current",lastUpdatedAt:1715850376e3,frontMatter:{title:"Transaction",description:"Use CLI to decode, verify, sign and submit a transaction"},sidebar:"general",previous:{title:"Account",permalink:"/general/manage-tokens/cli/account"},next:{title:"Address book",permalink:"/general/manage-tokens/cli/addressbook"}},c={},d=[{value:"Decode, Verify and Show a Transaction",id:"show",level:2},{value:"Sign a Transaction",id:"sign",level:2},{value:"Submit a Transaction",id:"submit",level:2}];function l(n){const e={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...n.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(e.h1,{id:"transaction-tools",children:"Transaction Tools"}),"\n",(0,s.jsxs)(e.p,{children:["The ",(0,s.jsx)(e.code,{children:"transaction"})," command offers convenient tools for processing raw\nconsensus or ParaTime transactions stored in a JSON file:"]}),"\n",(0,s.jsxs)(e.ul,{children:["\n",(0,s.jsx)(e.li,{children:"decoding and displaying the transaction,"}),"\n",(0,s.jsx)(e.li,{children:"verifying transaction's signature,"}),"\n",(0,s.jsx)(e.li,{children:"signing the transaction,"}),"\n",(0,s.jsx)(e.li,{children:"broadcasting the transaction."}),"\n"]}),"\n",(0,s.jsx)(e.h2,{id:"show",children:"Decode, Verify and Show a Transaction"}),"\n",(0,s.jsxs)(e.p,{children:["To show the transaction, invoke ",(0,s.jsx)(e.code,{children:"transaction show "})," and provide\na filename containing a previously generated transaction by ",(0,s.jsx)(e.code,{children:"oasis-node"})," or the\nOasis CLI's ",(0,s.jsx)(e.a,{href:"/general/manage-tokens/cli/account#output-file",children:(0,s.jsx)(e.code,{children:"--output-file"})})," parameter."]}),"\n",(0,s.jsxs)(e.p,{children:["For example, let's take the following transaction transferring ",(0,s.jsx)(e.code,{children:"1.0 TEST"})," from\n",(0,s.jsx)(e.code,{children:"test:alice"})," to ",(0,s.jsx)(e.code,{children:"test:bob"})," on Testnet consensus layer and store it to\n",(0,s.jsx)(e.code,{children:"testtx.json"}),":"]}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-json",metastring:'title="testtx.json"',children:'{\n "untrusted_raw_value": "pGNmZWWiY2dhcwFmYW1vdW50QGRib2R5omJ0b1UAyND0Wds45cwxynfmbSxEVty+tQJmYW1vdW50RDuaygBlbm9uY2UBZm1ldGhvZHBzdGFraW5nLlRyYW5zZmVy",\n "signature": {\n "public_key": "NcPzNW3YU2T+ugNUtUWtoQnRvbOL9dYSaBfbjHLP1pE=",\n "signature": "ph5Sj29JFG8p0rCqAXjHm+yLwiXHybxah9C1cVTI01SDeJlyXT8dbp4BfI1hFxBomgi1hOrevTpShX0f9puTCQ=="\n }\n}\n'})}),"\n",(0,s.jsx)(e.p,{children:"We can decode and verify the transaction as follows:"}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-shell",children:"oasis transaction show testtx.json --network testnet\n"})}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{children:"Hash: c996e9d17d652d5dc64589d10806c244a5ef0f650cc2ec8c810b28a85fef5705\nSigner: NcPzNW3YU2T+ugNUtUWtoQnRvbOL9dYSaBfbjHLP1pE=\n (signature: ph5Sj29JFG8p0rCqAXjHm+yLwiXHybxah9C1cVTI01SDeJlyXT8dbp4BfI1hFxBomgi1hOrevTpShX0f9puTCQ==)\nContent:\n Method: staking.Transfer\n Body:\n To: oasis1qrydpazemvuwtnp3efm7vmfvg3tde044qg6cxwzx\n Amount: 1.0 TEST\n Nonce: 1\n Fee:\n Amount: 0.0 TEST\n Gas limit: 1\n (gas price: 0.0 TEST per gas unit)\n\nNetwork: testnet\nParaTime: none (consensus layer)\n"})}),"\n",(0,s.jsxs)(e.p,{children:["Since the signature depends on the ",(0,s.jsx)(e.a,{href:"/core/crypto#chain-domain-separation",children:"chain domain separation context"}),", the\ntransaction above will be invalid on other networks such as the Mainnet. In this\ncase the Oasis CLI will print the ",(0,s.jsx)(e.code,{children:"[INVALID SIGNATURE]"})," warning below the\nsignature:"]}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-shell",children:"oasis transaction show testtx.json --network mainnet\n"})}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-text",metastring:"{4}",children:"Hash: c996e9d17d652d5dc64589d10806c244a5ef0f650cc2ec8c810b28a85fef5705\nSigner: NcPzNW3YU2T+ugNUtUWtoQnRvbOL9dYSaBfbjHLP1pE=\n (signature: ph5Sj29JFG8p0rCqAXjHm+yLwiXHybxah9C1cVTI01SDeJlyXT8dbp4BfI1hFxBomgi1hOrevTpShX0f9puTCQ==)\n [INVALID SIGNATURE]\nContent:\n Method: staking.Transfer\n Body:\n To: oasis1qrydpazemvuwtnp3efm7vmfvg3tde044qg6cxwzx\n Amount: 1.0 ROSE\n Nonce: 1\n Fee:\n Amount: 0.0 ROSE\n Gas limit: 1\n (gas price: 0.0 ROSE per gas unit)\n\nNetwork: mainnet\nParaTime: none (consensus layer)\n"})}),"\n",(0,s.jsxs)(e.p,{children:["The ",(0,s.jsx)(e.code,{children:"show"})," command is also compatible with ParaTime transactions. Take the\nfollowing transaction which transfers ",(0,s.jsx)(e.code,{children:"1.0 TEST"})," from ",(0,s.jsx)(e.code,{children:"test:alice"})," to ",(0,s.jsx)(e.code,{children:"test:bob"}),"\ninside Sapphire ParaTime on the Testnet:"]}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-json",metastring:'title="testtx2.json"',children:'{\n "Body": "o2F2AWJhaaJic2mBomVub25jZQFsYWRkcmVzc19zcGVjoWlzaWduYXR1cmWhZ2VkMjU1MTlYIDXD8zVt2FNk/roDVLVFraEJ0b2zi/XWEmgX24xyz9aRY2ZlZaJjZ2FzAWZhbW91bnSCQEBkY2FsbKJkYm9keaJidG9VAMjQ9FnbOOXMMcp35m0sRFbcvrUCZmFtb3VudIJIDeC2s6dkAABAZm1ldGhvZHFhY2NvdW50cy5UcmFuc2Zlcg==",\n "AuthProofs": [\n {\n "signature": "u71xOVJhRrUth5rNTAa2HuARYCsGLmvOCRE05fCbaQiSoQhXtKPVP9feoQSXmLVxISCHr/0aNnRLEoifJLMzBQ=="\n }\n ]\n}\n'})}),"\n",(0,s.jsxs)(e.p,{children:["The Oasis CLI will be able to verify a transaction only for the ",(0,s.jsx)(e.strong,{children:"exact network\nand ParaTime combination"})," since both are used to derive the chain domain\nseparation context for signing the transaction."]}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-shell",children:"oasis transaction show testtx2.json --network testnet --paratime sapphire\n"})}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{children:"Hash: 1558a5d6254a1b216a0885fa16114899e35b27622fd5af7c8b2eee7284dcad2e\nSigner(s):\n 1. NcPzNW3YU2T+ugNUtUWtoQnRvbOL9dYSaBfbjHLP1pE=\n (signature: u71xOVJhRrUth5rNTAa2HuARYCsGLmvOCRE05fCbaQiSoQhXtKPVP9feoQSXmLVxISCHr/0aNnRLEoifJLMzBQ==)\nContent:\n Format: plain\n Method: accounts.Transfer\n Body:\n To: test:bob (oasis1qrydpazemvuwtnp3efm7vmfvg3tde044qg6cxwzx)\n Amount: 1.0 TEST\n Authorized signer(s):\n 1. NcPzNW3YU2T+ugNUtUWtoQnRvbOL9dYSaBfbjHLP1pE= (ed25519)\n Nonce: 1\n Fee:\n Amount: 0.0 TEST\n Gas limit: 1\n (gas price: 0.0 TEST per gas unit)\n\nNetwork: testnet\nParaTime: sapphire\n"})}),"\n",(0,s.jsx)(e.h2,{id:"sign",children:"Sign a Transaction"}),"\n",(0,s.jsxs)(e.p,{children:["To sign a ",(0,s.jsx)(e.a,{href:"/general/manage-tokens/cli/account#unsigned",children:"previously unsigned transaction"})," transaction or to append\nanother signature to the transaction (",(0,s.jsx)(e.em,{children:"multisig"}),"), run\n",(0,s.jsx)(e.code,{children:"transaction sign "}),"."]}),"\n",(0,s.jsxs)(e.p,{children:["For example, let's transfer ",(0,s.jsx)(e.code,{children:"1.0 TEST"})," from ",(0,s.jsx)(e.code,{children:"test:alice"})," to ",(0,s.jsx)(e.code,{children:"test:bob"})," on\nTestnet consensus layer, but don't sign it and store it to\n",(0,s.jsx)(e.code,{children:"testtx_unsigned.json"}),":"]}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-json",metastring:'title="testtx_unsigned.json"',children:'{\n "nonce": 32,\n "fee": {\n "amount": "0",\n "gas": 1265\n },\n "method": "staking.Transfer",\n "body": "omJ0b1UAyND0Wds45cwxynfmbSxEVty+tQJmYW1vdW50RDuaygA="\n}\n'})}),"\n",(0,s.jsxs)(e.p,{children:["Comparing this transaction to ",(0,s.jsx)(e.a,{href:"#show",children:(0,s.jsx)(e.code,{children:"testtx.json"})})," which was signed, we can\nnotice that the transaction is not wrapped inside the ",(0,s.jsx)(e.code,{children:"untrusted_raw_value"}),"\nenvelope with the ",(0,s.jsx)(e.code,{children:"signature"})," field."]}),"\n",(0,s.jsx)(e.p,{children:"Decoding unsigned transaction gives us similar output:"}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-shell",children:"oasis transaction show testtx_unsigned.json --network testnet\n"})}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{children:"Method: staking.Transfer\nBody:\n To: oasis1qrydpazemvuwtnp3efm7vmfvg3tde044qg6cxwzx\n Amount: 1.0 TEST\nNonce: 32\nFee:\n Amount: 0.0 TEST\n Gas limit: 1265\n (gas price: 0.0 TEST per gas unit)\n\nNetwork: testnet\nParaTime: none (consensus layer)\n"})}),"\n",(0,s.jsx)(e.p,{children:"Finally, let's sign the transaction:"}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-shell",children:"oasis transaction sign testtx_unsigned.json --network testnet --account test:alice\n"})}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{children:"You are about to sign the following transaction:\nMethod: staking.Transfer\nBody:\n To: oasis1qrydpazemvuwtnp3efm7vmfvg3tde044qg6cxwzx\n Amount: 1.0 TEST\nNonce: 47\nFee:\n Amount: 0.0 TEST\n Gas limit: 1265\n (gas price: 0.0 TEST per gas unit)\n\nNetwork: testnet\nParaTime: none (consensus layer)\nAccount: test:alice\n"})}),"\n",(0,s.jsxs)(e.p,{children:["We can also use ",(0,s.jsx)(e.a,{href:"/general/manage-tokens/cli/account#output-file",children:(0,s.jsx)(e.code,{children:"--output-file"})})," here and store the\nsigned transaction back to another file instead of showing it."]}),"\n",(0,s.jsx)(e.admonition,{type:"info",children:(0,s.jsxs)(e.p,{children:[(0,s.jsx)(e.a,{href:"/general/manage-tokens/cli/account#npa",children:"Network and Account"})," selectors are available for the ",(0,s.jsx)(e.code,{children:"transaction sign"}),"\ncommand."]})}),"\n",(0,s.jsx)(e.h2,{id:"submit",children:"Submit a Transaction"}),"\n",(0,s.jsxs)(e.p,{children:["Invoking ",(0,s.jsx)(e.code,{children:"transaction submit "})," will broadcast the consensus or\nParaTime transaction to the selected network or ParaTime. If the transaction\nhasn't been signed yet, Oasis CLI will first sign it with the selected account\nin your wallet and then broadcast it."]}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-shell",children:"oasis tx submit testtx.json --network testnet --no-paratime\n"})}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{children:"Broadcasting transaction...\nTransaction executed successfully.\nTransaction hash: a81a1dcd203bba01761a55527f2c44251278110a247e63a12f064bf41e07f13a\n"})}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-shell",children:"oasis tx submit testtx2.json --network testnet --paratime sapphire\n"})}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{children:"Broadcasting transaction...\nTransaction included in block successfully.\nRound: 946461\nTransaction hash: 25f0b2a92b6171969e9cd41d047bc20b4e2307c3a329ddef41af73df69d95b5d\n"})})]})}function h(n={}){const{wrapper:e}={...(0,a.R)(),...n.components};return e?(0,s.jsx)(e,{...n,children:(0,s.jsx)(l,{...n})}):l(n)}},8453:(n,e,t)=>{t.d(e,{R:()=>o,x:()=>r});var s=t(6540);const a={},i=s.createContext(a);function o(n){const e=s.useContext(i);return s.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function r(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(a):n.components||a:o(n.components),s.createElement(i.Provider,{value:e},n.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/8509.15e604b0.js b/assets/js/8509.15e604b0.js
new file mode 100644
index 0000000000..dbb6c1b0aa
--- /dev/null
+++ b/assets/js/8509.15e604b0.js
@@ -0,0 +1,2 @@
+/*! For license information please see 8509.15e604b0.js.LICENSE.txt */
+(self.webpackChunkdocs_oasis_io=self.webpackChunkdocs_oasis_io||[]).push([[8509],{8478:(e,t,r)=>{"use strict";r.d(t,{A:()=>i});r(6540);var n=r(2303),a=r(4848);function i(e){let{children:t,fallback:r}=e;return(0,n.A)()?(0,a.jsx)(a.Fragment,{children:t?.()}):r??null}},8157:e=>{var t;self,t=function(){return function(){var e={9288:function(e,t,r){"use strict";var n=r(3400),a={"X,X div":'direction:ltr;font-family:"Open Sans",verdana,arial,sans-serif;margin:0;padding:0;',"X input,X button":'font-family:"Open Sans",verdana,arial,sans-serif;',"X input:focus,X button:focus":"outline:none;","X a":"text-decoration:none;","X a:hover":"text-decoration:none;","X .crisp":"shape-rendering:crispEdges;","X .user-select-none":"-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;","X svg":"overflow:hidden;","X svg a":"fill:#447adb;","X svg a:hover":"fill:#3c6dc5;","X .main-svg":"position:absolute;top:0;left:0;pointer-events:none;","X .main-svg .draglayer":"pointer-events:all;","X .cursor-default":"cursor:default;","X .cursor-pointer":"cursor:pointer;","X .cursor-crosshair":"cursor:crosshair;","X .cursor-move":"cursor:move;","X .cursor-col-resize":"cursor:col-resize;","X .cursor-row-resize":"cursor:row-resize;","X .cursor-ns-resize":"cursor:ns-resize;","X .cursor-ew-resize":"cursor:ew-resize;","X .cursor-sw-resize":"cursor:sw-resize;","X .cursor-s-resize":"cursor:s-resize;","X .cursor-se-resize":"cursor:se-resize;","X .cursor-w-resize":"cursor:w-resize;","X .cursor-e-resize":"cursor:e-resize;","X .cursor-nw-resize":"cursor:nw-resize;","X .cursor-n-resize":"cursor:n-resize;","X .cursor-ne-resize":"cursor:ne-resize;","X .cursor-grab":"cursor:-webkit-grab;cursor:grab;","X .modebar":"position:absolute;top:2px;right:2px;","X .ease-bg":"-webkit-transition:background-color .3s ease 0s;-moz-transition:background-color .3s ease 0s;-ms-transition:background-color .3s ease 0s;-o-transition:background-color .3s ease 0s;transition:background-color .3s ease 0s;","X .modebar--hover>:not(.watermark)":"opacity:0;-webkit-transition:opacity .3s ease 0s;-moz-transition:opacity .3s ease 0s;-ms-transition:opacity .3s ease 0s;-o-transition:opacity .3s ease 0s;transition:opacity .3s ease 0s;","X:hover .modebar--hover .modebar-group":"opacity:1;","X .modebar-group":"float:left;display:inline-block;box-sizing:border-box;padding-left:8px;position:relative;vertical-align:middle;white-space:nowrap;","X .modebar-btn":"position:relative;font-size:16px;padding:3px 4px;height:22px;cursor:pointer;line-height:normal;box-sizing:border-box;","X .modebar-btn svg":"position:relative;top:2px;","X .modebar.vertical":"display:flex;flex-direction:column;flex-wrap:wrap;align-content:flex-end;max-height:100%;","X .modebar.vertical svg":"top:-1px;","X .modebar.vertical .modebar-group":"display:block;float:none;padding-left:0px;padding-bottom:8px;","X .modebar.vertical .modebar-group .modebar-btn":"display:block;text-align:center;","X [data-title]:before,X [data-title]:after":"position:absolute;-webkit-transform:translate3d(0, 0, 0);-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-o-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);display:none;opacity:0;z-index:1001;pointer-events:none;top:110%;right:50%;","X [data-title]:hover:before,X [data-title]:hover:after":"display:block;opacity:1;","X [data-title]:before":'content:"";position:absolute;background:rgba(0,0,0,0);border:6px solid rgba(0,0,0,0);z-index:1002;margin-top:-12px;border-bottom-color:#69738a;margin-right:-6px;',"X [data-title]:after":"content:attr(data-title);background:#69738a;color:#fff;padding:8px 10px;font-size:12px;line-height:12px;white-space:nowrap;margin-right:-18px;border-radius:2px;","X .vertical [data-title]:before,X .vertical [data-title]:after":"top:0%;right:200%;","X .vertical [data-title]:before":"border:6px solid rgba(0,0,0,0);border-left-color:#69738a;margin-top:8px;margin-right:-30px;",Y:'font-family:"Open Sans",verdana,arial,sans-serif;position:fixed;top:50px;right:20px;z-index:10000;font-size:10pt;max-width:180px;',"Y p":"margin:0;","Y .notifier-note":"min-width:180px;max-width:250px;border:1px solid #fff;z-index:3000;margin:0;background-color:#8c97af;background-color:rgba(140,151,175,.9);color:#fff;padding:10px;overflow-wrap:break-word;word-wrap:break-word;-ms-hyphens:auto;-webkit-hyphens:auto;hyphens:auto;","Y .notifier-close":"color:#fff;opacity:.8;float:right;padding:0 5px;background:none;border:none;font-size:20px;font-weight:bold;line-height:20px;","Y .notifier-close:hover":"color:#444;text-decoration:none;cursor:pointer;"};for(var i in a){var o=i.replace(/^,/," ,").replace(/X/g,".js-plotly-plot .plotly").replace(/Y/g,".plotly-notifier");n.addStyleRule(o,a[i])}},6712:function(e,t,r){"use strict";e.exports=r(1843)},7240:function(e,t,r){"use strict";e.exports=r(1132)},6144:function(e,t,r){"use strict";e.exports=r(7776)},2016:function(e,t,r){"use strict";e.exports=r(4884)},5556:function(e,t,r){"use strict";e.exports=r(6744)},6489:function(e,t,r){"use strict";e.exports=r(2028)},3472:function(e,t,r){"use strict";var n=r(2016);n.register([r(7240),r(260),r(6712),r(5556),r(6489),r(7312),r(6144)]),e.exports=n},260:function(e,t,r){"use strict";e.exports=r(5792)},7312:function(e,t,r){"use strict";e.exports=r(6272)},2196:function(e){"use strict";e.exports=[{path:"",backoff:0},{path:"M-2.4,-3V3L0.6,0Z",backoff:.6},{path:"M-3.7,-2.5V2.5L1.3,0Z",backoff:1.3},{path:"M-4.45,-3L-1.65,-0.2V0.2L-4.45,3L1.55,0Z",backoff:1.55},{path:"M-2.2,-2.2L-0.2,-0.2V0.2L-2.2,2.2L-1.4,3L1.6,0L-1.4,-3Z",backoff:1.6},{path:"M-4.4,-2.1L-0.6,-0.2V0.2L-4.4,2.1L-4,3L2,0L-4,-3Z",backoff:2},{path:"M2,0A2,2 0 1,1 0,-2A2,2 0 0,1 2,0Z",backoff:0,noRotate:!0},{path:"M2,2V-2H-2V2Z",backoff:0,noRotate:!0}]},3916:function(e,t,r){"use strict";var n=r(2196),a=r(5376),i=r(3816),o=r(1780).templatedArray;r(6208),e.exports=o("annotation",{visible:{valType:"boolean",dflt:!0,editType:"calc+arraydraw"},text:{valType:"string",editType:"calc+arraydraw"},textangle:{valType:"angle",dflt:0,editType:"calc+arraydraw"},font:a({editType:"calc+arraydraw",colorEditType:"arraydraw"}),width:{valType:"number",min:1,dflt:null,editType:"calc+arraydraw"},height:{valType:"number",min:1,dflt:null,editType:"calc+arraydraw"},opacity:{valType:"number",min:0,max:1,dflt:1,editType:"arraydraw"},align:{valType:"enumerated",values:["left","center","right"],dflt:"center",editType:"arraydraw"},valign:{valType:"enumerated",values:["top","middle","bottom"],dflt:"middle",editType:"arraydraw"},bgcolor:{valType:"color",dflt:"rgba(0,0,0,0)",editType:"arraydraw"},bordercolor:{valType:"color",dflt:"rgba(0,0,0,0)",editType:"arraydraw"},borderpad:{valType:"number",min:0,dflt:1,editType:"calc+arraydraw"},borderwidth:{valType:"number",min:0,dflt:1,editType:"calc+arraydraw"},showarrow:{valType:"boolean",dflt:!0,editType:"calc+arraydraw"},arrowcolor:{valType:"color",editType:"arraydraw"},arrowhead:{valType:"integer",min:0,max:n.length,dflt:1,editType:"arraydraw"},startarrowhead:{valType:"integer",min:0,max:n.length,dflt:1,editType:"arraydraw"},arrowside:{valType:"flaglist",flags:["end","start"],extras:["none"],dflt:"end",editType:"arraydraw"},arrowsize:{valType:"number",min:.3,dflt:1,editType:"calc+arraydraw"},startarrowsize:{valType:"number",min:.3,dflt:1,editType:"calc+arraydraw"},arrowwidth:{valType:"number",min:.1,editType:"calc+arraydraw"},standoff:{valType:"number",min:0,dflt:0,editType:"calc+arraydraw"},startstandoff:{valType:"number",min:0,dflt:0,editType:"calc+arraydraw"},ax:{valType:"any",editType:"calc+arraydraw"},ay:{valType:"any",editType:"calc+arraydraw"},axref:{valType:"enumerated",dflt:"pixel",values:["pixel",i.idRegex.x.toString()],editType:"calc"},ayref:{valType:"enumerated",dflt:"pixel",values:["pixel",i.idRegex.y.toString()],editType:"calc"},xref:{valType:"enumerated",values:["paper",i.idRegex.x.toString()],editType:"calc"},x:{valType:"any",editType:"calc+arraydraw"},xanchor:{valType:"enumerated",values:["auto","left","center","right"],dflt:"auto",editType:"calc+arraydraw"},xshift:{valType:"number",dflt:0,editType:"calc+arraydraw"},yref:{valType:"enumerated",values:["paper",i.idRegex.y.toString()],editType:"calc"},y:{valType:"any",editType:"calc+arraydraw"},yanchor:{valType:"enumerated",values:["auto","top","middle","bottom"],dflt:"auto",editType:"calc+arraydraw"},yshift:{valType:"number",dflt:0,editType:"calc+arraydraw"},clicktoshow:{valType:"enumerated",values:[!1,"onoff","onout"],dflt:!1,editType:"arraydraw"},xclick:{valType:"any",editType:"arraydraw"},yclick:{valType:"any",editType:"arraydraw"},hovertext:{valType:"string",editType:"arraydraw"},hoverlabel:{bgcolor:{valType:"color",editType:"arraydraw"},bordercolor:{valType:"color",editType:"arraydraw"},font:a({editType:"arraydraw"}),editType:"arraydraw"},captureevents:{valType:"boolean",editType:"arraydraw"},editType:"calc",_deprecated:{ref:{valType:"string",editType:"calc"}}})},272:function(e,t,r){"use strict";var n=r(3400),a=r(4460),i=r(6196).draw;function o(e){var t=e._fullLayout;n.filterVisible(t.annotations).forEach((function(t){var r=a.getFromId(e,t.xref),n=a.getFromId(e,t.yref),i=a.getRefType(t.xref),o=a.getRefType(t.yref);t._extremes={},"range"===i&&l(t,r),"range"===o&&l(t,n)}))}function l(e,t){var r,n=t._id,i=n.charAt(0),o=e[i],l=e["a"+i],s=e[i+"ref"],c=e["a"+i+"ref"],u=e["_"+i+"padplus"],f=e["_"+i+"padminus"],d={x:1,y:-1}[i]*e[i+"shift"],h=3*e.arrowsize*e.arrowwidth||0,p=h+d,v=h-d,y=3*e.startarrowsize*e.arrowwidth||0,g=y+d,m=y-d;if(c===s){var x=a.findExtremes(t,[t.r2c(o)],{ppadplus:p,ppadminus:v}),b=a.findExtremes(t,[t.r2c(l)],{ppadplus:Math.max(u,g),ppadminus:Math.max(f,m)});r={min:[x.min[0],b.min[0]],max:[x.max[0],b.max[0]]}}else g=l?g+l:g,m=l?m-l:m,r=a.findExtremes(t,[t.r2c(o)],{ppadplus:Math.max(u,p,g),ppadminus:Math.max(f,v,m)});e._extremes[n]=r}e.exports=function(e){var t=e._fullLayout;if(n.filterVisible(t.annotations).length&&e._fullData.length)return n.syncOrAsync([i,o],e)}},2300:function(e,t,r){"use strict";var n=r(3400),a=r(4040),i=r(1780).arrayEditor;function o(e,t){var r,n,a,i,o,s,c,u=e._fullLayout.annotations,f=[],d=[],h=[],p=(t||[]).length;for(r=0;r0||r.explicitOff.length>0},onClick:function(e,t){var r,l,s=o(e,t),c=s.on,u=s.off.concat(s.explicitOff),f={},d=e._fullLayout.annotations;if(c.length||u.length){for(r=0;r2/3?"right":"center"),{center:0,middle:0,left:.5,bottom:-.5,right:-.5,top:.5}[t]}for(var Z=!1,W=["x","y"],X=0;X1)&&(ne===re?((he=ae.r2fraction(t["a"+te]))<0||he>1)&&(Z=!0):Z=!0),J=ae._offset+ae.r2p(t[te]),$=.5}else{var pe="domain"===de;"x"===te?(Q=t[te],J=pe?ae._offset+ae._length*Q:J=T.l+T.w*Q):(Q=1-t[te],J=pe?ae._offset+ae._length*Q:J=T.t+T.h*Q),$=t.showarrow?.5:Q}if(t.showarrow){fe.head=J;var ve=t["a"+te];if(ee=oe*U(.5,t.xanchor)-le*U(.5,t.yanchor),ne===re){var ye=s.getRefType(ne);"domain"===ye?("y"===te&&(ve=1-ve),fe.tail=ae._offset+ae._length*ve):"paper"===ye?"y"===te?(ve=1-ve,fe.tail=T.t+T.h*ve):fe.tail=T.l+T.w*ve:fe.tail=ae._offset+ae.r2p(ve),K=ee}else fe.tail=J+ve,K=ee+ve;fe.text=fe.tail+ee;var ge=w["x"===te?"width":"height"];if("paper"===re&&(fe.head=o.constrain(fe.head,1,ge-1)),"pixel"===ne){var me=-Math.max(fe.tail-3,fe.text),xe=Math.min(fe.tail+3,fe.text)-ge;me>0?(fe.tail+=me,fe.text+=me):xe>0&&(fe.tail-=xe,fe.text-=xe)}fe.tail+=ue,fe.head+=ue}else K=ee=se*U($,ce),fe.text=J+ee;fe.text+=ue,ee+=ue,K+=ue,t["_"+te+"padplus"]=se/2+K,t["_"+te+"padminus"]=se/2-K,t["_"+te+"size"]=se,t["_"+te+"shift"]=ee}if(Z)E.remove();else{var be=0,_e=0;if("left"!==t.align&&(be=(k-b)*("center"===t.align?.5:1)),"top"!==t.valign&&(_e=(R-_)*("middle"===t.valign?.5:1)),f)n.select("svg").attr({x:H+be-1,y:H+_e}).call(u.setClipUrl,B?O:null,e);else{var we=H+_e-v.top,Te=H+be-v.left;q.call(d.positionText,Te,we).call(u.setClipUrl,B?O:null,e)}Y.select("rect").call(u.setRect,H,H,k,R),j.call(u.setRect,N/2,N/2,F-N,V-N),E.call(u.setTranslate,Math.round(D.x.text-F/2),Math.round(D.y.text-V/2)),I.attr({transform:"rotate("+C+","+D.x.text+","+D.y.text+")"});var Me,ke=function(r,n){P.selectAll(".annotation-arrow-g").remove();var s=D.x.head,f=D.y.head,d=D.x.tail+r,h=D.y.tail+n,v=D.x.text+r,b=D.y.text+n,_=o.rotationXYMatrix(C,v,b),w=o.apply2DTransform(_),k=o.apply2DTransform2(_),O=+j.attr("width"),z=+j.attr("height"),R=v-.5*O,N=R+O,F=b-.5*z,H=F+z,B=[[R,F,R,H],[R,H,N,H],[N,H,N,F],[N,F,R,F]].map(k);if(!B.reduce((function(e,t){return e^!!o.segmentsIntersect(s,f,s+1e6,f+1e6,t[0],t[1],t[2],t[3])}),!1)){B.forEach((function(e){var t=o.segmentsIntersect(d,h,s,f,e[0],e[1],e[2],e[3]);t&&(d=t.x,h=t.y)}));var Y=t.arrowwidth,V=t.arrowcolor,U=t.arrowside,q=P.append("g").style({opacity:c.opacity(V)}).classed("annotation-arrow-g",!0),G=q.append("path").attr("d","M"+d+","+h+"L"+s+","+f).style("stroke-width",Y+"px").call(c.stroke,c.rgb(V));if(y(G,U,t),M.annotationPosition&&G.node().parentNode&&!i){var Z=s,W=f;if(t.standoff){var X=Math.sqrt(Math.pow(s-d,2)+Math.pow(f-h,2));Z+=t.standoff*(d-s)/X,W+=t.standoff*(h-f)/X}var J,K,Q=q.append("path").classed("annotation-arrow",!0).classed("anndrag",!0).classed("cursor-move",!0).attr({d:"M3,3H-3V-3H3ZM0,0L"+(d-Z)+","+(h-W),transform:l(Z,W)}).style("stroke-width",Y+6+"px").call(c.stroke,"rgba(0,0,0,0)").call(c.fill,"rgba(0,0,0,0)");p.init({element:Q.node(),gd:e,prepFn:function(){var e=u.getTranslate(E);J=e.x,K=e.y,g&&g.autorange&&A(g._name+".autorange",!0),x&&x.autorange&&A(x._name+".autorange",!0)},moveFn:function(e,r){var n=w(J,K),a=n[0]+e,i=n[1]+r;E.call(u.setTranslate,a,i),L("x",m(g,e,"x",T,t)),L("y",m(x,r,"y",T,t)),t.axref===t.xref&&L("ax",m(g,e,"ax",T,t)),t.ayref===t.yref&&L("ay",m(x,r,"ay",T,t)),q.attr("transform",l(e,r)),I.attr({transform:"rotate("+C+","+a+","+i+")"})},doneFn:function(){a.call("_guiRelayout",e,S());var t=document.querySelector(".js-notes-box-panel");t&&t.redraw(t.selectedObj)}})}}};t.showarrow&&ke(0,0),z&&p.init({element:E.node(),gd:e,prepFn:function(){Me=I.attr("transform")},moveFn:function(e,r){var n="pointer";if(t.showarrow)t.axref===t.xref?L("ax",m(g,e,"ax",T,t)):L("ax",t.ax+e),t.ayref===t.yref?L("ay",m(x,r,"ay",T.w,t)):L("ay",t.ay+r),ke(e,r);else{if(i)return;var a,o;if(g)a=m(g,e,"x",T,t);else{var s=t._xsize/T.w,c=t.x+(t._xshift-t.xshift)/T.w-s/2;a=p.align(c+e/T.w,s,0,1,t.xanchor)}if(x)o=m(x,r,"y",T,t);else{var u=t._ysize/T.h,f=t.y-(t._yshift+t.yshift)/T.h-u/2;o=p.align(f-r/T.h,u,0,1,t.yanchor)}L("x",a),L("y",o),g&&x||(n=p.getCursor(g?.5:a,x?.5:o,t.xanchor,t.yanchor))}I.attr({transform:l(e,r)+Me}),h(E,n)},clickFn:function(r,n){t.captureevents&&e.emit("plotly_clickannotation",G(n))},doneFn:function(){h(E),a.call("_guiRelayout",e,S());var t=document.querySelector(".js-notes-box-panel");t&&t.redraw(t.selectedObj)}})}}}e.exports={draw:function(e){var t=e._fullLayout;t._infolayer.selectAll(".annotation").remove();for(var r=0;r=0,x=t.indexOf("end")>=0,b=p.backoff*y+r.standoff,_=v.backoff*g+r.startstandoff;if("line"===h.nodeName){o={x:+e.attr("x1"),y:+e.attr("y1")},u={x:+e.attr("x2"),y:+e.attr("y2")};var w=o.x-u.x,T=o.y-u.y;if(d=(f=Math.atan2(T,w))+Math.PI,b&&_&&b+_>Math.sqrt(w*w+T*T))return void z();if(b){if(b*b>w*w+T*T)return void z();var M=b*Math.cos(f),k=b*Math.sin(f);u.x+=M,u.y+=k,e.attr({x2:u.x,y2:u.y})}if(_){if(_*_>w*w+T*T)return void z();var A=_*Math.cos(f),L=_*Math.sin(f);o.x-=A,o.y-=L,e.attr({x1:o.x,y1:o.y})}}else if("path"===h.nodeName){var S=h.getTotalLength(),O="";if(S1){c=!0;break}}c?e.fullLayout._infolayer.select(".annotation-"+e.id+'[data-index="'+l+'"]').remove():(s._pdata=a(e.glplot.cameraParams,[t.xaxis.r2l(s.x)*r[0],t.yaxis.r2l(s.y)*r[1],t.zaxis.r2l(s.z)*r[2]]),n(e.graphDiv,s,l,e.id,s._xa,s._ya))}}},6864:function(e,t,r){"use strict";var n=r(4040),a=r(3400);e.exports={moduleType:"component",name:"annotations3d",schema:{subplots:{scene:{annotations:r(5899)}}},layoutAttributes:r(5899),handleDefaults:r(2808),includeBasePlot:function(e,t){var r=n.subplotsRegistry.gl3d;if(r)for(var i=r.attrRegex,o=Object.keys(e),l=0;l=0))return e;if(3===o)n[o]>1&&(n[o]=1);else if(n[o]>=1)return e}var l=Math.round(255*n[0])+", "+Math.round(255*n[1])+", "+Math.round(255*n[2]);return i?"rgba("+l+", "+n[3]+")":"rgb("+l+")"}o.tinyRGB=function(e){var t=e.toRgb();return"rgb("+Math.round(t.r)+", "+Math.round(t.g)+", "+Math.round(t.b)+")"},o.rgb=function(e){return o.tinyRGB(n(e))},o.opacity=function(e){return e?n(e).getAlpha():0},o.addOpacity=function(e,t){var r=n(e).toRgb();return"rgba("+Math.round(r.r)+", "+Math.round(r.g)+", "+Math.round(r.b)+", "+t+")"},o.combine=function(e,t){var r=n(e).toRgb();if(1===r.a)return n(e).toRgbString();var a=n(t||c).toRgb(),i=1===a.a?a:{r:255*(1-a.a)+a.r*a.a,g:255*(1-a.a)+a.g*a.a,b:255*(1-a.a)+a.b*a.a},o={r:i.r*(1-r.a)+r.r*r.a,g:i.g*(1-r.a)+r.g*r.a,b:i.b*(1-r.a)+r.b*r.a};return n(o).toRgbString()},o.interpolate=function(e,t,r){var a=n(e).toRgb(),i=n(t).toRgb(),o={r:r*a.r+(1-r)*i.r,g:r*a.g+(1-r)*i.g,b:r*a.b+(1-r)*i.b};return n(o).toRgbString()},o.contrast=function(e,t,r){var a=n(e);return 1!==a.getAlpha()&&(a=n(o.combine(e,c))),(a.isDark()?t?a.lighten(t):c:r?a.darken(r):s).toString()},o.stroke=function(e,t){var r=n(t);e.style({stroke:o.tinyRGB(r),"stroke-opacity":r.getAlpha()})},o.fill=function(e,t){var r=n(t);e.style({fill:o.tinyRGB(r),"fill-opacity":r.getAlpha()})},o.clean=function(e){if(e&&"object"==typeof e){var t,r,n,a,l=Object.keys(e);for(t=0;t0?n>=s:n<=s));a++)n>u&&n0?n>=s:n<=s));a++)n>r[0]&&n1){var he=Math.pow(10,Math.floor(Math.log(de)/Math.LN10));ue*=he*c.roundUp(de/he,[2,5,10]),(Math.abs(G.start)/G.size+1e-6)%1<2e-6&&(se.tick0=0)}se.dtick=ue}se.domain=o?[oe+P/F.h,oe+$-P/F.h]:[oe+C/F.w,oe+$-C/F.w],se.setScale(),e.attr("transform",u(Math.round(F.l),Math.round(F.t)));var pe,ve=e.select("."+k.cbtitleunshift).attr("transform",u(-Math.round(F.l),-Math.round(F.t))),ye=se.ticklabelposition,ge=se.title.font.size,me=e.select("."+k.cbaxis),xe=0,be=0;function _e(n,a){var i={propContainer:se,propName:t._propPrefix+"title",traceIndex:t._traceIndex,_meta:t._meta,placeholder:N._dfltTitle.colorbar,containerGroup:e.select("."+k.cbtitle)},o="h"===n.charAt(0)?n.substr(1):"h"+n;e.selectAll("."+o+",."+o+"-math-group").remove(),v.draw(r,n,f(i,a||{}))}function we(){var e,t;(o&&ce||!o&&!ce)&&("top"===Y&&(e=C+F.l+ee*I,t=P+F.t+te*(1-oe-$)+3+.75*ge),"bottom"===Y&&(e=C+F.l+ee*I,t=P+F.t+te*(1-oe)-3-.25*ge),"right"===Y&&(t=P+F.t+te*z+3+.75*ge,e=C+F.l+ee*oe),_e(se._id+"title",{attributes:{x:e,y:t,"text-anchor":o?"start":"middle"}}))}function Te(){if(o&&!ce||!o&&ce){var e,a,i=se.position||0,l=se._offset+se._length/2;if("right"===Y)a=l,e=F.l+ee*i+10+ge*(se.showticklabels?1:.5);else if(e=l,"bottom"===Y&&(a=F.t+te*i+10+(-1===ye.indexOf("inside")?se.tickfont.size:0)+("intside"!==se.ticks&&t.ticklen||0)),"top"===Y){var s=B.text.split("
").length;a=F.t+te*i+10-J-w*ge*s}_e((o?"h":"v")+se._id+"title",{avoid:{selection:n.select(r).selectAll("g."+se._id+"tick"),side:Y,offsetTop:o?0:F.t,offsetLeft:o?F.l:0,maxShift:o?N.width:N.height},attributes:{x:e,y:a,"text-anchor":"middle"},transform:{rotate:o?-90:0,offset:0}})}}function Me(){if(!o&&!ce||o&&ce){var i,s=e.select("."+k.cbtitle),f=s.select("text"),d=[-A/2,A/2],p=s.select(".h"+se._id+"title-math-group").node(),v=15.6;if(f.node()&&(v=parseInt(f.node().style.fontSize,10)*w),p?(i=h.bBox(p),be=i.width,(xe=i.height)>v&&(d[1]-=(xe-v)/2)):f.node()&&!f.classed(k.jsPlaceholder)&&(i=h.bBox(f.node()),be=i.width,xe=i.height),o){if(xe){if(xe+=5,"top"===Y)se.domain[1]-=xe/F.h,d[1]*=-1;else{se.domain[0]+=xe/F.h;var g=y.lineCount(f);d[1]+=(1-g)*v}s.attr("transform",u(d[0],d[1])),se.setScale()}}else be&&("right"===Y&&(se.domain[0]+=(be+ge/2)/F.w),s.attr("transform",u(d[0],d[1])),se.setScale())}e.selectAll("."+k.cbfills+",."+k.cblines).attr("transform",o?u(0,Math.round(F.h*(1-se.domain[1]))):u(Math.round(F.w*se.domain[0]),0)),me.attr("transform",o?u(0,Math.round(-F.t)):u(Math.round(-F.l),0));var m=e.select("."+k.cbfills).selectAll("rect."+k.cbfill).attr("style","").data(W);m.enter().append("rect").classed(k.cbfill,!0).attr("style",""),m.exit().remove();var x=V.map(se.c2p).map(Math.round).sort((function(e,t){return e-t}));m.each((function(e,i){var l=[0===i?V[0]:(W[i]+W[i-1])/2,i===W.length-1?V[1]:(W[i]+W[i+1])/2].map(se.c2p).map(Math.round);o&&(l[1]=c.constrain(l[1]+(l[1]>l[0])?1:-1,x[0],x[1]));var s=n.select(this).attr(o?"x":"y",re).attr(o?"y":"x",n.min(l)).attr(o?"width":"height",Math.max(J,2)).attr(o?"height":"width",Math.max(n.max(l)-n.min(l),2));if(t._fillgradient)h.gradient(s,r,t._id,o?"vertical":"horizontalreversed",t._fillgradient,"fill");else{var u=q(e).replace("e-","");s.attr("fill",a(u).toHexString())}}));var b=e.select("."+k.cblines).selectAll("path."+k.cbline).data(j.color&&j.width?X:[]);b.enter().append("path").classed(k.cbline,!0),b.exit().remove(),b.each((function(e){var t=re,r=Math.round(se.c2p(e))+j.width/2%1;n.select(this).attr("d","M"+(o?t+","+r:r+","+t)+(o?"h":"v")+J).call(h.lineGroupStyle,j.width,U(e),j.dash)})),me.selectAll("g."+se._id+"tick,path").remove();var _=re+J+(A||0)/2-("outside"===t.ticks?1:0),T=l.calcTicks(se),M=l.getTickSigns(se)[2];return l.drawTicks(r,se,{vals:"inside"===se.ticks?l.clipEnds(se,T):T,layer:me,path:l.makeTickPath(se,_,M),transFn:l.makeTransTickFn(se)}),l.drawLabels(r,se,{vals:T,layer:me,transFn:l.makeTransTickLabelFn(se),labelFns:l.makeLabelFns(se,_)})}function ke(){var n,l=J+A/2;-1===ye.indexOf("inside")&&(n=h.bBox(me.node()),l+=o?n.width:n.height),pe=ve.select("text");var c=0,f=o&&"top"===Y,v=!o&&"right"===Y,y=0;if(pe.node()&&!pe.classed(k.jsPlaceholder)){var m,x=ve.select(".h"+se._id+"title-math-group").node();x&&(o&&ce||!o&&!ce)?(c=(n=h.bBox(x)).width,m=n.height):(c=(n=h.bBox(ve.node())).right-F.l-(o?re:le),m=n.bottom-F.t-(o?le:re),o||"top"!==Y||(l+=n.height,y=n.height)),v&&(pe.attr("transform",u(c/2+ge/2,0)),c*=2),l=Math.max(l,o?c:m)}var b=2*(o?C:P)+l+L+A/2,w=0;!o&&B.text&&"bottom"===D&&z<=0&&(b+=w=b/2,y+=w),N._hColorbarMoveTitle=w,N._hColorbarMoveCBTitle=y;var H=L+A,j=(o?re:le)-H/2-(o?C:0),V=(o?le:re)-(o?Q:P+y-w);e.select("."+k.cbbg).attr("x",j).attr("y",V).attr(o?"width":"height",Math.max(b-w,2)).attr(o?"height":"width",Math.max(Q+H,2)).call(p.fill,S).call(p.stroke,t.bordercolor).style("stroke-width",L);var U=v?Math.max(c-10,0):0;e.selectAll("."+k.cboutline).attr("x",(o?re:le+C)+U).attr("y",(o?le+P-Q:re)+(f?xe:0)).attr(o?"width":"height",Math.max(J,2)).attr(o?"height":"width",Math.max(Q-(o?2*P+xe:2*C+U),2)).call(p.stroke,t.outlinecolor).style({fill:"none","stroke-width":A});var q=o?ne*b:0,G=o?0:(1-ae)*b-y;if(q=E?F.l-q:-q,G=R?F.t-G:-G,e.attr("transform",u(q,G)),!o&&(L||a(S).getAlpha()&&!a.equals(N.paper_bgcolor,S))){var Z=me.selectAll("text"),W=Z[0].length,X=e.select("."+k.cbbg).node(),K=h.bBox(X),$=h.getTranslate(e),ee=2;Z.each((function(e,t){var r=0,n=W-1;if(t===r||t===n){var a,i=h.bBox(this),o=h.getTranslate(this);if(t===n){var l=i.right+o.x;(a=K.right+$.x+le-L-ee+I-l)>0&&(a=0)}else if(t===r){var s=i.left+o.x;(a=K.left+$.x+le+L+ee-s)<0&&(a=0)}a&&(W<3?this.setAttribute("transform","translate("+a+",0) "+this.getAttribute("transform")):this.setAttribute("visibility","hidden"))}}))}var te={},ie=T[O],oe=M[O],ue=T[D],fe=M[D],de=b-J;o?("pixels"===d?(te.y=z,te.t=Q*ue,te.b=Q*fe):(te.t=te.b=0,te.yt=z+s*ue,te.yb=z-s*fe),"pixels"===_?(te.x=I,te.l=b*ie,te.r=b*oe):(te.l=de*ie,te.r=de*oe,te.xl=I-g*ie,te.xr=I+g*oe)):("pixels"===d?(te.x=I,te.l=Q*ie,te.r=Q*oe):(te.l=te.r=0,te.xl=I+s*ie,te.xr=I-s*oe),"pixels"===_?(te.y=1-z,te.t=b*ue,te.b=b*fe):(te.t=de*ue,te.b=de*fe,te.yt=z-g*ue,te.yb=z+g*fe));var he=t.y<.5?"b":"t",be=t.x<.5?"l":"r";r._fullLayout._reservedMargin[t._id]={};var _e={r:N.width-j-q,l:j+te.r,b:N.height-V-G,t:V+te.b};E&&R?i.autoMargin(r,t._id,te):E?r._fullLayout._reservedMargin[t._id][he]=_e[he]:R||o?r._fullLayout._reservedMargin[t._id][be]=_e[be]:r._fullLayout._reservedMargin[t._id][he]=_e[he]}return c.syncOrAsync([i.previousPromises,we,Me,Te,i.previousPromises,ke],r)}(r,t,e);g&&g.then&&(e._promises||[]).push(g),e._context.edits.colorbarPosition&&function(e,t,r){var n,a,i,l="v"===t.orientation,c=r._fullLayout,f=c._size;s.init({element:e.node(),gd:r,prepFn:function(){n=e.attr("transform"),d(e)},moveFn:function(r,o){e.attr("transform",n+u(r,o)),a=s.align((l?t._uFrac:t._vFrac)+r/f.w,l?t._thickFrac:t._lenFrac,0,1,t.xanchor),i=s.align((l?t._vFrac:1-t._uFrac)-o/f.h,l?t._lenFrac:t._thickFrac,0,1,t.yanchor);var c=s.getCursor(a,i,t.xanchor,t.yanchor);d(e,c)},doneFn:function(){if(d(e),void 0!==a&&void 0!==i){var n={};n[t._propPrefix+"x"]=a,n[t._propPrefix+"y"]=i,void 0!==t._traceIndex?o.call("_guiRestyle",r,n,t._traceIndex):o.call("_guiRelayout",r,n)}}})}(r,t,e)})),t.exit().each((function(t){i.autoMargin(e,t._id)})).remove(),t.order()}}},553:function(e,t,r){"use strict";var n=r(3400);e.exports=function(e){return n.isPlainObject(e.colorbar)}},5080:function(e,t,r){"use strict";e.exports={moduleType:"component",name:"colorbar",attributes:r(616),supplyDefaults:r(4013),draw:r(7848).draw,hasColorbar:r(553)}},9084:function(e,t,r){"use strict";var n=r(616),a=r(3756).counter,i=r(2996),o=r(8304).scales;function l(e){return"`"+e+"`"}i(o),e.exports=function(e,t){e=e||"";var r,i=(t=t||{}).cLetter||"c",s=("onlyIfNumerical"in t?t.onlyIfNumerical:Boolean(e),"noScale"in t?t.noScale:"marker.line"===e),c="showScaleDflt"in t?t.showScaleDflt:"z"===i,u="string"==typeof t.colorscaleDflt?o[t.colorscaleDflt]:null,f=t.editTypeOverride||"",d=e?e+".":"";"colorAttr"in t?(r=t.colorAttr,t.colorAttr):l(d+(r={z:"z",c:"color"}[i]));var h=i+"auto",p=i+"min",v=i+"max",y=i+"mid",g=(l(d+h),l(d+p),l(d+v),{});g[p]=g[v]=void 0;var m={};m[h]=!1;var x={};return"color"===r&&(x.color={valType:"color",arrayOk:!0,editType:f||"style"},t.anim&&(x.color.anim=!0)),x[h]={valType:"boolean",dflt:!0,editType:"calc",impliedEdits:g},x[p]={valType:"number",dflt:null,editType:f||"plot",impliedEdits:m},x[v]={valType:"number",dflt:null,editType:f||"plot",impliedEdits:m},x[y]={valType:"number",dflt:null,editType:"calc",impliedEdits:g},x.colorscale={valType:"colorscale",editType:"calc",dflt:u,impliedEdits:{autocolorscale:!1}},x.autocolorscale={valType:"boolean",dflt:!1!==t.autoColorDflt,editType:"calc",impliedEdits:{colorscale:void 0}},x.reversescale={valType:"boolean",dflt:!1,editType:"plot"},s||(x.showscale={valType:"boolean",dflt:c,editType:"calc"},x.colorbar=n),t.noColorAxis||(x.coloraxis={valType:"subplotid",regex:a("coloraxis"),dflt:null,editType:"calc"}),x}},7128:function(e,t,r){"use strict";var n=r(8248),a=r(3400),i=r(4288).extractOpts;e.exports=function(e,t,r){var o,l=e._fullLayout,s=r.vals,c=r.containerStr,u=c?a.nestedProperty(t,c).get():t,f=i(u),d=!1!==f.auto,h=f.min,p=f.max,v=f.mid,y=function(){return a.aggNums(Math.min,null,s)},g=function(){return a.aggNums(Math.max,null,s)};void 0===h?h=y():d&&(h=u._colorAx&&n(h)?Math.min(h,y()):y()),void 0===p?p=g():d&&(p=u._colorAx&&n(p)?Math.max(p,g()):g()),d&&void 0!==v&&(p-v>v-h?h=v-(p-v):p-v=0?l.colorscale.sequential:l.colorscale.sequentialminus,f._sync("colorscale",o))}},5504:function(e,t,r){"use strict";var n=r(3400),a=r(4288).hasColorscale,i=r(4288).extractOpts;e.exports=function(e,t){function r(e,t){var r=e["_"+t];void 0!==r&&(e[t]=r)}function o(e,a){var o=a.container?n.nestedProperty(e,a.container).get():e;if(o)if(o.coloraxis)o._colorAx=t[o.coloraxis];else{var l=i(o),s=l.auto;(s||void 0===l.min)&&r(o,a.min),(s||void 0===l.max)&&r(o,a.max),l.autocolorscale&&r(o,"colorscale")}}for(var l=0;l=0;n--,a++){var i=e[n];r[a]=[1-i[0],i[1]]}return r}function p(e,t){t=t||{};for(var r=e.domain,o=e.range,s=o.length,c=new Array(s),u=0;u4/3-l?o:l}},7416:function(e,t,r){"use strict";var n=r(3400),a=[["sw-resize","s-resize","se-resize"],["w-resize","move","e-resize"],["nw-resize","n-resize","ne-resize"]];e.exports=function(e,t,r,i){return e="left"===r?0:"center"===r?1:"right"===r?2:n.constrain(Math.floor(3*e),0,2),t="bottom"===i?0:"middle"===i?1:"top"===i?2:n.constrain(Math.floor(3*t),0,2),a[t][e]}},2760:function(e,t){"use strict";t.selectMode=function(e){return"lasso"===e||"select"===e},t.drawMode=function(e){return"drawclosedpath"===e||"drawopenpath"===e||"drawline"===e||"drawrect"===e||"drawcircle"===e},t.openMode=function(e){return"drawline"===e||"drawopenpath"===e},t.rectMode=function(e){return"select"===e||"drawline"===e||"drawrect"===e||"drawcircle"===e},t.freeMode=function(e){return"lasso"===e||"drawclosedpath"===e||"drawopenpath"===e},t.selectingOrDrawing=function(e){return t.freeMode(e)||t.rectMode(e)}},6476:function(e,t,r){"use strict";var n=r(9128),a=r(2264),i=r(9184),o=r(3400).removeElement,l=r(3816),s=e.exports={};s.align=r(8316),s.getCursor=r(7416);var c=r(2616);function u(){var e=document.createElement("div");e.className="dragcover";var t=e.style;return t.position="fixed",t.left=0,t.right=0,t.top=0,t.bottom=0,t.zIndex=999999999,t.background="none",document.body.appendChild(e),e}function f(e){return n(e.changedTouches?e.changedTouches[0]:e,document.body)}s.unhover=c.wrapped,s.unhoverRaw=c.raw,s.init=function(e){var t,r,n,c,d,h,p,v,y=e.gd,g=1,m=y._context.doubleClickDelay,x=e.element;y._mouseDownTime||(y._mouseDownTime=0),x.style.pointerEvents="all",x.onmousedown=_,i?(x._ontouchstart&&x.removeEventListener("touchstart",x._ontouchstart),x._ontouchstart=_,x.addEventListener("touchstart",_,{passive:!1})):x.ontouchstart=_;var b=e.clampFn||function(e,t,r){return Math.abs(e)m&&(g=Math.max(g-1,1)),y._dragged)e.doneFn&&e.doneFn();else if(e.clickFn&&e.clickFn(g,h),!v){var r;try{r=new MouseEvent("click",t)}catch(i){var n=f(t);(r=document.createEvent("MouseEvents")).initMouseEvent("click",t.bubbles,t.cancelable,t.view,t.detail,t.screenX,t.screenY,n[0],n[1],t.ctrlKey,t.altKey,t.shiftKey,t.metaKey,t.button,t.relatedTarget)}p.dispatchEvent(r)}y._dragging=!1,y._dragged=!1}else y._dragged=!1}},s.coverSlip=u},2616:function(e,t,r){"use strict";var n=r(5924),a=r(1200),i=r(2200).getGraphDiv,o=r(2456),l=e.exports={};l.wrapped=function(e,t,r){(e=i(e))._fullLayout&&a.clear(e._fullLayout._uid+o.HOVERID),l.raw(e,t,r)},l.raw=function(e,t){var r=e._fullLayout,a=e._hoverdata;t||(t={}),t.target&&!e._dragged&&!1===n.triggerHandler(e,"plotly_beforehover",t)||(r._hoverlayer.selectAll("g").remove(),r._hoverlayer.selectAll("line").remove(),r._hoverlayer.selectAll("circle").remove(),e._hoverdata=void 0,t.target&&a&&e.emit("plotly_unhover",{event:t,points:a}))}},8192:function(e,t){"use strict";t.u={valType:"string",values:["solid","dot","dash","longdash","dashdot","longdashdot"],dflt:"solid",editType:"style"},t.c={shape:{valType:"enumerated",values:["","/","\\","x","-","|","+","."],dflt:"",arrayOk:!0,editType:"style"},fillmode:{valType:"enumerated",values:["replace","overlay"],dflt:"replace",editType:"style"},bgcolor:{valType:"color",arrayOk:!0,editType:"style"},fgcolor:{valType:"color",arrayOk:!0,editType:"style"},fgopacity:{valType:"number",editType:"style",min:0,max:1},size:{valType:"number",min:0,dflt:8,arrayOk:!0,editType:"style"},solidity:{valType:"number",min:0,max:1,dflt:.3,arrayOk:!0,editType:"style"},editType:"style"}},3616:function(e,t,r){"use strict";var n=r(3428),a=r(3400),i=a.numberFormat,o=r(8248),l=r(9760),s=r(4040),c=r(6308),u=r(8932),f=a.strTranslate,d=r(2736),h=r(9616),p=r(4284).LINE_SPACING,v=r(3448).DESELECTDIM,y=r(3028),g=r(7152),m=r(624).appendArrayPointValue,x=e.exports={};function b(e,t,r,n){var a=t.fillpattern,i=t.fillgradient,o=a&&x.getPatternAttr(a.shape,0,"");if(o){var l=x.getPatternAttr(a.bgcolor,0,null),s=x.getPatternAttr(a.fgcolor,0,null),u=a.fgopacity,f=x.getPatternAttr(a.size,0,8),d=x.getPatternAttr(a.solidity,0,.3),h=t.uid;x.pattern(e,"point",r,h,o,f,d,void 0,a.fillmode,l,s,u)}else if(i&&"none"!==i.type){var p,v,y=i.type,g="scatterfill-"+t.uid;n&&(g="legendfill-"+t.uid),n||void 0===i.start&&void 0===i.stop?("horizontal"===y&&(y+="reversed"),e.call(x.gradient,r,g,y,i.colorscale,"fill")):("horizontal"===y?(p={x:i.start,y:0},v={x:i.stop,y:0}):"vertical"===y&&(p={x:0,y:i.start},v={x:0,y:i.stop}),p.x=t._xA.c2p(void 0===p.x?t._extremes.x.min[0].val:p.x,!0),p.y=t._yA.c2p(void 0===p.y?t._extremes.y.min[0].val:p.y,!0),v.x=t._xA.c2p(void 0===v.x?t._extremes.x.max[0].val:v.x,!0),v.y=t._yA.c2p(void 0===v.y?t._extremes.y.max[0].val:v.y,!0),e.call(A,r,g,"linear",i.colorscale,"fill",p,v,!0,!1))}else t.fillcolor&&e.call(c.fill,t.fillcolor)}x.font=function(e,t,r,n,i,o,l){a.isPlainObject(t)&&(l=t.variant,o=t.style,i=t.weight,n=t.color,r=t.size,t=t.family),t&&e.style("font-family",t),r+1&&e.style("font-size",r+"px"),n&&e.call(c.fill,n),i&&e.style("font-weight",i),o&&e.style("font-style",o),l&&e.style("font-variant",l)},x.setPosition=function(e,t,r){e.attr("x",t).attr("y",r)},x.setSize=function(e,t,r){e.attr("width",t).attr("height",r)},x.setRect=function(e,t,r,n,a){e.call(x.setPosition,t,r).call(x.setSize,n,a)},x.translatePoint=function(e,t,r,n){var a=r.c2p(e.x),i=n.c2p(e.y);return!!(o(a)&&o(i)&&t.node())&&("text"===t.node().nodeName?t.attr("x",a).attr("y",i):t.attr("transform",f(a,i)),!0)},x.translatePoints=function(e,t,r){e.each((function(e){var a=n.select(this);x.translatePoint(e,a,t,r)}))},x.hideOutsideRangePoint=function(e,t,r,n,a,i){t.attr("display",r.isPtWithinRange(e,a)&&n.isPtWithinRange(e,i)?null:"none")},x.hideOutsideRangePoints=function(e,t){if(t._hasClipOnAxisFalse){var r=t.xaxis,a=t.yaxis;e.each((function(t){var i=t[0].trace,o=i.xcalendar,l=i.ycalendar,c=s.traceIs(i,"bar-like")?".bartext":".point,.textpoint";e.selectAll(c).each((function(e){x.hideOutsideRangePoint(e,n.select(this),r,a,o,l)}))}))}},x.crispRound=function(e,t,r){return t&&o(t)?e._context.staticPlot?t:t<1?1:Math.round(t):r||0},x.singleLineStyle=function(e,t,r,n,a){t.style("fill","none");var i=(((e||[])[0]||{}).trace||{}).line||{},o=r||i.width||0,l=a||i.dash||"";c.stroke(t,n||i.color),x.dashLine(t,l,o)},x.lineGroupStyle=function(e,t,r,a){e.style("fill","none").each((function(e){var i=(((e||[])[0]||{}).trace||{}).line||{},o=t||i.width||0,l=a||i.dash||"";n.select(this).call(c.stroke,r||i.color).call(x.dashLine,l,o)}))},x.dashLine=function(e,t,r){r=+r||0,t=x.dashStyle(t,r),e.style({"stroke-dasharray":t,"stroke-width":r+"px"})},x.dashStyle=function(e,t){t=+t||1;var r=Math.max(t,3);return"solid"===e?e="":"dot"===e?e=r+"px,"+r+"px":"dash"===e?e=3*r+"px,"+3*r+"px":"longdash"===e?e=5*r+"px,"+5*r+"px":"dashdot"===e?e=3*r+"px,"+r+"px,"+r+"px,"+r+"px":"longdashdot"===e&&(e=5*r+"px,"+2*r+"px,"+r+"px,"+2*r+"px"),e},x.singleFillStyle=function(e,t){var r=n.select(e.node());b(e,((r.data()[0]||[])[0]||{}).trace||{},t,!1)},x.fillGroupStyle=function(e,t,r){e.style("stroke-width",0).each((function(e){var a=n.select(this);e[0].trace&&b(a,e[0].trace,t,r)}))};var _=r(1984);x.symbolNames=[],x.symbolFuncs=[],x.symbolBackOffs=[],x.symbolNeedLines={},x.symbolNoDot={},x.symbolNoFill={},x.symbolList=[],Object.keys(_).forEach((function(e){var t=_[e],r=t.n;x.symbolList.push(r,String(r),e,r+100,String(r+100),e+"-open"),x.symbolNames[r]=e,x.symbolFuncs[r]=t.f,x.symbolBackOffs[r]=t.backoff||0,t.needLine&&(x.symbolNeedLines[r]=!0),t.noDot?x.symbolNoDot[r]=!0:x.symbolList.push(r+200,String(r+200),e+"-dot",r+300,String(r+300),e+"-open-dot"),t.noFill&&(x.symbolNoFill[r]=!0)}));var w=x.symbolNames.length;function T(e,t,r,n){var a=e%100;return x.symbolFuncs[a](t,r,n)+(e>=200?"M0,0.5L0.5,0L0,-0.5L-0.5,0Z":"")}x.symbolNumber=function(e){if(o(e))e=+e;else if("string"==typeof e){var t=0;e.indexOf("-open")>0&&(t=100,e=e.replace("-open","")),e.indexOf("-dot")>0&&(t+=200,e=e.replace("-dot","")),(e=x.symbolNames.indexOf(e))>=0&&(e+=t)}return e%100>=w||e>=400?0:Math.floor(Math.max(e,0))};var M=i("~f"),k={radial:{type:"radial"},radialreversed:{type:"radial",reversed:!0},horizontal:{type:"linear",start:{x:1,y:0},stop:{x:0,y:0}},horizontalreversed:{type:"linear",start:{x:1,y:0},stop:{x:0,y:0},reversed:!0},vertical:{type:"linear",start:{x:0,y:1},stop:{x:0,y:0}},verticalreversed:{type:"linear",start:{x:0,y:1},stop:{x:0,y:0},reversed:!0}};function A(e,t,r,i,o,s,u,f,d,h){var p,v=o.length;"linear"===i?p={node:"linearGradient",attrs:{x1:u.x,y1:u.y,x2:f.x,y2:f.y,gradientUnits:d?"userSpaceOnUse":"objectBoundingBox"},reversed:h}:"radial"===i&&(p={node:"radialGradient",reversed:h});for(var y=new Array(v),g=0;g=0&&void 0===e.i&&(e.i=o.i),t.style("opacity",n.selectedOpacityFn?n.selectedOpacityFn(e):void 0===e.mo?l.opacity:e.mo),n.ms2mrc){var u;u="various"===e.ms||"various"===l.size?3:n.ms2mrc(e.ms),e.mrc=u,n.selectedSizeFn&&(u=e.mrc=n.selectedSizeFn(e));var f=x.symbolNumber(e.mx||l.symbol)||0;e.om=f%200>=100;var d=te(e,r),h=U(e,r);t.attr("d",T(f,u,d,h))}var p,v,y,g=!1;if(e.so)y=s.outlierwidth,v=s.outliercolor,p=l.outliercolor;else{var m=(s||{}).width;y=(e.mlw+1||m+1||(e.trace?(e.trace.marker.line||{}).width:0)+1)-1||0,v="mlc"in e?e.mlcc=n.lineScale(e.mlc):a.isArrayOrTypedArray(s.color)?c.defaultLine:s.color,a.isArrayOrTypedArray(l.color)&&(p=c.defaultLine,g=!0),p="mc"in e?e.mcc=n.markerScale(e.mc):l.color||l.colors||"rgba(0,0,0,0)",n.selectedColorFn&&(p=n.selectedColorFn(e))}if(e.om)t.call(c.stroke,p).style({"stroke-width":(y||1)+"px",fill:"none"});else{t.style("stroke-width",(e.isBlank?0:y)+"px");var b=l.gradient,_=e.mgt;_?g=!0:_=b&&b.type,a.isArrayOrTypedArray(_)&&(_=_[0],k[_]||(_=0));var w=l.pattern,M=w&&x.getPatternAttr(w.shape,e.i,"");if(_&&"none"!==_){var A=e.mgc;A?g=!0:A=b.color;var L=r.uid;g&&(L+="-"+e.i),x.gradient(t,i,L,_,[[0,A],[1,p]],"fill")}else if(M){var S=!1,O=w.fgcolor;!O&&o&&o.color&&(O=o.color,S=!0);var D=x.getPatternAttr(O,e.i,o&&o.color||null),C=x.getPatternAttr(w.bgcolor,e.i,null),P=w.fgopacity,I=x.getPatternAttr(w.size,e.i,8),z=x.getPatternAttr(w.solidity,e.i,.3);S=S||e.mcc||a.isArrayOrTypedArray(w.shape)||a.isArrayOrTypedArray(w.bgcolor)||a.isArrayOrTypedArray(w.fgcolor)||a.isArrayOrTypedArray(w.size)||a.isArrayOrTypedArray(w.solidity);var R=r.uid;S&&(R+="-"+e.i),x.pattern(t,"point",i,R,M,I,z,e.mcc,w.fillmode,C,D,P)}else a.isArrayOrTypedArray(p)?c.fill(t,p[e.i]):c.fill(t,p);y&&c.stroke(t,v)}},x.makePointStyleFns=function(e){var t={},r=e.marker;return t.markerScale=x.tryColorscale(r,""),t.lineScale=x.tryColorscale(r,"line"),s.traceIs(e,"symbols")&&(t.ms2mrc=y.isBubble(e)?g(e):function(){return(r.size||6)/2}),e.selectedpoints&&a.extendFlat(t,x.makeSelectedPointStyleFns(e)),t},x.makeSelectedPointStyleFns=function(e){var t={},r=e.selected||{},n=e.unselected||{},i=e.marker||{},o=r.marker||{},l=n.marker||{},c=i.opacity,u=o.opacity,f=l.opacity,d=void 0!==u,h=void 0!==f;(a.isArrayOrTypedArray(c)||d||h)&&(t.selectedOpacityFn=function(e){var t=void 0===e.mo?i.opacity:e.mo;return e.selected?d?u:t:h?f:v*t});var p=i.color,y=o.color,g=l.color;(y||g)&&(t.selectedColorFn=function(e){var t=e.mcc||p;return e.selected?y||t:g||t});var m=i.size,x=o.size,b=l.size,_=void 0!==x,w=void 0!==b;return s.traceIs(e,"symbols")&&(_||w)&&(t.selectedSizeFn=function(e){var t=e.mrc||m/2;return e.selected?_?x/2:t:w?b/2:t}),t},x.makeSelectedTextStyleFns=function(e){var t={},r=e.selected||{},n=e.unselected||{},a=e.textfont||{},i=r.textfont||{},o=n.textfont||{},l=a.color,s=i.color,u=o.color;return t.selectedTextColorFn=function(e){var t=e.tc||l;return e.selected?s||t:u||(s?t:c.addOpacity(t,v))},t},x.selectedPointStyle=function(e,t){if(e.size()&&t.selectedpoints){var r=x.makeSelectedPointStyleFns(t),a=t.marker||{},i=[];r.selectedOpacityFn&&i.push((function(e,t){e.style("opacity",r.selectedOpacityFn(t))})),r.selectedColorFn&&i.push((function(e,t){c.fill(e,r.selectedColorFn(t))})),r.selectedSizeFn&&i.push((function(e,n){var i=n.mx||a.symbol||0,o=r.selectedSizeFn(n);e.attr("d",T(x.symbolNumber(i),o,te(n,t),U(n,t))),n.mrc2=o})),i.length&&e.each((function(e){for(var t=n.select(this),r=0;r0?r:0}function P(e,t,r){return r&&(e=F(e)),t?z(e[1]):I(e[0])}function I(e){var t=n.round(e,2);return L=t,t}function z(e){var t=n.round(e,2);return S=t,t}function R(e,t,r,n){var a=e[0]-t[0],i=e[1]-t[1],o=r[0]-t[0],l=r[1]-t[1],s=Math.pow(a*a+i*i,.25),c=Math.pow(o*o+l*l,.25),u=(c*c*a-s*s*o)*n,f=(c*c*i-s*s*l)*n,d=3*c*(s+c),h=3*s*(s+c);return[[I(t[0]+(d&&u/d)),z(t[1]+(d&&f/d))],[I(t[0]-(h&&u/h)),z(t[1]-(h&&f/h))]]}x.textPointStyle=function(e,t,r){if(e.size()){var i;if(t.selectedpoints){var o=x.makeSelectedTextStyleFns(t);i=o.selectedTextColorFn}var l=t.texttemplate,s=r._fullLayout;e.each((function(e){var o=n.select(this),c=l?a.extractOption(e,t,"txt","texttemplate"):a.extractOption(e,t,"tx","text");if(c||0===c){if(l){var u=t._module.formatLabels,f=u?u(e,t,s):{},h={};m(h,t,e.i);var p=t._meta||{};c=a.texttemplateString(c,f,s._d3locale,h,e,p)}var v=e.tp||t.textposition,y=C(e,t),g=i?i(e):e.tc||t.textfont.color;o.call(x.font,{family:e.tf||t.textfont.family,weight:e.tw||t.textfont.weight,style:e.ty||t.textfont.style,variant:e.tv||t.textfont.variant,size:y,color:g}).text(c).call(d.convertToTspans,r).call(D,v,y,e.mrc)}else o.remove()}))}},x.selectedTextStyle=function(e,t){if(e.size()&&t.selectedpoints){var r=x.makeSelectedTextStyleFns(t);e.each((function(e){var a=n.select(this),i=r.selectedTextColorFn(e),o=e.tp||t.textposition,l=C(e,t);c.fill(a,i);var u=s.traceIs(t,"bar-like");D(a,o,l,e.mrc2||e.mrc,u)}))}},x.smoothopen=function(e,t){if(e.length<3)return"M"+e.join("L");var r,n="M"+e[0],a=[];for(r=1;r=c||w>=f&&w<=c)&&(T<=d&&T>=u||T>=d&&T<=u)&&(e=[w,T])}return e}x.steps=function(e){var t=E[e]||N;return function(e){for(var r="M"+I(e[0][0])+","+z(e[0][1]),n=e.length,a=1;a=1e4&&(x.savedBBoxes={},H=0),r&&(x.savedBBoxes[r]=y),H++,a.extendFlat({},y)},x.setClipUrl=function(e,t,r){e.attr("clip-path",B(t,r))},x.getTranslate=function(e){var t=(e[e.attr?"attr":"getAttribute"]("transform")||"").replace(/.*\btranslate\((-?\d*\.?\d*)[^-\d]*(-?\d*\.?\d*)[^\d].*/,(function(e,t,r){return[t,r].join(" ")})).split(" ");return{x:+t[0]||0,y:+t[1]||0}},x.setTranslate=function(e,t,r){var n=e.attr?"attr":"getAttribute",a=e.attr?"attr":"setAttribute",i=e[n]("transform")||"";return t=t||0,r=r||0,i=i.replace(/(\btranslate\(.*?\);?)/,"").trim(),i=(i+=f(t,r)).trim(),e[a]("transform",i),i},x.getScale=function(e){var t=(e[e.attr?"attr":"getAttribute"]("transform")||"").replace(/.*\bscale\((\d*\.?\d*)[^\d]*(\d*\.?\d*)[^\d].*/,(function(e,t,r){return[t,r].join(" ")})).split(" ");return{x:+t[0]||1,y:+t[1]||1}},x.setScale=function(e,t,r){var n=e.attr?"attr":"getAttribute",a=e.attr?"attr":"setAttribute",i=e[n]("transform")||"";return t=t||1,r=r||1,i=i.replace(/(\bscale\(.*?\);?)/,"").trim(),i=(i+="scale("+t+","+r+")").trim(),e[a]("transform",i),i};var Y=/\s*sc.*/;x.setPointGroupScale=function(e,t,r){if(t=t||1,r=r||1,e){var n=1===t&&1===r?"":"scale("+t+","+r+")";e.each((function(){var e=(this.getAttribute("transform")||"").replace(Y,"");e=(e+=n).trim(),this.setAttribute("transform",e)}))}};var V=/translate\([^)]*\)\s*$/;function U(e,t){var r;return e&&(r=e.mf),void 0===r&&(r=t.marker&&t.marker.standoff||0),t._geo||t._xA?r:-r}x.setTextPointsScale=function(e,t,r){e&&e.each((function(){var e,a=n.select(this),i=a.select("text");if(i.node()){var o=parseFloat(i.attr("x")||0),l=parseFloat(i.attr("y")||0),s=(a.attr("transform")||"").match(V);e=1===t&&1===r?[]:[f(o,l),"scale("+t+","+r+")",f(-o,-l)],s&&e.push(s),a.attr("transform",e.join(""))}}))},x.getMarkerStandoff=U;var q,G,Z,W,X,J,K=Math.atan2,Q=Math.cos,$=Math.sin;function ee(e,t){var r=t[0],n=t[1];return[r*Q(e)-n*$(e),r*$(e)+n*Q(e)]}function te(e,t){var r,n,i=e.ma;void 0===i&&((i=t.marker.angle)&&!a.isArrayOrTypedArray(i)||(i=0));var l=t.marker.angleref;if("previous"===l||"north"===l){if(t._geo){var s=t._geo.project(e.lonlat);r=s[0],n=s[1]}else{var c=t._xA,u=t._yA;if(!c||!u)return 90;r=c.c2p(e.x),n=u.c2p(e.y)}if(t._geo){var f,d=e.lonlat[0],h=e.lonlat[1],p=t._geo.project([d,h+1e-5]),v=t._geo.project([d+1e-5,h]),y=K(v[1]-n,v[0]-r),g=K(p[1]-n,p[0]-r);if("north"===l)f=i/180*Math.PI;else if("previous"===l){var m=d/180*Math.PI,x=h/180*Math.PI,b=q/180*Math.PI,_=G/180*Math.PI,w=b-m,T=Q(_)*$(w),M=$(_)*Q(x)-Q(_)*$(x)*Q(w);f=-K(T,M)-Math.PI,q=d,G=h}var k=ee(y,[Q(f),0]),A=ee(g,[$(f),0]);i=K(k[1]+A[1],k[0]+A[0])/Math.PI*180,"previous"!==l||J===t.uid&&e.i===X+1||(i=null)}if("previous"===l&&!t._geo)if(J===t.uid&&e.i===X+1&&o(r)&&o(n)){var L=r-Z,S=n-W,O=t.line&&t.line.shape||"",D=O.slice(O.length-1);"h"===D&&(S=0),"v"===D&&(L=0),i+=K(S,L)/Math.PI*180+90}else i=null}return Z=r,W=n,X=e.i,J=t.uid,i}x.getMarkerAngle=te},1984:function(e,t,r){"use strict";var n,a,i,o,l=r(9604),s=r(3428).round,c="M0,0Z",u=Math.sqrt(2),f=Math.sqrt(3),d=Math.PI,h=Math.cos,p=Math.sin;function v(e){return null===e}function y(e,t,r){if(!(e&&e%360!=0||t))return r;if(i===e&&o===t&&n===r)return a;function s(e,r){var n=h(e),a=p(e),i=r[0],o=r[1]+(t||0);return[i*n-o*a,i*a+o*n]}i=e,o=t,n=r;for(var c=e/180*d,u=0,f=0,v=l(r),y="",g=0;g0,f=e._context.staticPlot;t.each((function(t){var d,h=t[0].trace,p=h.error_x||{},v=h.error_y||{};h.ids&&(d=function(e){return e.id});var y=o.hasMarkers(h)&&h.marker.maxdisplayed>0;v.visible||p.visible||(t=[]);var g=n.select(this).selectAll("g.errorbar").data(t,d);if(g.exit().remove(),t.length){p.visible||g.selectAll("path.xerror").remove(),v.visible||g.selectAll("path.yerror").remove(),g.style("opacity",1);var m=g.enter().append("g").classed("errorbar",!0);u&&m.style("opacity",0).transition().duration(l.duration).style("opacity",1),i.setClipUrl(g,r.layerClipId,e),g.each((function(e){var t=n.select(this),r=function(e,t,r){var n={x:t.c2p(e.x),y:r.c2p(e.y)};return void 0!==e.yh&&(n.yh=r.c2p(e.yh),n.ys=r.c2p(e.ys),a(n.ys)||(n.noYS=!0,n.ys=r.c2p(e.ys,!0))),void 0!==e.xh&&(n.xh=t.c2p(e.xh),n.xs=t.c2p(e.xs),a(n.xs)||(n.noXS=!0,n.xs=t.c2p(e.xs,!0))),n}(e,s,c);if(!y||e.vis){var i,o=t.select("path.yerror");if(v.visible&&a(r.x)&&a(r.yh)&&a(r.ys)){var d=v.width;i="M"+(r.x-d)+","+r.yh+"h"+2*d+"m-"+d+",0V"+r.ys,r.noYS||(i+="m-"+d+",0h"+2*d),o.size()?u&&(o=o.transition().duration(l.duration).ease(l.easing)):o=t.append("path").style("vector-effect",f?"none":"non-scaling-stroke").classed("yerror",!0),o.attr("d",i)}else o.remove();var h=t.select("path.xerror");if(p.visible&&a(r.y)&&a(r.xh)&&a(r.xs)){var g=(p.copy_ystyle?v:p).width;i="M"+r.xh+","+(r.y-g)+"v"+2*g+"m0,-"+g+"H"+r.xs,r.noXS||(i+="m0,-"+g+"v"+2*g),h.size()?u&&(h=h.transition().duration(l.duration).ease(l.easing)):h=t.append("path").style("vector-effect",f?"none":"non-scaling-stroke").classed("xerror",!0),h.attr("d",i)}else h.remove()}}))}}))}},2036:function(e,t,r){"use strict";var n=r(3428),a=r(6308);e.exports=function(e){e.each((function(e){var t=e[0].trace,r=t.error_y||{},i=t.error_x||{},o=n.select(this);o.selectAll("path.yerror").style("stroke-width",r.thickness+"px").call(a.stroke,r.color),i.copy_ystyle&&(i=r),o.selectAll("path.xerror").style("stroke-width",i.thickness+"px").call(a.stroke,i.color)}))}},5756:function(e,t,r){"use strict";var n=r(5376),a=r(5460).hoverlabel,i=r(2880).extendFlat;e.exports={hoverlabel:{bgcolor:i({},a.bgcolor,{arrayOk:!0}),bordercolor:i({},a.bordercolor,{arrayOk:!0}),font:n({arrayOk:!0,editType:"none"}),align:i({},a.align,{arrayOk:!0}),namelength:i({},a.namelength,{arrayOk:!0}),editType:"none"}}},5056:function(e,t,r){"use strict";var n=r(3400),a=r(4040);function i(e,t,r,a){a=a||n.identity,Array.isArray(e)&&(t[0][r]=a(e))}e.exports=function(e){var t=e.calcdata,r=e._fullLayout;function o(e){return function(t){return n.coerceHoverinfo({hoverinfo:t},{_module:e._module},r)}}for(var l=0;l=0&&r.indexX[0]._length||be<0||be>J[0]._length)return v.unhoverRaw(e,t)}else xe="xpx"in t?t.xpx:X[0]._length/2,be="ypx"in t?t.ypx:J[0]._length/2;if(t.pointerX=xe+X[0]._offset,t.pointerY=be+J[0]._offset,re="xval"in t?m.flat(x,t.xval):m.p2c(X,xe),ne="yval"in t?m.flat(x,t.yval):m.p2c(J,be),!a(re[0])||!a(ne[0]))return o.warn("Fx.hover failed",t,e),v.unhoverRaw(e,t)}var Me=1/0;function ke(r,n){for(ie=0;iepe&&(ve.splice(0,pe),Me=ve[0].distance),k&&0!==te&&0===ve.length){he.distance=te,he.index=!1;var u=le._module.hoverPoints(he,fe,de,"closest",{hoverLayer:b._hoverlayer});if(u&&(u=u.filter((function(e){return e.spikeDistance<=te}))),u&&u.length){var f,d=u.filter((function(e){return e.xa.showspikes&&"hovered data"!==e.xa.spikesnap}));if(d.length){var h=d[0];a(h.x0)&&a(h.y0)&&(f=Le(h),(!ge.vLinePoint||ge.vLinePoint.spikeDistance>f.spikeDistance)&&(ge.vLinePoint=f))}var v=u.filter((function(e){return e.ya.showspikes&&"hovered data"!==e.ya.spikesnap}));if(v.length){var y=v[0];a(y.x0)&&a(y.y0)&&(f=Le(y),(!ge.hLinePoint||ge.hLinePoint.spikeDistance>f.spikeDistance)&&(ge.hLinePoint=f))}}}}}function Ae(e,t,r){for(var n,a=null,i=1/0,o=0;o0&&Math.abs(e.distance)Fe-1;He--)Ve(ve[He]);ve=je,Ce()}var Ue=e._hoverdata,qe=[],Ge=V(e),Ze=U(e);for(ae=0;ae1||ve.length>1)||"closest"===A&&me&&ve.length>1,ot=p.combine(b.plot_bgcolor||p.background,b.paper_bgcolor),lt=z(ve,{gd:e,hovermode:A,rotateLabels:it,bgColor:ot,container:b._hoverlayer,outerContainer:b._paper.node(),commonLabelOpts:b.hoverlabel,hoverdistance:b.hoverdistance}),st=lt.hoverLabels;if(m.isUnifiedHover(A)||(function(e,t,r,n){var a,i,o,l,s,c,u,f=t?"xa":"ya",d=t?"ya":"xa",h=0,p=1,v=e.size(),y=new Array(v),g=0,m=n.minX,x=n.maxX,b=n.minY,_=n.maxY,w=function(e){return e*r._invScaleX},T=function(e){return e*r._invScaleY};function k(e){var t=e[0],r=e[e.length-1];if(i=t.pmin-t.pos-t.dp+t.size,o=r.pos+r.dp+r.size-t.pmax,i>.01){for(s=e.length-1;s>=0;s--)e[s].dp+=i;a=!1}if(!(o<.01)){if(i<-.01){for(s=e.length-1;s>=0;s--)e[s].dp-=o;a=!1}if(a){var n=0;for(l=0;lt.pmax&&n++;for(l=e.length-1;l>=0&&!(n<=0);l--)(c=e[l]).pos>t.pmax-1&&(c.del=!0,n--);for(l=0;l=0;s--)e[s].dp-=o;for(l=e.length-1;l>=0&&!(n<=0);l--)(c=e[l]).pos+c.dp+c.size>t.pmax&&(c.del=!0,n--)}}}for(e.each((function(e){var n=e[f],a=e[d],i="x"===n._id.charAt(0),o=n.range;0===g&&o&&o[0]>o[1]!==i&&(p=-1);var l=0,s=i?r.width:r.height;if("x"===r.hovermode||"y"===r.hovermode){var c,u,h=E(e,t),v=e.anchor,k="end"===v?-1:1;if("middle"===v)u=(c=e.crossPos+(i?T(h.y-e.by/2):w(e.bx/2+e.tx2width/2)))+(i?T(e.by):w(e.bx));else if(i)u=(c=e.crossPos+T(L+h.y)-T(e.by/2-L))+T(e.by);else{var A=w(k*L+h.x),S=A+w(k*e.bx);c=e.crossPos+Math.min(A,S),u=e.crossPos+Math.max(A,S)}i?void 0!==b&&void 0!==_&&Math.min(u,_)-Math.max(c,b)>1&&("left"===a.side?(l=a._mainLinePosition,s=r.width):s=a._mainLinePosition):void 0!==m&&void 0!==x&&Math.min(u,x)-Math.max(c,m)>1&&("top"===a.side?(l=a._mainLinePosition,s=r.height):s=a._mainLinePosition)}y[g++]=[{datum:e,traceIndex:e.trace.index,dp:0,pos:e.pos,posref:e.posref,size:e.by*(i?M:1)/2,pmin:l,pmax:s}]})),y.sort((function(e,t){return e[0].posref-t[0].posref||p*(t[0].traceIndex-e[0].traceIndex)}));!a&&h<=v;){for(h++,a=!0,l=0;l.01&&O.pmin===D.pmin&&O.pmax===D.pmax){for(s=S.length-1;s>=0;s--)S[s].dp+=i;for(A.push.apply(A,S),y.splice(l+1,1),u=0,s=A.length-1;s>=0;s--)u+=A[s].dp;for(o=u/A.length,s=A.length-1;s>=0;s--)A[s].dp-=o;a=!1}else l++}y.forEach(k)}for(l=y.length-1;l>=0;l--){var C=y[l];for(s=C.length-1;s>=0;s--){var P=C[s],I=P.datum;I.offset=P.dp,I.del=P.del}}}(st,it,b,lt.commonLabelBoundingBox),N(st,it,b._invScaleX,b._invScaleY)),s&&s.tagName){var ct=g.getComponentMethod("annotations","hasClickToShow")(e,qe);d(n.select(s),ct?"pointer":"")}s&&!i&&function(e,t,r){if(!r||r.length!==e._hoverdata.length)return!0;for(var n=r.length-1;n>=0;n--){var a=r[n],i=e._hoverdata[n];if(a.curveNumber!==i.curveNumber||String(a.pointNumber)!==String(i.pointNumber)||String(a.pointNumbers)!==String(i.pointNumbers))return!0}return!1}(e,0,Ue)&&(Ue&&e.emit("plotly_unhover",{event:t,points:Ue}),e.emit("plotly_hover",{event:t,points:e._hoverdata,xaxes:X,yaxes:J,xvals:re,yvals:ne}))}(e,t,r,i,s)}))},t.loneHover=function(e,t){var r=!0;Array.isArray(e)||(r=!1,e=[e]);var a=t.gd,i=V(a),o=U(a),l=!1,s=z(e.map((function(e){var r=e._x0||e.x0||e.x||0,n=e._x1||e.x1||e.x||0,l=e._y0||e.y0||e.y||0,s=e._y1||e.y1||e.y||0,c=e.eventData;if(c){var u=Math.min(r,n),f=Math.max(r,n),d=Math.min(l,s),h=Math.max(l,s),v=e.trace;if(g.traceIs(v,"gl3d")){var y=a._fullLayout[v.scene]._scene.container,m=y.offsetLeft,x=y.offsetTop;u+=m,f+=m,d+=x,h+=x}c.bbox={x0:u+o,x1:f+o,y0:d+i,y1:h+i},t.inOut_bbox&&t.inOut_bbox.push(c.bbox)}else c=!1;return{color:e.color||p.defaultLine,x0:e.x0||e.x||0,x1:e.x1||e.x||0,y0:e.y0||e.y||0,y1:e.y1||e.y||0,xLabel:e.xLabel,yLabel:e.yLabel,zLabel:e.zLabel,text:e.text,name:e.name,idealAlign:e.idealAlign,borderColor:e.borderColor,fontFamily:e.fontFamily,fontSize:e.fontSize,fontColor:e.fontColor,fontWeight:e.fontWeight,fontStyle:e.fontStyle,fontVariant:e.fontVariant,nameLength:e.nameLength,textAlign:e.textAlign,trace:e.trace||{index:0,hoverinfo:""},xa:{_offset:0},ya:{_offset:0},index:0,hovertemplate:e.hovertemplate||!1,hovertemplateLabels:e.hovertemplateLabels||!1,eventData:c}})),{gd:a,hovermode:"closest",rotateLabels:l,bgColor:t.bgColor||p.background,container:n.select(t.container),outerContainer:t.outerContainer||t.container}).hoverLabels,c=0,u=0;return s.sort((function(e,t){return e.y0-t.y0})).each((function(e,r){var n=e.y0-e.by/2;e.offset=n-5([\s\S]*)<\/extra>/;function z(e,t){var r=t.gd,a=r._fullLayout,i=t.hovermode,l=t.rotateLabels,u=t.bgColor,d=t.container,v=t.outerContainer,y=t.commonLabelOpts||{};if(0===e.length)return[[]];var T=t.fontFamily||x.HOVERFONT,M=t.fontSize||x.HOVERFONTSIZE,k=t.fontWeight||a.font.weight,A=t.fontStyle||a.font.style,O=t.fontVariant||a.font.variant,D=e[0],C=D.xa,I=D.ya,z=i.charAt(0),E=z+"Label",N=D[E];if(void 0===N&&"multicategory"===C.type)for(var F=0;Fa.width-_&&(w=a.width-_),t.attr("d","M"+(g-w)+",0L"+(g-w+L)+","+b+L+"H"+_+"v"+b+(2*S+x.height)+"H"+-_+"V"+b+L+"H"+(g-w-L)+"Z"),g=w,J.minX=g-_,J.maxX=g+_,"top"===C.side?(J.minY=m-(2*S+x.height),J.maxY=m-S):(J.minY=m+S,J.maxY=m+(2*S+x.height))}else{var P,z,R;"right"===I.side?(P="start",z=1,R="",g=C._offset+C._length):(P="end",z=-1,R="-",g=C._offset),m=I._offset+(D.y0+D.y1)/2,l.attr("text-anchor",P),t.attr("d","M0,0L"+R+L+","+L+"V"+(S+x.height/2)+"h"+R+(2*S+x.width)+"V-"+(S+x.height/2)+"H"+R+L+"V-"+L+"Z"),J.minY=m-(S+x.height/2),J.maxY=m+(S+x.height/2),"right"===I.side?(J.minX=g+L,J.maxX=g+L+(2*S+x.width)):(J.minX=g-L-(2*S+x.width),J.maxX=g-L);var E,F=x.height/2,H=j-x.top-F,B="clip"+a._uid+"commonlabel"+I._id;if(g=0?fe:de+ve=0?de:Te+ve=0?ce:ue+ye=0?ue:Me+ye=0,"top"!==e.idealAlign&&W||!X?W?(E+=H/2,e.anchor="start"):e.anchor="middle":(E-=H/2,e.anchor="end"),e.crossPos=E;else{if(e.pos=E,W=z+F/2+J<=B,X=z-F/2-J>=0,"left"!==e.idealAlign&&W||!X)if(W)z+=F/2,e.anchor="start";else{e.anchor="middle";var K=J/2,Q=z+K-B,$=z-K;Q>0&&(z-=Q),$<0&&(z+=-$)}else z-=F/2,e.anchor="end";e.crossPos=z}_.attr("text-anchor",e.anchor),C&&D.attr("text-anchor",e.anchor),t.attr("transform",s(z,E)+(l?c(w):""))})),{hoverLabels:ke,commonLabelBoundingBox:J}}function R(e,t,r,n,a,i){var l="",s="";void 0!==e.nameOverride&&(e.name=e.nameOverride),e.name&&(e.trace._meta&&(e.name=o.templateString(e.name,e.trace._meta)),l=B(e.name,e.nameLength));var c=r.charAt(0),u="x"===c?"y":"x";void 0!==e.zLabel?(void 0!==e.xLabel&&(s+="x: "+e.xLabel+"
"),void 0!==e.yLabel&&(s+="y: "+e.yLabel+"
"),"choropleth"!==e.trace.type&&"choroplethmapbox"!==e.trace.type&&(s+=(s?"z: ":"")+e.zLabel)):t&&e[c+"Label"]===a?s=e[u+"Label"]||"":void 0===e.xLabel?void 0!==e.yLabel&&"scattercarpet"!==e.trace.type&&(s=e.yLabel):s=void 0===e.yLabel?e.xLabel:"("+e.xLabel+", "+e.yLabel+")",!e.text&&0!==e.text||Array.isArray(e.text)||(s+=(s?"
":"")+e.text),void 0!==e.extraText&&(s+=(s?"
":"")+e.extraText),i&&""===s&&!e.hovertemplate&&(""===l&&i.remove(),s=l);var f=e.hovertemplate||!1;if(f){var d=e.hovertemplateLabels||e;e[c+"Label"]!==a&&(d[c+"other"]=d[c+"Val"],d[c+"otherLabel"]=d[c+"Label"]),s=(s=o.hovertemplateString(f,d,n._d3locale,e.eventData[0]||{},e.trace._meta)).replace(I,(function(t,r){return l=B(r,e.nameLength),""}))}return[s,l]}function E(e,t){var r=0,n=e.offset;return t&&(n*=-A,r=e.offset*k),{x:r,y:n}}function N(e,t,r,a){var i=function(e){return e*r},o=function(e){return e*a};e.each((function(e){var r=n.select(this);if(e.del)return r.remove();var a,l,s,c,u=r.select("text.nums"),d=e.anchor,p="end"===d?-1:1,v=(l={start:1,end:-1,middle:0}[(a=e).anchor],c=(s=l*(L+S))+l*(a.txwidth+S),"middle"===a.anchor&&(s-=a.tx2width/2,c+=a.txwidth/2+S),{alignShift:l,textShiftX:s,text2ShiftX:c}),y=E(e,t),g=y.x,m=y.y,x="middle"===d;r.select("path").attr("d",x?"M-"+i(e.bx/2+e.tx2width/2)+","+o(m-e.by/2)+"h"+i(e.bx)+"v"+o(e.by)+"h-"+i(e.bx)+"Z":"M0,0L"+i(p*L+g)+","+o(L+m)+"v"+o(e.by/2-L)+"h"+i(p*e.bx)+"v-"+o(e.by)+"H"+i(p*L+g)+"V"+o(m-L)+"Z");var b=g+v.textShiftX,_=m+e.ty0-e.by/2+S,w=e.textAlign||"auto";"auto"!==w&&("left"===w&&"start"!==d?(u.attr("text-anchor","start"),b=x?-e.bx/2-e.tx2width/2+S:-e.bx-S):"right"===w&&"end"!==d&&(u.attr("text-anchor","end"),b=x?e.bx/2-e.tx2width/2-S:e.bx+S)),u.call(f.positionText,i(b),o(_)),e.tx2width&&(r.select("text.name").call(f.positionText,i(v.text2ShiftX+v.alignShift*S+g),o(m+e.ty0-e.by/2+S)),r.select("rect").call(h.setRect,i(v.text2ShiftX+(v.alignShift-1)*e.tx2width/2+g),o(m-e.by/2-1),i(e.tx2width),o(e.by+2)))}))}function F(e,t){var r=e.index,n=e.trace||{},i=e.cd[0],l=e.cd[r]||{};function s(e){return e||a(e)&&0===e}var c=Array.isArray(r)?function(e,t){var a=o.castOption(i,r,e);return s(a)?a:o.extractOption({},n,"",t)}:function(e,t){return o.extractOption(l,n,e,t)};function u(t,r,n){var a=c(r,n);s(a)&&(e[t]=a)}if(u("hoverinfo","hi","hoverinfo"),u("bgcolor","hbg","hoverlabel.bgcolor"),u("borderColor","hbc","hoverlabel.bordercolor"),u("fontFamily","htf","hoverlabel.font.family"),u("fontSize","hts","hoverlabel.font.size"),u("fontColor","htc","hoverlabel.font.color"),u("fontWeight","htw","hoverlabel.font.weight"),u("fontStyle","hty","hoverlabel.font.style"),u("fontVariant","htv","hoverlabel.font.variant"),u("nameLength","hnl","hoverlabel.namelength"),u("textAlign","hta","hoverlabel.align"),e.posref="y"===t||"closest"===t&&"h"===n.orientation?e.xa._offset+(e.x0+e.x1)/2:e.ya._offset+(e.y0+e.y1)/2,e.x0=o.constrain(e.x0,0,e.xa._length),e.x1=o.constrain(e.x1,0,e.xa._length),e.y0=o.constrain(e.y0,0,e.ya._length),e.y1=o.constrain(e.y1,0,e.ya._length),void 0!==e.xLabelVal&&(e.xLabel="xLabel"in e?e.xLabel:y.hoverLabelText(e.xa,e.xLabelVal,n.xhoverformat),e.xVal=e.xa.c2d(e.xLabelVal)),void 0!==e.yLabelVal&&(e.yLabel="yLabel"in e?e.yLabel:y.hoverLabelText(e.ya,e.yLabelVal,n.yhoverformat),e.yVal=e.ya.c2d(e.yLabelVal)),void 0!==e.zLabelVal&&void 0===e.zLabel&&(e.zLabel=String(e.zLabelVal)),!(isNaN(e.xerr)||"log"===e.xa.type&&e.xerr<=0)){var f=y.tickText(e.xa,e.xa.c2l(e.xerr),"hover").text;void 0!==e.xerrneg?e.xLabel+=" +"+f+" / -"+y.tickText(e.xa,e.xa.c2l(e.xerrneg),"hover").text:e.xLabel+=" \xb1 "+f,"x"===t&&(e.distance+=1)}if(!(isNaN(e.yerr)||"log"===e.ya.type&&e.yerr<=0)){var d=y.tickText(e.ya,e.ya.c2l(e.yerr),"hover").text;void 0!==e.yerrneg?e.yLabel+=" +"+d+" / -"+y.tickText(e.ya,e.ya.c2l(e.yerrneg),"hover").text:e.yLabel+=" \xb1 "+d,"y"===t&&(e.distance+=1)}var h=e.hoverinfo||e.trace.hoverinfo;return h&&"all"!==h&&(-1===(h=Array.isArray(h)?h:h.split("+")).indexOf("x")&&(e.xLabel=void 0),-1===h.indexOf("y")&&(e.yLabel=void 0),-1===h.indexOf("z")&&(e.zLabel=void 0),-1===h.indexOf("text")&&(e.text=void 0),-1===h.indexOf("name")&&(e.name=void 0)),e}function H(e,t,r){var n,a,o=r.container,l=r.fullLayout,s=l._size,c=r.event,u=!!t.hLinePoint,f=!!t.vLinePoint;if(o.selectAll(".spikeline").remove(),f||u){var d=p.combine(l.plot_bgcolor,l.paper_bgcolor);if(u){var v,g,m=t.hLinePoint;n=m&&m.xa,"cursor"===(a=m&&m.ya).spikesnap?(v=c.pointerX,g=c.pointerY):(v=n._offset+m.x,g=a._offset+m.y);var x,b,_=i.readability(m.color,d)<1.5?p.contrast(d):m.color,w=a.spikemode,T=a.spikethickness,M=a.spikecolor||_,k=y.getPxPosition(e,a);if(-1!==w.indexOf("toaxis")||-1!==w.indexOf("across")){if(-1!==w.indexOf("toaxis")&&(x=k,b=v),-1!==w.indexOf("across")){var A=a._counterDomainMin,L=a._counterDomainMax;"free"===a.anchor&&(A=Math.min(A,a.position),L=Math.max(L,a.position)),x=s.l+A*s.w,b=s.l+L*s.w}o.insert("line",":first-child").attr({x1:x,x2:b,y1:g,y2:g,"stroke-width":T,stroke:M,"stroke-dasharray":h.dashStyle(a.spikedash,T)}).classed("spikeline",!0).classed("crisp",!0),o.insert("line",":first-child").attr({x1:x,x2:b,y1:g,y2:g,"stroke-width":T+2,stroke:d}).classed("spikeline",!0).classed("crisp",!0)}-1!==w.indexOf("marker")&&o.insert("circle",":first-child").attr({cx:k+("right"!==a.side?T:-T),cy:g,r:T,fill:M}).classed("spikeline",!0)}if(f){var S,O,D=t.vLinePoint;n=D&&D.xa,a=D&&D.ya,"cursor"===n.spikesnap?(S=c.pointerX,O=c.pointerY):(S=n._offset+D.x,O=a._offset+D.y);var C,P,I=i.readability(D.color,d)<1.5?p.contrast(d):D.color,z=n.spikemode,R=n.spikethickness,E=n.spikecolor||I,N=y.getPxPosition(e,n);if(-1!==z.indexOf("toaxis")||-1!==z.indexOf("across")){if(-1!==z.indexOf("toaxis")&&(C=N,P=O),-1!==z.indexOf("across")){var F=n._counterDomainMin,H=n._counterDomainMax;"free"===n.anchor&&(F=Math.min(F,n.position),H=Math.max(H,n.position)),C=s.t+(1-H)*s.h,P=s.t+(1-F)*s.h}o.insert("line",":first-child").attr({x1:S,x2:S,y1:C,y2:P,"stroke-width":R,stroke:E,"stroke-dasharray":h.dashStyle(n.spikedash,R)}).classed("spikeline",!0).classed("crisp",!0),o.insert("line",":first-child").attr({x1:S,x2:S,y1:C,y2:P,"stroke-width":R+2,stroke:d}).classed("spikeline",!0).classed("crisp",!0)}-1!==z.indexOf("marker")&&o.insert("circle",":first-child").attr({cx:S,cy:N-("top"!==n.side?R:-R),r:R,fill:E}).classed("spikeline",!0)}}}function j(e,t){return!t||t.vLinePoint!==e._spikepoints.vLinePoint||t.hLinePoint!==e._spikepoints.hLinePoint}function B(e,t){return f.plainText(e||"",{len:t,allowedTags:["br","sub","sup","b","i","em"]})}function Y(e,t,r){var n=t[e+"a"],a=t[e+"Val"],i=t.cd[0];if("category"===n.type||"multicategory"===n.type)a=n._categoriesMap[a];else if("date"===n.type){var o=t.trace[e+"periodalignment"];if(o){var l=t.cd[t.index],s=l[e+"Start"];void 0===s&&(s=l[e]);var c=l[e+"End"];void 0===c&&(c=l[e]);var u=c-s;"end"===o?a+=u:"middle"===o&&(a+=u/2)}a=n.d2c(a)}return i&&i.t&&i.t.posLetter===n._id&&("group"!==r.boxmode&&"group"!==r.violinmode||(a+=i.t.dPos)),a}function V(e){return e.offsetTop+e.clientTop}function U(e){return e.offsetLeft+e.clientLeft}function q(e,t){var r=e._fullLayout,n=t.getBoundingClientRect(),a=n.left,i=n.top,l=a+n.width,s=i+n.height,c=o.apply3DTransform(r._invTransform)(a,i),u=o.apply3DTransform(r._invTransform)(l,s),f=c[0],d=c[1],h=u[0],p=u[1];return{x:f,y:d,width:h-f,height:p-d,top:Math.min(d,p),left:Math.min(f,h),right:Math.max(f,h),bottom:Math.max(d,p)}}},6132:function(e,t,r){"use strict";var n=r(3400),a=r(6308),i=r(624).isUnifiedHover;e.exports=function(e,t,r,o){o=o||{};var l=t.legend;function s(e){o.font[e]||(o.font[e]=l?t.legend.font[e]:t.font[e])}t&&i(t.hovermode)&&(o.font||(o.font={}),s("size"),s("family"),s("color"),s("weight"),s("style"),s("variant"),l?(o.bgcolor||(o.bgcolor=a.combine(t.legend.bgcolor,t.paper_bgcolor)),o.bordercolor||(o.bordercolor=t.legend.bordercolor)):o.bgcolor||(o.bgcolor=t.paper_bgcolor)),r("hoverlabel.bgcolor",o.bgcolor),r("hoverlabel.bordercolor",o.bordercolor),r("hoverlabel.namelength",o.namelength),n.coerceFont(r,"hoverlabel.font",o.font),r("hoverlabel.align",o.align)}},1008:function(e,t,r){"use strict";var n=r(3400),a=r(5460);e.exports=function(e,t){function r(r,i){return void 0!==t[r]?t[r]:n.coerce(e,t,a,r,i)}return r("clickmode"),r("hoversubplots"),r("hovermode")}},3024:function(e,t,r){"use strict";var n=r(3428),a=r(3400),i=r(6476),o=r(624),l=r(5460),s=r(3292);e.exports={moduleType:"component",name:"fx",constants:r(2456),schema:{layout:l},attributes:r(5756),layoutAttributes:l,supplyLayoutGlobalDefaults:r(1976),supplyDefaults:r(5448),supplyLayoutDefaults:r(8336),calc:r(5056),getDistanceFunction:o.getDistanceFunction,getClosest:o.getClosest,inbox:o.inbox,quadrature:o.quadrature,appendArrayPointValue:o.appendArrayPointValue,castHoverOption:function(e,t,r){return a.castOption(e,t,"hoverlabel."+r)},castHoverinfo:function(e,t,r){return a.castOption(e,r,"hoverinfo",(function(r){return a.coerceHoverinfo({hoverinfo:r},{_module:e._module},t)}))},hover:s.hover,unhover:i.unhover,loneHover:s.loneHover,loneUnhover:function(e){var t=a.isD3Selection(e)?e:n.select(e);t.selectAll("g.hovertext").remove(),t.selectAll(".spikeline").remove()},click:r(2376)}},5460:function(e,t,r){"use strict";var n=r(2456),a=r(5376),i=a({editType:"none"});i.family.dflt=n.HOVERFONT,i.size.dflt=n.HOVERFONTSIZE,e.exports={clickmode:{valType:"flaglist",flags:["event","select"],dflt:"event",editType:"plot",extras:["none"]},dragmode:{valType:"enumerated",values:["zoom","pan","select","lasso","drawclosedpath","drawopenpath","drawline","drawrect","drawcircle","orbit","turntable",!1],dflt:"zoom",editType:"modebar"},hovermode:{valType:"enumerated",values:["x","y","closest",!1,"x unified","y unified"],dflt:"closest",editType:"modebar"},hoversubplots:{valType:"enumerated",values:["single","overlaying","axis"],dflt:"overlaying",editType:"none"},hoverdistance:{valType:"integer",min:-1,dflt:20,editType:"none"},spikedistance:{valType:"integer",min:-1,dflt:-1,editType:"none"},hoverlabel:{bgcolor:{valType:"color",editType:"none"},bordercolor:{valType:"color",editType:"none"},font:i,grouptitlefont:a({editType:"none"}),align:{valType:"enumerated",values:["left","right","auto"],dflt:"auto",editType:"none"},namelength:{valType:"integer",min:-1,dflt:15,editType:"none"},editType:"none"},selectdirection:{valType:"enumerated",values:["h","v","d","any"],dflt:"any",editType:"none"}}},8336:function(e,t,r){"use strict";var n=r(3400),a=r(5460),i=r(1008),o=r(6132);e.exports=function(e,t){function r(r,i){return n.coerce(e,t,a,r,i)}i(e,t)&&(r("hoverdistance"),r("spikedistance")),"select"===r("dragmode")&&r("selectdirection");var l=t._has("mapbox"),s=t._has("geo"),c=t._basePlotModules.length;"zoom"===t.dragmode&&((l||s)&&1===c||l&&s&&2===c)&&(t.dragmode="pan"),o(e,t,r),n.coerceFont(r,"hoverlabel.grouptitlefont",t.hoverlabel.font)}},1976:function(e,t,r){"use strict";var n=r(3400),a=r(6132),i=r(5460);e.exports=function(e,t){a(e,t,(function(r,a){return n.coerce(e,t,i,r,a)}))}},2704:function(e,t,r){"use strict";var n=r(3400),a=r(3756).counter,i=r(6968).u,o=r(3816).idRegex,l=r(1780),s={rows:{valType:"integer",min:1,editType:"plot"},roworder:{valType:"enumerated",values:["top to bottom","bottom to top"],dflt:"top to bottom",editType:"plot"},columns:{valType:"integer",min:1,editType:"plot"},subplots:{valType:"info_array",freeLength:!0,dimensions:2,items:{valType:"enumerated",values:[a("xy").toString(),""],editType:"plot"},editType:"plot"},xaxes:{valType:"info_array",freeLength:!0,items:{valType:"enumerated",values:[o.x.toString(),""],editType:"plot"},editType:"plot"},yaxes:{valType:"info_array",freeLength:!0,items:{valType:"enumerated",values:[o.y.toString(),""],editType:"plot"},editType:"plot"},pattern:{valType:"enumerated",values:["independent","coupled"],dflt:"coupled",editType:"plot"},xgap:{valType:"number",min:0,max:1,editType:"plot"},ygap:{valType:"number",min:0,max:1,editType:"plot"},domain:i({name:"grid",editType:"plot",noGridCell:!0},{}),xside:{valType:"enumerated",values:["bottom","bottom plot","top plot","top"],dflt:"bottom plot",editType:"plot"},yside:{valType:"enumerated",values:["left","left plot","right plot","right"],dflt:"left plot",editType:"plot"},editType:"plot"};function c(e,t,r){var n=t[r+"axes"],a=Object.keys((e._splomAxes||{})[r]||{});return Array.isArray(n)?n:a.length?a:void 0}function u(e,t,r,n,a,i){var o=t(e+"gap",r),l=t("domain."+e);t(e+"side",n);for(var s=new Array(a),c=l[0],u=(l[1]-c)/(a-o),f=u*(1-o),d=0;d1){d||h||p||"independent"===M("pattern")&&(d=!0),y._hasSubplotGrid=d;var x,b,_="top to bottom"===M("roworder"),w=d?.2:.1,T=d?.3:.1;v&&t._splomGridDflt&&(x=t._splomGridDflt.xside,b=t._splomGridDflt.yside),y._domains={x:u("x",M,w,x,m),y:u("y",M,T,b,g,_)}}else delete t.grid}function M(e,t){return n.coerce(r,y,s,e,t)}},contentDefaults:function(e,t){var r=t.grid;if(r&&r._domains){var n,a,i,o,l,s,u,d=e.grid||{},h=t._subplots,p=r._hasSubplotGrid,v=r.rows,y=r.columns,g="independent"===r.pattern,m=r._axisMap={};if(p){var x=d.subplots||[];s=r.subplots=new Array(v);var b=1;for(n=0;n("legend"===e?1:0));if(!1===A&&(r[e]=void 0),(!1!==A||f.uirevision)&&(h("uirevision",r.uirevision),!1!==A)){h("borderwidth");var L,S,O,D="h"===h("orientation"),C="paper"===h("yref"),P="paper"===h("xref"),I="left";if(D?(L=0,n.getComponentMethod("rangeslider","isVisible")(t.xaxis)?C?(S=1.1,O="bottom"):(S=1,O="top"):C?(S=-.1,O="top"):(S=0,O="bottom")):(S=1,O="auto",P?L=1.02:(L=1,I="right")),a.coerce(f,d,{x:{valType:"number",editType:"legend",min:P?-2:0,max:P?3:1,dflt:L}},"x"),a.coerce(f,d,{y:{valType:"number",editType:"legend",min:C?-2:0,max:C?3:1,dflt:S}},"y"),h("traceorder",_),c.isGrouped(r[e])&&h("tracegroupgap"),h("entrywidth"),h("entrywidthmode"),h("indentation"),h("itemsizing"),h("itemwidth"),h("itemclick"),h("itemdoubleclick"),h("groupclick"),h("xanchor",I),h("yanchor",O),h("valign"),a.noneOrAll(f,d,["x","y"]),h("title.text")){h("title.side",D?"left":"top");var z=a.extendFlat({},p,{size:a.bigFont(p.size)});a.coerceFont(h,"title.font",z)}}}}e.exports=function(e,t,r){var n,i=r.slice(),o=t.shapes;if(o)for(n=0;n1)}var F=p.hiddenlabels||[];if(!(T||p.showlegend&&L.length))return l.selectAll("."+w).remove(),p._topdefs.select("#"+r).remove(),i.autoMargin(e,w);var H=a.ensureSingle(l,"g",w,(function(e){T||e.attr("pointer-events","all")})),j=a.ensureSingleById(p._topdefs,"clipPath",r,(function(e){e.append("rect")})),B=a.ensureSingle(H,"rect","bg",(function(e){e.attr("shape-rendering","crispEdges")}));B.call(u.stroke,d.bordercolor).call(u.fill,d.bgcolor).style("stroke-width",d.borderwidth+"px");var Y,V=a.ensureSingle(H,"g","scrollbox"),U=d.title;d._titleWidth=0,d._titleHeight=0,U.text?((Y=a.ensureSingle(V,"text",w+"titletext")).attr("text-anchor","start").call(c.font,U.font).text(U.text),O(Y,V,e,d,_)):V.selectAll("."+w+"titletext").remove();var q=a.ensureSingle(H,"rect","scrollbar",(function(e){e.attr(h.scrollBarEnterAttrs).call(u.fill,h.scrollBarColor)})),G=V.selectAll("g.groups").data(L);G.enter().append("g").attr("class","groups"),G.exit().remove();var Z=G.selectAll("g.traces").data(a.identity);Z.enter().append("g").attr("class","traces"),Z.exit().remove(),Z.style("opacity",(function(e){var t=e[0].trace;return o.traceIs(t,"pie-like")?-1!==F.indexOf(e[0].label)?.5:1:"legendonly"===t.visible?.5:1})).each((function(){n.select(this).call(A,e,d)})).call(x,e,d).each((function(){T||n.select(this).call(S,e,w)})),a.syncOrAsync([i.previousPromises,function(){return function(e,t,r,a){var i=e._fullLayout,o=P(a);a||(a=i[o]);var l=i._size,s=b.isVertical(a),u=b.isGrouped(a),f="fraction"===a.entrywidthmode,d=a.borderwidth,p=2*d,v=h.itemGap,y=a.indentation+a.itemwidth+2*v,g=2*(d+v),m=C(a),x=a.y<0||0===a.y&&"top"===m,_=a.y>1||1===a.y&&"bottom"===m,w=a.tracegroupgap,T={};a._maxHeight=Math.max(x||_?i.height/2:l.h,30);var k=0;a._width=0,a._height=0;var A=function(e){var t=0,r=0,n=e.title.side;return n&&(-1!==n.indexOf("left")&&(t=e._titleWidth),-1!==n.indexOf("top")&&(r=e._titleHeight)),[t,r]}(a);if(s)r.each((function(e){var t=e[0].height;c.setTranslate(this,d+A[0],d+A[1]+a._height+t/2+v),a._height+=t,a._width=Math.max(a._width,e[0].width)})),k=y+a._width,a._width+=v+y+p,a._height+=g,u&&(t.each((function(e,t){c.setTranslate(this,0,t*a.tracegroupgap)})),a._height+=(a._lgroupsLength-1)*a.tracegroupgap);else{var L=D(a),S=a.x<0||0===a.x&&"right"===L,O=a.x>1||1===a.x&&"left"===L,I=_||x,z=i.width/2;a._maxWidth=Math.max(S?I&&"left"===L?l.l+l.w:z:O?I&&"right"===L?l.r+l.w:z:l.w,2*y);var R=0,E=0;r.each((function(e){var t=M(e,a,y);R=Math.max(R,t),E+=t})),k=null;var N=0;if(u){var F=0,H=0,j=0;t.each((function(){var e=0,t=0;n.select(this).selectAll("g.traces").each((function(r){var n=M(r,a,y),i=r[0].height;c.setTranslate(this,A[0],A[1]+d+v+i/2+t),t+=i,e=Math.max(e,n),T[r[0].trace.legendgroup]=e}));var r=e+v;H>0&&r+d+H>a._maxWidth?(N=Math.max(N,H),H=0,j+=F+w,F=t):F=Math.max(F,t),c.setTranslate(this,H,j),H+=r})),a._width=Math.max(N,H)+d,a._height=j+F+g}else{var B=r.size(),Y=E+p+(B-1)*v=a._maxWidth&&(N=Math.max(N,G),U=0,q+=V,a._height+=V,V=0),c.setTranslate(this,A[0]+d+U,A[1]+d+q+t/2+v),G=U+r+v,U+=n,V=Math.max(V,t)})),Y?(a._width=U+p,a._height=V+g):(a._width=Math.max(N,G)+p,a._height+=V+g)}}a._width=Math.ceil(Math.max(a._width+A[0],a._titleWidth+2*(d+h.titlePad))),a._height=Math.ceil(Math.max(a._height+A[1],a._titleHeight+2*(d+h.itemGap))),a._effHeight=Math.min(a._height,a._maxHeight);var Z=e._context.edits,W=Z.legendText||Z.legendPosition;r.each((function(e){var t=n.select(this).select("."+o+"toggle"),r=e[0].height,i=e[0].trace.legendgroup,l=M(e,a,y);u&&""!==i&&(l=T[i]);var d=W?y:k||l;s||f||(d+=v/2),c.setRect(t,0,-r/2,d,r)}))}(e,G,Z,d)},function(){var t,u,m,x,b=p._size,_=d.borderwidth,M="paper"===d.xref,A="paper"===d.yref;if(U.text&&function(e,t,r){if("top center"===t.title.side||"top right"===t.title.side){var n=t.title.font.size*v,a=0,i=e.node(),o=c.bBox(i).width;"top center"===t.title.side?a=.5*(t._width-2*r-2*h.titlePad-o):"top right"===t.title.side&&(a=t._width-2*r-2*h.titlePad-o),f.positionText(e,r+h.titlePad+a,r+n)}}(Y,d,_),!T){var L,S;L=M?b.l+b.w*d.x-y[D(d)]*d._width:p.width*d.x-y[D(d)]*d._width,S=A?b.t+b.h*(1-d.y)-y[C(d)]*d._effHeight:p.height*(1-d.y)-y[C(d)]*d._effHeight;var O=function(e,t,r,n){var a=e._fullLayout,o=a[t],l=D(o),s=C(o),c="paper"===o.xref,u="paper"===o.yref;e._fullLayout._reservedMargin[t]={};var f=o.y<.5?"b":"t",d=o.x<.5?"l":"r",h={r:a.width-r,l:r+o._width,b:a.height-n,t:n+o._effHeight};if(c&&u)return i.autoMargin(e,t,{x:o.x,y:o.y,l:o._width*y[l],r:o._width*g[l],b:o._effHeight*g[s],t:o._effHeight*y[s]});c?e._fullLayout._reservedMargin[t][f]=h[f]:u||"v"===o.orientation?e._fullLayout._reservedMargin[t][d]=h[d]:e._fullLayout._reservedMargin[t][f]=h[f]}(e,w,L,S);if(O)return;if(p.margin.autoexpand){var P=L,I=S;L=M?a.constrain(L,0,p.width-d._width):P,S=A?a.constrain(S,0,p.height-d._effHeight):I,L!==P&&a.log("Constrain "+w+".x to make legend fit inside graph"),S!==I&&a.log("Constrain "+w+".y to make legend fit inside graph")}c.setTranslate(H,L,S)}if(q.on(".drag",null),H.on("wheel",null),T||d._height<=d._maxHeight||e._context.staticPlot){var z=d._effHeight;T&&(z=d._height),B.attr({width:d._width-_,height:z-_,x:_/2,y:_/2}),c.setTranslate(V,0,0),j.select("rect").attr({width:d._width-2*_,height:z-2*_,x:_,y:_}),c.setClipUrl(V,r,e),c.setRect(q,0,0,0,0),delete d._scrollY}else{var R,E,N,F=Math.max(h.scrollBarMinHeight,d._effHeight*d._effHeight/d._height),G=d._effHeight-F-2*h.scrollBarMargin,Z=d._height-d._effHeight,W=G/Z,X=Math.min(d._scrollY||0,Z);B.attr({width:d._width-2*_+h.scrollBarWidth+h.scrollBarMargin,height:d._effHeight-_,x:_/2,y:_/2}),j.select("rect").attr({width:d._width-2*_+h.scrollBarWidth+h.scrollBarMargin,height:d._effHeight-2*_,x:_,y:_+X}),c.setClipUrl(V,r,e),Q(X,F,W),H.on("wheel",(function(){Q(X=a.constrain(d._scrollY+n.event.deltaY/G*Z,0,Z),F,W),0!==X&&X!==Z&&n.event.preventDefault()}));var J=n.behavior.drag().on("dragstart",(function(){var e=n.event.sourceEvent;R="touchstart"===e.type?e.changedTouches[0].clientY:e.clientY,N=X})).on("drag",(function(){var e=n.event.sourceEvent;2===e.buttons||e.ctrlKey||(E="touchmove"===e.type?e.changedTouches[0].clientY:e.clientY,X=function(e,t,r){var n=(r-t)/W+e;return a.constrain(n,0,Z)}(N,R,E),Q(X,F,W))}));q.call(J);var K=n.behavior.drag().on("dragstart",(function(){var e=n.event.sourceEvent;"touchstart"===e.type&&(R=e.changedTouches[0].clientY,N=X)})).on("drag",(function(){var e=n.event.sourceEvent;"touchmove"===e.type&&(E=e.changedTouches[0].clientY,X=function(e,t,r){var n=(t-r)/W+e;return a.constrain(n,0,Z)}(N,R,E),Q(X,F,W))}));V.call(K)}function Q(t,r,n){d._scrollY=e._fullLayout[w]._scrollY=t,c.setTranslate(V,0,-t),c.setRect(q,d._width,h.scrollBarMargin+t*n,h.scrollBarWidth,r),j.select("rect").attr("y",_+t)}e._context.edits.legendPosition&&(H.classed("cursor-move",!0),s.init({element:H.node(),gd:e,prepFn:function(){var e=c.getTranslate(H);m=e.x,x=e.y},moveFn:function(e,r){var n=m+e,a=x+r;c.setTranslate(H,n,a),t=s.align(n,d._width,b.l,b.l+b.w,d.xanchor),u=s.align(a+d._height,-d._height,b.t+b.h,b.t,d.yanchor)},doneFn:function(){if(void 0!==t&&void 0!==u){var r={};r[w+".x"]=t,r[w+".y"]=u,o.call("_guiRelayout",e,r)}},clickFn:function(t,r){var n=l.selectAll("g.traces").filter((function(){var e=this.getBoundingClientRect();return r.clientX>=e.left&&r.clientX<=e.right&&r.clientY>=e.top&&r.clientY<=e.bottom}));n.size()>0&&k(e,H,n,t,r)}}))}],e)}}function M(e,t,r){var n=e[0],a=n.width,i=t.entrywidthmode,o=n.trace.legendwidth||t.entrywidth;return"fraction"===i?t._maxWidth*o:r+(o||a)}function k(e,t,r,n,a){var i=r.data()[0][0].trace,s={event:a,node:r.node(),curveNumber:i.index,expandedIndex:i._expandedIndex,data:e.data,layout:e.layout,frames:e._transitionData._frames,config:e._context,fullData:e._fullData,fullLayout:e._fullLayout};i._group&&(s.group=i._group),o.traceIs(i,"pie-like")&&(s.label=r.datum()[0].label);var c=l.triggerHandler(e,"plotly_legendclick",s);if(1===n){if(!1===c)return;t._clickTimeout=setTimeout((function(){e._fullLayout&&d(r,e,n)}),e._context.doubleClickDelay)}else 2===n&&(t._clickTimeout&&clearTimeout(t._clickTimeout),e._legendMouseDownTime=0,!1!==l.triggerHandler(e,"plotly_legenddoubleclick",s)&&!1!==c&&d(r,e,n))}function A(e,t,r){var n,i,l=P(r),s=e.data()[0][0],u=s.trace,d=o.traceIs(u,"pie-like"),p=!r._inHover&&t._context.edits.legendText&&!d,v=r._maxNameLength;s.groupTitle?(n=s.groupTitle.text,i=s.groupTitle.font):(i=r.font,r.entries?n=s.text:(n=d?s.label:u.name,u._meta&&(n=a.templateString(n,u._meta))));var y=a.ensureSingle(e,"text",l+"text");y.attr("text-anchor","start").call(c.font,i).text(p?L(n,v):n);var g=r.indentation+r.itemwidth+2*h.itemGap;f.positionText(y,g,0),p?y.call(f.makeEditable,{gd:t,text:n}).call(O,e,t,r).on("edit",(function(n){this.text(L(n,v)).call(O,e,t,r);var i=s.trace._fullInput||{},l={};if(o.hasTransform(i,"groupby")){var c=o.getTransformIndices(i,"groupby"),f=c[c.length-1],d=a.keyedContainer(i,"transforms["+f+"].styles","target","value.name");d.set(s.trace._group,n),l=d.constructUpdate()}else l.name=n;return i._isShape?o.call("_guiRelayout",t,"shapes["+u.index+"].name",l.name):o.call("_guiRestyle",t,l,u.index)})):O(y,e,t,r)}function L(e,t){var r=Math.max(4,t);if(e&&e.trim().length>=r/2)return e;for(var n=r-(e=e||"").length;n>0;n--)e+=" ";return e}function S(e,t,r){var i,o=t._context.doubleClickDelay,l=1,s=a.ensureSingle(e,"rect",r+"toggle",(function(e){t._context.staticPlot||e.style("cursor","pointer").attr("pointer-events","all"),e.call(u.fill,"rgba(0,0,0,0)")}));t._context.staticPlot||(s.on("mousedown",(function(){(i=(new Date).getTime())-t._legendMouseDownTimeo&&(l=Math.max(l-1,1)),k(t,a,e,l,n.event)}})))}function O(e,t,r,n,a){n._inHover&&e.attr("data-notex",!0),f.convertToTspans(e,r,(function(){!function(e,t,r,n){var a=e.data()[0][0];if(r._inHover||!a||a.trace.showlegend){var i=e.select("g[class*=math-group]"),o=i.node(),l=P(r);r||(r=t._fullLayout[l]);var s,u,d=r.borderwidth,p=(n===_?r.title.font:a.groupTitle?a.groupTitle.font:r.font).size*v;if(o){var y=c.bBox(o);s=y.height,u=y.width,n===_?c.setTranslate(i,d,d+.75*s):c.setTranslate(i,0,.25*s)}else{var g="."+l+(n===_?"title":"")+"text",m=e.select(g),x=f.lineCount(m),b=m.node();if(s=p*x,u=b?c.bBox(b).width:0,n===_)"left"===r.title.side&&(u+=2*h.itemGap),f.positionText(m,d+h.titlePad,d+p);else{var w=2*h.itemGap+r.indentation+r.itemwidth;a.groupTitle&&(w=h.itemGap,u-=r.indentation+r.itemwidth),f.positionText(m,w,-p*((x-1)/2-.3))}}n===_?(r._titleWidth=u,r._titleHeight=s):(a.lineHeight=p,a.height=Math.max(s,16)+3,a.width=u)}else e.remove()}(t,r,n,a)}))}function D(e){return a.isRightAnchor(e)?"right":a.isCenterAnchor(e)?"center":"left"}function C(e){return a.isBottomAnchor(e)?"bottom":a.isMiddleAnchor(e)?"middle":"top"}function P(e){return e._id||"legend"}e.exports=function(e,t){if(t)T(e,t);else{var r=e._fullLayout,a=r._legends;r._infolayer.selectAll('[class^="legend"]').each((function(){var e=n.select(this),t=e.attr("class").split(" ")[0];t.match(w)&&-1===a.indexOf(t)&&e.remove()}));for(var i=0;iL&&(A=L)}M[i][0]._groupMinRank=A,M[i][0]._preGroupSort=i}var S=function(e,t){return e.trace.legendrank-t.trace.legendrank||e._preSort-t._preSort};for(M.forEach((function(e,t){e[0]._preGroupSort=t})),M.sort((function(e,t){return e[0]._groupMinRank-t[0]._groupMinRank||e[0]._preGroupSort-t[0]._preGroupSort})),i=0;ir?r:e}e.exports=function(e,t,r){var g=t._fullLayout;r||(r=g.legend);var m="constant"===r.itemsizing,x=r.itemwidth,b=(x+2*h.itemGap)/2,_=o(b,0),w=function(e,t,r,n){var a;if(e+1)a=e;else{if(!(t&&t.width>0))return 0;a=t.width}return m?n:Math.min(a,r)};function T(e,i,o){var u=e[0].trace,f=u.marker||{},d=f.line||{},h=f.cornerradius?"M6,3a3,3,0,0,1-3,3H-3a3,3,0,0,1-3-3V-3a3,3,0,0,1,3-3H3a3,3,0,0,1,3,3Z":"M6,6H-6V-6H6Z",p=o?u.visible&&u.type===o:a.traceIs(u,"bar"),v=n.select(i).select("g.legendpoints").selectAll("path.legend"+o).data(p?[e]:[]);v.enter().append("path").classed("legend"+o,!0).attr("d",h).attr("transform",_),v.exit().remove(),v.each((function(e){var a=n.select(this),i=e[0],o=w(i.mlw,f.line,5,2);a.style("stroke-width",o+"px");var h=i.mcc;if(!r._inHover&&"mc"in i){var p=c(f),v=p.mid;void 0===v&&(v=(p.max+p.min)/2),h=l.tryColorscale(f,"")(v)}var g=h||i.mc||f.color,m=f.pattern,x=m&&l.getPatternAttr(m.shape,0,"");if(x){var b=l.getPatternAttr(m.bgcolor,0,null),_=l.getPatternAttr(m.fgcolor,0,null),T=m.fgopacity,M=y(m.size,8,10),k=y(m.solidity,.5,1),A="legend-"+u.uid;a.call(l.pattern,"legend",t,A,x,M,k,h,m.fillmode,b,_,T)}else a.call(s.fill,g);o&&s.stroke(a,i.mlc||d.color)}))}function M(e,r,o){var l=e[0],s=l.trace,c=o?s.visible&&s.type===o:a.traceIs(s,o),u=n.select(r).select("g.legendpoints").selectAll("path.legend"+o).data(c?[e]:[]);if(u.enter().append("path").classed("legend"+o,!0).attr("d","M6,6H-6V-6H6Z").attr("transform",_),u.exit().remove(),u.size()){var h=s.marker||{},p=w(d(h.line.width,l.pts),h.line,5,2),v="pieLike",y=i.minExtend(s,{marker:{line:{width:p}}},v),g=i.minExtend(l,{trace:y},v);f(u,g,y,t)}}e.each((function(e){var t=n.select(this),a=i.ensureSingle(t,"g","layers");a.style("opacity",e[0].trace.opacity);var l=r.indentation,s=r.valign,c=e[0].lineHeight,u=e[0].height;if("middle"===s&&0===l||!c||!u)a.attr("transform",null);else{var f={top:1,bottom:-1}[s]*(.5*(c-u+3))||0,d=r.indentation;a.attr("transform",o(d,f))}a.selectAll("g.legendfill").data([e]).enter().append("g").classed("legendfill",!0),a.selectAll("g.legendlines").data([e]).enter().append("g").classed("legendlines",!0);var h=a.selectAll("g.legendsymbols").data([e]);h.enter().append("g").classed("legendsymbols",!0),h.selectAll("g.legendpoints").data([e]).enter().append("g").classed("legendpoints",!0)})).each((function(e){var r,a=e[0].trace,o=[];if(a.visible)switch(a.type){case"histogram2d":case"heatmap":o=[["M-15,-2V4H15V-2Z"]],r=!0;break;case"choropleth":case"choroplethmapbox":o=[["M-6,-6V6H6V-6Z"]],r=!0;break;case"densitymapbox":o=[["M-6,0 a6,6 0 1,0 12,0 a 6,6 0 1,0 -12,0"]],r="radial";break;case"cone":o=[["M-6,2 A2,2 0 0,0 -6,6 V6L6,4Z"],["M-6,-6 A2,2 0 0,0 -6,-2 L6,-4Z"],["M-6,-2 A2,2 0 0,0 -6,2 L6,0Z"]],r=!1;break;case"streamtube":o=[["M-6,2 A2,2 0 0,0 -6,6 H6 A2,2 0 0,1 6,2 Z"],["M-6,-6 A2,2 0 0,0 -6,-2 H6 A2,2 0 0,1 6,-6 Z"],["M-6,-2 A2,2 0 0,0 -6,2 H6 A2,2 0 0,1 6,-2 Z"]],r=!1;break;case"surface":o=[["M-6,-6 A2,3 0 0,0 -6,0 H6 A2,3 0 0,1 6,-6 Z"],["M-6,1 A2,3 0 0,1 -6,6 H6 A2,3 0 0,0 6,0 Z"]],r=!0;break;case"mesh3d":o=[["M-6,6H0L-6,-6Z"],["M6,6H0L6,-6Z"],["M-6,-6H6L0,6Z"]],r=!1;break;case"volume":o=[["M-6,6H0L-6,-6Z"],["M6,6H0L6,-6Z"],["M-6,-6H6L0,6Z"]],r=!0;break;case"isosurface":o=[["M-6,6H0L-6,-6Z"],["M6,6H0L6,-6Z"],["M-6,-6 A12,24 0 0,0 6,-6 L0,6Z"]],r=!1}var u=n.select(this).select("g.legendpoints").selectAll("path.legend3dandfriends").data(o);u.enter().append("path").classed("legend3dandfriends",!0).attr("transform",_).style("stroke-miterlimit",1),u.exit().remove(),u.each((function(e,o){var u,f=n.select(this),d=c(a),h=d.colorscale,v=d.reversescale;if(h){if(!r){var y=h.length;u=0===o?h[v?y-1:0][1]:1===o?h[v?0:y-1][1]:h[Math.floor((y-1)/2)][1]}}else{var g=a.vertexcolor||a.facecolor||a.color;u=i.isArrayOrTypedArray(g)?g[o]||g[0]:g}f.attr("d",e[0]),u?f.call(s.fill,u):f.call((function(e){if(e.size()){var n="legendfill-"+a.uid;l.gradient(e,t,n,p(v,"radial"===r),h,"fill")}}))}))})).each((function(e){var t=e[0].trace,r="waterfall"===t.type;if(e[0]._distinct&&r){var a=e[0].trace[e[0].dir].marker;return e[0].mc=a.color,e[0].mlw=a.line.width,e[0].mlc=a.line.color,T(e,this,"waterfall")}var i=[];t.visible&&r&&(i=e[0].hasTotals?[["increasing","M-6,-6V6H0Z"],["totals","M6,6H0L-6,-6H-0Z"],["decreasing","M6,6V-6H0Z"]]:[["increasing","M-6,-6V6H6Z"],["decreasing","M6,6V-6H-6Z"]]);var o=n.select(this).select("g.legendpoints").selectAll("path.legendwaterfall").data(i);o.enter().append("path").classed("legendwaterfall",!0).attr("transform",_).style("stroke-miterlimit",1),o.exit().remove(),o.each((function(e){var r=n.select(this),a=t[e[0]].marker,i=w(void 0,a.line,5,2);r.attr("d",e[1]).style("stroke-width",i+"px").call(s.fill,a.color),i&&r.call(s.stroke,a.line.color)}))})).each((function(e){T(e,this,"funnel")})).each((function(e){T(e,this)})).each((function(e){var r=e[0].trace,o=n.select(this).select("g.legendpoints").selectAll("path.legendbox").data(r.visible&&a.traceIs(r,"box-violin")?[e]:[]);o.enter().append("path").classed("legendbox",!0).attr("d","M6,6H-6V-6H6Z").attr("transform",_),o.exit().remove(),o.each((function(){var e=n.select(this);if("all"!==r.boxpoints&&"all"!==r.points||0!==s.opacity(r.fillcolor)||0!==s.opacity((r.line||{}).color)){var a=w(void 0,r.line,5,2);e.style("stroke-width",a+"px").call(s.fill,r.fillcolor),a&&s.stroke(e,r.line.color)}else{var c=i.minExtend(r,{marker:{size:m?12:i.constrain(r.marker.size,2,16),sizeref:1,sizemin:1,sizemode:"diameter"}});o.call(l.pointStyle,c,t)}}))})).each((function(e){M(e,this,"funnelarea")})).each((function(e){M(e,this,"pie")})).each((function(e){var r,a,o=v(e),s=o.showFill,f=o.showLine,d=o.showGradientLine,h=o.showGradientFill,y=o.anyFill,g=o.anyLine,m=e[0],b=m.trace,_=c(b),T=_.colorscale,M=_.reversescale,k=u.hasMarkers(b)||!y?"M5,0":g?"M5,-2":"M5,-3",A=n.select(this),L=A.select(".legendfill").selectAll("path").data(s||h?[e]:[]);if(L.enter().append("path").classed("js-fill",!0),L.exit().remove(),L.attr("d",k+"h"+x+"v6h-"+x+"z").call((function(e){if(e.size())if(s)l.fillGroupStyle(e,t,!0);else{var r="legendfill-"+b.uid;l.gradient(e,t,r,p(M),T,"fill")}})),f||d){var S=w(void 0,b.line,10,5);a=i.minExtend(b,{line:{width:S}}),r=[i.minExtend(m,{trace:a})]}var O=A.select(".legendlines").selectAll("path").data(f||d?[r]:[]);O.enter().append("path").classed("js-line",!0),O.exit().remove(),O.attr("d",k+(d?"l"+x+",0.0001":"h"+x)).call(f?l.lineGroupStyle:function(e){if(e.size()){var r="legendline-"+b.uid;l.lineGroupStyle(e),l.gradient(e,t,r,p(M),T,"stroke")}})})).each((function(e){var r,a,o=v(e),s=o.anyFill,c=o.anyLine,f=o.showLine,d=o.showMarker,h=e[0],p=h.trace,y=!d&&!c&&!s&&u.hasText(p);function g(e,t,r,n){var a=i.nestedProperty(p,e).get(),o=i.isArrayOrTypedArray(a)&&t?t(a):a;if(m&&o&&void 0!==n&&(o=n),r){if(or[1])return r[1]}return o}function x(e){return h._distinct&&h.index&&e[h.index]?e[h.index]:e[0]}if(d||y||f){var b={},w={};if(d){b.mc=g("marker.color",x),b.mx=g("marker.symbol",x),b.mo=g("marker.opacity",i.mean,[.2,1]),b.mlc=g("marker.line.color",x),b.mlw=g("marker.line.width",i.mean,[0,5],2),w.marker={sizeref:1,sizemin:1,sizemode:"diameter"};var T=g("marker.size",i.mean,[2,16],12);b.ms=T,w.marker.size=T}f&&(w.line={width:g("line.width",x,[0,10],5)}),y&&(b.tx="Aa",b.tp=g("textposition",x),b.ts=10,b.tc=g("textfont.color",x),b.tf=g("textfont.family",x),b.tw=g("textfont.weight",x),b.ty=g("textfont.style",x),b.tv=g("textfont.variant",x)),r=[i.minExtend(h,b)],(a=i.minExtend(p,w)).selectedpoints=null,a.texttemplate=null}var M=n.select(this).select("g.legendpoints"),k=M.selectAll("path.scatterpts").data(d?r:[]);k.enter().insert("path",":first-child").classed("scatterpts",!0).attr("transform",_),k.exit().remove(),k.call(l.pointStyle,a,t),d&&(r[0].mrc=3);var A=M.selectAll("g.pointtext").data(y?r:[]);A.enter().append("g").classed("pointtext",!0).append("text").attr("transform",_),A.exit().remove(),A.selectAll("text").call(l.textPointStyle,a,t)})).each((function(e){var t=e[0].trace,r=n.select(this).select("g.legendpoints").selectAll("path.legendcandle").data(t.visible&&"candlestick"===t.type?[e,e]:[]);r.enter().append("path").classed("legendcandle",!0).attr("d",(function(e,t){return t?"M-15,0H-8M-8,6V-6H8Z":"M15,0H8M8,-6V6H-8Z"})).attr("transform",_).style("stroke-miterlimit",1),r.exit().remove(),r.each((function(e,r){var a=n.select(this),i=t[r?"increasing":"decreasing"],o=w(void 0,i.line,5,2);a.style("stroke-width",o+"px").call(s.fill,i.fillcolor),o&&s.stroke(a,i.line.color)}))})).each((function(e){var t=e[0].trace,r=n.select(this).select("g.legendpoints").selectAll("path.legendohlc").data(t.visible&&"ohlc"===t.type?[e,e]:[]);r.enter().append("path").classed("legendohlc",!0).attr("d",(function(e,t){return t?"M-15,0H0M-8,-6V0":"M15,0H0M8,6V0"})).attr("transform",_).style("stroke-miterlimit",1),r.exit().remove(),r.each((function(e,r){var a=n.select(this),i=t[r?"increasing":"decreasing"],o=w(void 0,i.line,5,2);a.style("fill","none").call(l.dashLine,i.line.dash,o),o&&s.stroke(a,i.line.color)}))}))}},6540:function(e,t,r){"use strict";r(6052),e.exports={editType:"modebar",orientation:{valType:"enumerated",values:["v","h"],dflt:"h",editType:"modebar"},bgcolor:{valType:"color",editType:"modebar"},color:{valType:"color",editType:"modebar"},activecolor:{valType:"color",editType:"modebar"},uirevision:{valType:"any",editType:"none"},add:{valType:"string",arrayOk:!0,dflt:"",editType:"modebar"},remove:{valType:"string",arrayOk:!0,dflt:"",editType:"modebar"}}},1868:function(e,t,r){"use strict";var n=r(4040),a=r(7316),i=r(9811),o=r(9224),l=r(4016).eraseActiveShape,s=r(3400),c=s._,u=e.exports={};function f(e,t){var r,a,o=t.currentTarget,l=o.getAttribute("data-attr"),s=o.getAttribute("data-val")||!0,c=e._fullLayout,u={},f=i.list(e,null,!0),d=c._cartesianSpikesEnabled;if("zoom"===l){var h,p="in"===s?.5:2,v=(1+p)/2,y=(1-p)/2;for(a=0;a1?(P=["toggleHover"],I=["resetViews"]):g?(C=["zoomInGeo","zoomOutGeo"],P=["hoverClosestGeo"],I=["resetGeo"]):y?(P=["hoverClosest3d"],I=["resetCameraDefault3d","resetCameraLastSave3d"]):w?(C=["zoomInMapbox","zoomOutMapbox"],P=["toggleHover"],I=["resetViewMapbox"]):b?P=["hoverClosestGl2d"]:m?P=["hoverClosestPie"]:k?(P=["hoverClosestCartesian","hoverCompareCartesian"],I=["resetViewSankey"]):P=["toggleHover"],v&&(P=["toggleSpikelines","hoverClosestCartesian","hoverCompareCartesian"]),(function(e){for(var t=0;t0)){var v=function(e,t,r){for(var n=r.filter((function(r){return t[r].anchor===e._id})),a=0,i=0;i0?e.touches[0].clientX:0}function g(e,t,r,n){var a=o.ensureSingle(e,"rect",v.bgClassName,(function(e){e.attr({x:0,y:0,"shape-rendering":"crispEdges"})})),i=n.borderwidth%2==0?n.borderwidth:n.borderwidth-1,u=-n._offsetShift,f=s.crispRound(t,n.borderwidth);a.attr({width:n._width+i,height:n._height+i,transform:l(u,u),"stroke-width":f}).call(c.stroke,n.bordercolor).call(c.fill,n.bgcolor)}function m(e,t,r,n){var a=t._fullLayout;o.ensureSingleById(a._topdefs,"clipPath",n._clipId,(function(e){e.append("rect").attr({x:0,y:0})})).select("rect").attr({width:n._width,height:n._height})}function x(e,t,r,a){var l,c=t.calcdata,u=e.selectAll("g."+v.rangePlotClassName).data(r._subplotsWith,o.identity);u.enter().append("g").attr("class",(function(e){return v.rangePlotClassName+" "+e})).call(s.setClipUrl,a._clipId,t),u.order(),u.exit().remove(),u.each((function(e,o){var s=n.select(this),u=0===o,h=d.getFromId(t,e,"y"),p=h._name,v=a[p],y={data:[],layout:{xaxis:{type:r.type,domain:[0,1],range:a.range.slice(),calendar:r.calendar},width:a._width,height:a._height,margin:{t:0,b:0,l:0,r:0}},_context:t._context};r.rangebreaks&&(y.layout.xaxis.rangebreaks=r.rangebreaks),y.layout[p]={type:h.type,domain:[0,1],range:"match"!==v.rangemode?v.range.slice():h.range.slice(),calendar:h.calendar},h.rangebreaks&&(y.layout[p].rangebreaks=h.rangebreaks),i.supplyDefaults(y);var g=y._fullLayout.xaxis,m=y._fullLayout[p];g.clearCalc(),g.setScale(),m.clearCalc(),m.setScale();var x={id:e,plotgroup:s,xaxis:g,yaxis:m,isRangePlot:!0};u?l=x:(x.mainplot="xy",x.mainplotinfo=l),f.rangePlot(t,x,function(e,t){for(var r=[],n=0;n=n.max)t=F[r+1];else if(e=n.pmax)t=F[r+1];else if(er._length||m+_<0)return;u=g+_,h=m+_;break;case s:if(b="col-resize",g+_>r._length)return;u=g+_,h=m;break;case c:if(b="col-resize",m+_<0)return;u=g,h=m+_;break;default:b="ew-resize",u=v,h=v+_}if(h=0;M--){var k=r.append("path").attr(y).style("opacity",M?.1:g).call(o.stroke,x).call(o.fill,m).call(l.dashLine,M?"solid":_,M?4+b:b);if(p(k,e,i),w){var A=s(e.layout,"selections",i);k.style({cursor:"move"});var L={element:k.node(),plotinfo:h,gd:e,editHelpers:A,isActiveSelection:!0},S=n(c,e);a(S,k,L)}else k.style("pointer-events",M?"all":"none");T[M]=k}var O=T[0];T[1].node().addEventListener("click",(function(){return function(e,t){if(d(e)){var r=t.node(),n=+r.getAttribute("data-index");if(n>=0){if(n===e._fullLayout._activeSelectionIndex)return void v(e);e._fullLayout._activeSelectionIndex=n,e._fullLayout._deactivateSelection=v,f(e)}}}(e,O)}))}(e._fullLayout._selectionLayer)}function p(e,t,r){var n=r.xref+r.yref;l.setClipUrl(e,"clip"+t._fullLayout._uid+n,t)}function v(e){d(e)&&e._fullLayout._activeSelectionIndex>=0&&(i(e),delete e._fullLayout._activeSelectionIndex,f(e))}e.exports={draw:f,drawOne:h,activateLastSelection:function(e){if(d(e)){var t=e._fullLayout.selections.length-1;e._fullLayout._activeSelectionIndex=t,e._fullLayout._deactivateSelection=v,f(e)}}}},4200:function(e,t,r){"use strict";var n=r(8192).u,a=r(2880).extendFlat;e.exports={newselection:{mode:{valType:"enumerated",values:["immediate","gradual"],dflt:"immediate",editType:"none"},line:{color:{valType:"color",editType:"none"},width:{valType:"number",min:1,dflt:1,editType:"none"},dash:a({},n,{dflt:"dot",editType:"none"}),editType:"none"},editType:"none"},activeselection:{fillcolor:{valType:"color",dflt:"rgba(0,0,0,0)",editType:"none"},opacity:{valType:"number",min:0,max:1,dflt:.5,editType:"none"},editType:"none"}}},1004:function(e){"use strict";e.exports=function(e,t,r){r("newselection.mode"),r("newselection.line.width")&&(r("newselection.line.color"),r("newselection.line.dash")),r("activeselection.fillcolor"),r("activeselection.opacity")}},5968:function(e,t,r){"use strict";var n=r(2760).selectMode,a=r(1936).clearOutline,i=r(9856),o=i.readPaths,l=i.writePaths,s=i.fixDatesForPaths;e.exports=function(e,t){if(e.length){var r=e[0][0];if(r){var i=r.getAttribute("d"),c=t.gd,u=c._fullLayout.newselection,f=t.plotinfo,d=f.xaxis,h=f.yaxis,p=t.isActiveSelection,v=t.dragmode,y=(c.layout||{}).selections||[];if(!n(v)&&void 0!==p){var g=c._fullLayout._activeSelectionIndex;if(g-1,b=[];if(function(e){return e&&Array.isArray(e)&&!0!==e[0].hoverOnBox}(g)){G(e,t,i);var _=function(e,t){var r,n,a=e[0],i=-1,o=[];for(n=0;n0?function(e,t){var r,n,a,i=[];for(a=0;a0&&i.push(r);if(1===i.length&&i[0]===t.searchInfo&&(n=t.searchInfo.cd[0].trace).selectedpoints.length===t.pointNumbers.length){for(a=0;a