diff --git a/404.html b/404.html index 103ed2714f..8fc67ce917 100644 --- a/404.html +++ b/404.html @@ -17,8 +17,8 @@ - - + + @@ -100,7 +100,7 @@
- - + + \ No newline at end of file diff --git a/Demo/Demo/index.html b/Demo/Demo/index.html index 4650f15341..d32e27e5ae 100644 --- a/Demo/Demo/index.html +++ b/Demo/Demo/index.html @@ -17,8 +17,8 @@ - - + + @@ -100,7 +100,7 @@
- - + + \ No newline at end of file diff --git a/Home/Home/index.html b/Home/Home/index.html index f12abc42db..453d31f7e5 100644 --- a/Home/Home/index.html +++ b/Home/Home/index.html @@ -17,8 +17,8 @@ - - + + @@ -100,7 +100,7 @@
- - + + \ No newline at end of file diff --git a/Playground/Playground/index.html b/Playground/Playground/index.html index ba1376a92e..4fb1efc9ed 100644 --- a/Playground/Playground/index.html +++ b/Playground/Playground/index.html @@ -17,8 +17,8 @@ - - + + @@ -100,7 +100,7 @@
- - + + \ No newline at end of file diff --git a/assets/js/000be755.0ead002c.js b/assets/js/000be755.a825b08e.js similarity index 97% rename from assets/js/000be755.0ead002c.js rename to assets/js/000be755.a825b08e.js index c5e8e1be15..f52382416e 100644 --- a/assets/js/000be755.0ead002c.js +++ b/assets/js/000be755.a825b08e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6688],{3905:function(e,t,r){r.d(t,{Zo:function(){return u},kt:function(){return f}});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),c=l(r),m=a,f=c["".concat(s,".").concat(m)]||c[m]||d[m]||o;return r?n.createElement(f,i(i({ref:t},u),{},{components:r})):n.createElement(f,i({ref:t},u))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[c]="string"==typeof e?e:a,i[1]=p;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),c=l(r),m=a,f=c["".concat(s,".").concat(m)]||c[m]||d[m]||o;return r?n.createElement(f,i(i({ref:t},u),{},{components:r})):n.createElement(f,i({ref:t},u))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[c]="string"==typeof e?e:a,i[1]=p;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),u=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=u(e.components);return a.createElement(c.Provider,{value:t},e.children)},h="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),h=u(n),d=r,y=h["".concat(c,".").concat(d)]||h[d]||p[d]||o;return n?a.createElement(y,i(i({ref:t},l),{},{components:n})):a.createElement(y,i({ref:t},l))}));function y(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[h]="string"==typeof e?e:r,i[1]=s;for(var u=2;u=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),u=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=u(e.components);return a.createElement(c.Provider,{value:t},e.children)},h="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),h=u(n),d=r,y=h["".concat(c,".").concat(d)]||h[d]||p[d]||o;return n?a.createElement(y,i(i({ref:t},l),{},{components:n})):a.createElement(y,i({ref:t},l))}));function y(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[h]="string"==typeof e?e:r,i[1]=s;for(var u=2;u=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=s(e,["components","mdxType","originalType","parentName"]),u=l(r),m=a,y=u["".concat(p,".").concat(m)]||u[m]||f[m]||o;return r?n.createElement(y,c(c({ref:t},i),{},{components:r})):n.createElement(y,c({ref:t},i))}));function y(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,c=new Array(o);c[0]=m;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:a,c[1]=s;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=s(e,["components","mdxType","originalType","parentName"]),u=l(r),m=a,y=u["".concat(p,".").concat(m)]||u[m]||f[m]||o;return r?n.createElement(y,c(c({ref:t},i),{},{components:r})):n.createElement(y,c({ref:t},i))}));function y(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,c=new Array(o);c[0]=m;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:a,c[1]=s;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),i=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=i(e.components);return a.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},k=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=i(n),k=r,m=u["".concat(l,".").concat(k)]||u[k]||d[k]||o;return n?a.createElement(m,s(s({ref:t},p),{},{components:n})):a.createElement(m,s({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=k;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[u]="string"==typeof e?e:r,s[1]=c;for(var i=2;icep18_test_contract Contract Package",id:"install-the-cep18_test_contract-contract-package",level:2},{value:"Next Steps",id:"next-steps",level:3}],d={toc:u},k="wrapper";function m(e){var t=e.components,n=(0,r.Z)(e,s);return(0,o.kt)(k,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"installing-and-interacting-with-a-cep-18-contract"},"Installing and Interacting with a CEP-18 Contract"),(0,o.kt)("p",null,"This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live"},"Casper network"),"."),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"https://eips.ethereum.org/EIPS/eip-20#specification"},"Ethereum Request for Comment (ERC-20)")," standard defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed. These fungible tokens are blockchain-based assets that have value and can be transferred or recorded."),(0,o.kt)("p",null,"To execute transactions on a Casper network (involving fungible tokens), you will need some CSPR tokens to pay for the transactions."),(0,o.kt)("p",null,"For greater detail into the creation and mechanics of the Casper fungible token contract, see the full ",(0,o.kt)("a",{parentName:"p",href:"/resources/tokens/cep18/full-tutorial"},"Casper Fungible Token Tutorial"),"."),(0,o.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,o.kt)("p",null,"Before using this guide, ensure you meet the following requirements:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Set up your machine as per the ",(0,o.kt)("a",{parentName:"li",href:"/developers/prerequisites/"},"prerequisites")),(0,o.kt)("li",{parentName:"ul"},"Use the ","[Casper command-line client]"),(0,o.kt)("li",{parentName:"ul"},"Get a valid ",(0,o.kt)("a",{parentName:"li",href:"https://cspr.live/tools/peers"},(0,o.kt)("inlineCode",{parentName:"a"},"node-address"))),(0,o.kt)("li",{parentName:"ul"},"Know how to deploy a ",(0,o.kt)("a",{parentName:"li",href:"/developers/cli/sending-deploys/"},"smart contract")," to a Casper network"),(0,o.kt)("li",{parentName:"ul"},"Hold enough CSPR tokens to pay for transactions")),(0,o.kt)("h1",{id:"setup"},"Setup"),(0,o.kt)("p",null,"Clone the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep18"},"fungible token (CEP-18) contract repository")," and run the ",(0,o.kt)("inlineCode",{parentName:"p"},"make build-contract")," command. This will create the ",(0,o.kt)("inlineCode",{parentName:"p"},"cep18.wasm")," and the ",(0,o.kt)("inlineCode",{parentName:"p"},"cep18_test_contract.wasm"),". The token Wasm is the main contract. We will use the ",(0,o.kt)("inlineCode",{parentName:"p"},"cep18_test_contract")," Wasm to query the balances and allowances of the fungible token balances throughout this workflow."),(0,o.kt)("h2",{id:"install-the-main-fungible-token-contract"},"Install the Main Fungible Token Contract"),(0,o.kt)("p",null,"The following command will create a deploy containing the CEP-18 contract instance using your supplied arguments as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Name")," - The name of your CEP-18 token"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Symbol")," - The symbol used to refer to your CEP-18 token"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Total_supply")," - The total supply of the CEP-18 token to be minted"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Decimals")," - The number of spaces after the decimal. (As an example, a total supply of 1000000 with a ",(0,o.kt)("inlineCode",{parentName:"li"},"decimals")," setting of 3 would be 1,000.000 tokens)")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy -n http://: \\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-path ~/casper/demo/cep18.wasm \\\n--session-arg \"name:string='CEP18'\" \\\n--session-arg \"symbol:string='gris'\" \\\n--session-arg \"total_supply:u256='100'\" \\\n--session-arg \"decimals:u8='1'\" \\\n--payment-amount 150000000000\n")),(0,o.kt)("h2",{id:"install-the-cep18_test_contract-contract-package"},"Install the ",(0,o.kt)("inlineCode",{parentName:"h2"},"cep18_test_contract")," Contract Package"),(0,o.kt)("p",null,"The following command will install the CEP-18 helper contract that allows you to check balances and access approval features."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy -n http://: \\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-path ~/casper/demo/cep18_test_contract.wasm \\\n--payment-amount 50000000000\n")),(0,o.kt)("p",null,"At this point, the account that installed both the main contract and the helper contract will look like this."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "src": {\n "Account": {\n "_accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",\n "namedKeys": [\n {\n "name": "cep18_test_contract",\n "key": "hash-999326ca8408dfd37da023eb6fd82f174151be64f83f9fb837632a0d69fd4c7e"\n },\n {\n "name": "cep18_token_contract",\n "key": "hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180"\n },\n ],\n "mainPurse": "uref-6c062525debdee18d5cad083ca530fcb65ef8741574fba4c97673f4ed00093f7-007",\n "associatedKeys": [\n {\n "accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",\n "weight": 1\n }\n ],\n "actionThresholds": {\n "deployment": 1,\n "keyManagement": 1\n }\n }\n }\n}\n')),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("em",{parentName:"strong"},"Note:"))),(0,o.kt)("blockquote",null,(0,o.kt)("ol",{parentName:"blockquote"},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"cep18_token_contract")," is the main contract, and is a stored contract, record its hash"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"cep18_test_call")," is a contract package which contains the utility contract required to read the balances and allowances of users within the fungible token state."))),(0,o.kt)("h3",{id:"next-steps"},"Next Steps"),(0,o.kt)("p",null,"In the following sections, the sample guide explains the querying of the contract package, token transfers, and approvals."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/resources/tokens/cep18/query"},"Exploring the CEP18 Contracts")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/resources/tokens/cep18/transfer"},"CEP-18 Token Transfers and Allowances")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/resources/tokens/cep18/tests"},"Testing Framework for CEP-18"))))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[1598],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),i=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=i(e.components);return a.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},k=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=i(n),k=r,m=u["".concat(l,".").concat(k)]||u[k]||d[k]||o;return n?a.createElement(m,s(s({ref:t},p),{},{components:n})):a.createElement(m,s({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=k;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[u]="string"==typeof e?e:r,s[1]=c;for(var i=2;icep18_test_contract Contract Package",id:"install-the-cep18_test_contract-contract-package",level:2},{value:"Next Steps",id:"next-steps",level:3}],d={toc:u},k="wrapper";function m(e){var t=e.components,n=(0,r.Z)(e,s);return(0,o.kt)(k,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"installing-and-interacting-with-a-cep-18-contract"},"Installing and Interacting with a CEP-18 Contract"),(0,o.kt)("p",null,"This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live"},"Casper network"),"."),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"https://eips.ethereum.org/EIPS/eip-20#specification"},"Ethereum Request for Comment (ERC-20)")," standard defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed. These fungible tokens are blockchain-based assets that have value and can be transferred or recorded."),(0,o.kt)("p",null,"To execute transactions on a Casper network (involving fungible tokens), you will need some CSPR tokens to pay for the transactions."),(0,o.kt)("p",null,"For greater detail into the creation and mechanics of the Casper fungible token contract, see the full ",(0,o.kt)("a",{parentName:"p",href:"/resources/tokens/cep18/full-tutorial"},"Casper Fungible Token Tutorial"),"."),(0,o.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,o.kt)("p",null,"Before using this guide, ensure you meet the following requirements:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Set up your machine as per the ",(0,o.kt)("a",{parentName:"li",href:"/developers/prerequisites/"},"prerequisites")),(0,o.kt)("li",{parentName:"ul"},"Use the ","[Casper command-line client]"),(0,o.kt)("li",{parentName:"ul"},"Get a valid ",(0,o.kt)("a",{parentName:"li",href:"https://cspr.live/tools/peers"},(0,o.kt)("inlineCode",{parentName:"a"},"node-address"))),(0,o.kt)("li",{parentName:"ul"},"Know how to deploy a ",(0,o.kt)("a",{parentName:"li",href:"/developers/cli/sending-deploys/"},"smart contract")," to a Casper network"),(0,o.kt)("li",{parentName:"ul"},"Hold enough CSPR tokens to pay for transactions")),(0,o.kt)("h1",{id:"setup"},"Setup"),(0,o.kt)("p",null,"Clone the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep18"},"fungible token (CEP-18) contract repository")," and run the ",(0,o.kt)("inlineCode",{parentName:"p"},"make build-contract")," command. This will create the ",(0,o.kt)("inlineCode",{parentName:"p"},"cep18.wasm")," and the ",(0,o.kt)("inlineCode",{parentName:"p"},"cep18_test_contract.wasm"),". The token Wasm is the main contract. We will use the ",(0,o.kt)("inlineCode",{parentName:"p"},"cep18_test_contract")," Wasm to query the balances and allowances of the fungible token balances throughout this workflow."),(0,o.kt)("h2",{id:"install-the-main-fungible-token-contract"},"Install the Main Fungible Token Contract"),(0,o.kt)("p",null,"The following command will create a deploy containing the CEP-18 contract instance using your supplied arguments as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Name")," - The name of your CEP-18 token"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Symbol")," - The symbol used to refer to your CEP-18 token"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Total_supply")," - The total supply of the CEP-18 token to be minted"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Decimals")," - The number of spaces after the decimal. (As an example, a total supply of 1000000 with a ",(0,o.kt)("inlineCode",{parentName:"li"},"decimals")," setting of 3 would be 1,000.000 tokens)")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy -n http://: \\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-path ~/casper/demo/cep18.wasm \\\n--session-arg \"name:string='CEP18'\" \\\n--session-arg \"symbol:string='gris'\" \\\n--session-arg \"total_supply:u256='100'\" \\\n--session-arg \"decimals:u8='1'\" \\\n--payment-amount 150000000000\n")),(0,o.kt)("h2",{id:"install-the-cep18_test_contract-contract-package"},"Install the ",(0,o.kt)("inlineCode",{parentName:"h2"},"cep18_test_contract")," Contract Package"),(0,o.kt)("p",null,"The following command will install the CEP-18 helper contract that allows you to check balances and access approval features."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy -n http://: \\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-path ~/casper/demo/cep18_test_contract.wasm \\\n--payment-amount 50000000000\n")),(0,o.kt)("p",null,"At this point, the account that installed both the main contract and the helper contract will look like this."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "src": {\n "Account": {\n "_accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",\n "namedKeys": [\n {\n "name": "cep18_test_contract",\n "key": "hash-999326ca8408dfd37da023eb6fd82f174151be64f83f9fb837632a0d69fd4c7e"\n },\n {\n "name": "cep18_token_contract",\n "key": "hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180"\n },\n ],\n "mainPurse": "uref-6c062525debdee18d5cad083ca530fcb65ef8741574fba4c97673f4ed00093f7-007",\n "associatedKeys": [\n {\n "accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",\n "weight": 1\n }\n ],\n "actionThresholds": {\n "deployment": 1,\n "keyManagement": 1\n }\n }\n }\n}\n')),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("em",{parentName:"strong"},"Note:"))),(0,o.kt)("blockquote",null,(0,o.kt)("ol",{parentName:"blockquote"},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"cep18_token_contract")," is the main contract, and is a stored contract, record its hash"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"cep18_test_call")," is a contract package which contains the utility contract required to read the balances and allowances of users within the fungible token state."))),(0,o.kt)("h3",{id:"next-steps"},"Next Steps"),(0,o.kt)("p",null,"In the following sections, the sample guide explains the querying of the contract package, token transfers, and approvals."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/resources/tokens/cep18/query"},"Exploring the CEP18 Contracts")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/resources/tokens/cep18/transfer"},"CEP-18 Token Transfers and Allowances")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/resources/tokens/cep18/tests"},"Testing Framework for CEP-18"))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/04253889.efcb9c95.js b/assets/js/04253889.cd7cd926.js similarity index 99% rename from assets/js/04253889.efcb9c95.js rename to assets/js/04253889.cd7cd926.js index d6f27fe084..4bec8d3a40 100644 --- a/assets/js/04253889.efcb9c95.js +++ b/assets/js/04253889.cd7cd926.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[9415],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=o.createContext({}),u=function(e){var t=o.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=u(e.components);return o.createElement(i.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,i=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=u(n),h=a,m=c["".concat(i,".").concat(h)]||c[h]||d[h]||r;return n?o.createElement(m,s(s({ref:t},p),{},{components:n})):o.createElement(m,s({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,s=new Array(r);s[0]=h;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[c]="string"==typeof e?e:a,s[1]=l;for(var u=2;ucasper-client (Optional)",id:"enable-bash-auto-completion-for-casper-client-optional",level:2},{value:"Installing All Protocols",id:"installing-all-protocols",level:2},{value:"Validator Keys",id:"validator-keys",level:2},{value:"Getting a Trusted Hash",id:"getting-a-trusted-hash",level:2},{value:"Node Address",id:"node-address",level:3},{value:"Protocol Version",id:"protocol-version",level:3},{value:"Load trusted_hash in Config.toml of the Protocol Version",id:"load-trusted_hash-in-configtoml-of-the-protocol-version",level:3},{value:"Syncing to Genesis",id:"syncing-to-genesis",level:2},{value:"Starting the Node",id:"starting-the-node",level:2},{value:"Monitoring the Synchronization Process",id:"monitoring-the-synchronization-process",level:3},{value:"Monitoring the Running Node",id:"monitoring-the-running-node",level:3},{value:"A Note on Speculative Execution",id:"a-note-on-speculative-execution",level:2}],d={toc:c},h="wrapper";function m(e){var t=e.components,n=(0,a.Z)(e,s);return(0,r.kt)(h,(0,o.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"installing-a-node"},"Installing a Node"),(0,r.kt)("p",null,"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet."),(0,r.kt)("h2",{id:"network-requirements"},"Network Requirements"),(0,r.kt)("p",null,"The following ports are used by the node:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"35000 (required to be externally visible)"),(0,r.kt)("li",{parentName:"ul"},"7777 RPC endpoint for interaction with JSON-RPC API"),(0,r.kt)("li",{parentName:"ul"},"8888 REST endpoint for status and metrics (having this accessible allows your node to be part of network status)"),(0,r.kt)("li",{parentName:"ul"},"9999 SSE endpoint for event stream")),(0,r.kt)("p",null,"Of these ",(0,r.kt)("inlineCode",{parentName:"p"},"35000")," is the only port required to be open for your node to function, however, opening ",(0,r.kt)("inlineCode",{parentName:"p"},"8888")," will allow others to know general network health. For more details, see the additional information on ",(0,r.kt)("a",{parentName:"p",href:"/operators/setup/node-endpoints"},"Node Endpoints"),"."),(0,r.kt)("h2",{id:"operating-system-requirements"},"Operating System Requirements"),(0,r.kt)("p",null,"The recommended OS version is Ubuntu 20.04."),(0,r.kt)("h3",{id:"using-ubuntu-2204"},"Using Ubuntu 22.04"),(0,r.kt)("p",null,"Installing using Ubuntu 22.04 follows the same instructions as 20.04 with one exception:"),(0,r.kt)("p",null,"If you try to install packages, you will receive:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"casper-client : Depends: libssl1.1 (>= 1.1.0) but it is not installable\n")),(0,r.kt)("p",null,"This message is due to the default ",(0,r.kt)("inlineCode",{parentName:"p"},"openssl")," moving to 3.",(0,r.kt)("em",{parentName:"p"}," with Ubuntu 22.04. You need to install OpenSSL 1.")," for prior versions of Ubuntu to use the Casper binaries with the following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"curl -f -JLO http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb\nsudo apt install ./libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb\n")),(0,r.kt)("h2",{id:"required-number-of-open-files"},"Required Number of Open Files"),(0,r.kt)("p",null,"Before beginning, ",(0,r.kt)("a",{parentName:"p",href:"/operators/setup/open-files"},"update the maximum open files limit")," for your system. Specifically, update the node's ",(0,r.kt)("inlineCode",{parentName:"p"},"/etc/security/limits.conf")," file as described ",(0,r.kt)("a",{parentName:"p",href:"/operators/setup/open-files#updating-limits-conf"},"here"),", to ensure proper node operation."),(0,r.kt)("h2",{id:"required-clean-up"},"Required Clean Up"),(0,r.kt)("p",null,"If you were running a previous node on this box, this will clean up state. If packages are not installed, the ",(0,r.kt)("inlineCode",{parentName:"p"},"apt remove")," may give errors, but this is not a problem."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo systemctl stop casper-node-launcher.service\nsudo apt remove -y casper-client\nsudo apt remove -y casper-node\nsudo apt remove -y casper-node-launcher\nsudo rm /etc/casper/casper-node-launcher-state.toml\nsudo rm -rf /etc/casper/1_*\nsudo rm -rf /var/lib/casper/*\n")),(0,r.kt)("h2",{id:"required-packages"},"Required Packages"),(0,r.kt)("p",null,"The following commands will set up the Casper Labs repository for packages:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'echo "deb [arch=amd64] https://repo.casperlabs.io/releases focal main" | sudo tee -a /etc/apt/sources.list.d/casper.list\ncurl -O https://repo.casperlabs.io/casper-repo-pubkey.asc\nsudo apt-key add casper-repo-pubkey.asc\nsudo apt update\n')),(0,r.kt)("h2",{id:"required-tools"},"Required Tools"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt install -y casper-client casper-node-launcher jq\n")),(0,r.kt)("h2",{id:"enable-bash-auto-completion-for-casper-client-optional"},"Enable Bash Auto-Completion for ",(0,r.kt)("inlineCode",{parentName:"h2"},"casper-client")," (Optional)"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo casper-client generate-completion\n")),(0,r.kt)("p",null,"It defaults to ",(0,r.kt)("inlineCode",{parentName:"p"},"bash")," but can be changed with the ",(0,r.kt)("inlineCode",{parentName:"p"},"--shell")," argument:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"--shell The type of shell to generate the completion script for [default: bash] [possible values:\n zsh, bash, fish, powershell, elvish]\n\nsudo casper-client generate-completion --shell powershell\n")),(0,r.kt)("p",null,"You need to source the new auto completion script or log out and log in again to activate it for the current shell:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"source /usr/share/bash-completion/completions/casper-client\n")),(0,r.kt)("p",null,"Now you can use ",(0,r.kt)("inlineCode",{parentName:"p"},"casper-client")," and press the ",(0,r.kt)("inlineCode",{parentName:"p"},"tab")," key to get auto completion for your commands."),(0,r.kt)("h2",{id:"installing-all-protocols"},"Installing All Protocols"),(0,r.kt)("p",null,"On ",(0,r.kt)("strong",{parentName:"p"},"Mainnet"),", run:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf\n")),(0,r.kt)("p",null,"On ",(0,r.kt)("strong",{parentName:"p"},"Testnet"),", run:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf\n")),(0,r.kt)("h2",{id:"validator-keys"},"Validator Keys"),(0,r.kt)("p",null,"If you do not have keys yet, you can create them using the following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client keygen /etc/casper/validator_keys\n")),(0,r.kt)("p",null,"For more details, see the ",(0,r.kt)("a",{parentName:"p",href:"/operators/setup/basic-node-configuration#create-fund-keys"},"Node Setup")," page."),(0,r.kt)("h2",{id:"getting-a-trusted-hash"},"Getting a Trusted Hash"),(0,r.kt)("p",null,"In the past, we have used a lower ",(0,r.kt)("inlineCode",{parentName:"p"},"trusted_hash"),". Connecting at the tip, we now use as high of a ",(0,r.kt)("inlineCode",{parentName:"p"},"trusted_hash")," as possible. Find out more about ",(0,r.kt)("a",{parentName:"p",href:"/operators/setup/fast-sync"},"Fast Sync"),"."),(0,r.kt)("h3",{id:"node-address"},"Node Address"),(0,r.kt)("p",null,"NODE_ADDR can be set to an IP of a trusted node, or to Casper Labs' public nodes"),(0,r.kt)("p",null,"You can find active peers at ",(0,r.kt)("a",{parentName:"p",href:"https://cspr.live/tools/peers"},"https://cspr.live/tools/peers")," or use the following Casper Labs public nodes:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"Testnet - NODE_ADDR=",(0,r.kt)("a",{parentName:"p",href:"https://rpc.testnet.casperlabs.io"},"https://rpc.testnet.casperlabs.io"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"Mainnet - NODE_ADDR=",(0,r.kt)("a",{parentName:"p",href:"https://rpc.mainnet.casperlabs.io"},"https://rpc.mainnet.casperlabs.io")))),(0,r.kt)("h3",{id:"protocol-version"},"Protocol Version"),(0,r.kt)("p",null,"Protocol version should be set to the largest available protocol version you see in ",(0,r.kt)("inlineCode",{parentName:"p"},"ls /etc/casper"),". As of writing this, it was 1_5_2:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"PROTOCOL=1_5_2\n")),(0,r.kt)("h3",{id:"load-trusted_hash-in-configtoml-of-the-protocol-version"},"Load ",(0,r.kt)("inlineCode",{parentName:"h3"},"trusted_hash")," in Config.toml of the Protocol Version"),(0,r.kt)("p",null,"The following command uses the previously established NODE_ADDR and PROTOCOL to load the ",(0,r.kt)("inlineCode",{parentName:"p"},"trusted_hash"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"NODE_ADDR=https://rpc.mainnet.casperlabs.io\nPROTOCOL=1_5_2\nsudo sed -i \"/trusted_hash =/c\\trusted_hash = '$(casper-client get-block --node-address $NODE_ADDR | jq -r .result.block.hash | tr -d '\\n')'\" /etc/casper/$PROTOCOL/config.toml\n")),(0,r.kt)("h2",{id:"syncing-to-genesis"},"Syncing to Genesis"),(0,r.kt)("p",null,"In the latest protocol version's ",(0,r.kt)("em",{parentName:"p"},"Config.toml"),", you will find the option ",(0,r.kt)("inlineCode",{parentName:"p"},"sync_to_genesis"),". By default, this value will be set to ",(0,r.kt)("inlineCode",{parentName:"p"},"true"),"."),(0,r.kt)("p",null,"If you are planning to run a validator node, it is better to not sync your node to genesis. This will increase node performance. In this case, the option should be changed to:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sync_to_genesis = false\n")),(0,r.kt)("p",null,"If you are using the node for historical data and want to query back to genesis, you can leave the default value in place."),(0,r.kt)("h2",{id:"starting-the-node"},"Starting the Node"),(0,r.kt)("p",null,"Start the node using the following commands:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo /etc/casper/node_util.py rotate_logs\nsudo /etc/casper/node_util.py start\n")),(0,r.kt)("h3",{id:"monitoring-the-synchronization-process"},"Monitoring the Synchronization Process"),(0,r.kt)("p",null,"The following command will display the node synchronization details:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"/etc/casper/node_util.py watch\n")),(0,r.kt)("p",null,"When you first run the watch command, you may see the message ",(0,r.kt)("inlineCode",{parentName:"p"},"RPC: Not Ready"),". Once the node is synchronized, the status will change to ",(0,r.kt)("inlineCode",{parentName:"p"},"RPC: Ready")," and a similar output:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"Last Block: 630151 (Era: 4153)\nPeer Count: 297\nUptime: 4days 6h 40m 18s 553ms\nBuild: 1.4.5-a7f6a648d-casper-mainnet\nKey: 0147b4cae09d64ab6acd02dd0868722be9a9bcc355c2fdff7c2c244cbfcd30f158\nNext Upgrade: None\n\nRPC: Ready\n\n\u25cf casper-node-launcher.service - Casper Node Launcher\n Loaded: loaded (/lib/systemd/system/casper-node-launcher.service; enabled; vendor preset: enabled)\n Active: active (running) since Wed 2022-03-16 21:08:50 UTC; 4 days ago\n Docs: https://docs.casper.network\n Main PID: 2934 (casper-node-lau)\n Tasks: 12 (limit: 4915)\n CGroup: /system.slice/casper-node-launcher.service\n \u251c\u2500 2934 /usr/bin/casper-node-launcher\n \u2514\u250016842 /var/lib/casper/bin/1_4_5/casper-node validator /etc/casper/1_4_5/config.toml\n")),(0,r.kt)("p",null,"The reactor state will be in CatchUp mode until it acquires the full tip state, at which point it will shift to KeepUp mode. If you left ",(0,r.kt)("inlineCode",{parentName:"p"},"sync_to_genesis")," as ",(0,r.kt)("inlineCode",{parentName:"p"},"true"),", it will begin syncing back history at this time."),(0,r.kt)("p",null,"Seeing available block range - Low: 0 High: 0 is normal until the fill tip is downloaded. You can see download progress with a look at metrics:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"$ curl -s 127.0.0.1:8888/metrics | grep trie_or_chunk\n# HELP trie_or_chunk_fetch_total number of trie_or_chunk all fetch requests made\n# TYPE trie_or_chunk_fetch_total counter\ntrie_or_chunk_fetch_total 102647\n# HELP trie_or_chunk_found_in_storage number of fetch requests that found trie_or_chunk in local storage\n# TYPE trie_or_chunk_found_in_storage counter\ntrie_or_chunk_found_in_storage 0\n# HELP trie_or_chunk_found_on_peer number of fetch requests that fetched trie_or_chunk from peer\n# TYPE trie_or_chunk_found_on_peer counter\ntrie_or_chunk_found_on_peer 102263\n# HELP trie_or_chunk_timeouts number of trie_or_chunk fetch requests that timed out\n# TYPE trie_or_chunk_timeouts counter\ntrie_or_chunk_timeouts 0\n")),(0,r.kt)("p",null,"If the node is not showing active (running) status, it is either stopped or in the process of restarting."),(0,r.kt)("h3",{id:"monitoring-the-running-node"},"Monitoring the Running Node"),(0,r.kt)("p",null,"The community has created a few tools to monitor your node once it is running, such as:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Status.py: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/RapidMark/casper-tools"},"https://github.com/RapidMark/casper-tools")),(0,r.kt)("li",{parentName:"ul"},"Grafana: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/matsuro-hadouken/casper-tools"},"https://github.com/matsuro-hadouken/casper-tools"))),(0,r.kt)("h2",{id:"a-note-on-speculative-execution"},"A Note on Speculative Execution"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"speculative_exec_server")," defaults to off and can be enabled in your ",(0,r.kt)("em",{parentName:"p"},"Config.toml")," file."),(0,r.kt)("p",null,"While this is a useful tool, understand that it is also an attack vector for a node. The intent is for someone to run on their node as a tool. You ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("em",{parentName:"strong"},"should not"))," use this if you are an active validator, as requests into this port can block execution_engine processing for legitimate network traffic."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[9415],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=o.createContext({}),u=function(e){var t=o.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=u(e.components);return o.createElement(i.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,i=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=u(n),h=a,m=c["".concat(i,".").concat(h)]||c[h]||d[h]||r;return n?o.createElement(m,s(s({ref:t},p),{},{components:n})):o.createElement(m,s({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,s=new Array(r);s[0]=h;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[c]="string"==typeof e?e:a,s[1]=l;for(var u=2;ucasper-client (Optional)",id:"enable-bash-auto-completion-for-casper-client-optional",level:2},{value:"Installing All Protocols",id:"installing-all-protocols",level:2},{value:"Validator Keys",id:"validator-keys",level:2},{value:"Getting a Trusted Hash",id:"getting-a-trusted-hash",level:2},{value:"Node Address",id:"node-address",level:3},{value:"Protocol Version",id:"protocol-version",level:3},{value:"Load trusted_hash in Config.toml of the Protocol Version",id:"load-trusted_hash-in-configtoml-of-the-protocol-version",level:3},{value:"Syncing to Genesis",id:"syncing-to-genesis",level:2},{value:"Starting the Node",id:"starting-the-node",level:2},{value:"Monitoring the Synchronization Process",id:"monitoring-the-synchronization-process",level:3},{value:"Monitoring the Running Node",id:"monitoring-the-running-node",level:3},{value:"A Note on Speculative Execution",id:"a-note-on-speculative-execution",level:2}],d={toc:c},h="wrapper";function m(e){var t=e.components,n=(0,a.Z)(e,s);return(0,r.kt)(h,(0,o.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"installing-a-node"},"Installing a Node"),(0,r.kt)("p",null,"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet."),(0,r.kt)("h2",{id:"network-requirements"},"Network Requirements"),(0,r.kt)("p",null,"The following ports are used by the node:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"35000 (required to be externally visible)"),(0,r.kt)("li",{parentName:"ul"},"7777 RPC endpoint for interaction with JSON-RPC API"),(0,r.kt)("li",{parentName:"ul"},"8888 REST endpoint for status and metrics (having this accessible allows your node to be part of network status)"),(0,r.kt)("li",{parentName:"ul"},"9999 SSE endpoint for event stream")),(0,r.kt)("p",null,"Of these ",(0,r.kt)("inlineCode",{parentName:"p"},"35000")," is the only port required to be open for your node to function, however, opening ",(0,r.kt)("inlineCode",{parentName:"p"},"8888")," will allow others to know general network health. For more details, see the additional information on ",(0,r.kt)("a",{parentName:"p",href:"/operators/setup/node-endpoints"},"Node Endpoints"),"."),(0,r.kt)("h2",{id:"operating-system-requirements"},"Operating System Requirements"),(0,r.kt)("p",null,"The recommended OS version is Ubuntu 20.04."),(0,r.kt)("h3",{id:"using-ubuntu-2204"},"Using Ubuntu 22.04"),(0,r.kt)("p",null,"Installing using Ubuntu 22.04 follows the same instructions as 20.04 with one exception:"),(0,r.kt)("p",null,"If you try to install packages, you will receive:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"casper-client : Depends: libssl1.1 (>= 1.1.0) but it is not installable\n")),(0,r.kt)("p",null,"This message is due to the default ",(0,r.kt)("inlineCode",{parentName:"p"},"openssl")," moving to 3.",(0,r.kt)("em",{parentName:"p"}," with Ubuntu 22.04. You need to install OpenSSL 1.")," for prior versions of Ubuntu to use the Casper binaries with the following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"curl -f -JLO http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb\nsudo apt install ./libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb\n")),(0,r.kt)("h2",{id:"required-number-of-open-files"},"Required Number of Open Files"),(0,r.kt)("p",null,"Before beginning, ",(0,r.kt)("a",{parentName:"p",href:"/operators/setup/open-files"},"update the maximum open files limit")," for your system. Specifically, update the node's ",(0,r.kt)("inlineCode",{parentName:"p"},"/etc/security/limits.conf")," file as described ",(0,r.kt)("a",{parentName:"p",href:"/operators/setup/open-files#updating-limits-conf"},"here"),", to ensure proper node operation."),(0,r.kt)("h2",{id:"required-clean-up"},"Required Clean Up"),(0,r.kt)("p",null,"If you were running a previous node on this box, this will clean up state. If packages are not installed, the ",(0,r.kt)("inlineCode",{parentName:"p"},"apt remove")," may give errors, but this is not a problem."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo systemctl stop casper-node-launcher.service\nsudo apt remove -y casper-client\nsudo apt remove -y casper-node\nsudo apt remove -y casper-node-launcher\nsudo rm /etc/casper/casper-node-launcher-state.toml\nsudo rm -rf /etc/casper/1_*\nsudo rm -rf /var/lib/casper/*\n")),(0,r.kt)("h2",{id:"required-packages"},"Required Packages"),(0,r.kt)("p",null,"The following commands will set up the Casper Labs repository for packages:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'echo "deb [arch=amd64] https://repo.casperlabs.io/releases focal main" | sudo tee -a /etc/apt/sources.list.d/casper.list\ncurl -O https://repo.casperlabs.io/casper-repo-pubkey.asc\nsudo apt-key add casper-repo-pubkey.asc\nsudo apt update\n')),(0,r.kt)("h2",{id:"required-tools"},"Required Tools"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt install -y casper-client casper-node-launcher jq\n")),(0,r.kt)("h2",{id:"enable-bash-auto-completion-for-casper-client-optional"},"Enable Bash Auto-Completion for ",(0,r.kt)("inlineCode",{parentName:"h2"},"casper-client")," (Optional)"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo casper-client generate-completion\n")),(0,r.kt)("p",null,"It defaults to ",(0,r.kt)("inlineCode",{parentName:"p"},"bash")," but can be changed with the ",(0,r.kt)("inlineCode",{parentName:"p"},"--shell")," argument:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"--shell The type of shell to generate the completion script for [default: bash] [possible values:\n zsh, bash, fish, powershell, elvish]\n\nsudo casper-client generate-completion --shell powershell\n")),(0,r.kt)("p",null,"You need to source the new auto completion script or log out and log in again to activate it for the current shell:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"source /usr/share/bash-completion/completions/casper-client\n")),(0,r.kt)("p",null,"Now you can use ",(0,r.kt)("inlineCode",{parentName:"p"},"casper-client")," and press the ",(0,r.kt)("inlineCode",{parentName:"p"},"tab")," key to get auto completion for your commands."),(0,r.kt)("h2",{id:"installing-all-protocols"},"Installing All Protocols"),(0,r.kt)("p",null,"On ",(0,r.kt)("strong",{parentName:"p"},"Mainnet"),", run:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf\n")),(0,r.kt)("p",null,"On ",(0,r.kt)("strong",{parentName:"p"},"Testnet"),", run:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf\n")),(0,r.kt)("h2",{id:"validator-keys"},"Validator Keys"),(0,r.kt)("p",null,"If you do not have keys yet, you can create them using the following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client keygen /etc/casper/validator_keys\n")),(0,r.kt)("p",null,"For more details, see the ",(0,r.kt)("a",{parentName:"p",href:"/operators/setup/basic-node-configuration#create-fund-keys"},"Node Setup")," page."),(0,r.kt)("h2",{id:"getting-a-trusted-hash"},"Getting a Trusted Hash"),(0,r.kt)("p",null,"In the past, we have used a lower ",(0,r.kt)("inlineCode",{parentName:"p"},"trusted_hash"),". Connecting at the tip, we now use as high of a ",(0,r.kt)("inlineCode",{parentName:"p"},"trusted_hash")," as possible. Find out more about ",(0,r.kt)("a",{parentName:"p",href:"/operators/setup/fast-sync"},"Fast Sync"),"."),(0,r.kt)("h3",{id:"node-address"},"Node Address"),(0,r.kt)("p",null,"NODE_ADDR can be set to an IP of a trusted node, or to Casper Labs' public nodes"),(0,r.kt)("p",null,"You can find active peers at ",(0,r.kt)("a",{parentName:"p",href:"https://cspr.live/tools/peers"},"https://cspr.live/tools/peers")," or use the following Casper Labs public nodes:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"Testnet - NODE_ADDR=",(0,r.kt)("a",{parentName:"p",href:"https://rpc.testnet.casperlabs.io"},"https://rpc.testnet.casperlabs.io"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"Mainnet - NODE_ADDR=",(0,r.kt)("a",{parentName:"p",href:"https://rpc.mainnet.casperlabs.io"},"https://rpc.mainnet.casperlabs.io")))),(0,r.kt)("h3",{id:"protocol-version"},"Protocol Version"),(0,r.kt)("p",null,"Protocol version should be set to the largest available protocol version you see in ",(0,r.kt)("inlineCode",{parentName:"p"},"ls /etc/casper"),". As of writing this, it was 1_5_2:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"PROTOCOL=1_5_2\n")),(0,r.kt)("h3",{id:"load-trusted_hash-in-configtoml-of-the-protocol-version"},"Load ",(0,r.kt)("inlineCode",{parentName:"h3"},"trusted_hash")," in Config.toml of the Protocol Version"),(0,r.kt)("p",null,"The following command uses the previously established NODE_ADDR and PROTOCOL to load the ",(0,r.kt)("inlineCode",{parentName:"p"},"trusted_hash"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"NODE_ADDR=https://rpc.mainnet.casperlabs.io\nPROTOCOL=1_5_2\nsudo sed -i \"/trusted_hash =/c\\trusted_hash = '$(casper-client get-block --node-address $NODE_ADDR | jq -r .result.block.hash | tr -d '\\n')'\" /etc/casper/$PROTOCOL/config.toml\n")),(0,r.kt)("h2",{id:"syncing-to-genesis"},"Syncing to Genesis"),(0,r.kt)("p",null,"In the latest protocol version's ",(0,r.kt)("em",{parentName:"p"},"Config.toml"),", you will find the option ",(0,r.kt)("inlineCode",{parentName:"p"},"sync_to_genesis"),". By default, this value will be set to ",(0,r.kt)("inlineCode",{parentName:"p"},"true"),"."),(0,r.kt)("p",null,"If you are planning to run a validator node, it is better to not sync your node to genesis. This will increase node performance. In this case, the option should be changed to:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sync_to_genesis = false\n")),(0,r.kt)("p",null,"If you are using the node for historical data and want to query back to genesis, you can leave the default value in place."),(0,r.kt)("h2",{id:"starting-the-node"},"Starting the Node"),(0,r.kt)("p",null,"Start the node using the following commands:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo /etc/casper/node_util.py rotate_logs\nsudo /etc/casper/node_util.py start\n")),(0,r.kt)("h3",{id:"monitoring-the-synchronization-process"},"Monitoring the Synchronization Process"),(0,r.kt)("p",null,"The following command will display the node synchronization details:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"/etc/casper/node_util.py watch\n")),(0,r.kt)("p",null,"When you first run the watch command, you may see the message ",(0,r.kt)("inlineCode",{parentName:"p"},"RPC: Not Ready"),". Once the node is synchronized, the status will change to ",(0,r.kt)("inlineCode",{parentName:"p"},"RPC: Ready")," and a similar output:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"Last Block: 630151 (Era: 4153)\nPeer Count: 297\nUptime: 4days 6h 40m 18s 553ms\nBuild: 1.4.5-a7f6a648d-casper-mainnet\nKey: 0147b4cae09d64ab6acd02dd0868722be9a9bcc355c2fdff7c2c244cbfcd30f158\nNext Upgrade: None\n\nRPC: Ready\n\n\u25cf casper-node-launcher.service - Casper Node Launcher\n Loaded: loaded (/lib/systemd/system/casper-node-launcher.service; enabled; vendor preset: enabled)\n Active: active (running) since Wed 2022-03-16 21:08:50 UTC; 4 days ago\n Docs: https://docs.casper.network\n Main PID: 2934 (casper-node-lau)\n Tasks: 12 (limit: 4915)\n CGroup: /system.slice/casper-node-launcher.service\n \u251c\u2500 2934 /usr/bin/casper-node-launcher\n \u2514\u250016842 /var/lib/casper/bin/1_4_5/casper-node validator /etc/casper/1_4_5/config.toml\n")),(0,r.kt)("p",null,"The reactor state will be in CatchUp mode until it acquires the full tip state, at which point it will shift to KeepUp mode. If you left ",(0,r.kt)("inlineCode",{parentName:"p"},"sync_to_genesis")," as ",(0,r.kt)("inlineCode",{parentName:"p"},"true"),", it will begin syncing back history at this time."),(0,r.kt)("p",null,"Seeing available block range - Low: 0 High: 0 is normal until the fill tip is downloaded. You can see download progress with a look at metrics:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"$ curl -s 127.0.0.1:8888/metrics | grep trie_or_chunk\n# HELP trie_or_chunk_fetch_total number of trie_or_chunk all fetch requests made\n# TYPE trie_or_chunk_fetch_total counter\ntrie_or_chunk_fetch_total 102647\n# HELP trie_or_chunk_found_in_storage number of fetch requests that found trie_or_chunk in local storage\n# TYPE trie_or_chunk_found_in_storage counter\ntrie_or_chunk_found_in_storage 0\n# HELP trie_or_chunk_found_on_peer number of fetch requests that fetched trie_or_chunk from peer\n# TYPE trie_or_chunk_found_on_peer counter\ntrie_or_chunk_found_on_peer 102263\n# HELP trie_or_chunk_timeouts number of trie_or_chunk fetch requests that timed out\n# TYPE trie_or_chunk_timeouts counter\ntrie_or_chunk_timeouts 0\n")),(0,r.kt)("p",null,"If the node is not showing active (running) status, it is either stopped or in the process of restarting."),(0,r.kt)("h3",{id:"monitoring-the-running-node"},"Monitoring the Running Node"),(0,r.kt)("p",null,"The community has created a few tools to monitor your node once it is running, such as:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Status.py: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/RapidMark/casper-tools"},"https://github.com/RapidMark/casper-tools")),(0,r.kt)("li",{parentName:"ul"},"Grafana: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/matsuro-hadouken/casper-tools"},"https://github.com/matsuro-hadouken/casper-tools"))),(0,r.kt)("h2",{id:"a-note-on-speculative-execution"},"A Note on Speculative Execution"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"speculative_exec_server")," defaults to off and can be enabled in your ",(0,r.kt)("em",{parentName:"p"},"Config.toml")," file."),(0,r.kt)("p",null,"While this is a useful tool, understand that it is also an attack vector for a node. The intent is for someone to run on their node as a tool. You ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("em",{parentName:"strong"},"should not"))," use this if you are an active validator, as requests into this port can block execution_engine processing for legitimate network traffic."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/043e2a1e.3c76adb8.js b/assets/js/043e2a1e.0f2254ad.js similarity index 99% rename from assets/js/043e2a1e.3c76adb8.js rename to assets/js/043e2a1e.0f2254ad.js index 5d80f59c7d..7d125689aa 100644 --- a/assets/js/043e2a1e.3c76adb8.js +++ b/assets/js/043e2a1e.0f2254ad.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[8699],{3905:function(e,t,n){n.d(t,{Zo:function(){return l},kt:function(){return u}});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function p(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=o.createContext({}),c=function(e){var t=o.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):p(p({},t),e)),n},l=function(e){var t=c(e.components);return o.createElement(i.Provider,{value:t},e.children)},d="mdxType",_={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},y=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,i=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=c(n),y=a,u=d["".concat(i,".").concat(y)]||d[y]||_[y]||r;return n?o.createElement(u,p(p({ref:t},l),{},{components:n})):o.createElement(u,p({ref:t},l))}));function u(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,p=new Array(r);p[0]=y;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[d]="string"==typeof e?e:a,p[1]=s;for(var c=2;c NodeClient:\n """Returns a pycspr client instance.\n """\n return NodeClient(NodeConnectionInfo(\n host=node_host,\n port_rpc=node_port_rpc,\n ))\n\n\n def _get_counter_parties(path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key) -> typing.Tuple[PrivateKey, PublicKey]:\n """Returns the 2 counter-parties participating in the transfer.\n """\n cp1 = pycspr.parse_private_key(\n path_to_cp1_secret_key,\n type_of_cp1_secret_key,\n )\n cp2 = pycspr.parse_public_key(\n path_to_cp2_account_key\n )\n\n return cp1, cp2\n\n\n def _get_deploy(chain_name, cp1: PrivateKey, cp2: PublicKey) -> Deploy:\n """Returns transfer deploy to be dispatched to a node.\n """\n # Set standard deploy parameters.\n deploy_params = pycspr.create_deploy_parameters(\n account = cp1,\n chain_name = chain_name\n )\n\n # Set deploy.\n deploy = pycspr.create_native_transfer(\n params = deploy_params,\n amount = int(2.5e9),\n target = cp2.account_hash,\n correlation_id = random.randint(1, 1e6)\n )\n\n return deploy\n\n\n # Entry point.\n if __name__ == \'__main__\':\n _main(node_host, node_port_rpc, path_to_cp1_secret_key, type_of_cp1_secret_key, path_to_cp2_account_key, chain_name)\n')),(0,r.kt)("h3",{id:"staking"},"Staking"),(0,r.kt)("p",null,"This example shows you how to define and stake funds with a validator."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'\n import os\n import pathlib\n\n import pycspr\n from pycspr.client import NodeClient\n from pycspr.client import NodeConnectionInfo\n from pycspr.crypto import KeyAlgorithm\n from pycspr.types import Deploy\n from pycspr.types import PrivateKey\n\n # path to cp1 secret key - defaults to NCTL user 1.\n path_to_validator_secret_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-1" / "secret_key.pem"\n\n # type of cp1 secret key - defaults to ED25519.\n type_of_validator_secret_key = KeyAlgorithm.ED25519.name\n\n # path to session code wasm binary - defaults to NCTL bin/eco/add_bid.wasm.\n path_to_wasm = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "bin" / "auction" / "add_bid.wasm"\n\n # amount to stake, i.e. bond, into the network.\n amount = int(2.5e9)\n\n # amount to charge delegators for service provision.\n delegation_rate = 2\n\n # name of target chain - defaults to NCTL chain.\n chain_name = "casper-net-1"\n\n # host address of target node - defaults to NCTL node 1.\n node_host = "localhost"\n\n # Node API JSON-RPC port - defaults to 11101 @ NCTL node 1.\n node_port_rpc = 11101\n\n def _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm):\n """Main entry point.\n :param args: Parsed command line arguments.\n """\n # Set node client.\n client: NodeClient = _get_client(node_host, node_port_rpc)\n\n # Set validator key.\n validator: PrivateKey = pycspr.parse_private_key(\n path_to_validator_secret_key,\n type_of_validator_secret_key,\n )\n\n # Set deploy.\n deploy: Deploy = _get_deploy(validator, chain_name, amount, delegation_rate, path_to_wasm)\n\n # Approve deploy.\n deploy.approve(validator)\n\n # Dispatch deploy to a node.\n client.deploys.send(deploy)\n\n print(f"Deploy dispatched to node [{node_host}]: {deploy.hash.hex()}")\n\n\n def _get_client(node_host, node_port_rpc) -> NodeClient:\n """Returns a pycspr client instance.\n """\n return NodeClient(NodeConnectionInfo(\n host = node_host,\n port_rpc = node_port_rpc,\n ))\n\n\n def _get_deploy(validator: PrivateKey, chain_name, amount, delegation_rate, path_to_wasm) -> Deploy:\n """Returns delegation deploy to be dispatched to a node.\n """\n # Set standard deploy parameters.\n deploy_params = pycspr.create_deploy_parameters(\n account = validator,\n chain_name = chain_name\n )\n\n # Set deploy.\n deploy = pycspr.create_validator_auction_bid(\n params = deploy_params,\n amount = amount,\n delegation_rate = delegation_rate,\n public_key = validator.as_public_key(),\n path_to_wasm = path_to_wasm\n )\n\n return deploy\n\n\n # Entry point.\n if __name__ == \'__main__\':\n _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm)\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[8699],{3905:function(e,t,n){n.d(t,{Zo:function(){return l},kt:function(){return u}});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function p(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=o.createContext({}),c=function(e){var t=o.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):p(p({},t),e)),n},l=function(e){var t=c(e.components);return o.createElement(i.Provider,{value:t},e.children)},d="mdxType",_={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},y=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,i=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=c(n),y=a,u=d["".concat(i,".").concat(y)]||d[y]||_[y]||r;return n?o.createElement(u,p(p({ref:t},l),{},{components:n})):o.createElement(u,p({ref:t},l))}));function u(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,p=new Array(r);p[0]=y;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[d]="string"==typeof e?e:a,p[1]=s;for(var c=2;c NodeClient:\n """Returns a pycspr client instance.\n """\n return NodeClient(NodeConnectionInfo(\n host=node_host,\n port_rpc=node_port_rpc,\n ))\n\n\n def _get_counter_parties(path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key) -> typing.Tuple[PrivateKey, PublicKey]:\n """Returns the 2 counter-parties participating in the transfer.\n """\n cp1 = pycspr.parse_private_key(\n path_to_cp1_secret_key,\n type_of_cp1_secret_key,\n )\n cp2 = pycspr.parse_public_key(\n path_to_cp2_account_key\n )\n\n return cp1, cp2\n\n\n def _get_deploy(chain_name, cp1: PrivateKey, cp2: PublicKey) -> Deploy:\n """Returns transfer deploy to be dispatched to a node.\n """\n # Set standard deploy parameters.\n deploy_params = pycspr.create_deploy_parameters(\n account = cp1,\n chain_name = chain_name\n )\n\n # Set deploy.\n deploy = pycspr.create_native_transfer(\n params = deploy_params,\n amount = int(2.5e9),\n target = cp2.account_hash,\n correlation_id = random.randint(1, 1e6)\n )\n\n return deploy\n\n\n # Entry point.\n if __name__ == \'__main__\':\n _main(node_host, node_port_rpc, path_to_cp1_secret_key, type_of_cp1_secret_key, path_to_cp2_account_key, chain_name)\n')),(0,r.kt)("h3",{id:"staking"},"Staking"),(0,r.kt)("p",null,"This example shows you how to define and stake funds with a validator."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'\n import os\n import pathlib\n\n import pycspr\n from pycspr.client import NodeClient\n from pycspr.client import NodeConnectionInfo\n from pycspr.crypto import KeyAlgorithm\n from pycspr.types import Deploy\n from pycspr.types import PrivateKey\n\n # path to cp1 secret key - defaults to NCTL user 1.\n path_to_validator_secret_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-1" / "secret_key.pem"\n\n # type of cp1 secret key - defaults to ED25519.\n type_of_validator_secret_key = KeyAlgorithm.ED25519.name\n\n # path to session code wasm binary - defaults to NCTL bin/eco/add_bid.wasm.\n path_to_wasm = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "bin" / "auction" / "add_bid.wasm"\n\n # amount to stake, i.e. bond, into the network.\n amount = int(2.5e9)\n\n # amount to charge delegators for service provision.\n delegation_rate = 2\n\n # name of target chain - defaults to NCTL chain.\n chain_name = "casper-net-1"\n\n # host address of target node - defaults to NCTL node 1.\n node_host = "localhost"\n\n # Node API JSON-RPC port - defaults to 11101 @ NCTL node 1.\n node_port_rpc = 11101\n\n def _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm):\n """Main entry point.\n :param args: Parsed command line arguments.\n """\n # Set node client.\n client: NodeClient = _get_client(node_host, node_port_rpc)\n\n # Set validator key.\n validator: PrivateKey = pycspr.parse_private_key(\n path_to_validator_secret_key,\n type_of_validator_secret_key,\n )\n\n # Set deploy.\n deploy: Deploy = _get_deploy(validator, chain_name, amount, delegation_rate, path_to_wasm)\n\n # Approve deploy.\n deploy.approve(validator)\n\n # Dispatch deploy to a node.\n client.deploys.send(deploy)\n\n print(f"Deploy dispatched to node [{node_host}]: {deploy.hash.hex()}")\n\n\n def _get_client(node_host, node_port_rpc) -> NodeClient:\n """Returns a pycspr client instance.\n """\n return NodeClient(NodeConnectionInfo(\n host = node_host,\n port_rpc = node_port_rpc,\n ))\n\n\n def _get_deploy(validator: PrivateKey, chain_name, amount, delegation_rate, path_to_wasm) -> Deploy:\n """Returns delegation deploy to be dispatched to a node.\n """\n # Set standard deploy parameters.\n deploy_params = pycspr.create_deploy_parameters(\n account = validator,\n chain_name = chain_name\n )\n\n # Set deploy.\n deploy = pycspr.create_validator_auction_bid(\n params = deploy_params,\n amount = amount,\n delegation_rate = delegation_rate,\n public_key = validator.as_public_key(),\n path_to_wasm = path_to_wasm\n )\n\n return deploy\n\n\n # Entry point.\n if __name__ == \'__main__\':\n _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm)\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/04e20c99.8d925a8d.js b/assets/js/04e20c99.35b08f30.js similarity index 98% rename from assets/js/04e20c99.8d925a8d.js rename to assets/js/04e20c99.35b08f30.js index 62952a4ad1..9f0d5f6c24 100644 --- a/assets/js/04e20c99.8d925a8d.js +++ b/assets/js/04e20c99.35b08f30.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[4455],{3905:function(e,t,r){r.d(t,{Zo:function(){return p},kt:function(){return f}});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},k=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=c(r),k=o,f=u["".concat(l,".").concat(k)]||u[k]||h[k]||a;return r?n.createElement(f,s(s({ref:t},p),{},{components:r})):n.createElement(f,s({ref:t},p))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,s=new Array(a);s[0]=k;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:o,s[1]=i;for(var c=2;c=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},k=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=c(r),k=o,f=u["".concat(l,".").concat(k)]||u[k]||h[k]||a;return r?n.createElement(f,s(s({ref:t},p),{},{components:r})):n.createElement(f,s({ref:t},p))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,s=new Array(a);s[0]=k;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:o,s[1]=i;for(var c=2;c=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),d=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},s=function(e){var t=d(e.components);return n.createElement(i.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,i=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),c=d(r),m=a,f=c["".concat(i,".").concat(m)]||c[m]||u[m]||p;return r?n.createElement(f,o(o({ref:t},s),{},{components:r})):n.createElement(f,o({ref:t},s))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,o=new Array(p);o[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[c]="string"==typeof e?e:a,o[1]=l;for(var d=2;d=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),d=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},s=function(e){var t=d(e.components);return n.createElement(i.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,i=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),c=d(r),m=a,f=c["".concat(i,".").concat(m)]||c[m]||u[m]||p;return r?n.createElement(f,o(o({ref:t},s),{},{components:r})):n.createElement(f,o({ref:t},s))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,o=new Array(p);o[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[c]="string"==typeof e?e:a,o[1]=l;for(var d=2;d=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=c(a),h=i,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||r;return a?n.createElement(m,o(o({ref:t},p),{},{components:a})):n.createElement(m,o({ref:t},p))}));function m(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:i,o[1]=s;for(var c=2;c> global_state.toml\n")),(0,r.kt)("p",null,"By using ",(0,r.kt)("inlineCode",{parentName:"p"},">>")," shell redirection you will always append contents to existing file without overwriting it. This is helpful when you need to chain multiple operations in a single upgrade."),(0,r.kt)("p",null,"Common options:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"--data-dir")," path to a global state directory where ",(0,r.kt)("inlineCode",{parentName:"li"},"data.lmdb")," can be found"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"--state-hash")," is the state root hash at the latest block. You should use the client to obtain the most recent state root hash to generate the ",(0,r.kt)("inlineCode",{parentName:"li"},"global_state.toml"),".")),(0,r.kt)("h3",{id:"rotating-validators"},"Rotating validators"),(0,r.kt)("p",null,"The following command rotates the validator set. Perform a network upgrade with a ",(0,r.kt)("inlineCode",{parentName:"p"},"global_state.toml")," with the new entries generated by the ",(0,r.kt)("inlineCode",{parentName:"p"},"global-state-update-gen")," command."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"global-state-update-gen validators \\\n --data-dir $DATA_DIR \\\n --state-hash $STATE_ROOT_HASH \\\n --validator NEW_PUBLIC_KEY,NEW_STAKE \\\n --validator NEW_PUBLIC_KEY2,NEW_STAKE2\n")),(0,r.kt)("h3",{id:"adding-new-administrators"},"Adding new administrators"),(0,r.kt)("p",null,"The following command produces the administrator content in the ",(0,r.kt)("inlineCode",{parentName:"p"},"global_state.toml")," file."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"global-state-update-gen generate-admins --admin NEW_PUBLIC_KEY,NEW_BALANCE --data-dir $DATA_DIR --state-hash $STATE_ROOT_HASH\n")),(0,r.kt)("p",null,"Remember that new administrators can be created, and the validator set can also be rotated in a single update."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"chainspec.toml")," file should contain the following entries that include new administrators as well as existing ones for an upgrade:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-toml"},'[core]\nadministrators = ["NEW_PUBLIC_KEY"]\n')),(0,r.kt)("p",null,"After this step, the private network would be ready for use."),(0,r.kt)("h2",{id:"setting-up-a-block-explorer"},"Setting up a Block Explorer"),(0,r.kt)("p",null,"Private and hybrid blockchains can find information on how to set up and operate our free version of a block explorer ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-blockexplorer-frontend"},"here"),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[7156],{3905:function(e,t,a){a.d(t,{Zo:function(){return p},kt:function(){return m}});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=c(a),h=i,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||r;return a?n.createElement(m,o(o({ref:t},p),{},{components:a})):n.createElement(m,o({ref:t},p))}));function m(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:i,o[1]=s;for(var c=2;c> global_state.toml\n")),(0,r.kt)("p",null,"By using ",(0,r.kt)("inlineCode",{parentName:"p"},">>")," shell redirection you will always append contents to existing file without overwriting it. This is helpful when you need to chain multiple operations in a single upgrade."),(0,r.kt)("p",null,"Common options:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"--data-dir")," path to a global state directory where ",(0,r.kt)("inlineCode",{parentName:"li"},"data.lmdb")," can be found"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"--state-hash")," is the state root hash at the latest block. You should use the client to obtain the most recent state root hash to generate the ",(0,r.kt)("inlineCode",{parentName:"li"},"global_state.toml"),".")),(0,r.kt)("h3",{id:"rotating-validators"},"Rotating validators"),(0,r.kt)("p",null,"The following command rotates the validator set. Perform a network upgrade with a ",(0,r.kt)("inlineCode",{parentName:"p"},"global_state.toml")," with the new entries generated by the ",(0,r.kt)("inlineCode",{parentName:"p"},"global-state-update-gen")," command."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"global-state-update-gen validators \\\n --data-dir $DATA_DIR \\\n --state-hash $STATE_ROOT_HASH \\\n --validator NEW_PUBLIC_KEY,NEW_STAKE \\\n --validator NEW_PUBLIC_KEY2,NEW_STAKE2\n")),(0,r.kt)("h3",{id:"adding-new-administrators"},"Adding new administrators"),(0,r.kt)("p",null,"The following command produces the administrator content in the ",(0,r.kt)("inlineCode",{parentName:"p"},"global_state.toml")," file."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"global-state-update-gen generate-admins --admin NEW_PUBLIC_KEY,NEW_BALANCE --data-dir $DATA_DIR --state-hash $STATE_ROOT_HASH\n")),(0,r.kt)("p",null,"Remember that new administrators can be created, and the validator set can also be rotated in a single update."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"chainspec.toml")," file should contain the following entries that include new administrators as well as existing ones for an upgrade:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-toml"},'[core]\nadministrators = ["NEW_PUBLIC_KEY"]\n')),(0,r.kt)("p",null,"After this step, the private network would be ready for use."),(0,r.kt)("h2",{id:"setting-up-a-block-explorer"},"Setting up a Block Explorer"),(0,r.kt)("p",null,"Private and hybrid blockchains can find information on how to set up and operate our free version of a block explorer ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-blockexplorer-frontend"},"here"),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/08ab7f39.cda8d9b9.js b/assets/js/08ab7f39.a75f8dcc.js similarity index 99% rename from assets/js/08ab7f39.cda8d9b9.js rename to assets/js/08ab7f39.a75f8dcc.js index 89458629c9..37c41025a7 100644 --- a/assets/js/08ab7f39.cda8d9b9.js +++ b/assets/js/08ab7f39.a75f8dcc.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5614],{3905:function(e,n,t){t.d(n,{Zo:function(){return c},kt:function(){return m}});var o=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=o.createContext({}),p=function(e){var n=o.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},c=function(e){var n=p(e.components);return o.createElement(s.Provider,{value:n},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},k=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(t),k=r,m=d["".concat(s,".").concat(k)]||d[k]||u[k]||i;return t?o.createElement(m,a(a({ref:n},c),{},{components:t})):o.createElement(m,a({ref:n},c))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var i=t.length,a=new Array(i);a[0]=k;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l[d]="string"==typeof e?e:r,a[1]=l;for(var p=2;pprotocol_versions",id:"more-on-protocol_versions",level:3},{value:"Protocol Version",id:"protocol-version",level:2},{value:"Network Configuration File",id:"network-configuration-file",level:2},{value:"Setup Configuration Files",id:"setup-configuration-files",level:2},{value:"chainspec.toml",id:"chainspectoml",level:3},{value:"config-example.toml",id:"config-exampletoml",level:3},{value:"Staging a Protocol Version",id:"staging-a-protocol-version",level:2}],u={toc:d},k="wrapper";function m(e){var n=e.components,t=(0,r.Z)(e,a);return(0,i.kt)(k,(0,o.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"staging-files-for-a-new-network"},"Staging Files for a New Network"),(0,i.kt)("admonition",{type:"important"},(0,i.kt)("p",{parentName:"admonition"},"Staging files is not needed for already established running networks."),(0,i.kt)("p",{parentName:"admonition"},"Only use these instructions if you are creating a new Casper network and hosting protocol files for this network.")),(0,i.kt)("h2",{id:"hosting-server"},"Hosting Server"),(0,i.kt)("p",null,"Files for staging protocol versions are hosted on a typical HTTP(S) server."),(0,i.kt)("p",null,"Scripts included with the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," have network configurations for Mainnet and Testnet. These scripts point to the server hosting files and network name."),(0,i.kt)("p",null,"Since a given server can be used for multiple networks, a network named directory is used to hold files for that network."),(0,i.kt)("p",null,"This is a description of Mainnet protocol version hosting (with network name: ",(0,i.kt)("inlineCode",{parentName:"p"},"casper"),")."),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"genesis.casperlab.io")," is the web server URL with the following directory structure:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"casper"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"protocol_versions")," - File listing active protocol versions so scripts know what directories to use"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"1_0_0")," - Genesis protocol version",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"config.tar.gz")," - Configuration files to be expanded into ",(0,i.kt)("inlineCode",{parentName:"li"},"/etc/casper/1_0_0")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"bin.tar.gz")," - Binary files to be expanded into ",(0,i.kt)("inlineCode",{parentName:"li"},"/var/lib/casper/bin/1_0_0")))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"1_1_0")," - First upgrade",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"config.tar.gz")," - Configuration files to be expanded into ",(0,i.kt)("inlineCode",{parentName:"li"},"/etc/casper/1_1_0")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"bin.tar.gz")," - Binary files to be expanded into ",(0,i.kt)("inlineCode",{parentName:"li"},"/var/lib/casper/bin/1_1_0")))),(0,i.kt)("li",{parentName:"ul"},"... (skipping many other protocol versions)"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"1_4_6")," - A later upgrade",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"config.tar.gz")," - Configuration files to be expanded into ",(0,i.kt)("inlineCode",{parentName:"li"},"/etc/casper/1_4_6")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"bin.tar.gz")," - Binary files to be expanded into ",(0,i.kt)("inlineCode",{parentName:"li"},"/var/lib/casper/bin/1_4_6"))))))),(0,i.kt)("h3",{id:"more-on-protocol_versions"},"More on ",(0,i.kt)("inlineCode",{parentName:"h3"},"protocol_versions")),(0,i.kt)("p",null,"At the root of the hosting server directory for a given network, a ",(0,i.kt)("inlineCode",{parentName:"p"},"protocol_versions")," file exists. This holds the valid protocol versions for a network."),(0,i.kt)("p",null,"We can look at this manually on Mainnet using ",(0,i.kt)("em",{parentName:"p"},"curl"),". As of writing this, ",(0,i.kt)("inlineCode",{parentName:"p"},"1.4.6")," is the latest version and the contents of this file will change."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"\n$ curl -s genesis.casperlabs.io/casper/protocol_versions\n1_0_0\n1_1_0\n1_1_2\n1_2_0\n1_2_1\n1_3_2\n1_3_4\n1_4_1\n1_4_3\n1_4_4\n1_4_5\n1_4_6\n\n")),(0,i.kt)("p",null,"We should find ",(0,i.kt)("inlineCode",{parentName:"p"},"bin.tar.gz")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"config.tar.gz")," in those directories under ",(0,i.kt)("inlineCode",{parentName:"p"},"casper"),"."),(0,i.kt)("h2",{id:"protocol-version"},"Protocol Version"),(0,i.kt)("p",null,"The protocol version of a network is not related to the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," version. In Mainnet, these have often been the same. However, with a new network, you would use the latest ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," version for your ",(0,i.kt)("inlineCode",{parentName:"p"},"1.0.0")," protocol."),(0,i.kt)("h2",{id:"network-configuration-file"},"Network Configuration File"),(0,i.kt)("p",null,"When the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," package is installed, both ",(0,i.kt)("inlineCode",{parentName:"p"},"casper.conf")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-test.conf")," are installed in ",(0,i.kt)("inlineCode",{parentName:"p"},"/etc/casper/network_configs"),". Once a valid config file for a new network is copied to this location, all commands with ",(0,i.kt)("em",{parentName:"p"},"node_util.py")," will work as they do on existing networks."),(0,i.kt)("p",null,"By convention, we name the config file the same as the network. So Mainnet has a network name of ",(0,i.kt)("inlineCode",{parentName:"p"},"casper")," and we use ",(0,i.kt)("inlineCode",{parentName:"p"},"casper.conf")," for the config file."),(0,i.kt)("p",null,"For a new network using server ",(0,i.kt)("inlineCode",{parentName:"p"},"casper.mydomain.com")," to host files for ",(0,i.kt)("inlineCode",{parentName:"p"},"our-network")," network, we would have a ",(0,i.kt)("inlineCode",{parentName:"p"},"our-network.conf")," file that looks like this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"SOURCE_URL=casper.mydomain.com\nNETWORK_NAME=our-network\n")),(0,i.kt)("p",null,"Host this ",(0,i.kt)("inlineCode",{parentName:"p"},"our-network.conf")," in the root of ",(0,i.kt)("inlineCode",{parentName:"p"},"casper.mydomain.com/our-network")," at the same level as ",(0,i.kt)("inlineCode",{parentName:"p"},"protocol_versions"),"."),(0,i.kt)("p",null,"This allows any node which wants to use the new network to run the following to install this configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"cd /etc/casper/network_configs\nsudo -u casper curl -JLO casper.mydomain.com/our-network/our-network.conf\n")),(0,i.kt)("p",null,"Any command needing a network config from ",(0,i.kt)("inlineCode",{parentName:"p"},"node_util.py")," can use ",(0,i.kt)("inlineCode",{parentName:"p"},"our-network.conf"),"."),(0,i.kt)("p",null,"Staging protocol versions for a new node with this network or staging an upcoming upgrade would just need this command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper /etc/casper/node_util.py stage_protocols our-network.conf\n")),(0,i.kt)("h2",{id:"setup-configuration-files"},"Setup Configuration Files"),(0,i.kt)("p",null,"For a network to be started, we to build the configuration files for a certain genesis time and with nodes that will be running. These files need to be configured in advanced, so a genesis time should be selected that allows packaging the files, loading onto nodes and starting nodes prior to the genesis time."),(0,i.kt)("h3",{id:"chainspectoml"},"chainspec.toml"),(0,i.kt)("p",null,"The ",(0,i.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec.toml")," file is configuration for the network and must be exactly the same on all nodes."),(0,i.kt)("p",null,"The name for a network is specified ",(0,i.kt)("inlineCode",{parentName:"p"},"network.name"),"."),(0,i.kt)("p",null,"Each protocol will have a ",(0,i.kt)("inlineCode",{parentName:"p"},"version")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"activation_point"),". At genesis this is a date and time in format shown below. For future upgrades it would be an integer of the ",(0,i.kt)("inlineCode",{parentName:"p"},"era_id")," for activation of the upgrade."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"[protocol]\nversion = '1.0.0'\nactivation_point = '2022-08-01T10:00:00Z'\n\n[network]\nname = 'mynetwork'\n")),(0,i.kt)("h3",{id:"config-exampletoml"},"config-example.toml"),(0,i.kt)("p",null,"The config-example.toml is used to generate config.toml for a protocol after the node's IP is inserted. The ",(0,i.kt)("inlineCode",{parentName:"p"},"public_address")," is auto-detected with ",(0,i.kt)("inlineCode",{parentName:"p"},"node_util.py stage_protocols"),". If using a NAT environment, the public IP can be specified with the ",(0,i.kt)("inlineCode",{parentName:"p"},"--ip")," argument."),(0,i.kt)("p",null,"This file should have ",(0,i.kt)("inlineCode",{parentName:"p"},"known_addresses")," added that are relevant to the network. Nodes that will be genesis validators are added to this list in the form:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"[network]\nknown_addresses = [':35000',':35000',':35000']\n")),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"config.toml")," can be setup to customized fields for a given node. ",(0,i.kt)("inlineCode",{parentName:"p"},"config-example.toml")," is a default configuration."),(0,i.kt)("h2",{id:"staging-a-protocol-version"},"Staging a Protocol Version"),(0,i.kt)("p",null,"For the initial genesis protocol version or future upgrade protocol versions, you will typically use prebuilt and tested ",(0,i.kt)("inlineCode",{parentName:"p"},"bin.tar.gz")," that have been tested and staged for existing networks. The ",(0,i.kt)("inlineCode",{parentName:"p"},"config.tar.gz")," file must be customized for the specific network with a network name, protocol version and activation point at the very least."),(0,i.kt)("p",null,"These archives should be created with no directory information stored. This is done by using ",(0,i.kt)("inlineCode",{parentName:"p"},"tar")," in the same directory as the files."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"mkdir config\ncd config\nmv [source of chainspec.toml] ./chainspec.toml\nmv [source of config-example.toml] ./config-example.toml\ntar -czvf ../config.tar.gz .\n")),(0,i.kt)("p",null,"You can test what was compressed with untar'ing the file."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"mkdir conftest\ncd conftest\ntar -xzvf ../config.tar.gz .\n")),(0,i.kt)("p",null,"This will expand files for verification."),(0,i.kt)("p",null,"For custom ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," builds, the minimum contents of ",(0,i.kt)("inlineCode",{parentName:"p"},"bin.tar.gz")," is the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," executable."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"mkdir bin\ncd bin\ncp [source of casper-node] ./casper-node\ntar -czvf ../bin.tar.gz .\n")),(0,i.kt)("p",null,"A directory for the protocol_version will be created on the server. For example: ",(0,i.kt)("inlineCode",{parentName:"p"},"1_1_0"),"."),(0,i.kt)("p",null,"We will copy ",(0,i.kt)("inlineCode",{parentName:"p"},"bin.tar.gz")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"config.tar.gz")," into ",(0,i.kt)("inlineCode",{parentName:"p"},"1_1_0"),". Once this is done, we are safe to update ",(0,i.kt)("inlineCode",{parentName:"p"},"protocol_versions")," by appending ",(0,i.kt)("inlineCode",{parentName:"p"},"1_1_0")," to the end of the file and uploading it into the root of the network directory."),(0,i.kt)("p",null,"Any node that runs the following command will get this new upgrade:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper /etc/casper/node_util.py stage_protocols \n")))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5614],{3905:function(e,n,t){t.d(n,{Zo:function(){return c},kt:function(){return m}});var o=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=o.createContext({}),p=function(e){var n=o.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},c=function(e){var n=p(e.components);return o.createElement(s.Provider,{value:n},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},k=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(t),k=r,m=d["".concat(s,".").concat(k)]||d[k]||u[k]||i;return t?o.createElement(m,a(a({ref:n},c),{},{components:t})):o.createElement(m,a({ref:n},c))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var i=t.length,a=new Array(i);a[0]=k;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l[d]="string"==typeof e?e:r,a[1]=l;for(var p=2;pprotocol_versions",id:"more-on-protocol_versions",level:3},{value:"Protocol Version",id:"protocol-version",level:2},{value:"Network Configuration File",id:"network-configuration-file",level:2},{value:"Setup Configuration Files",id:"setup-configuration-files",level:2},{value:"chainspec.toml",id:"chainspectoml",level:3},{value:"config-example.toml",id:"config-exampletoml",level:3},{value:"Staging a Protocol Version",id:"staging-a-protocol-version",level:2}],u={toc:d},k="wrapper";function m(e){var n=e.components,t=(0,r.Z)(e,a);return(0,i.kt)(k,(0,o.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"staging-files-for-a-new-network"},"Staging Files for a New Network"),(0,i.kt)("admonition",{type:"important"},(0,i.kt)("p",{parentName:"admonition"},"Staging files is not needed for already established running networks."),(0,i.kt)("p",{parentName:"admonition"},"Only use these instructions if you are creating a new Casper network and hosting protocol files for this network.")),(0,i.kt)("h2",{id:"hosting-server"},"Hosting Server"),(0,i.kt)("p",null,"Files for staging protocol versions are hosted on a typical HTTP(S) server."),(0,i.kt)("p",null,"Scripts included with the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," have network configurations for Mainnet and Testnet. These scripts point to the server hosting files and network name."),(0,i.kt)("p",null,"Since a given server can be used for multiple networks, a network named directory is used to hold files for that network."),(0,i.kt)("p",null,"This is a description of Mainnet protocol version hosting (with network name: ",(0,i.kt)("inlineCode",{parentName:"p"},"casper"),")."),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"genesis.casperlab.io")," is the web server URL with the following directory structure:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"casper"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"protocol_versions")," - File listing active protocol versions so scripts know what directories to use"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"1_0_0")," - Genesis protocol version",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"config.tar.gz")," - Configuration files to be expanded into ",(0,i.kt)("inlineCode",{parentName:"li"},"/etc/casper/1_0_0")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"bin.tar.gz")," - Binary files to be expanded into ",(0,i.kt)("inlineCode",{parentName:"li"},"/var/lib/casper/bin/1_0_0")))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"1_1_0")," - First upgrade",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"config.tar.gz")," - Configuration files to be expanded into ",(0,i.kt)("inlineCode",{parentName:"li"},"/etc/casper/1_1_0")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"bin.tar.gz")," - Binary files to be expanded into ",(0,i.kt)("inlineCode",{parentName:"li"},"/var/lib/casper/bin/1_1_0")))),(0,i.kt)("li",{parentName:"ul"},"... (skipping many other protocol versions)"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"1_4_6")," - A later upgrade",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"config.tar.gz")," - Configuration files to be expanded into ",(0,i.kt)("inlineCode",{parentName:"li"},"/etc/casper/1_4_6")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"bin.tar.gz")," - Binary files to be expanded into ",(0,i.kt)("inlineCode",{parentName:"li"},"/var/lib/casper/bin/1_4_6"))))))),(0,i.kt)("h3",{id:"more-on-protocol_versions"},"More on ",(0,i.kt)("inlineCode",{parentName:"h3"},"protocol_versions")),(0,i.kt)("p",null,"At the root of the hosting server directory for a given network, a ",(0,i.kt)("inlineCode",{parentName:"p"},"protocol_versions")," file exists. This holds the valid protocol versions for a network."),(0,i.kt)("p",null,"We can look at this manually on Mainnet using ",(0,i.kt)("em",{parentName:"p"},"curl"),". As of writing this, ",(0,i.kt)("inlineCode",{parentName:"p"},"1.4.6")," is the latest version and the contents of this file will change."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"\n$ curl -s genesis.casperlabs.io/casper/protocol_versions\n1_0_0\n1_1_0\n1_1_2\n1_2_0\n1_2_1\n1_3_2\n1_3_4\n1_4_1\n1_4_3\n1_4_4\n1_4_5\n1_4_6\n\n")),(0,i.kt)("p",null,"We should find ",(0,i.kt)("inlineCode",{parentName:"p"},"bin.tar.gz")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"config.tar.gz")," in those directories under ",(0,i.kt)("inlineCode",{parentName:"p"},"casper"),"."),(0,i.kt)("h2",{id:"protocol-version"},"Protocol Version"),(0,i.kt)("p",null,"The protocol version of a network is not related to the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," version. In Mainnet, these have often been the same. However, with a new network, you would use the latest ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," version for your ",(0,i.kt)("inlineCode",{parentName:"p"},"1.0.0")," protocol."),(0,i.kt)("h2",{id:"network-configuration-file"},"Network Configuration File"),(0,i.kt)("p",null,"When the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," package is installed, both ",(0,i.kt)("inlineCode",{parentName:"p"},"casper.conf")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-test.conf")," are installed in ",(0,i.kt)("inlineCode",{parentName:"p"},"/etc/casper/network_configs"),". Once a valid config file for a new network is copied to this location, all commands with ",(0,i.kt)("em",{parentName:"p"},"node_util.py")," will work as they do on existing networks."),(0,i.kt)("p",null,"By convention, we name the config file the same as the network. So Mainnet has a network name of ",(0,i.kt)("inlineCode",{parentName:"p"},"casper")," and we use ",(0,i.kt)("inlineCode",{parentName:"p"},"casper.conf")," for the config file."),(0,i.kt)("p",null,"For a new network using server ",(0,i.kt)("inlineCode",{parentName:"p"},"casper.mydomain.com")," to host files for ",(0,i.kt)("inlineCode",{parentName:"p"},"our-network")," network, we would have a ",(0,i.kt)("inlineCode",{parentName:"p"},"our-network.conf")," file that looks like this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"SOURCE_URL=casper.mydomain.com\nNETWORK_NAME=our-network\n")),(0,i.kt)("p",null,"Host this ",(0,i.kt)("inlineCode",{parentName:"p"},"our-network.conf")," in the root of ",(0,i.kt)("inlineCode",{parentName:"p"},"casper.mydomain.com/our-network")," at the same level as ",(0,i.kt)("inlineCode",{parentName:"p"},"protocol_versions"),"."),(0,i.kt)("p",null,"This allows any node which wants to use the new network to run the following to install this configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"cd /etc/casper/network_configs\nsudo -u casper curl -JLO casper.mydomain.com/our-network/our-network.conf\n")),(0,i.kt)("p",null,"Any command needing a network config from ",(0,i.kt)("inlineCode",{parentName:"p"},"node_util.py")," can use ",(0,i.kt)("inlineCode",{parentName:"p"},"our-network.conf"),"."),(0,i.kt)("p",null,"Staging protocol versions for a new node with this network or staging an upcoming upgrade would just need this command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper /etc/casper/node_util.py stage_protocols our-network.conf\n")),(0,i.kt)("h2",{id:"setup-configuration-files"},"Setup Configuration Files"),(0,i.kt)("p",null,"For a network to be started, we to build the configuration files for a certain genesis time and with nodes that will be running. These files need to be configured in advanced, so a genesis time should be selected that allows packaging the files, loading onto nodes and starting nodes prior to the genesis time."),(0,i.kt)("h3",{id:"chainspectoml"},"chainspec.toml"),(0,i.kt)("p",null,"The ",(0,i.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec.toml")," file is configuration for the network and must be exactly the same on all nodes."),(0,i.kt)("p",null,"The name for a network is specified ",(0,i.kt)("inlineCode",{parentName:"p"},"network.name"),"."),(0,i.kt)("p",null,"Each protocol will have a ",(0,i.kt)("inlineCode",{parentName:"p"},"version")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"activation_point"),". At genesis this is a date and time in format shown below. For future upgrades it would be an integer of the ",(0,i.kt)("inlineCode",{parentName:"p"},"era_id")," for activation of the upgrade."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"[protocol]\nversion = '1.0.0'\nactivation_point = '2022-08-01T10:00:00Z'\n\n[network]\nname = 'mynetwork'\n")),(0,i.kt)("h3",{id:"config-exampletoml"},"config-example.toml"),(0,i.kt)("p",null,"The config-example.toml is used to generate config.toml for a protocol after the node's IP is inserted. The ",(0,i.kt)("inlineCode",{parentName:"p"},"public_address")," is auto-detected with ",(0,i.kt)("inlineCode",{parentName:"p"},"node_util.py stage_protocols"),". If using a NAT environment, the public IP can be specified with the ",(0,i.kt)("inlineCode",{parentName:"p"},"--ip")," argument."),(0,i.kt)("p",null,"This file should have ",(0,i.kt)("inlineCode",{parentName:"p"},"known_addresses")," added that are relevant to the network. Nodes that will be genesis validators are added to this list in the form:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"[network]\nknown_addresses = [':35000',':35000',':35000']\n")),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"config.toml")," can be setup to customized fields for a given node. ",(0,i.kt)("inlineCode",{parentName:"p"},"config-example.toml")," is a default configuration."),(0,i.kt)("h2",{id:"staging-a-protocol-version"},"Staging a Protocol Version"),(0,i.kt)("p",null,"For the initial genesis protocol version or future upgrade protocol versions, you will typically use prebuilt and tested ",(0,i.kt)("inlineCode",{parentName:"p"},"bin.tar.gz")," that have been tested and staged for existing networks. The ",(0,i.kt)("inlineCode",{parentName:"p"},"config.tar.gz")," file must be customized for the specific network with a network name, protocol version and activation point at the very least."),(0,i.kt)("p",null,"These archives should be created with no directory information stored. This is done by using ",(0,i.kt)("inlineCode",{parentName:"p"},"tar")," in the same directory as the files."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"mkdir config\ncd config\nmv [source of chainspec.toml] ./chainspec.toml\nmv [source of config-example.toml] ./config-example.toml\ntar -czvf ../config.tar.gz .\n")),(0,i.kt)("p",null,"You can test what was compressed with untar'ing the file."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"mkdir conftest\ncd conftest\ntar -xzvf ../config.tar.gz .\n")),(0,i.kt)("p",null,"This will expand files for verification."),(0,i.kt)("p",null,"For custom ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," builds, the minimum contents of ",(0,i.kt)("inlineCode",{parentName:"p"},"bin.tar.gz")," is the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," executable."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"mkdir bin\ncd bin\ncp [source of casper-node] ./casper-node\ntar -czvf ../bin.tar.gz .\n")),(0,i.kt)("p",null,"A directory for the protocol_version will be created on the server. For example: ",(0,i.kt)("inlineCode",{parentName:"p"},"1_1_0"),"."),(0,i.kt)("p",null,"We will copy ",(0,i.kt)("inlineCode",{parentName:"p"},"bin.tar.gz")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"config.tar.gz")," into ",(0,i.kt)("inlineCode",{parentName:"p"},"1_1_0"),". Once this is done, we are safe to update ",(0,i.kt)("inlineCode",{parentName:"p"},"protocol_versions")," by appending ",(0,i.kt)("inlineCode",{parentName:"p"},"1_1_0")," to the end of the file and uploading it into the root of the network directory."),(0,i.kt)("p",null,"Any node that runs the following command will get this new upgrade:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper /etc/casper/node_util.py stage_protocols \n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/09666a94.648e341f.js b/assets/js/09666a94.9e0d8219.js similarity index 99% rename from assets/js/09666a94.648e341f.js rename to assets/js/09666a94.9e0d8219.js index cee34b84c2..8622e695e0 100644 --- a/assets/js/09666a94.648e341f.js +++ b/assets/js/09666a94.9e0d8219.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[716],{3905:function(e,t,a){a.d(t,{Zo:function(){return p},kt:function(){return m}});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=n.createContext({}),d=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=d(e.components);return n.createElement(s.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=d(a),h=i,m=c["".concat(s,".").concat(h)]||c[h]||u[h]||r;return a?n.createElement(m,o(o({ref:t},p),{},{components:a})):n.createElement(m,o({ref:t},p))}));function m(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:i,o[1]=l;for(var d=2;d \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-hash \\\n--session-entry-point delegate \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"delegator:public_key=''\"\n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,r.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,r.kt)("em",{parentName:"li"},"casper-test")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-hash")," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Testnet"),": ",(0,r.kt)("inlineCode",{parentName:"li"},"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Mainnet"),": ",(0,r.kt)("inlineCode",{parentName:"li"},"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"))),(0,r.kt)("ol",{start:6},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-entry-point")," - Name of the entry point that will be used when calling the contract")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"delegate")," entry point expects three arguments:"),(0,r.kt)("ol",{start:7},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"validator"),": The hexadecimal public key of the validator receiving the delegated tokens"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"amount"),": The number of tokens to be delegated"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"delegator"),": The hexadecimal public key of the account delegating tokens to a validator. ",(0,r.kt)("strong",{parentName:"li"},"This key must match the secret key that signs the delegation"))),(0,r.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,r.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#deploy-status"},"Deploy Status")," section for more details."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"delegate")," entry point on the auction contract has a fixed cost of 2.5 CSPR.")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Example:")),(0,r.kt)("p",null,"This example shows an account delegating 500 CSPR:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point delegate \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n")),(0,r.kt)("p",null,"Next, ",(0,r.kt)("a",{parentName:"p",href:"#confirming-the-delegation"},"confirm the delegation"),"."),(0,r.kt)("h3",{id:"delegating-compiled-wasm"},"Method 2: Delegating with Compiled Wasm"),(0,r.kt)("p",null,"Another way to send a delegation is to compile the ",(0,r.kt)("inlineCode",{parentName:"p"},"delegate.wasm")," and send it to the network via a deploy. Here are the steps to compile the contract yourself."),(0,r.kt)("h4",{id:"building-the-delegation-wasm"},"Building the delegation Wasm"),(0,r.kt)("p",null,"Obtain the ",(0,r.kt)("inlineCode",{parentName:"p"},"delegate.wasm")," by cloning the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node"},"casper-node")," repository."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/casper-network/casper-node\n")),(0,r.kt)("p",null,"Prepare the Rust environment and then build the contracts using the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/dev/Makefile"},"Makefile")," provided in the repository."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"cd casper-node\nmake setup-rs\nmake build-contracts-rs\n")),(0,r.kt)("p",null,"Once you build the contracts, you can use the ",(0,r.kt)("inlineCode",{parentName:"p"},"delegate.wasm")," to create a deploy that will initiate the delegation process. The Wasm can be found in this directory: ",(0,r.kt)("inlineCode",{parentName:"p"},"target/wasm32-unknown-unknown/release/"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"ls target/wasm32-unknown-unknown/release/delegate.wasm\n")),(0,r.kt)("h4",{id:"sending-the-delegation-wasm-request"},"Sending the delegation request"),(0,r.kt)("p",null,"In this example, we use the Casper client to send a deploy containing the ",(0,r.kt)("inlineCode",{parentName:"p"},"delegate.wasm")," to the network to initiate the delegation process."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-path /delegate.wasm \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"delegator:public_key=''\"\n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,r.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,r.kt)("em",{parentName:"li"},"casper-test")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to where the ",(0,r.kt)("inlineCode",{parentName:"li"},"delegate.wasm")," is located")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"delegate")," entry point expects three arguments:"),(0,r.kt)("ol",{start:6},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"validator"),": The hexadecimal public key of the validator receiving the delegated tokens"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"amount"),": The number of tokens to be delegated"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"delegator"),": The hexadecimal public key of the account delegating tokens to a validator. ",(0,r.kt)("strong",{parentName:"li"},"This key must match the secret key that signs the delegation"))),(0,r.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,r.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#deploy-status"},"Deploy Status")," section for more details."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Example:")),(0,r.kt)("p",null,"This example command uses the Casper Testnet to delegate 500 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),". However, notice that this method is more expensive than the previous one that calls the delegate entry point."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 20000000000 \\\n--session-path ~/delegate.wasm \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n")),(0,r.kt)("p",null,"Next, ",(0,r.kt)("a",{parentName:"p",href:"#confirming-the-delegation"},"confirm the delegation"),"."),(0,r.kt)("h2",{id:"confirming-the-delegation"},"Confirming the Delegation"),(0,r.kt)("p",null,"A Casper network maintains an ",(0,r.kt)("em",{parentName:"p"},"auction")," where validators ",(0,r.kt)("em",{parentName:"p"},"bid")," on slots to become part of the active validator set. Delegation rewards are only earned for a validator who has won the auction and is part of the active set. Thus to ensure the delegated tokens can earn rewards, you must first check the foloowing:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Your delegation is part of the ",(0,r.kt)("em",{parentName:"li"},"bid")," to the ",(0,r.kt)("em",{parentName:"li"},"auction")),(0,r.kt)("li",{parentName:"ol"},"The validator is part of the ",(0,r.kt)("em",{parentName:"li"},"active")," validator set")),(0,r.kt)("p",null,"Once the deploy has been processed, you can query the auction for information to confirm our delegation. Use the Casper command-line client to create an RPC request with the following query:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-auction-info \\\n--node-address http://:7777\n")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Request fields"),":"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"get-auction-info")," call will return all the bids currently in the auction contract and the list of active validators for ",(0,r.kt)("inlineCode",{parentName:"p"},"4")," future eras from the present era."),(0,r.kt)("p",null,"Below is a sample of the ",(0,r.kt)("inlineCode",{parentName:"p"},"bids")," structure:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"bids": [\n{\n "bid": {\n "bonding_purse": "uref-a5ce7dbc5f7e02ef52048e64b2ff4693a472a1a56fe71e83b180cd33271b2ed9-007",\n "delegation_rate": 1,\n "delegators": [\n {\n "bonding_purse": "uref-ca9247ad56a4d5be70484303133e2d6db97f7d7385772155763749af98ace0b0-007",\n "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "public_key": "010c7fef89bf1fc38363bd2ec20bbfb5e1152d6a9579c8847615c59c7e461ece89",\n "staked_amount": "1"\n },\n {\n "bonding_purse": "uref-38a2e9cad51b380e478c9a325578f4bbdaa0337b99b9ab9bf1dc2a114eb948b9-007",\n "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "public_key": "016ebb38d613f2550e7c21ff9d99f6249b4ae5fb9e30938f6ece2d84a22a36b035",\n "staked_amount": "478473232415318176495746923"\n }\n ],\n "inactive": false,\n "staked_amount": "493754513995516852173468935"\n },\n "public_key": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd"\n},\n')),(0,r.kt)("p",null,"The delegation request has been processed successfully if your public key and associated amount appear in the ",(0,r.kt)("inlineCode",{parentName:"p"},"bid")," data structure. However, this does not mean the associated validator is part of the validator set, so you must check the validator status recorded in the ",(0,r.kt)("inlineCode",{parentName:"p"},"era_validators")," structure."),(0,r.kt)("h4",{id:"checking-validator-status"},"Checking Validator Status"),(0,r.kt)("p",null,"The auction maintains a field called ",(0,r.kt)("inlineCode",{parentName:"p"},"era_validators"),", which contains the validator information for 4 future eras from the current era. An entry for a specific era lists the ",(0,r.kt)("inlineCode",{parentName:"p"},"PublicKeys")," of the active validators for that era, along with their stake in the network."),(0,r.kt)("p",null,"If a validator is part of the set, its public key will be in the ",(0,r.kt)("inlineCode",{parentName:"p"},"era_validators")," field as part of the ",(0,r.kt)("inlineCode",{parentName:"p"},"Auction")," data structure returned by ",(0,r.kt)("inlineCode",{parentName:"p"},"casper-client get-auction-info"),"."),(0,r.kt)("p",null,"In the response, check the ",(0,r.kt)("inlineCode",{parentName:"p"},'"auction_state"."era_validators"')," structure, which should contain the public key of the selected validator for the era in which the validator will be active."),(0,r.kt)("p",null,"Below is an example of the ",(0,r.kt)("inlineCode",{parentName:"p"},"era_validators")," structure:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"block_height":105,\n "era_validators":[\n {\n "era_id":9,\n "validator_weights":[\n {\n "public_key":"0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "weight":"648151805935226166098427654"\n },\n {\n "public_key":"01aa67009b37a23c7ad0ca632da5da239d5db46067d4b34125f61b04611f610baf",\n "weight":"648151805938466925128109996"\n },\n {\n "public_key":"01b7afa2beeddffd13458b763d7a00259f7dc0fa45498dfed05b4d7df4b7d65e2c",\n "weight":"648151805935226166098427656"\n },\n {\n "public_key":"01ca5463dac047cbd750d97ee42dd810cf1e081ece7d83ae4fc03b25a9ecad3b6a",\n "weight":"648151805938466925128109998"\n },\n {\n "public_key":"01f4a7644695aa129eba09fb3f11d0277b2bea1a3d5bc1933bcda93fdb4ad17e55",\n "weight":"648151805938466925128110000"\n }\n ]\n },\n')),(0,r.kt)("p",null,"In the above example, we see the public keys of the active validators in Era ",(0,r.kt)("inlineCode",{parentName:"p"},"9"),"."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Note"),": Validators earn delegation rewards only when they are part of the active set. This information is time-sensitive; therefore, a validator selected today may not be part of the set tomorrow. Keep this in mind when creating a delegation request."),(0,r.kt)("p",null,"If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been delegated:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"https://testnet.cspr.live/"},"Testnet explorer")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"https://cspr.live/"},"Mainnet explorer"))))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[716],{3905:function(e,t,a){a.d(t,{Zo:function(){return p},kt:function(){return m}});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=n.createContext({}),d=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=d(e.components);return n.createElement(s.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=d(a),h=i,m=c["".concat(s,".").concat(h)]||c[h]||u[h]||r;return a?n.createElement(m,o(o({ref:t},p),{},{components:a})):n.createElement(m,o({ref:t},p))}));function m(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:i,o[1]=l;for(var d=2;d \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-hash \\\n--session-entry-point delegate \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"delegator:public_key=''\"\n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,r.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,r.kt)("em",{parentName:"li"},"casper-test")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-hash")," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Testnet"),": ",(0,r.kt)("inlineCode",{parentName:"li"},"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Mainnet"),": ",(0,r.kt)("inlineCode",{parentName:"li"},"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"))),(0,r.kt)("ol",{start:6},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-entry-point")," - Name of the entry point that will be used when calling the contract")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"delegate")," entry point expects three arguments:"),(0,r.kt)("ol",{start:7},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"validator"),": The hexadecimal public key of the validator receiving the delegated tokens"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"amount"),": The number of tokens to be delegated"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"delegator"),": The hexadecimal public key of the account delegating tokens to a validator. ",(0,r.kt)("strong",{parentName:"li"},"This key must match the secret key that signs the delegation"))),(0,r.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,r.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#deploy-status"},"Deploy Status")," section for more details."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"delegate")," entry point on the auction contract has a fixed cost of 2.5 CSPR.")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Example:")),(0,r.kt)("p",null,"This example shows an account delegating 500 CSPR:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point delegate \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n")),(0,r.kt)("p",null,"Next, ",(0,r.kt)("a",{parentName:"p",href:"#confirming-the-delegation"},"confirm the delegation"),"."),(0,r.kt)("h3",{id:"delegating-compiled-wasm"},"Method 2: Delegating with Compiled Wasm"),(0,r.kt)("p",null,"Another way to send a delegation is to compile the ",(0,r.kt)("inlineCode",{parentName:"p"},"delegate.wasm")," and send it to the network via a deploy. Here are the steps to compile the contract yourself."),(0,r.kt)("h4",{id:"building-the-delegation-wasm"},"Building the delegation Wasm"),(0,r.kt)("p",null,"Obtain the ",(0,r.kt)("inlineCode",{parentName:"p"},"delegate.wasm")," by cloning the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node"},"casper-node")," repository."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/casper-network/casper-node\n")),(0,r.kt)("p",null,"Prepare the Rust environment and then build the contracts using the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/dev/Makefile"},"Makefile")," provided in the repository."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"cd casper-node\nmake setup-rs\nmake build-contracts-rs\n")),(0,r.kt)("p",null,"Once you build the contracts, you can use the ",(0,r.kt)("inlineCode",{parentName:"p"},"delegate.wasm")," to create a deploy that will initiate the delegation process. The Wasm can be found in this directory: ",(0,r.kt)("inlineCode",{parentName:"p"},"target/wasm32-unknown-unknown/release/"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"ls target/wasm32-unknown-unknown/release/delegate.wasm\n")),(0,r.kt)("h4",{id:"sending-the-delegation-wasm-request"},"Sending the delegation request"),(0,r.kt)("p",null,"In this example, we use the Casper client to send a deploy containing the ",(0,r.kt)("inlineCode",{parentName:"p"},"delegate.wasm")," to the network to initiate the delegation process."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-path /delegate.wasm \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"delegator:public_key=''\"\n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,r.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,r.kt)("em",{parentName:"li"},"casper-test")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to where the ",(0,r.kt)("inlineCode",{parentName:"li"},"delegate.wasm")," is located")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"delegate")," entry point expects three arguments:"),(0,r.kt)("ol",{start:6},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"validator"),": The hexadecimal public key of the validator receiving the delegated tokens"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"amount"),": The number of tokens to be delegated"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"delegator"),": The hexadecimal public key of the account delegating tokens to a validator. ",(0,r.kt)("strong",{parentName:"li"},"This key must match the secret key that signs the delegation"))),(0,r.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,r.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#deploy-status"},"Deploy Status")," section for more details."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Example:")),(0,r.kt)("p",null,"This example command uses the Casper Testnet to delegate 500 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),". However, notice that this method is more expensive than the previous one that calls the delegate entry point."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 20000000000 \\\n--session-path ~/delegate.wasm \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n")),(0,r.kt)("p",null,"Next, ",(0,r.kt)("a",{parentName:"p",href:"#confirming-the-delegation"},"confirm the delegation"),"."),(0,r.kt)("h2",{id:"confirming-the-delegation"},"Confirming the Delegation"),(0,r.kt)("p",null,"A Casper network maintains an ",(0,r.kt)("em",{parentName:"p"},"auction")," where validators ",(0,r.kt)("em",{parentName:"p"},"bid")," on slots to become part of the active validator set. Delegation rewards are only earned for a validator who has won the auction and is part of the active set. Thus to ensure the delegated tokens can earn rewards, you must first check the foloowing:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Your delegation is part of the ",(0,r.kt)("em",{parentName:"li"},"bid")," to the ",(0,r.kt)("em",{parentName:"li"},"auction")),(0,r.kt)("li",{parentName:"ol"},"The validator is part of the ",(0,r.kt)("em",{parentName:"li"},"active")," validator set")),(0,r.kt)("p",null,"Once the deploy has been processed, you can query the auction for information to confirm our delegation. Use the Casper command-line client to create an RPC request with the following query:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-auction-info \\\n--node-address http://:7777\n")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Request fields"),":"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"get-auction-info")," call will return all the bids currently in the auction contract and the list of active validators for ",(0,r.kt)("inlineCode",{parentName:"p"},"4")," future eras from the present era."),(0,r.kt)("p",null,"Below is a sample of the ",(0,r.kt)("inlineCode",{parentName:"p"},"bids")," structure:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"bids": [\n{\n "bid": {\n "bonding_purse": "uref-a5ce7dbc5f7e02ef52048e64b2ff4693a472a1a56fe71e83b180cd33271b2ed9-007",\n "delegation_rate": 1,\n "delegators": [\n {\n "bonding_purse": "uref-ca9247ad56a4d5be70484303133e2d6db97f7d7385772155763749af98ace0b0-007",\n "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "public_key": "010c7fef89bf1fc38363bd2ec20bbfb5e1152d6a9579c8847615c59c7e461ece89",\n "staked_amount": "1"\n },\n {\n "bonding_purse": "uref-38a2e9cad51b380e478c9a325578f4bbdaa0337b99b9ab9bf1dc2a114eb948b9-007",\n "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "public_key": "016ebb38d613f2550e7c21ff9d99f6249b4ae5fb9e30938f6ece2d84a22a36b035",\n "staked_amount": "478473232415318176495746923"\n }\n ],\n "inactive": false,\n "staked_amount": "493754513995516852173468935"\n },\n "public_key": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd"\n},\n')),(0,r.kt)("p",null,"The delegation request has been processed successfully if your public key and associated amount appear in the ",(0,r.kt)("inlineCode",{parentName:"p"},"bid")," data structure. However, this does not mean the associated validator is part of the validator set, so you must check the validator status recorded in the ",(0,r.kt)("inlineCode",{parentName:"p"},"era_validators")," structure."),(0,r.kt)("h4",{id:"checking-validator-status"},"Checking Validator Status"),(0,r.kt)("p",null,"The auction maintains a field called ",(0,r.kt)("inlineCode",{parentName:"p"},"era_validators"),", which contains the validator information for 4 future eras from the current era. An entry for a specific era lists the ",(0,r.kt)("inlineCode",{parentName:"p"},"PublicKeys")," of the active validators for that era, along with their stake in the network."),(0,r.kt)("p",null,"If a validator is part of the set, its public key will be in the ",(0,r.kt)("inlineCode",{parentName:"p"},"era_validators")," field as part of the ",(0,r.kt)("inlineCode",{parentName:"p"},"Auction")," data structure returned by ",(0,r.kt)("inlineCode",{parentName:"p"},"casper-client get-auction-info"),"."),(0,r.kt)("p",null,"In the response, check the ",(0,r.kt)("inlineCode",{parentName:"p"},'"auction_state"."era_validators"')," structure, which should contain the public key of the selected validator for the era in which the validator will be active."),(0,r.kt)("p",null,"Below is an example of the ",(0,r.kt)("inlineCode",{parentName:"p"},"era_validators")," structure:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"block_height":105,\n "era_validators":[\n {\n "era_id":9,\n "validator_weights":[\n {\n "public_key":"0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "weight":"648151805935226166098427654"\n },\n {\n "public_key":"01aa67009b37a23c7ad0ca632da5da239d5db46067d4b34125f61b04611f610baf",\n "weight":"648151805938466925128109996"\n },\n {\n "public_key":"01b7afa2beeddffd13458b763d7a00259f7dc0fa45498dfed05b4d7df4b7d65e2c",\n "weight":"648151805935226166098427656"\n },\n {\n "public_key":"01ca5463dac047cbd750d97ee42dd810cf1e081ece7d83ae4fc03b25a9ecad3b6a",\n "weight":"648151805938466925128109998"\n },\n {\n "public_key":"01f4a7644695aa129eba09fb3f11d0277b2bea1a3d5bc1933bcda93fdb4ad17e55",\n "weight":"648151805938466925128110000"\n }\n ]\n },\n')),(0,r.kt)("p",null,"In the above example, we see the public keys of the active validators in Era ",(0,r.kt)("inlineCode",{parentName:"p"},"9"),"."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Note"),": Validators earn delegation rewards only when they are part of the active set. This information is time-sensitive; therefore, a validator selected today may not be part of the set tomorrow. Keep this in mind when creating a delegation request."),(0,r.kt)("p",null,"If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been delegated:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"https://testnet.cspr.live/"},"Testnet explorer")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"https://cspr.live/"},"Mainnet explorer"))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/09f38b0b.d87933eb.js b/assets/js/09f38b0b.e30ba452.js similarity index 98% rename from assets/js/09f38b0b.d87933eb.js rename to assets/js/09f38b0b.e30ba452.js index fb6c75a763..0b209cef83 100644 --- a/assets/js/09f38b0b.d87933eb.js +++ b/assets/js/09f38b0b.e30ba452.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[972],{3905:function(e,t,r){r.d(t,{Zo:function(){return l},kt:function(){return d}});var o=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function s(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=o.createContext({}),i=function(e){var t=o.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},l=function(e){var t=i(e.components);return o.createElement(p.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},f=o.forwardRef((function(e,t){var r=e.components,a=e.mdxType,n=e.originalType,p=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),h=i(r),f=a,d=h["".concat(p,".").concat(f)]||h[f]||u[f]||n;return r?o.createElement(d,s(s({ref:t},l),{},{components:r})):o.createElement(d,s({ref:t},l))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var n=r.length,s=new Array(n);s[0]=f;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[h]="string"==typeof e?e:a,s[1]=c;for(var i=2;i=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=o.createContext({}),i=function(e){var t=o.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},l=function(e){var t=i(e.components);return o.createElement(p.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},f=o.forwardRef((function(e,t){var r=e.components,a=e.mdxType,n=e.originalType,p=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),h=i(r),f=a,d=h["".concat(p,".").concat(f)]||h[f]||u[f]||n;return r?o.createElement(d,s(s({ref:t},l),{},{components:r})):o.createElement(d,s({ref:t},l))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var n=r.length,s=new Array(n);s[0]=f;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[h]="string"==typeof e?e:a,s[1]=c;for(var i=2;i=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),i=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},p=function(e){var t=i(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=i(a),h=r,m=u["".concat(c,".").concat(h)]||u[h]||d[h]||o;return a?n.createElement(m,l(l({ref:t},p),{},{components:a})):n.createElement(m,l({ref:t},p))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,l=new Array(o);l[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:r,l[1]=s;for(var i=2;i=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),i=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},p=function(e){var t=i(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=i(a),h=r,m=u["".concat(c,".").concat(h)]||u[h]||d[h]||o;return a?n.createElement(m,l(l({ref:t},p),{},{components:a})):n.createElement(m,l({ref:t},p))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,l=new Array(o);l[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:r,l[1]=s;for(var i=2;i=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),i=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):c(c({},t),e)),a},u=function(e){var t=i(e.components);return n.createElement(l.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),h=i(a),p=r,f=h["".concat(l,".").concat(p)]||h[p]||d[p]||o;return a?n.createElement(f,c(c({ref:t},u),{},{components:a})):n.createElement(f,c({ref:t},u))}));function f(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,c=new Array(o);c[0]=p;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[h]="string"==typeof e?e:r,c[1]=s;for(var i=2;i=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),i=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):c(c({},t),e)),a},u=function(e){var t=i(e.components);return n.createElement(l.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),h=i(a),p=r,f=h["".concat(l,".").concat(p)]||h[p]||d[p]||o;return a?n.createElement(f,c(c({ref:t},u),{},{components:a})):n.createElement(f,c({ref:t},u))}));function f(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,c=new Array(o);c[0]=p;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[h]="string"==typeof e?e:r,c[1]=s;for(var i=2;i=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(r),y=a,m=f["".concat(p,".").concat(y)]||f[y]||i[y]||o;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[f]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(r),y=a,m=f["".concat(p,".").concat(y)]||f[y]||i[y]||o;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[f]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=r.createContext({}),l=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return r.createElement(p.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=l(n),u=a,h=m["".concat(p,".").concat(u)]||m[u]||d[u]||o;return n?r.createElement(h,i(i({ref:t},c),{},{components:n})):r.createElement(h,i({ref:t},c))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=u;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[m]="string"==typeof e?e:a,i[1]=s;for(var l=2;l=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=r.createContext({}),l=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return r.createElement(p.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=l(n),u=a,h=m["".concat(p,".").concat(u)]||m[u]||d[u]||o;return n?r.createElement(h,i(i({ref:t},c),{},{components:n})):r.createElement(h,i({ref:t},c))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=u;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[m]="string"==typeof e?e:a,i[1]=s;for(var l=2;l=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var u=r.createContext({}),c=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=c(e.components);return r.createElement(u.Provider,{value:t},e.children)},p="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),p=c(n),h=o,A=p["".concat(u,".").concat(h)]||p[h]||g[h]||i;return n?r.createElement(A,a(a({ref:t},l),{},{components:n})):r.createElement(A,a({ref:t},l))}));function A(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=h;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[p]="string"==typeof e?e:o,a[1]=s;for(var c=2;c=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var u=r.createContext({}),c=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=c(e.components);return r.createElement(u.Provider,{value:t},e.children)},p="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),p=c(n),h=o,A=p["".concat(u,".").concat(h)]||p[h]||g[h]||i;return n?r.createElement(A,a(a({ref:t},l),{},{components:n})):r.createElement(A,a({ref:t},l))}));function A(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=h;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[p]="string"==typeof e?e:o,a[1]=s;for(var c=2;c=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),p=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(r),m=a,f=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return r?n.createElement(f,i(i({ref:t},c),{},{components:r})):n.createElement(f,i({ref:t},c))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:a,i[1]=l;for(var p=2;p=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),p=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(r),m=a,f=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return r?n.createElement(f,i(i({ref:t},c),{},{components:r})):n.createElement(f,i({ref:t},c))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:a,i[1]=l;for(var p=2;p=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),l=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),d=l(n),h=r,y=d["".concat(s,".").concat(h)]||d[h]||u[h]||o;return n?a.createElement(y,i(i({ref:t},c),{},{components:n})):a.createElement(y,i({ref:t},c))}));function y(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=h;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[d]="string"==typeof e?e:r,i[1]=p;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),l=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),d=l(n),h=r,y=d["".concat(s,".").concat(h)]||d[h]||u[h]||o;return n?a.createElement(y,i(i({ref:t},c),{},{components:n})):a.createElement(y,i({ref:t},c))}));function y(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=h;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[d]="string"==typeof e?e:r,i[1]=p;for(var l=2;l=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var a=n.createContext({}),s=function(e){var t=n.useContext(a),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},l=function(e){var t=s(e.components);return n.createElement(a.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,a=e.parentName,l=u(e,["components","mdxType","originalType","parentName"]),p=s(r),h=o,d=p["".concat(a,".").concat(h)]||p[h]||f[h]||i;return r?n.createElement(d,c(c({ref:t},l),{},{components:r})):n.createElement(d,c({ref:t},l))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,c=new Array(i);c[0]=h;var u={};for(var a in t)hasOwnProperty.call(t,a)&&(u[a]=t[a]);u.originalType=e,u[p]="string"==typeof e?e:o,c[1]=u;for(var s=2;s=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var a=n.createContext({}),s=function(e){var t=n.useContext(a),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},l=function(e){var t=s(e.components);return n.createElement(a.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,a=e.parentName,l=u(e,["components","mdxType","originalType","parentName"]),p=s(r),h=o,d=p["".concat(a,".").concat(h)]||p[h]||f[h]||i;return r?n.createElement(d,c(c({ref:t},l),{},{components:r})):n.createElement(d,c({ref:t},l))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,c=new Array(i);c[0]=h;var u={};for(var a in t)hasOwnProperty.call(t,a)&&(u[a]=t[a]);u.originalType=e,u[p]="string"==typeof e?e:o,c[1]=u;for(var s=2;s=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),h=c(a),u=i,m=h["".concat(l,".").concat(u)]||h[u]||d[u]||o;return a?n.createElement(m,r(r({ref:t},p),{},{components:a})):n.createElement(m,r({ref:t},p))}));function m(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=a.length,r=new Array(o);r[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[h]="string"==typeof e?e:i,r[1]=s;for(var c=2;cURefs",id:"execution-semantics-urefs",level:4},{value:"Accounts",id:"accounts-head",level:2},{value:"Creating an account",id:"accounts-creating",level:3},{value:"Permissions Model",id:"accounts-permissions",level:3},{value:"Actions and Thresholds",id:"accounts-actions-thresholds",level:4},{value:"Associated Keys and Weights",id:"accounts-associated-keys-weights",level:4},{value:"Key Management Actions",id:"accounts-key-management",level:4},{value:"Account security and recovery using key management",id:"accounts-recovery",level:4},{value:"The Account Context",id:"accounts-context",level:3},{value:"Unforgeable Reference (URef)",id:"uref-head",level:2},{value:"Permissions for URefs",id:"uref-permissions",level:3},{value:"URefs and Purses",id:"urefs-and-purses",level:3},{value:"Block Structure",id:"block-structure-head",level:2},{value:"Data Fields",id:"block-structure-data",level:3},{value:"block_hash",id:"block_hash",level:4},{value:"Header",id:"header",level:4},{value:"Body",id:"body",level:4},{value:"Tokens",id:"tokens-head",level:2},{value:"Token Generation and Distribution",id:"token-generation-and-distribution",level:3},{value:"Divisibility of Tokens",id:"tokens-divisibility",level:3},{value:"Purses and Accounts",id:"tokens-purses-and-accounts",level:3},{value:"The Casper Mint Contract",id:"mint-contract",level:3},{value:"The mint Contract Interface",id:"tokens-mint-interface",level:2}],d={toc:h},u="wrapper";function m(e){var t=e.components,s=(0,i.Z)(e,r);return(0,o.kt)(u,(0,n.Z)({},d,s,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"casper-network-design"},"Casper Network Design"),(0,o.kt)("h2",{id:"introduction"},"Introduction"),(0,o.kt)("p",null,"Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#consensus"},"consensus"),". A Casper network stores data in a structure known as ",(0,o.kt)("a",{parentName:"p",href:"/concepts/global-state"},"Global State"),". Users interact with global state through session code sent in a ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/D#deploy"},"Deploy"),". Deploys contain ",(0,o.kt)("a",{parentName:"p",href:"https://webassembly.org/"},"Wasm")," to be executed by the network, thus allowing developers to use their preferred programming language rather than a proprietary language."),(0,o.kt)("p",null,"A deploy executes in the context of the user's ",(0,o.kt)("a",{parentName:"p",href:"#accounts-head"},"Account")," but can call stored Wasm that will execute in its own context. User-related information other than an account is stored in global state as an ",(0,o.kt)("a",{parentName:"p",href:"#uref-head"},"Unforgeable Reference")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),". After a node accepts a deploy as valid, it places the deploy in a proposed ",(0,o.kt)("a",{parentName:"p",href:"#block-structure-head"},"Block")," and gossips it among nodes until the network reaches consensus. At this point, the network executes the Wasm included within the deploy."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("a",{parentName:"p",href:"#execution-semantics-head"},"Execution Semantics"))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("a",{parentName:"p",href:"#accounts-head"},"Accounts"))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("a",{parentName:"p",href:"#uref-head"},"Unforgeable Reference (URef)"))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("a",{parentName:"p",href:"#block-structure-head"},"Block Structure"))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("a",{parentName:"p",href:"#tokens-head"},"Tokens")))),(0,o.kt)("h2",{id:"execution-semantics-head"},"Execution Semantics"),(0,o.kt)("p",null,"A Casper network is a decentralized computation platform. This section describes aspects of the Casper computational model."),(0,o.kt)("h3",{id:"execution-semantics-gas"},"Measuring Computational Work"),(0,o.kt)("p",null,"Computation is done in a ",(0,o.kt)("a",{parentName:"p",href:"https://webassembly.org/"},"WebAssembly (Wasm)")," interpreter, allowing any programming language which compiles to Wasm to become a smart contract language for the Casper blockchain. Similar to Ethereum, Casper uses ",(0,o.kt)("a",{parentName:"p",href:"/concepts/economics/gas-concepts"},(0,o.kt)("inlineCode",{parentName:"a"},"Gas"))," to measure computational work in a way that is consistent from node to node in a Casper network. Each Wasm opcode is assigned a ",(0,o.kt)("inlineCode",{parentName:"p"},"Gas")," cost, and the amount of gas spent is tracked by the runtime with each opcode executed by the interpreter."),(0,o.kt)("p",null,"Costs for opcode instructions on the Casper Mainnet network can be found ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/chainspec.toml#L115"},"here"),"."),(0,o.kt)("p",null,"All executions are finite because each has a finite ",(0,o.kt)("em",{parentName:"p"},"gas limit")," that specifies the maximum amount of gas available to spend before the runtime terminates the computation. The payment executable session determines how to pay for the deploy. The gas limit is set by executing the payment code specified within the deploy."),(0,o.kt)("p",null,"Although the network measures costs in ",(0,o.kt)("inlineCode",{parentName:"p"},"Gas"),", payment for computation occurs in ",(0,o.kt)("a",{parentName:"p",href:"#tokens-divisibility"},"motes"),". Therefore, there is a conversion rate between ",(0,o.kt)("inlineCode",{parentName:"p"},"Gas")," and motes."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Please note that Casper will not refund any amount of unused gas."),(0,o.kt)("p",{parentName:"admonition"},"This decision is taken to incentivize the ",(0,o.kt)("a",{parentName:"p",href:"/runtime#runtime-economics"},"Casper Runtime Economics")," by efficiently allocating the computational resources. The ",(0,o.kt)("a",{parentName:"p",href:"/runtime#consensus-before-execution-basics-of-payment"},"consensus-before-execution model")," implements the mechanism to encourage the optimized gas consumption from users and to prevent the overuse of block space by poorly handled deploys.")),(0,o.kt)("h3",{id:"execution-semantics-runtime"},"The Casper Network Runtime"),(0,o.kt)("p",null,"A Wasm module is not natively able to create any effects outside of reading or writing from its own linear memory. Wasm modules must import functions from the host environment they are running in to enable other desired effects, such as reading or writing to global state."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"Casper Network Runtime",src:a(7440).Z,width:"1220",height:"604"})),(0,o.kt)("p",null,"All these features are accessible via functions in the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html"},"Casper External FFI"),"."),(0,o.kt)("h4",{id:"execution-semantics-urefs"},"Generating ",(0,o.kt)("inlineCode",{parentName:"h4"},"URef"),"s"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s are generated using a ",(0,o.kt)("a",{parentName:"p",href:"https://rust-random.github.io/rand/rand_chacha/struct.ChaCha20Rng.html"},"cryptographically secure random number generator")," using the ",(0,o.kt)("a",{parentName:"p",href:"https://cr.yp.to/chacha.html"},"ChaCha algorithm"),". The random number generator is seeded by taking the ",(0,o.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the deploy hash concatenated with an index representing the current phase of execution (to prevent collisions between ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s generated in different phases of the same deploy)."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"Generating URefs",src:a(4473).Z,width:"1121",height:"289"})),(0,o.kt)("h2",{id:"accounts-head"},"Accounts"),(0,o.kt)("p",null,"The Casper blockchain uses an on-chain account-based model, uniquely identified by an ",(0,o.kt)("inlineCode",{parentName:"p"},"AccountHash")," derived from a specific ",(0,o.kt)("inlineCode",{parentName:"p"},"PublicKey"),". The ",(0,o.kt)("a",{parentName:"p",href:"#global-state-trie"},"global state trie store")," requires all keys to be the same length, so the AccountHash is a 32-byte derivative used to abstract any of the supported public key variants."),(0,o.kt)("p",null,"The Casper platform supports two types of keys for creating accounts and signing transactions:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/concepts/accounts-and-keys#eddsa-keys"},"Ed25519")," keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/concepts/accounts-and-keys#ecdsa-keys"},"Secp256k1")," keys, commonly known as Ethereum keys, which are 68 bytes long")),(0,o.kt)("p",null,'By default, a transactional interaction with the blockchain takes the form of a Deploy cryptographically signed by the key-pair corresponding to the PublicKey used to create the account. All user activity on the Casper blockchain (i.e., "deploys") must originate from an account. Each account has its own context where it can locally store information (e.g., references to useful contracts, metrics, and aggregated data from other parts of the blockchain). Each account also has a "main purse" where it can hold Casper tokens (see ',(0,o.kt)("a",{parentName:"p",href:"#tokens-purses-and-accounts"},"Tokens")," for more information)."),(0,o.kt)("p",null,"This chapter describes the permission model for accounts and their local storage capabilities and briefly mentions some runtime functions for interacting with accounts."),(0,o.kt)("h3",{id:"accounts-creating"},"Creating an account"),(0,o.kt)("p",null,"Account creation automatically happens upon transferring tokens to a yet unused ",(0,o.kt)("inlineCode",{parentName:"p"},"PublicKey"),". On account creation, the balance of its main purse is equal to the number of tokens transferred during the creation process. Its action thresholds are equal to 1, and there is one associated key. The associated key is the ",(0,o.kt)("inlineCode",{parentName:"p"},"PublicKey")," used to create the account. In this way, an account is essentially a context object encapsulating the main purse, used to pay for transactions. However, an account may have an additional purse beyond the main purse."),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{src:"/image/design/account-structure.png",alt:"Image showing the account data structure",width:"200"})),(0,o.kt)("p",null,"An ",(0,o.kt)("inlineCode",{parentName:"p"},"Account")," contains the following data:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"A ",(0,o.kt)("inlineCode",{parentName:"li"},"URef"),' representing the account\'s "main purse"'),(0,o.kt)("li",{parentName:"ul"},"A collection of named keys (playing the same role as the named keys in a stored contract)"),(0,o.kt)("li",{parentName:"ul"},'A collection of "associated keys" (see ',(0,o.kt)("a",{parentName:"li",href:"#accounts-associated-keys-weights"},"below for more information"),")"),(0,o.kt)("li",{parentName:"ul"},'"Action thresholds" (see ',(0,o.kt)("a",{parentName:"li",href:"#accounts-actions-thresholds"},"below for more information"),")")),(0,o.kt)("h3",{id:"accounts-permissions"},"Permissions Model"),(0,o.kt)("h4",{id:"accounts-actions-thresholds"},"Actions and Thresholds"),(0,o.kt)("p",null,"An account can perform two types of actions: sending deploys and managing keys. A deploy is simply executing some code on the blockchain, while key management involves changing the associated keys (which will be described in more detail later). Key management cannot be performed independently, as all effects on the blockchain must come via a deploy; therefore, a key management action implies that a deploy action is also taking place."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"ActionThresholds")," contained in the ",(0,o.kt)("inlineCode",{parentName:"p"},"Account")," data structure set a ",(0,o.kt)("inlineCode",{parentName:"p"},"Weight"),", which must be met to perform that action. The next section describes these weight thresholds. Since a key management action requires a deploy action, the key management threshold should always be greater than or equal to the deploy threshold."),(0,o.kt)("h4",{id:"accounts-associated-keys-weights"},"Associated Keys and Weights"),(0,o.kt)("p",null,"Accounts on a Casper network can associate other key pairs through a multiple signature scheme for sending transactions. An account's ",(0,o.kt)("em",{parentName:"p"},"associated keys"),' are the set of public keys allowed to provide signatures on deploys for that account. Each associated key has a weight; these weights combine to meet the action thresholds provided in the previous section. Each deploy must be signed by one or more keys associated with the account that deploy is for, and the sum of the weights of those keys must be greater than or equal to the deployment threshold weight for that account. We call the keys that have signed a deploy the "authorizing keys". Similarly, if a deploy contains key management actions (detailed below), the sum of the weights of the authorizing keys must be greater than or equal to the key management action threshold of the account.'),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},'Any key may help authorize any action; there are no "special keys". All keys contribute their weight in exactly the same way.')),(0,o.kt)("h4",{id:"accounts-key-management"},"Key Management Actions"),(0,o.kt)("p",null,"A ",(0,o.kt)("em",{parentName:"p"},"key management action")," is a change to the account permissions, including:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Adding or removing an associated key"),(0,o.kt)("li",{parentName:"ul"},"Changing the weight of an associated key"),(0,o.kt)("li",{parentName:"ul"},"Changing the threshold of any action")),(0,o.kt)("p",null,"Key management actions have validity rules preventing users from locking themselves out of their accounts. For example, one can set a threshold, at most, the sum of the weights of all associated keys."),(0,o.kt)("h4",{id:"accounts-recovery"},"Account security and recovery using key management"),(0,o.kt)("p",null,"This permissions model's purpose is to keep accounts safe from lost or stolen keys while allowing the usage of modern mobile devices. For example, it may be convenient to sign deploys from a smartphone without worrying about the repercussions of losing the phone. The recommended setup is to have a low-weight key on the phone, enough for the deploy threshold but not enough for key management. If the phone is lost or stolen, a key management action using other associated keys from another device (e.g., a home computer) can be used to remove the lost associated key and add a key that resides on a replacement phone."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},'It is extremely important to ensure there will always be access to a sufficient number of keys to perform the key management action. Otherwise, future recovery will be impossible (Casper currently does not support "inactive recovery").')),(0,o.kt)("h3",{id:"accounts-context"},"The Account Context"),(0,o.kt)("p",null,"A deploy is a user request to perform some execution on the blockchain (see ",(0,o.kt)("a",{parentName:"p",href:"#execution-semantics-head"},"Execution Semantics"),' for more information). It contains "payment code" and "session code", which are references to stored on-chain contracts or Wasm to be executed. For executable Wasm, its execution and the logic therein occur within the context of the account signing the deploy. This means that the executing Wasm has access to the named keys and main purse of the account\'s context.'),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"In the case where there is a reference to stored on-chain Wasm (smart contracts), the execution of the on-chain Wasm will occur in its own separate runtime context. As a result, the stored Wasm will not have access to the named keys or main purse of the calling account.")),(0,o.kt)("h2",{id:"uref-head"},"Unforgeable Reference (URef)"),(0,o.kt)("p",null,"This key type is used for storing any value except ",(0,o.kt)("inlineCode",{parentName:"p"},"Account"),". Additionally, ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s used in Wasm carry permission information to prevent unauthorized usage of the value stored under the key. The runtime tracks this permission information. This means that if malicious Wasm attempts to produce a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),' with permissions that the Wasm does not have, the Wasm has attempted to "forge" the unforgeable reference, and the runtime will raise a forged ',(0,o.kt)("inlineCode",{parentName:"p"},"URef")," error. Permissions for a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," can be given across contract calls, allowing data stored under a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," to be shared in a controlled way. The 32-byte identifier representing the key is generated randomly by the runtime (see ",(0,o.kt)("a",{parentName:"p",href:"#execution-semantics-head"},"Execution Semantics")," for more information). The serialization for ",(0,o.kt)("inlineCode",{parentName:"p"},"Access Rights")," that define the permissions for ",(0,o.kt)("inlineCode",{parentName:"p"},"URefs")," is detailed in the ",(0,o.kt)("a",{parentName:"p",href:"/concepts/serialization-standard"},"CLValues")," section."),(0,o.kt)("h3",{id:"uref-permissions"},"Permissions for ",(0,o.kt)("inlineCode",{parentName:"h3"},"URef"),"s"),(0,o.kt)("p",null,"In the runtime, a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," carries its permissions called ",(0,o.kt)("inlineCode",{parentName:"p"},"AccessRights"),". Additionally, the runtime tracks what ",(0,o.kt)("inlineCode",{parentName:"p"},"AccessRights")," would be valid for each ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," in each context. The system assumes that a sent ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," is invalid, regardless of declared ",(0,o.kt)("inlineCode",{parentName:"p"},"AccessRights"),", and will check it against the executing context to determine validity on each usage. Only the host logic can add a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),", in the following ways:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},'It can exist in a set of "known" ',(0,o.kt)("inlineCode",{parentName:"li"},"URef"),"s"),(0,o.kt)("li",{parentName:"ul"},"It can be freshly created by the runtime via the ",(0,o.kt)("inlineCode",{parentName:"li"},"new_uref")," function"),(0,o.kt)("li",{parentName:"ul"},"For called contracts, the caller can pass it in via the arguments to ",(0,o.kt)("inlineCode",{parentName:"li"},"call_contract")),(0,o.kt)("li",{parentName:"ul"},"It can be returned to the caller from ",(0,o.kt)("inlineCode",{parentName:"li"},"call_contract")," via the ",(0,o.kt)("inlineCode",{parentName:"li"},"ret")," function")),(0,o.kt)("p",null,"Note that only valid ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s may be added to the known ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s or cross-call boundaries; this means the system cannot be tricked into accepting a forged ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," by getting it through a contract or stashing it in the known ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s."),(0,o.kt)("p",null,"The ability to pass ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s between contexts via ",(0,o.kt)("inlineCode",{parentName:"p"},"call_contract")," / ",(0,o.kt)("inlineCode",{parentName:"p"},"ret"),", allows them to share state among a fixed number of parties while keeping it private from all others."),(0,o.kt)("h3",{id:"urefs-and-purses"},(0,o.kt)("inlineCode",{parentName:"h3"},"URef"),"s and Purses"),(0,o.kt)("p",null,"Purses represent a unique type of ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," used for accounting measures within a Casper network. ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s exist as a top-level entity, meaning that individual accounts do not own \u2018URef\u2019s. As described above, accounts and contracts possess certain ",(0,o.kt)("inlineCode",{parentName:"p"},"Access Rights"),", allowing them to interact with the given ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),". While an account will possess an associated ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," representing their main purse, this ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," exists as a ",(0,o.kt)("a",{parentName:"p",href:"/concepts/serialization-standard#clvalue-unit"},(0,o.kt)("inlineCode",{parentName:"a"},"Unit"))," and corresponds to a ",(0,o.kt)("em",{parentName:"p"},"balance")," key within the Casper ",(0,o.kt)("em",{parentName:"p"},"mint"),". The individual balance key within the Casper mint is the account's purse, with transfers authorized solely through the associated ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," and the ",(0,o.kt)("inlineCode",{parentName:"p"},"Access Rights")," granted to it."),(0,o.kt)("p",null,"Through this logic, the Casper mint holds all motes on the network and transfers between balance keys at the behest of accounts and contracts as required."),(0,o.kt)("h2",{id:"block-structure-head"},"Block Structure"),(0,o.kt)("p",null,"A ",(0,o.kt)("em",{parentName:"p"},"block")," is the primary data structure by which network nodes communicate information about the state of a Casper network. We briefly describe here the format of this data structure."),(0,o.kt)("h3",{id:"block-structure-data"},"Data Fields"),(0,o.kt)("p",null,"A block consists of the following:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"A ",(0,o.kt)("inlineCode",{parentName:"li"},"block_hash")),(0,o.kt)("li",{parentName:"ul"},"A header"),(0,o.kt)("li",{parentName:"ul"},"A body")),(0,o.kt)("p",null,"Each of these fields is detailed in the subsequent sections."),(0,o.kt)("h4",{id:"block_hash"},(0,o.kt)("inlineCode",{parentName:"h4"},"block_hash")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"block_hash")," is the ",(0,o.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the block header."),(0,o.kt)("h4",{id:"header"},"Header"),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"/concepts/serialization-standard#serialization-standard-block"},"block header")," contains the following fields:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"parent_hash")),(0,o.kt)("p",{parentName:"li"},"A list of ",(0,o.kt)("inlineCode",{parentName:"p"},"block_hash"),"es giving the parents of the block.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"state_root_hash")),(0,o.kt)("p",{parentName:"li"},"The global state root hash produced by executing this block's body.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"body_hash")),(0,o.kt)("p",{parentName:"li"},"The hash of the block body.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"random_bit")),(0,o.kt)("p",{parentName:"li"},"A boolean needed for initializing a future era.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"accumulated_seed")),(0,o.kt)("p",{parentName:"li"},"A seed needed for initializing a future era.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"era_end")),(0,o.kt)("p",{parentName:"li"},"Contains equivocation and reward information to be included in the terminal finalized block. It is an optional field.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"timestamp")),(0,o.kt)("p",{parentName:"li"},"The timestamp from when the block was proposed.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"era_id")),(0,o.kt)("p",{parentName:"li"},"Era ID in which this block was created.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"height")),(0,o.kt)("p",{parentName:"li"},"The height of this block, i.e., the number of ancestors.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"protocol_version")),(0,o.kt)("p",{parentName:"li"},"The version of the Casper network when this block was proposed."))),(0,o.kt)("h4",{id:"body"},"Body"),(0,o.kt)("p",null,"The block body contains an ",(0,o.kt)("strong",{parentName:"p"},"ordered")," list of ",(0,o.kt)("inlineCode",{parentName:"p"},"DeployHashes")," which refer to deploys, and an ",(0,o.kt)("strong",{parentName:"p"},"ordered")," list of ",(0,o.kt)("inlineCode",{parentName:"p"},"DeployHashes")," for native transfers (which are specialized deploys that only transfer tokens between accounts). All deploys, including a specialization such as native transfer, can be broadly categorized as some unit of work that, when executed and committed, affect change to ",(0,o.kt)("a",{parentName:"p",href:"#global-state-intro"},"Global State"),". A valid block may contain no deploys and / or native transfers."),(0,o.kt)("p",null,"The block body also contains the public key of the validator that proposed the block."),(0,o.kt)("p",null,"Refer to the ",(0,o.kt)("a",{parentName:"p",href:"/concepts/serialization-standard"},"Serialization Standard")," for additional information on how blocks and deploy are serialized."),(0,o.kt)("h2",{id:"tokens-head"},"Tokens"),(0,o.kt)("p",null,"Casper is a decentralized Proof-of-Stake blockchain platform that uses a consensus algorithm called ",(0,o.kt)("a",{parentName:"p",href:"/concepts/design/highway"},"Highway"),". Having a unit of value is required to make this system work because users must pay for computation, and validators must have ",(0,o.kt)("a",{parentName:"p",href:"/staking"},"stake")," to bond. In the blockchain space, this unit of value is a ",(0,o.kt)("em",{parentName:"p"},"token"),"."),(0,o.kt)("p",null,"This chapter describes tokens and how one can use them on the Casper platform."),(0,o.kt)("h3",{id:"token-generation-and-distribution"},"Token Generation and Distribution"),(0,o.kt)("p",null,"A blockchain system generally needs a supply of tokens available to pay for computation and reward validators for processing transactions on the network. The initial supply at the launch of Mainnet was 10 billion CSPR. The current supply is available ",(0,o.kt)("a",{parentName:"p",href:"https://api.cspr.live/supply"},"here"),". In addition to the initial supply, the system will have a low rate of inflation, the results of which will be paid out to validators in the form of seigniorage."),(0,o.kt)("p",null,"The number of tokens used to calculate seigniorage is the initial supply of tokens at genesis."),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{src:"/image/design/token-lifecycle.png",alt:"Image showing the token lifecycle",width:"700"})),(0,o.kt)("h3",{id:"tokens-divisibility"},"Divisibility of Tokens"),(0,o.kt)("p",null,"Typically, a ",(0,o.kt)("em",{parentName:"p"},"token")," is divisible into some number of parts. We call the indivisible units which make up the CSPR token ",(0,o.kt)("em",{parentName:"p"},"motes"),". Each CSPR is divisible into 10",(0,o.kt)("sup",null,"9")," motes. To avoid rounding errors, it is essential to always represent token balances in motes. In comparison, Ether is divisible into 10",(0,o.kt)("sup",null,"18")," parts called Wei."),(0,o.kt)("p",null,"The concept of ",(0,o.kt)("inlineCode",{parentName:"p"},"CSPR")," is human-readable convenience and does not exist within the actual infrastructure of a Casper network. Instead, all transactions deal solely with ",(0,o.kt)("em",{parentName:"p"},"motes"),"."),(0,o.kt)("h3",{id:"tokens-purses-and-accounts"},"Purses and Accounts"),(0,o.kt)("p",null,"All ",(0,o.kt)("a",{parentName:"p",href:"#accounts-head"},"accounts")," on the Casper system have a purse associated with the Casper system mint, called the ",(0,o.kt)("em",{parentName:"p"},"main purse"),". However, for security reasons, the ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," of the main purse is only available to code running in the context of that account (i.e. only in payment or session code). Therefore, the mint's ",(0,o.kt)("inlineCode",{parentName:"p"},"transfer")," method that accepts ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s is not the most convenient when transferring between account main purses. For this reason, Casper supplies a ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_account.html"},"transfer_to_account")," function, which takes the public key used to derive the identity key of the account. This function uses the mint transfer function with the current account's main purse as the ",(0,o.kt)("inlineCode",{parentName:"p"},"source")," and the main purse of the account at the provided key as the ",(0,o.kt)("inlineCode",{parentName:"p"},"target"),"."),(0,o.kt)("h3",{id:"mint-contract"},"The Casper Mint Contract"),(0,o.kt)("p",null,"The Casper ",(0,o.kt)("em",{parentName:"p"},"mint")," is a system contract that manages the balance of ",(0,o.kt)("em",{parentName:"p"},"motes")," within a Casper network. These motes are used to pay for computation and bonding on the network. The mint system contract holds all motes on a Casper network but maintains an internal ledger of the balances for each Account's ",(0,o.kt)("em",{parentName:"p"},"main purse"),". Each balance is associated with a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),", which is a key to instruct the mint to perform actions on that balance (e.g., transfer motes). Informally, these balances are referred to as ",(0,o.kt)("em",{parentName:"p"},"purses")," and conceptually represent a container for motes. The ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," is how a purse is referenced externally, outside the mint."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"AccessRights")," of the URefs permissions model determines what actions can be performed when using a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," associated with a purse."),(0,o.kt)("p",null,"As all ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s are unforgeable, the only way to interact with a purse is for a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," with appropriate ",(0,o.kt)("inlineCode",{parentName:"p"},"AccessRights")," to be validly given to the current context."),(0,o.kt)("p",null,"The basic global state options map onto more standard monetary operations according to the table below:"),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Global State"),(0,o.kt)("th",{parentName:"tr",align:null},"Action Monetary Action"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"Add"),(0,o.kt)("td",{parentName:"tr",align:null},"Deposit (i.e. transfer to)")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"Write"),(0,o.kt)("td",{parentName:"tr",align:null},"Withdraw (i.e. transfer from)")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"Read"),(0,o.kt)("td",{parentName:"tr",align:null},"Balance check")))),(0,o.kt)("h2",{id:"tokens-mint-interface"},"The mint Contract Interface"),(0,o.kt)("p",null,"The mint system contract exposes the following methods:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"transfer(source: URef, target: URef, amount: Motes) -> TransferResult"),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"source")," must have at least ",(0,o.kt)("inlineCode",{parentName:"li"},"Write")," access rights, ",(0,o.kt)("inlineCode",{parentName:"li"},"target")," must have at least ",(0,o.kt)("inlineCode",{parentName:"li"},"Add")," access rights"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"TransferResult")," may be a success acknowledgment or an error in the case of invalid ",(0,o.kt)("inlineCode",{parentName:"li"},"source")," or ",(0,o.kt)("inlineCode",{parentName:"li"},"target")," or insufficient balance in the ",(0,o.kt)("inlineCode",{parentName:"li"},"source")," purse"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"mint(amount: Motes) -> MintResult"),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"MintResult")," either gives the created ",(0,o.kt)("inlineCode",{parentName:"li"},"URef")," (with full access rights), which now has a balance equal to the given ",(0,o.kt)("inlineCode",{parentName:"li"},"amount"),"; or an error due to the minting of new motes not being allowed"),(0,o.kt)("li",{parentName:"ul"},"In the Casper mint, only the system account can call ",(0,o.kt)("inlineCode",{parentName:"li"},"mint"),", and it has no private key to produce valid cryptographic signatures, which means only the software itself can execute contracts in the context of the system account"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"create() -> URef"),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"a convenience function for ",(0,o.kt)("inlineCode",{parentName:"li"},"mint(0)")," which cannot fail because it is always allowed to create an empty purse"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"balance(purse: URef) -> Option"),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"purse")," must have at least ",(0,o.kt)("inlineCode",{parentName:"li"},"Read")," access rights"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"BalanceResult")," either returns the number of motes held by the ",(0,o.kt)("inlineCode",{parentName:"li"},"purse"),", or nothing if the ",(0,o.kt)("inlineCode",{parentName:"li"},"URef")," is not valid")))))}m.isMDXComponent=!0},7440:function(e,t,a){t.Z=a.p+"assets/images/casper-runtime-9bc2eb0948168ce8a2eef7f037af6ba4.png"},4473:function(e,t,a){t.Z=a.p+"assets/images/generating-urefs-af02bd8d865f5da9599a205bb682678e.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[1677],{3905:function(e,t,a){a.d(t,{Zo:function(){return p},kt:function(){return m}});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function r(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),h=c(a),u=i,m=h["".concat(l,".").concat(u)]||h[u]||d[u]||o;return a?n.createElement(m,r(r({ref:t},p),{},{components:a})):n.createElement(m,r({ref:t},p))}));function m(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=a.length,r=new Array(o);r[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[h]="string"==typeof e?e:i,r[1]=s;for(var c=2;cURefs",id:"execution-semantics-urefs",level:4},{value:"Accounts",id:"accounts-head",level:2},{value:"Creating an account",id:"accounts-creating",level:3},{value:"Permissions Model",id:"accounts-permissions",level:3},{value:"Actions and Thresholds",id:"accounts-actions-thresholds",level:4},{value:"Associated Keys and Weights",id:"accounts-associated-keys-weights",level:4},{value:"Key Management Actions",id:"accounts-key-management",level:4},{value:"Account security and recovery using key management",id:"accounts-recovery",level:4},{value:"The Account Context",id:"accounts-context",level:3},{value:"Unforgeable Reference (URef)",id:"uref-head",level:2},{value:"Permissions for URefs",id:"uref-permissions",level:3},{value:"URefs and Purses",id:"urefs-and-purses",level:3},{value:"Block Structure",id:"block-structure-head",level:2},{value:"Data Fields",id:"block-structure-data",level:3},{value:"block_hash",id:"block_hash",level:4},{value:"Header",id:"header",level:4},{value:"Body",id:"body",level:4},{value:"Tokens",id:"tokens-head",level:2},{value:"Token Generation and Distribution",id:"token-generation-and-distribution",level:3},{value:"Divisibility of Tokens",id:"tokens-divisibility",level:3},{value:"Purses and Accounts",id:"tokens-purses-and-accounts",level:3},{value:"The Casper Mint Contract",id:"mint-contract",level:3},{value:"The mint Contract Interface",id:"tokens-mint-interface",level:2}],d={toc:h},u="wrapper";function m(e){var t=e.components,s=(0,i.Z)(e,r);return(0,o.kt)(u,(0,n.Z)({},d,s,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"casper-network-design"},"Casper Network Design"),(0,o.kt)("h2",{id:"introduction"},"Introduction"),(0,o.kt)("p",null,"Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#consensus"},"consensus"),". A Casper network stores data in a structure known as ",(0,o.kt)("a",{parentName:"p",href:"/concepts/global-state"},"Global State"),". Users interact with global state through session code sent in a ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/D#deploy"},"Deploy"),". Deploys contain ",(0,o.kt)("a",{parentName:"p",href:"https://webassembly.org/"},"Wasm")," to be executed by the network, thus allowing developers to use their preferred programming language rather than a proprietary language."),(0,o.kt)("p",null,"A deploy executes in the context of the user's ",(0,o.kt)("a",{parentName:"p",href:"#accounts-head"},"Account")," but can call stored Wasm that will execute in its own context. User-related information other than an account is stored in global state as an ",(0,o.kt)("a",{parentName:"p",href:"#uref-head"},"Unforgeable Reference")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),". After a node accepts a deploy as valid, it places the deploy in a proposed ",(0,o.kt)("a",{parentName:"p",href:"#block-structure-head"},"Block")," and gossips it among nodes until the network reaches consensus. At this point, the network executes the Wasm included within the deploy."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("a",{parentName:"p",href:"#execution-semantics-head"},"Execution Semantics"))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("a",{parentName:"p",href:"#accounts-head"},"Accounts"))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("a",{parentName:"p",href:"#uref-head"},"Unforgeable Reference (URef)"))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("a",{parentName:"p",href:"#block-structure-head"},"Block Structure"))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("a",{parentName:"p",href:"#tokens-head"},"Tokens")))),(0,o.kt)("h2",{id:"execution-semantics-head"},"Execution Semantics"),(0,o.kt)("p",null,"A Casper network is a decentralized computation platform. This section describes aspects of the Casper computational model."),(0,o.kt)("h3",{id:"execution-semantics-gas"},"Measuring Computational Work"),(0,o.kt)("p",null,"Computation is done in a ",(0,o.kt)("a",{parentName:"p",href:"https://webassembly.org/"},"WebAssembly (Wasm)")," interpreter, allowing any programming language which compiles to Wasm to become a smart contract language for the Casper blockchain. Similar to Ethereum, Casper uses ",(0,o.kt)("a",{parentName:"p",href:"/concepts/economics/gas-concepts"},(0,o.kt)("inlineCode",{parentName:"a"},"Gas"))," to measure computational work in a way that is consistent from node to node in a Casper network. Each Wasm opcode is assigned a ",(0,o.kt)("inlineCode",{parentName:"p"},"Gas")," cost, and the amount of gas spent is tracked by the runtime with each opcode executed by the interpreter."),(0,o.kt)("p",null,"Costs for opcode instructions on the Casper Mainnet network can be found ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/chainspec.toml#L115"},"here"),"."),(0,o.kt)("p",null,"All executions are finite because each has a finite ",(0,o.kt)("em",{parentName:"p"},"gas limit")," that specifies the maximum amount of gas available to spend before the runtime terminates the computation. The payment executable session determines how to pay for the deploy. The gas limit is set by executing the payment code specified within the deploy."),(0,o.kt)("p",null,"Although the network measures costs in ",(0,o.kt)("inlineCode",{parentName:"p"},"Gas"),", payment for computation occurs in ",(0,o.kt)("a",{parentName:"p",href:"#tokens-divisibility"},"motes"),". Therefore, there is a conversion rate between ",(0,o.kt)("inlineCode",{parentName:"p"},"Gas")," and motes."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Please note that Casper will not refund any amount of unused gas."),(0,o.kt)("p",{parentName:"admonition"},"This decision is taken to incentivize the ",(0,o.kt)("a",{parentName:"p",href:"/runtime#runtime-economics"},"Casper Runtime Economics")," by efficiently allocating the computational resources. The ",(0,o.kt)("a",{parentName:"p",href:"/runtime#consensus-before-execution-basics-of-payment"},"consensus-before-execution model")," implements the mechanism to encourage the optimized gas consumption from users and to prevent the overuse of block space by poorly handled deploys.")),(0,o.kt)("h3",{id:"execution-semantics-runtime"},"The Casper Network Runtime"),(0,o.kt)("p",null,"A Wasm module is not natively able to create any effects outside of reading or writing from its own linear memory. Wasm modules must import functions from the host environment they are running in to enable other desired effects, such as reading or writing to global state."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"Casper Network Runtime",src:a(7440).Z,width:"1220",height:"604"})),(0,o.kt)("p",null,"All these features are accessible via functions in the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html"},"Casper External FFI"),"."),(0,o.kt)("h4",{id:"execution-semantics-urefs"},"Generating ",(0,o.kt)("inlineCode",{parentName:"h4"},"URef"),"s"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s are generated using a ",(0,o.kt)("a",{parentName:"p",href:"https://rust-random.github.io/rand/rand_chacha/struct.ChaCha20Rng.html"},"cryptographically secure random number generator")," using the ",(0,o.kt)("a",{parentName:"p",href:"https://cr.yp.to/chacha.html"},"ChaCha algorithm"),". The random number generator is seeded by taking the ",(0,o.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the deploy hash concatenated with an index representing the current phase of execution (to prevent collisions between ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s generated in different phases of the same deploy)."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"Generating URefs",src:a(4473).Z,width:"1121",height:"289"})),(0,o.kt)("h2",{id:"accounts-head"},"Accounts"),(0,o.kt)("p",null,"The Casper blockchain uses an on-chain account-based model, uniquely identified by an ",(0,o.kt)("inlineCode",{parentName:"p"},"AccountHash")," derived from a specific ",(0,o.kt)("inlineCode",{parentName:"p"},"PublicKey"),". The ",(0,o.kt)("a",{parentName:"p",href:"#global-state-trie"},"global state trie store")," requires all keys to be the same length, so the AccountHash is a 32-byte derivative used to abstract any of the supported public key variants."),(0,o.kt)("p",null,"The Casper platform supports two types of keys for creating accounts and signing transactions:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/concepts/accounts-and-keys#eddsa-keys"},"Ed25519")," keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/concepts/accounts-and-keys#ecdsa-keys"},"Secp256k1")," keys, commonly known as Ethereum keys, which are 68 bytes long")),(0,o.kt)("p",null,'By default, a transactional interaction with the blockchain takes the form of a Deploy cryptographically signed by the key-pair corresponding to the PublicKey used to create the account. All user activity on the Casper blockchain (i.e., "deploys") must originate from an account. Each account has its own context where it can locally store information (e.g., references to useful contracts, metrics, and aggregated data from other parts of the blockchain). Each account also has a "main purse" where it can hold Casper tokens (see ',(0,o.kt)("a",{parentName:"p",href:"#tokens-purses-and-accounts"},"Tokens")," for more information)."),(0,o.kt)("p",null,"This chapter describes the permission model for accounts and their local storage capabilities and briefly mentions some runtime functions for interacting with accounts."),(0,o.kt)("h3",{id:"accounts-creating"},"Creating an account"),(0,o.kt)("p",null,"Account creation automatically happens upon transferring tokens to a yet unused ",(0,o.kt)("inlineCode",{parentName:"p"},"PublicKey"),". On account creation, the balance of its main purse is equal to the number of tokens transferred during the creation process. Its action thresholds are equal to 1, and there is one associated key. The associated key is the ",(0,o.kt)("inlineCode",{parentName:"p"},"PublicKey")," used to create the account. In this way, an account is essentially a context object encapsulating the main purse, used to pay for transactions. However, an account may have an additional purse beyond the main purse."),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{src:"/image/design/account-structure.png",alt:"Image showing the account data structure",width:"200"})),(0,o.kt)("p",null,"An ",(0,o.kt)("inlineCode",{parentName:"p"},"Account")," contains the following data:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"A ",(0,o.kt)("inlineCode",{parentName:"li"},"URef"),' representing the account\'s "main purse"'),(0,o.kt)("li",{parentName:"ul"},"A collection of named keys (playing the same role as the named keys in a stored contract)"),(0,o.kt)("li",{parentName:"ul"},'A collection of "associated keys" (see ',(0,o.kt)("a",{parentName:"li",href:"#accounts-associated-keys-weights"},"below for more information"),")"),(0,o.kt)("li",{parentName:"ul"},'"Action thresholds" (see ',(0,o.kt)("a",{parentName:"li",href:"#accounts-actions-thresholds"},"below for more information"),")")),(0,o.kt)("h3",{id:"accounts-permissions"},"Permissions Model"),(0,o.kt)("h4",{id:"accounts-actions-thresholds"},"Actions and Thresholds"),(0,o.kt)("p",null,"An account can perform two types of actions: sending deploys and managing keys. A deploy is simply executing some code on the blockchain, while key management involves changing the associated keys (which will be described in more detail later). Key management cannot be performed independently, as all effects on the blockchain must come via a deploy; therefore, a key management action implies that a deploy action is also taking place."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"ActionThresholds")," contained in the ",(0,o.kt)("inlineCode",{parentName:"p"},"Account")," data structure set a ",(0,o.kt)("inlineCode",{parentName:"p"},"Weight"),", which must be met to perform that action. The next section describes these weight thresholds. Since a key management action requires a deploy action, the key management threshold should always be greater than or equal to the deploy threshold."),(0,o.kt)("h4",{id:"accounts-associated-keys-weights"},"Associated Keys and Weights"),(0,o.kt)("p",null,"Accounts on a Casper network can associate other key pairs through a multiple signature scheme for sending transactions. An account's ",(0,o.kt)("em",{parentName:"p"},"associated keys"),' are the set of public keys allowed to provide signatures on deploys for that account. Each associated key has a weight; these weights combine to meet the action thresholds provided in the previous section. Each deploy must be signed by one or more keys associated with the account that deploy is for, and the sum of the weights of those keys must be greater than or equal to the deployment threshold weight for that account. We call the keys that have signed a deploy the "authorizing keys". Similarly, if a deploy contains key management actions (detailed below), the sum of the weights of the authorizing keys must be greater than or equal to the key management action threshold of the account.'),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},'Any key may help authorize any action; there are no "special keys". All keys contribute their weight in exactly the same way.')),(0,o.kt)("h4",{id:"accounts-key-management"},"Key Management Actions"),(0,o.kt)("p",null,"A ",(0,o.kt)("em",{parentName:"p"},"key management action")," is a change to the account permissions, including:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Adding or removing an associated key"),(0,o.kt)("li",{parentName:"ul"},"Changing the weight of an associated key"),(0,o.kt)("li",{parentName:"ul"},"Changing the threshold of any action")),(0,o.kt)("p",null,"Key management actions have validity rules preventing users from locking themselves out of their accounts. For example, one can set a threshold, at most, the sum of the weights of all associated keys."),(0,o.kt)("h4",{id:"accounts-recovery"},"Account security and recovery using key management"),(0,o.kt)("p",null,"This permissions model's purpose is to keep accounts safe from lost or stolen keys while allowing the usage of modern mobile devices. For example, it may be convenient to sign deploys from a smartphone without worrying about the repercussions of losing the phone. The recommended setup is to have a low-weight key on the phone, enough for the deploy threshold but not enough for key management. If the phone is lost or stolen, a key management action using other associated keys from another device (e.g., a home computer) can be used to remove the lost associated key and add a key that resides on a replacement phone."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},'It is extremely important to ensure there will always be access to a sufficient number of keys to perform the key management action. Otherwise, future recovery will be impossible (Casper currently does not support "inactive recovery").')),(0,o.kt)("h3",{id:"accounts-context"},"The Account Context"),(0,o.kt)("p",null,"A deploy is a user request to perform some execution on the blockchain (see ",(0,o.kt)("a",{parentName:"p",href:"#execution-semantics-head"},"Execution Semantics"),' for more information). It contains "payment code" and "session code", which are references to stored on-chain contracts or Wasm to be executed. For executable Wasm, its execution and the logic therein occur within the context of the account signing the deploy. This means that the executing Wasm has access to the named keys and main purse of the account\'s context.'),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"In the case where there is a reference to stored on-chain Wasm (smart contracts), the execution of the on-chain Wasm will occur in its own separate runtime context. As a result, the stored Wasm will not have access to the named keys or main purse of the calling account.")),(0,o.kt)("h2",{id:"uref-head"},"Unforgeable Reference (URef)"),(0,o.kt)("p",null,"This key type is used for storing any value except ",(0,o.kt)("inlineCode",{parentName:"p"},"Account"),". Additionally, ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s used in Wasm carry permission information to prevent unauthorized usage of the value stored under the key. The runtime tracks this permission information. This means that if malicious Wasm attempts to produce a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),' with permissions that the Wasm does not have, the Wasm has attempted to "forge" the unforgeable reference, and the runtime will raise a forged ',(0,o.kt)("inlineCode",{parentName:"p"},"URef")," error. Permissions for a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," can be given across contract calls, allowing data stored under a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," to be shared in a controlled way. The 32-byte identifier representing the key is generated randomly by the runtime (see ",(0,o.kt)("a",{parentName:"p",href:"#execution-semantics-head"},"Execution Semantics")," for more information). The serialization for ",(0,o.kt)("inlineCode",{parentName:"p"},"Access Rights")," that define the permissions for ",(0,o.kt)("inlineCode",{parentName:"p"},"URefs")," is detailed in the ",(0,o.kt)("a",{parentName:"p",href:"/concepts/serialization-standard"},"CLValues")," section."),(0,o.kt)("h3",{id:"uref-permissions"},"Permissions for ",(0,o.kt)("inlineCode",{parentName:"h3"},"URef"),"s"),(0,o.kt)("p",null,"In the runtime, a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," carries its permissions called ",(0,o.kt)("inlineCode",{parentName:"p"},"AccessRights"),". Additionally, the runtime tracks what ",(0,o.kt)("inlineCode",{parentName:"p"},"AccessRights")," would be valid for each ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," in each context. The system assumes that a sent ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," is invalid, regardless of declared ",(0,o.kt)("inlineCode",{parentName:"p"},"AccessRights"),", and will check it against the executing context to determine validity on each usage. Only the host logic can add a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),", in the following ways:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},'It can exist in a set of "known" ',(0,o.kt)("inlineCode",{parentName:"li"},"URef"),"s"),(0,o.kt)("li",{parentName:"ul"},"It can be freshly created by the runtime via the ",(0,o.kt)("inlineCode",{parentName:"li"},"new_uref")," function"),(0,o.kt)("li",{parentName:"ul"},"For called contracts, the caller can pass it in via the arguments to ",(0,o.kt)("inlineCode",{parentName:"li"},"call_contract")),(0,o.kt)("li",{parentName:"ul"},"It can be returned to the caller from ",(0,o.kt)("inlineCode",{parentName:"li"},"call_contract")," via the ",(0,o.kt)("inlineCode",{parentName:"li"},"ret")," function")),(0,o.kt)("p",null,"Note that only valid ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s may be added to the known ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s or cross-call boundaries; this means the system cannot be tricked into accepting a forged ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," by getting it through a contract or stashing it in the known ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s."),(0,o.kt)("p",null,"The ability to pass ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s between contexts via ",(0,o.kt)("inlineCode",{parentName:"p"},"call_contract")," / ",(0,o.kt)("inlineCode",{parentName:"p"},"ret"),", allows them to share state among a fixed number of parties while keeping it private from all others."),(0,o.kt)("h3",{id:"urefs-and-purses"},(0,o.kt)("inlineCode",{parentName:"h3"},"URef"),"s and Purses"),(0,o.kt)("p",null,"Purses represent a unique type of ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," used for accounting measures within a Casper network. ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s exist as a top-level entity, meaning that individual accounts do not own \u2018URef\u2019s. As described above, accounts and contracts possess certain ",(0,o.kt)("inlineCode",{parentName:"p"},"Access Rights"),", allowing them to interact with the given ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),". While an account will possess an associated ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," representing their main purse, this ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," exists as a ",(0,o.kt)("a",{parentName:"p",href:"/concepts/serialization-standard#clvalue-unit"},(0,o.kt)("inlineCode",{parentName:"a"},"Unit"))," and corresponds to a ",(0,o.kt)("em",{parentName:"p"},"balance")," key within the Casper ",(0,o.kt)("em",{parentName:"p"},"mint"),". The individual balance key within the Casper mint is the account's purse, with transfers authorized solely through the associated ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," and the ",(0,o.kt)("inlineCode",{parentName:"p"},"Access Rights")," granted to it."),(0,o.kt)("p",null,"Through this logic, the Casper mint holds all motes on the network and transfers between balance keys at the behest of accounts and contracts as required."),(0,o.kt)("h2",{id:"block-structure-head"},"Block Structure"),(0,o.kt)("p",null,"A ",(0,o.kt)("em",{parentName:"p"},"block")," is the primary data structure by which network nodes communicate information about the state of a Casper network. We briefly describe here the format of this data structure."),(0,o.kt)("h3",{id:"block-structure-data"},"Data Fields"),(0,o.kt)("p",null,"A block consists of the following:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"A ",(0,o.kt)("inlineCode",{parentName:"li"},"block_hash")),(0,o.kt)("li",{parentName:"ul"},"A header"),(0,o.kt)("li",{parentName:"ul"},"A body")),(0,o.kt)("p",null,"Each of these fields is detailed in the subsequent sections."),(0,o.kt)("h4",{id:"block_hash"},(0,o.kt)("inlineCode",{parentName:"h4"},"block_hash")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"block_hash")," is the ",(0,o.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the block header."),(0,o.kt)("h4",{id:"header"},"Header"),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"/concepts/serialization-standard#serialization-standard-block"},"block header")," contains the following fields:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"parent_hash")),(0,o.kt)("p",{parentName:"li"},"A list of ",(0,o.kt)("inlineCode",{parentName:"p"},"block_hash"),"es giving the parents of the block.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"state_root_hash")),(0,o.kt)("p",{parentName:"li"},"The global state root hash produced by executing this block's body.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"body_hash")),(0,o.kt)("p",{parentName:"li"},"The hash of the block body.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"random_bit")),(0,o.kt)("p",{parentName:"li"},"A boolean needed for initializing a future era.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"accumulated_seed")),(0,o.kt)("p",{parentName:"li"},"A seed needed for initializing a future era.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"era_end")),(0,o.kt)("p",{parentName:"li"},"Contains equivocation and reward information to be included in the terminal finalized block. It is an optional field.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"timestamp")),(0,o.kt)("p",{parentName:"li"},"The timestamp from when the block was proposed.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"era_id")),(0,o.kt)("p",{parentName:"li"},"Era ID in which this block was created.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"height")),(0,o.kt)("p",{parentName:"li"},"The height of this block, i.e., the number of ancestors.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"protocol_version")),(0,o.kt)("p",{parentName:"li"},"The version of the Casper network when this block was proposed."))),(0,o.kt)("h4",{id:"body"},"Body"),(0,o.kt)("p",null,"The block body contains an ",(0,o.kt)("strong",{parentName:"p"},"ordered")," list of ",(0,o.kt)("inlineCode",{parentName:"p"},"DeployHashes")," which refer to deploys, and an ",(0,o.kt)("strong",{parentName:"p"},"ordered")," list of ",(0,o.kt)("inlineCode",{parentName:"p"},"DeployHashes")," for native transfers (which are specialized deploys that only transfer tokens between accounts). All deploys, including a specialization such as native transfer, can be broadly categorized as some unit of work that, when executed and committed, affect change to ",(0,o.kt)("a",{parentName:"p",href:"#global-state-intro"},"Global State"),". A valid block may contain no deploys and / or native transfers."),(0,o.kt)("p",null,"The block body also contains the public key of the validator that proposed the block."),(0,o.kt)("p",null,"Refer to the ",(0,o.kt)("a",{parentName:"p",href:"/concepts/serialization-standard"},"Serialization Standard")," for additional information on how blocks and deploy are serialized."),(0,o.kt)("h2",{id:"tokens-head"},"Tokens"),(0,o.kt)("p",null,"Casper is a decentralized Proof-of-Stake blockchain platform that uses a consensus algorithm called ",(0,o.kt)("a",{parentName:"p",href:"/concepts/design/highway"},"Highway"),". Having a unit of value is required to make this system work because users must pay for computation, and validators must have ",(0,o.kt)("a",{parentName:"p",href:"/staking"},"stake")," to bond. In the blockchain space, this unit of value is a ",(0,o.kt)("em",{parentName:"p"},"token"),"."),(0,o.kt)("p",null,"This chapter describes tokens and how one can use them on the Casper platform."),(0,o.kt)("h3",{id:"token-generation-and-distribution"},"Token Generation and Distribution"),(0,o.kt)("p",null,"A blockchain system generally needs a supply of tokens available to pay for computation and reward validators for processing transactions on the network. The initial supply at the launch of Mainnet was 10 billion CSPR. The current supply is available ",(0,o.kt)("a",{parentName:"p",href:"https://api.cspr.live/supply"},"here"),". In addition to the initial supply, the system will have a low rate of inflation, the results of which will be paid out to validators in the form of seigniorage."),(0,o.kt)("p",null,"The number of tokens used to calculate seigniorage is the initial supply of tokens at genesis."),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{src:"/image/design/token-lifecycle.png",alt:"Image showing the token lifecycle",width:"700"})),(0,o.kt)("h3",{id:"tokens-divisibility"},"Divisibility of Tokens"),(0,o.kt)("p",null,"Typically, a ",(0,o.kt)("em",{parentName:"p"},"token")," is divisible into some number of parts. We call the indivisible units which make up the CSPR token ",(0,o.kt)("em",{parentName:"p"},"motes"),". Each CSPR is divisible into 10",(0,o.kt)("sup",null,"9")," motes. To avoid rounding errors, it is essential to always represent token balances in motes. In comparison, Ether is divisible into 10",(0,o.kt)("sup",null,"18")," parts called Wei."),(0,o.kt)("p",null,"The concept of ",(0,o.kt)("inlineCode",{parentName:"p"},"CSPR")," is human-readable convenience and does not exist within the actual infrastructure of a Casper network. Instead, all transactions deal solely with ",(0,o.kt)("em",{parentName:"p"},"motes"),"."),(0,o.kt)("h3",{id:"tokens-purses-and-accounts"},"Purses and Accounts"),(0,o.kt)("p",null,"All ",(0,o.kt)("a",{parentName:"p",href:"#accounts-head"},"accounts")," on the Casper system have a purse associated with the Casper system mint, called the ",(0,o.kt)("em",{parentName:"p"},"main purse"),". However, for security reasons, the ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," of the main purse is only available to code running in the context of that account (i.e. only in payment or session code). Therefore, the mint's ",(0,o.kt)("inlineCode",{parentName:"p"},"transfer")," method that accepts ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s is not the most convenient when transferring between account main purses. For this reason, Casper supplies a ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_account.html"},"transfer_to_account")," function, which takes the public key used to derive the identity key of the account. This function uses the mint transfer function with the current account's main purse as the ",(0,o.kt)("inlineCode",{parentName:"p"},"source")," and the main purse of the account at the provided key as the ",(0,o.kt)("inlineCode",{parentName:"p"},"target"),"."),(0,o.kt)("h3",{id:"mint-contract"},"The Casper Mint Contract"),(0,o.kt)("p",null,"The Casper ",(0,o.kt)("em",{parentName:"p"},"mint")," is a system contract that manages the balance of ",(0,o.kt)("em",{parentName:"p"},"motes")," within a Casper network. These motes are used to pay for computation and bonding on the network. The mint system contract holds all motes on a Casper network but maintains an internal ledger of the balances for each Account's ",(0,o.kt)("em",{parentName:"p"},"main purse"),". Each balance is associated with a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),", which is a key to instruct the mint to perform actions on that balance (e.g., transfer motes). Informally, these balances are referred to as ",(0,o.kt)("em",{parentName:"p"},"purses")," and conceptually represent a container for motes. The ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," is how a purse is referenced externally, outside the mint."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"AccessRights")," of the URefs permissions model determines what actions can be performed when using a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," associated with a purse."),(0,o.kt)("p",null,"As all ",(0,o.kt)("inlineCode",{parentName:"p"},"URef"),"s are unforgeable, the only way to interact with a purse is for a ",(0,o.kt)("inlineCode",{parentName:"p"},"URef")," with appropriate ",(0,o.kt)("inlineCode",{parentName:"p"},"AccessRights")," to be validly given to the current context."),(0,o.kt)("p",null,"The basic global state options map onto more standard monetary operations according to the table below:"),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Global State"),(0,o.kt)("th",{parentName:"tr",align:null},"Action Monetary Action"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"Add"),(0,o.kt)("td",{parentName:"tr",align:null},"Deposit (i.e. transfer to)")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"Write"),(0,o.kt)("td",{parentName:"tr",align:null},"Withdraw (i.e. transfer from)")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"Read"),(0,o.kt)("td",{parentName:"tr",align:null},"Balance check")))),(0,o.kt)("h2",{id:"tokens-mint-interface"},"The mint Contract Interface"),(0,o.kt)("p",null,"The mint system contract exposes the following methods:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"transfer(source: URef, target: URef, amount: Motes) -> TransferResult"),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"source")," must have at least ",(0,o.kt)("inlineCode",{parentName:"li"},"Write")," access rights, ",(0,o.kt)("inlineCode",{parentName:"li"},"target")," must have at least ",(0,o.kt)("inlineCode",{parentName:"li"},"Add")," access rights"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"TransferResult")," may be a success acknowledgment or an error in the case of invalid ",(0,o.kt)("inlineCode",{parentName:"li"},"source")," or ",(0,o.kt)("inlineCode",{parentName:"li"},"target")," or insufficient balance in the ",(0,o.kt)("inlineCode",{parentName:"li"},"source")," purse"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"mint(amount: Motes) -> MintResult"),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"MintResult")," either gives the created ",(0,o.kt)("inlineCode",{parentName:"li"},"URef")," (with full access rights), which now has a balance equal to the given ",(0,o.kt)("inlineCode",{parentName:"li"},"amount"),"; or an error due to the minting of new motes not being allowed"),(0,o.kt)("li",{parentName:"ul"},"In the Casper mint, only the system account can call ",(0,o.kt)("inlineCode",{parentName:"li"},"mint"),", and it has no private key to produce valid cryptographic signatures, which means only the software itself can execute contracts in the context of the system account"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"create() -> URef"),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"a convenience function for ",(0,o.kt)("inlineCode",{parentName:"li"},"mint(0)")," which cannot fail because it is always allowed to create an empty purse"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"balance(purse: URef) -> Option"),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"purse")," must have at least ",(0,o.kt)("inlineCode",{parentName:"li"},"Read")," access rights"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"BalanceResult")," either returns the number of motes held by the ",(0,o.kt)("inlineCode",{parentName:"li"},"purse"),", or nothing if the ",(0,o.kt)("inlineCode",{parentName:"li"},"URef")," is not valid")))))}m.isMDXComponent=!0},7440:function(e,t,a){t.Z=a.p+"assets/images/casper-runtime-9bc2eb0948168ce8a2eef7f037af6ba4.png"},4473:function(e,t,a){t.Z=a.p+"assets/images/generating-urefs-af02bd8d865f5da9599a205bb682678e.png"}}]); \ No newline at end of file diff --git a/assets/js/14c517c6.ade39fcb.js b/assets/js/14c517c6.d1af03cd.js similarity index 97% rename from assets/js/14c517c6.ade39fcb.js rename to assets/js/14c517c6.d1af03cd.js index 3028fc9553..70c5825935 100644 --- a/assets/js/14c517c6.ade39fcb.js +++ b/assets/js/14c517c6.d1af03cd.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[7378],{3905:function(e,t,r){r.d(t,{Zo:function(){return u},kt:function(){return m}});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(r),y=a,m=f["".concat(p,".").concat(y)]||f[y]||i[y]||o;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[f]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(r),y=a,m=f["".concat(p,".").concat(y)]||f[y]||i[y]||o;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[f]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},c=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),u=p(r),m=a,h=u["".concat(l,".").concat(m)]||u[m]||d[m]||o;return r?n.createElement(h,s(s({ref:t},c),{},{components:r})):n.createElement(h,s({ref:t},c))}));function h(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:a,s[1]=i;for(var p=2;p=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},c=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),u=p(r),m=a,h=u["".concat(l,".").concat(m)]||u[m]||d[m]||o;return r?n.createElement(h,s(s({ref:t},c),{},{components:r})):n.createElement(h,s({ref:t},c))}));function h(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:a,s[1]=i;for(var p=2;p=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(n),m=o,h=p["".concat(l,".").concat(m)]||p[m]||u[m]||r;return n?a.createElement(h,i(i({ref:t},d),{},{components:n})):a.createElement(h,i({ref:t},d))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:o,i[1]=s;for(var c=2;c \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-hash \\\n--session-entry-point withdraw_bid \\\n--session-arg=\"public_key:public_key=''\" \\\n--session-arg=\"amount:u512=''\"\n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,r.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,r.kt)("em",{parentName:"li"},"casper-test")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-hash")," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Testnet"),": ",(0,r.kt)("inlineCode",{parentName:"li"},"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Mainnet"),": ",(0,r.kt)("inlineCode",{parentName:"li"},"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"))),(0,r.kt)("ol",{start:6},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-entry-point")," - Name of the entrypoint that will be used when calling the contract")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"withdraw_bid")," entry point expects two arguments, while the third one is optional:"),(0,r.kt)("ol",{start:7},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"public key"),": The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"amount"),": The amount being withdrawn")),(0,r.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"withdraw_bid")," entry point on the auction contract has a fixed cost of 2.5 CSPR.")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Example:")),(0,r.kt)("p",null,"This example command uses the Casper Testnet to withdraw 5 CSPR from the bid:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point withdraw_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[5 * 1000000000]'\"\n")),(0,r.kt)("p",null,"Below is the same command with the optional purse set to a different purse where the amount will be returned. ",(0,r.kt)("strong",{parentName:"p"},"Adjust all the values to your use case.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point withdraw_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[5 * 1000000000]'\"\n")),(0,r.kt)("h2",{id:"withdraw-compiled-wasm"},"Method 2: Unbonding with Compiled Wasm"),(0,r.kt)("p",null,"There is a second way to withdraw a bid, using the compiled Wasm ",(0,r.kt)("inlineCode",{parentName:"p"},"withdraw_bid.wasm"),". The process is the same as bonding but uses a different contract."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-path /casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \\\n--session-arg=\"public_key:public_key=''\" \\\n--session-arg=\"amount:u512=''\"\n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,r.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,r.kt)("em",{parentName:"li"},"casper-test")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes estimated"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to the compiled Wasm on your computer")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"withdraw_bid.wasm")," expects two arguments, while the third one is optional:"),(0,r.kt)("ol",{start:6},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"public key"),": The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"amount"),": The amount being withdrawn")),(0,r.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"This method is more expensive than calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"withdraw_bid")," entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR.")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Example:")),(0,r.kt)("p",null,"Here is an example request to unbond stake using the ",(0,r.kt)("inlineCode",{parentName:"p"},"withdraw_bid.wasm"),". The payment amount specified is 4 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec.toml"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \\\n--payment-amount 4000000000 \\\n--session-arg=\"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg=\"amount:u512='1000000000000'\"\n")),(0,r.kt)("h2",{id:"check-the-auction-contract"},"Check the Auction Contract"),(0,r.kt)("p",null,"Check the auction contract for updates to the bid amounts."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-auction-info --node-address http://\n")),(0,r.kt)("h2",{id:"unbonding-wait-period"},"Unbonding Wait Period"),(0,r.kt)("p",null,"To prevent long-range attacks, requests to unbond must go through a mandatory wait period, currently set to 7 eras lasting approximately 14-16 hours."))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[7925],{3905:function(e,t,n){n.d(t,{Zo:function(){return d},kt:function(){return h}});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(n),m=o,h=p["".concat(l,".").concat(m)]||p[m]||u[m]||r;return n?a.createElement(h,i(i({ref:t},d),{},{components:n})):a.createElement(h,i({ref:t},d))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:o,i[1]=s;for(var c=2;c \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-hash \\\n--session-entry-point withdraw_bid \\\n--session-arg=\"public_key:public_key=''\" \\\n--session-arg=\"amount:u512=''\"\n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,r.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,r.kt)("em",{parentName:"li"},"casper-test")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-hash")," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Testnet"),": ",(0,r.kt)("inlineCode",{parentName:"li"},"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Mainnet"),": ",(0,r.kt)("inlineCode",{parentName:"li"},"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"))),(0,r.kt)("ol",{start:6},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-entry-point")," - Name of the entrypoint that will be used when calling the contract")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"withdraw_bid")," entry point expects two arguments, while the third one is optional:"),(0,r.kt)("ol",{start:7},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"public key"),": The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"amount"),": The amount being withdrawn")),(0,r.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"withdraw_bid")," entry point on the auction contract has a fixed cost of 2.5 CSPR.")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Example:")),(0,r.kt)("p",null,"This example command uses the Casper Testnet to withdraw 5 CSPR from the bid:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point withdraw_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[5 * 1000000000]'\"\n")),(0,r.kt)("p",null,"Below is the same command with the optional purse set to a different purse where the amount will be returned. ",(0,r.kt)("strong",{parentName:"p"},"Adjust all the values to your use case.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point withdraw_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[5 * 1000000000]'\"\n")),(0,r.kt)("h2",{id:"withdraw-compiled-wasm"},"Method 2: Unbonding with Compiled Wasm"),(0,r.kt)("p",null,"There is a second way to withdraw a bid, using the compiled Wasm ",(0,r.kt)("inlineCode",{parentName:"p"},"withdraw_bid.wasm"),". The process is the same as bonding but uses a different contract."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-path /casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \\\n--session-arg=\"public_key:public_key=''\" \\\n--session-arg=\"amount:u512=''\"\n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,r.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,r.kt)("em",{parentName:"li"},"casper-test")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes estimated"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to the compiled Wasm on your computer")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"withdraw_bid.wasm")," expects two arguments, while the third one is optional:"),(0,r.kt)("ol",{start:6},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"public key"),": The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"amount"),": The amount being withdrawn")),(0,r.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"This method is more expensive than calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"withdraw_bid")," entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR.")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Example:")),(0,r.kt)("p",null,"Here is an example request to unbond stake using the ",(0,r.kt)("inlineCode",{parentName:"p"},"withdraw_bid.wasm"),". The payment amount specified is 4 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec.toml"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \\\n--payment-amount 4000000000 \\\n--session-arg=\"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg=\"amount:u512='1000000000000'\"\n")),(0,r.kt)("h2",{id:"check-the-auction-contract"},"Check the Auction Contract"),(0,r.kt)("p",null,"Check the auction contract for updates to the bid amounts."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-auction-info --node-address http://\n")),(0,r.kt)("h2",{id:"unbonding-wait-period"},"Unbonding Wait Period"),(0,r.kt)("p",null,"To prevent long-range attacks, requests to unbond must go through a mandatory wait period, currently set to 7 eras lasting approximately 14-16 hours."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1afb40fe.b74d0572.js b/assets/js/1afb40fe.e93f957e.js similarity index 99% rename from assets/js/1afb40fe.b74d0572.js rename to assets/js/1afb40fe.e93f957e.js index bad23caac7..4631668f70 100644 --- a/assets/js/1afb40fe.b74d0572.js +++ b/assets/js/1afb40fe.e93f957e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[870],{3905:function(e,t,a){a.d(t,{Zo:function(){return s},kt:function(){return u}});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function d(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var i=n.createContext({}),o=function(e){var t=n.useContext(i),a=t;return e&&(a="function"==typeof e?e(t):d(d({},t),e)),a},s=function(e){var t=o(e.components);return n.createElement(i.Provider,{value:t},e.children)},p="mdxType",b={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,l=e.originalType,i=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),p=o(a),f=r,u=p["".concat(i,".").concat(f)]||p[f]||b[f]||l;return a?n.createElement(u,d(d({ref:t},s),{},{components:a})):n.createElement(u,d({ref:t},s))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=a.length,d=new Array(l);d[0]=f;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c[p]="string"==typeof e?e:r,d[1]=c;for(var o=2;ochain_get_block_result",id:"chain_get_block_result",level:3},{value:"chain_get_block_transfers",id:"chain-get-block-transfers",level:2},{value:"chain_get_block_transfers_result",id:"chain_get_block_transfers_result",level:3},{value:"chain_get_era_summary",id:"chain-get-era-summary",level:2},{value:"chain_get_era_summary_result",id:"chain_get_era_summary_result",level:3},{value:"chain_get_state_root_hash",id:"chain-get-state-root-hash",level:2},{value:"chain_get_state_root_hash_result",id:"chain_get_state_root_hash_result",level:3},{value:"info_get_chainspec",id:"info-get-chainspec",level:2},{value:"info_get_chainspec_result",id:"info_get_chainspec_result",level:3},{value:"info_get_deploy",id:"info-get-deploy",level:2},{value:"info_get_deploy_result",id:"info_get_deploy_result",level:3},{value:"query_balance",id:"query-balance",level:2},{value:"query_balance_result",id:"query_balance_result",level:3},{value:"query_global_state",id:"query-global-state",level:2},{value:"query_global_state_result",id:"query_global_state_result",level:3},{value:"state_get_account_info",id:"state-get-account-info",level:2},{value:"state_get_account_info_result",id:"state_get_account_info_result",level:3},{value:"state_get_dictionary_item",id:"state-get-dictionary-item",level:2},{value:"info_get_peers",id:"info-get-peers",level:2},{value:"info_get_peers_result",id:"info_get_peers_result",level:3},{value:"info_get_status",id:"info-get-status",level:2},{value:"info_get_status_result",id:"info_get_status_result",level:3}],b={toc:p},f="wrapper";function u(e){var t=e.components,a=(0,r.Z)(e,d);return(0,l.kt)(f,(0,n.Z)({},b,a,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"informational"},"Informational JSON-RPC Methods"),(0,l.kt)("p",null,"The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network."),(0,l.kt)("hr",null),(0,l.kt)("h2",{id:"chain-get-block"},"chain_get_block"),(0,l.kt)("p",null,"This method returns the JSON representation of a ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#block-structure-head"},"Block")," from the network."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block hash or the Block height.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_block request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_block",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"chain_get_block_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"chain_get_block_result")),(0,l.kt)("p",null,"The result from ",(0,l.kt)("inlineCode",{parentName:"p"},"chain_get_block")," depends on block availability from a given node. If ",(0,l.kt)("inlineCode",{parentName:"p"},"chain_get_block")," returns an error message that the node does not have information on the given block, you may attempt to get the information from a different node."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#jsonblock"},"block")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block, if found. (Not required)")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_block result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block": {\n "body": {\n "deploy_hashes": [],\n "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "transfer_hashes": [\n "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"\n ]\n },\n "hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "header": {\n "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",\n "body_hash": "cd502c5393a3c8b66d6979ad7857507c9baf5a8ba16ba99c28378d3a970fff42",\n "era_end": {\n "era_report": {\n "equivocators": [\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ],\n "inactive_validators": [\n "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"\n ],\n "rewards": [\n {\n "amount": 1000,\n "validator": "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c"\n }\n ]\n },\n "next_era_validator_weights": [\n {\n "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",\n "weight": "456"\n },\n {\n "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",\n "weight": "789"\n },\n {\n "validator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "weight": "123"\n }\n ]\n },\n "era_id": 1,\n "height": 10,\n "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "protocol_version": "1.0.0",\n "random_bit": true,\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "timestamp": "2020-11-17T00:39:24.072Z"\n },\n "proofs": [\n {\n "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "016291a7b2689e2edcc6e79030be50edd02f9bd7d809921ae2654012f808c7b9a0f125bc32d6aa610cbd012395a9832ccfaa9262023339f1db71ca073a13bb9707"\n }\n ]\n }\n }\n}\n\n'))),(0,l.kt)("h2",{id:"chain-get-block-transfers"},"chain_get_block_transfers"),(0,l.kt)("p",null,"This method returns all ",(0,l.kt)("strong",{parentName:"p"},"successful")," native transfers within a given ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#block-structure-head"},"Block")," from a network."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block hash.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_block_transfers request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_block_transfers",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"chain_get_block_transfers_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"chain_get_block_transfers_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockhash"},"block_hash")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block hash, if found.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#transfer"},"transfers")),(0,l.kt)("td",{parentName:"tr",align:null},"Array"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block's successful transfers, if found.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_block_transfers result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "transfers": [\n {\n "amount": "0",\n "deploy_hash": "0000000000000000000000000000000000000000000000000000000000000000",\n "from": "account-hash-0000000000000000000000000000000000000000000000000000000000000000",\n "gas": "0",\n "id": null,\n "source": "uref-0000000000000000000000000000000000000000000000000000000000000000-000",\n "target": "uref-0000000000000000000000000000000000000000000000000000000000000000-000",\n "to": null\n }\n ]\n }\n}\n\n'))),(0,l.kt)("h2",{id:"chain-get-era-summary"},"chain_get_era_summary"),(0,l.kt)("p",null,"This method returns the era summary at a given ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#block-structure-head"},"Block"),". If you do not specify a ",(0,l.kt)("inlineCode",{parentName:"p"},"block_identifier"),", you will receive the era summary at the highest state root hash."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block hash. (Optional)")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_era_summary request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc":"2.0",\n "method":"chain_get_era_summary",\n "params": [\n {\n "Hash":"9bfa58709058935882a095ca6adf844b72a2ddf0f49b8575ef1ceda987452fb8"\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"chain_get_era_summary_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"chain_get_era_summary_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#erasummary"},"era_summary")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The era summary (if found).")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_era_summary result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "jsonrpc": "2.0",\n "id": 1,\n "result": {\n "api_version": "1.0.0",\n "era_summary": {\n "block_hash": "9bfa58709058935882a095ca6adf844b72a2ddf0f49b8575ef1ceda987452fb8",\n "era_id": 1,\n "stored_value": {\n "EraInfo": {\n "seigniorage_allocations": [\n {\n "Delegator": {\n "delegator_public_key": "01c08939bf1ecd1139448d435989a761c975466d30b96c2dd74e9d23c7b12bc9ff",\n "validator_public_key": "01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b",\n "amount": "53472520551166781393617756"\n }\n },\n {\n "Validator": {\n "validator_public_key": "01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b",\n "amount": "54552773491594393138943367"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "01264689a5b4c57dac1088cd0aae8074de105f2269f6041e2c120e80df7a95e6b5",\n "validator_public_key": "013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c18726",\n "amount": "51312014670568117976319374"\n }\n },\n {\n "Validator": {\n "validator_public_key": "013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c18726",\n "amount": "56713279372733183026458256"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "016f571eaf1d3a442e684ecdb31d00a51448dcbaa06d00b340983311f0ba3e76db",\n "validator_public_key": "0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f12",\n "amount": "51852141140784624481333262"\n }\n },\n {\n "Validator": {\n "validator_public_key": "0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f12",\n "amount": "56173152902516676521444368"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "0161e7ed5c592f16b507b9dd196662b530f9bde6c5b2cfd957fe8d0700ecfbe20b",\n "validator_public_key": "01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b",\n "amount": "52392267611001130986347150"\n }\n },\n {\n "Validator": {\n "validator_public_key": "01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b",\n "amount": "55633026432300170016430480"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "01b1339a1d114036d84d7b65c804669166d38456114657abbb0e53e67bf1667c60",\n "validator_public_key": "01dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f",\n "amount": "52932394080952975520954950"\n }\n },\n {\n "Validator": {\n "validator_public_key": "01dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f",\n "amount": "55092899961808199011606173"\n }\n }\n ]\n }\n },\n "state_root_hash": "918abd1973171867e03c1e6e56fd7dd9da35c92461784f9a15c0df23e437d850",\n "merkle_proof": "010000000e0000000000000000000000000000000000000000000000000000000000000000070a0000000101c08939bf1ecd1139448d435989a761c975466d30b96c2dd74e9d23c7b12bc9ff01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b0b5c4316483512c2253f3b2c0001039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b0b87d59268bf17d8c6ff1f2d0101264689a5b4c57dac1088cd0aae8074de105f2269f6041e2c120e80df7a95e6b5013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c187260b8e45261378f096e3bd712a00013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c187260b90eee69bba24050981e92e01016f571eaf1d3a442e684ecdb31d00a51448dcbaa06d00b340983311f0ba3e76db0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f120b0ef09fedb1f521341ee42a000186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f120b10446dc1801f7ab820772e010161e7ed5c592f16b507b9dd196662b530f9bde6c5b2cfd957fe8d0700ecfbe20b01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b0b8e9a19c8ebfaac847e562b0001d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b0b9099f3e6461aef67c0042e0101b1339a1d114036d84d7b65c804669166d38456114657abbb0e53e67bf1667c6001dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f0b46fad737700f37d5dec82b0001dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f0b9d1ed178841a631760922d01000000000e060000000001fb7043fe388fef916937aa899a0dda9b042168149e600fb068ecb16839d545d60101a0676758b903440b28c8f4a1d46404e9879fcfc0b90dad20962536de493aecc302013584bc9d5c00ac639fe14410b4cfa480b12eddd8f3dce08d7b76ae47977c1c680601664224aca1272e2a5632da4a56399dee6c585318ebbb7bb4040039792d3ad33c07013b48237cd26eb35ec3c864e1ae250ca656d00893de1dfc4c951e0d779adeda1d0a002c722cac61792676eb19d773fd3c41e37a63f54f78bdf7712ca96a5c5e5c4986"\n }\n }\n}\n\n'))),(0,l.kt)("h2",{id:"chain-get-state-root-hash"},"chain_get_state_root_hash"),(0,l.kt)("p",null,"This method returns a state root hash at a given ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#block-structure-head"},"Block"),". If you do not specify a ",(0,l.kt)("inlineCode",{parentName:"p"},"block_identifier"),", you will receive the highest state root hash."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block hash. (Optional)")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_state_root_hash request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_state_root_hash",\n "params": [\n {\n "Height": 10\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"chain_get_state_root_hash_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"chain_get_state_root_hash_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#digest"},"state_root_hash")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"Hex-encoded hash of the state root.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_state_root_hash result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808"\n }\n}\n\n'))),(0,l.kt)("h2",{id:"info-get-chainspec"},"info_get_chainspec"),(0,l.kt)("p",null,"This method returns raw bytes for chainspec files."),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_chainspec request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "jsonrpc": "2.0",\n "method": "info_get_chainspec",\n "id": 5510244237763930243\n}\n\n'))),(0,l.kt)("h3",{id:"info_get_chainspec_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"info_get_chainspec_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#ChainspecRawBytes"},"chainspec_bytes")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_chainspec result"),(0,l.kt)("p",null,"Please note that adding a ",(0,l.kt)("inlineCode",{parentName:"p"},"--vv")," flag will return the full chainspec bytes."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.0",\n "chainspec_bytes": {\n "chainspec_bytes": "[22040 hex chars]",\n "maybe_genesis_accounts_bytes": null,\n "maybe_global_state_bytes": null\n }\n },\n "id": 5510244237763930243\n}\n\n'))),(0,l.kt)("h2",{id:"info-get-deploy"},"info_get_deploy"),(0,l.kt)("p",null,"This method retrieves a ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#execution-semantics-deploys"},"Deploy")," from a network. It requires a ",(0,l.kt)("inlineCode",{parentName:"p"},"deploy_hash")," to query the Deploy."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#deployhash"},"deploy_hash")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The Deploy hash.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#finalizedapprovals"},"finalized_approvals")),(0,l.kt)("td",{parentName:"tr",align:null},"Boolean"),(0,l.kt)("td",{parentName:"tr",align:null},"Determines whether to return the Deploy with the finalized approvals substituted. (Optional)")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_deploy request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_deploy",\n "params": [\n "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",\n true\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"info_get_deploy_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"info_get_deploy_result")),(0,l.kt)("p",null,"The response contains the Deploy and the results of executing the Deploy."),(0,l.kt)("p",null,"If the ",(0,l.kt)("inlineCode",{parentName:"p"},"execution_results")," field is empty, it means that the network processed the ",(0,l.kt)("inlineCode",{parentName:"p"},"Deploy"),", but has yet to execute it. If the network executed the ",(0,l.kt)("inlineCode",{parentName:"p"},"Deploy"),", it will return the results of the execution. The execution results contain the Block hash which contains the Deploy."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#deploy"},"deploy")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Deploy.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#jsonexecutionresult"},"execution_results")),(0,l.kt)("td",{parentName:"tr",align:null},"Array"),(0,l.kt)("td",{parentName:"tr",align:null},"An array of execution results with Block hashes.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_deploy result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy": {\n "approvals": [\n {\n "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007",\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n ],\n "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",\n "header": {\n "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",\n "chain_name": "casper-example",\n "dependencies": [\n "0101010101010101010101010101010101010101010101010101010101010101"\n ],\n "gas_price": 1,\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h"\n },\n "payment": {\n "StoredContractByName": {\n "args": [\n [\n "amount",\n {\n "bytes": "e8030000",\n "cl_type": "I32",\n "parsed": 1000\n }\n ]\n ],\n "entry_point": "example-entry-point",\n "name": "casper-example"\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "bytes": "e8030000",\n "cl_type": "I32",\n "parsed": 1000\n }\n ]\n ]\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "result": {\n "Success": {\n "cost": "123456",\n "effect": {\n "operations": [\n {\n "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",\n "kind": "Write"\n },\n {\n "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n "kind": "Read"\n }\n ],\n "transforms": [\n {\n "key": "uref-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb-007",\n "transform": {\n "AddUInt64": 8\n }\n },\n {\n "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n "transform": "Identity"\n }\n ]\n },\n "transfers": [\n "transfer-5959595959595959595959595959595959595959595959595959595959595959",\n "transfer-8282828282828282828282828282828282828282828282828282828282828282"\n ]\n }\n }\n }\n ]\n }\n}\n\n'))),(0,l.kt)("h2",{id:"query-balance"},"query_balance"),(0,l.kt)("p",null,"This method allows you to query for the balance of a purse using a ",(0,l.kt)("inlineCode",{parentName:"p"},"PurseIdentifier")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"StateIdentifier"),"."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#purseidentifier"},"purse_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The identifier to obtain the purse corresponding to the balance query.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#globalstateidentifier"},"state_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The state identifier used for the query; if none is passed the tip of the chain will be used.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example query_balance request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": [\n {\n "name": "state_identifier",\n "value": {\n "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n },\n {\n "name": "purse_identifier",\n "value": {\n "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"\n }\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"query_balance_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"query_balance_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#u512"},"balance")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The balance represented in motes.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example query_balance result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "jsonrpc": "2.0",\n "id": -6143675785141640608,\n "result": {\n "api_version": "1.0.0",\n "balance": "1000000000000000000000000000000000"\n }\n}\n\n'))),(0,l.kt)("h2",{id:"query-global-state"},"query_global_state"),(0,l.kt)("p",null,"This method allows for you to query for a value stored under certain keys in global state. You may query using either a ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#block_hash"},"Block hash")," or state root hash."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"Note: Querying a purse's balance requires the use of ",(0,l.kt)("inlineCode",{parentName:"li"},"query_balance"),", rather than any iteration of ",(0,l.kt)("inlineCode",{parentName:"li"},"query_global_state"),".")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#globalstateidentifier"},"state_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The identifier used for the query.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"key"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"casper_types::Key")," as a formatted string.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"path"),(0,l.kt)("td",{parentName:"tr",align:null},"Array"),(0,l.kt)("td",{parentName:"tr",align:null},"The path components starting from the key as base.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example query_global_state request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": [\n "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n [],\n {\n "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"query_global_state_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"query_global_state_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#jsonblockheader"},"block_header")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block header if a Block hash was provided. (Not required)")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#storedvalue"},"stored_value")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The stored value.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#merkle-proof"},"merkle_proof")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The merkle proof.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example query_global_state result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": {\n "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",\n "body_hash": "cd502c5393a3c8b66d6979ad7857507c9baf5a8ba16ba99c28378d3a970fff42",\n "era_end": {\n "era_report": {\n "equivocators": [\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ],\n "inactive_validators": [\n "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"\n ],\n "rewards": [\n {\n "amount": 1000,\n "validator": "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c"\n }\n ]\n },\n "next_era_validator_weights": [\n {\n "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",\n "weight": "456"\n },\n {\n "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",\n "weight": "789"\n },\n {\n "validator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "weight": "123"\n }\n ]\n },\n "era_id": 1,\n "height": 10,\n "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "protocol_version": "1.0.0",\n "random_bit": true,\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "timestamp": "2020-11-17T00:39:24.072Z"\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "named_keys": []\n }\n }\n }\n}\n\n'))),(0,l.kt)("h2",{id:"state-get-account-info"},"state_get_account_info"),(0,l.kt)("p",null,"This method returns a JSON representation of an ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-head"},"Account")," from the network. The ",(0,l.kt)("inlineCode",{parentName:"p"},"block_identifier")," must refer to a Block after the Account's creation, or the method will return an empty response."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#publickey"},"public_key")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The public key of the Account.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block identifier.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example state_get_account_info request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_account_info",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n },\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"state_get_account_info_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"state_get_account_info_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#account"},"account")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"A JSON representation of the Account structure.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#merkleproof"},"merkle_proof")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The merkle proof.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example state_get_account_info result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "account": {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "named_keys": []\n },\n "api_version": "1.4.13",\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n}\n\n'))),(0,l.kt)("h2",{id:"state-get-dictionary-item"},"state_get_dictionary_item"),(0,l.kt)("p",null,"This method returns an item from a Dictionary. Every dictionary has a seed URef, findable by using a ",(0,l.kt)("inlineCode",{parentName:"p"},"dictionary_identifier"),". The address of a stored value is the blake2b hash of the seed URef and the byte representation of the dictionary key."),(0,l.kt)("p",null,"You may query a stored value directly using the dictionary address."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#digest"},"state_root_hash")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"Hash of the state root.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#dictionaryidentifier"},"dictionary_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Dictionary query identifier.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example state_get_dictionary_item request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_dictionary_item",\n "params": [\n {\n "URef": {\n "dictionary_item_key": "a_unique_entry_identifier",\n "seed_uref": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"\n }\n },\n "0808080808080808080808080808080808080808080808080808080808080808"\n ]\n}\n\n'))),"### `state_get_dictionary_item_result`",(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"dictionary_key"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The key under which the value is stored.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#storedvalue"},"stored_value")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The stored value.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#merkle-proof"},"merkle_proof")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The merkle proof.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example state_get_dictionary_item result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "dictionary_key": "dictionary-67518854aa916c97d4e53df8570c8217ccc259da2721b692102d76acd0ee8d1f",\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",\n "stored_value": {\n "CLValue": {\n "bytes": "0100000000000000",\n "cl_type": "U64",\n "parsed": 1\n }\n }\n }\n}\n\n'))),(0,l.kt)("hr",null),(0,l.kt)("h1",{id:"node-informational"},"Node Informational JSON-RPC Methods"),(0,l.kt)("p",null,"The following methods return information from a node on a Casper network. The responses return information specific to the queried node, and as such, will vary."),(0,l.kt)("hr",null),(0,l.kt)("h2",{id:"info-get-peers"},"info_get_peers"),(0,l.kt)("p",null,"This method returns a list of peers connected to the node."),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_peers request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_peers",\n "params": []\n}\n\n'))),(0,l.kt)("h3",{id:"info_get_peers_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"info_get_peers_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#peersmap"},"peers")),(0,l.kt)("td",{parentName:"tr",align:null},"Array"),(0,l.kt)("td",{parentName:"tr",align:null},"The node ID and network address of each connected peer.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_peers result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "peers": [\n {\n "address": "127.0.0.1:54321",\n "node_id": "tls:0101..0101"\n }\n ]\n }\n}\n\n'))),(0,l.kt)("h2",{id:"info-get-status"},"info_get_status"),(0,l.kt)("p",null,"This method returns the current status of a node."),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_status request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_status",\n "params": []\n}\n\n'))),(0,l.kt)("h3",{id:"info_get_status_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"info_get_status_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#AvailableBlockRange"},"available_block_range")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The available block range in storage.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#BlockSynchronizerStatus"},"block_sync")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The status of the block synchronizer builders.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"build_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The compiled node version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"chainspec_name"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The chainspec name, used to identify the currently connected network.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#minimalblockinfo"},"last_added_block_info")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The minimal info of the last Block from the linear chain.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#timestamp"},"last_progress")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"Timestamp of the last recorded progress in the reactor.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#nextupgrade"},"next_upgrade")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"Information about the next scheduled upgrade.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#publickey"},"our_public_signing_key")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"Our public signing key.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#peersmap"},"peers")),(0,l.kt)("td",{parentName:"tr",align:null},"Array"),(0,l.kt)("td",{parentName:"tr",align:null},"The node ID and network address of each connected peer.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#reactorstate"},"reactor_state")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The current state of the node reactor.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#timediff"},"round_length")),(0,l.kt)("td",{parentName:"tr",align:null},"Integer"),(0,l.kt)("td",{parentName:"tr",align:null},"The next round length if this node is a validator. A round length is the amount of time it takes to reach consensus on proposing a Block.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#digest"},"starting_state_root_hash")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The state root hash used at the start of the current session.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#timediff"},"uptime")),(0,l.kt)("td",{parentName:"tr",align:null},"Integer"),(0,l.kt)("td",{parentName:"tr",align:null},"Time that passed since the node has started.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_status result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_status_result",\n "value": {\n "peers": [\n {\n "node_id": "tls:0101..0101",\n "address": "127.0.0.1:54321"\n }\n ],\n "api_version": "1.4.8",\n "build_version": "1.0.0-xxxxxxxxx@DEBUG",\n "chainspec_name": "casper-example",\n "starting_state_root_hash": null,\n "last_added_block_info": {\n "hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "era_id": 1,\n "height": 10,\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "creator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n "our_public_signing_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "round_length": "1m 5s 536ms",\n "next_upgrade": {\n "activation_point": 42,\n "protocol_version": "2.0.1"\n },\n "uptime": "13s",\n "reactor_state": "Initialize",\n "last_progress": "1970-01-01T00:00:00.000Z",\n "available_block_range": {\n "low": 0,\n "high": 0\n },\n "block_sync": {\n "historical": {\n "block_hash": "16ddf28e2b3d2e17f4cef36f8b58827eca917af225d139b0c77df3b4a67dc55e",\n "block_height": 40,\n "acquisition_state": "have strict finality(40) for: block hash 16dd..c55e"\n },\n "forward": {\n "block_hash": "59907b1e32a9158169c4d89d9ce5ac9164fc31240bfcfb0969227ece06d74983",\n "block_height": 6701,\n "acquisition_state": "have block body(6701) for: block hash 5990..4983"\n }\n }\n }\n}\n\n'))))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[870],{3905:function(e,t,a){a.d(t,{Zo:function(){return s},kt:function(){return u}});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function d(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var i=n.createContext({}),o=function(e){var t=n.useContext(i),a=t;return e&&(a="function"==typeof e?e(t):d(d({},t),e)),a},s=function(e){var t=o(e.components);return n.createElement(i.Provider,{value:t},e.children)},p="mdxType",b={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,l=e.originalType,i=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),p=o(a),f=r,u=p["".concat(i,".").concat(f)]||p[f]||b[f]||l;return a?n.createElement(u,d(d({ref:t},s),{},{components:a})):n.createElement(u,d({ref:t},s))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=a.length,d=new Array(l);d[0]=f;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c[p]="string"==typeof e?e:r,d[1]=c;for(var o=2;ochain_get_block_result",id:"chain_get_block_result",level:3},{value:"chain_get_block_transfers",id:"chain-get-block-transfers",level:2},{value:"chain_get_block_transfers_result",id:"chain_get_block_transfers_result",level:3},{value:"chain_get_era_summary",id:"chain-get-era-summary",level:2},{value:"chain_get_era_summary_result",id:"chain_get_era_summary_result",level:3},{value:"chain_get_state_root_hash",id:"chain-get-state-root-hash",level:2},{value:"chain_get_state_root_hash_result",id:"chain_get_state_root_hash_result",level:3},{value:"info_get_chainspec",id:"info-get-chainspec",level:2},{value:"info_get_chainspec_result",id:"info_get_chainspec_result",level:3},{value:"info_get_deploy",id:"info-get-deploy",level:2},{value:"info_get_deploy_result",id:"info_get_deploy_result",level:3},{value:"query_balance",id:"query-balance",level:2},{value:"query_balance_result",id:"query_balance_result",level:3},{value:"query_global_state",id:"query-global-state",level:2},{value:"query_global_state_result",id:"query_global_state_result",level:3},{value:"state_get_account_info",id:"state-get-account-info",level:2},{value:"state_get_account_info_result",id:"state_get_account_info_result",level:3},{value:"state_get_dictionary_item",id:"state-get-dictionary-item",level:2},{value:"info_get_peers",id:"info-get-peers",level:2},{value:"info_get_peers_result",id:"info_get_peers_result",level:3},{value:"info_get_status",id:"info-get-status",level:2},{value:"info_get_status_result",id:"info_get_status_result",level:3}],b={toc:p},f="wrapper";function u(e){var t=e.components,a=(0,r.Z)(e,d);return(0,l.kt)(f,(0,n.Z)({},b,a,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"informational"},"Informational JSON-RPC Methods"),(0,l.kt)("p",null,"The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network."),(0,l.kt)("hr",null),(0,l.kt)("h2",{id:"chain-get-block"},"chain_get_block"),(0,l.kt)("p",null,"This method returns the JSON representation of a ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#block-structure-head"},"Block")," from the network."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block hash or the Block height.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_block request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_block",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"chain_get_block_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"chain_get_block_result")),(0,l.kt)("p",null,"The result from ",(0,l.kt)("inlineCode",{parentName:"p"},"chain_get_block")," depends on block availability from a given node. If ",(0,l.kt)("inlineCode",{parentName:"p"},"chain_get_block")," returns an error message that the node does not have information on the given block, you may attempt to get the information from a different node."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#jsonblock"},"block")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block, if found. (Not required)")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_block result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block": {\n "body": {\n "deploy_hashes": [],\n "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "transfer_hashes": [\n "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"\n ]\n },\n "hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "header": {\n "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",\n "body_hash": "cd502c5393a3c8b66d6979ad7857507c9baf5a8ba16ba99c28378d3a970fff42",\n "era_end": {\n "era_report": {\n "equivocators": [\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ],\n "inactive_validators": [\n "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"\n ],\n "rewards": [\n {\n "amount": 1000,\n "validator": "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c"\n }\n ]\n },\n "next_era_validator_weights": [\n {\n "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",\n "weight": "456"\n },\n {\n "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",\n "weight": "789"\n },\n {\n "validator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "weight": "123"\n }\n ]\n },\n "era_id": 1,\n "height": 10,\n "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "protocol_version": "1.0.0",\n "random_bit": true,\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "timestamp": "2020-11-17T00:39:24.072Z"\n },\n "proofs": [\n {\n "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "016291a7b2689e2edcc6e79030be50edd02f9bd7d809921ae2654012f808c7b9a0f125bc32d6aa610cbd012395a9832ccfaa9262023339f1db71ca073a13bb9707"\n }\n ]\n }\n }\n}\n\n'))),(0,l.kt)("h2",{id:"chain-get-block-transfers"},"chain_get_block_transfers"),(0,l.kt)("p",null,"This method returns all ",(0,l.kt)("strong",{parentName:"p"},"successful")," native transfers within a given ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#block-structure-head"},"Block")," from a network."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block hash.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_block_transfers request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_block_transfers",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"chain_get_block_transfers_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"chain_get_block_transfers_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockhash"},"block_hash")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block hash, if found.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#transfer"},"transfers")),(0,l.kt)("td",{parentName:"tr",align:null},"Array"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block's successful transfers, if found.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_block_transfers result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "transfers": [\n {\n "amount": "0",\n "deploy_hash": "0000000000000000000000000000000000000000000000000000000000000000",\n "from": "account-hash-0000000000000000000000000000000000000000000000000000000000000000",\n "gas": "0",\n "id": null,\n "source": "uref-0000000000000000000000000000000000000000000000000000000000000000-000",\n "target": "uref-0000000000000000000000000000000000000000000000000000000000000000-000",\n "to": null\n }\n ]\n }\n}\n\n'))),(0,l.kt)("h2",{id:"chain-get-era-summary"},"chain_get_era_summary"),(0,l.kt)("p",null,"This method returns the era summary at a given ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#block-structure-head"},"Block"),". If you do not specify a ",(0,l.kt)("inlineCode",{parentName:"p"},"block_identifier"),", you will receive the era summary at the highest state root hash."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block hash. (Optional)")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_era_summary request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc":"2.0",\n "method":"chain_get_era_summary",\n "params": [\n {\n "Hash":"9bfa58709058935882a095ca6adf844b72a2ddf0f49b8575ef1ceda987452fb8"\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"chain_get_era_summary_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"chain_get_era_summary_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#erasummary"},"era_summary")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The era summary (if found).")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_era_summary result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "jsonrpc": "2.0",\n "id": 1,\n "result": {\n "api_version": "1.0.0",\n "era_summary": {\n "block_hash": "9bfa58709058935882a095ca6adf844b72a2ddf0f49b8575ef1ceda987452fb8",\n "era_id": 1,\n "stored_value": {\n "EraInfo": {\n "seigniorage_allocations": [\n {\n "Delegator": {\n "delegator_public_key": "01c08939bf1ecd1139448d435989a761c975466d30b96c2dd74e9d23c7b12bc9ff",\n "validator_public_key": "01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b",\n "amount": "53472520551166781393617756"\n }\n },\n {\n "Validator": {\n "validator_public_key": "01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b",\n "amount": "54552773491594393138943367"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "01264689a5b4c57dac1088cd0aae8074de105f2269f6041e2c120e80df7a95e6b5",\n "validator_public_key": "013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c18726",\n "amount": "51312014670568117976319374"\n }\n },\n {\n "Validator": {\n "validator_public_key": "013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c18726",\n "amount": "56713279372733183026458256"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "016f571eaf1d3a442e684ecdb31d00a51448dcbaa06d00b340983311f0ba3e76db",\n "validator_public_key": "0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f12",\n "amount": "51852141140784624481333262"\n }\n },\n {\n "Validator": {\n "validator_public_key": "0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f12",\n "amount": "56173152902516676521444368"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "0161e7ed5c592f16b507b9dd196662b530f9bde6c5b2cfd957fe8d0700ecfbe20b",\n "validator_public_key": "01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b",\n "amount": "52392267611001130986347150"\n }\n },\n {\n "Validator": {\n "validator_public_key": "01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b",\n "amount": "55633026432300170016430480"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "01b1339a1d114036d84d7b65c804669166d38456114657abbb0e53e67bf1667c60",\n "validator_public_key": "01dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f",\n "amount": "52932394080952975520954950"\n }\n },\n {\n "Validator": {\n "validator_public_key": "01dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f",\n "amount": "55092899961808199011606173"\n }\n }\n ]\n }\n },\n "state_root_hash": "918abd1973171867e03c1e6e56fd7dd9da35c92461784f9a15c0df23e437d850",\n "merkle_proof": "010000000e0000000000000000000000000000000000000000000000000000000000000000070a0000000101c08939bf1ecd1139448d435989a761c975466d30b96c2dd74e9d23c7b12bc9ff01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b0b5c4316483512c2253f3b2c0001039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b0b87d59268bf17d8c6ff1f2d0101264689a5b4c57dac1088cd0aae8074de105f2269f6041e2c120e80df7a95e6b5013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c187260b8e45261378f096e3bd712a00013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c187260b90eee69bba24050981e92e01016f571eaf1d3a442e684ecdb31d00a51448dcbaa06d00b340983311f0ba3e76db0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f120b0ef09fedb1f521341ee42a000186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f120b10446dc1801f7ab820772e010161e7ed5c592f16b507b9dd196662b530f9bde6c5b2cfd957fe8d0700ecfbe20b01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b0b8e9a19c8ebfaac847e562b0001d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b0b9099f3e6461aef67c0042e0101b1339a1d114036d84d7b65c804669166d38456114657abbb0e53e67bf1667c6001dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f0b46fad737700f37d5dec82b0001dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f0b9d1ed178841a631760922d01000000000e060000000001fb7043fe388fef916937aa899a0dda9b042168149e600fb068ecb16839d545d60101a0676758b903440b28c8f4a1d46404e9879fcfc0b90dad20962536de493aecc302013584bc9d5c00ac639fe14410b4cfa480b12eddd8f3dce08d7b76ae47977c1c680601664224aca1272e2a5632da4a56399dee6c585318ebbb7bb4040039792d3ad33c07013b48237cd26eb35ec3c864e1ae250ca656d00893de1dfc4c951e0d779adeda1d0a002c722cac61792676eb19d773fd3c41e37a63f54f78bdf7712ca96a5c5e5c4986"\n }\n }\n}\n\n'))),(0,l.kt)("h2",{id:"chain-get-state-root-hash"},"chain_get_state_root_hash"),(0,l.kt)("p",null,"This method returns a state root hash at a given ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#block-structure-head"},"Block"),". If you do not specify a ",(0,l.kt)("inlineCode",{parentName:"p"},"block_identifier"),", you will receive the highest state root hash."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block hash. (Optional)")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_state_root_hash request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_state_root_hash",\n "params": [\n {\n "Height": 10\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"chain_get_state_root_hash_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"chain_get_state_root_hash_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#digest"},"state_root_hash")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"Hex-encoded hash of the state root.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_state_root_hash result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808"\n }\n}\n\n'))),(0,l.kt)("h2",{id:"info-get-chainspec"},"info_get_chainspec"),(0,l.kt)("p",null,"This method returns raw bytes for chainspec files."),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_chainspec request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "jsonrpc": "2.0",\n "method": "info_get_chainspec",\n "id": 5510244237763930243\n}\n\n'))),(0,l.kt)("h3",{id:"info_get_chainspec_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"info_get_chainspec_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#ChainspecRawBytes"},"chainspec_bytes")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_chainspec result"),(0,l.kt)("p",null,"Please note that adding a ",(0,l.kt)("inlineCode",{parentName:"p"},"--vv")," flag will return the full chainspec bytes."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.0",\n "chainspec_bytes": {\n "chainspec_bytes": "[22040 hex chars]",\n "maybe_genesis_accounts_bytes": null,\n "maybe_global_state_bytes": null\n }\n },\n "id": 5510244237763930243\n}\n\n'))),(0,l.kt)("h2",{id:"info-get-deploy"},"info_get_deploy"),(0,l.kt)("p",null,"This method retrieves a ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#execution-semantics-deploys"},"Deploy")," from a network. It requires a ",(0,l.kt)("inlineCode",{parentName:"p"},"deploy_hash")," to query the Deploy."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#deployhash"},"deploy_hash")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The Deploy hash.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#finalizedapprovals"},"finalized_approvals")),(0,l.kt)("td",{parentName:"tr",align:null},"Boolean"),(0,l.kt)("td",{parentName:"tr",align:null},"Determines whether to return the Deploy with the finalized approvals substituted. (Optional)")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_deploy request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_deploy",\n "params": [\n "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",\n true\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"info_get_deploy_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"info_get_deploy_result")),(0,l.kt)("p",null,"The response contains the Deploy and the results of executing the Deploy."),(0,l.kt)("p",null,"If the ",(0,l.kt)("inlineCode",{parentName:"p"},"execution_results")," field is empty, it means that the network processed the ",(0,l.kt)("inlineCode",{parentName:"p"},"Deploy"),", but has yet to execute it. If the network executed the ",(0,l.kt)("inlineCode",{parentName:"p"},"Deploy"),", it will return the results of the execution. The execution results contain the Block hash which contains the Deploy."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#deploy"},"deploy")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Deploy.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#jsonexecutionresult"},"execution_results")),(0,l.kt)("td",{parentName:"tr",align:null},"Array"),(0,l.kt)("td",{parentName:"tr",align:null},"An array of execution results with Block hashes.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_deploy result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy": {\n "approvals": [\n {\n "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007",\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n ],\n "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",\n "header": {\n "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",\n "chain_name": "casper-example",\n "dependencies": [\n "0101010101010101010101010101010101010101010101010101010101010101"\n ],\n "gas_price": 1,\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h"\n },\n "payment": {\n "StoredContractByName": {\n "args": [\n [\n "amount",\n {\n "bytes": "e8030000",\n "cl_type": "I32",\n "parsed": 1000\n }\n ]\n ],\n "entry_point": "example-entry-point",\n "name": "casper-example"\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "bytes": "e8030000",\n "cl_type": "I32",\n "parsed": 1000\n }\n ]\n ]\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "result": {\n "Success": {\n "cost": "123456",\n "effect": {\n "operations": [\n {\n "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",\n "kind": "Write"\n },\n {\n "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n "kind": "Read"\n }\n ],\n "transforms": [\n {\n "key": "uref-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb-007",\n "transform": {\n "AddUInt64": 8\n }\n },\n {\n "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n "transform": "Identity"\n }\n ]\n },\n "transfers": [\n "transfer-5959595959595959595959595959595959595959595959595959595959595959",\n "transfer-8282828282828282828282828282828282828282828282828282828282828282"\n ]\n }\n }\n }\n ]\n }\n}\n\n'))),(0,l.kt)("h2",{id:"query-balance"},"query_balance"),(0,l.kt)("p",null,"This method allows you to query for the balance of a purse using a ",(0,l.kt)("inlineCode",{parentName:"p"},"PurseIdentifier")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"StateIdentifier"),"."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#purseidentifier"},"purse_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The identifier to obtain the purse corresponding to the balance query.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#globalstateidentifier"},"state_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The state identifier used for the query; if none is passed the tip of the chain will be used.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example query_balance request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": [\n {\n "name": "state_identifier",\n "value": {\n "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n },\n {\n "name": "purse_identifier",\n "value": {\n "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"\n }\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"query_balance_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"query_balance_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#u512"},"balance")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The balance represented in motes.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example query_balance result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "jsonrpc": "2.0",\n "id": -6143675785141640608,\n "result": {\n "api_version": "1.0.0",\n "balance": "1000000000000000000000000000000000"\n }\n}\n\n'))),(0,l.kt)("h2",{id:"query-global-state"},"query_global_state"),(0,l.kt)("p",null,"This method allows for you to query for a value stored under certain keys in global state. You may query using either a ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#block_hash"},"Block hash")," or state root hash."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"Note: Querying a purse's balance requires the use of ",(0,l.kt)("inlineCode",{parentName:"li"},"query_balance"),", rather than any iteration of ",(0,l.kt)("inlineCode",{parentName:"li"},"query_global_state"),".")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#globalstateidentifier"},"state_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The identifier used for the query.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"key"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"casper_types::Key")," as a formatted string.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"path"),(0,l.kt)("td",{parentName:"tr",align:null},"Array"),(0,l.kt)("td",{parentName:"tr",align:null},"The path components starting from the key as base.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example query_global_state request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": [\n "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n [],\n {\n "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"query_global_state_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"query_global_state_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#jsonblockheader"},"block_header")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block header if a Block hash was provided. (Not required)")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#storedvalue"},"stored_value")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The stored value.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#merkle-proof"},"merkle_proof")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The merkle proof.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example query_global_state result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": {\n "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",\n "body_hash": "cd502c5393a3c8b66d6979ad7857507c9baf5a8ba16ba99c28378d3a970fff42",\n "era_end": {\n "era_report": {\n "equivocators": [\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ],\n "inactive_validators": [\n "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"\n ],\n "rewards": [\n {\n "amount": 1000,\n "validator": "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c"\n }\n ]\n },\n "next_era_validator_weights": [\n {\n "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",\n "weight": "456"\n },\n {\n "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",\n "weight": "789"\n },\n {\n "validator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "weight": "123"\n }\n ]\n },\n "era_id": 1,\n "height": 10,\n "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "protocol_version": "1.0.0",\n "random_bit": true,\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "timestamp": "2020-11-17T00:39:24.072Z"\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "named_keys": []\n }\n }\n }\n}\n\n'))),(0,l.kt)("h2",{id:"state-get-account-info"},"state_get_account_info"),(0,l.kt)("p",null,"This method returns a JSON representation of an ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-head"},"Account")," from the network. The ",(0,l.kt)("inlineCode",{parentName:"p"},"block_identifier")," must refer to a Block after the Account's creation, or the method will return an empty response."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#publickey"},"public_key")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The public key of the Account.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block identifier.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example state_get_account_info request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_account_info",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n },\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"state_get_account_info_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"state_get_account_info_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#account"},"account")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"A JSON representation of the Account structure.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#merkleproof"},"merkle_proof")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The merkle proof.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example state_get_account_info result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "account": {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "named_keys": []\n },\n "api_version": "1.4.13",\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n}\n\n'))),(0,l.kt)("h2",{id:"state-get-dictionary-item"},"state_get_dictionary_item"),(0,l.kt)("p",null,"This method returns an item from a Dictionary. Every dictionary has a seed URef, findable by using a ",(0,l.kt)("inlineCode",{parentName:"p"},"dictionary_identifier"),". The address of a stored value is the blake2b hash of the seed URef and the byte representation of the dictionary key."),(0,l.kt)("p",null,"You may query a stored value directly using the dictionary address."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#digest"},"state_root_hash")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"Hash of the state root.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#dictionaryidentifier"},"dictionary_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Dictionary query identifier.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example state_get_dictionary_item request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_dictionary_item",\n "params": [\n {\n "URef": {\n "dictionary_item_key": "a_unique_entry_identifier",\n "seed_uref": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"\n }\n },\n "0808080808080808080808080808080808080808080808080808080808080808"\n ]\n}\n\n'))),"### `state_get_dictionary_item_result`",(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"dictionary_key"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The key under which the value is stored.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#storedvalue"},"stored_value")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The stored value.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#merkle-proof"},"merkle_proof")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The merkle proof.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example state_get_dictionary_item result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "dictionary_key": "dictionary-67518854aa916c97d4e53df8570c8217ccc259da2721b692102d76acd0ee8d1f",\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",\n "stored_value": {\n "CLValue": {\n "bytes": "0100000000000000",\n "cl_type": "U64",\n "parsed": 1\n }\n }\n }\n}\n\n'))),(0,l.kt)("hr",null),(0,l.kt)("h1",{id:"node-informational"},"Node Informational JSON-RPC Methods"),(0,l.kt)("p",null,"The following methods return information from a node on a Casper network. The responses return information specific to the queried node, and as such, will vary."),(0,l.kt)("hr",null),(0,l.kt)("h2",{id:"info-get-peers"},"info_get_peers"),(0,l.kt)("p",null,"This method returns a list of peers connected to the node."),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_peers request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_peers",\n "params": []\n}\n\n'))),(0,l.kt)("h3",{id:"info_get_peers_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"info_get_peers_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#peersmap"},"peers")),(0,l.kt)("td",{parentName:"tr",align:null},"Array"),(0,l.kt)("td",{parentName:"tr",align:null},"The node ID and network address of each connected peer.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_peers result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "peers": [\n {\n "address": "127.0.0.1:54321",\n "node_id": "tls:0101..0101"\n }\n ]\n }\n}\n\n'))),(0,l.kt)("h2",{id:"info-get-status"},"info_get_status"),(0,l.kt)("p",null,"This method returns the current status of a node."),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_status request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_status",\n "params": []\n}\n\n'))),(0,l.kt)("h3",{id:"info_get_status_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"info_get_status_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#AvailableBlockRange"},"available_block_range")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The available block range in storage.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#BlockSynchronizerStatus"},"block_sync")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The status of the block synchronizer builders.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"build_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The compiled node version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"chainspec_name"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The chainspec name, used to identify the currently connected network.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#minimalblockinfo"},"last_added_block_info")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The minimal info of the last Block from the linear chain.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#timestamp"},"last_progress")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"Timestamp of the last recorded progress in the reactor.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#nextupgrade"},"next_upgrade")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"Information about the next scheduled upgrade.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#publickey"},"our_public_signing_key")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"Our public signing key.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#peersmap"},"peers")),(0,l.kt)("td",{parentName:"tr",align:null},"Array"),(0,l.kt)("td",{parentName:"tr",align:null},"The node ID and network address of each connected peer.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#reactorstate"},"reactor_state")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The current state of the node reactor.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#timediff"},"round_length")),(0,l.kt)("td",{parentName:"tr",align:null},"Integer"),(0,l.kt)("td",{parentName:"tr",align:null},"The next round length if this node is a validator. A round length is the amount of time it takes to reach consensus on proposing a Block.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#digest"},"starting_state_root_hash")),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The state root hash used at the start of the current session.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#timediff"},"uptime")),(0,l.kt)("td",{parentName:"tr",align:null},"Integer"),(0,l.kt)("td",{parentName:"tr",align:null},"Time that passed since the node has started.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_status result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_status_result",\n "value": {\n "peers": [\n {\n "node_id": "tls:0101..0101",\n "address": "127.0.0.1:54321"\n }\n ],\n "api_version": "1.4.8",\n "build_version": "1.0.0-xxxxxxxxx@DEBUG",\n "chainspec_name": "casper-example",\n "starting_state_root_hash": null,\n "last_added_block_info": {\n "hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "era_id": 1,\n "height": 10,\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "creator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n "our_public_signing_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "round_length": "1m 5s 536ms",\n "next_upgrade": {\n "activation_point": 42,\n "protocol_version": "2.0.1"\n },\n "uptime": "13s",\n "reactor_state": "Initialize",\n "last_progress": "1970-01-01T00:00:00.000Z",\n "available_block_range": {\n "low": 0,\n "high": 0\n },\n "block_sync": {\n "historical": {\n "block_hash": "16ddf28e2b3d2e17f4cef36f8b58827eca917af225d139b0c77df3b4a67dc55e",\n "block_height": 40,\n "acquisition_state": "have strict finality(40) for: block hash 16dd..c55e"\n },\n "forward": {\n "block_hash": "59907b1e32a9158169c4d89d9ce5ac9164fc31240bfcfb0969227ece06d74983",\n "block_height": 6701,\n "acquisition_state": "have block body(6701) for: block hash 5990..4983"\n }\n }\n }\n}\n\n'))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1b581919.189083f6.js b/assets/js/1b581919.5e8cc799.js similarity index 99% rename from assets/js/1b581919.189083f6.js rename to assets/js/1b581919.5e8cc799.js index 74c006ab33..580945a52b 100644 --- a/assets/js/1b581919.189083f6.js +++ b/assets/js/1b581919.5e8cc799.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[7832],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=c(n),h=i,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||o;return n?a.createElement(m,r(r({ref:t},p),{},{components:n})):a.createElement(m,r({ref:t},p))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:i,r[1]=s;for(var c=2;c with your public key manually and run this command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-auction-info | jq '.result.auction_state.bids[] | select( .public_key == \"\")'\n")),(0,o.kt)("p",null,"Or, if you set up the node as described in this documentation, you can run another command that will automatically put in your public key:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-auction-info | jq --arg pk \"$(cat /etc/casper/validator_keys/public_key_hex)\" '.result.auction_state.bids[] | select( (.public_key | ascii_downcase) == ($pk | ascii_downcase) )'\n")),(0,o.kt)("p",null,"You know you were evicted if the ",(0,o.kt)("inlineCode",{parentName:"p"},"get-auction-info")," command returned your bid showing an ",(0,o.kt)("strong",{parentName:"p"},"inactive")," field. See the ",(0,o.kt)("a",{parentName:"p",href:"/operators/becoming-a-validator/inactive-vs-faulty"},"Inactive vs. Faulty Validator Nodes")," page for more information."),(0,o.kt)("p",null,"If you receive a ",(0,o.kt)("inlineCode",{parentName:"p"},"parse error: Invalid numeric literal at"),", this usually means that your RPC port is not up yet. Get your node in sync, and the RPC will come up. This should be working before you try to recover. Try running the following command to check the status of your RPC port:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-auction-info\n")),(0,o.kt)("h2",{id:"correcting-any-underlying-node-issues"},"Correcting any Underlying Node Issues"),(0,o.kt)("p",null,"Before fixing the eviction, you need to correct the problem that caused your node to be evicted. Stage missed upgrades, correct any node issues, and get your node in sync."),(0,o.kt)("p",null,"To check if your node is in sync, compare the current block height at ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live/"},"https://cspr.live/")," with the height from your node with:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s localhost:8888/status | jq .last_added_block_info\n")),(0,o.kt)("p",null,"If you cannot figure out the issue, ask for help in the ",(0,o.kt)("em",{parentName:"p"},"node-tech-support")," channel on ",(0,o.kt)("a",{parentName:"p",href:"https://discord.com/invite/casperblockchain"},"Discord"),"."),(0,o.kt)("h2",{id:"activating-the-bid"},"Activating the Bid"),(0,o.kt)("p",null,"Once your node is in sync and ready to validate again, you must activate your invalid bid. There are two ways to reactivate your bid. The recommended and cheaper method is to call the ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid")," entry point from the system auction contract. The second method involves building the ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid.wasm")," contract as explained in ",(0,o.kt)("a",{parentName:"p",href:"/operators/setup/joining#step-3-build-contracts"},"Building the Required Contracts"),"."),(0,o.kt)("p",null,"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."),(0,o.kt)("h3",{id:"activating-system-auction"},"Method 1: Activating the Bid with the System Auction Contract"),(0,o.kt)("p",null,"This method calls the existing ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid")," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-hash \\\n--session-entry-point activate_bid \\\n--session-arg \"validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'\"\n")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,o.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,o.kt)("em",{parentName:"li"},"casper-test")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. You must check the network's chainspec. For example, this entry point call needs 10,000 motes for node version ",(0,o.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-hash")," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Testnet"),": ",(0,o.kt)("inlineCode",{parentName:"li"},"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Mainnet"),": ",(0,o.kt)("inlineCode",{parentName:"li"},"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"))),(0,o.kt)("ol",{start:6},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-entry-point")," - Name of the entry point that will be used when calling the system auction contract. In this case, it is ",(0,o.kt)("inlineCode",{parentName:"li"},"activate_bid"))),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid")," entry point expects one argument:"),(0,o.kt)("ol",{start:7},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"validator_public_key"),": The hexadecimal public key of the validator reactivating its bid. ",(0,o.kt)("strong",{parentName:"li"},"This key must match the secret key that signs the bid activation request"))),(0,o.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,o.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#deploy-status"},"Deploy Status")," section for more details."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"Calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid")," entry point on the auction contract has a fixed cost of 10,000 motes.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example:")),(0,o.kt)("p",null,"This example uses the Casper Testnet to reactivate a bid:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 10000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point activate_bid \\\n--session-arg \"validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'\"\n")),(0,o.kt)("p",null,"Next, ",(0,o.kt)("a",{parentName:"p",href:"#checking-the-bid-activation"},"check the bid activation")," status."),(0,o.kt)("h3",{id:"activating-compiled-wasm"},"Method 2: Activating the Bid with Compiled Wasm"),(0,o.kt)("p",null,"The second method to rejoin the network is to reactivate your bid using the ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid.wasm"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'sudo -u casper casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \\\n--session-arg "validator_public_key:public_key=\'$(cat /etc/casper/validator_keys/public_key_hex)\'"\n')),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,o.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,o.kt)("em",{parentName:"li"},"casper-test")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to the compiled Wasm on your computer")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid.wasm")," expects one argument:"),(0,o.kt)("ol",{start:6},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"validator_public_key"),": The hexadecimal public key of the validator reactivating its bid. ",(0,o.kt)("strong",{parentName:"li"},"This key must match the secret key that signs the bid activation request"))),(0,o.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"As described above, this method is much more expensive than calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid")," entry point.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example:")),(0,o.kt)("p",null,"Here is an example that reactivates a bid using the ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid.wasm"),". You must modify the payment and other values in the deploy based on your environment and the network's ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec.toml"),". For example, if you use the ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid.wasm")," on a network with node version ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/release-1.4.9/resources/production/chainspec.toml"},"1.4.9"),", you will require a balance of at least 5 CSPR for this contract."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 5000000000 \\\n--session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \\\n--session-arg "validator_public_key:public_key=\'$(cat /etc/casper/validator_keys/public_key_hex)\'"\n')),(0,o.kt)("p",null,"Check that the deploy was successful with the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-client get-deploy ")," or by searching for the deploy hash on ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live/"},"https://cspr.live/"),". Also, check the bid activation status as shown below."),(0,o.kt)("h2",{id:"checking-the-bid-activation"},"Checking the Bid Activation"),(0,o.kt)("p",null,"Once your deploy processes, you can ",(0,o.kt)("a",{parentName:"p",href:"/operators/becoming-a-validator/recovering#detecting-the-eviction-using-the-casper-client"},"check your bid")," again. You should now see ",(0,o.kt)("inlineCode",{parentName:"p"},'"inactive": false')," in the output."),(0,o.kt)("p",null,"If you wait until the next Era starts, you should also see your public key as a future validator on the ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live/validators"},"Validators")," tab."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[7832],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=c(n),h=i,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||o;return n?a.createElement(m,r(r({ref:t},p),{},{components:n})):a.createElement(m,r({ref:t},p))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:i,r[1]=s;for(var c=2;c with your public key manually and run this command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-auction-info | jq '.result.auction_state.bids[] | select( .public_key == \"\")'\n")),(0,o.kt)("p",null,"Or, if you set up the node as described in this documentation, you can run another command that will automatically put in your public key:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-auction-info | jq --arg pk \"$(cat /etc/casper/validator_keys/public_key_hex)\" '.result.auction_state.bids[] | select( (.public_key | ascii_downcase) == ($pk | ascii_downcase) )'\n")),(0,o.kt)("p",null,"You know you were evicted if the ",(0,o.kt)("inlineCode",{parentName:"p"},"get-auction-info")," command returned your bid showing an ",(0,o.kt)("strong",{parentName:"p"},"inactive")," field. See the ",(0,o.kt)("a",{parentName:"p",href:"/operators/becoming-a-validator/inactive-vs-faulty"},"Inactive vs. Faulty Validator Nodes")," page for more information."),(0,o.kt)("p",null,"If you receive a ",(0,o.kt)("inlineCode",{parentName:"p"},"parse error: Invalid numeric literal at"),", this usually means that your RPC port is not up yet. Get your node in sync, and the RPC will come up. This should be working before you try to recover. Try running the following command to check the status of your RPC port:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-auction-info\n")),(0,o.kt)("h2",{id:"correcting-any-underlying-node-issues"},"Correcting any Underlying Node Issues"),(0,o.kt)("p",null,"Before fixing the eviction, you need to correct the problem that caused your node to be evicted. Stage missed upgrades, correct any node issues, and get your node in sync."),(0,o.kt)("p",null,"To check if your node is in sync, compare the current block height at ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live/"},"https://cspr.live/")," with the height from your node with:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s localhost:8888/status | jq .last_added_block_info\n")),(0,o.kt)("p",null,"If you cannot figure out the issue, ask for help in the ",(0,o.kt)("em",{parentName:"p"},"node-tech-support")," channel on ",(0,o.kt)("a",{parentName:"p",href:"https://discord.com/invite/casperblockchain"},"Discord"),"."),(0,o.kt)("h2",{id:"activating-the-bid"},"Activating the Bid"),(0,o.kt)("p",null,"Once your node is in sync and ready to validate again, you must activate your invalid bid. There are two ways to reactivate your bid. The recommended and cheaper method is to call the ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid")," entry point from the system auction contract. The second method involves building the ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid.wasm")," contract as explained in ",(0,o.kt)("a",{parentName:"p",href:"/operators/setup/joining#step-3-build-contracts"},"Building the Required Contracts"),"."),(0,o.kt)("p",null,"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."),(0,o.kt)("h3",{id:"activating-system-auction"},"Method 1: Activating the Bid with the System Auction Contract"),(0,o.kt)("p",null,"This method calls the existing ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid")," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-hash \\\n--session-entry-point activate_bid \\\n--session-arg \"validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'\"\n")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,o.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,o.kt)("em",{parentName:"li"},"casper-test")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. You must check the network's chainspec. For example, this entry point call needs 10,000 motes for node version ",(0,o.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-hash")," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Testnet"),": ",(0,o.kt)("inlineCode",{parentName:"li"},"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Mainnet"),": ",(0,o.kt)("inlineCode",{parentName:"li"},"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"))),(0,o.kt)("ol",{start:6},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-entry-point")," - Name of the entry point that will be used when calling the system auction contract. In this case, it is ",(0,o.kt)("inlineCode",{parentName:"li"},"activate_bid"))),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid")," entry point expects one argument:"),(0,o.kt)("ol",{start:7},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"validator_public_key"),": The hexadecimal public key of the validator reactivating its bid. ",(0,o.kt)("strong",{parentName:"li"},"This key must match the secret key that signs the bid activation request"))),(0,o.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,o.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#deploy-status"},"Deploy Status")," section for more details."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"Calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid")," entry point on the auction contract has a fixed cost of 10,000 motes.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example:")),(0,o.kt)("p",null,"This example uses the Casper Testnet to reactivate a bid:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 10000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point activate_bid \\\n--session-arg \"validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'\"\n")),(0,o.kt)("p",null,"Next, ",(0,o.kt)("a",{parentName:"p",href:"#checking-the-bid-activation"},"check the bid activation")," status."),(0,o.kt)("h3",{id:"activating-compiled-wasm"},"Method 2: Activating the Bid with Compiled Wasm"),(0,o.kt)("p",null,"The second method to rejoin the network is to reactivate your bid using the ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid.wasm"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'sudo -u casper casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \\\n--session-arg "validator_public_key:public_key=\'$(cat /etc/casper/validator_keys/public_key_hex)\'"\n')),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,o.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,o.kt)("em",{parentName:"li"},"casper-test")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to the compiled Wasm on your computer")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid.wasm")," expects one argument:"),(0,o.kt)("ol",{start:6},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"validator_public_key"),": The hexadecimal public key of the validator reactivating its bid. ",(0,o.kt)("strong",{parentName:"li"},"This key must match the secret key that signs the bid activation request"))),(0,o.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"As described above, this method is much more expensive than calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid")," entry point.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example:")),(0,o.kt)("p",null,"Here is an example that reactivates a bid using the ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid.wasm"),". You must modify the payment and other values in the deploy based on your environment and the network's ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec.toml"),". For example, if you use the ",(0,o.kt)("inlineCode",{parentName:"p"},"activate_bid.wasm")," on a network with node version ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/release-1.4.9/resources/production/chainspec.toml"},"1.4.9"),", you will require a balance of at least 5 CSPR for this contract."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 5000000000 \\\n--session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \\\n--session-arg "validator_public_key:public_key=\'$(cat /etc/casper/validator_keys/public_key_hex)\'"\n')),(0,o.kt)("p",null,"Check that the deploy was successful with the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-client get-deploy ")," or by searching for the deploy hash on ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live/"},"https://cspr.live/"),". Also, check the bid activation status as shown below."),(0,o.kt)("h2",{id:"checking-the-bid-activation"},"Checking the Bid Activation"),(0,o.kt)("p",null,"Once your deploy processes, you can ",(0,o.kt)("a",{parentName:"p",href:"/operators/becoming-a-validator/recovering#detecting-the-eviction-using-the-casper-client"},"check your bid")," again. You should now see ",(0,o.kt)("inlineCode",{parentName:"p"},'"inactive": false')," in the output."),(0,o.kt)("p",null,"If you wait until the next Era starts, you should also see your public key as a future validator on the ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live/validators"},"Validators")," tab."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1c22d3ad.a70828b6.js b/assets/js/1c22d3ad.30334d14.js similarity index 99% rename from assets/js/1c22d3ad.a70828b6.js rename to assets/js/1c22d3ad.30334d14.js index 69b0e96ee8..4a6129e527 100644 --- a/assets/js/1c22d3ad.a70828b6.js +++ b/assets/js/1c22d3ad.30334d14.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5870],{3905:function(e,n,t){t.d(n,{Zo:function(){return p},kt:function(){return m}});var a=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function r(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var l=a.createContext({}),d=function(e){var n=a.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},p=function(e){var n=d(e.components);return a.createElement(l.Provider,{value:n},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},h=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),c=d(t),h=i,m=c["".concat(l,".").concat(h)]||c[h]||u[h]||o;return t?a.createElement(m,r(r({ref:n},p),{},{components:t})):a.createElement(m,r({ref:n},p))}));function m(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var o=t.length,r=new Array(o);r[0]=h;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s[c]="string"==typeof e?e:i,r[1]=s;for(var d=2;dMessage Type",id:"the-message-type",level:2},{value:"Handshake Behavior",id:"handshake-behavior",level:2},{value:"Blocking Nodes",id:"blocking-nodes",level:2},{value:"The Payload Type",id:"the-payload-type",level:2},{value:"Consensus",id:"consensus",level:3},{value:"Gossiping",id:"gossiping",level:3},{value:"Unsafe-for-syncing",id:"unsafe-for-syncing",level:3},{value:"Gossiping",id:"gossiping-1",level:2},{value:"GetRequests",id:"getrequests",level:2},{value:"Finality Signatures",id:"finality-signatures",level:2},{value:"Trie Chunking",id:"trie-chunking",level:2}],u={toc:c},h="wrapper";function m(e){var n=e.components,t=(0,i.Z)(e,r);return(0,o.kt)(h,(0,a.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"casper-node-networking-protocol"},"Casper Node Networking Protocol"),(0,o.kt)("h2",{id:"casper-node-networking-protocol-mainnet-protocol-version-150"},"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)"),(0,o.kt)("p",null,"This is a description of the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node"),"'s networking protocol. This document follows the conventions laid out in ",(0,o.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc2119"},"RFC2119"),"."),(0,o.kt)("h2",{id:"connection-level"},"Connection Level"),(0,o.kt)("p",null,"Any ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," taking part in the Casper network SHOULD open connections to every other casper-node it is aware of and has not blocked. These connections are established using TLS, presenting a client certificate."),(0,o.kt)("h3",{id:"reciprocity-retries-and-data-direction"},"Reciprocity, retries and data direction"),(0,o.kt)("p",null,"A connection that was initiated by a node is considered an ",(0,o.kt)("em",{parentName:"p"},"outgoing")," connection by the node itself, but an ",(0,o.kt)("em",{parentName:"p"},"incoming")," connection by all other peers."),(0,o.kt)("p",null,"A node that created an outgoing connection SHOULD terminate the connection if it does not detect an incoming connection from the connected-to node within a short amount of time."),(0,o.kt)("p",null,"A node that receives an incoming connection MUST eventually establish an outgoing connection to the node."),(0,o.kt)("p",null,"A node SHOULD retry any failed outgoing connection periodically with exponential backoff. A node MUST NOT attempt to reconnect more than once per second."),(0,o.kt)("p",null,"Nodes MUST NOT send data through incoming connections, other than handshakes. Nodes MUST NOT accept any data coming through outgoing connections, other than handshakes."),(0,o.kt)("h3",{id:"tls-parameters"},"TLS parameters"),(0,o.kt)("p",null,"Any node creating a connection to a node MUST present a client certificate with the following properties:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Signature algorithm: ",(0,o.kt)("inlineCode",{parentName:"li"},"ECDSA_WITH_SHA512")),(0,o.kt)("li",{parentName:"ul"},"Subject name: Same as issuer name (self-signed certificate!)"),(0,o.kt)("li",{parentName:"ul"},"Serial number: 1"),(0,o.kt)("li",{parentName:"ul"},'Expiration ("not before"): Must be earlier than current time.'),(0,o.kt)("li",{parentName:"ul"},'Expiration ("not after"): Must be later than current time.'),(0,o.kt)("li",{parentName:"ul"},"Signature: Must be using ",(0,o.kt)("inlineCode",{parentName:"li"},"SECP521R1")," with ",(0,o.kt)("inlineCode",{parentName:"li"},"SHA512")," and valid.")),(0,o.kt)("p",null,"The SHA512 fingerprint of the ",(0,o.kt)("em",{parentName:"p"},"public key")," is considered the ",(0,o.kt)("strong",{parentName:"p"},"NodeID")," of the node."),(0,o.kt)("p",null,"Any node MUST immediately terminate a connection if it does not match the given parameters. The same certificate MUST be used as a server certificate for other clients connecting to this node."),(0,o.kt)("p",null,"An incoming connection with a valid TLS certificate SHOULD be accepted. As all certificates are self-signed, no further checking is done."),(0,o.kt)("h3",{id:"discovery"},"Discovery"),(0,o.kt)("p",null,"A node address is defined as an IPv4 address and a port. A node's address is the publicly reachable IP address and port that it is listening on for node-to-node-communication."),(0,o.kt)("p",null,"Every node SHOULD have one or more so-called ",(0,o.kt)("em",{parentName:"p"},"known node addresses")," of other nodes configured."),(0,o.kt)("p",null,"On start-up, a node SHOULD attempt to connect to all known nodes. A node SHOULD never forget a known node address."),(0,o.kt)("p",null,"Every node MUST periodically gossip its own node address to the network (see gossiping below)."),(0,o.kt)("p",null,"A node ",(0,o.kt)("em",{parentName:"p"},"learns")," new node addresses through receiving a gossiped node address, or being told of an address through the handshake."),(0,o.kt)("p",null,"Upon learning of a previously unknown node address, a node SHOULD attempt to connect to it."),(0,o.kt)("p",null,"After failing to connect to a node address, a node MAY forget it after a certain amount of retries, this process is called ",(0,o.kt)("em",{parentName:"p"},"forgetting")," a node. An address that has been forgotten will be considered new the next time it is learned."),(0,o.kt)("p",null,"A node MUST NOT forget the known addresses it was configured with initially."),(0,o.kt)("h2",{id:"framing"},"Framing"),(0,o.kt)("p",null,"To send a message to a peer across an established TLS connection, a node MUST send a message length header consisting of a 32 byte big endian integer with the message length first."),(0,o.kt)("p",null,"A node receiving a message length header that exceeds the maximum message size specified in the chainspec MUST immediately terminate the connection."),(0,o.kt)("h2",{id:"encoding"},"Encoding"),(0,o.kt)("p",null,"The node uses three encoding schemes: Handshakes (see below) are encoded using ",(0,o.kt)("a",{parentName:"p",href:"https://msgpack.org"},"MessagePack"),", while regular messages are encoded using ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/bincode"},"bincode"),". Many (but not all) data objects use ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/bytesrepr/index.html"},(0,o.kt)("inlineCode",{parentName:"a"},"bytesrepr"))," for serialization."),(0,o.kt)("p",null,"The node uses the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/rmp-serde/0.14.4/rmp_serde/index.html"},(0,o.kt)("inlineCode",{parentName:"a"},"rmp-serde"))," crate, version ",(0,o.kt)("inlineCode",{parentName:"p"},"0.14.4"),", which is kept fixed to ensure handshake compatibility with protocol version 1.0 of the node."),(0,o.kt)("p",null,"All nodes MUST use the following settings for ",(0,o.kt)("inlineCode",{parentName:"p"},"bincode")," encoding of network messages:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Byte limit: Unlimited"),(0,o.kt)("li",{parentName:"ul"},"Endianness: Little Endian"),(0,o.kt)("li",{parentName:"ul"},"Integer Encoding: Varint"),(0,o.kt)("li",{parentName:"ul"},"Trailing Bytes: Not allowed")),(0,o.kt)("p",null,"Any other use of ",(0,o.kt)("inlineCode",{parentName:"p"},"bincode")," encoding (e.g. for GetRequest payloads, see below) MUST use the following ",(0,o.kt)("inlineCode",{parentName:"p"},"bincode")," encoding settings:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Byte limit: Unlimited"),(0,o.kt)("li",{parentName:"ul"},"Endianness: Little Endian"),(0,o.kt)("li",{parentName:"ul"},"Integer Encoding: Fixint"),(0,o.kt)("li",{parentName:"ul"},"Trailing Bytes: Allowed")),(0,o.kt)("p",null,"Unless noted otherwise, any structure encoded as MessagePack or bincode is serialized using the standard ",(0,o.kt)("a",{parentName:"p",href:"https://serde.rs"},(0,o.kt)("inlineCode",{parentName:"a"},"serde")),"-derived encoding. For ",(0,o.kt)("inlineCode",{parentName:"p"},"bytesrepr")," serialization refer to the specific implementations in the ",(0,o.kt)("inlineCode",{parentName:"p"},"bytesrepr")," crate."),(0,o.kt)("p",null,"Any data types given from here on out are described using simplified ",(0,o.kt)("a",{parentName:"p",href:"https://www.rust-lang.org/"},"Rust")," structure definitions."),(0,o.kt)("h2",{id:"the-message-type"},"The ",(0,o.kt)("inlineCode",{parentName:"h2"},"Message")," Type"),(0,o.kt)("p",null,"The following data types make up the networking protocol:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"enum Message {\n Handshake {\n network_name: String,\n public_addr: SocketAddr,\n // default: 1.0\n protocol_version: ProtocolVersion,\n // default: `None`\n consensus_certificate: Option,\n // default: false\n is_syncing: bool,\n // default: `None`\n chainspec_hash: Option,\n },\n Payload(Payload),\n}\n\nstruct ConsensusCertificate {\n public_key: PublicKey,\n signature: Signature,\n}\n\nstruct Digest([u8; 32]);\n")),(0,o.kt)("p",null,"For ",(0,o.kt)("a",{parentName:"p",href:"https://doc.rust-lang.org/std/string/struct.String.html"},(0,o.kt)("inlineCode",{parentName:"a"},"String")),", ",(0,o.kt)("a",{parentName:"p",href:"https://doc.rust-lang.org/std/net/enum.SocketAddr.html"},(0,o.kt)("inlineCode",{parentName:"a"},"SocketAddr")),", ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/struct.ProtocolVersion.html"},(0,o.kt)("inlineCode",{parentName:"a"},"ProtocolVersion")),", ",(0,o.kt)("a",{parentName:"p",href:"https://doc.rust-lang.org/std/option/enum.Option.html"},(0,o.kt)("inlineCode",{parentName:"a"},"Option")),", ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/crypto/enum.PublicKey.html"},(0,o.kt)("inlineCode",{parentName:"a"},"PublicKey")),", ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/crypto/enum.Signature.html"},(0,o.kt)("inlineCode",{parentName:"a"},"Signature"))," see the respective docs and details below."),(0,o.kt)("h2",{id:"handshake-behavior"},"Handshake Behavior"),(0,o.kt)("p",null,"A node establishing a new connection MUST immediately send a handshake through said connection to the peer, regardless of whether an incoming or outgoing connection was established (this is an exception to the restriction of only sending data through outgoing connections)."),(0,o.kt)("p",null,"A handshake MUST be encoded using the ",(0,o.kt)("inlineCode",{parentName:"p"},"Message::Handshake")," structure. A node running version 1.5 SHOULD NOT omit any of the fields for which default values are available (",(0,o.kt)("inlineCode",{parentName:"p"},"protocol_version"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"consensus_certificate"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"is_syncing"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"chainspec_hash"),"). A node MUST accept any handshake that omits one or more of these fields and fill them with defaults."),(0,o.kt)("p",null,"After receiving a handshake, a node MUST compare the ",(0,o.kt)("inlineCode",{parentName:"p"},"network_name"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"protocol_version")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"chainspec_hash")," fields against its own configuration: If any of these do not match, it MUST disconnect from the node and SHOULD block it."),(0,o.kt)("p",null,"A node MUST mark any peer that connects to it (thus is an incoming connection from the perspective of the node) with a value of ",(0,o.kt)("inlineCode",{parentName:"p"},"is_syncing")," set to ",(0,o.kt)("inlineCode",{parentName:"p"},"true"),' as "syncing" and MUST NOT allow any of its own messages that are marked unsafe-for-syncing to be sent to that node, by silently dropping them instead.'),(0,o.kt)("p",null,"A node MAY compare peers that provide a ",(0,o.kt)("inlineCode",{parentName:"p"},"consensus_certificate")," to the currently active set of validators and mark it as an active validator to give it preferential treatment when outgoing bandwidth is limited."),(0,o.kt)("p",null,"Upon handshake completion, the node SHOULD learn the provided ",(0,o.kt)("inlineCode",{parentName:"p"},"public_addr"),"."),(0,o.kt)("h2",{id:"blocking-nodes"},"Blocking Nodes"),(0,o.kt)("p",null,"If a node blocks a peer, it MUST sever all incoming and outgoing connections to said node. It MUST take note of the NodeId of the node, marking it as blocked and MUST not allow any new connection to proceed past the handshake."),(0,o.kt)("p",null,"A node MUST NOT block peers based on IP address or port. Nodes MUST NOT block peers for more than an hour."),(0,o.kt)("p",null,"After a block on a node is expired, the node SHOULD ",(0,o.kt)("em",{parentName:"p"},"forget")," the nodes IP address, allowing a later ",(0,o.kt)("em",{parentName:"p"},"learning")," of said address again."),(0,o.kt)("h2",{id:"the-payload-type"},"The ",(0,o.kt)("inlineCode",{parentName:"h2"},"Payload")," Type"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"Payload")," (found in the node sources as ",(0,o.kt)("inlineCode",{parentName:"p"},"Message")," in ",(0,o.kt)("inlineCode",{parentName:"p"},"payload.rs"),") contains variants for all node-to-node communicating subsystems of a running node, which are described below. Note that some of the variants have been renamed for clarity in this specification. Since field names are not used in ",(0,o.kt)("inlineCode",{parentName:"p"},"bincode")," encoding, this should have no effect on implementations."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"enum Payload {\n Consensus(ConsensusMessage),\n DeployGossiper(DeployGossiperMessage),\n AddressGossiper(AddressGossiperMessage),\n GetRequest {\n tag: Tag,\n serialized_id: Vec,\n },\n GetResponse {\n tag: Tag,\n serialized_item: Vec<[u8]>,\n },\n FinalitySignature(FinalitySignature),\n}\n\nenum DeployGossiperMessage {\n Gossip(DeployHash),\n GossipResponse {\n item_id: DeployHash,\n is_already_held: bool,\n },\n}\n\nenum AddressGossiperMessage {\n Gossip(GossippedAddress),\n GossipResponse {\n item_id: GossippedAddress,\n is_already_held: bool,\n },\n}\n\nstruct DeployHash(Digest);\nstruct GossipedAddress(SocketAddr);\n")),(0,o.kt)("h3",{id:"consensus"},"Consensus"),(0,o.kt)("p",null,"A consensus message is sent exclusively between instances of the consensus component, from one peer to another. A precise description of the Highway consensus protocol is out of scope of this document, see the ",(0,o.kt)("inlineCode",{parentName:"p"},"consensus::Message")," type or an appropriate description of the underlying protocol for details."),(0,o.kt)("h3",{id:"gossiping"},"Gossiping"),(0,o.kt)("p",null,"Gossiping messages are sent by a node to a subset of its peers to announce the availability of new data items. Peers MUST be distinguished by NodeID, not by listening address."),(0,o.kt)("p",null,"A node must support a gossiper for deploys and one for ",(0,o.kt)("inlineCode",{parentName:"p"},"GossippedAddress"),", which is an alias for the regular Rust standard library's ",(0,o.kt)("inlineCode",{parentName:"p"},"SocketAddr"),"."),(0,o.kt)("p",null,"A node SHOULD begin a gossiping process for all deploys previously unknown to it. A node MUST periodically send an ",(0,o.kt)("inlineCode",{parentName:"p"},"AddressGossiperMessage::Gossip")," message to a random subset selected in a similar manner as the one for deploy gossip to make its own address known, see the gossiping process section below for details."),(0,o.kt)("h3",{id:"unsafe-for-syncing"},"Unsafe-for-syncing"),(0,o.kt)("p",null,"A node that is syncing MUST indicate this by setting ",(0,o.kt)("inlineCode",{parentName:"p"},"is_syncing")," to ",(0,o.kt)("inlineCode",{parentName:"p"},"true"),"."),(0,o.kt)("p",null,"A node MAY implement a scheme for request throttling/backpressure for GetRequests (see below) of ",(0,o.kt)("inlineCode",{parentName:"p"},"TrieNode"),"s that can cause issues with peers that are also sending GetRequests."),(0,o.kt)("p",null,"A node that succeeds in a handshake with a peer that has set ",(0,o.kt)("inlineCode",{parentName:"p"},"is_syncing")," MUST make note of this flag. If the node itself is implementing the feature described above, it MUST NOT make any GetRequests directed at this peer for ",(0,o.kt)("inlineCode",{parentName:"p"},"TrieNode"),"s."),(0,o.kt)("h2",{id:"gossiping-1"},"Gossiping"),(0,o.kt)("p",null,"Gossiping is distributing items across the network by sending it to a subset of known peers that do not have the item already, and having them repeat this process until a certain degree of saturation is observed."),(0,o.kt)("p",null,"Any item has an associated ID type which denotes what is used to uniquely identify it when gossiping. If an item is small enough, the ID may just be the item itself."),(0,o.kt)("p",null,"Gossiper messages have the following structure:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"enum GossiperMessage {\n Gossip(Id),\n GossipResponse {\n item_id: Id,\n is_already_held: bool,\n },\n}\n")),(0,o.kt)("p",null,"To gossip, a node MAY send a ",(0,o.kt)("inlineCode",{parentName:"p"},"GossiperMessage::Gossip")," message to a random subset of configurable size of peers to announce that it has received and validated a new item. Any peer receiving such a message SHOULD answer with a ",(0,o.kt)("inlineCode",{parentName:"p"},"GossiperMessage:GossipResponse"),", citing the given id and using ",(0,o.kt)("inlineCode",{parentName:"p"},"is_already_held")," to indicate whether it already possessed the given item."),(0,o.kt)("p",null,"The node SHOULD attempt to continue to find peers with a negative response, up to a configurable limit of attempts and/or success rate, or until running out of valid peers."),(0,o.kt)("p",null,"The node that initiated the gossip MUST keep track of which peer replied with a positive (",(0,o.kt)("inlineCode",{parentName:"p"},"is_already_held")," being ",(0,o.kt)("inlineCode",{parentName:"p"},"true"),") response and MUST NOT send another ",(0,o.kt)("inlineCode",{parentName:"p"},"Gossip")," message for same ID to any of these peers during this gossip process. However, it MAY restart gossiping the same item at a later time, considering these peers again."),(0,o.kt)("p",null,"If a node receives a negative ",(0,o.kt)("inlineCode",{parentName:"p"},"GossiperMessage::GossipResponse")," (i.e. ",(0,o.kt)("inlineCode",{parentName:"p"},"is_already_held")," being ",(0,o.kt)("inlineCode",{parentName:"p"},"false"),"), and the item's ID is not the item itself, it MUST handle that repsponse as if the peer had sent a ",(0,o.kt)("inlineCode",{parentName:"p"},"GetRequest")," for the item (see GetRequests section below)."),(0,o.kt)("h2",{id:"getrequests"},"GetRequests"),(0,o.kt)("p",null,'The "GetRequests" mechanism allows retrieving various items through primary or derived keys from peers.'),(0,o.kt)("p",null,"A peer MAY send a ",(0,o.kt)("inlineCode",{parentName:"p"},"GetRequest")," (see ",(0,o.kt)("inlineCode",{parentName:"p"},"Payload::GetRequest"),") with a ",(0,o.kt)("inlineCode",{parentName:"p"},"Tag")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"serialized_id")," payload. Both ",(0,o.kt)("inlineCode",{parentName:"p"},"serialized_id")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"serialized_item")," MUST be encoded using ",(0,o.kt)("inlineCode",{parentName:"p"},"bincode"),' (see "Encoding" section for details).'),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"pub enum Tag {\n Deploy,\n FinalizedApprovals,\n Block,\n GossipedAddress,\n BlockAndMetadataByHeight,\n BlockHeaderByHash,\n BlockHeaderAndFinalitySignaturesByHeight,\n TrieOrChunk,\n BlockAndDeploysByHash,\n BlockHeaderBatch,\n FinalitySignaturesByHash,\n}\n")),(0,o.kt)("p",null,"The tag dictates which item is being retrieved, and which key (ID type) is being used."),(0,o.kt)("p",null,"A node that receives a ",(0,o.kt)("inlineCode",{parentName:"p"},"GetRequest")," from a peer SHOULD return a ",(0,o.kt)("inlineCode",{parentName:"p"},"GetResponse")," (see ",(0,o.kt)("inlineCode",{parentName:"p"},"Payload::GetResponse"),"). The ",(0,o.kt)("inlineCode",{parentName:"p"},"GetResponse")," MUST use the same ",(0,o.kt)("inlineCode",{parentName:"p"},"Tag"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"pub enum FetchedOrNotFound {\n Fetched(T),\n NotFound(Id),\n}\n")),(0,o.kt)("p",null,"If the item was found, ",(0,o.kt)("inlineCode",{parentName:"p"},"serialized_item")," MUST contain a serialized ",(0,o.kt)("inlineCode",{parentName:"p"},"FetchedOrNotFound::Fetched")," instance, with the inner value ",(0,o.kt)("inlineCode",{parentName:"p"},"T")," being the item."),(0,o.kt)("p",null,"If the item was not found, ",(0,o.kt)("inlineCode",{parentName:"p"},"serialized_item")," MUST contain a ",(0,o.kt)("inlineCode",{parentName:"p"},"FetchedOrNotFound::NotFound")," instance, with the inner value ",(0,o.kt)("inlineCode",{parentName:"p"},"Id")," being the ID found in the originating ",(0,o.kt)("inlineCode",{parentName:"p"},"GetRequest"),"."),(0,o.kt)("p",null,"A node MUST not send any items to a peer that it itself has not verified."),(0,o.kt)("p",null,"The following table shows which tag corresponds to which ID and item type. Type definitions for ",(0,o.kt)("inlineCode",{parentName:"p"},"DeployHash")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"GossippedAddress")," can be found earlier in this document, other types are described following this section. Further details of many of these types can be found in the ",(0,o.kt)("a",{parentName:"p",href:"/concepts/serialization-standard"},"Serialization Standard"),", but be aware that those docs describe serializing using bytesrepr rather than bincode."),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Tag"),(0,o.kt)("th",{parentName:"tr",align:null},"ID type"),(0,o.kt)("th",{parentName:"tr",align:null},"Payload (item) type"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"Deploy"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"DeployHash")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"Deploy"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"FinalizedApprovals"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"DeployHash")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"FinalizedApprovalsWithId"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"Block"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHash")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"Block"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"GossipedAddress"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"GossipedAddress")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"GossipedAddress"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"BlockAndMetadataByHeight"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"u64")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockWithMetadata"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"BlockHeaderByHash"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHash")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHeader"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"BlockHeaderAndFinalitySignaturesByHeight"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"u64")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHeaderWithMetadata"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"TrieOrChunk"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"TrieOrChunkId")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"TrieOrChunk"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"BlockAndDeploysByHash"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHash")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockAndDeploys"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"BlockHeaderBatch"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHeadersBatchId")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHeadersBatch"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"FinalitySignaturesByHash"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHash")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockSignatures"))))),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"pub struct Deploy {\n hash: DeployHash,\n header: DeployHeader,\n payment: ExecutableDeployItem,\n session: ExecutableDeployItem,\n approvals: BTreeSet,\n}\n\nstruct DeployHeader {\n account: PublicKey,\n timestamp: u64,\n ttl: u64,\n gas_price: u64,\n body_hash: Digest,\n dependencies: Vec,\n chain_name: String,\n}\n\nenum PublicKey {\n System,\n Ed25519(Vec),\n Secp256k1(Vec),\n}\n\nenum ExecutableDeployItem {\n ModuleBytes {\n module_bytes: Vec,\n args: RuntimeArgs,\n },\n StoredContractByHash {\n hash: [u8; 32],\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredContractByName {\n name: String,\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredVersionedContractByHash {\n hash: [u8; 32],\n version: Option,\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredVersionedContractByName {\n name: String,\n version: Option,\n entry_point: String,\n args: RuntimeArgs,\n },\n Transfer { args: RuntimeArgs },\n}\n\nstruct RuntimeArgs(Vec);\n\nstruct NamedArg(String, CLValue);\n\nstruct CLValue(CLType, Vec);\n\nenum CLType {\n Bool,\n I32,\n I64,\n U8,\n U32,\n U64,\n U128,\n U256,\n U512,\n Unit,\n String,\n Key,\n URef,\n PublicKey,\n Option(Box),\n List(Box),\n ByteArray(u32),\n Result { ok: Box, err: Box },\n Map { key: Box, value: Box },\n Tuple1([Box; 1]),\n Tuple2([Box; 2]),\n Tuple3([Box; 3]),\n Any,\n}\n\nstruct Approval {\n signer: PublicKey,\n signature: Signature,\n}\n\nenum Signature {\n System,\n Ed25519(Vec),\n Secp256k1(Vec),\n}\n\nstruct FinalizedApprovalsWithId {\n id: DeployHash,\n approvals: FinalizedApprovals,\n}\n\nstruct FinalizedApprovals(BTreeSet);\n\nstruct Block {\n hash: BlockHash,\n header: BlockHeader,\n body: BlockBody,\n}\n\nstruct BlockHash(Digest);\n\nstruct BlockHeader {\n parent_hash: BlockHash,\n state_root_hash: Digest,\n body_hash: Digest,\n random_bit: bool,\n accumulated_seed: Digest,\n era_end: Option,\n timestamp: u64,\n era_id: u64,\n height: u64,\n protocol_version: ProtocolVersion,\n}\n\nstruct EraEnd {\n era_report: EraReport,\n next_era_validator_weights: BTreeMap,\n}\n\nstruct EraReport {\n equivocators: Vec,\n rewards: BTreeMap,\n inactive_validators: Vec,\n}\n\nstruct ProtocolVersion {\n major: u32,\n minor: u32,\n patch: u32,\n}\n\nstruct BlockBody {\n proposer: PublicKey,\n deploy_hashes: Vec,\n transfer_hashes: Vec,\n}\n")),(0,o.kt)("p",null,"Custom variable length encoding is used when serializing ",(0,o.kt)("inlineCode",{parentName:"p"},"U512"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"U256")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"U128")," types. They are encoded in a way equivalent to encoding the following pseudo struct:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"struct Bigint {\n serialized_length: u8,\n little_endian_unpadded_bytes: [u8, serialized_length - 1],\n}\n")),(0,o.kt)("p",null,"In other words, the following steps are taken:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"convert the bigint to an array of bytes in little-endian form"),(0,o.kt)("li",{parentName:"ul"},"strip the contiguous range of irrelevant padding ",(0,o.kt)("inlineCode",{parentName:"li"},"0")," bytes from the right hand end, if any"),(0,o.kt)("li",{parentName:"ul"},"prefix this remaining array with a byte holding the number of remaining bytes + 1, to indicate the length of the final byte array including the length byte itself")),(0,o.kt)("p",null,"For a description explaining the use of ",(0,o.kt)("inlineCode",{parentName:"p"},"TrieOrChunk"),' and related types, see the "Trie chunking" section. The relevant types are:'),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"struct TrieOrChunkId(u64, Digest);\n\nenum TrieOrChunk {\n Trie(Bytes),\n ChunkWithProof(ChunkWithProof),\n}\n\nstruct ChunkWithProof {\n proof: IndexedMerkleProof,\n chunk: Bytes,\n}\n\nstruct IndexedMerkleProof {\n index: u64,\n count: u64,\n merkle_proof: Vec,\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"BlockHeadersBatchId")," is used to request multiple ",(0,o.kt)("inlineCode",{parentName:"p"},"BlockHeader"),"s with a single request."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"struct BlockHeadersBatchId {\n highest: u64,\n lowest: u64,\n}\n\nstruct BlockWithMetadata {\n block: Block,\n finality_signatures: BlockSignatures,\n}\n\nstruct BlockHeaderWithMetadata {\n block_header: BlockHeader,\n block_signatures: BlockSignatures,\n}\n\nstruct BlockSignatures {\n block_hash: BlockHash,\n era_id: u64,\n proofs: BTreeMap,\n}\n\nstruct BlockAndDeploys {\n block: Block,\n deploys: Vec,\n}\n\nstruct BlockHeadersBatch(Vec);\n")),(0,o.kt)("h2",{id:"finality-signatures"},"Finality Signatures"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"Payload::FinalitySignature")," variant is used when broadcasting finality signatures."),(0,o.kt)("p",null,"A node that is an active validator MUST create and broadcast, i.e. send to all connected peers, a finality signature for every valid block it receives or creates."),(0,o.kt)("h2",{id:"trie-chunking"},"Trie Chunking"),(0,o.kt)("p",null,"Large trie nodes are split when transferred across the network, according to ",(0,o.kt)("inlineCode",{parentName:"p"},"CHUNK_SIZE_BYTES"),", which is set to 8388608 bytes (8 megabytes). Any trie node that is less than 8388608 in size will be represented by a ",(0,o.kt)("inlineCode",{parentName:"p"},"TrieOrChunk::Trie")," instance."),(0,o.kt)("p",null,"Should a trie node be larger than this, a Merkle tree is constructed with ",(0,o.kt)("inlineCode",{parentName:"p"},"CHUNK_SIZE_BYTES")," sized chunks and is identified by the root hash of the resulting tree instead."),(0,o.kt)("p",null,"Peers MUST only request chunks. The ",(0,o.kt)("inlineCode",{parentName:"p"},"TrieOrChunkId")," type allows for requesting the n-th chunk of a given trie node. See the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-hashing"},"casper-hashing")," crate for details."),(0,o.kt)("p",null,"A node receiving a ",(0,o.kt)("inlineCode",{parentName:"p"},"TrieOrChunk")," item from a peer MUST validate it by checking the given Merkle proof against the item hash (which is the tree's root hash), before accepting it."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5870],{3905:function(e,n,t){t.d(n,{Zo:function(){return p},kt:function(){return m}});var a=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function r(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var l=a.createContext({}),d=function(e){var n=a.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},p=function(e){var n=d(e.components);return a.createElement(l.Provider,{value:n},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},h=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),c=d(t),h=i,m=c["".concat(l,".").concat(h)]||c[h]||u[h]||o;return t?a.createElement(m,r(r({ref:n},p),{},{components:t})):a.createElement(m,r({ref:n},p))}));function m(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var o=t.length,r=new Array(o);r[0]=h;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s[c]="string"==typeof e?e:i,r[1]=s;for(var d=2;dMessage Type",id:"the-message-type",level:2},{value:"Handshake Behavior",id:"handshake-behavior",level:2},{value:"Blocking Nodes",id:"blocking-nodes",level:2},{value:"The Payload Type",id:"the-payload-type",level:2},{value:"Consensus",id:"consensus",level:3},{value:"Gossiping",id:"gossiping",level:3},{value:"Unsafe-for-syncing",id:"unsafe-for-syncing",level:3},{value:"Gossiping",id:"gossiping-1",level:2},{value:"GetRequests",id:"getrequests",level:2},{value:"Finality Signatures",id:"finality-signatures",level:2},{value:"Trie Chunking",id:"trie-chunking",level:2}],u={toc:c},h="wrapper";function m(e){var n=e.components,t=(0,i.Z)(e,r);return(0,o.kt)(h,(0,a.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"casper-node-networking-protocol"},"Casper Node Networking Protocol"),(0,o.kt)("h2",{id:"casper-node-networking-protocol-mainnet-protocol-version-150"},"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)"),(0,o.kt)("p",null,"This is a description of the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node"),"'s networking protocol. This document follows the conventions laid out in ",(0,o.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc2119"},"RFC2119"),"."),(0,o.kt)("h2",{id:"connection-level"},"Connection Level"),(0,o.kt)("p",null,"Any ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," taking part in the Casper network SHOULD open connections to every other casper-node it is aware of and has not blocked. These connections are established using TLS, presenting a client certificate."),(0,o.kt)("h3",{id:"reciprocity-retries-and-data-direction"},"Reciprocity, retries and data direction"),(0,o.kt)("p",null,"A connection that was initiated by a node is considered an ",(0,o.kt)("em",{parentName:"p"},"outgoing")," connection by the node itself, but an ",(0,o.kt)("em",{parentName:"p"},"incoming")," connection by all other peers."),(0,o.kt)("p",null,"A node that created an outgoing connection SHOULD terminate the connection if it does not detect an incoming connection from the connected-to node within a short amount of time."),(0,o.kt)("p",null,"A node that receives an incoming connection MUST eventually establish an outgoing connection to the node."),(0,o.kt)("p",null,"A node SHOULD retry any failed outgoing connection periodically with exponential backoff. A node MUST NOT attempt to reconnect more than once per second."),(0,o.kt)("p",null,"Nodes MUST NOT send data through incoming connections, other than handshakes. Nodes MUST NOT accept any data coming through outgoing connections, other than handshakes."),(0,o.kt)("h3",{id:"tls-parameters"},"TLS parameters"),(0,o.kt)("p",null,"Any node creating a connection to a node MUST present a client certificate with the following properties:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Signature algorithm: ",(0,o.kt)("inlineCode",{parentName:"li"},"ECDSA_WITH_SHA512")),(0,o.kt)("li",{parentName:"ul"},"Subject name: Same as issuer name (self-signed certificate!)"),(0,o.kt)("li",{parentName:"ul"},"Serial number: 1"),(0,o.kt)("li",{parentName:"ul"},'Expiration ("not before"): Must be earlier than current time.'),(0,o.kt)("li",{parentName:"ul"},'Expiration ("not after"): Must be later than current time.'),(0,o.kt)("li",{parentName:"ul"},"Signature: Must be using ",(0,o.kt)("inlineCode",{parentName:"li"},"SECP521R1")," with ",(0,o.kt)("inlineCode",{parentName:"li"},"SHA512")," and valid.")),(0,o.kt)("p",null,"The SHA512 fingerprint of the ",(0,o.kt)("em",{parentName:"p"},"public key")," is considered the ",(0,o.kt)("strong",{parentName:"p"},"NodeID")," of the node."),(0,o.kt)("p",null,"Any node MUST immediately terminate a connection if it does not match the given parameters. The same certificate MUST be used as a server certificate for other clients connecting to this node."),(0,o.kt)("p",null,"An incoming connection with a valid TLS certificate SHOULD be accepted. As all certificates are self-signed, no further checking is done."),(0,o.kt)("h3",{id:"discovery"},"Discovery"),(0,o.kt)("p",null,"A node address is defined as an IPv4 address and a port. A node's address is the publicly reachable IP address and port that it is listening on for node-to-node-communication."),(0,o.kt)("p",null,"Every node SHOULD have one or more so-called ",(0,o.kt)("em",{parentName:"p"},"known node addresses")," of other nodes configured."),(0,o.kt)("p",null,"On start-up, a node SHOULD attempt to connect to all known nodes. A node SHOULD never forget a known node address."),(0,o.kt)("p",null,"Every node MUST periodically gossip its own node address to the network (see gossiping below)."),(0,o.kt)("p",null,"A node ",(0,o.kt)("em",{parentName:"p"},"learns")," new node addresses through receiving a gossiped node address, or being told of an address through the handshake."),(0,o.kt)("p",null,"Upon learning of a previously unknown node address, a node SHOULD attempt to connect to it."),(0,o.kt)("p",null,"After failing to connect to a node address, a node MAY forget it after a certain amount of retries, this process is called ",(0,o.kt)("em",{parentName:"p"},"forgetting")," a node. An address that has been forgotten will be considered new the next time it is learned."),(0,o.kt)("p",null,"A node MUST NOT forget the known addresses it was configured with initially."),(0,o.kt)("h2",{id:"framing"},"Framing"),(0,o.kt)("p",null,"To send a message to a peer across an established TLS connection, a node MUST send a message length header consisting of a 32 byte big endian integer with the message length first."),(0,o.kt)("p",null,"A node receiving a message length header that exceeds the maximum message size specified in the chainspec MUST immediately terminate the connection."),(0,o.kt)("h2",{id:"encoding"},"Encoding"),(0,o.kt)("p",null,"The node uses three encoding schemes: Handshakes (see below) are encoded using ",(0,o.kt)("a",{parentName:"p",href:"https://msgpack.org"},"MessagePack"),", while regular messages are encoded using ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/bincode"},"bincode"),". Many (but not all) data objects use ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/bytesrepr/index.html"},(0,o.kt)("inlineCode",{parentName:"a"},"bytesrepr"))," for serialization."),(0,o.kt)("p",null,"The node uses the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/rmp-serde/0.14.4/rmp_serde/index.html"},(0,o.kt)("inlineCode",{parentName:"a"},"rmp-serde"))," crate, version ",(0,o.kt)("inlineCode",{parentName:"p"},"0.14.4"),", which is kept fixed to ensure handshake compatibility with protocol version 1.0 of the node."),(0,o.kt)("p",null,"All nodes MUST use the following settings for ",(0,o.kt)("inlineCode",{parentName:"p"},"bincode")," encoding of network messages:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Byte limit: Unlimited"),(0,o.kt)("li",{parentName:"ul"},"Endianness: Little Endian"),(0,o.kt)("li",{parentName:"ul"},"Integer Encoding: Varint"),(0,o.kt)("li",{parentName:"ul"},"Trailing Bytes: Not allowed")),(0,o.kt)("p",null,"Any other use of ",(0,o.kt)("inlineCode",{parentName:"p"},"bincode")," encoding (e.g. for GetRequest payloads, see below) MUST use the following ",(0,o.kt)("inlineCode",{parentName:"p"},"bincode")," encoding settings:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Byte limit: Unlimited"),(0,o.kt)("li",{parentName:"ul"},"Endianness: Little Endian"),(0,o.kt)("li",{parentName:"ul"},"Integer Encoding: Fixint"),(0,o.kt)("li",{parentName:"ul"},"Trailing Bytes: Allowed")),(0,o.kt)("p",null,"Unless noted otherwise, any structure encoded as MessagePack or bincode is serialized using the standard ",(0,o.kt)("a",{parentName:"p",href:"https://serde.rs"},(0,o.kt)("inlineCode",{parentName:"a"},"serde")),"-derived encoding. For ",(0,o.kt)("inlineCode",{parentName:"p"},"bytesrepr")," serialization refer to the specific implementations in the ",(0,o.kt)("inlineCode",{parentName:"p"},"bytesrepr")," crate."),(0,o.kt)("p",null,"Any data types given from here on out are described using simplified ",(0,o.kt)("a",{parentName:"p",href:"https://www.rust-lang.org/"},"Rust")," structure definitions."),(0,o.kt)("h2",{id:"the-message-type"},"The ",(0,o.kt)("inlineCode",{parentName:"h2"},"Message")," Type"),(0,o.kt)("p",null,"The following data types make up the networking protocol:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"enum Message {\n Handshake {\n network_name: String,\n public_addr: SocketAddr,\n // default: 1.0\n protocol_version: ProtocolVersion,\n // default: `None`\n consensus_certificate: Option,\n // default: false\n is_syncing: bool,\n // default: `None`\n chainspec_hash: Option,\n },\n Payload(Payload),\n}\n\nstruct ConsensusCertificate {\n public_key: PublicKey,\n signature: Signature,\n}\n\nstruct Digest([u8; 32]);\n")),(0,o.kt)("p",null,"For ",(0,o.kt)("a",{parentName:"p",href:"https://doc.rust-lang.org/std/string/struct.String.html"},(0,o.kt)("inlineCode",{parentName:"a"},"String")),", ",(0,o.kt)("a",{parentName:"p",href:"https://doc.rust-lang.org/std/net/enum.SocketAddr.html"},(0,o.kt)("inlineCode",{parentName:"a"},"SocketAddr")),", ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/struct.ProtocolVersion.html"},(0,o.kt)("inlineCode",{parentName:"a"},"ProtocolVersion")),", ",(0,o.kt)("a",{parentName:"p",href:"https://doc.rust-lang.org/std/option/enum.Option.html"},(0,o.kt)("inlineCode",{parentName:"a"},"Option")),", ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/crypto/enum.PublicKey.html"},(0,o.kt)("inlineCode",{parentName:"a"},"PublicKey")),", ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/crypto/enum.Signature.html"},(0,o.kt)("inlineCode",{parentName:"a"},"Signature"))," see the respective docs and details below."),(0,o.kt)("h2",{id:"handshake-behavior"},"Handshake Behavior"),(0,o.kt)("p",null,"A node establishing a new connection MUST immediately send a handshake through said connection to the peer, regardless of whether an incoming or outgoing connection was established (this is an exception to the restriction of only sending data through outgoing connections)."),(0,o.kt)("p",null,"A handshake MUST be encoded using the ",(0,o.kt)("inlineCode",{parentName:"p"},"Message::Handshake")," structure. A node running version 1.5 SHOULD NOT omit any of the fields for which default values are available (",(0,o.kt)("inlineCode",{parentName:"p"},"protocol_version"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"consensus_certificate"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"is_syncing"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"chainspec_hash"),"). A node MUST accept any handshake that omits one or more of these fields and fill them with defaults."),(0,o.kt)("p",null,"After receiving a handshake, a node MUST compare the ",(0,o.kt)("inlineCode",{parentName:"p"},"network_name"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"protocol_version")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"chainspec_hash")," fields against its own configuration: If any of these do not match, it MUST disconnect from the node and SHOULD block it."),(0,o.kt)("p",null,"A node MUST mark any peer that connects to it (thus is an incoming connection from the perspective of the node) with a value of ",(0,o.kt)("inlineCode",{parentName:"p"},"is_syncing")," set to ",(0,o.kt)("inlineCode",{parentName:"p"},"true"),' as "syncing" and MUST NOT allow any of its own messages that are marked unsafe-for-syncing to be sent to that node, by silently dropping them instead.'),(0,o.kt)("p",null,"A node MAY compare peers that provide a ",(0,o.kt)("inlineCode",{parentName:"p"},"consensus_certificate")," to the currently active set of validators and mark it as an active validator to give it preferential treatment when outgoing bandwidth is limited."),(0,o.kt)("p",null,"Upon handshake completion, the node SHOULD learn the provided ",(0,o.kt)("inlineCode",{parentName:"p"},"public_addr"),"."),(0,o.kt)("h2",{id:"blocking-nodes"},"Blocking Nodes"),(0,o.kt)("p",null,"If a node blocks a peer, it MUST sever all incoming and outgoing connections to said node. It MUST take note of the NodeId of the node, marking it as blocked and MUST not allow any new connection to proceed past the handshake."),(0,o.kt)("p",null,"A node MUST NOT block peers based on IP address or port. Nodes MUST NOT block peers for more than an hour."),(0,o.kt)("p",null,"After a block on a node is expired, the node SHOULD ",(0,o.kt)("em",{parentName:"p"},"forget")," the nodes IP address, allowing a later ",(0,o.kt)("em",{parentName:"p"},"learning")," of said address again."),(0,o.kt)("h2",{id:"the-payload-type"},"The ",(0,o.kt)("inlineCode",{parentName:"h2"},"Payload")," Type"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"Payload")," (found in the node sources as ",(0,o.kt)("inlineCode",{parentName:"p"},"Message")," in ",(0,o.kt)("inlineCode",{parentName:"p"},"payload.rs"),") contains variants for all node-to-node communicating subsystems of a running node, which are described below. Note that some of the variants have been renamed for clarity in this specification. Since field names are not used in ",(0,o.kt)("inlineCode",{parentName:"p"},"bincode")," encoding, this should have no effect on implementations."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"enum Payload {\n Consensus(ConsensusMessage),\n DeployGossiper(DeployGossiperMessage),\n AddressGossiper(AddressGossiperMessage),\n GetRequest {\n tag: Tag,\n serialized_id: Vec,\n },\n GetResponse {\n tag: Tag,\n serialized_item: Vec<[u8]>,\n },\n FinalitySignature(FinalitySignature),\n}\n\nenum DeployGossiperMessage {\n Gossip(DeployHash),\n GossipResponse {\n item_id: DeployHash,\n is_already_held: bool,\n },\n}\n\nenum AddressGossiperMessage {\n Gossip(GossippedAddress),\n GossipResponse {\n item_id: GossippedAddress,\n is_already_held: bool,\n },\n}\n\nstruct DeployHash(Digest);\nstruct GossipedAddress(SocketAddr);\n")),(0,o.kt)("h3",{id:"consensus"},"Consensus"),(0,o.kt)("p",null,"A consensus message is sent exclusively between instances of the consensus component, from one peer to another. A precise description of the Highway consensus protocol is out of scope of this document, see the ",(0,o.kt)("inlineCode",{parentName:"p"},"consensus::Message")," type or an appropriate description of the underlying protocol for details."),(0,o.kt)("h3",{id:"gossiping"},"Gossiping"),(0,o.kt)("p",null,"Gossiping messages are sent by a node to a subset of its peers to announce the availability of new data items. Peers MUST be distinguished by NodeID, not by listening address."),(0,o.kt)("p",null,"A node must support a gossiper for deploys and one for ",(0,o.kt)("inlineCode",{parentName:"p"},"GossippedAddress"),", which is an alias for the regular Rust standard library's ",(0,o.kt)("inlineCode",{parentName:"p"},"SocketAddr"),"."),(0,o.kt)("p",null,"A node SHOULD begin a gossiping process for all deploys previously unknown to it. A node MUST periodically send an ",(0,o.kt)("inlineCode",{parentName:"p"},"AddressGossiperMessage::Gossip")," message to a random subset selected in a similar manner as the one for deploy gossip to make its own address known, see the gossiping process section below for details."),(0,o.kt)("h3",{id:"unsafe-for-syncing"},"Unsafe-for-syncing"),(0,o.kt)("p",null,"A node that is syncing MUST indicate this by setting ",(0,o.kt)("inlineCode",{parentName:"p"},"is_syncing")," to ",(0,o.kt)("inlineCode",{parentName:"p"},"true"),"."),(0,o.kt)("p",null,"A node MAY implement a scheme for request throttling/backpressure for GetRequests (see below) of ",(0,o.kt)("inlineCode",{parentName:"p"},"TrieNode"),"s that can cause issues with peers that are also sending GetRequests."),(0,o.kt)("p",null,"A node that succeeds in a handshake with a peer that has set ",(0,o.kt)("inlineCode",{parentName:"p"},"is_syncing")," MUST make note of this flag. If the node itself is implementing the feature described above, it MUST NOT make any GetRequests directed at this peer for ",(0,o.kt)("inlineCode",{parentName:"p"},"TrieNode"),"s."),(0,o.kt)("h2",{id:"gossiping-1"},"Gossiping"),(0,o.kt)("p",null,"Gossiping is distributing items across the network by sending it to a subset of known peers that do not have the item already, and having them repeat this process until a certain degree of saturation is observed."),(0,o.kt)("p",null,"Any item has an associated ID type which denotes what is used to uniquely identify it when gossiping. If an item is small enough, the ID may just be the item itself."),(0,o.kt)("p",null,"Gossiper messages have the following structure:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"enum GossiperMessage {\n Gossip(Id),\n GossipResponse {\n item_id: Id,\n is_already_held: bool,\n },\n}\n")),(0,o.kt)("p",null,"To gossip, a node MAY send a ",(0,o.kt)("inlineCode",{parentName:"p"},"GossiperMessage::Gossip")," message to a random subset of configurable size of peers to announce that it has received and validated a new item. Any peer receiving such a message SHOULD answer with a ",(0,o.kt)("inlineCode",{parentName:"p"},"GossiperMessage:GossipResponse"),", citing the given id and using ",(0,o.kt)("inlineCode",{parentName:"p"},"is_already_held")," to indicate whether it already possessed the given item."),(0,o.kt)("p",null,"The node SHOULD attempt to continue to find peers with a negative response, up to a configurable limit of attempts and/or success rate, or until running out of valid peers."),(0,o.kt)("p",null,"The node that initiated the gossip MUST keep track of which peer replied with a positive (",(0,o.kt)("inlineCode",{parentName:"p"},"is_already_held")," being ",(0,o.kt)("inlineCode",{parentName:"p"},"true"),") response and MUST NOT send another ",(0,o.kt)("inlineCode",{parentName:"p"},"Gossip")," message for same ID to any of these peers during this gossip process. However, it MAY restart gossiping the same item at a later time, considering these peers again."),(0,o.kt)("p",null,"If a node receives a negative ",(0,o.kt)("inlineCode",{parentName:"p"},"GossiperMessage::GossipResponse")," (i.e. ",(0,o.kt)("inlineCode",{parentName:"p"},"is_already_held")," being ",(0,o.kt)("inlineCode",{parentName:"p"},"false"),"), and the item's ID is not the item itself, it MUST handle that repsponse as if the peer had sent a ",(0,o.kt)("inlineCode",{parentName:"p"},"GetRequest")," for the item (see GetRequests section below)."),(0,o.kt)("h2",{id:"getrequests"},"GetRequests"),(0,o.kt)("p",null,'The "GetRequests" mechanism allows retrieving various items through primary or derived keys from peers.'),(0,o.kt)("p",null,"A peer MAY send a ",(0,o.kt)("inlineCode",{parentName:"p"},"GetRequest")," (see ",(0,o.kt)("inlineCode",{parentName:"p"},"Payload::GetRequest"),") with a ",(0,o.kt)("inlineCode",{parentName:"p"},"Tag")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"serialized_id")," payload. Both ",(0,o.kt)("inlineCode",{parentName:"p"},"serialized_id")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"serialized_item")," MUST be encoded using ",(0,o.kt)("inlineCode",{parentName:"p"},"bincode"),' (see "Encoding" section for details).'),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"pub enum Tag {\n Deploy,\n FinalizedApprovals,\n Block,\n GossipedAddress,\n BlockAndMetadataByHeight,\n BlockHeaderByHash,\n BlockHeaderAndFinalitySignaturesByHeight,\n TrieOrChunk,\n BlockAndDeploysByHash,\n BlockHeaderBatch,\n FinalitySignaturesByHash,\n}\n")),(0,o.kt)("p",null,"The tag dictates which item is being retrieved, and which key (ID type) is being used."),(0,o.kt)("p",null,"A node that receives a ",(0,o.kt)("inlineCode",{parentName:"p"},"GetRequest")," from a peer SHOULD return a ",(0,o.kt)("inlineCode",{parentName:"p"},"GetResponse")," (see ",(0,o.kt)("inlineCode",{parentName:"p"},"Payload::GetResponse"),"). The ",(0,o.kt)("inlineCode",{parentName:"p"},"GetResponse")," MUST use the same ",(0,o.kt)("inlineCode",{parentName:"p"},"Tag"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"pub enum FetchedOrNotFound {\n Fetched(T),\n NotFound(Id),\n}\n")),(0,o.kt)("p",null,"If the item was found, ",(0,o.kt)("inlineCode",{parentName:"p"},"serialized_item")," MUST contain a serialized ",(0,o.kt)("inlineCode",{parentName:"p"},"FetchedOrNotFound::Fetched")," instance, with the inner value ",(0,o.kt)("inlineCode",{parentName:"p"},"T")," being the item."),(0,o.kt)("p",null,"If the item was not found, ",(0,o.kt)("inlineCode",{parentName:"p"},"serialized_item")," MUST contain a ",(0,o.kt)("inlineCode",{parentName:"p"},"FetchedOrNotFound::NotFound")," instance, with the inner value ",(0,o.kt)("inlineCode",{parentName:"p"},"Id")," being the ID found in the originating ",(0,o.kt)("inlineCode",{parentName:"p"},"GetRequest"),"."),(0,o.kt)("p",null,"A node MUST not send any items to a peer that it itself has not verified."),(0,o.kt)("p",null,"The following table shows which tag corresponds to which ID and item type. Type definitions for ",(0,o.kt)("inlineCode",{parentName:"p"},"DeployHash")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"GossippedAddress")," can be found earlier in this document, other types are described following this section. Further details of many of these types can be found in the ",(0,o.kt)("a",{parentName:"p",href:"/concepts/serialization-standard"},"Serialization Standard"),", but be aware that those docs describe serializing using bytesrepr rather than bincode."),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Tag"),(0,o.kt)("th",{parentName:"tr",align:null},"ID type"),(0,o.kt)("th",{parentName:"tr",align:null},"Payload (item) type"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"Deploy"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"DeployHash")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"Deploy"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"FinalizedApprovals"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"DeployHash")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"FinalizedApprovalsWithId"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"Block"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHash")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"Block"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"GossipedAddress"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"GossipedAddress")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"GossipedAddress"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"BlockAndMetadataByHeight"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"u64")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockWithMetadata"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"BlockHeaderByHash"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHash")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHeader"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"BlockHeaderAndFinalitySignaturesByHeight"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"u64")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHeaderWithMetadata"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"TrieOrChunk"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"TrieOrChunkId")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"TrieOrChunk"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"BlockAndDeploysByHash"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHash")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockAndDeploys"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"BlockHeaderBatch"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHeadersBatchId")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHeadersBatch"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"FinalitySignaturesByHash"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockHash")),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"BlockSignatures"))))),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"pub struct Deploy {\n hash: DeployHash,\n header: DeployHeader,\n payment: ExecutableDeployItem,\n session: ExecutableDeployItem,\n approvals: BTreeSet,\n}\n\nstruct DeployHeader {\n account: PublicKey,\n timestamp: u64,\n ttl: u64,\n gas_price: u64,\n body_hash: Digest,\n dependencies: Vec,\n chain_name: String,\n}\n\nenum PublicKey {\n System,\n Ed25519(Vec),\n Secp256k1(Vec),\n}\n\nenum ExecutableDeployItem {\n ModuleBytes {\n module_bytes: Vec,\n args: RuntimeArgs,\n },\n StoredContractByHash {\n hash: [u8; 32],\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredContractByName {\n name: String,\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredVersionedContractByHash {\n hash: [u8; 32],\n version: Option,\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredVersionedContractByName {\n name: String,\n version: Option,\n entry_point: String,\n args: RuntimeArgs,\n },\n Transfer { args: RuntimeArgs },\n}\n\nstruct RuntimeArgs(Vec);\n\nstruct NamedArg(String, CLValue);\n\nstruct CLValue(CLType, Vec);\n\nenum CLType {\n Bool,\n I32,\n I64,\n U8,\n U32,\n U64,\n U128,\n U256,\n U512,\n Unit,\n String,\n Key,\n URef,\n PublicKey,\n Option(Box),\n List(Box),\n ByteArray(u32),\n Result { ok: Box, err: Box },\n Map { key: Box, value: Box },\n Tuple1([Box; 1]),\n Tuple2([Box; 2]),\n Tuple3([Box; 3]),\n Any,\n}\n\nstruct Approval {\n signer: PublicKey,\n signature: Signature,\n}\n\nenum Signature {\n System,\n Ed25519(Vec),\n Secp256k1(Vec),\n}\n\nstruct FinalizedApprovalsWithId {\n id: DeployHash,\n approvals: FinalizedApprovals,\n}\n\nstruct FinalizedApprovals(BTreeSet);\n\nstruct Block {\n hash: BlockHash,\n header: BlockHeader,\n body: BlockBody,\n}\n\nstruct BlockHash(Digest);\n\nstruct BlockHeader {\n parent_hash: BlockHash,\n state_root_hash: Digest,\n body_hash: Digest,\n random_bit: bool,\n accumulated_seed: Digest,\n era_end: Option,\n timestamp: u64,\n era_id: u64,\n height: u64,\n protocol_version: ProtocolVersion,\n}\n\nstruct EraEnd {\n era_report: EraReport,\n next_era_validator_weights: BTreeMap,\n}\n\nstruct EraReport {\n equivocators: Vec,\n rewards: BTreeMap,\n inactive_validators: Vec,\n}\n\nstruct ProtocolVersion {\n major: u32,\n minor: u32,\n patch: u32,\n}\n\nstruct BlockBody {\n proposer: PublicKey,\n deploy_hashes: Vec,\n transfer_hashes: Vec,\n}\n")),(0,o.kt)("p",null,"Custom variable length encoding is used when serializing ",(0,o.kt)("inlineCode",{parentName:"p"},"U512"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"U256")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"U128")," types. They are encoded in a way equivalent to encoding the following pseudo struct:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"struct Bigint {\n serialized_length: u8,\n little_endian_unpadded_bytes: [u8, serialized_length - 1],\n}\n")),(0,o.kt)("p",null,"In other words, the following steps are taken:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"convert the bigint to an array of bytes in little-endian form"),(0,o.kt)("li",{parentName:"ul"},"strip the contiguous range of irrelevant padding ",(0,o.kt)("inlineCode",{parentName:"li"},"0")," bytes from the right hand end, if any"),(0,o.kt)("li",{parentName:"ul"},"prefix this remaining array with a byte holding the number of remaining bytes + 1, to indicate the length of the final byte array including the length byte itself")),(0,o.kt)("p",null,"For a description explaining the use of ",(0,o.kt)("inlineCode",{parentName:"p"},"TrieOrChunk"),' and related types, see the "Trie chunking" section. The relevant types are:'),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"struct TrieOrChunkId(u64, Digest);\n\nenum TrieOrChunk {\n Trie(Bytes),\n ChunkWithProof(ChunkWithProof),\n}\n\nstruct ChunkWithProof {\n proof: IndexedMerkleProof,\n chunk: Bytes,\n}\n\nstruct IndexedMerkleProof {\n index: u64,\n count: u64,\n merkle_proof: Vec,\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"BlockHeadersBatchId")," is used to request multiple ",(0,o.kt)("inlineCode",{parentName:"p"},"BlockHeader"),"s with a single request."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"struct BlockHeadersBatchId {\n highest: u64,\n lowest: u64,\n}\n\nstruct BlockWithMetadata {\n block: Block,\n finality_signatures: BlockSignatures,\n}\n\nstruct BlockHeaderWithMetadata {\n block_header: BlockHeader,\n block_signatures: BlockSignatures,\n}\n\nstruct BlockSignatures {\n block_hash: BlockHash,\n era_id: u64,\n proofs: BTreeMap,\n}\n\nstruct BlockAndDeploys {\n block: Block,\n deploys: Vec,\n}\n\nstruct BlockHeadersBatch(Vec);\n")),(0,o.kt)("h2",{id:"finality-signatures"},"Finality Signatures"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"Payload::FinalitySignature")," variant is used when broadcasting finality signatures."),(0,o.kt)("p",null,"A node that is an active validator MUST create and broadcast, i.e. send to all connected peers, a finality signature for every valid block it receives or creates."),(0,o.kt)("h2",{id:"trie-chunking"},"Trie Chunking"),(0,o.kt)("p",null,"Large trie nodes are split when transferred across the network, according to ",(0,o.kt)("inlineCode",{parentName:"p"},"CHUNK_SIZE_BYTES"),", which is set to 8388608 bytes (8 megabytes). Any trie node that is less than 8388608 in size will be represented by a ",(0,o.kt)("inlineCode",{parentName:"p"},"TrieOrChunk::Trie")," instance."),(0,o.kt)("p",null,"Should a trie node be larger than this, a Merkle tree is constructed with ",(0,o.kt)("inlineCode",{parentName:"p"},"CHUNK_SIZE_BYTES")," sized chunks and is identified by the root hash of the resulting tree instead."),(0,o.kt)("p",null,"Peers MUST only request chunks. The ",(0,o.kt)("inlineCode",{parentName:"p"},"TrieOrChunkId")," type allows for requesting the n-th chunk of a given trie node. See the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-hashing"},"casper-hashing")," crate for details."),(0,o.kt)("p",null,"A node receiving a ",(0,o.kt)("inlineCode",{parentName:"p"},"TrieOrChunk")," item from a peer MUST validate it by checking the given Merkle proof against the item hash (which is the tree's root hash), before accepting it."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1c7bd663.d78af67e.js b/assets/js/1c7bd663.23cac1af.js similarity index 98% rename from assets/js/1c7bd663.d78af67e.js rename to assets/js/1c7bd663.23cac1af.js index 1b357bbdb7..759b9425f7 100644 --- a/assets/js/1c7bd663.d78af67e.js +++ b/assets/js/1c7bd663.23cac1af.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3549],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return f}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var o=a.createContext({}),c=function(e){var t=a.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(o.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,o=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(n),h=r,f=d["".concat(o,".").concat(h)]||d[h]||u[h]||s;return n?a.createElement(f,i(i({ref:t},p),{},{components:n})):a.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,i=new Array(s);i[0]=h;var l={};for(var o in t)hasOwnProperty.call(t,o)&&(l[o]=t[o]);l.originalType=e,l[d]="string"==typeof e?e:r,i[1]=l;for(var c=2;c=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var o=a.createContext({}),c=function(e){var t=a.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(o.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,o=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(n),h=r,f=d["".concat(o,".").concat(h)]||d[h]||u[h]||s;return n?a.createElement(f,i(i({ref:t},p),{},{components:n})):a.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,i=new Array(s);i[0]=h;var l={};for(var o in t)hasOwnProperty.call(t,o)&&(l[o]=t[o]);l.originalType=e,l[d]="string"==typeof e?e:r,i[1]=l;for(var c=2;c=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(r),m=a,y=u["".concat(p,".").concat(m)]||u[m]||f[m]||o;return r?n.createElement(y,s(s({ref:t},i),{},{components:r})):n.createElement(y,s({ref:t},i))}));function y(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=m;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(r),m=a,y=u["".concat(p,".").concat(m)]||u[m]||f[m]||o;return r?n.createElement(y,s(s({ref:t},i),{},{components:r})):n.createElement(y,s({ref:t},i))}));function y(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=m;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),u=p(n),m=i,h=u["".concat(s,".").concat(m)]||u[m]||d[m]||r;return n?a.createElement(h,l(l({ref:t},c),{},{components:n})):a.createElement(h,l({ref:t},c))}));function h(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,l=new Array(r);l[0]=m;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[u]="string"==typeof e?e:i,l[1]=o;for(var p=2;p=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),u=p(n),m=i,h=u["".concat(s,".").concat(m)]||u[m]||d[m]||r;return n?a.createElement(h,l(l({ref:t},c),{},{components:n})):a.createElement(h,l({ref:t},c))}));function h(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,l=new Array(r);l[0]=m;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[u]="string"==typeof e?e:i,l[1]=o;for(var p=2;p=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},d="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,l=p(e,["components","mdxType","originalType","parentName"]),d=u(r),m=a,f=d["".concat(s,".").concat(m)]||d[m]||c[m]||o;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[d]="string"==typeof e?e:a,i[1]=p;for(var u=2;u=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},d="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,l=p(e,["components","mdxType","originalType","parentName"]),d=u(r),m=a,f=d["".concat(s,".").concat(m)]||d[m]||c[m]||o;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[d]="string"==typeof e?e:a,i[1]=p;for(var u=2;u=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=l(n),h=a,y=p["".concat(c,".").concat(h)]||p[h]||u[h]||o;return n?r.createElement(y,i(i({ref:t},d),{},{components:n})):r.createElement(y,i({ref:t},d))}));function y(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:a,i[1]=s;for(var l=2;l=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=l(n),h=a,y=p["".concat(c,".").concat(h)]||p[h]||u[h]||o;return n?r.createElement(y,i(i({ref:t},d),{},{components:n})):r.createElement(y,i({ref:t},d))}));function y(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:a,i[1]=s;for(var l=2;l=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var r=o.createContext({}),p=function(e){var t=o.useContext(r),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return o.createElement(r.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,r=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),h=a,y=d["".concat(r,".").concat(h)]||d[h]||u[h]||i;return n?o.createElement(y,l(l({ref:t},c),{},{components:n})):o.createElement(y,l({ref:t},c))}));function y(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,l=new Array(i);l[0]=h;var s={};for(var r in t)hasOwnProperty.call(t,r)&&(s[r]=t[r]);s.originalType=e,s[d]="string"==typeof e?e:a,l[1]=s;for(var p=2;p=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var r=o.createContext({}),p=function(e){var t=o.useContext(r),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return o.createElement(r.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,r=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),h=a,y=d["".concat(r,".").concat(h)]||d[h]||u[h]||i;return n?o.createElement(y,l(l({ref:t},c),{},{components:n})):o.createElement(y,l({ref:t},c))}));function y(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,l=new Array(i);l[0]=h;var s={};for(var r in t)hasOwnProperty.call(t,r)&&(s[r]=t[r]);s.originalType=e,s[d]="string"==typeof e?e:a,l[1]=s;for(var p=2;p=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(r),y=a,m=f["".concat(p,".").concat(y)]||f[y]||i[y]||o;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[f]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(r),y=a,m=f["".concat(p,".").concat(y)]||f[y]||i[y]||o;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[f]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(a),h=r,f=p["".concat(l,".").concat(h)]||p[h]||d[h]||o;return a?n.createElement(f,i(i({ref:t},u),{},{components:a})):n.createElement(f,i({ref:t},u))}));function f(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;c=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(a),h=r,f=p["".concat(l,".").concat(h)]||p[h]||d[h]||o;return a?n.createElement(f,i(i({ref:t},u),{},{components:a})):n.createElement(f,i({ref:t},u))}));function f(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;c=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),c=p(n),m=r,h=c["".concat(l,".").concat(m)]||c[m]||u[m]||o;return n?a.createElement(h,i(i({ref:t},d),{},{components:n})):a.createElement(h,i({ref:t},d))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:r,i[1]=s;for(var p=2;p [path_to]/file.tar.zst\n")),(0,o.kt)("h3",{id:"compression-level"},"Compression level"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"-[level]")," argument is the compression level from 1 to 19 (and 20-22 with expansion). In testing, we found 15 to be the sweet spot in compression time vs. size. We recommend lower compression if you plan to transfer the archive only once. If you are creating an archive to be downloaded by many, then the extra time for higher compression may be helpful."),(0,o.kt)("p",null,"Here are some examples of a Mainnet DB compression at block 741160:"),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Level"),(0,o.kt)("th",{parentName:"tr",align:null},"Time (min:sec)"),(0,o.kt)("th",{parentName:"tr",align:null},"Size"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"12"),(0,o.kt)("td",{parentName:"tr",align:null},"29:20"),(0,o.kt)("td",{parentName:"tr",align:null},"15.8 GB")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"15"),(0,o.kt)("td",{parentName:"tr",align:null},"46:15"),(0,o.kt)("td",{parentName:"tr",align:null},"13.0 GB")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"17"),(0,o.kt)("td",{parentName:"tr",align:null},"87:42"),(0,o.kt)("td",{parentName:"tr",align:null},"13.0 GB")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"19"),(0,o.kt)("td",{parentName:"tr",align:null},"197:08"),(0,o.kt)("td",{parentName:"tr",align:null},"12.9 GB")))),(0,o.kt)("p",null,"For local backups, using 1-5 is a great compression speed-to-size trade-off."),(0,o.kt)("h3",{id:"thread-count"},"Thread count"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"-T[thread count]")," is the number of threads that ",(0,o.kt)("inlineCode",{parentName:"p"},"zstd")," should use for compression. If running a script or command on varying machines, use ",(0,o.kt)("inlineCode",{parentName:"p"},"T0")," to allow ",(0,o.kt)("inlineCode",{parentName:"p"},"zstd")," to detect the number of cores and run with the same number of threads as the detected cores. A speed-up can be obtained for machines with multiple threads per core by configuring a thread count near the number of threads. It is advisable to stay within the number of CPU threads. The recommendations in this article will use ",(0,o.kt)("inlineCode",{parentName:"p"},"-T0"),"."),(0,o.kt)("h3",{id:"long-distance-matching"},"Long-distance matching"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"--long=31")," argument is where we see the most space gained by the algorithm because it controls the size of the matching window in powers of 2 (2","*","*","31 is 2 GB). The downside is that it requires 2.0 GB memory during compression and decompression as it looks and rebuilds ahead. The default is 27 or 128 MB."),(0,o.kt)("p",null,"At compression 19, we see a 30 GB file using the default 128 MB look ahead, and a 13 GB file using 2 GB look ahead. Since all validators should have 16-32 GB of memory, we keep this at ",(0,o.kt)("inlineCode",{parentName:"p"},"--long=31"),"."),(0,o.kt)("p",null,"An important note is that decompression requires a compatible argument. Trying with a different long-distance matching value will result in an error. However, it will also return the necessary value to provide."),(0,o.kt)("h3",{id:"summary-of-commands"},"Summary of commands"),(0,o.kt)("p",null,"The general command for compression is:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"tar -b 4096 -cv --sparse . | zstd -15 -cv -T0 --long=31 > [path_to]/file.tar.zst\n")),(0,o.kt)("p",null,"For local backups, use a lower compression level:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"tar -b 4096 -cv --sparse . | zstd -5 -cv -T0 --long=31 > [path_to]/file.tar.zst\n")),(0,o.kt)("h2",{id:"decompression"},"Decompression"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"zstd -d")," is the command for decompression; however, the same ",(0,o.kt)("inlineCode",{parentName:"p"},"--long")," value used for compression must be specified. For all ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," DB-related decompression, you will likely use this command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"zstd -cd --long=31 <.tar.zst file>\n")),(0,o.kt)("p",null,"If ",(0,o.kt)("inlineCode",{parentName:"p"},"--long=31")," is omitted, you might see an error such as this, which also gives you the solution:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"./casper.tar.zst : Decoding error (36) : Frame requires too much memory for decoding\n./casper.tar.zst : Window size larger than maximum : 2147483648 > 134217728\n./casper.tar.zst : Use --long=31 or --memory=2048MB\n")),(0,o.kt)("p",null,"You can then use the ",(0,o.kt)("inlineCode",{parentName:"p"},"zstd")," result to populate a ",(0,o.kt)("inlineCode",{parentName:"p"},"tar -xv")," command. Also, create the decompressed files using ",(0,o.kt)("inlineCode",{parentName:"p"},"sudo -u casper"),", because the files will be used by the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node"),". Run the following command inside an empty DB location:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"zstd -cd --long=31 <.tar.zst file> | sudo -u casper tar -xv\n")),(0,o.kt)("p",null,"To fix ownership, use this command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo /etc/casper/node_util.py fix_permissions\n")),(0,o.kt)("h2",{id:"streamed-decompression"},"Streamed Decompression"),(0,o.kt)("p",null,"If a ",(0,o.kt)("inlineCode",{parentName:"p"},".tar.zst")," archive is hosted on a website and you will not need the file after decompressing, you can stream it into the process using ",(0,o.kt)("inlineCode",{parentName:"p"},"curl"),", which can output to stdout with ",(0,o.kt)("inlineCode",{parentName:"p"},"--output")," and stream binary to your terminal."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s --output - \n")),(0,o.kt)("p",null,"If you use the output along with the previous process, you can decompress the files from ",(0,o.kt)("inlineCode",{parentName:"p"},"curl")," directly into a local directory:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s --output - | zstd -d --long=31 | sudo -u casper tar -xv\n")),(0,o.kt)("h2",{id:"starting-a-new-node-with-a-decompressed-db"},"Starting a New Node with a Decompressed DB"),(0,o.kt)("p",null,"If you are starting a node with a decompressed DB, you must tell the node to run at the protocol version of the tip of your DB. You can do this most efficiently with the ",(0,o.kt)("inlineCode",{parentName:"p"},"node_util.py")," script included in the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," installation."),(0,o.kt)("p",null,"For example, if you are using a DB archive from node version 1.4.5, you would run this command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo /etc/casper/node_util.py force_run_version 1_4_5\n")))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6717],{3905:function(e,t,n){n.d(t,{Zo:function(){return d},kt:function(){return h}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),c=p(n),m=r,h=c["".concat(l,".").concat(m)]||c[m]||u[m]||o;return n?a.createElement(h,i(i({ref:t},d),{},{components:n})):a.createElement(h,i({ref:t},d))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:r,i[1]=s;for(var p=2;p [path_to]/file.tar.zst\n")),(0,o.kt)("h3",{id:"compression-level"},"Compression level"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"-[level]")," argument is the compression level from 1 to 19 (and 20-22 with expansion). In testing, we found 15 to be the sweet spot in compression time vs. size. We recommend lower compression if you plan to transfer the archive only once. If you are creating an archive to be downloaded by many, then the extra time for higher compression may be helpful."),(0,o.kt)("p",null,"Here are some examples of a Mainnet DB compression at block 741160:"),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Level"),(0,o.kt)("th",{parentName:"tr",align:null},"Time (min:sec)"),(0,o.kt)("th",{parentName:"tr",align:null},"Size"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"12"),(0,o.kt)("td",{parentName:"tr",align:null},"29:20"),(0,o.kt)("td",{parentName:"tr",align:null},"15.8 GB")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"15"),(0,o.kt)("td",{parentName:"tr",align:null},"46:15"),(0,o.kt)("td",{parentName:"tr",align:null},"13.0 GB")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"17"),(0,o.kt)("td",{parentName:"tr",align:null},"87:42"),(0,o.kt)("td",{parentName:"tr",align:null},"13.0 GB")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"19"),(0,o.kt)("td",{parentName:"tr",align:null},"197:08"),(0,o.kt)("td",{parentName:"tr",align:null},"12.9 GB")))),(0,o.kt)("p",null,"For local backups, using 1-5 is a great compression speed-to-size trade-off."),(0,o.kt)("h3",{id:"thread-count"},"Thread count"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"-T[thread count]")," is the number of threads that ",(0,o.kt)("inlineCode",{parentName:"p"},"zstd")," should use for compression. If running a script or command on varying machines, use ",(0,o.kt)("inlineCode",{parentName:"p"},"T0")," to allow ",(0,o.kt)("inlineCode",{parentName:"p"},"zstd")," to detect the number of cores and run with the same number of threads as the detected cores. A speed-up can be obtained for machines with multiple threads per core by configuring a thread count near the number of threads. It is advisable to stay within the number of CPU threads. The recommendations in this article will use ",(0,o.kt)("inlineCode",{parentName:"p"},"-T0"),"."),(0,o.kt)("h3",{id:"long-distance-matching"},"Long-distance matching"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"--long=31")," argument is where we see the most space gained by the algorithm because it controls the size of the matching window in powers of 2 (2","*","*","31 is 2 GB). The downside is that it requires 2.0 GB memory during compression and decompression as it looks and rebuilds ahead. The default is 27 or 128 MB."),(0,o.kt)("p",null,"At compression 19, we see a 30 GB file using the default 128 MB look ahead, and a 13 GB file using 2 GB look ahead. Since all validators should have 16-32 GB of memory, we keep this at ",(0,o.kt)("inlineCode",{parentName:"p"},"--long=31"),"."),(0,o.kt)("p",null,"An important note is that decompression requires a compatible argument. Trying with a different long-distance matching value will result in an error. However, it will also return the necessary value to provide."),(0,o.kt)("h3",{id:"summary-of-commands"},"Summary of commands"),(0,o.kt)("p",null,"The general command for compression is:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"tar -b 4096 -cv --sparse . | zstd -15 -cv -T0 --long=31 > [path_to]/file.tar.zst\n")),(0,o.kt)("p",null,"For local backups, use a lower compression level:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"tar -b 4096 -cv --sparse . | zstd -5 -cv -T0 --long=31 > [path_to]/file.tar.zst\n")),(0,o.kt)("h2",{id:"decompression"},"Decompression"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"zstd -d")," is the command for decompression; however, the same ",(0,o.kt)("inlineCode",{parentName:"p"},"--long")," value used for compression must be specified. For all ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," DB-related decompression, you will likely use this command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"zstd -cd --long=31 <.tar.zst file>\n")),(0,o.kt)("p",null,"If ",(0,o.kt)("inlineCode",{parentName:"p"},"--long=31")," is omitted, you might see an error such as this, which also gives you the solution:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"./casper.tar.zst : Decoding error (36) : Frame requires too much memory for decoding\n./casper.tar.zst : Window size larger than maximum : 2147483648 > 134217728\n./casper.tar.zst : Use --long=31 or --memory=2048MB\n")),(0,o.kt)("p",null,"You can then use the ",(0,o.kt)("inlineCode",{parentName:"p"},"zstd")," result to populate a ",(0,o.kt)("inlineCode",{parentName:"p"},"tar -xv")," command. Also, create the decompressed files using ",(0,o.kt)("inlineCode",{parentName:"p"},"sudo -u casper"),", because the files will be used by the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node"),". Run the following command inside an empty DB location:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"zstd -cd --long=31 <.tar.zst file> | sudo -u casper tar -xv\n")),(0,o.kt)("p",null,"To fix ownership, use this command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo /etc/casper/node_util.py fix_permissions\n")),(0,o.kt)("h2",{id:"streamed-decompression"},"Streamed Decompression"),(0,o.kt)("p",null,"If a ",(0,o.kt)("inlineCode",{parentName:"p"},".tar.zst")," archive is hosted on a website and you will not need the file after decompressing, you can stream it into the process using ",(0,o.kt)("inlineCode",{parentName:"p"},"curl"),", which can output to stdout with ",(0,o.kt)("inlineCode",{parentName:"p"},"--output")," and stream binary to your terminal."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s --output - \n")),(0,o.kt)("p",null,"If you use the output along with the previous process, you can decompress the files from ",(0,o.kt)("inlineCode",{parentName:"p"},"curl")," directly into a local directory:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s --output - | zstd -d --long=31 | sudo -u casper tar -xv\n")),(0,o.kt)("h2",{id:"starting-a-new-node-with-a-decompressed-db"},"Starting a New Node with a Decompressed DB"),(0,o.kt)("p",null,"If you are starting a node with a decompressed DB, you must tell the node to run at the protocol version of the tip of your DB. You can do this most efficiently with the ",(0,o.kt)("inlineCode",{parentName:"p"},"node_util.py")," script included in the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," installation."),(0,o.kt)("p",null,"For example, if you are using a DB archive from node version 1.4.5, you would run this command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo /etc/casper/node_util.py force_run_version 1_4_5\n")))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2747ce3a.f2ba58ef.js b/assets/js/2747ce3a.c1071f7d.js similarity index 99% rename from assets/js/2747ce3a.f2ba58ef.js rename to assets/js/2747ce3a.c1071f7d.js index 64a537b369..cd5526bf4a 100644 --- a/assets/js/2747ce3a.f2ba58ef.js +++ b/assets/js/2747ce3a.c1071f7d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[2031],{3905:function(e,t,r){r.d(t,{Zo:function(){return l},kt:function(){return m}});var a=r(7294);function s(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function c(e){for(var t=1;t=0||(s[r]=e[r]);return s}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(s[r]=e[r])}return s}var o=a.createContext({}),i=function(e){var t=a.useContext(o),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},l=function(e){var t=i(e.components);return a.createElement(o.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var r=e.components,s=e.mdxType,n=e.originalType,o=e.parentName,l=p(e,["components","mdxType","originalType","parentName"]),u=i(r),h=s,m=u["".concat(o,".").concat(h)]||u[h]||d[h]||n;return r?a.createElement(m,c(c({ref:t},l),{},{components:r})):a.createElement(m,c({ref:t},l))}));function m(e,t){var r=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var n=r.length,c=new Array(n);c[0]=h;var p={};for(var o in t)hasOwnProperty.call(t,o)&&(p[o]=t[o]);p.originalType=e,p[u]="string"==typeof e?e:s,c[1]=p;for(var i=2;icasper-types",id:"casper-types",level:2},{value:"casper-contract",id:"casper-contract",level:2},{value:"casper-engine-test-support",id:"casper-engine-test-support",level:2},{value:"casper-node",id:"casper-node",level:2},{value:"casper-client",id:"casper-client",level:2},{value:"casper-event-standard",id:"casper-event-standard",level:2},{value:"casper-hashing",id:"casper-hashing",level:2},{value:"casper-wasm-utils",id:"casper-wasm-utils",level:2},{value:"cargo-casper",id:"cargo-casper",level:2},{value:"Other Libraries",id:"other-libraries",level:2}],d={toc:u},h="wrapper";function m(e){var t=e.components,r=(0,s.Z)(e,c);return(0,n.kt)(h,(0,a.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"essential-rust-crates"},"Essential Rust Crates"),(0,n.kt)("p",null,"Several Rust crates are available on ",(0,n.kt)("a",{parentName:"p",href:"https://crates.io/"},"crates.io")," to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on ",(0,n.kt)("a",{parentName:"p",href:"https://docs.rs"},"docs.rs"),". The most important crates are listed below."),(0,n.kt)("h2",{id:"casper-types"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-types")),(0,n.kt)("p",null,"Types shared by many Casper crates:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-types"},"https://crates.io/crates/casper-types")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-types/latest"},"https://docs.rs/casper-types/latest"))),(0,n.kt)("h2",{id:"casper-contract"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-contract")),(0,n.kt)("p",null,"A library for developing Casper smart contracts:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-contract"},"https://crates.io/crates/casper-contract")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-contract/latest"},"https://docs.rs/casper-contract/latest"))),(0,n.kt)("h2",{id:"casper-engine-test-support"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-engine-test-support")),(0,n.kt)("p",null,"The Casper test support library:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-engine-test-support"},"https://crates.io/crates/casper-engine-test-support")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-engine-test-support/"},"https://docs.rs/casper-engine-test-support/"))),(0,n.kt)("h2",{id:"casper-node"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-node")),(0,n.kt)("p",null,"The component for running a node on a Casper network:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-node"},"https://crates.io/crates/casper-node")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-node/latest"},"https://docs.rs/casper-node/latest"))),(0,n.kt)("h2",{id:"casper-client"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-client")),(0,n.kt)("p",null,"A client library for interacting with a Casper network:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-client"},"https://crates.io/crates/casper-client")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-client/latest"},"https://docs.rs/casper-client/latest"))),(0,n.kt)("h2",{id:"casper-event-standard"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-event-standard")),(0,n.kt)("p",null,"A Rust library that provides a simple and standardized way for Casper contracts to emit events:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-event-standard"},"https://crates.io/crates/casper-event-standard")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-event-standard/latest"},"https://docs.rs/casper-event-standard/latest"))),(0,n.kt)("h2",{id:"casper-hashing"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-hashing")),(0,n.kt)("p",null,"A library providing hashing functionality including Merkle Proof utilities:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-hashing"},"https://crates.io/crates/casper-hashing")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-hashing/latest/"},"https://docs.rs/casper-hashing/latest/"))),(0,n.kt)("h2",{id:"casper-wasm-utils"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-wasm-utils")),(0,n.kt)("p",null,"Command-line utilities and corresponding Rust API for producing pwasm-compatible executables:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-wasm-utils"},"https://crates.io/crates/casper-wasm-utils")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-wasm-utils/latest"},"https://docs.rs/casper-wasm-utils/latest"))),(0,n.kt)("h2",{id:"cargo-casper"},(0,n.kt)("inlineCode",{parentName:"h2"},"cargo-casper")),(0,n.kt)("p",null,"A command line tool for creating a Wasm smart contract and tests:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/cargo-casper"},"https://crates.io/crates/cargo-casper")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/crate/cargo-casper/latest"},"https://docs.rs/crate/cargo-casper/latest"))),(0,n.kt)("h2",{id:"other-libraries"},"Other Libraries"),(0,n.kt)("p",null,"The ",(0,n.kt)("a",{parentName:"p",href:"/resources/build-on-casper/casper-open-source-software"},"Open-Source Software")," page provides other community-curated tools and libraries."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[2031],{3905:function(e,t,r){r.d(t,{Zo:function(){return l},kt:function(){return m}});var a=r(7294);function s(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function c(e){for(var t=1;t=0||(s[r]=e[r]);return s}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(s[r]=e[r])}return s}var o=a.createContext({}),i=function(e){var t=a.useContext(o),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},l=function(e){var t=i(e.components);return a.createElement(o.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var r=e.components,s=e.mdxType,n=e.originalType,o=e.parentName,l=p(e,["components","mdxType","originalType","parentName"]),u=i(r),h=s,m=u["".concat(o,".").concat(h)]||u[h]||d[h]||n;return r?a.createElement(m,c(c({ref:t},l),{},{components:r})):a.createElement(m,c({ref:t},l))}));function m(e,t){var r=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var n=r.length,c=new Array(n);c[0]=h;var p={};for(var o in t)hasOwnProperty.call(t,o)&&(p[o]=t[o]);p.originalType=e,p[u]="string"==typeof e?e:s,c[1]=p;for(var i=2;icasper-types",id:"casper-types",level:2},{value:"casper-contract",id:"casper-contract",level:2},{value:"casper-engine-test-support",id:"casper-engine-test-support",level:2},{value:"casper-node",id:"casper-node",level:2},{value:"casper-client",id:"casper-client",level:2},{value:"casper-event-standard",id:"casper-event-standard",level:2},{value:"casper-hashing",id:"casper-hashing",level:2},{value:"casper-wasm-utils",id:"casper-wasm-utils",level:2},{value:"cargo-casper",id:"cargo-casper",level:2},{value:"Other Libraries",id:"other-libraries",level:2}],d={toc:u},h="wrapper";function m(e){var t=e.components,r=(0,s.Z)(e,c);return(0,n.kt)(h,(0,a.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"essential-rust-crates"},"Essential Rust Crates"),(0,n.kt)("p",null,"Several Rust crates are available on ",(0,n.kt)("a",{parentName:"p",href:"https://crates.io/"},"crates.io")," to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on ",(0,n.kt)("a",{parentName:"p",href:"https://docs.rs"},"docs.rs"),". The most important crates are listed below."),(0,n.kt)("h2",{id:"casper-types"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-types")),(0,n.kt)("p",null,"Types shared by many Casper crates:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-types"},"https://crates.io/crates/casper-types")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-types/latest"},"https://docs.rs/casper-types/latest"))),(0,n.kt)("h2",{id:"casper-contract"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-contract")),(0,n.kt)("p",null,"A library for developing Casper smart contracts:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-contract"},"https://crates.io/crates/casper-contract")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-contract/latest"},"https://docs.rs/casper-contract/latest"))),(0,n.kt)("h2",{id:"casper-engine-test-support"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-engine-test-support")),(0,n.kt)("p",null,"The Casper test support library:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-engine-test-support"},"https://crates.io/crates/casper-engine-test-support")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-engine-test-support/"},"https://docs.rs/casper-engine-test-support/"))),(0,n.kt)("h2",{id:"casper-node"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-node")),(0,n.kt)("p",null,"The component for running a node on a Casper network:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-node"},"https://crates.io/crates/casper-node")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-node/latest"},"https://docs.rs/casper-node/latest"))),(0,n.kt)("h2",{id:"casper-client"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-client")),(0,n.kt)("p",null,"A client library for interacting with a Casper network:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-client"},"https://crates.io/crates/casper-client")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-client/latest"},"https://docs.rs/casper-client/latest"))),(0,n.kt)("h2",{id:"casper-event-standard"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-event-standard")),(0,n.kt)("p",null,"A Rust library that provides a simple and standardized way for Casper contracts to emit events:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-event-standard"},"https://crates.io/crates/casper-event-standard")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-event-standard/latest"},"https://docs.rs/casper-event-standard/latest"))),(0,n.kt)("h2",{id:"casper-hashing"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-hashing")),(0,n.kt)("p",null,"A library providing hashing functionality including Merkle Proof utilities:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-hashing"},"https://crates.io/crates/casper-hashing")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-hashing/latest/"},"https://docs.rs/casper-hashing/latest/"))),(0,n.kt)("h2",{id:"casper-wasm-utils"},(0,n.kt)("inlineCode",{parentName:"h2"},"casper-wasm-utils")),(0,n.kt)("p",null,"Command-line utilities and corresponding Rust API for producing pwasm-compatible executables:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-wasm-utils"},"https://crates.io/crates/casper-wasm-utils")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/casper-wasm-utils/latest"},"https://docs.rs/casper-wasm-utils/latest"))),(0,n.kt)("h2",{id:"cargo-casper"},(0,n.kt)("inlineCode",{parentName:"h2"},"cargo-casper")),(0,n.kt)("p",null,"A command line tool for creating a Wasm smart contract and tests:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://crates.io/crates/cargo-casper"},"https://crates.io/crates/cargo-casper")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.rs/crate/cargo-casper/latest"},"https://docs.rs/crate/cargo-casper/latest"))),(0,n.kt)("h2",{id:"other-libraries"},"Other Libraries"),(0,n.kt)("p",null,"The ",(0,n.kt)("a",{parentName:"p",href:"/resources/build-on-casper/casper-open-source-software"},"Open-Source Software")," page provides other community-curated tools and libraries."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/27a494b1.43fa8b10.js b/assets/js/27a494b1.b3c69563.js similarity index 98% rename from assets/js/27a494b1.43fa8b10.js rename to assets/js/27a494b1.b3c69563.js index 18431a9d05..0e60f3cb96 100644 --- a/assets/js/27a494b1.43fa8b10.js +++ b/assets/js/27a494b1.b3c69563.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6109],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return h}});var r=n(7294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var u=r.createContext({}),c=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(u.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,s=e.mdxType,a=e.originalType,u=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),l=c(n),f=s,h=l["".concat(u,".").concat(f)]||l[f]||d[f]||a;return n?r.createElement(h,o(o({ref:t},p),{},{components:n})):r.createElement(h,o({ref:t},p))}));function h(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var a=n.length,o=new Array(a);o[0]=f;var i={};for(var u in t)hasOwnProperty.call(t,u)&&(i[u]=t[u]);i.originalType=e,i[l]="string"==typeof e?e:s,o[1]=i;for(var c=2;c=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var u=r.createContext({}),c=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(u.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,s=e.mdxType,a=e.originalType,u=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),l=c(n),f=s,h=l["".concat(u,".").concat(f)]||l[f]||d[f]||a;return n?r.createElement(h,o(o({ref:t},p),{},{components:n})):r.createElement(h,o({ref:t},p))}));function h(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var a=n.length,o=new Array(a);o[0]=f;var i={};for(var u in t)hasOwnProperty.call(t,u)&&(i[u]=t[u]);i.originalType=e,i[l]="string"==typeof e?e:s,o[1]=i;for(var c=2;c=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},f=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),f=r,h=u["".concat(c,".").concat(f)]||u[f]||d[f]||a;return n?o.createElement(h,i(i({ref:t},p),{},{components:n})):o.createElement(h,i({ref:t},p))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=f;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:r,i[1]=s;for(var l=2;l /\n--chain-name /\n--secret-key /\n--session-path /\n--payment-amount \n--speculative-exec \n\n")),(0,a.kt)("p",null,"You should receive ",(0,a.kt)("inlineCode",{parentName:"p"},"execution_result"),"s that show a ",(0,a.kt)("inlineCode",{parentName:"p"},"cost"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "jsonrpc": "2.0",\n "id": -4571113357017152230,\n "result": {\n "api_version": "1.0.0",\n "block_hash": "6ca035b08de092e7f5e8fff771b880c5b4d7463a8f7a9b108888aaad958e5b0f",\n "execution_result": {\n "Success": {\n "effect": {\n \n },\n "transfers": [],\n "cost": "87300473670"\n }\n }\n }\n}\n\n')),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},"Cost estimates acquired through ",(0,a.kt)("inlineCode",{parentName:"p"},"speculative_exec")," may vary from the cost of sending the same Deploy to a Casper network. Speculative execution is a tool to help narrow down the potential cost of sending a Deploy, but many factors can cause the actual cost to vary.")))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[2881],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return h}});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},f=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),f=r,h=u["".concat(c,".").concat(f)]||u[f]||d[f]||a;return n?o.createElement(h,i(i({ref:t},p),{},{components:n})):o.createElement(h,i({ref:t},p))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=f;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:r,i[1]=s;for(var l=2;l /\n--chain-name /\n--secret-key /\n--session-path /\n--payment-amount \n--speculative-exec \n\n")),(0,a.kt)("p",null,"You should receive ",(0,a.kt)("inlineCode",{parentName:"p"},"execution_result"),"s that show a ",(0,a.kt)("inlineCode",{parentName:"p"},"cost"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "jsonrpc": "2.0",\n "id": -4571113357017152230,\n "result": {\n "api_version": "1.0.0",\n "block_hash": "6ca035b08de092e7f5e8fff771b880c5b4d7463a8f7a9b108888aaad958e5b0f",\n "execution_result": {\n "Success": {\n "effect": {\n \n },\n "transfers": [],\n "cost": "87300473670"\n }\n }\n }\n}\n\n')),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},"Cost estimates acquired through ",(0,a.kt)("inlineCode",{parentName:"p"},"speculative_exec")," may vary from the cost of sending the same Deploy to a Casper network. Speculative execution is a tool to help narrow down the potential cost of sending a Deploy, but many factors can cause the actual cost to vary.")))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2a99fafe.d2eb3836.js b/assets/js/2a99fafe.d47f1bdc.js similarity index 99% rename from assets/js/2a99fafe.d2eb3836.js rename to assets/js/2a99fafe.d47f1bdc.js index b061c67300..ed69c25357 100644 --- a/assets/js/2a99fafe.d2eb3836.js +++ b/assets/js/2a99fafe.d47f1bdc.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6263],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function c(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),l=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(i.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),h=r,m=u["".concat(i,".").concat(h)]||u[h]||d[h]||o;return n?a.createElement(m,c(c({ref:t},p),{},{components:n})):a.createElement(m,c({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,c=new Array(o);c[0]=h;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[u]="string"==typeof e?e:r,c[1]=s;for(var l=2;l()\n .expect("should be u32.");\n\n assert_eq!(version, 2);\n'))),(0,o.kt)("p",null,"You can also test the new entry point by using the Rust command-line client."),(0,o.kt)("p",null,"Get the NEW state-root-hash:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n")),(0,o.kt)("p",null,"Check the new contract entry points. You should see the ",(0,o.kt)("em",{parentName:"p"},"counter_decrement")," entry point now."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n')),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Example output"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},' {\n "id": 5602352547578277096,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[54054 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-wasmc014187ccf3366cca70317d6d567cd56a05ecf1ee50ed3bd02727c2864e3d3a8",\n "contract_wasm_hash": "contract-wasm-64d252f1ab72c7295a85d15c3f456f8bdda586580b0b7106e203fa4fd83f05d7",\n "entry_points": [\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_decrement",\n "ret": "Unit"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_get",\n "ret": "I32"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_inc",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-ca980a2e4c08dc3f233b728b22b909cd4e894295155a7902bf88a59eac1531d1-007",\n "name": "count"\n }\n ],\n "protocol_version": "1.4.13"\n }\n }\n }\n}\n'))),(0,o.kt)("p",null,"Check the version and package details with the latest state root hash:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "version"\n')),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Example output"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'{\n "id": 9084525900533244372,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[64874 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "02000000",\n "cl_type": "U32",\n "parsed": 2\n }\n }\n }\n\n'))),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter_package_name"\n')),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Example output"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'{\n "id": 6933525663267881367,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[52174 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-101817ffd5aa47b08ca710649dbdc41edf0a20d7802c736d34053656c0a99eaf-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-4ee8a4cfbc0a183d189611b6a14c0f7b57e7635fa17a8acfc5c645fec4c36316",\n "contract_version": 1,\n "protocol_version_major": 1\n },\n {\n "contract_hash": "contract-2cd9f6485423ba846fae83729016b03df26d9babb939466906c8f1d168b40949",\n "contract_version": 2,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n\n\n'))),(0,o.kt)("p",null,"Call the new entry point, ",(0,o.kt)("em",{parentName:"p"},"counter_decrement"),", using the package name and check the results."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-name "counter_package_name" \\\n --session-entry-point "counter_decrement"\n')),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"There are two ways to call versioned contracts:"),(0,o.kt)("ol",{parentName:"admonition"},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"/developers/writing-onchain-code/calling-contracts/#StoredVersionedContractByHash"},"Calling Contracts by Package Hash")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"/developers/writing-onchain-code/calling-contracts/#StoredVersionedContractByName"},"Calling Contracts by Package Name")))),(0,o.kt)("p",null,"After calling the entry point, the count value should be decremented. You can verify it by querying the network again using the new state root hash."),(0,o.kt)("h2",{id:"disabling-and-enabling-contract-versions"},"Disabling and Enabling Contract Versions"),(0,o.kt)("p",null,"You can disable a contract version within a contract package by using the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.disable_contract_version.html"},"disable_contract_version")," function."),(0,o.kt)("p",null,"Disabled contract versions can no longer be executed. As such, if there is only a single contract version within the package, you will no longer be able to use the contract."),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.enable_contract_version.html"},"Enable_contract_version")," allows you to re-enable a previously disabled contract version."),(0,o.kt)("p",null,"::note"),(0,o.kt)("p",null,"Be aware that calling a contract package will use the most recent contract version. It is not necessary to disable a previous contract version, unless you have a specific need to do so."),(0,o.kt)("p",null,":::"),(0,o.kt)("h2",{id:"locked-contract-package"},"Creating a Locked Contract Package"),(0,o.kt)("p",null,"You can create a locked contract package with the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_locked_contract.html"},"new_locked_contract")," function. This contract can never be upgraded."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'let (stored_contract_hash, _) = storage::new_locked_contract(\n contract_entry_points,\n Some(contract_named_keys),\n Some("contract_package_name".to_string()),\n Some("contract_access_uref".to_string()),\n);\n')),(0,o.kt)("p",null,"Apply the contract entry points and named keys when you call the function. You can also specify a hash_name and uref_name that will be put in the context's named keys. You do not need to save the version number returned since the version of this contract package would always be equal to 1."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Creating a locked contract package is an irreversible decision. To upgrade a contract, use ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html"},"new_contract")," as Step 1 explains.")))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6263],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function c(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),l=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(i.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),h=r,m=u["".concat(i,".").concat(h)]||u[h]||d[h]||o;return n?a.createElement(m,c(c({ref:t},p),{},{components:n})):a.createElement(m,c({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,c=new Array(o);c[0]=h;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[u]="string"==typeof e?e:r,c[1]=s;for(var l=2;l()\n .expect("should be u32.");\n\n assert_eq!(version, 2);\n'))),(0,o.kt)("p",null,"You can also test the new entry point by using the Rust command-line client."),(0,o.kt)("p",null,"Get the NEW state-root-hash:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n")),(0,o.kt)("p",null,"Check the new contract entry points. You should see the ",(0,o.kt)("em",{parentName:"p"},"counter_decrement")," entry point now."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n')),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Example output"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},' {\n "id": 5602352547578277096,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[54054 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-wasmc014187ccf3366cca70317d6d567cd56a05ecf1ee50ed3bd02727c2864e3d3a8",\n "contract_wasm_hash": "contract-wasm-64d252f1ab72c7295a85d15c3f456f8bdda586580b0b7106e203fa4fd83f05d7",\n "entry_points": [\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_decrement",\n "ret": "Unit"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_get",\n "ret": "I32"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_inc",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-ca980a2e4c08dc3f233b728b22b909cd4e894295155a7902bf88a59eac1531d1-007",\n "name": "count"\n }\n ],\n "protocol_version": "1.4.13"\n }\n }\n }\n}\n'))),(0,o.kt)("p",null,"Check the version and package details with the latest state root hash:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "version"\n')),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Example output"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'{\n "id": 9084525900533244372,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[64874 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "02000000",\n "cl_type": "U32",\n "parsed": 2\n }\n }\n }\n\n'))),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter_package_name"\n')),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Example output"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'{\n "id": 6933525663267881367,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[52174 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-101817ffd5aa47b08ca710649dbdc41edf0a20d7802c736d34053656c0a99eaf-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-4ee8a4cfbc0a183d189611b6a14c0f7b57e7635fa17a8acfc5c645fec4c36316",\n "contract_version": 1,\n "protocol_version_major": 1\n },\n {\n "contract_hash": "contract-2cd9f6485423ba846fae83729016b03df26d9babb939466906c8f1d168b40949",\n "contract_version": 2,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n\n\n'))),(0,o.kt)("p",null,"Call the new entry point, ",(0,o.kt)("em",{parentName:"p"},"counter_decrement"),", using the package name and check the results."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-name "counter_package_name" \\\n --session-entry-point "counter_decrement"\n')),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"There are two ways to call versioned contracts:"),(0,o.kt)("ol",{parentName:"admonition"},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"/developers/writing-onchain-code/calling-contracts/#StoredVersionedContractByHash"},"Calling Contracts by Package Hash")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"/developers/writing-onchain-code/calling-contracts/#StoredVersionedContractByName"},"Calling Contracts by Package Name")))),(0,o.kt)("p",null,"After calling the entry point, the count value should be decremented. You can verify it by querying the network again using the new state root hash."),(0,o.kt)("h2",{id:"disabling-and-enabling-contract-versions"},"Disabling and Enabling Contract Versions"),(0,o.kt)("p",null,"You can disable a contract version within a contract package by using the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.disable_contract_version.html"},"disable_contract_version")," function."),(0,o.kt)("p",null,"Disabled contract versions can no longer be executed. As such, if there is only a single contract version within the package, you will no longer be able to use the contract."),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.enable_contract_version.html"},"Enable_contract_version")," allows you to re-enable a previously disabled contract version."),(0,o.kt)("p",null,"::note"),(0,o.kt)("p",null,"Be aware that calling a contract package will use the most recent contract version. It is not necessary to disable a previous contract version, unless you have a specific need to do so."),(0,o.kt)("p",null,":::"),(0,o.kt)("h2",{id:"locked-contract-package"},"Creating a Locked Contract Package"),(0,o.kt)("p",null,"You can create a locked contract package with the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_locked_contract.html"},"new_locked_contract")," function. This contract can never be upgraded."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'let (stored_contract_hash, _) = storage::new_locked_contract(\n contract_entry_points,\n Some(contract_named_keys),\n Some("contract_package_name".to_string()),\n Some("contract_access_uref".to_string()),\n);\n')),(0,o.kt)("p",null,"Apply the contract entry points and named keys when you call the function. You can also specify a hash_name and uref_name that will be put in the context's named keys. You do not need to save the version number returned since the version of this contract package would always be equal to 1."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Creating a locked contract package is an irreversible decision. To upgrade a contract, use ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html"},"new_contract")," as Step 1 explains.")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2bee511f.7e5892e8.js b/assets/js/2bee511f.0dce014e.js similarity index 99% rename from assets/js/2bee511f.7e5892e8.js rename to assets/js/2bee511f.0dce014e.js index 8aff1b3905..59b1dc5d18 100644 --- a/assets/js/2bee511f.7e5892e8.js +++ b/assets/js/2bee511f.0dce014e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[8933],{3905:function(e,t,a){a.d(t,{Zo:function(){return d},kt:function(){return h}});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function r(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},d=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},k=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,l=e.originalType,s=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),m=p(a),k=i,h=m["".concat(s,".").concat(k)]||m[k]||u[k]||l;return a?n.createElement(h,r(r({ref:t},d),{},{components:a})):n.createElement(h,r({ref:t},d))}));function h(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var l=a.length,r=new Array(l);r[0]=k;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[m]="string"==typeof e?e:i,r[1]=o;for(var p=2;pFailure",id:"failure",level:3},{value:"Success",id:"success",level:3},{value:"Group",id:"group",level:2},{value:"Groups",id:"groups",level:2},{value:"Keys",id:"serialization-standard-state-keys",level:2},{value:"Account identity key",id:"global-state-account-key",level:3},{value:"Hash key",id:"serialization-standard-hash-key",level:3},{value:"Unforgeable Reference (URef)",id:"serialization-standard-uref",level:3},{value:"Transfer Key",id:"serialization-standard-transfer-key",level:3},{value:"DeployInfo Key",id:"serialization-standard-deploy-info-key",level:3},{value:"EraInfo Key",id:"serialization-standard-era-info-key",level:3},{value:"Serialization for Key",id:"serialization-standard-serialization-key",level:3},{value:"Permissions",id:"serialization-standard-permissions",level:2},{value:"NamedArg",id:"namedarg",level:2},{value:"NamedKey",id:"namedkey",level:2},{value:"Operation",id:"operation",level:2},{value:"Parameter",id:"parameter",level:2},{value:"ProtocolVersion",id:"protocolversion",level:2},{value:"PublicKey",id:"publickey",level:2},{value:"RuntimeArgs",id:"runtimeargs",level:2},{value:"SeigniorageAllocation",id:"seigniorageallocation",level:2},{value:"Signature",id:"signature",level:2},{value:"SystemContractRegistry",id:"systemcontractregistry",level:2},{value:"TimeDiff",id:"timediff",level:2},{value:"Timestamp",id:"timestamp",level:2},{value:"TransferAddr",id:"transferaddr",level:2},{value:"Transform",id:"transform",level:2},{value:"TransformEntry",id:"transformentry",level:2},{value:"UnbondingPurse",id:"unbondingpurse",level:2},{value:"Values",id:"serialization-standard-values",level:2},{value:"CLValue",id:"clvalue",level:3},{value:"Boolean",id:"clvalue-boolean",level:4},{value:"Numeric",id:"clvalue-numeric",level:4},{value:"Unit",id:"clvalue-unit",level:4},{value:"String",id:"clvalue-string",level:4},{value:"Option",id:"clvalue-option",level:4},{value:"List",id:"clvalue-list",level:4},{value:"ByteArray",id:"clvalue-ByteArray",level:4},{value:"Result",id:"clvalue-result",level:4},{value:"Tuple",id:"clvalue-tuple",level:4},{value:"Map",id:"clvalue-map",level:4},{value:"URef",id:"clvalue-uref",level:4},{value:"PublicKey",id:"clvalue-publickey",level:4},{value:"Key",id:"clvalue-key",level:4},{value:"CLType",id:"clvalue-cltype",level:4},{value:"CLValue",id:"clvalue-clvalue",level:4},{value:"Contracts",id:"global-state-contracts",level:3},{value:"WithdrawPurse",id:"withdrawpurse",level:2}],u={toc:m},k="wrapper";function h(e){var t=e.components,a=(0,i.Z)(e,r);return(0,l.kt)(k,(0,n.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"serialization-standard-head"},"Serialization Standard"),(0,l.kt)("p",null,"We provide a custom implementation to serialize data structures used by the Casper node to their byte representation. This document details how this custom serialization is implemented, allowing developers to build a library that implements the custom serialization."),(0,l.kt)("p",null,"In your smart contracts, you can implement serialization using ",(0,l.kt)("inlineCode",{parentName:"p"},"cltype-any"),"."),(0,l.kt)("h2",{id:"serialization-standard-account"},"Account"),(0,l.kt)("p",null,"An Account is a structure that represents a user on a Casper network. The account structure consists of the following fields:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#account-hash"},(0,l.kt)("inlineCode",{parentName:"a"},"account_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#namedkey"},(0,l.kt)("inlineCode",{parentName:"a"},"named_keys")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"main_purse")),(0,l.kt)("p",{parentName:"li"},"The account's main purse ",(0,l.kt)("inlineCode",{parentName:"p"},"URef"),". You may find information on ",(0,l.kt)("inlineCode",{parentName:"p"},"URef")," serialization ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-uref"},"here"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#associated-keys"},(0,l.kt)("inlineCode",{parentName:"a"},"associated_keys")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#action-thresholds"},(0,l.kt)("inlineCode",{parentName:"a"},"action_thresholds"))))),(0,l.kt)("h2",{id:"account-hash"},"Account Hash"),(0,l.kt)("p",null,"A ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b")," hash of the public key, representing the address of a user's account. The account hash serializes as a 32-byte buffer containing the bytes of the account hash."),(0,l.kt)("h2",{id:"action-thresholds"},"Action Thresholds"),(0,l.kt)("p",null,"The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as two consecutive ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u8")," values")," as follows."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"deployment")," The minimum weight threshold required to perform deployment actions as a ",(0,l.kt)("inlineCode",{parentName:"p"},"u8")," value.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key_management")," The minimum weight threshold required to perform key management actions as a ",(0,l.kt)("inlineCode",{parentName:"p"},"u8")," value."))),(0,l.kt)("h2",{id:"activation-point"},"Activation Point"),(0,l.kt)("p",null,"The first era to which the associated protocol version applies. It serializes as a single ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u8"))," tag indicating if the era in question is genesis. If it is the genesis era, the following bytes will be a ",(0,l.kt)("inlineCode",{parentName:"p"},"timestamp"),". If not, the bytes represent an ",(0,l.kt)("inlineCode",{parentName:"p"},"era_id"),"."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"era_id")," An ",(0,l.kt)("a",{parentName:"p",href:"#eraid"},"Era ID newtype")," identifying the era when the protocol version will activate.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"timestamp")," A ",(0,l.kt)("a",{parentName:"p",href:"#timestamp"},"timestamp")," if the activation point is of the Genesis variant."))),(0,l.kt)("h2",{id:"approval"},"Approval"),(0,l.kt)("p",null,"A struct containing a signature and the public key of the signer."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"signature")," The approval signature, which serializes as the byte representation of the ",(0,l.kt)("a",{parentName:"p",href:"#signature"},(0,l.kt)("inlineCode",{parentName:"a"},"Signature")),". The first byte within the signature is 1 in the case of an ",(0,l.kt)("inlineCode",{parentName:"p"},"Ed25519")," signature or 2 in the case of ",(0,l.kt)("inlineCode",{parentName:"p"},"Secp256k1"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"signer")," The public key of the approvals signer. It serializes to the byte representation of the ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),". If the ",(0,l.kt)("inlineCode",{parentName:"p"},"PublicKey")," is an ",(0,l.kt)("inlineCode",{parentName:"p"},"Ed25519")," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,l.kt)("inlineCode",{parentName:"p"},"Secp256k1"),", the first byte is 2."))),(0,l.kt)("h2",{id:"associatedkey"},"AssociatedKey"),(0,l.kt)("p",null,"A key granted limited permissions to an Account, for purposes such as multisig. It is serialized as a ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeMap")," where the first 4 bytes represent a ",(0,l.kt)("inlineCode",{parentName:"p"},"u32")," value describing the number of keys and weights held within. The remainder consists of a repeating pattern of serialized named keys and then weights of the length dictated by the first four bytes."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"account_hash")," The ",(0,l.kt)("a",{parentName:"p",href:"#account-hash"},"account hash")," of the associated key.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"weight")," The weight of an associated key. The weight serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u8")," value"),"."))),(0,l.kt)("h2",{id:"availableblockrange"},"AvailableBlockRange"),(0,l.kt)("p",null,"An unbroken, inclusive range of blocks. It serializes as two consecutive ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64")," values")," containing the following two fields:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"low")," The inclusive lower bound of the range.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"high")," - The inclusive upper bound of the range."))),(0,l.kt)("h2",{id:"bid"},"Bid"),(0,l.kt)("p",null,"An entry in the validator map. The structure consists of the following fields:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"validator_public_key")," The validator's public key. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"bonding_purse")," The purse used for bonding. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-uref"},(0,l.kt)("inlineCode",{parentName:"a"},"Uref")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"staked_amount")," The amount of tokens staked by a validator (not including delegators). It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512")," value"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"delegation_rate")," The delegation rate of the bid. It serializes as an ",(0,l.kt)("inlineCode",{parentName:"p"},"i32")," signed 32-bit integer primitive.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"vesting_schedule")," The vesting schedule for a genesis validator. ",(0,l.kt)("inlineCode",{parentName:"p"},"None")," if it is a non-genesis validator. It serializes as an ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-option"},(0,l.kt)("inlineCode",{parentName:"a"},"Option")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"delegators")," The validator's delegators, indexed by their public keys. They are serialized as a ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeMap")," where the first 4 bytes represent a ",(0,l.kt)("inlineCode",{parentName:"p"},"u32")," value describing the number of ",(0,l.kt)("inlineCode",{parentName:"p"},"PublicKey"),"s and delegators held within. The remainder consists of a repeating pattern of serialized ",(0,l.kt)("inlineCode",{parentName:"p"},"PublicKey"),"s and then delegators of the length dictated by the first four bytes.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"inactive")," If the validator has been evicted. A ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-boolean"},"boolean")," value that serializes as a single byte; ",(0,l.kt)("inlineCode",{parentName:"p"},"true")," maps to ",(0,l.kt)("inlineCode",{parentName:"p"},"1"),", while ",(0,l.kt)("inlineCode",{parentName:"p"},"false")," maps to ",(0,l.kt)("inlineCode",{parentName:"p"},"0"),"."))),(0,l.kt)("h2",{id:"serialization-standard-block"},"Block"),(0,l.kt)("p",null,"A block is the core component of the Casper linear blockchain, used in two contexts:"),(0,l.kt)("ol",null,(0,l.kt)("li",{parentName:"ol"},"A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain."),(0,l.kt)("li",{parentName:"ol"},"A message that is exchanged between nodes containing the data structure as explained in (1).")),(0,l.kt)("p",null,"Each block has a globally unique ID, achieved by hashing the contents of the block."),(0,l.kt)("p",null,"Each block points to its parent. An exception is the first block, which has no parent."),(0,l.kt)("p",null,"A block is structurally defined as follows:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"hash"),": A hash over the header of the block."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"header"),": The header of the block that contains information about the contents of the block with additional metadata."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"body"),": The block's body contains the proposer of the block and hashes of deploys and transfers contained within it.")),(0,l.kt)("h3",{id:"block-hash"},"Block hash"),(0,l.kt)("p",null,"The block hash is a ",(0,l.kt)("inlineCode",{parentName:"p"},"Digest")," over the contents of the block Header. The ",(0,l.kt)("inlineCode",{parentName:"p"},"BlockHash")," serializes as the byte representation of the hash itself."),(0,l.kt)("h3",{id:"block-header"},"Block header"),(0,l.kt)("p",null,"The header portion of a block, structurally, is defined as follows:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"parent_hash"),": is the hash of the parent block. It serializes to the byte representation of the parent hash. The serialized buffer of the ",(0,l.kt)("inlineCode",{parentName:"li"},"parent_hash")," is 32 bytes long."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"state_root_hash"),": is the global state root hash produced by executing this block's body. It serializes to the byte representation of the ",(0,l.kt)("inlineCode",{parentName:"li"},"state root hash"),". The serialized buffer of the ",(0,l.kt)("inlineCode",{parentName:"li"},"state_root_hash")," is 32 bytes long."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"body_hash"),": the hash of the block body. It serializes to the byte representation of the body hash. The serialized buffer of the ",(0,l.kt)("inlineCode",{parentName:"li"},"body_hash")," is 32 bytes long."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"random_bit"),": is a boolean needed for initializing a future era. It is serialized as a single byte; true maps to 1, while false maps to 0."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"accumulated_seed"),": A seed needed for initializing a future era. It serializes to the byte representation of the parent Hash. The serialized buffer of the ",(0,l.kt)("inlineCode",{parentName:"li"},"accumulated_hash")," is 32 bytes long."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"era_end"),": contains equivocation and reward information to be included in the terminal finalized block. It is an optional field. Thus if the field is set as ",(0,l.kt)("inlineCode",{parentName:"li"},"None"),", it serializes to ",(0,l.kt)("em",{parentName:"li"},"0"),". The serialization of the other case is described in the EraEnd."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"timestamp"),": The timestamp from when the block was proposed. It serializes as a single ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," value. The serialization of a ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," value is described in the CLValues section."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"era_id"),": Era ID in which this block was created. It serializes as a single ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," value."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"height"),": The height of this block, i.e., the number of ancestors. It serializes as a single ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," value."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"protocol_version"),": The version of the Casper network when this block was proposed. It is 3-element tuple containing ",(0,l.kt)("inlineCode",{parentName:"li"},"u32")," values. It serializes as a buffer containing the three ",(0,l.kt)("inlineCode",{parentName:"li"},"u32")," serialized values. Refer to the CLValues section on how ",(0,l.kt)("inlineCode",{parentName:"li"},"u32")," values are serialized.")),(0,l.kt)("h3",{id:"serialization-standard-era-end"},"EraEnd"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"EraEnd")," as represented within the block header, is a struct containing two fields."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"era_report"),": The first field is termed as ",(0,l.kt)("inlineCode",{parentName:"li"},"EraReport")," and contains information about equivocators and rewards for an era."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"next_era_validator_weights"),": The second field is map for the validators and their weights for the era to follow.")),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"EraReport")," itself contains two fields:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"equivocators"),": A vector of ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey"),"."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"rewards"),": A Binary Tree Map of ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," and ",(0,l.kt)("inlineCode",{parentName:"li"},"u64"),".")),(0,l.kt)("p",null,"When serializing an EraReport, the buffer is first filled with the individual serialization of the PublicKey contained within the vector."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"If the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," is an ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519")," key, the first byte within the buffer is a ",(0,l.kt)("inlineCode",{parentName:"li"},"1")," followed by the individual bytes of the serialized key."),(0,l.kt)("li",{parentName:"ul"},"If the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," is an ",(0,l.kt)("inlineCode",{parentName:"li"},"Secp256k1")," key, the first byte within the buffer is a ",(0,l.kt)("inlineCode",{parentName:"li"},"2")," followed by the individual bytes of the serialized key.")),(0,l.kt)("p",null,"When serializing the overarching struct of ",(0,l.kt)("inlineCode",{parentName:"p"},"EraEnd"),", we first allocate a buffer, which contains the serialized representation of the ",(0,l.kt)("inlineCode",{parentName:"p"},"EraReport")," as described above, followed by the serialized BTreeMap."),(0,l.kt)("p",null,"Note that ",(0,l.kt)("inlineCode",{parentName:"p"},"EraEnd")," is an optional field. Thus the above scheme only applies if there is an ",(0,l.kt)("inlineCode",{parentName:"p"},"EraEnd"),"; if there is no era end, the field simply serializes to ",(0,l.kt)("em",{parentName:"p"},"0"),"."),(0,l.kt)("h3",{id:"body"},"Body"),(0,l.kt)("p",null,"The body portion of the block is structurally defined as:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"proposer"),": The PublicKey which proposed this block."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"deploy_hashes"),": Is a vector of hex-encoded hashes identifying Deploys included in this block."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"transfer_hashes"),": Is a vector of hex-encoded hashes identifying Transfers included in this block.")),(0,l.kt)("p",null,"When we serialize the ",(0,l.kt)("inlineCode",{parentName:"p"},"BlockBody"),", we create a buffer that contains the serialized representations of the individual fields present within the block."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"proposer"),": serializes to the byte representation of the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey"),". If the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," is an ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519")," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,l.kt)("inlineCode",{parentName:"li"},"Secp256k1"),", the first byte is 2."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"deploy_hashes"),": serializes to the byte representation of all the deploy_hashes within the block header. Its length is ",(0,l.kt)("inlineCode",{parentName:"li"},"32 * n"),", where n denotes the number of deploy hashes present within the body."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"transfer_hashes"),": serializes to the byte representation of all the deploy_hashes within the block header. Its length is ",(0,l.kt)("inlineCode",{parentName:"li"},"32 * n"),", where n denotes the number of transfers present within the body.")),(0,l.kt)("h2",{id:"blockidentifier"},"BlockIdentifier"),(0,l.kt)("p",null,"Identifier for possible ways to retrieve a Block. It can consist of any of the following in most situations:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#block-hash"},(0,l.kt)("inlineCode",{parentName:"a"},"hash"))," Identify and retrieve a Block with its hash. The ",(0,l.kt)("inlineCode",{parentName:"p"},"BlockHash")," serializes as the byte representation of the hash itself.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"height")," Identify and retrieve the Block with its height. Height serializes as a single ",(0,l.kt)("inlineCode",{parentName:"p"},"u64")," value.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"state_root_hash")," Identify and retrieve the Block with its state root hash. It serializes to the byte representation of the ",(0,l.kt)("inlineCode",{parentName:"p"},"state root hash"),". The serialized buffer of the ",(0,l.kt)("inlineCode",{parentName:"p"},"state_root_hash")," is 32 bytes long."))),(0,l.kt)("h2",{id:"chainspecregistry"},"ChainspecRegistry"),(0,l.kt)("p",null,"ChainspecRegistry is a unique key variant which contains a mapping of file names to the hash of the file itself. This map includes ",(0,l.kt)("em",{parentName:"p"},"Chainspec.toml")," and may include ",(0,l.kt)("em",{parentName:"p"},"Accounts.toml")," and ",(0,l.kt)("em",{parentName:"p"},"GlobalState.toml"),". It is serialized as a ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeMap")," where the first 4 bytes represent a ",(0,l.kt)("inlineCode",{parentName:"p"},"u32")," value describing the number of names as strings and ",(0,l.kt)("a",{parentName:"p",href:"#digest"},"digests")," held within. The remainder consists of a repeating pattern of serialized strings and then digests of the length dictated by the first four bytes. Digests and their inclusion criteria are as follows:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"chainspec_raw_hash")," will always be included.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"genesis_accounts_raw_hash")," may be included in specific circumstances.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"global_state_raw_hash")," may be included in specific circumstances."))),(0,l.kt)("h2",{id:"contract"},"Contract"),(0,l.kt)("p",null,"A contract struct containing the following fields:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#contractpackagehash"},(0,l.kt)("inlineCode",{parentName:"a"},"contract_package_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#contractwasmhash"},(0,l.kt)("inlineCode",{parentName:"a"},"contract_wasm_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#namedkey"},(0,l.kt)("inlineCode",{parentName:"a"},"named_keys")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#entrypoint"},(0,l.kt)("inlineCode",{parentName:"a"},"entry_points")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#protocolversion"},(0,l.kt)("inlineCode",{parentName:"a"},"protocol_version"))))),(0,l.kt)("h2",{id:"contracthash"},"ContractHash"),(0,l.kt)("p",null,"A ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b")," hash of a contract. The contract hash serializes as a 32-byte buffer containing the bytes of the contract hash."),(0,l.kt)("h2",{id:"contractpackagehash"},"ContractPackageHash"),(0,l.kt)("p",null,"A ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b")," hash of a contract package. The contract package hash serializes as a 32-byte buffer containing the bytes of the contract package hash."),(0,l.kt)("h2",{id:"contractversion"},"ContractVersion"),(0,l.kt)("p",null,"The version of the contract."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#contracthash"},(0,l.kt)("inlineCode",{parentName:"a"},"contract_hash"))," The contract hash of the contract.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"contract_version")," The version of the contract within the protocol major version. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u32")," value"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"protocol_version_major")," The major element of the protocol version this contract is compatible with. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u32")," value"),"."))),(0,l.kt)("h2",{id:"contractwasmhash"},"ContractWasmHash"),(0,l.kt)("p",null,"A ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b")," hash of a contract's Wasm. The contract's Wasm hash serializes as a 32-byte buffer containing the bytes of the contract's Wasm hash."),(0,l.kt)("h2",{id:"delegator"},"Delegator"),(0,l.kt)("p",null,'Represents a party delegating their stake to a validator (or "delegatee"). The structure consists of the following fields:'),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"delegator_public_key")," The public key of the delegator, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"staked_amount")," The amount staked by the delegator, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512")," value"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"bonding_purse")," The bonding purse associated with the delegation. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-uref"},(0,l.kt)("inlineCode",{parentName:"a"},"URef")," value"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"validator_public_key")," The public key of the validator that the delegator will be delegating to, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"vesting_schedule")," The vesting schedule for the provided delegator bid. ",(0,l.kt)("inlineCode",{parentName:"p"},"None")," if it is a non-genesis validator. It serializes as an ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-option"},(0,l.kt)("inlineCode",{parentName:"a"},"Option")),"."))),(0,l.kt)("h2",{id:"serialization-standard-deploy"},"Deploy"),(0,l.kt)("p",null,"A deploy is a data structure containing a smart contract and the requester's signature(s). Additionally, the deploy header contains additional metadata about the deploy itself. A deploy is structurally defined as follows:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"hash"),": The hash of the deploy header."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"header"),": Contains metadata about the deploy. The structure of the header is detailed further in this document."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"payment"),": The payment code for contained smart contract."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"session"),": The stored contract itself."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"approvals"),": A list of signatures:")),(0,l.kt)("h3",{id:"deploy-hash"},"Deploy-Hash"),(0,l.kt)("p",null,"The deploy hash is a digest over the contents of the deploy header. The deploy hash serializes as the byte representation of the hash itself."),(0,l.kt)("h3",{id:"deploy-header"},"Deploy-Header"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"account"),": A supported public key variant (currently either ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519")," or ",(0,l.kt)("inlineCode",{parentName:"li"},"Secp256k1"),"). An ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519")," key is serialized as a buffer of bytes, with the leading byte being ",(0,l.kt)("inlineCode",{parentName:"li"},"1")," for ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519"),", with remainder of the buffer containing the byte representation of the signature. Correspondingly, a ",(0,l.kt)("inlineCode",{parentName:"li"},"Secp256k1")," key is serialized as a buffer of bytes, with the leading byte being ",(0,l.kt)("inlineCode",{parentName:"li"},"2"),"."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"timestamp"),": A timestamp is a struct that is a unary tuple containing a ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," value. This value is a count of the milliseconds since the UNIX epoch. Thus the value ",(0,l.kt)("inlineCode",{parentName:"li"},"1603994401469")," serializes as ",(0,l.kt)("inlineCode",{parentName:"li"},"0xbd3a847575010000")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"ttl"),": The ",(0,l.kt)("strong",{parentName:"li"},"Time to live")," is defined as the amount of time for which deploy is considered valid. The ",(0,l.kt)("inlineCode",{parentName:"li"},"ttl")," serializes in the same manner as the timestamp."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"gas_price"),": The gas is ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," value which is serialized as ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," CLValue discussed below."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"body_hash"),": Body hash is a hash over the contents of the deploy body, which includes the payment, session, and approval fields. Its serialization is the byte representation of the hash itself."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"dependencies"),": Dependencies is a vector of deploy hashes referencing deploys that must execute before the current deploy can be executed. It serializes as a buffer containing the individual serialization of each DeployHash within the Vector."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"chain_name"),": Chain name is a human-readable string describing the name of the chain as detailed in the chainspec. It is serialized as a String CLValue described below.")),(0,l.kt)("h3",{id:"payment--session"},"Payment & Session"),(0,l.kt)("p",null,"Payment and Session are both defined as ",(0,l.kt)("inlineCode",{parentName:"p"},"ExecutableDeployItems"),". More information on ",(0,l.kt)("inlineCode",{parentName:"p"},"ExecutableDeployItems")," can be found ",(0,l.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/calling-contracts"},"here")),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"Module Bytes are serialized such that the first byte within the serialized buffer is ",(0,l.kt)("inlineCode",{parentName:"p"},"0")," with the rest of the buffer containing the bytes present."),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},'ModuleBytes { module_bytes: "[72 bytes]", args: 434705a38470ec2b008bb693426f47f330802f3bd63588ee275e943407649d3bab1898897ab0400d7fa09fe02ab7b7e8ea443d28069ca557e206916515a7e21d15e5be5eb46235f5 }')," will serialize to"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"0x0048000000420481b0d5a665c8a7678398103d4333c684461a71e9ee2a13f6e859fb6cd419ed5f8876fc6c3e12dce4385acc777edf42dcf8d8d844bf6a704e5b2446750559911a4a328d649ddd48000000434705a38470ec2b008bb693426f47f330802f3bd63588ee275e943407649d3bab1898897ab0400d7fa09fe02ab7b7e8ea443d28069ca557e206916515a7e21d15e5be5eb46235f5")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"StoredContractByHash serializes such that the first byte within the serialized buffer is 1u8. This is followed by the byte representation of the remaining fields."),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},'StoredContractByHash { hash: c4c411864f7b717c27839e56f6f1ebe5da3f35ec0043f437324325d65a22afa4, entry_point: "pclphXwfYmCmdITj8hnh", args: d8b59728274edd2334ea328b3292ed15eaf9134f9a00dce31a87d9050570fb0267a4002c85f3a8384d2502733b2e46f44981df85fed5e4854200bbca313e3bca8d888a84a76a1c5b1b3d236a12401a2999d3cad003c9b9d98c92ab1850 }')),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"0x01c4c411864f7b717c27839e56f6f1ebe5da3f35ec0043f437324325d65a22afa41400000070636c7068587766596d436d6449546a38686e685d000000d8b59728274edd2334ea328b3292ed15eaf9134f9a00dce31a87d9050570fb0267a4002c85f3a8384d2502733b2e46f44981df85fed5e4854200bbca313e3bca8d888a84a76a1c5b1b3d236a12401a2999d3cad003c9b9d98c92ab1850")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"StoredContractByName serializes such that the first byte within the serialized buffer is 2u8. This is followed by the individual byte representation of the remaining fields."),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},'StoredContractByName { name: "U5A74bSZH8abT8HqVaK9", entry_point: "gIetSxltnRDvMhWdxTqQ", args: 07beadc3da884faa17454a }')),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"0x0214000000553541373462535a483861625438487156614b39140000006749657453786c746e5244764d685764785471510b00000007beadc3da884faa17454a")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"StoredVersionedContractByHash serializes such that the first byte within the serialized buffer is 3u8. However, the field version within the enum serializes as an ",(0,l.kt)("a",{parentName:"p",href:"#option-clvalue-option"},"Option")," CLValue."),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},'StoredVersionedContractByHash { hash: b348fdd0d0b3f66468687df93141b5924f6bb957d5893c08b60d5a78d0b9a423, version: None, entry_point: "PsLz5c7JsqT8BK8ll0kF", args: 3d0d7f193f70740386cb78b383e2e30c4f976cf3fa834bafbda4ed9dbfeb52ce1777817e8ed8868cfac6462b7cd31028aa5a7a60066db35371a2f8 }')),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"0x03b348fdd0d0b3f66468687df93141b5924f6bb957d5893c08b60d5a78d0b9a423001400000050734c7a3563374a73715438424b386c6c306b463b0000003d0d7f193f70740386cb78b383e2e30c4f976cf3fa834bafbda4ed9dbfeb52ce1777817e8ed8868cfac6462b7cd31028aa5a7a60066db35371a2f8")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"StoredVersionedContractByName serializes such that the first byte within the serialized buffer is 4u8. The name and entry_point are serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#string-clvalue-string"},"String")," CLValue, with the version field serializing as an ",(0,l.kt)("a",{parentName:"p",href:"#option-clvalue-option"},"Option"),"."),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},'StoredVersionedContractByName { name: "lWJWKdZUEudSakJzw1tn", version: Some(1632552656), entry_point: "S1cXRT3E1jyFlWBAIVQ8", args: 9975e6957ea6b07176c7d8471478fb28df9f02a61689ef58234b1a3cffaebf9f303e3ef60ae0d8 }')),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"0x04140000006c574a574b645a5545756453616b4a7a7731746e01d0c64e61140000005331635852543345316a79466c57424149565138270000009975e6957ea6b07176c7d8471478fb28df9f02a61689ef58234b1a3cffaebf9f303e3ef60ae0d8")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"Transfer serializes such that the first byte within the serialized buffer contains is 5u8, with the remaining bytes of the buffer containing the bytes contained within the args field of Transfer."))),(0,l.kt)("h3",{id:"approval"},"Approval"),(0,l.kt)("p",null,"Approval contains two fields:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"signer"),": The public key of the approvals signer. It serializes to the byte representation of the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey"),". If the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," is an ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519")," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,l.kt)("inlineCode",{parentName:"li"},"Secp256k1"),", the first byte is 2."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"signature"),": The approval signature, which serializes as the byte representation of the ",(0,l.kt)("inlineCode",{parentName:"li"},"Signature"),". The first byte within the signature is 1 in the case of an ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519")," signature or 2 in the case of ",(0,l.kt)("inlineCode",{parentName:"li"},"Secp256k1"),".")),(0,l.kt)("h2",{id:"deployinfo"},"DeployInfo"),(0,l.kt)("p",null,"Information relating to a given deploy. The structure consists of the following fields:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"deploy_hash")," The hash of the relevant deploy, serialized as a byte representation of the hash itself.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"transfers")," Transfers performed by the deploy, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-list"},(0,l.kt)("inlineCode",{parentName:"a"},"List")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"from")," The account identifier of the creator of the deploy, serialized as an ",(0,l.kt)("a",{parentName:"p",href:"#account-hash"},(0,l.kt)("inlineCode",{parentName:"a"},"account_hash")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"source")," The source purse used for payment of the deploy, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-uref"},(0,l.kt)("inlineCode",{parentName:"a"},"URef")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"gas")," The gas cost of executing the deploy, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512")),"."))),(0,l.kt)("h2",{id:"digest"},"Digest"),(0,l.kt)("p",null,"A ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b")," hash digest. The digest serializes as a byte representation of the hash itself."),(0,l.kt)("h2",{id:"disabledversions"},"DisabledVersions"),(0,l.kt)("p",null,"Disabled contract versions, containing the following:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"contract_version")," The version of the contract within the protocol major version. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u32")," value"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"protocol_version_major")," The major element of the protocol version this contract is compatible with. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u32")," value"),"."))),(0,l.kt)("h2",{id:"entrypoint"},"EntryPoint"),(0,l.kt)("p",null,"A type of signature method. Order of arguments matters, since this can be referenced by index as well as name."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"name")," The name of the entry point, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-string"},(0,l.kt)("inlineCode",{parentName:"a"},"String")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"args")," Arguments for this method. They serialize as a list of the ",(0,l.kt)("a",{parentName:"p",href:"#parameter"},(0,l.kt)("inlineCode",{parentName:"a"},"Parameter")),"s, where each parameter represents an argument passed to the entrypoint.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"ret")," The return type of the method, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-unit"},(0,l.kt)("inlineCode",{parentName:"a"},"Unit")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"access")," An enum describing the possible access control options for a contract entry point. It serializes as a 1 for public or a 1 followed by a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-list"},(0,l.kt)("inlineCode",{parentName:"a"},"List"))," of authorized users.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"entry_point_type")," Identifies the type of entry point. It serializes as a ",(0,l.kt)("inlineCode",{parentName:"p"},"0")," for Session and a ",(0,l.kt)("inlineCode",{parentName:"p"},"1")," for Contract."))),(0,l.kt)("h2",{id:"eraid"},"EraID"),(0,l.kt)("p",null,"An Era ID newtype. It serializes as a single ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64")," value"),"."),(0,l.kt)("h2",{id:"erainfo"},"EraInfo"),(0,l.kt)("p",null,"Auction metadata, intended to be recorded each era. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-list"},(0,l.kt)("inlineCode",{parentName:"a"},"List"))," of ",(0,l.kt)("a",{parentName:"p",href:"#seigniorageallocation"},"seigniorage allocations"),"."),(0,l.kt)("h2",{id:"executioneffect"},"ExecutionEffect"),(0,l.kt)("p",null,"The journal of execution transforms from a single deploy."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"operations")," The resulting operations, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-list"},(0,l.kt)("inlineCode",{parentName:"a"},"List"))," of ",(0,l.kt)("a",{parentName:"p",href:"#operation"},"operations"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"transforms")," The actual ",(0,l.kt)("a",{parentName:"p",href:"#transform"},"transformation")," performed while executing a deploy."))),(0,l.kt)("h2",{id:"executionresult"},"ExecutionResult"),(0,l.kt)("p",null,"The result of a single deploy. It serializes as a ",(0,l.kt)("inlineCode",{parentName:"p"},"u8")," tag indicating either ",(0,l.kt)("inlineCode",{parentName:"p"},"Failure")," as a 0 or ",(0,l.kt)("inlineCode",{parentName:"p"},"Success")," as a 1. This is followed by the appropriate structure below:"),(0,l.kt)("h3",{id:"failure"},(0,l.kt)("inlineCode",{parentName:"h3"},"Failure")),(0,l.kt)("p",null,"The result of a failed execution."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"effect")," The ",(0,l.kt)("a",{parentName:"p",href:"#executioneffect"},"effect")," of executing the deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"transfers")," A record of transfers performed while executing the deploy, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-list"},(0,l.kt)("inlineCode",{parentName:"a"},"List")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"cost")," The cost of executing the deploy, serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512"))," value.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"error_message")," The error message associated with executing the deploy, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-string"},(0,l.kt)("inlineCode",{parentName:"a"},"String")),"."))),(0,l.kt)("h3",{id:"success"},(0,l.kt)("inlineCode",{parentName:"h3"},"Success")),(0,l.kt)("p",null,"The result of a successful execution."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"effect")," The ",(0,l.kt)("a",{parentName:"p",href:"#executioneffect"},"effect")," of executing the deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"transfers")," A record of transfers performed while executing the deploy, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-list"},(0,l.kt)("inlineCode",{parentName:"a"},"List")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"cost")," The cost of executing the deploy, serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512"))," value."))),(0,l.kt)("h2",{id:"group"},"Group"),(0,l.kt)("p",null,'A (labeled) "user group". Each method of a versioned contract may be associated with one or more user groups which are allowed to call it. User groups are serialized as a ',(0,l.kt)("a",{parentName:"p",href:"#clvalue-string"},"String"),"."),(0,l.kt)("h2",{id:"groups"},"Groups"),(0,l.kt)("p",null,"They are serialized as a ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeMap")," where the first 4 bytes represent a ",(0,l.kt)("inlineCode",{parentName:"p"},"u32")," value describing the number of user groups and ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeSets")," of ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-uref"},(0,l.kt)("inlineCode",{parentName:"a"},"URef")),"s held within. The remainder consists of a repeating pattern of serialized user groups and ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeSets")," of the length dictated by the first four bytes."),(0,l.kt)("h2",{id:"serialization-standard-state-keys"},"Keys"),(0,l.kt)("p",null,'In this chapter, we describe what constitutes a "key", the permissions model for the keys, and how they are serialized.'),(0,l.kt)("p",null,"A ",(0,l.kt)("em",{parentName:"p"},"key")," in ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#global-state-head"},"Global State")," is one of the following data types:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},'32-byte account identifier (called an "account identity key")'),(0,l.kt)("li",{parentName:"ul"},'32-byte immutable contract identifier (called a "hash key")'),(0,l.kt)("li",{parentName:"ul"},'32-byte reference identifier (called an "unforgeable reference")'),(0,l.kt)("li",{parentName:"ul"},"32-byte transfer identifier"),(0,l.kt)("li",{parentName:"ul"},"32-byte deploy information identifier"),(0,l.kt)("li",{parentName:"ul"},"32-byte purse balance identifier"),(0,l.kt)("li",{parentName:"ul"},"32-byte Auction bid identifier"),(0,l.kt)("li",{parentName:"ul"},"32-byte Auction withdrawal identifier"),(0,l.kt)("li",{parentName:"ul"},"32-byte Dictionary identifier"),(0,l.kt)("li",{parentName:"ul"},"32-byte System Contract Registry"),(0,l.kt)("li",{parentName:"ul"},"32-byte Auction unbond identifier"),(0,l.kt)("li",{parentName:"ul"},"32-byte Chainspec Registry")),(0,l.kt)("p",null,"The one exception to note here is the identifier for ",(0,l.kt)("a",{parentName:"p",href:"#erainfo"},(0,l.kt)("inlineCode",{parentName:"a"},"EraInfo")),", which actually serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64"))," value with an additional byte for the tag."),(0,l.kt)("h3",{id:"global-state-account-key"},"Account identity key"),(0,l.kt)("p",null,"This key type is used specifically for accounts in the global state. All accounts in the system must be stored under an account identity key, and no other types. The 32-byte identifier which represents this key is derived from the ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the public key used to create the associated account (see ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-associated-keys-weights"},"Accounts")," for more information)."),(0,l.kt)("h3",{id:"serialization-standard-hash-key"},"Hash key"),(0,l.kt)("p",null,"This key type is used for storing contracts immutably. Once a contract is written under a hash key, that contract can never change. The 32-byte identifier representing this key is derived from the ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the deploy hash (see ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#block-structure-head"},"block-structure-head")," for more information) concatenated with a 4-byte sequential ID. The ID begins at zero for each deploy and increments by one each time a contract is stored. The purpose of this ID is to allow each contract stored in the same deploy to have a unique key."),(0,l.kt)("h3",{id:"serialization-standard-uref"},"Unforgeable Reference (",(0,l.kt)("inlineCode",{parentName:"h3"},"URef"),")"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"URef")," broadly speaking can be used to store values and manage permissions to interact with the value stored under the ",(0,l.kt)("inlineCode",{parentName:"p"},"URef"),". ",(0,l.kt)("inlineCode",{parentName:"p"},"URef")," is a tuple which contains the address under which the values are stored and the Access rights to the ",(0,l.kt)("inlineCode",{parentName:"p"},"URef"),". Refer to the ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#uref-head"},"Unforgeable Reference")," section for details on how ",(0,l.kt)("inlineCode",{parentName:"p"},"URefs")," are managed."),(0,l.kt)("h3",{id:"serialization-standard-transfer-key"},"Transfer Key"),(0,l.kt)("p",null,"This key type is used specifically for transfers in the global state. All transfers in the system must be stored under a transfer key and no other type. The 32-byte identifier which represents this key is derived from the ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the transfer address associated with the given transfer"),(0,l.kt)("h3",{id:"serialization-standard-deploy-info-key"},"DeployInfo Key"),(0,l.kt)("p",null,"This key type is used specifically for storing information related to deploys in the global state. Information for a given deploy is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the deploy itself."),(0,l.kt)("h3",{id:"serialization-standard-era-info-key"},"EraInfo Key"),(0,l.kt)("p",null,"This key type is used specifically for storing information related to the ",(0,l.kt)("inlineCode",{parentName:"p"},"Auction")," metadata for a particular era. The underlying data type stored under this is a vector of the allocation of seigniorage for that given era. The identifier for this key is a new type that wraps around the primitive ",(0,l.kt)("inlineCode",{parentName:"p"},"u64")," data type and co-relates to the era number when the auction information was stored."),(0,l.kt)("p",null,"This key type is used specifically for storing information related to auction bids in the global state. Information for the bids is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the public key used to create the associated account (see ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-associated-keys-weights"},"Accounts")," for more information)."),(0,l.kt)("p",null,"This key type is used specifically for storing information related to auction withdraws in the global state. Information for the withdrawals is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the public key used to create the associated account (see ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-associated-keys-weights"},"Accounts")," for more information)."),(0,l.kt)("h3",{id:"serialization-standard-serialization-key"},"Serialization for ",(0,l.kt)("inlineCode",{parentName:"h3"},"Key")),(0,l.kt)("p",null,"Given the different variants for the over-arching ",(0,l.kt)("inlineCode",{parentName:"p"},"Key")," data-type, each of the different variants is serialized differently. This section of this chapter details how the individual variants are serialized. The leading byte of the serialized buffer acts as a tag indicating the serialized variant."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"th"},"Key")),(0,l.kt)("th",{parentName:"tr",align:null},"Serialization Tag"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Account")),(0,l.kt)("td",{parentName:"tr",align:null},"0")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Hash")),(0,l.kt)("td",{parentName:"tr",align:null},"1")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"URef")),(0,l.kt)("td",{parentName:"tr",align:null},"2")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Transfer")),(0,l.kt)("td",{parentName:"tr",align:null},"3")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"DeployInfo")),(0,l.kt)("td",{parentName:"tr",align:null},"4")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"EraInfo")),(0,l.kt)("td",{parentName:"tr",align:null},"5")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Balance")),(0,l.kt)("td",{parentName:"tr",align:null},"6")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Bid")),(0,l.kt)("td",{parentName:"tr",align:null},"7")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Withdraw")),(0,l.kt)("td",{parentName:"tr",align:null},"8")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Dictionary")),(0,l.kt)("td",{parentName:"tr",align:null},"9")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"SystemContractRegistry")),(0,l.kt)("td",{parentName:"tr",align:null},"10")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Unbond")),(0,l.kt)("td",{parentName:"tr",align:null},"11")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"ChainspecRegistry")),(0,l.kt)("td",{parentName:"tr",align:null},"12")))),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Account")," serializes as a 32 byte long buffer containing the byte representation of the underlying ",(0,l.kt)("inlineCode",{parentName:"li"},"AccountHash")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Hash")," serializes as a 32 byte long buffer containing the byte representation of the underlying ",(0,l.kt)("inlineCode",{parentName:"li"},"Hash")," itself."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"URef")," is a tuple that contains the address of the URef and the access rights to that ",(0,l.kt)("inlineCode",{parentName:"li"},"URef"),". The serialized representation of the ",(0,l.kt)("inlineCode",{parentName:"li"},"URef")," is 33 bytes long. The first 32 bytes are the byte representation of the ",(0,l.kt)("inlineCode",{parentName:"li"},"URef")," address, and the last byte contains the bits corresponding to the access rights of the ",(0,l.kt)("inlineCode",{parentName:"li"},"URef"),". Refer to the ",(0,l.kt)("a",{parentName:"li",href:"#serialization-standard-values"},"CLValue")," section of this chapter for details on how ",(0,l.kt)("inlineCode",{parentName:"li"},"AccessRights")," are serialized."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Transfer")," serializes as a 32 byte long buffer containing the byte representation of the hash of the transfer."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"DeployInfo")," serializes as 32 byte long buffer containing the byte representation of the Deploy hash. See the Deploy section above for how Deploy hashes are serialized."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"EraInfo")," serializes a ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," primitive type containing the little-endian byte representation of ",(0,l.kt)("inlineCode",{parentName:"li"},"u64"),"."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Balance")," serializes as 32 byte long buffer containing the byte representation of the URef address."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Bid")," and ",(0,l.kt)("inlineCode",{parentName:"li"},"Withdraw")," both contain the ",(0,l.kt)("inlineCode",{parentName:"li"},"AccountHash")," as their identifier; therefore, they serialize in the same manner as the ",(0,l.kt)("inlineCode",{parentName:"li"},"Account")," variant."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Dictionary")," as the 32 byte long buffer containing the byte representation of the seed URef hashed with the identifying name of the dictionary item."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"SystemContractRegistry")," as a 32 byte long buffer of zeros."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Unbond")," contains the ",(0,l.kt)("inlineCode",{parentName:"li"},"AccountHash")," as its identifier; therefore, it serialize in the same manner as the ",(0,l.kt)("inlineCode",{parentName:"li"},"Account")," variant."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"ChainspecRegistry")," as a 32 byte long buffer of ones.")),(0,l.kt)("h2",{id:"serialization-standard-permissions"},"Permissions"),(0,l.kt)("p",null,"There are three types of actions that can be done on a value: read, write, add. The reason for ",(0,l.kt)("em",{parentName:"p"},"add")," to be called out separately from ",(0,l.kt)("em",{parentName:"p"},"write")," is to allow for commutativity checking. The available actions depend on the key type and the context. Some key types only allow controlled access by smart contracts via the contract API, and other key types refer to values produced and used by the system itself and are not accessible to smart contracts at all but can be read via off-chain queries. This is summarized in the table below:"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Key"),(0,l.kt)("th",{parentName:"tr",align:null},"Type Available Actions"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Account"),(0,l.kt)("td",{parentName:"tr",align:null},"Read + Add (via API)")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Hash"),(0,l.kt)("td",{parentName:"tr",align:null},"Read")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"URef"),(0,l.kt)("td",{parentName:"tr",align:null},"Read + Write and/or Add")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Transfer"),(0,l.kt)("td",{parentName:"tr",align:null},"System")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Deploy"),(0,l.kt)("td",{parentName:"tr",align:null},"System")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"EraInfo"),(0,l.kt)("td",{parentName:"tr",align:null},"System")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Balance"),(0,l.kt)("td",{parentName:"tr",align:null},"Read (via API)")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Bid"),(0,l.kt)("td",{parentName:"tr",align:null},"System")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Withdraw"),(0,l.kt)("td",{parentName:"tr",align:null},"System")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Dictionary"),(0,l.kt)("td",{parentName:"tr",align:null},"Read (via API)")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"SystemContractRegistry"),(0,l.kt)("td",{parentName:"tr",align:null},"Read (via API)")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Unbond"),(0,l.kt)("td",{parentName:"tr",align:null},"System")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ChainspecRegistry"),(0,l.kt)("td",{parentName:"tr",align:null},"Read (via API)")))),(0,l.kt)("hr",null),(0,l.kt)("p",null,"Refer to ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#uref-permissions"},"URef permissions")," on how permissions are handled in the case of ",(0,l.kt)("inlineCode",{parentName:"p"},"URef"),"s."),(0,l.kt)("h2",{id:"namedarg"},"NamedArg"),(0,l.kt)("p",null,"Named arguments to a contract. It is serialized by the combination of a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-string"},(0,l.kt)("inlineCode",{parentName:"a"},"String"))," followed by the associated ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-clvalue"},(0,l.kt)("inlineCode",{parentName:"a"},"CLValue")),"."),(0,l.kt)("h2",{id:"namedkey"},"NamedKey"),(0,l.kt)("p",null,"A mapping of string identifiers to a Casper ",(0,l.kt)("inlineCode",{parentName:"p"},"Key")," type. It is serialized as a ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeMap")," where the first 4 bytes represent a ",(0,l.kt)("inlineCode",{parentName:"p"},"u32")," value describing the number of named keys and values held within. The remainder consists of a repeating pattern of serialized named keys and then values of the length dictated by the first four bytes."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"name")," The name of the entry. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-string"},(0,l.kt)("inlineCode",{parentName:"a"},"string")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key")," The value of the entry, which is a Casper ",(0,l.kt)("inlineCode",{parentName:"p"},"Key")," type."))),(0,l.kt)("p",null,"The named keys portion of the account structure serializes as a mapping of a string to Casper ",(0,l.kt)("inlineCode",{parentName:"p"},"Key")," values as described ",(0,l.kt)("a",{parentName:"p",href:"#serialization-standard-serialization-key"},"here"),"."),(0,l.kt)("h2",{id:"operation"},"Operation"),(0,l.kt)("p",null,"An operation performed while executing a deploy. It contains:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key")," The formatted string of the key, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-string"},(0,l.kt)("inlineCode",{parentName:"a"},"String")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"kind")," OpKind, The type of operation performed. It serializes as a single byte based on the following table:"))),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"OpKind"),(0,l.kt)("th",{parentName:"tr",align:null},"Serialization"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Read"),(0,l.kt)("td",{parentName:"tr",align:null},"0")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write"),(0,l.kt)("td",{parentName:"tr",align:null},"1")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Add"),(0,l.kt)("td",{parentName:"tr",align:null},"2")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"NoOp"),(0,l.kt)("td",{parentName:"tr",align:null},"3")))),(0,l.kt)("h2",{id:"parameter"},"Parameter"),(0,l.kt)("p",null,"Parameter to a method, structured as a name followed by a ",(0,l.kt)("inlineCode",{parentName:"p"},"CLType"),". It is serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-string"},(0,l.kt)("inlineCode",{parentName:"a"},"String"))," followed by a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-cltype"},(0,l.kt)("inlineCode",{parentName:"a"},"CLType")),"."),(0,l.kt)("h2",{id:"protocolversion"},"ProtocolVersion"),(0,l.kt)("p",null,"A newtype indicating the Casper Platform protocol version. It is serialized as three ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u32"))," values indicating major, minor and patch versions in that order."),(0,l.kt)("h2",{id:"publickey"},"PublicKey"),(0,l.kt)("p",null,"Hex-encoded cryptographic public key, including the algorithm tag prefix. Serialization can be found under ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),"."),(0,l.kt)("h2",{id:"runtimeargs"},"RuntimeArgs"),(0,l.kt)("p",null,"Represents a collection of arguments passed to a smart contract. They serialize as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-list"},(0,l.kt)("inlineCode",{parentName:"a"},"List"))," comprised of ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-tuple"},(0,l.kt)("inlineCode",{parentName:"a"},"Tuples")),"."),(0,l.kt)("h2",{id:"seigniorageallocation"},"SeigniorageAllocation"),(0,l.kt)("p",null,"Information about seigniorage allocation."),(0,l.kt)("p",null,"If the seigniorage allocation in question is for a validator, it serializes as the validator's ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey"))," followed by the ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512")," amount"),"."),(0,l.kt)("p",null,"If it is a delegator, it serializes as the delegator's ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),", followed by the validator's ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey"))," and finally the ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512")," amount"),"."),(0,l.kt)("h2",{id:"signature"},"Signature"),(0,l.kt)("p",null,"The signature serializes the byte representation of the underlying cryptographic primitive signature. The first byte within the signature is 1 in the case of an ",(0,l.kt)("inlineCode",{parentName:"p"},"Ed25519")," signature or 2 in the case of ",(0,l.kt)("inlineCode",{parentName:"p"},"Secp256k1"),"."),(0,l.kt)("h2",{id:"systemcontractregistry"},"SystemContractRegistry"),(0,l.kt)("p",null,"SystemContractRegistry is a unique ",(0,l.kt)("inlineCode",{parentName:"p"},"Key")," under which a mapping of the names and ",(0,l.kt)("inlineCode",{parentName:"p"},"ContractHashes")," for system contracts. This includes ",(0,l.kt)("inlineCode",{parentName:"p"},"Mint"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"Auction"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"HandlePayment")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"StandardPayment"),". It is serialized as a ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeMap")," where the first 4 bytes represent a ",(0,l.kt)("inlineCode",{parentName:"p"},"u32")," value describing the number of names as strings and ",(0,l.kt)("a",{parentName:"p",href:"#contracthash"},"ContractHashes")," held within. The remainder consists of a repeating pattern of serialized strings and then ContractHashes of the length dictated by the first four bytes."),(0,l.kt)("h2",{id:"timediff"},"TimeDiff"),(0,l.kt)("p",null,"A human-readable duration between two timestamps. It serializes as a single ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64"))," value."),(0,l.kt)("h2",{id:"timestamp"},"Timestamp"),(0,l.kt)("p",null,"A timestamp formatted as per RFC 3339 and serialized as a single ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64"))," value."),(0,l.kt)("h2",{id:"transferaddr"},"TransferAddr"),(0,l.kt)("p",null,"Hex-encoded transfer address, which serializes as a byte representation of itself."),(0,l.kt)("h2",{id:"transform"},"Transform"),(0,l.kt)("p",null,"The actual transformation performed while executing a deploy. It serializes as a single ",(0,l.kt)("inlineCode",{parentName:"p"},"u8")," value indicating the type of transform performed as per the following table. The remaining bytes represent the information and serialization as listed."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Transform Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Serialization"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Identity"),(0,l.kt)("td",{parentName:"tr",align:null},"0"),(0,l.kt)("td",{parentName:"tr",align:null},"A transform having no effect.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_CLValue"),(0,l.kt)("td",{parentName:"tr",align:null},"1"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes the given ",(0,l.kt)("a",{parentName:"td",href:"#clvalue-calvalue"},(0,l.kt)("inlineCode",{parentName:"a"},"CLValue"))," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Account"),(0,l.kt)("td",{parentName:"tr",align:null},"2"),(0,l.kt)("td",{parentName:"tr",align:null},"Write the given ",(0,l.kt)("a",{parentName:"td",href:"#account-hash"},(0,l.kt)("inlineCode",{parentName:"a"},"Account"))," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Contract_WASM"),(0,l.kt)("td",{parentName:"tr",align:null},"3"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes a smart ",(0,l.kt)("a",{parentName:"td",href:"#contractwasmhash"},"contract as Wasm")," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Contract"),(0,l.kt)("td",{parentName:"tr",align:null},"4"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes a smart ",(0,l.kt)("a",{parentName:"td",href:"#contracthash"},"contract")," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Contract_Package"),(0,l.kt)("td",{parentName:"tr",align:null},"5"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes a smart ",(0,l.kt)("a",{parentName:"td",href:"#contractpackagehash"},"contract package")," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Deploy_Info"),(0,l.kt)("td",{parentName:"tr",align:null},"6"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes the given ",(0,l.kt)("a",{parentName:"td",href:"#deployinfo"},(0,l.kt)("inlineCode",{parentName:"a"},"DeployInfo"))," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Transfer"),(0,l.kt)("td",{parentName:"tr",align:null},"7"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes the given ",(0,l.kt)("a",{parentName:"td",href:"#transferaddr"},"Transfer")," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Era_Info"),(0,l.kt)("td",{parentName:"tr",align:null},"8"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes the given ",(0,l.kt)("a",{parentName:"td",href:"#erainfo"},(0,l.kt)("inlineCode",{parentName:"a"},"EraInfo"))," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Bid"),(0,l.kt)("td",{parentName:"tr",align:null},"9"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes the given ",(0,l.kt)("a",{parentName:"td",href:"#bid"},(0,l.kt)("inlineCode",{parentName:"a"},"Bid"))," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Withdraw"),(0,l.kt)("td",{parentName:"tr",align:null},"10"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes the given ",(0,l.kt)("a",{parentName:"td",href:"#unbondingpurse"},"Withdraw")," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Add_INT32"),(0,l.kt)("td",{parentName:"tr",align:null},"11"),(0,l.kt)("td",{parentName:"tr",align:null},"Adds the given ",(0,l.kt)("a",{parentName:"td",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"i32")),".")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Add_UINT64"),(0,l.kt)("td",{parentName:"tr",align:null},"12"),(0,l.kt)("td",{parentName:"tr",align:null},"Adds the given ",(0,l.kt)("a",{parentName:"td",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64")),".")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Add_UINT128"),(0,l.kt)("td",{parentName:"tr",align:null},"13"),(0,l.kt)("td",{parentName:"tr",align:null},"Adds the given ",(0,l.kt)("a",{parentName:"td",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U128")),".")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Add_UINT256"),(0,l.kt)("td",{parentName:"tr",align:null},"14"),(0,l.kt)("td",{parentName:"tr",align:null},"Adds the given ",(0,l.kt)("a",{parentName:"td",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U256")),".")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Add_UINT512"),(0,l.kt)("td",{parentName:"tr",align:null},"15"),(0,l.kt)("td",{parentName:"tr",align:null},"Adds the given ",(0,l.kt)("a",{parentName:"td",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512")),".")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Add_Keys"),(0,l.kt)("td",{parentName:"tr",align:null},"16"),(0,l.kt)("td",{parentName:"tr",align:null},"Adds the given collection of ",(0,l.kt)("a",{parentName:"td",href:"#namedkey"},"named keys"),".")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Failure"),(0,l.kt)("td",{parentName:"tr",align:null},"17"),(0,l.kt)("td",{parentName:"tr",align:null},"A failed transformation, containing an error message.")))),(0,l.kt)("h2",{id:"transformentry"},"TransformEntry"),(0,l.kt)("p",null,"A transformation performed while executing a deploy."),(0,l.kt)("h2",{id:"unbondingpurse"},"UnbondingPurse"),(0,l.kt)("p",null,"A purse used for unbonding. The structure consists of the following:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"bonding_purse")," The bonding purse, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-uref"},(0,l.kt)("inlineCode",{parentName:"a"},"URef")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"validator_public_key")," The public key of the validator, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"unbonder_public_key")," The public key of the unbonder, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"era_of_creation")," Era in which this unbonding request was created, as an ",(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"EraId"))," newtype, which serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64"))," value.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"amount")," The unbonding amount, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512"))," value.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"new_validator")," The validator public key to redelegate to, serialized as an ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-option"},(0,l.kt)("inlineCode",{parentName:"a"},"Option"))," containing the public key."))),(0,l.kt)("h2",{id:"serialization-standard-values"},"Values"),(0,l.kt)("p",null,"A value stored in the global state is a ",(0,l.kt)("inlineCode",{parentName:"p"},"StoredValue"),". A ",(0,l.kt)("inlineCode",{parentName:"p"},"StoredValue")," is one of three possible variants:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"A ",(0,l.kt)("inlineCode",{parentName:"li"},"CLValue")),(0,l.kt)("li",{parentName:"ul"},"A contract"),(0,l.kt)("li",{parentName:"ul"},"An account")),(0,l.kt)("p",null,"We discuss ",(0,l.kt)("inlineCode",{parentName:"p"},"CLValue")," and contract in more detail below. Details about accounts can be found in ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-head"},"accounts-head"),"."),(0,l.kt)("p",null,"Each ",(0,l.kt)("inlineCode",{parentName:"p"},"StoredValue")," is serialized when written to the global state. The serialization format consists of a single byte tag, indicating which variant of ",(0,l.kt)("inlineCode",{parentName:"p"},"StoredValue")," it is, followed by the serialization of that variant. The tag for each variant is as follows:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"CLValue")," is ",(0,l.kt)("inlineCode",{parentName:"li"},"0")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Account")," is ",(0,l.kt)("inlineCode",{parentName:"li"},"1")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Contract")," is ",(0,l.kt)("inlineCode",{parentName:"li"},"2"))),(0,l.kt)("p",null,"The details of ",(0,l.kt)("inlineCode",{parentName:"p"},"CLType")," serialization are in the following section. Using the serialization format for ",(0,l.kt)("inlineCode",{parentName:"p"},"CLValue")," as a basis, we can succinctly write the serialization rules for contracts and accounts:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"contracts serialize in the same way as data with ",(0,l.kt)("inlineCode",{parentName:"li"},"CLType")," equal to ",(0,l.kt)("inlineCode",{parentName:"li"},"Tuple3(List(U8), Map(String, Key), Tuple3(U32, U32, U32))"),";"),(0,l.kt)("li",{parentName:"ul"},"accounts serialize in the same way as data with ",(0,l.kt)("inlineCode",{parentName:"li"},"CLType")," equal to ",(0,l.kt)("inlineCode",{parentName:"li"},"Tuple5(ByteArray(U8, 32), Map(String, Key), URef, Map(ByteArray(U8, 32), U8), Tuple2(U8, U8))"),".")),(0,l.kt)("p",null,"Note: ",(0,l.kt)("inlineCode",{parentName:"p"},"Tuple5")," is not a presently supported ",(0,l.kt)("inlineCode",{parentName:"p"},"CLType"),". However, it is clear how to generalize the rules for ",(0,l.kt)("inlineCode",{parentName:"p"},"Tuple1"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"Tuple2"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"Tuple3")," to any size tuple."),(0,l.kt)("h3",{id:"clvalue"},(0,l.kt)("inlineCode",{parentName:"h3"},"CLValue")),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"CLValue")," is used to describe data that is used by smart contracts. This could be as a local state variable, input argument, or return value. A ",(0,l.kt)("inlineCode",{parentName:"p"},"CLValue")," consists of two parts: a ",(0,l.kt)("inlineCode",{parentName:"p"},"CLType")," describing the type of the value and an array of bytes representing the data in our serialization format."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"CLType")," is described by the following recursive data type:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-rust"},'enum CLType {\n Bool, // boolean primitive\n I32, // signed 32-bit integer primitive\n I64, // signed 64-bit integer primitive\n U8, // unsigned 8-bit integer primitive\n U32, // unsigned 32-bit integer primitive\n U64, // unsigned 64-bit integer primitive\n U128, // unsigned 128-bit integer primitive\n U256, // unsigned 256-bit integer primitive\n U512, // unsigned 512-bit integer primitive\n Unit, // singleton value without additional semantics\n String, // e.g. "Hello, World!"\n URef, // unforgeable reference (see above)\n Key, // global state key (see above)\n PublicKey // A Casper system PublicKey type\n Option(CLType), // optional value of the given type\n List(CLType), // list of values of the given type (e.g. Vec in rust)\n ByteArray(CLType, u32), // same as `List` above, but number of elements\n // is statically known (e.g. arrays in rust)\n Result(CLType, CLType), // co-product of the given types;\n // one variant meaning success, the other failure\n Map(CLType, CLType), // key-value association where keys and values have the given types\n Tuple1(CLType), // single value of the given type\n Tuple2(CLType, CLType), // pair consisting of elements of the given types\n Tuple3(CLType, CLType, CLType), // triple consisting of elements of the given types\n Any // Indicates the type is not known\n}\n')),(0,l.kt)("p",null,"All data which can be assigned a (non-",(0,l.kt)("inlineCode",{parentName:"p"},"Any"),") ",(0,l.kt)("inlineCode",{parentName:"p"},"CLType")," can be serialized according to the following rules (this defines the Casper serialization format):"),(0,l.kt)("h4",{id:"clvalue-boolean"},"Boolean"),(0,l.kt)("p",null,"Boolean values serialize as a single byte; ",(0,l.kt)("inlineCode",{parentName:"p"},"true")," maps to ",(0,l.kt)("inlineCode",{parentName:"p"},"1"),", while ",(0,l.kt)("inlineCode",{parentName:"p"},"false")," maps to ",(0,l.kt)("inlineCode",{parentName:"p"},"0"),"."),(0,l.kt)("h4",{id:"clvalue-numeric"},"Numeric"),(0,l.kt)("p",null,"Numeric values consisting of 64 bits or less serialize in the two's complement representation with little-endian byte order, and the appropriate number of bytes for the bit-width."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"p"},"7u8")," serializes as ",(0,l.kt)("inlineCode",{parentName:"p"},"0x07"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"p"},"7u32")," serializes as ",(0,l.kt)("inlineCode",{parentName:"p"},"0x07000000"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"p"},"1024u32")," serializes as ",(0,l.kt)("inlineCode",{parentName:"p"},"0x00040000"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"Wider numeric values (i.e. ",(0,l.kt)("inlineCode",{parentName:"p"},"U128"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"U256"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"U512"),") serialize as one byte given the length of the next number (in bytes), followed by the two's complement representation with little-endian byte order. The number of bytes should be chosen as small as possible to represent the given number. This is done to reduce the serialization size when small numbers are represented within a wide data type.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"p"},"U512::from(7)")," serializes as ",(0,l.kt)("inlineCode",{parentName:"p"},"0x0107"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"p"},"U512::from(1024)")," serializes as ",(0,l.kt)("inlineCode",{parentName:"p"},"0x020004"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"p"},'U512::from("123456789101112131415")')," serializes as ",(0,l.kt)("inlineCode",{parentName:"p"},"0x0957ff1ada959f4eb106")))),(0,l.kt)("h4",{id:"clvalue-unit"},"Unit"),(0,l.kt)("p",null,"Unit serializes to an empty byte array."),(0,l.kt)("h4",{id:"clvalue-string"},"String"),(0,l.kt)("p",null,"Strings serialize as a 32-bit integer representing the length in bytes (note: this might be different than the number of characters since special characters, such as emojis, take more than one byte), followed by the UTF-8 encoding of the characters in the string."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"li"},'"Hello, World!"')," serializes as ",(0,l.kt)("inlineCode",{parentName:"li"},"0x0d00000048656c6c6f2c20576f726c6421"))),(0,l.kt)("h4",{id:"clvalue-option"},"Option"),(0,l.kt)("p",null,"Optional values serialize with a single byte tag, followed by the serialization of the value itself. The tag is equal to ",(0,l.kt)("inlineCode",{parentName:"p"},"0")," if the value is missing, and ",(0,l.kt)("inlineCode",{parentName:"p"},"1")," if it is present."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"li"},"None")," serializes as ",(0,l.kt)("inlineCode",{parentName:"li"},"0x00")),(0,l.kt)("li",{parentName:"ul"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"li"},"Some(10u32)")," serializes as ",(0,l.kt)("inlineCode",{parentName:"li"},"0x010a000000"))),(0,l.kt)("h4",{id:"clvalue-list"},"List"),(0,l.kt)("p",null,"A list of values serializes as a 32-bit integer representing the number of elements in the list (note this differs from strings where it gives the number of ",(0,l.kt)("em",{parentName:"p"},"bytes"),"), followed by the concatenation of each serialized element."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"li"},"List()")," serializes as ",(0,l.kt)("inlineCode",{parentName:"li"},"0x00000000")),(0,l.kt)("li",{parentName:"ul"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"li"},"List(1u32, 2u32, 3u32)")," serializes as ",(0,l.kt)("inlineCode",{parentName:"li"},"0x03000000010000000200000003000000"))),(0,l.kt)("h4",{id:"clvalue-ByteArray"},"ByteArray"),(0,l.kt)("p",null,"A fixed-length list of values serializes as the concatenation of the serialized elements. Unlike a variable-length list, the length is not included in the serialization because it is statically known by the type of the value."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"li"},"[1u32, 2u32, 3u32]")," serializes as ",(0,l.kt)("inlineCode",{parentName:"li"},"0x010000000200000003000000"))),(0,l.kt)("h4",{id:"clvalue-result"},"Result"),(0,l.kt)("p",null,"A ",(0,l.kt)("inlineCode",{parentName:"p"},"Result")," serializes as a single byte tag followed by the serialization of the contained value. The tag is equal to ",(0,l.kt)("inlineCode",{parentName:"p"},"1")," for the success variant and ",(0,l.kt)("inlineCode",{parentName:"p"},"0")," for the error variant."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},'- E.g. `Ok(314u64)` serializes as `0x013a01000000000000`\n- E.g. `Err("Uh oh")` serializes as `0x00050000005568206f68`\n')),(0,l.kt)("h4",{id:"clvalue-tuple"},"Tuple"),(0,l.kt)("p",null,"Tuples serialize as the concatenation of their serialized elements. Similar to ",(0,l.kt)("inlineCode",{parentName:"p"},"ByteArray")," the number of elements is not included in the serialization because it is statically known in the type."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},'- E.g. `(1u32, "Hello, World!", true)` serializes as `0x010000000d00000048656c6c6f2c20576f726c642101`\n')),(0,l.kt)("h4",{id:"clvalue-map"},"Map"),(0,l.kt)("p",null,"A ",(0,l.kt)("inlineCode",{parentName:"p"},"Map")," serializes as a list of key-value tuples. There must be a well-defined ordering on the keys, and in the serialization, the pairs are listed in ascending order. This is done to ensure determinism in the serialization, as ",(0,l.kt)("inlineCode",{parentName:"p"},"Map")," data structures can be unordered."),(0,l.kt)("h4",{id:"clvalue-uref"},"URef"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"URef")," values serialize as the concatenation of its address (which is a fixed-length list of ",(0,l.kt)("inlineCode",{parentName:"p"},"u8"),") and a single byte tag representing the access rights. Access rights are converted as follows:"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Access Rights"),(0,l.kt)("th",{parentName:"tr",align:null},"Serialization"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"NONE")),(0,l.kt)("td",{parentName:"tr",align:null},"0")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"READ")),(0,l.kt)("td",{parentName:"tr",align:null},"1")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"WRITE")),(0,l.kt)("td",{parentName:"tr",align:null},"2")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"READ_WRITE")),(0,l.kt)("td",{parentName:"tr",align:null},"3")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"ADD")),(0,l.kt)("td",{parentName:"tr",align:null},"4")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"READ_ADD")),(0,l.kt)("td",{parentName:"tr",align:null},"5")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"ADD_WRITE")),(0,l.kt)("td",{parentName:"tr",align:null},"6")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"READ_ADD_WRITE")),(0,l.kt)("td",{parentName:"tr",align:null},"7")))),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"- E.g. `uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-007` shows a `URef` with full `READ_ADD_WRITE` rights.\n")),(0,l.kt)("admonition",{type:"warning"},(0,l.kt)("p",{parentName:"admonition"},"When passing a URef to another entity on chain, you must ensure that the ",(0,l.kt)("inlineCode",{parentName:"p"},"AccessRights")," are set correctly. If the URef represents a ",(0,l.kt)("a",{parentName:"p",href:"/concepts/glossary/P#purse-purse"},"purse"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"AccessRights")," impact who can deposit and withdraw CSPR.")),(0,l.kt)("p",null,"If a passed URef contains ",(0,l.kt)("inlineCode",{parentName:"p"},"ADD")," permissions, the entity receiving the URef will then be able to deposit CSPR into the associated purse. ",(0,l.kt)("inlineCode",{parentName:"p"},"WRITE")," permissions allow for withdrawing CSPR. As of 1.4.5, passing a main purse URef as a runtime argument will cause the host to automatically remove ",(0,l.kt)("inlineCode",{parentName:"p"},"WRITE")," permissions. In this event, ",(0,l.kt)("inlineCode",{parentName:"p"},"READ")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"ADD")," permissions will remain. Regardless, all due diligence should be performed to avoid passing a URef with ",(0,l.kt)("inlineCode",{parentName:"p"},"WRITE")," permissions unintentionally."),(0,l.kt)("h4",{id:"clvalue-publickey"},"PublicKey"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"PublicKey")," serializes as a single byte tag representing the algorithm followed by 32 bytes of the ",(0,l.kt)("inlineCode",{parentName:"p"},"PublicKey")," itself:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"If the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," is a ",(0,l.kt)("inlineCode",{parentName:"li"},"System")," key, the single tag byte is ",(0,l.kt)("inlineCode",{parentName:"li"},"0"),". With this variant, the single byte of ",(0,l.kt)("inlineCode",{parentName:"li"},"0")," is the entire key."),(0,l.kt)("li",{parentName:"ul"},"If the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," is an ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519")," key, the single tag byte is ",(0,l.kt)("inlineCode",{parentName:"li"},"1")," followed by the individual bytes of the serialized key."),(0,l.kt)("li",{parentName:"ul"},"If the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," is a ",(0,l.kt)("inlineCode",{parentName:"li"},"Secp256k1")," key, the single tag byte is a ",(0,l.kt)("inlineCode",{parentName:"li"},"2")," followed by the individual bytes of the serialized key.")),(0,l.kt)("h4",{id:"clvalue-key"},"Key"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"Key")," values serialize as a single byte tag representing the variant, followed by the serialization of the data that variant contains. For most variants, this is simply a fixed-length 32-byte array. The exception is ",(0,l.kt)("inlineCode",{parentName:"p"},"Key::URef"),", which contains a ",(0,l.kt)("inlineCode",{parentName:"p"},"URef"),"; so its data serializes per the description above. The tags are as follows: ",(0,l.kt)("inlineCode",{parentName:"p"},"Key::Account")," serializes as ",(0,l.kt)("inlineCode",{parentName:"p"},"0"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"Key::Hash")," as ",(0,l.kt)("inlineCode",{parentName:"p"},"1"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"Key::URef")," as ",(0,l.kt)("inlineCode",{parentName:"p"},"2"),"."),(0,l.kt)("h4",{id:"clvalue-cltype"},"CLType"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"CLType")," itself also has rules for serialization. A ",(0,l.kt)("inlineCode",{parentName:"p"},"CLType")," serializes as a single-byte tag, followed by the concatenation of serialized inner types, if any (e.g., lists and tuples have inner types). ",(0,l.kt)("inlineCode",{parentName:"p"},"ByteArray")," is a minor exception because it also includes the length in the type. However, the length is included in the serialization (as a 32-bit integer, per the serialization rules above), following the serialization of the inner type. The tags are as follows:"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"th"},"CLType")),(0,l.kt)("th",{parentName:"tr",align:null},"Serialization Tag"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Bool")),(0,l.kt)("td",{parentName:"tr",align:null},"0")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"I32")),(0,l.kt)("td",{parentName:"tr",align:null},"1")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"I64")),(0,l.kt)("td",{parentName:"tr",align:null},"2")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"U8")),(0,l.kt)("td",{parentName:"tr",align:null},"3")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"U32")),(0,l.kt)("td",{parentName:"tr",align:null},"4")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"U64")),(0,l.kt)("td",{parentName:"tr",align:null},"5")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"U128")),(0,l.kt)("td",{parentName:"tr",align:null},"6")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"U256")),(0,l.kt)("td",{parentName:"tr",align:null},"7")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"U512")),(0,l.kt)("td",{parentName:"tr",align:null},"8")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Unit")),(0,l.kt)("td",{parentName:"tr",align:null},"9")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"String")),(0,l.kt)("td",{parentName:"tr",align:null},"10")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Key")),(0,l.kt)("td",{parentName:"tr",align:null},"11")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"URef")),(0,l.kt)("td",{parentName:"tr",align:null},"12")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Option")),(0,l.kt)("td",{parentName:"tr",align:null},"13")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"List")),(0,l.kt)("td",{parentName:"tr",align:null},"14")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"ByteArray")),(0,l.kt)("td",{parentName:"tr",align:null},"15")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Result")),(0,l.kt)("td",{parentName:"tr",align:null},"16")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Map")),(0,l.kt)("td",{parentName:"tr",align:null},"17")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Tuple1")),(0,l.kt)("td",{parentName:"tr",align:null},"18")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Tuple2")),(0,l.kt)("td",{parentName:"tr",align:null},"19")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Tuple3")),(0,l.kt)("td",{parentName:"tr",align:null},"20")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Any")),(0,l.kt)("td",{parentName:"tr",align:null},"21")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"PublicKey")),(0,l.kt)("td",{parentName:"tr",align:null},"22")))),(0,l.kt)("h4",{id:"clvalue-clvalue"},"CLValue"),(0,l.kt)("p",null,"A complete ",(0,l.kt)("inlineCode",{parentName:"p"},"CLValue"),", including both the data and the type, can also be serialized (to store it in the global state). This is done by concatenating: the serialization of the length (as a 32-bit integer) of the serialized data (in bytes), the serialized data itself, and the serialization of the type."),(0,l.kt)("h3",{id:"global-state-contracts"},"Contracts"),(0,l.kt)("p",null,"Contracts are a special value type because they contain the on-chain logic of the applications running on a Casper network. A ",(0,l.kt)("em",{parentName:"p"},"contract")," contains the following data:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"a ",(0,l.kt)("a",{parentName:"li",href:"https://webassembly.github.io/spec/core/syntax/modules.html"},"wasm module")),(0,l.kt)("li",{parentName:"ul"},"a collection of named keys"),(0,l.kt)("li",{parentName:"ul"},"a protocol version")),(0,l.kt)("p",null,"The wasm module must contain a function named ",(0,l.kt)("inlineCode",{parentName:"p"},"call"),", which takes no arguments and returns no values. This is the main entry point into the contract. Moreover, the module may import any of the functions supported by the ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#execution-semantics-runtime"},"Casper runtime"),"."),(0,l.kt)("p",null,"Note: though the ",(0,l.kt)("inlineCode",{parentName:"p"},"call")," function signature has no arguments and no return value, within the ",(0,l.kt)("inlineCode",{parentName:"p"},"call")," function body, the ",(0,l.kt)("inlineCode",{parentName:"p"},"get_named_arg")," runtime function can be used to accept arguments (by ordinal), and the ",(0,l.kt)("inlineCode",{parentName:"p"},"ret")," runtime function can be used to return a single ",(0,l.kt)("inlineCode",{parentName:"p"},"CLValue")," to the caller."),(0,l.kt)("p",null,"The named keys are used to give human-readable names to keys in the global state, which are essential to the contract. For example, the hash key of another contract it frequently calls may be stored under a meaningful name. It is also used to store the ",(0,l.kt)("inlineCode",{parentName:"p"},"URef"),"s, which are known to the contract (see the section on Permissions for details)."),(0,l.kt)("p",null,"Each contract specifies the Casper protocol version that was active when the contract was written to the global state."),(0,l.kt)("h2",{id:"withdrawpurse"},"WithdrawPurse"),(0,l.kt)("p",null,"A purse used for unbonding, replaced in 1.5 by ",(0,l.kt)("a",{parentName:"p",href:"#unbondingpurse"},"UnbondingPurse"),". WithdrawPurses prior to 1.5 were known as UnbondingPurses and now consist of historical data."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"bonding_purse")," The bonding purse, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-uref"},(0,l.kt)("inlineCode",{parentName:"a"},"URef")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"validator_public_key")," The public key of the validator, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"unbonder_public_key")," The public key of the unbonder, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"era_of_creation")," Era in which this unbonding request was created, as an ",(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"EraId"))," newtype, which serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64"))," value.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"amount")," The unbonding amount, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512"))," value."))))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[8933],{3905:function(e,t,a){a.d(t,{Zo:function(){return d},kt:function(){return h}});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function r(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},d=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},k=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,l=e.originalType,s=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),m=p(a),k=i,h=m["".concat(s,".").concat(k)]||m[k]||u[k]||l;return a?n.createElement(h,r(r({ref:t},d),{},{components:a})):n.createElement(h,r({ref:t},d))}));function h(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var l=a.length,r=new Array(l);r[0]=k;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[m]="string"==typeof e?e:i,r[1]=o;for(var p=2;pFailure",id:"failure",level:3},{value:"Success",id:"success",level:3},{value:"Group",id:"group",level:2},{value:"Groups",id:"groups",level:2},{value:"Keys",id:"serialization-standard-state-keys",level:2},{value:"Account identity key",id:"global-state-account-key",level:3},{value:"Hash key",id:"serialization-standard-hash-key",level:3},{value:"Unforgeable Reference (URef)",id:"serialization-standard-uref",level:3},{value:"Transfer Key",id:"serialization-standard-transfer-key",level:3},{value:"DeployInfo Key",id:"serialization-standard-deploy-info-key",level:3},{value:"EraInfo Key",id:"serialization-standard-era-info-key",level:3},{value:"Serialization for Key",id:"serialization-standard-serialization-key",level:3},{value:"Permissions",id:"serialization-standard-permissions",level:2},{value:"NamedArg",id:"namedarg",level:2},{value:"NamedKey",id:"namedkey",level:2},{value:"Operation",id:"operation",level:2},{value:"Parameter",id:"parameter",level:2},{value:"ProtocolVersion",id:"protocolversion",level:2},{value:"PublicKey",id:"publickey",level:2},{value:"RuntimeArgs",id:"runtimeargs",level:2},{value:"SeigniorageAllocation",id:"seigniorageallocation",level:2},{value:"Signature",id:"signature",level:2},{value:"SystemContractRegistry",id:"systemcontractregistry",level:2},{value:"TimeDiff",id:"timediff",level:2},{value:"Timestamp",id:"timestamp",level:2},{value:"TransferAddr",id:"transferaddr",level:2},{value:"Transform",id:"transform",level:2},{value:"TransformEntry",id:"transformentry",level:2},{value:"UnbondingPurse",id:"unbondingpurse",level:2},{value:"Values",id:"serialization-standard-values",level:2},{value:"CLValue",id:"clvalue",level:3},{value:"Boolean",id:"clvalue-boolean",level:4},{value:"Numeric",id:"clvalue-numeric",level:4},{value:"Unit",id:"clvalue-unit",level:4},{value:"String",id:"clvalue-string",level:4},{value:"Option",id:"clvalue-option",level:4},{value:"List",id:"clvalue-list",level:4},{value:"ByteArray",id:"clvalue-ByteArray",level:4},{value:"Result",id:"clvalue-result",level:4},{value:"Tuple",id:"clvalue-tuple",level:4},{value:"Map",id:"clvalue-map",level:4},{value:"URef",id:"clvalue-uref",level:4},{value:"PublicKey",id:"clvalue-publickey",level:4},{value:"Key",id:"clvalue-key",level:4},{value:"CLType",id:"clvalue-cltype",level:4},{value:"CLValue",id:"clvalue-clvalue",level:4},{value:"Contracts",id:"global-state-contracts",level:3},{value:"WithdrawPurse",id:"withdrawpurse",level:2}],u={toc:m},k="wrapper";function h(e){var t=e.components,a=(0,i.Z)(e,r);return(0,l.kt)(k,(0,n.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"serialization-standard-head"},"Serialization Standard"),(0,l.kt)("p",null,"We provide a custom implementation to serialize data structures used by the Casper node to their byte representation. This document details how this custom serialization is implemented, allowing developers to build a library that implements the custom serialization."),(0,l.kt)("p",null,"In your smart contracts, you can implement serialization using ",(0,l.kt)("inlineCode",{parentName:"p"},"cltype-any"),"."),(0,l.kt)("h2",{id:"serialization-standard-account"},"Account"),(0,l.kt)("p",null,"An Account is a structure that represents a user on a Casper network. The account structure consists of the following fields:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#account-hash"},(0,l.kt)("inlineCode",{parentName:"a"},"account_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#namedkey"},(0,l.kt)("inlineCode",{parentName:"a"},"named_keys")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"main_purse")),(0,l.kt)("p",{parentName:"li"},"The account's main purse ",(0,l.kt)("inlineCode",{parentName:"p"},"URef"),". You may find information on ",(0,l.kt)("inlineCode",{parentName:"p"},"URef")," serialization ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-uref"},"here"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#associated-keys"},(0,l.kt)("inlineCode",{parentName:"a"},"associated_keys")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#action-thresholds"},(0,l.kt)("inlineCode",{parentName:"a"},"action_thresholds"))))),(0,l.kt)("h2",{id:"account-hash"},"Account Hash"),(0,l.kt)("p",null,"A ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b")," hash of the public key, representing the address of a user's account. The account hash serializes as a 32-byte buffer containing the bytes of the account hash."),(0,l.kt)("h2",{id:"action-thresholds"},"Action Thresholds"),(0,l.kt)("p",null,"The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as two consecutive ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u8")," values")," as follows."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"deployment")," The minimum weight threshold required to perform deployment actions as a ",(0,l.kt)("inlineCode",{parentName:"p"},"u8")," value.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key_management")," The minimum weight threshold required to perform key management actions as a ",(0,l.kt)("inlineCode",{parentName:"p"},"u8")," value."))),(0,l.kt)("h2",{id:"activation-point"},"Activation Point"),(0,l.kt)("p",null,"The first era to which the associated protocol version applies. It serializes as a single ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u8"))," tag indicating if the era in question is genesis. If it is the genesis era, the following bytes will be a ",(0,l.kt)("inlineCode",{parentName:"p"},"timestamp"),". If not, the bytes represent an ",(0,l.kt)("inlineCode",{parentName:"p"},"era_id"),"."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"era_id")," An ",(0,l.kt)("a",{parentName:"p",href:"#eraid"},"Era ID newtype")," identifying the era when the protocol version will activate.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"timestamp")," A ",(0,l.kt)("a",{parentName:"p",href:"#timestamp"},"timestamp")," if the activation point is of the Genesis variant."))),(0,l.kt)("h2",{id:"approval"},"Approval"),(0,l.kt)("p",null,"A struct containing a signature and the public key of the signer."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"signature")," The approval signature, which serializes as the byte representation of the ",(0,l.kt)("a",{parentName:"p",href:"#signature"},(0,l.kt)("inlineCode",{parentName:"a"},"Signature")),". The first byte within the signature is 1 in the case of an ",(0,l.kt)("inlineCode",{parentName:"p"},"Ed25519")," signature or 2 in the case of ",(0,l.kt)("inlineCode",{parentName:"p"},"Secp256k1"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"signer")," The public key of the approvals signer. It serializes to the byte representation of the ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),". If the ",(0,l.kt)("inlineCode",{parentName:"p"},"PublicKey")," is an ",(0,l.kt)("inlineCode",{parentName:"p"},"Ed25519")," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,l.kt)("inlineCode",{parentName:"p"},"Secp256k1"),", the first byte is 2."))),(0,l.kt)("h2",{id:"associatedkey"},"AssociatedKey"),(0,l.kt)("p",null,"A key granted limited permissions to an Account, for purposes such as multisig. It is serialized as a ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeMap")," where the first 4 bytes represent a ",(0,l.kt)("inlineCode",{parentName:"p"},"u32")," value describing the number of keys and weights held within. The remainder consists of a repeating pattern of serialized named keys and then weights of the length dictated by the first four bytes."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"account_hash")," The ",(0,l.kt)("a",{parentName:"p",href:"#account-hash"},"account hash")," of the associated key.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"weight")," The weight of an associated key. The weight serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u8")," value"),"."))),(0,l.kt)("h2",{id:"availableblockrange"},"AvailableBlockRange"),(0,l.kt)("p",null,"An unbroken, inclusive range of blocks. It serializes as two consecutive ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64")," values")," containing the following two fields:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"low")," The inclusive lower bound of the range.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"high")," - The inclusive upper bound of the range."))),(0,l.kt)("h2",{id:"bid"},"Bid"),(0,l.kt)("p",null,"An entry in the validator map. The structure consists of the following fields:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"validator_public_key")," The validator's public key. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"bonding_purse")," The purse used for bonding. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-uref"},(0,l.kt)("inlineCode",{parentName:"a"},"Uref")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"staked_amount")," The amount of tokens staked by a validator (not including delegators). It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512")," value"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"delegation_rate")," The delegation rate of the bid. It serializes as an ",(0,l.kt)("inlineCode",{parentName:"p"},"i32")," signed 32-bit integer primitive.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"vesting_schedule")," The vesting schedule for a genesis validator. ",(0,l.kt)("inlineCode",{parentName:"p"},"None")," if it is a non-genesis validator. It serializes as an ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-option"},(0,l.kt)("inlineCode",{parentName:"a"},"Option")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"delegators")," The validator's delegators, indexed by their public keys. They are serialized as a ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeMap")," where the first 4 bytes represent a ",(0,l.kt)("inlineCode",{parentName:"p"},"u32")," value describing the number of ",(0,l.kt)("inlineCode",{parentName:"p"},"PublicKey"),"s and delegators held within. The remainder consists of a repeating pattern of serialized ",(0,l.kt)("inlineCode",{parentName:"p"},"PublicKey"),"s and then delegators of the length dictated by the first four bytes.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"inactive")," If the validator has been evicted. A ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-boolean"},"boolean")," value that serializes as a single byte; ",(0,l.kt)("inlineCode",{parentName:"p"},"true")," maps to ",(0,l.kt)("inlineCode",{parentName:"p"},"1"),", while ",(0,l.kt)("inlineCode",{parentName:"p"},"false")," maps to ",(0,l.kt)("inlineCode",{parentName:"p"},"0"),"."))),(0,l.kt)("h2",{id:"serialization-standard-block"},"Block"),(0,l.kt)("p",null,"A block is the core component of the Casper linear blockchain, used in two contexts:"),(0,l.kt)("ol",null,(0,l.kt)("li",{parentName:"ol"},"A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain."),(0,l.kt)("li",{parentName:"ol"},"A message that is exchanged between nodes containing the data structure as explained in (1).")),(0,l.kt)("p",null,"Each block has a globally unique ID, achieved by hashing the contents of the block."),(0,l.kt)("p",null,"Each block points to its parent. An exception is the first block, which has no parent."),(0,l.kt)("p",null,"A block is structurally defined as follows:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"hash"),": A hash over the header of the block."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"header"),": The header of the block that contains information about the contents of the block with additional metadata."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"body"),": The block's body contains the proposer of the block and hashes of deploys and transfers contained within it.")),(0,l.kt)("h3",{id:"block-hash"},"Block hash"),(0,l.kt)("p",null,"The block hash is a ",(0,l.kt)("inlineCode",{parentName:"p"},"Digest")," over the contents of the block Header. The ",(0,l.kt)("inlineCode",{parentName:"p"},"BlockHash")," serializes as the byte representation of the hash itself."),(0,l.kt)("h3",{id:"block-header"},"Block header"),(0,l.kt)("p",null,"The header portion of a block, structurally, is defined as follows:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"parent_hash"),": is the hash of the parent block. It serializes to the byte representation of the parent hash. The serialized buffer of the ",(0,l.kt)("inlineCode",{parentName:"li"},"parent_hash")," is 32 bytes long."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"state_root_hash"),": is the global state root hash produced by executing this block's body. It serializes to the byte representation of the ",(0,l.kt)("inlineCode",{parentName:"li"},"state root hash"),". The serialized buffer of the ",(0,l.kt)("inlineCode",{parentName:"li"},"state_root_hash")," is 32 bytes long."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"body_hash"),": the hash of the block body. It serializes to the byte representation of the body hash. The serialized buffer of the ",(0,l.kt)("inlineCode",{parentName:"li"},"body_hash")," is 32 bytes long."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"random_bit"),": is a boolean needed for initializing a future era. It is serialized as a single byte; true maps to 1, while false maps to 0."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"accumulated_seed"),": A seed needed for initializing a future era. It serializes to the byte representation of the parent Hash. The serialized buffer of the ",(0,l.kt)("inlineCode",{parentName:"li"},"accumulated_hash")," is 32 bytes long."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"era_end"),": contains equivocation and reward information to be included in the terminal finalized block. It is an optional field. Thus if the field is set as ",(0,l.kt)("inlineCode",{parentName:"li"},"None"),", it serializes to ",(0,l.kt)("em",{parentName:"li"},"0"),". The serialization of the other case is described in the EraEnd."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"timestamp"),": The timestamp from when the block was proposed. It serializes as a single ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," value. The serialization of a ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," value is described in the CLValues section."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"era_id"),": Era ID in which this block was created. It serializes as a single ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," value."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"height"),": The height of this block, i.e., the number of ancestors. It serializes as a single ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," value."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"protocol_version"),": The version of the Casper network when this block was proposed. It is 3-element tuple containing ",(0,l.kt)("inlineCode",{parentName:"li"},"u32")," values. It serializes as a buffer containing the three ",(0,l.kt)("inlineCode",{parentName:"li"},"u32")," serialized values. Refer to the CLValues section on how ",(0,l.kt)("inlineCode",{parentName:"li"},"u32")," values are serialized.")),(0,l.kt)("h3",{id:"serialization-standard-era-end"},"EraEnd"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"EraEnd")," as represented within the block header, is a struct containing two fields."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"era_report"),": The first field is termed as ",(0,l.kt)("inlineCode",{parentName:"li"},"EraReport")," and contains information about equivocators and rewards for an era."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"next_era_validator_weights"),": The second field is map for the validators and their weights for the era to follow.")),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"EraReport")," itself contains two fields:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"equivocators"),": A vector of ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey"),"."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"rewards"),": A Binary Tree Map of ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," and ",(0,l.kt)("inlineCode",{parentName:"li"},"u64"),".")),(0,l.kt)("p",null,"When serializing an EraReport, the buffer is first filled with the individual serialization of the PublicKey contained within the vector."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"If the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," is an ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519")," key, the first byte within the buffer is a ",(0,l.kt)("inlineCode",{parentName:"li"},"1")," followed by the individual bytes of the serialized key."),(0,l.kt)("li",{parentName:"ul"},"If the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," is an ",(0,l.kt)("inlineCode",{parentName:"li"},"Secp256k1")," key, the first byte within the buffer is a ",(0,l.kt)("inlineCode",{parentName:"li"},"2")," followed by the individual bytes of the serialized key.")),(0,l.kt)("p",null,"When serializing the overarching struct of ",(0,l.kt)("inlineCode",{parentName:"p"},"EraEnd"),", we first allocate a buffer, which contains the serialized representation of the ",(0,l.kt)("inlineCode",{parentName:"p"},"EraReport")," as described above, followed by the serialized BTreeMap."),(0,l.kt)("p",null,"Note that ",(0,l.kt)("inlineCode",{parentName:"p"},"EraEnd")," is an optional field. Thus the above scheme only applies if there is an ",(0,l.kt)("inlineCode",{parentName:"p"},"EraEnd"),"; if there is no era end, the field simply serializes to ",(0,l.kt)("em",{parentName:"p"},"0"),"."),(0,l.kt)("h3",{id:"body"},"Body"),(0,l.kt)("p",null,"The body portion of the block is structurally defined as:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"proposer"),": The PublicKey which proposed this block."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"deploy_hashes"),": Is a vector of hex-encoded hashes identifying Deploys included in this block."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"transfer_hashes"),": Is a vector of hex-encoded hashes identifying Transfers included in this block.")),(0,l.kt)("p",null,"When we serialize the ",(0,l.kt)("inlineCode",{parentName:"p"},"BlockBody"),", we create a buffer that contains the serialized representations of the individual fields present within the block."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"proposer"),": serializes to the byte representation of the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey"),". If the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," is an ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519")," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,l.kt)("inlineCode",{parentName:"li"},"Secp256k1"),", the first byte is 2."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"deploy_hashes"),": serializes to the byte representation of all the deploy_hashes within the block header. Its length is ",(0,l.kt)("inlineCode",{parentName:"li"},"32 * n"),", where n denotes the number of deploy hashes present within the body."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"transfer_hashes"),": serializes to the byte representation of all the deploy_hashes within the block header. Its length is ",(0,l.kt)("inlineCode",{parentName:"li"},"32 * n"),", where n denotes the number of transfers present within the body.")),(0,l.kt)("h2",{id:"blockidentifier"},"BlockIdentifier"),(0,l.kt)("p",null,"Identifier for possible ways to retrieve a Block. It can consist of any of the following in most situations:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#block-hash"},(0,l.kt)("inlineCode",{parentName:"a"},"hash"))," Identify and retrieve a Block with its hash. The ",(0,l.kt)("inlineCode",{parentName:"p"},"BlockHash")," serializes as the byte representation of the hash itself.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"height")," Identify and retrieve the Block with its height. Height serializes as a single ",(0,l.kt)("inlineCode",{parentName:"p"},"u64")," value.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"state_root_hash")," Identify and retrieve the Block with its state root hash. It serializes to the byte representation of the ",(0,l.kt)("inlineCode",{parentName:"p"},"state root hash"),". The serialized buffer of the ",(0,l.kt)("inlineCode",{parentName:"p"},"state_root_hash")," is 32 bytes long."))),(0,l.kt)("h2",{id:"chainspecregistry"},"ChainspecRegistry"),(0,l.kt)("p",null,"ChainspecRegistry is a unique key variant which contains a mapping of file names to the hash of the file itself. This map includes ",(0,l.kt)("em",{parentName:"p"},"Chainspec.toml")," and may include ",(0,l.kt)("em",{parentName:"p"},"Accounts.toml")," and ",(0,l.kt)("em",{parentName:"p"},"GlobalState.toml"),". It is serialized as a ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeMap")," where the first 4 bytes represent a ",(0,l.kt)("inlineCode",{parentName:"p"},"u32")," value describing the number of names as strings and ",(0,l.kt)("a",{parentName:"p",href:"#digest"},"digests")," held within. The remainder consists of a repeating pattern of serialized strings and then digests of the length dictated by the first four bytes. Digests and their inclusion criteria are as follows:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"chainspec_raw_hash")," will always be included.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"genesis_accounts_raw_hash")," may be included in specific circumstances.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"global_state_raw_hash")," may be included in specific circumstances."))),(0,l.kt)("h2",{id:"contract"},"Contract"),(0,l.kt)("p",null,"A contract struct containing the following fields:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#contractpackagehash"},(0,l.kt)("inlineCode",{parentName:"a"},"contract_package_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#contractwasmhash"},(0,l.kt)("inlineCode",{parentName:"a"},"contract_wasm_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#namedkey"},(0,l.kt)("inlineCode",{parentName:"a"},"named_keys")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#entrypoint"},(0,l.kt)("inlineCode",{parentName:"a"},"entry_points")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#protocolversion"},(0,l.kt)("inlineCode",{parentName:"a"},"protocol_version"))))),(0,l.kt)("h2",{id:"contracthash"},"ContractHash"),(0,l.kt)("p",null,"A ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b")," hash of a contract. The contract hash serializes as a 32-byte buffer containing the bytes of the contract hash."),(0,l.kt)("h2",{id:"contractpackagehash"},"ContractPackageHash"),(0,l.kt)("p",null,"A ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b")," hash of a contract package. The contract package hash serializes as a 32-byte buffer containing the bytes of the contract package hash."),(0,l.kt)("h2",{id:"contractversion"},"ContractVersion"),(0,l.kt)("p",null,"The version of the contract."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#contracthash"},(0,l.kt)("inlineCode",{parentName:"a"},"contract_hash"))," The contract hash of the contract.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"contract_version")," The version of the contract within the protocol major version. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u32")," value"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"protocol_version_major")," The major element of the protocol version this contract is compatible with. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u32")," value"),"."))),(0,l.kt)("h2",{id:"contractwasmhash"},"ContractWasmHash"),(0,l.kt)("p",null,"A ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b")," hash of a contract's Wasm. The contract's Wasm hash serializes as a 32-byte buffer containing the bytes of the contract's Wasm hash."),(0,l.kt)("h2",{id:"delegator"},"Delegator"),(0,l.kt)("p",null,'Represents a party delegating their stake to a validator (or "delegatee"). The structure consists of the following fields:'),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"delegator_public_key")," The public key of the delegator, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"staked_amount")," The amount staked by the delegator, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512")," value"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"bonding_purse")," The bonding purse associated with the delegation. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-uref"},(0,l.kt)("inlineCode",{parentName:"a"},"URef")," value"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"validator_public_key")," The public key of the validator that the delegator will be delegating to, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"vesting_schedule")," The vesting schedule for the provided delegator bid. ",(0,l.kt)("inlineCode",{parentName:"p"},"None")," if it is a non-genesis validator. It serializes as an ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-option"},(0,l.kt)("inlineCode",{parentName:"a"},"Option")),"."))),(0,l.kt)("h2",{id:"serialization-standard-deploy"},"Deploy"),(0,l.kt)("p",null,"A deploy is a data structure containing a smart contract and the requester's signature(s). Additionally, the deploy header contains additional metadata about the deploy itself. A deploy is structurally defined as follows:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"hash"),": The hash of the deploy header."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"header"),": Contains metadata about the deploy. The structure of the header is detailed further in this document."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"payment"),": The payment code for contained smart contract."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"session"),": The stored contract itself."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"approvals"),": A list of signatures:")),(0,l.kt)("h3",{id:"deploy-hash"},"Deploy-Hash"),(0,l.kt)("p",null,"The deploy hash is a digest over the contents of the deploy header. The deploy hash serializes as the byte representation of the hash itself."),(0,l.kt)("h3",{id:"deploy-header"},"Deploy-Header"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"account"),": A supported public key variant (currently either ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519")," or ",(0,l.kt)("inlineCode",{parentName:"li"},"Secp256k1"),"). An ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519")," key is serialized as a buffer of bytes, with the leading byte being ",(0,l.kt)("inlineCode",{parentName:"li"},"1")," for ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519"),", with remainder of the buffer containing the byte representation of the signature. Correspondingly, a ",(0,l.kt)("inlineCode",{parentName:"li"},"Secp256k1")," key is serialized as a buffer of bytes, with the leading byte being ",(0,l.kt)("inlineCode",{parentName:"li"},"2"),"."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"timestamp"),": A timestamp is a struct that is a unary tuple containing a ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," value. This value is a count of the milliseconds since the UNIX epoch. Thus the value ",(0,l.kt)("inlineCode",{parentName:"li"},"1603994401469")," serializes as ",(0,l.kt)("inlineCode",{parentName:"li"},"0xbd3a847575010000")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"ttl"),": The ",(0,l.kt)("strong",{parentName:"li"},"Time to live")," is defined as the amount of time for which deploy is considered valid. The ",(0,l.kt)("inlineCode",{parentName:"li"},"ttl")," serializes in the same manner as the timestamp."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"gas_price"),": The gas is ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," value which is serialized as ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," CLValue discussed below."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"body_hash"),": Body hash is a hash over the contents of the deploy body, which includes the payment, session, and approval fields. Its serialization is the byte representation of the hash itself."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"dependencies"),": Dependencies is a vector of deploy hashes referencing deploys that must execute before the current deploy can be executed. It serializes as a buffer containing the individual serialization of each DeployHash within the Vector."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"chain_name"),": Chain name is a human-readable string describing the name of the chain as detailed in the chainspec. It is serialized as a String CLValue described below.")),(0,l.kt)("h3",{id:"payment--session"},"Payment & Session"),(0,l.kt)("p",null,"Payment and Session are both defined as ",(0,l.kt)("inlineCode",{parentName:"p"},"ExecutableDeployItems"),". More information on ",(0,l.kt)("inlineCode",{parentName:"p"},"ExecutableDeployItems")," can be found ",(0,l.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/calling-contracts"},"here")),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"Module Bytes are serialized such that the first byte within the serialized buffer is ",(0,l.kt)("inlineCode",{parentName:"p"},"0")," with the rest of the buffer containing the bytes present."),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},'ModuleBytes { module_bytes: "[72 bytes]", args: 434705a38470ec2b008bb693426f47f330802f3bd63588ee275e943407649d3bab1898897ab0400d7fa09fe02ab7b7e8ea443d28069ca557e206916515a7e21d15e5be5eb46235f5 }')," will serialize to"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"0x0048000000420481b0d5a665c8a7678398103d4333c684461a71e9ee2a13f6e859fb6cd419ed5f8876fc6c3e12dce4385acc777edf42dcf8d8d844bf6a704e5b2446750559911a4a328d649ddd48000000434705a38470ec2b008bb693426f47f330802f3bd63588ee275e943407649d3bab1898897ab0400d7fa09fe02ab7b7e8ea443d28069ca557e206916515a7e21d15e5be5eb46235f5")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"StoredContractByHash serializes such that the first byte within the serialized buffer is 1u8. This is followed by the byte representation of the remaining fields."),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},'StoredContractByHash { hash: c4c411864f7b717c27839e56f6f1ebe5da3f35ec0043f437324325d65a22afa4, entry_point: "pclphXwfYmCmdITj8hnh", args: d8b59728274edd2334ea328b3292ed15eaf9134f9a00dce31a87d9050570fb0267a4002c85f3a8384d2502733b2e46f44981df85fed5e4854200bbca313e3bca8d888a84a76a1c5b1b3d236a12401a2999d3cad003c9b9d98c92ab1850 }')),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"0x01c4c411864f7b717c27839e56f6f1ebe5da3f35ec0043f437324325d65a22afa41400000070636c7068587766596d436d6449546a38686e685d000000d8b59728274edd2334ea328b3292ed15eaf9134f9a00dce31a87d9050570fb0267a4002c85f3a8384d2502733b2e46f44981df85fed5e4854200bbca313e3bca8d888a84a76a1c5b1b3d236a12401a2999d3cad003c9b9d98c92ab1850")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"StoredContractByName serializes such that the first byte within the serialized buffer is 2u8. This is followed by the individual byte representation of the remaining fields."),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},'StoredContractByName { name: "U5A74bSZH8abT8HqVaK9", entry_point: "gIetSxltnRDvMhWdxTqQ", args: 07beadc3da884faa17454a }')),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"0x0214000000553541373462535a483861625438487156614b39140000006749657453786c746e5244764d685764785471510b00000007beadc3da884faa17454a")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"StoredVersionedContractByHash serializes such that the first byte within the serialized buffer is 3u8. However, the field version within the enum serializes as an ",(0,l.kt)("a",{parentName:"p",href:"#option-clvalue-option"},"Option")," CLValue."),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},'StoredVersionedContractByHash { hash: b348fdd0d0b3f66468687df93141b5924f6bb957d5893c08b60d5a78d0b9a423, version: None, entry_point: "PsLz5c7JsqT8BK8ll0kF", args: 3d0d7f193f70740386cb78b383e2e30c4f976cf3fa834bafbda4ed9dbfeb52ce1777817e8ed8868cfac6462b7cd31028aa5a7a60066db35371a2f8 }')),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"0x03b348fdd0d0b3f66468687df93141b5924f6bb957d5893c08b60d5a78d0b9a423001400000050734c7a3563374a73715438424b386c6c306b463b0000003d0d7f193f70740386cb78b383e2e30c4f976cf3fa834bafbda4ed9dbfeb52ce1777817e8ed8868cfac6462b7cd31028aa5a7a60066db35371a2f8")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"StoredVersionedContractByName serializes such that the first byte within the serialized buffer is 4u8. The name and entry_point are serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#string-clvalue-string"},"String")," CLValue, with the version field serializing as an ",(0,l.kt)("a",{parentName:"p",href:"#option-clvalue-option"},"Option"),"."),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},'StoredVersionedContractByName { name: "lWJWKdZUEudSakJzw1tn", version: Some(1632552656), entry_point: "S1cXRT3E1jyFlWBAIVQ8", args: 9975e6957ea6b07176c7d8471478fb28df9f02a61689ef58234b1a3cffaebf9f303e3ef60ae0d8 }')),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"0x04140000006c574a574b645a5545756453616b4a7a7731746e01d0c64e61140000005331635852543345316a79466c57424149565138270000009975e6957ea6b07176c7d8471478fb28df9f02a61689ef58234b1a3cffaebf9f303e3ef60ae0d8")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"Transfer serializes such that the first byte within the serialized buffer contains is 5u8, with the remaining bytes of the buffer containing the bytes contained within the args field of Transfer."))),(0,l.kt)("h3",{id:"approval"},"Approval"),(0,l.kt)("p",null,"Approval contains two fields:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"signer"),": The public key of the approvals signer. It serializes to the byte representation of the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey"),". If the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," is an ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519")," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,l.kt)("inlineCode",{parentName:"li"},"Secp256k1"),", the first byte is 2."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"signature"),": The approval signature, which serializes as the byte representation of the ",(0,l.kt)("inlineCode",{parentName:"li"},"Signature"),". The first byte within the signature is 1 in the case of an ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519")," signature or 2 in the case of ",(0,l.kt)("inlineCode",{parentName:"li"},"Secp256k1"),".")),(0,l.kt)("h2",{id:"deployinfo"},"DeployInfo"),(0,l.kt)("p",null,"Information relating to a given deploy. The structure consists of the following fields:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"deploy_hash")," The hash of the relevant deploy, serialized as a byte representation of the hash itself.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"transfers")," Transfers performed by the deploy, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-list"},(0,l.kt)("inlineCode",{parentName:"a"},"List")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"from")," The account identifier of the creator of the deploy, serialized as an ",(0,l.kt)("a",{parentName:"p",href:"#account-hash"},(0,l.kt)("inlineCode",{parentName:"a"},"account_hash")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"source")," The source purse used for payment of the deploy, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-uref"},(0,l.kt)("inlineCode",{parentName:"a"},"URef")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"gas")," The gas cost of executing the deploy, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512")),"."))),(0,l.kt)("h2",{id:"digest"},"Digest"),(0,l.kt)("p",null,"A ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b")," hash digest. The digest serializes as a byte representation of the hash itself."),(0,l.kt)("h2",{id:"disabledversions"},"DisabledVersions"),(0,l.kt)("p",null,"Disabled contract versions, containing the following:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"contract_version")," The version of the contract within the protocol major version. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u32")," value"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"protocol_version_major")," The major element of the protocol version this contract is compatible with. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u32")," value"),"."))),(0,l.kt)("h2",{id:"entrypoint"},"EntryPoint"),(0,l.kt)("p",null,"A type of signature method. Order of arguments matters, since this can be referenced by index as well as name."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"name")," The name of the entry point, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-string"},(0,l.kt)("inlineCode",{parentName:"a"},"String")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"args")," Arguments for this method. They serialize as a list of the ",(0,l.kt)("a",{parentName:"p",href:"#parameter"},(0,l.kt)("inlineCode",{parentName:"a"},"Parameter")),"s, where each parameter represents an argument passed to the entrypoint.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"ret")," The return type of the method, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-unit"},(0,l.kt)("inlineCode",{parentName:"a"},"Unit")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"access")," An enum describing the possible access control options for a contract entry point. It serializes as a 1 for public or a 1 followed by a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-list"},(0,l.kt)("inlineCode",{parentName:"a"},"List"))," of authorized users.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"entry_point_type")," Identifies the type of entry point. It serializes as a ",(0,l.kt)("inlineCode",{parentName:"p"},"0")," for Session and a ",(0,l.kt)("inlineCode",{parentName:"p"},"1")," for Contract."))),(0,l.kt)("h2",{id:"eraid"},"EraID"),(0,l.kt)("p",null,"An Era ID newtype. It serializes as a single ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64")," value"),"."),(0,l.kt)("h2",{id:"erainfo"},"EraInfo"),(0,l.kt)("p",null,"Auction metadata, intended to be recorded each era. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-list"},(0,l.kt)("inlineCode",{parentName:"a"},"List"))," of ",(0,l.kt)("a",{parentName:"p",href:"#seigniorageallocation"},"seigniorage allocations"),"."),(0,l.kt)("h2",{id:"executioneffect"},"ExecutionEffect"),(0,l.kt)("p",null,"The journal of execution transforms from a single deploy."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"operations")," The resulting operations, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-list"},(0,l.kt)("inlineCode",{parentName:"a"},"List"))," of ",(0,l.kt)("a",{parentName:"p",href:"#operation"},"operations"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"transforms")," The actual ",(0,l.kt)("a",{parentName:"p",href:"#transform"},"transformation")," performed while executing a deploy."))),(0,l.kt)("h2",{id:"executionresult"},"ExecutionResult"),(0,l.kt)("p",null,"The result of a single deploy. It serializes as a ",(0,l.kt)("inlineCode",{parentName:"p"},"u8")," tag indicating either ",(0,l.kt)("inlineCode",{parentName:"p"},"Failure")," as a 0 or ",(0,l.kt)("inlineCode",{parentName:"p"},"Success")," as a 1. This is followed by the appropriate structure below:"),(0,l.kt)("h3",{id:"failure"},(0,l.kt)("inlineCode",{parentName:"h3"},"Failure")),(0,l.kt)("p",null,"The result of a failed execution."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"effect")," The ",(0,l.kt)("a",{parentName:"p",href:"#executioneffect"},"effect")," of executing the deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"transfers")," A record of transfers performed while executing the deploy, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-list"},(0,l.kt)("inlineCode",{parentName:"a"},"List")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"cost")," The cost of executing the deploy, serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512"))," value.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"error_message")," The error message associated with executing the deploy, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-string"},(0,l.kt)("inlineCode",{parentName:"a"},"String")),"."))),(0,l.kt)("h3",{id:"success"},(0,l.kt)("inlineCode",{parentName:"h3"},"Success")),(0,l.kt)("p",null,"The result of a successful execution."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"effect")," The ",(0,l.kt)("a",{parentName:"p",href:"#executioneffect"},"effect")," of executing the deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"transfers")," A record of transfers performed while executing the deploy, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-list"},(0,l.kt)("inlineCode",{parentName:"a"},"List")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"cost")," The cost of executing the deploy, serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512"))," value."))),(0,l.kt)("h2",{id:"group"},"Group"),(0,l.kt)("p",null,'A (labeled) "user group". Each method of a versioned contract may be associated with one or more user groups which are allowed to call it. User groups are serialized as a ',(0,l.kt)("a",{parentName:"p",href:"#clvalue-string"},"String"),"."),(0,l.kt)("h2",{id:"groups"},"Groups"),(0,l.kt)("p",null,"They are serialized as a ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeMap")," where the first 4 bytes represent a ",(0,l.kt)("inlineCode",{parentName:"p"},"u32")," value describing the number of user groups and ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeSets")," of ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-uref"},(0,l.kt)("inlineCode",{parentName:"a"},"URef")),"s held within. The remainder consists of a repeating pattern of serialized user groups and ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeSets")," of the length dictated by the first four bytes."),(0,l.kt)("h2",{id:"serialization-standard-state-keys"},"Keys"),(0,l.kt)("p",null,'In this chapter, we describe what constitutes a "key", the permissions model for the keys, and how they are serialized.'),(0,l.kt)("p",null,"A ",(0,l.kt)("em",{parentName:"p"},"key")," in ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#global-state-head"},"Global State")," is one of the following data types:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},'32-byte account identifier (called an "account identity key")'),(0,l.kt)("li",{parentName:"ul"},'32-byte immutable contract identifier (called a "hash key")'),(0,l.kt)("li",{parentName:"ul"},'32-byte reference identifier (called an "unforgeable reference")'),(0,l.kt)("li",{parentName:"ul"},"32-byte transfer identifier"),(0,l.kt)("li",{parentName:"ul"},"32-byte deploy information identifier"),(0,l.kt)("li",{parentName:"ul"},"32-byte purse balance identifier"),(0,l.kt)("li",{parentName:"ul"},"32-byte Auction bid identifier"),(0,l.kt)("li",{parentName:"ul"},"32-byte Auction withdrawal identifier"),(0,l.kt)("li",{parentName:"ul"},"32-byte Dictionary identifier"),(0,l.kt)("li",{parentName:"ul"},"32-byte System Contract Registry"),(0,l.kt)("li",{parentName:"ul"},"32-byte Auction unbond identifier"),(0,l.kt)("li",{parentName:"ul"},"32-byte Chainspec Registry")),(0,l.kt)("p",null,"The one exception to note here is the identifier for ",(0,l.kt)("a",{parentName:"p",href:"#erainfo"},(0,l.kt)("inlineCode",{parentName:"a"},"EraInfo")),", which actually serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64"))," value with an additional byte for the tag."),(0,l.kt)("h3",{id:"global-state-account-key"},"Account identity key"),(0,l.kt)("p",null,"This key type is used specifically for accounts in the global state. All accounts in the system must be stored under an account identity key, and no other types. The 32-byte identifier which represents this key is derived from the ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the public key used to create the associated account (see ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-associated-keys-weights"},"Accounts")," for more information)."),(0,l.kt)("h3",{id:"serialization-standard-hash-key"},"Hash key"),(0,l.kt)("p",null,"This key type is used for storing contracts immutably. Once a contract is written under a hash key, that contract can never change. The 32-byte identifier representing this key is derived from the ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the deploy hash (see ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#block-structure-head"},"block-structure-head")," for more information) concatenated with a 4-byte sequential ID. The ID begins at zero for each deploy and increments by one each time a contract is stored. The purpose of this ID is to allow each contract stored in the same deploy to have a unique key."),(0,l.kt)("h3",{id:"serialization-standard-uref"},"Unforgeable Reference (",(0,l.kt)("inlineCode",{parentName:"h3"},"URef"),")"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"URef")," broadly speaking can be used to store values and manage permissions to interact with the value stored under the ",(0,l.kt)("inlineCode",{parentName:"p"},"URef"),". ",(0,l.kt)("inlineCode",{parentName:"p"},"URef")," is a tuple which contains the address under which the values are stored and the Access rights to the ",(0,l.kt)("inlineCode",{parentName:"p"},"URef"),". Refer to the ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#uref-head"},"Unforgeable Reference")," section for details on how ",(0,l.kt)("inlineCode",{parentName:"p"},"URefs")," are managed."),(0,l.kt)("h3",{id:"serialization-standard-transfer-key"},"Transfer Key"),(0,l.kt)("p",null,"This key type is used specifically for transfers in the global state. All transfers in the system must be stored under a transfer key and no other type. The 32-byte identifier which represents this key is derived from the ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the transfer address associated with the given transfer"),(0,l.kt)("h3",{id:"serialization-standard-deploy-info-key"},"DeployInfo Key"),(0,l.kt)("p",null,"This key type is used specifically for storing information related to deploys in the global state. Information for a given deploy is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the deploy itself."),(0,l.kt)("h3",{id:"serialization-standard-era-info-key"},"EraInfo Key"),(0,l.kt)("p",null,"This key type is used specifically for storing information related to the ",(0,l.kt)("inlineCode",{parentName:"p"},"Auction")," metadata for a particular era. The underlying data type stored under this is a vector of the allocation of seigniorage for that given era. The identifier for this key is a new type that wraps around the primitive ",(0,l.kt)("inlineCode",{parentName:"p"},"u64")," data type and co-relates to the era number when the auction information was stored."),(0,l.kt)("p",null,"This key type is used specifically for storing information related to auction bids in the global state. Information for the bids is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the public key used to create the associated account (see ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-associated-keys-weights"},"Accounts")," for more information)."),(0,l.kt)("p",null,"This key type is used specifically for storing information related to auction withdraws in the global state. Information for the withdrawals is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,l.kt)("inlineCode",{parentName:"p"},"blake2b256")," hash of the public key used to create the associated account (see ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-associated-keys-weights"},"Accounts")," for more information)."),(0,l.kt)("h3",{id:"serialization-standard-serialization-key"},"Serialization for ",(0,l.kt)("inlineCode",{parentName:"h3"},"Key")),(0,l.kt)("p",null,"Given the different variants for the over-arching ",(0,l.kt)("inlineCode",{parentName:"p"},"Key")," data-type, each of the different variants is serialized differently. This section of this chapter details how the individual variants are serialized. The leading byte of the serialized buffer acts as a tag indicating the serialized variant."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"th"},"Key")),(0,l.kt)("th",{parentName:"tr",align:null},"Serialization Tag"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Account")),(0,l.kt)("td",{parentName:"tr",align:null},"0")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Hash")),(0,l.kt)("td",{parentName:"tr",align:null},"1")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"URef")),(0,l.kt)("td",{parentName:"tr",align:null},"2")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Transfer")),(0,l.kt)("td",{parentName:"tr",align:null},"3")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"DeployInfo")),(0,l.kt)("td",{parentName:"tr",align:null},"4")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"EraInfo")),(0,l.kt)("td",{parentName:"tr",align:null},"5")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Balance")),(0,l.kt)("td",{parentName:"tr",align:null},"6")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Bid")),(0,l.kt)("td",{parentName:"tr",align:null},"7")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Withdraw")),(0,l.kt)("td",{parentName:"tr",align:null},"8")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Dictionary")),(0,l.kt)("td",{parentName:"tr",align:null},"9")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"SystemContractRegistry")),(0,l.kt)("td",{parentName:"tr",align:null},"10")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Unbond")),(0,l.kt)("td",{parentName:"tr",align:null},"11")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"ChainspecRegistry")),(0,l.kt)("td",{parentName:"tr",align:null},"12")))),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Account")," serializes as a 32 byte long buffer containing the byte representation of the underlying ",(0,l.kt)("inlineCode",{parentName:"li"},"AccountHash")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Hash")," serializes as a 32 byte long buffer containing the byte representation of the underlying ",(0,l.kt)("inlineCode",{parentName:"li"},"Hash")," itself."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"URef")," is a tuple that contains the address of the URef and the access rights to that ",(0,l.kt)("inlineCode",{parentName:"li"},"URef"),". The serialized representation of the ",(0,l.kt)("inlineCode",{parentName:"li"},"URef")," is 33 bytes long. The first 32 bytes are the byte representation of the ",(0,l.kt)("inlineCode",{parentName:"li"},"URef")," address, and the last byte contains the bits corresponding to the access rights of the ",(0,l.kt)("inlineCode",{parentName:"li"},"URef"),". Refer to the ",(0,l.kt)("a",{parentName:"li",href:"#serialization-standard-values"},"CLValue")," section of this chapter for details on how ",(0,l.kt)("inlineCode",{parentName:"li"},"AccessRights")," are serialized."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Transfer")," serializes as a 32 byte long buffer containing the byte representation of the hash of the transfer."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"DeployInfo")," serializes as 32 byte long buffer containing the byte representation of the Deploy hash. See the Deploy section above for how Deploy hashes are serialized."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"EraInfo")," serializes a ",(0,l.kt)("inlineCode",{parentName:"li"},"u64")," primitive type containing the little-endian byte representation of ",(0,l.kt)("inlineCode",{parentName:"li"},"u64"),"."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Balance")," serializes as 32 byte long buffer containing the byte representation of the URef address."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Bid")," and ",(0,l.kt)("inlineCode",{parentName:"li"},"Withdraw")," both contain the ",(0,l.kt)("inlineCode",{parentName:"li"},"AccountHash")," as their identifier; therefore, they serialize in the same manner as the ",(0,l.kt)("inlineCode",{parentName:"li"},"Account")," variant."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Dictionary")," as the 32 byte long buffer containing the byte representation of the seed URef hashed with the identifying name of the dictionary item."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"SystemContractRegistry")," as a 32 byte long buffer of zeros."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Unbond")," contains the ",(0,l.kt)("inlineCode",{parentName:"li"},"AccountHash")," as its identifier; therefore, it serialize in the same manner as the ",(0,l.kt)("inlineCode",{parentName:"li"},"Account")," variant."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"ChainspecRegistry")," as a 32 byte long buffer of ones.")),(0,l.kt)("h2",{id:"serialization-standard-permissions"},"Permissions"),(0,l.kt)("p",null,"There are three types of actions that can be done on a value: read, write, add. The reason for ",(0,l.kt)("em",{parentName:"p"},"add")," to be called out separately from ",(0,l.kt)("em",{parentName:"p"},"write")," is to allow for commutativity checking. The available actions depend on the key type and the context. Some key types only allow controlled access by smart contracts via the contract API, and other key types refer to values produced and used by the system itself and are not accessible to smart contracts at all but can be read via off-chain queries. This is summarized in the table below:"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Key"),(0,l.kt)("th",{parentName:"tr",align:null},"Type Available Actions"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Account"),(0,l.kt)("td",{parentName:"tr",align:null},"Read + Add (via API)")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Hash"),(0,l.kt)("td",{parentName:"tr",align:null},"Read")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"URef"),(0,l.kt)("td",{parentName:"tr",align:null},"Read + Write and/or Add")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Transfer"),(0,l.kt)("td",{parentName:"tr",align:null},"System")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Deploy"),(0,l.kt)("td",{parentName:"tr",align:null},"System")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"EraInfo"),(0,l.kt)("td",{parentName:"tr",align:null},"System")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Balance"),(0,l.kt)("td",{parentName:"tr",align:null},"Read (via API)")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Bid"),(0,l.kt)("td",{parentName:"tr",align:null},"System")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Withdraw"),(0,l.kt)("td",{parentName:"tr",align:null},"System")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Dictionary"),(0,l.kt)("td",{parentName:"tr",align:null},"Read (via API)")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"SystemContractRegistry"),(0,l.kt)("td",{parentName:"tr",align:null},"Read (via API)")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Unbond"),(0,l.kt)("td",{parentName:"tr",align:null},"System")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ChainspecRegistry"),(0,l.kt)("td",{parentName:"tr",align:null},"Read (via API)")))),(0,l.kt)("hr",null),(0,l.kt)("p",null,"Refer to ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#uref-permissions"},"URef permissions")," on how permissions are handled in the case of ",(0,l.kt)("inlineCode",{parentName:"p"},"URef"),"s."),(0,l.kt)("h2",{id:"namedarg"},"NamedArg"),(0,l.kt)("p",null,"Named arguments to a contract. It is serialized by the combination of a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-string"},(0,l.kt)("inlineCode",{parentName:"a"},"String"))," followed by the associated ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-clvalue"},(0,l.kt)("inlineCode",{parentName:"a"},"CLValue")),"."),(0,l.kt)("h2",{id:"namedkey"},"NamedKey"),(0,l.kt)("p",null,"A mapping of string identifiers to a Casper ",(0,l.kt)("inlineCode",{parentName:"p"},"Key")," type. It is serialized as a ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeMap")," where the first 4 bytes represent a ",(0,l.kt)("inlineCode",{parentName:"p"},"u32")," value describing the number of named keys and values held within. The remainder consists of a repeating pattern of serialized named keys and then values of the length dictated by the first four bytes."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"name")," The name of the entry. It serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-string"},(0,l.kt)("inlineCode",{parentName:"a"},"string")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key")," The value of the entry, which is a Casper ",(0,l.kt)("inlineCode",{parentName:"p"},"Key")," type."))),(0,l.kt)("p",null,"The named keys portion of the account structure serializes as a mapping of a string to Casper ",(0,l.kt)("inlineCode",{parentName:"p"},"Key")," values as described ",(0,l.kt)("a",{parentName:"p",href:"#serialization-standard-serialization-key"},"here"),"."),(0,l.kt)("h2",{id:"operation"},"Operation"),(0,l.kt)("p",null,"An operation performed while executing a deploy. It contains:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key")," The formatted string of the key, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-string"},(0,l.kt)("inlineCode",{parentName:"a"},"String")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"kind")," OpKind, The type of operation performed. It serializes as a single byte based on the following table:"))),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"OpKind"),(0,l.kt)("th",{parentName:"tr",align:null},"Serialization"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Read"),(0,l.kt)("td",{parentName:"tr",align:null},"0")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write"),(0,l.kt)("td",{parentName:"tr",align:null},"1")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Add"),(0,l.kt)("td",{parentName:"tr",align:null},"2")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"NoOp"),(0,l.kt)("td",{parentName:"tr",align:null},"3")))),(0,l.kt)("h2",{id:"parameter"},"Parameter"),(0,l.kt)("p",null,"Parameter to a method, structured as a name followed by a ",(0,l.kt)("inlineCode",{parentName:"p"},"CLType"),". It is serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-string"},(0,l.kt)("inlineCode",{parentName:"a"},"String"))," followed by a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-cltype"},(0,l.kt)("inlineCode",{parentName:"a"},"CLType")),"."),(0,l.kt)("h2",{id:"protocolversion"},"ProtocolVersion"),(0,l.kt)("p",null,"A newtype indicating the Casper Platform protocol version. It is serialized as three ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u32"))," values indicating major, minor and patch versions in that order."),(0,l.kt)("h2",{id:"publickey"},"PublicKey"),(0,l.kt)("p",null,"Hex-encoded cryptographic public key, including the algorithm tag prefix. Serialization can be found under ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),"."),(0,l.kt)("h2",{id:"runtimeargs"},"RuntimeArgs"),(0,l.kt)("p",null,"Represents a collection of arguments passed to a smart contract. They serialize as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-list"},(0,l.kt)("inlineCode",{parentName:"a"},"List"))," comprised of ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-tuple"},(0,l.kt)("inlineCode",{parentName:"a"},"Tuples")),"."),(0,l.kt)("h2",{id:"seigniorageallocation"},"SeigniorageAllocation"),(0,l.kt)("p",null,"Information about seigniorage allocation."),(0,l.kt)("p",null,"If the seigniorage allocation in question is for a validator, it serializes as the validator's ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey"))," followed by the ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512")," amount"),"."),(0,l.kt)("p",null,"If it is a delegator, it serializes as the delegator's ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),", followed by the validator's ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey"))," and finally the ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512")," amount"),"."),(0,l.kt)("h2",{id:"signature"},"Signature"),(0,l.kt)("p",null,"The signature serializes the byte representation of the underlying cryptographic primitive signature. The first byte within the signature is 1 in the case of an ",(0,l.kt)("inlineCode",{parentName:"p"},"Ed25519")," signature or 2 in the case of ",(0,l.kt)("inlineCode",{parentName:"p"},"Secp256k1"),"."),(0,l.kt)("h2",{id:"systemcontractregistry"},"SystemContractRegistry"),(0,l.kt)("p",null,"SystemContractRegistry is a unique ",(0,l.kt)("inlineCode",{parentName:"p"},"Key")," under which a mapping of the names and ",(0,l.kt)("inlineCode",{parentName:"p"},"ContractHashes")," for system contracts. This includes ",(0,l.kt)("inlineCode",{parentName:"p"},"Mint"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"Auction"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"HandlePayment")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"StandardPayment"),". It is serialized as a ",(0,l.kt)("inlineCode",{parentName:"p"},"BTreeMap")," where the first 4 bytes represent a ",(0,l.kt)("inlineCode",{parentName:"p"},"u32")," value describing the number of names as strings and ",(0,l.kt)("a",{parentName:"p",href:"#contracthash"},"ContractHashes")," held within. The remainder consists of a repeating pattern of serialized strings and then ContractHashes of the length dictated by the first four bytes."),(0,l.kt)("h2",{id:"timediff"},"TimeDiff"),(0,l.kt)("p",null,"A human-readable duration between two timestamps. It serializes as a single ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64"))," value."),(0,l.kt)("h2",{id:"timestamp"},"Timestamp"),(0,l.kt)("p",null,"A timestamp formatted as per RFC 3339 and serialized as a single ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64"))," value."),(0,l.kt)("h2",{id:"transferaddr"},"TransferAddr"),(0,l.kt)("p",null,"Hex-encoded transfer address, which serializes as a byte representation of itself."),(0,l.kt)("h2",{id:"transform"},"Transform"),(0,l.kt)("p",null,"The actual transformation performed while executing a deploy. It serializes as a single ",(0,l.kt)("inlineCode",{parentName:"p"},"u8")," value indicating the type of transform performed as per the following table. The remaining bytes represent the information and serialization as listed."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Transform Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Serialization"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Identity"),(0,l.kt)("td",{parentName:"tr",align:null},"0"),(0,l.kt)("td",{parentName:"tr",align:null},"A transform having no effect.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_CLValue"),(0,l.kt)("td",{parentName:"tr",align:null},"1"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes the given ",(0,l.kt)("a",{parentName:"td",href:"#clvalue-calvalue"},(0,l.kt)("inlineCode",{parentName:"a"},"CLValue"))," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Account"),(0,l.kt)("td",{parentName:"tr",align:null},"2"),(0,l.kt)("td",{parentName:"tr",align:null},"Write the given ",(0,l.kt)("a",{parentName:"td",href:"#account-hash"},(0,l.kt)("inlineCode",{parentName:"a"},"Account"))," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Contract_WASM"),(0,l.kt)("td",{parentName:"tr",align:null},"3"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes a smart ",(0,l.kt)("a",{parentName:"td",href:"#contractwasmhash"},"contract as Wasm")," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Contract"),(0,l.kt)("td",{parentName:"tr",align:null},"4"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes a smart ",(0,l.kt)("a",{parentName:"td",href:"#contracthash"},"contract")," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Contract_Package"),(0,l.kt)("td",{parentName:"tr",align:null},"5"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes a smart ",(0,l.kt)("a",{parentName:"td",href:"#contractpackagehash"},"contract package")," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Deploy_Info"),(0,l.kt)("td",{parentName:"tr",align:null},"6"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes the given ",(0,l.kt)("a",{parentName:"td",href:"#deployinfo"},(0,l.kt)("inlineCode",{parentName:"a"},"DeployInfo"))," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Transfer"),(0,l.kt)("td",{parentName:"tr",align:null},"7"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes the given ",(0,l.kt)("a",{parentName:"td",href:"#transferaddr"},"Transfer")," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Era_Info"),(0,l.kt)("td",{parentName:"tr",align:null},"8"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes the given ",(0,l.kt)("a",{parentName:"td",href:"#erainfo"},(0,l.kt)("inlineCode",{parentName:"a"},"EraInfo"))," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Bid"),(0,l.kt)("td",{parentName:"tr",align:null},"9"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes the given ",(0,l.kt)("a",{parentName:"td",href:"#bid"},(0,l.kt)("inlineCode",{parentName:"a"},"Bid"))," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Write_Withdraw"),(0,l.kt)("td",{parentName:"tr",align:null},"10"),(0,l.kt)("td",{parentName:"tr",align:null},"Writes the given ",(0,l.kt)("a",{parentName:"td",href:"#unbondingpurse"},"Withdraw")," to global state.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Add_INT32"),(0,l.kt)("td",{parentName:"tr",align:null},"11"),(0,l.kt)("td",{parentName:"tr",align:null},"Adds the given ",(0,l.kt)("a",{parentName:"td",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"i32")),".")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Add_UINT64"),(0,l.kt)("td",{parentName:"tr",align:null},"12"),(0,l.kt)("td",{parentName:"tr",align:null},"Adds the given ",(0,l.kt)("a",{parentName:"td",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64")),".")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Add_UINT128"),(0,l.kt)("td",{parentName:"tr",align:null},"13"),(0,l.kt)("td",{parentName:"tr",align:null},"Adds the given ",(0,l.kt)("a",{parentName:"td",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U128")),".")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Add_UINT256"),(0,l.kt)("td",{parentName:"tr",align:null},"14"),(0,l.kt)("td",{parentName:"tr",align:null},"Adds the given ",(0,l.kt)("a",{parentName:"td",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U256")),".")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Add_UINT512"),(0,l.kt)("td",{parentName:"tr",align:null},"15"),(0,l.kt)("td",{parentName:"tr",align:null},"Adds the given ",(0,l.kt)("a",{parentName:"td",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512")),".")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Add_Keys"),(0,l.kt)("td",{parentName:"tr",align:null},"16"),(0,l.kt)("td",{parentName:"tr",align:null},"Adds the given collection of ",(0,l.kt)("a",{parentName:"td",href:"#namedkey"},"named keys"),".")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Failure"),(0,l.kt)("td",{parentName:"tr",align:null},"17"),(0,l.kt)("td",{parentName:"tr",align:null},"A failed transformation, containing an error message.")))),(0,l.kt)("h2",{id:"transformentry"},"TransformEntry"),(0,l.kt)("p",null,"A transformation performed while executing a deploy."),(0,l.kt)("h2",{id:"unbondingpurse"},"UnbondingPurse"),(0,l.kt)("p",null,"A purse used for unbonding. The structure consists of the following:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"bonding_purse")," The bonding purse, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-uref"},(0,l.kt)("inlineCode",{parentName:"a"},"URef")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"validator_public_key")," The public key of the validator, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"unbonder_public_key")," The public key of the unbonder, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"era_of_creation")," Era in which this unbonding request was created, as an ",(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"EraId"))," newtype, which serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64"))," value.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"amount")," The unbonding amount, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512"))," value.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"new_validator")," The validator public key to redelegate to, serialized as an ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-option"},(0,l.kt)("inlineCode",{parentName:"a"},"Option"))," containing the public key."))),(0,l.kt)("h2",{id:"serialization-standard-values"},"Values"),(0,l.kt)("p",null,"A value stored in the global state is a ",(0,l.kt)("inlineCode",{parentName:"p"},"StoredValue"),". A ",(0,l.kt)("inlineCode",{parentName:"p"},"StoredValue")," is one of three possible variants:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"A ",(0,l.kt)("inlineCode",{parentName:"li"},"CLValue")),(0,l.kt)("li",{parentName:"ul"},"A contract"),(0,l.kt)("li",{parentName:"ul"},"An account")),(0,l.kt)("p",null,"We discuss ",(0,l.kt)("inlineCode",{parentName:"p"},"CLValue")," and contract in more detail below. Details about accounts can be found in ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-head"},"accounts-head"),"."),(0,l.kt)("p",null,"Each ",(0,l.kt)("inlineCode",{parentName:"p"},"StoredValue")," is serialized when written to the global state. The serialization format consists of a single byte tag, indicating which variant of ",(0,l.kt)("inlineCode",{parentName:"p"},"StoredValue")," it is, followed by the serialization of that variant. The tag for each variant is as follows:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"CLValue")," is ",(0,l.kt)("inlineCode",{parentName:"li"},"0")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Account")," is ",(0,l.kt)("inlineCode",{parentName:"li"},"1")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Contract")," is ",(0,l.kt)("inlineCode",{parentName:"li"},"2"))),(0,l.kt)("p",null,"The details of ",(0,l.kt)("inlineCode",{parentName:"p"},"CLType")," serialization are in the following section. Using the serialization format for ",(0,l.kt)("inlineCode",{parentName:"p"},"CLValue")," as a basis, we can succinctly write the serialization rules for contracts and accounts:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"contracts serialize in the same way as data with ",(0,l.kt)("inlineCode",{parentName:"li"},"CLType")," equal to ",(0,l.kt)("inlineCode",{parentName:"li"},"Tuple3(List(U8), Map(String, Key), Tuple3(U32, U32, U32))"),";"),(0,l.kt)("li",{parentName:"ul"},"accounts serialize in the same way as data with ",(0,l.kt)("inlineCode",{parentName:"li"},"CLType")," equal to ",(0,l.kt)("inlineCode",{parentName:"li"},"Tuple5(ByteArray(U8, 32), Map(String, Key), URef, Map(ByteArray(U8, 32), U8), Tuple2(U8, U8))"),".")),(0,l.kt)("p",null,"Note: ",(0,l.kt)("inlineCode",{parentName:"p"},"Tuple5")," is not a presently supported ",(0,l.kt)("inlineCode",{parentName:"p"},"CLType"),". However, it is clear how to generalize the rules for ",(0,l.kt)("inlineCode",{parentName:"p"},"Tuple1"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"Tuple2"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"Tuple3")," to any size tuple."),(0,l.kt)("h3",{id:"clvalue"},(0,l.kt)("inlineCode",{parentName:"h3"},"CLValue")),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"CLValue")," is used to describe data that is used by smart contracts. This could be as a local state variable, input argument, or return value. A ",(0,l.kt)("inlineCode",{parentName:"p"},"CLValue")," consists of two parts: a ",(0,l.kt)("inlineCode",{parentName:"p"},"CLType")," describing the type of the value and an array of bytes representing the data in our serialization format."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"CLType")," is described by the following recursive data type:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-rust"},'enum CLType {\n Bool, // boolean primitive\n I32, // signed 32-bit integer primitive\n I64, // signed 64-bit integer primitive\n U8, // unsigned 8-bit integer primitive\n U32, // unsigned 32-bit integer primitive\n U64, // unsigned 64-bit integer primitive\n U128, // unsigned 128-bit integer primitive\n U256, // unsigned 256-bit integer primitive\n U512, // unsigned 512-bit integer primitive\n Unit, // singleton value without additional semantics\n String, // e.g. "Hello, World!"\n URef, // unforgeable reference (see above)\n Key, // global state key (see above)\n PublicKey // A Casper system PublicKey type\n Option(CLType), // optional value of the given type\n List(CLType), // list of values of the given type (e.g. Vec in rust)\n ByteArray(CLType, u32), // same as `List` above, but number of elements\n // is statically known (e.g. arrays in rust)\n Result(CLType, CLType), // co-product of the given types;\n // one variant meaning success, the other failure\n Map(CLType, CLType), // key-value association where keys and values have the given types\n Tuple1(CLType), // single value of the given type\n Tuple2(CLType, CLType), // pair consisting of elements of the given types\n Tuple3(CLType, CLType, CLType), // triple consisting of elements of the given types\n Any // Indicates the type is not known\n}\n')),(0,l.kt)("p",null,"All data which can be assigned a (non-",(0,l.kt)("inlineCode",{parentName:"p"},"Any"),") ",(0,l.kt)("inlineCode",{parentName:"p"},"CLType")," can be serialized according to the following rules (this defines the Casper serialization format):"),(0,l.kt)("h4",{id:"clvalue-boolean"},"Boolean"),(0,l.kt)("p",null,"Boolean values serialize as a single byte; ",(0,l.kt)("inlineCode",{parentName:"p"},"true")," maps to ",(0,l.kt)("inlineCode",{parentName:"p"},"1"),", while ",(0,l.kt)("inlineCode",{parentName:"p"},"false")," maps to ",(0,l.kt)("inlineCode",{parentName:"p"},"0"),"."),(0,l.kt)("h4",{id:"clvalue-numeric"},"Numeric"),(0,l.kt)("p",null,"Numeric values consisting of 64 bits or less serialize in the two's complement representation with little-endian byte order, and the appropriate number of bytes for the bit-width."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"p"},"7u8")," serializes as ",(0,l.kt)("inlineCode",{parentName:"p"},"0x07"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"p"},"7u32")," serializes as ",(0,l.kt)("inlineCode",{parentName:"p"},"0x07000000"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"p"},"1024u32")," serializes as ",(0,l.kt)("inlineCode",{parentName:"p"},"0x00040000"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"Wider numeric values (i.e. ",(0,l.kt)("inlineCode",{parentName:"p"},"U128"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"U256"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"U512"),") serialize as one byte given the length of the next number (in bytes), followed by the two's complement representation with little-endian byte order. The number of bytes should be chosen as small as possible to represent the given number. This is done to reduce the serialization size when small numbers are represented within a wide data type.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"p"},"U512::from(7)")," serializes as ",(0,l.kt)("inlineCode",{parentName:"p"},"0x0107"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"p"},"U512::from(1024)")," serializes as ",(0,l.kt)("inlineCode",{parentName:"p"},"0x020004"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"p"},'U512::from("123456789101112131415")')," serializes as ",(0,l.kt)("inlineCode",{parentName:"p"},"0x0957ff1ada959f4eb106")))),(0,l.kt)("h4",{id:"clvalue-unit"},"Unit"),(0,l.kt)("p",null,"Unit serializes to an empty byte array."),(0,l.kt)("h4",{id:"clvalue-string"},"String"),(0,l.kt)("p",null,"Strings serialize as a 32-bit integer representing the length in bytes (note: this might be different than the number of characters since special characters, such as emojis, take more than one byte), followed by the UTF-8 encoding of the characters in the string."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"li"},'"Hello, World!"')," serializes as ",(0,l.kt)("inlineCode",{parentName:"li"},"0x0d00000048656c6c6f2c20576f726c6421"))),(0,l.kt)("h4",{id:"clvalue-option"},"Option"),(0,l.kt)("p",null,"Optional values serialize with a single byte tag, followed by the serialization of the value itself. The tag is equal to ",(0,l.kt)("inlineCode",{parentName:"p"},"0")," if the value is missing, and ",(0,l.kt)("inlineCode",{parentName:"p"},"1")," if it is present."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"li"},"None")," serializes as ",(0,l.kt)("inlineCode",{parentName:"li"},"0x00")),(0,l.kt)("li",{parentName:"ul"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"li"},"Some(10u32)")," serializes as ",(0,l.kt)("inlineCode",{parentName:"li"},"0x010a000000"))),(0,l.kt)("h4",{id:"clvalue-list"},"List"),(0,l.kt)("p",null,"A list of values serializes as a 32-bit integer representing the number of elements in the list (note this differs from strings where it gives the number of ",(0,l.kt)("em",{parentName:"p"},"bytes"),"), followed by the concatenation of each serialized element."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"li"},"List()")," serializes as ",(0,l.kt)("inlineCode",{parentName:"li"},"0x00000000")),(0,l.kt)("li",{parentName:"ul"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"li"},"List(1u32, 2u32, 3u32)")," serializes as ",(0,l.kt)("inlineCode",{parentName:"li"},"0x03000000010000000200000003000000"))),(0,l.kt)("h4",{id:"clvalue-ByteArray"},"ByteArray"),(0,l.kt)("p",null,"A fixed-length list of values serializes as the concatenation of the serialized elements. Unlike a variable-length list, the length is not included in the serialization because it is statically known by the type of the value."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"E.g. ",(0,l.kt)("inlineCode",{parentName:"li"},"[1u32, 2u32, 3u32]")," serializes as ",(0,l.kt)("inlineCode",{parentName:"li"},"0x010000000200000003000000"))),(0,l.kt)("h4",{id:"clvalue-result"},"Result"),(0,l.kt)("p",null,"A ",(0,l.kt)("inlineCode",{parentName:"p"},"Result")," serializes as a single byte tag followed by the serialization of the contained value. The tag is equal to ",(0,l.kt)("inlineCode",{parentName:"p"},"1")," for the success variant and ",(0,l.kt)("inlineCode",{parentName:"p"},"0")," for the error variant."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},'- E.g. `Ok(314u64)` serializes as `0x013a01000000000000`\n- E.g. `Err("Uh oh")` serializes as `0x00050000005568206f68`\n')),(0,l.kt)("h4",{id:"clvalue-tuple"},"Tuple"),(0,l.kt)("p",null,"Tuples serialize as the concatenation of their serialized elements. Similar to ",(0,l.kt)("inlineCode",{parentName:"p"},"ByteArray")," the number of elements is not included in the serialization because it is statically known in the type."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},'- E.g. `(1u32, "Hello, World!", true)` serializes as `0x010000000d00000048656c6c6f2c20576f726c642101`\n')),(0,l.kt)("h4",{id:"clvalue-map"},"Map"),(0,l.kt)("p",null,"A ",(0,l.kt)("inlineCode",{parentName:"p"},"Map")," serializes as a list of key-value tuples. There must be a well-defined ordering on the keys, and in the serialization, the pairs are listed in ascending order. This is done to ensure determinism in the serialization, as ",(0,l.kt)("inlineCode",{parentName:"p"},"Map")," data structures can be unordered."),(0,l.kt)("h4",{id:"clvalue-uref"},"URef"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"URef")," values serialize as the concatenation of its address (which is a fixed-length list of ",(0,l.kt)("inlineCode",{parentName:"p"},"u8"),") and a single byte tag representing the access rights. Access rights are converted as follows:"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Access Rights"),(0,l.kt)("th",{parentName:"tr",align:null},"Serialization"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"NONE")),(0,l.kt)("td",{parentName:"tr",align:null},"0")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"READ")),(0,l.kt)("td",{parentName:"tr",align:null},"1")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"WRITE")),(0,l.kt)("td",{parentName:"tr",align:null},"2")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"READ_WRITE")),(0,l.kt)("td",{parentName:"tr",align:null},"3")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"ADD")),(0,l.kt)("td",{parentName:"tr",align:null},"4")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"READ_ADD")),(0,l.kt)("td",{parentName:"tr",align:null},"5")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"ADD_WRITE")),(0,l.kt)("td",{parentName:"tr",align:null},"6")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"READ_ADD_WRITE")),(0,l.kt)("td",{parentName:"tr",align:null},"7")))),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"- E.g. `uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-007` shows a `URef` with full `READ_ADD_WRITE` rights.\n")),(0,l.kt)("admonition",{type:"warning"},(0,l.kt)("p",{parentName:"admonition"},"When passing a URef to another entity on chain, you must ensure that the ",(0,l.kt)("inlineCode",{parentName:"p"},"AccessRights")," are set correctly. If the URef represents a ",(0,l.kt)("a",{parentName:"p",href:"/concepts/glossary/P#purse-purse"},"purse"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"AccessRights")," impact who can deposit and withdraw CSPR.")),(0,l.kt)("p",null,"If a passed URef contains ",(0,l.kt)("inlineCode",{parentName:"p"},"ADD")," permissions, the entity receiving the URef will then be able to deposit CSPR into the associated purse. ",(0,l.kt)("inlineCode",{parentName:"p"},"WRITE")," permissions allow for withdrawing CSPR. As of 1.4.5, passing a main purse URef as a runtime argument will cause the host to automatically remove ",(0,l.kt)("inlineCode",{parentName:"p"},"WRITE")," permissions. In this event, ",(0,l.kt)("inlineCode",{parentName:"p"},"READ")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"ADD")," permissions will remain. Regardless, all due diligence should be performed to avoid passing a URef with ",(0,l.kt)("inlineCode",{parentName:"p"},"WRITE")," permissions unintentionally."),(0,l.kt)("h4",{id:"clvalue-publickey"},"PublicKey"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"PublicKey")," serializes as a single byte tag representing the algorithm followed by 32 bytes of the ",(0,l.kt)("inlineCode",{parentName:"p"},"PublicKey")," itself:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"If the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," is a ",(0,l.kt)("inlineCode",{parentName:"li"},"System")," key, the single tag byte is ",(0,l.kt)("inlineCode",{parentName:"li"},"0"),". With this variant, the single byte of ",(0,l.kt)("inlineCode",{parentName:"li"},"0")," is the entire key."),(0,l.kt)("li",{parentName:"ul"},"If the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," is an ",(0,l.kt)("inlineCode",{parentName:"li"},"Ed25519")," key, the single tag byte is ",(0,l.kt)("inlineCode",{parentName:"li"},"1")," followed by the individual bytes of the serialized key."),(0,l.kt)("li",{parentName:"ul"},"If the ",(0,l.kt)("inlineCode",{parentName:"li"},"PublicKey")," is a ",(0,l.kt)("inlineCode",{parentName:"li"},"Secp256k1")," key, the single tag byte is a ",(0,l.kt)("inlineCode",{parentName:"li"},"2")," followed by the individual bytes of the serialized key.")),(0,l.kt)("h4",{id:"clvalue-key"},"Key"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"Key")," values serialize as a single byte tag representing the variant, followed by the serialization of the data that variant contains. For most variants, this is simply a fixed-length 32-byte array. The exception is ",(0,l.kt)("inlineCode",{parentName:"p"},"Key::URef"),", which contains a ",(0,l.kt)("inlineCode",{parentName:"p"},"URef"),"; so its data serializes per the description above. The tags are as follows: ",(0,l.kt)("inlineCode",{parentName:"p"},"Key::Account")," serializes as ",(0,l.kt)("inlineCode",{parentName:"p"},"0"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"Key::Hash")," as ",(0,l.kt)("inlineCode",{parentName:"p"},"1"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"Key::URef")," as ",(0,l.kt)("inlineCode",{parentName:"p"},"2"),"."),(0,l.kt)("h4",{id:"clvalue-cltype"},"CLType"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"CLType")," itself also has rules for serialization. A ",(0,l.kt)("inlineCode",{parentName:"p"},"CLType")," serializes as a single-byte tag, followed by the concatenation of serialized inner types, if any (e.g., lists and tuples have inner types). ",(0,l.kt)("inlineCode",{parentName:"p"},"ByteArray")," is a minor exception because it also includes the length in the type. However, the length is included in the serialization (as a 32-bit integer, per the serialization rules above), following the serialization of the inner type. The tags are as follows:"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"th"},"CLType")),(0,l.kt)("th",{parentName:"tr",align:null},"Serialization Tag"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Bool")),(0,l.kt)("td",{parentName:"tr",align:null},"0")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"I32")),(0,l.kt)("td",{parentName:"tr",align:null},"1")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"I64")),(0,l.kt)("td",{parentName:"tr",align:null},"2")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"U8")),(0,l.kt)("td",{parentName:"tr",align:null},"3")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"U32")),(0,l.kt)("td",{parentName:"tr",align:null},"4")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"U64")),(0,l.kt)("td",{parentName:"tr",align:null},"5")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"U128")),(0,l.kt)("td",{parentName:"tr",align:null},"6")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"U256")),(0,l.kt)("td",{parentName:"tr",align:null},"7")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"U512")),(0,l.kt)("td",{parentName:"tr",align:null},"8")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Unit")),(0,l.kt)("td",{parentName:"tr",align:null},"9")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"String")),(0,l.kt)("td",{parentName:"tr",align:null},"10")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Key")),(0,l.kt)("td",{parentName:"tr",align:null},"11")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"URef")),(0,l.kt)("td",{parentName:"tr",align:null},"12")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Option")),(0,l.kt)("td",{parentName:"tr",align:null},"13")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"List")),(0,l.kt)("td",{parentName:"tr",align:null},"14")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"ByteArray")),(0,l.kt)("td",{parentName:"tr",align:null},"15")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Result")),(0,l.kt)("td",{parentName:"tr",align:null},"16")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Map")),(0,l.kt)("td",{parentName:"tr",align:null},"17")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Tuple1")),(0,l.kt)("td",{parentName:"tr",align:null},"18")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Tuple2")),(0,l.kt)("td",{parentName:"tr",align:null},"19")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Tuple3")),(0,l.kt)("td",{parentName:"tr",align:null},"20")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"Any")),(0,l.kt)("td",{parentName:"tr",align:null},"21")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("inlineCode",{parentName:"td"},"PublicKey")),(0,l.kt)("td",{parentName:"tr",align:null},"22")))),(0,l.kt)("h4",{id:"clvalue-clvalue"},"CLValue"),(0,l.kt)("p",null,"A complete ",(0,l.kt)("inlineCode",{parentName:"p"},"CLValue"),", including both the data and the type, can also be serialized (to store it in the global state). This is done by concatenating: the serialization of the length (as a 32-bit integer) of the serialized data (in bytes), the serialized data itself, and the serialization of the type."),(0,l.kt)("h3",{id:"global-state-contracts"},"Contracts"),(0,l.kt)("p",null,"Contracts are a special value type because they contain the on-chain logic of the applications running on a Casper network. A ",(0,l.kt)("em",{parentName:"p"},"contract")," contains the following data:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"a ",(0,l.kt)("a",{parentName:"li",href:"https://webassembly.github.io/spec/core/syntax/modules.html"},"wasm module")),(0,l.kt)("li",{parentName:"ul"},"a collection of named keys"),(0,l.kt)("li",{parentName:"ul"},"a protocol version")),(0,l.kt)("p",null,"The wasm module must contain a function named ",(0,l.kt)("inlineCode",{parentName:"p"},"call"),", which takes no arguments and returns no values. This is the main entry point into the contract. Moreover, the module may import any of the functions supported by the ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#execution-semantics-runtime"},"Casper runtime"),"."),(0,l.kt)("p",null,"Note: though the ",(0,l.kt)("inlineCode",{parentName:"p"},"call")," function signature has no arguments and no return value, within the ",(0,l.kt)("inlineCode",{parentName:"p"},"call")," function body, the ",(0,l.kt)("inlineCode",{parentName:"p"},"get_named_arg")," runtime function can be used to accept arguments (by ordinal), and the ",(0,l.kt)("inlineCode",{parentName:"p"},"ret")," runtime function can be used to return a single ",(0,l.kt)("inlineCode",{parentName:"p"},"CLValue")," to the caller."),(0,l.kt)("p",null,"The named keys are used to give human-readable names to keys in the global state, which are essential to the contract. For example, the hash key of another contract it frequently calls may be stored under a meaningful name. It is also used to store the ",(0,l.kt)("inlineCode",{parentName:"p"},"URef"),"s, which are known to the contract (see the section on Permissions for details)."),(0,l.kt)("p",null,"Each contract specifies the Casper protocol version that was active when the contract was written to the global state."),(0,l.kt)("h2",{id:"withdrawpurse"},"WithdrawPurse"),(0,l.kt)("p",null,"A purse used for unbonding, replaced in 1.5 by ",(0,l.kt)("a",{parentName:"p",href:"#unbondingpurse"},"UnbondingPurse"),". WithdrawPurses prior to 1.5 were known as UnbondingPurses and now consist of historical data."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"bonding_purse")," The bonding purse, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-uref"},(0,l.kt)("inlineCode",{parentName:"a"},"URef")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"validator_public_key")," The public key of the validator, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"unbonder_public_key")," The public key of the unbonder, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"era_of_creation")," Era in which this unbonding request was created, as an ",(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"EraId"))," newtype, which serializes as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"u64"))," value.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"amount")," The unbonding amount, serialized as a ",(0,l.kt)("a",{parentName:"p",href:"#clvalue-numeric"},(0,l.kt)("inlineCode",{parentName:"a"},"U512"))," value."))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2c99ca03.bab7db00.js b/assets/js/2c99ca03.95e978e9.js similarity index 97% rename from assets/js/2c99ca03.bab7db00.js rename to assets/js/2c99ca03.95e978e9.js index 68fd4cdbc3..0294bcd0c3 100644 --- a/assets/js/2c99ca03.bab7db00.js +++ b/assets/js/2c99ca03.95e978e9.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[1258],{3905:function(e,t,n){n.d(t,{Zo:function(){return l},kt:function(){return f}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=p(n),m=a,f=u["".concat(s,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(f,i(i({ref:t},l),{},{components:n})):r.createElement(f,i({ref:t},l))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var p=2;p=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=p(n),m=a,f=u["".concat(s,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(f,i(i({ref:t},l),{},{components:n})):r.createElement(f,i({ref:t},l))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var p=2;p=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),g=a,h=u["".concat(s,".").concat(g)]||u[g]||d[g]||o;return n?r.createElement(h,i(i({ref:t},p),{},{components:n})):r.createElement(h,i({ref:t},p))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=g;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var l=2;l=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),g=a,h=u["".concat(s,".").concat(g)]||u[g]||d[g]||o;return n?r.createElement(h,i(i({ref:t},p),{},{components:n})):r.createElement(h,i({ref:t},p))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=g;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=u(r),f=a,m=p["".concat(s,".").concat(f)]||p[f]||d[f]||o;return r?n.createElement(m,i(i({ref:t},c),{},{components:r})):n.createElement(m,i({ref:t},c))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=f;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:a,i[1]=l;for(var u=2;u=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=u(r),f=a,m=p["".concat(s,".").concat(f)]||p[f]||d[f]||o;return r?n.createElement(m,i(i({ref:t},c),{},{components:r})):n.createElement(m,i({ref:t},c))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=f;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:a,i[1]=l;for(var u=2;u=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(n),h=r,f=p["".concat(l,".").concat(h)]||p[h]||d[h]||o;return n?a.createElement(f,i(i({ref:t},u),{},{components:n})):a.createElement(f,i({ref:t},u))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;c 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.')})))?void 0:n.filter(Boolean))?t:[]}(e).map((function(e){var t=e.props;return{value:t.value,label:t.label,attributes:t.attributes,default:t.default}}))}function d(e){var t=e.values,n=e.children;return(0,r.useMemo)((function(){var e=null!=t?t:p(n);return function(e){var t=(0,c.l)(e,(function(e,t){return e.value===t.value}));if(t.length>0)throw new Error('Docusaurus error: Duplicate values "'+t.map((function(e){return e.value})).join(", ")+'" found in . Every value needs to be unique.')}(e),e}),[t,n])}function h(e){var t=e.value;return e.tabValues.some((function(e){return e.value===t}))}function f(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId,o=(0,s.k6)(),i=function(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId;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 null!=a?a:null}({queryString:n,groupId:a});return[(0,l._X)(i),(0,r.useCallback)((function(e){if(i){var t=new URLSearchParams(o.location.search);t.set(i,e),o.replace(Object.assign({},o.location,{search:t.toString()}))}}),[i,o])]}function m(e){var t,n,a,o,i=e.defaultValue,s=e.queryString,l=void 0!==s&&s,c=e.groupId,p=d(e),m=(0,r.useState)((function(){return function(e){var t,n=e.defaultValue,a=e.tabValues;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((function(e){return e.value})).join(", ")+". If you intend to show no default tab, use defaultValue={null} instead.");return n}var r=null!=(t=a.find((function(e){return e.default})))?t:a[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:i,tabValues:p})})),b=m[0],v=m[1],y=f({queryString:l,groupId:c}),g=y[0],k=y[1],w=(t=function(e){return e?"docusaurus.tab."+e:null}({groupId:c}.groupId),n=(0,u.Nk)(t),a=n[0],o=n[1],[a,(0,r.useCallback)((function(e){t&&o.set(e)}),[t,o])]),T=w[0],N=w[1],C=function(){var e=null!=g?g:T;return h({value:e,tabValues:p})?e:null}();return(0,r.useLayoutEffect)((function(){C&&v(C)}),[C]),{selectedValue:b,selectValue:(0,r.useCallback)((function(e){if(!h({value:e,tabValues:p}))throw new Error("Can't select invalid tab value="+e);v(e),k(e),N(e)}),[k,N,p]),tabValues:p}}var b=n(2389),v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){var t=e.className,n=e.block,s=e.selectedValue,l=e.selectValue,c=e.tabValues,u=[],p=(0,i.o5)().blockElementScrollPositionUntilNextRender,d=function(e){var t=e.currentTarget,n=u.indexOf(t),a=c[n].value;a!==s&&(p(t),l(a))},h=function(e){var t,n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":var a,r=u.indexOf(e.currentTarget)+1;n=null!=(a=u[r])?a:u[0];break;case"ArrowLeft":var o,i=u.indexOf(e.currentTarget)-1;n=null!=(o=u[i])?o:u[u.length-1]}null==(t=n)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},c.map((function(e){var t=e.value,n=e.label,i=e.attributes;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:function(e){return u.push(e)},onKeyDown:h,onClick:d},i,{className:(0,o.Z)("tabs__item",v.tabItem,null==i?void 0:i.className,{"tabs__item--active":s===t})}),null!=n?n:t)})))}function g(e){var t=e.lazy,n=e.children,a=e.selectedValue,o=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){var i=o.find((function(e){return e.props.value===a}));return i?(0,r.cloneElement)(i,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map((function(e,t){return(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a})})))}function k(e){var t=m(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",v.tabList)},r.createElement(y,(0,a.Z)({},e,t)),r.createElement(g,(0,a.Z)({},e,t)))}function w(e){var t=(0,b.Z)();return r.createElement(k,(0,a.Z)({key:String(t)},e))}},8438:function(e,t,n){n.r(t),n.d(t,{assets:function(){return d},contentTitle:function(){return u},default:function(){return b},frontMatter:function(){return c},metadata:function(){return p},toc:function(){return h}});var a=n(7462),r=n(3366),o=(n(7294),n(3905)),i=n(4866),s=n(5162),l=["components"],c={},u="dApp Technology Stack",p={unversionedId:"developers/dapps/technology-stack",id:"developers/dapps/technology-stack",title:"dApp Technology Stack",description:"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.",source:"@site/source/docs/casper/developers/dapps/technology-stack.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/technology-stack",permalink:"/developers/dapps/technology-stack",draft:!1,editUrl:"https://github.com/casper-network/docs/tree/dev/source/docs/casper/developers/dapps/technology-stack.md",tags:[],version:"current",lastUpdatedAt:1707837031,formattedLastUpdatedAt:"Feb 13, 2024",frontMatter:{},sidebar:"developers",previous:{title:"Python SDK",permalink:"/developers/dapps/sdk/python-sdk"},next:{title:"Front-end in React",permalink:"/developers/dapps/template-frontend"}},d={},h=[{value:"Front-End",id:"front-end",level:2},{value:"Signing Transactions",id:"signing-transactions",level:3},{value:"Querying Global State",id:"querying-global-state",level:3},{value:"Backend",id:"backend",level:2},{value:"Blockchain",id:"blockchain",level:2}],f={toc:h},m="wrapper";function b(e){var t=e.components,n=(0,r.Z)(e,l);return(0,o.kt)(m,(0,a.Z)({},f,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"dapp-technology-stack"},"dApp Technology Stack"),(0,o.kt)("p",null,"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each."),(0,o.kt)("h2",{id:"front-end"},"Front-End"),(0,o.kt)("p",null,"The front-end, or ",(0,o.kt)("em",{parentName:"p"},"client-side")," of a dApp consists of the interface that the user uses to interact with smart contracts on a Casper Network. This interface usually comes in the form of a website/webpage, mobile device application or computer program, but could also include APIs with endpoints that may be called or queried."),(0,o.kt)("p",null,"You will need to choose a Casper-compatible SDK for the language you are using to call and query smart contracts on a Casper network. Casper's SDKs have methods available for constructing Deploys and gathering global state data. While these interactions can be prepared on the front-end, they must be sent to the backend of your application before being sent off to a network, so as to fulfill ",(0,o.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS"},"CORS")," requirements."),(0,o.kt)("h3",{id:"signing-transactions"},"Signing Transactions"),(0,o.kt)("p",null,"The signing of transactions will, in many cases, need to be performed by the user on the front-end, for which you have a couple options:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"The Casper Wallet"),(0,o.kt)("p",{parentName:"li"},"Use the ",(0,o.kt)("a",{parentName:"p",href:"https://www.casperwallet.io/develop"},"Casper Wallet")," to sign deploys for a Casper network. Deploy objects are first converted to JSON, then sent to the Wallet to be signed, then must be sent to the backend and forwarded to a node."),(0,o.kt)("admonition",{parentName:"li",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"The Casper Signer has been deprecated and replaced with the ",(0,o.kt)("a",{parentName:"p",href:"https://www.casperwallet.io"},"Casper Wallet"),". We are in the process of updating this page. Meanwhile, visit the guide on ",(0,o.kt)("a",{parentName:"p",href:"https://www.casperwallet.io/develop"},"Building with the Casper Wallet"),"."))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Third-party signers"),(0,o.kt)("p",{parentName:"li"},"Third-party signers may be used as well. A JSON representation of the unsigned transaction should be forwarded to the third-party signer and accept a callback containing the signed deploy object."))),(0,o.kt)("h3",{id:"querying-global-state"},"Querying Global State"),(0,o.kt)("p",null,"To execute a query of global state, such as retrieving smart contract data or getting current chain information, the preparation may be done on the front-end, but the query to a node must ultimately originate from your application's backend. This preparatory stage comes only in the form of defining a contract hash and the path which you'd like to query data. Alternately, for chain information, you must define the endpoint you'd like to query."),(0,o.kt)("h2",{id:"backend"},"Backend"),(0,o.kt)("p",null,"The backend of a dApp consists of the server-side code that connects the blockchain to the front-end interface and deals with data-parsing and application-layer communication. A backend server is necessary for building dApps on Casper as Casper's nodes expect ",(0,o.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS"},"CORS headers")," from a specified origin on the HTTP requests they receive. Backend servers are helpful for other reasons too, such as queueing requests and analyzing the traffic moving between your dApp and the blockchain."),(0,o.kt)("p",null,"As the backend server of a dApp is the software communicating with Casper nodes (the blockchain), it needs to receive information such as which node and endpoint to connect to."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-javascript"},'const client = new CasperClient("http://NODE_ADDRESS:7777/rpc");\n'))),(0,o.kt)(s.Z,{value:"py",label:"Python",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-javascript"},'client = NodeClient(NodeConnection((host = "NODE_ADDRESS"), (port_rpc = 7777)));\n')))),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"You can find online peers for Mainnet at ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live"},"cspr.live")," or testnet at ",(0,o.kt)("a",{parentName:"p",href:"https://testnet.cspr.live"},"testnet.cspr.live"))),(0,o.kt)("p",null,"There are two main types of blockchain interactions that will originate from the front-end: deploys and queries. In the case of a dApp, both of these will pass through the back-end."),(0,o.kt)("p",null,"Blockchain interaction for state queries is handled solely on the backend. On the front-end, a user simply chooses the path at which they want to query data. This path is sent to the backend where the server will perform the state query and send the result back to the front-end."),(0,o.kt)("p",null,"In the case of a user-signed transaction originating from the dApp's front-end, the backend will need to accept this transaction and forward it to a Casper network. This is often accomplished by opening a POST endpoint that accepts JSON formatted transactions and forwards them along."),(0,o.kt)("h2",{id:"blockchain"},"Blockchain"),(0,o.kt)("p",null,"The last stop for a deploy or query is the blockchain itself. Like the majority of smart contract blockchains, Casper networks maintain a forever-growing, immutable ledger that can be read and written to. When building a dApp for a Casper network, user interactions in the form of queries and deploys originate from the front-end, are forwarded to the backend, and are then sent to a Casper node for interaction with the blockchain. You can communicate with Casper nodes using JSON RPC calls, and have a variety of open ",(0,o.kt)("a",{parentName:"p",href:"/developers/json-rpc/json-rpc-transactional"},"transactional"),", ",(0,o.kt)("a",{parentName:"p",href:"/developers/json-rpc/json-rpc-informational"},"informational"),", and ",(0,o.kt)("a",{parentName:"p",href:"/developers/json-rpc/json-rpc-pos"},"Proof-of-Stake")," endpoints. By utilizing an SDK on the backend, you won't need to construct these JSON RPC calls yourself, they'll be done for you within the available methods."),(0,o.kt)("p",null,"More than likely, you will want your dApp to perform personalized functions, store custom data, and perhaps even store or transact upon tokens with monetary value. All of these behaviors can be implemented by writing custom smart contracts for your application. Smart contracts on a Casper network can perform any function that a classical computer can. Casper's smart contracts are executed as ",(0,o.kt)("a",{parentName:"p",href:"https://webassembly.org/"},"WebAssembly")," binaries, and can be written in any language that compiles to WebAssembly. Currently, most developers choose to write their smart contracts in ",(0,o.kt)("a",{parentName:"p",href:"https://www.rust-lang.org/"},"Rust")," for its reliability and ease-of-use. Additionally, Casper's smart contract documentation is written for Rust."),(0,o.kt)("p",null,"To learn how to write smart contracts for your dApp, read the ",(0,o.kt)("a",{parentName:"p",href:"/writing-contracts"},"smart contract documentation"),"."))}b.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[2882],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return f}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(n),h=r,f=p["".concat(l,".").concat(h)]||p[h]||d[h]||o;return n?a.createElement(f,i(i({ref:t},u),{},{components:n})):a.createElement(f,i({ref:t},u))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;c 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.')})))?void 0:n.filter(Boolean))?t:[]}(e).map((function(e){var t=e.props;return{value:t.value,label:t.label,attributes:t.attributes,default:t.default}}))}function d(e){var t=e.values,n=e.children;return(0,r.useMemo)((function(){var e=null!=t?t:p(n);return function(e){var t=(0,c.l)(e,(function(e,t){return e.value===t.value}));if(t.length>0)throw new Error('Docusaurus error: Duplicate values "'+t.map((function(e){return e.value})).join(", ")+'" found in . Every value needs to be unique.')}(e),e}),[t,n])}function h(e){var t=e.value;return e.tabValues.some((function(e){return e.value===t}))}function f(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId,o=(0,s.k6)(),i=function(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId;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 null!=a?a:null}({queryString:n,groupId:a});return[(0,l._X)(i),(0,r.useCallback)((function(e){if(i){var t=new URLSearchParams(o.location.search);t.set(i,e),o.replace(Object.assign({},o.location,{search:t.toString()}))}}),[i,o])]}function m(e){var t,n,a,o,i=e.defaultValue,s=e.queryString,l=void 0!==s&&s,c=e.groupId,p=d(e),m=(0,r.useState)((function(){return function(e){var t,n=e.defaultValue,a=e.tabValues;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((function(e){return e.value})).join(", ")+". If you intend to show no default tab, use defaultValue={null} instead.");return n}var r=null!=(t=a.find((function(e){return e.default})))?t:a[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:i,tabValues:p})})),b=m[0],v=m[1],y=f({queryString:l,groupId:c}),g=y[0],k=y[1],w=(t=function(e){return e?"docusaurus.tab."+e:null}({groupId:c}.groupId),n=(0,u.Nk)(t),a=n[0],o=n[1],[a,(0,r.useCallback)((function(e){t&&o.set(e)}),[t,o])]),T=w[0],N=w[1],C=function(){var e=null!=g?g:T;return h({value:e,tabValues:p})?e:null}();return(0,r.useLayoutEffect)((function(){C&&v(C)}),[C]),{selectedValue:b,selectValue:(0,r.useCallback)((function(e){if(!h({value:e,tabValues:p}))throw new Error("Can't select invalid tab value="+e);v(e),k(e),N(e)}),[k,N,p]),tabValues:p}}var b=n(2389),v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){var t=e.className,n=e.block,s=e.selectedValue,l=e.selectValue,c=e.tabValues,u=[],p=(0,i.o5)().blockElementScrollPositionUntilNextRender,d=function(e){var t=e.currentTarget,n=u.indexOf(t),a=c[n].value;a!==s&&(p(t),l(a))},h=function(e){var t,n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":var a,r=u.indexOf(e.currentTarget)+1;n=null!=(a=u[r])?a:u[0];break;case"ArrowLeft":var o,i=u.indexOf(e.currentTarget)-1;n=null!=(o=u[i])?o:u[u.length-1]}null==(t=n)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},c.map((function(e){var t=e.value,n=e.label,i=e.attributes;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:function(e){return u.push(e)},onKeyDown:h,onClick:d},i,{className:(0,o.Z)("tabs__item",v.tabItem,null==i?void 0:i.className,{"tabs__item--active":s===t})}),null!=n?n:t)})))}function g(e){var t=e.lazy,n=e.children,a=e.selectedValue,o=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){var i=o.find((function(e){return e.props.value===a}));return i?(0,r.cloneElement)(i,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map((function(e,t){return(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a})})))}function k(e){var t=m(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",v.tabList)},r.createElement(y,(0,a.Z)({},e,t)),r.createElement(g,(0,a.Z)({},e,t)))}function w(e){var t=(0,b.Z)();return r.createElement(k,(0,a.Z)({key:String(t)},e))}},8438:function(e,t,n){n.r(t),n.d(t,{assets:function(){return d},contentTitle:function(){return u},default:function(){return b},frontMatter:function(){return c},metadata:function(){return p},toc:function(){return h}});var a=n(7462),r=n(3366),o=(n(7294),n(3905)),i=n(4866),s=n(5162),l=["components"],c={},u="dApp Technology Stack",p={unversionedId:"developers/dapps/technology-stack",id:"developers/dapps/technology-stack",title:"dApp Technology Stack",description:"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.",source:"@site/source/docs/casper/developers/dapps/technology-stack.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/technology-stack",permalink:"/developers/dapps/technology-stack",draft:!1,editUrl:"https://github.com/casper-network/docs/tree/dev/source/docs/casper/developers/dapps/technology-stack.md",tags:[],version:"current",lastUpdatedAt:1708091908,formattedLastUpdatedAt:"Feb 16, 2024",frontMatter:{},sidebar:"developers",previous:{title:"Python SDK",permalink:"/developers/dapps/sdk/python-sdk"},next:{title:"Front-end in React",permalink:"/developers/dapps/template-frontend"}},d={},h=[{value:"Front-End",id:"front-end",level:2},{value:"Signing Transactions",id:"signing-transactions",level:3},{value:"Querying Global State",id:"querying-global-state",level:3},{value:"Backend",id:"backend",level:2},{value:"Blockchain",id:"blockchain",level:2}],f={toc:h},m="wrapper";function b(e){var t=e.components,n=(0,r.Z)(e,l);return(0,o.kt)(m,(0,a.Z)({},f,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"dapp-technology-stack"},"dApp Technology Stack"),(0,o.kt)("p",null,"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each."),(0,o.kt)("h2",{id:"front-end"},"Front-End"),(0,o.kt)("p",null,"The front-end, or ",(0,o.kt)("em",{parentName:"p"},"client-side")," of a dApp consists of the interface that the user uses to interact with smart contracts on a Casper Network. This interface usually comes in the form of a website/webpage, mobile device application or computer program, but could also include APIs with endpoints that may be called or queried."),(0,o.kt)("p",null,"You will need to choose a Casper-compatible SDK for the language you are using to call and query smart contracts on a Casper network. Casper's SDKs have methods available for constructing Deploys and gathering global state data. While these interactions can be prepared on the front-end, they must be sent to the backend of your application before being sent off to a network, so as to fulfill ",(0,o.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS"},"CORS")," requirements."),(0,o.kt)("h3",{id:"signing-transactions"},"Signing Transactions"),(0,o.kt)("p",null,"The signing of transactions will, in many cases, need to be performed by the user on the front-end, for which you have a couple options:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"The Casper Wallet"),(0,o.kt)("p",{parentName:"li"},"Use the ",(0,o.kt)("a",{parentName:"p",href:"https://www.casperwallet.io/develop"},"Casper Wallet")," to sign deploys for a Casper network. Deploy objects are first converted to JSON, then sent to the Wallet to be signed, then must be sent to the backend and forwarded to a node."),(0,o.kt)("admonition",{parentName:"li",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"The Casper Signer has been deprecated and replaced with the ",(0,o.kt)("a",{parentName:"p",href:"https://www.casperwallet.io"},"Casper Wallet"),". We are in the process of updating this page. Meanwhile, visit the guide on ",(0,o.kt)("a",{parentName:"p",href:"https://www.casperwallet.io/develop"},"Building with the Casper Wallet"),"."))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Third-party signers"),(0,o.kt)("p",{parentName:"li"},"Third-party signers may be used as well. A JSON representation of the unsigned transaction should be forwarded to the third-party signer and accept a callback containing the signed deploy object."))),(0,o.kt)("h3",{id:"querying-global-state"},"Querying Global State"),(0,o.kt)("p",null,"To execute a query of global state, such as retrieving smart contract data or getting current chain information, the preparation may be done on the front-end, but the query to a node must ultimately originate from your application's backend. This preparatory stage comes only in the form of defining a contract hash and the path which you'd like to query data. Alternately, for chain information, you must define the endpoint you'd like to query."),(0,o.kt)("h2",{id:"backend"},"Backend"),(0,o.kt)("p",null,"The backend of a dApp consists of the server-side code that connects the blockchain to the front-end interface and deals with data-parsing and application-layer communication. A backend server is necessary for building dApps on Casper as Casper's nodes expect ",(0,o.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS"},"CORS headers")," from a specified origin on the HTTP requests they receive. Backend servers are helpful for other reasons too, such as queueing requests and analyzing the traffic moving between your dApp and the blockchain."),(0,o.kt)("p",null,"As the backend server of a dApp is the software communicating with Casper nodes (the blockchain), it needs to receive information such as which node and endpoint to connect to."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-javascript"},'const client = new CasperClient("http://NODE_ADDRESS:7777/rpc");\n'))),(0,o.kt)(s.Z,{value:"py",label:"Python",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-javascript"},'client = NodeClient(NodeConnection((host = "NODE_ADDRESS"), (port_rpc = 7777)));\n')))),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"You can find online peers for Mainnet at ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live"},"cspr.live")," or testnet at ",(0,o.kt)("a",{parentName:"p",href:"https://testnet.cspr.live"},"testnet.cspr.live"))),(0,o.kt)("p",null,"There are two main types of blockchain interactions that will originate from the front-end: deploys and queries. In the case of a dApp, both of these will pass through the back-end."),(0,o.kt)("p",null,"Blockchain interaction for state queries is handled solely on the backend. On the front-end, a user simply chooses the path at which they want to query data. This path is sent to the backend where the server will perform the state query and send the result back to the front-end."),(0,o.kt)("p",null,"In the case of a user-signed transaction originating from the dApp's front-end, the backend will need to accept this transaction and forward it to a Casper network. This is often accomplished by opening a POST endpoint that accepts JSON formatted transactions and forwards them along."),(0,o.kt)("h2",{id:"blockchain"},"Blockchain"),(0,o.kt)("p",null,"The last stop for a deploy or query is the blockchain itself. Like the majority of smart contract blockchains, Casper networks maintain a forever-growing, immutable ledger that can be read and written to. When building a dApp for a Casper network, user interactions in the form of queries and deploys originate from the front-end, are forwarded to the backend, and are then sent to a Casper node for interaction with the blockchain. You can communicate with Casper nodes using JSON RPC calls, and have a variety of open ",(0,o.kt)("a",{parentName:"p",href:"/developers/json-rpc/json-rpc-transactional"},"transactional"),", ",(0,o.kt)("a",{parentName:"p",href:"/developers/json-rpc/json-rpc-informational"},"informational"),", and ",(0,o.kt)("a",{parentName:"p",href:"/developers/json-rpc/json-rpc-pos"},"Proof-of-Stake")," endpoints. By utilizing an SDK on the backend, you won't need to construct these JSON RPC calls yourself, they'll be done for you within the available methods."),(0,o.kt)("p",null,"More than likely, you will want your dApp to perform personalized functions, store custom data, and perhaps even store or transact upon tokens with monetary value. All of these behaviors can be implemented by writing custom smart contracts for your application. Smart contracts on a Casper network can perform any function that a classical computer can. Casper's smart contracts are executed as ",(0,o.kt)("a",{parentName:"p",href:"https://webassembly.org/"},"WebAssembly")," binaries, and can be written in any language that compiles to WebAssembly. Currently, most developers choose to write their smart contracts in ",(0,o.kt)("a",{parentName:"p",href:"https://www.rust-lang.org/"},"Rust")," for its reliability and ease-of-use. Additionally, Casper's smart contract documentation is written for Rust."),(0,o.kt)("p",null,"To learn how to write smart contracts for your dApp, read the ",(0,o.kt)("a",{parentName:"p",href:"/writing-contracts"},"smart contract documentation"),"."))}b.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/35a30807.332ce4d9.js b/assets/js/35a30807.8a2a2cef.js similarity index 97% rename from assets/js/35a30807.332ce4d9.js rename to assets/js/35a30807.8a2a2cef.js index fdb4a2ec09..5c70ee3c8f 100644 --- a/assets/js/35a30807.332ce4d9.js +++ b/assets/js/35a30807.8a2a2cef.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[8638],{3905:function(e,t,r){r.d(t,{Zo:function(){return l},kt:function(){return m}});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var a=n.createContext({}),s=function(e){var t=n.useContext(a),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},l=function(e){var t=s(e.components);return n.createElement(a.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,a=e.parentName,l=u(e,["components","mdxType","originalType","parentName"]),p=s(r),h=o,m=p["".concat(a,".").concat(h)]||p[h]||f[h]||i;return r?n.createElement(m,c(c({ref:t},l),{},{components:r})):n.createElement(m,c({ref:t},l))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,c=new Array(i);c[0]=h;var u={};for(var a in t)hasOwnProperty.call(t,a)&&(u[a]=t[a]);u.originalType=e,u[p]="string"==typeof e?e:o,c[1]=u;for(var s=2;s=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var a=n.createContext({}),s=function(e){var t=n.useContext(a),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},l=function(e){var t=s(e.components);return n.createElement(a.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,a=e.parentName,l=u(e,["components","mdxType","originalType","parentName"]),p=s(r),h=o,m=p["".concat(a,".").concat(h)]||p[h]||f[h]||i;return r?n.createElement(m,c(c({ref:t},l),{},{components:r})):n.createElement(m,c({ref:t},l))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,c=new Array(i);c[0]=h;var u={};for(var a in t)hasOwnProperty.call(t,a)&&(u[a]=t[a]);u.originalType=e,u[p]="string"==typeof e?e:o,c[1]=u;for(var s=2;s=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var p=r.createContext({}),l=function(e){var t=r.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},d=function(e){var t=l(e.components);return r.createElement(p.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,s=e.originalType,p=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),c=l(a),h=n,m=c["".concat(p,".").concat(h)]||c[h]||u[h]||s;return a?r.createElement(m,o(o({ref:t},d),{},{components:a})):r.createElement(m,o({ref:t},d))}));function m(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var s=a.length,o=new Array(s);o[0]=h;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[c]="string"==typeof e?e:n,o[1]=i;for(var l=2;l=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var p=r.createContext({}),l=function(e){var t=r.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},d=function(e){var t=l(e.components);return r.createElement(p.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,s=e.originalType,p=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),c=l(a),h=n,m=c["".concat(p,".").concat(h)]||c[h]||u[h]||s;return a?r.createElement(m,o(o({ref:t},d),{},{components:a})):r.createElement(m,o({ref:t},d))}));function m(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var s=a.length,o=new Array(s);o[0]=h;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[c]="string"==typeof e?e:n,o[1]=i;for(var l=2;l=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var c=a.createContext({}),l=function(e){var t=a.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},y=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,i=p(e,["components","mdxType","originalType","parentName"]),u=l(r),y=n,m=u["".concat(c,".").concat(y)]||u[y]||f[y]||o;return r?a.createElement(m,s(s({ref:t},i),{},{components:r})):a.createElement(m,s({ref:t},i))}));function m(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,s=new Array(o);s[0]=y;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[u]="string"==typeof e?e:n,s[1]=p;for(var l=2;l=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var c=a.createContext({}),l=function(e){var t=a.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},y=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,i=p(e,["components","mdxType","originalType","parentName"]),u=l(r),y=n,m=u["".concat(c,".").concat(y)]||u[y]||f[y]||o;return r?a.createElement(m,s(s({ref:t},i),{},{components:r})):a.createElement(m,s({ref:t},i))}));function m(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,s=new Array(o);s[0]=y;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[u]="string"==typeof e?e:n,s[1]=p;for(var l=2;l=0||(s[a]=e[a]);return s}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(s[a]=e[a])}return s}var i=n.createContext({}),d=function(e){var t=n.useContext(i),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},c=function(e){var t=d(e.components);return n.createElement(i.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,s=e.mdxType,r=e.originalType,i=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),p=d(a),m=s,h=p["".concat(i,".").concat(m)]||p[m]||u[m]||r;return a?n.createElement(h,l(l({ref:t},c),{},{components:a})):n.createElement(h,l({ref:t},c))}));function h(e,t){var a=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var r=a.length,l=new Array(r);l[0]=m;var o={};for(var i in t)hasOwnProperty.call(t,i)&&(o[i]=t[i]);o.originalType=e,o[p]="string"==typeof e?e:s,l[1]=o;for(var d=2;d\n")),(0,r.kt)("p",null,"Update the weight of the primary key to 3 by calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"update_associated_keys.wasm"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/update_associated_keys.wasm \\\n--session-arg "associated_key:key=\'account-hash-\'" \\\n--session-arg "new_weight:u8=\'3\'"\n')),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("p",null,"Retrieve the latest state root hash and check the primary account details."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash \\\n--key account-hash-\n")),(0,r.kt)("p",null,"The primary key in this account should now have weight 3."),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Account details"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'))),(0,r.kt)("p",null,"The table below summarizes the updates."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Threshold / Key"),(0,r.kt)("th",{parentName:"tr",align:null},"Previous weight"),(0,r.kt)("th",{parentName:"tr",align:null},"Current weight"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"deployment")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"key_management")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Primary key (",(0,r.kt)("inlineCode",{parentName:"td"},"1ed5..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")))),(0,r.kt)("h3",{id:"step-4-update-the-accounts-action-thresholds"},"Step 4: Update the account's action thresholds"),(0,r.kt)("p",null,"Set up a multi-signature scheme for the account by updating the ",(0,r.kt)("inlineCode",{parentName:"p"},"deployment")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"key_management")," thresholds. The ",(0,r.kt)("inlineCode",{parentName:"p"},"update_thresholds.wasm")," will take two arguments and set the ",(0,r.kt)("inlineCode",{parentName:"p"},"deployment")," threshold to 2 and the ",(0,r.kt)("inlineCode",{parentName:"p"},"key_management")," threshold to 3."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address https://rpc.testnet.casperlabs.io \\\n--chain-name casper-test \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/update_thresholds.wasm \\\n--session-arg \"deployment_threshold:u8='2'\" \\\n--session-arg \"key_management_threshold:u8='3'\"\n")),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("p",null,"Retrieve the latest state root hash and check the primary account details."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash \\\n--key account-hash-\n")),(0,r.kt)("p",null,"The account's action thresholds should look like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"action_thresholds": {\n "deployment": 2,\n "key_management": 3\n},\n')),(0,r.kt)("p",null,"This account configuration requires a cumulative weight of 3 to manage keys and a cumulative weight of 2 to send deploys. For example, if two associated keys have weight 1, they must both sign and send the deploy as part of this account context. The cumulative weight of these two keys would not meet the threshold for key management."),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Account details"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'))),(0,r.kt)("p",null,"The table below summarizes the updates."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Threshold / Key"),(0,r.kt)("th",{parentName:"tr",align:null},"Previous weight"),(0,r.kt)("th",{parentName:"tr",align:null},"Current weight"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"deployment")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"2")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"key_management")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Primary key (",(0,r.kt)("inlineCode",{parentName:"td"},"1ed5..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")))),(0,r.kt)("h3",{id:"step-5-add-associated-keys-to-the-primary-account"},"Step 5: Add associated keys to the primary account"),(0,r.kt)("p",null,"To add an associated key to the primary account, use the ",(0,r.kt)("inlineCode",{parentName:"p"},"add_account.wasm")," provided. This example adds two keys to the primary account (",(0,r.kt)("inlineCode",{parentName:"p"},"account-hash-d89c*"),"): ",(0,r.kt)("inlineCode",{parentName:"p"},"user_1")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"account-hash-e2d0*"),", and ",(0,r.kt)("inlineCode",{parentName:"p"},"user_2")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"account-hash-04a9*"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7" \\\n--session-arg "weight:u8=\'1\'"\n')),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f" \\\n--session-arg "weight:u8=\'1\'"\n')),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("p",null,"Retrieve the latest state root hash and check the primary account details."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash \\\n--key account-hash-\n")),(0,r.kt)("p",null,"Now, the account should have one primary key with weight 3, and two associated accounts, each with weight 1."),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Account details"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'))),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("ol",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ol"},"All associated keys should be kept incredibly secure to ensure the security and integrity of the account."),(0,r.kt)("li",{parentName:"ol"},"After all associated keys and action thresholds have been set to the desired multi-signature scheme, the weight of the original primary key can be increased or lowered, depending on your use case. Be careful with this! If you lower the primary key's weight below the key management threshold, the account will require multiple signatures for key management. The account will be unusable if you do not have enough associated keys set up."))),(0,r.kt)("p",null,"The table below summarizes the updates."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Threshold / Key"),(0,r.kt)("th",{parentName:"tr",align:null},"Previous weight"),(0,r.kt)("th",{parentName:"tr",align:null},"Current weight"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"deployment")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"2")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"key_management")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Primary key (",(0,r.kt)("inlineCode",{parentName:"td"},"1ed5..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"04a9..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"N/A"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"e2d0..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"N/A"),(0,r.kt)("td",{parentName:"tr",align:null},"1")))),(0,r.kt)("h3",{id:"step-6-send-a-deploy-from-the-primary-account"},"Step 6: Send a deploy from the primary account"),(0,r.kt)("p",null,"This step sends a deploy containing Wasm (",(0,r.kt)("inlineCode",{parentName:"p"},"contract.wasm"),"), which adds a named key to the account. The source code for the Wasm comes from the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/hello-world"},"hello-world")," repository. The deploy should succeed as the primary account has a weight of 3, which is greater than the deployment threshold."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy --chain-name casper-test \\\n--payment-amount 3000000000 \\\n--session-path tests/wasm/contract.wasm \\\n--secret-key $PATH/secret_key.pem \\\n--session-arg \"my-key-name:string='primary_account_key'\" \\\n--session-arg \"message:string='Hello, World'\"\n")),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("p",null,"Retrieve the latest state root hash and check the primary account details."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash \\\n--key account-hash-\n")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"hello_world.wasm")," should have run and added a named key to the account."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"named_keys": [\n {\n "key": "uref-9b9ecaa9e5e235fc6955d4d528cb1b5b38f2d800f6cbbc55351131a3701b5a81-007",\n "name": "my-key-name"\n }\n]\n')),(0,r.kt)("h3",{id:"step-7-send-a-multi-signature-deploy-from-an-associated-key"},"Step 7: Send a multi-signature deploy from an associated key"),(0,r.kt)("p",null,"Given the multi-signature scheme set up in this example, two associated keys need to sign to send a deploy from one of the associated keys. This example uses the following commands to sign a deploy with multiple keys and send it to the network:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"make-deploy")," - creates and signs a deploy, saving the output to a file"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"sign-deploy")," - adds additional signatures for a multi-signature deploy"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"send-deploy")," - sends the deploy to the network")),(0,r.kt)("p",null,"Similar to step 6, this example uses Wasm (",(0,r.kt)("inlineCode",{parentName:"p"},"contract.wasm"),"), which adds a named key to the account. The deploy originates from the primary account, specified with the ",(0,r.kt)("inlineCode",{parentName:"p"},"--session-account")," argument. The deploy needs two signatures to meet the ",(0,r.kt)("inlineCode",{parentName:"p"},"deployment")," weight equal to 2. Once both associated keys sign the deploy, either can send it to the network."),(0,r.kt)("p",null,"When using the ",(0,r.kt)("inlineCode",{parentName:"p"},"--session-account")," argument, specify the hex-encoded public key of the primary account context under which the session code will be executed."),(0,r.kt)("p",null,"One associated key creates and signs the deploy with the ",(0,r.kt)("inlineCode",{parentName:"p"},"make-deploy")," command, indicating the account context under which the session code will be executed."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client make-deploy --chain-name casper-test \\\n--payment-amount 300000000 \\\n--session-path tests/wasm/contract.wasm \\\n--secret-key $PATH/user_1_secret_key.pem \\\n--session-arg \"my-key-name:string='user_1_key'\" \\\n--session-arg \"message:string='Hello, World'\" \\\n--session-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \\\n--output hello_world_one_signature\n")),(0,r.kt)("p",null,"The second associated key signs the deploy with ",(0,r.kt)("inlineCode",{parentName:"p"},"sign-deploy")," to meet the deployment threshold for the account."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client sign-deploy -i hello_world_one_signature -k $PATH/user_2_secret_key.pem -o hello_world_two_signatures\n")),(0,r.kt)("p",null,"The deploy can be sent to the network using the ",(0,r.kt)("inlineCode",{parentName:"p"},"send-deploy")," command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client send-deploy --node-address https://rpc.testnet.casperlabs.io -i hello_world_two_signatures\n")),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("p",null,"Retrieve the latest state root hash and check the primary account details."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash \\\n--key account-hash-\n")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"hello_world.wasm")," should have run and added a named key to the account."),(0,r.kt)("h2",{id:"removing-a-compromised-key"},"Removing a Compromised Key"),(0,r.kt)("p",null,"This example shows how to remove a compromised key from an account. The example adds an associated key only to remove it using the ",(0,r.kt)("inlineCode",{parentName:"p"},"remove_account.wasm")," session code."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Remove keys with caution! Do not run this example on Mainnet."),(0,r.kt)("p",{parentName:"admonition"},"Before removing a key, ensure the remaining associated keys can combine their weight to meet the threshold for key management. Otherwise, the account could become unusable. Changing key weights or adding new associated keys would only be possible by meeting the key management threshold. Proceed with caution.")),(0,r.kt)("p",null,"Given the current setup, the primary account will add an associated key, and then remove it. In other use cases, associated keys may need to combine their signatures to send a multi-sig deploy that removes a key."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8" \\\n--session-arg "weight:u8=\'1\'"\n')),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("p",null,"Retrieve the latest state root hash and check the primary account details."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash \\\n--key account-hash-\n")),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Account details"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'))),(0,r.kt)("p",null,"The table below summarizes the updates after calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"add_account.wasm"),"."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Threshold / Key"),(0,r.kt)("th",{parentName:"tr",align:null},"Previous weight"),(0,r.kt)("th",{parentName:"tr",align:null},"Current weight"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"deployment")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"2")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"key_management")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Primary key (",(0,r.kt)("inlineCode",{parentName:"td"},"1ed5..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"04a9..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"e2d0..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"1fed..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"N/A"),(0,r.kt)("td",{parentName:"tr",align:null},"1")))),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"remove_account.wasm")," will remove the newly added account to demonstrate the possibility of removing associated keys that may have been compromised."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/remove_account.wasm \\\n--session-arg "remove_key:key=\'account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8"\n')),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("p",null,"Retrieve the latest state root hash and check the primary account details."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash \\\n--key account-hash-\n")),(0,r.kt)("p",null,"The resulting account should not contain the associated key that was just removed."),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Account details"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'))),(0,r.kt)("p",null,"The table below summarizes the updates after calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"remove_account.wasm"),"."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Threshold / Key"),(0,r.kt)("th",{parentName:"tr",align:null},"Previous weight"),(0,r.kt)("th",{parentName:"tr",align:null},"Current weight"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"deployment")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"2")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"key_management")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Primary key (",(0,r.kt)("inlineCode",{parentName:"td"},"1ed5..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"04a9..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"e2d0..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"1fed..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"N/A (Removed)")))),(0,r.kt)("h2",{id:"next-steps"},"Next Steps"),(0,r.kt)("p",null,"The next section contains ",(0,r.kt)("a",{parentName:"p",href:"/resources/advanced/multi-sig/other-scenarios"},"additional examples")," where Casper's multi-signature feature would be helpful."))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[2870],{3905:function(e,t,a){a.d(t,{Zo:function(){return c},kt:function(){return h}});var n=a(7294);function s(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function l(e){for(var t=1;t=0||(s[a]=e[a]);return s}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(s[a]=e[a])}return s}var i=n.createContext({}),d=function(e){var t=n.useContext(i),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},c=function(e){var t=d(e.components);return n.createElement(i.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,s=e.mdxType,r=e.originalType,i=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),p=d(a),m=s,h=p["".concat(i,".").concat(m)]||p[m]||u[m]||r;return a?n.createElement(h,l(l({ref:t},c),{},{components:a})):n.createElement(h,l({ref:t},c))}));function h(e,t){var a=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var r=a.length,l=new Array(r);l[0]=m;var o={};for(var i in t)hasOwnProperty.call(t,i)&&(o[i]=t[i]);o.originalType=e,o[p]="string"==typeof e?e:s,l[1]=o;for(var d=2;d\n")),(0,r.kt)("p",null,"Update the weight of the primary key to 3 by calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"update_associated_keys.wasm"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/update_associated_keys.wasm \\\n--session-arg "associated_key:key=\'account-hash-\'" \\\n--session-arg "new_weight:u8=\'3\'"\n')),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("p",null,"Retrieve the latest state root hash and check the primary account details."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash \\\n--key account-hash-\n")),(0,r.kt)("p",null,"The primary key in this account should now have weight 3."),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Account details"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'))),(0,r.kt)("p",null,"The table below summarizes the updates."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Threshold / Key"),(0,r.kt)("th",{parentName:"tr",align:null},"Previous weight"),(0,r.kt)("th",{parentName:"tr",align:null},"Current weight"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"deployment")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"key_management")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Primary key (",(0,r.kt)("inlineCode",{parentName:"td"},"1ed5..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")))),(0,r.kt)("h3",{id:"step-4-update-the-accounts-action-thresholds"},"Step 4: Update the account's action thresholds"),(0,r.kt)("p",null,"Set up a multi-signature scheme for the account by updating the ",(0,r.kt)("inlineCode",{parentName:"p"},"deployment")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"key_management")," thresholds. The ",(0,r.kt)("inlineCode",{parentName:"p"},"update_thresholds.wasm")," will take two arguments and set the ",(0,r.kt)("inlineCode",{parentName:"p"},"deployment")," threshold to 2 and the ",(0,r.kt)("inlineCode",{parentName:"p"},"key_management")," threshold to 3."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address https://rpc.testnet.casperlabs.io \\\n--chain-name casper-test \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/update_thresholds.wasm \\\n--session-arg \"deployment_threshold:u8='2'\" \\\n--session-arg \"key_management_threshold:u8='3'\"\n")),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("p",null,"Retrieve the latest state root hash and check the primary account details."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash \\\n--key account-hash-\n")),(0,r.kt)("p",null,"The account's action thresholds should look like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"action_thresholds": {\n "deployment": 2,\n "key_management": 3\n},\n')),(0,r.kt)("p",null,"This account configuration requires a cumulative weight of 3 to manage keys and a cumulative weight of 2 to send deploys. For example, if two associated keys have weight 1, they must both sign and send the deploy as part of this account context. The cumulative weight of these two keys would not meet the threshold for key management."),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Account details"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'))),(0,r.kt)("p",null,"The table below summarizes the updates."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Threshold / Key"),(0,r.kt)("th",{parentName:"tr",align:null},"Previous weight"),(0,r.kt)("th",{parentName:"tr",align:null},"Current weight"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"deployment")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"2")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"key_management")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Primary key (",(0,r.kt)("inlineCode",{parentName:"td"},"1ed5..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")))),(0,r.kt)("h3",{id:"step-5-add-associated-keys-to-the-primary-account"},"Step 5: Add associated keys to the primary account"),(0,r.kt)("p",null,"To add an associated key to the primary account, use the ",(0,r.kt)("inlineCode",{parentName:"p"},"add_account.wasm")," provided. This example adds two keys to the primary account (",(0,r.kt)("inlineCode",{parentName:"p"},"account-hash-d89c*"),"): ",(0,r.kt)("inlineCode",{parentName:"p"},"user_1")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"account-hash-e2d0*"),", and ",(0,r.kt)("inlineCode",{parentName:"p"},"user_2")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"account-hash-04a9*"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7" \\\n--session-arg "weight:u8=\'1\'"\n')),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f" \\\n--session-arg "weight:u8=\'1\'"\n')),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("p",null,"Retrieve the latest state root hash and check the primary account details."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash \\\n--key account-hash-\n")),(0,r.kt)("p",null,"Now, the account should have one primary key with weight 3, and two associated accounts, each with weight 1."),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Account details"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'))),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("ol",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ol"},"All associated keys should be kept incredibly secure to ensure the security and integrity of the account."),(0,r.kt)("li",{parentName:"ol"},"After all associated keys and action thresholds have been set to the desired multi-signature scheme, the weight of the original primary key can be increased or lowered, depending on your use case. Be careful with this! If you lower the primary key's weight below the key management threshold, the account will require multiple signatures for key management. The account will be unusable if you do not have enough associated keys set up."))),(0,r.kt)("p",null,"The table below summarizes the updates."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Threshold / Key"),(0,r.kt)("th",{parentName:"tr",align:null},"Previous weight"),(0,r.kt)("th",{parentName:"tr",align:null},"Current weight"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"deployment")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"2")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"key_management")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Primary key (",(0,r.kt)("inlineCode",{parentName:"td"},"1ed5..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"04a9..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"N/A"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"e2d0..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"N/A"),(0,r.kt)("td",{parentName:"tr",align:null},"1")))),(0,r.kt)("h3",{id:"step-6-send-a-deploy-from-the-primary-account"},"Step 6: Send a deploy from the primary account"),(0,r.kt)("p",null,"This step sends a deploy containing Wasm (",(0,r.kt)("inlineCode",{parentName:"p"},"contract.wasm"),"), which adds a named key to the account. The source code for the Wasm comes from the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/hello-world"},"hello-world")," repository. The deploy should succeed as the primary account has a weight of 3, which is greater than the deployment threshold."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy --chain-name casper-test \\\n--payment-amount 3000000000 \\\n--session-path tests/wasm/contract.wasm \\\n--secret-key $PATH/secret_key.pem \\\n--session-arg \"my-key-name:string='primary_account_key'\" \\\n--session-arg \"message:string='Hello, World'\"\n")),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("p",null,"Retrieve the latest state root hash and check the primary account details."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash \\\n--key account-hash-\n")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"hello_world.wasm")," should have run and added a named key to the account."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"named_keys": [\n {\n "key": "uref-9b9ecaa9e5e235fc6955d4d528cb1b5b38f2d800f6cbbc55351131a3701b5a81-007",\n "name": "my-key-name"\n }\n]\n')),(0,r.kt)("h3",{id:"step-7-send-a-multi-signature-deploy-from-an-associated-key"},"Step 7: Send a multi-signature deploy from an associated key"),(0,r.kt)("p",null,"Given the multi-signature scheme set up in this example, two associated keys need to sign to send a deploy from one of the associated keys. This example uses the following commands to sign a deploy with multiple keys and send it to the network:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"make-deploy")," - creates and signs a deploy, saving the output to a file"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"sign-deploy")," - adds additional signatures for a multi-signature deploy"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"send-deploy")," - sends the deploy to the network")),(0,r.kt)("p",null,"Similar to step 6, this example uses Wasm (",(0,r.kt)("inlineCode",{parentName:"p"},"contract.wasm"),"), which adds a named key to the account. The deploy originates from the primary account, specified with the ",(0,r.kt)("inlineCode",{parentName:"p"},"--session-account")," argument. The deploy needs two signatures to meet the ",(0,r.kt)("inlineCode",{parentName:"p"},"deployment")," weight equal to 2. Once both associated keys sign the deploy, either can send it to the network."),(0,r.kt)("p",null,"When using the ",(0,r.kt)("inlineCode",{parentName:"p"},"--session-account")," argument, specify the hex-encoded public key of the primary account context under which the session code will be executed."),(0,r.kt)("p",null,"One associated key creates and signs the deploy with the ",(0,r.kt)("inlineCode",{parentName:"p"},"make-deploy")," command, indicating the account context under which the session code will be executed."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client make-deploy --chain-name casper-test \\\n--payment-amount 300000000 \\\n--session-path tests/wasm/contract.wasm \\\n--secret-key $PATH/user_1_secret_key.pem \\\n--session-arg \"my-key-name:string='user_1_key'\" \\\n--session-arg \"message:string='Hello, World'\" \\\n--session-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \\\n--output hello_world_one_signature\n")),(0,r.kt)("p",null,"The second associated key signs the deploy with ",(0,r.kt)("inlineCode",{parentName:"p"},"sign-deploy")," to meet the deployment threshold for the account."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client sign-deploy -i hello_world_one_signature -k $PATH/user_2_secret_key.pem -o hello_world_two_signatures\n")),(0,r.kt)("p",null,"The deploy can be sent to the network using the ",(0,r.kt)("inlineCode",{parentName:"p"},"send-deploy")," command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client send-deploy --node-address https://rpc.testnet.casperlabs.io -i hello_world_two_signatures\n")),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("p",null,"Retrieve the latest state root hash and check the primary account details."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash \\\n--key account-hash-\n")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"hello_world.wasm")," should have run and added a named key to the account."),(0,r.kt)("h2",{id:"removing-a-compromised-key"},"Removing a Compromised Key"),(0,r.kt)("p",null,"This example shows how to remove a compromised key from an account. The example adds an associated key only to remove it using the ",(0,r.kt)("inlineCode",{parentName:"p"},"remove_account.wasm")," session code."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Remove keys with caution! Do not run this example on Mainnet."),(0,r.kt)("p",{parentName:"admonition"},"Before removing a key, ensure the remaining associated keys can combine their weight to meet the threshold for key management. Otherwise, the account could become unusable. Changing key weights or adding new associated keys would only be possible by meeting the key management threshold. Proceed with caution.")),(0,r.kt)("p",null,"Given the current setup, the primary account will add an associated key, and then remove it. In other use cases, associated keys may need to combine their signatures to send a multi-sig deploy that removes a key."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8" \\\n--session-arg "weight:u8=\'1\'"\n')),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("p",null,"Retrieve the latest state root hash and check the primary account details."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash \\\n--key account-hash-\n")),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Account details"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'))),(0,r.kt)("p",null,"The table below summarizes the updates after calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"add_account.wasm"),"."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Threshold / Key"),(0,r.kt)("th",{parentName:"tr",align:null},"Previous weight"),(0,r.kt)("th",{parentName:"tr",align:null},"Current weight"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"deployment")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"2")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"key_management")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Primary key (",(0,r.kt)("inlineCode",{parentName:"td"},"1ed5..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"04a9..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"e2d0..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"1fed..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"N/A"),(0,r.kt)("td",{parentName:"tr",align:null},"1")))),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"remove_account.wasm")," will remove the newly added account to demonstrate the possibility of removing associated keys that may have been compromised."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/remove_account.wasm \\\n--session-arg "remove_key:key=\'account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8"\n')),(0,r.kt)("p",null,"Verify that the deploy ran successfully."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ \n")),(0,r.kt)("p",null,"Retrieve the latest state root hash and check the primary account details."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash \\\n--key account-hash-\n")),(0,r.kt)("p",null,"The resulting account should not contain the associated key that was just removed."),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Account details"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'))),(0,r.kt)("p",null,"The table below summarizes the updates after calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"remove_account.wasm"),"."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Threshold / Key"),(0,r.kt)("th",{parentName:"tr",align:null},"Previous weight"),(0,r.kt)("th",{parentName:"tr",align:null},"Current weight"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"deployment")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"2")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"key_management")),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Primary key (",(0,r.kt)("inlineCode",{parentName:"td"},"1ed5..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"3")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"04a9..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"e2d0..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Associated key (",(0,r.kt)("inlineCode",{parentName:"td"},"1fed..."),")"),(0,r.kt)("td",{parentName:"tr",align:null},"1"),(0,r.kt)("td",{parentName:"tr",align:null},"N/A (Removed)")))),(0,r.kt)("h2",{id:"next-steps"},"Next Steps"),(0,r.kt)("p",null,"The next section contains ",(0,r.kt)("a",{parentName:"p",href:"/resources/advanced/multi-sig/other-scenarios"},"additional examples")," where Casper's multi-signature feature would be helpful."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3b05c439.ca8c75d2.js b/assets/js/3b05c439.24bc6364.js similarity index 99% rename from assets/js/3b05c439.ca8c75d2.js rename to assets/js/3b05c439.24bc6364.js index 178940a8f2..27623ec32e 100644 --- a/assets/js/3b05c439.ca8c75d2.js +++ b/assets/js/3b05c439.24bc6364.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[299],{3905:function(e,t,o){o.d(t,{Zo:function(){return p},kt:function(){return u}});var a=o(7294);function n(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function r(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,a)}return o}function s(e){for(var t=1;t=0||(n[o]=e[o]);return n}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(n[o]=e[o])}return n}var c=a.createContext({}),i=function(e){var t=a.useContext(c),o=t;return e&&(o="function"==typeof e?e(t):s(s({},t),e)),o},p=function(e){var t=i(e.components);return a.createElement(c.Provider,{value:t},e.children)},k="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var o=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),k=i(o),d=n,u=k["".concat(c,".").concat(d)]||k[d]||h[d]||r;return o?a.createElement(u,s(s({ref:t},p),{},{components:o})):a.createElement(u,s({ref:t},p))}));function u(e,t){var o=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=o.length,s=new Array(r);s[0]=d;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[k]="string"==typeof e?e:n,s[1]=l;for(var i=2;i=0||(n[o]=e[o]);return n}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(n[o]=e[o])}return n}var c=a.createContext({}),i=function(e){var t=a.useContext(c),o=t;return e&&(o="function"==typeof e?e(t):s(s({},t),e)),o},p=function(e){var t=i(e.components);return a.createElement(c.Provider,{value:t},e.children)},k="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var o=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),k=i(o),d=n,u=k["".concat(c,".").concat(d)]||k[d]||h[d]||r;return o?a.createElement(u,s(s({ref:t},p),{},{components:o})):a.createElement(u,s({ref:t},p))}));function u(e,t){var o=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=o.length,s=new Array(r);s[0]=d;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[k]="string"==typeof e?e:n,s[1]=l;for(var i=2;i=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=r.createContext({}),l=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},i=function(e){var t=l(e.components);return r.createElement(p.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,f=u["".concat(p,".").concat(m)]||u[m]||h[m]||o;return n?r.createElement(f,s(s({ref:t},i),{},{components:n})):r.createElement(f,s({ref:t},i))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=m;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=r.createContext({}),l=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},i=function(e){var t=l(e.components);return r.createElement(p.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,f=u["".concat(p,".").concat(m)]||u[m]||h[m]||o;return n?r.createElement(f,s(s({ref:t},i),{},{components:n})):r.createElement(f,s({ref:t},i))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=m;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),l=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(i.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(r),d=a,f=u["".concat(i,".").concat(d)]||u[d]||m[d]||o;return r?n.createElement(f,c(c({ref:t},p),{},{components:r})):n.createElement(f,c({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,c=new Array(o);c[0]=d;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[u]="string"==typeof e?e:a,c[1]=s;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),l=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(i.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(r),d=a,f=u["".concat(i,".").concat(d)]||u[d]||m[d]||o;return r?n.createElement(f,c(c({ref:t},p),{},{components:r})):n.createElement(f,c({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,c=new Array(o);c[0]=d;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[u]="string"==typeof e?e:a,c[1]=s;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(r),y=a,m=u["".concat(p,".").concat(y)]||u[y]||f[y]||o;return r?n.createElement(m,s(s({ref:t},i),{},{components:r})):n.createElement(m,s({ref:t},i))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(r),y=a,m=u["".concat(p,".").concat(y)]||u[y]||f[y]||o;return r?n.createElement(m,s(s({ref:t},i),{},{components:r})):n.createElement(m,s({ref:t},i))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),l=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),d=l(n),m=r,h=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?a.createElement(h,i(i({ref:t},p),{},{components:n})):a.createElement(h,i({ref:t},p))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[d]="string"==typeof e?e:r,i[1]=c;for(var l=2;lcargo casper",id:"automatic-project-setup",level:3},{value:"Semi-automatically using plain cargo",id:"semi-automatic-project-setup",level:3},{value:"Manually",id:"manual-project-setup",level:3},{value:"Dependencies",id:"dependencies",level:3},{value:"Writing a Basic Smart Contract",id:"writing-a-basic-smart-contract",level:2},{value:"Updating the main.rs File",id:"updating-the-mainrs-file",level:3},{value:"Defining required dependencies",id:"defining-required-dependencies",level:4},{value:"Defining the global constants",id:"defining-the-global-constants",level:4},{value:"Defining the contract entry points",id:"defining-the-contract-entry-points",level:4},{value:"Defining the call function",id:"defining-the-call-function",level:4},{value:"Locked Contracts",id:"locked-contracts",level:2},{value:"Compiling Contract Code",id:"compiling-contract-code",level:2},{value:"Executing Contract Code",id:"executing-contract-code",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}],u={toc:d},m="wrapper";function h(e){var t=e.components,n=(0,r.Z)(e,i);return(0,o.kt)(m,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"writing-a-basic-smart-contract-in-rust"},"Writing a Basic Smart Contract in Rust"),(0,o.kt)("h2",{id:"what-is-a-smart-contract"},"What is a Smart Contract?"),(0,o.kt)("p",null,"A smart contract is a self-contained program installed on a blockchain. In the context of a Casper network, a smart contract consists of contract code installed on-chain using a ",(0,o.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#execution-semantics-deploys"},"Deploy"),". Casper smart contracts are programs that run on a Casper network. They interact with accounts and other contracts through entry points, allowing for various triggers, conditions, and logic."),(0,o.kt)("p",null,"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. These contracts can, in turn, call one another to perform interconnected operations and create more complex programs. The decentralized nature of blockchain technology means that these smart contracts do not suffer from any single point of failure. Even if a Casper node leaves the network, other nodes will continue to allow the contract to operate as intended."),(0,o.kt)("h2",{id:"key-features-of-casper-contracts"},"Key Features of Casper Contracts"),(0,o.kt)("p",null,"On the Casper platform, developers may write smart contracts in any language that compiles to Wasm binaries. This tutorial focuses specifically on writing a smart contract in the Rust language. The Rust compiler compiles the contract code into Wasm. After that, the Wasm binary can be ",(0,o.kt)("a",{parentName:"p",href:"/developers/cli/installing-contracts"},"sent to a node")," on a Casper network using a Deploy. Nodes within the network then ",(0,o.kt)("a",{parentName:"p",href:"/concepts/design/p2p#communications-gossiping"},"gossip deploys"),", include them within a block, and finalize them. After finalizing, the network executes the deploys within the block."),(0,o.kt)("p",null,"Further, the Casper platform allows for ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/upgrading-contracts"},"upgradable contracts"),". A ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackage.html"},"ContractPackage")," is created through the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html"},"new_contract")," or ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_locked_contract.html"},"new_locked_contract")," methods. Through these methods, the Casper execution engine automatically creates the new contract package and assigns a ",(0,o.kt)("a",{parentName:"p",href:"/concepts/hash-types#hash-and-key-explanations"},(0,o.kt)("inlineCode",{parentName:"a"},"ContractPackageHash")),". The new contract is added to this package with a ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html"},(0,o.kt)("inlineCode",{parentName:"a"},"ContractHash"))," key. The execution engine stores the new contract within the contract package alongside any previously installed contract versions, if applicable."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"new_contract")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"new_locked_contract")," methods are a convenience that automatically creates the package associated with a new contract. Developers choosing not to use these methods must first create a contract package to function as a container for their new contract."),(0,o.kt)("p",null,"The contract contains required metadata, and it is primarily identified by its ",(0,o.kt)("inlineCode",{parentName:"p"},"ContractHash"),". While the contract hash identifies a specific ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html"},"ContractVersion"),", the ",(0,o.kt)("inlineCode",{parentName:"p"},"ContractPackageHash")," serves as an identifier for the most recent contract version in the contract package."),(0,o.kt)("h2",{id:"directory-structure"},"Creating the Directory Structure"),(0,o.kt)("p",null,"To begin creating a smart contract, you need to set up the project structure, either manually or automatically, as shown below."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"project-directory/\n\n\u2514\u2500\u2500 contract/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 main.rs\n \u2514\u2500\u2500 Cargo.toml\n\n\u2514\u2500\u2500 Makefile\n\u2514\u2500\u2500 rust-toolchain\n\n\u2514\u2500\u2500 tests/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 integration-tests.rs\n \u2514\u2500\u2500 Cargo.toml\n")),(0,o.kt)("p",null,"The project structure would be different in a dApp with full-stack architecture. "),(0,o.kt)("h3",{id:"automatic-project-setup"},"Automatically using ",(0,o.kt)("inlineCode",{parentName:"h3"},"cargo casper")),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/getting-started#creating-a-project"},"cargo casper command")," can automatically set up the project structure. This is the recommended way of setting up a new Casper project."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cargo casper my-project\n")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"cargo casper")," command will generate an example contract in the contract directory and an example ",(0,o.kt)("inlineCode",{parentName:"p"},"tests")," crate with logic defined in the ",(0,o.kt)("inlineCode",{parentName:"p"},"integration-tests.rs")," file. The ",(0,o.kt)("inlineCode",{parentName:"p"},"Makefile")," includes commands to prepare and build the contract, and the ",(0,o.kt)("inlineCode",{parentName:"p"},"rust-toolchain")," file specifies the target build version of Rust."),(0,o.kt)("h3",{id:"semi-automatic-project-setup"},"Semi-automatically using plain ",(0,o.kt)("inlineCode",{parentName:"h3"},"cargo")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"If you are a beginner, ",(0,o.kt)("a",{parentName:"p",href:"#creating-the-project-automatically"},"creating the structure automatically")," with ",(0,o.kt)("inlineCode",{parentName:"p"},"cargo casper")," is recommended and the command creates everything you need to start coding.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Create a top-level project directory for the contract code and its corresponding tests.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Inside the project directory, run the following command to create a new binary package called ",(0,o.kt)("inlineCode",{parentName:"p"},"contract"),". Use a different name instead of ",(0,o.kt)("inlineCode",{parentName:"p"},"contract")," if you wish."),(0,o.kt)("pre",{parentName:"li"},(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cargo new contract\n")),(0,o.kt)("p",{parentName:"li"},"The command creates a ",(0,o.kt)("inlineCode",{parentName:"p"},"contract")," folder with a ",(0,o.kt)("inlineCode",{parentName:"p"},"/src/main.rs")," file and a ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file:"),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"main.rs")," - This file would contain the contract code."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Cargo.toml")," - This file would contain crate dependencies and other configurations.")),(0,o.kt)("p",{parentName:"li"},"The following sections explain how to update these files using example code.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Inside the project directory, run the command to auto-generate the folder structure for the tests. Use a different name instead of ",(0,o.kt)("inlineCode",{parentName:"p"},"tests")," if you wish."),(0,o.kt)("pre",{parentName:"li"},(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cargo new tests\n")),(0,o.kt)("p",{parentName:"li"},"The command creates a ",(0,o.kt)("inlineCode",{parentName:"p"},"tests")," folder with a ",(0,o.kt)("inlineCode",{parentName:"p"},"/src/main.rs")," file and a ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file:"),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"main.rs")," - This file would store the unit test code required to test the contract. You can rename the file to ",(0,o.kt)("inlineCode",{parentName:"li"},"integration-tests.rs")," as shown in the example structure."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Cargo.toml")," - This is the file with test configurations.")),(0,o.kt)("p",{parentName:"li"},"The ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/testing-contracts"},"Testing Smart Contracts")," guide explains how to update the tests using example code.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Unlike ",(0,o.kt)("inlineCode",{parentName:"p"},"cargo casper"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"cargo")," does not create a ",(0,o.kt)("inlineCode",{parentName:"p"},"Makefile")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"rust-toolchain")," configuration file. Therefore, you must manually add these files to the project's root folder."))),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Example Makefile"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"prepare:\n rustup target add wasm32-unknown-unknown\n\nbuild-contract:\n cd contract && cargo build --release --target wasm32-unknown-unknown\n wasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n\ntest: build-contract\n mkdir -p tests/wasm\n cp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm\n cd tests && cargo test\n\nclippy:\n cd contract && cargo clippy --all-targets -- -D warnings\n cd tests && cargo clippy --all-targets -- -D warnings\n\ncheck-lint: clippy\n cd contract && cargo fmt -- --check\n cd tests && cargo fmt -- --check\n\nlint: clippy\n cd contract && cargo fmt\n cd tests && cargo fmt\n"))),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Example rust-toolchain file"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"nightly-2022-08-03\n"))),(0,o.kt)("h3",{id:"manual-project-setup"},"Manually"),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"If you are a beginner, ",(0,o.kt)("a",{parentName:"p",href:"#creating-the-project-automatically"},"creating the structure automatically")," with ",(0,o.kt)("inlineCode",{parentName:"p"},"cargo casper")," is recommended, and the command creates everything you need to start coding.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Create a top-level project directory to store the contract code and corresponding tests.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Create a folder for the contract code inside the project directory. This folder contains the logic that will be compiled into Wasm and executed on a Casper node. In this example, we named the folder ",(0,o.kt)("inlineCode",{parentName:"p"},"contract"),". You can use a different folder name if you wish."),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"In the ",(0,o.kt)("inlineCode",{parentName:"li"},"contract")," folder, add a source folder called ",(0,o.kt)("inlineCode",{parentName:"li"},"src")," and a ",(0,o.kt)("inlineCode",{parentName:"li"},"Cargo.toml")," file, which specifies the contract's dependencies."),(0,o.kt)("li",{parentName:"ul"},"Add a Rust file with the contract code in the ",(0,o.kt)("inlineCode",{parentName:"li"},"src")," folder. In this example, we have the ",(0,o.kt)("inlineCode",{parentName:"li"},"main.rs")," file."))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Navigating back to the project directory, create a folder for the tests, which help verify the contract's functionality. In this example, we named the folder ",(0,o.kt)("inlineCode",{parentName:"p"},"tests"),"."),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"In the ",(0,o.kt)("inlineCode",{parentName:"li"},"tests")," folder, add a source folder called ",(0,o.kt)("inlineCode",{parentName:"li"},"src")," and a ",(0,o.kt)("inlineCode",{parentName:"li"},"Cargo.toml")," file, which specifies the required dependencies to run the tests."),(0,o.kt)("li",{parentName:"ul"},"In the ",(0,o.kt)("inlineCode",{parentName:"li"},"src")," folder, add a Rust file with the tests that verify the contract's behavior. In this example, we have the ",(0,o.kt)("inlineCode",{parentName:"li"},"integration-tests.rs")," file."))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Manually create Makefile and rust-toolchain as per ",(0,o.kt)("a",{parentName:"p",href:"#semi-automatic-project-setup"},"Semi-automatic setup (4.)")))),(0,o.kt)("h3",{id:"dependencies"},"Dependencies"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file in the ",(0,o.kt)("inlineCode",{parentName:"p"},"contract")," folder includes the dependencies and versions the contract requires. At a minimum, you need to import the latest versions of the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/"},"casper-contract")," and ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/"},"casper-types")," crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements."),(0,o.kt)("p",null,"If you followed the ",(0,o.kt)("a",{parentName:"p",href:"#automatic-project-setup"},"automatic setup"),", the dependencies should be in the ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file. For the ",(0,o.kt)("a",{parentName:"p",href:"#semi-automatic-project-setup"},"semi-automatic setup")," and ",(0,o.kt)("a",{parentName:"p",href:"#manual-project-setup"},"manual setup"),", however, you'll need to manually add the dependencies to the crate's ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[dependencies]\n# A library for developing Casper network smart contracts.\ncasper-contract = "1.4.4"\n# Types shared by many Casper crates for use on a Casper network.\ncasper-types = "1.5.0"\n')),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},'casper-contract = "1.4.4"')," - Provides the SDK for the execution engine (EE). The latest version of the crate is published ",(0,o.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-contract"},"here"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},'casper-types = "1.5.0"')," - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published ",(0,o.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-types"},"here"),".")),(0,o.kt)("h2",{id:"writing-a-basic-smart-contract"},"Writing a Basic Smart Contract"),(0,o.kt)("p",null,"At this point, you either have the default example contract defined in ",(0,o.kt)("inlineCode",{parentName:"p"},"contract/src/main.rs")," (",(0,o.kt)("a",{parentName:"p",href:"#automatic-project-setup"},"automatic")," setup using cargo-casper), an empty ",(0,o.kt)("inlineCode",{parentName:"p"},"contract/src/main.rs")," file (",(0,o.kt)("a",{parentName:"p",href:"#manual-project-setup"},"manual"),' project setup), or a Rust "hello world" program defined in the ',(0,o.kt)("inlineCode",{parentName:"p"},"contract/src/main.rs")," (",(0,o.kt)("a",{parentName:"p",href:"#semi-automatic-project-setup"},"semi-automatic")," setup)."),(0,o.kt)("p",null,"This section covers the process of writing a smart contract in Rust, step by step. Therefore, you should clear the contents of the ",(0,o.kt)("inlineCode",{parentName:"p"},"contract/main.rs")," file if there are any."),(0,o.kt)("p",null,"The example code comes from the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/"},"counter contract"),". This simple contract allows callers to increment and retrieve an integer. Casper provides a ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/index.html"},"contract API")," within the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/index.html"},(0,o.kt)("inlineCode",{parentName:"a"},"casper_contract"))," crate."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"Important syntax elements used frequently in Rust:"),(0,o.kt)("ul",{parentName:"admonition"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/rust-by-example/flow_control/match.html"},"Match"),(0,o.kt)("br",null)),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/rust-by-example/primitives/array.html"},"Array"),(0,o.kt)("br",null)),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/rust-by-example/flow_control/loop.html"},"Loop"),(0,o.kt)("br",null)),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/rust-by-example/std/vec.html"},"Vectors"),(0,o.kt)("br",null)),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/rust-by-example/fn.html"},"Functions"),(0,o.kt)("br",null))),(0,o.kt)("p",{parentName:"admonition"},"To be able to comfortably write code in Rust it is crucial to understand these topics before going further into the examples.")),(0,o.kt)("h3",{id:"updating-the-mainrs-file"},"Updating the ",(0,o.kt)("inlineCode",{parentName:"h3"},"main.rs")," File"),(0,o.kt)("p",null,"To begin writing contract code, add the following file attributes to support the Wasm execution environment. If you still have an auto-generated ",(0,o.kt)("inlineCode",{parentName:"p"},"main.rs")," file, remove the auto-generated main function."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"#![no_std]\n#![no_main]\n")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"#![no_main]")," - This attribute tells the program not to use the standard main function as its entry point."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"#![no_std]")," - This attribute tells the program not to import the standard libraries.")),(0,o.kt)("h4",{id:"defining-required-dependencies"},"Defining required dependencies"),(0,o.kt)("p",null,"Add the required imports and dependencies. The example code for the counter contract declares the following dependencies."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"// This code imports necessary aspects of external crates that we will use in our contract code.\nextern crate alloc;\n\n// Importing Rust types.\nuse alloc::{\n string::{String, ToString},\n vec::Vec,\n};\n// Importing aspects of the Casper platform.\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n// Importing specific Casper types.\nuse casper_types::{\n api_error::ApiError,\n contracts::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys},\n CLType, CLValue, URef,\n};\n")),(0,o.kt)("h4",{id:"defining-the-global-constants"},"Defining the global constants"),(0,o.kt)("p",null,"After importing the necessary dependencies, you should define the constants used within the contract, including entry points and values. The following example outlines the necessary constants for the counter contract."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'// Creating constants for values within the contract package.\nconst CONTRACT_PACKAGE_NAME: &str = "counter_package_name";\nconst CONTRACT_ACCESS_UREF: &str = "counter_access_uref";\n\n// Creating constants for the various contract entry points.\nconst ENTRY_POINT_COUNTER_INC: &str = "counter_inc";\nconst ENTRY_POINT_COUNTER_GET: &str = "counter_get";\n\n// Creating constants for values within the contract.\nconst CONTRACT_VERSION_KEY: &str = "version";\nconst CONTRACT_KEY: &str = "counter";\nconst COUNT_KEY: &str = "count";\n')),(0,o.kt)("h4",{id:"defining-the-contract-entry-points"},"Defining the contract entry points"),(0,o.kt)("p",null,"Entry points provide access to contract code installed in global state. Either ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code"},"session code")," or another smart contract may call these entry points. A contract must have at least one entry point and may have more than one entry point. Entry points are defined by their name, and those names should be clear and self-describing. Each entry point is equivalent to a static main entry point in a traditional program."),(0,o.kt)("p",null,"Entry points are not functions or methods, and they have no arguments. They are static entry points into the contract's logic. Yet, the contract logic can access parameters by name, passed along with the Deploy. Note that another smart contract may access any of these entry points."),(0,o.kt)("p",null,"If an entry point has one or more mandatory parameters that will cause the logic to revert if they are not included, declare them within that entry point. Optional and non-critical parameters should be excluded."),(0,o.kt)("p",null,"When defining entry points, begin with a ",(0,o.kt)("inlineCode",{parentName:"p"},"#[no_mangle]")," line to ensure the system does not change critical syntax within the method names. Each entry point should contain the contract code that drives the action you wish it to accomplish. Finally, include any storage or return values needed, as applicable."),(0,o.kt)("p",null,"The following entry point is an example from the counter contract. To see all the available entry points, review the contract in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs"},"GitHub"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn counter_inc() {\n let uref: URef = runtime::get_key(COUNT_KEY)\n .unwrap_or_revert_with(ApiError::MissingKey)\n .into_uref()\n .unwrap_or_revert_with(ApiError::UnexpectedKeyVariant);\n storage::add(uref, 1); // Increment the count by 1.\n}\n')),(0,o.kt)("h4",{id:"defining-the-call-function"},"Defining the ",(0,o.kt)("inlineCode",{parentName:"h4"},"call")," function"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function starts the code execution and installs the contract on-chain. In some cases, it also initializes some constructs, such as a Dictionary for record-keeping or a purse. The following steps describe how to structure the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function. Review the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/blob/8a622cd92d768893b9ef9fc2b150c674415be87e/contract-v1/src/main.rs#L55"},"call function")," in the counter contract."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Define the runtime arguments.")),(0,o.kt)("p",null,"At the time of contract installation, pass in parameters as runtime arguments. Use this pattern of variable definition to collect any sentinel values that dictate the behavior of the contract. If the entry point takes in arguments, you must declare those as part of the entry point's definition."),(0,o.kt)("p",null,"Look at the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs"},"CEP-78 contract")," to see examples of entry points taking in arguments. The counter contract does not use variable parameters since it is too simple."),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},"Add the entry points into the ",(0,o.kt)("inlineCode",{parentName:"li"},"call")," function.")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function replaces a traditional ",(0,o.kt)("inlineCode",{parentName:"p"},"main")," function and executes automatically when a caller interacts with the contract. Within the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function, we define entry points the caller can access using session code or another contract. When writing code that calls an entry point, there must be a one-to-one mapping of the entry point name. Otherwise, the execution engine will return an error that the entry point does not exist."),(0,o.kt)("p",null,"Each entry point should have these arguments:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"name")," - The entry point's name, which should be the same as the initial definition."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"arguments")," - A list of runtime arguments declared as part of the definition of the entry point."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"return type")," - The CLType returned by the entry point. Use the type ",(0,o.kt)("em",{parentName:"li"},"Unit")," for empty return types."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"access level")," - Access permissions of the entry point."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"entry point type")," - This can be ",(0,o.kt)("inlineCode",{parentName:"li"},"contract")," or ",(0,o.kt)("inlineCode",{parentName:"li"},"session")," code.")),(0,o.kt)("p",null,"This step adds the individual entry points to a ",(0,o.kt)("inlineCode",{parentName:"p"},"counter_entry_points")," object using the ",(0,o.kt)("inlineCode",{parentName:"p"},"add_entry_point")," method. This object will later be passed to the ",(0,o.kt)("inlineCode",{parentName:"p"},"new_contract")," method."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn call() {\n // Initialize the count to 0 locally\n let count_start = storage::new_uref(0_i32);\n // Create the entry points for this contract\n let mut counter_entry_points = EntryPoints::new();\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_GET,\n Vec::new(),\n CLType::I32,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_INC,\n Vec::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n}\n')),(0,o.kt)("p",null,"In the following, we will add more content to this call function."),(0,o.kt)("ol",{start:3},(0,o.kt)("li",{parentName:"ol"},"Create the contract's named keys.")),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html"},"NamedKeys")," are a collection of String-Key pairs used to identify some network data quickly."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"The ",(0,o.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/nightly/alloc/string/struct.String.html"},"String")," is the name given to identify the data"),(0,o.kt)("li",{parentName:"ul"},"The ",(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html"},"Key")," is the data to be referenced")),(0,o.kt)("p",null,"You can create named keys to store any record or value as needed, such as other accounts, smart contracts, URefs, transfers, deploy information, purse balances, etc. The list of possible Key variants can be found ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html"},"here"),"."),(0,o.kt)("p",null,"For the counter, we store the integer that we increment into a named key."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"}," // In the named keys of the counter contract, add a key for the count.\n let mut counter_named_keys = NamedKeys::new();\n let key_name = String::from(COUNT_KEY);\n counter_named_keys.insert(key_name, count_start.into());\n")),(0,o.kt)("ol",{start:4},(0,o.kt)("li",{parentName:"ol"},"Create the contract.")),(0,o.kt)("p",null,"Use the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html"},"new_contract")," method to create the contract with its named keys and entry points. This method creates the contract object and saves the access URef and the contract package hash in the caller's context. The execution engine automatically creates a contract package and assigns it a ",(0,o.kt)("inlineCode",{parentName:"p"},"contractPackageHash"),". Then, it adds the contract to the package with a ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html"},(0,o.kt)("inlineCode",{parentName:"a"},"contractHash")),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"}," // Create a new contract package that can be upgraded.\n let (stored_contract_hash, contract_version) = storage::new_contract(\n counter_entry_points,\n Some(counter_named_keys),\n Some(CONTRACT_PACKAGE_NAME.to_string()),\n Some(CONTRACT_ACCESS_UREF.to_string()),\n );\n")),(0,o.kt)("p",null,"Usually, these contracts are upgradeable with the ability to add new ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html"},"versions"),". You ",(0,o.kt)("strong",{parentName:"p"},"must have the access URef")," to the contract package to add a new contract version. This can be accomplished by passing the ",(0,o.kt)("inlineCode",{parentName:"p"},"Some(CONTRACT_ACCESS_UREF.to_string())")," argument to the ",(0,o.kt)("inlineCode",{parentName:"p"},"new_contract")," method. To prevent any upgrades to a contract, use the ",(0,o.kt)("inlineCode",{parentName:"p"},"new_locked_contract")," method described ",(0,o.kt)("a",{parentName:"p",href:"#locked-contracts"},"below"),"."),(0,o.kt)("ol",{start:5},(0,o.kt)("li",{parentName:"ol"},"Create additional named keys.")),(0,o.kt)("p",null,"Generally, the ",(0,o.kt)("inlineCode",{parentName:"p"},"Contract_Hash")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"Contract_Version")," are saved as ",(0,o.kt)("inlineCode",{parentName:"p"},"NamedKeys")," in the account's context for later use."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"}," // Store the contract version in the context's named keys.\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n\n // Create a named key for the contract hash.\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n")),(0,o.kt)("p",null,"The complete call function should look like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn call() {\n // Initialize the count to 0 locally\n let count_start = storage::new_uref(0_i32);\n // Create the entry points for this contract\n let mut counter_entry_points = EntryPoints::new();\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_GET,\n Vec::new(),\n CLType::I32,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_INC,\n Vec::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n // In the named keys of the counter contract, add a key for the count.\n let mut counter_named_keys = NamedKeys::new();\n let key_name = String::from(COUNT_KEY);\n counter_named_keys.insert(key_name, count_start.into());\n\n // Create a new contract package that can be upgraded.\n let (stored_contract_hash, contract_version) = storage::new_contract(\n counter_entry_points,\n Some(counter_named_keys),\n Some(CONTRACT_PACKAGE_NAME.to_string()),\n Some(CONTRACT_ACCESS_UREF.to_string()),\n );\n\n /* To create a locked contract instead, use new_locked_contract and throw away the contract version returned\n let (stored_contract_hash, _) =\n storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None); */\n\n // Store the contract version in the context\'s named keys.\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n\n // Create a named key for the contract hash.\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n}\n')),(0,o.kt)("h2",{id:"locked-contracts"},"Locked Contracts"),(0,o.kt)("p",null,"Locked contracts cannot contain other contract ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html"},"versions")," in the same contract package; thus, they cannot be upgraded. In this scenario, the Casper execution engine will create a contract package, add a contract to that package and prevent any further upgrades to the contract. Use locked contracts when you need to ensure high security and will not require updates to the contract."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"pub fn new_locked_contract(\n entry_points: EntryPoints,\n named_keys: Option,\n hash_name: Option,\n uref_name: Option,\n) -> (ContractHash, ContractVersion) {\n create_contract(entry_points, named_keys, hash_name, uref_name, true)\n}\n")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"entry_points")," - The set of entry points defined inside the smart contract."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"named_keys")," - Any ",(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html"},"named-key")," pairs for the contract."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"hash_name")," - Contract hash value. Puts ",(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html"},"contractHash")," in the current context's named keys under ",(0,o.kt)("inlineCode",{parentName:"li"},"hash_name"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"uref_name")," - Access URef value. Puts access_uref in the current context's named keys under ",(0,o.kt)("inlineCode",{parentName:"li"},"uref_name"),".")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Note"),": The current context is the context of the person who initiated the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function, usually an account."),(0,o.kt)("p",null,"The counter contract in our example would be locked if we created it this way:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"let (stored_contract_hash, _) =\n storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None);\n")),(0,o.kt)("h2",{id:"compiling-contract-code"},"Compiling Contract Code"),(0,o.kt)("p",null,"To compile the smart contract, run the following commands in the ",(0,o.kt)("inlineCode",{parentName:"p"},"contract")," folder in your project's directory, where the ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file and ",(0,o.kt)("inlineCode",{parentName:"p"},"src")," folder are hosted."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"rustup target add wasm32-unknown-unknown\ncargo build --release --target wasm32-unknown-unknown\n")),(0,o.kt)("p",null,"For the counter example, in the project directory where the ",(0,o.kt)("inlineCode",{parentName:"p"},"Makefile")," is, run the following commands:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"make prepare\nmake build-contract\n")),(0,o.kt)("h2",{id:"executing-contract-code"},"Executing Contract Code"),(0,o.kt)("p",null,"Contract execution must be initiated through an outside call, usually via ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code"},"session code")," or another smart contract. Developers should also be familiar with the difference between contract code and session code, explained in the next section."),(0,o.kt)("h2",{id:"video-walkthrough"},"Video Walkthrough"),(0,o.kt)("p",null,"The following brief video accompanies this guide."),(0,o.kt)("p",{align:"center"},(0,o.kt)("iframe",{width:"400",height:"225",src:"https://www.youtube.com/embed/yHJwkhO5EQg",frameborder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:!0})),(0,o.kt)("h2",{id:"whats-next"},"What's Next?"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Learn to ",(0,o.kt)("a",{parentName:"li",href:"/developers/writing-onchain-code/testing-contracts"},"test your contract"),"."),(0,o.kt)("li",{parentName:"ul"},"Understand ",(0,o.kt)("a",{parentName:"li",href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code"},"session code")," and how it triggers a smart contract."),(0,o.kt)("li",{parentName:"ul"},"Learn to ",(0,o.kt)("a",{parentName:"li",href:"/developers/cli/installing-contracts"},"install a contract and query global state")," with the Casper command-line client.")))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[4452],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return h}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),l=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),d=l(n),m=r,h=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?a.createElement(h,i(i({ref:t},p),{},{components:n})):a.createElement(h,i({ref:t},p))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[d]="string"==typeof e?e:r,i[1]=c;for(var l=2;lcargo casper",id:"automatic-project-setup",level:3},{value:"Semi-automatically using plain cargo",id:"semi-automatic-project-setup",level:3},{value:"Manually",id:"manual-project-setup",level:3},{value:"Dependencies",id:"dependencies",level:3},{value:"Writing a Basic Smart Contract",id:"writing-a-basic-smart-contract",level:2},{value:"Updating the main.rs File",id:"updating-the-mainrs-file",level:3},{value:"Defining required dependencies",id:"defining-required-dependencies",level:4},{value:"Defining the global constants",id:"defining-the-global-constants",level:4},{value:"Defining the contract entry points",id:"defining-the-contract-entry-points",level:4},{value:"Defining the call function",id:"defining-the-call-function",level:4},{value:"Locked Contracts",id:"locked-contracts",level:2},{value:"Compiling Contract Code",id:"compiling-contract-code",level:2},{value:"Executing Contract Code",id:"executing-contract-code",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}],u={toc:d},m="wrapper";function h(e){var t=e.components,n=(0,r.Z)(e,i);return(0,o.kt)(m,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"writing-a-basic-smart-contract-in-rust"},"Writing a Basic Smart Contract in Rust"),(0,o.kt)("h2",{id:"what-is-a-smart-contract"},"What is a Smart Contract?"),(0,o.kt)("p",null,"A smart contract is a self-contained program installed on a blockchain. In the context of a Casper network, a smart contract consists of contract code installed on-chain using a ",(0,o.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#execution-semantics-deploys"},"Deploy"),". Casper smart contracts are programs that run on a Casper network. They interact with accounts and other contracts through entry points, allowing for various triggers, conditions, and logic."),(0,o.kt)("p",null,"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. These contracts can, in turn, call one another to perform interconnected operations and create more complex programs. The decentralized nature of blockchain technology means that these smart contracts do not suffer from any single point of failure. Even if a Casper node leaves the network, other nodes will continue to allow the contract to operate as intended."),(0,o.kt)("h2",{id:"key-features-of-casper-contracts"},"Key Features of Casper Contracts"),(0,o.kt)("p",null,"On the Casper platform, developers may write smart contracts in any language that compiles to Wasm binaries. This tutorial focuses specifically on writing a smart contract in the Rust language. The Rust compiler compiles the contract code into Wasm. After that, the Wasm binary can be ",(0,o.kt)("a",{parentName:"p",href:"/developers/cli/installing-contracts"},"sent to a node")," on a Casper network using a Deploy. Nodes within the network then ",(0,o.kt)("a",{parentName:"p",href:"/concepts/design/p2p#communications-gossiping"},"gossip deploys"),", include them within a block, and finalize them. After finalizing, the network executes the deploys within the block."),(0,o.kt)("p",null,"Further, the Casper platform allows for ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/upgrading-contracts"},"upgradable contracts"),". A ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackage.html"},"ContractPackage")," is created through the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html"},"new_contract")," or ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_locked_contract.html"},"new_locked_contract")," methods. Through these methods, the Casper execution engine automatically creates the new contract package and assigns a ",(0,o.kt)("a",{parentName:"p",href:"/concepts/hash-types#hash-and-key-explanations"},(0,o.kt)("inlineCode",{parentName:"a"},"ContractPackageHash")),". The new contract is added to this package with a ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html"},(0,o.kt)("inlineCode",{parentName:"a"},"ContractHash"))," key. The execution engine stores the new contract within the contract package alongside any previously installed contract versions, if applicable."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"new_contract")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"new_locked_contract")," methods are a convenience that automatically creates the package associated with a new contract. Developers choosing not to use these methods must first create a contract package to function as a container for their new contract."),(0,o.kt)("p",null,"The contract contains required metadata, and it is primarily identified by its ",(0,o.kt)("inlineCode",{parentName:"p"},"ContractHash"),". While the contract hash identifies a specific ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html"},"ContractVersion"),", the ",(0,o.kt)("inlineCode",{parentName:"p"},"ContractPackageHash")," serves as an identifier for the most recent contract version in the contract package."),(0,o.kt)("h2",{id:"directory-structure"},"Creating the Directory Structure"),(0,o.kt)("p",null,"To begin creating a smart contract, you need to set up the project structure, either manually or automatically, as shown below."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"project-directory/\n\n\u2514\u2500\u2500 contract/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 main.rs\n \u2514\u2500\u2500 Cargo.toml\n\n\u2514\u2500\u2500 Makefile\n\u2514\u2500\u2500 rust-toolchain\n\n\u2514\u2500\u2500 tests/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 integration-tests.rs\n \u2514\u2500\u2500 Cargo.toml\n")),(0,o.kt)("p",null,"The project structure would be different in a dApp with full-stack architecture. "),(0,o.kt)("h3",{id:"automatic-project-setup"},"Automatically using ",(0,o.kt)("inlineCode",{parentName:"h3"},"cargo casper")),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/getting-started#creating-a-project"},"cargo casper command")," can automatically set up the project structure. This is the recommended way of setting up a new Casper project."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cargo casper my-project\n")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"cargo casper")," command will generate an example contract in the contract directory and an example ",(0,o.kt)("inlineCode",{parentName:"p"},"tests")," crate with logic defined in the ",(0,o.kt)("inlineCode",{parentName:"p"},"integration-tests.rs")," file. The ",(0,o.kt)("inlineCode",{parentName:"p"},"Makefile")," includes commands to prepare and build the contract, and the ",(0,o.kt)("inlineCode",{parentName:"p"},"rust-toolchain")," file specifies the target build version of Rust."),(0,o.kt)("h3",{id:"semi-automatic-project-setup"},"Semi-automatically using plain ",(0,o.kt)("inlineCode",{parentName:"h3"},"cargo")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"If you are a beginner, ",(0,o.kt)("a",{parentName:"p",href:"#creating-the-project-automatically"},"creating the structure automatically")," with ",(0,o.kt)("inlineCode",{parentName:"p"},"cargo casper")," is recommended and the command creates everything you need to start coding.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Create a top-level project directory for the contract code and its corresponding tests.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Inside the project directory, run the following command to create a new binary package called ",(0,o.kt)("inlineCode",{parentName:"p"},"contract"),". Use a different name instead of ",(0,o.kt)("inlineCode",{parentName:"p"},"contract")," if you wish."),(0,o.kt)("pre",{parentName:"li"},(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cargo new contract\n")),(0,o.kt)("p",{parentName:"li"},"The command creates a ",(0,o.kt)("inlineCode",{parentName:"p"},"contract")," folder with a ",(0,o.kt)("inlineCode",{parentName:"p"},"/src/main.rs")," file and a ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file:"),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"main.rs")," - This file would contain the contract code."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Cargo.toml")," - This file would contain crate dependencies and other configurations.")),(0,o.kt)("p",{parentName:"li"},"The following sections explain how to update these files using example code.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Inside the project directory, run the command to auto-generate the folder structure for the tests. Use a different name instead of ",(0,o.kt)("inlineCode",{parentName:"p"},"tests")," if you wish."),(0,o.kt)("pre",{parentName:"li"},(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cargo new tests\n")),(0,o.kt)("p",{parentName:"li"},"The command creates a ",(0,o.kt)("inlineCode",{parentName:"p"},"tests")," folder with a ",(0,o.kt)("inlineCode",{parentName:"p"},"/src/main.rs")," file and a ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file:"),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"main.rs")," - This file would store the unit test code required to test the contract. You can rename the file to ",(0,o.kt)("inlineCode",{parentName:"li"},"integration-tests.rs")," as shown in the example structure."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Cargo.toml")," - This is the file with test configurations.")),(0,o.kt)("p",{parentName:"li"},"The ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/testing-contracts"},"Testing Smart Contracts")," guide explains how to update the tests using example code.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Unlike ",(0,o.kt)("inlineCode",{parentName:"p"},"cargo casper"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"cargo")," does not create a ",(0,o.kt)("inlineCode",{parentName:"p"},"Makefile")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"rust-toolchain")," configuration file. Therefore, you must manually add these files to the project's root folder."))),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Example Makefile"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"prepare:\n rustup target add wasm32-unknown-unknown\n\nbuild-contract:\n cd contract && cargo build --release --target wasm32-unknown-unknown\n wasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n\ntest: build-contract\n mkdir -p tests/wasm\n cp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm\n cd tests && cargo test\n\nclippy:\n cd contract && cargo clippy --all-targets -- -D warnings\n cd tests && cargo clippy --all-targets -- -D warnings\n\ncheck-lint: clippy\n cd contract && cargo fmt -- --check\n cd tests && cargo fmt -- --check\n\nlint: clippy\n cd contract && cargo fmt\n cd tests && cargo fmt\n"))),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Example rust-toolchain file"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"nightly-2022-08-03\n"))),(0,o.kt)("h3",{id:"manual-project-setup"},"Manually"),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"If you are a beginner, ",(0,o.kt)("a",{parentName:"p",href:"#creating-the-project-automatically"},"creating the structure automatically")," with ",(0,o.kt)("inlineCode",{parentName:"p"},"cargo casper")," is recommended, and the command creates everything you need to start coding.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Create a top-level project directory to store the contract code and corresponding tests.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Create a folder for the contract code inside the project directory. This folder contains the logic that will be compiled into Wasm and executed on a Casper node. In this example, we named the folder ",(0,o.kt)("inlineCode",{parentName:"p"},"contract"),". You can use a different folder name if you wish."),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"In the ",(0,o.kt)("inlineCode",{parentName:"li"},"contract")," folder, add a source folder called ",(0,o.kt)("inlineCode",{parentName:"li"},"src")," and a ",(0,o.kt)("inlineCode",{parentName:"li"},"Cargo.toml")," file, which specifies the contract's dependencies."),(0,o.kt)("li",{parentName:"ul"},"Add a Rust file with the contract code in the ",(0,o.kt)("inlineCode",{parentName:"li"},"src")," folder. In this example, we have the ",(0,o.kt)("inlineCode",{parentName:"li"},"main.rs")," file."))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Navigating back to the project directory, create a folder for the tests, which help verify the contract's functionality. In this example, we named the folder ",(0,o.kt)("inlineCode",{parentName:"p"},"tests"),"."),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"In the ",(0,o.kt)("inlineCode",{parentName:"li"},"tests")," folder, add a source folder called ",(0,o.kt)("inlineCode",{parentName:"li"},"src")," and a ",(0,o.kt)("inlineCode",{parentName:"li"},"Cargo.toml")," file, which specifies the required dependencies to run the tests."),(0,o.kt)("li",{parentName:"ul"},"In the ",(0,o.kt)("inlineCode",{parentName:"li"},"src")," folder, add a Rust file with the tests that verify the contract's behavior. In this example, we have the ",(0,o.kt)("inlineCode",{parentName:"li"},"integration-tests.rs")," file."))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Manually create Makefile and rust-toolchain as per ",(0,o.kt)("a",{parentName:"p",href:"#semi-automatic-project-setup"},"Semi-automatic setup (4.)")))),(0,o.kt)("h3",{id:"dependencies"},"Dependencies"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file in the ",(0,o.kt)("inlineCode",{parentName:"p"},"contract")," folder includes the dependencies and versions the contract requires. At a minimum, you need to import the latest versions of the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/"},"casper-contract")," and ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/"},"casper-types")," crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements."),(0,o.kt)("p",null,"If you followed the ",(0,o.kt)("a",{parentName:"p",href:"#automatic-project-setup"},"automatic setup"),", the dependencies should be in the ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file. For the ",(0,o.kt)("a",{parentName:"p",href:"#semi-automatic-project-setup"},"semi-automatic setup")," and ",(0,o.kt)("a",{parentName:"p",href:"#manual-project-setup"},"manual setup"),", however, you'll need to manually add the dependencies to the crate's ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[dependencies]\n# A library for developing Casper network smart contracts.\ncasper-contract = "1.4.4"\n# Types shared by many Casper crates for use on a Casper network.\ncasper-types = "1.5.0"\n')),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},'casper-contract = "1.4.4"')," - Provides the SDK for the execution engine (EE). The latest version of the crate is published ",(0,o.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-contract"},"here"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},'casper-types = "1.5.0"')," - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published ",(0,o.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-types"},"here"),".")),(0,o.kt)("h2",{id:"writing-a-basic-smart-contract"},"Writing a Basic Smart Contract"),(0,o.kt)("p",null,"At this point, you either have the default example contract defined in ",(0,o.kt)("inlineCode",{parentName:"p"},"contract/src/main.rs")," (",(0,o.kt)("a",{parentName:"p",href:"#automatic-project-setup"},"automatic")," setup using cargo-casper), an empty ",(0,o.kt)("inlineCode",{parentName:"p"},"contract/src/main.rs")," file (",(0,o.kt)("a",{parentName:"p",href:"#manual-project-setup"},"manual"),' project setup), or a Rust "hello world" program defined in the ',(0,o.kt)("inlineCode",{parentName:"p"},"contract/src/main.rs")," (",(0,o.kt)("a",{parentName:"p",href:"#semi-automatic-project-setup"},"semi-automatic")," setup)."),(0,o.kt)("p",null,"This section covers the process of writing a smart contract in Rust, step by step. Therefore, you should clear the contents of the ",(0,o.kt)("inlineCode",{parentName:"p"},"contract/main.rs")," file if there are any."),(0,o.kt)("p",null,"The example code comes from the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/"},"counter contract"),". This simple contract allows callers to increment and retrieve an integer. Casper provides a ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/index.html"},"contract API")," within the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/index.html"},(0,o.kt)("inlineCode",{parentName:"a"},"casper_contract"))," crate."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"Important syntax elements used frequently in Rust:"),(0,o.kt)("ul",{parentName:"admonition"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/rust-by-example/flow_control/match.html"},"Match"),(0,o.kt)("br",null)),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/rust-by-example/primitives/array.html"},"Array"),(0,o.kt)("br",null)),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/rust-by-example/flow_control/loop.html"},"Loop"),(0,o.kt)("br",null)),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/rust-by-example/std/vec.html"},"Vectors"),(0,o.kt)("br",null)),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/rust-by-example/fn.html"},"Functions"),(0,o.kt)("br",null))),(0,o.kt)("p",{parentName:"admonition"},"To be able to comfortably write code in Rust it is crucial to understand these topics before going further into the examples.")),(0,o.kt)("h3",{id:"updating-the-mainrs-file"},"Updating the ",(0,o.kt)("inlineCode",{parentName:"h3"},"main.rs")," File"),(0,o.kt)("p",null,"To begin writing contract code, add the following file attributes to support the Wasm execution environment. If you still have an auto-generated ",(0,o.kt)("inlineCode",{parentName:"p"},"main.rs")," file, remove the auto-generated main function."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"#![no_std]\n#![no_main]\n")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"#![no_main]")," - This attribute tells the program not to use the standard main function as its entry point."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"#![no_std]")," - This attribute tells the program not to import the standard libraries.")),(0,o.kt)("h4",{id:"defining-required-dependencies"},"Defining required dependencies"),(0,o.kt)("p",null,"Add the required imports and dependencies. The example code for the counter contract declares the following dependencies."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"// This code imports necessary aspects of external crates that we will use in our contract code.\nextern crate alloc;\n\n// Importing Rust types.\nuse alloc::{\n string::{String, ToString},\n vec::Vec,\n};\n// Importing aspects of the Casper platform.\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n// Importing specific Casper types.\nuse casper_types::{\n api_error::ApiError,\n contracts::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys},\n CLType, CLValue, URef,\n};\n")),(0,o.kt)("h4",{id:"defining-the-global-constants"},"Defining the global constants"),(0,o.kt)("p",null,"After importing the necessary dependencies, you should define the constants used within the contract, including entry points and values. The following example outlines the necessary constants for the counter contract."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'// Creating constants for values within the contract package.\nconst CONTRACT_PACKAGE_NAME: &str = "counter_package_name";\nconst CONTRACT_ACCESS_UREF: &str = "counter_access_uref";\n\n// Creating constants for the various contract entry points.\nconst ENTRY_POINT_COUNTER_INC: &str = "counter_inc";\nconst ENTRY_POINT_COUNTER_GET: &str = "counter_get";\n\n// Creating constants for values within the contract.\nconst CONTRACT_VERSION_KEY: &str = "version";\nconst CONTRACT_KEY: &str = "counter";\nconst COUNT_KEY: &str = "count";\n')),(0,o.kt)("h4",{id:"defining-the-contract-entry-points"},"Defining the contract entry points"),(0,o.kt)("p",null,"Entry points provide access to contract code installed in global state. Either ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code"},"session code")," or another smart contract may call these entry points. A contract must have at least one entry point and may have more than one entry point. Entry points are defined by their name, and those names should be clear and self-describing. Each entry point is equivalent to a static main entry point in a traditional program."),(0,o.kt)("p",null,"Entry points are not functions or methods, and they have no arguments. They are static entry points into the contract's logic. Yet, the contract logic can access parameters by name, passed along with the Deploy. Note that another smart contract may access any of these entry points."),(0,o.kt)("p",null,"If an entry point has one or more mandatory parameters that will cause the logic to revert if they are not included, declare them within that entry point. Optional and non-critical parameters should be excluded."),(0,o.kt)("p",null,"When defining entry points, begin with a ",(0,o.kt)("inlineCode",{parentName:"p"},"#[no_mangle]")," line to ensure the system does not change critical syntax within the method names. Each entry point should contain the contract code that drives the action you wish it to accomplish. Finally, include any storage or return values needed, as applicable."),(0,o.kt)("p",null,"The following entry point is an example from the counter contract. To see all the available entry points, review the contract in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs"},"GitHub"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn counter_inc() {\n let uref: URef = runtime::get_key(COUNT_KEY)\n .unwrap_or_revert_with(ApiError::MissingKey)\n .into_uref()\n .unwrap_or_revert_with(ApiError::UnexpectedKeyVariant);\n storage::add(uref, 1); // Increment the count by 1.\n}\n')),(0,o.kt)("h4",{id:"defining-the-call-function"},"Defining the ",(0,o.kt)("inlineCode",{parentName:"h4"},"call")," function"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function starts the code execution and installs the contract on-chain. In some cases, it also initializes some constructs, such as a Dictionary for record-keeping or a purse. The following steps describe how to structure the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function. Review the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/blob/8a622cd92d768893b9ef9fc2b150c674415be87e/contract-v1/src/main.rs#L55"},"call function")," in the counter contract."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Define the runtime arguments.")),(0,o.kt)("p",null,"At the time of contract installation, pass in parameters as runtime arguments. Use this pattern of variable definition to collect any sentinel values that dictate the behavior of the contract. If the entry point takes in arguments, you must declare those as part of the entry point's definition."),(0,o.kt)("p",null,"Look at the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs"},"CEP-78 contract")," to see examples of entry points taking in arguments. The counter contract does not use variable parameters since it is too simple."),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},"Add the entry points into the ",(0,o.kt)("inlineCode",{parentName:"li"},"call")," function.")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function replaces a traditional ",(0,o.kt)("inlineCode",{parentName:"p"},"main")," function and executes automatically when a caller interacts with the contract. Within the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function, we define entry points the caller can access using session code or another contract. When writing code that calls an entry point, there must be a one-to-one mapping of the entry point name. Otherwise, the execution engine will return an error that the entry point does not exist."),(0,o.kt)("p",null,"Each entry point should have these arguments:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"name")," - The entry point's name, which should be the same as the initial definition."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"arguments")," - A list of runtime arguments declared as part of the definition of the entry point."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"return type")," - The CLType returned by the entry point. Use the type ",(0,o.kt)("em",{parentName:"li"},"Unit")," for empty return types."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"access level")," - Access permissions of the entry point."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"entry point type")," - This can be ",(0,o.kt)("inlineCode",{parentName:"li"},"contract")," or ",(0,o.kt)("inlineCode",{parentName:"li"},"session")," code.")),(0,o.kt)("p",null,"This step adds the individual entry points to a ",(0,o.kt)("inlineCode",{parentName:"p"},"counter_entry_points")," object using the ",(0,o.kt)("inlineCode",{parentName:"p"},"add_entry_point")," method. This object will later be passed to the ",(0,o.kt)("inlineCode",{parentName:"p"},"new_contract")," method."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn call() {\n // Initialize the count to 0 locally\n let count_start = storage::new_uref(0_i32);\n // Create the entry points for this contract\n let mut counter_entry_points = EntryPoints::new();\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_GET,\n Vec::new(),\n CLType::I32,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_INC,\n Vec::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n}\n')),(0,o.kt)("p",null,"In the following, we will add more content to this call function."),(0,o.kt)("ol",{start:3},(0,o.kt)("li",{parentName:"ol"},"Create the contract's named keys.")),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html"},"NamedKeys")," are a collection of String-Key pairs used to identify some network data quickly."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"The ",(0,o.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/nightly/alloc/string/struct.String.html"},"String")," is the name given to identify the data"),(0,o.kt)("li",{parentName:"ul"},"The ",(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html"},"Key")," is the data to be referenced")),(0,o.kt)("p",null,"You can create named keys to store any record or value as needed, such as other accounts, smart contracts, URefs, transfers, deploy information, purse balances, etc. The list of possible Key variants can be found ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html"},"here"),"."),(0,o.kt)("p",null,"For the counter, we store the integer that we increment into a named key."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"}," // In the named keys of the counter contract, add a key for the count.\n let mut counter_named_keys = NamedKeys::new();\n let key_name = String::from(COUNT_KEY);\n counter_named_keys.insert(key_name, count_start.into());\n")),(0,o.kt)("ol",{start:4},(0,o.kt)("li",{parentName:"ol"},"Create the contract.")),(0,o.kt)("p",null,"Use the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html"},"new_contract")," method to create the contract with its named keys and entry points. This method creates the contract object and saves the access URef and the contract package hash in the caller's context. The execution engine automatically creates a contract package and assigns it a ",(0,o.kt)("inlineCode",{parentName:"p"},"contractPackageHash"),". Then, it adds the contract to the package with a ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html"},(0,o.kt)("inlineCode",{parentName:"a"},"contractHash")),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"}," // Create a new contract package that can be upgraded.\n let (stored_contract_hash, contract_version) = storage::new_contract(\n counter_entry_points,\n Some(counter_named_keys),\n Some(CONTRACT_PACKAGE_NAME.to_string()),\n Some(CONTRACT_ACCESS_UREF.to_string()),\n );\n")),(0,o.kt)("p",null,"Usually, these contracts are upgradeable with the ability to add new ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html"},"versions"),". You ",(0,o.kt)("strong",{parentName:"p"},"must have the access URef")," to the contract package to add a new contract version. This can be accomplished by passing the ",(0,o.kt)("inlineCode",{parentName:"p"},"Some(CONTRACT_ACCESS_UREF.to_string())")," argument to the ",(0,o.kt)("inlineCode",{parentName:"p"},"new_contract")," method. To prevent any upgrades to a contract, use the ",(0,o.kt)("inlineCode",{parentName:"p"},"new_locked_contract")," method described ",(0,o.kt)("a",{parentName:"p",href:"#locked-contracts"},"below"),"."),(0,o.kt)("ol",{start:5},(0,o.kt)("li",{parentName:"ol"},"Create additional named keys.")),(0,o.kt)("p",null,"Generally, the ",(0,o.kt)("inlineCode",{parentName:"p"},"Contract_Hash")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"Contract_Version")," are saved as ",(0,o.kt)("inlineCode",{parentName:"p"},"NamedKeys")," in the account's context for later use."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"}," // Store the contract version in the context's named keys.\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n\n // Create a named key for the contract hash.\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n")),(0,o.kt)("p",null,"The complete call function should look like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn call() {\n // Initialize the count to 0 locally\n let count_start = storage::new_uref(0_i32);\n // Create the entry points for this contract\n let mut counter_entry_points = EntryPoints::new();\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_GET,\n Vec::new(),\n CLType::I32,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_INC,\n Vec::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n // In the named keys of the counter contract, add a key for the count.\n let mut counter_named_keys = NamedKeys::new();\n let key_name = String::from(COUNT_KEY);\n counter_named_keys.insert(key_name, count_start.into());\n\n // Create a new contract package that can be upgraded.\n let (stored_contract_hash, contract_version) = storage::new_contract(\n counter_entry_points,\n Some(counter_named_keys),\n Some(CONTRACT_PACKAGE_NAME.to_string()),\n Some(CONTRACT_ACCESS_UREF.to_string()),\n );\n\n /* To create a locked contract instead, use new_locked_contract and throw away the contract version returned\n let (stored_contract_hash, _) =\n storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None); */\n\n // Store the contract version in the context\'s named keys.\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n\n // Create a named key for the contract hash.\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n}\n')),(0,o.kt)("h2",{id:"locked-contracts"},"Locked Contracts"),(0,o.kt)("p",null,"Locked contracts cannot contain other contract ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html"},"versions")," in the same contract package; thus, they cannot be upgraded. In this scenario, the Casper execution engine will create a contract package, add a contract to that package and prevent any further upgrades to the contract. Use locked contracts when you need to ensure high security and will not require updates to the contract."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"pub fn new_locked_contract(\n entry_points: EntryPoints,\n named_keys: Option,\n hash_name: Option,\n uref_name: Option,\n) -> (ContractHash, ContractVersion) {\n create_contract(entry_points, named_keys, hash_name, uref_name, true)\n}\n")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"entry_points")," - The set of entry points defined inside the smart contract."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"named_keys")," - Any ",(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html"},"named-key")," pairs for the contract."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"hash_name")," - Contract hash value. Puts ",(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html"},"contractHash")," in the current context's named keys under ",(0,o.kt)("inlineCode",{parentName:"li"},"hash_name"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"uref_name")," - Access URef value. Puts access_uref in the current context's named keys under ",(0,o.kt)("inlineCode",{parentName:"li"},"uref_name"),".")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Note"),": The current context is the context of the person who initiated the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function, usually an account."),(0,o.kt)("p",null,"The counter contract in our example would be locked if we created it this way:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"let (stored_contract_hash, _) =\n storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None);\n")),(0,o.kt)("h2",{id:"compiling-contract-code"},"Compiling Contract Code"),(0,o.kt)("p",null,"To compile the smart contract, run the following commands in the ",(0,o.kt)("inlineCode",{parentName:"p"},"contract")," folder in your project's directory, where the ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file and ",(0,o.kt)("inlineCode",{parentName:"p"},"src")," folder are hosted."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"rustup target add wasm32-unknown-unknown\ncargo build --release --target wasm32-unknown-unknown\n")),(0,o.kt)("p",null,"For the counter example, in the project directory where the ",(0,o.kt)("inlineCode",{parentName:"p"},"Makefile")," is, run the following commands:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"make prepare\nmake build-contract\n")),(0,o.kt)("h2",{id:"executing-contract-code"},"Executing Contract Code"),(0,o.kt)("p",null,"Contract execution must be initiated through an outside call, usually via ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code"},"session code")," or another smart contract. Developers should also be familiar with the difference between contract code and session code, explained in the next section."),(0,o.kt)("h2",{id:"video-walkthrough"},"Video Walkthrough"),(0,o.kt)("p",null,"The following brief video accompanies this guide."),(0,o.kt)("p",{align:"center"},(0,o.kt)("iframe",{width:"400",height:"225",src:"https://www.youtube.com/embed/yHJwkhO5EQg",frameborder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:!0})),(0,o.kt)("h2",{id:"whats-next"},"What's Next?"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Learn to ",(0,o.kt)("a",{parentName:"li",href:"/developers/writing-onchain-code/testing-contracts"},"test your contract"),"."),(0,o.kt)("li",{parentName:"ul"},"Understand ",(0,o.kt)("a",{parentName:"li",href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code"},"session code")," and how it triggers a smart contract."),(0,o.kt)("li",{parentName:"ul"},"Learn to ",(0,o.kt)("a",{parentName:"li",href:"/developers/cli/installing-contracts"},"install a contract and query global state")," with the Casper command-line client.")))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/401abd7a.f21f56e0.js b/assets/js/401abd7a.c37c3889.js similarity index 98% rename from assets/js/401abd7a.f21f56e0.js rename to assets/js/401abd7a.c37c3889.js index e2290f5c40..7e3d26cf4e 100644 --- a/assets/js/401abd7a.f21f56e0.js +++ b/assets/js/401abd7a.c37c3889.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6661],{3905:function(e,t,r){r.d(t,{Zo:function(){return u},kt:function(){return k}});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var d=n.createContext({}),p=function(e){var t=n.useContext(d),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(d.Provider,{value:t},e.children)},s="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,d=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),s=p(r),m=a,k=s["".concat(d,".").concat(m)]||s[m]||c[m]||l;return r?n.createElement(k,o(o({ref:t},u),{},{components:r})):n.createElement(k,o({ref:t},u))}));function k(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=m;var i={};for(var d in t)hasOwnProperty.call(t,d)&&(i[d]=t[d]);i.originalType=e,i[s]="string"==typeof e?e:a,o[1]=i;for(var p=2;pParams",id:"invalid-params",level:2}],c={toc:s},m="wrapper";function k(e){var t=e.components,r=(0,a.Z)(e,o);return(0,l.kt)(m,(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"casper-json-rpc-error-codes"},"Casper JSON-RPC Error Codes"),(0,l.kt)("p",null,"The following document expands on custom error codes provided by ",(0,l.kt)("inlineCode",{parentName:"p"},"casper-json-rpc")," crate."),(0,l.kt)("h2",{id:"codes"},"Error Codes"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Code"),(0,l.kt)("th",{parentName:"tr",align:null},"Error"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-1"),(0,l.kt)("td",{parentName:"tr",align:null},"NoSuchDeploy"),(0,l.kt)("td",{parentName:"tr",align:null},"The requested Deploy was not found.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-2"),(0,l.kt)("td",{parentName:"tr",align:null},"NoSuchBlock"),(0,l.kt)("td",{parentName:"tr",align:null},"The requested Block was not found.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-3"),(0,l.kt)("td",{parentName:"tr",align:null},"FailedToParseQueryKey"),(0,l.kt)("td",{parentName:"tr",align:null},"Parsing the Key from a query failed.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-4"),(0,l.kt)("td",{parentName:"tr",align:null},"QueryFailed"),(0,l.kt)("td",{parentName:"tr",align:null},"The query failed to find a result.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-5"),(0,l.kt)("td",{parentName:"tr",align:null},"QueryFailedToExecute"),(0,l.kt)("td",{parentName:"tr",align:null},"Executing the query failed.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-6"),(0,l.kt)("td",{parentName:"tr",align:null},"FailedToParseGetBalanceURef"),(0,l.kt)("td",{parentName:"tr",align:null},"Parsing the URef while getting a balance failed.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-7"),(0,l.kt)("td",{parentName:"tr",align:null},"FailedToGetBalance"),(0,l.kt)("td",{parentName:"tr",align:null},"Failed to get the requested balance.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-8"),(0,l.kt)("td",{parentName:"tr",align:null},"GetBalanceFailedToExecute"),(0,l.kt)("td",{parentName:"tr",align:null},"Executing the query to retrieve the balance failed.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-9"),(0,l.kt)("td",{parentName:"tr",align:null},"InvalidDeploy"),(0,l.kt)("td",{parentName:"tr",align:null},"The given Deploy cannot be executed as it is invalid.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-10"),(0,l.kt)("td",{parentName:"tr",align:null},"NoSuchAccount"),(0,l.kt)("td",{parentName:"tr",align:null},"The given account was not found.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-11"),(0,l.kt)("td",{parentName:"tr",align:null},"FailedToGetDictionaryURef"),(0,l.kt)("td",{parentName:"tr",align:null},"Failed to get the requested dictionary URef.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-12"),(0,l.kt)("td",{parentName:"tr",align:null},"FailedToGetTrie"),(0,l.kt)("td",{parentName:"tr",align:null},"Failed to get the requested dictionary trie.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-13"),(0,l.kt)("td",{parentName:"tr",align:null},"NoSuchStateRoot"),(0,l.kt)("td",{parentName:"tr",align:null},"The requested state root hash was not found.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-32600"),(0,l.kt)("td",{parentName:"tr",align:null},"InvalidRequest"),(0,l.kt)("td",{parentName:"tr",align:null},"The JSON sent is not a valid Request object.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-32601"),(0,l.kt)("td",{parentName:"tr",align:null},"MethodNotFound"),(0,l.kt)("td",{parentName:"tr",align:null},"The method does not exist or is not available.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-32602"),(0,l.kt)("td",{parentName:"tr",align:null},"InvalidParams"),(0,l.kt)("td",{parentName:"tr",align:null},"Invalid method parameter(s)")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-32603"),(0,l.kt)("td",{parentName:"tr",align:null},"InternalError"),(0,l.kt)("td",{parentName:"tr",align:null},"Internal JSON-RPC error.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-32700"),(0,l.kt)("td",{parentName:"tr",align:null},"ParseError"),(0,l.kt)("td",{parentName:"tr",align:null},"Invalid JSON was received by the server.")))),(0,l.kt)("h2",{id:"invalid-params"},"Invalid ",(0,l.kt)("inlineCode",{parentName:"h2"},"Params")),(0,l.kt)("p",null,"The ",(0,l.kt)("inlineCode",{parentName:"p"},"casper-json-rpc")," no longer ignores invalid ",(0,l.kt)("inlineCode",{parentName:"p"},"params")," fields. ",(0,l.kt)("inlineCode",{parentName:"p"},"Params")," fields to be omitted should be an empty Array '[]', an empty Object '{}' or absent."),(0,l.kt)("p",null,"Failing to adhere to this will result in an ",(0,l.kt)("inlineCode",{parentName:"p"},"InvalidParams")," error."))}k.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6661],{3905:function(e,t,r){r.d(t,{Zo:function(){return u},kt:function(){return k}});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var d=n.createContext({}),p=function(e){var t=n.useContext(d),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(d.Provider,{value:t},e.children)},s="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,d=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),s=p(r),m=a,k=s["".concat(d,".").concat(m)]||s[m]||c[m]||l;return r?n.createElement(k,o(o({ref:t},u),{},{components:r})):n.createElement(k,o({ref:t},u))}));function k(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=m;var i={};for(var d in t)hasOwnProperty.call(t,d)&&(i[d]=t[d]);i.originalType=e,i[s]="string"==typeof e?e:a,o[1]=i;for(var p=2;pParams",id:"invalid-params",level:2}],c={toc:s},m="wrapper";function k(e){var t=e.components,r=(0,a.Z)(e,o);return(0,l.kt)(m,(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"casper-json-rpc-error-codes"},"Casper JSON-RPC Error Codes"),(0,l.kt)("p",null,"The following document expands on custom error codes provided by ",(0,l.kt)("inlineCode",{parentName:"p"},"casper-json-rpc")," crate."),(0,l.kt)("h2",{id:"codes"},"Error Codes"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Code"),(0,l.kt)("th",{parentName:"tr",align:null},"Error"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-1"),(0,l.kt)("td",{parentName:"tr",align:null},"NoSuchDeploy"),(0,l.kt)("td",{parentName:"tr",align:null},"The requested Deploy was not found.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-2"),(0,l.kt)("td",{parentName:"tr",align:null},"NoSuchBlock"),(0,l.kt)("td",{parentName:"tr",align:null},"The requested Block was not found.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-3"),(0,l.kt)("td",{parentName:"tr",align:null},"FailedToParseQueryKey"),(0,l.kt)("td",{parentName:"tr",align:null},"Parsing the Key from a query failed.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-4"),(0,l.kt)("td",{parentName:"tr",align:null},"QueryFailed"),(0,l.kt)("td",{parentName:"tr",align:null},"The query failed to find a result.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-5"),(0,l.kt)("td",{parentName:"tr",align:null},"QueryFailedToExecute"),(0,l.kt)("td",{parentName:"tr",align:null},"Executing the query failed.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-6"),(0,l.kt)("td",{parentName:"tr",align:null},"FailedToParseGetBalanceURef"),(0,l.kt)("td",{parentName:"tr",align:null},"Parsing the URef while getting a balance failed.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-7"),(0,l.kt)("td",{parentName:"tr",align:null},"FailedToGetBalance"),(0,l.kt)("td",{parentName:"tr",align:null},"Failed to get the requested balance.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-8"),(0,l.kt)("td",{parentName:"tr",align:null},"GetBalanceFailedToExecute"),(0,l.kt)("td",{parentName:"tr",align:null},"Executing the query to retrieve the balance failed.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-9"),(0,l.kt)("td",{parentName:"tr",align:null},"InvalidDeploy"),(0,l.kt)("td",{parentName:"tr",align:null},"The given Deploy cannot be executed as it is invalid.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-10"),(0,l.kt)("td",{parentName:"tr",align:null},"NoSuchAccount"),(0,l.kt)("td",{parentName:"tr",align:null},"The given account was not found.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-11"),(0,l.kt)("td",{parentName:"tr",align:null},"FailedToGetDictionaryURef"),(0,l.kt)("td",{parentName:"tr",align:null},"Failed to get the requested dictionary URef.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-12"),(0,l.kt)("td",{parentName:"tr",align:null},"FailedToGetTrie"),(0,l.kt)("td",{parentName:"tr",align:null},"Failed to get the requested dictionary trie.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-13"),(0,l.kt)("td",{parentName:"tr",align:null},"NoSuchStateRoot"),(0,l.kt)("td",{parentName:"tr",align:null},"The requested state root hash was not found.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-32600"),(0,l.kt)("td",{parentName:"tr",align:null},"InvalidRequest"),(0,l.kt)("td",{parentName:"tr",align:null},"The JSON sent is not a valid Request object.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-32601"),(0,l.kt)("td",{parentName:"tr",align:null},"MethodNotFound"),(0,l.kt)("td",{parentName:"tr",align:null},"The method does not exist or is not available.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-32602"),(0,l.kt)("td",{parentName:"tr",align:null},"InvalidParams"),(0,l.kt)("td",{parentName:"tr",align:null},"Invalid method parameter(s)")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-32603"),(0,l.kt)("td",{parentName:"tr",align:null},"InternalError"),(0,l.kt)("td",{parentName:"tr",align:null},"Internal JSON-RPC error.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"-32700"),(0,l.kt)("td",{parentName:"tr",align:null},"ParseError"),(0,l.kt)("td",{parentName:"tr",align:null},"Invalid JSON was received by the server.")))),(0,l.kt)("h2",{id:"invalid-params"},"Invalid ",(0,l.kt)("inlineCode",{parentName:"h2"},"Params")),(0,l.kt)("p",null,"The ",(0,l.kt)("inlineCode",{parentName:"p"},"casper-json-rpc")," no longer ignores invalid ",(0,l.kt)("inlineCode",{parentName:"p"},"params")," fields. ",(0,l.kt)("inlineCode",{parentName:"p"},"Params")," fields to be omitted should be an empty Array '[]', an empty Object '{}' or absent."),(0,l.kt)("p",null,"Failing to adhere to this will result in an ",(0,l.kt)("inlineCode",{parentName:"p"},"InvalidParams")," error."))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/41afe816.519480b3.js b/assets/js/41afe816.ad728689.js similarity index 98% rename from assets/js/41afe816.519480b3.js rename to assets/js/41afe816.ad728689.js index 6d7db25298..77f9a27a84 100644 --- a/assets/js/41afe816.519480b3.js +++ b/assets/js/41afe816.ad728689.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3457],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return y}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function p(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var o=r.createContext({}),s=function(e){var t=r.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=s(e.components);return r.createElement(o.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,p=e.originalType,o=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=s(n),m=a,y=u["".concat(o,".").concat(m)]||u[m]||d[m]||p;return n?r.createElement(y,i(i({ref:t},c),{},{components:n})):r.createElement(y,i({ref:t},c))}));function y(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=n.length,i=new Array(p);i[0]=m;var l={};for(var o in t)hasOwnProperty.call(t,o)&&(l[o]=t[o]);l.originalType=e,l[u]="string"==typeof e?e:a,i[1]=l;for(var s=2;s")," and also holds the CLType of the underlying data as a separate member. The ",(0,p.kt)("inlineCode",{parentName:"p"},"parsed")," field, representing the original value, is a convenience only available when a CLValue is encoded to JSON, and can always be set to null if preferred."),(0,p.kt)("ul",null,(0,p.kt)("li",{parentName:"ul"},(0,p.kt)("p",{parentName:"li"},(0,p.kt)("inlineCode",{parentName:"p"},"bytes")," A Casper serialized representation of the underlying value. For more information, reference the ",(0,p.kt)("a",{parentName:"p",href:"/concepts/serialization-standard"},"Serialization Standard"),".")),(0,p.kt)("li",{parentName:"ul"},(0,p.kt)("p",{parentName:"li"},(0,p.kt)("a",{parentName:"p",href:"#cltype"},(0,p.kt)("inlineCode",{parentName:"a"},"cl_type"))))))}y.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3457],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return y}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function p(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var o=r.createContext({}),s=function(e){var t=r.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=s(e.components);return r.createElement(o.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,p=e.originalType,o=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=s(n),m=a,y=u["".concat(o,".").concat(m)]||u[m]||d[m]||p;return n?r.createElement(y,i(i({ref:t},c),{},{components:n})):r.createElement(y,i({ref:t},c))}));function y(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=n.length,i=new Array(p);i[0]=m;var l={};for(var o in t)hasOwnProperty.call(t,o)&&(l[o]=t[o]);l.originalType=e,l[u]="string"==typeof e?e:a,i[1]=l;for(var s=2;s")," and also holds the CLType of the underlying data as a separate member. The ",(0,p.kt)("inlineCode",{parentName:"p"},"parsed")," field, representing the original value, is a convenience only available when a CLValue is encoded to JSON, and can always be set to null if preferred."),(0,p.kt)("ul",null,(0,p.kt)("li",{parentName:"ul"},(0,p.kt)("p",{parentName:"li"},(0,p.kt)("inlineCode",{parentName:"p"},"bytes")," A Casper serialized representation of the underlying value. For more information, reference the ",(0,p.kt)("a",{parentName:"p",href:"/concepts/serialization-standard"},"Serialization Standard"),".")),(0,p.kt)("li",{parentName:"ul"},(0,p.kt)("p",{parentName:"li"},(0,p.kt)("a",{parentName:"p",href:"#cltype"},(0,p.kt)("inlineCode",{parentName:"a"},"cl_type"))))))}y.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/4636fedf.b2a570c8.js b/assets/js/4636fedf.bcec48f4.js similarity index 99% rename from assets/js/4636fedf.b2a570c8.js rename to assets/js/4636fedf.bcec48f4.js index 58a328720e..bd11a89ca2 100644 --- a/assets/js/4636fedf.b2a570c8.js +++ b/assets/js/4636fedf.bcec48f4.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[8032],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return h}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=l(n),d=a,h=m["".concat(c,".").concat(d)]||m[d]||u[d]||o;return n?r.createElement(h,s(s({ref:t},p),{},{components:n})):r.createElement(h,s({ref:t},p))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[m]="string"==typeof e?e:a,s[1]=i;for(var l=2;l new WebAssembly.Instance(compiled, imports).exports,\n});\n')),(0,o.kt)("p",null,"Next, create a directory called ",(0,o.kt)("inlineCode",{parentName:"p"},"assembly"),", and in that directory, create a file called ",(0,o.kt)("inlineCode",{parentName:"p"},"tsconfig.json")," in the following way:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "extends": "../node_modules/assemblyscript/std/assembly.json",\n "include": ["./**/*.ts"]\n}\n')),(0,o.kt)("h3",{id:"sample-smart-contract"},"Sample Smart Contract"),(0,o.kt)("p",null,"In the ",(0,o.kt)("inlineCode",{parentName:"p"},"assembly")," directory, also create an ",(0,o.kt)("inlineCode",{parentName:"p"},"index.ts")," file, where the code for the contract needs to go."),(0,o.kt)("p",null,"You can use the following sample snippet, which demonstrates a simple smart contract that immediately returns an error and writes a message to a block when executed on a Casper network."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},'//@ts-nocheck\nimport { Error, ErrorCode } from "casper-contract/error";\n\n// simplest possible feedback loop\nexport function call(): void {\n Error.fromErrorCode(ErrorCode.None).revert(); // ErrorCode: 1\n}\n')),(0,o.kt)("p",null,"If you prefer a more complicated first contract, you can look at example contracts on the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem"},"Casper Ecosystem GitHub")," repository for inspiration."),(0,o.kt)("h3",{id:"compile-to-wasm"},"Compile to Wasm"),(0,o.kt)("p",null,"To compile the contract to Wasm, use ",(0,o.kt)("em",{parentName:"p"},"npm")," to run the ",(0,o.kt)("em",{parentName:"p"},"asbuild")," script from the project root:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"npm run asbuild\n")),(0,o.kt)("p",null,"If the build is successful, there will be a ",(0,o.kt)("inlineCode",{parentName:"p"},"dist")," folder in the ",(0,o.kt)("inlineCode",{parentName:"p"},"root")," folder and in it should be ",(0,o.kt)("inlineCode",{parentName:"p"},"your-contract-name.wasm"),"."))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[8032],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return h}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=l(n),d=a,h=m["".concat(c,".").concat(d)]||m[d]||u[d]||o;return n?r.createElement(h,s(s({ref:t},p),{},{components:n})):r.createElement(h,s({ref:t},p))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[m]="string"==typeof e?e:a,s[1]=i;for(var l=2;l new WebAssembly.Instance(compiled, imports).exports,\n});\n')),(0,o.kt)("p",null,"Next, create a directory called ",(0,o.kt)("inlineCode",{parentName:"p"},"assembly"),", and in that directory, create a file called ",(0,o.kt)("inlineCode",{parentName:"p"},"tsconfig.json")," in the following way:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "extends": "../node_modules/assemblyscript/std/assembly.json",\n "include": ["./**/*.ts"]\n}\n')),(0,o.kt)("h3",{id:"sample-smart-contract"},"Sample Smart Contract"),(0,o.kt)("p",null,"In the ",(0,o.kt)("inlineCode",{parentName:"p"},"assembly")," directory, also create an ",(0,o.kt)("inlineCode",{parentName:"p"},"index.ts")," file, where the code for the contract needs to go."),(0,o.kt)("p",null,"You can use the following sample snippet, which demonstrates a simple smart contract that immediately returns an error and writes a message to a block when executed on a Casper network."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},'//@ts-nocheck\nimport { Error, ErrorCode } from "casper-contract/error";\n\n// simplest possible feedback loop\nexport function call(): void {\n Error.fromErrorCode(ErrorCode.None).revert(); // ErrorCode: 1\n}\n')),(0,o.kt)("p",null,"If you prefer a more complicated first contract, you can look at example contracts on the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem"},"Casper Ecosystem GitHub")," repository for inspiration."),(0,o.kt)("h3",{id:"compile-to-wasm"},"Compile to Wasm"),(0,o.kt)("p",null,"To compile the contract to Wasm, use ",(0,o.kt)("em",{parentName:"p"},"npm")," to run the ",(0,o.kt)("em",{parentName:"p"},"asbuild")," script from the project root:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"npm run asbuild\n")),(0,o.kt)("p",null,"If the build is successful, there will be a ",(0,o.kt)("inlineCode",{parentName:"p"},"dist")," folder in the ",(0,o.kt)("inlineCode",{parentName:"p"},"root")," folder and in it should be ",(0,o.kt)("inlineCode",{parentName:"p"},"your-contract-name.wasm"),"."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/463fc8b8.1fe31a4c.js b/assets/js/463fc8b8.e8772e0f.js similarity index 99% rename from assets/js/463fc8b8.1fe31a4c.js rename to assets/js/463fc8b8.e8772e0f.js index 4c9caa1955..c2d954c2b9 100644 --- a/assets/js/463fc8b8.1fe31a4c.js +++ b/assets/js/463fc8b8.e8772e0f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[2807],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return f}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),i=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=i(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,c=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=i(n),h=r,f=d["".concat(l,".").concat(h)]||d[h]||p[h]||c;return n?a.createElement(f,o(o({ref:t},u),{},{components:n})):a.createElement(f,o({ref:t},u))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var c=n.length,o=new Array(c);o[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:r,o[1]=s;for(var i=2;i: \\\n// This is the contract package hash, which can be found within the `NamedKeys` of the account that sent the installing deploy.\n--key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \\\n// This is the most up to date state root hash, which can found by using the `get-state-root-hash` command in the Casper client.\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n")),(0,c.kt)("details",null,(0,c.kt)("summary",null,(0,c.kt)("b",null,"Casper client command without comments")),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state -n http://: \\\n--key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"))),(0,c.kt)("p",null,"This will return the ",(0,c.kt)("inlineCode",{parentName:"p"},"Contract Package")," object:"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -1489823435760214673,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[2048 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-8dac847ce0ae20f0156cf37dd233cc1d166fde8269fc9a393b0ea04174be1167-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n')),(0,c.kt)("ul",null,(0,c.kt)("li",{parentName:"ul"},"Note - In the ",(0,c.kt)("inlineCode",{parentName:"li"},"contract_hash")," field, the hash value represents the stored contract which we will invoke later.")),(0,c.kt)("h2",{id:"querying-the-utility-contract"},"Querying the Utility Contract"),(0,c.kt)("p",null,"In addition, there is a utility contract that invokes the various balance and allowance entry points of the main fungible token contract. Upon receiving the returned value, the utility contract will write the value to a URef called ",(0,c.kt)("inlineCode",{parentName:"p"},"result"),". You can find this URef in the ",(0,c.kt)("inlineCode",{parentName:"p"},"NamedKeys")," of the utility contract."),(0,c.kt)("p",null,"First, you will need to query the ",(0,c.kt)("inlineCode",{parentName:"p"},"cep18_test_contract")," hash found within the installing account's ",(0,c.kt)("inlineCode",{parentName:"p"},"NamedKeys"),":"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-json"},"casper-client query-global-state -n http://: \\\n// This is the contract hash for the `cep18_test_contract` as found from the installing account's `NamedKeys`\n--key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n")),(0,c.kt)("details",null,(0,c.kt)("summary",null,(0,c.kt)("b",null,"Casper client command without comments")),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-json"},"casper-client query-global-state -n http://: \\\n--key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"))),(0,c.kt)("p",null,"Which should return information similar to the following:"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 5359405942597097786,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[2048 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-1b867a3751f505762c69c8d92ba7462818cd0c2a705bb5d4270bce479410ee55-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n\n')),(0,c.kt)("p",null,"You will need to take the ",(0,c.kt)("inlineCode",{parentName:"p"},"contract_hash")," value and replace ",(0,c.kt)("inlineCode",{parentName:"p"},"contract")," with ",(0,c.kt)("inlineCode",{parentName:"p"},"hash")," to run another `query-global-state:"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state -n http://: \\\n--key hash-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n")),(0,c.kt)("p",null,"Which will return the full ",(0,c.kt)("inlineCode",{parentName:"p"},"cep18_test_contract")," information. The following snippet is condensed to show only the ",(0,c.kt)("inlineCode",{parentName:"p"},"NamedKeys"),", but you should also see the ",(0,c.kt)("inlineCode",{parentName:"p"},"entry_points")," when you run the command. You should see the URef ",(0,c.kt)("inlineCode",{parentName:"p"},"result"),", which will be used to view the results of any checks run through the utility contract."),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -1426549275795832481,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3370 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6",\n "contract_wasm_hash": "contract-wasm-7959083a4df983ddcd3a9ae46af092dbf126031181ab2619ddc64db09bde8c27",\n "named_keys": [\n {\n "key": "uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007",\n "name": "result"\n }\n ],\n "protocol_version": "1.0.0"\n }\n }\n }\n}\n\n')),(0,c.kt)("h2",{id:"next-steps"},"Next Steps"),(0,c.kt)("ul",null,(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("a",{parentName:"li",href:"/resources/tokens/cep18/transfer"},"CEP-18 Token Transfers and Allowances"))))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[2807],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return f}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),i=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=i(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,c=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=i(n),h=r,f=d["".concat(l,".").concat(h)]||d[h]||p[h]||c;return n?a.createElement(f,o(o({ref:t},u),{},{components:n})):a.createElement(f,o({ref:t},u))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var c=n.length,o=new Array(c);o[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:r,o[1]=s;for(var i=2;i: \\\n// This is the contract package hash, which can be found within the `NamedKeys` of the account that sent the installing deploy.\n--key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \\\n// This is the most up to date state root hash, which can found by using the `get-state-root-hash` command in the Casper client.\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n")),(0,c.kt)("details",null,(0,c.kt)("summary",null,(0,c.kt)("b",null,"Casper client command without comments")),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state -n http://: \\\n--key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"))),(0,c.kt)("p",null,"This will return the ",(0,c.kt)("inlineCode",{parentName:"p"},"Contract Package")," object:"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -1489823435760214673,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[2048 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-8dac847ce0ae20f0156cf37dd233cc1d166fde8269fc9a393b0ea04174be1167-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n')),(0,c.kt)("ul",null,(0,c.kt)("li",{parentName:"ul"},"Note - In the ",(0,c.kt)("inlineCode",{parentName:"li"},"contract_hash")," field, the hash value represents the stored contract which we will invoke later.")),(0,c.kt)("h2",{id:"querying-the-utility-contract"},"Querying the Utility Contract"),(0,c.kt)("p",null,"In addition, there is a utility contract that invokes the various balance and allowance entry points of the main fungible token contract. Upon receiving the returned value, the utility contract will write the value to a URef called ",(0,c.kt)("inlineCode",{parentName:"p"},"result"),". You can find this URef in the ",(0,c.kt)("inlineCode",{parentName:"p"},"NamedKeys")," of the utility contract."),(0,c.kt)("p",null,"First, you will need to query the ",(0,c.kt)("inlineCode",{parentName:"p"},"cep18_test_contract")," hash found within the installing account's ",(0,c.kt)("inlineCode",{parentName:"p"},"NamedKeys"),":"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-json"},"casper-client query-global-state -n http://: \\\n// This is the contract hash for the `cep18_test_contract` as found from the installing account's `NamedKeys`\n--key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n")),(0,c.kt)("details",null,(0,c.kt)("summary",null,(0,c.kt)("b",null,"Casper client command without comments")),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-json"},"casper-client query-global-state -n http://: \\\n--key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"))),(0,c.kt)("p",null,"Which should return information similar to the following:"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 5359405942597097786,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[2048 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-1b867a3751f505762c69c8d92ba7462818cd0c2a705bb5d4270bce479410ee55-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n\n')),(0,c.kt)("p",null,"You will need to take the ",(0,c.kt)("inlineCode",{parentName:"p"},"contract_hash")," value and replace ",(0,c.kt)("inlineCode",{parentName:"p"},"contract")," with ",(0,c.kt)("inlineCode",{parentName:"p"},"hash")," to run another `query-global-state:"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state -n http://: \\\n--key hash-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n")),(0,c.kt)("p",null,"Which will return the full ",(0,c.kt)("inlineCode",{parentName:"p"},"cep18_test_contract")," information. The following snippet is condensed to show only the ",(0,c.kt)("inlineCode",{parentName:"p"},"NamedKeys"),", but you should also see the ",(0,c.kt)("inlineCode",{parentName:"p"},"entry_points")," when you run the command. You should see the URef ",(0,c.kt)("inlineCode",{parentName:"p"},"result"),", which will be used to view the results of any checks run through the utility contract."),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -1426549275795832481,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3370 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6",\n "contract_wasm_hash": "contract-wasm-7959083a4df983ddcd3a9ae46af092dbf126031181ab2619ddc64db09bde8c27",\n "named_keys": [\n {\n "key": "uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007",\n "name": "result"\n }\n ],\n "protocol_version": "1.0.0"\n }\n }\n }\n}\n\n')),(0,c.kt)("h2",{id:"next-steps"},"Next Steps"),(0,c.kt)("ul",null,(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("a",{parentName:"li",href:"/resources/tokens/cep18/transfer"},"CEP-18 Token Transfers and Allowances"))))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/46ca92b5.4dcf13f1.js b/assets/js/46ca92b5.cd7e673d.js similarity index 99% rename from assets/js/46ca92b5.4dcf13f1.js rename to assets/js/46ca92b5.cd7e673d.js index d77cceccd3..095308f6ad 100644 --- a/assets/js/46ca92b5.4dcf13f1.js +++ b/assets/js/46ca92b5.cd7e673d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5814],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return f}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=r.createContext({}),s=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=s(e.components);return r.createElement(p.Provider,{value:t},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=s(n),d=a,f=c["".concat(p,".").concat(d)]||c[d]||m[d]||i;return n?r.createElement(f,o(o({ref:t},u),{},{components:n})):r.createElement(f,o({ref:t},u))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[c]="string"==typeof e?e:a,o[1]=l;for(var s=2;slimits.conf File",id:"updating-limits-conf",level:2}],m={toc:c},d="wrapper";function f(e){var t=e.components,n=(0,a.Z)(e,o);return(0,i.kt)(d,(0,r.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"setting-the-open-files-limit"},"Setting the Open Files Limit"),(0,i.kt)("p",null,"When the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," launches, it tries to set the maximum open files limit (",(0,i.kt)("inlineCode",{parentName:"p"},"nofile"),") for the process to ",(0,i.kt)("inlineCode",{parentName:"p"},"64000"),". With some systems, this limit will be larger than the default hard limit of ",(0,i.kt)("inlineCode",{parentName:"p"},"4096"),"."),(0,i.kt)("p",null,"The node software uses file handles for both files and network connections. Since network connections are unpredictable, running out of file handles can stop critical file writes from occurring. Therefore, the default ",(0,i.kt)("inlineCode",{parentName:"p"},"nofile")," limit needs to be increased."),(0,i.kt)("p",null,"With the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," running, you can see what the system allocated by finding the process ID (PID) for the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," with the following command."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'pgrep "casper-node$"\n')),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Sample output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'$ pgrep "casper-node$"\n275928\n')),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},"This PID will change, so you need to run the above command to get the current version with your system. Also, it will not be ",(0,i.kt)("inlineCode",{parentName:"p"},"275928")," each time."))),(0,i.kt)("p",null,"If you do not get a value in return, you do not have the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," running correctly."),(0,i.kt)("p",null,"To find the current ",(0,i.kt)("inlineCode",{parentName:"p"},"nofile")," (number of open files) hard limit, run ",(0,i.kt)("inlineCode",{parentName:"p"},"prlimit")," with the PID from the previous command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo prlimit -n -p \n")),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Sample output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"$ sudo prlimit -n -p 275928\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 1024 4096 files\n"))),(0,i.kt)("p",null,"You can also embed both commands as shown here:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'sudo prlimit -n -p $(pgrep "casper-node$")\n')),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Sample output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'$ sudo prlimit -n -p $(pgrep "casper-node$")\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 1024 4096 files\n'))),(0,i.kt)("p",null,"If you receive ",(0,i.kt)("inlineCode",{parentName:"p"},"prlimit: option requires an argument -- 'p'"),", then ",(0,i.kt)("inlineCode",{parentName:"p"},'pgrep "casper-node$"')," is not returning anything because the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," is no longer running."),(0,i.kt)("h2",{id:"updating-manually"},"Setting the Limit Manually"),(0,i.kt)("p",null,"Run the command below to set the ",(0,i.kt)("inlineCode",{parentName:"p"},"nofile")," limit for an active process without restarting the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," processes. Note that this setting is active only while the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," process runs. To make this setting permanent, ",(0,i.kt)("a",{parentName:"p",href:"#updating-limits-conf"},"update the ",(0,i.kt)("inlineCode",{parentName:"a"},"limits.conf"))," file instead."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'sudo prlimit --nofile=64000 --pid=$(pgrep "casper-node$")`\n')),(0,i.kt)("p",null,"Next, check that the ",(0,i.kt)("inlineCode",{parentName:"p"},"prlimit")," has changed:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'sudo prlimit -n -p $(pgrep "casper-node$")\n')),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Sample output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'$ sudo prlimit -n -p $(pgrep "casper-node$")\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 64000 64000 files\n'))),(0,i.kt)("h2",{id:"updating-limits-conf"},"Updating the ",(0,i.kt)("inlineCode",{parentName:"h2"},"limits.conf")," File"),(0,i.kt)("p",null,"It is possible to persist the ",(0,i.kt)("inlineCode",{parentName:"p"},"nofile")," limit across server reboots, ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," restarts, and protocol upgrades, by adding the ",(0,i.kt)("inlineCode",{parentName:"p"},"nofile")," setting for the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper")," user in ",(0,i.kt)("inlineCode",{parentName:"p"},"/etc/security/limits.conf"),"."),(0,i.kt)("p",null,"Add the following row to the bottom of the ",(0,i.kt)("inlineCode",{parentName:"p"},"/etc/security/limits.conf")," file:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"casper hard nofile 64000\n")),(0,i.kt)("p",null,"Afterward, log out of any shells to enable this change. Restarting the node should maintain the correct ",(0,i.kt)("inlineCode",{parentName:"p"},"nofile")," setting."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5814],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return f}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=r.createContext({}),s=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=s(e.components);return r.createElement(p.Provider,{value:t},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=s(n),d=a,f=c["".concat(p,".").concat(d)]||c[d]||m[d]||i;return n?r.createElement(f,o(o({ref:t},u),{},{components:n})):r.createElement(f,o({ref:t},u))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[c]="string"==typeof e?e:a,o[1]=l;for(var s=2;slimits.conf File",id:"updating-limits-conf",level:2}],m={toc:c},d="wrapper";function f(e){var t=e.components,n=(0,a.Z)(e,o);return(0,i.kt)(d,(0,r.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"setting-the-open-files-limit"},"Setting the Open Files Limit"),(0,i.kt)("p",null,"When the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," launches, it tries to set the maximum open files limit (",(0,i.kt)("inlineCode",{parentName:"p"},"nofile"),") for the process to ",(0,i.kt)("inlineCode",{parentName:"p"},"64000"),". With some systems, this limit will be larger than the default hard limit of ",(0,i.kt)("inlineCode",{parentName:"p"},"4096"),"."),(0,i.kt)("p",null,"The node software uses file handles for both files and network connections. Since network connections are unpredictable, running out of file handles can stop critical file writes from occurring. Therefore, the default ",(0,i.kt)("inlineCode",{parentName:"p"},"nofile")," limit needs to be increased."),(0,i.kt)("p",null,"With the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," running, you can see what the system allocated by finding the process ID (PID) for the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," with the following command."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'pgrep "casper-node$"\n')),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Sample output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'$ pgrep "casper-node$"\n275928\n')),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},"This PID will change, so you need to run the above command to get the current version with your system. Also, it will not be ",(0,i.kt)("inlineCode",{parentName:"p"},"275928")," each time."))),(0,i.kt)("p",null,"If you do not get a value in return, you do not have the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," running correctly."),(0,i.kt)("p",null,"To find the current ",(0,i.kt)("inlineCode",{parentName:"p"},"nofile")," (number of open files) hard limit, run ",(0,i.kt)("inlineCode",{parentName:"p"},"prlimit")," with the PID from the previous command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo prlimit -n -p \n")),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Sample output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"$ sudo prlimit -n -p 275928\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 1024 4096 files\n"))),(0,i.kt)("p",null,"You can also embed both commands as shown here:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'sudo prlimit -n -p $(pgrep "casper-node$")\n')),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Sample output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'$ sudo prlimit -n -p $(pgrep "casper-node$")\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 1024 4096 files\n'))),(0,i.kt)("p",null,"If you receive ",(0,i.kt)("inlineCode",{parentName:"p"},"prlimit: option requires an argument -- 'p'"),", then ",(0,i.kt)("inlineCode",{parentName:"p"},'pgrep "casper-node$"')," is not returning anything because the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," is no longer running."),(0,i.kt)("h2",{id:"updating-manually"},"Setting the Limit Manually"),(0,i.kt)("p",null,"Run the command below to set the ",(0,i.kt)("inlineCode",{parentName:"p"},"nofile")," limit for an active process without restarting the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," processes. Note that this setting is active only while the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node")," process runs. To make this setting permanent, ",(0,i.kt)("a",{parentName:"p",href:"#updating-limits-conf"},"update the ",(0,i.kt)("inlineCode",{parentName:"a"},"limits.conf"))," file instead."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'sudo prlimit --nofile=64000 --pid=$(pgrep "casper-node$")`\n')),(0,i.kt)("p",null,"Next, check that the ",(0,i.kt)("inlineCode",{parentName:"p"},"prlimit")," has changed:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'sudo prlimit -n -p $(pgrep "casper-node$")\n')),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Sample output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'$ sudo prlimit -n -p $(pgrep "casper-node$")\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 64000 64000 files\n'))),(0,i.kt)("h2",{id:"updating-limits-conf"},"Updating the ",(0,i.kt)("inlineCode",{parentName:"h2"},"limits.conf")," File"),(0,i.kt)("p",null,"It is possible to persist the ",(0,i.kt)("inlineCode",{parentName:"p"},"nofile")," limit across server reboots, ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," restarts, and protocol upgrades, by adding the ",(0,i.kt)("inlineCode",{parentName:"p"},"nofile")," setting for the ",(0,i.kt)("inlineCode",{parentName:"p"},"casper")," user in ",(0,i.kt)("inlineCode",{parentName:"p"},"/etc/security/limits.conf"),"."),(0,i.kt)("p",null,"Add the following row to the bottom of the ",(0,i.kt)("inlineCode",{parentName:"p"},"/etc/security/limits.conf")," file:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"casper hard nofile 64000\n")),(0,i.kt)("p",null,"Afterward, log out of any shells to enable this change. Restarting the node should maintain the correct ",(0,i.kt)("inlineCode",{parentName:"p"},"nofile")," setting."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/474a98da.d53e36e3.js b/assets/js/474a98da.f78bd321.js similarity index 98% rename from assets/js/474a98da.d53e36e3.js rename to assets/js/474a98da.f78bd321.js index c7b6f2d6ae..3ce664cdab 100644 --- a/assets/js/474a98da.d53e36e3.js +++ b/assets/js/474a98da.f78bd321.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[1918],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return h}});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var i=r.createContext({}),l=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(i.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,s=e.originalType,i=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),p=l(n),f=o,h=p["".concat(i,".").concat(f)]||p[f]||d[f]||s;return n?r.createElement(h,a(a({ref:t},u),{},{components:n})):r.createElement(h,a({ref:t},u))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=n.length,a=new Array(s);a[0]=f;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c[p]="string"==typeof e?e:o,a[1]=c;for(var l=2;l=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var i=r.createContext({}),l=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(i.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,s=e.originalType,i=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),p=l(n),f=o,h=p["".concat(i,".").concat(f)]||p[f]||d[f]||s;return n?r.createElement(h,a(a({ref:t},u),{},{components:n})):r.createElement(h,a({ref:t},u))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=n.length,a=new Array(s);a[0]=f;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c[p]="string"==typeof e?e:o,a[1]=c;for(var l=2;l=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=c(n),d=a,h=u["".concat(l,".").concat(d)]||u[d]||m[d]||o;return n?r.createElement(h,s(s({ref:t},p),{},{components:n})):r.createElement(h,s({ref:t},p))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:a,s[1]=i;for(var c=2;c=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=c(n),d=a,h=u["".concat(l,".").concat(d)]||u[d]||m[d]||o;return n?r.createElement(h,s(s({ref:t},p),{},{components:n})):r.createElement(h,s({ref:t},p))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:a,s[1]=i;for(var c=2;c=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=a.createContext({}),i=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=i(e.components);return a.createElement(c.Provider,{value:t},e.children)},h="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),h=i(n),d=o,m=h["".concat(c,".").concat(d)]||h[d]||p[d]||r;return n?a.createElement(m,l(l({ref:t},u),{},{components:n})):a.createElement(m,l({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,l=new Array(r);l[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[h]="string"==typeof e?e:o,l[1]=s;for(var i=2;i=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=a.createContext({}),i=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=i(e.components);return a.createElement(c.Provider,{value:t},e.children)},h="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),h=i(n),d=o,m=h["".concat(c,".").concat(d)]||h[d]||p[d]||r;return n?a.createElement(m,l(l({ref:t},u),{},{components:n})):a.createElement(m,l({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,l=new Array(r);l[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[h]="string"==typeof e?e:o,l[1]=s;for(var i=2;i=0||(a[r]=t[r]);return a}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,r)&&(a[r]=t[r])}return a}var u=n.createContext({}),l=function(t){var e=n.useContext(u),r=e;return t&&(r="function"==typeof t?t(e):i(i({},e),t)),r},c=function(t){var e=l(t.components);return n.createElement(u.Provider,{value:e},t.children)},d="mdxType",p={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},m=n.forwardRef((function(t,e){var r=t.components,a=t.mdxType,o=t.originalType,u=t.parentName,c=s(t,["components","mdxType","originalType","parentName"]),d=l(r),m=a,f=d["".concat(u,".").concat(m)]||d[m]||p[m]||o;return r?n.createElement(f,i(i({ref:e},c),{},{components:r})):n.createElement(f,i({ref:e},c))}));function f(t,e){var r=arguments,a=e&&e.mdxType;if("string"==typeof t||a){var o=r.length,i=new Array(o);i[0]=m;var s={};for(var u in e)hasOwnProperty.call(e,u)&&(s[u]=e[u]);s.originalType=t,s[d]="string"==typeof t?t:a,i[1]=s;for(var l=2;l=0||(a[r]=t[r]);return a}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,r)&&(a[r]=t[r])}return a}var u=n.createContext({}),l=function(t){var e=n.useContext(u),r=e;return t&&(r="function"==typeof t?t(e):i(i({},e),t)),r},c=function(t){var e=l(t.components);return n.createElement(u.Provider,{value:e},t.children)},d="mdxType",p={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},m=n.forwardRef((function(t,e){var r=t.components,a=t.mdxType,o=t.originalType,u=t.parentName,c=s(t,["components","mdxType","originalType","parentName"]),d=l(r),m=a,f=d["".concat(u,".").concat(m)]||d[m]||p[m]||o;return r?n.createElement(f,i(i({ref:e},c),{},{components:r})):n.createElement(f,i({ref:e},c))}));function f(t,e){var r=arguments,a=e&&e.mdxType;if("string"==typeof t||a){var o=r.length,i=new Array(o);i[0]=m;var s={};for(var u in e)hasOwnProperty.call(e,u)&&(s[u]=e[u]);s.originalType=t,s[d]="string"==typeof t?t:a,i[1]=s;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(n),d=r,h=p["".concat(c,".").concat(d)]||p[d]||m[d]||o;return n?a.createElement(h,i(i({ref:t},u),{},{components:n})):a.createElement(h,i({ref:t},u))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(n),d=r,h=p["".concat(c,".").concat(d)]||p[d]||m[d]||o;return n?a.createElement(h,i(i({ref:t},u),{},{components:n})):a.createElement(h,i({ref:t},u))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),u=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(s.Provider,{value:t},e.children)},g="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),g=u(n),d=r,m=g["".concat(s,".").concat(d)]||g[d]||p[d]||o;return n?a.createElement(m,i(i({ref:t},c),{},{components:n})):a.createElement(m,i({ref:t},c))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[g]="string"==typeof e?e:r,i[1]=l;for(var u=2;u=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),u=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(s.Provider,{value:t},e.children)},g="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),g=u(n),d=r,m=g["".concat(s,".").concat(d)]||g[d]||p[d]||o;return n?a.createElement(m,i(i({ref:t},c),{},{components:n})):a.createElement(m,i({ref:t},c))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[g]="string"==typeof e?e:r,i[1]=l;for(var u=2;u=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},f="mdxType",i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),f=l(r),m=a,y=f["".concat(c,".").concat(m)]||f[m]||i[m]||o;return r?n.createElement(y,s(s({ref:t},u),{},{components:r})):n.createElement(y,s({ref:t},u))}));function y(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=m;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[f]="string"==typeof e?e:a,s[1]=p;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},f="mdxType",i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),f=l(r),m=a,y=f["".concat(c,".").concat(m)]||f[m]||i[m]||o;return r?n.createElement(y,s(s({ref:t},u),{},{components:r})):n.createElement(y,s({ref:t},u))}));function y(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=m;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[f]="string"==typeof e?e:a,s[1]=p;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},d="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=l(r),f=a,m=d["".concat(p,".").concat(f)]||d[f]||c[f]||o;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=f;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[d]="string"==typeof e?e:a,i[1]=s;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},d="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=l(r),f=a,m=d["".concat(p,".").concat(f)]||d[f]||c[f]||o;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=f;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[d]="string"==typeof e?e:a,i[1]=s;for(var l=2;l=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=r.createContext({}),c=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=c(e.components);return r.createElement(p.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=c(n),g=o,f=u["".concat(p,".").concat(g)]||u[g]||d[g]||a;return n?r.createElement(f,i(i({ref:t},l),{},{components:n})):r.createElement(f,i({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=g;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var c=2;c=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=r.createContext({}),c=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=c(e.components);return r.createElement(p.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=c(n),g=o,f=u["".concat(p,".").concat(g)]||u[g]||d[g]||a;return n?r.createElement(f,i(i({ref:t},l),{},{components:n})):r.createElement(f,i({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=g;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var c=2;c=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),i=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},l=function(e){var t=i(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},k=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,l=p(e,["components","mdxType","originalType","parentName"]),u=i(n),k=a,m=u["".concat(c,".").concat(k)]||u[k]||d[k]||o;return n?r.createElement(m,s(s({ref:t},l),{},{components:n})):r.createElement(m,s({ref:t},l))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=k;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[u]="string"==typeof e?e:a,s[1]=p;for(var i=2;i=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),i=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},l=function(e){var t=i(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},k=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,l=p(e,["components","mdxType","originalType","parentName"]),u=i(n),k=a,m=u["".concat(c,".").concat(k)]||u[k]||d[k]||o;return n?r.createElement(m,s(s({ref:t},l),{},{components:n})):r.createElement(m,s({ref:t},l))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=k;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[u]="string"==typeof e?e:a,s[1]=p;for(var i=2;i=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(r),y=a,m=f["".concat(p,".").concat(y)]||f[y]||i[y]||o;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[f]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(r),y=a,m=f["".concat(p,".").concat(y)]||f[y]||i[y]||o;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[f]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var i=n.createContext({}),p=function(e){var t=n.useContext(i),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},c=function(e){var t=p(e.components);return n.createElement(i.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(a),d=r,h=u["".concat(i,".").concat(d)]||u[d]||m[d]||o;return a?n.createElement(h,l(l({ref:t},c),{},{components:a})):n.createElement(h,l({ref:t},c))}));function h(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,l=new Array(o);l[0]=d;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[u]="string"==typeof e?e:r,l[1]=s;for(var p=2;p=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var i=n.createContext({}),p=function(e){var t=n.useContext(i),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},c=function(e){var t=p(e.components);return n.createElement(i.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(a),d=r,h=u["".concat(i,".").concat(d)]||u[d]||m[d]||o;return a?n.createElement(h,l(l({ref:t},c),{},{components:a})):n.createElement(h,l({ref:t},c))}));function h(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,l=new Array(o);l[0]=d;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[u]="string"==typeof e?e:r,l[1]=s;for(var p=2;p=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var s=a.createContext({}),c=function(e){var t=a.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=c(e.components);return a.createElement(s.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=c(r),f=n,m=d["".concat(s,".").concat(f)]||d[f]||p[f]||o;return r?a.createElement(m,i(i({ref:t},u),{},{components:r})):a.createElement(m,i({ref:t},u))}));function m(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=f;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:n,i[1]=l;for(var c=2;c=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var s=a.createContext({}),c=function(e){var t=a.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=c(e.components);return a.createElement(s.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=c(r),f=n,m=d["".concat(s,".").concat(f)]||d[f]||p[f]||o;return r?a.createElement(m,i(i({ref:t},u),{},{components:r})):a.createElement(m,i({ref:t},u))}));function m(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=f;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:n,i[1]=l;for(var c=2;c=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),d=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},m=function(t){var e=d(t.components);return n.createElement(p.Provider,{value:e},t.children)},k="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},N=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,m=o(t,["components","mdxType","originalType","parentName"]),k=d(a),N=r,s=k["".concat(p,".").concat(N)]||k[N]||u[N]||l;return a?n.createElement(s,i(i({ref:e},m),{},{components:a})):n.createElement(s,i({ref:e},m))}));function s(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=N;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o[k]="string"==typeof t?t:r,i[1]=o;for(var d=2;dBr_Table OpCode Costs",id:"br_table-opcode-costs",level:2},{value:"External Function Costs",id:"external-function-costs",level:2},{value:"Protocol Operating Costs",id:"protocol-operating-costs",level:2},{value:"Auction System Contract Costs",id:"auction-system-contract-costs",level:3},{value:"Mint System Contract Costs",id:"mint-system-contract-costs",level:3},{value:"Handle_Payment System Contract Costs",id:"handle_payment-system-contract-costs",level:3},{value:"Standard_Payment System Contract Costs",id:"standard_payment-system-contract-costs",level:3}],u={toc:k},N="wrapper";function s(t){var e=t.components,a=(0,r.Z)(t,i);return(0,l.kt)(N,(0,n.Z)({},u,a,{components:e,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"opcode-costs-tables"},"OpCode Costs Tables"),(0,l.kt)("p",null,"The following tables outline the cost, in motes, for a given operation on Casper's Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated ",(0,l.kt)("inlineCode",{parentName:"p"},"chainspec.toml"),"."),(0,l.kt)("p",null,"More information on ",(0,l.kt)("inlineCode",{parentName:"p"},"chainspec"),"s for private networks can be found ",(0,l.kt)("a",{parentName:"p",href:"/operators/setup-network/chain-spec"},"here")),(0,l.kt)("admonition",{type:"note"},(0,l.kt)("p",{parentName:"admonition"},"All costs in this table are in ",(0,l.kt)("a",{parentName:"p",href:"/concepts/glossary/M/#motes"},"motes"),", not CSPR, and the corresponding chainspec is ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/53dd33865c2707c29284ccc0e8485f22ddd6fbe3/resources/production/chainspec.toml#L129"},"here"),".")),(0,l.kt)("h2",{id:"storage-costs"},"Storage Costs"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"gas_per_byte"),(0,l.kt)("td",{parentName:"tr",align:null},"Gas charged per byte stored in global state."),(0,l.kt)("td",{parentName:"tr",align:null},"630,000")))),(0,l.kt)("h2",{id:"opcode-costs"},"OpCode Costs"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"bit"),(0,l.kt)("td",{parentName:"tr",align:null},"Bit operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"300")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"add"),(0,l.kt)("td",{parentName:"tr",align:null},"Arithmetic add operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"210")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"mul"),(0,l.kt)("td",{parentName:"tr",align:null},"Mul operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"240")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"div"),(0,l.kt)("td",{parentName:"tr",align:null},"Div operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"320")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"load"),(0,l.kt)("td",{parentName:"tr",align:null},"Memory load operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"store"),(0,l.kt)("td",{parentName:"tr",align:null},"Memory store operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"4,700")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"const"),(0,l.kt)("td",{parentName:"tr",align:null},"Const store operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"110")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"local"),(0,l.kt)("td",{parentName:"tr",align:null},"Local operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"390")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"global"),(0,l.kt)("td",{parentName:"tr",align:null},"Global operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"390")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"integer_comparison"),(0,l.kt)("td",{parentName:"tr",align:null},"Integer operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"250")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"conversion"),(0,l.kt)("td",{parentName:"tr",align:null},"Conversion operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"420")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"unreachable"),(0,l.kt)("td",{parentName:"tr",align:null},"Unreachable operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"270")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"nop"),(0,l.kt)("td",{parentName:"tr",align:null},"Nop operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"200")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"current_memory"),(0,l.kt)("td",{parentName:"tr",align:null},"Get the current memory operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"290")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"grow_memory"),(0,l.kt)("td",{parentName:"tr",align:null},"Grow memory cost per page (64 kB)."),(0,l.kt)("td",{parentName:"tr",align:null},"240,000")))),(0,l.kt)("h2",{id:"control-flow-operation-costs"},"Control Flow Operation Costs"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"block"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"block")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"loop"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"loop")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"if"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"if")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"else"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"else")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"end"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"end")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"br"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"br")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"35_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"br_if"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"br_if")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"35,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"return"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"return")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"select"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"select")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"call"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"call")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"68_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"call_indirect"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"call_indirect")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"68,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"drop"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"drop")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")))),(0,l.kt)("h2",{id:"br_table-opcode-costs"},(0,l.kt)("inlineCode",{parentName:"h2"},"Br_Table")," OpCode Costs"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"cost"),(0,l.kt)("td",{parentName:"tr",align:null},"Fixed cost per ",(0,l.kt)("inlineCode",{parentName:"td"},"br_table")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"35,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"size_multiplier"),(0,l.kt)("td",{parentName:"tr",align:null},"Size of target labels in the ",(0,l.kt)("inlineCode",{parentName:"td"},"br_table")," opcode will be multiplied by ",(0,l.kt)("inlineCode",{parentName:"td"},"size_multiplier"),"."),(0,l.kt)("td",{parentName:"tr",align:null},"100")))),(0,l.kt)("h2",{id:"external-function-costs"},"External Function Costs"),(0,l.kt)("p",null,'The following costs are for low-level bindings for host-side ("external") functions. More information on the Casper external FFI can be found ',(0,l.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html"},"here"),"."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Host-Side Function"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"),(0,l.kt)("th",{parentName:"tr",align:null},"Arguments"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"add"),(0,l.kt)("td",{parentName:"tr",align:null},"5,800"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"add_associated_key"),(0,l.kt)("td",{parentName:"tr",align:null},"9,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"add_contract_version"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"blake2b"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"call_contract"),(0,l.kt)("td",{parentName:"tr",align:null},"4,500"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 420, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"call_versioned_contract"),(0,l.kt)("td",{parentName:"tr",align:null},"4,500"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 0, 0, 420, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"create_contract_package_at_hash"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"create_contract_user_group"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"create_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"disable_contract_version"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_balance"),(0,l.kt)("td",{parentName:"tr",align:null},"3,800"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_blocktime"),(0,l.kt)("td",{parentName:"tr",align:null},"330"),(0,l.kt)("td",{parentName:"tr",align:null},"[0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_caller"),(0,l.kt)("td",{parentName:"tr",align:null},"380"),(0,l.kt)("td",{parentName:"tr",align:null},"[0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_key"),(0,l.kt)("td",{parentName:"tr",align:null},"2,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 440, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_main_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"1,300"),(0,l.kt)("td",{parentName:"tr",align:null},"[0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_named_arg"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_named_arg_size"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_phase"),(0,l.kt)("td",{parentName:"tr",align:null},"710"),(0,l.kt)("td",{parentName:"tr",align:null},"[0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_system_contract"),(0,l.kt)("td",{parentName:"tr",align:null},"1,100"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"has_key"),(0,l.kt)("td",{parentName:"tr",align:null},"1,500"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 840]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"is_valid_uref"),(0,l.kt)("td",{parentName:"tr",align:null},"760"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"load_named_keys"),(0,l.kt)("td",{parentName:"tr",align:null},"42,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"new_uref"),(0,l.kt)("td",{parentName:"tr",align:null},"17,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 590]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"random_bytes"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"print"),(0,l.kt)("td",{parentName:"tr",align:null},"20,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 4,600]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"provision_contract_user_group_uref"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"put_key"),(0,l.kt)("td",{parentName:"tr",align:null},"38,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 1,100, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_host_buffer"),(0,l.kt)("td",{parentName:"tr",align:null},"3,500"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 310, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_value"),(0,l.kt)("td",{parentName:"tr",align:null},"6,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_value_local"),(0,l.kt)("td",{parentName:"tr",align:null},"5,500"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 590, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"remove_associated_key"),(0,l.kt)("td",{parentName:"tr",align:null},"4,200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"remove_contract_user_group"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"remove_contract_user_group_urefs"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"remove_key"),(0,l.kt)("td",{parentName:"tr",align:null},"61,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 3,200]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ret"),(0,l.kt)("td",{parentName:"tr",align:null},"23,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 420,000]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"revert"),(0,l.kt)("td",{parentName:"tr",align:null},"500"),(0,l.kt)("td",{parentName:"tr",align:null},"[0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"set_action_threshold"),(0,l.kt)("td",{parentName:"tr",align:null},"74,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"transfer_from_purse_to_account"),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"transfer_from_purse_to_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"82,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"transfer_to_account"),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"update_associated_key"),(0,l.kt)("td",{parentName:"tr",align:null},"4,200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"write"),(0,l.kt)("td",{parentName:"tr",align:null},"14,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 980]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"write_local"),(0,l.kt)("td",{parentName:"tr",align:null},"9,500"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 1,800, 0, 520]")))),(0,l.kt)("h2",{id:"protocol-operating-costs"},"Protocol Operating Costs"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"wasmless_transfer_cost"),(0,l.kt)("td",{parentName:"tr",align:null},"Default gas cost for a wasmless transfer."),(0,l.kt)("td",{parentName:"tr",align:null},"100,000,000")))),(0,l.kt)("h3",{id:"auction-system-contract-costs"},(0,l.kt)("inlineCode",{parentName:"h3"},"Auction")," System Contract Costs"),(0,l.kt)("p",null,"These are the costs of calling ",(0,l.kt)("inlineCode",{parentName:"p"},"auction")," system contract entrypoints."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Entrypoint"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_era_validators"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"get_era_validators")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_seigniorage_recipients"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"read_seigniorage_recipients")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"add_bid"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"add_bid")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"withdraw_bid"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"withdraw_bid")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"delegate"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"delegate")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"undelegate"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"undelegate")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"run_auction"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"run_auction")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"slash"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"slash")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"distribute"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"distribute")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"withdraw_delegator_reward"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"withdraw_delegator_reward")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"withdraw_validator_reward"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"withdraw_validator_reward")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_era_id"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"read_era_id")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"activate_bid"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"activate_bid")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"redelegate"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"redelegate")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")))),(0,l.kt)("h3",{id:"mint-system-contract-costs"},(0,l.kt)("inlineCode",{parentName:"h3"},"Mint")," System Contract Costs"),(0,l.kt)("p",null,"These are the costs of calling ",(0,l.kt)("inlineCode",{parentName:"p"},"mint")," system contract entrypoints."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Entrypoint"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"mint"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"mint")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"reduce_total_supply"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"reduce_total_supply")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"create"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"create")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"balance"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"balance")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"transfer"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"transfer")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_base_round_reward"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"read_base_round_reward")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"mint_into_existing_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"mint_into_existing_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")))),(0,l.kt)("h3",{id:"handle_payment-system-contract-costs"},(0,l.kt)("inlineCode",{parentName:"h3"},"Handle_Payment")," System Contract Costs"),(0,l.kt)("p",null,"These are the costs of calling entrypoints on the ",(0,l.kt)("inlineCode",{parentName:"p"},"handle_payment")," system contract."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Entrypoint"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_payment_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"get_payment_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"set_refund_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"set_refund_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_refund_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"get_refund_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"finalize_payment"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"finalize_payment")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")))),(0,l.kt)("h3",{id:"standard_payment-system-contract-costs"},(0,l.kt)("inlineCode",{parentName:"h3"},"Standard_Payment")," System Contract Costs"),(0,l.kt)("p",null,"These settings manage the costs of calling entrypoints on the ",(0,l.kt)("inlineCode",{parentName:"p"},"standard_payment")," system contract."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Entrypoint"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"pay"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"pay")," entrypoint and sending an amount to a payment purse."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")))))}s.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[2570],{3905:function(t,e,a){a.d(e,{Zo:function(){return m},kt:function(){return s}});var n=a(7294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),d=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},m=function(t){var e=d(t.components);return n.createElement(p.Provider,{value:e},t.children)},k="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},N=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,m=o(t,["components","mdxType","originalType","parentName"]),k=d(a),N=r,s=k["".concat(p,".").concat(N)]||k[N]||u[N]||l;return a?n.createElement(s,i(i({ref:e},m),{},{components:a})):n.createElement(s,i({ref:e},m))}));function s(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=N;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o[k]="string"==typeof t?t:r,i[1]=o;for(var d=2;dBr_Table OpCode Costs",id:"br_table-opcode-costs",level:2},{value:"External Function Costs",id:"external-function-costs",level:2},{value:"Protocol Operating Costs",id:"protocol-operating-costs",level:2},{value:"Auction System Contract Costs",id:"auction-system-contract-costs",level:3},{value:"Mint System Contract Costs",id:"mint-system-contract-costs",level:3},{value:"Handle_Payment System Contract Costs",id:"handle_payment-system-contract-costs",level:3},{value:"Standard_Payment System Contract Costs",id:"standard_payment-system-contract-costs",level:3}],u={toc:k},N="wrapper";function s(t){var e=t.components,a=(0,r.Z)(t,i);return(0,l.kt)(N,(0,n.Z)({},u,a,{components:e,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"opcode-costs-tables"},"OpCode Costs Tables"),(0,l.kt)("p",null,"The following tables outline the cost, in motes, for a given operation on Casper's Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated ",(0,l.kt)("inlineCode",{parentName:"p"},"chainspec.toml"),"."),(0,l.kt)("p",null,"More information on ",(0,l.kt)("inlineCode",{parentName:"p"},"chainspec"),"s for private networks can be found ",(0,l.kt)("a",{parentName:"p",href:"/operators/setup-network/chain-spec"},"here")),(0,l.kt)("admonition",{type:"note"},(0,l.kt)("p",{parentName:"admonition"},"All costs in this table are in ",(0,l.kt)("a",{parentName:"p",href:"/concepts/glossary/M/#motes"},"motes"),", not CSPR, and the corresponding chainspec is ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/53dd33865c2707c29284ccc0e8485f22ddd6fbe3/resources/production/chainspec.toml#L129"},"here"),".")),(0,l.kt)("h2",{id:"storage-costs"},"Storage Costs"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"gas_per_byte"),(0,l.kt)("td",{parentName:"tr",align:null},"Gas charged per byte stored in global state."),(0,l.kt)("td",{parentName:"tr",align:null},"630,000")))),(0,l.kt)("h2",{id:"opcode-costs"},"OpCode Costs"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"bit"),(0,l.kt)("td",{parentName:"tr",align:null},"Bit operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"300")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"add"),(0,l.kt)("td",{parentName:"tr",align:null},"Arithmetic add operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"210")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"mul"),(0,l.kt)("td",{parentName:"tr",align:null},"Mul operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"240")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"div"),(0,l.kt)("td",{parentName:"tr",align:null},"Div operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"320")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"load"),(0,l.kt)("td",{parentName:"tr",align:null},"Memory load operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"store"),(0,l.kt)("td",{parentName:"tr",align:null},"Memory store operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"4,700")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"const"),(0,l.kt)("td",{parentName:"tr",align:null},"Const store operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"110")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"local"),(0,l.kt)("td",{parentName:"tr",align:null},"Local operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"390")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"global"),(0,l.kt)("td",{parentName:"tr",align:null},"Global operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"390")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"integer_comparison"),(0,l.kt)("td",{parentName:"tr",align:null},"Integer operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"250")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"conversion"),(0,l.kt)("td",{parentName:"tr",align:null},"Conversion operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"420")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"unreachable"),(0,l.kt)("td",{parentName:"tr",align:null},"Unreachable operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"270")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"nop"),(0,l.kt)("td",{parentName:"tr",align:null},"Nop operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"200")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"current_memory"),(0,l.kt)("td",{parentName:"tr",align:null},"Get the current memory operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"290")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"grow_memory"),(0,l.kt)("td",{parentName:"tr",align:null},"Grow memory cost per page (64 kB)."),(0,l.kt)("td",{parentName:"tr",align:null},"240,000")))),(0,l.kt)("h2",{id:"control-flow-operation-costs"},"Control Flow Operation Costs"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"block"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"block")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"loop"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"loop")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"if"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"if")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"else"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"else")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"end"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"end")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"br"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"br")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"35_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"br_if"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"br_if")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"35,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"return"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"return")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"select"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"select")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"call"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"call")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"68_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"call_indirect"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"call_indirect")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"68,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"drop"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"drop")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")))),(0,l.kt)("h2",{id:"br_table-opcode-costs"},(0,l.kt)("inlineCode",{parentName:"h2"},"Br_Table")," OpCode Costs"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"cost"),(0,l.kt)("td",{parentName:"tr",align:null},"Fixed cost per ",(0,l.kt)("inlineCode",{parentName:"td"},"br_table")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"35,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"size_multiplier"),(0,l.kt)("td",{parentName:"tr",align:null},"Size of target labels in the ",(0,l.kt)("inlineCode",{parentName:"td"},"br_table")," opcode will be multiplied by ",(0,l.kt)("inlineCode",{parentName:"td"},"size_multiplier"),"."),(0,l.kt)("td",{parentName:"tr",align:null},"100")))),(0,l.kt)("h2",{id:"external-function-costs"},"External Function Costs"),(0,l.kt)("p",null,'The following costs are for low-level bindings for host-side ("external") functions. More information on the Casper external FFI can be found ',(0,l.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html"},"here"),"."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Host-Side Function"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"),(0,l.kt)("th",{parentName:"tr",align:null},"Arguments"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"add"),(0,l.kt)("td",{parentName:"tr",align:null},"5,800"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"add_associated_key"),(0,l.kt)("td",{parentName:"tr",align:null},"9,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"add_contract_version"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"blake2b"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"call_contract"),(0,l.kt)("td",{parentName:"tr",align:null},"4,500"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 420, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"call_versioned_contract"),(0,l.kt)("td",{parentName:"tr",align:null},"4,500"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 0, 0, 420, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"create_contract_package_at_hash"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"create_contract_user_group"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"create_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"disable_contract_version"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_balance"),(0,l.kt)("td",{parentName:"tr",align:null},"3,800"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_blocktime"),(0,l.kt)("td",{parentName:"tr",align:null},"330"),(0,l.kt)("td",{parentName:"tr",align:null},"[0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_caller"),(0,l.kt)("td",{parentName:"tr",align:null},"380"),(0,l.kt)("td",{parentName:"tr",align:null},"[0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_key"),(0,l.kt)("td",{parentName:"tr",align:null},"2,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 440, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_main_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"1,300"),(0,l.kt)("td",{parentName:"tr",align:null},"[0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_named_arg"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_named_arg_size"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_phase"),(0,l.kt)("td",{parentName:"tr",align:null},"710"),(0,l.kt)("td",{parentName:"tr",align:null},"[0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_system_contract"),(0,l.kt)("td",{parentName:"tr",align:null},"1,100"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"has_key"),(0,l.kt)("td",{parentName:"tr",align:null},"1,500"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 840]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"is_valid_uref"),(0,l.kt)("td",{parentName:"tr",align:null},"760"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"load_named_keys"),(0,l.kt)("td",{parentName:"tr",align:null},"42,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"new_uref"),(0,l.kt)("td",{parentName:"tr",align:null},"17,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 590]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"random_bytes"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"print"),(0,l.kt)("td",{parentName:"tr",align:null},"20,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 4,600]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"provision_contract_user_group_uref"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"put_key"),(0,l.kt)("td",{parentName:"tr",align:null},"38,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 1,100, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_host_buffer"),(0,l.kt)("td",{parentName:"tr",align:null},"3,500"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 310, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_value"),(0,l.kt)("td",{parentName:"tr",align:null},"6,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_value_local"),(0,l.kt)("td",{parentName:"tr",align:null},"5,500"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 590, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"remove_associated_key"),(0,l.kt)("td",{parentName:"tr",align:null},"4,200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"remove_contract_user_group"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"remove_contract_user_group_urefs"),(0,l.kt)("td",{parentName:"tr",align:null},"200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"remove_key"),(0,l.kt)("td",{parentName:"tr",align:null},"61,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 3,200]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ret"),(0,l.kt)("td",{parentName:"tr",align:null},"23,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 420,000]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"revert"),(0,l.kt)("td",{parentName:"tr",align:null},"500"),(0,l.kt)("td",{parentName:"tr",align:null},"[0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"set_action_threshold"),(0,l.kt)("td",{parentName:"tr",align:null},"74,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"transfer_from_purse_to_account"),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"transfer_from_purse_to_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"82,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"transfer_to_account"),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 0, 0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"update_associated_key"),(0,l.kt)("td",{parentName:"tr",align:null},"4,200"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"write"),(0,l.kt)("td",{parentName:"tr",align:null},"14,000"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 0, 0, 980]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"write_local"),(0,l.kt)("td",{parentName:"tr",align:null},"9,500"),(0,l.kt)("td",{parentName:"tr",align:null},"[0, 1,800, 0, 520]")))),(0,l.kt)("h2",{id:"protocol-operating-costs"},"Protocol Operating Costs"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"wasmless_transfer_cost"),(0,l.kt)("td",{parentName:"tr",align:null},"Default gas cost for a wasmless transfer."),(0,l.kt)("td",{parentName:"tr",align:null},"100,000,000")))),(0,l.kt)("h3",{id:"auction-system-contract-costs"},(0,l.kt)("inlineCode",{parentName:"h3"},"Auction")," System Contract Costs"),(0,l.kt)("p",null,"These are the costs of calling ",(0,l.kt)("inlineCode",{parentName:"p"},"auction")," system contract entrypoints."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Entrypoint"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_era_validators"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"get_era_validators")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_seigniorage_recipients"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"read_seigniorage_recipients")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"add_bid"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"add_bid")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"withdraw_bid"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"withdraw_bid")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"delegate"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"delegate")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"undelegate"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"undelegate")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"run_auction"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"run_auction")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"slash"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"slash")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"distribute"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"distribute")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"withdraw_delegator_reward"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"withdraw_delegator_reward")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"withdraw_validator_reward"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"withdraw_validator_reward")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_era_id"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"read_era_id")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"activate_bid"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"activate_bid")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"redelegate"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"redelegate")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")))),(0,l.kt)("h3",{id:"mint-system-contract-costs"},(0,l.kt)("inlineCode",{parentName:"h3"},"Mint")," System Contract Costs"),(0,l.kt)("p",null,"These are the costs of calling ",(0,l.kt)("inlineCode",{parentName:"p"},"mint")," system contract entrypoints."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Entrypoint"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"mint"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"mint")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"reduce_total_supply"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"reduce_total_supply")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"create"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"create")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"balance"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"balance")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"transfer"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"transfer")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_base_round_reward"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"read_base_round_reward")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"mint_into_existing_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"mint_into_existing_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2,500,000,000")))),(0,l.kt)("h3",{id:"handle_payment-system-contract-costs"},(0,l.kt)("inlineCode",{parentName:"h3"},"Handle_Payment")," System Contract Costs"),(0,l.kt)("p",null,"These are the costs of calling entrypoints on the ",(0,l.kt)("inlineCode",{parentName:"p"},"handle_payment")," system contract."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Entrypoint"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_payment_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"get_payment_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"set_refund_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"set_refund_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_refund_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"get_refund_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"finalize_payment"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"finalize_payment")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")))),(0,l.kt)("h3",{id:"standard_payment-system-contract-costs"},(0,l.kt)("inlineCode",{parentName:"h3"},"Standard_Payment")," System Contract Costs"),(0,l.kt)("p",null,"These settings manage the costs of calling entrypoints on the ",(0,l.kt)("inlineCode",{parentName:"p"},"standard_payment")," system contract."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Entrypoint"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Cost"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"pay"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"pay")," entrypoint and sending an amount to a payment purse."),(0,l.kt)("td",{parentName:"tr",align:null},"10,000")))))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5e4971e3.afb2f7d6.js b/assets/js/5e4971e3.3e632ba3.js similarity index 99% rename from assets/js/5e4971e3.afb2f7d6.js rename to assets/js/5e4971e3.3e632ba3.js index 9a37dc5ae9..bcc9afa4a1 100644 --- a/assets/js/5e4971e3.afb2f7d6.js +++ b/assets/js/5e4971e3.3e632ba3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3550],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},g=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(n),g=r,m=d["".concat(c,".").concat(g)]||d[g]||u[g]||i;return n?a.createElement(m,o(o({ref:t},p),{},{components:n})):a.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=g;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:r,o[1]=s;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},g=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(n),g=r,m=d["".concat(c,".").concat(g)]||d[g]||u[g]||i;return n?a.createElement(m,o(o({ref:t},p),{},{components:n})):a.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=g;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:r,o[1]=s;for(var l=2;l=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var c=a.createContext({}),l=function(e){var t=a.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,i=p(e,["components","mdxType","originalType","parentName"]),d=l(r),f=n,y=d["".concat(c,".").concat(f)]||d[f]||u[f]||o;return r?a.createElement(y,s(s({ref:t},i),{},{components:r})):a.createElement(y,s({ref:t},i))}));function y(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,s=new Array(o);s[0]=f;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[d]="string"==typeof e?e:n,s[1]=p;for(var l=2;l=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var c=a.createContext({}),l=function(e){var t=a.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,i=p(e,["components","mdxType","originalType","parentName"]),d=l(r),f=n,y=d["".concat(c,".").concat(f)]||d[f]||u[f]||o;return r?a.createElement(y,s(s({ref:t},i),{},{components:r})):a.createElement(y,s({ref:t},i))}));function y(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,s=new Array(o);s[0]=f;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[d]="string"==typeof e?e:n,s[1]=p;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),s=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=s(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),d=s(n),m=r,h=d["".concat(l,".").concat(m)]||d[m]||u[m]||o;return n?a.createElement(h,i(i({ref:t},c),{},{components:n})):a.createElement(h,i({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var p={};for(var l in t)hasOwnProperty.call(t,l)&&(p[l]=t[l]);p.originalType=e,p[d]="string"==typeof e?e:r,i[1]=p;for(var s=2;s=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),s=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=s(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),d=s(n),m=r,h=d["".concat(l,".").concat(m)]||d[m]||u[m]||o;return n?a.createElement(h,i(i({ref:t},c),{},{components:n})):a.createElement(h,i({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var p={};for(var l in t)hasOwnProperty.call(t,l)&&(p[l]=t[l]);p.originalType=e,p[d]="string"==typeof e?e:r,i[1]=p;for(var s=2;s=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(n),d=r,f=p["".concat(c,".").concat(d)]||p[d]||m[d]||i;return n?o.createElement(f,a(a({ref:t},u),{},{components:n})):o.createElement(f,a({ref:t},u))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:r,a[1]=s;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(n),d=r,f=p["".concat(c,".").concat(d)]||p[d]||m[d]||i;return n?o.createElement(f,a(a({ref:t},u),{},{components:n})):o.createElement(f,a({ref:t},u))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:r,a[1]=s;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),u=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,s=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),p=u(r),d=a,k=p["".concat(l,".").concat(d)]||p[d]||f[d]||s;return r?n.createElement(k,o(o({ref:t},c),{},{components:r})):n.createElement(k,o({ref:t},c))}));function k(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=r.length,o=new Array(s);o[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:a,o[1]=i;for(var u=2;u=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),u=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,s=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),p=u(r),d=a,k=p["".concat(l,".").concat(d)]||p[d]||f[d]||s;return r?n.createElement(k,o(o({ref:t},c),{},{components:r})):n.createElement(k,o({ref:t},c))}));function k(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=r.length,o=new Array(s);o[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:a,o[1]=i;for(var u=2;u=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=i.createContext({}),c=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},d=function(e){var t=c(e.components);return i.createElement(l.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},h=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),u=c(n),h=a,m=u["".concat(l,".").concat(h)]||u[h]||p[h]||o;return n?i.createElement(m,r(r({ref:t},d),{},{components:n})):i.createElement(m,r({ref:t},d))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,r[1]=s;for(var c=2;c=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=i.createContext({}),c=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},d=function(e){var t=c(e.components);return i.createElement(l.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},h=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),u=c(n),h=a,m=u["".concat(l,".").concat(h)]||u[h]||p[h]||o;return n?i.createElement(m,r(r({ref:t},d),{},{components:n})):i.createElement(m,r({ref:t},d))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,r[1]=s;for(var c=2;c=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var p=a.createContext({}),l=function(e){var t=a.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return a.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},y=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(r),y=n,g=u["".concat(p,".").concat(y)]||u[y]||f[y]||o;return r?a.createElement(g,s(s({ref:t},i),{},{components:r})):a.createElement(g,s({ref:t},i))}));function g(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:n,s[1]=c;for(var l=2;l=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var p=a.createContext({}),l=function(e){var t=a.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return a.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},y=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(r),y=n,g=u["".concat(p,".").concat(y)]||u[y]||f[y]||o;return r?a.createElement(g,s(s({ref:t},i),{},{components:r})):a.createElement(g,s({ref:t},i))}));function g(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:n,s[1]=c;for(var l=2;l=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var p=r.createContext({}),c=function(e){var n=r.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},d=function(e){var n=c(e.components);return r.createElement(p.Provider,{value:n},e.children)},i="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},m=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),i=c(t),m=a,f=i["".concat(p,".").concat(m)]||i[m]||u[m]||o;return t?r.createElement(f,s(s({ref:n},d),{},{components:t})):r.createElement(f,s({ref:n},d))}));function f(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var o=t.length,s=new Array(o);s[0]=m;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l[i]="string"==typeof e?e:a,s[1]=l;for(var c=2;c/rpc", http.DefaultClient)\n client := casper.NewRPCClient(handler)\n deployHash := "62972eddc6fdc03b7ec53e52f7da7e24f01add9a74d68e3e21d924051c43f126"\n deploy, err := client.GetDeploy(context.Background(), deployHash)\n if err != nil {\n return\n }\n fmt.Println(deploy.Deploy.Hash)\n}\n')),(0,o.kt)("h3",{id:"handle-the-deploy-processed-event"},"Handle the Deploy Processed Event"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'package main\n\nimport (\n "context"\n "log"\n\n "github.com/make-software/casper-go-sdk/sse"\n)\n\nfunc main() {\n client := sse.NewClient("https:///events/main")\n defer client.Stop()\n client.RegisterHandler(\n sse.DeployProcessedEventType,\n func(ctx context.Context, rawEvent sse.RawEvent) error {\n deploy, err := rawEvent.ParseAsDeployProcessedEvent()\n if err != nil {\n return err\n }\n log.Printf("Deploy hash: %s", deploy.DeployProcessed.DeployHash)\n return nil\n })\n lastEventID := 1234\n client.Start(context.TODO(), lastEventID)\n}\n')),(0,o.kt)("h3",{id:"sending-a-transfer"},"Sending a Transfer"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'package main\n\nimport (\n "context"\n "encoding/hex"\n "log"\n "math/big"\n "net/http"\n\n "github.com/make-software/casper-go-sdk/casper"\n "github.com/make-software/casper-go-sdk/types/clvalue"\n)\n\nfunc main() {\n accountPublicKey, err := casper.NewPublicKey("012488699f9a31e36ecf002675cd7186b48e6a735d10ec1b308587ca719937752c")\n if err != nil { return }\n amount := big.NewInt(100000000)\n session := casper.ExecutableDeployItem{\n ModuleBytes: &casper.ModuleBytes{\n ModuleBytes: hex.EncodeToString([]byte("")),\n Args: (&casper.Args{}).\n AddArgument("target", clvalue.NewCLByteArray(accountPublicKey.AccountHash().Bytes())).\n AddArgument("amount", *clvalue.NewCLUInt512(amount)),\n },\n }\n\n payment := casper.StandardPayment(amount)\n\n deployHeader := casper.DefaultHeader()\n deployHeader.Account = accountPublicKey\n deployHeader.ChainName = "casper-test"\n\n newDeploy, err := casper.MakeDeploy(deployHeader, payment, session)\n\n handler := casper.NewRPCHandler("https://:7777/rpc", http.DefaultClient)\n client := casper.NewRPCClient(handler)\n result, err := client.PutDeploy(context.Background(), *newDeploy)\n\n log.Println(result.DeployHash)\n}\n')))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[2388],{3905:function(e,n,t){t.d(n,{Zo:function(){return d},kt:function(){return f}});var r=t(7294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var p=r.createContext({}),c=function(e){var n=r.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},d=function(e){var n=c(e.components);return r.createElement(p.Provider,{value:n},e.children)},i="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},m=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),i=c(t),m=a,f=i["".concat(p,".").concat(m)]||i[m]||u[m]||o;return t?r.createElement(f,s(s({ref:n},d),{},{components:t})):r.createElement(f,s({ref:n},d))}));function f(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var o=t.length,s=new Array(o);s[0]=m;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l[i]="string"==typeof e?e:a,s[1]=l;for(var c=2;c/rpc", http.DefaultClient)\n client := casper.NewRPCClient(handler)\n deployHash := "62972eddc6fdc03b7ec53e52f7da7e24f01add9a74d68e3e21d924051c43f126"\n deploy, err := client.GetDeploy(context.Background(), deployHash)\n if err != nil {\n return\n }\n fmt.Println(deploy.Deploy.Hash)\n}\n')),(0,o.kt)("h3",{id:"handle-the-deploy-processed-event"},"Handle the Deploy Processed Event"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'package main\n\nimport (\n "context"\n "log"\n\n "github.com/make-software/casper-go-sdk/sse"\n)\n\nfunc main() {\n client := sse.NewClient("https:///events/main")\n defer client.Stop()\n client.RegisterHandler(\n sse.DeployProcessedEventType,\n func(ctx context.Context, rawEvent sse.RawEvent) error {\n deploy, err := rawEvent.ParseAsDeployProcessedEvent()\n if err != nil {\n return err\n }\n log.Printf("Deploy hash: %s", deploy.DeployProcessed.DeployHash)\n return nil\n })\n lastEventID := 1234\n client.Start(context.TODO(), lastEventID)\n}\n')),(0,o.kt)("h3",{id:"sending-a-transfer"},"Sending a Transfer"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'package main\n\nimport (\n "context"\n "encoding/hex"\n "log"\n "math/big"\n "net/http"\n\n "github.com/make-software/casper-go-sdk/casper"\n "github.com/make-software/casper-go-sdk/types/clvalue"\n)\n\nfunc main() {\n accountPublicKey, err := casper.NewPublicKey("012488699f9a31e36ecf002675cd7186b48e6a735d10ec1b308587ca719937752c")\n if err != nil { return }\n amount := big.NewInt(100000000)\n session := casper.ExecutableDeployItem{\n ModuleBytes: &casper.ModuleBytes{\n ModuleBytes: hex.EncodeToString([]byte("")),\n Args: (&casper.Args{}).\n AddArgument("target", clvalue.NewCLByteArray(accountPublicKey.AccountHash().Bytes())).\n AddArgument("amount", *clvalue.NewCLUInt512(amount)),\n },\n }\n\n payment := casper.StandardPayment(amount)\n\n deployHeader := casper.DefaultHeader()\n deployHeader.Account = accountPublicKey\n deployHeader.ChainName = "casper-test"\n\n newDeploy, err := casper.MakeDeploy(deployHeader, payment, session)\n\n handler := casper.NewRPCHandler("https://:7777/rpc", http.DefaultClient)\n client := casper.NewRPCClient(handler)\n result, err := client.PutDeploy(context.Background(), *newDeploy)\n\n log.Println(result.DeployHash)\n}\n')))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6faae04c.3f306220.js b/assets/js/6faae04c.fb16412d.js similarity index 99% rename from assets/js/6faae04c.3f306220.js rename to assets/js/6faae04c.fb16412d.js index e498163044..34cd4b0355 100644 --- a/assets/js/6faae04c.3f306220.js +++ b/assets/js/6faae04c.fb16412d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6986],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return h}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=p(n),m=r,h=d["".concat(l,".").concat(m)]||d[m]||u[m]||o;return n?a.createElement(h,s(s({ref:t},c),{},{components:n})):a.createElement(h,s({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[d]="string"==typeof e?e:r,s[1]=i;for(var p=2;p:7777 \\\n--amount 10000000000 \\\n--secret-key .pem \\\n--chain-name casper \\\n--target-account \\\n--payment-amount \n")),(0,o.kt)("p",null,"The payment amount varies based on the deploy and network ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),". For node version ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1"),", wasmless transfers cost 10^8 motes."),(0,o.kt)("h3",{id:"bulk-or-batched-wasm-transfer"},"Bulk or batched Wasm transfer"),(0,o.kt)("p",null,"Bulk or batched Wasm transfers allow you to apply some logic before or after the transfer. They also allow for conditional transfers. You may also use them if you are doing a series of transfers between multiple purses. Listed below are five methods for the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/index.html"},"Rust contract API"),", which can be used in session code to achieve batched Wasm transfer:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"transfer_to_account"),": Transfers amount of motes from the main purse of the account to the purse of a target account. If the target purse does not exist, the transfer process will create one. Can be called from session code only and not a contract as a contract doesn't have a main purse."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"transfer_to_public_key"),": Transfers amount of motes from the main purse of the caller\u2019s account to the main purse of the target. If the account referenced by the target does not exist, the transfer will create a new account. Can be called from session code only and not from a contract as a contract doesn't have a main purse."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"transfer_from_purse_to_purse"),": Transfers amount of motes from source purse to target purse. If the target does not exist, the transfer fails."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"transfer_from_purse_to_public_key"),": Transfers amount of motes from source to the main purse of target. If the account referenced by the target does not exist, the transfer will create it."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"transfer_from_purse_to_account"),": Transfers amount of motes from source purse to target account's purse. If the target account does not exist, the transfer creates a new account.")),(0,o.kt)("p",null,"For more information on how to write session code, see ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/writing-session-code"},"Writing Session Code"),". There are equivalent ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/e01b528db64f96fc1d3eac8b3b8e58e1337b398d/smart_contracts/contract_as/assembly/purse.ts#L135-L305"},"assembly script")," methods available. Alternatively, you can program directly against the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/e01b528db64f96fc1d3eac8b3b8e58e1337b398d/smart_contracts/contract/src/ext_ffi.rs#L283-L370"},"ext-FFI")," methods."),(0,o.kt)("h2",{id:"integrating-cspr"},"Integrating CSPR"),(0,o.kt)("p",null,"You can integrate with the ",(0,o.kt)("a",{parentName:"p",href:"/developers/json-rpc/"},"JSON-RPC API")," of a node on the Casper Mainnet. You can program directly against the RPC or if you prefer you can choose from the variety of SDK libraries that are available to use on a Casper network see ",(0,o.kt)("a",{parentName:"p",href:"/sdk"},"SDK Libraries"),". Casper also provides a stream server that gives you real-time information about a variety of events occurring on a node. Use of the stream is optional. You might want to use this feature as it notifies you of events instead of requiring you to ask periodically. For more information about various events, see ",(0,o.kt)("a",{parentName:"p",href:"/developers/dapps/monitor-and-consume-events"},"Monitoring and Consuming Events"),"."),(0,o.kt)("h2",{id:"testing-the-integration"},"Testing the Integration"),(0,o.kt)("p",null,"Our recommended testing mechanism is to have a test environment that points at the official Casper ",(0,o.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/"},"Testnet"),". Through this, you may run production like operations of your test exchange against the test environment. However, if you are not doing this and you just want to integrate with the ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live/"},"Mainnet"),", then you can do so with your own test accounts."),(0,o.kt)("p",null,"If you are not going to do a Testnet integration, then we suggest you create some additional test accounts and test the transactions on the Mainnet through your software prior to moving to the general public."),(0,o.kt)("h2",{id:"the-casper-protocol"},"The Casper Protocol"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Casper is integrated with BitGo for enterprise grade custody. If your exchange uses BitGo, support for Casper is available already."),(0,o.kt)("li",{parentName:"ul"},"Casper has an execution after consensus model, which means that transactions are executed after they are finalized. Transactions are not orphaned or uncle\u2019d on Casper and neither does chain reorganization happen on it. For more information on the execution process, see ",(0,o.kt)("a",{parentName:"li",href:"/concepts/design/casper-design#execution-semantics-head"},"Execution Semantics"),"."),(0,o.kt)("li",{parentName:"ul"},"Exchanges can check finality signatures. Validators send finality signatures after the finalized block is executed and global state is updated. The Casper node streams execution effects and finality signatures through an SSE architecture. For more information about various events, see ",(0,o.kt)("a",{parentName:"li",href:"/developers/dapps/monitor-and-consume-events"},"Monitoring and Consuming Events"),".")),(0,o.kt)("h2",{id:"staking-integration-for-exchanges"},"Staking Integration for Exchanges"),(0,o.kt)("p",null,"Exchanges seeking to integrate CSPR staking mechanisms will need to understand the processes of delegation, undelegation and redelegation through deploys on a Casper network. The following outlines the use of the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/casper-js-sdk/"},"JavaScript SDK")," to perform these actions, as well as parameters relating to staking. Further information about staking on a Casper network can be found ",(0,o.kt)("a",{parentName:"p",href:"/staking/"},"here"),"."),(0,o.kt)("h3",{id:"deploy-structures-and-parameters"},"Deploy Structures and Parameters"),(0,o.kt)("p",null,"Staking operations consists of two parts:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"/developers/cli/sending-deploys"},"Creating a deploy object")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"/developers/dapps/signing-a-deploy"},"Signing the deploy"))),(0,o.kt)("p",null,"The staking deploy requires the following information:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"The delegator's public key"),(0,o.kt)("li",{parentName:"ul"},"The validator's public key"),(0,o.kt)("li",{parentName:"ul"},"The new validator's public key (For redelegation only)"),(0,o.kt)("li",{parentName:"ul"},"The amount to be delegated"),(0,o.kt)("li",{parentName:"ul"},"The gas cost"),(0,o.kt)("li",{parentName:"ul"},"The auction manager contract's hash"),(0,o.kt)("li",{parentName:"ul"},"The appropriate entry point")),(0,o.kt)("p",null,"Casper provides a series of prebuilt Wasm files for use in these operations. They are provided for convenience, and you are free to create your own custom deploys. You can find them in our ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node"},"casper-node")," repository, in the following locations:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/delegate"},"Delegate")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/undelegate"},"Undelegate")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/redelegate"},"Redelegate"))),(0,o.kt)("h4",{id:"1-creating-a-deploy-object"},"1. Creating a deploy object"),(0,o.kt)("p",null,"To create a deploy using the JavaScript SDK, we will need ",(0,o.kt)("inlineCode",{parentName:"p"},"deployParams"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"session")," and a ",(0,o.kt)("inlineCode",{parentName:"p"},"payment"),"."),(0,o.kt)("p",null,"Deploy params is a ",(0,o.kt)("inlineCode",{parentName:"p"},"DeployUtil.DeployParams")," object created from the delegator's ",(0,o.kt)("inlineCode",{parentName:"p"},"publicKey")," and the network name as shown in the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { DeployUtil, CLPublicKey } from 'casper-js-sdk';\n\nconst deployParams = new DeployUtil.DeployParams(\n CLPublicKey.fromHex(publicKeyHex),\n network_name // 'testnet' | 'mainnet'\n);\n")),(0,o.kt)("p",null,"For creating a ",(0,o.kt)("inlineCode",{parentName:"p"},"session")," object, which is ",(0,o.kt)("inlineCode",{parentName:"p"},"DeployUtil.ExecutableDeployItem"),", we need"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"The ",(0,o.kt)("strong",{parentName:"li"},"delegator")," and ",(0,o.kt)("strong",{parentName:"li"},"validator's public keys")),(0,o.kt)("li",{parentName:"ul"},"The ",(0,o.kt)("strong",{parentName:"li"},"amount")," of tokens to delegate/undelegate/redelgate"),(0,o.kt)("li",{parentName:"ul"},"The ",(0,o.kt)("strong",{parentName:"li"},"auction manager contract's hash")),(0,o.kt)("li",{parentName:"ul"},"The ",(0,o.kt)("strong",{parentName:"li"},"entry point"))),(0,o.kt)("p",null,"First, create a variable ",(0,o.kt)("inlineCode",{parentName:"p"},"RuntimeArgs")," from the public keys and the amount. We will need to use it below in ",(0,o.kt)("inlineCode",{parentName:"p"},"session"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { RuntimeArgs, CLValueBuilder, CLPublicKey } from 'casper-js-sdk';\n\nconst args = RuntimeArgs.fromMap({\n delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),\n validator: CLPublicKey.fromHex(validatorPublicKeyHex),\n amount: CLValueBuilder.u512(amountMotes) // in motes\n});\n")),(0,o.kt)("p",null,"Second, create a ",(0,o.kt)("inlineCode",{parentName:"p"},"session")," parameter. It is a ",(0,o.kt)("inlineCode",{parentName:"p"},"Uint8Array")," consisting of the ",(0,o.kt)("inlineCode",{parentName:"p"},"auction manager contract's hash"),", the ",(0,o.kt)("inlineCode",{parentName:"p"},"entry points")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"runtime arguments"),", which we previously created."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"auction manager contract's hash")," will depend on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},"Mainnet"),(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},"Testnet"),(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2")))),(0,o.kt)("p",null,"Your ",(0,o.kt)("inlineCode",{parentName:"p"},"entry point")," will depend on which action you are performing, with the following three available:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"delegate")," - Initial delegation to a validator"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"undelegate")," - Undelegating tokens from a validator back to the delegator"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"redelegate")," - Redelegating tokens to a new validator")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { decodeBase16, DeployUtil } from 'casper-js-sdk';\n\nconst session = DeployUtil.ExecutableDeployItem.newStoredContractByHash(\n decodeBase16(auction_manager_contract_hash), // auction manager contract hash\n contractEntryPoint, // auction manager entry point\n args\n);\n")),(0,o.kt)("p",null,"To create the ",(0,o.kt)("inlineCode",{parentName:"p"},"payment")," parameter for the deploy, we need a deploy cost. The actual costs can be pulled from the network chainspec. Here is the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/release-1.4.8/resources/production/chainspec.toml"},(0,o.kt)("inlineCode",{parentName:"a"},"chainspec for version 1.4.8")),". You will need the chainspec for the network version you are using."),(0,o.kt)("p",null,"Use the ",(0,o.kt)("inlineCode",{parentName:"p"},"DeployUtil.standardPayment")," method for creating ",(0,o.kt)("inlineCode",{parentName:"p"},"payment"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { DeployUtil } from 'casper-js-sdk';\n\nconst payment = DeployUtil.standardPayment(deployCost);\n")),(0,o.kt)("p",null,"The last operation is creating the deploy:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { DeployUtil } from 'casper-js-sdk';\n\nDeployUtil.makeDeploy(deployParams, session, payment);\n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Redelegation"),", occurs the same way as delegation, but with the introduction of a third public_key."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { RuntimeArgs, CLPublicKey, CLValueBuilder } from 'casper-js-sdk';\n\nconst args = RuntimeArgs.fromMap({\n delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),\n validator: CLPublicKey.fromHex(validatorPublicKeyHex),\n new_validator: CLPublicKey.fromHex(redelegateValidatorPublicKeyHex),\n amount: CLValueBuilder.u512(amountMotes)\n})\n")),(0,o.kt)("h4",{id:"2a-sign-the-deploy-casper-signer"},"2a. Sign the deploy (Casper Signer)"),(0,o.kt)("p",null,"To get the signature, you will need to use ",(0,o.kt)("inlineCode",{parentName:"p"},"Signer.sign")," from the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/casper-js-sdk/"},"JavaScript SDK"),". It will return ",(0,o.kt)("inlineCode",{parentName:"p"},"Promise<{ deploy }>"),", which is the signed object."),(0,o.kt)("p",null,"Use ",(0,o.kt)("inlineCode",{parentName:"p"},"DeployUtil.deployFromJson")," to convert the result and sent it to network with:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { Signer, CasperServiceByJsonRPC, DeployUtil } from 'casper-js-sdk';\n\nconst casperService = new CasperServiceByJsonRPC(GRPC_URL);\nconst deployJson = DeployUtil.deployToJson(deploy);\nSigner.sign(\n deployJson,\n accountPublicKey,\n recipientPublicKey\n).then((signedDeployJson) => {\n const signedDeploy = DeployUtil.deployFromJson(signedDeployJson);\n if (signedDeploy.ok) {\n casperService.deploy(signedDeploy.val! as DeployUtil.Deploy); // sent deploy\n }\n}\n")),(0,o.kt)("h4",{id:"2b-sign-the-deploy-ledger"},"2b. Sign the deploy (Ledger)"),(0,o.kt)("p",null,"You will need to connect with your ",(0,o.kt)("inlineCode",{parentName:"p"},"Ledger")," first to get the signature."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import TransportWebUSB from '@ledgerhq/hw-transport-webusb';\nimport LedgerApp, { ResponseBase } from '@zondax/ledger-casper';\nimport { DeployUtil } from 'casper-js-sdk';\n\nconst getBipPath = (index: number) => {\n const idx = index.toString();\n return `m/44'/506'/0'/0/${idx}`;\n};\n\nconst deployBytes = DeployUtil.deployToBytes(deploy) as Buffer;\nconst transport = await TransportWebUSB.create();\nconst ledgerApp = new LedgerApp(transport);\nconst res = await ledgerApp.sign(\n getBipPath(selectedAccountIndex),\n deployBytes\n);\n")),(0,o.kt)("p",null,"The Signature will be in a property called ",(0,o.kt)("inlineCode",{parentName:"p"},"res.signatureRS"),"."),(0,o.kt)("p",null,"After that, we can create a signed deploy,"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { DeployUtil, CLPublicKey } from 'casper-js-sdk';\n\nconst signedDeploy = DeployUtil.setSignature(\n deploy,\n signatureRS,\n CLPublicKey.fromHex(accountPublicKey)\n);\n")),(0,o.kt)("p",null,"We can then send it to a network."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"casperService.deploy(signedDeploy)\n")),(0,o.kt)("h3",{id:"costs-and-minimums"},"Costs and Minimums"),(0,o.kt)("p",null,"The following are costs and minimum amounts for version 1.5.1, but up-to-date values should be pulled from the network ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),"."),(0,o.kt)("p",null,"Transfer Cost: 100,000,000 motes or 0.1 ",(0,o.kt)("strong",{parentName:"p"},"CSPR")),(0,o.kt)("p",null,"Delegation Cost: 2,500,000,000 motes or 2.5 ",(0,o.kt)("strong",{parentName:"p"},"CSPR")),(0,o.kt)("p",null,"Minimum transfer amount: 2,500,000,000 motes, or 2.5 ",(0,o.kt)("strong",{parentName:"p"},"CSPR")),(0,o.kt)("p",null,"Minimum amount required for delegation: 500,000,000,000 motes, or 500 ",(0,o.kt)("strong",{parentName:"p"},"CSPR"),"."),(0,o.kt)("h3",{id:"the-delegation-cap"},"The Delegation Cap"),(0,o.kt)("p",null,"Casper includes a delegator limit rule, which limits the number of delegators that a single validator may have at ",(0,o.kt)("inlineCode",{parentName:"p"},"953"),". This is a temporary solution to prevent complications with Casper\u2019s fast sync mechanism - in which high bond counts could break fast sync."),(0,o.kt)("p",null,"Validators with a delegator count at or above ",(0,o.kt)("inlineCode",{parentName:"p"},"953")," at the time of the ",(0,o.kt)("strong",{parentName:"p"},"1.4.5")," upgrade were grandfathered in, however new delegators will not be able to delegate to any validator until the delegator count for that validator falls below ",(0,o.kt)("inlineCode",{parentName:"p"},"953"),"."),(0,o.kt)("p",null,"Existing delegators may continue to delegate additional CSPR, regardless of the current number of delegators staking their ",(0,o.kt)("strong",{parentName:"p"},"CSPR")," to that validator. However, no new delegators may join the validator until it drops below the ",(0,o.kt)("inlineCode",{parentName:"p"},"953")," limit."))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6986],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return h}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=p(n),m=r,h=d["".concat(l,".").concat(m)]||d[m]||u[m]||o;return n?a.createElement(h,s(s({ref:t},c),{},{components:n})):a.createElement(h,s({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[d]="string"==typeof e?e:r,s[1]=i;for(var p=2;p:7777 \\\n--amount 10000000000 \\\n--secret-key .pem \\\n--chain-name casper \\\n--target-account \\\n--payment-amount \n")),(0,o.kt)("p",null,"The payment amount varies based on the deploy and network ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),". For node version ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1"),", wasmless transfers cost 10^8 motes."),(0,o.kt)("h3",{id:"bulk-or-batched-wasm-transfer"},"Bulk or batched Wasm transfer"),(0,o.kt)("p",null,"Bulk or batched Wasm transfers allow you to apply some logic before or after the transfer. They also allow for conditional transfers. You may also use them if you are doing a series of transfers between multiple purses. Listed below are five methods for the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/index.html"},"Rust contract API"),", which can be used in session code to achieve batched Wasm transfer:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"transfer_to_account"),": Transfers amount of motes from the main purse of the account to the purse of a target account. If the target purse does not exist, the transfer process will create one. Can be called from session code only and not a contract as a contract doesn't have a main purse."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"transfer_to_public_key"),": Transfers amount of motes from the main purse of the caller\u2019s account to the main purse of the target. If the account referenced by the target does not exist, the transfer will create a new account. Can be called from session code only and not from a contract as a contract doesn't have a main purse."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"transfer_from_purse_to_purse"),": Transfers amount of motes from source purse to target purse. If the target does not exist, the transfer fails."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"transfer_from_purse_to_public_key"),": Transfers amount of motes from source to the main purse of target. If the account referenced by the target does not exist, the transfer will create it."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"transfer_from_purse_to_account"),": Transfers amount of motes from source purse to target account's purse. If the target account does not exist, the transfer creates a new account.")),(0,o.kt)("p",null,"For more information on how to write session code, see ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/writing-session-code"},"Writing Session Code"),". There are equivalent ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/e01b528db64f96fc1d3eac8b3b8e58e1337b398d/smart_contracts/contract_as/assembly/purse.ts#L135-L305"},"assembly script")," methods available. Alternatively, you can program directly against the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/e01b528db64f96fc1d3eac8b3b8e58e1337b398d/smart_contracts/contract/src/ext_ffi.rs#L283-L370"},"ext-FFI")," methods."),(0,o.kt)("h2",{id:"integrating-cspr"},"Integrating CSPR"),(0,o.kt)("p",null,"You can integrate with the ",(0,o.kt)("a",{parentName:"p",href:"/developers/json-rpc/"},"JSON-RPC API")," of a node on the Casper Mainnet. You can program directly against the RPC or if you prefer you can choose from the variety of SDK libraries that are available to use on a Casper network see ",(0,o.kt)("a",{parentName:"p",href:"/sdk"},"SDK Libraries"),". Casper also provides a stream server that gives you real-time information about a variety of events occurring on a node. Use of the stream is optional. You might want to use this feature as it notifies you of events instead of requiring you to ask periodically. For more information about various events, see ",(0,o.kt)("a",{parentName:"p",href:"/developers/dapps/monitor-and-consume-events"},"Monitoring and Consuming Events"),"."),(0,o.kt)("h2",{id:"testing-the-integration"},"Testing the Integration"),(0,o.kt)("p",null,"Our recommended testing mechanism is to have a test environment that points at the official Casper ",(0,o.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/"},"Testnet"),". Through this, you may run production like operations of your test exchange against the test environment. However, if you are not doing this and you just want to integrate with the ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live/"},"Mainnet"),", then you can do so with your own test accounts."),(0,o.kt)("p",null,"If you are not going to do a Testnet integration, then we suggest you create some additional test accounts and test the transactions on the Mainnet through your software prior to moving to the general public."),(0,o.kt)("h2",{id:"the-casper-protocol"},"The Casper Protocol"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Casper is integrated with BitGo for enterprise grade custody. If your exchange uses BitGo, support for Casper is available already."),(0,o.kt)("li",{parentName:"ul"},"Casper has an execution after consensus model, which means that transactions are executed after they are finalized. Transactions are not orphaned or uncle\u2019d on Casper and neither does chain reorganization happen on it. For more information on the execution process, see ",(0,o.kt)("a",{parentName:"li",href:"/concepts/design/casper-design#execution-semantics-head"},"Execution Semantics"),"."),(0,o.kt)("li",{parentName:"ul"},"Exchanges can check finality signatures. Validators send finality signatures after the finalized block is executed and global state is updated. The Casper node streams execution effects and finality signatures through an SSE architecture. For more information about various events, see ",(0,o.kt)("a",{parentName:"li",href:"/developers/dapps/monitor-and-consume-events"},"Monitoring and Consuming Events"),".")),(0,o.kt)("h2",{id:"staking-integration-for-exchanges"},"Staking Integration for Exchanges"),(0,o.kt)("p",null,"Exchanges seeking to integrate CSPR staking mechanisms will need to understand the processes of delegation, undelegation and redelegation through deploys on a Casper network. The following outlines the use of the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/casper-js-sdk/"},"JavaScript SDK")," to perform these actions, as well as parameters relating to staking. Further information about staking on a Casper network can be found ",(0,o.kt)("a",{parentName:"p",href:"/staking/"},"here"),"."),(0,o.kt)("h3",{id:"deploy-structures-and-parameters"},"Deploy Structures and Parameters"),(0,o.kt)("p",null,"Staking operations consists of two parts:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"/developers/cli/sending-deploys"},"Creating a deploy object")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"/developers/dapps/signing-a-deploy"},"Signing the deploy"))),(0,o.kt)("p",null,"The staking deploy requires the following information:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"The delegator's public key"),(0,o.kt)("li",{parentName:"ul"},"The validator's public key"),(0,o.kt)("li",{parentName:"ul"},"The new validator's public key (For redelegation only)"),(0,o.kt)("li",{parentName:"ul"},"The amount to be delegated"),(0,o.kt)("li",{parentName:"ul"},"The gas cost"),(0,o.kt)("li",{parentName:"ul"},"The auction manager contract's hash"),(0,o.kt)("li",{parentName:"ul"},"The appropriate entry point")),(0,o.kt)("p",null,"Casper provides a series of prebuilt Wasm files for use in these operations. They are provided for convenience, and you are free to create your own custom deploys. You can find them in our ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node"},"casper-node")," repository, in the following locations:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/delegate"},"Delegate")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/undelegate"},"Undelegate")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/redelegate"},"Redelegate"))),(0,o.kt)("h4",{id:"1-creating-a-deploy-object"},"1. Creating a deploy object"),(0,o.kt)("p",null,"To create a deploy using the JavaScript SDK, we will need ",(0,o.kt)("inlineCode",{parentName:"p"},"deployParams"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"session")," and a ",(0,o.kt)("inlineCode",{parentName:"p"},"payment"),"."),(0,o.kt)("p",null,"Deploy params is a ",(0,o.kt)("inlineCode",{parentName:"p"},"DeployUtil.DeployParams")," object created from the delegator's ",(0,o.kt)("inlineCode",{parentName:"p"},"publicKey")," and the network name as shown in the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { DeployUtil, CLPublicKey } from 'casper-js-sdk';\n\nconst deployParams = new DeployUtil.DeployParams(\n CLPublicKey.fromHex(publicKeyHex),\n network_name // 'testnet' | 'mainnet'\n);\n")),(0,o.kt)("p",null,"For creating a ",(0,o.kt)("inlineCode",{parentName:"p"},"session")," object, which is ",(0,o.kt)("inlineCode",{parentName:"p"},"DeployUtil.ExecutableDeployItem"),", we need"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"The ",(0,o.kt)("strong",{parentName:"li"},"delegator")," and ",(0,o.kt)("strong",{parentName:"li"},"validator's public keys")),(0,o.kt)("li",{parentName:"ul"},"The ",(0,o.kt)("strong",{parentName:"li"},"amount")," of tokens to delegate/undelegate/redelgate"),(0,o.kt)("li",{parentName:"ul"},"The ",(0,o.kt)("strong",{parentName:"li"},"auction manager contract's hash")),(0,o.kt)("li",{parentName:"ul"},"The ",(0,o.kt)("strong",{parentName:"li"},"entry point"))),(0,o.kt)("p",null,"First, create a variable ",(0,o.kt)("inlineCode",{parentName:"p"},"RuntimeArgs")," from the public keys and the amount. We will need to use it below in ",(0,o.kt)("inlineCode",{parentName:"p"},"session"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { RuntimeArgs, CLValueBuilder, CLPublicKey } from 'casper-js-sdk';\n\nconst args = RuntimeArgs.fromMap({\n delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),\n validator: CLPublicKey.fromHex(validatorPublicKeyHex),\n amount: CLValueBuilder.u512(amountMotes) // in motes\n});\n")),(0,o.kt)("p",null,"Second, create a ",(0,o.kt)("inlineCode",{parentName:"p"},"session")," parameter. It is a ",(0,o.kt)("inlineCode",{parentName:"p"},"Uint8Array")," consisting of the ",(0,o.kt)("inlineCode",{parentName:"p"},"auction manager contract's hash"),", the ",(0,o.kt)("inlineCode",{parentName:"p"},"entry points")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"runtime arguments"),", which we previously created."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"auction manager contract's hash")," will depend on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},"Mainnet"),(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},"Testnet"),(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2")))),(0,o.kt)("p",null,"Your ",(0,o.kt)("inlineCode",{parentName:"p"},"entry point")," will depend on which action you are performing, with the following three available:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"delegate")," - Initial delegation to a validator"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"undelegate")," - Undelegating tokens from a validator back to the delegator"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"redelegate")," - Redelegating tokens to a new validator")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { decodeBase16, DeployUtil } from 'casper-js-sdk';\n\nconst session = DeployUtil.ExecutableDeployItem.newStoredContractByHash(\n decodeBase16(auction_manager_contract_hash), // auction manager contract hash\n contractEntryPoint, // auction manager entry point\n args\n);\n")),(0,o.kt)("p",null,"To create the ",(0,o.kt)("inlineCode",{parentName:"p"},"payment")," parameter for the deploy, we need a deploy cost. The actual costs can be pulled from the network chainspec. Here is the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/release-1.4.8/resources/production/chainspec.toml"},(0,o.kt)("inlineCode",{parentName:"a"},"chainspec for version 1.4.8")),". You will need the chainspec for the network version you are using."),(0,o.kt)("p",null,"Use the ",(0,o.kt)("inlineCode",{parentName:"p"},"DeployUtil.standardPayment")," method for creating ",(0,o.kt)("inlineCode",{parentName:"p"},"payment"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { DeployUtil } from 'casper-js-sdk';\n\nconst payment = DeployUtil.standardPayment(deployCost);\n")),(0,o.kt)("p",null,"The last operation is creating the deploy:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { DeployUtil } from 'casper-js-sdk';\n\nDeployUtil.makeDeploy(deployParams, session, payment);\n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Redelegation"),", occurs the same way as delegation, but with the introduction of a third public_key."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { RuntimeArgs, CLPublicKey, CLValueBuilder } from 'casper-js-sdk';\n\nconst args = RuntimeArgs.fromMap({\n delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),\n validator: CLPublicKey.fromHex(validatorPublicKeyHex),\n new_validator: CLPublicKey.fromHex(redelegateValidatorPublicKeyHex),\n amount: CLValueBuilder.u512(amountMotes)\n})\n")),(0,o.kt)("h4",{id:"2a-sign-the-deploy-casper-signer"},"2a. Sign the deploy (Casper Signer)"),(0,o.kt)("p",null,"To get the signature, you will need to use ",(0,o.kt)("inlineCode",{parentName:"p"},"Signer.sign")," from the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/casper-js-sdk/"},"JavaScript SDK"),". It will return ",(0,o.kt)("inlineCode",{parentName:"p"},"Promise<{ deploy }>"),", which is the signed object."),(0,o.kt)("p",null,"Use ",(0,o.kt)("inlineCode",{parentName:"p"},"DeployUtil.deployFromJson")," to convert the result and sent it to network with:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { Signer, CasperServiceByJsonRPC, DeployUtil } from 'casper-js-sdk';\n\nconst casperService = new CasperServiceByJsonRPC(GRPC_URL);\nconst deployJson = DeployUtil.deployToJson(deploy);\nSigner.sign(\n deployJson,\n accountPublicKey,\n recipientPublicKey\n).then((signedDeployJson) => {\n const signedDeploy = DeployUtil.deployFromJson(signedDeployJson);\n if (signedDeploy.ok) {\n casperService.deploy(signedDeploy.val! as DeployUtil.Deploy); // sent deploy\n }\n}\n")),(0,o.kt)("h4",{id:"2b-sign-the-deploy-ledger"},"2b. Sign the deploy (Ledger)"),(0,o.kt)("p",null,"You will need to connect with your ",(0,o.kt)("inlineCode",{parentName:"p"},"Ledger")," first to get the signature."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import TransportWebUSB from '@ledgerhq/hw-transport-webusb';\nimport LedgerApp, { ResponseBase } from '@zondax/ledger-casper';\nimport { DeployUtil } from 'casper-js-sdk';\n\nconst getBipPath = (index: number) => {\n const idx = index.toString();\n return `m/44'/506'/0'/0/${idx}`;\n};\n\nconst deployBytes = DeployUtil.deployToBytes(deploy) as Buffer;\nconst transport = await TransportWebUSB.create();\nconst ledgerApp = new LedgerApp(transport);\nconst res = await ledgerApp.sign(\n getBipPath(selectedAccountIndex),\n deployBytes\n);\n")),(0,o.kt)("p",null,"The Signature will be in a property called ",(0,o.kt)("inlineCode",{parentName:"p"},"res.signatureRS"),"."),(0,o.kt)("p",null,"After that, we can create a signed deploy,"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import { DeployUtil, CLPublicKey } from 'casper-js-sdk';\n\nconst signedDeploy = DeployUtil.setSignature(\n deploy,\n signatureRS,\n CLPublicKey.fromHex(accountPublicKey)\n);\n")),(0,o.kt)("p",null,"We can then send it to a network."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"casperService.deploy(signedDeploy)\n")),(0,o.kt)("h3",{id:"costs-and-minimums"},"Costs and Minimums"),(0,o.kt)("p",null,"The following are costs and minimum amounts for version 1.5.1, but up-to-date values should be pulled from the network ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),"."),(0,o.kt)("p",null,"Transfer Cost: 100,000,000 motes or 0.1 ",(0,o.kt)("strong",{parentName:"p"},"CSPR")),(0,o.kt)("p",null,"Delegation Cost: 2,500,000,000 motes or 2.5 ",(0,o.kt)("strong",{parentName:"p"},"CSPR")),(0,o.kt)("p",null,"Minimum transfer amount: 2,500,000,000 motes, or 2.5 ",(0,o.kt)("strong",{parentName:"p"},"CSPR")),(0,o.kt)("p",null,"Minimum amount required for delegation: 500,000,000,000 motes, or 500 ",(0,o.kt)("strong",{parentName:"p"},"CSPR"),"."),(0,o.kt)("h3",{id:"the-delegation-cap"},"The Delegation Cap"),(0,o.kt)("p",null,"Casper includes a delegator limit rule, which limits the number of delegators that a single validator may have at ",(0,o.kt)("inlineCode",{parentName:"p"},"953"),". This is a temporary solution to prevent complications with Casper\u2019s fast sync mechanism - in which high bond counts could break fast sync."),(0,o.kt)("p",null,"Validators with a delegator count at or above ",(0,o.kt)("inlineCode",{parentName:"p"},"953")," at the time of the ",(0,o.kt)("strong",{parentName:"p"},"1.4.5")," upgrade were grandfathered in, however new delegators will not be able to delegate to any validator until the delegator count for that validator falls below ",(0,o.kt)("inlineCode",{parentName:"p"},"953"),"."),(0,o.kt)("p",null,"Existing delegators may continue to delegate additional CSPR, regardless of the current number of delegators staking their ",(0,o.kt)("strong",{parentName:"p"},"CSPR")," to that validator. However, no new delegators may join the validator until it drops below the ",(0,o.kt)("inlineCode",{parentName:"p"},"953")," limit."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6fc855ed.1d44d10a.js b/assets/js/6fc855ed.0b153bd6.js similarity index 99% rename from assets/js/6fc855ed.1d44d10a.js rename to assets/js/6fc855ed.0b153bd6.js index bcbf8f0d15..b335821f37 100644 --- a/assets/js/6fc855ed.1d44d10a.js +++ b/assets/js/6fc855ed.0b153bd6.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[1263],{3905:function(e,t,r){r.d(t,{Zo:function(){return p},kt:function(){return k}});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},g="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),g=c(r),d=a,k=g["".concat(s,".").concat(d)]||g[d]||u[d]||i;return r?n.createElement(k,l(l({ref:t},p),{},{components:r})):n.createElement(k,l({ref:t},p))}));function k(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,l=new Array(i);l[0]=d;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[g]="string"==typeof e?e:a,l[1]=o;for(var c=2;c=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},g="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),g=c(r),d=a,k=g["".concat(s,".").concat(d)]||g[d]||u[d]||i;return r?n.createElement(k,l(l({ref:t},p),{},{components:r})):n.createElement(k,l({ref:t},p))}));function k(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,l=new Array(i);l[0]=d;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[g]="string"==typeof e?e:a,l[1]=o;for(var c=2;c=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=a.createContext({}),d=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},l=function(e){var t=d(e.components);return a.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),p=d(n),h=i,y=p["".concat(c,".").concat(h)]||p[h]||u[h]||r;return n?a.createElement(y,o(o({ref:t},l),{},{components:n})):a.createElement(y,o({ref:t},l))}));function y(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:i,o[1]=s;for(var d=2;dContractNamedKey lookup via a Contract's named keys.",id:"contractnamedkey-lookup-via-a-contracts-named-keys",level:3},{value:"URef lookup via the dictionary's seed URef.",id:"uref-lookup-via-the-dictionarys-seed-uref",level:3},{value:"Dictionary lookup via the unique dictionary item key.",id:"dictionary-lookup-via-the-unique-dictionary-item-key",level:3}],u={toc:p},h="wrapper";function y(e){var t=e.components,n=(0,i.Z)(e,o);return(0,r.kt)(h,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"dictionaries"},"Understanding Dictionaries"),(0,r.kt)("p",null,"In a Casper network, you can now store sets of data under ",(0,r.kt)("a",{parentName:"p",href:"/concepts/hash-types#hash-and-key-explanations"},(0,r.kt)("inlineCode",{parentName:"a"},"Keys")),". Previously, ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/U#uref"},"URefs")," were the exclusive means by which users could store data in global state. To maintain persistent access to these URefs, they would have to be stored within an ",(0,r.kt)("inlineCode",{parentName:"p"},"Account")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"Contract")," context. In the case of Contracts, sustained and continuous use of URefs would result in the expansion of the associated ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/N#namedkeys"},"NamedKeys")," structures."),(0,r.kt)("p",null,"Individual value changes to data stored within the NamedKeys would require deserializing the entire NamedKeys data structure, increasing gas costs over time and thus having a negative impact. Additionally, users storing large subsets of mapped data structures would face the same deep copy problem where minor or single updates required the complete deserialization of the map structure, also leading to increased gas costs."),(0,r.kt)("p",null,"As a solution to this problem, the Casper platform provides the ",(0,r.kt)("inlineCode",{parentName:"p"},"Dictionary")," feature, which allows users a more efficient and scalable means to aggregate data over time."),(0,r.kt)("p",null,"In almost all cases, dictionaries are the better form of data storage. They allow greater flexibility in altering stored data at a lower cost."),(0,r.kt)("h2",{id:"seed-urefs"},"Seed URefs"),(0,r.kt)("p",null,"Items within a dictionary exist as individual records stored underneath their unique ",(0,r.kt)("a",{parentName:"p",href:"/concepts/hash-types#hash-and-key-explanations"},"dictionary address")," in global state. In other words, items associated with a specific dictionary share the same seed ",(0,r.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#uref-head"},(0,r.kt)("inlineCode",{parentName:"a"},"URef"))," but are otherwise independent of each other. Dictionary items are not stored beneath this URef, it is only used to create the dictionary key."),(0,r.kt)("p",null,"As each dictionary item exists as a stand-alone entity in global state, regularly used dictionary keys may be used directly without referencing their seed URef."),(0,r.kt)("h2",{id:"using-dictionaries"},"Using Dictionaries"),(0,r.kt)("p",null,"Dictionaries are ideal for storing larger volumes of data for which ",(0,r.kt)("inlineCode",{parentName:"p"},"NamedKeys")," would be less suitable."),(0,r.kt)("p",null,"Creating a new dictionary is fairly simple and done within the context of a ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," sent to a Casper network. The associated code is included within the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/"},(0,r.kt)("inlineCode",{parentName:"a"},"casper_contract"))," crate. Creating a dictionary also stores the associated seed URef within the named keys of the current context."),(0,r.kt)("p",null,"Developers should always consider context when creating dictionaries. We recommend creating a dictionary within the context of a Contract."),(0,r.kt)("p",null,"While you can create a dictionary in the context of an Account and then pass associated access rights to a Contract, this approach can create potential security issues. If a third party uses the Contract, the initiating Account with access rights to the dictionary may be undesirable. To rectify this, you may send an additional ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," removing those access rights, but it is better to create the dictionary within the context of the Contract."),(0,r.kt)("p",null,"Dictionaries allow a contract to store additional data without drastically expanding the size of the ",(0,r.kt)("inlineCode",{parentName:"p"},"NamedKeys")," within their context. If a contract's ",(0,r.kt)("inlineCode",{parentName:"p"},"NamedKeys")," expand too far, they may run into system limitations that would unintentionally disable the contract's functionality."),(0,r.kt)("p",null,"A dictionary item key can be no longer than 64 bytes in length."),(0,r.kt)("h2",{id:"practical-dictionary-examples"},"Practical Dictionary Examples"),(0,r.kt)("p",null,"The ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft"},"Casper CEP-78 Enhanced NFT Standard")," includes several practical applications of dictionaries."),(0,r.kt)("p",null,"Simple examples for dictionary use within CEP-78 include the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs#L772"},(0,r.kt)("inlineCode",{parentName:"a"},"approve"))," dictionary."),(0,r.kt)("p",null,"More advanced dictionary functionality can be found in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft#the-cep-78-page-system"},"CEP-78 Page System"),", which uses a series of dictionaries to keep track of token ownership. These dictionaries form the basis of the reverse lookup mode, which allows users to easily view a list of owned tokens by account or contract."),(0,r.kt)("h2",{id:"creating-dictionaries-in-a-contracts-context"},"Creating Dictionaries in a Contract's Context"),(0,r.kt)("p",null,"The following code snippet shows the most basic example of creating a dictionary."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-rust"},"\ncasper_contract::contract_api::storage::new_dictionary(dict_name)\n\n")),(0,r.kt)("p",null,"The following example includes the creation of a dictionary ",(0,r.kt)("inlineCode",{parentName:"p"},'"ledger"')," within a contract's context. In this instance, the dictionary will be used to track donations made to a fundraising purse also created by the ",(0,r.kt)("inlineCode",{parentName:"p"},"init")," entry point. In any case where you want to use a dictionary within your contract, it should be set up within the initializing entry point."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-rust"},'\n#[no_mangle]\npub extern "C" fn init() {\n let fundraising_purse = system::create_purse();\n runtime::put_key("fundraising_purse", fundraising_purse.into());\n // Create a dictionary to track the mapping of account hashes to number of donations made.\n storage::new_dictionary("ledger").unwrap_or_revert();\n}\n\n')),(0,r.kt)("h2",{id:"writing-entries-into-a-dictionary"},"Writing Entries into a Dictionary"),(0,r.kt)("p",null,"After the creation of a dictionary, you may then add entries through the use of the following code:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-rust"},"\nstorage::dictionary_put(dictionary_uref, &dictionary_item_key, value);\n\n")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"dictionary_uref")," refers to the seed URef established during the dictionary creation process. The ",(0,r.kt)("inlineCode",{parentName:"p"},"key")," is the unique identifier for this dictionary item, and the ",(0,r.kt)("inlineCode",{parentName:"p"},"value")," is the data to be stored within the dictionary."),(0,r.kt)("p",null,"As stated above, these dictionary items do not require the seed URef, and they exist as individual keys in global state. If you know an individual key's address, you do not need to go through the process of identifying the seed URef first."),(0,r.kt)("p",null,"The following function serves to add an entry to the dictionary. If the item already exists, the entry point will update the value stored and referenced by that key. In this case, the code is storing the number of donations made. Any Rust structure may be stored under a dictionary item, but when updating a value within a larger structure (i.e., a list), the entire structure will be overwritten as part of the update. Updating a larger structure will incur the full cost of writing the structure to a dictionary item."),(0,r.kt)("p",null,"The first section acquiring the ",(0,r.kt)("inlineCode",{parentName:"p"},"LEDGER")," seed URef to assign the new dictionary item to the proper dictionary."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-rust"},'\nfn update_ledger_record(dictionary_item_key: String) {\n // Acquiring the LEDGER seed URef to properly assign the dictionary item.\n let ledger_seed_uref = *runtime::get_key("ledger")\n .unwrap_or_revert_with(FundRaisingError::MissingLedgerSeedURef)\n .as_uref()\n .unwrap_or_revert();\n\n')),(0,r.kt)("p",null,"The second section uses ",(0,r.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_get.html"},(0,r.kt)("inlineCode",{parentName:"a"},"dictionary_get"))," to read an entry within the ",(0,r.kt)("inlineCode",{parentName:"p"},"LEDGER")," dictionary. If the entry does not exist on global state, it will create the entry. If it already exists, the entry is updated with the current value using a ",(0,r.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_put.html"},(0,r.kt)("inlineCode",{parentName:"a"},"dictionary_put"))," operation. As stated above, regardless of the size of the change within the entry, the entire dictionary entry will need to be overwritten and will incur the associated cost."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-rust"},"\n // This identifies an item within the dictionary and either creates or updates the associated value.\n match storage::dictionary_get::(ledger_seed_uref, &dictionary_item_key).unwrap_or_revert()\n {\n None => storage::dictionary_put(ledger_seed_uref, &dictionary_item_key, 1u64),\n Some(current_number_of_donations) => storage::dictionary_put(\n ledger_seed_uref,\n &dictionary_item_key,\n current_number_of_donations + 1u64,\n ),\n }\n}\n\n")),(0,r.kt)("h2",{id:"reading-items-from-a-dictionary-using-the-json-rpc"},"Reading Items from a Dictionary using the JSON-RPC"),(0,r.kt)("p",null,"The Casper platform provides several means of looking up a dictionary item. These means are explained within the ",(0,r.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_chain#dictionaryidentifier"},(0,r.kt)("inlineCode",{parentName:"a"},"DictionaryIdentifier"))," JSON-RPC type. The following explains how to query the dictionary items using the ",(0,r.kt)("a",{parentName:"p",href:"https://crates.io/crates/casper-client"},"Casper client"),"."),(0,r.kt)("h3",{id:"contractnamedkey-lookup-via-a-contracts-named-keys"},(0,r.kt)("inlineCode",{parentName:"h3"},"ContractNamedKey")," lookup via a Contract's named keys."),(0,r.kt)("p",null,"Reading a dictionary item using the Contract's ",(0,r.kt)("inlineCode",{parentName:"p"},"NamedKeys")," requires the following parameters:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("inlineCode",{parentName:"p"},"Node Address")," - The IP and port of a node on a Casper network. In the example below, the node address is pointing to a local NCTL network.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("inlineCode",{parentName:"p"},"State Root Hash")," - The current state root hash of a Casper network hosting the dictionary item you are attempting to read.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("inlineCode",{parentName:"p"},"Contract Hash")," - The hash of the contract that references the dictionary in its ",(0,r.kt)("inlineCode",{parentName:"p"},"NamedKeys"),".")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("inlineCode",{parentName:"p"},"Dictionary Name")," - The name of the dictionary as a ",(0,r.kt)("inlineCode",{parentName:"p"},"String")," stored in the Contract's ",(0,r.kt)("inlineCode",{parentName:"p"},"NamedKeys"),".")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("inlineCode",{parentName:"p"},"Dictionary Item Key")," - The specific dictionary item key to be read, as a ",(0,r.kt)("inlineCode",{parentName:"p"},"String"),"."))),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --contract-hash hash-09c8fa7c1441ae7c1cbe27ae3a722fd4ffc5290315f8546454454c1b9f85c842 \\\n --dictionary-name \\\n --dictionary-item-key \n\n")),(0,r.kt)("h3",{id:"uref-lookup-via-the-dictionarys-seed-uref"},(0,r.kt)("inlineCode",{parentName:"h3"},"URef")," lookup via the dictionary's seed URef."),(0,r.kt)("p",null,"Reading a dictionary item using the dictionary's seed URef requires the ",(0,r.kt)("inlineCode",{parentName:"p"},"Node Address"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"State Root Hash")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"Dictionary Item Key")," as above. However, it does not require the ",(0,r.kt)("inlineCode",{parentName:"p"},"Contract Hash")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"Dictionary Name"),". Instead, it requires:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"Seed URef")," - The ",(0,r.kt)("a",{parentName:"li",href:"#seed-urefs"},"Seed URef")," of the dictionary to reference.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --dictionary-item-key \\\n --seed-uref uref-90b4a8d936b881d3b45b73a102adb2b652181d75c76b7547ae9d1bb213f8db6b-007\n\n")),(0,r.kt)("h3",{id:"dictionary-lookup-via-the-unique-dictionary-item-key"},(0,r.kt)("inlineCode",{parentName:"h3"},"Dictionary")," lookup via the unique dictionary item key."),(0,r.kt)("p",null,"In the event that you know the ",(0,r.kt)("inlineCode",{parentName:"p"},"dictionary address")," of the dictionary item key you need to read, you can read it directly using the following Casper client command."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --dictionary-address dictionary-\n\n")))}y.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[9212],{3905:function(e,t,n){n.d(t,{Zo:function(){return l},kt:function(){return y}});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=a.createContext({}),d=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},l=function(e){var t=d(e.components);return a.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),p=d(n),h=i,y=p["".concat(c,".").concat(h)]||p[h]||u[h]||r;return n?a.createElement(y,o(o({ref:t},l),{},{components:n})):a.createElement(y,o({ref:t},l))}));function y(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:i,o[1]=s;for(var d=2;dContractNamedKey lookup via a Contract's named keys.",id:"contractnamedkey-lookup-via-a-contracts-named-keys",level:3},{value:"URef lookup via the dictionary's seed URef.",id:"uref-lookup-via-the-dictionarys-seed-uref",level:3},{value:"Dictionary lookup via the unique dictionary item key.",id:"dictionary-lookup-via-the-unique-dictionary-item-key",level:3}],u={toc:p},h="wrapper";function y(e){var t=e.components,n=(0,i.Z)(e,o);return(0,r.kt)(h,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"dictionaries"},"Understanding Dictionaries"),(0,r.kt)("p",null,"In a Casper network, you can now store sets of data under ",(0,r.kt)("a",{parentName:"p",href:"/concepts/hash-types#hash-and-key-explanations"},(0,r.kt)("inlineCode",{parentName:"a"},"Keys")),". Previously, ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/U#uref"},"URefs")," were the exclusive means by which users could store data in global state. To maintain persistent access to these URefs, they would have to be stored within an ",(0,r.kt)("inlineCode",{parentName:"p"},"Account")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"Contract")," context. In the case of Contracts, sustained and continuous use of URefs would result in the expansion of the associated ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/N#namedkeys"},"NamedKeys")," structures."),(0,r.kt)("p",null,"Individual value changes to data stored within the NamedKeys would require deserializing the entire NamedKeys data structure, increasing gas costs over time and thus having a negative impact. Additionally, users storing large subsets of mapped data structures would face the same deep copy problem where minor or single updates required the complete deserialization of the map structure, also leading to increased gas costs."),(0,r.kt)("p",null,"As a solution to this problem, the Casper platform provides the ",(0,r.kt)("inlineCode",{parentName:"p"},"Dictionary")," feature, which allows users a more efficient and scalable means to aggregate data over time."),(0,r.kt)("p",null,"In almost all cases, dictionaries are the better form of data storage. They allow greater flexibility in altering stored data at a lower cost."),(0,r.kt)("h2",{id:"seed-urefs"},"Seed URefs"),(0,r.kt)("p",null,"Items within a dictionary exist as individual records stored underneath their unique ",(0,r.kt)("a",{parentName:"p",href:"/concepts/hash-types#hash-and-key-explanations"},"dictionary address")," in global state. In other words, items associated with a specific dictionary share the same seed ",(0,r.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#uref-head"},(0,r.kt)("inlineCode",{parentName:"a"},"URef"))," but are otherwise independent of each other. Dictionary items are not stored beneath this URef, it is only used to create the dictionary key."),(0,r.kt)("p",null,"As each dictionary item exists as a stand-alone entity in global state, regularly used dictionary keys may be used directly without referencing their seed URef."),(0,r.kt)("h2",{id:"using-dictionaries"},"Using Dictionaries"),(0,r.kt)("p",null,"Dictionaries are ideal for storing larger volumes of data for which ",(0,r.kt)("inlineCode",{parentName:"p"},"NamedKeys")," would be less suitable."),(0,r.kt)("p",null,"Creating a new dictionary is fairly simple and done within the context of a ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," sent to a Casper network. The associated code is included within the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/"},(0,r.kt)("inlineCode",{parentName:"a"},"casper_contract"))," crate. Creating a dictionary also stores the associated seed URef within the named keys of the current context."),(0,r.kt)("p",null,"Developers should always consider context when creating dictionaries. We recommend creating a dictionary within the context of a Contract."),(0,r.kt)("p",null,"While you can create a dictionary in the context of an Account and then pass associated access rights to a Contract, this approach can create potential security issues. If a third party uses the Contract, the initiating Account with access rights to the dictionary may be undesirable. To rectify this, you may send an additional ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," removing those access rights, but it is better to create the dictionary within the context of the Contract."),(0,r.kt)("p",null,"Dictionaries allow a contract to store additional data without drastically expanding the size of the ",(0,r.kt)("inlineCode",{parentName:"p"},"NamedKeys")," within their context. If a contract's ",(0,r.kt)("inlineCode",{parentName:"p"},"NamedKeys")," expand too far, they may run into system limitations that would unintentionally disable the contract's functionality."),(0,r.kt)("p",null,"A dictionary item key can be no longer than 64 bytes in length."),(0,r.kt)("h2",{id:"practical-dictionary-examples"},"Practical Dictionary Examples"),(0,r.kt)("p",null,"The ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft"},"Casper CEP-78 Enhanced NFT Standard")," includes several practical applications of dictionaries."),(0,r.kt)("p",null,"Simple examples for dictionary use within CEP-78 include the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs#L772"},(0,r.kt)("inlineCode",{parentName:"a"},"approve"))," dictionary."),(0,r.kt)("p",null,"More advanced dictionary functionality can be found in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft#the-cep-78-page-system"},"CEP-78 Page System"),", which uses a series of dictionaries to keep track of token ownership. These dictionaries form the basis of the reverse lookup mode, which allows users to easily view a list of owned tokens by account or contract."),(0,r.kt)("h2",{id:"creating-dictionaries-in-a-contracts-context"},"Creating Dictionaries in a Contract's Context"),(0,r.kt)("p",null,"The following code snippet shows the most basic example of creating a dictionary."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-rust"},"\ncasper_contract::contract_api::storage::new_dictionary(dict_name)\n\n")),(0,r.kt)("p",null,"The following example includes the creation of a dictionary ",(0,r.kt)("inlineCode",{parentName:"p"},'"ledger"')," within a contract's context. In this instance, the dictionary will be used to track donations made to a fundraising purse also created by the ",(0,r.kt)("inlineCode",{parentName:"p"},"init")," entry point. In any case where you want to use a dictionary within your contract, it should be set up within the initializing entry point."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-rust"},'\n#[no_mangle]\npub extern "C" fn init() {\n let fundraising_purse = system::create_purse();\n runtime::put_key("fundraising_purse", fundraising_purse.into());\n // Create a dictionary to track the mapping of account hashes to number of donations made.\n storage::new_dictionary("ledger").unwrap_or_revert();\n}\n\n')),(0,r.kt)("h2",{id:"writing-entries-into-a-dictionary"},"Writing Entries into a Dictionary"),(0,r.kt)("p",null,"After the creation of a dictionary, you may then add entries through the use of the following code:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-rust"},"\nstorage::dictionary_put(dictionary_uref, &dictionary_item_key, value);\n\n")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"dictionary_uref")," refers to the seed URef established during the dictionary creation process. The ",(0,r.kt)("inlineCode",{parentName:"p"},"key")," is the unique identifier for this dictionary item, and the ",(0,r.kt)("inlineCode",{parentName:"p"},"value")," is the data to be stored within the dictionary."),(0,r.kt)("p",null,"As stated above, these dictionary items do not require the seed URef, and they exist as individual keys in global state. If you know an individual key's address, you do not need to go through the process of identifying the seed URef first."),(0,r.kt)("p",null,"The following function serves to add an entry to the dictionary. If the item already exists, the entry point will update the value stored and referenced by that key. In this case, the code is storing the number of donations made. Any Rust structure may be stored under a dictionary item, but when updating a value within a larger structure (i.e., a list), the entire structure will be overwritten as part of the update. Updating a larger structure will incur the full cost of writing the structure to a dictionary item."),(0,r.kt)("p",null,"The first section acquiring the ",(0,r.kt)("inlineCode",{parentName:"p"},"LEDGER")," seed URef to assign the new dictionary item to the proper dictionary."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-rust"},'\nfn update_ledger_record(dictionary_item_key: String) {\n // Acquiring the LEDGER seed URef to properly assign the dictionary item.\n let ledger_seed_uref = *runtime::get_key("ledger")\n .unwrap_or_revert_with(FundRaisingError::MissingLedgerSeedURef)\n .as_uref()\n .unwrap_or_revert();\n\n')),(0,r.kt)("p",null,"The second section uses ",(0,r.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_get.html"},(0,r.kt)("inlineCode",{parentName:"a"},"dictionary_get"))," to read an entry within the ",(0,r.kt)("inlineCode",{parentName:"p"},"LEDGER")," dictionary. If the entry does not exist on global state, it will create the entry. If it already exists, the entry is updated with the current value using a ",(0,r.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_put.html"},(0,r.kt)("inlineCode",{parentName:"a"},"dictionary_put"))," operation. As stated above, regardless of the size of the change within the entry, the entire dictionary entry will need to be overwritten and will incur the associated cost."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-rust"},"\n // This identifies an item within the dictionary and either creates or updates the associated value.\n match storage::dictionary_get::(ledger_seed_uref, &dictionary_item_key).unwrap_or_revert()\n {\n None => storage::dictionary_put(ledger_seed_uref, &dictionary_item_key, 1u64),\n Some(current_number_of_donations) => storage::dictionary_put(\n ledger_seed_uref,\n &dictionary_item_key,\n current_number_of_donations + 1u64,\n ),\n }\n}\n\n")),(0,r.kt)("h2",{id:"reading-items-from-a-dictionary-using-the-json-rpc"},"Reading Items from a Dictionary using the JSON-RPC"),(0,r.kt)("p",null,"The Casper platform provides several means of looking up a dictionary item. These means are explained within the ",(0,r.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_chain#dictionaryidentifier"},(0,r.kt)("inlineCode",{parentName:"a"},"DictionaryIdentifier"))," JSON-RPC type. The following explains how to query the dictionary items using the ",(0,r.kt)("a",{parentName:"p",href:"https://crates.io/crates/casper-client"},"Casper client"),"."),(0,r.kt)("h3",{id:"contractnamedkey-lookup-via-a-contracts-named-keys"},(0,r.kt)("inlineCode",{parentName:"h3"},"ContractNamedKey")," lookup via a Contract's named keys."),(0,r.kt)("p",null,"Reading a dictionary item using the Contract's ",(0,r.kt)("inlineCode",{parentName:"p"},"NamedKeys")," requires the following parameters:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("inlineCode",{parentName:"p"},"Node Address")," - The IP and port of a node on a Casper network. In the example below, the node address is pointing to a local NCTL network.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("inlineCode",{parentName:"p"},"State Root Hash")," - The current state root hash of a Casper network hosting the dictionary item you are attempting to read.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("inlineCode",{parentName:"p"},"Contract Hash")," - The hash of the contract that references the dictionary in its ",(0,r.kt)("inlineCode",{parentName:"p"},"NamedKeys"),".")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("inlineCode",{parentName:"p"},"Dictionary Name")," - The name of the dictionary as a ",(0,r.kt)("inlineCode",{parentName:"p"},"String")," stored in the Contract's ",(0,r.kt)("inlineCode",{parentName:"p"},"NamedKeys"),".")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("inlineCode",{parentName:"p"},"Dictionary Item Key")," - The specific dictionary item key to be read, as a ",(0,r.kt)("inlineCode",{parentName:"p"},"String"),"."))),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --contract-hash hash-09c8fa7c1441ae7c1cbe27ae3a722fd4ffc5290315f8546454454c1b9f85c842 \\\n --dictionary-name \\\n --dictionary-item-key \n\n")),(0,r.kt)("h3",{id:"uref-lookup-via-the-dictionarys-seed-uref"},(0,r.kt)("inlineCode",{parentName:"h3"},"URef")," lookup via the dictionary's seed URef."),(0,r.kt)("p",null,"Reading a dictionary item using the dictionary's seed URef requires the ",(0,r.kt)("inlineCode",{parentName:"p"},"Node Address"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"State Root Hash")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"Dictionary Item Key")," as above. However, it does not require the ",(0,r.kt)("inlineCode",{parentName:"p"},"Contract Hash")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"Dictionary Name"),". Instead, it requires:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"Seed URef")," - The ",(0,r.kt)("a",{parentName:"li",href:"#seed-urefs"},"Seed URef")," of the dictionary to reference.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --dictionary-item-key \\\n --seed-uref uref-90b4a8d936b881d3b45b73a102adb2b652181d75c76b7547ae9d1bb213f8db6b-007\n\n")),(0,r.kt)("h3",{id:"dictionary-lookup-via-the-unique-dictionary-item-key"},(0,r.kt)("inlineCode",{parentName:"h3"},"Dictionary")," lookup via the unique dictionary item key."),(0,r.kt)("p",null,"In the event that you know the ",(0,r.kt)("inlineCode",{parentName:"p"},"dictionary address")," of the dictionary item key you need to read, you can read it directly using the following Casper client command."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --dictionary-address dictionary-\n\n")))}y.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/71c4e358.6a76edb9.js b/assets/js/71c4e358.5f4f8f8d.js similarity index 97% rename from assets/js/71c4e358.6a76edb9.js rename to assets/js/71c4e358.5f4f8f8d.js index 1af5712317..d2c2e41f4d 100644 --- a/assets/js/71c4e358.6a76edb9.js +++ b/assets/js/71c4e358.5f4f8f8d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[7080],{3905:function(e,t,r){r.d(t,{Zo:function(){return i},kt:function(){return m}});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(r),y=a,m=u["".concat(p,".").concat(y)]||u[y]||f[y]||o;return r?n.createElement(m,s(s({ref:t},i),{},{components:r})):n.createElement(m,s({ref:t},i))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(r),y=a,m=u["".concat(p,".").concat(y)]||u[y]||f[y]||o;return r?n.createElement(m,s(s({ref:t},i),{},{components:r})):n.createElement(m,s({ref:t},i))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),l=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(i.Provider,{value:t},e.children)},u="mdxType",_={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,i=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=l(n),h=r,d=u["".concat(i,".").concat(h)]||u[h]||_[h]||s;return n?a.createElement(d,c(c({ref:t},p),{},{components:n})):a.createElement(d,c({ref:t},p))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,c=new Array(s);c[0]=h;var o={};for(var i in t)hasOwnProperty.call(t,i)&&(o[i]=t[i]);o.originalType=e,o[u]="string"==typeof e?e:r,c[1]=o;for(var l=2;l (InMemoryWasmTestBuilder, TestContext) {\n setup_with_args(runtime_args! {\n ARG_NAME => TOKEN_NAME,\n ARG_SYMBOL => TOKEN_SYMBOL,\n ARG_DECIMALS => TOKEN_DECIMALS,\n ARG_TOTAL_SUPPLY => U256::from(TOKEN_TOTAL_SUPPLY),\n })\n}\n\n// Establishing test accounts.\n\npub(crate) fn setup_with_args(install_args: RuntimeArgs) -> (InMemoryWasmTestBuilder, TestContext) {\n let mut builder = InMemoryWasmTestBuilder::default();\n builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST);\n\n let id: Option = None;\n let transfer_1_args = runtime_args! {\n mint::ARG_TARGET => *ACCOUNT_1_ADDR,\n mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,\n mint::ARG_ID => id,\n };\n let transfer_2_args = runtime_args! {\n mint::ARG_TARGET => *ACCOUNT_2_ADDR,\n mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,\n mint::ARG_ID => id,\n };\n\n let transfer_request_1 =\n ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_1_args).build();\n let transfer_request_2 =\n ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_2_args).build();\n\n // Installing the test version of CEP-18 with the default account.\n\n let install_request_1 =\n ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CEP18_CONTRACT_WASM, install_args)\n .build();\n\n let install_request_2 = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n CEP18_TEST_CONTRACT_WASM,\n RuntimeArgs::default(),\n )\n .build();\n\n builder.exec(transfer_request_1).expect_success().commit();\n builder.exec(transfer_request_2).expect_success().commit();\n builder.exec(install_request_1).expect_success().commit();\n builder.exec(install_request_2).expect_success().commit();\n\n let account = builder\n .get_account(*DEFAULT_ACCOUNT_ADDR)\n .expect("should have account");\n\n let cep18_token = account\n .named_keys()\n .get(CEP18_TOKEN_CONTRACT_KEY)\n .and_then(|key| key.into_hash())\n .map(ContractHash::new)\n .expect("should have contract hash");\n\n let cep18_test_contract_package = account\n .named_keys()\n .get(CEP18_TEST_CONTRACT_KEY)\n .and_then(|key| key.into_hash())\n .map(ContractPackageHash::new)\n .expect("should have contract package hash");\n\n let test_context = TestContext {\n cep18_token,\n cep18_test_contract_package,\n };\n\n (builder, test_context)\n}\n'))),(0,s.kt)("h3",{id:"creating-helper-functions"},"Creating Helper Functions"),(0,s.kt)("p",null,"The previous step has simulated sending a real deploy on the network. The next code snippet in ",(0,s.kt)("inlineCode",{parentName:"p"},"installer_request_builders.rs")," defines helper functions that will be used throughout the testing framework:"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"cep18_check_total_supply")," - A function for testing the total supply of the CEP-18 contract instance."),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"cep18_check_balance_of")," - A function for checking an account's balance of CEP-18 tokens."),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"cep18_check_allowance_of")," - A function for checking an account's spending allowance from another account's balance.")),(0,s.kt)("p",null,"These are followed by functions that check specific aspects of the CEP-18 contract. These include ",(0,s.kt)("inlineCode",{parentName:"p"},"test_cep18_transfer"),", ",(0,s.kt)("inlineCode",{parentName:"p"},"make_cep18_approve_request")," and ",(0,s.kt)("inlineCode",{parentName:"p"},"test_approve_for"),"."),(0,s.kt)("p",null,"The following code snippet is an example function that tests the ability to transfer CEP-18 tokens from the default address to the two other addresses established in ",(0,s.kt)("a",{parentName:"p",href:"#installing-the-contract-deploying-the-contract"},"contract installation"),":"),(0,s.kt)("details",null,(0,s.kt)("summary",null,"Example helper function"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\npub(crate) fn test_cep18_transfer(\n builder: &mut InMemoryWasmTestBuilder,\n test_context: &TestContext,\n sender1: Key,\n recipient1: Key,\n sender2: Key,\n recipient2: Key) {\n let TestContext { cep18_token, .. } = test_context;\n\n // Defining the amount to be transferred to each account.\n\n let transfer_amount_1 = U256::from(TRANSFER_AMOUNT_1);\n let transfer_amount_2 = U256::from(TRANSFER_AMOUNT_2);\n\n // Checking the pre-existing balances of the default address and the two receiving addresses.\n\n let sender_balance_before = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_ne!(sender_balance_before, U256::zero());\n\n let account_1_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_1_balance_before, U256::zero());\n\n let account_2_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_2_balance_before, U256::zero());\n\n // Creating the first transfer request.\n\n let token_transfer_request_1 =\n make_cep18_transfer_request(sender1, cep18_token, recipient1, transfer_amount_1);\n\n builder\n .exec(token_transfer_request_1)\n .expect_success()\n .commit();\n\n // Checking the prior balance against the new balance to ensure the transfer occurred correctly.\n\n let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_1_balance_after, transfer_amount_1);\n let account_1_balance_before = account_1_balance_after;\n\n let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_eq!(\n sender_balance_after,\n sender_balance_before - transfer_amount_1\n );\n let sender_balance_before = sender_balance_after;\n\n // Creating the second transfer request.\n\n let token_transfer_request_2 =\n make_cep18_transfer_request(sender2, cep18_token, recipient2, transfer_amount_2);\n\n builder\n .exec(token_transfer_request_2)\n .expect_success()\n .commit();\n\n // Checking prior balances against new balances.\n\n let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_eq!(sender_balance_after, sender_balance_before);\n\n let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert!(account_1_balance_after < account_1_balance_before);\n assert_eq!(\n account_1_balance_after,\n transfer_amount_1 - transfer_amount_2\n );\n\n let account_2_balance_after = cep18_check_balance_of(builder, cep18_token, recipient2);\n assert_eq!(account_2_balance_after, transfer_amount_2);\n}\n"))),(0,s.kt)("h2",{id:"creating-unit-tests"},"Creating Unit Tests"),(0,s.kt)("p",null,"Within this testing context, the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src"},(0,s.kt)("inlineCode",{parentName:"a"},"tests")," directory")," includes a variety of unit tests, which verify the contract code by invoking the functions defined in the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs"},"installer_request_builders.rs")," file."),(0,s.kt)("p",null,"The example below shows one of the tests. Visit ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src"},"GitHub")," to find all the available tests."),(0,s.kt)("details",null,(0,s.kt)("summary",null,"Example test querying token properties"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/install.rs\n\nuse casper_engine_test_support::DEFAULT_ACCOUNT_ADDR;\nuse casper_types::{Key, U256};\n\nuse crate::utility::{\n constants::{\n ALLOWANCES_KEY, BALANCES_KEY, DECIMALS_KEY, NAME_KEY, SYMBOL_KEY, TOKEN_DECIMALS,\n TOKEN_NAME, TOKEN_SYMBOL, TOKEN_TOTAL_SUPPLY, TOTAL_SUPPLY_KEY,\n },\n installer_request_builders::{\n cep18_check_balance_of, invert_cep18_address, setup, TestContext,\n },\n};\n\n#[test]\nfn should_have_queryable_properties() {\n let (mut builder, TestContext { cep18_token, .. }) = setup();\n\n let name: String = builder.get_value(cep18_token, NAME_KEY);\n assert_eq!(name, TOKEN_NAME);\n\n let symbol: String = builder.get_value(cep18_token, SYMBOL_KEY);\n assert_eq!(symbol, TOKEN_SYMBOL);\n\n let decimals: u8 = builder.get_value(cep18_token, DECIMALS_KEY);\n assert_eq!(decimals, TOKEN_DECIMALS);\n\n let total_supply: U256 = builder.get_value(cep18_token, TOTAL_SUPPLY_KEY);\n assert_eq!(total_supply, U256::from(TOKEN_TOTAL_SUPPLY));\n\n let owner_key = Key::Account(*DEFAULT_ACCOUNT_ADDR);\n\n let owner_balance = cep18_check_balance_of(&mut builder, &cep18_token, owner_key);\n assert_eq!(owner_balance, total_supply);\n\n let contract_balance =\n cep18_check_balance_of(&mut builder, &cep18_token, Key::Hash(cep18_token.value()));\n assert_eq!(contract_balance, U256::zero());\n\n // Ensures that Account and Contract ownership is respected and we're not keying ownership under\n // the raw bytes regardless of variant.\n let inverted_owner_key = invert_cep18_address(owner_key);\n let inverted_owner_balance =\n cep18_check_balance_of(&mut builder, &cep18_token, inverted_owner_key);\n assert_eq!(inverted_owner_balance, U256::zero());\n}\n"))),(0,s.kt)("h2",{id:"running-the-tests"},"Running the Tests"),(0,s.kt)("p",null,"The ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/lib.rs"},"lib.rs")," file is configured to run the example integration tests via the ",(0,s.kt)("inlineCode",{parentName:"p"},"make test")," command:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},"#[cfg(test)]\nmod allowance;\n#[cfg(test)]\nmod install;\n#[cfg(test)]\nmod mint_and_burn;\n#[cfg(test)]\nmod transfer;\n#[cfg(test)]\nmod utility;\n")),(0,s.kt)("p",null,"To run the tests, navigate to the parent ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep18"},"cep18 directory")," and run the command:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"make test\n")),(0,s.kt)("p",null,"This example uses ",(0,s.kt)("inlineCode",{parentName:"p"},"bash"),". If you are using a Rust IDE, you need to configure it to run the tests."))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[7059],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return d}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function c(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),l=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(i.Provider,{value:t},e.children)},u="mdxType",_={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,i=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=l(n),h=r,d=u["".concat(i,".").concat(h)]||u[h]||_[h]||s;return n?a.createElement(d,c(c({ref:t},p),{},{components:n})):a.createElement(d,c({ref:t},p))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,c=new Array(s);c[0]=h;var o={};for(var i in t)hasOwnProperty.call(t,i)&&(o[i]=t[i]);o.originalType=e,o[u]="string"==typeof e?e:r,c[1]=o;for(var l=2;l (InMemoryWasmTestBuilder, TestContext) {\n setup_with_args(runtime_args! {\n ARG_NAME => TOKEN_NAME,\n ARG_SYMBOL => TOKEN_SYMBOL,\n ARG_DECIMALS => TOKEN_DECIMALS,\n ARG_TOTAL_SUPPLY => U256::from(TOKEN_TOTAL_SUPPLY),\n })\n}\n\n// Establishing test accounts.\n\npub(crate) fn setup_with_args(install_args: RuntimeArgs) -> (InMemoryWasmTestBuilder, TestContext) {\n let mut builder = InMemoryWasmTestBuilder::default();\n builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST);\n\n let id: Option = None;\n let transfer_1_args = runtime_args! {\n mint::ARG_TARGET => *ACCOUNT_1_ADDR,\n mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,\n mint::ARG_ID => id,\n };\n let transfer_2_args = runtime_args! {\n mint::ARG_TARGET => *ACCOUNT_2_ADDR,\n mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,\n mint::ARG_ID => id,\n };\n\n let transfer_request_1 =\n ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_1_args).build();\n let transfer_request_2 =\n ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_2_args).build();\n\n // Installing the test version of CEP-18 with the default account.\n\n let install_request_1 =\n ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CEP18_CONTRACT_WASM, install_args)\n .build();\n\n let install_request_2 = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n CEP18_TEST_CONTRACT_WASM,\n RuntimeArgs::default(),\n )\n .build();\n\n builder.exec(transfer_request_1).expect_success().commit();\n builder.exec(transfer_request_2).expect_success().commit();\n builder.exec(install_request_1).expect_success().commit();\n builder.exec(install_request_2).expect_success().commit();\n\n let account = builder\n .get_account(*DEFAULT_ACCOUNT_ADDR)\n .expect("should have account");\n\n let cep18_token = account\n .named_keys()\n .get(CEP18_TOKEN_CONTRACT_KEY)\n .and_then(|key| key.into_hash())\n .map(ContractHash::new)\n .expect("should have contract hash");\n\n let cep18_test_contract_package = account\n .named_keys()\n .get(CEP18_TEST_CONTRACT_KEY)\n .and_then(|key| key.into_hash())\n .map(ContractPackageHash::new)\n .expect("should have contract package hash");\n\n let test_context = TestContext {\n cep18_token,\n cep18_test_contract_package,\n };\n\n (builder, test_context)\n}\n'))),(0,s.kt)("h3",{id:"creating-helper-functions"},"Creating Helper Functions"),(0,s.kt)("p",null,"The previous step has simulated sending a real deploy on the network. The next code snippet in ",(0,s.kt)("inlineCode",{parentName:"p"},"installer_request_builders.rs")," defines helper functions that will be used throughout the testing framework:"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"cep18_check_total_supply")," - A function for testing the total supply of the CEP-18 contract instance."),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"cep18_check_balance_of")," - A function for checking an account's balance of CEP-18 tokens."),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"cep18_check_allowance_of")," - A function for checking an account's spending allowance from another account's balance.")),(0,s.kt)("p",null,"These are followed by functions that check specific aspects of the CEP-18 contract. These include ",(0,s.kt)("inlineCode",{parentName:"p"},"test_cep18_transfer"),", ",(0,s.kt)("inlineCode",{parentName:"p"},"make_cep18_approve_request")," and ",(0,s.kt)("inlineCode",{parentName:"p"},"test_approve_for"),"."),(0,s.kt)("p",null,"The following code snippet is an example function that tests the ability to transfer CEP-18 tokens from the default address to the two other addresses established in ",(0,s.kt)("a",{parentName:"p",href:"#installing-the-contract-deploying-the-contract"},"contract installation"),":"),(0,s.kt)("details",null,(0,s.kt)("summary",null,"Example helper function"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\npub(crate) fn test_cep18_transfer(\n builder: &mut InMemoryWasmTestBuilder,\n test_context: &TestContext,\n sender1: Key,\n recipient1: Key,\n sender2: Key,\n recipient2: Key) {\n let TestContext { cep18_token, .. } = test_context;\n\n // Defining the amount to be transferred to each account.\n\n let transfer_amount_1 = U256::from(TRANSFER_AMOUNT_1);\n let transfer_amount_2 = U256::from(TRANSFER_AMOUNT_2);\n\n // Checking the pre-existing balances of the default address and the two receiving addresses.\n\n let sender_balance_before = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_ne!(sender_balance_before, U256::zero());\n\n let account_1_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_1_balance_before, U256::zero());\n\n let account_2_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_2_balance_before, U256::zero());\n\n // Creating the first transfer request.\n\n let token_transfer_request_1 =\n make_cep18_transfer_request(sender1, cep18_token, recipient1, transfer_amount_1);\n\n builder\n .exec(token_transfer_request_1)\n .expect_success()\n .commit();\n\n // Checking the prior balance against the new balance to ensure the transfer occurred correctly.\n\n let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_1_balance_after, transfer_amount_1);\n let account_1_balance_before = account_1_balance_after;\n\n let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_eq!(\n sender_balance_after,\n sender_balance_before - transfer_amount_1\n );\n let sender_balance_before = sender_balance_after;\n\n // Creating the second transfer request.\n\n let token_transfer_request_2 =\n make_cep18_transfer_request(sender2, cep18_token, recipient2, transfer_amount_2);\n\n builder\n .exec(token_transfer_request_2)\n .expect_success()\n .commit();\n\n // Checking prior balances against new balances.\n\n let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_eq!(sender_balance_after, sender_balance_before);\n\n let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert!(account_1_balance_after < account_1_balance_before);\n assert_eq!(\n account_1_balance_after,\n transfer_amount_1 - transfer_amount_2\n );\n\n let account_2_balance_after = cep18_check_balance_of(builder, cep18_token, recipient2);\n assert_eq!(account_2_balance_after, transfer_amount_2);\n}\n"))),(0,s.kt)("h2",{id:"creating-unit-tests"},"Creating Unit Tests"),(0,s.kt)("p",null,"Within this testing context, the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src"},(0,s.kt)("inlineCode",{parentName:"a"},"tests")," directory")," includes a variety of unit tests, which verify the contract code by invoking the functions defined in the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs"},"installer_request_builders.rs")," file."),(0,s.kt)("p",null,"The example below shows one of the tests. Visit ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src"},"GitHub")," to find all the available tests."),(0,s.kt)("details",null,(0,s.kt)("summary",null,"Example test querying token properties"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/install.rs\n\nuse casper_engine_test_support::DEFAULT_ACCOUNT_ADDR;\nuse casper_types::{Key, U256};\n\nuse crate::utility::{\n constants::{\n ALLOWANCES_KEY, BALANCES_KEY, DECIMALS_KEY, NAME_KEY, SYMBOL_KEY, TOKEN_DECIMALS,\n TOKEN_NAME, TOKEN_SYMBOL, TOKEN_TOTAL_SUPPLY, TOTAL_SUPPLY_KEY,\n },\n installer_request_builders::{\n cep18_check_balance_of, invert_cep18_address, setup, TestContext,\n },\n};\n\n#[test]\nfn should_have_queryable_properties() {\n let (mut builder, TestContext { cep18_token, .. }) = setup();\n\n let name: String = builder.get_value(cep18_token, NAME_KEY);\n assert_eq!(name, TOKEN_NAME);\n\n let symbol: String = builder.get_value(cep18_token, SYMBOL_KEY);\n assert_eq!(symbol, TOKEN_SYMBOL);\n\n let decimals: u8 = builder.get_value(cep18_token, DECIMALS_KEY);\n assert_eq!(decimals, TOKEN_DECIMALS);\n\n let total_supply: U256 = builder.get_value(cep18_token, TOTAL_SUPPLY_KEY);\n assert_eq!(total_supply, U256::from(TOKEN_TOTAL_SUPPLY));\n\n let owner_key = Key::Account(*DEFAULT_ACCOUNT_ADDR);\n\n let owner_balance = cep18_check_balance_of(&mut builder, &cep18_token, owner_key);\n assert_eq!(owner_balance, total_supply);\n\n let contract_balance =\n cep18_check_balance_of(&mut builder, &cep18_token, Key::Hash(cep18_token.value()));\n assert_eq!(contract_balance, U256::zero());\n\n // Ensures that Account and Contract ownership is respected and we're not keying ownership under\n // the raw bytes regardless of variant.\n let inverted_owner_key = invert_cep18_address(owner_key);\n let inverted_owner_balance =\n cep18_check_balance_of(&mut builder, &cep18_token, inverted_owner_key);\n assert_eq!(inverted_owner_balance, U256::zero());\n}\n"))),(0,s.kt)("h2",{id:"running-the-tests"},"Running the Tests"),(0,s.kt)("p",null,"The ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/lib.rs"},"lib.rs")," file is configured to run the example integration tests via the ",(0,s.kt)("inlineCode",{parentName:"p"},"make test")," command:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},"#[cfg(test)]\nmod allowance;\n#[cfg(test)]\nmod install;\n#[cfg(test)]\nmod mint_and_burn;\n#[cfg(test)]\nmod transfer;\n#[cfg(test)]\nmod utility;\n")),(0,s.kt)("p",null,"To run the tests, navigate to the parent ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep18"},"cep18 directory")," and run the command:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"make test\n")),(0,s.kt)("p",null,"This example uses ",(0,s.kt)("inlineCode",{parentName:"p"},"bash"),". If you are using a Rust IDE, you need to configure it to run the tests."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/72301f79.47a57eba.js b/assets/js/72301f79.4567d6e6.js similarity index 99% rename from assets/js/72301f79.47a57eba.js rename to assets/js/72301f79.4567d6e6.js index e39c82150f..a8d33f28b2 100644 --- a/assets/js/72301f79.47a57eba.js +++ b/assets/js/72301f79.4567d6e6.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[4970],{3905:function(e,n,t){t.d(n,{Zo:function(){return d},kt:function(){return m}});var a=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function c(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var i=a.createContext({}),l=function(e){var n=a.useContext(i),t=n;return e&&(t="function"==typeof e?e(n):c(c({},n),e)),t},d=function(e){var n=l(e.components);return a.createElement(i.Provider,{value:n},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=l(t),u=r,m=p["".concat(i,".").concat(u)]||p[u]||h[u]||o;return t?a.createElement(m,c(c({ref:n},d),{},{components:t})):a.createElement(m,c({ref:n},d))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,c=new Array(o);c[0]=u;var s={};for(var i in n)hasOwnProperty.call(n,i)&&(s[i]=n[i]);s.originalType=e,s[p]="string"==typeof e?e:r,c[1]=s;for(var l=2;l = BTreeMap::new();\n\n // Insert the new value into the named keys\n named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the Uref into a casper_types::Key\n // Create a new vector\n let mut params = Vec::new();\n vec.push(Parameter::new("message", CLType::String));\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Describing the metadata for the entry point\n entry_points.add_entry_point(EntryPoint::new(\n "update_msg", // the name of the entry point\n vec, // the arguments which can be passed into the entry point\n CLType::Unit, // return type of the entry point\n EntryPointAccess::Public, // access permissions - public can be accessed always\n EntryPointType::Contract // in most cases it will be contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys\n Some("Hello_world_package_name".to_string()), // package name\n Some("Hello_world_access_uref".to_string()) // access uref\n );\n\n // To access the contract hash from the accounts named keys\n runtime::put_key("hello_world_contract", stored_contract_hash.into());\n\n}\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},(0,o.kt)("inlineCode",{parentName:"p"},"runtime")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"storage")," appear frequently in our code. If these terms are unfamiliar to you, you should familiarize yourself with the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/index.html"},"Contract API Modules"),".")),(0,o.kt)("p",null,"The metadata for each of the contract's entry points is defined in the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," entry point. When installing the contract, the system will look for the name of the entry point as specified by the metadata for that entry point. Therefore, each of the entry points defined in the code must share the same name as the ",(0,o.kt)("inlineCode",{parentName:"p"},"String")," value passed when defining the metadata for the entry point."),(0,o.kt)("p",null,"The #","[no_mangle]"," flag ensures that the compiler does not modify the name of the entry point. The compiler will not enforce the condition that the name of the entry point is the same value present in its metadata definition, therefore the developer must be careful when defining their entry points."),(0,o.kt)("p",null,"In our case, we will define the entry point ",(0,o.kt)("inlineCode",{parentName:"p"},"update_msg")," in the contract code just before ",(0,o.kt)("inlineCode",{parentName:"p"},"call"),"."),(0,o.kt)("p",null,"Your complete contract should match the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types\nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n#[no_mangle]\npub extern "C" fn update_msg() {\n\n let value: String = runtime::get_named_arg("message");\n // Get the uref of the message stored in global state\n let uref = runtime::get_key("message").unwrap_or_revert().into_uref().unwrap_or_revert();\n // Write the message to global state\n storage::write(uref, String::from(value));\n}\n\n\n#[no_mangle]\npub extern "C" fn call() {\n // Get the value of a passed parameter with the key "message"\n let value: String = runtime::get_named_arg("message");\n // The value will be wraped in a URef\n let value_ref = storage::new_uref(value);\n // Creating the new set of named keys\n // The keys are a Map of Key/Value\n let mut named_keys: BTreeMap = BTreeMap::new();\n // Insert the new value into the named keys\n named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the value to the key\n // Create a new vector\n let mut vec = Vec::new();\n vec.push(Parameter::new("message", CLType::String));\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Define the metadata for the entry point `update_msg`\n entry_points.add_entry_point(EntryPoint::new(\n "update_msg",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points metadata\n Some(named_keys), // named keys\n Some("Hello_world_package_name".to_string()), // package name\n Some("Hello_world_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("hello_world_contract", stored_contract_hash.into());\n}\n')),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"There is a distinction between storing data in a contract\u2019s ",(0,o.kt)("inlineCode",{parentName:"p"},"NamedKeys")," and using a dictionary. ",(0,o.kt)("a",{parentName:"p",href:"/concepts/dictionaries"},"Dictionaries")," can be used to store dApp-centric data, but they are not a SQL database and should only be used for data that needs to be stored in global state. Objects referenced in a contract should only be used as links within a bigger application.")),(0,o.kt)("h2",{id:"deploying-contract"},"Deploying the Contract"),(0,o.kt)("p",null,"There are many tools available to send a deploy to a Casper network. The simplest method is to use the Rust CLI with the subcommand ",(0,o.kt)("a",{parentName:"p",href:"/developers/cli/installing-contracts#installing-contract-code"},"put_deploy"),"."),(0,o.kt)("p",null,"Be sure to go through the prerequisites from the ",(0,o.kt)("a",{parentName:"p",href:"/developers/cli/installing-contracts"},"Installing Smart Contracts and Querying Global State")," documentation."),(0,o.kt)("p",null,"Make sure that after doing this you have:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"A valid private key for your account."),(0,o.kt)("li",{parentName:"ol"},"Funded your account with 2000 CSPR on the Testnet, which you can use for testing your smart contract.")),(0,o.kt)("p",null,"Create the ",(0,o.kt)("inlineCode",{parentName:"p"},"keys")," folder in the main folder of your project and make sure that the private key which you put into the folder is called ",(0,o.kt)("inlineCode",{parentName:"p"},"secret_key.pem"),"."),(0,o.kt)("p",null,"Compile the contract in the contract directory so you obtain the contracts ",(0,o.kt)("inlineCode",{parentName:"p"},".wasm"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cd cross-contract\nmake prepare\nmake build-contract\n")),(0,o.kt)("p",null,"This should produce the following outcome:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cd contract && cargo build --release --target wasm32-unknown-unknown\n Finished release [optimized] target(s) in 0.13s\nwasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n")),(0,o.kt)("p",null,"With this step everything is in place to deploy the contract."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"When working with lengthy command strings, it may help to maintain a .txt file where you can edit the runtime arguments of the commands before sending them to the CLI. This will save you time and frustration when working with multiple contracts and commands.")),(0,o.kt)("p",null,"Since we are using a default contract structure, the command called from the ",(0,o.kt)("inlineCode",{parentName:"p"},"cross-contract")," folder should be the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n --session-arg \"message:string='hello world'\"\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The parameters used in this command need to be adjusted based on your use case. For details, see ",(0,o.kt)("a",{parentName:"p",href:"/developers/prerequisites#acquire-node-address-from-network-peers"},"querying a node")," and ",(0,o.kt)("a",{parentName:"p",href:"/developers/cli/installing-contracts"},"installing contracts"),". The payment amount may also need to be adjusted based on the latest Testnet ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),".")),(0,o.kt)("p",null,"The output of this command is:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -9119604526598719721,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832"\n }\n}\n')),(0,o.kt)("p",null,"To verify that the contract was successfully deployed, use the ",(0,o.kt)("inlineCode",{parentName:"p"},"get-deploy")," subcommand, providing as a parameter the ",(0,o.kt)("inlineCode",{parentName:"p"},"deploy_hash")," received from the ",(0,o.kt)("inlineCode",{parentName:"p"},"put-deploy")," above."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832\n")),(0,o.kt)("p",null,"This should return a JSON output containing information such as header data, approvers and payments. You can also receive this information by using the ",(0,o.kt)("inlineCode",{parentName:"p"},"verbose")," flag with the ",(0,o.kt)("inlineCode",{parentName:"p"},"put-deploy")," subcommand. Take time to familiarize yourself with the structure of the output."),(0,o.kt)("p",null,"We can use the supplied deploy hash, ",(0,o.kt)("inlineCode",{parentName:"p"},"af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832")," to find this contract using a block explorer. When viewed through the explorer, the status of the Deploy should be marked as ",(0,o.kt)("inlineCode",{parentName:"p"},"Success"),"."),(0,o.kt)("p",null,"From your ",(0,o.kt)("inlineCode",{parentName:"p"},"cspr.live")," account, you will find a tab called ",(0,o.kt)("inlineCode",{parentName:"p"},"NamedKeys"),". This tab includes a list of all contracts deployed using the private key connected to your account."),(0,o.kt)("p",null,"By clicking the contract hash, you can see all entry points included in the contract, as well as the ",(0,o.kt)("inlineCode",{parentName:"p"},"NamedKeys")," under which your contract\u2019s name is stored. You should keep these named keys organized to avoid losing track while creating larger implementations."),(0,o.kt)("p",null,"An additional tab, ",(0,o.kt)("inlineCode",{parentName:"p"},"Deploys"),", that is currently empty. If our contract included a cross-contract call that called an entry point from another contract, it would appear here. For now, we can note the hash of the contract, which is ",(0,o.kt)("inlineCode",{parentName:"p"},"hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea"),"."),(0,o.kt)("h2",{id:"cross-contract"},"Create Another Contract for the Cross-Contract Call"),(0,o.kt)("p",null,"This section describes the process of writing an additional contract, which will use an entry point titled ",(0,o.kt)("inlineCode",{parentName:"p"},"call_contract_2")," to invoke the ",(0,o.kt)("inlineCode",{parentName:"p"},"update_msg")," entry point on the previous contract."),(0,o.kt)("p",null,"In this tutorial we will be passing the contract hash, as an argument, into the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," entry point and use this to perform the calls to the destination contract."),(0,o.kt)("p",null,"Prepare the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," entry point as described below:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'\n#[no_mangle]\npub extern "C" fn call() {\n\n // Create the list of required runtime arguments for the given entry point.\n let mut vec = Vec::new();\n vec.push(Parameter::new("new_message", CLType::String));\n vec.push(Parameter::new("hello_world_contract", CLType::Key));\n\n // In the named keys of the contract, add a key for the count.\n let mut named_keys = NamedKeys::new();\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Add the entry point metadata definition.\n entry_points.add_entry_point(EntryPoint::new(\n "call_contract_2",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys\n Some("contract2_package_name".to_string()), // package name\n Some("contract2_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("cross_contract_2", stored_contract_hash.into());\n}\n\n')),(0,o.kt)("p",null,"This would be the easiest implementation of the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," entry point. There is only one entry point which accepts the key ",(0,o.kt)("inlineCode",{parentName:"p"},"contract2")," of type ",(0,o.kt)("inlineCode",{parentName:"p"},"String")," and the key ",(0,o.kt)("inlineCode",{parentName:"p"},"hello_world_contract")," of the type ",(0,o.kt)("inlineCode",{parentName:"p"},"Key"),". There aren't any named keys which will be saved in the contract's context. The contract is then stored in global state and placed as an entry within the account's named keys."),(0,o.kt)("p",null,"Now that we have defined the metadata for the ",(0,o.kt)("inlineCode",{parentName:"p"},"call_contract_2")," entry point, we must now define the entry point itself. This entry point will take the second contract hash as an argument and call the entry point ",(0,o.kt)("inlineCode",{parentName:"p"},"update_msg"),". It will then pass a message to the second contract as a parameter, which will be stored in that contract\u2019s context."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'#[no_mangle]\npub extern "C" fn call_contract_2() {\n\n // Get the contract hash from the named arguments passed to the `call_contract_2` entry point.\n let contract_hash: ContractHash = runtime::get_named_arg::(CONTRACT_HASH)\n .into_hash()\n .map(|hash| ContractHash::new(hash))\n .unwrap();\n\n // Get the value of the message from the second parameter\n let new_value: String = runtime::get_named_arg("new_message");\n\n // Call the update_msg entry point on the other contract with the parameter values\n let _: () = runtime::call_contract(\n contract_hash,\n "update_msg",\n runtime_args! {\n "message" => new_value,\n },\n );\n\n}\n')),(0,o.kt)("p",null,"Your complete contract implementation should look as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'\n#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types\nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse crate::alloc::string::ToString;\nuse crate::runtime_args::RuntimeArgs;\n\n// Casper crates\nuse casper_types::{\n api_error::ApiError,\n contracts::NamedKeys, runtime_args, CLType, Key, ContractHash, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n unwrap_or_revert::UnwrapOrRevert,\n contract_api::{runtime, storage},\n};\n\n// The contract key in the account named keys\nconst CONTRACT_HASH: &str = "hello_world_contract";\n\n#[no_mangle]\npub extern "C" fn call_contract_2() {\n\n let contract_hash: ContractHash = runtime::get_named_arg::(CONTRACT_HASH)\n .into_hash()\n .map(|hash| ContractHash::new(hash))\n .unwrap();\n\n let new_value: String = runtime::get_named_arg("new_message");\n\n let _: () = runtime::call_contract(\n contract_hash,\n "update_msg",\n runtime_args! {\n // key => value\n "message" => new_value,\n },\n );\n\n}\n\n#[no_mangle]\npub extern "C" fn call() {\n\n // Create a new vector - this will be the signature of the entrypoint\n let mut vec = Vec::new();\n vec.push(Parameter::new("new_message", CLType::String));\n vec.push(Parameter::new("hello_world_contract", CLType::Key));\n\n // In the named keys of the contract, add a key for the count.\n let named_keys = NamedKeys::new();\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Add the entry point to the entry points object\n entry_points.add_entry_point(EntryPoint::new(\n "call_contract_2",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys\n Some("contract2_package_name".to_string()), // package name\n Some("contract2_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("cross_contract_2", stored_contract_hash.into());\n\n}\n')),(0,o.kt)("p",null,"After you run ",(0,o.kt)("inlineCode",{parentName:"p"},"make build-contract")," in your second contract's directory, you should obtain the outcome:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cd contract && cargo build --release --target wasm32-unknown-unknown\n Compiling contract v0.1.0 (/Users/karolmarter/Desktop/Rust_Projects/cross-contract-2/contract)\n Finished release [optimized] target(s) in 0.69s\nwasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n")),(0,o.kt)("p",null,"Create the ",(0,o.kt)("inlineCode",{parentName:"p"},"keys")," subfolder and copy the keys from the ",(0,o.kt)("inlineCode",{parentName:"p"},"keys")," subfolder in the first contract into this subfolder. The call from the terminal will look as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"You may have noticed that the contract.wasm is always output to the same filename for each new ",(0,o.kt)("inlineCode",{parentName:"p"},"cargo casper")," project. You can change this by editing the ",(0,o.kt)("inlineCode",{parentName:"p"},"Makefile")," in the main directory. You can then observe the result by recompiling your contract with these commands;"),(0,o.kt)("pre",{parentName:"admonition"},(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"make prepare\nmake build-contract\n"))),(0,o.kt)("p",null,"After the deploy we can check if it was successful and inspect the runtime arguments of the deployed entry points."),(0,o.kt)("p",null,"The result of invoking the ",(0,o.kt)("inlineCode",{parentName:"p"},"put-deploy")," subcommand is:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -7557689417621513622,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "faeb7e4f010c20c88d2dd126da545933c26fd8ce370282b8cd49f7f6fe7304b9"\n }\n}\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"If the contract name doesn't change during concurrent deploys, the urefs/hashes will be overwritten in the account's named keys.")),(0,o.kt)("p",null,"Observing the deploy, we can see that it succeeded:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832\n")),(0,o.kt)("p",null,"In the ",(0,o.kt)("inlineCode",{parentName:"p"},"execution_results"),' JSON element we should see "Success".'),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'\n "execution_results": [\n {\n "block_hash": "bc3040214e46fe0eaa9d98150a8a67a1033b931619dbc3e5f1a841d3a2d6f869",\n "result": {\n "Success": {\n "cost": "16580565260",\n "effect": { ...\n\n }\n }\n }\n }\n ]\n\n')),(0,o.kt)("p",null,"Get the state root hash of the current network state:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address http://136.243.187.84:7777\n")),(0,o.kt)("p",null,"The result of invoking the",(0,o.kt)("inlineCode",{parentName:"p"},"get-state-root-hash")," command is:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -3631326529646611302,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "state_root_hash": "2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb"\n }\n}\n')),(0,o.kt)("p",null,"Query the state of Casper network using the account hash:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"}," casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9\n")),(0,o.kt)("p",null,"If we check the account's named keys, we can see all of the account's deployed contracts:"),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Account's named keys"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -6842818667609668962,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[30424 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "weight": 1\n }\n ],\n "main_purse": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",\n "named_keys": [\n {\n "key": "uref-94c54f24273f1fb874eff33f3d4211a254622edfd1b980d5e758bd719b46fd0d-007",\n "name": "Hello_world_access_uref"\n },\n {\n "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "name": "Hello_world_package_name"\n },\n {\n "key": "uref-ae2f94bf959ec06a80b2035f31d7e4c65c01bf24bbbf794a473bc743c4b2f655-007",\n "name": "contract2_access_uref"\n },\n {\n "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",\n "name": "contract2_package_name"\n },\n {\n "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",\n "name": "cross_contract_2"\n },\n {\n "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "name": "hello_world_contract"\n }\n ]\n }\n }\n }\n}\n'))),(0,o.kt)("br",null),(0,o.kt)("p",null,"As we have now managed to deploy two contracts, we can call the entry point of this contract, passing appropriate arguments to the function."),(0,o.kt)("p",null,"The Uref of the message variable is stored under the Named Keys in the contract."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": 2434670480361972874,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[25224 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-wasm7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "contract_wasm_hash": "contract-wasm-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",\n "entry_points": [\n {\n "access": "Public",\n "args": [\n {\n "cl_type": "String",\n "name": "message"\n }\n ],\n "entry_point_type": "Contract",\n "name": "update_msg",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-007",\n "name": "message"\n }\n ],\n "protocol_version": "1.4.13"\n }\n }\n }\n}\n')),(0,o.kt)("p",null,"Checking the state of the message in the first contract, we observe the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"\n')),(0,o.kt)("p",null,"This is a simple ",(0,o.kt)("inlineCode",{parentName:"p"},"hello world")," string. After invoking the entry point using the command below this value should change."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},(0,o.kt)("inlineCode",{parentName:"p"},"--session-hash")," - is the contract hash, which is returned from the put-deploy."),(0,o.kt)("p",{parentName:"admonition"},(0,o.kt)("inlineCode",{parentName:"p"},"--session-arg"),' "hello world_contract:Key= ..." - the hash of the contract which we want to call from within the contract identified by the session-hash.')),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-hash hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92 \\\n --session-entry-point "call_contract_2" \\\n --session-arg "new_message:string=\'Hello new message!\'" \\\n --session-arg "hello_world_contract:Key=\'hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea\'"\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The contract hash has to be of type ",(0,o.kt)("inlineCode",{parentName:"p"},"ContractHash")," in the contract itself. We can pass the hash as a ",(0,o.kt)("inlineCode",{parentName:"p"},"Key")," argument and change it to ",(0,o.kt)("inlineCode",{parentName:"p"},"ContractHash")," in the smart contract.")),(0,o.kt)("p",null,"The output of the above command is:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -6419793201665396463,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537"\n }\n}\n')),(0,o.kt)("p",null,"Check the deploy with:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537\n")),(0,o.kt)("p",null,"After the deploy finishes successfully, you should see a similar outcome to the following:"),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Deploy details"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": 3968762702269106998,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy": {\n "approvals": [\n {\n "signature": "01319eee9bcfde6963e5b47164dd2c8044f0c20dd59f0c2993db55bec6bd3802fec2c9c6cae6ca8993c8aee0440be43f6c38bdc4bbdce501837ff5ca66fbd7c902",\n "signer": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af"\n }\n ],\n "hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "header": {\n "account": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af",\n "body_hash": "26282fa50b8e7c240025d683f197661ca846f2c1a3521a5dd604e6066d89d6d7",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2023-03-09T14:39:24.974Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "0500c817a804",\n "cl_type": "U512",\n "parsed": "20000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "StoredContractByHash": {\n "args": [\n [\n "new_message",\n {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n ],\n [\n "hello_world_contract",\n {\n "bytes": "01b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "cl_type": "Key",\n "parsed": {\n "Hash": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea"\n }\n }\n ]\n ],\n "entry_point": "call_contract_2",\n "hash": "32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "9c81259ac5ef7b953656a9327a479ae771a15c5ef131c91216e9e697dfdb09eb",\n "result": {\n "Success": {\n "cost": "462273650",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",\n "transform": {\n "WriteCLValue": {\n "bytes": "0600876bf27301",\n "cl_type": "U512",\n "parsed": "1597500000000"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "20000000000"\n }\n },\n {\n "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",\n "transform": "Identity"\n },\n {\n "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",\n "transform": "Identity"\n },\n {\n "key": "hash-b48ccc725ba948405d01205e64acff09ac24c899aed8d649f7bc1572216266c2",\n "transform": "Identity"\n },\n {\n "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "transform": "Identity"\n },\n {\n "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "transform": "Identity"\n },\n {\n "key": "hash-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",\n "transform": "Identity"\n },\n {\n "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n }\n },\n {\n "key": "deploy-15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "from": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "gas": "462273650",\n "source": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",\n "transfers": []\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",\n "transform": {\n "AddUInt512": "20000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'))),(0,o.kt)("br",null),(0,o.kt)("p",null,"We would expect that the value of the message reference in the other contract would have changed, which we can check:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"\n')),(0,o.kt)("p",null,"The output of the above command is:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -5477027327608594231,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[61444 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n }\n }\n}\n')),(0,o.kt)("p",null,"With this we have succeeded in cross-contract communication between two contracts."),(0,o.kt)("h2",{id:"summary"},"Summary"),(0,o.kt)("p",null,"In this tutorial, we:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Developed two Rust contracts on a Casper network, where one smart contract is calling an entry point of the second smart contract"),(0,o.kt)("li",{parentName:"ul"},"Called an entry point on one contract from the other contract, passing a value as an argument to this entry point.")))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[4970],{3905:function(e,n,t){t.d(n,{Zo:function(){return d},kt:function(){return m}});var a=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function c(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var i=a.createContext({}),l=function(e){var n=a.useContext(i),t=n;return e&&(t="function"==typeof e?e(n):c(c({},n),e)),t},d=function(e){var n=l(e.components);return a.createElement(i.Provider,{value:n},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=l(t),u=r,m=p["".concat(i,".").concat(u)]||p[u]||h[u]||o;return t?a.createElement(m,c(c({ref:n},d),{},{components:t})):a.createElement(m,c({ref:n},d))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,c=new Array(o);c[0]=u;var s={};for(var i in n)hasOwnProperty.call(n,i)&&(s[i]=n[i]);s.originalType=e,s[p]="string"==typeof e?e:r,c[1]=s;for(var l=2;l = BTreeMap::new();\n\n // Insert the new value into the named keys\n named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the Uref into a casper_types::Key\n // Create a new vector\n let mut params = Vec::new();\n vec.push(Parameter::new("message", CLType::String));\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Describing the metadata for the entry point\n entry_points.add_entry_point(EntryPoint::new(\n "update_msg", // the name of the entry point\n vec, // the arguments which can be passed into the entry point\n CLType::Unit, // return type of the entry point\n EntryPointAccess::Public, // access permissions - public can be accessed always\n EntryPointType::Contract // in most cases it will be contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys\n Some("Hello_world_package_name".to_string()), // package name\n Some("Hello_world_access_uref".to_string()) // access uref\n );\n\n // To access the contract hash from the accounts named keys\n runtime::put_key("hello_world_contract", stored_contract_hash.into());\n\n}\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},(0,o.kt)("inlineCode",{parentName:"p"},"runtime")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"storage")," appear frequently in our code. If these terms are unfamiliar to you, you should familiarize yourself with the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/index.html"},"Contract API Modules"),".")),(0,o.kt)("p",null,"The metadata for each of the contract's entry points is defined in the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," entry point. When installing the contract, the system will look for the name of the entry point as specified by the metadata for that entry point. Therefore, each of the entry points defined in the code must share the same name as the ",(0,o.kt)("inlineCode",{parentName:"p"},"String")," value passed when defining the metadata for the entry point."),(0,o.kt)("p",null,"The #","[no_mangle]"," flag ensures that the compiler does not modify the name of the entry point. The compiler will not enforce the condition that the name of the entry point is the same value present in its metadata definition, therefore the developer must be careful when defining their entry points."),(0,o.kt)("p",null,"In our case, we will define the entry point ",(0,o.kt)("inlineCode",{parentName:"p"},"update_msg")," in the contract code just before ",(0,o.kt)("inlineCode",{parentName:"p"},"call"),"."),(0,o.kt)("p",null,"Your complete contract should match the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types\nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n#[no_mangle]\npub extern "C" fn update_msg() {\n\n let value: String = runtime::get_named_arg("message");\n // Get the uref of the message stored in global state\n let uref = runtime::get_key("message").unwrap_or_revert().into_uref().unwrap_or_revert();\n // Write the message to global state\n storage::write(uref, String::from(value));\n}\n\n\n#[no_mangle]\npub extern "C" fn call() {\n // Get the value of a passed parameter with the key "message"\n let value: String = runtime::get_named_arg("message");\n // The value will be wraped in a URef\n let value_ref = storage::new_uref(value);\n // Creating the new set of named keys\n // The keys are a Map of Key/Value\n let mut named_keys: BTreeMap = BTreeMap::new();\n // Insert the new value into the named keys\n named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the value to the key\n // Create a new vector\n let mut vec = Vec::new();\n vec.push(Parameter::new("message", CLType::String));\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Define the metadata for the entry point `update_msg`\n entry_points.add_entry_point(EntryPoint::new(\n "update_msg",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points metadata\n Some(named_keys), // named keys\n Some("Hello_world_package_name".to_string()), // package name\n Some("Hello_world_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("hello_world_contract", stored_contract_hash.into());\n}\n')),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"There is a distinction between storing data in a contract\u2019s ",(0,o.kt)("inlineCode",{parentName:"p"},"NamedKeys")," and using a dictionary. ",(0,o.kt)("a",{parentName:"p",href:"/concepts/dictionaries"},"Dictionaries")," can be used to store dApp-centric data, but they are not a SQL database and should only be used for data that needs to be stored in global state. Objects referenced in a contract should only be used as links within a bigger application.")),(0,o.kt)("h2",{id:"deploying-contract"},"Deploying the Contract"),(0,o.kt)("p",null,"There are many tools available to send a deploy to a Casper network. The simplest method is to use the Rust CLI with the subcommand ",(0,o.kt)("a",{parentName:"p",href:"/developers/cli/installing-contracts#installing-contract-code"},"put_deploy"),"."),(0,o.kt)("p",null,"Be sure to go through the prerequisites from the ",(0,o.kt)("a",{parentName:"p",href:"/developers/cli/installing-contracts"},"Installing Smart Contracts and Querying Global State")," documentation."),(0,o.kt)("p",null,"Make sure that after doing this you have:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"A valid private key for your account."),(0,o.kt)("li",{parentName:"ol"},"Funded your account with 2000 CSPR on the Testnet, which you can use for testing your smart contract.")),(0,o.kt)("p",null,"Create the ",(0,o.kt)("inlineCode",{parentName:"p"},"keys")," folder in the main folder of your project and make sure that the private key which you put into the folder is called ",(0,o.kt)("inlineCode",{parentName:"p"},"secret_key.pem"),"."),(0,o.kt)("p",null,"Compile the contract in the contract directory so you obtain the contracts ",(0,o.kt)("inlineCode",{parentName:"p"},".wasm"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cd cross-contract\nmake prepare\nmake build-contract\n")),(0,o.kt)("p",null,"This should produce the following outcome:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cd contract && cargo build --release --target wasm32-unknown-unknown\n Finished release [optimized] target(s) in 0.13s\nwasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n")),(0,o.kt)("p",null,"With this step everything is in place to deploy the contract."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"When working with lengthy command strings, it may help to maintain a .txt file where you can edit the runtime arguments of the commands before sending them to the CLI. This will save you time and frustration when working with multiple contracts and commands.")),(0,o.kt)("p",null,"Since we are using a default contract structure, the command called from the ",(0,o.kt)("inlineCode",{parentName:"p"},"cross-contract")," folder should be the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n --session-arg \"message:string='hello world'\"\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The parameters used in this command need to be adjusted based on your use case. For details, see ",(0,o.kt)("a",{parentName:"p",href:"/developers/prerequisites#acquire-node-address-from-network-peers"},"querying a node")," and ",(0,o.kt)("a",{parentName:"p",href:"/developers/cli/installing-contracts"},"installing contracts"),". The payment amount may also need to be adjusted based on the latest Testnet ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),".")),(0,o.kt)("p",null,"The output of this command is:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -9119604526598719721,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832"\n }\n}\n')),(0,o.kt)("p",null,"To verify that the contract was successfully deployed, use the ",(0,o.kt)("inlineCode",{parentName:"p"},"get-deploy")," subcommand, providing as a parameter the ",(0,o.kt)("inlineCode",{parentName:"p"},"deploy_hash")," received from the ",(0,o.kt)("inlineCode",{parentName:"p"},"put-deploy")," above."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832\n")),(0,o.kt)("p",null,"This should return a JSON output containing information such as header data, approvers and payments. You can also receive this information by using the ",(0,o.kt)("inlineCode",{parentName:"p"},"verbose")," flag with the ",(0,o.kt)("inlineCode",{parentName:"p"},"put-deploy")," subcommand. Take time to familiarize yourself with the structure of the output."),(0,o.kt)("p",null,"We can use the supplied deploy hash, ",(0,o.kt)("inlineCode",{parentName:"p"},"af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832")," to find this contract using a block explorer. When viewed through the explorer, the status of the Deploy should be marked as ",(0,o.kt)("inlineCode",{parentName:"p"},"Success"),"."),(0,o.kt)("p",null,"From your ",(0,o.kt)("inlineCode",{parentName:"p"},"cspr.live")," account, you will find a tab called ",(0,o.kt)("inlineCode",{parentName:"p"},"NamedKeys"),". This tab includes a list of all contracts deployed using the private key connected to your account."),(0,o.kt)("p",null,"By clicking the contract hash, you can see all entry points included in the contract, as well as the ",(0,o.kt)("inlineCode",{parentName:"p"},"NamedKeys")," under which your contract\u2019s name is stored. You should keep these named keys organized to avoid losing track while creating larger implementations."),(0,o.kt)("p",null,"An additional tab, ",(0,o.kt)("inlineCode",{parentName:"p"},"Deploys"),", that is currently empty. If our contract included a cross-contract call that called an entry point from another contract, it would appear here. For now, we can note the hash of the contract, which is ",(0,o.kt)("inlineCode",{parentName:"p"},"hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea"),"."),(0,o.kt)("h2",{id:"cross-contract"},"Create Another Contract for the Cross-Contract Call"),(0,o.kt)("p",null,"This section describes the process of writing an additional contract, which will use an entry point titled ",(0,o.kt)("inlineCode",{parentName:"p"},"call_contract_2")," to invoke the ",(0,o.kt)("inlineCode",{parentName:"p"},"update_msg")," entry point on the previous contract."),(0,o.kt)("p",null,"In this tutorial we will be passing the contract hash, as an argument, into the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," entry point and use this to perform the calls to the destination contract."),(0,o.kt)("p",null,"Prepare the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," entry point as described below:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'\n#[no_mangle]\npub extern "C" fn call() {\n\n // Create the list of required runtime arguments for the given entry point.\n let mut vec = Vec::new();\n vec.push(Parameter::new("new_message", CLType::String));\n vec.push(Parameter::new("hello_world_contract", CLType::Key));\n\n // In the named keys of the contract, add a key for the count.\n let mut named_keys = NamedKeys::new();\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Add the entry point metadata definition.\n entry_points.add_entry_point(EntryPoint::new(\n "call_contract_2",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys\n Some("contract2_package_name".to_string()), // package name\n Some("contract2_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("cross_contract_2", stored_contract_hash.into());\n}\n\n')),(0,o.kt)("p",null,"This would be the easiest implementation of the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," entry point. There is only one entry point which accepts the key ",(0,o.kt)("inlineCode",{parentName:"p"},"contract2")," of type ",(0,o.kt)("inlineCode",{parentName:"p"},"String")," and the key ",(0,o.kt)("inlineCode",{parentName:"p"},"hello_world_contract")," of the type ",(0,o.kt)("inlineCode",{parentName:"p"},"Key"),". There aren't any named keys which will be saved in the contract's context. The contract is then stored in global state and placed as an entry within the account's named keys."),(0,o.kt)("p",null,"Now that we have defined the metadata for the ",(0,o.kt)("inlineCode",{parentName:"p"},"call_contract_2")," entry point, we must now define the entry point itself. This entry point will take the second contract hash as an argument and call the entry point ",(0,o.kt)("inlineCode",{parentName:"p"},"update_msg"),". It will then pass a message to the second contract as a parameter, which will be stored in that contract\u2019s context."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'#[no_mangle]\npub extern "C" fn call_contract_2() {\n\n // Get the contract hash from the named arguments passed to the `call_contract_2` entry point.\n let contract_hash: ContractHash = runtime::get_named_arg::(CONTRACT_HASH)\n .into_hash()\n .map(|hash| ContractHash::new(hash))\n .unwrap();\n\n // Get the value of the message from the second parameter\n let new_value: String = runtime::get_named_arg("new_message");\n\n // Call the update_msg entry point on the other contract with the parameter values\n let _: () = runtime::call_contract(\n contract_hash,\n "update_msg",\n runtime_args! {\n "message" => new_value,\n },\n );\n\n}\n')),(0,o.kt)("p",null,"Your complete contract implementation should look as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'\n#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types\nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse crate::alloc::string::ToString;\nuse crate::runtime_args::RuntimeArgs;\n\n// Casper crates\nuse casper_types::{\n api_error::ApiError,\n contracts::NamedKeys, runtime_args, CLType, Key, ContractHash, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n unwrap_or_revert::UnwrapOrRevert,\n contract_api::{runtime, storage},\n};\n\n// The contract key in the account named keys\nconst CONTRACT_HASH: &str = "hello_world_contract";\n\n#[no_mangle]\npub extern "C" fn call_contract_2() {\n\n let contract_hash: ContractHash = runtime::get_named_arg::(CONTRACT_HASH)\n .into_hash()\n .map(|hash| ContractHash::new(hash))\n .unwrap();\n\n let new_value: String = runtime::get_named_arg("new_message");\n\n let _: () = runtime::call_contract(\n contract_hash,\n "update_msg",\n runtime_args! {\n // key => value\n "message" => new_value,\n },\n );\n\n}\n\n#[no_mangle]\npub extern "C" fn call() {\n\n // Create a new vector - this will be the signature of the entrypoint\n let mut vec = Vec::new();\n vec.push(Parameter::new("new_message", CLType::String));\n vec.push(Parameter::new("hello_world_contract", CLType::Key));\n\n // In the named keys of the contract, add a key for the count.\n let named_keys = NamedKeys::new();\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Add the entry point to the entry points object\n entry_points.add_entry_point(EntryPoint::new(\n "call_contract_2",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys\n Some("contract2_package_name".to_string()), // package name\n Some("contract2_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("cross_contract_2", stored_contract_hash.into());\n\n}\n')),(0,o.kt)("p",null,"After you run ",(0,o.kt)("inlineCode",{parentName:"p"},"make build-contract")," in your second contract's directory, you should obtain the outcome:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cd contract && cargo build --release --target wasm32-unknown-unknown\n Compiling contract v0.1.0 (/Users/karolmarter/Desktop/Rust_Projects/cross-contract-2/contract)\n Finished release [optimized] target(s) in 0.69s\nwasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n")),(0,o.kt)("p",null,"Create the ",(0,o.kt)("inlineCode",{parentName:"p"},"keys")," subfolder and copy the keys from the ",(0,o.kt)("inlineCode",{parentName:"p"},"keys")," subfolder in the first contract into this subfolder. The call from the terminal will look as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"You may have noticed that the contract.wasm is always output to the same filename for each new ",(0,o.kt)("inlineCode",{parentName:"p"},"cargo casper")," project. You can change this by editing the ",(0,o.kt)("inlineCode",{parentName:"p"},"Makefile")," in the main directory. You can then observe the result by recompiling your contract with these commands;"),(0,o.kt)("pre",{parentName:"admonition"},(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"make prepare\nmake build-contract\n"))),(0,o.kt)("p",null,"After the deploy we can check if it was successful and inspect the runtime arguments of the deployed entry points."),(0,o.kt)("p",null,"The result of invoking the ",(0,o.kt)("inlineCode",{parentName:"p"},"put-deploy")," subcommand is:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -7557689417621513622,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "faeb7e4f010c20c88d2dd126da545933c26fd8ce370282b8cd49f7f6fe7304b9"\n }\n}\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"If the contract name doesn't change during concurrent deploys, the urefs/hashes will be overwritten in the account's named keys.")),(0,o.kt)("p",null,"Observing the deploy, we can see that it succeeded:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832\n")),(0,o.kt)("p",null,"In the ",(0,o.kt)("inlineCode",{parentName:"p"},"execution_results"),' JSON element we should see "Success".'),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'\n "execution_results": [\n {\n "block_hash": "bc3040214e46fe0eaa9d98150a8a67a1033b931619dbc3e5f1a841d3a2d6f869",\n "result": {\n "Success": {\n "cost": "16580565260",\n "effect": { ...\n\n }\n }\n }\n }\n ]\n\n')),(0,o.kt)("p",null,"Get the state root hash of the current network state:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address http://136.243.187.84:7777\n")),(0,o.kt)("p",null,"The result of invoking the",(0,o.kt)("inlineCode",{parentName:"p"},"get-state-root-hash")," command is:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -3631326529646611302,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "state_root_hash": "2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb"\n }\n}\n')),(0,o.kt)("p",null,"Query the state of Casper network using the account hash:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"}," casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9\n")),(0,o.kt)("p",null,"If we check the account's named keys, we can see all of the account's deployed contracts:"),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Account's named keys"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -6842818667609668962,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[30424 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "weight": 1\n }\n ],\n "main_purse": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",\n "named_keys": [\n {\n "key": "uref-94c54f24273f1fb874eff33f3d4211a254622edfd1b980d5e758bd719b46fd0d-007",\n "name": "Hello_world_access_uref"\n },\n {\n "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "name": "Hello_world_package_name"\n },\n {\n "key": "uref-ae2f94bf959ec06a80b2035f31d7e4c65c01bf24bbbf794a473bc743c4b2f655-007",\n "name": "contract2_access_uref"\n },\n {\n "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",\n "name": "contract2_package_name"\n },\n {\n "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",\n "name": "cross_contract_2"\n },\n {\n "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "name": "hello_world_contract"\n }\n ]\n }\n }\n }\n}\n'))),(0,o.kt)("br",null),(0,o.kt)("p",null,"As we have now managed to deploy two contracts, we can call the entry point of this contract, passing appropriate arguments to the function."),(0,o.kt)("p",null,"The Uref of the message variable is stored under the Named Keys in the contract."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": 2434670480361972874,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[25224 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-wasm7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "contract_wasm_hash": "contract-wasm-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",\n "entry_points": [\n {\n "access": "Public",\n "args": [\n {\n "cl_type": "String",\n "name": "message"\n }\n ],\n "entry_point_type": "Contract",\n "name": "update_msg",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-007",\n "name": "message"\n }\n ],\n "protocol_version": "1.4.13"\n }\n }\n }\n}\n')),(0,o.kt)("p",null,"Checking the state of the message in the first contract, we observe the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"\n')),(0,o.kt)("p",null,"This is a simple ",(0,o.kt)("inlineCode",{parentName:"p"},"hello world")," string. After invoking the entry point using the command below this value should change."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},(0,o.kt)("inlineCode",{parentName:"p"},"--session-hash")," - is the contract hash, which is returned from the put-deploy."),(0,o.kt)("p",{parentName:"admonition"},(0,o.kt)("inlineCode",{parentName:"p"},"--session-arg"),' "hello world_contract:Key= ..." - the hash of the contract which we want to call from within the contract identified by the session-hash.')),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-hash hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92 \\\n --session-entry-point "call_contract_2" \\\n --session-arg "new_message:string=\'Hello new message!\'" \\\n --session-arg "hello_world_contract:Key=\'hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea\'"\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The contract hash has to be of type ",(0,o.kt)("inlineCode",{parentName:"p"},"ContractHash")," in the contract itself. We can pass the hash as a ",(0,o.kt)("inlineCode",{parentName:"p"},"Key")," argument and change it to ",(0,o.kt)("inlineCode",{parentName:"p"},"ContractHash")," in the smart contract.")),(0,o.kt)("p",null,"The output of the above command is:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -6419793201665396463,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537"\n }\n}\n')),(0,o.kt)("p",null,"Check the deploy with:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537\n")),(0,o.kt)("p",null,"After the deploy finishes successfully, you should see a similar outcome to the following:"),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Deploy details"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": 3968762702269106998,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy": {\n "approvals": [\n {\n "signature": "01319eee9bcfde6963e5b47164dd2c8044f0c20dd59f0c2993db55bec6bd3802fec2c9c6cae6ca8993c8aee0440be43f6c38bdc4bbdce501837ff5ca66fbd7c902",\n "signer": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af"\n }\n ],\n "hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "header": {\n "account": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af",\n "body_hash": "26282fa50b8e7c240025d683f197661ca846f2c1a3521a5dd604e6066d89d6d7",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2023-03-09T14:39:24.974Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "0500c817a804",\n "cl_type": "U512",\n "parsed": "20000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "StoredContractByHash": {\n "args": [\n [\n "new_message",\n {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n ],\n [\n "hello_world_contract",\n {\n "bytes": "01b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "cl_type": "Key",\n "parsed": {\n "Hash": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea"\n }\n }\n ]\n ],\n "entry_point": "call_contract_2",\n "hash": "32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "9c81259ac5ef7b953656a9327a479ae771a15c5ef131c91216e9e697dfdb09eb",\n "result": {\n "Success": {\n "cost": "462273650",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",\n "transform": {\n "WriteCLValue": {\n "bytes": "0600876bf27301",\n "cl_type": "U512",\n "parsed": "1597500000000"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "20000000000"\n }\n },\n {\n "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",\n "transform": "Identity"\n },\n {\n "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",\n "transform": "Identity"\n },\n {\n "key": "hash-b48ccc725ba948405d01205e64acff09ac24c899aed8d649f7bc1572216266c2",\n "transform": "Identity"\n },\n {\n "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "transform": "Identity"\n },\n {\n "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "transform": "Identity"\n },\n {\n "key": "hash-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",\n "transform": "Identity"\n },\n {\n "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n }\n },\n {\n "key": "deploy-15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "from": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "gas": "462273650",\n "source": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",\n "transfers": []\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",\n "transform": {\n "AddUInt512": "20000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'))),(0,o.kt)("br",null),(0,o.kt)("p",null,"We would expect that the value of the message reference in the other contract would have changed, which we can check:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"\n')),(0,o.kt)("p",null,"The output of the above command is:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -5477027327608594231,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[61444 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n }\n }\n}\n')),(0,o.kt)("p",null,"With this we have succeeded in cross-contract communication between two contracts."),(0,o.kt)("h2",{id:"summary"},"Summary"),(0,o.kt)("p",null,"In this tutorial, we:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Developed two Rust contracts on a Casper network, where one smart contract is calling an entry point of the second smart contract"),(0,o.kt)("li",{parentName:"ul"},"Called an entry point on one contract from the other contract, passing a value as an argument to this entry point.")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/725b7e74.ef17b217.js b/assets/js/725b7e74.4f95983b.js similarity index 98% rename from assets/js/725b7e74.ef17b217.js rename to assets/js/725b7e74.4f95983b.js index 664f5fd755..360dec2c6e 100644 --- a/assets/js/725b7e74.ef17b217.js +++ b/assets/js/725b7e74.4f95983b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6958],{3905:function(e,n,t){t.d(n,{Zo:function(){return l},kt:function(){return h}});var a=t(7294);function s(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function r(e){for(var n=1;n=0||(s[t]=e[t]);return s}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(s[t]=e[t])}return s}var i=a.createContext({}),u=function(e){var n=a.useContext(i),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},l=function(e){var n=u(e.components);return a.createElement(i.Provider,{value:n},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},m=a.forwardRef((function(e,n){var t=e.components,s=e.mdxType,o=e.originalType,i=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),d=u(t),m=s,h=d["".concat(i,".").concat(m)]||d[m]||p[m]||o;return t?a.createElement(h,r(r({ref:n},l),{},{components:t})):a.createElement(h,r({ref:n},l))}));function h(e,n){var t=arguments,s=n&&n.mdxType;if("string"==typeof e||s){var o=t.length,r=new Array(o);r[0]=m;var c={};for(var i in n)hasOwnProperty.call(n,i)&&(c[i]=n[i]);c.originalType=e,c[d]="string"==typeof e?e:s,r[1]=c;for(var u=2;u=0||(s[t]=e[t]);return s}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(s[t]=e[t])}return s}var i=a.createContext({}),u=function(e){var n=a.useContext(i),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},l=function(e){var n=u(e.components);return a.createElement(i.Provider,{value:n},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},m=a.forwardRef((function(e,n){var t=e.components,s=e.mdxType,o=e.originalType,i=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),d=u(t),m=s,h=d["".concat(i,".").concat(m)]||d[m]||p[m]||o;return t?a.createElement(h,r(r({ref:n},l),{},{components:t})):a.createElement(h,r({ref:n},l))}));function h(e,n){var t=arguments,s=n&&n.mdxType;if("string"==typeof e||s){var o=t.length,r=new Array(o);r[0]=m;var c={};for(var i in n)hasOwnProperty.call(n,i)&&(c[i]=n[i]);c.originalType=e,c[d]="string"==typeof e?e:s,r[1]=c;for(var u=2;u=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),i=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=i(e.components);return a.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,c=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=i(n),f=r,h=p["".concat(c,".").concat(f)]||p[f]||u[f]||s;return n?a.createElement(h,o(o({ref:t},d),{},{components:n})):a.createElement(h,o({ref:t},d))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,o=new Array(s);o[0]=f;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[p]="string"==typeof e?e:r,o[1]=l;for(var i=2;i=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),i=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=i(e.components);return a.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,c=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=i(n),f=r,h=p["".concat(c,".").concat(f)]||p[f]||u[f]||s;return n?a.createElement(h,o(o({ref:t},d),{},{components:n})):a.createElement(h,o({ref:t},d))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,o=new Array(s);o[0]=f;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[p]="string"==typeof e?e:r,o[1]=l;for(var i=2;i=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),u=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),p=u(n),m=r,h=p["".concat(s,".").concat(m)]||p[m]||d[m]||l;return n?a.createElement(h,o(o({ref:t},c),{},{components:n})):a.createElement(h,o({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[p]="string"==typeof e?e:r,o[1]=i;for(var u=2;u 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.')})))?void 0:n.filter(Boolean))?t:[]}(e).map((function(e){var t=e.props;return{value:t.value,label:t.label,attributes:t.attributes,default:t.default}}))}function d(e){var t=e.values,n=e.children;return(0,r.useMemo)((function(){var e=null!=t?t:p(n);return function(e){var t=(0,u.l)(e,(function(e,t){return e.value===t.value}));if(t.length>0)throw new Error('Docusaurus error: Duplicate values "'+t.map((function(e){return e.value})).join(", ")+'" found in . Every value needs to be unique.')}(e),e}),[t,n])}function m(e){var t=e.value;return e.tabValues.some((function(e){return e.value===t}))}function h(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId,l=(0,i.k6)(),o=function(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId;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 null!=a?a:null}({queryString:n,groupId:a});return[(0,s._X)(o),(0,r.useCallback)((function(e){if(o){var t=new URLSearchParams(l.location.search);t.set(o,e),l.replace(Object.assign({},l.location,{search:t.toString()}))}}),[o,l])]}function k(e){var t,n,a,l,o=e.defaultValue,i=e.queryString,s=void 0!==i&&i,u=e.groupId,p=d(e),k=(0,r.useState)((function(){return function(e){var t,n=e.defaultValue,a=e.tabValues;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({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((function(e){return e.value})).join(", ")+". If you intend to show no default tab, use defaultValue={null} instead.");return n}var r=null!=(t=a.find((function(e){return e.default})))?t:a[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:o,tabValues:p})})),g=k[0],f=k[1],v=h({queryString:s,groupId:u}),b=v[0],y=v[1],N=(t=function(e){return e?"docusaurus.tab."+e:null}({groupId:u}.groupId),n=(0,c.Nk)(t),a=n[0],l=n[1],[a,(0,r.useCallback)((function(e){t&&l.set(e)}),[t,l])]),w=N[0],C=N[1],I=function(){var e=null!=b?b:w;return m({value:e,tabValues:p})?e:null}();return(0,r.useLayoutEffect)((function(){I&&f(I)}),[I]),{selectedValue:g,selectValue:(0,r.useCallback)((function(e){if(!m({value:e,tabValues:p}))throw new Error("Can't select invalid tab value="+e);f(e),y(e),C(e)}),[y,C,p]),tabValues:p}}var g=n(2389),f={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function v(e){var t=e.className,n=e.block,i=e.selectedValue,s=e.selectValue,u=e.tabValues,c=[],p=(0,o.o5)().blockElementScrollPositionUntilNextRender,d=function(e){var t=e.currentTarget,n=c.indexOf(t),a=u[n].value;a!==i&&(p(t),s(a))},m=function(e){var t,n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":var a,r=c.indexOf(e.currentTarget)+1;n=null!=(a=c[r])?a:c[0];break;case"ArrowLeft":var l,o=c.indexOf(e.currentTarget)-1;n=null!=(l=c[o])?l:c[c.length-1]}null==(t=n)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":n},t)},u.map((function(e){var t=e.value,n=e.label,o=e.attributes;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:function(e){return c.push(e)},onKeyDown:m,onClick:d},o,{className:(0,l.Z)("tabs__item",f.tabItem,null==o?void 0:o.className,{"tabs__item--active":i===t})}),null!=n?n:t)})))}function b(e){var t=e.lazy,n=e.children,a=e.selectedValue,l=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){var o=l.find((function(e){return e.props.value===a}));return o?(0,r.cloneElement)(o,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},l.map((function(e,t){return(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a})})))}function y(e){var t=k(e);return r.createElement("div",{className:(0,l.Z)("tabs-container",f.tabList)},r.createElement(v,(0,a.Z)({},e,t)),r.createElement(b,(0,a.Z)({},e,t)))}function N(e){var t=(0,g.Z)();return r.createElement(y,(0,a.Z)({key:String(t)},e))}},3235:function(e,t,n){n.r(t),n.d(t,{assets:function(){return d},contentTitle:function(){return c},default:function(){return g},frontMatter:function(){return u},metadata:function(){return p},toc:function(){return m}});var a=n(7462),r=n(3366),l=(n(7294),n(3905)),o=(n(4996),n(4866)),i=n(5162),s=["components"],u={},c="Development Prerequisites",p={unversionedId:"developers/prerequisites",id:"developers/prerequisites",title:"Development Prerequisites",description:"This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04 or macOS. Developing on Windows is not advised.",source:"@site/source/docs/casper/developers/prerequisites.md",sourceDirName:"developers",slug:"/developers/prerequisites",permalink:"/developers/prerequisites",draft:!1,editUrl:"https://github.com/casper-network/docs/tree/dev/source/docs/casper/developers/prerequisites.md",tags:[],version:"current",lastUpdatedAt:1707837031,formattedLastUpdatedAt:"Feb 13, 2024",frontMatter:{},sidebar:"developers",previous:{title:"Overview",permalink:"/developers"},next:{title:"Essential Rust Crates",permalink:"/developers/essential-crates"}},d={},m=[{value:"Preparing your Development Environment",id:"preparing-your-development-environment",level:2},{value:"Installing curl",id:"install-curl",level:3},{value:"Installing essential Linux packages",id:"install-essential",level:3},{value:"Installing packages required for Casper tools",id:"install-adds",level:3},{value:"Installing cargo on Linux",id:"install-linux-cargo",level:3},{value:"Installing Xcode developer tools for macOS",id:"install-xcode",level:3},{value:"Installing brew",id:"install-brew",level:3},{value:"Installing packages required for Casper tools",id:"install-adds-macos",level:3},{value:"Installing Rust",id:"install-rust",level:2},{value:"Installing the Casper Crates",id:"installing-the-casper-crates",level:2},{value:"Installing the Casper Client",id:"install-casper-client",level:2},{value:"Accessing the Casper client source code",id:"building-client-from-source",level:3},{value:"Installing CMake",id:"install-cmake",level:2},{value:"Installing an IDE",id:"installing-an-ide",level:2},{value:"Setting up a Casper Account",id:"setting-up-an-account",level:2},{value:"Creating an account",id:"creating-an-account",level:3},{value:"Generating the account hash",id:"generating-the-account-hash",level:3},{value:"Funding an Account",id:"fund-your-account",level:2},{value:"Acquiring a Node Address from the Network",id:"acquire-node-address-from-network-peers",level:2}],h={toc:m},k="wrapper";function g(e){var t=e.components,n=(0,r.Z)(e,s);return(0,l.kt)(k,(0,a.Z)({},h,n,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"development-prerequisites"},"Development Prerequisites"),(0,l.kt)("p",null,"This page covers the necessary software for your Casper development environment. To develop comfortably, you should use ",(0,l.kt)("inlineCode",{parentName:"p"},"Linux Ubuntu 20.04")," or ",(0,l.kt)("inlineCode",{parentName:"p"},"macOS"),". Developing on Windows is not advised."),(0,l.kt)("admonition",{type:"caution"},(0,l.kt)("p",{parentName:"admonition"},"Casper does not officially support ",(0,l.kt)("inlineCode",{parentName:"p"},"macOS"),". If you encounter any problems, reach out to the community on ",(0,l.kt)("a",{parentName:"p",href:"https://t.me/casperblockchain"},"Telegram")," or ",(0,l.kt)("a",{parentName:"p",href:"https://discord.com/invite/casperblockchain"},"Discord"),".")),(0,l.kt)("h2",{id:"preparing-your-development-environment"},"Preparing your Development Environment"),(0,l.kt)(o.Z,{mdxType:"Tabs"},(0,l.kt)(i.Z,{value:"Linux",label:"Linux",mdxType:"TabItem"},(0,l.kt)("h3",{id:"install-curl"},"Installing ",(0,l.kt)("inlineCode",{parentName:"h3"},"curl")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt install curl\n")),(0,l.kt)("h3",{id:"install-essential"},"Installing essential Linux packages"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt install build-essential\n")),(0,l.kt)("h3",{id:"install-adds"},"Installing packages required for Casper tools"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt-get install pkg-config\nsudo apt-get install openssl\nsudo apt-get install libssl-dev\n")),(0,l.kt)("h3",{id:"install-linux-cargo"},"Installing ",(0,l.kt)("inlineCode",{parentName:"h3"},"cargo")," on Linux"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt install cargo\n"))),(0,l.kt)(i.Z,{value:"macOS",label:"macOS",mdxType:"TabItem"},(0,l.kt)("h3",{id:"install-xcode"},"Installing Xcode developer tools for macOS"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"xcode-select --install\n")),(0,l.kt)("p",null,"Verify the installation:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"xcode-select -p\n")),(0,l.kt)("h3",{id:"install-brew"},"Installing ",(0,l.kt)("inlineCode",{parentName:"h3"},"brew")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n')),(0,l.kt)("h3",{id:"install-adds-macos"},"Installing packages required for Casper tools"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"brew install pkg-config\nbrew install openssl\n")))),(0,l.kt)("h2",{id:"install-rust"},"Installing Rust"),(0,l.kt)("p",null,"Install the ",(0,l.kt)("a",{parentName:"p",href:"https://www.rust-lang.org"},"Rust programming language")," if you don't already have it on your computer."),(0,l.kt)("p",null,"The ",(0,l.kt)("a",{parentName:"p",href:"https://www.rust-lang.org/tools/install"},"official Rust guide")," recommends installing Rust by using ",(0,l.kt)("inlineCode",{parentName:"p"},"curl"),":"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n")),(0,l.kt)("p",null,"After your next login, the installation script automatically adds Rust to your system PATH. To start using Rust immediately, run the following command in your shell instead of restarting your terminal. The command will add Rust to your system PATH."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"source $HOME/.cargo/env\n")),(0,l.kt)("p",null,"Verify the installation:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"rustup --version\n")),(0,l.kt)("p",null,"Note: You can also use ",(0,l.kt)("inlineCode",{parentName:"p"},"brew")," on MacOS or ",(0,l.kt)("inlineCode",{parentName:"p"},"apt")," on Linux to install Rust."),(0,l.kt)("h2",{id:"installing-the-casper-crates"},"Installing the Casper Crates"),(0,l.kt)("p",null,"The best and fastest way to set up a Casper Rust project is to use ",(0,l.kt)("a",{parentName:"p",href:"https://crates.io/crates/cargo-casper"},"cargo casper"),", which is the command line tool for creating a Wasm smart contract and tests for use on a Casper network. This tool will create a simple contract, a runtime environment, and a testing framework with a simple test. ",(0,l.kt)("em",{parentName:"p"},"Cargo")," is a build system and package manager for Rust (much like ",(0,l.kt)("em",{parentName:"p"},"pip")," if you are familiar with Python, or ",(0,l.kt)("em",{parentName:"p"},"npm")," and ",(0,l.kt)("em",{parentName:"p"},"yarn")," for those familiar with Javascript). It is also possible to use this configuration in your CI/CD pipeline."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"cargo install cargo-casper\n")),(0,l.kt)("p",null,"If you run into any issues with this command and you have not recently installed Rust from scratch, please make sure to update your Rust version with this command:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"rustup update\n")),(0,l.kt)("p",null,"Verify the installation:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"cargo-casper --version\n")),(0,l.kt)("admonition",{type:"note"},(0,l.kt)("p",{parentName:"admonition"},"Familiarize yourself with the essential Casper crates described ",(0,l.kt)("a",{parentName:"p",href:"/developers/essential-crates"},"here"),".")),(0,l.kt)("h2",{id:"install-casper-client"},"Installing the Casper Client"),(0,l.kt)("p",null,"The default Casper client is on ",(0,l.kt)("a",{parentName:"p",href:"https://crates.io/crates/casper-client"},"crates.io"),". This client can transmit your deploys to a Casper network."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"cargo install casper-client\n")),(0,l.kt)("p",null,"Verify the installation:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client --version\n")),(0,l.kt)("p",null,"The Casper client can print out help information, which provides an up-to-date list of supported commands. To do so, use the following command:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client --help\n")),(0,l.kt)("p",null,"You can use ",(0,l.kt)("inlineCode",{parentName:"p"},"help")," for each command to get the most up-to-date arguments and descriptions."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client --help\n")),(0,l.kt)("h3",{id:"building-client-from-source"},"Accessing the Casper client source code"),(0,l.kt)("p",null,"You can access the Casper client source code ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/casper-client-rs"},"here"),". The ",(0,l.kt)("inlineCode",{parentName:"p"},"lib")," directory contains the source for the client library, which may be called directly rather than through the CLI binary. The CLI app ",(0,l.kt)("inlineCode",{parentName:"p"},"casper-client")," uses this library to implement its functionality."),(0,l.kt)("p",null,"If you wish to compile it, you will need to first install the nightly Rust toolchain with this command:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"rustup toolchain install nightly\n")),(0,l.kt)("p",null,"Then, compile the source code:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"cargo build --release\n")),(0,l.kt)("p",null,"You will find the ",(0,l.kt)("inlineCode",{parentName:"p"},"casper-client")," executable in the ",(0,l.kt)("inlineCode",{parentName:"p"},"target/release")," directory."),(0,l.kt)("h2",{id:"install-cmake"},"Installing CMake"),(0,l.kt)("p",null,"If you plan to compile contracts from the source code, including those provided in the ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node"},"casper-node")," repository, install ",(0,l.kt)("inlineCode",{parentName:"p"},"CMake")," with the commands below."),(0,l.kt)("p",null,(0,l.kt)("a",{parentName:"p",href:"https://cmake.org/"},"CMake")," is a popular build tool that we will use, and you may have it installed. If you do, make sure that you have the latest version. If you need to install or upgrade it, follow the steps below or on the ",(0,l.kt)("a",{parentName:"p",href:"https://cmake.org/install/"},"CMake website"),". Once installed, check your version as shown below."),(0,l.kt)(o.Z,{mdxType:"Tabs"},(0,l.kt)(i.Z,{value:"Linux",label:"Linux",mdxType:"TabItem"},(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt-get -y install cmake\n"))),(0,l.kt)(i.Z,{value:"macOS",label:"macOS",mdxType:"TabItem"},(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"brew install cmake\n")))),(0,l.kt)("p",null,"Check your version:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"cmake --version\n")),(0,l.kt)("p",null,"Sample output:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"cmake version 3.20.0 (or above)\n\nCMake suite maintained and supported by Kitware (kitware.com/cmake).\n")),(0,l.kt)("h2",{id:"installing-an-ide"},"Installing an IDE"),(0,l.kt)("p",null,"We advise using an integrated development environment such as Visual Studio Code (VSC) for development. There are many IDEs available for Rust development. The most popular IDEs for Rust are the following:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://code.visualstudio.com"},"Visual Studio Code")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://www.jetbrains.com/clion/"},"CLion")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://www.jetbrains.com/idea/"},"IntelliJ Idea")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://www.vim.org/"},"Vim"))),(0,l.kt)("p",null,"You can use any IDE you wish. Most of our documentation and examples use Visual Studio Code (VSC), a popular IDE with many extensions that might be helpful during development."),(0,l.kt)("p",null,"If you are using VSC, you might find the following extensions useful:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"CodeLLDB")," \u2013 An important extension for debugging Rust code"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"rust-analyzer")," \u2013 The official Rust language extension"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Better TOML")," \u2013 Support for formatting TOML files"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"crates")," \u2013 An extension to help manage crates"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Error Lens")," \u2013 Enhances the programming experience by highlighting syntax errors")),(0,l.kt)("h2",{id:"setting-up-an-account"},"Setting up a Casper Account"),(0,l.kt)("p",null,"The ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-head"},"Account")," creation process consists of two steps:"),(0,l.kt)("ol",null,(0,l.kt)("li",{parentName:"ol"},"Creating an Account"),(0,l.kt)("li",{parentName:"ol"},"Funding the Account")),(0,l.kt)("p",null,"The following video complements the instructions below, showing you the expected output."),(0,l.kt)("p",{align:"center"},(0,l.kt)("iframe",{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sA1HTPjV_bc&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=3",frameborder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:!0})),(0,l.kt)("h3",{id:"creating-an-account"},"Creating an account"),(0,l.kt)("p",null,"The Casper blockchain uses an on-chain account-based model, uniquely identified by an ",(0,l.kt)("inlineCode",{parentName:"p"},"AccountHash")," derived from a specific ",(0,l.kt)("inlineCode",{parentName:"p"},"PublicKey"),"."),(0,l.kt)("p",null,"By default, a transactional interaction with the blockchain takes the form of a ",(0,l.kt)("inlineCode",{parentName:"p"},"Deploy")," cryptographically signed by the key-pair corresponding to the ",(0,l.kt)("inlineCode",{parentName:"p"},"PublicKey")," used to create the account."),(0,l.kt)("p",null,"Users can create accounts using the ",(0,l.kt)("a",{parentName:"p",href:"/concepts/accounts-and-keys#option-1-generating-keys-using-the-casper-client-option-1-key-generation-using-the-casper-client"},"Casper command-line client"),"."),(0,l.kt)("p",null,"Alternatively, some Casper networks, such as the official Testnet and Mainnet, provide a browser-based block explorer that allows account creation as outlined ",(0,l.kt)("a",{parentName:"p",href:"/concepts/accounts-and-keys#option-2-generating-keys-using-a-block-explorer-option-2-key-generation-using-a-block-explorer"},"here"),"."),(0,l.kt)("p",null,"Use either method to generate an account and its corresponding cryptographic key-pair."),(0,l.kt)("h3",{id:"generating-the-account-hash"},"Generating the account hash"),(0,l.kt)("p",null,"As a developer, you will often use an account hash, which is a 32-byte hash of the public key. This is because responses from the node contain ",(0,l.kt)("inlineCode",{parentName:"p"},"AccountHashes")," instead of the direct hexadecimal-encoded public key. To view the account hash for a public key, use the ",(0,l.kt)("inlineCode",{parentName:"p"},"account-address")," option of the Casper CLI client:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client account-address --public-key \n")),(0,l.kt)("h2",{id:"fund-your-account"},"Funding an Account"),(0,l.kt)("p",null,"After generating the cryptographic key-pair for an Account, you must fund the account's main purse to create it on-chain."),(0,l.kt)("p",null,"On Testnet, you can fund an account by requesting test tokens according to ",(0,l.kt)("a",{parentName:"p",href:"/users/testnet-faucet"},"this guide"),". You can request test tokens ",(0,l.kt)("strong",{parentName:"p"},"only once")," for each account."),(0,l.kt)("p",null,"On Mainnet, a pre-existing account must transfer CSPR tokens to the newly created account's main purse to finalize the setup. The source account needs to transfer CSPR tokens to the hexadecimal-encoded public key of the target account. This transfer will automatically create the target account if it does not exist. Currently, this is the only way to create an account on Mainnet."),(0,l.kt)("h2",{id:"acquire-node-address-from-network-peers"},"Acquiring a Node Address from the Network"),(0,l.kt)("p",null,"Clients can interact with a node on the blockchain via requests sent to that node's JSON-RPC endpoint, ",(0,l.kt)("inlineCode",{parentName:"p"},"http://:7777")," by default."),(0,l.kt)("p",null,"The node address is the IP of a peer node."),(0,l.kt)("p",null,"Both the official Testnet and Mainnet provide block explorers that list the IP addresses of nodes on their respective networks."),(0,l.kt)("p",null,"You can get the ",(0,l.kt)("inlineCode",{parentName:"p"},"node-ip-address")," of a node on the network by visiting the following block explorers:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://testnet.cspr.live/tools/peers"},"Peers")," on Testnet"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://cspr.live/tools/peers"},"Peers")," on Mainnet")),(0,l.kt)("p",null,"You will see a list of peers, and you can select the IP of any peer on the list."),(0,l.kt)("p",null,(0,l.kt)("strong",{parentName:"p"},"Note"),": If the selected peer is unresponsive, pick a different peer and try again."))}g.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5390],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return h}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),u=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),p=u(n),m=r,h=p["".concat(s,".").concat(m)]||p[m]||d[m]||l;return n?a.createElement(h,o(o({ref:t},c),{},{components:n})):a.createElement(h,o({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[p]="string"==typeof e?e:r,o[1]=i;for(var u=2;u 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.')})))?void 0:n.filter(Boolean))?t:[]}(e).map((function(e){var t=e.props;return{value:t.value,label:t.label,attributes:t.attributes,default:t.default}}))}function d(e){var t=e.values,n=e.children;return(0,r.useMemo)((function(){var e=null!=t?t:p(n);return function(e){var t=(0,u.l)(e,(function(e,t){return e.value===t.value}));if(t.length>0)throw new Error('Docusaurus error: Duplicate values "'+t.map((function(e){return e.value})).join(", ")+'" found in . Every value needs to be unique.')}(e),e}),[t,n])}function m(e){var t=e.value;return e.tabValues.some((function(e){return e.value===t}))}function h(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId,l=(0,i.k6)(),o=function(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId;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 null!=a?a:null}({queryString:n,groupId:a});return[(0,s._X)(o),(0,r.useCallback)((function(e){if(o){var t=new URLSearchParams(l.location.search);t.set(o,e),l.replace(Object.assign({},l.location,{search:t.toString()}))}}),[o,l])]}function k(e){var t,n,a,l,o=e.defaultValue,i=e.queryString,s=void 0!==i&&i,u=e.groupId,p=d(e),k=(0,r.useState)((function(){return function(e){var t,n=e.defaultValue,a=e.tabValues;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({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((function(e){return e.value})).join(", ")+". If you intend to show no default tab, use defaultValue={null} instead.");return n}var r=null!=(t=a.find((function(e){return e.default})))?t:a[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:o,tabValues:p})})),g=k[0],f=k[1],v=h({queryString:s,groupId:u}),b=v[0],y=v[1],N=(t=function(e){return e?"docusaurus.tab."+e:null}({groupId:u}.groupId),n=(0,c.Nk)(t),a=n[0],l=n[1],[a,(0,r.useCallback)((function(e){t&&l.set(e)}),[t,l])]),w=N[0],C=N[1],I=function(){var e=null!=b?b:w;return m({value:e,tabValues:p})?e:null}();return(0,r.useLayoutEffect)((function(){I&&f(I)}),[I]),{selectedValue:g,selectValue:(0,r.useCallback)((function(e){if(!m({value:e,tabValues:p}))throw new Error("Can't select invalid tab value="+e);f(e),y(e),C(e)}),[y,C,p]),tabValues:p}}var g=n(2389),f={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function v(e){var t=e.className,n=e.block,i=e.selectedValue,s=e.selectValue,u=e.tabValues,c=[],p=(0,o.o5)().blockElementScrollPositionUntilNextRender,d=function(e){var t=e.currentTarget,n=c.indexOf(t),a=u[n].value;a!==i&&(p(t),s(a))},m=function(e){var t,n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":var a,r=c.indexOf(e.currentTarget)+1;n=null!=(a=c[r])?a:c[0];break;case"ArrowLeft":var l,o=c.indexOf(e.currentTarget)-1;n=null!=(l=c[o])?l:c[c.length-1]}null==(t=n)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":n},t)},u.map((function(e){var t=e.value,n=e.label,o=e.attributes;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:function(e){return c.push(e)},onKeyDown:m,onClick:d},o,{className:(0,l.Z)("tabs__item",f.tabItem,null==o?void 0:o.className,{"tabs__item--active":i===t})}),null!=n?n:t)})))}function b(e){var t=e.lazy,n=e.children,a=e.selectedValue,l=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){var o=l.find((function(e){return e.props.value===a}));return o?(0,r.cloneElement)(o,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},l.map((function(e,t){return(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a})})))}function y(e){var t=k(e);return r.createElement("div",{className:(0,l.Z)("tabs-container",f.tabList)},r.createElement(v,(0,a.Z)({},e,t)),r.createElement(b,(0,a.Z)({},e,t)))}function N(e){var t=(0,g.Z)();return r.createElement(y,(0,a.Z)({key:String(t)},e))}},3235:function(e,t,n){n.r(t),n.d(t,{assets:function(){return d},contentTitle:function(){return c},default:function(){return g},frontMatter:function(){return u},metadata:function(){return p},toc:function(){return m}});var a=n(7462),r=n(3366),l=(n(7294),n(3905)),o=(n(4996),n(4866)),i=n(5162),s=["components"],u={},c="Development Prerequisites",p={unversionedId:"developers/prerequisites",id:"developers/prerequisites",title:"Development Prerequisites",description:"This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04 or macOS. Developing on Windows is not advised.",source:"@site/source/docs/casper/developers/prerequisites.md",sourceDirName:"developers",slug:"/developers/prerequisites",permalink:"/developers/prerequisites",draft:!1,editUrl:"https://github.com/casper-network/docs/tree/dev/source/docs/casper/developers/prerequisites.md",tags:[],version:"current",lastUpdatedAt:1708091908,formattedLastUpdatedAt:"Feb 16, 2024",frontMatter:{},sidebar:"developers",previous:{title:"Overview",permalink:"/developers"},next:{title:"Essential Rust Crates",permalink:"/developers/essential-crates"}},d={},m=[{value:"Preparing your Development Environment",id:"preparing-your-development-environment",level:2},{value:"Installing curl",id:"install-curl",level:3},{value:"Installing essential Linux packages",id:"install-essential",level:3},{value:"Installing packages required for Casper tools",id:"install-adds",level:3},{value:"Installing cargo on Linux",id:"install-linux-cargo",level:3},{value:"Installing Xcode developer tools for macOS",id:"install-xcode",level:3},{value:"Installing brew",id:"install-brew",level:3},{value:"Installing packages required for Casper tools",id:"install-adds-macos",level:3},{value:"Installing Rust",id:"install-rust",level:2},{value:"Installing the Casper Crates",id:"installing-the-casper-crates",level:2},{value:"Installing the Casper Client",id:"install-casper-client",level:2},{value:"Accessing the Casper client source code",id:"building-client-from-source",level:3},{value:"Installing CMake",id:"install-cmake",level:2},{value:"Installing an IDE",id:"installing-an-ide",level:2},{value:"Setting up a Casper Account",id:"setting-up-an-account",level:2},{value:"Creating an account",id:"creating-an-account",level:3},{value:"Generating the account hash",id:"generating-the-account-hash",level:3},{value:"Funding an Account",id:"fund-your-account",level:2},{value:"Acquiring a Node Address from the Network",id:"acquire-node-address-from-network-peers",level:2}],h={toc:m},k="wrapper";function g(e){var t=e.components,n=(0,r.Z)(e,s);return(0,l.kt)(k,(0,a.Z)({},h,n,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"development-prerequisites"},"Development Prerequisites"),(0,l.kt)("p",null,"This page covers the necessary software for your Casper development environment. To develop comfortably, you should use ",(0,l.kt)("inlineCode",{parentName:"p"},"Linux Ubuntu 20.04")," or ",(0,l.kt)("inlineCode",{parentName:"p"},"macOS"),". Developing on Windows is not advised."),(0,l.kt)("admonition",{type:"caution"},(0,l.kt)("p",{parentName:"admonition"},"Casper does not officially support ",(0,l.kt)("inlineCode",{parentName:"p"},"macOS"),". If you encounter any problems, reach out to the community on ",(0,l.kt)("a",{parentName:"p",href:"https://t.me/casperblockchain"},"Telegram")," or ",(0,l.kt)("a",{parentName:"p",href:"https://discord.com/invite/casperblockchain"},"Discord"),".")),(0,l.kt)("h2",{id:"preparing-your-development-environment"},"Preparing your Development Environment"),(0,l.kt)(o.Z,{mdxType:"Tabs"},(0,l.kt)(i.Z,{value:"Linux",label:"Linux",mdxType:"TabItem"},(0,l.kt)("h3",{id:"install-curl"},"Installing ",(0,l.kt)("inlineCode",{parentName:"h3"},"curl")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt install curl\n")),(0,l.kt)("h3",{id:"install-essential"},"Installing essential Linux packages"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt install build-essential\n")),(0,l.kt)("h3",{id:"install-adds"},"Installing packages required for Casper tools"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt-get install pkg-config\nsudo apt-get install openssl\nsudo apt-get install libssl-dev\n")),(0,l.kt)("h3",{id:"install-linux-cargo"},"Installing ",(0,l.kt)("inlineCode",{parentName:"h3"},"cargo")," on Linux"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt install cargo\n"))),(0,l.kt)(i.Z,{value:"macOS",label:"macOS",mdxType:"TabItem"},(0,l.kt)("h3",{id:"install-xcode"},"Installing Xcode developer tools for macOS"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"xcode-select --install\n")),(0,l.kt)("p",null,"Verify the installation:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"xcode-select -p\n")),(0,l.kt)("h3",{id:"install-brew"},"Installing ",(0,l.kt)("inlineCode",{parentName:"h3"},"brew")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n')),(0,l.kt)("h3",{id:"install-adds-macos"},"Installing packages required for Casper tools"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"brew install pkg-config\nbrew install openssl\n")))),(0,l.kt)("h2",{id:"install-rust"},"Installing Rust"),(0,l.kt)("p",null,"Install the ",(0,l.kt)("a",{parentName:"p",href:"https://www.rust-lang.org"},"Rust programming language")," if you don't already have it on your computer."),(0,l.kt)("p",null,"The ",(0,l.kt)("a",{parentName:"p",href:"https://www.rust-lang.org/tools/install"},"official Rust guide")," recommends installing Rust by using ",(0,l.kt)("inlineCode",{parentName:"p"},"curl"),":"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n")),(0,l.kt)("p",null,"After your next login, the installation script automatically adds Rust to your system PATH. To start using Rust immediately, run the following command in your shell instead of restarting your terminal. The command will add Rust to your system PATH."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"source $HOME/.cargo/env\n")),(0,l.kt)("p",null,"Verify the installation:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"rustup --version\n")),(0,l.kt)("p",null,"Note: You can also use ",(0,l.kt)("inlineCode",{parentName:"p"},"brew")," on MacOS or ",(0,l.kt)("inlineCode",{parentName:"p"},"apt")," on Linux to install Rust."),(0,l.kt)("h2",{id:"installing-the-casper-crates"},"Installing the Casper Crates"),(0,l.kt)("p",null,"The best and fastest way to set up a Casper Rust project is to use ",(0,l.kt)("a",{parentName:"p",href:"https://crates.io/crates/cargo-casper"},"cargo casper"),", which is the command line tool for creating a Wasm smart contract and tests for use on a Casper network. This tool will create a simple contract, a runtime environment, and a testing framework with a simple test. ",(0,l.kt)("em",{parentName:"p"},"Cargo")," is a build system and package manager for Rust (much like ",(0,l.kt)("em",{parentName:"p"},"pip")," if you are familiar with Python, or ",(0,l.kt)("em",{parentName:"p"},"npm")," and ",(0,l.kt)("em",{parentName:"p"},"yarn")," for those familiar with Javascript). It is also possible to use this configuration in your CI/CD pipeline."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"cargo install cargo-casper\n")),(0,l.kt)("p",null,"If you run into any issues with this command and you have not recently installed Rust from scratch, please make sure to update your Rust version with this command:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"rustup update\n")),(0,l.kt)("p",null,"Verify the installation:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"cargo-casper --version\n")),(0,l.kt)("admonition",{type:"note"},(0,l.kt)("p",{parentName:"admonition"},"Familiarize yourself with the essential Casper crates described ",(0,l.kt)("a",{parentName:"p",href:"/developers/essential-crates"},"here"),".")),(0,l.kt)("h2",{id:"install-casper-client"},"Installing the Casper Client"),(0,l.kt)("p",null,"The default Casper client is on ",(0,l.kt)("a",{parentName:"p",href:"https://crates.io/crates/casper-client"},"crates.io"),". This client can transmit your deploys to a Casper network."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"cargo install casper-client\n")),(0,l.kt)("p",null,"Verify the installation:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client --version\n")),(0,l.kt)("p",null,"The Casper client can print out help information, which provides an up-to-date list of supported commands. To do so, use the following command:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client --help\n")),(0,l.kt)("p",null,"You can use ",(0,l.kt)("inlineCode",{parentName:"p"},"help")," for each command to get the most up-to-date arguments and descriptions."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client --help\n")),(0,l.kt)("h3",{id:"building-client-from-source"},"Accessing the Casper client source code"),(0,l.kt)("p",null,"You can access the Casper client source code ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/casper-client-rs"},"here"),". The ",(0,l.kt)("inlineCode",{parentName:"p"},"lib")," directory contains the source for the client library, which may be called directly rather than through the CLI binary. The CLI app ",(0,l.kt)("inlineCode",{parentName:"p"},"casper-client")," uses this library to implement its functionality."),(0,l.kt)("p",null,"If you wish to compile it, you will need to first install the nightly Rust toolchain with this command:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"rustup toolchain install nightly\n")),(0,l.kt)("p",null,"Then, compile the source code:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"cargo build --release\n")),(0,l.kt)("p",null,"You will find the ",(0,l.kt)("inlineCode",{parentName:"p"},"casper-client")," executable in the ",(0,l.kt)("inlineCode",{parentName:"p"},"target/release")," directory."),(0,l.kt)("h2",{id:"install-cmake"},"Installing CMake"),(0,l.kt)("p",null,"If you plan to compile contracts from the source code, including those provided in the ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node"},"casper-node")," repository, install ",(0,l.kt)("inlineCode",{parentName:"p"},"CMake")," with the commands below."),(0,l.kt)("p",null,(0,l.kt)("a",{parentName:"p",href:"https://cmake.org/"},"CMake")," is a popular build tool that we will use, and you may have it installed. If you do, make sure that you have the latest version. If you need to install or upgrade it, follow the steps below or on the ",(0,l.kt)("a",{parentName:"p",href:"https://cmake.org/install/"},"CMake website"),". Once installed, check your version as shown below."),(0,l.kt)(o.Z,{mdxType:"Tabs"},(0,l.kt)(i.Z,{value:"Linux",label:"Linux",mdxType:"TabItem"},(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt-get -y install cmake\n"))),(0,l.kt)(i.Z,{value:"macOS",label:"macOS",mdxType:"TabItem"},(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"brew install cmake\n")))),(0,l.kt)("p",null,"Check your version:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"cmake --version\n")),(0,l.kt)("p",null,"Sample output:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"cmake version 3.20.0 (or above)\n\nCMake suite maintained and supported by Kitware (kitware.com/cmake).\n")),(0,l.kt)("h2",{id:"installing-an-ide"},"Installing an IDE"),(0,l.kt)("p",null,"We advise using an integrated development environment such as Visual Studio Code (VSC) for development. There are many IDEs available for Rust development. The most popular IDEs for Rust are the following:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://code.visualstudio.com"},"Visual Studio Code")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://www.jetbrains.com/clion/"},"CLion")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://www.jetbrains.com/idea/"},"IntelliJ Idea")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://www.vim.org/"},"Vim"))),(0,l.kt)("p",null,"You can use any IDE you wish. Most of our documentation and examples use Visual Studio Code (VSC), a popular IDE with many extensions that might be helpful during development."),(0,l.kt)("p",null,"If you are using VSC, you might find the following extensions useful:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"CodeLLDB")," \u2013 An important extension for debugging Rust code"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"rust-analyzer")," \u2013 The official Rust language extension"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Better TOML")," \u2013 Support for formatting TOML files"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"crates")," \u2013 An extension to help manage crates"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Error Lens")," \u2013 Enhances the programming experience by highlighting syntax errors")),(0,l.kt)("h2",{id:"setting-up-an-account"},"Setting up a Casper Account"),(0,l.kt)("p",null,"The ",(0,l.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-head"},"Account")," creation process consists of two steps:"),(0,l.kt)("ol",null,(0,l.kt)("li",{parentName:"ol"},"Creating an Account"),(0,l.kt)("li",{parentName:"ol"},"Funding the Account")),(0,l.kt)("p",null,"The following video complements the instructions below, showing you the expected output."),(0,l.kt)("p",{align:"center"},(0,l.kt)("iframe",{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sA1HTPjV_bc&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=3",frameborder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:!0})),(0,l.kt)("h3",{id:"creating-an-account"},"Creating an account"),(0,l.kt)("p",null,"The Casper blockchain uses an on-chain account-based model, uniquely identified by an ",(0,l.kt)("inlineCode",{parentName:"p"},"AccountHash")," derived from a specific ",(0,l.kt)("inlineCode",{parentName:"p"},"PublicKey"),"."),(0,l.kt)("p",null,"By default, a transactional interaction with the blockchain takes the form of a ",(0,l.kt)("inlineCode",{parentName:"p"},"Deploy")," cryptographically signed by the key-pair corresponding to the ",(0,l.kt)("inlineCode",{parentName:"p"},"PublicKey")," used to create the account."),(0,l.kt)("p",null,"Users can create accounts using the ",(0,l.kt)("a",{parentName:"p",href:"/concepts/accounts-and-keys#option-1-generating-keys-using-the-casper-client-option-1-key-generation-using-the-casper-client"},"Casper command-line client"),"."),(0,l.kt)("p",null,"Alternatively, some Casper networks, such as the official Testnet and Mainnet, provide a browser-based block explorer that allows account creation as outlined ",(0,l.kt)("a",{parentName:"p",href:"/concepts/accounts-and-keys#option-2-generating-keys-using-a-block-explorer-option-2-key-generation-using-a-block-explorer"},"here"),"."),(0,l.kt)("p",null,"Use either method to generate an account and its corresponding cryptographic key-pair."),(0,l.kt)("h3",{id:"generating-the-account-hash"},"Generating the account hash"),(0,l.kt)("p",null,"As a developer, you will often use an account hash, which is a 32-byte hash of the public key. This is because responses from the node contain ",(0,l.kt)("inlineCode",{parentName:"p"},"AccountHashes")," instead of the direct hexadecimal-encoded public key. To view the account hash for a public key, use the ",(0,l.kt)("inlineCode",{parentName:"p"},"account-address")," option of the Casper CLI client:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client account-address --public-key \n")),(0,l.kt)("h2",{id:"fund-your-account"},"Funding an Account"),(0,l.kt)("p",null,"After generating the cryptographic key-pair for an Account, you must fund the account's main purse to create it on-chain."),(0,l.kt)("p",null,"On Testnet, you can fund an account by requesting test tokens according to ",(0,l.kt)("a",{parentName:"p",href:"/users/testnet-faucet"},"this guide"),". You can request test tokens ",(0,l.kt)("strong",{parentName:"p"},"only once")," for each account."),(0,l.kt)("p",null,"On Mainnet, a pre-existing account must transfer CSPR tokens to the newly created account's main purse to finalize the setup. The source account needs to transfer CSPR tokens to the hexadecimal-encoded public key of the target account. This transfer will automatically create the target account if it does not exist. Currently, this is the only way to create an account on Mainnet."),(0,l.kt)("h2",{id:"acquire-node-address-from-network-peers"},"Acquiring a Node Address from the Network"),(0,l.kt)("p",null,"Clients can interact with a node on the blockchain via requests sent to that node's JSON-RPC endpoint, ",(0,l.kt)("inlineCode",{parentName:"p"},"http://:7777")," by default."),(0,l.kt)("p",null,"The node address is the IP of a peer node."),(0,l.kt)("p",null,"Both the official Testnet and Mainnet provide block explorers that list the IP addresses of nodes on their respective networks."),(0,l.kt)("p",null,"You can get the ",(0,l.kt)("inlineCode",{parentName:"p"},"node-ip-address")," of a node on the network by visiting the following block explorers:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://testnet.cspr.live/tools/peers"},"Peers")," on Testnet"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://cspr.live/tools/peers"},"Peers")," on Mainnet")),(0,l.kt)("p",null,"You will see a list of peers, and you can select the IP of any peer on the list."),(0,l.kt)("p",null,(0,l.kt)("strong",{parentName:"p"},"Note"),": If the selected peer is unresponsive, pick a different peer and try again."))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/74ff8362.b4646ff4.js b/assets/js/74ff8362.dcda4205.js similarity index 99% rename from assets/js/74ff8362.b4646ff4.js rename to assets/js/74ff8362.dcda4205.js index 9d538b2148..55333a527d 100644 --- a/assets/js/74ff8362.b4646ff4.js +++ b/assets/js/74ff8362.dcda4205.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[1132],{3905:function(e,t,a){a.d(t,{Zo:function(){return p},kt:function(){return d}});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(a),h=r,d=u["".concat(l,".").concat(h)]||u[h]||m[h]||o;return a?n.createElement(d,i(i({ref:t},p),{},{components:a})):n.createElement(d,i({ref:t},p))}));function d(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:r,i[1]=s;for(var c=2;c=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(a),h=r,d=u["".concat(l,".").concat(h)]||u[h]||m[h]||o;return a?n.createElement(d,i(i({ref:t},p),{},{components:a})):n.createElement(d,i({ref:t},p))}));function d(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:r,i[1]=s;for(var c=2;c=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),p=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(u.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,u=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),c=p(r),m=o,k=c["".concat(u,".").concat(m)]||c[m]||d[m]||a;return r?n.createElement(k,s(s({ref:t},l),{},{components:r})):n.createElement(k,s({ref:t},l))}));function k(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,s=new Array(a);s[0]=m;var i={};for(var u in t)hasOwnProperty.call(t,u)&&(i[u]=t[u]);i.originalType=e,i[c]="string"==typeof e?e:o,s[1]=i;for(var p=2;p")," in the instructions below with your username."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Use ",(0,a.kt)("a",{parentName:"p",href:"https://www.ssh.com/academy/ssh/keygen"},"ssh-keygen")," to generate a new SSH key.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Create the user with no password, as the key is your password."))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"sudo adduser --disabled-password\n")),(0,a.kt)("ol",{start:3},(0,a.kt)("li",{parentName:"ol"},"Create authorized_keys with your key to log in.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"sudo su - \nmkdir .ssh\nchmod 700 .ssh\ntouch .ssh/authorized_keys\n")),(0,a.kt)("ol",{start:4},(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Use the editor of your choice and paste your .ssh public key i the ",(0,a.kt)("inlineCode",{parentName:"p"},".ssh/authorized_keys")," file.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Exit out of the ",(0,a.kt)("inlineCode",{parentName:"p"},"")," account and log into the root or previous sudo-er account."))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"exit\n")),(0,a.kt)("ol",{start:6},(0,a.kt)("li",{parentName:"ol"},"Add your user to sudo-ers under the root account or your previous sudo-er account.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"sudo visudo\n")),(0,a.kt)("ol",{start:7},(0,a.kt)("li",{parentName:"ol"},"Type ",(0,a.kt)("inlineCode",{parentName:"li"}," ALL=(ALL:ALL) NOPASSWD:ALL")," below the row containing ",(0,a.kt)("inlineCode",{parentName:"li"},"root ALL=(ALL:ALL) ALL"),".")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"# User privilege specification\nroot ALL=(ALL:ALL) ALL\n ALL=(ALL:ALL) NOPASSWD:ALL\n")),(0,a.kt)("ol",{start:8},(0,a.kt)("li",{parentName:"ol"},"You should be able to log in with the key and not use the root user.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"ssh -i @\n")),(0,a.kt)("p",null,"Here is an example command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"ssh -i ~/.ssh/id_rsa casper@10.21.10.200\n")))}k.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5863],{3905:function(e,t,r){r.d(t,{Zo:function(){return l},kt:function(){return k}});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),p=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(u.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,u=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),c=p(r),m=o,k=c["".concat(u,".").concat(m)]||c[m]||d[m]||a;return r?n.createElement(k,s(s({ref:t},l),{},{components:r})):n.createElement(k,s({ref:t},l))}));function k(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,s=new Array(a);s[0]=m;var i={};for(var u in t)hasOwnProperty.call(t,u)&&(i[u]=t[u]);i.originalType=e,i[c]="string"==typeof e?e:o,s[1]=i;for(var p=2;p")," in the instructions below with your username."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Use ",(0,a.kt)("a",{parentName:"p",href:"https://www.ssh.com/academy/ssh/keygen"},"ssh-keygen")," to generate a new SSH key.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Create the user with no password, as the key is your password."))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"sudo adduser --disabled-password\n")),(0,a.kt)("ol",{start:3},(0,a.kt)("li",{parentName:"ol"},"Create authorized_keys with your key to log in.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"sudo su - \nmkdir .ssh\nchmod 700 .ssh\ntouch .ssh/authorized_keys\n")),(0,a.kt)("ol",{start:4},(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Use the editor of your choice and paste your .ssh public key i the ",(0,a.kt)("inlineCode",{parentName:"p"},".ssh/authorized_keys")," file.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Exit out of the ",(0,a.kt)("inlineCode",{parentName:"p"},"")," account and log into the root or previous sudo-er account."))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"exit\n")),(0,a.kt)("ol",{start:6},(0,a.kt)("li",{parentName:"ol"},"Add your user to sudo-ers under the root account or your previous sudo-er account.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"sudo visudo\n")),(0,a.kt)("ol",{start:7},(0,a.kt)("li",{parentName:"ol"},"Type ",(0,a.kt)("inlineCode",{parentName:"li"}," ALL=(ALL:ALL) NOPASSWD:ALL")," below the row containing ",(0,a.kt)("inlineCode",{parentName:"li"},"root ALL=(ALL:ALL) ALL"),".")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"# User privilege specification\nroot ALL=(ALL:ALL) ALL\n ALL=(ALL:ALL) NOPASSWD:ALL\n")),(0,a.kt)("ol",{start:8},(0,a.kt)("li",{parentName:"ol"},"You should be able to log in with the key and not use the root user.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"ssh -i @\n")),(0,a.kt)("p",null,"Here is an example command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"ssh -i ~/.ssh/id_rsa casper@10.21.10.200\n")))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/78143ba1.0d0f02a1.js b/assets/js/78143ba1.48fec082.js similarity index 98% rename from assets/js/78143ba1.0d0f02a1.js rename to assets/js/78143ba1.48fec082.js index 549620016a..177abb6a23 100644 --- a/assets/js/78143ba1.0d0f02a1.js +++ b/assets/js/78143ba1.48fec082.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[586],{3905:function(e,t,r){r.d(t,{Zo:function(){return i},kt:function(){return h}});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(r),m=a,h=u["".concat(p,".").concat(m)]||u[m]||f[m]||o;return r?n.createElement(h,s(s({ref:t},i),{},{components:r})):n.createElement(h,s({ref:t},i))}));function h(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=m;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(r),m=a,h=u["".concat(p,".").concat(m)]||u[m]||f[m]||o;return r?n.createElement(h,s(s({ref:t},i),{},{components:r})):n.createElement(h,s({ref:t},i))}));function h(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=m;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var d=a.createContext({}),p=function(e){var t=a.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},m=function(e){var t=p(e.components);return a.createElement(d.Provider,{value:t},e.children)},s="mdxType",k={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,d=e.parentName,m=o(e,["components","mdxType","originalType","parentName"]),s=p(n),h=i,c=s["".concat(d,".").concat(h)]||s[h]||k[h]||r;return n?a.createElement(c,l(l({ref:t},m),{},{components:n})):a.createElement(c,l({ref:t},m))}));function c(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,l=new Array(r);l[0]=h;var o={};for(var d in t)hasOwnProperty.call(t,d)&&(o[d]=t[d]);o.originalType=e,o[s]="string"==typeof e?e:i,l[1]=o;for(var p=2;p")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"cep78_contract_package_access_"),"."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"V_1_0_standard"),": This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the contract will retrieve the package hash and the access URef from the ",(0,r.kt)("inlineCode",{parentName:"li"},"NamedKey")," entries originally created during the 1.0 installation."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"V_1_0_custom"),": This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the calling account must provide the ",(0,r.kt)("inlineCode",{parentName:"li"},"NamedKey")," entries under which the package hash and the access URef are saved. Additionally, this requires the passing of the runtime arguments ",(0,r.kt)("inlineCode",{parentName:"li"},"access_key_name")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"hash_key_name")," for the access URef and package hash, respectively. In this modality, these arguments are required and must be passed in.")),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"NamedKeyConvention"),(0,r.kt)("th",{parentName:"tr",align:null},"u8"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"DerivedFromCollectionName"),(0,r.kt)("td",{parentName:"tr",align:null},"0")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"V_1_0_standard"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"V_1_0_custom"),(0,r.kt)("td",{parentName:"tr",align:null},"2")))),(0,r.kt)("h2",{id:"eventsmode"},"EventsMode"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"EventsMode")," modality determines how the installed instance of CEP-78 will handle the recording of events that occur from interacting with the contract."),(0,r.kt)("p",null,"The modality provides three options:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"NoEvents"),": This modality will signal the contract to not record events at all. This is the default mode."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"CEP47"),": This modality will signal the contract to record events using the CEP47 event schema. Further information can be found ",(0,r.kt)("a",{parentName:"li",href:"#cep47-mode"},"below"),"."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"CES"),": This modality will signal the contract to record events using the ",(0,r.kt)("a",{parentName:"li",href:"#casper-event-standard"},"Casper Event Standard"),".")),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"EventsMode"),(0,r.kt)("th",{parentName:"tr",align:null},"u8"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"NoEvents"),(0,r.kt)("td",{parentName:"tr",align:null},"0")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"CEP47"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"CES"),(0,r.kt)("td",{parentName:"tr",align:null},"2")))),(0,r.kt)("h3",{id:"transfer-filter-hook"},"Transfer Filter Hook"),(0,r.kt)("p",null,"The transfer filter modality, if enabled, specifies a contract package hash pointing to a contract that will be called when the ",(0,r.kt)("inlineCode",{parentName:"p"},"transfer")," method is invoked on the contract. CEP-78 will call the ",(0,r.kt)("inlineCode",{parentName:"p"},"can_transfer")," method on the specified callback contract, which is expected to return a value of ",(0,r.kt)("inlineCode",{parentName:"p"},"TransferFilterContractResult"),", represented as a u8."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"TransferFilterContractResult::DenyTransfer")," will block the transfer regardless of the outcome of other checks"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"TransferFilterContractResult::ProceedTransfer")," will allow the transfer to proceed if other checks also pass")),(0,r.kt)("p",null,"The transfer filter can be enabled by passing a ",(0,r.kt)("inlineCode",{parentName:"p"},"ARG_TRANSFER_FILTER_CONTRACT")," argument to the install method, with a value of type ",(0,r.kt)("inlineCode",{parentName:"p"},"Option")),(0,r.kt)("h3",{id:"cep47-mode"},"CEP47 Mode"),(0,r.kt)("p",null,"The CEP47 ",(0,r.kt)("inlineCode",{parentName:"p"},"EventsMode")," modality mimics the event schema previously used in the CEP47 NFT standard. Events are stored as a ",(0,r.kt)("inlineCode",{parentName:"p"},"BTreeMap")," within a dictionary (",(0,r.kt)("inlineCode",{parentName:"p"},"EVENTS"),") in the contract's context. Entries consist of the ",(0,r.kt)("inlineCode",{parentName:"p"},"PREFIX_HASH_KEY_NAME"),", followed by the ",(0,r.kt)("inlineCode",{parentName:"p"},"EVENT_TYPE")," and then variable data as listed in the table below. The events can be retrieved directly via their dictionary entry using the JSON-RPC, with more information on this process available ",(0,r.kt)("a",{parentName:"p",href:"./concepts/dictionaries"},"here"),"."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Event name"),(0,r.kt)("th",{parentName:"tr",align:null},"Included values and type"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Mint"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"recipient (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Transfer"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"operator (Option)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"recipient (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Burn"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ApprovalGranted"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"spender (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ApprovalRevoked"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ApprovalForAll"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"operator (Key)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"RevokedForAll"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"operator (Key)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"MetadataUpdate"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Migration"),(0,r.kt)("td",{parentName:"tr",align:null},"-")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"VariablesSet"),(0,r.kt)("td",{parentName:"tr",align:null},"-")))),(0,r.kt)("h3",{id:"casper-event-standard"},"Casper Event Standard"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"CES")," is an option within the ",(0,r.kt)("inlineCode",{parentName:"p"},"EventsMode")," modality that determines how changes to tokens issued by the contract instance will be recorded. Any changes are recorded in the ",(0,r.kt)("inlineCode",{parentName:"p"},"__events")," dictionary and can be observed via a node's Server Side Events stream. They may also be viewed by querying the dictionary at any time using the JSON-RPC interface."),(0,r.kt)("p",null,"The emitted events are encoded according to the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/make-software/casper-event-standard"},"Casper Event Standard"),", and the schema is visible to an observer reading the ",(0,r.kt)("inlineCode",{parentName:"p"},"__events_schema")," contract named key."),(0,r.kt)("p",null,"For this CEP-78 reference implementation, the events schema is as follows:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Event name"),(0,r.kt)("th",{parentName:"tr",align:null},"Included values and type"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Mint"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"recipient (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"data (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Transfer"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"operator (Option)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"recipient (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Burn"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Approval"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"spender (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ApprovalRevoked"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ApprovalForAll"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"operator (Key)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"RevokedForAll"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"operator (Key)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"MetadataUpdated"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"data (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Migration"),(0,r.kt)("td",{parentName:"tr",align:null},"-")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"VariablesSet"),(0,r.kt)("td",{parentName:"tr",align:null},"-")))),(0,r.kt)("h2",{id:"modality-conflicts"},"Modality Conflicts"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"MetadataMutability")," option set to ",(0,r.kt)("inlineCode",{parentName:"p"},"Mutable")," cannot be used in conjunction with the ",(0,r.kt)("inlineCode",{parentName:"p"},"NFTIdentifierMode")," modality set to ",(0,r.kt)("inlineCode",{parentName:"p"},"Hash"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3013],{3905:function(e,t,n){n.d(t,{Zo:function(){return m},kt:function(){return c}});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var d=a.createContext({}),p=function(e){var t=a.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},m=function(e){var t=p(e.components);return a.createElement(d.Provider,{value:t},e.children)},s="mdxType",k={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,d=e.parentName,m=o(e,["components","mdxType","originalType","parentName"]),s=p(n),h=i,c=s["".concat(d,".").concat(h)]||s[h]||k[h]||r;return n?a.createElement(c,l(l({ref:t},m),{},{components:n})):a.createElement(c,l({ref:t},m))}));function c(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,l=new Array(r);l[0]=h;var o={};for(var d in t)hasOwnProperty.call(t,d)&&(o[d]=t[d]);o.originalType=e,o[s]="string"==typeof e?e:i,l[1]=o;for(var p=2;p")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"cep78_contract_package_access_"),"."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"V_1_0_standard"),": This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the contract will retrieve the package hash and the access URef from the ",(0,r.kt)("inlineCode",{parentName:"li"},"NamedKey")," entries originally created during the 1.0 installation."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"V_1_0_custom"),": This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the calling account must provide the ",(0,r.kt)("inlineCode",{parentName:"li"},"NamedKey")," entries under which the package hash and the access URef are saved. Additionally, this requires the passing of the runtime arguments ",(0,r.kt)("inlineCode",{parentName:"li"},"access_key_name")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"hash_key_name")," for the access URef and package hash, respectively. In this modality, these arguments are required and must be passed in.")),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"NamedKeyConvention"),(0,r.kt)("th",{parentName:"tr",align:null},"u8"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"DerivedFromCollectionName"),(0,r.kt)("td",{parentName:"tr",align:null},"0")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"V_1_0_standard"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"V_1_0_custom"),(0,r.kt)("td",{parentName:"tr",align:null},"2")))),(0,r.kt)("h2",{id:"eventsmode"},"EventsMode"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"EventsMode")," modality determines how the installed instance of CEP-78 will handle the recording of events that occur from interacting with the contract."),(0,r.kt)("p",null,"The modality provides three options:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"NoEvents"),": This modality will signal the contract to not record events at all. This is the default mode."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"CEP47"),": This modality will signal the contract to record events using the CEP47 event schema. Further information can be found ",(0,r.kt)("a",{parentName:"li",href:"#cep47-mode"},"below"),"."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"CES"),": This modality will signal the contract to record events using the ",(0,r.kt)("a",{parentName:"li",href:"#casper-event-standard"},"Casper Event Standard"),".")),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"EventsMode"),(0,r.kt)("th",{parentName:"tr",align:null},"u8"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"NoEvents"),(0,r.kt)("td",{parentName:"tr",align:null},"0")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"CEP47"),(0,r.kt)("td",{parentName:"tr",align:null},"1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"CES"),(0,r.kt)("td",{parentName:"tr",align:null},"2")))),(0,r.kt)("h3",{id:"transfer-filter-hook"},"Transfer Filter Hook"),(0,r.kt)("p",null,"The transfer filter modality, if enabled, specifies a contract package hash pointing to a contract that will be called when the ",(0,r.kt)("inlineCode",{parentName:"p"},"transfer")," method is invoked on the contract. CEP-78 will call the ",(0,r.kt)("inlineCode",{parentName:"p"},"can_transfer")," method on the specified callback contract, which is expected to return a value of ",(0,r.kt)("inlineCode",{parentName:"p"},"TransferFilterContractResult"),", represented as a u8."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"TransferFilterContractResult::DenyTransfer")," will block the transfer regardless of the outcome of other checks"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"TransferFilterContractResult::ProceedTransfer")," will allow the transfer to proceed if other checks also pass")),(0,r.kt)("p",null,"The transfer filter can be enabled by passing a ",(0,r.kt)("inlineCode",{parentName:"p"},"ARG_TRANSFER_FILTER_CONTRACT")," argument to the install method, with a value of type ",(0,r.kt)("inlineCode",{parentName:"p"},"Option")),(0,r.kt)("h3",{id:"cep47-mode"},"CEP47 Mode"),(0,r.kt)("p",null,"The CEP47 ",(0,r.kt)("inlineCode",{parentName:"p"},"EventsMode")," modality mimics the event schema previously used in the CEP47 NFT standard. Events are stored as a ",(0,r.kt)("inlineCode",{parentName:"p"},"BTreeMap")," within a dictionary (",(0,r.kt)("inlineCode",{parentName:"p"},"EVENTS"),") in the contract's context. Entries consist of the ",(0,r.kt)("inlineCode",{parentName:"p"},"PREFIX_HASH_KEY_NAME"),", followed by the ",(0,r.kt)("inlineCode",{parentName:"p"},"EVENT_TYPE")," and then variable data as listed in the table below. The events can be retrieved directly via their dictionary entry using the JSON-RPC, with more information on this process available ",(0,r.kt)("a",{parentName:"p",href:"./concepts/dictionaries"},"here"),"."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Event name"),(0,r.kt)("th",{parentName:"tr",align:null},"Included values and type"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Mint"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"recipient (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Transfer"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"operator (Option)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"recipient (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Burn"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ApprovalGranted"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"spender (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ApprovalRevoked"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ApprovalForAll"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"operator (Key)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"RevokedForAll"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"operator (Key)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"MetadataUpdate"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Migration"),(0,r.kt)("td",{parentName:"tr",align:null},"-")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"VariablesSet"),(0,r.kt)("td",{parentName:"tr",align:null},"-")))),(0,r.kt)("h3",{id:"casper-event-standard"},"Casper Event Standard"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"CES")," is an option within the ",(0,r.kt)("inlineCode",{parentName:"p"},"EventsMode")," modality that determines how changes to tokens issued by the contract instance will be recorded. Any changes are recorded in the ",(0,r.kt)("inlineCode",{parentName:"p"},"__events")," dictionary and can be observed via a node's Server Side Events stream. They may also be viewed by querying the dictionary at any time using the JSON-RPC interface."),(0,r.kt)("p",null,"The emitted events are encoded according to the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/make-software/casper-event-standard"},"Casper Event Standard"),", and the schema is visible to an observer reading the ",(0,r.kt)("inlineCode",{parentName:"p"},"__events_schema")," contract named key."),(0,r.kt)("p",null,"For this CEP-78 reference implementation, the events schema is as follows:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Event name"),(0,r.kt)("th",{parentName:"tr",align:null},"Included values and type"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Mint"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"recipient (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"data (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Transfer"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"operator (Option)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"recipient (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Burn"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Approval"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"spender (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ApprovalRevoked"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ApprovalForAll"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"operator (Key)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"RevokedForAll"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"owner (Key)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"operator (Key)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"MetadataUpdated"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"token_id (String)"),", ",(0,r.kt)("inlineCode",{parentName:"td"},"data (String)"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Migration"),(0,r.kt)("td",{parentName:"tr",align:null},"-")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"VariablesSet"),(0,r.kt)("td",{parentName:"tr",align:null},"-")))),(0,r.kt)("h2",{id:"modality-conflicts"},"Modality Conflicts"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"MetadataMutability")," option set to ",(0,r.kt)("inlineCode",{parentName:"p"},"Mutable")," cannot be used in conjunction with the ",(0,r.kt)("inlineCode",{parentName:"p"},"NFTIdentifierMode")," modality set to ",(0,r.kt)("inlineCode",{parentName:"p"},"Hash"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7adc1d42.2f67eb3e.js b/assets/js/7adc1d42.8fad03fa.js similarity index 99% rename from assets/js/7adc1d42.2f67eb3e.js rename to assets/js/7adc1d42.8fad03fa.js index 477e60b67d..9d541210bc 100644 --- a/assets/js/7adc1d42.2f67eb3e.js +++ b/assets/js/7adc1d42.8fad03fa.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[9889],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var s=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);t&&(s=s.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,s)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(s=0;s=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=s.createContext({}),l=function(e){var t=s.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return s.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return s.createElement(s.Fragment,{},t)}},h=s.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=l(n),h=r,m=u["".concat(c,".").concat(h)]||u[h]||d[h]||a;return n?s.createElement(m,i(i({ref:t},p),{},{components:n})):s.createElement(m,i({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=h;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o[u]="string"==typeof e?e:r,i[1]=o;for(var l=2;l{\n // Test function implementation\n}\n")),(0,a.kt)("p",null,"This ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/tests/src/integration_tests.rs#L15-L55"},"unit test")," is a good example of testing session code. At a high level, the test follows this process:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Initialize an instance of the execution engine and the ",(0,a.kt)("inlineCode",{parentName:"li"},"InMemoryWasmTestBuilder"),".")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-rust"}," let mut builder = InMemoryWasmTestBuilder::default();\n")),(0,a.kt)("ol",{start:2},(0,a.kt)("li",{parentName:"ol"},"Execute the genesis process.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-rust"}," builder.run_genesis(&*DEFAULT_RUN_GENESIS_REQUEST).commit();\n")),(0,a.kt)("ol",{start:3},(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Execute the test-specific logic. In this example, retrieve information about the account running the session code and its associated keys. For full details, visit ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/tests/src/integration_tests.rs#L15-L55"},"GitHub"),".")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Retrieve runtime arguments, which should be the same as defined in the contract.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Create the execution request that sets up the session code to be processed. In this example, the ",(0,a.kt)("inlineCode",{parentName:"p"},"CONTRACT_WASM")," is the session code."))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-rust"}," let execute_request =\n ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CONTRACT_WASM, runtime_args)\n .build();\n")),(0,a.kt)("ol",{start:6},(0,a.kt)("li",{parentName:"ol"},"Invoke the execution engine to process the session code.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-rust"}," builder.exec(execute_request).expect_success().commit();\n")),(0,a.kt)("ol",{start:7},(0,a.kt)("li",{parentName:"ol"},"Verify that the results match the expected output. This example checks the associated keys.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-rust"}," assert!(associated_keys.contains_key(&ASSOCIATED_ACCOUNT_HASH));\n")),(0,a.kt)("h3",{id:"running-the-test"},"Running the Test"),(0,a.kt)("p",null,"This example uses a ",(0,a.kt)("inlineCode",{parentName:"p"},"Makefile")," to run the tests."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"make test\n")),(0,a.kt)("p",null,"Under the hood, the ",(0,a.kt)("inlineCode",{parentName:"p"},"Makefile")," generates a ",(0,a.kt)("inlineCode",{parentName:"p"},"tests/wasm")," folder, copies the Wasm to the folder, and runs the tests with ",(0,a.kt)("inlineCode",{parentName:"p"},"cargo test"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"mkdir -p tests/wasm\ncp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm\ncd tests && cargo test\n")),(0,a.kt)("h3",{id:"other-examples"},"Other Examples"),(0,a.kt)("p",null,"In the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs"},"counter unit tests"),", we use session code to call the contract. The code loads the account that pays for the session code, the session code Wasm, and the runtime arguments. Then, the code invokes the execution engine to process the session code."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-rust"}," // Use session code to increment the counter.\n let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n )\n .build();\n\n builder.exec(session_code_request)\n .expect_success()\n .commit();\n")),(0,a.kt)("p",null,"The verification step looks like this:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-rust"},'\n let incremented_count = builder\n .query(None, count_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::()\n .expect("should be i32.");\n\n assert_eq!(incremented_count, 1);\n')),(0,a.kt)("p",null,"For many more examples, visit the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/test"},"casper-node")," GitHub repository."),(0,a.kt)("h2",{id:"video-walkthrough"},"Video Walkthrough"),(0,a.kt)("p",null,"The following brief video describes testing the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/two-party-multi-sig/"},"sample session code")," for configuring an account."),(0,a.kt)("p",{align:"center"},(0,a.kt)("iframe",{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=5",frameborder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:!0})),(0,a.kt)("h2",{id:"whats-next"},"What's Next?"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Learn to ",(0,a.kt)("a",{parentName:"li",href:"/developers/cli/installing-contracts"},"install a contract and query global state"),".")))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[9889],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var s=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);t&&(s=s.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,s)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(s=0;s=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=s.createContext({}),l=function(e){var t=s.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return s.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return s.createElement(s.Fragment,{},t)}},h=s.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=l(n),h=r,m=u["".concat(c,".").concat(h)]||u[h]||d[h]||a;return n?s.createElement(m,i(i({ref:t},p),{},{components:n})):s.createElement(m,i({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=h;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o[u]="string"==typeof e?e:r,i[1]=o;for(var l=2;l{\n // Test function implementation\n}\n")),(0,a.kt)("p",null,"This ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/tests/src/integration_tests.rs#L15-L55"},"unit test")," is a good example of testing session code. At a high level, the test follows this process:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Initialize an instance of the execution engine and the ",(0,a.kt)("inlineCode",{parentName:"li"},"InMemoryWasmTestBuilder"),".")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-rust"}," let mut builder = InMemoryWasmTestBuilder::default();\n")),(0,a.kt)("ol",{start:2},(0,a.kt)("li",{parentName:"ol"},"Execute the genesis process.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-rust"}," builder.run_genesis(&*DEFAULT_RUN_GENESIS_REQUEST).commit();\n")),(0,a.kt)("ol",{start:3},(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Execute the test-specific logic. In this example, retrieve information about the account running the session code and its associated keys. For full details, visit ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/tests/src/integration_tests.rs#L15-L55"},"GitHub"),".")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Retrieve runtime arguments, which should be the same as defined in the contract.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Create the execution request that sets up the session code to be processed. In this example, the ",(0,a.kt)("inlineCode",{parentName:"p"},"CONTRACT_WASM")," is the session code."))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-rust"}," let execute_request =\n ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CONTRACT_WASM, runtime_args)\n .build();\n")),(0,a.kt)("ol",{start:6},(0,a.kt)("li",{parentName:"ol"},"Invoke the execution engine to process the session code.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-rust"}," builder.exec(execute_request).expect_success().commit();\n")),(0,a.kt)("ol",{start:7},(0,a.kt)("li",{parentName:"ol"},"Verify that the results match the expected output. This example checks the associated keys.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-rust"}," assert!(associated_keys.contains_key(&ASSOCIATED_ACCOUNT_HASH));\n")),(0,a.kt)("h3",{id:"running-the-test"},"Running the Test"),(0,a.kt)("p",null,"This example uses a ",(0,a.kt)("inlineCode",{parentName:"p"},"Makefile")," to run the tests."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"make test\n")),(0,a.kt)("p",null,"Under the hood, the ",(0,a.kt)("inlineCode",{parentName:"p"},"Makefile")," generates a ",(0,a.kt)("inlineCode",{parentName:"p"},"tests/wasm")," folder, copies the Wasm to the folder, and runs the tests with ",(0,a.kt)("inlineCode",{parentName:"p"},"cargo test"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"mkdir -p tests/wasm\ncp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm\ncd tests && cargo test\n")),(0,a.kt)("h3",{id:"other-examples"},"Other Examples"),(0,a.kt)("p",null,"In the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs"},"counter unit tests"),", we use session code to call the contract. The code loads the account that pays for the session code, the session code Wasm, and the runtime arguments. Then, the code invokes the execution engine to process the session code."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-rust"}," // Use session code to increment the counter.\n let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n )\n .build();\n\n builder.exec(session_code_request)\n .expect_success()\n .commit();\n")),(0,a.kt)("p",null,"The verification step looks like this:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-rust"},'\n let incremented_count = builder\n .query(None, count_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::()\n .expect("should be i32.");\n\n assert_eq!(incremented_count, 1);\n')),(0,a.kt)("p",null,"For many more examples, visit the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/test"},"casper-node")," GitHub repository."),(0,a.kt)("h2",{id:"video-walkthrough"},"Video Walkthrough"),(0,a.kt)("p",null,"The following brief video describes testing the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/two-party-multi-sig/"},"sample session code")," for configuring an account."),(0,a.kt)("p",{align:"center"},(0,a.kt)("iframe",{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=5",frameborder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:!0})),(0,a.kt)("h2",{id:"whats-next"},"What's Next?"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Learn to ",(0,a.kt)("a",{parentName:"li",href:"/developers/cli/installing-contracts"},"install a contract and query global state"),".")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7c09a624.6d653f8c.js b/assets/js/7c09a624.97fb84e6.js similarity index 98% rename from assets/js/7c09a624.6d653f8c.js rename to assets/js/7c09a624.97fb84e6.js index b13746477d..e6cdea5b15 100644 --- a/assets/js/7c09a624.6d653f8c.js +++ b/assets/js/7c09a624.97fb84e6.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6439],{3905:function(e,t,n){n.d(t,{Zo:function(){return l},kt:function(){return m}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),u=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=u(e.components);return r.createElement(s.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),d=u(n),h=a,m=d["".concat(s,".").concat(h)]||d[h]||p[h]||o;return n?r.createElement(m,i(i({ref:t},l),{},{components:n})):r.createElement(m,i({ref:t},l))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=h;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[d]="string"==typeof e?e:a,i[1]=c;for(var u=2;u donating_account_key\n },\n );\n system::transfer_from_purse_to_purse(\n account::get_main_purse(),\n donating_purse_uref,\n donation_amount,\n None\n )\n .unwrap_or_revert()\n}\n\n')),(0,o.kt)("p",null,"This session code calls into a contract's entry point by using ",(0,o.kt)("inlineCode",{parentName:"p"},"runtime::call_contract"),", supplying the ",(0,o.kt)("inlineCode",{parentName:"p"},"contract_hash")," to identify the contract to be called, and the name of the entry point to be invoked, in this case ",(0,o.kt)("inlineCode",{parentName:"p"},"donate"),". It supplies the ",(0,o.kt)("inlineCode",{parentName:"p"},"donating_account_key"),", which in this case is the account key of the caller. The contract will then provide a return value, in this case ",(0,o.kt)("inlineCode",{parentName:"p"},"donating_purse_uref"),". To call an entry point, you will need to know the ",(0,o.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_cl"},"CLType")," of the return value and identify it within the code."),(0,o.kt)("p",null,"You can determine the type of the return value by ",(0,o.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#querying-an-account"},"querying the contract object")," in global state. To query a contract rather than an account, replace the key parameter with the formatted string representation of the contract hash."),(0,o.kt)("p",null,"This example code takes that returned value and transfers a ",(0,o.kt)("inlineCode",{parentName:"p"},"donation_amount")," from the calling account's main purse to the established donation purse. It is not necessary for the code to store, or even use, the returned value. Use of the returned value depends on the needs of the developer."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6439],{3905:function(e,t,n){n.d(t,{Zo:function(){return l},kt:function(){return m}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),u=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=u(e.components);return r.createElement(s.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),d=u(n),h=a,m=d["".concat(s,".").concat(h)]||d[h]||p[h]||o;return n?r.createElement(m,i(i({ref:t},l),{},{components:n})):r.createElement(m,i({ref:t},l))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=h;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[d]="string"==typeof e?e:a,i[1]=c;for(var u=2;u donating_account_key\n },\n );\n system::transfer_from_purse_to_purse(\n account::get_main_purse(),\n donating_purse_uref,\n donation_amount,\n None\n )\n .unwrap_or_revert()\n}\n\n')),(0,o.kt)("p",null,"This session code calls into a contract's entry point by using ",(0,o.kt)("inlineCode",{parentName:"p"},"runtime::call_contract"),", supplying the ",(0,o.kt)("inlineCode",{parentName:"p"},"contract_hash")," to identify the contract to be called, and the name of the entry point to be invoked, in this case ",(0,o.kt)("inlineCode",{parentName:"p"},"donate"),". It supplies the ",(0,o.kt)("inlineCode",{parentName:"p"},"donating_account_key"),", which in this case is the account key of the caller. The contract will then provide a return value, in this case ",(0,o.kt)("inlineCode",{parentName:"p"},"donating_purse_uref"),". To call an entry point, you will need to know the ",(0,o.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_cl"},"CLType")," of the return value and identify it within the code."),(0,o.kt)("p",null,"You can determine the type of the return value by ",(0,o.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#querying-an-account"},"querying the contract object")," in global state. To query a contract rather than an account, replace the key parameter with the formatted string representation of the contract hash."),(0,o.kt)("p",null,"This example code takes that returned value and transfers a ",(0,o.kt)("inlineCode",{parentName:"p"},"donation_amount")," from the calling account's main purse to the established donation purse. It is not necessary for the code to store, or even use, the returned value. Use of the returned value depends on the needs of the developer."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7d846783.e1e79c9c.js b/assets/js/7d846783.c728110d.js similarity index 99% rename from assets/js/7d846783.e1e79c9c.js rename to assets/js/7d846783.c728110d.js index 5b60c2a6dc..78392ef047 100644 --- a/assets/js/7d846783.e1e79c9c.js +++ b/assets/js/7d846783.c728110d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[1002],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return h}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(n),m=r,h=d["".concat(c,".").concat(m)]||d[m]||u[m]||o;return n?a.createElement(h,i(i({ref:t},p),{},{components:n})):a.createElement(h,i({ref:t},p))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:r,i[1]=s;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(n),m=r,h=d["".concat(c,".").concat(m)]||d[m]||u[m]||o;return n?a.createElement(h,i(i({ref:t},p),{},{components:n})):a.createElement(h,i({ref:t},p))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:r,i[1]=s;for(var l=2;l=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),d=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},u=function(e){var t=d(e.components);return n.createElement(l.Provider,{value:t},e.children)},c="mdxType",_={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=d(a),p=r,h=c["".concat(l,".").concat(p)]||c[p]||_[p]||i;return a?n.createElement(h,o(o({ref:t},u),{},{components:a})):n.createElement(h,o({ref:t},u))}));function h(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=p;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:r,o[1]=s;for(var d=2;dadd_keys.wasm",id:"add_keyswasm",level:4},{value:"contract_call.wasm",id:"contract_callwasm",level:4},{value:"Testing this example",id:"testing-this-example",level:3},{value:"Test 1: should_allow_install_contract_with_default_account",id:"test-1-should_allow_install_contract_with_default_account",level:4},{value:"Test 2: should_disallow_install_with_non_added_authorization_key",id:"test-2-should_disallow_install_with_non_added_authorization_key",level:4},{value:"Test 3: should_allow_install_with_added_authorization_key",id:"test-3-should_allow_install_with_added_authorization_key",level:4},{value:"Test 4: should_allow_entry_point_with_installer_authorization_key",id:"test-4-should_allow_entry_point_with_installer_authorization_key",level:4},{value:"Test 5: should_allow_entry_point_with_account_authorization_key",id:"test-5-should_allow_entry_point_with_account_authorization_key",level:4},{value:"Test 6: should_disallow_entry_point_without_authorization_key",id:"test-6-should_disallow_entry_point_without_authorization_key",level:4},{value:"Test 7: should_allow_entry_point_through_contract_call_with_authorization_key",id:"test-7-should_allow_entry_point_through_contract_call_with_authorization_key",level:4},{value:"Test 8: should_disallow_entry_point_through_contract_call_without_authorization_key",id:"test-8-should_disallow_entry_point_through_contract_call_without_authorization_key",level:4}],_={toc:c},p="wrapper";function h(e){var t=e.components,a=(0,r.Z)(e,o);return(0,i.kt)(p,(0,n.Z)({},_,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"working-with-authorization-keys"},"Working with Authorization Keys"),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use.")),(0,i.kt)("p",null,"This tutorial demonstrates retrieving and using the authorization keys associated with a deploy using the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_authorization_keys.html"},"list_authorization_keys")," function."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let authorization_keys = runtime::list_authorization_keys();\n")),(0,i.kt)("p",null,"Remember that authorization keys are listed under a Deploy's ",(0,i.kt)("a",{parentName:"p",href:"/concepts/serialization-standard#serialization-standard-deploy"},"approvals")," section, which lists the signatures and the public keys of the signers, also called authorizing keys. Here is an example of a deploy's approvals:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'"approvals": [\n {\n "signer": "02021a4da3d6f32ea3ebd2519e1a37a1b811671085bf4f1cf2a36b931344a99b756a",\n "signature": "02df8cdf0bff3bd93e831d24563d5acbefa0ed13814550e910d03208d5fb3c11770dd3d918784ec84342e53666eacf59aeecbf4ce0cdd60e167c4a4b20e4b8f481"\n }\n]\n')),(0,i.kt)("p",null,"The contract code in this example retrieves the set of authorization keys for a given deploy by calling the ",(0,i.kt)("inlineCode",{parentName:"p"},"runtime::list_authorization_keys")," function. In other words, ",(0,i.kt)("inlineCode",{parentName:"p"},"list_authorization_keys")," returns the set of account hashes representing the keys used to sign a deploy. Upon installation, the contract code stores the authorization keys for the installer deploy into a NamedKey. The contract also contains an entry point that returns the intersection of the caller deploy's, and installer deploy's authorization keys. The tests in this repository verify different scenarios and check the resulting intersection."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"You meet the ",(0,i.kt)("a",{parentName:"li",href:"/developers/prerequisites"},"development prerequisites")," and are familiar with ",(0,i.kt)("a",{parentName:"li",href:"/writing-contracts"},"writing and testing on-chain code")),(0,i.kt)("li",{parentName:"ul"},"You know how to ",(0,i.kt)("a",{parentName:"li",href:"/developers/cli/sending-deploys"},"send and verify deploys")),(0,i.kt)("li",{parentName:"ul"},"You are familiar with these concepts:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#serialization-standard-account"},"Casper Accounts")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#serialization-standard-deploy"},"Deploys")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#associatedkey"},"Associated Keys")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#approval"},"Approvals"),", also known as authorization keys")))),(0,i.kt)("h2",{id:"workflow"},"Workflow"),(0,i.kt)("p",null,"To start, clone the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm"},"tutorials-example-wasm")," repository. Then, open the ",(0,i.kt)("inlineCode",{parentName:"p"},"authorization-keys-example")," directory, prepare your Rust environment, and build the tests with the following commands."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/casper-ecosystem/tutorials-example-wasm\ncd tutorials-example-wasm/authorization-keys-example\nmake prepare\nmake test\n")),(0,i.kt)("p",null,"Review the repository's structure:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/client"},"client")," - A client folder containing two Wasm files",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"add_keys.wasm")," - Session code that adds an associated key to the calling account"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"contract_call.wasm")," - Session code that calls the contract's entry point and stores the result into a named key"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/contract"},"contract")," - A simple contract that demonstrates the usage of authorization keys and compiles into a ",(0,i.kt)("inlineCode",{parentName:"li"},"contract.wasm")," file"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/tests"},"tests")," - Tests and supporting utilities to verify and demonstrate the contract's expected behavior")),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},"This tutorial highlights certain lines of code found in ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example"},"GitHub"),".")),(0,i.kt)("h3",{id:"the-example-contract"},"The example contract"),(0,i.kt)("p",null,"Upon ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/contract/src/main.rs#L75"},"installation"),", the contract in this example stores the authorization keys that signed the installer deploy into a named key."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn init() {\n if runtime::get_key(AUTHORIZATION_KEYS_INSTALLER).is_none() {\n let authorization_keys: Vec =\n runtime::list_authorization_keys().iter().cloned().collect();\n\n let authorization_keys: Key = storage::new_uref(authorization_keys).into();\n runtime::put_key(AUTHORIZATION_KEYS_INSTALLER, authorization_keys);\n }\n}\n')),(0,i.kt)("p",null,"The contract contains an entry point that returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys saved during contract installation. The following ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/contract/src/main.rs#L52"},"usage")," of ",(0,i.kt)("inlineCode",{parentName:"p"},"runtime::list_authorization_keys")," retrieves the set of account hashes representing the keys signing the caller deploy."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let authorization_keys_caller: Vec =\n runtime::list_authorization_keys().iter().cloned().collect();\n")),(0,i.kt)("h3",{id:"client-wasm-files"},"Client Wasm files"),(0,i.kt)("h4",{id:"add_keyswasm"},(0,i.kt)("inlineCode",{parentName:"h4"},"add_keys.wasm")),(0,i.kt)("p",null,"This file contains session code that adds an associated key to the calling account. For more details and a similar example, visit the ",(0,i.kt)("a",{parentName:"p",href:"/resources/tutorials/advanced/two-party-multi-sig"},"Two-Party Multi-Signature")," tutorial."),(0,i.kt)("h4",{id:"contract_callwasm"},(0,i.kt)("inlineCode",{parentName:"h4"},"contract_call.wasm")),(0,i.kt)("p",null,"This session code calls the contract's entry point, which returns the intersection between two sets of keys:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The authorization keys that signed the deploy that installed the contract (referred to in this tutorial as the installer deploy)"),(0,i.kt)("li",{parentName:"ul"},"The authorization keys that signed the deploy calling the entry point (referred to in this tutorial as the caller deploy).")),(0,i.kt)("p",null,"The intersection result is a list stored under a named key of the account calling the ",(0,i.kt)("inlineCode",{parentName:"p"},"contract_call.wasm"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let key_name: String = runtime::get_named_arg(ARG_KEY_NAME);\nlet intersection =\n runtime::call_contract::>(contract_hash, ENTRY_POINT, runtime_args! {});\nruntime::put_key(&key_name, storage::new_uref(intersection).into());\n}\n")),(0,i.kt)("h3",{id:"testing-this-example"},"Testing this example"),(0,i.kt)("p",null,"This section highlights the tests written for this example, demonstrating the usage of authorization keys. The tests are divided into three parts:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Testing the contract installation"),(0,i.kt)("li",{parentName:"ul"},"Testing the contract's unique entry point"),(0,i.kt)("li",{parentName:"ul"},"Testing the entry point using a client contract call")),(0,i.kt)("p",null,"These tests focus on testing the contract installation."),(0,i.kt)("h4",{id:"test-1-should_allow_install_contract_with_default_account"},"Test 1: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_allow_install_contract_with_default_account")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Expected outcome"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},"Successful contract installation")))),(0,i.kt)("p",null,"This ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L28"},"test")," signs the installer deploy with an authorization key ",(0,i.kt)("inlineCode",{parentName:"p"},"DEFAULT_ACCOUNT_ADDR")," that belongs to the calling accounts's associated keys. In other words, since the caller is the default account, ",(0,i.kt)("inlineCode",{parentName:"p"},"DEFAULT_ACCOUNT_ADDR")," can be used to sign the deploy."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let session_code = PathBuf::from(CONTRACT_WASM);\nlet session_args = RuntimeArgs::new();\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\n")),(0,i.kt)("h4",{id:"test-2-should_disallow_install_with_non_added_authorization_key"},"Test 2: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_disallow_install_with_non_added_authorization_key")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Expected outcome"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR"),", ",(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_1")),(0,i.kt)("td",{parentName:"tr",align:null},"Failed contract installation")))),(0,i.kt)("p",null,"This ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L57"},"test")," tries to sign the installer deploy with an authorization key that is not part of the caller's associated keys. This is not allowed because the authorization keys used to sign a deploy need to be a subset of the caller's associated keys. So, the installer deploy fails as expected."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},'let session_code = PathBuf::from(CONTRACT_WASM);\nlet session_args = RuntimeArgs::new();\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();\nbuilder.exec(execute_request).commit().expect_failure();\nlet error = builder.get_error().expect("must have error");\nassert_eq!(error.to_string(), "Authorization failure: not authorized.");\n')),(0,i.kt)("h4",{id:"test-3-should_allow_install_with_added_authorization_key"},"Test 3: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_allow_install_with_added_authorization_key")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Expected outcome"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR"),", ",(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_1")),(0,i.kt)("td",{parentName:"tr",align:null},"Successful contract installation")))),(0,i.kt)("p",null,"This ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L83"},"test")," demonstrates a successful installer deploy using an added authorization key. After the initial test framework setup, the test calls session code to add the associated account ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_1")," to the default account's associated keys."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"// Add account_addr_1 to the default account's associated keys\nlet session_code = PathBuf::from(ADD_KEYS_WASM);\nlet session_args = runtime_args! {\n ASSOCIATED_ACCOUNT => account_addr_1\n};\n\nlet add_keys_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet add_keys_execute_request =\n ExecuteRequestBuilder::from_deploy_item(add_keys_deploy_item).build();\n\nbuilder\n .exec(add_keys_execute_request)\n .commit()\n .expect_success();\n")),(0,i.kt)("p",null,"Since the deploy threshold is now 2, the installer deploy is signed with the default account hash and with ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_1"),". See ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L191"},"GitHub"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();\nbuilder.exec(execute_request).commit().expect_success();\n")),(0,i.kt)("p",null,"The next tests exercise the contract's unique entry point to calculate the intersection between the caller deploy's authorization keys and the installer deploy's authorization keys."),(0,i.kt)("h4",{id:"test-4-should_allow_entry_point_with_installer_authorization_key"},"Test 4: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_allow_entry_point_with_installer_authorization_key")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Caller deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Intersection returned by the entry point"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_1"),", ",(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_1"))))),(0,i.kt)("p",null,"This ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L144"},"test")," builds upon the previous test, which adds an associated account to the default account's associated keys and installs the contract using these two keys. Additionally, on line 201, the test invokes the contract's entry point using a deploy that runs under ",(0,i.kt)("inlineCode",{parentName:"p"},"ACCOUNT_USER_1")," signed only with ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_1"),". This is possible because the deploy action threshold for ",(0,i.kt)("inlineCode",{parentName:"p"},"ACCOUNT_USER_1")," is 1 as you can see ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L201"},"here"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},'let contract_hash = builder\n .get_expected_account(*DEFAULT_ACCOUNT_ADDR)\n .named_keys()\n .get(CONTRACT_HASH)\n .expect("must have this entry in named keys")\n .into_hash()\n .map(ContractHash::new)\n .unwrap();\n\nlet entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1])\n .with_address(account_addr_1)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).expect_success().commit();\n')),(0,i.kt)("p",null,"The entry point returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys. The intersection is a list containing the key ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_1"),". Thus, the caller deploy is expected to succeed and return a result."),(0,i.kt)("h4",{id:"test-5-should_allow_entry_point_with_account_authorization_key"},"Test 5: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_allow_entry_point_with_account_authorization_key")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Caller deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Intersection returned by the entry point"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_1"),", ",(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR"))))),(0,i.kt)("p",null,"This is the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L224"},"main test")," in this example repository. After installing the contract using the default account, the test adds the default account hash to ",(0,i.kt)("inlineCode",{parentName:"p"},"ACCOUNT_USER_1")," as an associated key."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let session_code = PathBuf::from(ADD_KEYS_WASM);\nlet session_args = runtime_args! {\n ASSOCIATED_ACCOUNT => *DEFAULT_ACCOUNT_ADDR\n};\n\nlet add_keys_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n")),(0,i.kt)("p",null,"Then, the test creates a deploy to invoke the contract's entry point. This deploy executes under ",(0,i.kt)("inlineCode",{parentName:"p"},"ACCOUNT_USER_1")," and has two authorization keys, ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_1")," and the default account hash. Note that both authorization keys must sign the deploy to meet the deploy's action threshold, which is set to 2. The deploy should be executed successfully because the resulting intersection should contain the default account hash."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])\n .with_address(account_addr_1)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).expect_success().commit();\n")),(0,i.kt)("h4",{id:"test-6-should_disallow_entry_point_without_authorization_key"},"Test 6: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_disallow_entry_point_without_authorization_key")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Caller deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Intersection returned by the entry point"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_2")),(0,i.kt)("td",{parentName:"tr",align:null},"None")))),(0,i.kt)("p",null,"This ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L304"},"test")," verifies that the entry point returns an error when there is no intersection between the caller deploy's authorization keys and the installer deploy's authorization keys."),(0,i.kt)("p",null,"The default account hash is used to sign the installer deploy."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, runtime_args! {})\n .build();\n")),(0,i.kt)("p",null,"In the test, a new account, ",(0,i.kt)("inlineCode",{parentName:"p"},"ACCOUNT_USER_2"),", creates a deploy invoking the contract's entry point and signs the deploy with ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_2"),". When calling the entry point, an error is returned because the caller and the installer deploys do not have any authorization keys in common."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},' // Here ACCOUNT_USER_2 does not have DEFAULT_ACCOUNT_ADDR (from the contract installer) in its associated keys\n // The deploy will therefore revert with PermissionDenied\n let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_2])\n .with_address(account_addr_2)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\n let entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\n builder.exec(entry_point_request).commit().expect_failure();\n let error = builder.get_error().expect("must have User error: 0");\n assert_expected_error(\n error,\n 0,\n "should fail execution since DEFAULT_ACCOUNT_ADDR is not in ACCOUNT_USER_2 associated keys",\n );\n')),(0,i.kt)("p",null,"The following tests exercise the entry point using a ",(0,i.kt)("a",{parentName:"p",href:"#contract_callwasm"},"contract call")," and verifying the result returned."),(0,i.kt)("h4",{id:"test-7-should_allow_entry_point_through_contract_call_with_authorization_key"},"Test 7: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_allow_entry_point_through_contract_call_with_authorization_key")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Caller deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Intersection returned by the entry point"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_1"),", ",(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR"))))),(0,i.kt)("p",null,"This ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L403"},"test")," validates the contract's entry point using a client contract call. The contract is installed using the default account hash in the deploy's authorization keys."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, runtime_args! {})\n .build();\n")),(0,i.kt)("p",null,"The caller deploy is signed by ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_1")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"DEFAULT_ACCOUNT_ADDR"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\nbuilder.exec(entry_point_request).expect_success().commit();\n")),(0,i.kt)("p",null,"The test then verifies that the result returned was saved in the named keys for ",(0,i.kt)("inlineCode",{parentName:"p"},"ACCOUNT_USER_1"),", containing the default account hash."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},'let intersection_receipt: Key = *builder\n .get_expected_account(account_addr_1)\n .named_keys()\n .get(INTERSECTION_RECEIPT)\n .expect("must have this entry in named keys");\n\nlet actual_intersection = builder\n .query(None, intersection_receipt, &[])\n .expect("must have stored_value")\n .as_cl_value()\n .map(|intersection_cl_value| {\n CLValue::into_t::>(intersection_cl_value.clone())\n })\n .unwrap()\n .unwrap();\n\nlet expected_intersection = vec![*DEFAULT_ACCOUNT_ADDR];\n\nassert_eq!(actual_intersection, expected_intersection);\n')),(0,i.kt)("h4",{id:"test-8-should_disallow_entry_point_through_contract_call_without_authorization_key"},"Test 8: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_disallow_entry_point_through_contract_call_without_authorization_key")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Caller deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Intersection returned by the entry point"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_1"),", ",(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_2")),(0,i.kt)("td",{parentName:"tr",align:null},"None")))),(0,i.kt)("p",null,"The ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L509"},"final test")," in this tutorial checks that when there is no intersection between the caller deploy's authorization keys (",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_1"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_2"),") and the installer deploy's authorization keys (",(0,i.kt)("inlineCode",{parentName:"p"},"DEFAULT_ACCOUNT_ADDR"),"), the entry point returns an error."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},' let session_code = PathBuf::from(CONTRACT_CALL_WASM);\n\nlet session_args = runtime_args! {\n ARG_CONTRACT_HASH => Key::from(contract_hash),\n ARG_KEY_NAME => INTERSECTION_RECEIPT\n};\n\n// account_addr_2 as an associated key is not among the default account\'s associated keys\n// The deploy will therefore revert with PermissionDenied\nlet entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, account_addr_2])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).commit().expect_failure();\n\nlet error = builder.get_error().expect("must have User error: 0");\nassert_expected_error(\n error,\n 0,\n "should fail execution since ACCOUNT_USER_2 as associated key is not in installer (DEFAULT_ACCOUNT_ADDR) associated keys",\n);\n')))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3174],{3905:function(e,t,a){a.d(t,{Zo:function(){return u},kt:function(){return h}});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),d=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},u=function(e){var t=d(e.components);return n.createElement(l.Provider,{value:t},e.children)},c="mdxType",_={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=d(a),p=r,h=c["".concat(l,".").concat(p)]||c[p]||_[p]||i;return a?n.createElement(h,o(o({ref:t},u),{},{components:a})):n.createElement(h,o({ref:t},u))}));function h(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=p;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:r,o[1]=s;for(var d=2;dadd_keys.wasm",id:"add_keyswasm",level:4},{value:"contract_call.wasm",id:"contract_callwasm",level:4},{value:"Testing this example",id:"testing-this-example",level:3},{value:"Test 1: should_allow_install_contract_with_default_account",id:"test-1-should_allow_install_contract_with_default_account",level:4},{value:"Test 2: should_disallow_install_with_non_added_authorization_key",id:"test-2-should_disallow_install_with_non_added_authorization_key",level:4},{value:"Test 3: should_allow_install_with_added_authorization_key",id:"test-3-should_allow_install_with_added_authorization_key",level:4},{value:"Test 4: should_allow_entry_point_with_installer_authorization_key",id:"test-4-should_allow_entry_point_with_installer_authorization_key",level:4},{value:"Test 5: should_allow_entry_point_with_account_authorization_key",id:"test-5-should_allow_entry_point_with_account_authorization_key",level:4},{value:"Test 6: should_disallow_entry_point_without_authorization_key",id:"test-6-should_disallow_entry_point_without_authorization_key",level:4},{value:"Test 7: should_allow_entry_point_through_contract_call_with_authorization_key",id:"test-7-should_allow_entry_point_through_contract_call_with_authorization_key",level:4},{value:"Test 8: should_disallow_entry_point_through_contract_call_without_authorization_key",id:"test-8-should_disallow_entry_point_through_contract_call_without_authorization_key",level:4}],_={toc:c},p="wrapper";function h(e){var t=e.components,a=(0,r.Z)(e,o);return(0,i.kt)(p,(0,n.Z)({},_,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"working-with-authorization-keys"},"Working with Authorization Keys"),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use.")),(0,i.kt)("p",null,"This tutorial demonstrates retrieving and using the authorization keys associated with a deploy using the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_authorization_keys.html"},"list_authorization_keys")," function."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let authorization_keys = runtime::list_authorization_keys();\n")),(0,i.kt)("p",null,"Remember that authorization keys are listed under a Deploy's ",(0,i.kt)("a",{parentName:"p",href:"/concepts/serialization-standard#serialization-standard-deploy"},"approvals")," section, which lists the signatures and the public keys of the signers, also called authorizing keys. Here is an example of a deploy's approvals:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'"approvals": [\n {\n "signer": "02021a4da3d6f32ea3ebd2519e1a37a1b811671085bf4f1cf2a36b931344a99b756a",\n "signature": "02df8cdf0bff3bd93e831d24563d5acbefa0ed13814550e910d03208d5fb3c11770dd3d918784ec84342e53666eacf59aeecbf4ce0cdd60e167c4a4b20e4b8f481"\n }\n]\n')),(0,i.kt)("p",null,"The contract code in this example retrieves the set of authorization keys for a given deploy by calling the ",(0,i.kt)("inlineCode",{parentName:"p"},"runtime::list_authorization_keys")," function. In other words, ",(0,i.kt)("inlineCode",{parentName:"p"},"list_authorization_keys")," returns the set of account hashes representing the keys used to sign a deploy. Upon installation, the contract code stores the authorization keys for the installer deploy into a NamedKey. The contract also contains an entry point that returns the intersection of the caller deploy's, and installer deploy's authorization keys. The tests in this repository verify different scenarios and check the resulting intersection."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"You meet the ",(0,i.kt)("a",{parentName:"li",href:"/developers/prerequisites"},"development prerequisites")," and are familiar with ",(0,i.kt)("a",{parentName:"li",href:"/writing-contracts"},"writing and testing on-chain code")),(0,i.kt)("li",{parentName:"ul"},"You know how to ",(0,i.kt)("a",{parentName:"li",href:"/developers/cli/sending-deploys"},"send and verify deploys")),(0,i.kt)("li",{parentName:"ul"},"You are familiar with these concepts:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#serialization-standard-account"},"Casper Accounts")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#serialization-standard-deploy"},"Deploys")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#associatedkey"},"Associated Keys")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#approval"},"Approvals"),", also known as authorization keys")))),(0,i.kt)("h2",{id:"workflow"},"Workflow"),(0,i.kt)("p",null,"To start, clone the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm"},"tutorials-example-wasm")," repository. Then, open the ",(0,i.kt)("inlineCode",{parentName:"p"},"authorization-keys-example")," directory, prepare your Rust environment, and build the tests with the following commands."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/casper-ecosystem/tutorials-example-wasm\ncd tutorials-example-wasm/authorization-keys-example\nmake prepare\nmake test\n")),(0,i.kt)("p",null,"Review the repository's structure:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/client"},"client")," - A client folder containing two Wasm files",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"add_keys.wasm")," - Session code that adds an associated key to the calling account"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"contract_call.wasm")," - Session code that calls the contract's entry point and stores the result into a named key"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/contract"},"contract")," - A simple contract that demonstrates the usage of authorization keys and compiles into a ",(0,i.kt)("inlineCode",{parentName:"li"},"contract.wasm")," file"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/tests"},"tests")," - Tests and supporting utilities to verify and demonstrate the contract's expected behavior")),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},"This tutorial highlights certain lines of code found in ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example"},"GitHub"),".")),(0,i.kt)("h3",{id:"the-example-contract"},"The example contract"),(0,i.kt)("p",null,"Upon ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/contract/src/main.rs#L75"},"installation"),", the contract in this example stores the authorization keys that signed the installer deploy into a named key."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn init() {\n if runtime::get_key(AUTHORIZATION_KEYS_INSTALLER).is_none() {\n let authorization_keys: Vec =\n runtime::list_authorization_keys().iter().cloned().collect();\n\n let authorization_keys: Key = storage::new_uref(authorization_keys).into();\n runtime::put_key(AUTHORIZATION_KEYS_INSTALLER, authorization_keys);\n }\n}\n')),(0,i.kt)("p",null,"The contract contains an entry point that returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys saved during contract installation. The following ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/contract/src/main.rs#L52"},"usage")," of ",(0,i.kt)("inlineCode",{parentName:"p"},"runtime::list_authorization_keys")," retrieves the set of account hashes representing the keys signing the caller deploy."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let authorization_keys_caller: Vec =\n runtime::list_authorization_keys().iter().cloned().collect();\n")),(0,i.kt)("h3",{id:"client-wasm-files"},"Client Wasm files"),(0,i.kt)("h4",{id:"add_keyswasm"},(0,i.kt)("inlineCode",{parentName:"h4"},"add_keys.wasm")),(0,i.kt)("p",null,"This file contains session code that adds an associated key to the calling account. For more details and a similar example, visit the ",(0,i.kt)("a",{parentName:"p",href:"/resources/tutorials/advanced/two-party-multi-sig"},"Two-Party Multi-Signature")," tutorial."),(0,i.kt)("h4",{id:"contract_callwasm"},(0,i.kt)("inlineCode",{parentName:"h4"},"contract_call.wasm")),(0,i.kt)("p",null,"This session code calls the contract's entry point, which returns the intersection between two sets of keys:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The authorization keys that signed the deploy that installed the contract (referred to in this tutorial as the installer deploy)"),(0,i.kt)("li",{parentName:"ul"},"The authorization keys that signed the deploy calling the entry point (referred to in this tutorial as the caller deploy).")),(0,i.kt)("p",null,"The intersection result is a list stored under a named key of the account calling the ",(0,i.kt)("inlineCode",{parentName:"p"},"contract_call.wasm"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let key_name: String = runtime::get_named_arg(ARG_KEY_NAME);\nlet intersection =\n runtime::call_contract::>(contract_hash, ENTRY_POINT, runtime_args! {});\nruntime::put_key(&key_name, storage::new_uref(intersection).into());\n}\n")),(0,i.kt)("h3",{id:"testing-this-example"},"Testing this example"),(0,i.kt)("p",null,"This section highlights the tests written for this example, demonstrating the usage of authorization keys. The tests are divided into three parts:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Testing the contract installation"),(0,i.kt)("li",{parentName:"ul"},"Testing the contract's unique entry point"),(0,i.kt)("li",{parentName:"ul"},"Testing the entry point using a client contract call")),(0,i.kt)("p",null,"These tests focus on testing the contract installation."),(0,i.kt)("h4",{id:"test-1-should_allow_install_contract_with_default_account"},"Test 1: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_allow_install_contract_with_default_account")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Expected outcome"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},"Successful contract installation")))),(0,i.kt)("p",null,"This ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L28"},"test")," signs the installer deploy with an authorization key ",(0,i.kt)("inlineCode",{parentName:"p"},"DEFAULT_ACCOUNT_ADDR")," that belongs to the calling accounts's associated keys. In other words, since the caller is the default account, ",(0,i.kt)("inlineCode",{parentName:"p"},"DEFAULT_ACCOUNT_ADDR")," can be used to sign the deploy."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let session_code = PathBuf::from(CONTRACT_WASM);\nlet session_args = RuntimeArgs::new();\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\n")),(0,i.kt)("h4",{id:"test-2-should_disallow_install_with_non_added_authorization_key"},"Test 2: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_disallow_install_with_non_added_authorization_key")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Expected outcome"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR"),", ",(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_1")),(0,i.kt)("td",{parentName:"tr",align:null},"Failed contract installation")))),(0,i.kt)("p",null,"This ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L57"},"test")," tries to sign the installer deploy with an authorization key that is not part of the caller's associated keys. This is not allowed because the authorization keys used to sign a deploy need to be a subset of the caller's associated keys. So, the installer deploy fails as expected."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},'let session_code = PathBuf::from(CONTRACT_WASM);\nlet session_args = RuntimeArgs::new();\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();\nbuilder.exec(execute_request).commit().expect_failure();\nlet error = builder.get_error().expect("must have error");\nassert_eq!(error.to_string(), "Authorization failure: not authorized.");\n')),(0,i.kt)("h4",{id:"test-3-should_allow_install_with_added_authorization_key"},"Test 3: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_allow_install_with_added_authorization_key")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Expected outcome"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR"),", ",(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_1")),(0,i.kt)("td",{parentName:"tr",align:null},"Successful contract installation")))),(0,i.kt)("p",null,"This ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L83"},"test")," demonstrates a successful installer deploy using an added authorization key. After the initial test framework setup, the test calls session code to add the associated account ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_1")," to the default account's associated keys."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"// Add account_addr_1 to the default account's associated keys\nlet session_code = PathBuf::from(ADD_KEYS_WASM);\nlet session_args = runtime_args! {\n ASSOCIATED_ACCOUNT => account_addr_1\n};\n\nlet add_keys_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet add_keys_execute_request =\n ExecuteRequestBuilder::from_deploy_item(add_keys_deploy_item).build();\n\nbuilder\n .exec(add_keys_execute_request)\n .commit()\n .expect_success();\n")),(0,i.kt)("p",null,"Since the deploy threshold is now 2, the installer deploy is signed with the default account hash and with ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_1"),". See ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L191"},"GitHub"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();\nbuilder.exec(execute_request).commit().expect_success();\n")),(0,i.kt)("p",null,"The next tests exercise the contract's unique entry point to calculate the intersection between the caller deploy's authorization keys and the installer deploy's authorization keys."),(0,i.kt)("h4",{id:"test-4-should_allow_entry_point_with_installer_authorization_key"},"Test 4: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_allow_entry_point_with_installer_authorization_key")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Caller deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Intersection returned by the entry point"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_1"),", ",(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_1"))))),(0,i.kt)("p",null,"This ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L144"},"test")," builds upon the previous test, which adds an associated account to the default account's associated keys and installs the contract using these two keys. Additionally, on line 201, the test invokes the contract's entry point using a deploy that runs under ",(0,i.kt)("inlineCode",{parentName:"p"},"ACCOUNT_USER_1")," signed only with ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_1"),". This is possible because the deploy action threshold for ",(0,i.kt)("inlineCode",{parentName:"p"},"ACCOUNT_USER_1")," is 1 as you can see ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L201"},"here"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},'let contract_hash = builder\n .get_expected_account(*DEFAULT_ACCOUNT_ADDR)\n .named_keys()\n .get(CONTRACT_HASH)\n .expect("must have this entry in named keys")\n .into_hash()\n .map(ContractHash::new)\n .unwrap();\n\nlet entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1])\n .with_address(account_addr_1)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).expect_success().commit();\n')),(0,i.kt)("p",null,"The entry point returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys. The intersection is a list containing the key ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_1"),". Thus, the caller deploy is expected to succeed and return a result."),(0,i.kt)("h4",{id:"test-5-should_allow_entry_point_with_account_authorization_key"},"Test 5: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_allow_entry_point_with_account_authorization_key")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Caller deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Intersection returned by the entry point"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_1"),", ",(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR"))))),(0,i.kt)("p",null,"This is the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L224"},"main test")," in this example repository. After installing the contract using the default account, the test adds the default account hash to ",(0,i.kt)("inlineCode",{parentName:"p"},"ACCOUNT_USER_1")," as an associated key."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let session_code = PathBuf::from(ADD_KEYS_WASM);\nlet session_args = runtime_args! {\n ASSOCIATED_ACCOUNT => *DEFAULT_ACCOUNT_ADDR\n};\n\nlet add_keys_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n")),(0,i.kt)("p",null,"Then, the test creates a deploy to invoke the contract's entry point. This deploy executes under ",(0,i.kt)("inlineCode",{parentName:"p"},"ACCOUNT_USER_1")," and has two authorization keys, ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_1")," and the default account hash. Note that both authorization keys must sign the deploy to meet the deploy's action threshold, which is set to 2. The deploy should be executed successfully because the resulting intersection should contain the default account hash."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])\n .with_address(account_addr_1)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).expect_success().commit();\n")),(0,i.kt)("h4",{id:"test-6-should_disallow_entry_point_without_authorization_key"},"Test 6: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_disallow_entry_point_without_authorization_key")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Caller deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Intersection returned by the entry point"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_2")),(0,i.kt)("td",{parentName:"tr",align:null},"None")))),(0,i.kt)("p",null,"This ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L304"},"test")," verifies that the entry point returns an error when there is no intersection between the caller deploy's authorization keys and the installer deploy's authorization keys."),(0,i.kt)("p",null,"The default account hash is used to sign the installer deploy."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, runtime_args! {})\n .build();\n")),(0,i.kt)("p",null,"In the test, a new account, ",(0,i.kt)("inlineCode",{parentName:"p"},"ACCOUNT_USER_2"),", creates a deploy invoking the contract's entry point and signs the deploy with ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_2"),". When calling the entry point, an error is returned because the caller and the installer deploys do not have any authorization keys in common."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},' // Here ACCOUNT_USER_2 does not have DEFAULT_ACCOUNT_ADDR (from the contract installer) in its associated keys\n // The deploy will therefore revert with PermissionDenied\n let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_2])\n .with_address(account_addr_2)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\n let entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\n builder.exec(entry_point_request).commit().expect_failure();\n let error = builder.get_error().expect("must have User error: 0");\n assert_expected_error(\n error,\n 0,\n "should fail execution since DEFAULT_ACCOUNT_ADDR is not in ACCOUNT_USER_2 associated keys",\n );\n')),(0,i.kt)("p",null,"The following tests exercise the entry point using a ",(0,i.kt)("a",{parentName:"p",href:"#contract_callwasm"},"contract call")," and verifying the result returned."),(0,i.kt)("h4",{id:"test-7-should_allow_entry_point_through_contract_call_with_authorization_key"},"Test 7: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_allow_entry_point_through_contract_call_with_authorization_key")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Caller deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Intersection returned by the entry point"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_1"),", ",(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR"))))),(0,i.kt)("p",null,"This ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L403"},"test")," validates the contract's entry point using a client contract call. The contract is installed using the default account hash in the deploy's authorization keys."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, runtime_args! {})\n .build();\n")),(0,i.kt)("p",null,"The caller deploy is signed by ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_1")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"DEFAULT_ACCOUNT_ADDR"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},"let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\nbuilder.exec(entry_point_request).expect_success().commit();\n")),(0,i.kt)("p",null,"The test then verifies that the result returned was saved in the named keys for ",(0,i.kt)("inlineCode",{parentName:"p"},"ACCOUNT_USER_1"),", containing the default account hash."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},'let intersection_receipt: Key = *builder\n .get_expected_account(account_addr_1)\n .named_keys()\n .get(INTERSECTION_RECEIPT)\n .expect("must have this entry in named keys");\n\nlet actual_intersection = builder\n .query(None, intersection_receipt, &[])\n .expect("must have stored_value")\n .as_cl_value()\n .map(|intersection_cl_value| {\n CLValue::into_t::>(intersection_cl_value.clone())\n })\n .unwrap()\n .unwrap();\n\nlet expected_intersection = vec![*DEFAULT_ACCOUNT_ADDR];\n\nassert_eq!(actual_intersection, expected_intersection);\n')),(0,i.kt)("h4",{id:"test-8-should_disallow_entry_point_through_contract_call_without_authorization_key"},"Test 8: ",(0,i.kt)("inlineCode",{parentName:"h4"},"should_disallow_entry_point_through_contract_call_without_authorization_key")),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Installer deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Caller deploy authorization keys"),(0,i.kt)("th",{parentName:"tr",align:null},"Intersection returned by the entry point"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"DEFAULT_ACCOUNT_ADDR")),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_1"),", ",(0,i.kt)("inlineCode",{parentName:"td"},"account_addr_2")),(0,i.kt)("td",{parentName:"tr",align:null},"None")))),(0,i.kt)("p",null,"The ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L509"},"final test")," in this tutorial checks that when there is no intersection between the caller deploy's authorization keys (",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_1"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"account_addr_2"),") and the installer deploy's authorization keys (",(0,i.kt)("inlineCode",{parentName:"p"},"DEFAULT_ACCOUNT_ADDR"),"), the entry point returns an error."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-rust"},' let session_code = PathBuf::from(CONTRACT_CALL_WASM);\n\nlet session_args = runtime_args! {\n ARG_CONTRACT_HASH => Key::from(contract_hash),\n ARG_KEY_NAME => INTERSECTION_RECEIPT\n};\n\n// account_addr_2 as an associated key is not among the default account\'s associated keys\n// The deploy will therefore revert with PermissionDenied\nlet entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, account_addr_2])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).commit().expect_failure();\n\nlet error = builder.get_error().expect("must have User error: 0");\nassert_expected_error(\n error,\n 0,\n "should fail execution since ACCOUNT_USER_2 as associated key is not in installer (DEFAULT_ACCOUNT_ADDR) associated keys",\n);\n')))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/80eab72b.d3aee779.js b/assets/js/80eab72b.a2eea8b9.js similarity index 99% rename from assets/js/80eab72b.d3aee779.js rename to assets/js/80eab72b.a2eea8b9.js index e0ea608282..163e98e24d 100644 --- a/assets/js/80eab72b.d3aee779.js +++ b/assets/js/80eab72b.a2eea8b9.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[7562],{3905:function(e,n,a){a.d(n,{Zo:function(){return i},kt:function(){return u}});var t=a(7294);function r(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function c(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function f(e){for(var n=1;n=0||(r[a]=e[a]);return r}(e,n);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var d=t.createContext({}),o=function(e){var n=t.useContext(d),a=n;return e&&(a="function"==typeof e?e(n):f(f({},n),e)),a},i=function(e){var n=o(e.components);return t.createElement(d.Provider,{value:n},e.children)},l="mdxType",b={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},p=t.forwardRef((function(e,n){var a=e.components,r=e.mdxType,c=e.originalType,d=e.parentName,i=s(e,["components","mdxType","originalType","parentName"]),l=o(a),p=r,u=l["".concat(d,".").concat(p)]||l[p]||b[p]||c;return a?t.createElement(u,f(f({ref:n},i),{},{components:a})):t.createElement(u,f({ref:n},i))}));function u(e,n){var a=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var c=a.length,f=new Array(c);f[0]=p;var s={};for(var d in n)hasOwnProperty.call(n,d)&&(s[d]=n[d]);s.originalType=e,s[l]="string"==typeof e?e:r,f[1]=s;for(var o=2;o \\\n--transfer-id \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--amount [AMOUNT_TO_TRANSFER] \\\n--secret-key [KEY_PATH]/secret_key.pem \\\n--chain-name [CHAIN_NAME] \\\n--target-account [TARGET_PUBLIC_KEY_HEX] \\\n--payment-amount [PAYMENT_AMOUNT_IN_MOTES]\n")),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"Request fields:")),(0,c.kt)("ul",null,(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"id")," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned")),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"transfer-id")," -<64-BIT INTEGER> The ",(0,c.kt)("inlineCode",{parentName:"p"},"transfer-id")," is a memo field, providing additional information about the recipient, which is necessary when transferring tokens to some recipients. For example, if depositing tokens into an account's purse where off-chain management keeps track of individual sub-balances, it is necessary to provide a memo ID uniquely identifying the actual recipient. If this is not necessary for a given recipient, you may pass ",(0,c.kt)("inlineCode",{parentName:"p"},"0")," or some ",(0,c.kt)("inlineCode",{parentName:"p"},"u64")," value that is meaningful to you")),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"node-address")," - Hostname or IP and port of a node on a network bound to a JSON-RPC endpoint ","[","default:",(0,c.kt)("a",{parentName:"p",href:"http://localhost:7777"},"http://localhost:7777"),"]")),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"amount")," -<512-BIT INTEGER> The number of motes to transfer (1 CSPR = 1,000,000,000 ",(0,c.kt)("inlineCode",{parentName:"p"},"Motes"),")")),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"secret-key")," - Path to secret key file")),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"chain-name")," - Name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain"),(0,c.kt)("ul",{parentName:"li"},(0,c.kt)("li",{parentName:"ul"},"The ",(0,c.kt)("em",{parentName:"li"},"chain-name")," for Testnet is ",(0,c.kt)("strong",{parentName:"li"},"casper-test")),(0,c.kt)("li",{parentName:"ul"},"The ",(0,c.kt)("em",{parentName:"li"},"chain-name")," for Mainnet is ",(0,c.kt)("strong",{parentName:"li"},"casper")))),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"target-account")," - Hex-encoded public key of the account that will receive the funds in its main purse")),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"payment-amount")," - The payment for the transfer in motes. The payment amount varies based on each deploy and network ",(0,c.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),". For Testnet node version ",(0,c.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1"),", you can specify 10^8 motes"))),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"Important response fields:")),(0,c.kt)("ul",null,(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("inlineCode",{parentName:"li"},'"result"."deploy_hash"')," - The address of the deploy, needed to look up additional information about the transfer")),(0,c.kt)("admonition",{type:"note"},(0,c.kt)("p",{parentName:"admonition"},"Save the returned ",(0,c.kt)("em",{parentName:"p"},"deploy_hash")," from the output to query information about the transfer deploy later.")),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"Example Transfer:")),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client transfer -v \\\n--id 3 \\\n--transfer-id 11102023 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--amount 5000000000 \\\n--secret-key ~/KEYS/secret_key.pem \\\n--chain-name casper-test \\\n--target-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \\\n--payment-amount 100000000\n")),(0,c.kt)("details",null,(0,c.kt)("summary",null,"Explore the JSON-RPC request and response generated."),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"JSON-RPC Request"),":"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": {\n "deploy": {\n "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2023-10-12T14:59:40.760Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500f2052a01",\n "parsed": "5000000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "014767a90000000000",\n "parsed": 11102023\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"\n }\n ]\n }\n },\n "id": 3\n}\n')),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"JSON-RPC Response"),":"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "id": 3,\n "result": {\n "api_version": "1.5.3",\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c"\n }\n}\n'))),(0,c.kt)("h2",{id:"verify-deploy"},"Verifying the Deploy"),(0,c.kt)("p",null,"A transfer on a Casper network is only executed after it has been included in a finalized block."),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy\n--node-address [NODE_SERVER_ADDRESS] [DEPLOY_HASH]\n")),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"Important response fields:")),(0,c.kt)("ul",null,(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("inlineCode",{parentName:"li"},'"result"."execution_results"[0]."transfers[0]"')," - the address of the executed transfer that the source account initiated. We will use it to look up additional information about the transfer"),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("inlineCode",{parentName:"li"},'"result"."execution_results"[0]."block_hash"')," - contains the block hash of the block that included the transfer. We will require the ",(0,c.kt)("em",{parentName:"li"},"state_root_hash")," of this block to look up information about the accounts and their purse balances")),(0,c.kt)("admonition",{type:"note"},(0,c.kt)("p",{parentName:"admonition"},"Transfer addresses use a ",(0,c.kt)("inlineCode",{parentName:"p"},"transfer-")," string prefix.")),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"Example Query:")),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy\n--node-address https://rpc.testnet.casperlabs.io\n1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c\n")),(0,c.kt)("details",null,(0,c.kt)("summary",null,"Explore the JSON-RPC request and response generated."),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"JSON-RPC Request"),":"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "method": "info_get_deploy",\n "params": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "finalized_approvals": false\n },\n "id": -3447643973713335073\n}\n')),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"JSON-RPC Response"),":"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "deploy": {\n "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2023-10-12T14:59:40.760Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500f2052a01",\n "parsed": "5000000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "014767a90000000000",\n "parsed": 11102023\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"\n }\n ]\n },\n "execution_results": [\n {\n "block_hash": "aac51dad028ba8b3d6fec86a39252bbc4285d513fd57a8af4696ab5390ac5c2b",\n "result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06621c3e660301",\n "parsed": "1114111876194"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06621c3e660301",\n "parsed": "1114111876194"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06622a383c0201",\n "parsed": "1109111876194"\n }\n }\n },\n {\n "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",\n "transform": {\n "AddUInt512": "5000000000"\n }\n },\n {\n "key": "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405",\n "transform": {\n "WriteTransfer": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004",\n "amount": "5000000000",\n "gas": "0",\n "id": 11102023\n }\n }\n },\n {\n "key": "deploy-1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "transfers": ["transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"],\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "gas": "100000000"\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",\n "transform": {\n "AddUInt512": "100000000"\n }\n }\n ]\n },\n "transfers": ["transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"],\n "cost": "100000000"\n }\n }\n }\n ]\n },\n "id": -3447643973713335073\n}\n'))),(0,c.kt)("p",null,"Refer to the Section on ",(0,c.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#querying-deploys"},"querying deploys")," for more information."),(0,c.kt)("h2",{id:"verifying-the-transfer"},"Verifying the Transfer"),(0,c.kt)("p",null,"In addition to verifying the deploy, you also need to ",(0,c.kt)("a",{parentName:"p",href:"/developers/cli/transfers/verify-transfer"},"verify the transfer details"),". The deploy may have been successful, but you also need to ensure the source and target accounts were updated correctly."))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[7562],{3905:function(e,n,a){a.d(n,{Zo:function(){return i},kt:function(){return u}});var t=a(7294);function r(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function c(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function f(e){for(var n=1;n=0||(r[a]=e[a]);return r}(e,n);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var d=t.createContext({}),o=function(e){var n=t.useContext(d),a=n;return e&&(a="function"==typeof e?e(n):f(f({},n),e)),a},i=function(e){var n=o(e.components);return t.createElement(d.Provider,{value:n},e.children)},l="mdxType",b={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},p=t.forwardRef((function(e,n){var a=e.components,r=e.mdxType,c=e.originalType,d=e.parentName,i=s(e,["components","mdxType","originalType","parentName"]),l=o(a),p=r,u=l["".concat(d,".").concat(p)]||l[p]||b[p]||c;return a?t.createElement(u,f(f({ref:n},i),{},{components:a})):t.createElement(u,f({ref:n},i))}));function u(e,n){var a=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var c=a.length,f=new Array(c);f[0]=p;var s={};for(var d in n)hasOwnProperty.call(n,d)&&(s[d]=n[d]);s.originalType=e,s[l]="string"==typeof e?e:r,f[1]=s;for(var o=2;o \\\n--transfer-id \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--amount [AMOUNT_TO_TRANSFER] \\\n--secret-key [KEY_PATH]/secret_key.pem \\\n--chain-name [CHAIN_NAME] \\\n--target-account [TARGET_PUBLIC_KEY_HEX] \\\n--payment-amount [PAYMENT_AMOUNT_IN_MOTES]\n")),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"Request fields:")),(0,c.kt)("ul",null,(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"id")," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned")),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"transfer-id")," -<64-BIT INTEGER> The ",(0,c.kt)("inlineCode",{parentName:"p"},"transfer-id")," is a memo field, providing additional information about the recipient, which is necessary when transferring tokens to some recipients. For example, if depositing tokens into an account's purse where off-chain management keeps track of individual sub-balances, it is necessary to provide a memo ID uniquely identifying the actual recipient. If this is not necessary for a given recipient, you may pass ",(0,c.kt)("inlineCode",{parentName:"p"},"0")," or some ",(0,c.kt)("inlineCode",{parentName:"p"},"u64")," value that is meaningful to you")),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"node-address")," - Hostname or IP and port of a node on a network bound to a JSON-RPC endpoint ","[","default:",(0,c.kt)("a",{parentName:"p",href:"http://localhost:7777"},"http://localhost:7777"),"]")),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"amount")," -<512-BIT INTEGER> The number of motes to transfer (1 CSPR = 1,000,000,000 ",(0,c.kt)("inlineCode",{parentName:"p"},"Motes"),")")),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"secret-key")," - Path to secret key file")),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"chain-name")," - Name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain"),(0,c.kt)("ul",{parentName:"li"},(0,c.kt)("li",{parentName:"ul"},"The ",(0,c.kt)("em",{parentName:"li"},"chain-name")," for Testnet is ",(0,c.kt)("strong",{parentName:"li"},"casper-test")),(0,c.kt)("li",{parentName:"ul"},"The ",(0,c.kt)("em",{parentName:"li"},"chain-name")," for Mainnet is ",(0,c.kt)("strong",{parentName:"li"},"casper")))),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"target-account")," - Hex-encoded public key of the account that will receive the funds in its main purse")),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("p",{parentName:"li"},(0,c.kt)("inlineCode",{parentName:"p"},"payment-amount")," - The payment for the transfer in motes. The payment amount varies based on each deploy and network ",(0,c.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),". For Testnet node version ",(0,c.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1"),", you can specify 10^8 motes"))),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"Important response fields:")),(0,c.kt)("ul",null,(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("inlineCode",{parentName:"li"},'"result"."deploy_hash"')," - The address of the deploy, needed to look up additional information about the transfer")),(0,c.kt)("admonition",{type:"note"},(0,c.kt)("p",{parentName:"admonition"},"Save the returned ",(0,c.kt)("em",{parentName:"p"},"deploy_hash")," from the output to query information about the transfer deploy later.")),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"Example Transfer:")),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client transfer -v \\\n--id 3 \\\n--transfer-id 11102023 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--amount 5000000000 \\\n--secret-key ~/KEYS/secret_key.pem \\\n--chain-name casper-test \\\n--target-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \\\n--payment-amount 100000000\n")),(0,c.kt)("details",null,(0,c.kt)("summary",null,"Explore the JSON-RPC request and response generated."),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"JSON-RPC Request"),":"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": {\n "deploy": {\n "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2023-10-12T14:59:40.760Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500f2052a01",\n "parsed": "5000000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "014767a90000000000",\n "parsed": 11102023\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"\n }\n ]\n }\n },\n "id": 3\n}\n')),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"JSON-RPC Response"),":"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "id": 3,\n "result": {\n "api_version": "1.5.3",\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c"\n }\n}\n'))),(0,c.kt)("h2",{id:"verify-deploy"},"Verifying the Deploy"),(0,c.kt)("p",null,"A transfer on a Casper network is only executed after it has been included in a finalized block."),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy\n--node-address [NODE_SERVER_ADDRESS] [DEPLOY_HASH]\n")),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"Important response fields:")),(0,c.kt)("ul",null,(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("inlineCode",{parentName:"li"},'"result"."execution_results"[0]."transfers[0]"')," - the address of the executed transfer that the source account initiated. We will use it to look up additional information about the transfer"),(0,c.kt)("li",{parentName:"ul"},(0,c.kt)("inlineCode",{parentName:"li"},'"result"."execution_results"[0]."block_hash"')," - contains the block hash of the block that included the transfer. We will require the ",(0,c.kt)("em",{parentName:"li"},"state_root_hash")," of this block to look up information about the accounts and their purse balances")),(0,c.kt)("admonition",{type:"note"},(0,c.kt)("p",{parentName:"admonition"},"Transfer addresses use a ",(0,c.kt)("inlineCode",{parentName:"p"},"transfer-")," string prefix.")),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"Example Query:")),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy\n--node-address https://rpc.testnet.casperlabs.io\n1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c\n")),(0,c.kt)("details",null,(0,c.kt)("summary",null,"Explore the JSON-RPC request and response generated."),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"JSON-RPC Request"),":"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "method": "info_get_deploy",\n "params": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "finalized_approvals": false\n },\n "id": -3447643973713335073\n}\n')),(0,c.kt)("p",null,(0,c.kt)("strong",{parentName:"p"},"JSON-RPC Response"),":"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "deploy": {\n "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2023-10-12T14:59:40.760Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500f2052a01",\n "parsed": "5000000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "014767a90000000000",\n "parsed": 11102023\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"\n }\n ]\n },\n "execution_results": [\n {\n "block_hash": "aac51dad028ba8b3d6fec86a39252bbc4285d513fd57a8af4696ab5390ac5c2b",\n "result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06621c3e660301",\n "parsed": "1114111876194"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06621c3e660301",\n "parsed": "1114111876194"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06622a383c0201",\n "parsed": "1109111876194"\n }\n }\n },\n {\n "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",\n "transform": {\n "AddUInt512": "5000000000"\n }\n },\n {\n "key": "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405",\n "transform": {\n "WriteTransfer": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004",\n "amount": "5000000000",\n "gas": "0",\n "id": 11102023\n }\n }\n },\n {\n "key": "deploy-1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "transfers": ["transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"],\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "gas": "100000000"\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",\n "transform": {\n "AddUInt512": "100000000"\n }\n }\n ]\n },\n "transfers": ["transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"],\n "cost": "100000000"\n }\n }\n }\n ]\n },\n "id": -3447643973713335073\n}\n'))),(0,c.kt)("p",null,"Refer to the Section on ",(0,c.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#querying-deploys"},"querying deploys")," for more information."),(0,c.kt)("h2",{id:"verifying-the-transfer"},"Verifying the Transfer"),(0,c.kt)("p",null,"In addition to verifying the deploy, you also need to ",(0,c.kt)("a",{parentName:"p",href:"/developers/cli/transfers/verify-transfer"},"verify the transfer details"),". The deploy may have been successful, but you also need to ensure the source and target accounts were updated correctly."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/81637ed9.637b21ae.js b/assets/js/81637ed9.5a98629b.js similarity index 97% rename from assets/js/81637ed9.637b21ae.js rename to assets/js/81637ed9.5a98629b.js index 291f9dfcfb..b825541009 100644 --- a/assets/js/81637ed9.637b21ae.js +++ b/assets/js/81637ed9.5a98629b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[7576],{3905:function(e,r,t){t.d(r,{Zo:function(){return p},kt:function(){return g}});var n=t(7294);function a(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function s(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r=0||(a[t]=e[t]);return a}(e,r);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},p=function(e){var r=l(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,a=e.mdxType,s=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=l(t),d=a,g=u["".concat(c,".").concat(d)]||u[d]||f[d]||s;return t?n.createElement(g,i(i({ref:r},p),{},{components:t})):n.createElement(g,i({ref:r},p))}));function g(e,r){var t=arguments,a=r&&r.mdxType;if("string"==typeof e||a){var s=t.length,i=new Array(s);i[0]=d;var o={};for(var c in r)hasOwnProperty.call(r,c)&&(o[c]=r[c]);o.originalType=e,o[u]="string"==typeof e?e:a,i[1]=o;for(var l=2;l=0||(a[t]=e[t]);return a}(e,r);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},p=function(e){var r=l(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,a=e.mdxType,s=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=l(t),d=a,g=u["".concat(c,".").concat(d)]||u[d]||f[d]||s;return t?n.createElement(g,i(i({ref:r},p),{},{components:t})):n.createElement(g,i({ref:r},p))}));function g(e,r){var t=arguments,a=r&&r.mdxType;if("string"==typeof e||a){var s=t.length,i=new Array(s);i[0]=d;var o={};for(var c in r)hasOwnProperty.call(r,c)&&(o[c]=r[c]);o.originalType=e,o[u]="string"==typeof e?e:a,i[1]=o;for(var l=2;l=0||(n[o]=e[o]);return n}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(n[o]=e[o])}return n}var c=a.createContext({}),u=function(e){var t=a.useContext(c),o=t;return e&&(o="function"==typeof e?e(t):s(s({},t),e)),o},l=function(e){var t=u(e.components);return a.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var o=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),p=u(o),h=n,m=p["".concat(c,".").concat(h)]||p[h]||d[h]||r;return o?a.createElement(m,s(s({ref:t},l),{},{components:o})):a.createElement(m,s({ref:t},l))}));function m(e,t){var o=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=o.length,s=new Array(r);s[0]=h;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[p]="string"==typeof e?e:n,s[1]=i;for(var u=2;u=0||(n[o]=e[o]);return n}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(n[o]=e[o])}return n}var c=a.createContext({}),u=function(e){var t=a.useContext(c),o=t;return e&&(o="function"==typeof e?e(t):s(s({},t),e)),o},l=function(e){var t=u(e.components);return a.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var o=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),p=u(o),h=n,m=p["".concat(c,".").concat(h)]||p[h]||d[h]||r;return o?a.createElement(m,s(s({ref:t},l),{},{components:o})):a.createElement(m,s({ref:t},l))}));function m(e,t){var o=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=o.length,s=new Array(r);s[0]=h;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[p]="string"==typeof e?e:n,s[1]=i;for(var u=2;u=0||(c[n]=t[n]);return c}(t,e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(c[n]=t[n])}return c}var s=a.createContext({}),l=function(t){var e=a.useContext(s),n=e;return t&&(n="function"==typeof t?t(e):o(o({},e),t)),n},p=function(t){var e=l(t.components);return a.createElement(s.Provider,{value:e},t.children)},h="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},d=a.forwardRef((function(t,e){var n=t.components,c=t.mdxType,r=t.originalType,s=t.parentName,p=i(t,["components","mdxType","originalType","parentName"]),h=l(n),d=c,m=h["".concat(s,".").concat(d)]||h[d]||u[d]||r;return n?a.createElement(m,o(o({ref:e},p),{},{components:n})):a.createElement(m,o({ref:e},p))}));function m(t,e){var n=arguments,c=e&&e.mdxType;if("string"==typeof t||c){var r=n.length,o=new Array(r);o[0]=d;var i={};for(var s in e)hasOwnProperty.call(e,s)&&(i[s]=e[s]);i.originalType=t,i[h]="string"==typeof t?t:c,o[1]=i;for(var l=2;l=0||(c[n]=t[n]);return c}(t,e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(c[n]=t[n])}return c}var s=a.createContext({}),l=function(t){var e=a.useContext(s),n=e;return t&&(n="function"==typeof t?t(e):o(o({},e),t)),n},p=function(t){var e=l(t.components);return a.createElement(s.Provider,{value:e},t.children)},h="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},d=a.forwardRef((function(t,e){var n=t.components,c=t.mdxType,r=t.originalType,s=t.parentName,p=i(t,["components","mdxType","originalType","parentName"]),h=l(n),d=c,m=h["".concat(s,".").concat(d)]||h[d]||u[d]||r;return n?a.createElement(m,o(o({ref:e},p),{},{components:n})):a.createElement(m,o({ref:e},p))}));function m(t,e){var n=arguments,c=e&&e.mdxType;if("string"==typeof t||c){var r=n.length,o=new Array(r);o[0]=d;var i={};for(var s in e)hasOwnProperty.call(e,s)&&(i[s]=e[s]);i.originalType=t,i[h]="string"==typeof t?t:c,o[1]=i;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),i=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=i(e.components);return a.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=i(n),h=r,m=u["".concat(c,".").concat(h)]||u[h]||d[h]||s;return n?a.createElement(m,o(o({ref:t},p),{},{components:n})):a.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,o=new Array(s);o[0]=h;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[u]="string"==typeof e?e:r,o[1]=l;for(var i=2;i\n")),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Getting the account hash")),(0,s.kt)("p",null,"Run the following command and supply the path to your public key in hexadecimal format to get the account hash."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client account-address --public-key "[PATH_TO_YOUR_KEY]/public_key_hex"\n')),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Querying global state")),(0,s.kt)("p",null,"Use the command template below to query the network status with regard to your account."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state \\\n--node-address http:// \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n")),(0,s.kt)("h3",{id:"deploying-the-contract"},"Installing the Contract"),(0,s.kt)("p",null,"Now you can install the contract to the network and check how it behaves."),(0,s.kt)("p",null,"If you are sending the deploy on Mainnet, try several put deploys on the Testnet to understand the exact gas amount required for that deploy. Refer to the ",(0,s.kt)("a",{parentName:"p",href:"/developers/cli/sending-deploys/#a-note-about-gas-price"},"note about gas price")," to understand more about payment amounts and gas price adjustments."),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"The Casper platform currently does not refund any tokens as part of sending a deploy.")," For example, if you spend 10 CSPR for the deployment and it only costs 1 CSPR, you will not receive the remaining 9 CSPR. Refer to the ",(0,s.kt)("a",{parentName:"p",href:"/concepts/economics/gas-concepts/"},"Gas and the Casper Blockchain")," documentation for further details."),(0,s.kt)("p",null,"Use the following command template to deploy the contract:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy \\\n --node-address http:// \\\n --chain-name [NETWORK_NAME]] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [AMOUNT] \\\n --session-path [WASM_FILE_PATH]/[File_Name].wasm\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n')),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"NETWORK_NAME"),": Use the relevant network name. Here we use '",(0,s.kt)("em",{parentName:"li"},"casper-test"),"'"),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"PATH_TO_YOUR_KEY"),": Replace this with the actual path of your secret key"),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"PAYMENT_AMOUNT"),": Gas amount in tokens needed for contract execution. If there are no adequate tokens, the deploy will not execute and will return an error"),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"WASM FILE PATH"),": The session-path argument should point to the location of your compiled Fungible Token Wasm file")),(0,s.kt)("p",null,"Here is a sample ",(0,s.kt)("em",{parentName:"p"},"put-deploy")," command:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy \\\n--node-address http://95.216.24.237:7777 \\\n--chain-name casper-test \\\n--secret-key "/home/ubuntu/secret_key.pem" \\\n--payment-amount 1000000 \\\n--session-path "/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"\n--session-arg "name=\'Token test\', symbol=\'TEST\', decimals:u8=10, total_supply:u256=1000"\n')),(0,s.kt)("h3",{id:"querying-the-network-status"},"Querying the Network Status"),(0,s.kt)("p",null,"You will need the newest state root hash to view the network status, as it changed with the deploy. The account hash remains the same since you are using the same account. Follow the ",(0,s.kt)("a",{parentName:"p",href:"#viewing-the-network-status"},"viewing the network state")," section to execute this step with the new state root hash."),(0,s.kt)("h3",{id:"verifying-the-deploy"},"Verifying the Deploy"),(0,s.kt)("p",null,"Now you can verify the sent deploy using the ",(0,s.kt)("inlineCode",{parentName:"p"},"get-deploy")," command. This will output the details of the sent deploy."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy \\\n--node-address http:// [DEPLOY_HASH]\n")),(0,s.kt)("h3",{id:"querying-with-arguments"},"Querying with Arguments"),(0,s.kt)("p",null,"This step will narrow down the context and check the status of a specific entry point. You will use the details inside the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs"},"Fungible Token contract")," to derive arguments."),(0,s.kt)("p",null,"Use the command template below to query the network state with arguments:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state \\\n--node-address http:// \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "[CONTRACT_NAME/ARGUMENT]"\n')),(0,s.kt)("h3",{id:"sample-deploy-testnet"},"Example Deploy on Testnet"),(0,s.kt)("p",null,"The following steps will guide you through the process with sample values and results."),(0,s.kt)("h4",{id:"cloning-the-fungible-token-contract"},"Cloning the Fungible Token Contract"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/casper-ecosystem/cep18.git\n")),(0,s.kt)("h3",{id:"getting-an-ip-address-from-a-testnet-peer"},"Getting an IP Address from a Testnet Peer"),(0,s.kt)("p",null,"Use ",(0,s.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/tools/peers"},"peers")," to get the node IP address."),(0,s.kt)("h4",{id:"viewing-the-network-status"},"Viewing the Network Status"),(0,s.kt)("p",null,"Here is the command to query the state of the network:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state \\\n--key account-hash- \\\n--node-address http:// \\\n--state-root-hash E5B679BD1562fE6257257F5f969A79482E8DCEBBD501501BfA6d5844b61cBE3f\n")),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Result"),":"),(0,s.kt)("p",null,"This result contains the network state before the deploy. You can see the ",(0,s.kt)("inlineCode",{parentName:"p"},"named-key")," field is empty since we haven't sent the deploy to the network yet."),(0,s.kt)("details",null,(0,s.kt)("summary",null,"Result from querying the network status"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": 401803927542812599,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "merkle_proof": "[25564 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash- ",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash- ",\n "weight": 1\n }\n ],\n "main_purse": "uref-",\n "named_keys": []\n }\n }\n }\n}\n'))),(0,s.kt)("br",null),(0,s.kt)("h4",{id:"sending-the-deploy"},"Sending the Deploy"),(0,s.kt)("p",null,"Send the Deploy containing your contract with this command:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy \\\n--node-address http:// \\\n--chain-name casper-test \\\n--secret-key "/home/ubuntu/secret_key.pem" \\\n--payment-amount 1000000 \\\n--session-path "/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"\n--session-arg "name=\'Token test\', symbol=\'TEST\', decimals:u8=10, total_supply:u256=1000"\n')),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Result"),":"),(0,s.kt)("p",null,"This command execution will output the ",(0,s.kt)("inlineCode",{parentName:"p"},"deploy_hash")," of the applied deploy. We can use the deploy_hash to get the details of the deploy."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": 931694842944790108,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "deploy_hash": "b00E59f8aBA5c7aB9...."\n }\n}\n')),(0,s.kt)("h4",{id:"viewing-the-deploy-details"},"Viewing the Deploy Details"),(0,s.kt)("p",null,"You can view the details of the sent deploy using the command below:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy \\\n--node-address http:// \\\nb00E59f8aBA5c7aB9.....\n")),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Result"),":"),(0,s.kt)("p",null,"This contains the header, payment, and session details along with the execution results."),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"If the execution result field appears as ",(0,s.kt)("inlineCode",{parentName:"li"},'"execution_results":[]'),", it means that the deploy hasn't been executed yet. The time to load the execution result may vary depending on the network.")),(0,s.kt)("details",null,(0,s.kt)("summary",null,"Result from querying the deploy"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'{\n {\n "id": -870982079597140956,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "deploy": {\n "approvals": [\n {\n "signature": "[130 hex chars]",\n "signer": "017B8CE645c728......................."\n }\n ],\n "hash": "F9D4C649Fa78Da07E.......................",\n "header": {\n "account": "017B8CE645c7285.......................",\n "body_hash": "8eAEd6B7bCBB493d75d.......................",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2022-01-04T15:14:29.203Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "0500e8764817",\n "cl_type": "U512",\n "parsed": "100000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "ModuleBytes": {\n "args": [],\n "module_bytes": "[417800 hex chars]"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "d3644f0306F20fa6.......................",\n "result": {\n "Success": {\n "cost": "45040980830",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5E4aCF51f54Eb5.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-624dBE2395b9D9503FB.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3Fe81B7b862E50C77.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dC3A5c44A20b.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-C051e7EC16e08De.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-C051e7EC16e08Def8b556",\n "transform": {\n "WriteCLValue": {\n "bytes": "06E07f3abEa001",\n "cl_type": "U512",\n "parsed": "1789897900000"\n }\n }\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": {\n "AddUInt512": "100000000000"\n }\n },\n {\n "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A3...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-007",\n "name": "balances"\n }\n ]\n }\n },\n {\n "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A311...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-007",\n "name": "allowances"\n }\n ]\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "0400ca9A3B",\n "cl_type": "U256",\n "parsed": "1000000000"\n }\n }\n },\n {\n "key": "uref-4EB0a2A42afBb1d3D5ae9BD4781dc96E528C7AD3f0eEC240Cf1DbDaDF4f3D486-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "0A00000043617370657254657374",\n "cl_type": "String",\n "parsed": "CasperTest"\n }\n }\n },\n {\n "key": "uref-6e87fd661D5a65aF95f02baDfEb64f8E0F44C006661d4903A68E9dF8dEAa413d-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "050000004353505254",\n "cl_type": "String",\n "parsed": "CSPRT"\n }\n }\n },\n {\n "key": "uref-aCA2425C80584391fB883603460578B1472d13a429Ebbd1a18a55cE19cE8F3C6-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "08",\n "cl_type": "U8",\n "parsed": 8\n }\n }\n },\n {\n "key": "dictionary-baA61231F04B1c2Ee97025f425eaD2F70CAd9c1E8c24355246d159038AdCb2e9",\n "transform": {\n "WriteCLValue": {\n "bytes": "[188 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8C...................................................",\n "transform": "Identity"\n },\n {\n "key": "account-hash-7f4bf39A311a75...................................................",\n "transform": {\n "WriteAccount": "account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53"\n }\n },\n {\n "key": "account-hash-7f4bf39A311a7538...................................................",\n "transform": "Identity"\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8C...................................................",\n "transform": {\n "WriteAccount": "account-hash-7f4bf39A311a75..................................................."\n }\n },\n {\n "key": "uref-868c0e0BEB2EB3C10e893be96E6D6bE7FC6375f3f038e46c3262509245c117a0-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "WriteContractPackage"\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "Identity"\n },\n {\n "key": "hash-AdF81845d77907054ACb250c196392c7DAEE5481d4EabEB76c318A307c11E5cB",\n "transform": "WriteContractWasm"\n },\n {\n "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",\n "transform": "WriteContract"\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "WriteContractPackage"\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",\n "name": "test_contract"\n }\n ]\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": "Identity"\n },\n {\n "key": "dictionary-04932d42aff9367579770E219ce1C4Da83D1Fd42Fa0FaA4Ae98AE07914c4c1E4",\n "transform": {\n "WriteCLValue": {\n "bytes": "[186 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "04400cAa3b",\n "cl_type": "U256",\n "parsed": "1001000000"\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": "Identity"\n },\n {\n "key": "dictionary-Ec3f20485A29255dd2c2D7b8c008207A0d139dFDCE89224DA8b63F21c157A97F",\n "transform": {\n "WriteCLValue": {\n "bytes": "[186 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "04C090c83b",\n "cl_type": "U256",\n "parsed": "1003000000"\n }\n }\n },\n {\n "key": "deploy-F9D4C649Fa78Da...................................................",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "F9D4C649Fa78Da07Ec6EFcFC615ff1Bd3B68347750FA0C81B6a74C3f9582d7E4",\n "from": "account-hash-7f4bf39A311a...................................................",\n "gas": "45040980830",\n "source": "uref-C051e7EC16e08Def8b556F9...................................................",\n "transfers": []\n }\n }\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5E4aCF51f54Eb59291599187838Dc3BC234089c46fc6cA8AD17e762aE4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3Fe81B7b862E50C77EF9A958a05BfA98444F26f96f23d37A13c96244cFB7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dC3A5c44A20b9FD260a412437933835B52Fc683d8AE36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": "Identity"\n },\n {\n "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",\n "transform": {\n "AddUInt512": "100000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'))),(0,s.kt)("br",null),(0,s.kt)("h4",{id:"querying-contract-entry-points"},"Querying Contract Entry Points"),(0,s.kt)("p",null,"We will query the argument 'name' in this example."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state --node-address http://95.216.24.237:7777 \\\n--state-root-hash D00dF8c35B0E9995c2911803F37A212d82c960D9bC5bA3C4F99a661e18D09411 \\\n--key account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53 \\\n-q "test_contract/name"\n')),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Result"),":"),(0,s.kt)("p",null,"You can see that the name is ",(0,s.kt)("inlineCode",{parentName:"p"},"CasperTest")," in this example."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -3650676146668320186,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "block_header": null,\n "merkle_proof": "[80252 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "0A00000043617370657254657374",\n "cl_type": "String",\n "parsed": "CasperTest"\n }\n }\n }\n}\n\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[4511],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),i=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=i(e.components);return a.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=i(n),h=r,m=u["".concat(c,".").concat(h)]||u[h]||d[h]||s;return n?a.createElement(m,o(o({ref:t},p),{},{components:n})):a.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,o=new Array(s);o[0]=h;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[u]="string"==typeof e?e:r,o[1]=l;for(var i=2;i\n")),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Getting the account hash")),(0,s.kt)("p",null,"Run the following command and supply the path to your public key in hexadecimal format to get the account hash."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client account-address --public-key "[PATH_TO_YOUR_KEY]/public_key_hex"\n')),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Querying global state")),(0,s.kt)("p",null,"Use the command template below to query the network status with regard to your account."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state \\\n--node-address http:// \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n")),(0,s.kt)("h3",{id:"deploying-the-contract"},"Installing the Contract"),(0,s.kt)("p",null,"Now you can install the contract to the network and check how it behaves."),(0,s.kt)("p",null,"If you are sending the deploy on Mainnet, try several put deploys on the Testnet to understand the exact gas amount required for that deploy. Refer to the ",(0,s.kt)("a",{parentName:"p",href:"/developers/cli/sending-deploys/#a-note-about-gas-price"},"note about gas price")," to understand more about payment amounts and gas price adjustments."),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"The Casper platform currently does not refund any tokens as part of sending a deploy.")," For example, if you spend 10 CSPR for the deployment and it only costs 1 CSPR, you will not receive the remaining 9 CSPR. Refer to the ",(0,s.kt)("a",{parentName:"p",href:"/concepts/economics/gas-concepts/"},"Gas and the Casper Blockchain")," documentation for further details."),(0,s.kt)("p",null,"Use the following command template to deploy the contract:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy \\\n --node-address http:// \\\n --chain-name [NETWORK_NAME]] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [AMOUNT] \\\n --session-path [WASM_FILE_PATH]/[File_Name].wasm\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n')),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"NETWORK_NAME"),": Use the relevant network name. Here we use '",(0,s.kt)("em",{parentName:"li"},"casper-test"),"'"),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"PATH_TO_YOUR_KEY"),": Replace this with the actual path of your secret key"),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"PAYMENT_AMOUNT"),": Gas amount in tokens needed for contract execution. If there are no adequate tokens, the deploy will not execute and will return an error"),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"WASM FILE PATH"),": The session-path argument should point to the location of your compiled Fungible Token Wasm file")),(0,s.kt)("p",null,"Here is a sample ",(0,s.kt)("em",{parentName:"p"},"put-deploy")," command:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy \\\n--node-address http://95.216.24.237:7777 \\\n--chain-name casper-test \\\n--secret-key "/home/ubuntu/secret_key.pem" \\\n--payment-amount 1000000 \\\n--session-path "/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"\n--session-arg "name=\'Token test\', symbol=\'TEST\', decimals:u8=10, total_supply:u256=1000"\n')),(0,s.kt)("h3",{id:"querying-the-network-status"},"Querying the Network Status"),(0,s.kt)("p",null,"You will need the newest state root hash to view the network status, as it changed with the deploy. The account hash remains the same since you are using the same account. Follow the ",(0,s.kt)("a",{parentName:"p",href:"#viewing-the-network-status"},"viewing the network state")," section to execute this step with the new state root hash."),(0,s.kt)("h3",{id:"verifying-the-deploy"},"Verifying the Deploy"),(0,s.kt)("p",null,"Now you can verify the sent deploy using the ",(0,s.kt)("inlineCode",{parentName:"p"},"get-deploy")," command. This will output the details of the sent deploy."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy \\\n--node-address http:// [DEPLOY_HASH]\n")),(0,s.kt)("h3",{id:"querying-with-arguments"},"Querying with Arguments"),(0,s.kt)("p",null,"This step will narrow down the context and check the status of a specific entry point. You will use the details inside the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs"},"Fungible Token contract")," to derive arguments."),(0,s.kt)("p",null,"Use the command template below to query the network state with arguments:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state \\\n--node-address http:// \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "[CONTRACT_NAME/ARGUMENT]"\n')),(0,s.kt)("h3",{id:"sample-deploy-testnet"},"Example Deploy on Testnet"),(0,s.kt)("p",null,"The following steps will guide you through the process with sample values and results."),(0,s.kt)("h4",{id:"cloning-the-fungible-token-contract"},"Cloning the Fungible Token Contract"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/casper-ecosystem/cep18.git\n")),(0,s.kt)("h3",{id:"getting-an-ip-address-from-a-testnet-peer"},"Getting an IP Address from a Testnet Peer"),(0,s.kt)("p",null,"Use ",(0,s.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/tools/peers"},"peers")," to get the node IP address."),(0,s.kt)("h4",{id:"viewing-the-network-status"},"Viewing the Network Status"),(0,s.kt)("p",null,"Here is the command to query the state of the network:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state \\\n--key account-hash- \\\n--node-address http:// \\\n--state-root-hash E5B679BD1562fE6257257F5f969A79482E8DCEBBD501501BfA6d5844b61cBE3f\n")),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Result"),":"),(0,s.kt)("p",null,"This result contains the network state before the deploy. You can see the ",(0,s.kt)("inlineCode",{parentName:"p"},"named-key")," field is empty since we haven't sent the deploy to the network yet."),(0,s.kt)("details",null,(0,s.kt)("summary",null,"Result from querying the network status"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": 401803927542812599,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "merkle_proof": "[25564 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash- ",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash- ",\n "weight": 1\n }\n ],\n "main_purse": "uref-",\n "named_keys": []\n }\n }\n }\n}\n'))),(0,s.kt)("br",null),(0,s.kt)("h4",{id:"sending-the-deploy"},"Sending the Deploy"),(0,s.kt)("p",null,"Send the Deploy containing your contract with this command:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy \\\n--node-address http:// \\\n--chain-name casper-test \\\n--secret-key "/home/ubuntu/secret_key.pem" \\\n--payment-amount 1000000 \\\n--session-path "/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"\n--session-arg "name=\'Token test\', symbol=\'TEST\', decimals:u8=10, total_supply:u256=1000"\n')),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Result"),":"),(0,s.kt)("p",null,"This command execution will output the ",(0,s.kt)("inlineCode",{parentName:"p"},"deploy_hash")," of the applied deploy. We can use the deploy_hash to get the details of the deploy."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": 931694842944790108,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "deploy_hash": "b00E59f8aBA5c7aB9...."\n }\n}\n')),(0,s.kt)("h4",{id:"viewing-the-deploy-details"},"Viewing the Deploy Details"),(0,s.kt)("p",null,"You can view the details of the sent deploy using the command below:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy \\\n--node-address http:// \\\nb00E59f8aBA5c7aB9.....\n")),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Result"),":"),(0,s.kt)("p",null,"This contains the header, payment, and session details along with the execution results."),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"If the execution result field appears as ",(0,s.kt)("inlineCode",{parentName:"li"},'"execution_results":[]'),", it means that the deploy hasn't been executed yet. The time to load the execution result may vary depending on the network.")),(0,s.kt)("details",null,(0,s.kt)("summary",null,"Result from querying the deploy"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'{\n {\n "id": -870982079597140956,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "deploy": {\n "approvals": [\n {\n "signature": "[130 hex chars]",\n "signer": "017B8CE645c728......................."\n }\n ],\n "hash": "F9D4C649Fa78Da07E.......................",\n "header": {\n "account": "017B8CE645c7285.......................",\n "body_hash": "8eAEd6B7bCBB493d75d.......................",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2022-01-04T15:14:29.203Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "0500e8764817",\n "cl_type": "U512",\n "parsed": "100000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "ModuleBytes": {\n "args": [],\n "module_bytes": "[417800 hex chars]"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "d3644f0306F20fa6.......................",\n "result": {\n "Success": {\n "cost": "45040980830",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5E4aCF51f54Eb5.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-624dBE2395b9D9503FB.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3Fe81B7b862E50C77.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dC3A5c44A20b.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-C051e7EC16e08De.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-C051e7EC16e08Def8b556",\n "transform": {\n "WriteCLValue": {\n "bytes": "06E07f3abEa001",\n "cl_type": "U512",\n "parsed": "1789897900000"\n }\n }\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": {\n "AddUInt512": "100000000000"\n }\n },\n {\n "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A3...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-007",\n "name": "balances"\n }\n ]\n }\n },\n {\n "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A311...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-007",\n "name": "allowances"\n }\n ]\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "0400ca9A3B",\n "cl_type": "U256",\n "parsed": "1000000000"\n }\n }\n },\n {\n "key": "uref-4EB0a2A42afBb1d3D5ae9BD4781dc96E528C7AD3f0eEC240Cf1DbDaDF4f3D486-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "0A00000043617370657254657374",\n "cl_type": "String",\n "parsed": "CasperTest"\n }\n }\n },\n {\n "key": "uref-6e87fd661D5a65aF95f02baDfEb64f8E0F44C006661d4903A68E9dF8dEAa413d-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "050000004353505254",\n "cl_type": "String",\n "parsed": "CSPRT"\n }\n }\n },\n {\n "key": "uref-aCA2425C80584391fB883603460578B1472d13a429Ebbd1a18a55cE19cE8F3C6-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "08",\n "cl_type": "U8",\n "parsed": 8\n }\n }\n },\n {\n "key": "dictionary-baA61231F04B1c2Ee97025f425eaD2F70CAd9c1E8c24355246d159038AdCb2e9",\n "transform": {\n "WriteCLValue": {\n "bytes": "[188 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8C...................................................",\n "transform": "Identity"\n },\n {\n "key": "account-hash-7f4bf39A311a75...................................................",\n "transform": {\n "WriteAccount": "account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53"\n }\n },\n {\n "key": "account-hash-7f4bf39A311a7538...................................................",\n "transform": "Identity"\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8C...................................................",\n "transform": {\n "WriteAccount": "account-hash-7f4bf39A311a75..................................................."\n }\n },\n {\n "key": "uref-868c0e0BEB2EB3C10e893be96E6D6bE7FC6375f3f038e46c3262509245c117a0-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "WriteContractPackage"\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "Identity"\n },\n {\n "key": "hash-AdF81845d77907054ACb250c196392c7DAEE5481d4EabEB76c318A307c11E5cB",\n "transform": "WriteContractWasm"\n },\n {\n "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",\n "transform": "WriteContract"\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "WriteContractPackage"\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",\n "name": "test_contract"\n }\n ]\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": "Identity"\n },\n {\n "key": "dictionary-04932d42aff9367579770E219ce1C4Da83D1Fd42Fa0FaA4Ae98AE07914c4c1E4",\n "transform": {\n "WriteCLValue": {\n "bytes": "[186 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "04400cAa3b",\n "cl_type": "U256",\n "parsed": "1001000000"\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": "Identity"\n },\n {\n "key": "dictionary-Ec3f20485A29255dd2c2D7b8c008207A0d139dFDCE89224DA8b63F21c157A97F",\n "transform": {\n "WriteCLValue": {\n "bytes": "[186 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "04C090c83b",\n "cl_type": "U256",\n "parsed": "1003000000"\n }\n }\n },\n {\n "key": "deploy-F9D4C649Fa78Da...................................................",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "F9D4C649Fa78Da07Ec6EFcFC615ff1Bd3B68347750FA0C81B6a74C3f9582d7E4",\n "from": "account-hash-7f4bf39A311a...................................................",\n "gas": "45040980830",\n "source": "uref-C051e7EC16e08Def8b556F9...................................................",\n "transfers": []\n }\n }\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5E4aCF51f54Eb59291599187838Dc3BC234089c46fc6cA8AD17e762aE4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3Fe81B7b862E50C77EF9A958a05BfA98444F26f96f23d37A13c96244cFB7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dC3A5c44A20b9FD260a412437933835B52Fc683d8AE36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": "Identity"\n },\n {\n "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",\n "transform": {\n "AddUInt512": "100000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'))),(0,s.kt)("br",null),(0,s.kt)("h4",{id:"querying-contract-entry-points"},"Querying Contract Entry Points"),(0,s.kt)("p",null,"We will query the argument 'name' in this example."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state --node-address http://95.216.24.237:7777 \\\n--state-root-hash D00dF8c35B0E9995c2911803F37A212d82c960D9bC5bA3C4F99a661e18D09411 \\\n--key account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53 \\\n-q "test_contract/name"\n')),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Result"),":"),(0,s.kt)("p",null,"You can see that the name is ",(0,s.kt)("inlineCode",{parentName:"p"},"CasperTest")," in this example."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -3650676146668320186,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "block_header": null,\n "merkle_proof": "[80252 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "0A00000043617370657254657374",\n "cl_type": "String",\n "parsed": "CasperTest"\n }\n }\n }\n}\n\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/87ec732b.439ed684.js b/assets/js/87ec732b.1c0684a1.js similarity index 97% rename from assets/js/87ec732b.439ed684.js rename to assets/js/87ec732b.1c0684a1.js index 2b8f320fd2..bcb6c4c6dc 100644 --- a/assets/js/87ec732b.439ed684.js +++ b/assets/js/87ec732b.1c0684a1.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5607],{3905:function(e,t,r){r.d(t,{Zo:function(){return i},kt:function(){return y}});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(r),h=a,y=u["".concat(p,".").concat(h)]||u[h]||f[h]||o;return r?n.createElement(y,s(s({ref:t},i),{},{components:r})):n.createElement(y,s({ref:t},i))}));function y(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=h;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(r),h=a,y=u["".concat(p,".").concat(h)]||u[h]||f[h]||o;return r?n.createElement(y,s(s({ref:t},i),{},{components:r})):n.createElement(y,s({ref:t},i))}));function y(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=h;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=p(n),m=a,f=u["".concat(s,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(f,i(i({ref:t},l),{},{components:n})):r.createElement(f,i({ref:t},l))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var p=2;p=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=p(n),m=a,f=u["".concat(s,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(f,i(i({ref:t},l),{},{components:n})):r.createElement(f,i({ref:t},l))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var p=2;p=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var c=n.createContext({}),s=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},g=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,g=o(e,["components","mdxType","originalType","parentName"]),d=s(r),u=i,k=d["".concat(c,".").concat(u)]||d[u]||p[u]||a;return r?n.createElement(k,l(l({ref:t},g),{},{components:r})):n.createElement(k,l({ref:t},g))}));function k(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=r.length,l=new Array(a);l[0]=u;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o[d]="string"==typeof e?e:i,l[1]=o;for(var s=2;s=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var c=n.createContext({}),s=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},g=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,g=o(e,["components","mdxType","originalType","parentName"]),d=s(r),u=i,k=d["".concat(c,".").concat(u)]||d[u]||p[u]||a;return r?n.createElement(k,l(l({ref:t},g),{},{components:r})):n.createElement(k,l({ref:t},g))}));function k(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=r.length,l=new Array(a);l[0]=u;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o[d]="string"==typeof e?e:i,l[1]=o;for(var s=2;s=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),h=l(n),p=a,m=h["".concat(c,".").concat(p)]||h[p]||d[p]||o;return n?r.createElement(m,s(s({ref:t},u),{},{components:n})):r.createElement(m,s({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=p;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[h]="string"==typeof e?e:a,s[1]=i;for(var l=2;l new_purse\n });\n}\n\n')),(0,o.kt)("h3",{id:"scenario1-advanced"},"Scenario 1 - Advanced Variation"),(0,o.kt)("p",null,"Advanced versions of this scenario can mitigate the wastefulness inherent in the example. If the caller creates a named purse independent of their main purse, they can integrate it with the contract in question. In this way, the same purse can be used to fund a contract repeatedly."),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/release-1.4.4/smart_contracts/contracts/client/named-purse-payment/src/main.rs"},"This example")," provides a framework for the idea, but will require modification to suit developer needs."),(0,o.kt)("h2",{id:"scenario2"},"Scenario 2 - Maintaining a Reusable Purse within Contract Logic"),(0,o.kt)("p",null,"The second scenario involves more complex internal logic to allow for a purse's reuse. The contract itself keeps track of a purse associated with the caller as internal bookkeeping."),(0,o.kt)("p",null,"In ",(0,o.kt)("a",{parentName:"p",href:"#scenario1"},"Scenario 1"),", the newly created purse is a pure means of transferring tokens from the caller to the callee. In contrast, Scenario 2 maintains an internal purse associated with the caller's address. This purse serves as token storage for actions the caller wishes the contract to undertake on their behalf. It differs from ",(0,o.kt)("a",{parentName:"p",href:"#scenario1-advanced"},"Scenario 1's Advanced Variation")," in that the purse in question is under the control of the contract rather than the caller."),(0,o.kt)("p",null,"Scenario 2 offers a less wasteful means of transferring tokens to a contract but comes with the added burden of internal complexity. When choosing between the two scenarios, you must evaluate the scope and needs of your project and choose accordingly."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'// Scenario 2: with this style, the contract being called has some internal accounting\n// to keep track of a reusable purse associated to the calling account; this avoids\n// wasteful creation of one time purses but requires the smart contract being called\n// to have more sophisticated internal logic.\n#[no_mangle]\npub extern "C" fn call() {\n let amount: U512 = runtime::get_named_arg("amount");\n\n // This is demonstrating the most direct case, wherein you pass in the contract_hash and\n // the entry_point_names of the target contract as args.\n // With prior setup having been done, this can also be simplified.\n let contract_hash = runtime::get_named_arg("contract_hash");\n // the name of the entry point on the contract that returns a purse uref to receive token at\n // the actual name of the entry point is up to the smart contract authors\n let deposit_point_name = runtime::get_named_arg("deposit_point_name");\n // whatever entry point on the smart contract does the actual work if token has been transferred\n // the actual name of which is up to the smart contract authors.\n let other_entry_point_name = runtime::get_named_arg("other_entry_point_name");\n\n // The smart contract returns a purse URef of a deposit purse (with ADD access rights only)\n // for the caller to transfer to.\n let deposit_purse: URef = runtime::call_contract(contract_hash, deposit_point_name, runtime_args! {});\n\n // transfer from the caller\'s purse to the purse provided by the contract; the transfer is handled\n // safely by the host and the caller\'s purse is never exposed to the called smart contract.\n system::transfer_from_purse_to_purse(account::get_main_purse(), deposit_purse, amount, None)\n .unwrap_or_revert();\n\n // The contract being interacted with looks up the associated purse, checks its balance, etc.\n // within its logic. That side of it is entirely up to the smart contract authors to code; the caller\n // merely calls the logic. Also, the entry point might require one or more runtime arguments.\n // In all cases some discovery of the API of the contract you are calling is necessary.\n runtime::call_contract(contract_hash, other_entry_point_name, runtime_args! {});\n}\n\n')),(0,o.kt)("h3",{id:"scenario2-advanced"},"Scenario 2 - Advanced Variation"),(0,o.kt)("p",null,"In Scenario 2, the contract in question maintains a purse for each associated caller. The advanced variation establishes an internal ledger that records the balance of each caller. The contract can record the information for each caller as a dictionary item and respond accordingly. In this fashion, a single purse can store the motes of all callers accessing the contract."),(0,o.kt)("p",null,"This design streamlines the internal accounting process of the contract but does require a greater degree of complexity during the initial setup."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3608],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return m}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),h=l(n),p=a,m=h["".concat(c,".").concat(p)]||h[p]||d[p]||o;return n?r.createElement(m,s(s({ref:t},u),{},{components:n})):r.createElement(m,s({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=p;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[h]="string"==typeof e?e:a,s[1]=i;for(var l=2;l new_purse\n });\n}\n\n')),(0,o.kt)("h3",{id:"scenario1-advanced"},"Scenario 1 - Advanced Variation"),(0,o.kt)("p",null,"Advanced versions of this scenario can mitigate the wastefulness inherent in the example. If the caller creates a named purse independent of their main purse, they can integrate it with the contract in question. In this way, the same purse can be used to fund a contract repeatedly."),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/release-1.4.4/smart_contracts/contracts/client/named-purse-payment/src/main.rs"},"This example")," provides a framework for the idea, but will require modification to suit developer needs."),(0,o.kt)("h2",{id:"scenario2"},"Scenario 2 - Maintaining a Reusable Purse within Contract Logic"),(0,o.kt)("p",null,"The second scenario involves more complex internal logic to allow for a purse's reuse. The contract itself keeps track of a purse associated with the caller as internal bookkeeping."),(0,o.kt)("p",null,"In ",(0,o.kt)("a",{parentName:"p",href:"#scenario1"},"Scenario 1"),", the newly created purse is a pure means of transferring tokens from the caller to the callee. In contrast, Scenario 2 maintains an internal purse associated with the caller's address. This purse serves as token storage for actions the caller wishes the contract to undertake on their behalf. It differs from ",(0,o.kt)("a",{parentName:"p",href:"#scenario1-advanced"},"Scenario 1's Advanced Variation")," in that the purse in question is under the control of the contract rather than the caller."),(0,o.kt)("p",null,"Scenario 2 offers a less wasteful means of transferring tokens to a contract but comes with the added burden of internal complexity. When choosing between the two scenarios, you must evaluate the scope and needs of your project and choose accordingly."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'// Scenario 2: with this style, the contract being called has some internal accounting\n// to keep track of a reusable purse associated to the calling account; this avoids\n// wasteful creation of one time purses but requires the smart contract being called\n// to have more sophisticated internal logic.\n#[no_mangle]\npub extern "C" fn call() {\n let amount: U512 = runtime::get_named_arg("amount");\n\n // This is demonstrating the most direct case, wherein you pass in the contract_hash and\n // the entry_point_names of the target contract as args.\n // With prior setup having been done, this can also be simplified.\n let contract_hash = runtime::get_named_arg("contract_hash");\n // the name of the entry point on the contract that returns a purse uref to receive token at\n // the actual name of the entry point is up to the smart contract authors\n let deposit_point_name = runtime::get_named_arg("deposit_point_name");\n // whatever entry point on the smart contract does the actual work if token has been transferred\n // the actual name of which is up to the smart contract authors.\n let other_entry_point_name = runtime::get_named_arg("other_entry_point_name");\n\n // The smart contract returns a purse URef of a deposit purse (with ADD access rights only)\n // for the caller to transfer to.\n let deposit_purse: URef = runtime::call_contract(contract_hash, deposit_point_name, runtime_args! {});\n\n // transfer from the caller\'s purse to the purse provided by the contract; the transfer is handled\n // safely by the host and the caller\'s purse is never exposed to the called smart contract.\n system::transfer_from_purse_to_purse(account::get_main_purse(), deposit_purse, amount, None)\n .unwrap_or_revert();\n\n // The contract being interacted with looks up the associated purse, checks its balance, etc.\n // within its logic. That side of it is entirely up to the smart contract authors to code; the caller\n // merely calls the logic. Also, the entry point might require one or more runtime arguments.\n // In all cases some discovery of the API of the contract you are calling is necessary.\n runtime::call_contract(contract_hash, other_entry_point_name, runtime_args! {});\n}\n\n')),(0,o.kt)("h3",{id:"scenario2-advanced"},"Scenario 2 - Advanced Variation"),(0,o.kt)("p",null,"In Scenario 2, the contract in question maintains a purse for each associated caller. The advanced variation establishes an internal ledger that records the balance of each caller. The contract can record the information for each caller as a dictionary item and respond accordingly. In this fashion, a single purse can store the motes of all callers accessing the contract."),(0,o.kt)("p",null,"This design streamlines the internal accounting process of the contract but does require a greater degree of complexity during the initial setup."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8f925d60.a4d99eef.js b/assets/js/8f925d60.fcb8e3d9.js similarity index 99% rename from assets/js/8f925d60.a4d99eef.js rename to assets/js/8f925d60.fcb8e3d9.js index 54c0ae372f..4f4709605b 100644 --- a/assets/js/8f925d60.a4d99eef.js +++ b/assets/js/8f925d60.fcb8e3d9.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[4835],{3905:function(e,t,a){a.d(t,{Zo:function(){return s},kt:function(){return u}});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),d=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},s=function(e){var t=d(e.components);return n.createElement(c.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},b=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,l=e.originalType,c=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),p=d(a),b=r,u=p["".concat(c,".").concat(b)]||p[b]||f[b]||l;return a?n.createElement(u,o(o({ref:t},s),{},{components:a})):n.createElement(u,o({ref:t},s))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=a.length,o=new Array(l);o[0]=b;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[p]="string"==typeof e?e:r,o[1]=i;for(var d=2;dstate_get_auction_info_result",id:"state_get_auction_info_result",level:3},{value:"info_get_validator_changes",id:"info-get-validator-changes",level:2},{value:"info_get_validator_changes_result",id:"info_get_validator_changes_result",level:3},{value:"chain_get_era_info_by_switch_block",id:"chain_get_era_info_by_switch_block",level:2},{value:"chain_get_era_info_by_switch_block_result",id:"chain_get_era_info_by_switch_block_result",level:3}],f={toc:p},b="wrapper";function u(e){var t=e.components,a=(0,r.Z)(e,o);return(0,l.kt)(b,(0,n.Z)({},f,a,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"proof-of-stake"},"Proof-of-Stake JSON-RPC Methods"),(0,l.kt)("p",null,"The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation."),(0,l.kt)("hr",null),(0,l.kt)("h2",{id:"state-get-auction-info"},"state_get_auction_info"),(0,l.kt)("p",null,"This method returns the ",(0,l.kt)("a",{parentName:"p",href:"/concepts/economics/consensus#bids"},"bids")," and ",(0,l.kt)("a",{parentName:"p",href:"/concepts/glossary/V#validator"},"validators")," as of either a specific Block (by height or hash). If you do not provide a ",(0,l.kt)("inlineCode",{parentName:"p"},"block_identifier"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"state_get_auction_info")," will return information from the most recent Block."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block identifier.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example state_get_auction_info request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_auction_info",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"state_get_auction_info_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"state_get_auction_info_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#auctionstate"},"auction_state")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The auction state.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example state_get_auction_info result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "auction_state": {\n "bids": [\n {\n "bid": {\n "bonding_purse": "uref-fafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafa-007",\n "delegation_rate": 0,\n "delegators": [],\n "inactive": false,\n "staked_amount": "10"\n },\n "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61"\n }\n ],\n "block_height": 10,\n "era_validators": [\n {\n "era_id": 10,\n "validator_weights": [\n {\n "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "weight": "10"\n }\n ]\n }\n ],\n "state_root_hash": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"\n }\n }\n}\n\n'))),(0,l.kt)("h2",{id:"info-get-validator-changes"},"info_get_validator_changes"),(0,l.kt)("p",null,"This method returns status changes of active validators. Listed changes occurred during the ",(0,l.kt)("inlineCode",{parentName:"p"},"EraId")," contained within the response itself. A validator may show more than one change in a single era."),(0,l.kt)("p",null,"Potential change types:"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Change Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Added"),(0,l.kt)("td",{parentName:"tr",align:null},"The validator has been added to the set.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Removed"),(0,l.kt)("td",{parentName:"tr",align:null},"The validator has been removed from the set.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Banned"),(0,l.kt)("td",{parentName:"tr",align:null},"The validator has been banned in the current era.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"CannotPropose"),(0,l.kt)("td",{parentName:"tr",align:null},"The validator cannot propose a Block.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"SeenAsFaulty"),(0,l.kt)("td",{parentName:"tr",align:null},"The validator has performed questionable activity.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_validator_changes request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_validator_changes",\n "params": []\n}\n\n'))),(0,l.kt)("h3",{id:"info_get_validator_changes_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"info_get_validator_changes_result")),(0,l.kt)("p",null,"If no changes occurred in the current era, ",(0,l.kt)("inlineCode",{parentName:"p"},"info_get_validator_changes")," will return empty."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#jsonvalidatorchanges"},"changes")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The validators' status changes.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_validator_changes result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "changes": [\n {\n "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "status_changes": [\n {\n "era_id": 1,\n "validator_change": "Added"\n }\n ]\n }\n ]\n }\n}\n\n'))),(0,l.kt)("h2",{id:"chain_get_era_info_by_switch_block"},"chain_get_era_info_by_switch_block"),(0,l.kt)("p",null,"This method returns an EraInfo from the network. Only the last Block in an ",(0,l.kt)("inlineCode",{parentName:"p"},"era"),", known as a switch block, will contain an ",(0,l.kt)("inlineCode",{parentName:"p"},"era_summary"),"."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block identifier. If you do not supply a ",(0,l.kt)("inlineCode",{parentName:"td"},"block_identifier"),", the returned information will be the most recent Block. (Optional)")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_era_info_by_switch_block request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_era_info_by_switch_block",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"chain_get_era_info_by_switch_block_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"chain_get_era_info_by_switch_block_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#erasummary"},"era_summary")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The era summary (If found).")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_era_info_by_switch_block"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "era_summary": {\n "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "era_id": 42,\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "stored_value": {\n "EraInfo": {\n "seigniorage_allocations": [\n {\n "Delegator": {\n "amount": "1000",\n "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876"\n }\n },\n {\n "Validator": {\n "amount": "2000",\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876"\n }\n }\n ]\n }\n }\n }\n }\n}\n\n'))))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[4835],{3905:function(e,t,a){a.d(t,{Zo:function(){return s},kt:function(){return u}});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),d=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},s=function(e){var t=d(e.components);return n.createElement(c.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},b=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,l=e.originalType,c=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),p=d(a),b=r,u=p["".concat(c,".").concat(b)]||p[b]||f[b]||l;return a?n.createElement(u,o(o({ref:t},s),{},{components:a})):n.createElement(u,o({ref:t},s))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=a.length,o=new Array(l);o[0]=b;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[p]="string"==typeof e?e:r,o[1]=i;for(var d=2;dstate_get_auction_info_result",id:"state_get_auction_info_result",level:3},{value:"info_get_validator_changes",id:"info-get-validator-changes",level:2},{value:"info_get_validator_changes_result",id:"info_get_validator_changes_result",level:3},{value:"chain_get_era_info_by_switch_block",id:"chain_get_era_info_by_switch_block",level:2},{value:"chain_get_era_info_by_switch_block_result",id:"chain_get_era_info_by_switch_block_result",level:3}],f={toc:p},b="wrapper";function u(e){var t=e.components,a=(0,r.Z)(e,o);return(0,l.kt)(b,(0,n.Z)({},f,a,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"proof-of-stake"},"Proof-of-Stake JSON-RPC Methods"),(0,l.kt)("p",null,"The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation."),(0,l.kt)("hr",null),(0,l.kt)("h2",{id:"state-get-auction-info"},"state_get_auction_info"),(0,l.kt)("p",null,"This method returns the ",(0,l.kt)("a",{parentName:"p",href:"/concepts/economics/consensus#bids"},"bids")," and ",(0,l.kt)("a",{parentName:"p",href:"/concepts/glossary/V#validator"},"validators")," as of either a specific Block (by height or hash). If you do not provide a ",(0,l.kt)("inlineCode",{parentName:"p"},"block_identifier"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"state_get_auction_info")," will return information from the most recent Block."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block identifier.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example state_get_auction_info request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_auction_info",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"state_get_auction_info_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"state_get_auction_info_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#auctionstate"},"auction_state")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The auction state.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example state_get_auction_info result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "auction_state": {\n "bids": [\n {\n "bid": {\n "bonding_purse": "uref-fafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafa-007",\n "delegation_rate": 0,\n "delegators": [],\n "inactive": false,\n "staked_amount": "10"\n },\n "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61"\n }\n ],\n "block_height": 10,\n "era_validators": [\n {\n "era_id": 10,\n "validator_weights": [\n {\n "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "weight": "10"\n }\n ]\n }\n ],\n "state_root_hash": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"\n }\n }\n}\n\n'))),(0,l.kt)("h2",{id:"info-get-validator-changes"},"info_get_validator_changes"),(0,l.kt)("p",null,"This method returns status changes of active validators. Listed changes occurred during the ",(0,l.kt)("inlineCode",{parentName:"p"},"EraId")," contained within the response itself. A validator may show more than one change in a single era."),(0,l.kt)("p",null,"Potential change types:"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Change Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Added"),(0,l.kt)("td",{parentName:"tr",align:null},"The validator has been added to the set.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Removed"),(0,l.kt)("td",{parentName:"tr",align:null},"The validator has been removed from the set.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"Banned"),(0,l.kt)("td",{parentName:"tr",align:null},"The validator has been banned in the current era.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"CannotPropose"),(0,l.kt)("td",{parentName:"tr",align:null},"The validator cannot propose a Block.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"SeenAsFaulty"),(0,l.kt)("td",{parentName:"tr",align:null},"The validator has performed questionable activity.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_validator_changes request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_validator_changes",\n "params": []\n}\n\n'))),(0,l.kt)("h3",{id:"info_get_validator_changes_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"info_get_validator_changes_result")),(0,l.kt)("p",null,"If no changes occurred in the current era, ",(0,l.kt)("inlineCode",{parentName:"p"},"info_get_validator_changes")," will return empty."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#jsonvalidatorchanges"},"changes")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The validators' status changes.")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example info_get_validator_changes result"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "changes": [\n {\n "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "status_changes": [\n {\n "era_id": 1,\n "validator_change": "Added"\n }\n ]\n }\n ]\n }\n}\n\n'))),(0,l.kt)("h2",{id:"chain_get_era_info_by_switch_block"},"chain_get_era_info_by_switch_block"),(0,l.kt)("p",null,"This method returns an EraInfo from the network. Only the last Block in an ",(0,l.kt)("inlineCode",{parentName:"p"},"era"),", known as a switch block, will contain an ",(0,l.kt)("inlineCode",{parentName:"p"},"era_summary"),"."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The Block identifier. If you do not supply a ",(0,l.kt)("inlineCode",{parentName:"td"},"block_identifier"),", the returned information will be the most recent Block. (Optional)")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_era_info_by_switch_block request"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_era_info_by_switch_block",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'))),(0,l.kt)("h3",{id:"chain_get_era_info_by_switch_block_result"},(0,l.kt)("inlineCode",{parentName:"h3"},"chain_get_era_info_by_switch_block_result")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Type"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"api_version"),(0,l.kt)("td",{parentName:"tr",align:null},"String"),(0,l.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},(0,l.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#erasummary"},"era_summary")),(0,l.kt)("td",{parentName:"tr",align:null},"Object"),(0,l.kt)("td",{parentName:"tr",align:null},"The era summary (If found).")))),(0,l.kt)("details",null,(0,l.kt)("summary",null,"Example chain_get_era_info_by_switch_block"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "era_summary": {\n "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "era_id": 42,\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "stored_value": {\n "EraInfo": {\n "seigniorage_allocations": [\n {\n "Delegator": {\n "amount": "1000",\n "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876"\n }\n },\n {\n "Validator": {\n "amount": "2000",\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876"\n }\n }\n ]\n }\n }\n }\n }\n}\n\n'))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/92692c02.16df54f2.js b/assets/js/92692c02.7de1d214.js similarity index 99% rename from assets/js/92692c02.16df54f2.js rename to assets/js/92692c02.7de1d214.js index 28e35e2a89..5d88b6b740 100644 --- a/assets/js/92692c02.16df54f2.js +++ b/assets/js/92692c02.7de1d214.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3065],{3905:function(e,t,a){a.d(t,{Zo:function(){return d},kt:function(){return h}});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var s=n.createContext({}),c=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=c(a),p=r,h=u["".concat(s,".").concat(p)]||u[p]||g[p]||i;return a?n.createElement(h,o(o({ref:t},d),{},{components:a})):n.createElement(h,o({ref:t},d))}));function h(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=p;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[u]="string"==typeof e?e:r,o[1]=l;for(var c=2;cImportant Notes",id:"important-notes",level:3},{value:"Staking with a Validator",id:"2-staking",level:2},{value:"Connect and Login with Ledger",id:"connect-and-login-with-ledger",level:3},{value:"Receive Tokens from an External Source",id:"receive-tokens-from-an-external-source",level:3},{value:"Staking Tokens",id:"staking-tokens",level:3},{value:"Unstaking with a Validator",id:"3-unstaking",level:2},{value:"Initiate the Undelegation",id:"initiate-the-undelegation",level:3},{value:"Sign the Undelegation",id:"sign-the-undelegation",level:3}],p={toc:g},h="wrapper";function k(e){var t=e.components,a=(0,r.Z)(e,l);return(0,i.kt)(h,(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"delegating-with-ledger-devices"},"Delegating with Ledger Devices"),(0,i.kt)("h2",{id:"1-initialization"},"Ledger Initialization"),(0,i.kt)("p",null,"Before getting started, you need to complete two prerequisite steps:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Set up your Ledger device using the ",(0,i.kt)("a",{parentName:"li",href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true"},"official documentation"),"."),(0,i.kt)("li",{parentName:"ol"},"Connect the Ledger to your ",(0,i.kt)("a",{parentName:"li",href:"https://cspr.live/"},"cspr.live")," account by following the ",(0,i.kt)("a",{parentName:"li",href:"/workflow/ledger-setup/"},"Ledger Setup")," guide.")),(0,i.kt)("h3",{id:"important-notes"},(0,i.kt)("strong",{parentName:"h3"},"Important Notes")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},(0,i.kt)("span",{style:{color:"#ee5945"}},"CRITICAL")),": Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key."),(0,i.kt)("li",{parentName:"ol"},"When logging in to ",(0,i.kt)("a",{parentName:"li",href:"https://cspr.live/"},"cspr.live"),", the UI will offer numerous public keys. Choose any of them. They are all derived from the Master Seed that is secured in the Ledger key (",(0,i.kt)("a",{parentName:"li",href:"https://www.ledger.com/academy/crypto/where-are-my-coins"},"more info here"),"). Make sure you write down whichever public key(s) you end up using so that you have no confusion when trying to log in.")),(0,i.kt)("h2",{id:"2-staking"},"Staking with a Validator"),(0,i.kt)("h3",{id:"connect-and-login-with-ledger"},"Connect and Login with Ledger"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Connect your Ledger to your computer via USB and enter your PIN to unlock it.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'Open the Casper app on the Ledger (you will see the message "Casper Ready").'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger1.png"),alt:"Casper Ready",width:"400"})),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Sign in to ",(0,i.kt)("a",{parentName:"p",href:"https://cspr.live/"},"cspr.live"),' with your Ledger by clicking "Connect" under the Ledger option, as shown in the screenshot below.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger2.png"),alt:"Casper Ready",width:"800"})),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Select the public key connected to your Ledger account."),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger3.png"),alt:"Casper Ready",width:"800"})),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"View your account by clicking on your public key at the top right corner."),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger4.png"),alt:"Casper Ready",width:"800"}))),(0,i.kt)("h3",{id:"receive-tokens-from-an-external-source"},"Receive Tokens from an External Source"),(0,i.kt)("p",null,"This portion will vary slightly depending on where your funds are currently stored. However, the process will require that you send tokens to your public key as described in the ",(0,i.kt)("a",{parentName:"p",href:"/workflow/ledger-setup/#receive-tokens"},"documentation"),"."),(0,i.kt)("h3",{id:"staking-tokens"},"Staking Tokens"),(0,i.kt)("p",null,"Once you have tokens in your account, staking (delegating) with a validator is easy."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'Go back to your account, but this time open the "delegate" tab located at: ',(0,i.kt)("a",{parentName:"p",href:"https://cspr.live/delegate-stake"},"https://cspr.live/delegate-stake")," (alternatively, click on ",(0,i.kt)("inlineCode",{parentName:"p"},"Wallet \u21d2 Delegate Stake")," to go there).")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"From the validator list, choose any validator you like. You will notice that validators charge different fees and have different amounts staked to them. This may inform your decision to choose the right validator for you.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'Specify the amount you wish to stake or click "Delegate max" as shown below. Notes:'),(0,i.kt)("ol",{parentName:"li"},(0,i.kt)("li",{parentName:"ol"},"Remember that the total delegation amount to one validator cannot be less than 500 CSPR."),(0,i.kt)("li",{parentName:"ol"},"Both delegation and undelegation have an associated fee, so you need to leave some funds in your account to cover transaction fees. Otherwise, you may need to deposit additional funds to undelegate later."))),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'Click "Next" to continue, as shown below.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger5.png"),alt:"Casper Ready",width:"800"})),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'The page will update with a confirmation page asking you to verify all the details. If everything looks correct, click the "Confirm and delegate stake" button.')),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'You will be presented with a final page asking you to sign the transaction with Ledger. Click the "Sign with Ledger" button at the bottom.'),(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Note"),': If you get an error showing a "Transaction rejected" message, make sure your Ledger device is active and connected to your computer. You may also need to re-enter your PIN if it locked itself due to inactivity.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger6.png"),alt:"Casper Ready",width:"800"})),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'On the Ledger, you will see a message saying, "Please review". Click through the fields and verify everything matches what is being shown to you on ',(0,i.kt)("a",{parentName:"p",href:"https://cspr.live"},"cspr.live"),"."),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger7.png"),alt:"Casper Ready",width:"400"})),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'Once you click "Approve", you will see the Delegation Completed screen verifying that your staking successfully was submitted to the blockchain.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger8.png"),alt:"Casper Ready",width:"400"})," ",(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger9.png"),alt:"Casper Ready",width:"800"})),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'At this point, you can return to your account and wait until the completion of the era when the block gets included in the chain. Once the era completes, you will see that your liquid balance has decreased by your staked amount and is reflected in the "Staked As Delegator" row.'),(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Note"),": If you staked your full balance, don't panic if you see a 0 CSPR balance whenever you log in! This is because it shows your liquid assets, not your total balance. You can go to your account details page, as shown below, to see your full balance and asset breakdown between liquid, staked, and undelegated tokens."),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger10.png"),alt:"Casper Ready",width:"800"}))),(0,i.kt)("h2",{id:"3-unstaking"},"Unstaking with a Validator"),(0,i.kt)("h3",{id:"initiate-the-undelegation"},"Initiate the Undelegation"),(0,i.kt)("p",null,'Now that you have funds delegated, you can liquidate them by undelegating them first. As demonstrated below, on your account\'s profile page, click "Undelegate" to get started.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger11.png"),alt:"Casper Ready",width:"800"}),(0,i.kt)("p",null,'The next page, "Undelegation details", will ask you how much you wish to undelegate. If you select "Undelegate max", it will attempt to liquidate all of your staked assets (minus the transaction fee). Once you enter a valid amount, the "Next" button will become clickable. Below you can see that I entered 313.02931 CSPR to be able to proceed.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger12.png"),alt:"Casper Ready",width:"800"}),(0,i.kt)("p",null,'You will next be shown a confirmation screen. If everything looks good, then click "Confirm and undelegate stake" to proceed.'),(0,i.kt)("h3",{id:"sign-the-undelegation"},"Sign the Undelegation"),(0,i.kt)("p",null,"You will have to sign the transaction to verify your account is initiating this action."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Connect your Ledger device to your computer.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Unlock your Ledger by entering your PIN.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'Open the "Casper" app and ensure you see "Casper Ready".')),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Then back on ",(0,i.kt)("a",{parentName:"p",href:"https://cspr.live"},"cspr.live"),' click the "Sign with Ledger" button shown below.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger13.png"),alt:"Casper Ready",width:"800"}))),(0,i.kt)("p",null,'On your Ledger, you will see the transaction details. Verify all the information with what is being presented on the screen. If it looks good, then approve the transaction. If all goes according to plan, you will be presented with an "Undelegation completed!" screen.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger14.png"),alt:"Casper Ready",width:"800"}),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Note"),': There is a 7 era delay to undelegate. Era duration is approximately 120 minutes. While the funds go through undelegation, the balance will appear in the "Undelegation" row on your account profile page, as you can see below.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger15.png"),alt:"Casper Ready",width:"800"}),(0,i.kt)("p",null,"After the undelegation period completes, your funds will be liquid and available for you to re-stake, withdraw, or use however you wish."))}k.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3065],{3905:function(e,t,a){a.d(t,{Zo:function(){return d},kt:function(){return h}});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var s=n.createContext({}),c=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=c(a),p=r,h=u["".concat(s,".").concat(p)]||u[p]||g[p]||i;return a?n.createElement(h,o(o({ref:t},d),{},{components:a})):n.createElement(h,o({ref:t},d))}));function h(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=p;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[u]="string"==typeof e?e:r,o[1]=l;for(var c=2;cImportant Notes",id:"important-notes",level:3},{value:"Staking with a Validator",id:"2-staking",level:2},{value:"Connect and Login with Ledger",id:"connect-and-login-with-ledger",level:3},{value:"Receive Tokens from an External Source",id:"receive-tokens-from-an-external-source",level:3},{value:"Staking Tokens",id:"staking-tokens",level:3},{value:"Unstaking with a Validator",id:"3-unstaking",level:2},{value:"Initiate the Undelegation",id:"initiate-the-undelegation",level:3},{value:"Sign the Undelegation",id:"sign-the-undelegation",level:3}],p={toc:g},h="wrapper";function k(e){var t=e.components,a=(0,r.Z)(e,l);return(0,i.kt)(h,(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"delegating-with-ledger-devices"},"Delegating with Ledger Devices"),(0,i.kt)("h2",{id:"1-initialization"},"Ledger Initialization"),(0,i.kt)("p",null,"Before getting started, you need to complete two prerequisite steps:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Set up your Ledger device using the ",(0,i.kt)("a",{parentName:"li",href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true"},"official documentation"),"."),(0,i.kt)("li",{parentName:"ol"},"Connect the Ledger to your ",(0,i.kt)("a",{parentName:"li",href:"https://cspr.live/"},"cspr.live")," account by following the ",(0,i.kt)("a",{parentName:"li",href:"/workflow/ledger-setup/"},"Ledger Setup")," guide.")),(0,i.kt)("h3",{id:"important-notes"},(0,i.kt)("strong",{parentName:"h3"},"Important Notes")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},(0,i.kt)("span",{style:{color:"#ee5945"}},"CRITICAL")),": Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key."),(0,i.kt)("li",{parentName:"ol"},"When logging in to ",(0,i.kt)("a",{parentName:"li",href:"https://cspr.live/"},"cspr.live"),", the UI will offer numerous public keys. Choose any of them. They are all derived from the Master Seed that is secured in the Ledger key (",(0,i.kt)("a",{parentName:"li",href:"https://www.ledger.com/academy/crypto/where-are-my-coins"},"more info here"),"). Make sure you write down whichever public key(s) you end up using so that you have no confusion when trying to log in.")),(0,i.kt)("h2",{id:"2-staking"},"Staking with a Validator"),(0,i.kt)("h3",{id:"connect-and-login-with-ledger"},"Connect and Login with Ledger"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Connect your Ledger to your computer via USB and enter your PIN to unlock it.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'Open the Casper app on the Ledger (you will see the message "Casper Ready").'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger1.png"),alt:"Casper Ready",width:"400"})),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Sign in to ",(0,i.kt)("a",{parentName:"p",href:"https://cspr.live/"},"cspr.live"),' with your Ledger by clicking "Connect" under the Ledger option, as shown in the screenshot below.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger2.png"),alt:"Casper Ready",width:"800"})),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Select the public key connected to your Ledger account."),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger3.png"),alt:"Casper Ready",width:"800"})),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"View your account by clicking on your public key at the top right corner."),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger4.png"),alt:"Casper Ready",width:"800"}))),(0,i.kt)("h3",{id:"receive-tokens-from-an-external-source"},"Receive Tokens from an External Source"),(0,i.kt)("p",null,"This portion will vary slightly depending on where your funds are currently stored. However, the process will require that you send tokens to your public key as described in the ",(0,i.kt)("a",{parentName:"p",href:"/workflow/ledger-setup/#receive-tokens"},"documentation"),"."),(0,i.kt)("h3",{id:"staking-tokens"},"Staking Tokens"),(0,i.kt)("p",null,"Once you have tokens in your account, staking (delegating) with a validator is easy."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'Go back to your account, but this time open the "delegate" tab located at: ',(0,i.kt)("a",{parentName:"p",href:"https://cspr.live/delegate-stake"},"https://cspr.live/delegate-stake")," (alternatively, click on ",(0,i.kt)("inlineCode",{parentName:"p"},"Wallet \u21d2 Delegate Stake")," to go there).")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"From the validator list, choose any validator you like. You will notice that validators charge different fees and have different amounts staked to them. This may inform your decision to choose the right validator for you.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'Specify the amount you wish to stake or click "Delegate max" as shown below. Notes:'),(0,i.kt)("ol",{parentName:"li"},(0,i.kt)("li",{parentName:"ol"},"Remember that the total delegation amount to one validator cannot be less than 500 CSPR."),(0,i.kt)("li",{parentName:"ol"},"Both delegation and undelegation have an associated fee, so you need to leave some funds in your account to cover transaction fees. Otherwise, you may need to deposit additional funds to undelegate later."))),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'Click "Next" to continue, as shown below.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger5.png"),alt:"Casper Ready",width:"800"})),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'The page will update with a confirmation page asking you to verify all the details. If everything looks correct, click the "Confirm and delegate stake" button.')),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'You will be presented with a final page asking you to sign the transaction with Ledger. Click the "Sign with Ledger" button at the bottom.'),(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Note"),': If you get an error showing a "Transaction rejected" message, make sure your Ledger device is active and connected to your computer. You may also need to re-enter your PIN if it locked itself due to inactivity.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger6.png"),alt:"Casper Ready",width:"800"})),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'On the Ledger, you will see a message saying, "Please review". Click through the fields and verify everything matches what is being shown to you on ',(0,i.kt)("a",{parentName:"p",href:"https://cspr.live"},"cspr.live"),"."),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger7.png"),alt:"Casper Ready",width:"400"})),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'Once you click "Approve", you will see the Delegation Completed screen verifying that your staking successfully was submitted to the blockchain.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger8.png"),alt:"Casper Ready",width:"400"})," ",(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger9.png"),alt:"Casper Ready",width:"800"})),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'At this point, you can return to your account and wait until the completion of the era when the block gets included in the chain. Once the era completes, you will see that your liquid balance has decreased by your staked amount and is reflected in the "Staked As Delegator" row.'),(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Note"),": If you staked your full balance, don't panic if you see a 0 CSPR balance whenever you log in! This is because it shows your liquid assets, not your total balance. You can go to your account details page, as shown below, to see your full balance and asset breakdown between liquid, staked, and undelegated tokens."),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger10.png"),alt:"Casper Ready",width:"800"}))),(0,i.kt)("h2",{id:"3-unstaking"},"Unstaking with a Validator"),(0,i.kt)("h3",{id:"initiate-the-undelegation"},"Initiate the Undelegation"),(0,i.kt)("p",null,'Now that you have funds delegated, you can liquidate them by undelegating them first. As demonstrated below, on your account\'s profile page, click "Undelegate" to get started.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger11.png"),alt:"Casper Ready",width:"800"}),(0,i.kt)("p",null,'The next page, "Undelegation details", will ask you how much you wish to undelegate. If you select "Undelegate max", it will attempt to liquidate all of your staked assets (minus the transaction fee). Once you enter a valid amount, the "Next" button will become clickable. Below you can see that I entered 313.02931 CSPR to be able to proceed.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger12.png"),alt:"Casper Ready",width:"800"}),(0,i.kt)("p",null,'You will next be shown a confirmation screen. If everything looks good, then click "Confirm and undelegate stake" to proceed.'),(0,i.kt)("h3",{id:"sign-the-undelegation"},"Sign the Undelegation"),(0,i.kt)("p",null,"You will have to sign the transaction to verify your account is initiating this action."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Connect your Ledger device to your computer.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Unlock your Ledger by entering your PIN.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},'Open the "Casper" app and ensure you see "Casper Ready".')),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Then back on ",(0,i.kt)("a",{parentName:"p",href:"https://cspr.live"},"cspr.live"),' click the "Sign with Ledger" button shown below.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger13.png"),alt:"Casper Ready",width:"800"}))),(0,i.kt)("p",null,'On your Ledger, you will see the transaction details. Verify all the information with what is being presented on the screen. If it looks good, then approve the transaction. If all goes according to plan, you will be presented with an "Undelegation completed!" screen.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger14.png"),alt:"Casper Ready",width:"800"}),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Note"),': There is a 7 era delay to undelegate. Era duration is approximately 120 minutes. While the funds go through undelegation, the balance will appear in the "Undelegation" row on your account profile page, as you can see below.'),(0,i.kt)("img",{class:"align-center",src:(0,o.Z)("/image/tutorials/ledger/staking/ledger15.png"),alt:"Casper Ready",width:"800"}),(0,i.kt)("p",null,"After the undelegation period completes, your funds will be liquid and available for you to re-stake, withdraw, or use however you wish."))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/956d710b.ed13cd24.js b/assets/js/956d710b.21f28172.js similarity index 99% rename from assets/js/956d710b.ed13cd24.js rename to assets/js/956d710b.21f28172.js index 8fd2643349..a778bb7b34 100644 --- a/assets/js/956d710b.ed13cd24.js +++ b/assets/js/956d710b.21f28172.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[8422],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return k}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),i=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=i(e.components);return a.createElement(p.Provider,{value:t},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,p=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=i(n),d=r,k=c["".concat(p,".").concat(d)]||c[d]||m[d]||o;return n?a.createElement(k,l(l({ref:t},u),{},{components:n})):a.createElement(k,l({ref:t},u))}));function k(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[c]="string"==typeof e?e:r,l[1]=s;for(var i=2;i\n(env) $ git clone https://github.com/casper-network/casper-node-launcher\n")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Assuming you have set up a small local network, you can speed up the process of creating new blocks with NCTL by reducing the ",(0,o.kt)("inlineCode",{parentName:"p"},"deploy_delay")," in your ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/dev/resources/local/config.toml#L390"},"local config.toml")," before running ",(0,o.kt)("inlineCode",{parentName:"p"},"nctl-assets-setup"),".")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Step 11.")," Next, clone the ",(0,o.kt)("em",{parentName:"p"},"casper-node")," software, also in your working directory."),(0,o.kt)("p",null,"Instructions for MacOS and Linux:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"(env) $ git clone https://github.com/casper-network/casper-node\n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Step 12.")," Finally, clone the ",(0,o.kt)("em",{parentName:"p"},"casper-client-rs")," software in your working directory."),(0,o.kt)("p",null,"Instructions for MacOS and Linux:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"(env) $ git clone https://github.com/casper-ecosystem/casper-client-rs\n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Step 13.")," Activate the NCTL environment with the following command."),(0,o.kt)("p",null,"Instructions for MacOS and Linux:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"(env) $ source casper-node/utils/nctl/activate\n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Step 14.")," Compile the NCTL binary scripts. The following command compiles both the ",(0,o.kt)("em",{parentName:"p"},"casper-node")," and the ",(0,o.kt)("em",{parentName:"p"},"casper-client")," in release mode."),(0,o.kt)("p",null,"Instructions for MacOS and Linux:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"(env) $ nctl-compile\n")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"The compilation takes some time, so it might be a perfect moment to get some coffee.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Step 15.")," Set up all the assets required to run a local network, including binaries, chainspec, config, faucet, and keys. Also, spin up the network right after. The default network will have 10 nodes, with 5 active nodes and 5 inactive nodes."),(0,o.kt)("p",null,"Instructions for MacOS and Linux:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"(env) $ nctl-assets-setup && nctl-start\n")),(0,o.kt)("p",null,"Once a network is up and running, you can control each node within the network and add new nodes to the network."),(0,o.kt)("p",null,"Several other NCTL commands are available via aliases for execution from within a terminal session. All such commands are prefixed by ",(0,o.kt)("em",{parentName:"p"},"nctl-")," and allow you to perform various tasks."),(0,o.kt)("p",null,"You should see the new directory ",(0,o.kt)("em",{parentName:"p"},"utils/nctl/assets"),", with the following structure."),(0,o.kt)("img",{src:(0,l.Z)("/image/nctl/assets_setup.png"),alt:"assets_setup",width:"200"}),(0,o.kt)("p",null,"Here is the command line output you would expect."),(0,o.kt)("img",{src:(0,l.Z)("/image/nctl/nctl_output.png"),alt:"nctl_output"}),(0,o.kt)("h2",{id:"stopping-the-network"},"Stopping the Network"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Step 15.")," Although not necessary, you can stop and clean the NCTL setup with the following commands."),(0,o.kt)("p",null,"Instructions for MacOS and Linux:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"(env) $ nctl-stop\n(env) $ nctl-clean\n")),(0,o.kt)("h2",{id:"next-steps"},"Next Steps"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Explore the ",(0,o.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/master/utils/nctl/docs/commands.md"},"various NCTL commands"),"."),(0,o.kt)("li",{parentName:"ol"},"Explore the ",(0,o.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/master/utils/nctl/docs/usage.md"},"NCTL usage guide"),".")))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[8422],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return k}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),i=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=i(e.components);return a.createElement(p.Provider,{value:t},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,p=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=i(n),d=r,k=c["".concat(p,".").concat(d)]||c[d]||m[d]||o;return n?a.createElement(k,l(l({ref:t},u),{},{components:n})):a.createElement(k,l({ref:t},u))}));function k(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[c]="string"==typeof e?e:r,l[1]=s;for(var i=2;i\n(env) $ git clone https://github.com/casper-network/casper-node-launcher\n")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Assuming you have set up a small local network, you can speed up the process of creating new blocks with NCTL by reducing the ",(0,o.kt)("inlineCode",{parentName:"p"},"deploy_delay")," in your ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/dev/resources/local/config.toml#L390"},"local config.toml")," before running ",(0,o.kt)("inlineCode",{parentName:"p"},"nctl-assets-setup"),".")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Step 11.")," Next, clone the ",(0,o.kt)("em",{parentName:"p"},"casper-node")," software, also in your working directory."),(0,o.kt)("p",null,"Instructions for MacOS and Linux:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"(env) $ git clone https://github.com/casper-network/casper-node\n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Step 12.")," Finally, clone the ",(0,o.kt)("em",{parentName:"p"},"casper-client-rs")," software in your working directory."),(0,o.kt)("p",null,"Instructions for MacOS and Linux:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"(env) $ git clone https://github.com/casper-ecosystem/casper-client-rs\n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Step 13.")," Activate the NCTL environment with the following command."),(0,o.kt)("p",null,"Instructions for MacOS and Linux:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"(env) $ source casper-node/utils/nctl/activate\n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Step 14.")," Compile the NCTL binary scripts. The following command compiles both the ",(0,o.kt)("em",{parentName:"p"},"casper-node")," and the ",(0,o.kt)("em",{parentName:"p"},"casper-client")," in release mode."),(0,o.kt)("p",null,"Instructions for MacOS and Linux:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"(env) $ nctl-compile\n")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"The compilation takes some time, so it might be a perfect moment to get some coffee.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Step 15.")," Set up all the assets required to run a local network, including binaries, chainspec, config, faucet, and keys. Also, spin up the network right after. The default network will have 10 nodes, with 5 active nodes and 5 inactive nodes."),(0,o.kt)("p",null,"Instructions for MacOS and Linux:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"(env) $ nctl-assets-setup && nctl-start\n")),(0,o.kt)("p",null,"Once a network is up and running, you can control each node within the network and add new nodes to the network."),(0,o.kt)("p",null,"Several other NCTL commands are available via aliases for execution from within a terminal session. All such commands are prefixed by ",(0,o.kt)("em",{parentName:"p"},"nctl-")," and allow you to perform various tasks."),(0,o.kt)("p",null,"You should see the new directory ",(0,o.kt)("em",{parentName:"p"},"utils/nctl/assets"),", with the following structure."),(0,o.kt)("img",{src:(0,l.Z)("/image/nctl/assets_setup.png"),alt:"assets_setup",width:"200"}),(0,o.kt)("p",null,"Here is the command line output you would expect."),(0,o.kt)("img",{src:(0,l.Z)("/image/nctl/nctl_output.png"),alt:"nctl_output"}),(0,o.kt)("h2",{id:"stopping-the-network"},"Stopping the Network"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Step 15.")," Although not necessary, you can stop and clean the NCTL setup with the following commands."),(0,o.kt)("p",null,"Instructions for MacOS and Linux:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"(env) $ nctl-stop\n(env) $ nctl-clean\n")),(0,o.kt)("h2",{id:"next-steps"},"Next Steps"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Explore the ",(0,o.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/master/utils/nctl/docs/commands.md"},"various NCTL commands"),"."),(0,o.kt)("li",{parentName:"ol"},"Explore the ",(0,o.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/master/utils/nctl/docs/usage.md"},"NCTL usage guide"),".")))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/963db545.f7c0fcf5.js b/assets/js/963db545.a199f73e.js similarity index 99% rename from assets/js/963db545.f7c0fcf5.js rename to assets/js/963db545.a199f73e.js index a0e5b36e81..7cad83d25d 100644 --- a/assets/js/963db545.f7c0fcf5.js +++ b/assets/js/963db545.a199f73e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[9065],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return m}});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=a.createContext({}),l=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(p.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),h=o,m=d["".concat(p,".").concat(h)]||d[h]||u[h]||r;return n?a.createElement(m,i(i({ref:t},c),{},{components:n})):a.createElement(m,i({ref:t},c))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=h;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var l=2;l")," and will require you to define the path to your specific ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," Wasm.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"The ",(0,r.kt)("strong",{parentName:"p"},"node address")," for a node on your NCTL network. In this example, we are using the node at ",(0,r.kt)("inlineCode",{parentName:"p"},"http://localhost:11101"),". On the Casper Mainnet or Testnet, nodes will use port ",(0,r.kt)("inlineCode",{parentName:"p"},"7777"),". This will appear in our example put-deploy as ",(0,r.kt)("inlineCode",{parentName:"p"},"--node-address http://:7777"),"."))),(0,r.kt)("p",null,"The command to send your ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," should look similar to the following code snippet:"),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Use of the ",(0,r.kt)("inlineCode",{parentName:"p"},"$(get_path_to_client)")," command assumes that you are operating in an activated NCTL envrionment.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'$(get_path_to_client) put-deploy \\\n--chain-name "casper-net-1" \\\n--secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-path \\\n--node-address http://localhost:11101\n')),(0,r.kt)("p",null,"The response will return something similar to the following information. Note the ",(0,r.kt)("inlineCode",{parentName:"p"},"deploy_hash"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'{\n "id": 4824893960188648146,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "deploy_hash": "8e6309cc37bc58d8fedc1094ee1bd264a636d39fc0e05b5e1d72d98f7b6faf13"\n }\n}\n')),(0,r.kt)("h2",{id:"verifying-deploy-execution"},"Verifying Deploy Execution"),(0,r.kt)("p",null,"The previous command sent the ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," to the NCTL network, but we recommend verifying deploy execution before continuing. The ",(0,r.kt)("inlineCode",{parentName:"p"},"deploy_hash")," received in the response allows you to query the ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy"),"'s status."),(0,r.kt)("p",null,"To query the ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy"),"'s status, you will pass both the ",(0,r.kt)("inlineCode",{parentName:"p"},"deploy_hash")," and the same ",(0,r.kt)("inlineCode",{parentName:"p"},"node-address")," from above using the following command. This will return either an error message in the event of failure or the ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," details if it succeeds."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"$(get_path_to_client) get-deploy 8e6309cc37bc58d8fedc1094ee1bd264a636d39fc0e05b5e1d72d98f7b6faf13 -n http://localhost:11101\n")),(0,r.kt)("h2",{id:"interacting-with-the-installed-contract"},"Interacting with the Installed Contract"),(0,r.kt)("p",null,"Once your NCTL network executes your ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy"),", you can test the functionality of the installed contract. To do so, you will first need to identify any arguments to pass to the contract, starting with the ",(0,r.kt)("inlineCode",{parentName:"p"},"ContractHash")," itself. This hash identifies the contract and allows you to target the included entry points. As we used the pre-established node-1 account to ",(0,r.kt)("a",{parentName:"p",href:"/developers/cli/sending-deploys"},"send the ",(0,r.kt)("inlineCode",{parentName:"a"},"Deploy")),", we can retrieve the ",(0,r.kt)("inlineCode",{parentName:"p"},"ContractHash")," from the node-1 account information. To do so, we will use the following command with a node address and the ",(0,r.kt)("inlineCode",{parentName:"p"},"PublicKey")," of the node in question."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"$(get_path_to_client) get-account-info \\\n--node-address http://localhost:11101 \\\n--public-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/public_key.pem\n")),(0,r.kt)("p",null,"This command will return information pertaining to the account, including the ",(0,r.kt)("inlineCode",{parentName:"p"},"NamedKeys"),". The ",(0,r.kt)("inlineCode",{parentName:"p"},"ContractHash")," of the contract to be tested will appear here. The process of calling the contract is similar to that of installing it, as they are both accomplished through sending a ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy"),". In this instance, you will need the following information:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"The ",(0,r.kt)("strong",{parentName:"p"},"node address"),", entered in this instance using ",(0,r.kt)("inlineCode",{parentName:"p"},"--node-address http://localhost:11101"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"The ",(0,r.kt)("strong",{parentName:"p"},"chain name"),", entered in this instance using ",(0,r.kt)("inlineCode",{parentName:"p"},'--chain-name "casper-net-1"'))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"The ",(0,r.kt)("strong",{parentName:"p"},"payment amount")," for this ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," in motes, which may need to be adjusted depending on cost and network ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),". In this instance, we will use ",(0,r.kt)("inlineCode",{parentName:"p"},"--payment-amount 500000000"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"The ",(0,r.kt)("strong",{parentName:"p"},"session path"),", defining the location of the Wasm bearing file for the ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy"),". It appears in our example as ",(0,r.kt)("inlineCode",{parentName:"p"},"--session-path ")," but you must define the path to your specific file.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"Any ",(0,r.kt)("strong",{parentName:"p"},"session arguments")," specific to the contract that you are testing. Multiple instances of ",(0,r.kt)("inlineCode",{parentName:"p"},"--session-arg")," may be used as necessary to provide values to the contract, including the ",(0,r.kt)("inlineCode",{parentName:"p"},"ContractHash")," you acquired above. In the example below, you will see a demonstration of the ",(0,r.kt)("inlineCode",{parentName:"p"},"ContractHash")," as a session argument as ",(0,r.kt)("inlineCode",{parentName:"p"},"--session-arg \"contract_key:key='hash-8c13aaeef50ae7f447ee21276965c31cfa45c4ea3abb03d35d078cdd6a40e4a'\"")))),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'$(get_path_to_client) put-deploy \\\n--node-address http://localhost:11101 \\\n--chain-name "casper-net-1" \\\n--payment-amount 500000000 \\\n--session-path \\\n--session-arg "contract_key:key=\'hash-8c13aaeef50ae7f447ee21276965c31cfa45c4ea3abb03d35d078cdd6a40e4a\'"\n')),(0,r.kt)("h2",{id:"verifying-correct-contract-behavior"},"Verifying Correct Contract Behavior"),(0,r.kt)("p",null,"After calling your installed contract, you can verify that the contract behaved as expected by observing the associated change in ",(0,r.kt)("a",{parentName:"p",href:"/developers/cli/installing-contracts#querying-global-state"},"global state"),". Depending on how your contract functions, this can have different meanings and results. If we use our donation contract from the ",(0,r.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/simple-contract"},"basic smart contract tutorial"),", the NCTL process would have the following flow:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},"Send a ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy"),' to install the "Donation" smart contract.')),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},"Verify the execution of the ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy"),".")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},"Interact with the installed contract using an additional ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," that calls one or several of the entry points. For example, calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"donate")," entry point to donate an amount to the fundraising purse.")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},"Verify the associated change in global state. Namely, an increase in the balance of the fundraising purse."))))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[9065],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return m}});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=a.createContext({}),l=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(p.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),h=o,m=d["".concat(p,".").concat(h)]||d[h]||u[h]||r;return n?a.createElement(m,i(i({ref:t},c),{},{components:n})):a.createElement(m,i({ref:t},c))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=h;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var l=2;l")," and will require you to define the path to your specific ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," Wasm.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"The ",(0,r.kt)("strong",{parentName:"p"},"node address")," for a node on your NCTL network. In this example, we are using the node at ",(0,r.kt)("inlineCode",{parentName:"p"},"http://localhost:11101"),". On the Casper Mainnet or Testnet, nodes will use port ",(0,r.kt)("inlineCode",{parentName:"p"},"7777"),". This will appear in our example put-deploy as ",(0,r.kt)("inlineCode",{parentName:"p"},"--node-address http://:7777"),"."))),(0,r.kt)("p",null,"The command to send your ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," should look similar to the following code snippet:"),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Use of the ",(0,r.kt)("inlineCode",{parentName:"p"},"$(get_path_to_client)")," command assumes that you are operating in an activated NCTL envrionment.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'$(get_path_to_client) put-deploy \\\n--chain-name "casper-net-1" \\\n--secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-path \\\n--node-address http://localhost:11101\n')),(0,r.kt)("p",null,"The response will return something similar to the following information. Note the ",(0,r.kt)("inlineCode",{parentName:"p"},"deploy_hash"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'{\n "id": 4824893960188648146,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "deploy_hash": "8e6309cc37bc58d8fedc1094ee1bd264a636d39fc0e05b5e1d72d98f7b6faf13"\n }\n}\n')),(0,r.kt)("h2",{id:"verifying-deploy-execution"},"Verifying Deploy Execution"),(0,r.kt)("p",null,"The previous command sent the ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," to the NCTL network, but we recommend verifying deploy execution before continuing. The ",(0,r.kt)("inlineCode",{parentName:"p"},"deploy_hash")," received in the response allows you to query the ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy"),"'s status."),(0,r.kt)("p",null,"To query the ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy"),"'s status, you will pass both the ",(0,r.kt)("inlineCode",{parentName:"p"},"deploy_hash")," and the same ",(0,r.kt)("inlineCode",{parentName:"p"},"node-address")," from above using the following command. This will return either an error message in the event of failure or the ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," details if it succeeds."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"$(get_path_to_client) get-deploy 8e6309cc37bc58d8fedc1094ee1bd264a636d39fc0e05b5e1d72d98f7b6faf13 -n http://localhost:11101\n")),(0,r.kt)("h2",{id:"interacting-with-the-installed-contract"},"Interacting with the Installed Contract"),(0,r.kt)("p",null,"Once your NCTL network executes your ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy"),", you can test the functionality of the installed contract. To do so, you will first need to identify any arguments to pass to the contract, starting with the ",(0,r.kt)("inlineCode",{parentName:"p"},"ContractHash")," itself. This hash identifies the contract and allows you to target the included entry points. As we used the pre-established node-1 account to ",(0,r.kt)("a",{parentName:"p",href:"/developers/cli/sending-deploys"},"send the ",(0,r.kt)("inlineCode",{parentName:"a"},"Deploy")),", we can retrieve the ",(0,r.kt)("inlineCode",{parentName:"p"},"ContractHash")," from the node-1 account information. To do so, we will use the following command with a node address and the ",(0,r.kt)("inlineCode",{parentName:"p"},"PublicKey")," of the node in question."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"$(get_path_to_client) get-account-info \\\n--node-address http://localhost:11101 \\\n--public-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/public_key.pem\n")),(0,r.kt)("p",null,"This command will return information pertaining to the account, including the ",(0,r.kt)("inlineCode",{parentName:"p"},"NamedKeys"),". The ",(0,r.kt)("inlineCode",{parentName:"p"},"ContractHash")," of the contract to be tested will appear here. The process of calling the contract is similar to that of installing it, as they are both accomplished through sending a ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy"),". In this instance, you will need the following information:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"The ",(0,r.kt)("strong",{parentName:"p"},"node address"),", entered in this instance using ",(0,r.kt)("inlineCode",{parentName:"p"},"--node-address http://localhost:11101"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"The ",(0,r.kt)("strong",{parentName:"p"},"chain name"),", entered in this instance using ",(0,r.kt)("inlineCode",{parentName:"p"},'--chain-name "casper-net-1"'))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"The ",(0,r.kt)("strong",{parentName:"p"},"payment amount")," for this ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," in motes, which may need to be adjusted depending on cost and network ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),". In this instance, we will use ",(0,r.kt)("inlineCode",{parentName:"p"},"--payment-amount 500000000"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"The ",(0,r.kt)("strong",{parentName:"p"},"session path"),", defining the location of the Wasm bearing file for the ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy"),". It appears in our example as ",(0,r.kt)("inlineCode",{parentName:"p"},"--session-path ")," but you must define the path to your specific file.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"Any ",(0,r.kt)("strong",{parentName:"p"},"session arguments")," specific to the contract that you are testing. Multiple instances of ",(0,r.kt)("inlineCode",{parentName:"p"},"--session-arg")," may be used as necessary to provide values to the contract, including the ",(0,r.kt)("inlineCode",{parentName:"p"},"ContractHash")," you acquired above. In the example below, you will see a demonstration of the ",(0,r.kt)("inlineCode",{parentName:"p"},"ContractHash")," as a session argument as ",(0,r.kt)("inlineCode",{parentName:"p"},"--session-arg \"contract_key:key='hash-8c13aaeef50ae7f447ee21276965c31cfa45c4ea3abb03d35d078cdd6a40e4a'\"")))),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'$(get_path_to_client) put-deploy \\\n--node-address http://localhost:11101 \\\n--chain-name "casper-net-1" \\\n--payment-amount 500000000 \\\n--session-path \\\n--session-arg "contract_key:key=\'hash-8c13aaeef50ae7f447ee21276965c31cfa45c4ea3abb03d35d078cdd6a40e4a\'"\n')),(0,r.kt)("h2",{id:"verifying-correct-contract-behavior"},"Verifying Correct Contract Behavior"),(0,r.kt)("p",null,"After calling your installed contract, you can verify that the contract behaved as expected by observing the associated change in ",(0,r.kt)("a",{parentName:"p",href:"/developers/cli/installing-contracts#querying-global-state"},"global state"),". Depending on how your contract functions, this can have different meanings and results. If we use our donation contract from the ",(0,r.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/simple-contract"},"basic smart contract tutorial"),", the NCTL process would have the following flow:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},"Send a ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy"),' to install the "Donation" smart contract.')),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},"Verify the execution of the ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy"),".")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},"Interact with the installed contract using an additional ",(0,r.kt)("inlineCode",{parentName:"p"},"Deploy")," that calls one or several of the entry points. For example, calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"donate")," entry point to donate an amount to the fundraising purse.")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},"Verify the associated change in global state. Namely, an increase in the balance of the fundraising purse."))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9755a710.b1d3d828.js b/assets/js/9755a710.34aa371c.js similarity index 98% rename from assets/js/9755a710.b1d3d828.js rename to assets/js/9755a710.34aa371c.js index ef05b6206f..fba3426ef7 100644 --- a/assets/js/9755a710.b1d3d828.js +++ b/assets/js/9755a710.34aa371c.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[8996],{3905:function(e,t,r){r.d(t,{Zo:function(){return l},kt:function(){return f}});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),s=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l=function(e){var t=s(e.components);return n.createElement(u.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},g=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),p=s(r),g=o,f=p["".concat(u,".").concat(g)]||p[g]||d[g]||i;return r?n.createElement(f,a(a({ref:t},l),{},{components:r})):n.createElement(f,a({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=g;var c={};for(var u in t)hasOwnProperty.call(t,u)&&(c[u]=t[u]);c.originalType=e,c[p]="string"==typeof e?e:o,a[1]=c;for(var s=2;s=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),s=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l=function(e){var t=s(e.components);return n.createElement(u.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},g=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),p=s(r),g=o,f=p["".concat(u,".").concat(g)]||p[g]||d[g]||i;return r?n.createElement(f,a(a({ref:t},l),{},{components:r})):n.createElement(f,a({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=g;var c={};for(var u in t)hasOwnProperty.call(t,u)&&(c[u]=t[u]);c.originalType=e,c[p]="string"==typeof e?e:o,a[1]=c;for(var s=2;s=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var i=a.createContext({}),l=function(e){var n=a.useContext(i),t=n;return e&&(t="function"==typeof e?e(n):c(c({},n),e)),t},p=function(e){var n=l(e.components);return a.createElement(i.Provider,{value:n},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},h=a.forwardRef((function(e,n){var t=e.components,o=e.mdxType,s=e.originalType,i=e.parentName,p=r(e,["components","mdxType","originalType","parentName"]),u=l(t),h=o,m=u["".concat(i,".").concat(h)]||u[h]||d[h]||s;return t?a.createElement(m,c(c({ref:n},p),{},{components:t})):a.createElement(m,c({ref:n},p))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var s=t.length,c=new Array(s);c[0]=h;var r={};for(var i in n)hasOwnProperty.call(n,i)&&(r[i]=n[i]);r.originalType=e,r[u]="string"==typeof e?e:o,c[1]=r;for(var l=2;lcheck_balance_of Entry Point",id:"invoking-the-check_balance_of-entry-point",level:3},{value:"Approving an Allowance for Another Account",id:"approving-an-allowance-for-another-account",level:2},{value:"Approving an Account to Spend Tokens on Another Account's Behalf",id:"approving-an-account-to-spend-tokens-on-another-accounts-behalf",level:3},{value:"Verifying a Previously Issued Allowance",id:"verifying-a-previously-issued-allowance",level:3},{value:"Transferring Tokens from an Allowance",id:"transferring-tokens-from-an-allowance",level:3},{value:"Increasing and Decreasing an Allowance",id:"increasing-and-decreasing-an-allowance",level:3},{value:"Increasing an Allowance",id:"increasing-an-allowance",level:4},{value:"Decreasing an Allowance",id:"decreasing-an-allowance",level:4},{value:"Minting and Burning Additional CEP-18 Tokens",id:"minting-and-burning-additional-cep-18-tokens",level:3},{value:"Minting Additional Tokens",id:"minting-additional-tokens",level:4},{value:"Burning Tokens",id:"burning-tokens",level:4},{value:"Changing Account Security Permissions",id:"changing-account-security-permissions",level:3},{value:"Next Steps",id:"next-steps",level:3}],d={toc:u},h="wrapper";function m(e){var n=e.components,t=(0,o.Z)(e,c);return(0,s.kt)(h,(0,a.Z)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"cep-18-token-transfers-and-allowances"},"CEP-18 Token Transfers and Allowances"),(0,s.kt)("p",null,"This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The ",(0,s.kt)("a",{parentName:"p",href:"/resources/tokens/cep18/query"},"Exploring the CEP18 Contracts")," documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document."),(0,s.kt)("h2",{id:"transferring-cep-18-tokens-to-another-account"},"Transferring CEP-18 Tokens to Another Account"),(0,s.kt)("p",null,"The following command will invoke the ",(0,s.kt)("inlineCode",{parentName:"p"},"transfer")," entry point on your instance of CEP-18, directing it to transfer 10 of the associated CEP-18 tokens to another account."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-json"},'casper-client put-deploy -n http://: \\\n// The chain name of the Casper network on which your CEP-18 instance was installed.\n--chain-name \\\n// The local path to your account\'s secret key.\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// The contract hash of your CEP-18 contract instance.\n--session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \\\n// The name of the entry point you are invoking.\n--session-entry-point "transfer" \\\n// The account hash of the account that you are sending CEP-18 tokens to.\n--session-arg "recipient:key=\'account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \\\n// The amount of CEP-18 tokens you are sending to the receiving account.\n--session-arg "amount:u256=\'10\'" \\\n// The gas payment you are allotting, in motes.\n--payment-amount "10000000000"\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \\\n--session-entry-point "transfer" \\\n--session-arg "recipient:key=\'account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \\\n--session-arg "amount:u256=\'50\'" \\\n--payment-amount "10000000000"\n'))),(0,s.kt)("p",null,"This command will return a deploy hash that you can query using ",(0,s.kt)("inlineCode",{parentName:"p"},"casper-client get-deploy"),". Querying the Deploy allows you to verify execution success, but you will need to use the ",(0,s.kt)("inlineCode",{parentName:"p"},"check_balance_of")," entry point on the utility contract to verify the account's balance."),(0,s.kt)("h3",{id:"invoking-the-check_balance_of-entry-point"},"Invoking the ",(0,s.kt)("inlineCode",{parentName:"h3"},"check_balance_of")," Entry Point"),(0,s.kt)("p",null,"The following Casper client command invokes the ",(0,s.kt)("inlineCode",{parentName:"p"},"check_balance_of")," entry point on the ",(0,s.kt)("inlineCode",{parentName:"p"},"cep18_test_contract"),"."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-json"},'casper-client put-deploy -n http://:\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_balance_of" \\\n// This is the contract hash of your CEP-18 contract instance, passed in as an `account-hash-`.\n--session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n// This is the account hash of the account you are checking the balance of.\n--session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \\\n--chain-name \\\n--payment-amount 1000000000\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://:\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_balance_of" \\\n--session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n--session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'))),(0,s.kt)("p",null,"After sending this command, you will need to query the ",(0,s.kt)("inlineCode",{parentName:"p"},"results")," URef within the ",(0,s.kt)("inlineCode",{parentName:"p"},"NamedKeys")," of your ",(0,s.kt)("inlineCode",{parentName:"p"},"cep18_test_contract")," utility contract instance. More information on finding this URef can be found in the ",(0,s.kt)("a",{parentName:"p",href:"/resources/tokens/cep18/query#querying-the-utility-contract"},"Exploring the CEP18 Contracts")," document."),(0,s.kt)("p",null,"You can use the following command to query global state for the ",(0,s.kt)("inlineCode",{parentName:"p"},"results")," URef."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-json"},"casper-client query-global-state -n http://: \\\n// This is the `results` URef location from your `cep18_test_contract` `NamedKeys`\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7\n")),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state -n http://: \\\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7\n"))),(0,s.kt)("p",null,"This command should show something similar to the following in response, with ",(0,s.kt)("inlineCode",{parentName:"p"},"parsed")," being the amount of CEP-18 tokens that the account holds."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -8841145064950441692,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3796 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "010a",\n "cl_type": "U256",\n "parsed": "10"\n }\n }\n }\n}\n')),(0,s.kt)("h2",{id:"approving-an-allowance-for-another-account"},"Approving an Allowance for Another Account"),(0,s.kt)("p",null,"The Casper fungible token contract features an ",(0,s.kt)("inlineCode",{parentName:"p"},"allowance")," entry point that allows an account to delegate another account to spend a preset number of CEP-18 tokens from their balance."),(0,s.kt)("h3",{id:"approving-an-account-to-spend-tokens-on-another-accounts-behalf"},"Approving an Account to Spend Tokens on Another Account's Behalf"),(0,s.kt)("p",null,"The following command approves a third-party account to spend an ",(0,s.kt)("inlineCode",{parentName:"p"},"allowance")," of 15 CEP-18 tokens from the balance of the account that sent the CEP-18 instance."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-json"},'casper-client put-deploy -n http://:\\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// This is the contract hash of the CEP-18 token contract.\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "approve" \\\n// This is the account hash of the account that will receive an allowance from the balance of the account that sent the Deploy.\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n// This is the number of CEP-18 tokens included in the allowance.\n--session-arg "amount:u256=\'15\'" \\\n--payment-amount "10000000000"\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://:\\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "approve" \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "amount:u256=\'15\'" \\\n--payment-amount "10000000000"\n'))),(0,s.kt)("h3",{id:"verifying-a-previously-issued-allowance"},"Verifying a Previously Issued Allowance"),(0,s.kt)("p",null,"After approving an account to spend an ",(0,s.kt)("inlineCode",{parentName:"p"},"allowance")," of tokens, we can verify the allotted allowance by using the utility contract. The following command will write the ",(0,s.kt)("inlineCode",{parentName:"p"},"allowance")," of the spender's account to the ",(0,s.kt)("inlineCode",{parentName:"p"},"result")," URef of in the utility contract's ",(0,s.kt)("inlineCode",{parentName:"p"},"NamedKeys"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-json"},'casper-client put-deploy -n http://:\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_allowance_of" \\\n// This is the contract hash for the CEP-18 token.\n--session-arg "token_contract:account_hash=\'account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e\'" \\\n// This is the account hash for the account that owns the CEP-18 tokens.\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n// This is the account hash for the account previously authorized to spend an allowance of the owning account\'s CEP-18 tokens.\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--chain-name \\\n--payment-amount 10000000000\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://:\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_allowance_of" \\\n--session-arg "token_contract:account_hash=\'account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e\'" \\\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--chain-name \\\n--payment-amount 10000000000\n'))),(0,s.kt)("p",null,"The following command queries global state to return the value stored under the ",(0,s.kt)("inlineCode",{parentName:"p"},"result")," URef:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-json"},"casper-client query-global-state -n http://: \\\n// This is the previously identified `result` URef from the utility contract's `NamedKeys`\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1\n")),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state -n http://: \\\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1\n"))),(0,s.kt)("p",null,"You should get a response similar to the following:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -9142472925449984061,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3796 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "010f",\n "cl_type": "U256",\n "parsed": "15"\n }\n }\n }\n}\n')),(0,s.kt)("h3",{id:"transferring-tokens-from-an-allowance"},"Transferring Tokens from an Allowance"),(0,s.kt)("p",null,"The following command allows an account to transfer CEP-18 tokens held by another account up to their approved ",(0,s.kt)("inlineCode",{parentName:"p"},"allowance"),"."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-json"},'casper-client put-deploy -n http://: \\\n--chain-name \\\n// This is the secret key for the account that is spending their `allowance` from another account\'s balance.\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// This is the CEP-18 token contract.\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "transfer_from" \\\n// This is the account hash of the account that holds the CEP-18 in their balance.\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n// This is the account hash of the account that will receive the transferred CEP-18 tokens.\n--session-arg "recipient:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n// This is the amount of tokens to be transferred. If this amount exceeds the `allowance` of the account sending the Deploy, it will fail.\n--session-arg "amount:u256=\'10\'" \\\n--payment-amount "10000000000"\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "transfer_from" \\\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n--session-arg "recipient:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "amount:u256=\'10\'" \\\n--payment-amount "10000000000"\n'))),(0,s.kt)("h3",{id:"increasing-and-decreasing-an-allowance"},"Increasing and Decreasing an Allowance"),(0,s.kt)("h4",{id:"increasing-an-allowance"},"Increasing an Allowance"),(0,s.kt)("p",null,"The following command increases the designated ",(0,s.kt)("inlineCode",{parentName:"p"},"allowance")," for the provided account."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "increase_allowance" \\\n// This is the account hash of the previously authorized allowance account.\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the additional number of CEP-18 tokens that the authorized account may spend.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "increase_allowance" \\\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'))),(0,s.kt)("h4",{id:"decreasing-an-allowance"},"Decreasing an Allowance"),(0,s.kt)("p",null,"The following command decreases the designated allowance for the provided account."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "decrease_allowance" \\\n// This is the account hash of the previously authorized allowance account.\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the additional number of CEP-18 tokens that the authorized account may spend.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "decrease_allowance" \\\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'))),(0,s.kt)("h3",{id:"minting-and-burning-additional-cep-18-tokens"},"Minting and Burning Additional CEP-18 Tokens"),(0,s.kt)("h4",{id:"minting-additional-tokens"},"Minting Additional Tokens"),(0,s.kt)("p",null,"If the contract allows for minting, the following command will mint a number of CEP-18 tokens directly to the provided account. This increases the total supply of the token in question."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "mint" \\\n// This is the account that will receive the newly minted CEP-18 tokens.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of additional CEP-18 tokens to add to the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "mint" \\\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'))),(0,s.kt)("h4",{id:"burning-tokens"},"Burning Tokens"),(0,s.kt)("p",null,"If the contract allows for burning, the following command will burn a number of CEP-18 tokens directly from the provided account. This decreases the total supply of the token in question."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "burn" \\\n// This is the account that the tokens will be burned from.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of CEP-18 tokens to remove from the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "burn" \\\n// This is the account that the tokens will be burned from.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of CEP-18 tokens to remove from the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'))),(0,s.kt)("h3",{id:"changing-account-security-permissions"},"Changing Account Security Permissions"),(0,s.kt)("p",null,"The ",(0,s.kt)("inlineCode",{parentName:"p"},"change_security")," entrypoint can be used by an account with ",(0,s.kt)("inlineCode",{parentName:"p"},"admin")," access to alter the security level of other accounts."),(0,s.kt)("p",null,"There are five security levels, with the strongest level taking precedence over any other assigned levels. In order of highest strength to lowest:"),(0,s.kt)("ol",null,(0,s.kt)("li",{parentName:"ol"},(0,s.kt)("p",{parentName:"li"},(0,s.kt)("inlineCode",{parentName:"p"},"None")," - ",(0,s.kt)("inlineCode",{parentName:"p"},"None")," overrides other security levels and removes all admin, minting and burning access of an account.")),(0,s.kt)("li",{parentName:"ol"},(0,s.kt)("p",{parentName:"li"},(0,s.kt)("inlineCode",{parentName:"p"},"Admin")," - Allows the account full access and control over the CEP-18 contract.")),(0,s.kt)("li",{parentName:"ol"},(0,s.kt)("p",{parentName:"li"},(0,s.kt)("inlineCode",{parentName:"p"},"MintAndBurn")," - Allows the account to mint new tokens and burn existing tokens.")),(0,s.kt)("li",{parentName:"ol"},(0,s.kt)("p",{parentName:"li"},(0,s.kt)("inlineCode",{parentName:"p"},"Burner")," - The account can burn tokens.")),(0,s.kt)("li",{parentName:"ol"},(0,s.kt)("p",{parentName:"li"},(0,s.kt)("inlineCode",{parentName:"p"},"Minter")," - The account can mint new tokens."))),(0,s.kt)("p",null,"Here is an example of a ",(0,s.kt)("inlineCode",{parentName:"p"},"session-arg")," that provides a list of account hashes to be included on the ",(0,s.kt)("inlineCode",{parentName:"p"},"mint_and_burn_list"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"--session-arg \"mint_and_burn_list:string='account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7,account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34,account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655'\"\n")),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Be aware that removing all admin accounts will lock out all admin functionality.")),(0,s.kt)("p",null,"The following command can be supplied with any of the optional arguments above:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "change_security" \\\n/// The following arguments are all optional and each consists of a string of the account hashes to be added to the list specified, separated by commas.\n--session-arg "none_list:string:\'\'" \\\n--session-arg "admin_list:string:\'\'" \\\n--session-arg "mint_and_burn_list:string:\'\'" \\\n--session-arg "burner_list:string:\'\'" \\\n--chain-name \\\n--payment-amount 1000000000\n')),(0,s.kt)("h3",{id:"next-steps"},"Next Steps"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("a",{parentName:"li",href:"/resources/tokens/cep18/tests"},"Testing Framework for CEP-18"))))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5477],{3905:function(e,n,t){t.d(n,{Zo:function(){return p},kt:function(){return m}});var a=t(7294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function s(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function c(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var i=a.createContext({}),l=function(e){var n=a.useContext(i),t=n;return e&&(t="function"==typeof e?e(n):c(c({},n),e)),t},p=function(e){var n=l(e.components);return a.createElement(i.Provider,{value:n},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},h=a.forwardRef((function(e,n){var t=e.components,o=e.mdxType,s=e.originalType,i=e.parentName,p=r(e,["components","mdxType","originalType","parentName"]),u=l(t),h=o,m=u["".concat(i,".").concat(h)]||u[h]||d[h]||s;return t?a.createElement(m,c(c({ref:n},p),{},{components:t})):a.createElement(m,c({ref:n},p))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var s=t.length,c=new Array(s);c[0]=h;var r={};for(var i in n)hasOwnProperty.call(n,i)&&(r[i]=n[i]);r.originalType=e,r[u]="string"==typeof e?e:o,c[1]=r;for(var l=2;lcheck_balance_of Entry Point",id:"invoking-the-check_balance_of-entry-point",level:3},{value:"Approving an Allowance for Another Account",id:"approving-an-allowance-for-another-account",level:2},{value:"Approving an Account to Spend Tokens on Another Account's Behalf",id:"approving-an-account-to-spend-tokens-on-another-accounts-behalf",level:3},{value:"Verifying a Previously Issued Allowance",id:"verifying-a-previously-issued-allowance",level:3},{value:"Transferring Tokens from an Allowance",id:"transferring-tokens-from-an-allowance",level:3},{value:"Increasing and Decreasing an Allowance",id:"increasing-and-decreasing-an-allowance",level:3},{value:"Increasing an Allowance",id:"increasing-an-allowance",level:4},{value:"Decreasing an Allowance",id:"decreasing-an-allowance",level:4},{value:"Minting and Burning Additional CEP-18 Tokens",id:"minting-and-burning-additional-cep-18-tokens",level:3},{value:"Minting Additional Tokens",id:"minting-additional-tokens",level:4},{value:"Burning Tokens",id:"burning-tokens",level:4},{value:"Changing Account Security Permissions",id:"changing-account-security-permissions",level:3},{value:"Next Steps",id:"next-steps",level:3}],d={toc:u},h="wrapper";function m(e){var n=e.components,t=(0,o.Z)(e,c);return(0,s.kt)(h,(0,a.Z)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"cep-18-token-transfers-and-allowances"},"CEP-18 Token Transfers and Allowances"),(0,s.kt)("p",null,"This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The ",(0,s.kt)("a",{parentName:"p",href:"/resources/tokens/cep18/query"},"Exploring the CEP18 Contracts")," documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document."),(0,s.kt)("h2",{id:"transferring-cep-18-tokens-to-another-account"},"Transferring CEP-18 Tokens to Another Account"),(0,s.kt)("p",null,"The following command will invoke the ",(0,s.kt)("inlineCode",{parentName:"p"},"transfer")," entry point on your instance of CEP-18, directing it to transfer 10 of the associated CEP-18 tokens to another account."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-json"},'casper-client put-deploy -n http://: \\\n// The chain name of the Casper network on which your CEP-18 instance was installed.\n--chain-name \\\n// The local path to your account\'s secret key.\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// The contract hash of your CEP-18 contract instance.\n--session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \\\n// The name of the entry point you are invoking.\n--session-entry-point "transfer" \\\n// The account hash of the account that you are sending CEP-18 tokens to.\n--session-arg "recipient:key=\'account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \\\n// The amount of CEP-18 tokens you are sending to the receiving account.\n--session-arg "amount:u256=\'10\'" \\\n// The gas payment you are allotting, in motes.\n--payment-amount "10000000000"\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \\\n--session-entry-point "transfer" \\\n--session-arg "recipient:key=\'account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \\\n--session-arg "amount:u256=\'50\'" \\\n--payment-amount "10000000000"\n'))),(0,s.kt)("p",null,"This command will return a deploy hash that you can query using ",(0,s.kt)("inlineCode",{parentName:"p"},"casper-client get-deploy"),". Querying the Deploy allows you to verify execution success, but you will need to use the ",(0,s.kt)("inlineCode",{parentName:"p"},"check_balance_of")," entry point on the utility contract to verify the account's balance."),(0,s.kt)("h3",{id:"invoking-the-check_balance_of-entry-point"},"Invoking the ",(0,s.kt)("inlineCode",{parentName:"h3"},"check_balance_of")," Entry Point"),(0,s.kt)("p",null,"The following Casper client command invokes the ",(0,s.kt)("inlineCode",{parentName:"p"},"check_balance_of")," entry point on the ",(0,s.kt)("inlineCode",{parentName:"p"},"cep18_test_contract"),"."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-json"},'casper-client put-deploy -n http://:\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_balance_of" \\\n// This is the contract hash of your CEP-18 contract instance, passed in as an `account-hash-`.\n--session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n// This is the account hash of the account you are checking the balance of.\n--session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \\\n--chain-name \\\n--payment-amount 1000000000\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://:\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_balance_of" \\\n--session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n--session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'))),(0,s.kt)("p",null,"After sending this command, you will need to query the ",(0,s.kt)("inlineCode",{parentName:"p"},"results")," URef within the ",(0,s.kt)("inlineCode",{parentName:"p"},"NamedKeys")," of your ",(0,s.kt)("inlineCode",{parentName:"p"},"cep18_test_contract")," utility contract instance. More information on finding this URef can be found in the ",(0,s.kt)("a",{parentName:"p",href:"/resources/tokens/cep18/query#querying-the-utility-contract"},"Exploring the CEP18 Contracts")," document."),(0,s.kt)("p",null,"You can use the following command to query global state for the ",(0,s.kt)("inlineCode",{parentName:"p"},"results")," URef."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-json"},"casper-client query-global-state -n http://: \\\n// This is the `results` URef location from your `cep18_test_contract` `NamedKeys`\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7\n")),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state -n http://: \\\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7\n"))),(0,s.kt)("p",null,"This command should show something similar to the following in response, with ",(0,s.kt)("inlineCode",{parentName:"p"},"parsed")," being the amount of CEP-18 tokens that the account holds."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -8841145064950441692,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3796 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "010a",\n "cl_type": "U256",\n "parsed": "10"\n }\n }\n }\n}\n')),(0,s.kt)("h2",{id:"approving-an-allowance-for-another-account"},"Approving an Allowance for Another Account"),(0,s.kt)("p",null,"The Casper fungible token contract features an ",(0,s.kt)("inlineCode",{parentName:"p"},"allowance")," entry point that allows an account to delegate another account to spend a preset number of CEP-18 tokens from their balance."),(0,s.kt)("h3",{id:"approving-an-account-to-spend-tokens-on-another-accounts-behalf"},"Approving an Account to Spend Tokens on Another Account's Behalf"),(0,s.kt)("p",null,"The following command approves a third-party account to spend an ",(0,s.kt)("inlineCode",{parentName:"p"},"allowance")," of 15 CEP-18 tokens from the balance of the account that sent the CEP-18 instance."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-json"},'casper-client put-deploy -n http://:\\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// This is the contract hash of the CEP-18 token contract.\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "approve" \\\n// This is the account hash of the account that will receive an allowance from the balance of the account that sent the Deploy.\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n// This is the number of CEP-18 tokens included in the allowance.\n--session-arg "amount:u256=\'15\'" \\\n--payment-amount "10000000000"\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://:\\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "approve" \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "amount:u256=\'15\'" \\\n--payment-amount "10000000000"\n'))),(0,s.kt)("h3",{id:"verifying-a-previously-issued-allowance"},"Verifying a Previously Issued Allowance"),(0,s.kt)("p",null,"After approving an account to spend an ",(0,s.kt)("inlineCode",{parentName:"p"},"allowance")," of tokens, we can verify the allotted allowance by using the utility contract. The following command will write the ",(0,s.kt)("inlineCode",{parentName:"p"},"allowance")," of the spender's account to the ",(0,s.kt)("inlineCode",{parentName:"p"},"result")," URef of in the utility contract's ",(0,s.kt)("inlineCode",{parentName:"p"},"NamedKeys"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-json"},'casper-client put-deploy -n http://:\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_allowance_of" \\\n// This is the contract hash for the CEP-18 token.\n--session-arg "token_contract:account_hash=\'account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e\'" \\\n// This is the account hash for the account that owns the CEP-18 tokens.\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n// This is the account hash for the account previously authorized to spend an allowance of the owning account\'s CEP-18 tokens.\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--chain-name \\\n--payment-amount 10000000000\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://:\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_allowance_of" \\\n--session-arg "token_contract:account_hash=\'account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e\'" \\\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--chain-name \\\n--payment-amount 10000000000\n'))),(0,s.kt)("p",null,"The following command queries global state to return the value stored under the ",(0,s.kt)("inlineCode",{parentName:"p"},"result")," URef:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-json"},"casper-client query-global-state -n http://: \\\n// This is the previously identified `result` URef from the utility contract's `NamedKeys`\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1\n")),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state -n http://: \\\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1\n"))),(0,s.kt)("p",null,"You should get a response similar to the following:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -9142472925449984061,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3796 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "010f",\n "cl_type": "U256",\n "parsed": "15"\n }\n }\n }\n}\n')),(0,s.kt)("h3",{id:"transferring-tokens-from-an-allowance"},"Transferring Tokens from an Allowance"),(0,s.kt)("p",null,"The following command allows an account to transfer CEP-18 tokens held by another account up to their approved ",(0,s.kt)("inlineCode",{parentName:"p"},"allowance"),"."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-json"},'casper-client put-deploy -n http://: \\\n--chain-name \\\n// This is the secret key for the account that is spending their `allowance` from another account\'s balance.\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// This is the CEP-18 token contract.\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "transfer_from" \\\n// This is the account hash of the account that holds the CEP-18 in their balance.\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n// This is the account hash of the account that will receive the transferred CEP-18 tokens.\n--session-arg "recipient:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n// This is the amount of tokens to be transferred. If this amount exceeds the `allowance` of the account sending the Deploy, it will fail.\n--session-arg "amount:u256=\'10\'" \\\n--payment-amount "10000000000"\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "transfer_from" \\\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n--session-arg "recipient:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "amount:u256=\'10\'" \\\n--payment-amount "10000000000"\n'))),(0,s.kt)("h3",{id:"increasing-and-decreasing-an-allowance"},"Increasing and Decreasing an Allowance"),(0,s.kt)("h4",{id:"increasing-an-allowance"},"Increasing an Allowance"),(0,s.kt)("p",null,"The following command increases the designated ",(0,s.kt)("inlineCode",{parentName:"p"},"allowance")," for the provided account."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "increase_allowance" \\\n// This is the account hash of the previously authorized allowance account.\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the additional number of CEP-18 tokens that the authorized account may spend.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "increase_allowance" \\\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'))),(0,s.kt)("h4",{id:"decreasing-an-allowance"},"Decreasing an Allowance"),(0,s.kt)("p",null,"The following command decreases the designated allowance for the provided account."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "decrease_allowance" \\\n// This is the account hash of the previously authorized allowance account.\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the additional number of CEP-18 tokens that the authorized account may spend.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "decrease_allowance" \\\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'))),(0,s.kt)("h3",{id:"minting-and-burning-additional-cep-18-tokens"},"Minting and Burning Additional CEP-18 Tokens"),(0,s.kt)("h4",{id:"minting-additional-tokens"},"Minting Additional Tokens"),(0,s.kt)("p",null,"If the contract allows for minting, the following command will mint a number of CEP-18 tokens directly to the provided account. This increases the total supply of the token in question."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "mint" \\\n// This is the account that will receive the newly minted CEP-18 tokens.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of additional CEP-18 tokens to add to the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "mint" \\\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'))),(0,s.kt)("h4",{id:"burning-tokens"},"Burning Tokens"),(0,s.kt)("p",null,"If the contract allows for burning, the following command will burn a number of CEP-18 tokens directly from the provided account. This decreases the total supply of the token in question."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "burn" \\\n// This is the account that the tokens will be burned from.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of CEP-18 tokens to remove from the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n')),(0,s.kt)("details",null,(0,s.kt)("summary",null,(0,s.kt)("b",null,"Casper client command without comments")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "burn" \\\n// This is the account that the tokens will be burned from.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of CEP-18 tokens to remove from the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'))),(0,s.kt)("h3",{id:"changing-account-security-permissions"},"Changing Account Security Permissions"),(0,s.kt)("p",null,"The ",(0,s.kt)("inlineCode",{parentName:"p"},"change_security")," entrypoint can be used by an account with ",(0,s.kt)("inlineCode",{parentName:"p"},"admin")," access to alter the security level of other accounts."),(0,s.kt)("p",null,"There are five security levels, with the strongest level taking precedence over any other assigned levels. In order of highest strength to lowest:"),(0,s.kt)("ol",null,(0,s.kt)("li",{parentName:"ol"},(0,s.kt)("p",{parentName:"li"},(0,s.kt)("inlineCode",{parentName:"p"},"None")," - ",(0,s.kt)("inlineCode",{parentName:"p"},"None")," overrides other security levels and removes all admin, minting and burning access of an account.")),(0,s.kt)("li",{parentName:"ol"},(0,s.kt)("p",{parentName:"li"},(0,s.kt)("inlineCode",{parentName:"p"},"Admin")," - Allows the account full access and control over the CEP-18 contract.")),(0,s.kt)("li",{parentName:"ol"},(0,s.kt)("p",{parentName:"li"},(0,s.kt)("inlineCode",{parentName:"p"},"MintAndBurn")," - Allows the account to mint new tokens and burn existing tokens.")),(0,s.kt)("li",{parentName:"ol"},(0,s.kt)("p",{parentName:"li"},(0,s.kt)("inlineCode",{parentName:"p"},"Burner")," - The account can burn tokens.")),(0,s.kt)("li",{parentName:"ol"},(0,s.kt)("p",{parentName:"li"},(0,s.kt)("inlineCode",{parentName:"p"},"Minter")," - The account can mint new tokens."))),(0,s.kt)("p",null,"Here is an example of a ",(0,s.kt)("inlineCode",{parentName:"p"},"session-arg")," that provides a list of account hashes to be included on the ",(0,s.kt)("inlineCode",{parentName:"p"},"mint_and_burn_list"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"--session-arg \"mint_and_burn_list:string='account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7,account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34,account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655'\"\n")),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Be aware that removing all admin accounts will lock out all admin functionality.")),(0,s.kt)("p",null,"The following command can be supplied with any of the optional arguments above:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "change_security" \\\n/// The following arguments are all optional and each consists of a string of the account hashes to be added to the list specified, separated by commas.\n--session-arg "none_list:string:\'\'" \\\n--session-arg "admin_list:string:\'\'" \\\n--session-arg "mint_and_burn_list:string:\'\'" \\\n--session-arg "burner_list:string:\'\'" \\\n--chain-name \\\n--payment-amount 1000000000\n')),(0,s.kt)("h3",{id:"next-steps"},"Next Steps"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("a",{parentName:"li",href:"/resources/tokens/cep18/tests"},"Testing Framework for CEP-18"))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/99756d1f.d2ce0dcd.js b/assets/js/99756d1f.49993a67.js similarity index 99% rename from assets/js/99756d1f.d2ce0dcd.js rename to assets/js/99756d1f.49993a67.js index 2c751ba0a9..5a3fa869ff 100644 --- a/assets/js/99756d1f.d2ce0dcd.js +++ b/assets/js/99756d1f.49993a67.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[8669],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return f}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),d=l(n),m=a,f=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?r.createElement(f,i(i({ref:t},c),{},{components:n})):r.createElement(f,i({ref:t},c))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=m;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[d]="string"==typeof e?e:a,i[1]=p;for(var l=2;l/rpc-schema\n")),(0,o.kt)("p",null,"To see an example, navigate to a node's RPC schema using a browser."),(0,o.kt)("p",null,"The Casper client subcommand ",(0,o.kt)("inlineCode",{parentName:"p"},"list-rpcs")," provides all currently supported RPCs. Here is an example of running the Casper client to list RPCs:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"casper-client list-rpcs --node-address \n")),(0,o.kt)("h2",{id:"table-of-contents"},"Table of Contents"),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Page"),(0,o.kt)("th",{parentName:"tr",align:null},"Description"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"/developers/json-rpc/guidance"},"Guidance for JSON-RPC SDK Compliance")),(0,o.kt)("td",{parentName:"tr",align:null},"Requirements for a compliant Casper SDK")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"/developers/json-rpc/minimal-compliance"},"Required JSON-RPC Methods for Minimal Compliance")),(0,o.kt)("td",{parentName:"tr",align:null},"Methods required for a minimally compliant Casper SDK")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"/developers/json-rpc/json-rpc-transactional"},"Transactional JSON-RPC Method")),(0,o.kt)("td",{parentName:"tr",align:null},"Methods allowing interaction with a Casper network")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"/developers/json-rpc/json-rpc-informational"},"Informational JSON-RPC Methods")),(0,o.kt)("td",{parentName:"tr",align:null},"Methods returning information about the network from a Casper node")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"/developers/json-rpc/json-rpc-pos"},"Proof-of-Stake JSON-RPC Methods")),(0,o.kt)("td",{parentName:"tr",align:null},"Methods pertaining to Proof-of-Stake functionality on a Casper network")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain"},"Types")),(0,o.kt)("td",{parentName:"tr",align:null},"Information on types used within JSON-RPC methods")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_cl"},"CL Types")),(0,o.kt)("td",{parentName:"tr",align:null},"Information related to CL Types")))))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[8669],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return f}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),d=l(n),m=a,f=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?r.createElement(f,i(i({ref:t},c),{},{components:n})):r.createElement(f,i({ref:t},c))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=m;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[d]="string"==typeof e?e:a,i[1]=p;for(var l=2;l/rpc-schema\n")),(0,o.kt)("p",null,"To see an example, navigate to a node's RPC schema using a browser."),(0,o.kt)("p",null,"The Casper client subcommand ",(0,o.kt)("inlineCode",{parentName:"p"},"list-rpcs")," provides all currently supported RPCs. Here is an example of running the Casper client to list RPCs:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"casper-client list-rpcs --node-address \n")),(0,o.kt)("h2",{id:"table-of-contents"},"Table of Contents"),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Page"),(0,o.kt)("th",{parentName:"tr",align:null},"Description"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"/developers/json-rpc/guidance"},"Guidance for JSON-RPC SDK Compliance")),(0,o.kt)("td",{parentName:"tr",align:null},"Requirements for a compliant Casper SDK")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"/developers/json-rpc/minimal-compliance"},"Required JSON-RPC Methods for Minimal Compliance")),(0,o.kt)("td",{parentName:"tr",align:null},"Methods required for a minimally compliant Casper SDK")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"/developers/json-rpc/json-rpc-transactional"},"Transactional JSON-RPC Method")),(0,o.kt)("td",{parentName:"tr",align:null},"Methods allowing interaction with a Casper network")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"/developers/json-rpc/json-rpc-informational"},"Informational JSON-RPC Methods")),(0,o.kt)("td",{parentName:"tr",align:null},"Methods returning information about the network from a Casper node")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"/developers/json-rpc/json-rpc-pos"},"Proof-of-Stake JSON-RPC Methods")),(0,o.kt)("td",{parentName:"tr",align:null},"Methods pertaining to Proof-of-Stake functionality on a Casper network")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain"},"Types")),(0,o.kt)("td",{parentName:"tr",align:null},"Information on types used within JSON-RPC methods")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_cl"},"CL Types")),(0,o.kt)("td",{parentName:"tr",align:null},"Information related to CL Types")))))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9ae83eb2.19122969.js b/assets/js/9ae83eb2.494315b3.js similarity index 99% rename from assets/js/9ae83eb2.19122969.js rename to assets/js/9ae83eb2.494315b3.js index 0ddd1faf2a..dab2f794ab 100644 --- a/assets/js/9ae83eb2.19122969.js +++ b/assets/js/9ae83eb2.494315b3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5240],{3905:function(e,t,n){n.d(t,{Zo:function(){return d},kt:function(){return h}});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),c=p(n),m=i,h=c["".concat(s,".").concat(m)]||c[m]||u[m]||o;return n?a.createElement(h,r(r({ref:t},d),{},{components:n})):a.createElement(h,r({ref:t},d))}));function h(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:i,r[1]=l;for(var p=2;p/usr/bin/",id:"usrbin",level:3},{value:"/etc/casper/",id:"etccasper",level:3},{value:"/var/lib/casper/",id:"varlibcasper",level:3},{value:"Node Version Installation",id:"node-version-installation",level:2},{value:"The Node Configuration File",id:"config-file",level:2},{value:"The Trusted Hash for Synchronizing",id:"trusted-hash-for-synchronizing",level:3},{value:"Known Addresses",id:"known-addresses",level:3},{value:"Updating the config.toml file",id:"updating-config-file",level:3},{value:"Secret Keys",id:"secret-keys",level:3},{value:"Networking and Gossiping",id:"networking--gossiping",level:3},{value:"Enabling Speculative Execution",id:"enabling-speculative-execution",level:3},{value:"Example Config.toml configuration with speculative execution enabled",id:"example-configtoml-configuration-with-speculative-execution-enabled",level:4},{value:"Rust Client Installation",id:"client-installation",level:2},{value:"Creating Keys and Funding Accounts",id:"create-fund-keys",level:2}],u={toc:c},m="wrapper";function h(e){var t=e.components,n=(0,i.Z)(e,r);return(0,o.kt)(m,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"basic-node-configuration"},"Basic Node Configuration"),(0,o.kt)("p",null,"This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the ",(0,o.kt)("a",{parentName:"p",href:"/operators/setup/install-node"},"Node Setup")," guide."),(0,o.kt)("h2",{id:"casper-node-launcher"},"The Casper Node Launcher"),(0,o.kt)("p",null,"A node is usually run by executing the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher"),", which executes the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," as a child process and also handles upgrades to bring the node to the latest version released."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," can be installed via a Debian package, which also creates the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper")," user and directory structures and sets up a ",(0,o.kt)("inlineCode",{parentName:"p"},"systemd")," unit and logging."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," Debian package can be obtained from ",(0,o.kt)("a",{parentName:"p",href:"https://repo.casperlabs.io"},"https://repo.casperlabs.io"),". You only need to run the steps detailed there once."),(0,o.kt)("p",null,"Then, proceed to install the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," by running these commands:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt update\nsudo apt install casper-node-launcher\n")),(0,o.kt)("p",null,"You can also build ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node-launcher"},"from source"),". However, all the setup and pull of casper-node releases will be manual."),(0,o.kt)("h2",{id:"file-locations"},"File Locations"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," Debian installation creates the directories and files needed to run ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," versions and perform upgrades. A ",(0,o.kt)("inlineCode",{parentName:"p"},"casper")," user and ",(0,o.kt)("inlineCode",{parentName:"p"},"casper")," group are created during installation and used to run the software. Two main folders are relevant for our software: ",(0,o.kt)("inlineCode",{parentName:"p"},"/etc/casper")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"/var/lib/casper"),"."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"The casper-node install version")),(0,o.kt)("p",null,"Each version of the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," install is located based on the semantic version with underscores. For example, version 1.0.3 is represented by a directory named ",(0,o.kt)("inlineCode",{parentName:"p"},"1_0_3"),". This convention applies to both binary and configuration file locations. Versioning with ",(0,o.kt)("inlineCode",{parentName:"p"},"[m_n_p]")," represents the major, minor, and patch of a semantic version."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Multiple versioned folders will exist on a system when upgrades are set up.")),(0,o.kt)("p",null,"The following is the filesystem's state after installing the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-client")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," Debian packages, and after running the command ",(0,o.kt)("inlineCode",{parentName:"p"},"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf")," (Use casper-test.conf if on Testnet)."),(0,o.kt)("h3",{id:"usrbin"},(0,o.kt)("inlineCode",{parentName:"h3"},"/usr/bin/")),(0,o.kt)("p",null,"The default location for executables from the Debian package install is ",(0,o.kt)("inlineCode",{parentName:"p"},"/usr/bin"),"."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"casper-client")," - A client for interacting with a Casper network"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"casper-node-launcher")," - The launcher application which starts the ",(0,o.kt)("inlineCode",{parentName:"li"},"casper-node")," as a child process")),(0,o.kt)("h3",{id:"etccasper"},(0,o.kt)("inlineCode",{parentName:"h3"},"/etc/casper/")),(0,o.kt)("p",null,"This is the default location for configuration files. It can be overwritten with the ",(0,o.kt)("inlineCode",{parentName:"p"},"CASPER_CONFIG_DIR")," environment variable. The paths in this document assume the default configuration file location of ",(0,o.kt)("inlineCode",{parentName:"p"},"/etc/casper"),". The data is organized as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"delete_local_db.sh")," - Removes ",(0,o.kt)("inlineCode",{parentName:"li"},"*.lmdb*")," files from ",(0,o.kt)("inlineCode",{parentName:"li"},"/var/lib/casper/casper-node")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"pull_casper_node_version.sh")," - Pulls ",(0,o.kt)("inlineCode",{parentName:"li"},"bin.tar.gz")," and ",(0,o.kt)("inlineCode",{parentName:"li"},"config.tar.gz")," from ",(0,o.kt)("a",{parentName:"li",href:"https://genesis.casperlabs.io/"},"genesis.casperlabs.io")," for a specified protocol version and extracts them into ",(0,o.kt)("inlineCode",{parentName:"li"},"/var/lib/bin/")," and ",(0,o.kt)("inlineCode",{parentName:"li"},"/etc/casper/")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"config_from_example.sh")," - Gets external IP to replace and create the ",(0,o.kt)("inlineCode",{parentName:"li"},"config.toml")," from ",(0,o.kt)("inlineCode",{parentName:"li"},"config-example.toml")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"node_util.py")," - A script that will be replacing other scripts and is the preferred method of performing the actions of ",(0,o.kt)("inlineCode",{parentName:"li"},"pull_casper_node_version.sh"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"config_from_example.sh"),", and ",(0,o.kt)("inlineCode",{parentName:"li"},"delete_local_db.sh"),". Other scripts will be deprecated in future releases of ",(0,o.kt)("inlineCode",{parentName:"li"},"casper-node-launcher"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"casper-node-launcher-state.toml")," - The local state for the ",(0,o.kt)("inlineCode",{parentName:"li"},"casper-node-launcher")," which is created during the first run"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"validator_keys/")," - The default folder for node keys, containing:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"README.md")," - Instructions on how to create validator keys using the ",(0,o.kt)("inlineCode",{parentName:"li"},"casper-client")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"secret_key.pem")," - Secret key used by the validator node to sign blocks and peer-to-peer messages"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"public_key.pem")," - Public key associated with the secret key above, stored in PEM format"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"public_key_hex")," - Public key associated with the secret key above, stored in hex format"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"1_0_0/")," - Folder for genesis configuration files, containing:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"accounts.toml")," - Contains the genesis validators and delegators"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"chainspec.toml")," - Contains invariant network settings, with the ",(0,o.kt)("inlineCode",{parentName:"li"},"activation_point")," (network start time) as a timestamp"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"config-example.toml")," - Example for creating a ",(0,o.kt)("inlineCode",{parentName:"li"},"config.toml")," file"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"config.toml")," - Contains variable node configuration settings, created by a node operator manually or by running ",(0,o.kt)("inlineCode",{parentName:"li"},"config_from_example.sh 1_0_0")))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"m_n_p/")," - Folder for each installed upgrade package's configuration files, containing:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"chainspec.toml")," - Contains invariant network settings, with the ",(0,o.kt)("inlineCode",{parentName:"li"},"activation_point")," as an era ID (the era at which this protocol version of the node became or will become active)"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"config-example.toml")," - As per ",(0,o.kt)("inlineCode",{parentName:"li"},"1_0_0/config-example.toml"),", but compatible with the ",(0,o.kt)("inlineCode",{parentName:"li"},"m.n.p")," version of the node"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"config.toml")," - As per ",(0,o.kt)("inlineCode",{parentName:"li"},"1_0_0/config.toml"),", but compatible with the ",(0,o.kt)("inlineCode",{parentName:"li"},"m.n.p")," version of the node")))),(0,o.kt)("h3",{id:"varlibcasper"},(0,o.kt)("inlineCode",{parentName:"h3"},"/var/lib/casper/")),(0,o.kt)("p",null,"This is the location for larger and variable data for the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node"),", organized in the following folders and files:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"bin/")," - The parent folder storing the versions of ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," executables. This location can be overwritten with the ",(0,o.kt)("inlineCode",{parentName:"p"},"CASPER_BIN_DIR")," environment variable. The paths in this document assume the default of ",(0,o.kt)("inlineCode",{parentName:"p"},"/var/lib/casper/bin/"),"."),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"1_0_0/")," - Folder for genesis binary files, containing:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"casper-node")," - The node executable - defaults to the Ubuntu 20.04 compatible binary"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"README.md")," - Information about the repository location and the Git hash used for compilation to allow a rebuild on other platforms"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"m_n_p/")," - Folder for each installed upgrade package, containing:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"casper-node")," - As per ",(0,o.kt)("inlineCode",{parentName:"li"},"1_0_0/casper-node"),", but the ",(0,o.kt)("inlineCode",{parentName:"li"},"m.n.p")," version of the node"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"README.md")," - As per ",(0,o.kt)("inlineCode",{parentName:"li"},"1_0_0/README.md"),", but compatible with the ",(0,o.kt)("inlineCode",{parentName:"li"},"m.n.p")," version of the node"))))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"casper-node/")," - Folder containing databases and related files produced by the node binary. For Mainnet, the network name is ",(0,o.kt)("inlineCode",{parentName:"p"},"casper")," and for Testnet it is ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-test"),"."),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"data.lmdb")," - Persistent global state store of the network"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"data.lmbd-lock")," - Lockfile for the ",(0,o.kt)("inlineCode",{parentName:"li"},"data.lmdb")," database"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"storage.lmdb")," - Persistent store of all other network data, primarily Blocks and Deploys"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"storage.lmdb-lock")," - Lockfile for the ",(0,o.kt)("inlineCode",{parentName:"li"},"storage.lmdb")," database"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"unit_files/")," - Folder containing transient caches of consensus information")))),(0,o.kt)("h2",{id:"node-version-installation"},"Node Version Installation"),(0,o.kt)("p",null,"Included with the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," is ",(0,o.kt)("inlineCode",{parentName:"p"},"node_util.py")," for installing ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," versions. This command will stage all current ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," versions:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper /etc/casper/node_util.py stage_protocols \n")),(0,o.kt)("p",null,"For ",(0,o.kt)("inlineCode",{parentName:"p"},""),", we use ",(0,o.kt)("inlineCode",{parentName:"p"},"casper.conf")," for Mainnet and ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-test.conf")," for Testnet. This will install all currently released protocols in one step."),(0,o.kt)("p",null,"This command will do the following:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Create ",(0,o.kt)("inlineCode",{parentName:"li"},"/var/lib/casper/bin/1_0_2/")," and expand the ",(0,o.kt)("inlineCode",{parentName:"li"},"bin.tar.gz")," containing at a minimum ",(0,o.kt)("inlineCode",{parentName:"li"},"casper-node")),(0,o.kt)("li",{parentName:"ul"},"Create ",(0,o.kt)("inlineCode",{parentName:"li"},"/etc/casper/1_0_2/")," and expand the ",(0,o.kt)("inlineCode",{parentName:"li"},"config.tar.gz")," containing ",(0,o.kt)("inlineCode",{parentName:"li"},"chainspec.toml"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"config-example.toml"),", and possibly ",(0,o.kt)("inlineCode",{parentName:"li"},"accounts.csv")," and other files"),(0,o.kt)("li",{parentName:"ul"},"Remove the archive files and run ",(0,o.kt)("inlineCode",{parentName:"li"},"/etc/casper/config_from_example.sh 1_0_2")," to create a ",(0,o.kt)("inlineCode",{parentName:"li"},"config.toml")," from the ",(0,o.kt)("inlineCode",{parentName:"li"},"config-example.toml"))),(0,o.kt)("p",null,"Release versions are invoked using the underscore format, such as:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper /etc/casper/pull_casper_node_version.sh 1_0_2\n")),(0,o.kt)("h2",{id:"config-file"},"The Node Configuration File"),(0,o.kt)("p",null,"One ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," file exists for each ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," version installed. It is located in the ",(0,o.kt)("inlineCode",{parentName:"p"},"/etc/casper/[m_n_p]/")," directory, where ",(0,o.kt)("inlineCode",{parentName:"p"},"m_n_p")," is the current semantic version. This can be created from the ",(0,o.kt)("inlineCode",{parentName:"p"},"config-example.toml")," by using ",(0,o.kt)("inlineCode",{parentName:"p"},"/etc/casper/config_from_example.sh [m_n_p]")," where ",(0,o.kt)("inlineCode",{parentName:"p"},"[m_n_p]")," is replaced with the current version, using underscores."),(0,o.kt)("p",null,"Below are some fields in the ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," that you may need to adjust."),(0,o.kt)("h3",{id:"trusted-hash-for-synchronizing"},"The Trusted Hash for Synchronizing"),(0,o.kt)("p",null,"Each Casper network is a permissionless, Proof-of-Stake network, implying that nodes can join and leave the network. As a result, some nodes may not be synchronized or as secure as bonded validators. Ideally, all nodes will join the network using a trusted source, such as a bonded validator."),(0,o.kt)("p",null,"When joining the network, the system will start from the hash of a recent block and then work backward to obtain the finalized blocks from the linear block store. Here is the process to get the trusted hash of a bonded validator:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Find a list of trusted validators"),(0,o.kt)("li",{parentName:"ul"},"Query the status endpoint of a trusted validator (",(0,o.kt)("inlineCode",{parentName:"li"},"http://:8888/status"),")"),(0,o.kt)("li",{parentName:"ul"},"Obtain the hash of a block from the status endpoint"),(0,o.kt)("li",{parentName:"ul"},"Update the ",(0,o.kt)("inlineCode",{parentName:"li"},"config.toml")," for the node to include the trusted hash. There is a field dedicated to this near the top of the file")),(0,o.kt)("p",null,"Here is an example command for obtaining a trusted hash. Replace the node address with an updated address from a node on the network."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo sed -i \"/trusted_hash =/c\\trusted_hash = '$(casper-client get-block --node-address http://3.14.161.135:7777 -b 20 | jq -r .result.block.hash | tr -d '\\n')'\" /etc/casper/1_0_0/config.toml\n")),(0,o.kt)("h3",{id:"known-addresses"},"Known Addresses"),(0,o.kt)("p",null,"For the node to connect to a network, the node needs a set of trusted peers for that network. For ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live/"},"Mainnet"),", these are listed in the ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," as ",(0,o.kt)("inlineCode",{parentName:"p"},"known_addresses"),". For other networks, locate and update the list to include at least two trusted IP addresses for peers in that network. Here is an ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-protocol-release/blob/main/config/config-example.toml"},"example configuration"),". The ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-protocol-release"},"casper-protocol-release")," repository stores configurations for various environments, which you can also use as examples."),(0,o.kt)("h3",{id:"updating-config-file"},"Updating the ",(0,o.kt)("inlineCode",{parentName:"h3"},"config.toml")," file"),(0,o.kt)("p",null,"At the top of a ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," file as shown here, enter the trusted block hash to replace the ",(0,o.kt)("inlineCode",{parentName:"p"},"'HEX-FORMATTED BLOCK HASH'")," and uncomment the line by deleting the leading '#'. See the ",(0,o.kt)("a",{parentName:"p",href:"/operators/setup/basic-node-configuration#config-file"},"Configuration File")," for more details."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"# ================================\n# Configuration options for a node\n# ================================\n[node]\n\n# If set, use this hash as a trust anchor when joining an existing network.\n#trusted_hash = 'HEX-FORMATTED BLOCK HASH'\n")),(0,o.kt)("h3",{id:"secret-keys"},"Secret Keys"),(0,o.kt)("p",null,"Provide the path to the secret keys for the node. This path is set to ",(0,o.kt)("inlineCode",{parentName:"p"},"etc/casper/validator_keys/")," by default. See ",(0,o.kt)("a",{parentName:"p",href:"#create-fund-keys"},"Creating Keys and Funding Accounts")," for more details."),(0,o.kt)("h3",{id:"networking--gossiping"},"Networking and Gossiping"),(0,o.kt)("p",null,"The node requires a publicly accessible IP address. The ",(0,o.kt)("inlineCode",{parentName:"p"},"config_from_example.sh")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"node_util.py")," both allow IP for network address translation (NAT) setup. Specify the public IP address of the node. If you use the ",(0,o.kt)("inlineCode",{parentName:"p"},"config_from_example.sh")," external services are called to find your IP and this is inserted into the ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," created."),(0,o.kt)("p",null,"The following default values are specified in the file if you want to change them:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"The port that will be used for status and deploys"),(0,o.kt)("li",{parentName:"ul"},"The port used for networking"),(0,o.kt)("li",{parentName:"ul"},"Known_addresses - these are the bootstrap nodes (there is no need to change these)")),(0,o.kt)("h3",{id:"enabling-speculative-execution"},"Enabling Speculative Execution"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"speculative_exec")," endpoint provides a method to execute a Deploy without committing its execution effects to global state. This can be used by developers to roughly estimate the gas costs of sending the Deploy in question. By default, ",(0,o.kt)("inlineCode",{parentName:"p"},"speculative_exec")," is disabled on a node."),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"speculative_exec")," can be enabled within ",(0,o.kt)("em",{parentName:"p"},"config.toml")," by changing ",(0,o.kt)("inlineCode",{parentName:"p"},"enable_server")," to ",(0,o.kt)("inlineCode",{parentName:"p"},"true")," under the configuration options for the speculative execution JSON-RPC HTTP server."),(0,o.kt)("p",null,"Node operators may also change the incoming request port for speculative execution, which defaults to ",(0,o.kt)("inlineCode",{parentName:"p"},"7778"),". Further, you can choose to alter the ",(0,o.kt)("inlineCode",{parentName:"p"},"qps_limit")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"max_body_bytes"),", which limit the amount and size of requests to the speculative execution server."),(0,o.kt)("h4",{id:"example-configtoml-configuration-with-speculative-execution-enabled"},"Example Config.toml configuration with speculative execution enabled"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"# ========================================================================\n# Configuration options for the speculative execution JSON-RPC HTTP server\n# ========================================================================\n[speculative_exec_server]\n\n# Flag which enables the speculative execution JSON-RPC HTTP server.\nenable_server = true\n\n# Listening address for speculative execution JSON-RPC HTTP server. If the port\n# is set to 0, a random port will be used.\n#\n# If the specified port cannot be bound to, a random port will be tried instead.\n# If binding fails, the speculative execution JSON-RPC HTTP server will not run,\n# but the node will be otherwise unaffected.\n#\n# The actual bound address will be reported via a log line if logging is enabled.\naddress = '0.0.0.0:7778'\n\n# The global max rate of requests (per second) before they are limited.\n# Request will be delayed to the next 1 second bucket once limited.\nqps_limit = 1\n\n# Maximum number of bytes to accept in a single request body.\nmax_body_bytes = 2_621_440\n\n# Specifies which origin will be reported as allowed by speculative execution server.\n#\n# If left empty, CORS will be disabled.\n# If set to '*', any origin is allowed.\n# Otherwise, only a specified origin is allowed. The given string must conform to the [origin scheme](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin).\ncors_origin = ''\n\n")),(0,o.kt)("h2",{id:"client-installation"},"Rust Client Installation"),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"/developers/prerequisites#the-casper-command-line-client"},"Prerequisites")," page lists installation instructions for the Casper client, which is useful for generating keys and retrieving information from the network."),(0,o.kt)("h2",{id:"create-fund-keys"},"Creating Keys and Funding Accounts"),(0,o.kt)("p",null,"The following command will create keys in the ",(0,o.kt)("inlineCode",{parentName:"p"},"/etc/casper/validator_keys")," folder."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client keygen /etc/casper/validator_keys\n")),(0,o.kt)("p",null,"To learn about other options for generating keys, see ",(0,o.kt)("a",{parentName:"p",href:"/concepts/accounts-and-keys"},"Accounts and Cryptographic Keys")," or run the Rust client ",(0,o.kt)("inlineCode",{parentName:"p"},"keygen")," command with the ",(0,o.kt)("inlineCode",{parentName:"p"},"--help")," option."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client keygen --help\n")),(0,o.kt)("p",null,"More about keys and key generation can also be found in ",(0,o.kt)("inlineCode",{parentName:"p"},"/etc/casper/validator_keys/README.md")," if the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," was installed from the Debian package."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Save your keys in a secure location, preferably offline.")),(0,o.kt)("p",null,"To submit a bonding request, you will need to ",(0,o.kt)("a",{parentName:"p",href:"/developers/prerequisites#fund-your-account"},"fund your account")," as well."))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5240],{3905:function(e,t,n){n.d(t,{Zo:function(){return d},kt:function(){return h}});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),c=p(n),m=i,h=c["".concat(s,".").concat(m)]||c[m]||u[m]||o;return n?a.createElement(h,r(r({ref:t},d),{},{components:n})):a.createElement(h,r({ref:t},d))}));function h(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:i,r[1]=l;for(var p=2;p/usr/bin/",id:"usrbin",level:3},{value:"/etc/casper/",id:"etccasper",level:3},{value:"/var/lib/casper/",id:"varlibcasper",level:3},{value:"Node Version Installation",id:"node-version-installation",level:2},{value:"The Node Configuration File",id:"config-file",level:2},{value:"The Trusted Hash for Synchronizing",id:"trusted-hash-for-synchronizing",level:3},{value:"Known Addresses",id:"known-addresses",level:3},{value:"Updating the config.toml file",id:"updating-config-file",level:3},{value:"Secret Keys",id:"secret-keys",level:3},{value:"Networking and Gossiping",id:"networking--gossiping",level:3},{value:"Enabling Speculative Execution",id:"enabling-speculative-execution",level:3},{value:"Example Config.toml configuration with speculative execution enabled",id:"example-configtoml-configuration-with-speculative-execution-enabled",level:4},{value:"Rust Client Installation",id:"client-installation",level:2},{value:"Creating Keys and Funding Accounts",id:"create-fund-keys",level:2}],u={toc:c},m="wrapper";function h(e){var t=e.components,n=(0,i.Z)(e,r);return(0,o.kt)(m,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"basic-node-configuration"},"Basic Node Configuration"),(0,o.kt)("p",null,"This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the ",(0,o.kt)("a",{parentName:"p",href:"/operators/setup/install-node"},"Node Setup")," guide."),(0,o.kt)("h2",{id:"casper-node-launcher"},"The Casper Node Launcher"),(0,o.kt)("p",null,"A node is usually run by executing the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher"),", which executes the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," as a child process and also handles upgrades to bring the node to the latest version released."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," can be installed via a Debian package, which also creates the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper")," user and directory structures and sets up a ",(0,o.kt)("inlineCode",{parentName:"p"},"systemd")," unit and logging."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," Debian package can be obtained from ",(0,o.kt)("a",{parentName:"p",href:"https://repo.casperlabs.io"},"https://repo.casperlabs.io"),". You only need to run the steps detailed there once."),(0,o.kt)("p",null,"Then, proceed to install the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," by running these commands:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt update\nsudo apt install casper-node-launcher\n")),(0,o.kt)("p",null,"You can also build ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node-launcher"},"from source"),". However, all the setup and pull of casper-node releases will be manual."),(0,o.kt)("h2",{id:"file-locations"},"File Locations"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," Debian installation creates the directories and files needed to run ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," versions and perform upgrades. A ",(0,o.kt)("inlineCode",{parentName:"p"},"casper")," user and ",(0,o.kt)("inlineCode",{parentName:"p"},"casper")," group are created during installation and used to run the software. Two main folders are relevant for our software: ",(0,o.kt)("inlineCode",{parentName:"p"},"/etc/casper")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"/var/lib/casper"),"."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"The casper-node install version")),(0,o.kt)("p",null,"Each version of the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," install is located based on the semantic version with underscores. For example, version 1.0.3 is represented by a directory named ",(0,o.kt)("inlineCode",{parentName:"p"},"1_0_3"),". This convention applies to both binary and configuration file locations. Versioning with ",(0,o.kt)("inlineCode",{parentName:"p"},"[m_n_p]")," represents the major, minor, and patch of a semantic version."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Multiple versioned folders will exist on a system when upgrades are set up.")),(0,o.kt)("p",null,"The following is the filesystem's state after installing the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-client")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," Debian packages, and after running the command ",(0,o.kt)("inlineCode",{parentName:"p"},"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf")," (Use casper-test.conf if on Testnet)."),(0,o.kt)("h3",{id:"usrbin"},(0,o.kt)("inlineCode",{parentName:"h3"},"/usr/bin/")),(0,o.kt)("p",null,"The default location for executables from the Debian package install is ",(0,o.kt)("inlineCode",{parentName:"p"},"/usr/bin"),"."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"casper-client")," - A client for interacting with a Casper network"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"casper-node-launcher")," - The launcher application which starts the ",(0,o.kt)("inlineCode",{parentName:"li"},"casper-node")," as a child process")),(0,o.kt)("h3",{id:"etccasper"},(0,o.kt)("inlineCode",{parentName:"h3"},"/etc/casper/")),(0,o.kt)("p",null,"This is the default location for configuration files. It can be overwritten with the ",(0,o.kt)("inlineCode",{parentName:"p"},"CASPER_CONFIG_DIR")," environment variable. The paths in this document assume the default configuration file location of ",(0,o.kt)("inlineCode",{parentName:"p"},"/etc/casper"),". The data is organized as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"delete_local_db.sh")," - Removes ",(0,o.kt)("inlineCode",{parentName:"li"},"*.lmdb*")," files from ",(0,o.kt)("inlineCode",{parentName:"li"},"/var/lib/casper/casper-node")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"pull_casper_node_version.sh")," - Pulls ",(0,o.kt)("inlineCode",{parentName:"li"},"bin.tar.gz")," and ",(0,o.kt)("inlineCode",{parentName:"li"},"config.tar.gz")," from ",(0,o.kt)("a",{parentName:"li",href:"https://genesis.casperlabs.io/"},"genesis.casperlabs.io")," for a specified protocol version and extracts them into ",(0,o.kt)("inlineCode",{parentName:"li"},"/var/lib/bin/")," and ",(0,o.kt)("inlineCode",{parentName:"li"},"/etc/casper/")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"config_from_example.sh")," - Gets external IP to replace and create the ",(0,o.kt)("inlineCode",{parentName:"li"},"config.toml")," from ",(0,o.kt)("inlineCode",{parentName:"li"},"config-example.toml")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"node_util.py")," - A script that will be replacing other scripts and is the preferred method of performing the actions of ",(0,o.kt)("inlineCode",{parentName:"li"},"pull_casper_node_version.sh"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"config_from_example.sh"),", and ",(0,o.kt)("inlineCode",{parentName:"li"},"delete_local_db.sh"),". Other scripts will be deprecated in future releases of ",(0,o.kt)("inlineCode",{parentName:"li"},"casper-node-launcher"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"casper-node-launcher-state.toml")," - The local state for the ",(0,o.kt)("inlineCode",{parentName:"li"},"casper-node-launcher")," which is created during the first run"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"validator_keys/")," - The default folder for node keys, containing:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"README.md")," - Instructions on how to create validator keys using the ",(0,o.kt)("inlineCode",{parentName:"li"},"casper-client")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"secret_key.pem")," - Secret key used by the validator node to sign blocks and peer-to-peer messages"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"public_key.pem")," - Public key associated with the secret key above, stored in PEM format"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"public_key_hex")," - Public key associated with the secret key above, stored in hex format"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"1_0_0/")," - Folder for genesis configuration files, containing:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"accounts.toml")," - Contains the genesis validators and delegators"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"chainspec.toml")," - Contains invariant network settings, with the ",(0,o.kt)("inlineCode",{parentName:"li"},"activation_point")," (network start time) as a timestamp"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"config-example.toml")," - Example for creating a ",(0,o.kt)("inlineCode",{parentName:"li"},"config.toml")," file"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"config.toml")," - Contains variable node configuration settings, created by a node operator manually or by running ",(0,o.kt)("inlineCode",{parentName:"li"},"config_from_example.sh 1_0_0")))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"m_n_p/")," - Folder for each installed upgrade package's configuration files, containing:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"chainspec.toml")," - Contains invariant network settings, with the ",(0,o.kt)("inlineCode",{parentName:"li"},"activation_point")," as an era ID (the era at which this protocol version of the node became or will become active)"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"config-example.toml")," - As per ",(0,o.kt)("inlineCode",{parentName:"li"},"1_0_0/config-example.toml"),", but compatible with the ",(0,o.kt)("inlineCode",{parentName:"li"},"m.n.p")," version of the node"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"config.toml")," - As per ",(0,o.kt)("inlineCode",{parentName:"li"},"1_0_0/config.toml"),", but compatible with the ",(0,o.kt)("inlineCode",{parentName:"li"},"m.n.p")," version of the node")))),(0,o.kt)("h3",{id:"varlibcasper"},(0,o.kt)("inlineCode",{parentName:"h3"},"/var/lib/casper/")),(0,o.kt)("p",null,"This is the location for larger and variable data for the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node"),", organized in the following folders and files:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"bin/")," - The parent folder storing the versions of ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," executables. This location can be overwritten with the ",(0,o.kt)("inlineCode",{parentName:"p"},"CASPER_BIN_DIR")," environment variable. The paths in this document assume the default of ",(0,o.kt)("inlineCode",{parentName:"p"},"/var/lib/casper/bin/"),"."),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"1_0_0/")," - Folder for genesis binary files, containing:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"casper-node")," - The node executable - defaults to the Ubuntu 20.04 compatible binary"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"README.md")," - Information about the repository location and the Git hash used for compilation to allow a rebuild on other platforms"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"m_n_p/")," - Folder for each installed upgrade package, containing:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"casper-node")," - As per ",(0,o.kt)("inlineCode",{parentName:"li"},"1_0_0/casper-node"),", but the ",(0,o.kt)("inlineCode",{parentName:"li"},"m.n.p")," version of the node"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"README.md")," - As per ",(0,o.kt)("inlineCode",{parentName:"li"},"1_0_0/README.md"),", but compatible with the ",(0,o.kt)("inlineCode",{parentName:"li"},"m.n.p")," version of the node"))))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"casper-node/")," - Folder containing databases and related files produced by the node binary. For Mainnet, the network name is ",(0,o.kt)("inlineCode",{parentName:"p"},"casper")," and for Testnet it is ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-test"),"."),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"data.lmdb")," - Persistent global state store of the network"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"data.lmbd-lock")," - Lockfile for the ",(0,o.kt)("inlineCode",{parentName:"li"},"data.lmdb")," database"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"storage.lmdb")," - Persistent store of all other network data, primarily Blocks and Deploys"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"storage.lmdb-lock")," - Lockfile for the ",(0,o.kt)("inlineCode",{parentName:"li"},"storage.lmdb")," database"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"unit_files/")," - Folder containing transient caches of consensus information")))),(0,o.kt)("h2",{id:"node-version-installation"},"Node Version Installation"),(0,o.kt)("p",null,"Included with the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," is ",(0,o.kt)("inlineCode",{parentName:"p"},"node_util.py")," for installing ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," versions. This command will stage all current ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," versions:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper /etc/casper/node_util.py stage_protocols \n")),(0,o.kt)("p",null,"For ",(0,o.kt)("inlineCode",{parentName:"p"},""),", we use ",(0,o.kt)("inlineCode",{parentName:"p"},"casper.conf")," for Mainnet and ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-test.conf")," for Testnet. This will install all currently released protocols in one step."),(0,o.kt)("p",null,"This command will do the following:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Create ",(0,o.kt)("inlineCode",{parentName:"li"},"/var/lib/casper/bin/1_0_2/")," and expand the ",(0,o.kt)("inlineCode",{parentName:"li"},"bin.tar.gz")," containing at a minimum ",(0,o.kt)("inlineCode",{parentName:"li"},"casper-node")),(0,o.kt)("li",{parentName:"ul"},"Create ",(0,o.kt)("inlineCode",{parentName:"li"},"/etc/casper/1_0_2/")," and expand the ",(0,o.kt)("inlineCode",{parentName:"li"},"config.tar.gz")," containing ",(0,o.kt)("inlineCode",{parentName:"li"},"chainspec.toml"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"config-example.toml"),", and possibly ",(0,o.kt)("inlineCode",{parentName:"li"},"accounts.csv")," and other files"),(0,o.kt)("li",{parentName:"ul"},"Remove the archive files and run ",(0,o.kt)("inlineCode",{parentName:"li"},"/etc/casper/config_from_example.sh 1_0_2")," to create a ",(0,o.kt)("inlineCode",{parentName:"li"},"config.toml")," from the ",(0,o.kt)("inlineCode",{parentName:"li"},"config-example.toml"))),(0,o.kt)("p",null,"Release versions are invoked using the underscore format, such as:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper /etc/casper/pull_casper_node_version.sh 1_0_2\n")),(0,o.kt)("h2",{id:"config-file"},"The Node Configuration File"),(0,o.kt)("p",null,"One ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," file exists for each ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," version installed. It is located in the ",(0,o.kt)("inlineCode",{parentName:"p"},"/etc/casper/[m_n_p]/")," directory, where ",(0,o.kt)("inlineCode",{parentName:"p"},"m_n_p")," is the current semantic version. This can be created from the ",(0,o.kt)("inlineCode",{parentName:"p"},"config-example.toml")," by using ",(0,o.kt)("inlineCode",{parentName:"p"},"/etc/casper/config_from_example.sh [m_n_p]")," where ",(0,o.kt)("inlineCode",{parentName:"p"},"[m_n_p]")," is replaced with the current version, using underscores."),(0,o.kt)("p",null,"Below are some fields in the ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," that you may need to adjust."),(0,o.kt)("h3",{id:"trusted-hash-for-synchronizing"},"The Trusted Hash for Synchronizing"),(0,o.kt)("p",null,"Each Casper network is a permissionless, Proof-of-Stake network, implying that nodes can join and leave the network. As a result, some nodes may not be synchronized or as secure as bonded validators. Ideally, all nodes will join the network using a trusted source, such as a bonded validator."),(0,o.kt)("p",null,"When joining the network, the system will start from the hash of a recent block and then work backward to obtain the finalized blocks from the linear block store. Here is the process to get the trusted hash of a bonded validator:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Find a list of trusted validators"),(0,o.kt)("li",{parentName:"ul"},"Query the status endpoint of a trusted validator (",(0,o.kt)("inlineCode",{parentName:"li"},"http://:8888/status"),")"),(0,o.kt)("li",{parentName:"ul"},"Obtain the hash of a block from the status endpoint"),(0,o.kt)("li",{parentName:"ul"},"Update the ",(0,o.kt)("inlineCode",{parentName:"li"},"config.toml")," for the node to include the trusted hash. There is a field dedicated to this near the top of the file")),(0,o.kt)("p",null,"Here is an example command for obtaining a trusted hash. Replace the node address with an updated address from a node on the network."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo sed -i \"/trusted_hash =/c\\trusted_hash = '$(casper-client get-block --node-address http://3.14.161.135:7777 -b 20 | jq -r .result.block.hash | tr -d '\\n')'\" /etc/casper/1_0_0/config.toml\n")),(0,o.kt)("h3",{id:"known-addresses"},"Known Addresses"),(0,o.kt)("p",null,"For the node to connect to a network, the node needs a set of trusted peers for that network. For ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live/"},"Mainnet"),", these are listed in the ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," as ",(0,o.kt)("inlineCode",{parentName:"p"},"known_addresses"),". For other networks, locate and update the list to include at least two trusted IP addresses for peers in that network. Here is an ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-protocol-release/blob/main/config/config-example.toml"},"example configuration"),". The ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-protocol-release"},"casper-protocol-release")," repository stores configurations for various environments, which you can also use as examples."),(0,o.kt)("h3",{id:"updating-config-file"},"Updating the ",(0,o.kt)("inlineCode",{parentName:"h3"},"config.toml")," file"),(0,o.kt)("p",null,"At the top of a ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," file as shown here, enter the trusted block hash to replace the ",(0,o.kt)("inlineCode",{parentName:"p"},"'HEX-FORMATTED BLOCK HASH'")," and uncomment the line by deleting the leading '#'. See the ",(0,o.kt)("a",{parentName:"p",href:"/operators/setup/basic-node-configuration#config-file"},"Configuration File")," for more details."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"# ================================\n# Configuration options for a node\n# ================================\n[node]\n\n# If set, use this hash as a trust anchor when joining an existing network.\n#trusted_hash = 'HEX-FORMATTED BLOCK HASH'\n")),(0,o.kt)("h3",{id:"secret-keys"},"Secret Keys"),(0,o.kt)("p",null,"Provide the path to the secret keys for the node. This path is set to ",(0,o.kt)("inlineCode",{parentName:"p"},"etc/casper/validator_keys/")," by default. See ",(0,o.kt)("a",{parentName:"p",href:"#create-fund-keys"},"Creating Keys and Funding Accounts")," for more details."),(0,o.kt)("h3",{id:"networking--gossiping"},"Networking and Gossiping"),(0,o.kt)("p",null,"The node requires a publicly accessible IP address. The ",(0,o.kt)("inlineCode",{parentName:"p"},"config_from_example.sh")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"node_util.py")," both allow IP for network address translation (NAT) setup. Specify the public IP address of the node. If you use the ",(0,o.kt)("inlineCode",{parentName:"p"},"config_from_example.sh")," external services are called to find your IP and this is inserted into the ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," created."),(0,o.kt)("p",null,"The following default values are specified in the file if you want to change them:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"The port that will be used for status and deploys"),(0,o.kt)("li",{parentName:"ul"},"The port used for networking"),(0,o.kt)("li",{parentName:"ul"},"Known_addresses - these are the bootstrap nodes (there is no need to change these)")),(0,o.kt)("h3",{id:"enabling-speculative-execution"},"Enabling Speculative Execution"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"speculative_exec")," endpoint provides a method to execute a Deploy without committing its execution effects to global state. This can be used by developers to roughly estimate the gas costs of sending the Deploy in question. By default, ",(0,o.kt)("inlineCode",{parentName:"p"},"speculative_exec")," is disabled on a node."),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"speculative_exec")," can be enabled within ",(0,o.kt)("em",{parentName:"p"},"config.toml")," by changing ",(0,o.kt)("inlineCode",{parentName:"p"},"enable_server")," to ",(0,o.kt)("inlineCode",{parentName:"p"},"true")," under the configuration options for the speculative execution JSON-RPC HTTP server."),(0,o.kt)("p",null,"Node operators may also change the incoming request port for speculative execution, which defaults to ",(0,o.kt)("inlineCode",{parentName:"p"},"7778"),". Further, you can choose to alter the ",(0,o.kt)("inlineCode",{parentName:"p"},"qps_limit")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"max_body_bytes"),", which limit the amount and size of requests to the speculative execution server."),(0,o.kt)("h4",{id:"example-configtoml-configuration-with-speculative-execution-enabled"},"Example Config.toml configuration with speculative execution enabled"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"# ========================================================================\n# Configuration options for the speculative execution JSON-RPC HTTP server\n# ========================================================================\n[speculative_exec_server]\n\n# Flag which enables the speculative execution JSON-RPC HTTP server.\nenable_server = true\n\n# Listening address for speculative execution JSON-RPC HTTP server. If the port\n# is set to 0, a random port will be used.\n#\n# If the specified port cannot be bound to, a random port will be tried instead.\n# If binding fails, the speculative execution JSON-RPC HTTP server will not run,\n# but the node will be otherwise unaffected.\n#\n# The actual bound address will be reported via a log line if logging is enabled.\naddress = '0.0.0.0:7778'\n\n# The global max rate of requests (per second) before they are limited.\n# Request will be delayed to the next 1 second bucket once limited.\nqps_limit = 1\n\n# Maximum number of bytes to accept in a single request body.\nmax_body_bytes = 2_621_440\n\n# Specifies which origin will be reported as allowed by speculative execution server.\n#\n# If left empty, CORS will be disabled.\n# If set to '*', any origin is allowed.\n# Otherwise, only a specified origin is allowed. The given string must conform to the [origin scheme](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin).\ncors_origin = ''\n\n")),(0,o.kt)("h2",{id:"client-installation"},"Rust Client Installation"),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"/developers/prerequisites#the-casper-command-line-client"},"Prerequisites")," page lists installation instructions for the Casper client, which is useful for generating keys and retrieving information from the network."),(0,o.kt)("h2",{id:"create-fund-keys"},"Creating Keys and Funding Accounts"),(0,o.kt)("p",null,"The following command will create keys in the ",(0,o.kt)("inlineCode",{parentName:"p"},"/etc/casper/validator_keys")," folder."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client keygen /etc/casper/validator_keys\n")),(0,o.kt)("p",null,"To learn about other options for generating keys, see ",(0,o.kt)("a",{parentName:"p",href:"/concepts/accounts-and-keys"},"Accounts and Cryptographic Keys")," or run the Rust client ",(0,o.kt)("inlineCode",{parentName:"p"},"keygen")," command with the ",(0,o.kt)("inlineCode",{parentName:"p"},"--help")," option."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client keygen --help\n")),(0,o.kt)("p",null,"More about keys and key generation can also be found in ",(0,o.kt)("inlineCode",{parentName:"p"},"/etc/casper/validator_keys/README.md")," if the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node-launcher")," was installed from the Debian package."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Save your keys in a secure location, preferably offline.")),(0,o.kt)("p",null,"To submit a bonding request, you will need to ",(0,o.kt)("a",{parentName:"p",href:"/developers/prerequisites#fund-your-account"},"fund your account")," as well."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9b4bb048.a6783ade.js b/assets/js/9b4bb048.a251fedd.js similarity index 98% rename from assets/js/9b4bb048.a6783ade.js rename to assets/js/9b4bb048.a251fedd.js index 127520862e..f059601698 100644 --- a/assets/js/9b4bb048.a6783ade.js +++ b/assets/js/9b4bb048.a251fedd.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6171],{3905:function(e,t,r){r.d(t,{Zo:function(){return l},kt:function(){return f}});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),c=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l=function(e){var t=c(e.components);return n.createElement(u.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),p=c(r),m=o,f=p["".concat(u,".").concat(m)]||p[m]||d[m]||i;return r?n.createElement(f,a(a({ref:t},l),{},{components:r})):n.createElement(f,a({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=m;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[p]="string"==typeof e?e:o,a[1]=s;for(var c=2;c=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),c=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l=function(e){var t=c(e.components);return n.createElement(u.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),p=c(r),m=o,f=p["".concat(u,".").concat(m)]||p[m]||d[m]||i;return r?n.createElement(f,a(a({ref:t},l),{},{components:r})):n.createElement(f,a({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=m;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[p]="string"==typeof e?e:o,a[1]=s;for(var c=2;c=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(a),m=r,h=p["".concat(l,".").concat(m)]||p[m]||d[m]||o;return a?n.createElement(h,i(i({ref:t},u),{},{components:a})):n.createElement(h,i({ref:t},u))}));function h(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;c 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.')})))?void 0:a.filter(Boolean))?t:[]}(e).map((function(e){var t=e.props;return{value:t.value,label:t.label,attributes:t.attributes,default:t.default}}))}function d(e){var t=e.values,a=e.children;return(0,r.useMemo)((function(){var e=null!=t?t:p(a);return function(e){var t=(0,c.l)(e,(function(e,t){return e.value===t.value}));if(t.length>0)throw new Error('Docusaurus error: Duplicate values "'+t.map((function(e){return e.value})).join(", ")+'" found in . Every value needs to be unique.')}(e),e}),[t,a])}function m(e){var t=e.value;return e.tabValues.some((function(e){return e.value===t}))}function h(e){var t=e.queryString,a=void 0!==t&&t,n=e.groupId,o=(0,s.k6)(),i=function(e){var t=e.queryString,a=void 0!==t&&t,n=e.groupId;if("string"==typeof a)return a;if(!1===a)return null;if(!0===a&&!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 null!=n?n:null}({queryString:a,groupId:n});return[(0,l._X)(i),(0,r.useCallback)((function(e){if(i){var t=new URLSearchParams(o.location.search);t.set(i,e),o.replace(Object.assign({},o.location,{search:t.toString()}))}}),[i,o])]}function f(e){var t,a,n,o,i=e.defaultValue,s=e.queryString,l=void 0!==s&&s,c=e.groupId,p=d(e),f=(0,r.useState)((function(){return function(e){var t,a=e.defaultValue,n=e.tabValues;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(a){if(!m({value:a,tabValues:n}))throw new Error('Docusaurus error: The has a defaultValue "'+a+'" but none of its children has the corresponding value. Available values are: '+n.map((function(e){return e.value})).join(", ")+". If you intend to show no default tab, use defaultValue={null} instead.");return a}var r=null!=(t=n.find((function(e){return e.default})))?t:n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:i,tabValues:p})})),g=f[0],b=f[1],k=h({queryString:l,groupId:c}),y=k[0],v=k[1],w=(t=function(e){return e?"docusaurus.tab."+e:null}({groupId:c}.groupId),a=(0,u.Nk)(t),n=a[0],o=a[1],[n,(0,r.useCallback)((function(e){t&&o.set(e)}),[t,o])]),N=w[0],T=w[1],x=function(){var e=null!=y?y:N;return m({value:e,tabValues:p})?e:null}();return(0,r.useLayoutEffect)((function(){x&&b(x)}),[x]),{selectedValue:g,selectValue:(0,r.useCallback)((function(e){if(!m({value:e,tabValues:p}))throw new Error("Can't select invalid tab value="+e);b(e),v(e),T(e)}),[v,T,p]),tabValues:p}}var g=a(2389),b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){var t=e.className,a=e.block,s=e.selectedValue,l=e.selectValue,c=e.tabValues,u=[],p=(0,i.o5)().blockElementScrollPositionUntilNextRender,d=function(e){var t=e.currentTarget,a=u.indexOf(t),n=c[a].value;n!==s&&(p(t),l(n))},m=function(e){var t,a=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":var n,r=u.indexOf(e.currentTarget)+1;a=null!=(n=u[r])?n:u[0];break;case"ArrowLeft":var o,i=u.indexOf(e.currentTarget)-1;a=null!=(o=u[i])?o:u[u.length-1]}null==(t=a)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":a},t)},c.map((function(e){var t=e.value,a=e.label,i=e.attributes;return r.createElement("li",(0,n.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:function(e){return u.push(e)},onKeyDown:m,onClick:d},i,{className:(0,o.Z)("tabs__item",b.tabItem,null==i?void 0:i.className,{"tabs__item--active":s===t})}),null!=a?a:t)})))}function y(e){var t=e.lazy,a=e.children,n=e.selectedValue,o=(Array.isArray(a)?a:[a]).filter(Boolean);if(t){var i=o.find((function(e){return e.props.value===n}));return i?(0,r.cloneElement)(i,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map((function(e,t){return(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==n})})))}function v(e){var t=f(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",b.tabList)},r.createElement(k,(0,n.Z)({},e,t)),r.createElement(y,(0,n.Z)({},e,t)))}function w(e){var t=(0,g.Z)();return r.createElement(v,(0,n.Z)({key:String(t)},e))}},2229:function(e,t,a){a.r(t),a.d(t,{assets:function(){return d},contentTitle:function(){return u},default:function(){return g},frontMatter:function(){return c},metadata:function(){return p},toc:function(){return m}});var n=a(7462),r=a(3366),o=(a(7294),a(3905)),i=(a(4996),a(4866)),s=a(5162),l=["components"],c={title:"Move to Casper"},u="Moving to Casper from another Blockchain",p={unversionedId:"resources/moving-to-casper",id:"resources/moving-to-casper",title:"Move to Casper",description:"moving-to-casper}",source:"@site/source/docs/casper/resources/moving-to-casper.md",sourceDirName:"resources",slug:"/resources/moving-to-casper",permalink:"/resources/moving-to-casper",draft:!1,editUrl:"https://github.com/casper-network/docs/tree/dev/source/docs/casper/resources/moving-to-casper.md",tags:[],version:"current",lastUpdatedAt:1707837031,formattedLastUpdatedAt:"Feb 13, 2024",frontMatter:{title:"Move to Casper"},sidebar:"resources",previous:{title:"Build on Casper",permalink:"/resources/build-on-casper/introduction"},next:{title:"Casper Token Standards",permalink:"/resources/tokens/"}},d={},m=[{value:"Smart Contract Platform",id:"contract-overview",level:2},{value:"Variable Storage and State Management",id:"variable-storage",level:2},{value:"Contract Functions",id:"contract-functions",level:2},{value:"Passing Arguments",id:"passing-arguments",level:2},{value:"Additional Considerations",id:"additional-considerations",level:2}],h={toc:m},f="wrapper";function g(e){var t=e.components,a=(0,r.Z)(e,l);return(0,o.kt)(f,(0,n.Z)({},h,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"moving-to-casper"},"Moving to Casper from another Blockchain"),(0,o.kt)("p",null,"This page covers various considerations for moving to Casper from another blockchain by comparing Casper to Ethereum, Near, Aptos, and Solana in these aspects:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"#contract-overview"},"Smart Contract Platform Overview")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"#variable-storage"},"Variable Storage and State Management")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"#contract-functions"},"Contract Functions")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"#passing-arguments"},"Passing Arguments"))),(0,o.kt)("p",null,"Since other blockchain projects use different technologies, it is essential to consider how those technologies serve your use case."),(0,o.kt)("p",null,"When choosing a blockchain, it is also essential to compare consensus mechanisms, tokenomics, cross-contract capabilities, contract upgradability, and software development kits (SDKs) as described ",(0,o.kt)("a",{parentName:"p",href:"#additional-considerations"},"here"),"."),(0,o.kt)("h2",{id:"contract-overview"},"Smart Contract Platform"),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{value:"Casper",label:"Casper",mdxType:"TabItem"},(0,o.kt)("p",null,"Casper smart contracts are written in Rust."),(0,o.kt)("p",null,"Variables defined within the smart contract can be stored as either ",(0,o.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_chain#namedkey"},"Named Keys")," or ",(0,o.kt)("a",{parentName:"p",href:"/concepts/dictionaries"},"Dictionaries")," as described in ",(0,o.kt)("a",{parentName:"p",href:"/concepts/design/reading-and-writing-to-the-blockchain"},"Reading and Writing Data to the Blockchain"),"."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function serves as the main entry point of the ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/simple-contract"},"smart contract"),". It automatically executes when the smart contract is installed, setting the initial state of the contract and defining all other entry points."),(0,o.kt)("p",null,"It's worth noting that Casper only supports public entry points for contracts. Additionally, contracts can be defined as upgradable or immutable as described ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/upgrading-contracts"},"here"),".")),(0,o.kt)(s.Z,{value:"Ethereum",label:"Ethereum",mdxType:"TabItem"},(0,o.kt)("p",null,"Ethereum smart contracts are primarily written in Solidity, a programming language specifically designed for this purpose. These contracts comprise a collection of global variables that persist on the blockchain and define the contract's state."),(0,o.kt)("p",null,"Furthermore, Ethereum smart contracts feature a constructor that specifies an initial state after deployment on the blockchain. Public functions declared within the contract can be invoked from outside the blockchain."),(0,o.kt)("p",null,'In terms of immutability, Ethereum smart contracts are inherently immutable once deployed. However, design patterns such as "Proxy" or "Diamond" facilitate versioning contracts on the Ethereum blockchain.'),(0,o.kt)("p",null,"Solidity smart contracts adhere to object-oriented programming principles and support features such as inheritance and libraries.")),(0,o.kt)(s.Z,{value:"Near",label:"Near",mdxType:"TabItem"},(0,o.kt)("p",null,"Near smart contracts can be written in JavaScript or Rust, and the Near SDK can pack the code with lightweight runtime. This can be compiled into a single WebAssembly file and deployed on the NEAR network."),(0,o.kt)("p",null,'In the Near ecosystem, smart contracts function as classes. The constructor, referred to as the "init" method, can receive attributes required for initializing the contract\'s initial state.'),(0,o.kt)("p",null,"All public methods defined within the contract serve as its interface, exposing its functionality."),(0,o.kt)("p",null,"Near smart contracts are immutable, but their state can change as transactions are executed. Contracts can also be upgraded by deploying new versions of the contract. The Near blockchain provides various capabilities for versioning, including state migrations, state versioning, and contract self-updates.")),(0,o.kt)(s.Z,{value:"Aptos",label:"Aptos",mdxType:"TabItem"},(0,o.kt)("p",null,"The Aptos programming language is known as Move. Its primary concepts revolve around scripts and modules. Scripts enable developers to incorporate additional logic into transactions, while modules allow them to expand blockchain functionality or create custom smart contracts."),(0,o.kt)("p",null,"A distinctive feature of Move is the concept of Resources, which are specialized structures representing assets. This design allows resources to be managed similarly to other data types in Aptos, such as vectors or structs."),(0,o.kt)("p",null,"A smart contract in the Aptos blockchain is called a Module. It is always connected with an account address. The modules have to be compiled to call functions in the Module."),(0,o.kt)("p",null,"The Module's public methods are its interface and can be invoked from code outside the blockchain."),(0,o.kt)("p",null,"Module code can be upgraded and changed under the account address, which does not change. The upgrade is only accepted if the code is backward compatible.")),(0,o.kt)(s.Z,{value:"Solana",label:"Solana",mdxType:"TabItem"},(0,o.kt)("p",null,"Solana smart contracts are primarily written in Rust."),(0,o.kt)("p",null,"Unlike other blockchain platforms, Solana's smart contracts are stateless and solely focus on program logic. The management of the contract state is handled at the account level, separating the state stored within the account and the contract logic defined in the programs."),(0,o.kt)("p",null,"Smart contracts are commonly referred to as on-chain programs. These programs expose their interface as a public entry point, allowing external interaction."),(0,o.kt)("p",null,'It is worth noting that Solana programs can be updated using an authority known as the "update authority," which holds the necessary permissions for making modifications to the program.'))),(0,o.kt)("h2",{id:"variable-storage"},"Variable Storage and State Management"),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{value:"Casper",label:"Casper",mdxType:"TabItem"},(0,o.kt)("p",null,"Variables can be stored as Named Keys or Dictionaries as described in ",(0,o.kt)("a",{parentName:"p",href:"/concepts/design/reading-and-writing-to-the-blockchain"},"Reading and Writing Data to the Blockchain"),"."),(0,o.kt)("p",null,"Additionally, local variables are available within the entry points and can be used to perform necessary actions or computations within the scope of each entry point.")),(0,o.kt)(s.Z,{value:"Ethereum",label:"Ethereum",mdxType:"TabItem"},(0,o.kt)("p",null,"The variables within the contract are responsible for storing the state of the contract at a specific moment in time. However, it's important to note that local variables used within the call functions are not stored in the contract's state. Instead, they are employed solely for computational purposes within those specific functions."),(0,o.kt)("p",null,"State variables must be strongly typed so that the smart contract compiler can enforce type consistency and ensure the storage space aligns with the declared data types. Strong typing promotes code correctness and prevents potential data corruption or memory-related issues related to the contract's state variables.")),(0,o.kt)(s.Z,{value:"Near",label:"Near",mdxType:"TabItem"},(0,o.kt)("p",null,"Variables in the contract can be stored as native types, SDK collections, or internal structures. SDK collections offer advantages over native types."),(0,o.kt)("p",null,"Additionally, there is a distinction between class attributes and local variables. Class attributes represent the state of the contract, while local variables are specific to the invocation of a function and have no impact on the contract's overall state."),(0,o.kt)("p",null,"SDK Collections are typical when creating state variables because they provide convenient data structures such as lists, maps, and sets. These data structures can organize and manage complex data within the contract's storage. Using SDK Collections ensures efficient storage and facilitates easier access and data management in the smart contract.")),(0,o.kt)(s.Z,{value:"Aptos",label:"Aptos",mdxType:"TabItem"},(0,o.kt)("p",null,"Aptos employs primitive types, such as integers, booleans, and addresses, to represent variables. These elementary types can be combined to create structures, but it's important to note that struct definitions are only permitted within Modules."),(0,o.kt)("p",null,"Aptos advises developers to cluster related data into Resources for efficient data management and organization. Resources represent assets or specific data entities on the blockchain. By grouping data into Resources, you can maintain logical coherence and improve the readability and maintainability of the code."),(0,o.kt)("p",null,"The Aptos blockchain introduces a tree-shaped persistent global storage that allows read and write operations. Global storage consists of trees originating from an account address.")),(0,o.kt)(s.Z,{value:"Solana",label:"Solana",mdxType:"TabItem"},(0,o.kt)("p",null,"Variables can be utilized locally within the execution context of a specific entry point. They are limited to the scope of that entry point and not accessible outside of it. These variables can be defined as elementary types such as bool, String, int, etc."),(0,o.kt)("p",null,"Data persists in structs within the account. The Binary Object Representation Serializer for Hashing (Borsh) facilitates the serialization and deserialization of these structs. The process involves reading the data from the account, deserializing it to obtain the values it contains, updating the values, and then serializing the modified data to save the new values back into the account."))),(0,o.kt)("h2",{id:"contract-functions"},"Contract Functions"),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{value:"Casper",label:"Casper",mdxType:"TabItem"},(0,o.kt)("p",null,"For Casper smart contracts, public functions are called entry points. To declare them, the following format is used:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn counter_inc() {\n\n // Entry point body\n}\n')),(0,o.kt)("p",null,"It's important to note that entry points do not have input arguments in their definition, but the arguments can be accessed using the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/struct.RuntimeArgs.html"},"RuntimeArgs")," passed to the contract. Entry points are instantiated within the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," entry point."),(0,o.kt)("p",null,"If a return value is needed, it should be declared using the syntax described in the ",(0,o.kt)("a",{parentName:"p",href:"/resources/tutorials/advanced/return-values-tutorial"},"Interacting with Runtime Return Values")," tutorial."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"runtime::ret(value);\n")),(0,o.kt)("p",null,"Each call to an entry point is treated as a ",(0,o.kt)("a",{parentName:"p",href:"/deploy-and-deploy-lifecycle"},"Deploy")," to the network, and therefore, each call incurs a cost paid in motes (the network's native accounting unit).")),(0,o.kt)(s.Z,{value:"Ethereum",label:"Ethereum",mdxType:"TabItem"},(0,o.kt)("p",null,"On Ethereum, public methods serve two purposes: they can be used to execute contract logic and modify the contract's state, or they can be utilized to retrieve data stored within the contract's state."),(0,o.kt)("p",null,"The declaration of public methods in Ethereum follows the format:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"function update_name(string value) public {\n dapp_name = value;\n}\n")),(0,o.kt)("p",null,"In cases where a public method only returns a value without modifying the state, it should be defined as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"function balanceOf(address _owner) public view returns (uint256 return_parameter) { }\n")),(0,o.kt)("p",null,"It is worth noting that public view methods on Ethereum, which solely retrieve data without making state changes, do not consume gas.")),(0,o.kt)(s.Z,{value:"Near",label:"Near",mdxType:"TabItem"},(0,o.kt)("p",null,"In the Near blockchain, there are three types of public functions:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Init Methods")," - These are used as the class constructors to initialize the state of the contract."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"View Methods")," - These functions are used to read the state of the contract variables."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Call Methods")," - These methods can mutate the state of the contract and perform specific actions, such as calling another contract.")),(0,o.kt)("p",null,"The definition of public methods in Near is as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"pub fn add_message(&mut self, ...) { }\n")),(0,o.kt)("p",null,"For public methods that return variables, the definition would be:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"pub fn get_messages(&self, from_index: Option, limit: Option) -> Vec { }\n")),(0,o.kt)("p",null,"The actual implementation of the functions may include the necessary parameters and logic based on the contract's specific requirements.")),(0,o.kt)(s.Z,{value:"Aptos",label:"Aptos",mdxType:"TabItem"},(0,o.kt)("p",null,"Public functions in Aptos are similar to public methods or functions found in other blockchain networks. The definition of a public function in Aptos appears as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"public fun start_collection(account: &signer) {}\n")),(0,o.kt)("p",null,"For public functions that return variables, the definition would be as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"public fun max(a: u8, b: u8): (u8, bool) {}\n")),(0,o.kt)("p",null,"In the Aptos blockchain, it is possible to return one or more values from a function.")),(0,o.kt)(s.Z,{value:"Solana",label:"Solana",mdxType:"TabItem"},(0,o.kt)("p",null,"In Solana, functions are defined as public entry points that act as interfaces visible to the network. The declaration of an entry point follows this format:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"entrypoint!(process_instruction);\n")),(0,o.kt)("p",null,"The implementation of the entry point may resemble the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"pub fn process_instruction(\n program_id: &Pubkey,\n accounts: &[AccountInfo],\n _instruction_data: &[u8],\n) -> ProgramResult {}\n")),(0,o.kt)("p",null,"Within the entry point function, the necessary parameters are specified, such as ",(0,o.kt)("inlineCode",{parentName:"p"},"program_id"),", which represents the program's identifier, ",(0,o.kt)("inlineCode",{parentName:"p"},"accounts"),", an array of ",(0,o.kt)("inlineCode",{parentName:"p"},"AccountInfo")," providing account details, and ",(0,o.kt)("inlineCode",{parentName:"p"},"_instruction_data"),", representing the instruction data received. The function returns a ",(0,o.kt)("inlineCode",{parentName:"p"},"ProgramResult"),", which indicates the success or failure of the instruction execution."))),(0,o.kt)("h2",{id:"passing-arguments"},"Passing Arguments"),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{value:"Casper",label:"Casper",mdxType:"TabItem"},(0,o.kt)("p",null,"Named arguments are passed as strings with type specifiers. To provide session arguments to the entry point during a Deploy, you can utilize the following approach:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n')),(0,o.kt)("p",null,"To understand the context of this example, refer to: ",(0,o.kt)("a",{parentName:"p",href:"/developers/cli/delegate"},"Delegating with the Casper Client"),"."),(0,o.kt)("p",null,"In the contract, you can access the session arguments as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"let uref: URef = runtime::get_key(Key_Name)\n")),(0,o.kt)("p",null,"Use the ",(0,o.kt)("inlineCode",{parentName:"p"},"get_key")," function to retrieve the desired session argument by specifying the key's name."),(0,o.kt)("p",null,"If you are uncertain how to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"get_key")," function to obtain a specific session argument, check how to ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/simple-contract"},"write a basic smart contract on Casper"),".")),(0,o.kt)(s.Z,{value:"Ethereum",label:"Ethereum",mdxType:"TabItem"},(0,o.kt)("p",null,"Ethereum uses strongly typed function arguments, and developers must explicitly define the input and return variables. The compiler checks the correctness of the arguments passed to the functions during runtime. As a result, developers must explicitly specify the argument and return types in the function signature. The compiler ensures that the provided arguments adhere to the specified types, helping to catch type-related errors and ensure type safety."),(0,o.kt)("p",null,"By enforcing strong typing, the compiler helps prevent potential runtime errors and enhances code reliability by verifying the compatibility of the passed arguments and expected return types.")),(0,o.kt)(s.Z,{value:"Near",label:"Near",mdxType:"TabItem"},(0,o.kt)("p",null,"Strongly typed function arguments require explicitly defining the input and return variables. By enforcing strong typing, the programming language ensures that the arguments passed to a function match the expected types, preventing type-related errors and promoting code correctness. Strong typing provides additional clarity and safety by explicitly stating the data types of the function's inputs and outputs.")),(0,o.kt)(s.Z,{value:"Aptos",label:"Aptos",mdxType:"TabItem"},(0,o.kt)("p",null,"Like Near, Aptos requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness.")),(0,o.kt)(s.Z,{value:"Solana",label:"Solana",mdxType:"TabItem"},(0,o.kt)("p",null,"Like Near and Aptos, Solana requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness."))),(0,o.kt)("h2",{id:"additional-considerations"},"Additional Considerations"),(0,o.kt)("p",null,"When choosing a blockchain, you may also look into the network's consensus mechanism, the tokenomics or economic model, cross-contract communication, smart contract upgrades, and the available software development kits (SDKs)."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("strong",{parentName:"p"},"Consensus mechanism")," refers to the algorithm the blockchain network uses to achieve agreement on the validity and ordering of transactions. Different blockchains employ various consensus mechanisms such as Proof-of-Work (PoW), Proof-of-Stake (PoS), or Delegated Proof-of-Stake (DPoS). The choice of consensus mechanism impacts factors like security, scalability, and energy efficiency.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("strong",{parentName:"p"},"Tokenomics")," relates to the economic model of the blockchain network and its native tokens, involving token distribution, inflation, utility, and governance. Understanding the tokenomics of the network is crucial for evaluating the ecosystem's long-term viability and potential value.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("strong",{parentName:"p"},"Cross-contract capabilities")," refer to the ability of smart contracts to interact and communicate within the blockchain network. This feature is essential for building complex decentralized applications (dApps) and implementing inter-contract functionality.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("strong",{parentName:"p"},"Contract upgradability")," determines whether the smart contracts installed on the network can be modified or updated after installation. It is essential to assess the flexibility of the chosen blockchain in terms of contract maintenance, bug fixes, and incorporating new features or improvements without disrupting the existing ecosystem.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("strong",{parentName:"p"},"SDK availability")," also plays a significant role in the development process. SDKs provide tools, libraries, and documentation to simplify the creation of applications and smart contracts on the blockchain. Evaluating the maturity, community support, and compatibility of the available SDKs is crucial for developers."))),(0,o.kt)("p",null,"Considering these aspects helps when selecting a blockchain that aligns with a project or application's specific requirements and goals."),(0,o.kt)("p",null,"The Casper ecosystem aims to fulfill all of these aspects, including supporting enterprise-grade projects."))}g.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[319],{3905:function(e,t,a){a.d(t,{Zo:function(){return u},kt:function(){return h}});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(a),m=r,h=p["".concat(l,".").concat(m)]||p[m]||d[m]||o;return a?n.createElement(h,i(i({ref:t},u),{},{components:a})):n.createElement(h,i({ref:t},u))}));function h(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;c 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.')})))?void 0:a.filter(Boolean))?t:[]}(e).map((function(e){var t=e.props;return{value:t.value,label:t.label,attributes:t.attributes,default:t.default}}))}function d(e){var t=e.values,a=e.children;return(0,r.useMemo)((function(){var e=null!=t?t:p(a);return function(e){var t=(0,c.l)(e,(function(e,t){return e.value===t.value}));if(t.length>0)throw new Error('Docusaurus error: Duplicate values "'+t.map((function(e){return e.value})).join(", ")+'" found in . Every value needs to be unique.')}(e),e}),[t,a])}function m(e){var t=e.value;return e.tabValues.some((function(e){return e.value===t}))}function h(e){var t=e.queryString,a=void 0!==t&&t,n=e.groupId,o=(0,s.k6)(),i=function(e){var t=e.queryString,a=void 0!==t&&t,n=e.groupId;if("string"==typeof a)return a;if(!1===a)return null;if(!0===a&&!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 null!=n?n:null}({queryString:a,groupId:n});return[(0,l._X)(i),(0,r.useCallback)((function(e){if(i){var t=new URLSearchParams(o.location.search);t.set(i,e),o.replace(Object.assign({},o.location,{search:t.toString()}))}}),[i,o])]}function f(e){var t,a,n,o,i=e.defaultValue,s=e.queryString,l=void 0!==s&&s,c=e.groupId,p=d(e),f=(0,r.useState)((function(){return function(e){var t,a=e.defaultValue,n=e.tabValues;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(a){if(!m({value:a,tabValues:n}))throw new Error('Docusaurus error: The has a defaultValue "'+a+'" but none of its children has the corresponding value. Available values are: '+n.map((function(e){return e.value})).join(", ")+". If you intend to show no default tab, use defaultValue={null} instead.");return a}var r=null!=(t=n.find((function(e){return e.default})))?t:n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:i,tabValues:p})})),g=f[0],b=f[1],k=h({queryString:l,groupId:c}),y=k[0],v=k[1],w=(t=function(e){return e?"docusaurus.tab."+e:null}({groupId:c}.groupId),a=(0,u.Nk)(t),n=a[0],o=a[1],[n,(0,r.useCallback)((function(e){t&&o.set(e)}),[t,o])]),N=w[0],T=w[1],x=function(){var e=null!=y?y:N;return m({value:e,tabValues:p})?e:null}();return(0,r.useLayoutEffect)((function(){x&&b(x)}),[x]),{selectedValue:g,selectValue:(0,r.useCallback)((function(e){if(!m({value:e,tabValues:p}))throw new Error("Can't select invalid tab value="+e);b(e),v(e),T(e)}),[v,T,p]),tabValues:p}}var g=a(2389),b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){var t=e.className,a=e.block,s=e.selectedValue,l=e.selectValue,c=e.tabValues,u=[],p=(0,i.o5)().blockElementScrollPositionUntilNextRender,d=function(e){var t=e.currentTarget,a=u.indexOf(t),n=c[a].value;n!==s&&(p(t),l(n))},m=function(e){var t,a=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":var n,r=u.indexOf(e.currentTarget)+1;a=null!=(n=u[r])?n:u[0];break;case"ArrowLeft":var o,i=u.indexOf(e.currentTarget)-1;a=null!=(o=u[i])?o:u[u.length-1]}null==(t=a)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":a},t)},c.map((function(e){var t=e.value,a=e.label,i=e.attributes;return r.createElement("li",(0,n.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:function(e){return u.push(e)},onKeyDown:m,onClick:d},i,{className:(0,o.Z)("tabs__item",b.tabItem,null==i?void 0:i.className,{"tabs__item--active":s===t})}),null!=a?a:t)})))}function y(e){var t=e.lazy,a=e.children,n=e.selectedValue,o=(Array.isArray(a)?a:[a]).filter(Boolean);if(t){var i=o.find((function(e){return e.props.value===n}));return i?(0,r.cloneElement)(i,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map((function(e,t){return(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==n})})))}function v(e){var t=f(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",b.tabList)},r.createElement(k,(0,n.Z)({},e,t)),r.createElement(y,(0,n.Z)({},e,t)))}function w(e){var t=(0,g.Z)();return r.createElement(v,(0,n.Z)({key:String(t)},e))}},2229:function(e,t,a){a.r(t),a.d(t,{assets:function(){return d},contentTitle:function(){return u},default:function(){return g},frontMatter:function(){return c},metadata:function(){return p},toc:function(){return m}});var n=a(7462),r=a(3366),o=(a(7294),a(3905)),i=(a(4996),a(4866)),s=a(5162),l=["components"],c={title:"Move to Casper"},u="Moving to Casper from another Blockchain",p={unversionedId:"resources/moving-to-casper",id:"resources/moving-to-casper",title:"Move to Casper",description:"moving-to-casper}",source:"@site/source/docs/casper/resources/moving-to-casper.md",sourceDirName:"resources",slug:"/resources/moving-to-casper",permalink:"/resources/moving-to-casper",draft:!1,editUrl:"https://github.com/casper-network/docs/tree/dev/source/docs/casper/resources/moving-to-casper.md",tags:[],version:"current",lastUpdatedAt:1708091908,formattedLastUpdatedAt:"Feb 16, 2024",frontMatter:{title:"Move to Casper"},sidebar:"resources",previous:{title:"Build on Casper",permalink:"/resources/build-on-casper/introduction"},next:{title:"Casper Token Standards",permalink:"/resources/tokens/"}},d={},m=[{value:"Smart Contract Platform",id:"contract-overview",level:2},{value:"Variable Storage and State Management",id:"variable-storage",level:2},{value:"Contract Functions",id:"contract-functions",level:2},{value:"Passing Arguments",id:"passing-arguments",level:2},{value:"Additional Considerations",id:"additional-considerations",level:2}],h={toc:m},f="wrapper";function g(e){var t=e.components,a=(0,r.Z)(e,l);return(0,o.kt)(f,(0,n.Z)({},h,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"moving-to-casper"},"Moving to Casper from another Blockchain"),(0,o.kt)("p",null,"This page covers various considerations for moving to Casper from another blockchain by comparing Casper to Ethereum, Near, Aptos, and Solana in these aspects:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"#contract-overview"},"Smart Contract Platform Overview")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"#variable-storage"},"Variable Storage and State Management")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"#contract-functions"},"Contract Functions")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"#passing-arguments"},"Passing Arguments"))),(0,o.kt)("p",null,"Since other blockchain projects use different technologies, it is essential to consider how those technologies serve your use case."),(0,o.kt)("p",null,"When choosing a blockchain, it is also essential to compare consensus mechanisms, tokenomics, cross-contract capabilities, contract upgradability, and software development kits (SDKs) as described ",(0,o.kt)("a",{parentName:"p",href:"#additional-considerations"},"here"),"."),(0,o.kt)("h2",{id:"contract-overview"},"Smart Contract Platform"),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{value:"Casper",label:"Casper",mdxType:"TabItem"},(0,o.kt)("p",null,"Casper smart contracts are written in Rust."),(0,o.kt)("p",null,"Variables defined within the smart contract can be stored as either ",(0,o.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_chain#namedkey"},"Named Keys")," or ",(0,o.kt)("a",{parentName:"p",href:"/concepts/dictionaries"},"Dictionaries")," as described in ",(0,o.kt)("a",{parentName:"p",href:"/concepts/design/reading-and-writing-to-the-blockchain"},"Reading and Writing Data to the Blockchain"),"."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function serves as the main entry point of the ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/simple-contract"},"smart contract"),". It automatically executes when the smart contract is installed, setting the initial state of the contract and defining all other entry points."),(0,o.kt)("p",null,"It's worth noting that Casper only supports public entry points for contracts. Additionally, contracts can be defined as upgradable or immutable as described ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/upgrading-contracts"},"here"),".")),(0,o.kt)(s.Z,{value:"Ethereum",label:"Ethereum",mdxType:"TabItem"},(0,o.kt)("p",null,"Ethereum smart contracts are primarily written in Solidity, a programming language specifically designed for this purpose. These contracts comprise a collection of global variables that persist on the blockchain and define the contract's state."),(0,o.kt)("p",null,"Furthermore, Ethereum smart contracts feature a constructor that specifies an initial state after deployment on the blockchain. Public functions declared within the contract can be invoked from outside the blockchain."),(0,o.kt)("p",null,'In terms of immutability, Ethereum smart contracts are inherently immutable once deployed. However, design patterns such as "Proxy" or "Diamond" facilitate versioning contracts on the Ethereum blockchain.'),(0,o.kt)("p",null,"Solidity smart contracts adhere to object-oriented programming principles and support features such as inheritance and libraries.")),(0,o.kt)(s.Z,{value:"Near",label:"Near",mdxType:"TabItem"},(0,o.kt)("p",null,"Near smart contracts can be written in JavaScript or Rust, and the Near SDK can pack the code with lightweight runtime. This can be compiled into a single WebAssembly file and deployed on the NEAR network."),(0,o.kt)("p",null,'In the Near ecosystem, smart contracts function as classes. The constructor, referred to as the "init" method, can receive attributes required for initializing the contract\'s initial state.'),(0,o.kt)("p",null,"All public methods defined within the contract serve as its interface, exposing its functionality."),(0,o.kt)("p",null,"Near smart contracts are immutable, but their state can change as transactions are executed. Contracts can also be upgraded by deploying new versions of the contract. The Near blockchain provides various capabilities for versioning, including state migrations, state versioning, and contract self-updates.")),(0,o.kt)(s.Z,{value:"Aptos",label:"Aptos",mdxType:"TabItem"},(0,o.kt)("p",null,"The Aptos programming language is known as Move. Its primary concepts revolve around scripts and modules. Scripts enable developers to incorporate additional logic into transactions, while modules allow them to expand blockchain functionality or create custom smart contracts."),(0,o.kt)("p",null,"A distinctive feature of Move is the concept of Resources, which are specialized structures representing assets. This design allows resources to be managed similarly to other data types in Aptos, such as vectors or structs."),(0,o.kt)("p",null,"A smart contract in the Aptos blockchain is called a Module. It is always connected with an account address. The modules have to be compiled to call functions in the Module."),(0,o.kt)("p",null,"The Module's public methods are its interface and can be invoked from code outside the blockchain."),(0,o.kt)("p",null,"Module code can be upgraded and changed under the account address, which does not change. The upgrade is only accepted if the code is backward compatible.")),(0,o.kt)(s.Z,{value:"Solana",label:"Solana",mdxType:"TabItem"},(0,o.kt)("p",null,"Solana smart contracts are primarily written in Rust."),(0,o.kt)("p",null,"Unlike other blockchain platforms, Solana's smart contracts are stateless and solely focus on program logic. The management of the contract state is handled at the account level, separating the state stored within the account and the contract logic defined in the programs."),(0,o.kt)("p",null,"Smart contracts are commonly referred to as on-chain programs. These programs expose their interface as a public entry point, allowing external interaction."),(0,o.kt)("p",null,'It is worth noting that Solana programs can be updated using an authority known as the "update authority," which holds the necessary permissions for making modifications to the program.'))),(0,o.kt)("h2",{id:"variable-storage"},"Variable Storage and State Management"),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{value:"Casper",label:"Casper",mdxType:"TabItem"},(0,o.kt)("p",null,"Variables can be stored as Named Keys or Dictionaries as described in ",(0,o.kt)("a",{parentName:"p",href:"/concepts/design/reading-and-writing-to-the-blockchain"},"Reading and Writing Data to the Blockchain"),"."),(0,o.kt)("p",null,"Additionally, local variables are available within the entry points and can be used to perform necessary actions or computations within the scope of each entry point.")),(0,o.kt)(s.Z,{value:"Ethereum",label:"Ethereum",mdxType:"TabItem"},(0,o.kt)("p",null,"The variables within the contract are responsible for storing the state of the contract at a specific moment in time. However, it's important to note that local variables used within the call functions are not stored in the contract's state. Instead, they are employed solely for computational purposes within those specific functions."),(0,o.kt)("p",null,"State variables must be strongly typed so that the smart contract compiler can enforce type consistency and ensure the storage space aligns with the declared data types. Strong typing promotes code correctness and prevents potential data corruption or memory-related issues related to the contract's state variables.")),(0,o.kt)(s.Z,{value:"Near",label:"Near",mdxType:"TabItem"},(0,o.kt)("p",null,"Variables in the contract can be stored as native types, SDK collections, or internal structures. SDK collections offer advantages over native types."),(0,o.kt)("p",null,"Additionally, there is a distinction between class attributes and local variables. Class attributes represent the state of the contract, while local variables are specific to the invocation of a function and have no impact on the contract's overall state."),(0,o.kt)("p",null,"SDK Collections are typical when creating state variables because they provide convenient data structures such as lists, maps, and sets. These data structures can organize and manage complex data within the contract's storage. Using SDK Collections ensures efficient storage and facilitates easier access and data management in the smart contract.")),(0,o.kt)(s.Z,{value:"Aptos",label:"Aptos",mdxType:"TabItem"},(0,o.kt)("p",null,"Aptos employs primitive types, such as integers, booleans, and addresses, to represent variables. These elementary types can be combined to create structures, but it's important to note that struct definitions are only permitted within Modules."),(0,o.kt)("p",null,"Aptos advises developers to cluster related data into Resources for efficient data management and organization. Resources represent assets or specific data entities on the blockchain. By grouping data into Resources, you can maintain logical coherence and improve the readability and maintainability of the code."),(0,o.kt)("p",null,"The Aptos blockchain introduces a tree-shaped persistent global storage that allows read and write operations. Global storage consists of trees originating from an account address.")),(0,o.kt)(s.Z,{value:"Solana",label:"Solana",mdxType:"TabItem"},(0,o.kt)("p",null,"Variables can be utilized locally within the execution context of a specific entry point. They are limited to the scope of that entry point and not accessible outside of it. These variables can be defined as elementary types such as bool, String, int, etc."),(0,o.kt)("p",null,"Data persists in structs within the account. The Binary Object Representation Serializer for Hashing (Borsh) facilitates the serialization and deserialization of these structs. The process involves reading the data from the account, deserializing it to obtain the values it contains, updating the values, and then serializing the modified data to save the new values back into the account."))),(0,o.kt)("h2",{id:"contract-functions"},"Contract Functions"),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{value:"Casper",label:"Casper",mdxType:"TabItem"},(0,o.kt)("p",null,"For Casper smart contracts, public functions are called entry points. To declare them, the following format is used:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn counter_inc() {\n\n // Entry point body\n}\n')),(0,o.kt)("p",null,"It's important to note that entry points do not have input arguments in their definition, but the arguments can be accessed using the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/struct.RuntimeArgs.html"},"RuntimeArgs")," passed to the contract. Entry points are instantiated within the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," entry point."),(0,o.kt)("p",null,"If a return value is needed, it should be declared using the syntax described in the ",(0,o.kt)("a",{parentName:"p",href:"/resources/tutorials/advanced/return-values-tutorial"},"Interacting with Runtime Return Values")," tutorial."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"runtime::ret(value);\n")),(0,o.kt)("p",null,"Each call to an entry point is treated as a ",(0,o.kt)("a",{parentName:"p",href:"/deploy-and-deploy-lifecycle"},"Deploy")," to the network, and therefore, each call incurs a cost paid in motes (the network's native accounting unit).")),(0,o.kt)(s.Z,{value:"Ethereum",label:"Ethereum",mdxType:"TabItem"},(0,o.kt)("p",null,"On Ethereum, public methods serve two purposes: they can be used to execute contract logic and modify the contract's state, or they can be utilized to retrieve data stored within the contract's state."),(0,o.kt)("p",null,"The declaration of public methods in Ethereum follows the format:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"function update_name(string value) public {\n dapp_name = value;\n}\n")),(0,o.kt)("p",null,"In cases where a public method only returns a value without modifying the state, it should be defined as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"function balanceOf(address _owner) public view returns (uint256 return_parameter) { }\n")),(0,o.kt)("p",null,"It is worth noting that public view methods on Ethereum, which solely retrieve data without making state changes, do not consume gas.")),(0,o.kt)(s.Z,{value:"Near",label:"Near",mdxType:"TabItem"},(0,o.kt)("p",null,"In the Near blockchain, there are three types of public functions:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Init Methods")," - These are used as the class constructors to initialize the state of the contract."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"View Methods")," - These functions are used to read the state of the contract variables."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Call Methods")," - These methods can mutate the state of the contract and perform specific actions, such as calling another contract.")),(0,o.kt)("p",null,"The definition of public methods in Near is as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"pub fn add_message(&mut self, ...) { }\n")),(0,o.kt)("p",null,"For public methods that return variables, the definition would be:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"pub fn get_messages(&self, from_index: Option, limit: Option) -> Vec { }\n")),(0,o.kt)("p",null,"The actual implementation of the functions may include the necessary parameters and logic based on the contract's specific requirements.")),(0,o.kt)(s.Z,{value:"Aptos",label:"Aptos",mdxType:"TabItem"},(0,o.kt)("p",null,"Public functions in Aptos are similar to public methods or functions found in other blockchain networks. The definition of a public function in Aptos appears as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"public fun start_collection(account: &signer) {}\n")),(0,o.kt)("p",null,"For public functions that return variables, the definition would be as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"public fun max(a: u8, b: u8): (u8, bool) {}\n")),(0,o.kt)("p",null,"In the Aptos blockchain, it is possible to return one or more values from a function.")),(0,o.kt)(s.Z,{value:"Solana",label:"Solana",mdxType:"TabItem"},(0,o.kt)("p",null,"In Solana, functions are defined as public entry points that act as interfaces visible to the network. The declaration of an entry point follows this format:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"entrypoint!(process_instruction);\n")),(0,o.kt)("p",null,"The implementation of the entry point may resemble the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"pub fn process_instruction(\n program_id: &Pubkey,\n accounts: &[AccountInfo],\n _instruction_data: &[u8],\n) -> ProgramResult {}\n")),(0,o.kt)("p",null,"Within the entry point function, the necessary parameters are specified, such as ",(0,o.kt)("inlineCode",{parentName:"p"},"program_id"),", which represents the program's identifier, ",(0,o.kt)("inlineCode",{parentName:"p"},"accounts"),", an array of ",(0,o.kt)("inlineCode",{parentName:"p"},"AccountInfo")," providing account details, and ",(0,o.kt)("inlineCode",{parentName:"p"},"_instruction_data"),", representing the instruction data received. The function returns a ",(0,o.kt)("inlineCode",{parentName:"p"},"ProgramResult"),", which indicates the success or failure of the instruction execution."))),(0,o.kt)("h2",{id:"passing-arguments"},"Passing Arguments"),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{value:"Casper",label:"Casper",mdxType:"TabItem"},(0,o.kt)("p",null,"Named arguments are passed as strings with type specifiers. To provide session arguments to the entry point during a Deploy, you can utilize the following approach:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n')),(0,o.kt)("p",null,"To understand the context of this example, refer to: ",(0,o.kt)("a",{parentName:"p",href:"/developers/cli/delegate"},"Delegating with the Casper Client"),"."),(0,o.kt)("p",null,"In the contract, you can access the session arguments as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"let uref: URef = runtime::get_key(Key_Name)\n")),(0,o.kt)("p",null,"Use the ",(0,o.kt)("inlineCode",{parentName:"p"},"get_key")," function to retrieve the desired session argument by specifying the key's name."),(0,o.kt)("p",null,"If you are uncertain how to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"get_key")," function to obtain a specific session argument, check how to ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/simple-contract"},"write a basic smart contract on Casper"),".")),(0,o.kt)(s.Z,{value:"Ethereum",label:"Ethereum",mdxType:"TabItem"},(0,o.kt)("p",null,"Ethereum uses strongly typed function arguments, and developers must explicitly define the input and return variables. The compiler checks the correctness of the arguments passed to the functions during runtime. As a result, developers must explicitly specify the argument and return types in the function signature. The compiler ensures that the provided arguments adhere to the specified types, helping to catch type-related errors and ensure type safety."),(0,o.kt)("p",null,"By enforcing strong typing, the compiler helps prevent potential runtime errors and enhances code reliability by verifying the compatibility of the passed arguments and expected return types.")),(0,o.kt)(s.Z,{value:"Near",label:"Near",mdxType:"TabItem"},(0,o.kt)("p",null,"Strongly typed function arguments require explicitly defining the input and return variables. By enforcing strong typing, the programming language ensures that the arguments passed to a function match the expected types, preventing type-related errors and promoting code correctness. Strong typing provides additional clarity and safety by explicitly stating the data types of the function's inputs and outputs.")),(0,o.kt)(s.Z,{value:"Aptos",label:"Aptos",mdxType:"TabItem"},(0,o.kt)("p",null,"Like Near, Aptos requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness.")),(0,o.kt)(s.Z,{value:"Solana",label:"Solana",mdxType:"TabItem"},(0,o.kt)("p",null,"Like Near and Aptos, Solana requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness."))),(0,o.kt)("h2",{id:"additional-considerations"},"Additional Considerations"),(0,o.kt)("p",null,"When choosing a blockchain, you may also look into the network's consensus mechanism, the tokenomics or economic model, cross-contract communication, smart contract upgrades, and the available software development kits (SDKs)."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("strong",{parentName:"p"},"Consensus mechanism")," refers to the algorithm the blockchain network uses to achieve agreement on the validity and ordering of transactions. Different blockchains employ various consensus mechanisms such as Proof-of-Work (PoW), Proof-of-Stake (PoS), or Delegated Proof-of-Stake (DPoS). The choice of consensus mechanism impacts factors like security, scalability, and energy efficiency.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("strong",{parentName:"p"},"Tokenomics")," relates to the economic model of the blockchain network and its native tokens, involving token distribution, inflation, utility, and governance. Understanding the tokenomics of the network is crucial for evaluating the ecosystem's long-term viability and potential value.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("strong",{parentName:"p"},"Cross-contract capabilities")," refer to the ability of smart contracts to interact and communicate within the blockchain network. This feature is essential for building complex decentralized applications (dApps) and implementing inter-contract functionality.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("strong",{parentName:"p"},"Contract upgradability")," determines whether the smart contracts installed on the network can be modified or updated after installation. It is essential to assess the flexibility of the chosen blockchain in terms of contract maintenance, bug fixes, and incorporating new features or improvements without disrupting the existing ecosystem.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("strong",{parentName:"p"},"SDK availability")," also plays a significant role in the development process. SDKs provide tools, libraries, and documentation to simplify the creation of applications and smart contracts on the blockchain. Evaluating the maturity, community support, and compatibility of the available SDKs is crucial for developers."))),(0,o.kt)("p",null,"Considering these aspects helps when selecting a blockchain that aligns with a project or application's specific requirements and goals."),(0,o.kt)("p",null,"The Casper ecosystem aims to fulfill all of these aspects, including supporting enterprise-grade projects."))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9df8dea5.26dae446.js b/assets/js/9df8dea5.145e77a3.js similarity index 99% rename from assets/js/9df8dea5.26dae446.js rename to assets/js/9df8dea5.145e77a3.js index d421cf814a..e449de8c41 100644 --- a/assets/js/9df8dea5.26dae446.js +++ b/assets/js/9df8dea5.145e77a3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[4685],{3905:function(t,e,a){a.d(e,{Zo:function(){return m},kt:function(){return N}});var n=a(7294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var o=n.createContext({}),p=function(t){var e=n.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},m=function(t){var e=p(t.components);return n.createElement(o.Provider,{value:e},t.children)},s="mdxType",k={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,o=t.parentName,m=d(t,["components","mdxType","originalType","parentName"]),s=p(a),u=r,N=s["".concat(o,".").concat(u)]||s[u]||k[u]||l;return a?n.createElement(N,i(i({ref:e},m),{},{components:a})):n.createElement(N,i({ref:e},m))}));function N(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=u;var d={};for(var o in e)hasOwnProperty.call(e,o)&&(d[o]=e[o]);d.originalType=t,d[s]="string"==typeof t?t:r,i[1]=d;for(var p=2;p=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var o=n.createContext({}),p=function(t){var e=n.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},m=function(t){var e=p(t.components);return n.createElement(o.Provider,{value:e},t.children)},s="mdxType",k={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,o=t.parentName,m=d(t,["components","mdxType","originalType","parentName"]),s=p(a),u=r,N=s["".concat(o,".").concat(u)]||s[u]||k[u]||l;return a?n.createElement(N,i(i({ref:e},m),{},{components:a})):n.createElement(N,i({ref:e},m))}));function N(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=u;var d={};for(var o in e)hasOwnProperty.call(e,o)&&(d[o]=e[o]);d.originalType=t,d[s]="string"==typeof t?t:r,i[1]=d;for(var p=2;p=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),s=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=s(e.components);return o.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(n),m=r,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return n?o.createElement(f,i(i({ref:t},p),{},{components:n})):o.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[u]="string"==typeof e?e:r,i[1]=l;for(var s=2;s=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),s=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=s(e.components);return o.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(n),m=r,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return n?o.createElement(f,i(i({ref:t},p),{},{components:n})):o.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[u]="string"==typeof e?e:r,i[1]=l;for(var s=2;s=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=a.createContext({}),c=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=c(e.components);return a.createElement(p.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=c(n),h=o,f=d["".concat(p,".").concat(h)]||d[h]||u[h]||r;return n?a.createElement(f,i(i({ref:t},l),{},{components:n})):a.createElement(f,i({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=h;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var c=2;c=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=a.createContext({}),c=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=c(e.components);return a.createElement(p.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=c(n),h=o,f=d["".concat(p,".").concat(h)]||d[h]||u[h]||r;return n?a.createElement(f,i(i({ref:t},l),{},{components:n})):a.createElement(f,i({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=h;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var c=2;c=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var i=a.createContext({}),c=function(e){var n=a.useContext(i),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},d=function(e){var n=c(e.components);return a.createElement(i.Provider,{value:n},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},h=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=c(t),h=r,b=u["".concat(i,".").concat(h)]||u[h]||p[h]||o;return t?a.createElement(b,s(s({ref:n},d),{},{components:t})):a.createElement(b,s({ref:n},d))}));function b(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,s=new Array(o);s[0]=h;var l={};for(var i in n)hasOwnProperty.call(n,i)&&(l[i]=n[i]);l.originalType=e,l[u]="string"==typeof e?e:r,s[1]=l;for(var c=2;c:7777\n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Request fields:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"id")," - (STRING OR INTEGER) Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Explore the JSON-RPC request and response generated."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Request"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "method": "chain_get_state_root_hash",\n "params": null,\n "id": 1\n}\n')),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Response"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "state_root_hash": "f97d8d36630a8f4acdb323223596f6fa01ee3b0d49ad70d84d715c156c5dbec6"\n },\n "id": 1\n}\n'))),(0,o.kt)("h2",{id:"querying-an-account"},"Querying an Account"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-head"},"Accounts")," are stored in the global state and can be queried using the ",(0,o.kt)("inlineCode",{parentName:"p"},"query-global-state")," command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state \\\n --id 4 \\\n --node-address http://:7777 \\\n --state-root-hash \\\n --key \n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Request fields:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"id")," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"state-root-hash")," - Hex-encoded hash of the state root"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"key")," - The base key for the query. This must be a properly formatted public key, account hash, contract address hash, URef, transfer hash or deploy-info hash.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Important response fields:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},'"result"."stored_value"."Account"."main_purse"')," - the address of the main purse containing the sender's tokens. This purse is the source of the tokens transferred in this example")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example Account Query with Verbose Output:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state -v \\\n --id 4 \\\n --node-address https://rpc.testnet.casperlabs.io/ \\\n --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \\\n --key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Explore the sample JSON-RPC request and response generated."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Request"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"\n },\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "path": []\n },\n "id": 4\n}\n')),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Response"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "id": 4,\n "result": {\n "api_version": "1.5.2",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "named_keys": [\n {\n "name": "counter",\n "key": "hash-4bf23564c8849a0a3193781f0a9df7d27c4bce2cc585d6e9bb161a7a1ce5cd7e"\n },\n {\n "name": "counter_access_uref",\n "key": "uref-76b6c7e7a87b752d34a8c3ccdc070dbfd1940960016c537525b2ab9076b61a3e-007"\n },\n {\n "name": "counter_package_name",\n "key": "hash-e4b2060f098fa763f9a68c5c98a2d98a4fa80815ec0fd6b93ac9efbb0c18f19b"\n },\n {\n "name": "my-key-name",\n "key": "uref-09376d4202d32457ceefa4d9cdf1db6ab2324981ade06ba6f495cdf14124c3b9-007"\n },\n {\n "name": "version",\n "key": "uref-244a270207dd13ef5ff190f75d84efe4ab54bd5787be0bbb175c3fb154b7f5ed-007"\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-77ea2e433c94c9cb8303942335da458672249d38c1fa5d1d7a7500b862ff52a4",\n "weight": 1\n },\n {\n "account_hash": "account-hash-d65d053f5017af101b752a9a12ba4c41fe3054b8632998a69193b891eab4caf5",\n "weight": 1\n },\n {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "weight": 1\n },\n {\n "account_hash": "account-hash-f1802d2dbd83e41f638eb9b046f762e481d56b27d4aa00817fec77fbb21f944a",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n }\n }\n },\n "merkle_proof": "[32054 hex chars]"\n }\n}\n'))),(0,o.kt)("p",null,"To query the account balance, use the ",(0,o.kt)("inlineCode",{parentName:"p"},"query-balance")," command and the purse identifier, which can be a public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef can be used. The balance returned is in motes (the unit that makes up the Casper token). For full details, run the following help command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-balance --help\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-balance \\\n--id 6 \\\n--node-address http://:7777 \\\n--state-root-hash \\\n--purse-identifier \n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Request fields:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"id")," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"state-root-hash")," - Hex-encoded hash of the state root"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"purse-identifier")," - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef.")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"-v")," option generates verbose output, printing the RPC request and response generated. Let's explore an example below."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example Balance Query with Verbose Output:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-balance -v \\\n --id 6 \\\n --node-address https://rpc.testnet.casperlabs.io/ \\\n --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \\\n --purse-identifier 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Explore the JSON-RPC request and response generated."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Request"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"\n },\n "purse_identifier": {\n "main_purse_under_public_key": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n },\n "id": 6\n}\n')),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Response"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.2",\n "balance": "164000000000"\n },\n "id": 6\n}\n'))),(0,o.kt)("h2",{id:"querying-blocks"},"Querying Blocks"),(0,o.kt)("p",null,"It is possible to obtain detailed block information from the system. To do this, obtain the hash of the block of interest and send this query to a node in the network. Here is an example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-block \\\n --id 3 \\\n --node-address http://:7777 \\\n --block-identifier \\\n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Request fields:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"id")," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"block-identifier")," - Hex-encoded block hash or height of the block. If not given, the last block added to the chain as known at the given node will be used")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Important response fields:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},'"result"."block"."header"."state_root_hash"')," - contains the ",(0,o.kt)("inlineCode",{parentName:"li"},"state-root-hash")," for this block")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Explore the JSON-RPC request and response generated."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Request"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": 3,\n "jsonrpc": "2.0",\n "method": "chain_get_block",\n "params": {\n "block_identifier": {\n "Hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9"\n }\n }\n}\n')),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Response"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": 3,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block": {\n "body": {\n "deploy_hashes": [],\n "proposer": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",\n "transfer_hashes": ["ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713"]\n },\n "hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9",\n "header": {\n "accumulated_seed": "50b8ac019b7300cd1fdeec050310e61b900e9238aa879929745900a91bd0fc4f",\n "body_hash": "224076b19c04279ae9b97f620801d5ff40ba64f431fe0d5089ef7cb84fdff45a",\n "era_end": null,\n "era_id": 0,\n "height": 8,\n "parent_hash": "416f339c4c2ff299c64a4b3271c5ef2ac2297bb40a477ceacce1483451a4db16",\n "protocol_version": "1.0.0",\n "random_bit": true,\n "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3",\n "timestamp": "2021-04-20T18:04:42.368Z"\n },\n "proofs": [\n {\n "public_key": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150",\n "signature": "130 chars"\n },\n {\n "public_key": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",\n "signature": "130 chars"\n },\n {\n "public_key": "018d5da83f22c9b65cdfdf9f9fdf9f7c98aa2b8c7bcf14bf855177bbb9c1ac7f0a",\n "signature": "130 chars"\n },\n {\n "public_key": "01b9088b92c8a8d592f6ec8c3e8153d7c55fc0c38b5999a214e37e73a2edd6fe0f",\n "signature": "130 chars"\n },\n {\n "public_key": "01b9e3484d96d5693e6c5fe789e7b28972aa392b054a76d175f079692967f604de",\n "signature": "130 chars"\n }\n ]\n }\n }\n}\n'))),(0,o.kt)("h2",{id:"querying-deploys"},"Querying Deploys"),(0,o.kt)("p",null,"Once you submit a deploy to the network, you can check its execution status using ",(0,o.kt)("inlineCode",{parentName:"p"},"get-deploy"),". If the ",(0,o.kt)("inlineCode",{parentName:"p"},"execution_results")," in the output are null, the transaction has not run yet. Note that transactions are finalized upon execution."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy \\\n --id 2 \\\n --node-address http://:7777 \\\n \n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Request fields:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"id")," - JSON-RPC identifier, applied to the request and returned in the response. If not provided, a random integer will be assigned"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"deploy-hash")," - Hex-encoded hash of the deploy")))}b.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3355],{3905:function(e,n,t){t.d(n,{Zo:function(){return d},kt:function(){return b}});var a=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function s(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var i=a.createContext({}),c=function(e){var n=a.useContext(i),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},d=function(e){var n=c(e.components);return a.createElement(i.Provider,{value:n},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},h=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=c(t),h=r,b=u["".concat(i,".").concat(h)]||u[h]||p[h]||o;return t?a.createElement(b,s(s({ref:n},d),{},{components:t})):a.createElement(b,s({ref:n},d))}));function b(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,s=new Array(o);s[0]=h;var l={};for(var i in n)hasOwnProperty.call(n,i)&&(l[i]=n[i]);l.originalType=e,l[u]="string"==typeof e?e:r,s[1]=l;for(var c=2;c:7777\n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Request fields:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"id")," - (STRING OR INTEGER) Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Explore the JSON-RPC request and response generated."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Request"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "method": "chain_get_state_root_hash",\n "params": null,\n "id": 1\n}\n')),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Response"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "state_root_hash": "f97d8d36630a8f4acdb323223596f6fa01ee3b0d49ad70d84d715c156c5dbec6"\n },\n "id": 1\n}\n'))),(0,o.kt)("h2",{id:"querying-an-account"},"Querying an Account"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-head"},"Accounts")," are stored in the global state and can be queried using the ",(0,o.kt)("inlineCode",{parentName:"p"},"query-global-state")," command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state \\\n --id 4 \\\n --node-address http://:7777 \\\n --state-root-hash \\\n --key \n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Request fields:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"id")," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"state-root-hash")," - Hex-encoded hash of the state root"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"key")," - The base key for the query. This must be a properly formatted public key, account hash, contract address hash, URef, transfer hash or deploy-info hash.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Important response fields:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},'"result"."stored_value"."Account"."main_purse"')," - the address of the main purse containing the sender's tokens. This purse is the source of the tokens transferred in this example")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example Account Query with Verbose Output:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state -v \\\n --id 4 \\\n --node-address https://rpc.testnet.casperlabs.io/ \\\n --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \\\n --key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Explore the sample JSON-RPC request and response generated."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Request"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"\n },\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "path": []\n },\n "id": 4\n}\n')),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Response"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "id": 4,\n "result": {\n "api_version": "1.5.2",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "named_keys": [\n {\n "name": "counter",\n "key": "hash-4bf23564c8849a0a3193781f0a9df7d27c4bce2cc585d6e9bb161a7a1ce5cd7e"\n },\n {\n "name": "counter_access_uref",\n "key": "uref-76b6c7e7a87b752d34a8c3ccdc070dbfd1940960016c537525b2ab9076b61a3e-007"\n },\n {\n "name": "counter_package_name",\n "key": "hash-e4b2060f098fa763f9a68c5c98a2d98a4fa80815ec0fd6b93ac9efbb0c18f19b"\n },\n {\n "name": "my-key-name",\n "key": "uref-09376d4202d32457ceefa4d9cdf1db6ab2324981ade06ba6f495cdf14124c3b9-007"\n },\n {\n "name": "version",\n "key": "uref-244a270207dd13ef5ff190f75d84efe4ab54bd5787be0bbb175c3fb154b7f5ed-007"\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-77ea2e433c94c9cb8303942335da458672249d38c1fa5d1d7a7500b862ff52a4",\n "weight": 1\n },\n {\n "account_hash": "account-hash-d65d053f5017af101b752a9a12ba4c41fe3054b8632998a69193b891eab4caf5",\n "weight": 1\n },\n {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "weight": 1\n },\n {\n "account_hash": "account-hash-f1802d2dbd83e41f638eb9b046f762e481d56b27d4aa00817fec77fbb21f944a",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n }\n }\n },\n "merkle_proof": "[32054 hex chars]"\n }\n}\n'))),(0,o.kt)("p",null,"To query the account balance, use the ",(0,o.kt)("inlineCode",{parentName:"p"},"query-balance")," command and the purse identifier, which can be a public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef can be used. The balance returned is in motes (the unit that makes up the Casper token). For full details, run the following help command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-balance --help\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-balance \\\n--id 6 \\\n--node-address http://:7777 \\\n--state-root-hash \\\n--purse-identifier \n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Request fields:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"id")," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"state-root-hash")," - Hex-encoded hash of the state root"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"purse-identifier")," - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef.")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"-v")," option generates verbose output, printing the RPC request and response generated. Let's explore an example below."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example Balance Query with Verbose Output:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-balance -v \\\n --id 6 \\\n --node-address https://rpc.testnet.casperlabs.io/ \\\n --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \\\n --purse-identifier 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Explore the JSON-RPC request and response generated."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Request"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"\n },\n "purse_identifier": {\n "main_purse_under_public_key": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n },\n "id": 6\n}\n')),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Response"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.2",\n "balance": "164000000000"\n },\n "id": 6\n}\n'))),(0,o.kt)("h2",{id:"querying-blocks"},"Querying Blocks"),(0,o.kt)("p",null,"It is possible to obtain detailed block information from the system. To do this, obtain the hash of the block of interest and send this query to a node in the network. Here is an example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-block \\\n --id 3 \\\n --node-address http://:7777 \\\n --block-identifier \\\n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Request fields:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"id")," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"block-identifier")," - Hex-encoded block hash or height of the block. If not given, the last block added to the chain as known at the given node will be used")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Important response fields:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},'"result"."block"."header"."state_root_hash"')," - contains the ",(0,o.kt)("inlineCode",{parentName:"li"},"state-root-hash")," for this block")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Explore the JSON-RPC request and response generated."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Request"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": 3,\n "jsonrpc": "2.0",\n "method": "chain_get_block",\n "params": {\n "block_identifier": {\n "Hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9"\n }\n }\n}\n')),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"JSON-RPC Response"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": 3,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block": {\n "body": {\n "deploy_hashes": [],\n "proposer": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",\n "transfer_hashes": ["ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713"]\n },\n "hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9",\n "header": {\n "accumulated_seed": "50b8ac019b7300cd1fdeec050310e61b900e9238aa879929745900a91bd0fc4f",\n "body_hash": "224076b19c04279ae9b97f620801d5ff40ba64f431fe0d5089ef7cb84fdff45a",\n "era_end": null,\n "era_id": 0,\n "height": 8,\n "parent_hash": "416f339c4c2ff299c64a4b3271c5ef2ac2297bb40a477ceacce1483451a4db16",\n "protocol_version": "1.0.0",\n "random_bit": true,\n "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3",\n "timestamp": "2021-04-20T18:04:42.368Z"\n },\n "proofs": [\n {\n "public_key": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150",\n "signature": "130 chars"\n },\n {\n "public_key": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",\n "signature": "130 chars"\n },\n {\n "public_key": "018d5da83f22c9b65cdfdf9f9fdf9f7c98aa2b8c7bcf14bf855177bbb9c1ac7f0a",\n "signature": "130 chars"\n },\n {\n "public_key": "01b9088b92c8a8d592f6ec8c3e8153d7c55fc0c38b5999a214e37e73a2edd6fe0f",\n "signature": "130 chars"\n },\n {\n "public_key": "01b9e3484d96d5693e6c5fe789e7b28972aa392b054a76d175f079692967f604de",\n "signature": "130 chars"\n }\n ]\n }\n }\n}\n'))),(0,o.kt)("h2",{id:"querying-deploys"},"Querying Deploys"),(0,o.kt)("p",null,"Once you submit a deploy to the network, you can check its execution status using ",(0,o.kt)("inlineCode",{parentName:"p"},"get-deploy"),". If the ",(0,o.kt)("inlineCode",{parentName:"p"},"execution_results")," in the output are null, the transaction has not run yet. Note that transactions are finalized upon execution."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy \\\n --id 2 \\\n --node-address http://:7777 \\\n \n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Request fields:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"id")," - JSON-RPC identifier, applied to the request and returned in the response. If not provided, a random integer will be assigned"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"deploy-hash")," - Hex-encoded hash of the deploy")))}b.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a27f3afe.1685f38a.js b/assets/js/a27f3afe.17a89467.js similarity index 99% rename from assets/js/a27f3afe.1685f38a.js rename to assets/js/a27f3afe.17a89467.js index 3b44b0636e..901734f5c7 100644 --- a/assets/js/a27f3afe.1685f38a.js +++ b/assets/js/a27f3afe.17a89467.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3055],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return m}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,c=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),p=l(n),h=r,m=p["".concat(c,".").concat(h)]||p[h]||d[h]||s;return n?a.createElement(m,o(o({ref:t},u),{},{components:n})):a.createElement(m,o({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,o=new Array(s);o[0]=h;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[p]="string"==typeof e?e:r,o[1]=i;for(var l=2;lCargo.toml",id:"defining-dependencies-in-cargotoml",level:3},{value:"Writing the Tests",id:"writing-the-tests",level:2},{value:"Importing Builders and Constants",id:"importing-builders-and-constants",level:3},{value:"Creating a Test Function",id:"creating-a-test-function",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:4},{value:"Calling the Contract by Hash",id:"calling-the-contract-by-hash",level:4},{value:"Calling the Contract using Session Code",id:"calling-the-contract-using-session-code",level:4},{value:"Evaluating and Comparing Results",id:"evaluating-and-comparing-results",level:4},{value:"Testing Contracts that Call Contracts",id:"testing-contracts-that-call-contracts",level:2},{value:"Running the Tests",id:"running-the-tests",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"Further Testing",id:"further-testing",level:2},{value:"What's Next?",id:"whats-next",level:2}],d={toc:p},h="wrapper";function m(e){var t=e.components,n=(0,r.Z)(e,o);return(0,s.kt)(h,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"testing-smart-contracts"},"Testing Smart Contracts"),(0,s.kt)("h2",{id:"introduction"},"Introduction"),(0,s.kt)("p",null,"As part of the Casper development environment, we provide a ",(0,s.kt)("a",{parentName:"p",href:"https://docs.rs/casper-engine-test-support/latest/casper_engine_test_support/"},"testing framework")," to test new contracts without running a full node. The framework creates an instance of the Casper execution engine, which can confirm successful deploys and monitor changes to global state using assertions. The Casper test crate must be included within the Rust workspace alongside the Wasm-producing crate to be validated."),(0,s.kt)("admonition",{type:"note"},(0,s.kt)("p",{parentName:"admonition"},"The Casper test support crate is one of many options for testing contracts before sending them to a Casper network. If you prefer, you can create your own testing framework.")),(0,s.kt)("h3",{id:"defining-dependencies-in-cargotoml"},"Defining Dependencies in ",(0,s.kt)("inlineCode",{parentName:"h3"},"Cargo.toml")),(0,s.kt)("p",null,"This guide uses the project structure, and example contract outlined ",(0,s.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/simple-contract#directory-structure"},"here")," for creating tests."),(0,s.kt)("p",null,"To begin, outline the required test dependencies in the ",(0,s.kt)("inlineCode",{parentName:"p"},"/tests/Cargo.toml")," file. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. For the counter tests, we have the following dependencies:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},'[dependencies]\ncasper-execution-engine = "2.0.1"\ncasper-engine-test-support = { version = "2.2.0", features = ["test-support"] }\ncasper-types = "1.5.0"\n')),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"casper-execution-engine")," - This crate imports the execution engine functionality, enabling Wasm execution within the test framework. Each node contains an instance of an execution engine, and the testing framework simulates this behavior."),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"casper-engine-test-support")," - A helper crate that provides the interface to write tests and interact with an instance of the execution engine."),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"casper-types")," - Types shared by many Casper crates for use on a Casper network.")),(0,s.kt)("h2",{id:"writing-the-tests"},"Writing the Tests"),(0,s.kt)("p",null,"The tests for the contract usually reside in the ",(0,s.kt)("inlineCode",{parentName:"p"},"tests")," directory. Tests for the counter contract reside in the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs"},"tests/src/integration-tests.rs")," file. Notice that this file contains an empty ",(0,s.kt)("inlineCode",{parentName:"p"},"main")," method to initialize the test program. Alternatively, we could use the ",(0,s.kt)("inlineCode",{parentName:"p"},"#![no_main]")," annotation at the top of the file, as we did ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/blob/8a622cd92d768893b9ef9fc2b150c674415be87e/contract-v1/src/main.rs#L1-L2"},"here"),"."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},'fn main() {\n panic!("Execute \\"cargo test\\" to test the contract, not \\"cargo run\\".");\n}\n')),(0,s.kt)("p",null,"The ",(0,s.kt)("inlineCode",{parentName:"p"},"#[cfg(test)]")," attribute tells the Rust compiler to compile and run the tests only when invoking ",(0,s.kt)("inlineCode",{parentName:"p"},"cargo test"),", not while debugging or releasing. All testing functions reside within the grouping mechanism ",(0,s.kt)("inlineCode",{parentName:"p"},"mod tests"),"."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},"#[cfg(test)]\nmod tests {\n // The entire test program resides here\n}\n")),(0,s.kt)("h3",{id:"importing-builders-and-constants"},"Importing Builders and Constants"),(0,s.kt)("p",null,"Import external test support, which includes a variety of default values and helper methods to be used throughout the test. Additionally, you will need to import any ",(0,s.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_cl"},"CLTypes")," used within the contract code to be tested."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"}," // Outlining aspects of the Casper test support crate to include.\n use casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n DEFAULT_RUN_GENESIS_REQUEST,\n };\n // Custom Casper types that will be used within this test.\n use casper_types::{runtime_args, ContractHash, RuntimeArgs};\n")),(0,s.kt)("p",null,"Next, you need to define any global variables or constants for the test."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},' const COUNTER_V1_WASM: &str = "counter-v1.wasm"; // The first version of the contract\n const COUNTER_V2_WASM: &str = "counter-v2.wasm"; // The second version of the contract\n const COUNTER_CALL_WASM: &str = "counter-call.wasm"; // Session code that calls the contract\n\n const CONTRACT_KEY: &str = "counter"; // Named key referencing this contract\n const COUNT_KEY: &str = "count"; // Named key referencing the value to increment/decrement\n const CONTRACT_VERSION_KEY: &str = "version"; // Key maintaining the version of a contract package\n\n const ENTRY_POINT_COUNTER_DECREMENT: &str = "counter_decrement"; // Entry point to decrement the count value\n const ENTRY_POINT_COUNTER_INC: &str = "counter_inc"; // Entry point to increment the count value\n')),(0,s.kt)("h3",{id:"creating-a-test-function"},"Creating a Test Function"),(0,s.kt)("p",null,"Each test function installs the contract and calls entry points to assert that the contract's behavior matches expectations. The test uses the ",(0,s.kt)("inlineCode",{parentName:"p"},"InMemoryWasmTestBuilder")," to invoke an instance of the execution engine, effectively simulating the process of installing the contract on the chain."),(0,s.kt)("p",null,"As part of this process, we use the ",(0,s.kt)("inlineCode",{parentName:"p"},"DEFAULT_RUN_GENESIS_REQUEST")," to install the system contracts necessary for the tests, including the ",(0,s.kt)("inlineCode",{parentName:"p"},"Mint"),", ",(0,s.kt)("inlineCode",{parentName:"p"},"Auction"),", and ",(0,s.kt)("inlineCode",{parentName:"p"},"HandlePayment"),"contracts, as well as establishing a default account and funding the associated purse."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"}," #[test]\n /// Install version 1 of the counter contract and check its available entry points. ...\n fn install_version1_and_check_entry_points() {\n let mut builder = InMemoryWasmTestBuilder::default();\n builder.run_genesis(&*DEFAULT_RUN_GENESIS_REQUEST).commit();\n\n // See the repository for the full function.\n }\n")),(0,s.kt)("h4",{id:"installing-the-contract"},"Installing the Contract"),(0,s.kt)("p",null,"Test functions use the ",(0,s.kt)("inlineCode",{parentName:"p"},"ExecuteRequestBuilder")," to install a contract to be tested. In the counter tests, we use standard dependencies and the counter contract. Within the execution request, we specify the ",(0,s.kt)("inlineCode",{parentName:"p"},"DEFAULT_ACCOUNT_ADDR")," established by our genesis builder as the account sending the Deploy."),(0,s.kt)("p",null,"After building the ",(0,s.kt)("inlineCode",{parentName:"p"},"ExecuteRequestBuilder")," (in this example, ",(0,s.kt)("inlineCode",{parentName:"p"},"contract_installation_request"),"), we process the request through ",(0,s.kt)("inlineCode",{parentName:"p"},"builder.exec")," and then add and process other requests as necessary."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"}," // Install the contract.\n let contract_v1_installation_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_V1_WASM,\n runtime_args! {},\n )\n .build();\n\n builder\n .exec(contract_v1_installation_request)\n .expect_success()\n .commit();\n")),(0,s.kt)("h4",{id:"calling-the-contract-by-hash"},"Calling the Contract by Hash"),(0,s.kt)("p",null,"To verify the installed contract, we need its contract hash. The test will then call its entry points using the ",(0,s.kt)("inlineCode",{parentName:"p"},"contract_call_by_hash")," function. The following code retrieves the contract hash from the named keys of the ",(0,s.kt)("inlineCode",{parentName:"p"},"DEFAULT_ACCOUNT_ADDR")," that sent the installation Deploy."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},' // Check the contract hash.\n let contract_v1_hash = builder\n .get_expected_account(*DEFAULT_ACCOUNT_ADDR)\n .named_keys()\n .get(CONTRACT_KEY)\n .expect("must have contract hash key as part of contract creation")\n .into_hash()\n .map(ContractHash::new)\n .expect("must get contract hash");\n')),(0,s.kt)("p",null,"Next, we test an entry point that should not exist in the first version of the contract."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"}," // Call the decrement entry point, which should not be in version 1 before the upgrade.\n let contract_decrement_request = ExecuteRequestBuilder::contract_call_by_hash(\n *DEFAULT_ACCOUNT_ADDR,\n contract_v1_hash,\n ENTRY_POINT_COUNTER_DECREMENT,\n runtime_args! {},\n )\n .build();\n\n // Try executing the decrement entry point and expect an error.\n builder\n .exec(contract_decrement_request)\n .expect_failure()\n .commit();\n")),(0,s.kt)("h4",{id:"calling-the-contract-using-session-code"},"Calling the Contract using Session Code"),(0,s.kt)("p",null,"In the counter example, we use the session code included in the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/blob/master/counter-call/src/main.rs"},"counter-call.wasm")," file. For more details on what session code is and how it differs from contract code, see the ",(0,s.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code"},"next section"),"."),(0,s.kt)("p",null,"The following session code uses the contract hash to identify the contract, the account for sending the deploy (",(0,s.kt)("inlineCode",{parentName:"p"},"DEFAULT_ACCOUNT_ADDR"),"), the deploy to be sent (",(0,s.kt)("inlineCode",{parentName:"p"},"COUNTER_CALL_WASM"),"), and the runtime arguments required. Once again, the ",(0,s.kt)("inlineCode",{parentName:"p"},"ExecuteRequestBuilder")," simulates the execution of session code and calls the ",(0,s.kt)("inlineCode",{parentName:"p"},"counter-inc")," entry point."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"}," // Use session code to increment the counter.\n let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n )\n .build();\n\n builder.exec(session_code_request)\n .expect_success()\n .commit();\n")),(0,s.kt)("h4",{id:"evaluating-and-comparing-results"},"Evaluating and Comparing Results"),(0,s.kt)("p",null,"After calling the contract, we should verify the results received to ensure the contract operated as intended. The ",(0,s.kt)("inlineCode",{parentName:"p"},"builder")," method retrieves the required information and converts it to the value type required. Then, ",(0,s.kt)("inlineCode",{parentName:"p"},"assert_eq!()")," compares the result against the expected value."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},' // Verify the value of count is now 1.\n let incremented_count = builder\n .query(None, count_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::()\n .expect("should be i32.");\n\n assert_eq!(incremented_count, 1);\n')),(0,s.kt)("p",null,"For more test examples, visit the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/test"},"casper-node")," GitHub repository."),(0,s.kt)("h2",{id:"testing-contracts-that-call-contracts"},"Testing Contracts that Call Contracts"),(0,s.kt)("p",null,"If the code to be tested involves multiple contracts, they must be installed within the test. The exceptions are system contracts installed as part of the ",(0,s.kt)("inlineCode",{parentName:"p"},"DEFAULT_RUN_GENESIS_REQUEST"),". The testing framework exists independently of any Casper network, so you will need access to the original contract installation code or the Wasm you wish to include."),(0,s.kt)("p",null,"Each contract installation will require an additional Wasm file installed through a ",(0,s.kt)("inlineCode",{parentName:"p"},"Deploy")," using ",(0,s.kt)("inlineCode",{parentName:"p"},"ExecuteRequestBuilder"),". Depending on your requirements as a smart contract author, you may need to use ",(0,s.kt)("a",{parentName:"p",href:"/resources/tutorials/advanced/return-values-tutorial"},"return values")," to interact with stacks of contracts. Interaction between contracts will require session code to initiate the process, as contracts will not execute actions autonomously."),(0,s.kt)("p",null,"The major difference between calling a contract from session code versus contract code is the ability to use non-standard dependencies for the ",(0,s.kt)("inlineCode",{parentName:"p"},"ExecuteRequestBuilder"),". Where session code must designate a Wasm file within the standard dependencies, contract code can use one of the four available options for calling other contracts, namely:"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"contract_call_by_hash")," - Calling a contract by its ",(0,s.kt)("inlineCode",{parentName:"li"},"ContractHash"),"."),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"contract_call_by_name")," - Calling a contract referenced by a named key in the signer's Account context."),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"versioned_contract_call_by_hash")," - Calling a specific contract version using its ",(0,s.kt)("inlineCode",{parentName:"li"},"ContractHash"),"."),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"versioned_contract_call_by_name")," - Calling a specific version of a contract referenced by a named key in the signer's Account context.")),(0,s.kt)("p",null,"The calling contract must also provide an entry point and any necessary runtime arguments in all cases."),(0,s.kt)("h2",{id:"running-the-tests"},"Running the Tests"),(0,s.kt)("p",null,"To run the tests, the counter example uses a ",(0,s.kt)("inlineCode",{parentName:"p"},"Makefile"),"."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"make test\n")),(0,s.kt)("p",null,"Under the hood, the ",(0,s.kt)("inlineCode",{parentName:"p"},"Makefile")," generates a ",(0,s.kt)("inlineCode",{parentName:"p"},"tests/wasm")," folder, copies the Wasm files to the folder, and runs the tests using ",(0,s.kt)("inlineCode",{parentName:"p"},"cargo test"),"."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"test: build-contract\n mkdir -p tests/wasm\n cp contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm tests/wasm\n cp contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm tests/wasm\n cp counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm tests/wasm\n cd tests && cargo test\n")),(0,s.kt)("h2",{id:"video-walkthrough"},"Video Walkthrough"),(0,s.kt)("p",null,"The following brief video describes testing ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/"},"sample contract code"),"."),(0,s.kt)("p",{align:"center"},(0,s.kt)("iframe",{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=7",frameborder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:!0})),(0,s.kt)("h2",{id:"further-testing"},"Further Testing"),(0,s.kt)("p",null,"Unit testing is only one way to test contracts before installing them on a Casper network. After unit testing a contract, you may perform ",(0,s.kt)("a",{parentName:"p",href:"/developers/dapps/setup-nctl"},"local network testing")," using NCTL. This allows you to set up and control multiple local Casper nodes to perform ",(0,s.kt)("a",{parentName:"p",href:"/developers/dapps/nctl-test"},"testing in an other simulated network environment"),"."),(0,s.kt)("p",null,"You may also wish to test your contracts on the Casper ",(0,s.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/"},"Testnet"),"."),(0,s.kt)("h2",{id:"whats-next"},"What's Next?"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"Understand ",(0,s.kt)("a",{parentName:"li",href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code"},"session code")," and how it triggers a smart contract."),(0,s.kt)("li",{parentName:"ul"},"Learn to ",(0,s.kt)("a",{parentName:"li",href:"/developers/cli/installing-contracts"},"install a contract and query global state")," with the Casper command-line client.")))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3055],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return m}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,c=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),p=l(n),h=r,m=p["".concat(c,".").concat(h)]||p[h]||d[h]||s;return n?a.createElement(m,o(o({ref:t},u),{},{components:n})):a.createElement(m,o({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,o=new Array(s);o[0]=h;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[p]="string"==typeof e?e:r,o[1]=i;for(var l=2;lCargo.toml",id:"defining-dependencies-in-cargotoml",level:3},{value:"Writing the Tests",id:"writing-the-tests",level:2},{value:"Importing Builders and Constants",id:"importing-builders-and-constants",level:3},{value:"Creating a Test Function",id:"creating-a-test-function",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:4},{value:"Calling the Contract by Hash",id:"calling-the-contract-by-hash",level:4},{value:"Calling the Contract using Session Code",id:"calling-the-contract-using-session-code",level:4},{value:"Evaluating and Comparing Results",id:"evaluating-and-comparing-results",level:4},{value:"Testing Contracts that Call Contracts",id:"testing-contracts-that-call-contracts",level:2},{value:"Running the Tests",id:"running-the-tests",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"Further Testing",id:"further-testing",level:2},{value:"What's Next?",id:"whats-next",level:2}],d={toc:p},h="wrapper";function m(e){var t=e.components,n=(0,r.Z)(e,o);return(0,s.kt)(h,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"testing-smart-contracts"},"Testing Smart Contracts"),(0,s.kt)("h2",{id:"introduction"},"Introduction"),(0,s.kt)("p",null,"As part of the Casper development environment, we provide a ",(0,s.kt)("a",{parentName:"p",href:"https://docs.rs/casper-engine-test-support/latest/casper_engine_test_support/"},"testing framework")," to test new contracts without running a full node. The framework creates an instance of the Casper execution engine, which can confirm successful deploys and monitor changes to global state using assertions. The Casper test crate must be included within the Rust workspace alongside the Wasm-producing crate to be validated."),(0,s.kt)("admonition",{type:"note"},(0,s.kt)("p",{parentName:"admonition"},"The Casper test support crate is one of many options for testing contracts before sending them to a Casper network. If you prefer, you can create your own testing framework.")),(0,s.kt)("h3",{id:"defining-dependencies-in-cargotoml"},"Defining Dependencies in ",(0,s.kt)("inlineCode",{parentName:"h3"},"Cargo.toml")),(0,s.kt)("p",null,"This guide uses the project structure, and example contract outlined ",(0,s.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/simple-contract#directory-structure"},"here")," for creating tests."),(0,s.kt)("p",null,"To begin, outline the required test dependencies in the ",(0,s.kt)("inlineCode",{parentName:"p"},"/tests/Cargo.toml")," file. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. For the counter tests, we have the following dependencies:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},'[dependencies]\ncasper-execution-engine = "2.0.1"\ncasper-engine-test-support = { version = "2.2.0", features = ["test-support"] }\ncasper-types = "1.5.0"\n')),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"casper-execution-engine")," - This crate imports the execution engine functionality, enabling Wasm execution within the test framework. Each node contains an instance of an execution engine, and the testing framework simulates this behavior."),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"casper-engine-test-support")," - A helper crate that provides the interface to write tests and interact with an instance of the execution engine."),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"casper-types")," - Types shared by many Casper crates for use on a Casper network.")),(0,s.kt)("h2",{id:"writing-the-tests"},"Writing the Tests"),(0,s.kt)("p",null,"The tests for the contract usually reside in the ",(0,s.kt)("inlineCode",{parentName:"p"},"tests")," directory. Tests for the counter contract reside in the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs"},"tests/src/integration-tests.rs")," file. Notice that this file contains an empty ",(0,s.kt)("inlineCode",{parentName:"p"},"main")," method to initialize the test program. Alternatively, we could use the ",(0,s.kt)("inlineCode",{parentName:"p"},"#![no_main]")," annotation at the top of the file, as we did ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/blob/8a622cd92d768893b9ef9fc2b150c674415be87e/contract-v1/src/main.rs#L1-L2"},"here"),"."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},'fn main() {\n panic!("Execute \\"cargo test\\" to test the contract, not \\"cargo run\\".");\n}\n')),(0,s.kt)("p",null,"The ",(0,s.kt)("inlineCode",{parentName:"p"},"#[cfg(test)]")," attribute tells the Rust compiler to compile and run the tests only when invoking ",(0,s.kt)("inlineCode",{parentName:"p"},"cargo test"),", not while debugging or releasing. All testing functions reside within the grouping mechanism ",(0,s.kt)("inlineCode",{parentName:"p"},"mod tests"),"."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},"#[cfg(test)]\nmod tests {\n // The entire test program resides here\n}\n")),(0,s.kt)("h3",{id:"importing-builders-and-constants"},"Importing Builders and Constants"),(0,s.kt)("p",null,"Import external test support, which includes a variety of default values and helper methods to be used throughout the test. Additionally, you will need to import any ",(0,s.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_cl"},"CLTypes")," used within the contract code to be tested."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"}," // Outlining aspects of the Casper test support crate to include.\n use casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n DEFAULT_RUN_GENESIS_REQUEST,\n };\n // Custom Casper types that will be used within this test.\n use casper_types::{runtime_args, ContractHash, RuntimeArgs};\n")),(0,s.kt)("p",null,"Next, you need to define any global variables or constants for the test."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},' const COUNTER_V1_WASM: &str = "counter-v1.wasm"; // The first version of the contract\n const COUNTER_V2_WASM: &str = "counter-v2.wasm"; // The second version of the contract\n const COUNTER_CALL_WASM: &str = "counter-call.wasm"; // Session code that calls the contract\n\n const CONTRACT_KEY: &str = "counter"; // Named key referencing this contract\n const COUNT_KEY: &str = "count"; // Named key referencing the value to increment/decrement\n const CONTRACT_VERSION_KEY: &str = "version"; // Key maintaining the version of a contract package\n\n const ENTRY_POINT_COUNTER_DECREMENT: &str = "counter_decrement"; // Entry point to decrement the count value\n const ENTRY_POINT_COUNTER_INC: &str = "counter_inc"; // Entry point to increment the count value\n')),(0,s.kt)("h3",{id:"creating-a-test-function"},"Creating a Test Function"),(0,s.kt)("p",null,"Each test function installs the contract and calls entry points to assert that the contract's behavior matches expectations. The test uses the ",(0,s.kt)("inlineCode",{parentName:"p"},"InMemoryWasmTestBuilder")," to invoke an instance of the execution engine, effectively simulating the process of installing the contract on the chain."),(0,s.kt)("p",null,"As part of this process, we use the ",(0,s.kt)("inlineCode",{parentName:"p"},"DEFAULT_RUN_GENESIS_REQUEST")," to install the system contracts necessary for the tests, including the ",(0,s.kt)("inlineCode",{parentName:"p"},"Mint"),", ",(0,s.kt)("inlineCode",{parentName:"p"},"Auction"),", and ",(0,s.kt)("inlineCode",{parentName:"p"},"HandlePayment"),"contracts, as well as establishing a default account and funding the associated purse."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"}," #[test]\n /// Install version 1 of the counter contract and check its available entry points. ...\n fn install_version1_and_check_entry_points() {\n let mut builder = InMemoryWasmTestBuilder::default();\n builder.run_genesis(&*DEFAULT_RUN_GENESIS_REQUEST).commit();\n\n // See the repository for the full function.\n }\n")),(0,s.kt)("h4",{id:"installing-the-contract"},"Installing the Contract"),(0,s.kt)("p",null,"Test functions use the ",(0,s.kt)("inlineCode",{parentName:"p"},"ExecuteRequestBuilder")," to install a contract to be tested. In the counter tests, we use standard dependencies and the counter contract. Within the execution request, we specify the ",(0,s.kt)("inlineCode",{parentName:"p"},"DEFAULT_ACCOUNT_ADDR")," established by our genesis builder as the account sending the Deploy."),(0,s.kt)("p",null,"After building the ",(0,s.kt)("inlineCode",{parentName:"p"},"ExecuteRequestBuilder")," (in this example, ",(0,s.kt)("inlineCode",{parentName:"p"},"contract_installation_request"),"), we process the request through ",(0,s.kt)("inlineCode",{parentName:"p"},"builder.exec")," and then add and process other requests as necessary."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"}," // Install the contract.\n let contract_v1_installation_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_V1_WASM,\n runtime_args! {},\n )\n .build();\n\n builder\n .exec(contract_v1_installation_request)\n .expect_success()\n .commit();\n")),(0,s.kt)("h4",{id:"calling-the-contract-by-hash"},"Calling the Contract by Hash"),(0,s.kt)("p",null,"To verify the installed contract, we need its contract hash. The test will then call its entry points using the ",(0,s.kt)("inlineCode",{parentName:"p"},"contract_call_by_hash")," function. The following code retrieves the contract hash from the named keys of the ",(0,s.kt)("inlineCode",{parentName:"p"},"DEFAULT_ACCOUNT_ADDR")," that sent the installation Deploy."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},' // Check the contract hash.\n let contract_v1_hash = builder\n .get_expected_account(*DEFAULT_ACCOUNT_ADDR)\n .named_keys()\n .get(CONTRACT_KEY)\n .expect("must have contract hash key as part of contract creation")\n .into_hash()\n .map(ContractHash::new)\n .expect("must get contract hash");\n')),(0,s.kt)("p",null,"Next, we test an entry point that should not exist in the first version of the contract."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"}," // Call the decrement entry point, which should not be in version 1 before the upgrade.\n let contract_decrement_request = ExecuteRequestBuilder::contract_call_by_hash(\n *DEFAULT_ACCOUNT_ADDR,\n contract_v1_hash,\n ENTRY_POINT_COUNTER_DECREMENT,\n runtime_args! {},\n )\n .build();\n\n // Try executing the decrement entry point and expect an error.\n builder\n .exec(contract_decrement_request)\n .expect_failure()\n .commit();\n")),(0,s.kt)("h4",{id:"calling-the-contract-using-session-code"},"Calling the Contract using Session Code"),(0,s.kt)("p",null,"In the counter example, we use the session code included in the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/blob/master/counter-call/src/main.rs"},"counter-call.wasm")," file. For more details on what session code is and how it differs from contract code, see the ",(0,s.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code"},"next section"),"."),(0,s.kt)("p",null,"The following session code uses the contract hash to identify the contract, the account for sending the deploy (",(0,s.kt)("inlineCode",{parentName:"p"},"DEFAULT_ACCOUNT_ADDR"),"), the deploy to be sent (",(0,s.kt)("inlineCode",{parentName:"p"},"COUNTER_CALL_WASM"),"), and the runtime arguments required. Once again, the ",(0,s.kt)("inlineCode",{parentName:"p"},"ExecuteRequestBuilder")," simulates the execution of session code and calls the ",(0,s.kt)("inlineCode",{parentName:"p"},"counter-inc")," entry point."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"}," // Use session code to increment the counter.\n let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n )\n .build();\n\n builder.exec(session_code_request)\n .expect_success()\n .commit();\n")),(0,s.kt)("h4",{id:"evaluating-and-comparing-results"},"Evaluating and Comparing Results"),(0,s.kt)("p",null,"After calling the contract, we should verify the results received to ensure the contract operated as intended. The ",(0,s.kt)("inlineCode",{parentName:"p"},"builder")," method retrieves the required information and converts it to the value type required. Then, ",(0,s.kt)("inlineCode",{parentName:"p"},"assert_eq!()")," compares the result against the expected value."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},' // Verify the value of count is now 1.\n let incremented_count = builder\n .query(None, count_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::()\n .expect("should be i32.");\n\n assert_eq!(incremented_count, 1);\n')),(0,s.kt)("p",null,"For more test examples, visit the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/test"},"casper-node")," GitHub repository."),(0,s.kt)("h2",{id:"testing-contracts-that-call-contracts"},"Testing Contracts that Call Contracts"),(0,s.kt)("p",null,"If the code to be tested involves multiple contracts, they must be installed within the test. The exceptions are system contracts installed as part of the ",(0,s.kt)("inlineCode",{parentName:"p"},"DEFAULT_RUN_GENESIS_REQUEST"),". The testing framework exists independently of any Casper network, so you will need access to the original contract installation code or the Wasm you wish to include."),(0,s.kt)("p",null,"Each contract installation will require an additional Wasm file installed through a ",(0,s.kt)("inlineCode",{parentName:"p"},"Deploy")," using ",(0,s.kt)("inlineCode",{parentName:"p"},"ExecuteRequestBuilder"),". Depending on your requirements as a smart contract author, you may need to use ",(0,s.kt)("a",{parentName:"p",href:"/resources/tutorials/advanced/return-values-tutorial"},"return values")," to interact with stacks of contracts. Interaction between contracts will require session code to initiate the process, as contracts will not execute actions autonomously."),(0,s.kt)("p",null,"The major difference between calling a contract from session code versus contract code is the ability to use non-standard dependencies for the ",(0,s.kt)("inlineCode",{parentName:"p"},"ExecuteRequestBuilder"),". Where session code must designate a Wasm file within the standard dependencies, contract code can use one of the four available options for calling other contracts, namely:"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"contract_call_by_hash")," - Calling a contract by its ",(0,s.kt)("inlineCode",{parentName:"li"},"ContractHash"),"."),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"contract_call_by_name")," - Calling a contract referenced by a named key in the signer's Account context."),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"versioned_contract_call_by_hash")," - Calling a specific contract version using its ",(0,s.kt)("inlineCode",{parentName:"li"},"ContractHash"),"."),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("inlineCode",{parentName:"li"},"versioned_contract_call_by_name")," - Calling a specific version of a contract referenced by a named key in the signer's Account context.")),(0,s.kt)("p",null,"The calling contract must also provide an entry point and any necessary runtime arguments in all cases."),(0,s.kt)("h2",{id:"running-the-tests"},"Running the Tests"),(0,s.kt)("p",null,"To run the tests, the counter example uses a ",(0,s.kt)("inlineCode",{parentName:"p"},"Makefile"),"."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"make test\n")),(0,s.kt)("p",null,"Under the hood, the ",(0,s.kt)("inlineCode",{parentName:"p"},"Makefile")," generates a ",(0,s.kt)("inlineCode",{parentName:"p"},"tests/wasm")," folder, copies the Wasm files to the folder, and runs the tests using ",(0,s.kt)("inlineCode",{parentName:"p"},"cargo test"),"."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"test: build-contract\n mkdir -p tests/wasm\n cp contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm tests/wasm\n cp contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm tests/wasm\n cp counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm tests/wasm\n cd tests && cargo test\n")),(0,s.kt)("h2",{id:"video-walkthrough"},"Video Walkthrough"),(0,s.kt)("p",null,"The following brief video describes testing ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/"},"sample contract code"),"."),(0,s.kt)("p",{align:"center"},(0,s.kt)("iframe",{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=7",frameborder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:!0})),(0,s.kt)("h2",{id:"further-testing"},"Further Testing"),(0,s.kt)("p",null,"Unit testing is only one way to test contracts before installing them on a Casper network. After unit testing a contract, you may perform ",(0,s.kt)("a",{parentName:"p",href:"/developers/dapps/setup-nctl"},"local network testing")," using NCTL. This allows you to set up and control multiple local Casper nodes to perform ",(0,s.kt)("a",{parentName:"p",href:"/developers/dapps/nctl-test"},"testing in an other simulated network environment"),"."),(0,s.kt)("p",null,"You may also wish to test your contracts on the Casper ",(0,s.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/"},"Testnet"),"."),(0,s.kt)("h2",{id:"whats-next"},"What's Next?"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"Understand ",(0,s.kt)("a",{parentName:"li",href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code"},"session code")," and how it triggers a smart contract."),(0,s.kt)("li",{parentName:"ul"},"Learn to ",(0,s.kt)("a",{parentName:"li",href:"/developers/cli/installing-contracts"},"install a contract and query global state")," with the Casper command-line client.")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a2831d13.c42a8c60.js b/assets/js/a2831d13.a9d384c5.js similarity index 99% rename from assets/js/a2831d13.c42a8c60.js rename to assets/js/a2831d13.a9d384c5.js index 7b83a2a17d..ec488b6235 100644 --- a/assets/js/a2831d13.c42a8c60.js +++ b/assets/js/a2831d13.a9d384c5.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5826],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=o.createContext({}),c=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),h=a,m=u["".concat(l,".").concat(h)]||u[h]||d[h]||r;return n?o.createElement(m,i(i({ref:t},p),{},{components:n})):o.createElement(m,i({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var c=2;c}\\_m{modulo}\\_p{}"'),". Once again using the 2,350th token as an example, the receipt would read:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"cep78_collection_m_350_p_2\n")),(0,r.kt)("p",null,"You can determine the token number by multiplying the ",(0,r.kt)("inlineCode",{parentName:"p"},"page_number")," by the ",(0,r.kt)("inlineCode",{parentName:"p"},"page_size"),"(1,000) and adding the ",(0,r.kt)("inlineCode",{parentName:"p"},"modulo"),"."),(0,r.kt)("p",null,"If the ",(0,r.kt)("inlineCode",{parentName:"p"},"NFTIdentifierMode")," is set to ",(0,r.kt)("inlineCode",{parentName:"p"},"Ordinal"),", this number corresponds directly to the token ID."),(0,r.kt)("p",null,"If it is set to ",(0,r.kt)("inlineCode",{parentName:"p"},"Hash"),", you will need to reference the ",(0,r.kt)("inlineCode",{parentName:"p"},"HASH_BY_INDEX")," dictionary to determine the mapping of token numbers to token hashes."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5826],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=o.createContext({}),c=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),h=a,m=u["".concat(l,".").concat(h)]||u[h]||d[h]||r;return n?o.createElement(m,i(i({ref:t},p),{},{components:n})):o.createElement(m,i({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var c=2;c}\\_m{modulo}\\_p{}"'),". Once again using the 2,350th token as an example, the receipt would read:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"cep78_collection_m_350_p_2\n")),(0,r.kt)("p",null,"You can determine the token number by multiplying the ",(0,r.kt)("inlineCode",{parentName:"p"},"page_number")," by the ",(0,r.kt)("inlineCode",{parentName:"p"},"page_size"),"(1,000) and adding the ",(0,r.kt)("inlineCode",{parentName:"p"},"modulo"),"."),(0,r.kt)("p",null,"If the ",(0,r.kt)("inlineCode",{parentName:"p"},"NFTIdentifierMode")," is set to ",(0,r.kt)("inlineCode",{parentName:"p"},"Ordinal"),", this number corresponds directly to the token ID."),(0,r.kt)("p",null,"If it is set to ",(0,r.kt)("inlineCode",{parentName:"p"},"Hash"),", you will need to reference the ",(0,r.kt)("inlineCode",{parentName:"p"},"HASH_BY_INDEX")," dictionary to determine the mapping of token numbers to token hashes."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a45056cf.6482f7f0.js b/assets/js/a45056cf.10646cc0.js similarity index 98% rename from assets/js/a45056cf.6482f7f0.js rename to assets/js/a45056cf.10646cc0.js index fba5ec0681..e6545558dc 100644 --- a/assets/js/a45056cf.6482f7f0.js +++ b/assets/js/a45056cf.10646cc0.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6563],{3905:function(e,t,r){r.d(t,{Zo:function(){return l},kt:function(){return h}});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),i=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},l=function(e){var t=i(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=i(r),y=a,h=u["".concat(p,".").concat(y)]||u[y]||f[y]||o;return r?n.createElement(h,s(s({ref:t},l),{},{components:r})):n.createElement(h,s({ref:t},l))}));function h(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var i=2;i=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),i=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},l=function(e){var t=i(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=i(r),y=a,h=u["".concat(p,".").concat(y)]||u[y]||f[y]||o;return r?n.createElement(h,s(s({ref:t},l),{},{components:r})):n.createElement(h,s({ref:t},l))}));function h(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var i=2;i=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),p=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(i.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,i=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),d=p(n),m=r,f=d["".concat(i,".").concat(m)]||d[m]||u[m]||s;return n?a.createElement(f,l(l({ref:t},c),{},{components:n})):a.createElement(f,l({ref:t},c))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,l=new Array(s);l[0]=m;var o={};for(var i in t)hasOwnProperty.call(t,i)&&(o[i]=t[i]);o.originalType=e,o[d]="string"==typeof e?e:r,l[1]=o;for(var p=2;p=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),p=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(i.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,i=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),d=p(n),m=r,f=d["".concat(i,".").concat(m)]||d[m]||u[m]||s;return n?a.createElement(f,l(l({ref:t},c),{},{components:n})):a.createElement(f,l({ref:t},c))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,l=new Array(s);l[0]=m;var o={};for(var i in t)hasOwnProperty.call(t,i)&&(o[i]=t[i]);o.originalType=e,o[d]="string"==typeof e?e:r,l[1]=o;for(var p=2;p=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var i=n.createContext({}),p=function(e){var r=n.useContext(i),t=r;return e&&(t="function"==typeof e?e(r):s(s({},r),e)),t},l=function(e){var r=p(e.components);return n.createElement(i.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=p(t),m=o,f=u["".concat(i,".").concat(m)]||u[m]||d[m]||a;return t?n.createElement(f,s(s({ref:r},l),{},{components:t})):n.createElement(f,s({ref:r},l))}));function f(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,s=new Array(a);s[0]=m;var c={};for(var i in r)hasOwnProperty.call(r,i)&&(c[i]=r[i]);c.originalType=e,c[u]="string"==typeof e?e:o,s[1]=c;for(var p=2;p=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var i=n.createContext({}),p=function(e){var r=n.useContext(i),t=r;return e&&(t="function"==typeof e?e(r):s(s({},r),e)),t},l=function(e){var r=p(e.components);return n.createElement(i.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=p(t),m=o,f=u["".concat(i,".").concat(m)]||u[m]||d[m]||a;return t?n.createElement(f,s(s({ref:r},l),{},{components:t})):n.createElement(f,s({ref:r},l))}));function f(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,s=new Array(a);s[0]=m;var c={};for(var i in r)hasOwnProperty.call(r,i)&&(c[i]=r[i]);c.originalType=e,c[u]="string"==typeof e?e:o,s[1]=c;for(var p=2;p=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),u=p(n),m=o,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return n?r.createElement(f,s(s({ref:t},l),{},{components:n})):r.createElement(f,s({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,s=new Array(a);s[0]=m;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:o,s[1]=i;for(var p=2;p=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),u=p(n),m=o,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return n?r.createElement(f,s(s({ref:t},l),{},{components:n})):r.createElement(f,s({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,s=new Array(a);s[0]=m;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:o,s[1]=i;for(var p=2;p=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),p=d(n),m=r,f=p["".concat(s,".").concat(m)]||p[m]||u[m]||i;return n?a.createElement(f,l(l({ref:t},c),{},{components:n})):a.createElement(f,l({ref:t},c))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,l=new Array(i);l[0]=m;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[p]="string"==typeof e?e:r,l[1]=o;for(var d=2;d 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.')})))?void 0:n.filter(Boolean))?t:[]}(e).map((function(e){var t=e.props;return{value:t.value,label:t.label,attributes:t.attributes,default:t.default}}))}function u(e){var t=e.values,n=e.children;return(0,r.useMemo)((function(){var e=null!=t?t:p(n);return function(e){var t=(0,d.l)(e,(function(e,t){return e.value===t.value}));if(t.length>0)throw new Error('Docusaurus error: Duplicate values "'+t.map((function(e){return e.value})).join(", ")+'" found in . Every value needs to be unique.')}(e),e}),[t,n])}function m(e){var t=e.value;return e.tabValues.some((function(e){return e.value===t}))}function f(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId,i=(0,o.k6)(),l=function(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId;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 null!=a?a:null}({queryString:n,groupId:a});return[(0,s._X)(l),(0,r.useCallback)((function(e){if(l){var t=new URLSearchParams(i.location.search);t.set(l,e),i.replace(Object.assign({},i.location,{search:t.toString()}))}}),[l,i])]}function h(e){var t,n,a,i,l=e.defaultValue,o=e.queryString,s=void 0!==o&&o,d=e.groupId,p=u(e),h=(0,r.useState)((function(){return function(e){var t,n=e.defaultValue,a=e.tabValues;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({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((function(e){return e.value})).join(", ")+". If you intend to show no default tab, use defaultValue={null} instead.");return n}var r=null!=(t=a.find((function(e){return e.default})))?t:a[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:l,tabValues:p})})),v=h[0],k=h[1],b=f({queryString:s,groupId:d}),y=b[0],g=b[1],N=(t=function(e){return e?"docusaurus.tab."+e:null}({groupId:d}.groupId),n=(0,c.Nk)(t),a=n[0],i=n[1],[a,(0,r.useCallback)((function(e){t&&i.set(e)}),[t,i])]),w=N[0],E=N[1],T=function(){var e=null!=y?y:w;return m({value:e,tabValues:p})?e:null}();return(0,r.useLayoutEffect)((function(){T&&k(T)}),[T]),{selectedValue:v,selectValue:(0,r.useCallback)((function(e){if(!m({value:e,tabValues:p}))throw new Error("Can't select invalid tab value="+e);k(e),g(e),E(e)}),[g,E,p]),tabValues:p}}var v=n(2389),k={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function b(e){var t=e.className,n=e.block,o=e.selectedValue,s=e.selectValue,d=e.tabValues,c=[],p=(0,l.o5)().blockElementScrollPositionUntilNextRender,u=function(e){var t=e.currentTarget,n=c.indexOf(t),a=d[n].value;a!==o&&(p(t),s(a))},m=function(e){var t,n=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":var a,r=c.indexOf(e.currentTarget)+1;n=null!=(a=c[r])?a:c[0];break;case"ArrowLeft":var i,l=c.indexOf(e.currentTarget)-1;n=null!=(i=c[l])?i:c[c.length-1]}null==(t=n)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},d.map((function(e){var t=e.value,n=e.label,l=e.attributes;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:o===t?0:-1,"aria-selected":o===t,key:t,ref:function(e){return c.push(e)},onKeyDown:m,onClick:u},l,{className:(0,i.Z)("tabs__item",k.tabItem,null==l?void 0:l.className,{"tabs__item--active":o===t})}),null!=n?n:t)})))}function y(e){var t=e.lazy,n=e.children,a=e.selectedValue,i=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){var l=i.find((function(e){return e.props.value===a}));return l?(0,r.cloneElement)(l,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},i.map((function(e,t){return(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a})})))}function g(e){var t=h(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",k.tabList)},r.createElement(b,(0,a.Z)({},e,t)),r.createElement(y,(0,a.Z)({},e,t)))}function N(e){var t=(0,v.Z)();return r.createElement(g,(0,a.Z)({key:String(t)},e))}},9827:function(e,t,n){n.r(t),n.d(t,{assets:function(){return u},contentTitle:function(){return c},default:function(){return v},frontMatter:function(){return d},metadata:function(){return p},toc:function(){return m}});var a=n(7462),r=n(3366),i=(n(7294),n(3905)),l=n(4866),o=n(5162),s=["components"],d={},c="Monitoring and Consuming Events",p={unversionedId:"developers/dapps/monitor-and-consume-events",id:"developers/dapps/monitor-and-consume-events",title:"Monitoring and Consuming Events",description:"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using Casper's client-side SDKs, dApps actively listening for emitted events can consume these events and perform actions based on event data.",source:"@site/source/docs/casper/developers/dapps/monitor-and-consume-events.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/monitor-and-consume-events",permalink:"/developers/dapps/monitor-and-consume-events",draft:!1,editUrl:"https://github.com/casper-network/docs/tree/dev/source/docs/casper/developers/dapps/monitor-and-consume-events.md",tags:[],version:"current",lastUpdatedAt:1707837031,formattedLastUpdatedAt:"Feb 13, 2024",frontMatter:{},sidebar:"developers",previous:{title:"Local Network Testing",permalink:"/developers/dapps/nctl-test"},next:{title:"Interacting with the Blockchain",permalink:"/developers/cli/"}},u={},m=[{value:"Listening to the Event Stream",id:"listening-to-the-event-stream",level:2},{value:"Event Types",id:"event-types",level:2},{value:"ApiVersion",id:"apiversion",level:3},{value:"BlockAdded",id:"blockadded",level:3},{value:"DeployAccepted",id:"deployaccepted",level:3},{value:"DeployProcessed",id:"deployprocessed",level:3},{value:"DeployExpired",id:"deployexpired",level:3},{value:"Fault",id:"fault",level:3},{value:"FinalitySignature",id:"finalitysignature",level:3},{value:"Step",id:"step",level:3},{value:"Shutdown",id:"shutdown",level:3},{value:"Reacting to Events",id:"reacting-to-events",level:2},{value:"Unsubscribing from Events",id:"unsubscribing-from-events",level:2},{value:"Stopping the Event Stream",id:"stopping-the-event-stream",level:2},{value:"Replaying the Event Stream",id:"replaying-the-event-stream",level:2}],f={toc:m},h="wrapper";function v(e){var t=e.components,n=(0,r.Z)(e,s);return(0,i.kt)(h,(0,a.Z)({},f,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"monitoring-and-consuming-events"},"Monitoring and Consuming Events"),(0,i.kt)("p",null,"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using Casper's client-side SDKs, dApps actively listening for emitted events can consume these events and perform actions based on event data."),(0,i.kt)("p",null,"Each Casper node streams events through the SSE (Server Sent Event) server via the port specified as the ",(0,i.kt)("inlineCode",{parentName:"p"},"event_stream_server.address")," in the node's ",(0,i.kt)("em",{parentName:"p"},"config.toml"),". This port is by default ",(0,i.kt)("inlineCode",{parentName:"p"},"9999")," for nodes on ",(0,i.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/tools/peers"},"Testnet")," and ",(0,i.kt)("a",{parentName:"p",href:"https://cspr.live/tools/peers"},"Mainnet"),"."),(0,i.kt)("p",null,"Events are divided into three categories and streamed on their respective endpoints:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Deploy events")," - Associated with ",(0,i.kt)("a",{parentName:"li",href:"/concepts/design/casper-design#execution-semantics-deploys"},"Deploys")," on a node. Currently, only a ",(0,i.kt)("inlineCode",{parentName:"li"},"DeployAccepted")," event is emitted. The URL to consume deploy-related events on Mainnet and Testnet is ",(0,i.kt)("inlineCode",{parentName:"li"},"http://:9999/events/deploys/"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Finality Signature events")," - Emitted when a block has been finalized and cannot be altered. The URL to consume finality signature events on Mainnet and Testnet is ",(0,i.kt)("inlineCode",{parentName:"li"},"http://:9999/events/sigs/"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Main events")," - All other events fall under this type, including: ",(0,i.kt)("inlineCode",{parentName:"li"},"BlockAdded"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"DeployProcessed"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"DeployExpired"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"Fault"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"Step"),", and ",(0,i.kt)("inlineCode",{parentName:"li"},"Shutdown")," events. The URL to consume these events on Mainnet and Testnet is ",(0,i.kt)("inlineCode",{parentName:"li"},"http://:9999/events/main/"),".")),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},"An ",(0,i.kt)("inlineCode",{parentName:"p"},"ApiVersion")," event is always emitted when a new client connects to a node's SSE server, informing the client of the node's software version.")),(0,i.kt)("h2",{id:"listening-to-the-event-stream"},"Listening to the Event Stream"),(0,i.kt)("p",null,"Applications can listen for such events for a specific account during a particular era, containing certain data. Then, they can parse the data and discard what they do not need. To consume the event stream, set up an event listener in your dApp using the following code:"),(0,i.kt)(l.Z,{mdxType:"Tabs"},(0,i.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-javascript"},'const { EventStream, EventName } = require("casper-js-sdk");\n\nconst es = new EventStream("http://NODE_ADDRESS:9999/events/" + CHANNEL);\nes.start();\nes.subscribe(EventName.EVENT_NAME, eventHandler);\n\nconst eventHandler = (event) => {\n console.log(event);\n};\n'))),(0,i.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-python"},'from pycspr import NodeClient, NodeConnection, NodeEventChannel, NodeEventType\n\ndef eventHandler(event):\n print(event)\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\nclient.get_events(eventHandler, NodeEventChannel.CHANNEL, NodeEventType.EVENT_NAME)\n'))),(0,i.kt)(o.Z,{value:"curl",label:"cURL",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s http://NODE_ADDRESS:9999/events/CHANNEL\n")))),(0,i.kt)("p",null,"You can find node addresses of active online peers to replace ",(0,i.kt)("inlineCode",{parentName:"p"},"NODE_ADDRESS"),", by navigating to ",(0,i.kt)("a",{parentName:"p",href:"https://cspr.live/tools/peers"},"cspr.live")," for Mainnet and ",(0,i.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/tools/peers"},"testnet.cspr.live")," for Testnet."),(0,i.kt)("p",null,"Replace ",(0,i.kt)("inlineCode",{parentName:"p"},"EVENT_NAME")," with one of the event types listed ",(0,i.kt)("a",{parentName:"p",href:"#event-types"},"below"),"."),(0,i.kt)("p",null,"Replace ",(0,i.kt)("inlineCode",{parentName:"p"},"CHANNEL")," with one of the following event streams:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"main")," for ",(0,i.kt)("inlineCode",{parentName:"li"},"ApiVersion"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"BlockAdded"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"DeployExpired"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"DeployProcessed"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"Fault"),", or ",(0,i.kt)("inlineCode",{parentName:"li"},"Step")," events."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"deploys")," for ",(0,i.kt)("inlineCode",{parentName:"li"},"DeployAccepted")," events."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"sigs")," for ",(0,i.kt)("inlineCode",{parentName:"li"},"FinalitySignature")," events.")),(0,i.kt)("h2",{id:"event-types"},"Event Types"),(0,i.kt)("h3",{id:"apiversion"},"ApiVersion"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"ApiVersion")," event is always the first event emitted when a new client connects to a node's SSE server. It specifies the protocol version of a node on the Casper platform. The following example contains the JSON representation of the ",(0,i.kt)("inlineCode",{parentName:"p"},"ApiVersion")," event structure."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'data:{"ApiVersion":"1.0.0"}\n')),(0,i.kt)("h3",{id:"blockadded"},"BlockAdded"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"BlockAdded")," event is emitted when a new block is added to the blockchain and stored locally in the node."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand to view output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "BlockAdded": {\n "block_hash": "62ddf902e9b6988b978413e2a9a2c6c95f8e1ddf452afd8e8a68f0ac22bf391a",\n "block": {\n "hash": "62ddf105e9b6988b378413e2a9a2c6c95f8e1ddf458afd8e8268f0ac72bfe91a",\n "header": {\n "parent_hash": "ed11ac2117edb9c5b26cf0cde318a807fd68e76206855a70429012ef16b557f5",\n "state_root_hash": "3c1ad31757ae40f934de4825a818274e0c246d304c661daf656e22b65174ad66",\n "body_hash": "eb2344f37193395bbc83587e498bc12ad5f0019055abcfa4c3b989d382a7969a",\n "random_bit": true,\n "accumulated_seed": "b8b671530f2221c8fdf201083f43c51e215e2f6ffcbe2d63238a2779eb177922",\n "era_end": null,\n "timestamp": "2023-01-01T09:55:25.312Z",\n "era_id": 8426,\n "height": 1566677,\n "protocol_version": "1.4.13"\n },\n "body": {\n "proposer": "010e5669b0f0545e2b32bc66363b9d3d4390fca56bf52305f1411b7fa12ca311c7",\n "deploy_hashes": [],\n "transfer_hashes": []\n },\n "proofs": []\n }\n }\n}\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#block-hash"},"block_hash")," - The cryptographic hash that identifies a block."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#serialization-standard-block"},"block")," - The JSON representation of the block."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#body"},"proposer")," - The validator selected to propose the block."))),(0,i.kt)("h3",{id:"deployaccepted"},"DeployAccepted"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"DeployAccepted")," events are emitted when a node on the network receives a deploy."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand to view output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "DeployAccepted": {\n "hash": "db84ba229ea37716230ac9874f66c0f12b9731d8d42f28060e481ef3d7263ead",\n "header": {\n "account": "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c",\n "timestamp": "2023-01-01T20:22:45.383Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "8a377b07a01ac23905b2e416ff388508301feffbb9bdf275c59f87be1e9d0de5",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "040008af2f",\n "parsed": "800000000"\n }\n ]\n ]\n }\n },\n "session": {\n "StoredContractByHash": {\n "hash": "1040f40d06f0355a80149befc4b5d1f203231231d66c4903688e178c36066539",\n "entry_point": "test_entry_point",\n "args": [\n [\n "cost",\n {\n "cl_type": "U512",\n "bytes": "0500c817a804",\n "parsed": "20000000000"\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c",\n "signature": "01d81d4dc9504a356c23d3c161b87b39b1708cd282b59d3e44d9b999e787643ab495f168475bed8dc48d1056605e06c8ba74d96c69ae5b506c4312be8871c0c701"\n }\n ]\n }\n}\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/hash-types"},"hash")," - The blake2b hash of the Deploy."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#serialization-standard-account"},"account")," - The hexadecimal-encoded public key of the account submitting the Deploy."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/hash-types"},"body_hash")," - The blake2b hash of the Deploy body."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/glossary/P#payment-code"},"payment")," - Gas payment information."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code"},"session")," - The session logic defining the Deploy's functionality."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/developers/json-rpc/types_chain#approval"},"approvals")," - The signer's hexadecimal-encoded public key and signature."))),(0,i.kt)("p",null,"For details on custom serializations, check the ",(0,i.kt)("a",{parentName:"p",href:"/concepts/serialization-standard"},"Serialization Standard"),". Also, the ",(0,i.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_chain"},"Types")," page defines the terms used in the event stream output."),(0,i.kt)("h3",{id:"deployprocessed"},"DeployProcessed"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"DeployProcessed")," event is emitted when a given Deploy has been executed."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand to view output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "DeployProcessed": {\n "deploy_hash": "0f33be8f56ff23d7d503a9804675472e043830a6c17e6141dce717b4f0973c7d",\n "account": "0201cbff12155b6ae1e99d571c01d56e9e1ba0def6719a6f06bc3e4a08f30a887444",\n "timestamp": "2023-01-01T10:07:00.401Z",\n "ttl": "30m",\n "dependencies": [],\n "block_hash": "509b754648168a73e6ab67e64d4a783cf580d6fc0c7c0ec560c6650f717841e0",\n "execution_result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "account-hash-a8261377ef9cf8e7411d6858801c71e28c9322e66355586549c75ab24cdd73f2",\n "transform": "Identity"\n }\n ]\n },\n "transfers": ["transfer-3389144d15238240f48f5966f2dc299b6b20eb19c13d834409b4d28fc50fa909"],\n "cost": "100000000"\n }\n }\n }\n}\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#deploy-hash"},"deploy_hash")," - The cryptographic hash of a Deploy."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#serialization-standard-account"},"account")," - The hexadecimal-encoded public key of the account submitting the Deploy."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#timestamp"},"timestamp")," - A timestamp type representing a concrete moment in time."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#deploy-header"},"dependencies")," - A list of Deploy hashes."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#block-hash"},"block_hash")," - A cryptographic hash identifying a Block."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#executionresult"},"execution_result")," - The execution status of the Deploy, which is either ",(0,i.kt)("inlineCode",{parentName:"li"},"Success")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"Failure"),"."))),(0,i.kt)("h3",{id:"deployexpired"},"DeployExpired"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"DeployExpired")," event is emitted when the Deploy is no longer valid for processing or being added to a block due to its time to live (TTL) having expired."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand to view output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "DeployExpired": {\n "deploy_hash": "7ecf22fc284526d6db16fbf455f489e0a9cbf782234131c010cf3078fb9be353"\n }\n}\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#deploy-hash"},"deploy_hash")," - The cryptographic hash of a Deploy."))),(0,i.kt)("h3",{id:"fault"},"Fault"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"Fault")," event is emitted if there is a validator error."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand the below section to view the Fault event details:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "Fault": {\n "era_id": 4591448806312642600,\n "public_key": "013da85eb06279da42e28530e1116be04bfd2aa25ed8d63401ebff4d9153a609a9",\n "timestamp": "2023-01-01T01:26:58.364Z"\n }\n}\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#eraid"},"era_id")," - A period of time during which the validator set does not change."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#publickey"},"public_key")," - The hexadecimal-encoded public key of the validator that caused the fault."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#timestamp"},"timestamp")," - A timestamp representing the moment the validator faulted."))),(0,i.kt)("h3",{id:"finalitysignature"},"FinalitySignature"),(0,i.kt)("p",null,"This event indicates validators have signed the final approvals and further alterations to the block will not be allowed. Refer to the ",(0,i.kt)("a",{parentName:"p",href:"/deploy-and-deploy-lifecycle#consensus-reached"},"consensus reached")," and ",(0,i.kt)("a",{parentName:"p",href:"/concepts/glossary/B#block-finality"},"block finality")," sections to learn more about finality signatures."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand to view output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "FinalitySignature": {\n "block_hash": "eceed827e11f7969a7d3fe91d6fa4ce9749dd79d9f3ea26474fe2014db90e98d",\n "era_id": 8419,\n "signature": "0117087ef4b9a786e5a0ea8f198050e9de93dd94f87469b8124c346aeae5f36ad9adf80f670ee9c5887263267ed32cf932dce9b370353c596d59f91fbd57a1a205",\n "public_key": "01c375b425a36de25dc325c9182861679db2f634abcacd9ae2ee27b84ba62ac1f7"\n }\n}\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#block-hash"},"block_hash")," - A cryptographic hash identifying a Block."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#eraid"},"era_id")," - A period of time during which the validator set does not change."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#signature"},"signature")," - Serialized bytes representing the validator's signature."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#publickey"},"public_key")," - The hexadecimal-encoded public key of the validator."))),(0,i.kt)("h3",{id:"step"},"Step"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"Step")," event is emitted at the end of every era and contains the execution effects produced by running the auction contract's ",(0,i.kt)("inlineCode",{parentName:"p"},"step")," function."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand to view output:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "Step": {\n "era_id": 1,\n "execution_effect": {\n "operations": [],\n "transforms": [\n {\n "key": "uref-53df18bf01396fbd1ef3a8757c7bdffc684c407d90f2cfeebff166db1d923613-000",\n "transform": "Identity"\n },\n {\n "key": "uref-f268de37fcea55f8fb1abeba8536a1cc041b2aed2691f1cf34aeaaf0ae379aa5-000",\n "transform": "Identity"\n },\n {\n "key": "bid-278e5af1ca6cddf5d5438999cb072b47f0d65e1484799f692c3c9c40304be30e",\n "transform": "Identity"\n },\n {\n "key": "bid-278e5af1ca6cddf5d5438999cb072b47f0d65e1484799f692c3c9c40304be30e",\n "transform": {\n "WriteBid": {\n "validator_public_key": "0133eaae2821f090ac3ba0eadc0a897742094c0604df72b465c41d4b773298a7b9",\n "bonding_purse": "uref-136552c255d4d737bf7e43d2be250f9f38691b9fe5d9e34446bff18d6d1cf984-007",\n "staked_amount": "1000000000000005",\n "delegation_rate": 5,\n "vesting_schedule": {\n "initial_release_timestamp_millis": 1664475057182,\n "locked_amounts": null\n },\n "delegators": {\n "012a241eaa9fa3bd6ccb0e0aaaf4658538f3540e04e2f58973614a168f2f2f813d": {\n "delegator_public_key": "012a241eaa9fa3bd6ccb0e0aaaf4658538f3540e04e2f58973614a168f2f2f813d",\n "staked_amount": "51312014671568117976319379",\n "bonding_purse": "uref-c5ad00f9e6b2f2631ca647ad188187e63799a278a0a46ca25f6b4da64d556662-007",\n "validator_public_key": "0133eaae2821f090ac3ba0eadc0a897742094c0604df72b465c41d4b773298a7b9",\n "vesting_schedule": {\n "initial_release_timestamp_millis": 1664475057182,\n "locked_amounts": null\n }\n }\n },\n "inactive": false\n }\n }\n }\n ]\n }\n }\n}\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#eraid"},"era_id")," - A period of time during which the validator set does not change."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#executioneffect"},"execution_effect")," - The journal of execution transforms from a single Deploy."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#operation"},"operations")," - Operations performed while executing a Deploy."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#transform"},"transform")," - The actual transformation performed while executing a Deploy."))),(0,i.kt)("h3",{id:"shutdown"},"Shutdown"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"Shutdown")," event is emitted when the node is about to shut down, usually for an upgrade, causing a termination of the event stream."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand the below section to view the Shutdown event details:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'"Shutdown"\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},'Shutdown - The "Shutdown" text notifies the event listener that a shutdown will occur.'))),(0,i.kt)("h2",{id:"reacting-to-events"},"Reacting to Events"),(0,i.kt)("p",null,"An application may parse each event needed for its use case and respond accordingly. The dApp may act on some events and not others, or it may act upon them all, depending on its use case. Each event type contains additional data that might help in deciding whether or not to take an action. For example, ",(0,i.kt)("inlineCode",{parentName:"p"},"DeployAccepted")," events contain the account's public key that submitted the deploy, the contract address, and more. This information can help determine how to proceed or whether or not to react."),(0,i.kt)(l.Z,{mdxType:"Tabs"},(0,i.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-javascript"},'const eventHandler = (event) => {\n if (event.body.DeployAccepted.header.account == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c") {\n // Perform an action\n }\n};\n'))),(0,i.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-python"},'def eventHandler(event):\n if event["DeployAccepted"]["header"]["account"] == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c":\n # Perform an action\n')))),(0,i.kt)("h2",{id:"unsubscribing-from-events"},"Unsubscribing from Events"),(0,i.kt)("p",null,"In many cases, an application may need to unsubscribe after a certain time or may want to unsubscribe from some events but not others. The Casper SDKs provide this ability with the ",(0,i.kt)("inlineCode",{parentName:"p"},"unsubscribe")," function:"),(0,i.kt)(l.Z,{mdxType:"Tabs"},(0,i.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-javascript"},"es.unsubscribe(EventName.EVENT_NAME);\n")))),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"EVENT_NAME")," - One of the different ",(0,i.kt)("a",{parentName:"li",href:"#event-types"},"event types")," emitted by a Casper node.")),(0,i.kt)("h2",{id:"stopping-the-event-stream"},"Stopping the Event Stream"),(0,i.kt)("p",null,"A dApp may cease listening to all events using the ",(0,i.kt)("inlineCode",{parentName:"p"},"stop")," function:"),(0,i.kt)(l.Z,{mdxType:"Tabs"},(0,i.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-javascript"},"es.stop();\n")))),(0,i.kt)("h2",{id:"replaying-the-event-stream"},"Replaying the Event Stream"),(0,i.kt)("p",null,"This command will replay the event stream from an old event onward. Replace the ",(0,i.kt)("inlineCode",{parentName:"p"},"NODE_ADDRESS"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"CHANNEL"),", and ",(0,i.kt)("inlineCode",{parentName:"p"},"ID")," fields with the values of your scenario."),(0,i.kt)(l.Z,{mdxType:"Tabs"},(0,i.kt)(o.Z,{value:"curl",label:"cURL",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"curl -sN http://NODE_ADDRESS:9999/events/CHANNEL?start_from=ID\n")),(0,i.kt)("p",null,(0,i.kt)("em",{parentName:"p"},"Example:")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"curl -sN http://65.21.235.219:9999/events/main?start_from=29267508\n")))),(0,i.kt)("p",null,"Each URL can have a query string added to the form ",(0,i.kt)("inlineCode",{parentName:"p"},"?start_from=ID"),", where ID is an integer representing an old event ID. With this query, you can replay the event stream from that old event onward. If you specify an event ID already purged from the cache, the server will replay all the cached events."),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},"The server keeps only a limited number of events cached to allow replaying the stream to clients using the ",(0,i.kt)("inlineCode",{parentName:"p"},"?start_from=")," query string. The cache size can be set differently on each node using the ",(0,i.kt)("inlineCode",{parentName:"p"},"event_stream_buffer_length")," value in the ",(0,i.kt)("em",{parentName:"p"},"config.toml"),". By default, it is only 5000. The intended use case is to allow a client consuming the event stream that loses its connection to reconnect and catch up with events that were emitted while it was disconnected.")))}v.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[2691],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return f}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),p=d(n),m=r,f=p["".concat(s,".").concat(m)]||p[m]||u[m]||i;return n?a.createElement(f,l(l({ref:t},c),{},{components:n})):a.createElement(f,l({ref:t},c))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,l=new Array(i);l[0]=m;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[p]="string"==typeof e?e:r,l[1]=o;for(var d=2;d 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.')})))?void 0:n.filter(Boolean))?t:[]}(e).map((function(e){var t=e.props;return{value:t.value,label:t.label,attributes:t.attributes,default:t.default}}))}function u(e){var t=e.values,n=e.children;return(0,r.useMemo)((function(){var e=null!=t?t:p(n);return function(e){var t=(0,d.l)(e,(function(e,t){return e.value===t.value}));if(t.length>0)throw new Error('Docusaurus error: Duplicate values "'+t.map((function(e){return e.value})).join(", ")+'" found in . Every value needs to be unique.')}(e),e}),[t,n])}function m(e){var t=e.value;return e.tabValues.some((function(e){return e.value===t}))}function f(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId,i=(0,o.k6)(),l=function(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId;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 null!=a?a:null}({queryString:n,groupId:a});return[(0,s._X)(l),(0,r.useCallback)((function(e){if(l){var t=new URLSearchParams(i.location.search);t.set(l,e),i.replace(Object.assign({},i.location,{search:t.toString()}))}}),[l,i])]}function h(e){var t,n,a,i,l=e.defaultValue,o=e.queryString,s=void 0!==o&&o,d=e.groupId,p=u(e),h=(0,r.useState)((function(){return function(e){var t,n=e.defaultValue,a=e.tabValues;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({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((function(e){return e.value})).join(", ")+". If you intend to show no default tab, use defaultValue={null} instead.");return n}var r=null!=(t=a.find((function(e){return e.default})))?t:a[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:l,tabValues:p})})),v=h[0],k=h[1],b=f({queryString:s,groupId:d}),y=b[0],g=b[1],N=(t=function(e){return e?"docusaurus.tab."+e:null}({groupId:d}.groupId),n=(0,c.Nk)(t),a=n[0],i=n[1],[a,(0,r.useCallback)((function(e){t&&i.set(e)}),[t,i])]),w=N[0],E=N[1],T=function(){var e=null!=y?y:w;return m({value:e,tabValues:p})?e:null}();return(0,r.useLayoutEffect)((function(){T&&k(T)}),[T]),{selectedValue:v,selectValue:(0,r.useCallback)((function(e){if(!m({value:e,tabValues:p}))throw new Error("Can't select invalid tab value="+e);k(e),g(e),E(e)}),[g,E,p]),tabValues:p}}var v=n(2389),k={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function b(e){var t=e.className,n=e.block,o=e.selectedValue,s=e.selectValue,d=e.tabValues,c=[],p=(0,l.o5)().blockElementScrollPositionUntilNextRender,u=function(e){var t=e.currentTarget,n=c.indexOf(t),a=d[n].value;a!==o&&(p(t),s(a))},m=function(e){var t,n=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":var a,r=c.indexOf(e.currentTarget)+1;n=null!=(a=c[r])?a:c[0];break;case"ArrowLeft":var i,l=c.indexOf(e.currentTarget)-1;n=null!=(i=c[l])?i:c[c.length-1]}null==(t=n)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},d.map((function(e){var t=e.value,n=e.label,l=e.attributes;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:o===t?0:-1,"aria-selected":o===t,key:t,ref:function(e){return c.push(e)},onKeyDown:m,onClick:u},l,{className:(0,i.Z)("tabs__item",k.tabItem,null==l?void 0:l.className,{"tabs__item--active":o===t})}),null!=n?n:t)})))}function y(e){var t=e.lazy,n=e.children,a=e.selectedValue,i=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){var l=i.find((function(e){return e.props.value===a}));return l?(0,r.cloneElement)(l,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},i.map((function(e,t){return(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a})})))}function g(e){var t=h(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",k.tabList)},r.createElement(b,(0,a.Z)({},e,t)),r.createElement(y,(0,a.Z)({},e,t)))}function N(e){var t=(0,v.Z)();return r.createElement(g,(0,a.Z)({key:String(t)},e))}},9827:function(e,t,n){n.r(t),n.d(t,{assets:function(){return u},contentTitle:function(){return c},default:function(){return v},frontMatter:function(){return d},metadata:function(){return p},toc:function(){return m}});var a=n(7462),r=n(3366),i=(n(7294),n(3905)),l=n(4866),o=n(5162),s=["components"],d={},c="Monitoring and Consuming Events",p={unversionedId:"developers/dapps/monitor-and-consume-events",id:"developers/dapps/monitor-and-consume-events",title:"Monitoring and Consuming Events",description:"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using Casper's client-side SDKs, dApps actively listening for emitted events can consume these events and perform actions based on event data.",source:"@site/source/docs/casper/developers/dapps/monitor-and-consume-events.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/monitor-and-consume-events",permalink:"/developers/dapps/monitor-and-consume-events",draft:!1,editUrl:"https://github.com/casper-network/docs/tree/dev/source/docs/casper/developers/dapps/monitor-and-consume-events.md",tags:[],version:"current",lastUpdatedAt:1708091908,formattedLastUpdatedAt:"Feb 16, 2024",frontMatter:{},sidebar:"developers",previous:{title:"Local Network Testing",permalink:"/developers/dapps/nctl-test"},next:{title:"Interacting with the Blockchain",permalink:"/developers/cli/"}},u={},m=[{value:"Listening to the Event Stream",id:"listening-to-the-event-stream",level:2},{value:"Event Types",id:"event-types",level:2},{value:"ApiVersion",id:"apiversion",level:3},{value:"BlockAdded",id:"blockadded",level:3},{value:"DeployAccepted",id:"deployaccepted",level:3},{value:"DeployProcessed",id:"deployprocessed",level:3},{value:"DeployExpired",id:"deployexpired",level:3},{value:"Fault",id:"fault",level:3},{value:"FinalitySignature",id:"finalitysignature",level:3},{value:"Step",id:"step",level:3},{value:"Shutdown",id:"shutdown",level:3},{value:"Reacting to Events",id:"reacting-to-events",level:2},{value:"Unsubscribing from Events",id:"unsubscribing-from-events",level:2},{value:"Stopping the Event Stream",id:"stopping-the-event-stream",level:2},{value:"Replaying the Event Stream",id:"replaying-the-event-stream",level:2}],f={toc:m},h="wrapper";function v(e){var t=e.components,n=(0,r.Z)(e,s);return(0,i.kt)(h,(0,a.Z)({},f,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"monitoring-and-consuming-events"},"Monitoring and Consuming Events"),(0,i.kt)("p",null,"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using Casper's client-side SDKs, dApps actively listening for emitted events can consume these events and perform actions based on event data."),(0,i.kt)("p",null,"Each Casper node streams events through the SSE (Server Sent Event) server via the port specified as the ",(0,i.kt)("inlineCode",{parentName:"p"},"event_stream_server.address")," in the node's ",(0,i.kt)("em",{parentName:"p"},"config.toml"),". This port is by default ",(0,i.kt)("inlineCode",{parentName:"p"},"9999")," for nodes on ",(0,i.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/tools/peers"},"Testnet")," and ",(0,i.kt)("a",{parentName:"p",href:"https://cspr.live/tools/peers"},"Mainnet"),"."),(0,i.kt)("p",null,"Events are divided into three categories and streamed on their respective endpoints:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Deploy events")," - Associated with ",(0,i.kt)("a",{parentName:"li",href:"/concepts/design/casper-design#execution-semantics-deploys"},"Deploys")," on a node. Currently, only a ",(0,i.kt)("inlineCode",{parentName:"li"},"DeployAccepted")," event is emitted. The URL to consume deploy-related events on Mainnet and Testnet is ",(0,i.kt)("inlineCode",{parentName:"li"},"http://:9999/events/deploys/"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Finality Signature events")," - Emitted when a block has been finalized and cannot be altered. The URL to consume finality signature events on Mainnet and Testnet is ",(0,i.kt)("inlineCode",{parentName:"li"},"http://:9999/events/sigs/"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Main events")," - All other events fall under this type, including: ",(0,i.kt)("inlineCode",{parentName:"li"},"BlockAdded"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"DeployProcessed"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"DeployExpired"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"Fault"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"Step"),", and ",(0,i.kt)("inlineCode",{parentName:"li"},"Shutdown")," events. The URL to consume these events on Mainnet and Testnet is ",(0,i.kt)("inlineCode",{parentName:"li"},"http://:9999/events/main/"),".")),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},"An ",(0,i.kt)("inlineCode",{parentName:"p"},"ApiVersion")," event is always emitted when a new client connects to a node's SSE server, informing the client of the node's software version.")),(0,i.kt)("h2",{id:"listening-to-the-event-stream"},"Listening to the Event Stream"),(0,i.kt)("p",null,"Applications can listen for such events for a specific account during a particular era, containing certain data. Then, they can parse the data and discard what they do not need. To consume the event stream, set up an event listener in your dApp using the following code:"),(0,i.kt)(l.Z,{mdxType:"Tabs"},(0,i.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-javascript"},'const { EventStream, EventName } = require("casper-js-sdk");\n\nconst es = new EventStream("http://NODE_ADDRESS:9999/events/" + CHANNEL);\nes.start();\nes.subscribe(EventName.EVENT_NAME, eventHandler);\n\nconst eventHandler = (event) => {\n console.log(event);\n};\n'))),(0,i.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-python"},'from pycspr import NodeClient, NodeConnection, NodeEventChannel, NodeEventType\n\ndef eventHandler(event):\n print(event)\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\nclient.get_events(eventHandler, NodeEventChannel.CHANNEL, NodeEventType.EVENT_NAME)\n'))),(0,i.kt)(o.Z,{value:"curl",label:"cURL",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s http://NODE_ADDRESS:9999/events/CHANNEL\n")))),(0,i.kt)("p",null,"You can find node addresses of active online peers to replace ",(0,i.kt)("inlineCode",{parentName:"p"},"NODE_ADDRESS"),", by navigating to ",(0,i.kt)("a",{parentName:"p",href:"https://cspr.live/tools/peers"},"cspr.live")," for Mainnet and ",(0,i.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/tools/peers"},"testnet.cspr.live")," for Testnet."),(0,i.kt)("p",null,"Replace ",(0,i.kt)("inlineCode",{parentName:"p"},"EVENT_NAME")," with one of the event types listed ",(0,i.kt)("a",{parentName:"p",href:"#event-types"},"below"),"."),(0,i.kt)("p",null,"Replace ",(0,i.kt)("inlineCode",{parentName:"p"},"CHANNEL")," with one of the following event streams:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"main")," for ",(0,i.kt)("inlineCode",{parentName:"li"},"ApiVersion"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"BlockAdded"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"DeployExpired"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"DeployProcessed"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"Fault"),", or ",(0,i.kt)("inlineCode",{parentName:"li"},"Step")," events."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"deploys")," for ",(0,i.kt)("inlineCode",{parentName:"li"},"DeployAccepted")," events."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"sigs")," for ",(0,i.kt)("inlineCode",{parentName:"li"},"FinalitySignature")," events.")),(0,i.kt)("h2",{id:"event-types"},"Event Types"),(0,i.kt)("h3",{id:"apiversion"},"ApiVersion"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"ApiVersion")," event is always the first event emitted when a new client connects to a node's SSE server. It specifies the protocol version of a node on the Casper platform. The following example contains the JSON representation of the ",(0,i.kt)("inlineCode",{parentName:"p"},"ApiVersion")," event structure."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'data:{"ApiVersion":"1.0.0"}\n')),(0,i.kt)("h3",{id:"blockadded"},"BlockAdded"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"BlockAdded")," event is emitted when a new block is added to the blockchain and stored locally in the node."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand to view output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "BlockAdded": {\n "block_hash": "62ddf902e9b6988b978413e2a9a2c6c95f8e1ddf452afd8e8a68f0ac22bf391a",\n "block": {\n "hash": "62ddf105e9b6988b378413e2a9a2c6c95f8e1ddf458afd8e8268f0ac72bfe91a",\n "header": {\n "parent_hash": "ed11ac2117edb9c5b26cf0cde318a807fd68e76206855a70429012ef16b557f5",\n "state_root_hash": "3c1ad31757ae40f934de4825a818274e0c246d304c661daf656e22b65174ad66",\n "body_hash": "eb2344f37193395bbc83587e498bc12ad5f0019055abcfa4c3b989d382a7969a",\n "random_bit": true,\n "accumulated_seed": "b8b671530f2221c8fdf201083f43c51e215e2f6ffcbe2d63238a2779eb177922",\n "era_end": null,\n "timestamp": "2023-01-01T09:55:25.312Z",\n "era_id": 8426,\n "height": 1566677,\n "protocol_version": "1.4.13"\n },\n "body": {\n "proposer": "010e5669b0f0545e2b32bc66363b9d3d4390fca56bf52305f1411b7fa12ca311c7",\n "deploy_hashes": [],\n "transfer_hashes": []\n },\n "proofs": []\n }\n }\n}\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#block-hash"},"block_hash")," - The cryptographic hash that identifies a block."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#serialization-standard-block"},"block")," - The JSON representation of the block."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#body"},"proposer")," - The validator selected to propose the block."))),(0,i.kt)("h3",{id:"deployaccepted"},"DeployAccepted"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"DeployAccepted")," events are emitted when a node on the network receives a deploy."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand to view output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "DeployAccepted": {\n "hash": "db84ba229ea37716230ac9874f66c0f12b9731d8d42f28060e481ef3d7263ead",\n "header": {\n "account": "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c",\n "timestamp": "2023-01-01T20:22:45.383Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "8a377b07a01ac23905b2e416ff388508301feffbb9bdf275c59f87be1e9d0de5",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "040008af2f",\n "parsed": "800000000"\n }\n ]\n ]\n }\n },\n "session": {\n "StoredContractByHash": {\n "hash": "1040f40d06f0355a80149befc4b5d1f203231231d66c4903688e178c36066539",\n "entry_point": "test_entry_point",\n "args": [\n [\n "cost",\n {\n "cl_type": "U512",\n "bytes": "0500c817a804",\n "parsed": "20000000000"\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c",\n "signature": "01d81d4dc9504a356c23d3c161b87b39b1708cd282b59d3e44d9b999e787643ab495f168475bed8dc48d1056605e06c8ba74d96c69ae5b506c4312be8871c0c701"\n }\n ]\n }\n}\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/hash-types"},"hash")," - The blake2b hash of the Deploy."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#serialization-standard-account"},"account")," - The hexadecimal-encoded public key of the account submitting the Deploy."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/hash-types"},"body_hash")," - The blake2b hash of the Deploy body."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/glossary/P#payment-code"},"payment")," - Gas payment information."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code"},"session")," - The session logic defining the Deploy's functionality."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/developers/json-rpc/types_chain#approval"},"approvals")," - The signer's hexadecimal-encoded public key and signature."))),(0,i.kt)("p",null,"For details on custom serializations, check the ",(0,i.kt)("a",{parentName:"p",href:"/concepts/serialization-standard"},"Serialization Standard"),". Also, the ",(0,i.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_chain"},"Types")," page defines the terms used in the event stream output."),(0,i.kt)("h3",{id:"deployprocessed"},"DeployProcessed"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"DeployProcessed")," event is emitted when a given Deploy has been executed."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand to view output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "DeployProcessed": {\n "deploy_hash": "0f33be8f56ff23d7d503a9804675472e043830a6c17e6141dce717b4f0973c7d",\n "account": "0201cbff12155b6ae1e99d571c01d56e9e1ba0def6719a6f06bc3e4a08f30a887444",\n "timestamp": "2023-01-01T10:07:00.401Z",\n "ttl": "30m",\n "dependencies": [],\n "block_hash": "509b754648168a73e6ab67e64d4a783cf580d6fc0c7c0ec560c6650f717841e0",\n "execution_result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "account-hash-a8261377ef9cf8e7411d6858801c71e28c9322e66355586549c75ab24cdd73f2",\n "transform": "Identity"\n }\n ]\n },\n "transfers": ["transfer-3389144d15238240f48f5966f2dc299b6b20eb19c13d834409b4d28fc50fa909"],\n "cost": "100000000"\n }\n }\n }\n}\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#deploy-hash"},"deploy_hash")," - The cryptographic hash of a Deploy."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#serialization-standard-account"},"account")," - The hexadecimal-encoded public key of the account submitting the Deploy."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#timestamp"},"timestamp")," - A timestamp type representing a concrete moment in time."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#deploy-header"},"dependencies")," - A list of Deploy hashes."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#block-hash"},"block_hash")," - A cryptographic hash identifying a Block."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#executionresult"},"execution_result")," - The execution status of the Deploy, which is either ",(0,i.kt)("inlineCode",{parentName:"li"},"Success")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"Failure"),"."))),(0,i.kt)("h3",{id:"deployexpired"},"DeployExpired"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"DeployExpired")," event is emitted when the Deploy is no longer valid for processing or being added to a block due to its time to live (TTL) having expired."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand to view output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "DeployExpired": {\n "deploy_hash": "7ecf22fc284526d6db16fbf455f489e0a9cbf782234131c010cf3078fb9be353"\n }\n}\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#deploy-hash"},"deploy_hash")," - The cryptographic hash of a Deploy."))),(0,i.kt)("h3",{id:"fault"},"Fault"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"Fault")," event is emitted if there is a validator error."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand the below section to view the Fault event details:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "Fault": {\n "era_id": 4591448806312642600,\n "public_key": "013da85eb06279da42e28530e1116be04bfd2aa25ed8d63401ebff4d9153a609a9",\n "timestamp": "2023-01-01T01:26:58.364Z"\n }\n}\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#eraid"},"era_id")," - A period of time during which the validator set does not change."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#publickey"},"public_key")," - The hexadecimal-encoded public key of the validator that caused the fault."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#timestamp"},"timestamp")," - A timestamp representing the moment the validator faulted."))),(0,i.kt)("h3",{id:"finalitysignature"},"FinalitySignature"),(0,i.kt)("p",null,"This event indicates validators have signed the final approvals and further alterations to the block will not be allowed. Refer to the ",(0,i.kt)("a",{parentName:"p",href:"/deploy-and-deploy-lifecycle#consensus-reached"},"consensus reached")," and ",(0,i.kt)("a",{parentName:"p",href:"/concepts/glossary/B#block-finality"},"block finality")," sections to learn more about finality signatures."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand to view output"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "FinalitySignature": {\n "block_hash": "eceed827e11f7969a7d3fe91d6fa4ce9749dd79d9f3ea26474fe2014db90e98d",\n "era_id": 8419,\n "signature": "0117087ef4b9a786e5a0ea8f198050e9de93dd94f87469b8124c346aeae5f36ad9adf80f670ee9c5887263267ed32cf932dce9b370353c596d59f91fbd57a1a205",\n "public_key": "01c375b425a36de25dc325c9182861679db2f634abcacd9ae2ee27b84ba62ac1f7"\n }\n}\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#block-hash"},"block_hash")," - A cryptographic hash identifying a Block."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#eraid"},"era_id")," - A period of time during which the validator set does not change."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#signature"},"signature")," - Serialized bytes representing the validator's signature."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#publickey"},"public_key")," - The hexadecimal-encoded public key of the validator."))),(0,i.kt)("h3",{id:"step"},"Step"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"Step")," event is emitted at the end of every era and contains the execution effects produced by running the auction contract's ",(0,i.kt)("inlineCode",{parentName:"p"},"step")," function."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand to view output:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "Step": {\n "era_id": 1,\n "execution_effect": {\n "operations": [],\n "transforms": [\n {\n "key": "uref-53df18bf01396fbd1ef3a8757c7bdffc684c407d90f2cfeebff166db1d923613-000",\n "transform": "Identity"\n },\n {\n "key": "uref-f268de37fcea55f8fb1abeba8536a1cc041b2aed2691f1cf34aeaaf0ae379aa5-000",\n "transform": "Identity"\n },\n {\n "key": "bid-278e5af1ca6cddf5d5438999cb072b47f0d65e1484799f692c3c9c40304be30e",\n "transform": "Identity"\n },\n {\n "key": "bid-278e5af1ca6cddf5d5438999cb072b47f0d65e1484799f692c3c9c40304be30e",\n "transform": {\n "WriteBid": {\n "validator_public_key": "0133eaae2821f090ac3ba0eadc0a897742094c0604df72b465c41d4b773298a7b9",\n "bonding_purse": "uref-136552c255d4d737bf7e43d2be250f9f38691b9fe5d9e34446bff18d6d1cf984-007",\n "staked_amount": "1000000000000005",\n "delegation_rate": 5,\n "vesting_schedule": {\n "initial_release_timestamp_millis": 1664475057182,\n "locked_amounts": null\n },\n "delegators": {\n "012a241eaa9fa3bd6ccb0e0aaaf4658538f3540e04e2f58973614a168f2f2f813d": {\n "delegator_public_key": "012a241eaa9fa3bd6ccb0e0aaaf4658538f3540e04e2f58973614a168f2f2f813d",\n "staked_amount": "51312014671568117976319379",\n "bonding_purse": "uref-c5ad00f9e6b2f2631ca647ad188187e63799a278a0a46ca25f6b4da64d556662-007",\n "validator_public_key": "0133eaae2821f090ac3ba0eadc0a897742094c0604df72b465c41d4b773298a7b9",\n "vesting_schedule": {\n "initial_release_timestamp_millis": 1664475057182,\n "locked_amounts": null\n }\n }\n },\n "inactive": false\n }\n }\n }\n ]\n }\n }\n}\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#eraid"},"era_id")," - A period of time during which the validator set does not change."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#executioneffect"},"execution_effect")," - The journal of execution transforms from a single Deploy."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#operation"},"operations")," - Operations performed while executing a Deploy."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/concepts/serialization-standard#transform"},"transform")," - The actual transformation performed while executing a Deploy."))),(0,i.kt)("h3",{id:"shutdown"},"Shutdown"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"Shutdown")," event is emitted when the node is about to shut down, usually for an upgrade, causing a termination of the event stream."),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Expand the below section to view the Shutdown event details:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'"Shutdown"\n')),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},'Shutdown - The "Shutdown" text notifies the event listener that a shutdown will occur.'))),(0,i.kt)("h2",{id:"reacting-to-events"},"Reacting to Events"),(0,i.kt)("p",null,"An application may parse each event needed for its use case and respond accordingly. The dApp may act on some events and not others, or it may act upon them all, depending on its use case. Each event type contains additional data that might help in deciding whether or not to take an action. For example, ",(0,i.kt)("inlineCode",{parentName:"p"},"DeployAccepted")," events contain the account's public key that submitted the deploy, the contract address, and more. This information can help determine how to proceed or whether or not to react."),(0,i.kt)(l.Z,{mdxType:"Tabs"},(0,i.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-javascript"},'const eventHandler = (event) => {\n if (event.body.DeployAccepted.header.account == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c") {\n // Perform an action\n }\n};\n'))),(0,i.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-python"},'def eventHandler(event):\n if event["DeployAccepted"]["header"]["account"] == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c":\n # Perform an action\n')))),(0,i.kt)("h2",{id:"unsubscribing-from-events"},"Unsubscribing from Events"),(0,i.kt)("p",null,"In many cases, an application may need to unsubscribe after a certain time or may want to unsubscribe from some events but not others. The Casper SDKs provide this ability with the ",(0,i.kt)("inlineCode",{parentName:"p"},"unsubscribe")," function:"),(0,i.kt)(l.Z,{mdxType:"Tabs"},(0,i.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-javascript"},"es.unsubscribe(EventName.EVENT_NAME);\n")))),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"EVENT_NAME")," - One of the different ",(0,i.kt)("a",{parentName:"li",href:"#event-types"},"event types")," emitted by a Casper node.")),(0,i.kt)("h2",{id:"stopping-the-event-stream"},"Stopping the Event Stream"),(0,i.kt)("p",null,"A dApp may cease listening to all events using the ",(0,i.kt)("inlineCode",{parentName:"p"},"stop")," function:"),(0,i.kt)(l.Z,{mdxType:"Tabs"},(0,i.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-javascript"},"es.stop();\n")))),(0,i.kt)("h2",{id:"replaying-the-event-stream"},"Replaying the Event Stream"),(0,i.kt)("p",null,"This command will replay the event stream from an old event onward. Replace the ",(0,i.kt)("inlineCode",{parentName:"p"},"NODE_ADDRESS"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"CHANNEL"),", and ",(0,i.kt)("inlineCode",{parentName:"p"},"ID")," fields with the values of your scenario."),(0,i.kt)(l.Z,{mdxType:"Tabs"},(0,i.kt)(o.Z,{value:"curl",label:"cURL",mdxType:"TabItem"},(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"curl -sN http://NODE_ADDRESS:9999/events/CHANNEL?start_from=ID\n")),(0,i.kt)("p",null,(0,i.kt)("em",{parentName:"p"},"Example:")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"curl -sN http://65.21.235.219:9999/events/main?start_from=29267508\n")))),(0,i.kt)("p",null,"Each URL can have a query string added to the form ",(0,i.kt)("inlineCode",{parentName:"p"},"?start_from=ID"),", where ID is an integer representing an old event ID. With this query, you can replay the event stream from that old event onward. If you specify an event ID already purged from the cache, the server will replay all the cached events."),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},"The server keeps only a limited number of events cached to allow replaying the stream to clients using the ",(0,i.kt)("inlineCode",{parentName:"p"},"?start_from=")," query string. The cache size can be set differently on each node using the ",(0,i.kt)("inlineCode",{parentName:"p"},"event_stream_buffer_length")," value in the ",(0,i.kt)("em",{parentName:"p"},"config.toml"),". By default, it is only 5000. The intended use case is to allow a client consuming the event stream that loses its connection to reconnect and catch up with events that were emitted while it was disconnected.")))}v.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a6f4e53a.8ba03a22.js b/assets/js/a6f4e53a.07d86411.js similarity index 99% rename from assets/js/a6f4e53a.8ba03a22.js rename to assets/js/a6f4e53a.07d86411.js index 73883c712f..ccd77d1837 100644 --- a/assets/js/a6f4e53a.8ba03a22.js +++ b/assets/js/a6f4e53a.07d86411.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[9989],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=d(n),u=i,m=c["".concat(s,".").concat(u)]||c[u]||h[u]||o;return n?a.createElement(m,r(r({ref:t},p),{},{components:n})):a.createElement(m,r({ref:t},p))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:i,r[1]=l;for(var d=2;d \\\n--secret-key \\\n--chain-name \\\n--payment-amount 2500000000 \\\n--session-hash \\\n--session-entry-point redelegate \\\n--session-arg \"delegator:public_key=''\" \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"new_validator:public_key=''\"\n")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,o.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,o.kt)("em",{parentName:"li"},"casper-test")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-hash")," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Testnet"),": ",(0,o.kt)("inlineCode",{parentName:"li"},"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Mainnet"),": ",(0,o.kt)("inlineCode",{parentName:"li"},"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"))),(0,o.kt)("ol",{start:6},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-entry-point")," - Name of the entrypoint that will be used when calling the contract")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"redelegate")," entry point expects four arguments:"),(0,o.kt)("ol",{start:7},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"delegator:public_key"),": The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"validator:public_key"),": The hexadecimal public key of the validator from whom the tokens will be undelegated"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"amount"),": The amount to be redelegated to the new validator"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"new_validator:public_key"),": The hexadecimal public key of the validator to whom the tokens will be delegated")),(0,o.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"redelegate")," entry point on the auction contract has a fixed cost of 2.5 CSPR and there is a minimum delegation amount of 500 CSPR that also applies to redelegations.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example:")),(0,o.kt)("p",null,"This example uses a private network running ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," version 1.5. The payment amount specified is 2.5 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec.toml"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address http://3.143.158.19:7777 \\\n--chain-name integration-test \\\n--secret-key ~/KEYS/integration/Test_secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-e22d38bcf3454a93face78a353feaccbf1d637d1ef9ef2e061a655728ff59bbe \\\n--session-entry-point redelegate \\\n--session-arg \"validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'\" \\\n--session-arg \"new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'\"\n")),(0,o.kt)("p",null,"Next, ",(0,o.kt)("a",{parentName:"p",href:"#verifying-the-redelegation"},"verify the redelegation"),"."),(0,o.kt)("h2",{id:"bonding-compiled-wasm"},"Method 2: Redelegating with Compiled Wasm"),(0,o.kt)("p",null,"Another way to send a redelegation is to compile the ",(0,o.kt)("inlineCode",{parentName:"p"},"redelegate.wasm")," and send it to the network via a deploy. To compile the Wasm yourself, ",(0,o.kt)("a",{parentName:"p",href:"/developers/cli/delegate#building-the-delegation-wasm"},"build the casper-node contracts")," that will include the redelegation Wasm."),(0,o.kt)("h3",{id:"sending-the-redelegation-deploy"},"Sending the redelegation request"),(0,o.kt)("p",null,"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."),(0,o.kt)("p",null,"This example uses the Casper client to send a deploy containing the ",(0,o.kt)("inlineCode",{parentName:"p"},"redelegate.wasm")," to the network to initiate the redelegation process."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-path /redelegate.wasm \\\n--session-arg \"delegator:public_key=''\" \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"new_validator:public_key=''\"\n")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,o.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,o.kt)("em",{parentName:"li"},"casper-test")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to the ",(0,o.kt)("inlineCode",{parentName:"li"},"redelegate.wasm")," on your computer")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"redelegate.wasm")," expects four arguments:"),(0,o.kt)("ol",{start:6},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"delegator:public_key"),": The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"validator:public_key"),": The hexadecimal public key of the validator from whom the tokens will be undelegated"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"amount"),": The amount to be redelegated to the new validator"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"new_validator:public_key"),": The hexadecimal public key of the validator to whom the tokens will be delegated")),(0,o.kt)("p",null,"Save the returned ",(0,o.kt)("em",{parentName:"p"},"deploy_hash")," from the output to ",(0,o.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#querying-deploys"},"query information")," about the redelegation Deploy."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Running the ",(0,o.kt)("inlineCode",{parentName:"p"},"redelegate.wasm")," is a more expensive operation than calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"redelegate")," entrypoint from the system auction contract.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example:")),(0,o.kt)("p",null,"This example uses a private network running ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," version 1.5. The payment amount specified is 8 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec.toml"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address http://3.143.158.19:7777 \\\n--chain-name integration-test \\\n--secret-key ~/KEYS/integration/Test_secret_key.pem \\\n--payment-amount 8000000000 \\\n--session-path ~/redelegate.wasm \\\n--session-arg \"validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'\" \\\n--session-arg \"new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'\"\n")),(0,o.kt)("h2",{id:"verifying-the-redelegation"},"Verifying the Redelegation"),(0,o.kt)("p",null,"The redelegation process includes an unbonding delay before the tokens are redelegated to a new validator. In contrast, initial delegation occurs when a Casper network finalizes the associated Deploy."),(0,o.kt)("p",null,"Due to this delay, the new validator may become inactive before the redelegation completes. If this happens, the tokens will be returned to the delegator."),(0,o.kt)("p",null,"Once the redelegation Deploy has been processed, you can query the auction to confirm the redelegation. This process is the same as ",(0,o.kt)("a",{parentName:"p",href:"/developers/cli/delegate#confirming-the-delegation"},"verifying a delegation request")," using the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-client get-auction-info")," command."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[9989],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=d(n),u=i,m=c["".concat(s,".").concat(u)]||c[u]||h[u]||o;return n?a.createElement(m,r(r({ref:t},p),{},{components:n})):a.createElement(m,r({ref:t},p))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:i,r[1]=l;for(var d=2;d \\\n--secret-key \\\n--chain-name \\\n--payment-amount 2500000000 \\\n--session-hash \\\n--session-entry-point redelegate \\\n--session-arg \"delegator:public_key=''\" \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"new_validator:public_key=''\"\n")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,o.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,o.kt)("em",{parentName:"li"},"casper-test")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-hash")," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Testnet"),": ",(0,o.kt)("inlineCode",{parentName:"li"},"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Mainnet"),": ",(0,o.kt)("inlineCode",{parentName:"li"},"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"))),(0,o.kt)("ol",{start:6},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-entry-point")," - Name of the entrypoint that will be used when calling the contract")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"redelegate")," entry point expects four arguments:"),(0,o.kt)("ol",{start:7},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"delegator:public_key"),": The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"validator:public_key"),": The hexadecimal public key of the validator from whom the tokens will be undelegated"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"amount"),": The amount to be redelegated to the new validator"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"new_validator:public_key"),": The hexadecimal public key of the validator to whom the tokens will be delegated")),(0,o.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"redelegate")," entry point on the auction contract has a fixed cost of 2.5 CSPR and there is a minimum delegation amount of 500 CSPR that also applies to redelegations.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example:")),(0,o.kt)("p",null,"This example uses a private network running ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," version 1.5. The payment amount specified is 2.5 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec.toml"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address http://3.143.158.19:7777 \\\n--chain-name integration-test \\\n--secret-key ~/KEYS/integration/Test_secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-e22d38bcf3454a93face78a353feaccbf1d637d1ef9ef2e061a655728ff59bbe \\\n--session-entry-point redelegate \\\n--session-arg \"validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'\" \\\n--session-arg \"new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'\"\n")),(0,o.kt)("p",null,"Next, ",(0,o.kt)("a",{parentName:"p",href:"#verifying-the-redelegation"},"verify the redelegation"),"."),(0,o.kt)("h2",{id:"bonding-compiled-wasm"},"Method 2: Redelegating with Compiled Wasm"),(0,o.kt)("p",null,"Another way to send a redelegation is to compile the ",(0,o.kt)("inlineCode",{parentName:"p"},"redelegate.wasm")," and send it to the network via a deploy. To compile the Wasm yourself, ",(0,o.kt)("a",{parentName:"p",href:"/developers/cli/delegate#building-the-delegation-wasm"},"build the casper-node contracts")," that will include the redelegation Wasm."),(0,o.kt)("h3",{id:"sending-the-redelegation-deploy"},"Sending the redelegation request"),(0,o.kt)("p",null,"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."),(0,o.kt)("p",null,"This example uses the Casper client to send a deploy containing the ",(0,o.kt)("inlineCode",{parentName:"p"},"redelegate.wasm")," to the network to initiate the redelegation process."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-path /redelegate.wasm \\\n--session-arg \"delegator:public_key=''\" \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"new_validator:public_key=''\"\n")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,o.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,o.kt)("em",{parentName:"li"},"casper-test")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to the ",(0,o.kt)("inlineCode",{parentName:"li"},"redelegate.wasm")," on your computer")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"redelegate.wasm")," expects four arguments:"),(0,o.kt)("ol",{start:6},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"delegator:public_key"),": The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"validator:public_key"),": The hexadecimal public key of the validator from whom the tokens will be undelegated"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"amount"),": The amount to be redelegated to the new validator"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"new_validator:public_key"),": The hexadecimal public key of the validator to whom the tokens will be delegated")),(0,o.kt)("p",null,"Save the returned ",(0,o.kt)("em",{parentName:"p"},"deploy_hash")," from the output to ",(0,o.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#querying-deploys"},"query information")," about the redelegation Deploy."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Running the ",(0,o.kt)("inlineCode",{parentName:"p"},"redelegate.wasm")," is a more expensive operation than calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"redelegate")," entrypoint from the system auction contract.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example:")),(0,o.kt)("p",null,"This example uses a private network running ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-node")," version 1.5. The payment amount specified is 8 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec.toml"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address http://3.143.158.19:7777 \\\n--chain-name integration-test \\\n--secret-key ~/KEYS/integration/Test_secret_key.pem \\\n--payment-amount 8000000000 \\\n--session-path ~/redelegate.wasm \\\n--session-arg \"validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'\" \\\n--session-arg \"new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'\"\n")),(0,o.kt)("h2",{id:"verifying-the-redelegation"},"Verifying the Redelegation"),(0,o.kt)("p",null,"The redelegation process includes an unbonding delay before the tokens are redelegated to a new validator. In contrast, initial delegation occurs when a Casper network finalizes the associated Deploy."),(0,o.kt)("p",null,"Due to this delay, the new validator may become inactive before the redelegation completes. If this happens, the tokens will be returned to the delegator."),(0,o.kt)("p",null,"Once the redelegation Deploy has been processed, you can query the auction to confirm the redelegation. This process is the same as ",(0,o.kt)("a",{parentName:"p",href:"/developers/cli/delegate#confirming-the-delegation"},"verifying a delegation request")," using the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-client get-auction-info")," command."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a71eff7a.5141f7ca.js b/assets/js/a71eff7a.d7b268f4.js similarity index 99% rename from assets/js/a71eff7a.5141f7ca.js rename to assets/js/a71eff7a.d7b268f4.js index 56dfe63f9c..7142cf484f 100644 --- a/assets/js/a71eff7a.5141f7ca.js +++ b/assets/js/a71eff7a.d7b268f4.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6988],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var a=n(7294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var i=a.createContext({}),c=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(i.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,s=e.mdxType,r=e.originalType,i=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(n),h=s,m=u["".concat(i,".").concat(h)]||u[h]||d[h]||r;return n?a.createElement(m,o(o({ref:t},p),{},{components:n})):a.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var r=n.length,o=new Array(r);o[0]=h;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[u]="string"==typeof e?e:s,o[1]=l;for(var c=2;c=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var i=a.createContext({}),c=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(i.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,s=e.mdxType,r=e.originalType,i=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(n),h=s,m=u["".concat(i,".").concat(h)]||u[h]||d[h]||r;return n?a.createElement(m,o(o({ref:t},p),{},{components:n})):a.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var r=n.length,o=new Array(r);o[0]=h;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[u]="string"==typeof e?e:s,o[1]=l;for(var c=2;c=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),u=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=u(r),m=o,f=p["".concat(l,".").concat(m)]||p[m]||d[m]||a;return r?n.createElement(f,i(i({ref:t},c),{},{components:r})):n.createElement(f,i({ref:t},c))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:o,i[1]=s;for(var u=2;u=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),u=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=u(r),m=o,f=p["".concat(l,".").concat(m)]||p[m]||d[m]||a;return r?n.createElement(f,i(i({ref:t},c),{},{components:r})):n.createElement(f,i({ref:t},c))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:o,i[1]=s;for(var u=2;u=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var u=n.createContext({}),s=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=s(e.components);return n.createElement(u.Provider,{value:t},e.children)},p="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},g=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,u=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=s(r),g=a,f=p["".concat(u,".").concat(g)]||p[g]||c[g]||i;return r?n.createElement(f,o(o({ref:t},d),{},{components:r})):n.createElement(f,o({ref:t},d))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=g;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l[p]="string"==typeof e?e:a,o[1]=l;for(var s=2;s=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var u=n.createContext({}),s=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=s(e.components);return n.createElement(u.Provider,{value:t},e.children)},p="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},g=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,u=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=s(r),g=a,f=p["".concat(u,".").concat(g)]||p[g]||c[g]||i;return r?n.createElement(f,o(o({ref:t},d),{},{components:r})):n.createElement(f,o({ref:t},d))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=g;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l[p]="string"==typeof e?e:a,o[1]=l;for(var s=2;s=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=o.createContext({}),d=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=d(e.components);return o.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,s=e.originalType,c=e.parentName,l=r(e,["components","mdxType","originalType","parentName"]),p=d(n),h=i,m=p["".concat(c,".").concat(h)]||p[h]||u[h]||s;return n?o.createElement(m,a(a({ref:t},l),{},{components:n})):o.createElement(m,a({ref:t},l))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var s=n.length,a=new Array(s);a[0]=h;var r={};for(var c in t)hasOwnProperty.call(t,c)&&(r[c]=t[c]);r.originalType=e,r[p]="string"==typeof e?e:i,a[1]=r;for(var d=2;d=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=o.createContext({}),d=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=d(e.components);return o.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,s=e.originalType,c=e.parentName,l=r(e,["components","mdxType","originalType","parentName"]),p=d(n),h=i,m=p["".concat(c,".").concat(h)]||p[h]||u[h]||s;return n?o.createElement(m,a(a({ref:t},l),{},{components:n})):o.createElement(m,a({ref:t},l))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var s=n.length,a=new Array(s);a[0]=h;var r={};for(var c in t)hasOwnProperty.call(t,c)&&(r[c]=t[c]);r.originalType=e,r[p]="string"==typeof e?e:i,a[1]=r;for(var d=2;d=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var s=a.createContext({}),c=function(t){var e=a.useContext(s),n=e;return t&&(n="function"==typeof t?t(e):o(o({},e),t)),n},d=function(t){var e=c(t.components);return a.createElement(s.Provider,{value:e},t.children)},p="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},m=a.forwardRef((function(t,e){var n=t.components,r=t.mdxType,i=t.originalType,s=t.parentName,d=l(t,["components","mdxType","originalType","parentName"]),p=c(n),m=r,g=p["".concat(s,".").concat(m)]||p[m]||u[m]||i;return n?a.createElement(g,o(o({ref:e},d),{},{components:n})):a.createElement(g,o({ref:e},d))}));function g(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var i=n.length,o=new Array(i);o[0]=m;var l={};for(var s in e)hasOwnProperty.call(e,s)&&(l[s]=e[s]);l.originalType=t,l[p]="string"==typeof t?t:r,o[1]=l;for(var c=2;c=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var s=a.createContext({}),c=function(t){var e=a.useContext(s),n=e;return t&&(n="function"==typeof t?t(e):o(o({},e),t)),n},d=function(t){var e=c(t.components);return a.createElement(s.Provider,{value:e},t.children)},p="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},m=a.forwardRef((function(t,e){var n=t.components,r=t.mdxType,i=t.originalType,s=t.parentName,d=l(t,["components","mdxType","originalType","parentName"]),p=c(n),m=r,g=p["".concat(s,".").concat(m)]||p[m]||u[m]||i;return n?a.createElement(g,o(o({ref:e},d),{},{components:n})):a.createElement(g,o({ref:e},d))}));function g(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var i=n.length,o=new Array(i);o[0]=m;var l={};for(var s in e)hasOwnProperty.call(e,s)&&(l[s]=e[s]);l.originalType=t,l[p]="string"==typeof t?t:r,o[1]=l;for(var c=2;c=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),f=l(r),y=a,m=f["".concat(p,".").concat(y)]||f[y]||u[y]||o;return r?n.createElement(m,s(s({ref:t},i),{},{components:r})):n.createElement(m,s({ref:t},i))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[f]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),f=l(r),y=a,m=f["".concat(p,".").concat(y)]||f[y]||u[y]||o;return r?n.createElement(m,s(s({ref:t},i),{},{components:r})):n.createElement(m,s({ref:t},i))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[f]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=p(n),m=r,h=u["".concat(s,".").concat(m)]||u[m]||d[m]||o;return n?a.createElement(h,i(i({ref:t},c),{},{components:n})):a.createElement(h,i({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[u]="string"==typeof e?e:r,i[1]=l;for(var p=2;p 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.')})))?void 0:n.filter(Boolean))?t:[]}(e).map((function(e){var t=e.props;return{value:t.value,label:t.label,attributes:t.attributes,default:t.default}}))}function d(e){var t=e.values,n=e.children;return(0,r.useMemo)((function(){var e=null!=t?t:u(n);return function(e){var t=(0,p.l)(e,(function(e,t){return e.value===t.value}));if(t.length>0)throw new Error('Docusaurus error: Duplicate values "'+t.map((function(e){return e.value})).join(", ")+'" found in . Every value needs to be unique.')}(e),e}),[t,n])}function m(e){var t=e.value;return e.tabValues.some((function(e){return e.value===t}))}function h(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId,o=(0,l.k6)(),i=function(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId;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 null!=a?a:null}({queryString:n,groupId:a});return[(0,s._X)(i),(0,r.useCallback)((function(e){if(i){var t=new URLSearchParams(o.location.search);t.set(i,e),o.replace(Object.assign({},o.location,{search:t.toString()}))}}),[i,o])]}function f(e){var t,n,a,o,i=e.defaultValue,l=e.queryString,s=void 0!==l&&l,p=e.groupId,u=d(e),f=(0,r.useState)((function(){return function(e){var t,n=e.defaultValue,a=e.tabValues;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({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((function(e){return e.value})).join(", ")+". If you intend to show no default tab, use defaultValue={null} instead.");return n}var r=null!=(t=a.find((function(e){return e.default})))?t:a[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:i,tabValues:u})})),g=f[0],b=f[1],y=h({queryString:s,groupId:p}),k=y[0],v=y[1],w=(t=function(e){return e?"docusaurus.tab."+e:null}({groupId:p}.groupId),n=(0,c.Nk)(t),a=n[0],o=n[1],[a,(0,r.useCallback)((function(e){t&&o.set(e)}),[t,o])]),C=w[0],N=w[1],T=function(){var e=null!=k?k:C;return m({value:e,tabValues:u})?e:null}();return(0,r.useLayoutEffect)((function(){T&&b(T)}),[T]),{selectedValue:g,selectValue:(0,r.useCallback)((function(e){if(!m({value:e,tabValues:u}))throw new Error("Can't select invalid tab value="+e);b(e),v(e),N(e)}),[v,N,u]),tabValues:u}}var g=n(2389),b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){var t=e.className,n=e.block,l=e.selectedValue,s=e.selectValue,p=e.tabValues,c=[],u=(0,i.o5)().blockElementScrollPositionUntilNextRender,d=function(e){var t=e.currentTarget,n=c.indexOf(t),a=p[n].value;a!==l&&(u(t),s(a))},m=function(e){var t,n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":var a,r=c.indexOf(e.currentTarget)+1;n=null!=(a=c[r])?a:c[0];break;case"ArrowLeft":var o,i=c.indexOf(e.currentTarget)-1;n=null!=(o=c[i])?o:c[c.length-1]}null==(t=n)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},p.map((function(e){var t=e.value,n=e.label,i=e.attributes;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:function(e){return c.push(e)},onKeyDown:m,onClick:d},i,{className:(0,o.Z)("tabs__item",b.tabItem,null==i?void 0:i.className,{"tabs__item--active":l===t})}),null!=n?n:t)})))}function k(e){var t=e.lazy,n=e.children,a=e.selectedValue,o=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){var i=o.find((function(e){return e.props.value===a}));return i?(0,r.cloneElement)(i,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map((function(e,t){return(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a})})))}function v(e){var t=f(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",b.tabList)},r.createElement(y,(0,a.Z)({},e,t)),r.createElement(k,(0,a.Z)({},e,t)))}function w(e){var t=(0,g.Z)();return r.createElement(v,(0,a.Z)({key:String(t)},e))}},4095:function(e,t,n){n.r(t),n.d(t,{assets:function(){return c},contentTitle:function(){return s},default:function(){return h},frontMatter:function(){return l},metadata:function(){return p},toc:function(){return u}});var a=n(7462),r=n(3366),o=(n(7294),n(3905)),i=(n(4866),n(5162),["components"]),l={title:"Front-end in React"},s="Front-end Template with React",p={unversionedId:"developers/dapps/template-frontend",id:"developers/dapps/template-frontend",title:"Front-end in React",description:"For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the Casper JS SDK.",source:"@site/source/docs/casper/developers/dapps/template-frontend.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/template-frontend",permalink:"/developers/dapps/template-frontend",draft:!1,editUrl:"https://github.com/casper-network/docs/tree/dev/source/docs/casper/developers/dapps/template-frontend.md",tags:[],version:"current",lastUpdatedAt:1707837031,formattedLastUpdatedAt:"Feb 13, 2024",frontMatter:{title:"Front-end in React"},sidebar:"developers",previous:{title:"dApp Technology Stack",permalink:"/developers/dapps/technology-stack"},next:{title:"URef Access Rights",permalink:"/developers/dapps/uref-security"}},c={},u=[{value:"Get Started",id:"get-started",level:2},{value:"Casper Wallet Integration",id:"casper-wallet-integration",level:2},{value:"Disconnect the Casper Wallet",id:"disconnect-the-casper-wallet",level:3},{value:"Call a Smart Contract",id:"call-a-smart-contract",level:2},{value:"Query a Smart Contract",id:"query-a-smart-contract",level:2},{value:"Test Application",id:"test-application",level:2},{value:"Build for Production",id:"build-for-production",level:2}],d={toc:u},m="wrapper";function h(e){var t=e.components,n=(0,r.Z)(e,i);return(0,o.kt)(m,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"front-end-template-with-react"},"Front-end Template with React"),(0,o.kt)("p",null,"For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/casper-js-sdk"},"Casper JS SDK"),"."),(0,o.kt)("p",null,"This guide will walk you through setting up and developing a React application with ",(0,o.kt)("a",{parentName:"p",href:"https://vitejs.dev/"},"Vite")," that communicates with a Casper network. Experience with Vite is not required; however, if you have never built a React app, you should begin by ",(0,o.kt)("a",{parentName:"p",href:"https://reactjs.org/docs/getting-started.html"},"reading the React documentation"),"."),(0,o.kt)("h2",{id:"get-started"},"Get Started"),(0,o.kt)("p",null,"Begin by opening a terminal and running:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"node -v\n")),(0,o.kt)("p",null,"To get your Node.js version."),(0,o.kt)("p",null,"To ensure compatibility, you should be running Node.js version 18 or above. Upgrade to version 18 using the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/nvm-sh/nvm"},"Node Version Manager")," or another tool if you are running an earlier version."),(0,o.kt)("p",null,"Using ",(0,o.kt)("a",{parentName:"p",href:"https://www.npmjs.com/"},"npm"),", create a new Vite project by running:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"npm install -g vite\nnpm create vite@latest\n")),(0,o.kt)("p",null,'Name your project, select "React", then choose your preferred language. In this example, we will use JavaScript.'),(0,o.kt)("p",null,"Head into your new project directory, replacing ",(0,o.kt)("inlineCode",{parentName:"p"},"vite-project")," with your project name:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cd vite-project/\n")),(0,o.kt)("p",null,"Run the following command to test the server:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"npm install\nvite dev\n")),(0,o.kt)("p",null,"Quit the server by pressing ",(0,o.kt)("inlineCode",{parentName:"p"},"q"),". Install the Casper JS SDK by running the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"npm install casper-js-sdk\n")),(0,o.kt)("p",null,"This guide will use ",(0,o.kt)("a",{parentName:"p",href:"https://axios-http.com/"},"axios")," to communicate with the backend; install it by running:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"npm install axios\n")),(0,o.kt)("h2",{id:"casper-wallet-integration"},"Casper Wallet Integration"),(0,o.kt)("p",null,"The Casper Wallet extension content script injects the SDK into your website's global scope. Provider class and event types can be accessed with ",(0,o.kt)("inlineCode",{parentName:"p"},"window.CasperWalletProvider")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"window.CasperWalletEventTypes"),". If the value of these variables is ",(0,o.kt)("inlineCode",{parentName:"p"},"undefined")," the Casper Wallet is not installed."),(0,o.kt)("p",null,"Start with a helper for getting the provider instance:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"touch src/casper-wallet.js\n")),(0,o.kt)("p",null,"Fill the file with the following content:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'// Timeout (in ms) for requests to the extension [DEFAULT: 30 min]\nconst REQUESTS_TIMEOUT_MS = 30 * 60 * 1000;\n\nexport const getProvider = () => {\n let providerConstructor = window.CasperWalletProvider;\n if (providerConstructor === undefined) {\n alert("Casper Wallet extension is not installed!");\n return;\n }\n let provider = providerConstructor({\n timeout: REQUESTS_TIMEOUT_MS,\n });\n return provider;\n};\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"For complete integration details, refer to ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/make-software/casper-wallet-sdk/#readme"},"README of Casper Wallet SDK"),".")),(0,o.kt)("p",null,"To ensure that a user's public key will be available to all necessary components, create a React state variable in ",(0,o.kt)("em",{parentName:"p"},"src/App.jsx")," or another parent component that encapsulates the components that should have access to this public key:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-jsx"},'import React from "react";\nimport Connect from "./Connect";\nimport "./App.css";\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n \n
\n {publicKey !== null && (\n <>\n Wallet connected: {publicKey}\n
\n \n )}\n
\n \n );\n}\n\nexport default App;\n')),(0,o.kt)("p",null,"This is an example of ",(0,o.kt)("em",{parentName:"p"},"src/App.jsx")," that imports and displays the ",(0,o.kt)("inlineCode",{parentName:"p"},"Connect")," component that is described next. The ",(0,o.kt)("inlineCode",{parentName:"p"},"setPublicKey")," function is passed to the ",(0,o.kt)("inlineCode",{parentName:"p"},"Connect")," component as a ",(0,o.kt)("a",{parentName:"p",href:"https://legacy.reactjs.org/docs/components-and-props.html"},"prop")," so that it may set the public key and make it available to all of ",(0,o.kt)("em",{parentName:"p"},"src/App.jsx"),". This way, when more components are added to ",(0,o.kt)("em",{parentName:"p"},"src/App.jsx"),", they may utilize the ",(0,o.kt)("inlineCode",{parentName:"p"},"publicKey")," variable."),(0,o.kt)("p",null,"To connect to the Casper Wallet within your React app, create the ",(0,o.kt)("inlineCode",{parentName:"p"},"Connect")," component and import the ",(0,o.kt)("inlineCode",{parentName:"p"},"getProvider")," helper."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"touch src/Connect.jsx\n")),(0,o.kt)("p",null,"Open the file and write:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-jsx"},'import { getProvider } from "./casper-wallet";\n\nconst provider = getProvider();\n\nconst Connect = (props) => {\n return (\n <>\n \n {/* Place for disconnect button */}\n \n );\n};\n\nexport default Connect;\n')),(0,o.kt)("p",null,"Notice that ",(0,o.kt)("inlineCode",{parentName:"p"},"Connect")," accepts props, and forwards them to the ",(0,o.kt)("inlineCode",{parentName:"p"},"connectToWallet")," function described below. This function is called when the button is clicked, allowing it to set the public key within ",(0,o.kt)("em",{parentName:"p"},"src/App.jsx")," using ",(0,o.kt)("inlineCode",{parentName:"p"},"props.setPublicKey()"),"."),(0,o.kt)("p",null,"Write the ",(0,o.kt)("inlineCode",{parentName:"p"},"connectToWallet")," function under the ",(0,o.kt)("inlineCode",{parentName:"p"},"Connect")," function component:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-javascript"},'const connectToWallet = (props) => {\n provider\n .requestConnection()\n .then((connected) => {\n if (!connected) {\n alert("Couldn\'t connect to wallet");\n } else {\n provider\n .getActivePublicKey()\n .then((publicKey) => {\n props.setPublicKey(publicKey);\n })\n .catch((error) => {\n alert(error.message);\n });\n }\n })\n .catch((error) => {\n alert(error.message);\n });\n};\n')),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"connectToWallet()")," function calls ",(0,o.kt)("inlineCode",{parentName:"p"},"provider.isConnected()")," to check if the Casper Wallet is already connected. If it is, it gets the public key of the selected account; if it's not, it opens up a connection request within the Wallet. ",(0,o.kt)("inlineCode",{parentName:"p"},"provider.isConnected()")," will throw an error if the Wallet is not installed as an extension or if it is locked."),(0,o.kt)("h3",{id:"disconnect-the-casper-wallet"},"Disconnect the Casper Wallet"),(0,o.kt)("p",null,"To request that the Casper Wallet disconnect from a website, add the following function call to ",(0,o.kt)("em",{parentName:"p"},"src/Connect.jsx"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-javascript"},'const disconnect = (props) => {\n provider\n .disconnectFromSite()\n .then((disconnected) => {\n if (disconnected) {\n props.setPublicKey(null);\n alert("Disconnected");\n }\n })\n .catch((error) => {\n alert(error.message);\n });\n};\n')),(0,o.kt)("p",null,"Then connect it to a button:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-jsx"},"const Connect = (props) => {\n return (\n <>\n \n // highlight-next-line-green\n \n \n );\n};\n")),(0,o.kt)("h2",{id:"call-a-smart-contract"},"Call a Smart Contract"),(0,o.kt)("p",null,'For this example, we\'ll call a hypothetical "hello world" contract containing a single entrypoint "update_message". We\'ll call the "update_message" entrypoint with text entered by the user in an HTML ',(0,o.kt)("inlineCode",{parentName:"p"},"input")," field."),(0,o.kt)("p",null,"When calling smart contracts from React, you'll need to implement the logic within a function accessible from a React component. You can obtain user-entered data from the DOM using elements like ",(0,o.kt)("inlineCode",{parentName:"p"},"input"),", then grab the value within the smart-contract-calling function."),(0,o.kt)("p",null,"Create a new component:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"touch src/UpdateMessage.jsx\n")),(0,o.kt)("p",null,"Open the file and write:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-jsx"},'import { useState } from "react";\nimport { Contracts, CasperClient, RuntimeArgs, CLValueBuilder, CLPublicKey, DeployUtil } from "casper-js-sdk";\nimport axios from "axios";\nimport { getProvider } from "./casper-wallet";\n\nconst provider = getProvider();\n\nconst UpdateMessage = (props) => {\n const [message, setMessage] = useState("");\n\n return (\n <>\n {\n setMessage(e.target.value);\n }}\n />\n \n \n );\n};\n\nexport default UpdateMessage;\n')),(0,o.kt)("p",null,"On the front-end you'll need to build the deploy and forward it to the Casper Wallet to be signed. In most cases, you will be calling smart contract entrypoints. This example deploy shows the calling of entrypoint \"update_message\" which will update the chain's global state to reflect the new data. You'll need the user's active public key to prepare the deploy, and you may retrieve this from the ",(0,o.kt)("inlineCode",{parentName:"p"},"publicKey")," variable passed in as a prop from ",(0,o.kt)("inlineCode",{parentName:"p"},"src/App.jsx"),". Write this function under your ",(0,o.kt)("inlineCode",{parentName:"p"},"UpdateMessage")," component function."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-javascript"},'const NODE_URL = "http://65.108.127.242:7777/rpc";\nconst NETWORK_NAME = "casper-test"; // "casper" for mainnet\nconst CONTRACT_HASH = "hash-75143aa708275b7dead20ac2cc06c1c3eccff4ffcf1eb9aebb8cce7c35cea041";\n\nconst updateMessage = (props, message) => {\n const casperClient = new CasperClient(NODE_URL);\n const contract = new Contracts.Contract(casperClient);\n contract.setContractHash(CONTRACT_HASH);\n const runtimeArguments = RuntimeArgs.fromMap({\n message: CLValueBuilder.string(message),\n });\n const deploy = contract.callEntrypoint(\n "update_message",\n runtimeArguments,\n CLPublicKey.fromHex(props.publicKey),\n NETWORK_NAME,\n "1000000000", // 1 CSPR (10^9 Motes)\n );\n const deployJSON = DeployUtil.deployToJson(deploy);\n provider\n .sign(JSON.stringify(deployJSON), props.publicKey)\n .then((signedDeploy) => {\n // Initiates sign request\n axios\n .post("/sendDeploy", signedDeploy, {\n headers: {\n "Content-Type": "application/json",\n },\n })\n .then((response) => {\n alert(response.data);\n })\n .catch((error) => {\n console.error(error.message);\n });\n })\n .catch((error) => {\n console.error(error.message);\n });\n};\n')),(0,o.kt)("p",null,"In this example, ",(0,o.kt)("inlineCode",{parentName:"p"},"updateMessage")," builds a deploy and forwards it to the Casper Wallet to be signed by the user. Once it's been signed, ",(0,o.kt)("inlineCode",{parentName:"p"},"signedDeploy")," is forwarded to the backend at the ",(0,o.kt)("inlineCode",{parentName:"p"},"/sendDeploy")," endpoint using ",(0,o.kt)("inlineCode",{parentName:"p"},"axios.post")," before being sent off to a Casper node. If an error occurs, or the user rejects the signature request, it will be logged to ",(0,o.kt)("inlineCode",{parentName:"p"},"stderr"),". In this particular example, the result of this deployment will be presented to the user in the form of a JavaScript ",(0,o.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/API/Window/alert"},"alert"),"; however, you may do with the response data as you wish."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"The backend endpoint ",(0,o.kt)("inlineCode",{parentName:"p"},"/sendDeploy")," should handle signed deployment by simply passing it to a Casper node."),(0,o.kt)("p",{parentName:"admonition"},"In Casper node ",(0,o.kt)("inlineCode",{parentName:"p"},"v1.5.0"),", which sets up appropriate CORS headers, it will also be possible to send deployments directly from the browser, without relying on a backend server. This is useful for prototyping, however it is advised that you operate your own node.")),(0,o.kt)("p",null,"Now that this component is created, render it to the user interface in ",(0,o.kt)("em",{parentName:"p"},"src/App.jsx"),", passing along the ",(0,o.kt)("inlineCode",{parentName:"p"},"publicKey")," as a prop:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-jsx"},'import React from "react";\nimport Connect from "./Connect";\n// highlight-next-line-green\nimport UpdateMessage from "./UpdateMessage";\nimport "./App.css";\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n \n
\n {publicKey !== null && (\n <>\n Wallet connected: {publicKey}\n
\n // highlight-next-line-green\n \n \n )}\n
\n \n );\n}\n')),(0,o.kt)("h2",{id:"query-a-smart-contract"},"Query a Smart Contract"),(0,o.kt)("p",null,"Consider that the message written to the chain during the ",(0,o.kt)("inlineCode",{parentName:"p"},"update_message")," entrypoint invocation is stored in the ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/D#dictionary"},"dictionary")," ",(0,o.kt)("inlineCode",{parentName:"p"},"messages")," in the contract. Further consider that each account may write its own message and that the messages are stored under the account's ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/A#account-hash"},"account hash")," as the dictionary key. Querying this kind of data is essential in any dApp; here is how to communicate contract data to and from the front-end."),(0,o.kt)("p",null,"Create a new component:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"touch src/Query.jsx\n")),(0,o.kt)("p",null,"Open the file and write:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-jsx"},'import axios from "axios";\nimport { CLPublicKey } from "casper-js-sdk";\n\nconst Query = (props) => {\n return ;\n};\n\nconst query = (props) => {\n const accountHash = CLPublicKey.fromHex(props.publicKey).toAccountHashStr().substring(13);\n axios\n .get("/queryMessage?accountHash=" + accountHash)\n .then((response) => {\n alert(response.data);\n })\n .catch((error) => {\n console.error(error.message);\n });\n};\n\nexport default Query;\n')),(0,o.kt)("p",null,"All this component does is render an HTML ",(0,o.kt)("inlineCode",{parentName:"p"},"button")," element that, when pressed, performs a ",(0,o.kt)("inlineCode",{parentName:"p"},"GET")," request to the backend that includes the user's active account hash. The account hash is derived from the active public key, and is used to look up the message stored by the current user."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The ",(0,o.kt)("inlineCode",{parentName:"p"},"toAccountHashStr"),' method produces a string that is prepended by the text "account-hash-". In this case, this text is not needed, so it is discarded by chaining on the ',(0,o.kt)("inlineCode",{parentName:"p"},"substring(13)")," method.")),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"This functionality relies on the ",(0,o.kt)("inlineCode",{parentName:"p"},"/queryMessage")," endpoint, which should be implemented in your backend.")),(0,o.kt)("p",null,"Now add this component to ",(0,o.kt)("em",{parentName:"p"},"src/App.jsx"),", making available the ",(0,o.kt)("inlineCode",{parentName:"p"},"publicKey")," state variable via a prop:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-jsx"},'import React from "react";\nimport Connect from "./Connect";\nimport UpdateMessage from "./UpdateMessage";\n// highlight-next-line-green\nimport Query from "./Query";\nimport "./App.css";\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n \n
\n {publicKey !== null && (\n <>\n Wallet connected: {publicKey}\n
\n \n // highlight-next-line-green\n \n \n )}\n
\n \n );\n}\n')),(0,o.kt)("h2",{id:"test-application"},"Test Application"),(0,o.kt)("p",null,"Test your application by running the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"vite dev\n")),(0,o.kt)("p",null,"Your application will start locally, and a URL will be shown where you can visit your application. Alternatively, press ",(0,o.kt)("inlineCode",{parentName:"p"},"h"),", then ",(0,o.kt)("inlineCode",{parentName:"p"},"o")," to open the app in a browser."),(0,o.kt)("h2",{id:"build-for-production"},"Build for Production"),(0,o.kt)("p",null,"When you're ready to release your application, you'll want to compile it to pure JavaScript and serve it from a web server. Do so by running:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"vite build\n")),(0,o.kt)("p",null,"Once this is complete, you can preview your production build by running:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"vite preview\n")))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5779],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return h}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=p(n),m=r,h=u["".concat(s,".").concat(m)]||u[m]||d[m]||o;return n?a.createElement(h,i(i({ref:t},c),{},{components:n})):a.createElement(h,i({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[u]="string"==typeof e?e:r,i[1]=l;for(var p=2;p 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.')})))?void 0:n.filter(Boolean))?t:[]}(e).map((function(e){var t=e.props;return{value:t.value,label:t.label,attributes:t.attributes,default:t.default}}))}function d(e){var t=e.values,n=e.children;return(0,r.useMemo)((function(){var e=null!=t?t:u(n);return function(e){var t=(0,p.l)(e,(function(e,t){return e.value===t.value}));if(t.length>0)throw new Error('Docusaurus error: Duplicate values "'+t.map((function(e){return e.value})).join(", ")+'" found in . Every value needs to be unique.')}(e),e}),[t,n])}function m(e){var t=e.value;return e.tabValues.some((function(e){return e.value===t}))}function h(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId,o=(0,l.k6)(),i=function(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId;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 null!=a?a:null}({queryString:n,groupId:a});return[(0,s._X)(i),(0,r.useCallback)((function(e){if(i){var t=new URLSearchParams(o.location.search);t.set(i,e),o.replace(Object.assign({},o.location,{search:t.toString()}))}}),[i,o])]}function f(e){var t,n,a,o,i=e.defaultValue,l=e.queryString,s=void 0!==l&&l,p=e.groupId,u=d(e),f=(0,r.useState)((function(){return function(e){var t,n=e.defaultValue,a=e.tabValues;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({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((function(e){return e.value})).join(", ")+". If you intend to show no default tab, use defaultValue={null} instead.");return n}var r=null!=(t=a.find((function(e){return e.default})))?t:a[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:i,tabValues:u})})),g=f[0],b=f[1],y=h({queryString:s,groupId:p}),k=y[0],v=y[1],w=(t=function(e){return e?"docusaurus.tab."+e:null}({groupId:p}.groupId),n=(0,c.Nk)(t),a=n[0],o=n[1],[a,(0,r.useCallback)((function(e){t&&o.set(e)}),[t,o])]),C=w[0],N=w[1],T=function(){var e=null!=k?k:C;return m({value:e,tabValues:u})?e:null}();return(0,r.useLayoutEffect)((function(){T&&b(T)}),[T]),{selectedValue:g,selectValue:(0,r.useCallback)((function(e){if(!m({value:e,tabValues:u}))throw new Error("Can't select invalid tab value="+e);b(e),v(e),N(e)}),[v,N,u]),tabValues:u}}var g=n(2389),b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){var t=e.className,n=e.block,l=e.selectedValue,s=e.selectValue,p=e.tabValues,c=[],u=(0,i.o5)().blockElementScrollPositionUntilNextRender,d=function(e){var t=e.currentTarget,n=c.indexOf(t),a=p[n].value;a!==l&&(u(t),s(a))},m=function(e){var t,n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":var a,r=c.indexOf(e.currentTarget)+1;n=null!=(a=c[r])?a:c[0];break;case"ArrowLeft":var o,i=c.indexOf(e.currentTarget)-1;n=null!=(o=c[i])?o:c[c.length-1]}null==(t=n)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},p.map((function(e){var t=e.value,n=e.label,i=e.attributes;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:function(e){return c.push(e)},onKeyDown:m,onClick:d},i,{className:(0,o.Z)("tabs__item",b.tabItem,null==i?void 0:i.className,{"tabs__item--active":l===t})}),null!=n?n:t)})))}function k(e){var t=e.lazy,n=e.children,a=e.selectedValue,o=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){var i=o.find((function(e){return e.props.value===a}));return i?(0,r.cloneElement)(i,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map((function(e,t){return(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a})})))}function v(e){var t=f(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",b.tabList)},r.createElement(y,(0,a.Z)({},e,t)),r.createElement(k,(0,a.Z)({},e,t)))}function w(e){var t=(0,g.Z)();return r.createElement(v,(0,a.Z)({key:String(t)},e))}},4095:function(e,t,n){n.r(t),n.d(t,{assets:function(){return c},contentTitle:function(){return s},default:function(){return h},frontMatter:function(){return l},metadata:function(){return p},toc:function(){return u}});var a=n(7462),r=n(3366),o=(n(7294),n(3905)),i=(n(4866),n(5162),["components"]),l={title:"Front-end in React"},s="Front-end Template with React",p={unversionedId:"developers/dapps/template-frontend",id:"developers/dapps/template-frontend",title:"Front-end in React",description:"For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the Casper JS SDK.",source:"@site/source/docs/casper/developers/dapps/template-frontend.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/template-frontend",permalink:"/developers/dapps/template-frontend",draft:!1,editUrl:"https://github.com/casper-network/docs/tree/dev/source/docs/casper/developers/dapps/template-frontend.md",tags:[],version:"current",lastUpdatedAt:1708091908,formattedLastUpdatedAt:"Feb 16, 2024",frontMatter:{title:"Front-end in React"},sidebar:"developers",previous:{title:"dApp Technology Stack",permalink:"/developers/dapps/technology-stack"},next:{title:"URef Access Rights",permalink:"/developers/dapps/uref-security"}},c={},u=[{value:"Get Started",id:"get-started",level:2},{value:"Casper Wallet Integration",id:"casper-wallet-integration",level:2},{value:"Disconnect the Casper Wallet",id:"disconnect-the-casper-wallet",level:3},{value:"Call a Smart Contract",id:"call-a-smart-contract",level:2},{value:"Query a Smart Contract",id:"query-a-smart-contract",level:2},{value:"Test Application",id:"test-application",level:2},{value:"Build for Production",id:"build-for-production",level:2}],d={toc:u},m="wrapper";function h(e){var t=e.components,n=(0,r.Z)(e,i);return(0,o.kt)(m,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"front-end-template-with-react"},"Front-end Template with React"),(0,o.kt)("p",null,"For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/casper-js-sdk"},"Casper JS SDK"),"."),(0,o.kt)("p",null,"This guide will walk you through setting up and developing a React application with ",(0,o.kt)("a",{parentName:"p",href:"https://vitejs.dev/"},"Vite")," that communicates with a Casper network. Experience with Vite is not required; however, if you have never built a React app, you should begin by ",(0,o.kt)("a",{parentName:"p",href:"https://reactjs.org/docs/getting-started.html"},"reading the React documentation"),"."),(0,o.kt)("h2",{id:"get-started"},"Get Started"),(0,o.kt)("p",null,"Begin by opening a terminal and running:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"node -v\n")),(0,o.kt)("p",null,"To get your Node.js version."),(0,o.kt)("p",null,"To ensure compatibility, you should be running Node.js version 18 or above. Upgrade to version 18 using the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/nvm-sh/nvm"},"Node Version Manager")," or another tool if you are running an earlier version."),(0,o.kt)("p",null,"Using ",(0,o.kt)("a",{parentName:"p",href:"https://www.npmjs.com/"},"npm"),", create a new Vite project by running:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"npm install -g vite\nnpm create vite@latest\n")),(0,o.kt)("p",null,'Name your project, select "React", then choose your preferred language. In this example, we will use JavaScript.'),(0,o.kt)("p",null,"Head into your new project directory, replacing ",(0,o.kt)("inlineCode",{parentName:"p"},"vite-project")," with your project name:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cd vite-project/\n")),(0,o.kt)("p",null,"Run the following command to test the server:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"npm install\nvite dev\n")),(0,o.kt)("p",null,"Quit the server by pressing ",(0,o.kt)("inlineCode",{parentName:"p"},"q"),". Install the Casper JS SDK by running the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"npm install casper-js-sdk\n")),(0,o.kt)("p",null,"This guide will use ",(0,o.kt)("a",{parentName:"p",href:"https://axios-http.com/"},"axios")," to communicate with the backend; install it by running:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"npm install axios\n")),(0,o.kt)("h2",{id:"casper-wallet-integration"},"Casper Wallet Integration"),(0,o.kt)("p",null,"The Casper Wallet extension content script injects the SDK into your website's global scope. Provider class and event types can be accessed with ",(0,o.kt)("inlineCode",{parentName:"p"},"window.CasperWalletProvider")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"window.CasperWalletEventTypes"),". If the value of these variables is ",(0,o.kt)("inlineCode",{parentName:"p"},"undefined")," the Casper Wallet is not installed."),(0,o.kt)("p",null,"Start with a helper for getting the provider instance:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"touch src/casper-wallet.js\n")),(0,o.kt)("p",null,"Fill the file with the following content:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'// Timeout (in ms) for requests to the extension [DEFAULT: 30 min]\nconst REQUESTS_TIMEOUT_MS = 30 * 60 * 1000;\n\nexport const getProvider = () => {\n let providerConstructor = window.CasperWalletProvider;\n if (providerConstructor === undefined) {\n alert("Casper Wallet extension is not installed!");\n return;\n }\n let provider = providerConstructor({\n timeout: REQUESTS_TIMEOUT_MS,\n });\n return provider;\n};\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"For complete integration details, refer to ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/make-software/casper-wallet-sdk/#readme"},"README of Casper Wallet SDK"),".")),(0,o.kt)("p",null,"To ensure that a user's public key will be available to all necessary components, create a React state variable in ",(0,o.kt)("em",{parentName:"p"},"src/App.jsx")," or another parent component that encapsulates the components that should have access to this public key:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-jsx"},'import React from "react";\nimport Connect from "./Connect";\nimport "./App.css";\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n \n
\n {publicKey !== null && (\n <>\n Wallet connected: {publicKey}\n
\n \n )}\n
\n \n );\n}\n\nexport default App;\n')),(0,o.kt)("p",null,"This is an example of ",(0,o.kt)("em",{parentName:"p"},"src/App.jsx")," that imports and displays the ",(0,o.kt)("inlineCode",{parentName:"p"},"Connect")," component that is described next. The ",(0,o.kt)("inlineCode",{parentName:"p"},"setPublicKey")," function is passed to the ",(0,o.kt)("inlineCode",{parentName:"p"},"Connect")," component as a ",(0,o.kt)("a",{parentName:"p",href:"https://legacy.reactjs.org/docs/components-and-props.html"},"prop")," so that it may set the public key and make it available to all of ",(0,o.kt)("em",{parentName:"p"},"src/App.jsx"),". This way, when more components are added to ",(0,o.kt)("em",{parentName:"p"},"src/App.jsx"),", they may utilize the ",(0,o.kt)("inlineCode",{parentName:"p"},"publicKey")," variable."),(0,o.kt)("p",null,"To connect to the Casper Wallet within your React app, create the ",(0,o.kt)("inlineCode",{parentName:"p"},"Connect")," component and import the ",(0,o.kt)("inlineCode",{parentName:"p"},"getProvider")," helper."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"touch src/Connect.jsx\n")),(0,o.kt)("p",null,"Open the file and write:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-jsx"},'import { getProvider } from "./casper-wallet";\n\nconst provider = getProvider();\n\nconst Connect = (props) => {\n return (\n <>\n \n {/* Place for disconnect button */}\n \n );\n};\n\nexport default Connect;\n')),(0,o.kt)("p",null,"Notice that ",(0,o.kt)("inlineCode",{parentName:"p"},"Connect")," accepts props, and forwards them to the ",(0,o.kt)("inlineCode",{parentName:"p"},"connectToWallet")," function described below. This function is called when the button is clicked, allowing it to set the public key within ",(0,o.kt)("em",{parentName:"p"},"src/App.jsx")," using ",(0,o.kt)("inlineCode",{parentName:"p"},"props.setPublicKey()"),"."),(0,o.kt)("p",null,"Write the ",(0,o.kt)("inlineCode",{parentName:"p"},"connectToWallet")," function under the ",(0,o.kt)("inlineCode",{parentName:"p"},"Connect")," function component:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-javascript"},'const connectToWallet = (props) => {\n provider\n .requestConnection()\n .then((connected) => {\n if (!connected) {\n alert("Couldn\'t connect to wallet");\n } else {\n provider\n .getActivePublicKey()\n .then((publicKey) => {\n props.setPublicKey(publicKey);\n })\n .catch((error) => {\n alert(error.message);\n });\n }\n })\n .catch((error) => {\n alert(error.message);\n });\n};\n')),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"connectToWallet()")," function calls ",(0,o.kt)("inlineCode",{parentName:"p"},"provider.isConnected()")," to check if the Casper Wallet is already connected. If it is, it gets the public key of the selected account; if it's not, it opens up a connection request within the Wallet. ",(0,o.kt)("inlineCode",{parentName:"p"},"provider.isConnected()")," will throw an error if the Wallet is not installed as an extension or if it is locked."),(0,o.kt)("h3",{id:"disconnect-the-casper-wallet"},"Disconnect the Casper Wallet"),(0,o.kt)("p",null,"To request that the Casper Wallet disconnect from a website, add the following function call to ",(0,o.kt)("em",{parentName:"p"},"src/Connect.jsx"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-javascript"},'const disconnect = (props) => {\n provider\n .disconnectFromSite()\n .then((disconnected) => {\n if (disconnected) {\n props.setPublicKey(null);\n alert("Disconnected");\n }\n })\n .catch((error) => {\n alert(error.message);\n });\n};\n')),(0,o.kt)("p",null,"Then connect it to a button:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-jsx"},"const Connect = (props) => {\n return (\n <>\n \n // highlight-next-line-green\n \n \n );\n};\n")),(0,o.kt)("h2",{id:"call-a-smart-contract"},"Call a Smart Contract"),(0,o.kt)("p",null,'For this example, we\'ll call a hypothetical "hello world" contract containing a single entrypoint "update_message". We\'ll call the "update_message" entrypoint with text entered by the user in an HTML ',(0,o.kt)("inlineCode",{parentName:"p"},"input")," field."),(0,o.kt)("p",null,"When calling smart contracts from React, you'll need to implement the logic within a function accessible from a React component. You can obtain user-entered data from the DOM using elements like ",(0,o.kt)("inlineCode",{parentName:"p"},"input"),", then grab the value within the smart-contract-calling function."),(0,o.kt)("p",null,"Create a new component:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"touch src/UpdateMessage.jsx\n")),(0,o.kt)("p",null,"Open the file and write:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-jsx"},'import { useState } from "react";\nimport { Contracts, CasperClient, RuntimeArgs, CLValueBuilder, CLPublicKey, DeployUtil } from "casper-js-sdk";\nimport axios from "axios";\nimport { getProvider } from "./casper-wallet";\n\nconst provider = getProvider();\n\nconst UpdateMessage = (props) => {\n const [message, setMessage] = useState("");\n\n return (\n <>\n {\n setMessage(e.target.value);\n }}\n />\n \n \n );\n};\n\nexport default UpdateMessage;\n')),(0,o.kt)("p",null,"On the front-end you'll need to build the deploy and forward it to the Casper Wallet to be signed. In most cases, you will be calling smart contract entrypoints. This example deploy shows the calling of entrypoint \"update_message\" which will update the chain's global state to reflect the new data. You'll need the user's active public key to prepare the deploy, and you may retrieve this from the ",(0,o.kt)("inlineCode",{parentName:"p"},"publicKey")," variable passed in as a prop from ",(0,o.kt)("inlineCode",{parentName:"p"},"src/App.jsx"),". Write this function under your ",(0,o.kt)("inlineCode",{parentName:"p"},"UpdateMessage")," component function."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-javascript"},'const NODE_URL = "http://65.108.127.242:7777/rpc";\nconst NETWORK_NAME = "casper-test"; // "casper" for mainnet\nconst CONTRACT_HASH = "hash-75143aa708275b7dead20ac2cc06c1c3eccff4ffcf1eb9aebb8cce7c35cea041";\n\nconst updateMessage = (props, message) => {\n const casperClient = new CasperClient(NODE_URL);\n const contract = new Contracts.Contract(casperClient);\n contract.setContractHash(CONTRACT_HASH);\n const runtimeArguments = RuntimeArgs.fromMap({\n message: CLValueBuilder.string(message),\n });\n const deploy = contract.callEntrypoint(\n "update_message",\n runtimeArguments,\n CLPublicKey.fromHex(props.publicKey),\n NETWORK_NAME,\n "1000000000", // 1 CSPR (10^9 Motes)\n );\n const deployJSON = DeployUtil.deployToJson(deploy);\n provider\n .sign(JSON.stringify(deployJSON), props.publicKey)\n .then((signedDeploy) => {\n // Initiates sign request\n axios\n .post("/sendDeploy", signedDeploy, {\n headers: {\n "Content-Type": "application/json",\n },\n })\n .then((response) => {\n alert(response.data);\n })\n .catch((error) => {\n console.error(error.message);\n });\n })\n .catch((error) => {\n console.error(error.message);\n });\n};\n')),(0,o.kt)("p",null,"In this example, ",(0,o.kt)("inlineCode",{parentName:"p"},"updateMessage")," builds a deploy and forwards it to the Casper Wallet to be signed by the user. Once it's been signed, ",(0,o.kt)("inlineCode",{parentName:"p"},"signedDeploy")," is forwarded to the backend at the ",(0,o.kt)("inlineCode",{parentName:"p"},"/sendDeploy")," endpoint using ",(0,o.kt)("inlineCode",{parentName:"p"},"axios.post")," before being sent off to a Casper node. If an error occurs, or the user rejects the signature request, it will be logged to ",(0,o.kt)("inlineCode",{parentName:"p"},"stderr"),". In this particular example, the result of this deployment will be presented to the user in the form of a JavaScript ",(0,o.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/API/Window/alert"},"alert"),"; however, you may do with the response data as you wish."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"The backend endpoint ",(0,o.kt)("inlineCode",{parentName:"p"},"/sendDeploy")," should handle signed deployment by simply passing it to a Casper node."),(0,o.kt)("p",{parentName:"admonition"},"In Casper node ",(0,o.kt)("inlineCode",{parentName:"p"},"v1.5.0"),", which sets up appropriate CORS headers, it will also be possible to send deployments directly from the browser, without relying on a backend server. This is useful for prototyping, however it is advised that you operate your own node.")),(0,o.kt)("p",null,"Now that this component is created, render it to the user interface in ",(0,o.kt)("em",{parentName:"p"},"src/App.jsx"),", passing along the ",(0,o.kt)("inlineCode",{parentName:"p"},"publicKey")," as a prop:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-jsx"},'import React from "react";\nimport Connect from "./Connect";\n// highlight-next-line-green\nimport UpdateMessage from "./UpdateMessage";\nimport "./App.css";\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n \n
\n {publicKey !== null && (\n <>\n Wallet connected: {publicKey}\n
\n // highlight-next-line-green\n \n \n )}\n
\n \n );\n}\n')),(0,o.kt)("h2",{id:"query-a-smart-contract"},"Query a Smart Contract"),(0,o.kt)("p",null,"Consider that the message written to the chain during the ",(0,o.kt)("inlineCode",{parentName:"p"},"update_message")," entrypoint invocation is stored in the ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/D#dictionary"},"dictionary")," ",(0,o.kt)("inlineCode",{parentName:"p"},"messages")," in the contract. Further consider that each account may write its own message and that the messages are stored under the account's ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/A#account-hash"},"account hash")," as the dictionary key. Querying this kind of data is essential in any dApp; here is how to communicate contract data to and from the front-end."),(0,o.kt)("p",null,"Create a new component:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"touch src/Query.jsx\n")),(0,o.kt)("p",null,"Open the file and write:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-jsx"},'import axios from "axios";\nimport { CLPublicKey } from "casper-js-sdk";\n\nconst Query = (props) => {\n return ;\n};\n\nconst query = (props) => {\n const accountHash = CLPublicKey.fromHex(props.publicKey).toAccountHashStr().substring(13);\n axios\n .get("/queryMessage?accountHash=" + accountHash)\n .then((response) => {\n alert(response.data);\n })\n .catch((error) => {\n console.error(error.message);\n });\n};\n\nexport default Query;\n')),(0,o.kt)("p",null,"All this component does is render an HTML ",(0,o.kt)("inlineCode",{parentName:"p"},"button")," element that, when pressed, performs a ",(0,o.kt)("inlineCode",{parentName:"p"},"GET")," request to the backend that includes the user's active account hash. The account hash is derived from the active public key, and is used to look up the message stored by the current user."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The ",(0,o.kt)("inlineCode",{parentName:"p"},"toAccountHashStr"),' method produces a string that is prepended by the text "account-hash-". In this case, this text is not needed, so it is discarded by chaining on the ',(0,o.kt)("inlineCode",{parentName:"p"},"substring(13)")," method.")),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"This functionality relies on the ",(0,o.kt)("inlineCode",{parentName:"p"},"/queryMessage")," endpoint, which should be implemented in your backend.")),(0,o.kt)("p",null,"Now add this component to ",(0,o.kt)("em",{parentName:"p"},"src/App.jsx"),", making available the ",(0,o.kt)("inlineCode",{parentName:"p"},"publicKey")," state variable via a prop:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-jsx"},'import React from "react";\nimport Connect from "./Connect";\nimport UpdateMessage from "./UpdateMessage";\n// highlight-next-line-green\nimport Query from "./Query";\nimport "./App.css";\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n \n
\n {publicKey !== null && (\n <>\n Wallet connected: {publicKey}\n
\n \n // highlight-next-line-green\n \n \n )}\n
\n \n );\n}\n')),(0,o.kt)("h2",{id:"test-application"},"Test Application"),(0,o.kt)("p",null,"Test your application by running the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"vite dev\n")),(0,o.kt)("p",null,"Your application will start locally, and a URL will be shown where you can visit your application. Alternatively, press ",(0,o.kt)("inlineCode",{parentName:"p"},"h"),", then ",(0,o.kt)("inlineCode",{parentName:"p"},"o")," to open the app in a browser."),(0,o.kt)("h2",{id:"build-for-production"},"Build for Production"),(0,o.kt)("p",null,"When you're ready to release your application, you'll want to compile it to pure JavaScript and serve it from a web server. Do so by running:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"vite build\n")),(0,o.kt)("p",null,"Once this is complete, you can preview your production build by running:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"vite preview\n")))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b0120e2d.d0f70710.js b/assets/js/b0120e2d.973477d1.js similarity index 99% rename from assets/js/b0120e2d.d0f70710.js rename to assets/js/b0120e2d.973477d1.js index 39eb5c1157..1e353ad2b8 100644 --- a/assets/js/b0120e2d.d0f70710.js +++ b/assets/js/b0120e2d.973477d1.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[1636],{3905:function(e,t,n){n.d(t,{Zo:function(){return d},kt:function(){return h}});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var i=a.createContext({}),c=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},d=function(e){var t=c(e.components);return a.createElement(i.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,i=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=c(n),f=o,h=p["".concat(i,".").concat(f)]||p[f]||u[f]||r;return n?a.createElement(h,s(s({ref:t},d),{},{components:n})):a.createElement(h,s({ref:t},d))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,s=new Array(r);s[0]=f;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[p]="string"==typeof e?e:o,s[1]=l;for(var c=2;c/events/deploys")),(0,r.kt)("p",null,"With the following command, you can start watching the event stream for DeployAccepted events. Note the event ID recorded when you send the Deploy in the next section."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s http://65.21.235.219:9999/events/deploys\n")),(0,r.kt)("h2",{id:"sending-the-deploy"},"Sending a Deploy to the Network"),(0,r.kt)("p",null,"You can call the Casper client's ",(0,r.kt)("inlineCode",{parentName:"p"},"put-deploy")," command to put the compiled contract on the chain. In this example, the Deploy will execute in the account's context. See the ",(0,r.kt)("a",{parentName:"p",href:"#advanced-features"},"advanced features")," section for key delegation."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n --node-address \\\n --chain-name casper-test \\\n --secret-key \\\n --payment-amount \\\n --session-path \n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777. You can find a list of trusted peers in network's configuration file, ",(0,r.kt)("inlineCode",{parentName:"li"},"config.toml"),". Here is an ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/config-example.toml#L131"},"example"),". You may send deploys to one of the trusted nodes or use them to query other online nodes."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,r.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,r.kt)("em",{parentName:"li"},"casper-test"),". As you can see, this example uses the Testnet"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This example uses 2.5 CSPR, but you need to modify this for your contract. See the ",(0,r.kt)("a",{parentName:"li",href:"#a-note-about-gas-price"},"note")," below"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to the contract Wasm, which should point to wherever you compiled the contract (.wasm file) on your computer")),(0,r.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's execution results. Sending the deploy and receiving the deploy hash does not mean the deploy was processed successfully. Therefore, you must check the deploy execution using the deploy hash. See the deploy lifecycle for more details."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Note"),": Each Deploy gets a unique hash, which is part of the cryptographic security of blockchain technology. No two deploys will ever return the same hash."),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Sample put-deploy result"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": -6958186952964949950,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "deploy_hash": "34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496"\n }\n}\n'))),(0,r.kt)("p",null,"Verify the deploy details with the ",(0,r.kt)("inlineCode",{parentName:"p"},"get-deploy")," command and the ",(0,r.kt)("inlineCode",{parentName:"p"},"deploy_hash")," received above."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy \\\n --node-address \n")),(0,r.kt)("p",null,"If the Deploy succeeded, the ",(0,r.kt)("inlineCode",{parentName:"p"},"get-deploy")," command would return a JSON object with the full deploy details."),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Sample get-deploy result"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": -3532286620275982221,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "deploy": {\n "approvals": [\n {\n "signature": "015a7b0178e144fbf5ce52147c44a3e6bd6aae898ec6bb47c97b5802f3bcb6cd26331f7db18464cd1e51764c14ceb24b7ab9c4e3595505c32465fc0702e8d5510b",\n "signer": "01e76e0279a08b96d9d68e6b86c618de24a0c324d7d0c1fa8c035f0bc2af1a396d"\n }\n ],\n "hash": "34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496",\n "header": {\n "account": "01e76e0279a08b96d9d68e6b86c618de24a0c324d7d0c1fa8c035f0bc2af1a396d",\n "body_hash": "b1956600be3c11d7555ada11426ab1a8bdf36102f59838d6bf69cec321111a22",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2022-03-24T12:05:57.579Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "05000c774203",\n "cl_type": "U512",\n "parsed": "14000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "ModuleBytes": {\n "args": [],\n "module_bytes": "[94478 hex chars]"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "098b618878a2413393925e1fbf6d3cf92f1208f4f8662a904e86b49b0c4ab9f0",\n "result": {\n "Success": {\n "cost": "13327900740",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-3a61ed9a3b472f35f4cf1e241d674fad8a5f9509c97a56d62bb03f7bcc4b8474",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-3a61ed9a3b472f35f4cf1e241d674fad8a5f9509c97a56d62bb03f7bcc4b8474",\n "transform": {\n "WriteCLValue": {\n "bytes": "0500279bd1ca",\n "cl_type": "U512",\n "parsed": "871100000000"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "14000000000"\n }\n },\n {\n "key": "uref-82a7b5713f2b9b3f9e1b4f2d1f312a5fec7c3a0bed6fa897501913951729dbbf-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "00000000",\n "cl_type": "I32",\n "parsed": 0\n }\n }\n },\n {\n "key": "uref-ea022d75ff618533baf46040cc57692fb7f7840774c979c9dec0b5c3ddcec7e9-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-4d0e2bfb5d243ea567e9b37aa8229d2b8b01de838c4bd7ca570a178e012d6b82",\n "transform": "WriteContractPackage"\n },\n {\n "key": "hash-4d0e2bfb5d243ea567e9b37aa8229d2b8b01de838c4bd7ca570a178e012d6b82",\n "transform": "Identity"\n },\n {\n "key": "hash-3b69bafcc13b4541dddd7d5492e4754feee41c636990aeb6bf78d58fdd39fc43",\n "transform": "WriteContractWasm"\n },\n {\n "key": "hash-c39dd923df84c637e46e46a8a3326fcf85e43c60814878f44a08efd0074cb523",\n "transform": "WriteContract"\n },\n {\n "key": "hash-4d0e2bfb5d243ea567e9b37aa8229d2b8b01de838c4bd7ca570a178e012d6b82",\n "transform": "WriteContractPackage"\n },\n {\n "key": "account-hash-f407926760b91c2ce3af8bda7448841b3aa68c6e98053331d10819ef2d0a808e",\n "transform": {\n "AddKeys": [\n {\n "key": "hash-c39dd923df84c637e46e46a8a3326fcf85e43c60814878f44a08efd0074cb523",\n "name": "counter"\n }\n ]\n }\n },\n {\n "key": "deploy-34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496",\n "from": "account-hash-f407926760b91c2ce3af8bda7448841b3aa68c6e98053331d10819ef2d0a808e",\n "gas": "13327900740",\n "source": "uref-3a61ed9a3b472f35f4cf1e241d674fad8a5f9509c97a56d62bb03f7bcc4b8474-007",\n "transfers": []\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-0a24ef56971d46bfefbd5590afe20e5f3482299aba74e1a0fc33a55008cf9453",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-0a24ef56971d46bfefbd5590afe20e5f3482299aba74e1a0fc33a55008cf9453",\n "transform": {\n "AddUInt512": "14000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'))),(0,r.kt)("p",null,"We want to draw your attention to a few properties in the example output:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Execution cost 13327900740 motes, yet we paid 14000000000 motes. See the ",(0,r.kt)("a",{parentName:"li",href:"#a-note-about-gas-price"},"note about gas price")),(0,r.kt)("li",{parentName:"ul"},'The contract returned no errors. If you see an "Out of gas error", you did not specify a high enough value in the ',(0,r.kt)("inlineCode",{parentName:"li"},"--payment-amount")," arg"),(0,r.kt)("li",{parentName:"ul"},"The time-to-live was 30 minutes")),(0,r.kt)("p",null,"It is also possible to get a summary of the deploy's information by performing a ",(0,r.kt)("inlineCode",{parentName:"p"},"query-global-state")," command using the Casper client and providing a state root hash or a block hash from a block at or after the one in which the deploy was executed."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address \n\ncasper-client query-global-state --node-address \\\n --key deploy- \\\n --state-root-hash \n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state --node-address \\\n --key deploy-\n --block-hash \n")),(0,r.kt)("p",null,"Run the help command for ",(0,r.kt)("inlineCode",{parentName:"p"},"query-global-state")," to see its usage."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state --help\n")),(0,r.kt)("h3",{id:"ttl"},"Time-to-live"),(0,r.kt)("p",null,"Time-to-live is the parameter that determines how long a deploy will wait for execution. The acceptable maximum ",(0,r.kt)("inlineCode",{parentName:"p"},"ttl")," is configurable by chain, with the Casper Mainnet maximum set to ",(0,r.kt)("inlineCode",{parentName:"p"},"18hours"),". If you are sending a deploy to a different network, you will need to check ",(0,r.kt)("inlineCode",{parentName:"p"},"chainspec.toml")," for that network to determine the acceptable maximum. The minimum is theoretically zero, but this will result in an immediate expiration and an invalid deploy."),(0,r.kt)("p",null,"In the event of a network outage or other event that prevents execution within the ",(0,r.kt)("inlineCode",{parentName:"p"},"ttl"),", the solution is to resend the deploy in question."),(0,r.kt)("p",null,"Should the deploy's ",(0,r.kt)("inlineCode",{parentName:"p"},"ttl")," exceed the allowable limit, or if the deploy expires, the network's deploy acceptor will find the deploy invalid and return a warning."),(0,r.kt)("h3",{id:"deploy-payments"},"Deploy Payments"),(0,r.kt)("p",null,"Dependent upon the complexity and needs of the Deploy in question, several options exist to allow users to pay for smart contract execution."),(0,r.kt)("p",null,"The simplest way to pay for a Deploy on the Casper blockchain is to use the host side standard payment functionality. This can be done using an ",(0,r.kt)("strong",{parentName:"p"},"empty")," ",(0,r.kt)("inlineCode",{parentName:"p"},"ModuleBytes")," as your payment code. However, you must specify the amount within a runtime argument. ",(0,r.kt)("inlineCode",{parentName:"p"},"ModuleBytes")," can also serve as a custom payment contract if it is not empty, but any additional Wasm ran within will come at an additional cost on top of the payment. This includes invalid Wasm, which will still result in additional cost."),(0,r.kt)("p",null,"You may find the host side functionality of standard payment insufficient for your purposes. In this event, Casper provides the following options for custom payment code:"),(0,r.kt)("p",null,"\u2022 ",(0,r.kt)("inlineCode",{parentName:"p"},"StoredContractByHash")),(0,r.kt)("p",null,"\u2022 ",(0,r.kt)("inlineCode",{parentName:"p"},"StoredContractByName")),(0,r.kt)("p",null,"\u2022 ",(0,r.kt)("inlineCode",{parentName:"p"},"StoredVersionContractByHash")),(0,r.kt)("p",null,"\u2022 ",(0,r.kt)("inlineCode",{parentName:"p"},"StoredVersionContractByName")),(0,r.kt)("h2",{id:"using-arguments-with-deploys"},"Using Arguments with Deploys"),(0,r.kt)("p",null,"The session Wasm (or payment Wasm if you choose to ",(0,r.kt)("em",{parentName:"p"},"not"),' use the standard payment) of a Deploy often requires arguments to be passed to it when executed. These "runtime args" should be provided by using the ',(0,r.kt)("inlineCode",{parentName:"p"},"--session-arg")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"--payment-arg")," options, once for each arg required. The Casper client provides some examples of how to do this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy --show-arg-examples\n")),(0,r.kt)("h2",{id:"advanced-features"},"Advanced Features"),(0,r.kt)("p",null,"Casper networks support complex deploys using multiple signatures. ",(0,r.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-head"},"Casper Accounts")," use a powerful permissions model that enables a multi-signature scheme for deploys."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"put-deploy")," command performs multiple actions under the hood, optimizing the typical use case. It creates a deploy, signs it, and sends the Deploy to the network without allowing multiple signatures. However, it is possible to call the following three commands and separate key management from account creation:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"make-deploy")," - Creates a Deploy and outputs it to a file or stdout. As a file, the deploy can subsequently be signed by other parties using the ",(0,r.kt)("inlineCode",{parentName:"li"},"sign-deploy")," subcommand and then sent to the network for execution using the ",(0,r.kt)("inlineCode",{parentName:"li"},"send-deploy")," subcommand"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"sign-deploy")," - Reads a previously-saved Deploy from a file, cryptographically signs it, and outputs it to a file or stdout"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"send-deploy")," - Reads a previously-saved Deploy from a file and sends it to the network for execution")),(0,r.kt)("p",null,"To sign a Deploy with multiple keys, create the Deploy with the ",(0,r.kt)("inlineCode",{parentName:"p"},"make-deploy")," command. The generated deploy file can be sent to the other signers, who then sign it with their keys by calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"sign-deploy")," for each key. Signatures need to be gathered on the Deploy one after another until all required parties have signed the Deploy. Finally, the signed Deploy is sent to the network with the ",(0,r.kt)("inlineCode",{parentName:"p"},"send-deploy")," command for processing."),(0,r.kt)("p",null,"For a step-by-step workflow, visit the ",(0,r.kt)("a",{parentName:"p",href:"/developers/cli/transfers/multisig-deploy-transfer"},"Two-Party Multi-Signature Deploy")," guide. This workflow describes how a trivial two-party multi-signature scheme for signing and sending deploys can be enforced for an account on a Casper network."),(0,r.kt)("h2",{id:"a-note-about-gas-price"},"A Note about Gas Price"),(0,r.kt)("p",null,'A common question frequently arises: "How do I know what the payment amount (gas cost) should be?"'),(0,r.kt)("p",null,"We recommend installing your contracts in a test environment, making sure the cost tables match those of the production Casper network to which you want to send the deploy. If you plan on sending a deploy to ",(0,r.kt)("a",{parentName:"p",href:"https://cspr.live/"},"Mainnet"),", you can use the ",(0,r.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/"},"Testnet")," to estimate the payment amount needed for the deploy."),(0,r.kt)("p",null,"If your test configuration matches your production ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),", you can check the deploy status and roughly see how much it would cost. You can estimate the costs in this way and then add a small buffer to be sure. Refer to the ",(0,r.kt)("a",{parentName:"p",href:"/runtime#gas-allocation"},"runtime economics")," section for more details about gas usage and fees."),(0,r.kt)("p",null,"Please be aware that sending a deploy always requires payment. This is true regardless of the validity of included Wasm."),(0,r.kt)("p",null,"If the deploy failure occurs after session execution begins, the penalty payment of 2.5 CSPR is included in the gas costs of the ",(0,r.kt)("a",{parentName:"p",href:"/concepts/serialization-standard#executionresult-executionresult"},"failed execution"),"."),(0,r.kt)("p",null,"However, if the failure occurs prior to session execution, the penalty payment will not appear within the gas cost of the deploy. Instead, the system automatically deducts the 2.5 CSPR from the sending account's main purse."))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[1636],{3905:function(e,t,n){n.d(t,{Zo:function(){return d},kt:function(){return h}});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var i=a.createContext({}),c=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},d=function(e){var t=c(e.components);return a.createElement(i.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,i=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=c(n),f=o,h=p["".concat(i,".").concat(f)]||p[f]||u[f]||r;return n?a.createElement(h,s(s({ref:t},d),{},{components:n})):a.createElement(h,s({ref:t},d))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,s=new Array(r);s[0]=f;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[p]="string"==typeof e?e:o,s[1]=l;for(var c=2;c/events/deploys")),(0,r.kt)("p",null,"With the following command, you can start watching the event stream for DeployAccepted events. Note the event ID recorded when you send the Deploy in the next section."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s http://65.21.235.219:9999/events/deploys\n")),(0,r.kt)("h2",{id:"sending-the-deploy"},"Sending a Deploy to the Network"),(0,r.kt)("p",null,"You can call the Casper client's ",(0,r.kt)("inlineCode",{parentName:"p"},"put-deploy")," command to put the compiled contract on the chain. In this example, the Deploy will execute in the account's context. See the ",(0,r.kt)("a",{parentName:"p",href:"#advanced-features"},"advanced features")," section for key delegation."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n --node-address \\\n --chain-name casper-test \\\n --secret-key \\\n --payment-amount \\\n --session-path \n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777. You can find a list of trusted peers in network's configuration file, ",(0,r.kt)("inlineCode",{parentName:"li"},"config.toml"),". Here is an ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/config-example.toml#L131"},"example"),". You may send deploys to one of the trusted nodes or use them to query other online nodes."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,r.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,r.kt)("em",{parentName:"li"},"casper-test"),". As you can see, this example uses the Testnet"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This example uses 2.5 CSPR, but you need to modify this for your contract. See the ",(0,r.kt)("a",{parentName:"li",href:"#a-note-about-gas-price"},"note")," below"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to the contract Wasm, which should point to wherever you compiled the contract (.wasm file) on your computer")),(0,r.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's execution results. Sending the deploy and receiving the deploy hash does not mean the deploy was processed successfully. Therefore, you must check the deploy execution using the deploy hash. See the deploy lifecycle for more details."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Note"),": Each Deploy gets a unique hash, which is part of the cryptographic security of blockchain technology. No two deploys will ever return the same hash."),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Sample put-deploy result"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": -6958186952964949950,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "deploy_hash": "34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496"\n }\n}\n'))),(0,r.kt)("p",null,"Verify the deploy details with the ",(0,r.kt)("inlineCode",{parentName:"p"},"get-deploy")," command and the ",(0,r.kt)("inlineCode",{parentName:"p"},"deploy_hash")," received above."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy \\\n --node-address \n")),(0,r.kt)("p",null,"If the Deploy succeeded, the ",(0,r.kt)("inlineCode",{parentName:"p"},"get-deploy")," command would return a JSON object with the full deploy details."),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Sample get-deploy result"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": -3532286620275982221,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "deploy": {\n "approvals": [\n {\n "signature": "015a7b0178e144fbf5ce52147c44a3e6bd6aae898ec6bb47c97b5802f3bcb6cd26331f7db18464cd1e51764c14ceb24b7ab9c4e3595505c32465fc0702e8d5510b",\n "signer": "01e76e0279a08b96d9d68e6b86c618de24a0c324d7d0c1fa8c035f0bc2af1a396d"\n }\n ],\n "hash": "34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496",\n "header": {\n "account": "01e76e0279a08b96d9d68e6b86c618de24a0c324d7d0c1fa8c035f0bc2af1a396d",\n "body_hash": "b1956600be3c11d7555ada11426ab1a8bdf36102f59838d6bf69cec321111a22",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2022-03-24T12:05:57.579Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "05000c774203",\n "cl_type": "U512",\n "parsed": "14000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "ModuleBytes": {\n "args": [],\n "module_bytes": "[94478 hex chars]"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "098b618878a2413393925e1fbf6d3cf92f1208f4f8662a904e86b49b0c4ab9f0",\n "result": {\n "Success": {\n "cost": "13327900740",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-3a61ed9a3b472f35f4cf1e241d674fad8a5f9509c97a56d62bb03f7bcc4b8474",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-3a61ed9a3b472f35f4cf1e241d674fad8a5f9509c97a56d62bb03f7bcc4b8474",\n "transform": {\n "WriteCLValue": {\n "bytes": "0500279bd1ca",\n "cl_type": "U512",\n "parsed": "871100000000"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "14000000000"\n }\n },\n {\n "key": "uref-82a7b5713f2b9b3f9e1b4f2d1f312a5fec7c3a0bed6fa897501913951729dbbf-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "00000000",\n "cl_type": "I32",\n "parsed": 0\n }\n }\n },\n {\n "key": "uref-ea022d75ff618533baf46040cc57692fb7f7840774c979c9dec0b5c3ddcec7e9-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-4d0e2bfb5d243ea567e9b37aa8229d2b8b01de838c4bd7ca570a178e012d6b82",\n "transform": "WriteContractPackage"\n },\n {\n "key": "hash-4d0e2bfb5d243ea567e9b37aa8229d2b8b01de838c4bd7ca570a178e012d6b82",\n "transform": "Identity"\n },\n {\n "key": "hash-3b69bafcc13b4541dddd7d5492e4754feee41c636990aeb6bf78d58fdd39fc43",\n "transform": "WriteContractWasm"\n },\n {\n "key": "hash-c39dd923df84c637e46e46a8a3326fcf85e43c60814878f44a08efd0074cb523",\n "transform": "WriteContract"\n },\n {\n "key": "hash-4d0e2bfb5d243ea567e9b37aa8229d2b8b01de838c4bd7ca570a178e012d6b82",\n "transform": "WriteContractPackage"\n },\n {\n "key": "account-hash-f407926760b91c2ce3af8bda7448841b3aa68c6e98053331d10819ef2d0a808e",\n "transform": {\n "AddKeys": [\n {\n "key": "hash-c39dd923df84c637e46e46a8a3326fcf85e43c60814878f44a08efd0074cb523",\n "name": "counter"\n }\n ]\n }\n },\n {\n "key": "deploy-34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496",\n "from": "account-hash-f407926760b91c2ce3af8bda7448841b3aa68c6e98053331d10819ef2d0a808e",\n "gas": "13327900740",\n "source": "uref-3a61ed9a3b472f35f4cf1e241d674fad8a5f9509c97a56d62bb03f7bcc4b8474-007",\n "transfers": []\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-0a24ef56971d46bfefbd5590afe20e5f3482299aba74e1a0fc33a55008cf9453",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-0a24ef56971d46bfefbd5590afe20e5f3482299aba74e1a0fc33a55008cf9453",\n "transform": {\n "AddUInt512": "14000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'))),(0,r.kt)("p",null,"We want to draw your attention to a few properties in the example output:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Execution cost 13327900740 motes, yet we paid 14000000000 motes. See the ",(0,r.kt)("a",{parentName:"li",href:"#a-note-about-gas-price"},"note about gas price")),(0,r.kt)("li",{parentName:"ul"},'The contract returned no errors. If you see an "Out of gas error", you did not specify a high enough value in the ',(0,r.kt)("inlineCode",{parentName:"li"},"--payment-amount")," arg"),(0,r.kt)("li",{parentName:"ul"},"The time-to-live was 30 minutes")),(0,r.kt)("p",null,"It is also possible to get a summary of the deploy's information by performing a ",(0,r.kt)("inlineCode",{parentName:"p"},"query-global-state")," command using the Casper client and providing a state root hash or a block hash from a block at or after the one in which the deploy was executed."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address \n\ncasper-client query-global-state --node-address \\\n --key deploy- \\\n --state-root-hash \n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state --node-address \\\n --key deploy-\n --block-hash \n")),(0,r.kt)("p",null,"Run the help command for ",(0,r.kt)("inlineCode",{parentName:"p"},"query-global-state")," to see its usage."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state --help\n")),(0,r.kt)("h3",{id:"ttl"},"Time-to-live"),(0,r.kt)("p",null,"Time-to-live is the parameter that determines how long a deploy will wait for execution. The acceptable maximum ",(0,r.kt)("inlineCode",{parentName:"p"},"ttl")," is configurable by chain, with the Casper Mainnet maximum set to ",(0,r.kt)("inlineCode",{parentName:"p"},"18hours"),". If you are sending a deploy to a different network, you will need to check ",(0,r.kt)("inlineCode",{parentName:"p"},"chainspec.toml")," for that network to determine the acceptable maximum. The minimum is theoretically zero, but this will result in an immediate expiration and an invalid deploy."),(0,r.kt)("p",null,"In the event of a network outage or other event that prevents execution within the ",(0,r.kt)("inlineCode",{parentName:"p"},"ttl"),", the solution is to resend the deploy in question."),(0,r.kt)("p",null,"Should the deploy's ",(0,r.kt)("inlineCode",{parentName:"p"},"ttl")," exceed the allowable limit, or if the deploy expires, the network's deploy acceptor will find the deploy invalid and return a warning."),(0,r.kt)("h3",{id:"deploy-payments"},"Deploy Payments"),(0,r.kt)("p",null,"Dependent upon the complexity and needs of the Deploy in question, several options exist to allow users to pay for smart contract execution."),(0,r.kt)("p",null,"The simplest way to pay for a Deploy on the Casper blockchain is to use the host side standard payment functionality. This can be done using an ",(0,r.kt)("strong",{parentName:"p"},"empty")," ",(0,r.kt)("inlineCode",{parentName:"p"},"ModuleBytes")," as your payment code. However, you must specify the amount within a runtime argument. ",(0,r.kt)("inlineCode",{parentName:"p"},"ModuleBytes")," can also serve as a custom payment contract if it is not empty, but any additional Wasm ran within will come at an additional cost on top of the payment. This includes invalid Wasm, which will still result in additional cost."),(0,r.kt)("p",null,"You may find the host side functionality of standard payment insufficient for your purposes. In this event, Casper provides the following options for custom payment code:"),(0,r.kt)("p",null,"\u2022 ",(0,r.kt)("inlineCode",{parentName:"p"},"StoredContractByHash")),(0,r.kt)("p",null,"\u2022 ",(0,r.kt)("inlineCode",{parentName:"p"},"StoredContractByName")),(0,r.kt)("p",null,"\u2022 ",(0,r.kt)("inlineCode",{parentName:"p"},"StoredVersionContractByHash")),(0,r.kt)("p",null,"\u2022 ",(0,r.kt)("inlineCode",{parentName:"p"},"StoredVersionContractByName")),(0,r.kt)("h2",{id:"using-arguments-with-deploys"},"Using Arguments with Deploys"),(0,r.kt)("p",null,"The session Wasm (or payment Wasm if you choose to ",(0,r.kt)("em",{parentName:"p"},"not"),' use the standard payment) of a Deploy often requires arguments to be passed to it when executed. These "runtime args" should be provided by using the ',(0,r.kt)("inlineCode",{parentName:"p"},"--session-arg")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"--payment-arg")," options, once for each arg required. The Casper client provides some examples of how to do this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy --show-arg-examples\n")),(0,r.kt)("h2",{id:"advanced-features"},"Advanced Features"),(0,r.kt)("p",null,"Casper networks support complex deploys using multiple signatures. ",(0,r.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-head"},"Casper Accounts")," use a powerful permissions model that enables a multi-signature scheme for deploys."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"put-deploy")," command performs multiple actions under the hood, optimizing the typical use case. It creates a deploy, signs it, and sends the Deploy to the network without allowing multiple signatures. However, it is possible to call the following three commands and separate key management from account creation:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"make-deploy")," - Creates a Deploy and outputs it to a file or stdout. As a file, the deploy can subsequently be signed by other parties using the ",(0,r.kt)("inlineCode",{parentName:"li"},"sign-deploy")," subcommand and then sent to the network for execution using the ",(0,r.kt)("inlineCode",{parentName:"li"},"send-deploy")," subcommand"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"sign-deploy")," - Reads a previously-saved Deploy from a file, cryptographically signs it, and outputs it to a file or stdout"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"send-deploy")," - Reads a previously-saved Deploy from a file and sends it to the network for execution")),(0,r.kt)("p",null,"To sign a Deploy with multiple keys, create the Deploy with the ",(0,r.kt)("inlineCode",{parentName:"p"},"make-deploy")," command. The generated deploy file can be sent to the other signers, who then sign it with their keys by calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"sign-deploy")," for each key. Signatures need to be gathered on the Deploy one after another until all required parties have signed the Deploy. Finally, the signed Deploy is sent to the network with the ",(0,r.kt)("inlineCode",{parentName:"p"},"send-deploy")," command for processing."),(0,r.kt)("p",null,"For a step-by-step workflow, visit the ",(0,r.kt)("a",{parentName:"p",href:"/developers/cli/transfers/multisig-deploy-transfer"},"Two-Party Multi-Signature Deploy")," guide. This workflow describes how a trivial two-party multi-signature scheme for signing and sending deploys can be enforced for an account on a Casper network."),(0,r.kt)("h2",{id:"a-note-about-gas-price"},"A Note about Gas Price"),(0,r.kt)("p",null,'A common question frequently arises: "How do I know what the payment amount (gas cost) should be?"'),(0,r.kt)("p",null,"We recommend installing your contracts in a test environment, making sure the cost tables match those of the production Casper network to which you want to send the deploy. If you plan on sending a deploy to ",(0,r.kt)("a",{parentName:"p",href:"https://cspr.live/"},"Mainnet"),", you can use the ",(0,r.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/"},"Testnet")," to estimate the payment amount needed for the deploy."),(0,r.kt)("p",null,"If your test configuration matches your production ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),", you can check the deploy status and roughly see how much it would cost. You can estimate the costs in this way and then add a small buffer to be sure. Refer to the ",(0,r.kt)("a",{parentName:"p",href:"/runtime#gas-allocation"},"runtime economics")," section for more details about gas usage and fees."),(0,r.kt)("p",null,"Please be aware that sending a deploy always requires payment. This is true regardless of the validity of included Wasm."),(0,r.kt)("p",null,"If the deploy failure occurs after session execution begins, the penalty payment of 2.5 CSPR is included in the gas costs of the ",(0,r.kt)("a",{parentName:"p",href:"/concepts/serialization-standard#executionresult-executionresult"},"failed execution"),"."),(0,r.kt)("p",null,"However, if the failure occurs prior to session execution, the penalty payment will not appear within the gas cost of the deploy. Instead, the system automatically deducts the 2.5 CSPR from the sending account's main purse."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b161625a.b3b21cd9.js b/assets/js/b161625a.f9076dec.js similarity index 99% rename from assets/js/b161625a.b3b21cd9.js rename to assets/js/b161625a.f9076dec.js index 23f81f814e..8b31d5f051 100644 --- a/assets/js/b161625a.b3b21cd9.js +++ b/assets/js/b161625a.f9076dec.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[420],{3905:function(e,t,n){n.d(t,{Zo:function(){return d},kt:function(){return m}});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=l(n),h=r,m=p["".concat(c,".").concat(h)]||p[h]||u[h]||a;return n?o.createElement(m,i(i({ref:t},d),{},{components:n})):o.createElement(m,i({ref:t},d))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=l(n),h=r,m=p["".concat(c,".").concat(h)]||p[h]||u[h]||a;return n?o.createElement(m,i(i({ref:t},d),{},{components:n})):o.createElement(m,i({ref:t},d))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var l=2;l=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=l(n),h=a,m=u["".concat(c,".").concat(h)]||u[h]||d[h]||r;return n?o.createElement(m,s(s({ref:t},p),{},{components:n})):o.createElement(m,s({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,s=new Array(r);s[0]=h;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:a,s[1]=i;for(var l=2;l=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=l(n),h=a,m=u["".concat(c,".").concat(h)]||u[h]||d[h]||r;return n?o.createElement(m,s(s({ref:t},p),{},{components:n})):o.createElement(m,s({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,s=new Array(r);s[0]=h;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:a,s[1]=i;for(var l=2;l=0||(r[e]=t[e]);return r}(t,a);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,e)&&(r[e]=t[e])}return r}var s=n.createContext({}),m=function(t){var a=n.useContext(s),e=a;return t&&(e="function"==typeof t?t(a):p(p({},a),t)),e},d=function(t){var a=m(t.components);return n.createElement(s.Provider,{value:a},t.children)},o="mdxType",u={inlineCode:"code",wrapper:function(t){var a=t.children;return n.createElement(n.Fragment,{},a)}},k=n.forwardRef((function(t,a){var e=t.components,r=t.mdxType,l=t.originalType,s=t.parentName,d=i(t,["components","mdxType","originalType","parentName"]),o=m(e),k=r,c=o["".concat(s,".").concat(k)]||o[k]||u[k]||l;return e?n.createElement(c,p(p({ref:a},d),{},{components:e})):n.createElement(c,p({ref:a},d))}));function c(t,a){var e=arguments,r=a&&a.mdxType;if("string"==typeof t||r){var l=e.length,p=new Array(l);p[0]=k;var i={};for(var s in a)hasOwnProperty.call(a,s)&&(i[s]=a[s]);i.originalType=t,i[o]="string"==typeof t?t:r,p[1]=i;for(var m=2;m=0||(r[e]=t[e]);return r}(t,a);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,e)&&(r[e]=t[e])}return r}var s=n.createContext({}),m=function(t){var a=n.useContext(s),e=a;return t&&(e="function"==typeof t?t(a):p(p({},a),t)),e},d=function(t){var a=m(t.components);return n.createElement(s.Provider,{value:a},t.children)},o="mdxType",u={inlineCode:"code",wrapper:function(t){var a=t.children;return n.createElement(n.Fragment,{},a)}},k=n.forwardRef((function(t,a){var e=t.components,r=t.mdxType,l=t.originalType,s=t.parentName,d=i(t,["components","mdxType","originalType","parentName"]),o=m(e),k=r,c=o["".concat(s,".").concat(k)]||o[k]||u[k]||l;return e?n.createElement(c,p(p({ref:a},d),{},{components:e})):n.createElement(c,p({ref:a},d))}));function c(t,a){var e=arguments,r=a&&a.mdxType;if("string"==typeof t||r){var l=e.length,p=new Array(l);p[0]=k;var i={};for(var s in a)hasOwnProperty.call(a,s)&&(i[s]=a[s]);i.originalType=t,i[o]="string"==typeof t?t:r,p[1]=i;for(var m=2;m=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),d=p(a),m=r,y=d["".concat(s,".").concat(m)]||d[m]||u[m]||l;return a?n.createElement(y,i(i({ref:t},c),{},{components:a})):n.createElement(y,i({ref:t},c))}));function y(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=a.length,i=new Array(l);i[0]=m;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[d]="string"==typeof e?e:r,i[1]=o;for(var p=2;p=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),d=p(a),m=r,y=d["".concat(s,".").concat(m)]||d[m]||u[m]||l;return a?n.createElement(y,i(i({ref:t},c),{},{components:a})):n.createElement(y,i({ref:t},c))}));function y(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=a.length,i=new Array(l);i[0]=m;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[d]="string"==typeof e?e:r,i[1]=o;for(var p=2;p=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,h=u["".concat(c,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(h,s(s({ref:t},p),{},{components:n})):r.createElement(h,s({ref:t},p))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=m;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:a,s[1]=i;for(var l=2;lCargo.toml",id:"dependencies-in-cargotoml",level:3},{value:"Updating the main.rs File",id:"updating-the-mainrs-file",level:3},{value:"Example 2: Calling a Contract with Session Code",id:"calling-contracts-with-session-code",level:2},{value:"Example 3: Transfers using Session Code",id:"transfers-using-session-code",level:2},{value:"Compiling Session Code",id:"compiling-session-code",level:2},{value:"Executing Session Code",id:"executing-session-code",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}],d={toc:u},m="wrapper";function h(e){var t=e.components,n=(0,a.Z)(e,s);return(0,o.kt)(m,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"writing-session-code"},"Writing Session Code"),(0,o.kt)("p",null,"This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code"},"Comparing Session Code and Contract Code"),". Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust."),(0,o.kt)("h2",{id:"directory-structure"},"Creating the Directory Structure"),(0,o.kt)("p",null,"For writing session code, we use the same project structure used for writing contracts, described ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/simple-contract#directory-structure"},"here"),"."),(0,o.kt)("h2",{id:"writing-session-code"},"Example 1: Writing Session Code"),(0,o.kt)("p",null,"The following steps illustrate the process of writing session code using an example repository containing sample session code for configuring an account: ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/two-party-multi-sig/"},"https://github.com/casper-ecosystem/two-party-multi-sig/"),". The sample code adds an associated key to the account and updates the action thresholds. Remember that an ",(0,o.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-head"},"Account")," on a Casper network can add associated accounts and set up a multi-signature scheme for deploys. To follow along, clone the repository."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/casper-ecosystem/two-party-multi-sig/\n")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Before executing session code, ensure that you know exactly what the session code is doing. If you don't know what it is meant for, it could be doing something malicious.")),(0,o.kt)("h3",{id:"dependencies-in-cargotoml"},"Dependencies in ",(0,o.kt)("inlineCode",{parentName:"h3"},"Cargo.toml")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file includes the dependencies and versions the session code requires. At a minimum, you need to import the latest versions of the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/"},"casper-contract")," and ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/"},"casper-types")," crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},'casper-contract = "1.4.4"')," - Provides the SDK for the execution engine (EE). The latest version of the crate is published ",(0,o.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-contract"},"here"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},'casper-types = "1.5.0"')," - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published ",(0,o.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-types"},"here"),".")),(0,o.kt)("h3",{id:"updating-the-mainrs-file"},"Updating the ",(0,o.kt)("inlineCode",{parentName:"h3"},"main.rs")," File"),(0,o.kt)("p",null,"Open the ",(0,o.kt)("inlineCode",{parentName:"p"},"contract/src/main.rs")," file that contains the sample session code. Notice these directives at the top of the file:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"#![no_std]")," - Specifies not to import the standard library."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"#![no_main]")," - Indicates the ",(0,o.kt)("inlineCode",{parentName:"li"},"main")," function is not required since the session code has only one entry point as the ",(0,o.kt)("inlineCode",{parentName:"li"},"call")," function.")),(0,o.kt)("p",null,"Next, review the imported crates and other required libraries."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"#![no_std]\n#![no_main]\n\nuse casper_contract::contract_api::{account, runtime};\nuse casper_contract::unwrap_or_revert::UnwrapOrRevert;\nuse casper_types::account::{AccountHash, ActionType, Weight};\n")),(0,o.kt)("p",null,"After the imported libraries, we usually find the constants."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'const ASSOCIATED_ACCOUNT: &str = "deployment-account";\n')),(0,o.kt)("p",null,"Next, we see the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function, the only entry point in this example session code. The ",(0,o.kt)("inlineCode",{parentName:"p"},"#[no_mangle]")," flag ensures that the function name is retained as a string in the Wasm binary. For session code, this flag retains the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," string and marks the entry point for the execution engine. Explore the call function details by opening the cloned project."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn call() {\n // Open the repository for details\n}\n')),(0,o.kt)("p",null,"When compiled, the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function could be used from another library. For example, a C library could link to the resulting Wasm."),(0,o.kt)("h2",{id:"calling-contracts-with-session-code"},"Example 2: Calling a Contract with Session Code"),(0,o.kt)("p",null,"Another example of session code is the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/blob/master/counter-call/src/main.rs"},"counter-call/src/main.rs")," file, in the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter"},"counter")," repository. This example shows how we commonly use session code to invoke logic stored within a smart contract. To follow along, clone the repository."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/casper-ecosystem/counter/\n")),(0,o.kt)("p",null,"Observe how the project is set up and review the dependencies in the ",(0,o.kt)("inlineCode",{parentName:"p"},"counter/counter-call/Cargo.toml")," file. Then, open the ",(0,o.kt)("inlineCode",{parentName:"p"},"counter/counter-call/src/main.rs")," file containing the session code. Notice the directives at the top of the file, the required dependencies, and the declared constants."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function interacts with the contract's ",(0,o.kt)("inlineCode",{parentName:"p"},"counter_inc")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"counter_get")," entry points. This is how the session's ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," entry point triggers the logic stored inside the counter contract."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"}," // Call the counter to get the current value.\n let current_counter_value: u32 =\n runtime::call_contract(contract_hash, COUNTER_GET, RuntimeArgs::new());\n\n // Call the counter to increment the value.\n let _: () = runtime::call_contract(contract_hash, COUNTER_INC, RuntimeArgs::new());\n")),(0,o.kt)("h2",{id:"transfers-using-session-code"},"Example 3: Transfers using Session Code"),(0,o.kt)("p",null,"In this example, we use session code to perform a transfer using the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_purse.html"},"transfer_from_purse_to_purse")," system function. The entire session code is available in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/67c9c9bb84fdfc3f2d12103e25f0058104342bc0/smart_contracts/contracts/bench/transfer-to-purse/src/main.rs#L14"},"GitHub"),", but this is the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn call() {\n let target_purse: URef = runtime::get_named_arg(ARG_TARGET_PURSE);\n let amount: U512 = runtime::get_named_arg(ARG_AMOUNT);\n\n let source_purse = account::get_main_purse();\n\n system::transfer_from_purse_to_purse(source_purse, target_purse, amount, None)\n .unwrap_or_revert();\n}\n')),(0,o.kt)("p",null,"Another system function is ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_public_key.html"},"transfer_to_public_key"),". The full session code example is on ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/67c9c9bb84fdfc3f2d12103e25f0058104342bc0/smart_contracts/contracts/client/transfer-to-public-key/src/main.rs#L16"},"GitHub"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn call() {\n let account_hash: PublicKey = runtime::get_named_arg(ARG_TARGET);\n let transfer_amount: U512 = runtime::get_named_arg(ARG_AMOUNT);\n system::transfer_to_public_key(account_hash, transfer_amount, None).unwrap_or_revert();\n}\n')),(0,o.kt)("p",null,"Other transfer functions are available here:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_account.html"},"transfer_to_account")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_account.html"},"transfer_from_purse_to_account")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_public_key.html"},"transfer_from_purse_to_public_key"))),(0,o.kt)("h2",{id:"compiling-session-code"},"Compiling Session Code"),(0,o.kt)("p",null,"Before running session code to interact with a contract or other entities on the network, you must compile it to Wasm. Run the following command in the directory hosting the ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file and ",(0,o.kt)("inlineCode",{parentName:"p"},"src")," folder."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cargo build --release --target wasm32-unknown-unknown\n")),(0,o.kt)("p",null,"For the examples above, you may use the Makefiles provided:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"make build-contract\n")),(0,o.kt)("h2",{id:"executing-session-code"},"Executing Session Code"),(0,o.kt)("p",null,"Before running session code on a live Casper network, test it as described ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/testing-session-code"},"here"),". You can also set up a local network using ",(0,o.kt)("a",{parentName:"p",href:"/developers/dapps/setup-nctl"},"NCTL")," for additional tests."),(0,o.kt)("p",null,"Session code can execute on a Casper network via a ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/D#deploy"},"Deploy"),". All deploys can be broadly categorized as some unit of work that, when executed and committed, affects change to the network's global state."),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"/developers/prerequisites#the-casper-command-line-client"},"Casper command-line client")," and its ",(0,o.kt)("inlineCode",{parentName:"p"},"put-deploy")," command provide one way to execute session code."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy \\\n --node-address \\\n --chain-name \\\n --secret-key \\\n --payment-amount \\\n --session-path \\\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n')),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the deploy."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"chain-name")," - The network where the deploy should be sent. For Mainnet, use ",(0,o.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,o.kt)("em",{parentName:"li"},"casper-test"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"payment-amount")," - Payment for the deploy in motes. The payment amount varies based on the deploy and network ",(0,o.kt)("a",{parentName:"li",href:"/concepts/glossary/C#chainspec"},"chainspec"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"session-path")," - Path to the contract Wasm, pointing to the compiled contract."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"session-arg")," - A named and typed argument passed to the Wasm code.")),(0,o.kt)("p",null,"Use the ",(0,o.kt)("inlineCode",{parentName:"p"},"--help")," option to view an updated list of supported arguments."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy --help\n")),(0,o.kt)("h2",{id:"video-walkthrough"},"Video Walkthrough"),(0,o.kt)("p",null,"The following brief video describes ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/two-party-multi-sig/"},"sample session code")," for configuring an account."),(0,o.kt)("p",{align:"center"},(0,o.kt)("iframe",{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=4",frameborder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:!0})),(0,o.kt)("h2",{id:"whats-next"},"What's Next?"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Learn to ",(0,o.kt)("a",{parentName:"li",href:"/developers/writing-onchain-code/testing-session-code"},"test session code")," using the Casper testing framework.")))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[9352],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return h}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,h=u["".concat(c,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(h,s(s({ref:t},p),{},{components:n})):r.createElement(h,s({ref:t},p))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=m;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:a,s[1]=i;for(var l=2;lCargo.toml",id:"dependencies-in-cargotoml",level:3},{value:"Updating the main.rs File",id:"updating-the-mainrs-file",level:3},{value:"Example 2: Calling a Contract with Session Code",id:"calling-contracts-with-session-code",level:2},{value:"Example 3: Transfers using Session Code",id:"transfers-using-session-code",level:2},{value:"Compiling Session Code",id:"compiling-session-code",level:2},{value:"Executing Session Code",id:"executing-session-code",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}],d={toc:u},m="wrapper";function h(e){var t=e.components,n=(0,a.Z)(e,s);return(0,o.kt)(m,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"writing-session-code"},"Writing Session Code"),(0,o.kt)("p",null,"This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code"},"Comparing Session Code and Contract Code"),". Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust."),(0,o.kt)("h2",{id:"directory-structure"},"Creating the Directory Structure"),(0,o.kt)("p",null,"For writing session code, we use the same project structure used for writing contracts, described ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/simple-contract#directory-structure"},"here"),"."),(0,o.kt)("h2",{id:"writing-session-code"},"Example 1: Writing Session Code"),(0,o.kt)("p",null,"The following steps illustrate the process of writing session code using an example repository containing sample session code for configuring an account: ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/two-party-multi-sig/"},"https://github.com/casper-ecosystem/two-party-multi-sig/"),". The sample code adds an associated key to the account and updates the action thresholds. Remember that an ",(0,o.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-head"},"Account")," on a Casper network can add associated accounts and set up a multi-signature scheme for deploys. To follow along, clone the repository."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/casper-ecosystem/two-party-multi-sig/\n")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Before executing session code, ensure that you know exactly what the session code is doing. If you don't know what it is meant for, it could be doing something malicious.")),(0,o.kt)("h3",{id:"dependencies-in-cargotoml"},"Dependencies in ",(0,o.kt)("inlineCode",{parentName:"h3"},"Cargo.toml")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file includes the dependencies and versions the session code requires. At a minimum, you need to import the latest versions of the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/"},"casper-contract")," and ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-types/latest/casper_types/"},"casper-types")," crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},'casper-contract = "1.4.4"')," - Provides the SDK for the execution engine (EE). The latest version of the crate is published ",(0,o.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-contract"},"here"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},'casper-types = "1.5.0"')," - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published ",(0,o.kt)("a",{parentName:"li",href:"https://crates.io/crates/casper-types"},"here"),".")),(0,o.kt)("h3",{id:"updating-the-mainrs-file"},"Updating the ",(0,o.kt)("inlineCode",{parentName:"h3"},"main.rs")," File"),(0,o.kt)("p",null,"Open the ",(0,o.kt)("inlineCode",{parentName:"p"},"contract/src/main.rs")," file that contains the sample session code. Notice these directives at the top of the file:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"#![no_std]")," - Specifies not to import the standard library."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"#![no_main]")," - Indicates the ",(0,o.kt)("inlineCode",{parentName:"li"},"main")," function is not required since the session code has only one entry point as the ",(0,o.kt)("inlineCode",{parentName:"li"},"call")," function.")),(0,o.kt)("p",null,"Next, review the imported crates and other required libraries."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"#![no_std]\n#![no_main]\n\nuse casper_contract::contract_api::{account, runtime};\nuse casper_contract::unwrap_or_revert::UnwrapOrRevert;\nuse casper_types::account::{AccountHash, ActionType, Weight};\n")),(0,o.kt)("p",null,"After the imported libraries, we usually find the constants."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'const ASSOCIATED_ACCOUNT: &str = "deployment-account";\n')),(0,o.kt)("p",null,"Next, we see the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function, the only entry point in this example session code. The ",(0,o.kt)("inlineCode",{parentName:"p"},"#[no_mangle]")," flag ensures that the function name is retained as a string in the Wasm binary. For session code, this flag retains the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," string and marks the entry point for the execution engine. Explore the call function details by opening the cloned project."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn call() {\n // Open the repository for details\n}\n')),(0,o.kt)("p",null,"When compiled, the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function could be used from another library. For example, a C library could link to the resulting Wasm."),(0,o.kt)("h2",{id:"calling-contracts-with-session-code"},"Example 2: Calling a Contract with Session Code"),(0,o.kt)("p",null,"Another example of session code is the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter/blob/master/counter-call/src/main.rs"},"counter-call/src/main.rs")," file, in the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/counter"},"counter")," repository. This example shows how we commonly use session code to invoke logic stored within a smart contract. To follow along, clone the repository."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/casper-ecosystem/counter/\n")),(0,o.kt)("p",null,"Observe how the project is set up and review the dependencies in the ",(0,o.kt)("inlineCode",{parentName:"p"},"counter/counter-call/Cargo.toml")," file. Then, open the ",(0,o.kt)("inlineCode",{parentName:"p"},"counter/counter-call/src/main.rs")," file containing the session code. Notice the directives at the top of the file, the required dependencies, and the declared constants."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function interacts with the contract's ",(0,o.kt)("inlineCode",{parentName:"p"},"counter_inc")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"counter_get")," entry points. This is how the session's ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," entry point triggers the logic stored inside the counter contract."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"}," // Call the counter to get the current value.\n let current_counter_value: u32 =\n runtime::call_contract(contract_hash, COUNTER_GET, RuntimeArgs::new());\n\n // Call the counter to increment the value.\n let _: () = runtime::call_contract(contract_hash, COUNTER_INC, RuntimeArgs::new());\n")),(0,o.kt)("h2",{id:"transfers-using-session-code"},"Example 3: Transfers using Session Code"),(0,o.kt)("p",null,"In this example, we use session code to perform a transfer using the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_purse.html"},"transfer_from_purse_to_purse")," system function. The entire session code is available in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/67c9c9bb84fdfc3f2d12103e25f0058104342bc0/smart_contracts/contracts/bench/transfer-to-purse/src/main.rs#L14"},"GitHub"),", but this is the ",(0,o.kt)("inlineCode",{parentName:"p"},"call")," function:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn call() {\n let target_purse: URef = runtime::get_named_arg(ARG_TARGET_PURSE);\n let amount: U512 = runtime::get_named_arg(ARG_AMOUNT);\n\n let source_purse = account::get_main_purse();\n\n system::transfer_from_purse_to_purse(source_purse, target_purse, amount, None)\n .unwrap_or_revert();\n}\n')),(0,o.kt)("p",null,"Another system function is ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_public_key.html"},"transfer_to_public_key"),". The full session code example is on ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/67c9c9bb84fdfc3f2d12103e25f0058104342bc0/smart_contracts/contracts/client/transfer-to-public-key/src/main.rs#L16"},"GitHub"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},'#[no_mangle]\npub extern "C" fn call() {\n let account_hash: PublicKey = runtime::get_named_arg(ARG_TARGET);\n let transfer_amount: U512 = runtime::get_named_arg(ARG_AMOUNT);\n system::transfer_to_public_key(account_hash, transfer_amount, None).unwrap_or_revert();\n}\n')),(0,o.kt)("p",null,"Other transfer functions are available here:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_account.html"},"transfer_to_account")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_account.html"},"transfer_from_purse_to_account")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_public_key.html"},"transfer_from_purse_to_public_key"))),(0,o.kt)("h2",{id:"compiling-session-code"},"Compiling Session Code"),(0,o.kt)("p",null,"Before running session code to interact with a contract or other entities on the network, you must compile it to Wasm. Run the following command in the directory hosting the ",(0,o.kt)("inlineCode",{parentName:"p"},"Cargo.toml")," file and ",(0,o.kt)("inlineCode",{parentName:"p"},"src")," folder."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cargo build --release --target wasm32-unknown-unknown\n")),(0,o.kt)("p",null,"For the examples above, you may use the Makefiles provided:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"make build-contract\n")),(0,o.kt)("h2",{id:"executing-session-code"},"Executing Session Code"),(0,o.kt)("p",null,"Before running session code on a live Casper network, test it as described ",(0,o.kt)("a",{parentName:"p",href:"/developers/writing-onchain-code/testing-session-code"},"here"),". You can also set up a local network using ",(0,o.kt)("a",{parentName:"p",href:"/developers/dapps/setup-nctl"},"NCTL")," for additional tests."),(0,o.kt)("p",null,"Session code can execute on a Casper network via a ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/D#deploy"},"Deploy"),". All deploys can be broadly categorized as some unit of work that, when executed and committed, affects change to the network's global state."),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"/developers/prerequisites#the-casper-command-line-client"},"Casper command-line client")," and its ",(0,o.kt)("inlineCode",{parentName:"p"},"put-deploy")," command provide one way to execute session code."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy \\\n --node-address \\\n --chain-name \\\n --secret-key \\\n --payment-amount \\\n --session-path \\\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n')),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the deploy."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"chain-name")," - The network where the deploy should be sent. For Mainnet, use ",(0,o.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,o.kt)("em",{parentName:"li"},"casper-test"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"payment-amount")," - Payment for the deploy in motes. The payment amount varies based on the deploy and network ",(0,o.kt)("a",{parentName:"li",href:"/concepts/glossary/C#chainspec"},"chainspec"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"session-path")," - Path to the contract Wasm, pointing to the compiled contract."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"session-arg")," - A named and typed argument passed to the Wasm code.")),(0,o.kt)("p",null,"Use the ",(0,o.kt)("inlineCode",{parentName:"p"},"--help")," option to view an updated list of supported arguments."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy --help\n")),(0,o.kt)("h2",{id:"video-walkthrough"},"Video Walkthrough"),(0,o.kt)("p",null,"The following brief video describes ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/casper-ecosystem/two-party-multi-sig/"},"sample session code")," for configuring an account."),(0,o.kt)("p",{align:"center"},(0,o.kt)("iframe",{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=4",frameborder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:!0})),(0,o.kt)("h2",{id:"whats-next"},"What's Next?"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Learn to ",(0,o.kt)("a",{parentName:"li",href:"/developers/writing-onchain-code/testing-session-code"},"test session code")," using the Casper testing framework.")))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b643e154.6b17dc67.js b/assets/js/b643e154.2be4b603.js similarity index 98% rename from assets/js/b643e154.6b17dc67.js rename to assets/js/b643e154.2be4b603.js index e43a07854b..f10141cd5b 100644 --- a/assets/js/b643e154.6b17dc67.js +++ b/assets/js/b643e154.2be4b603.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6776],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return g}});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),h=o,g=u["".concat(l,".").concat(h)]||u[h]||d[h]||i;return n?a.createElement(g,r(r({ref:t},p),{},{components:n})):a.createElement(g,r({ref:t},p))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:o,r[1]=s;for(var c=2;c=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),h=o,g=u["".concat(l,".").concat(h)]||u[h]||d[h]||i;return n?a.createElement(g,r(r({ref:t},p),{},{components:n})):a.createElement(g,r({ref:t},p))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:o,r[1]=s;for(var c=2;c=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},u="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=p(n),m=r,h=u["".concat(l,".").concat(m)]||u[m]||c[m]||o;return n?a.createElement(h,s(s({ref:t},d),{},{components:n})):a.createElement(h,s({ref:t},d))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:r,s[1]=i;for(var p=2;p:8888/metrics\n")),(0,o.kt)("p",null,"You can check the node's status using this command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s http://:8888/status\n")),(0,o.kt)("p",null,"The status endpoint provides a JSON response that can be parsed with ",(0,o.kt)("inlineCode",{parentName:"p"},"jq"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s http://:8888/status | jq\n")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Sample response"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "api_version": "1.4.15",\n "chainspec_name": "casper-test",\n "starting_state_root_hash": "4c3856bd6a95b566301b9da61aaf84589a51ee2980f3cc7bbef78e7745386955",\n "peers": [\n {\n "node_id": "tls:007e..e14b",\n "address": "89.58.52.245:35000"\n },\n {\n "node_id": "tls:00eb..ac11",\n "address": "65.109.17.120:35000"\n },\n ...{\n "node_id": "tls:ffc0..555b",\n "address": "95.217.228.224:35000"\n }\n ],\n "last_added_block_info": {\n "hash": "7acd2f48b573704e96eab54322f7e91a0624252baca3583ad2aae38229fe1715",\n "timestamp": "2023-05-10T09:20:10.752Z",\n "era_id": 9085,\n "height": 1711254,\n "state_root_hash": "1ac74071c1e76937c372c8d2ae22ea036a77578aad03821ec98021fdc1c5d06b",\n "creator": "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca"\n },\n "our_public_signing_key": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e",\n "round_length": "32s 768ms",\n "next_upgrade": null,\n "build_version": "1.4.15-039d438f2-casper-mainnet",\n "uptime": "5days 13h 46m 54s 520ms"\n}\n'))),(0,o.kt)("p",null,"You can filter the result with dot notation, specifying one of the following parameters:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"api_version")," - The RPC API version"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"chainspec_name")," - The chainspec name, used to identify the currently connected network"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"starting_state_root_hash")," - The state root hash used at the start of the current session"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"peers")," - The node ID and network address of each connected peer"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"last_added_block_info")," - The minimal info of the last Block from the linear chain"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"our_public_signing_key")," - Our public signing key"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"round_length")," - The next round length if this node is a validator."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"next_upgrade")," - Information about the next scheduled upgrade"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"build_version")," - The compiled node version"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"uptime")," - Time that has passed since the node has started.")),(0,o.kt)("p",null,"Here is an example command for retrieving general network information:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s http://:8888/status | jq -r '.api_version, .last_added_block_info, .build_version, .uptime'\n")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Sample response"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'"1.4.15"\n{\n "hash": "dca9959b21df52633f85cd373a8117fe8e89629dd2a0455781484a439f7d9f62",\n "timestamp": "2023-05-10T09:26:43.968Z",\n "era_id": 9085,\n "height": 1711266,\n "state_root_hash": "5f374529e747a06ec825e07a030df7b9d80d1f7ffac9156779b4466620721872",\n "creator": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e"\n}\n"1.4.15-039d438f2-casper-mainnet"\n"5days 13h 53m 10s 763ms"\n'))),(0,o.kt)("p",null,"To get information about the next upgrade, use:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s http://:8888/status | jq .next_upgrade\n")),(0,o.kt)("p",null,"To get information about the last added block, use:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s http://:8888/status | jq .last_added_block_info\n")),(0,o.kt)("p",null,"To monitor the downloading of blocks to your node:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"watch -n 15 'curl -s http://:8888/status | jq \".peers | length\"; curl -s http://:8888/status | jq .last_added_block_info'\n")),(0,o.kt)("p",null,"To monitor local block height as well as RPC port status:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"watch -n 15 'curl -s http://:8888/status | jq \".peers | length\"; curl -s http://:8888/status | jq .last_added_block_info; casper-client get-block -n http://:8888/status'\n")),(0,o.kt)("h2",{id:"9999"},"Default SSE HTTP Event Stream Server Port: 9999"),(0,o.kt)("p",null,"The configuration options for the SSE HTTP event stream server are listed under the ",(0,o.kt)("inlineCode",{parentName:"p"},"event_stream_server")," section of the ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," file. The ",(0,o.kt)("inlineCode",{parentName:"p"},"address")," listing port 9999 is the listening address for the SSE HTTP event stream server."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-md"},"address = '0.0.0.0:9999'\n")),(0,o.kt)("p",null,"If this port is closed, the requests coming to this port will not be served, but the node remains unaffected. For details and useful commands, see ",(0,o.kt)("a",{parentName:"p",href:"/developers/dapps/monitor-and-consume-events"},"Monitoring and Consuming Events"),"."),(0,o.kt)("h2",{id:"setting-up-firewall-rules"},"Setting up Firewall Rules"),(0,o.kt)("p",null,"To limit inbound traffic to the node\u2019s endpoints, you can set firewall rules similar to the ",(0,o.kt)("inlineCode",{parentName:"p"},"ufw")," commands below:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt install ufw -y\nsudo ufw disable\nsudo ufw reset\nsudo ufw default allow outgoing\nsudo ufw default deny incoming\nsudo ufw limit ssh\nsudo ufw limit 7777/tcp\nsudo ufw limit 8888/tcp\nsudo ufw limit 35000/tcp\nsudo ufw enable\n")),(0,o.kt)("p",null,"These commands will limit requests to the available ports of your node. Port 35000 should be left open, although you can limit traffic, as it is crucial for node-to-node communication."),(0,o.kt)("p",null,"If you have any concerns, questions, or issues, please ",(0,o.kt)("a",{parentName:"p",href:"https://support.casperlabs.io/hc/en-gb/requests/new"},"submit a request")," to the Casper support team."),(0,o.kt)("h2",{id:"restricting-access-for-private-networks"},"Restricting Access for Private Networks"),(0,o.kt)("p",null,"Any node can join Mainnet and Testnet and communicate with the nodes in the network. Private networks may wish to restrict access for new nodes joining the network as described ",(0,o.kt)("a",{parentName:"p",href:"/operators/setup-network/create-private#network-access-control"},"here"),"."),(0,o.kt)("h2",{id:"summary-of-related-links"},"Summary of Related Links"),(0,o.kt)("p",null,"Here is a summary of the links mentioned on this page:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/operators/setup/install-node#network-requirements"},"Network requirements")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/concepts/design/p2p"},"Network communication")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/operators/setup/basic-node-configuration#config-file"},"The node configuration file")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developers/json-rpc/"},"Interacting with the Casper JSON-RPC API")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developers/cli/"},"Interacting with the network using CLI")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/operators/becoming-a-validator/bonding#example-bonding-transaction"},"Bonding")," or ",(0,o.kt)("a",{parentName:"li",href:"/operators/becoming-a-validator/unbonding"},"unbonding")," as a validator"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing"},"Getting a trusted node hash")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/operators/setup/upgrade#verifying-successful-staging"},"Verifying successful staging")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/operators/setup/joining#step-7-confirm-the-node-is-synchronized"},"Confirming that the node is synchronized")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developers/dapps/monitor-and-consume-events"},"Monitoring and consuming events")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/operators/setup-network/create-private#network-access-control"},"Private network access control")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://support.casperlabs.io/hc/en-gb/sections/6960448246683-Node-Operation-FAQ"},"FAQs for a basic validator node ")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.cspr.community/docs/faq-validator.html"},"External FAQs on Mainnet and Testnet validator node setup"))))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[1942],{3905:function(e,t,n){n.d(t,{Zo:function(){return d},kt:function(){return h}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},u="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=p(n),m=r,h=u["".concat(l,".").concat(m)]||u[m]||c[m]||o;return n?a.createElement(h,s(s({ref:t},d),{},{components:n})):a.createElement(h,s({ref:t},d))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:r,s[1]=i;for(var p=2;p:8888/metrics\n")),(0,o.kt)("p",null,"You can check the node's status using this command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s http://:8888/status\n")),(0,o.kt)("p",null,"The status endpoint provides a JSON response that can be parsed with ",(0,o.kt)("inlineCode",{parentName:"p"},"jq"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s http://:8888/status | jq\n")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Sample response"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "api_version": "1.4.15",\n "chainspec_name": "casper-test",\n "starting_state_root_hash": "4c3856bd6a95b566301b9da61aaf84589a51ee2980f3cc7bbef78e7745386955",\n "peers": [\n {\n "node_id": "tls:007e..e14b",\n "address": "89.58.52.245:35000"\n },\n {\n "node_id": "tls:00eb..ac11",\n "address": "65.109.17.120:35000"\n },\n ...{\n "node_id": "tls:ffc0..555b",\n "address": "95.217.228.224:35000"\n }\n ],\n "last_added_block_info": {\n "hash": "7acd2f48b573704e96eab54322f7e91a0624252baca3583ad2aae38229fe1715",\n "timestamp": "2023-05-10T09:20:10.752Z",\n "era_id": 9085,\n "height": 1711254,\n "state_root_hash": "1ac74071c1e76937c372c8d2ae22ea036a77578aad03821ec98021fdc1c5d06b",\n "creator": "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca"\n },\n "our_public_signing_key": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e",\n "round_length": "32s 768ms",\n "next_upgrade": null,\n "build_version": "1.4.15-039d438f2-casper-mainnet",\n "uptime": "5days 13h 46m 54s 520ms"\n}\n'))),(0,o.kt)("p",null,"You can filter the result with dot notation, specifying one of the following parameters:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"api_version")," - The RPC API version"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"chainspec_name")," - The chainspec name, used to identify the currently connected network"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"starting_state_root_hash")," - The state root hash used at the start of the current session"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"peers")," - The node ID and network address of each connected peer"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"last_added_block_info")," - The minimal info of the last Block from the linear chain"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"our_public_signing_key")," - Our public signing key"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"round_length")," - The next round length if this node is a validator."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"next_upgrade")," - Information about the next scheduled upgrade"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"build_version")," - The compiled node version"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"uptime")," - Time that has passed since the node has started.")),(0,o.kt)("p",null,"Here is an example command for retrieving general network information:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s http://:8888/status | jq -r '.api_version, .last_added_block_info, .build_version, .uptime'\n")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Sample response"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'"1.4.15"\n{\n "hash": "dca9959b21df52633f85cd373a8117fe8e89629dd2a0455781484a439f7d9f62",\n "timestamp": "2023-05-10T09:26:43.968Z",\n "era_id": 9085,\n "height": 1711266,\n "state_root_hash": "5f374529e747a06ec825e07a030df7b9d80d1f7ffac9156779b4466620721872",\n "creator": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e"\n}\n"1.4.15-039d438f2-casper-mainnet"\n"5days 13h 53m 10s 763ms"\n'))),(0,o.kt)("p",null,"To get information about the next upgrade, use:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s http://:8888/status | jq .next_upgrade\n")),(0,o.kt)("p",null,"To get information about the last added block, use:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"curl -s http://:8888/status | jq .last_added_block_info\n")),(0,o.kt)("p",null,"To monitor the downloading of blocks to your node:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"watch -n 15 'curl -s http://:8888/status | jq \".peers | length\"; curl -s http://:8888/status | jq .last_added_block_info'\n")),(0,o.kt)("p",null,"To monitor local block height as well as RPC port status:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"watch -n 15 'curl -s http://:8888/status | jq \".peers | length\"; curl -s http://:8888/status | jq .last_added_block_info; casper-client get-block -n http://:8888/status'\n")),(0,o.kt)("h2",{id:"9999"},"Default SSE HTTP Event Stream Server Port: 9999"),(0,o.kt)("p",null,"The configuration options for the SSE HTTP event stream server are listed under the ",(0,o.kt)("inlineCode",{parentName:"p"},"event_stream_server")," section of the ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," file. The ",(0,o.kt)("inlineCode",{parentName:"p"},"address")," listing port 9999 is the listening address for the SSE HTTP event stream server."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-md"},"address = '0.0.0.0:9999'\n")),(0,o.kt)("p",null,"If this port is closed, the requests coming to this port will not be served, but the node remains unaffected. For details and useful commands, see ",(0,o.kt)("a",{parentName:"p",href:"/developers/dapps/monitor-and-consume-events"},"Monitoring and Consuming Events"),"."),(0,o.kt)("h2",{id:"setting-up-firewall-rules"},"Setting up Firewall Rules"),(0,o.kt)("p",null,"To limit inbound traffic to the node\u2019s endpoints, you can set firewall rules similar to the ",(0,o.kt)("inlineCode",{parentName:"p"},"ufw")," commands below:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt install ufw -y\nsudo ufw disable\nsudo ufw reset\nsudo ufw default allow outgoing\nsudo ufw default deny incoming\nsudo ufw limit ssh\nsudo ufw limit 7777/tcp\nsudo ufw limit 8888/tcp\nsudo ufw limit 35000/tcp\nsudo ufw enable\n")),(0,o.kt)("p",null,"These commands will limit requests to the available ports of your node. Port 35000 should be left open, although you can limit traffic, as it is crucial for node-to-node communication."),(0,o.kt)("p",null,"If you have any concerns, questions, or issues, please ",(0,o.kt)("a",{parentName:"p",href:"https://support.casperlabs.io/hc/en-gb/requests/new"},"submit a request")," to the Casper support team."),(0,o.kt)("h2",{id:"restricting-access-for-private-networks"},"Restricting Access for Private Networks"),(0,o.kt)("p",null,"Any node can join Mainnet and Testnet and communicate with the nodes in the network. Private networks may wish to restrict access for new nodes joining the network as described ",(0,o.kt)("a",{parentName:"p",href:"/operators/setup-network/create-private#network-access-control"},"here"),"."),(0,o.kt)("h2",{id:"summary-of-related-links"},"Summary of Related Links"),(0,o.kt)("p",null,"Here is a summary of the links mentioned on this page:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/operators/setup/install-node#network-requirements"},"Network requirements")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/concepts/design/p2p"},"Network communication")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/operators/setup/basic-node-configuration#config-file"},"The node configuration file")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developers/json-rpc/"},"Interacting with the Casper JSON-RPC API")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developers/cli/"},"Interacting with the network using CLI")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/operators/becoming-a-validator/bonding#example-bonding-transaction"},"Bonding")," or ",(0,o.kt)("a",{parentName:"li",href:"/operators/becoming-a-validator/unbonding"},"unbonding")," as a validator"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing"},"Getting a trusted node hash")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/operators/setup/upgrade#verifying-successful-staging"},"Verifying successful staging")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/operators/setup/joining#step-7-confirm-the-node-is-synchronized"},"Confirming that the node is synchronized")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developers/dapps/monitor-and-consume-events"},"Monitoring and consuming events")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/operators/setup-network/create-private#network-access-control"},"Private network access control")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://support.casperlabs.io/hc/en-gb/sections/6960448246683-Node-Operation-FAQ"},"FAQs for a basic validator node ")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.cspr.community/docs/faq-validator.html"},"External FAQs on Mainnet and Testnet validator node setup"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b9da5eb7.245a3758.js b/assets/js/b9da5eb7.2956c416.js similarity index 98% rename from assets/js/b9da5eb7.245a3758.js rename to assets/js/b9da5eb7.2956c416.js index 1939e21109..b7c495cfc9 100644 --- a/assets/js/b9da5eb7.245a3758.js +++ b/assets/js/b9da5eb7.2956c416.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[2733],{3905:function(e,t,a){a.d(t,{Zo:function(){return p},kt:function(){return m}});var r=a(7294);function o(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function n(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function s(e){for(var t=1;t=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var i=r.createContext({}),l=function(e){var t=r.useContext(i),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},p=function(e){var t=l(e.components);return r.createElement(i.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var a=e.components,o=e.mdxType,n=e.originalType,i=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),h=l(a),f=o,m=h["".concat(i,".").concat(f)]||h[f]||u[f]||n;return a?r.createElement(m,s(s({ref:t},p),{},{components:a})):r.createElement(m,s({ref:t},p))}));function m(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var n=a.length,s=new Array(n);s[0]=f;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c[h]="string"==typeof e?e:o,s[1]=c;for(var l=2;l=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var i=r.createContext({}),l=function(e){var t=r.useContext(i),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},p=function(e){var t=l(e.components);return r.createElement(i.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var a=e.components,o=e.mdxType,n=e.originalType,i=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),h=l(a),f=o,m=h["".concat(i,".").concat(f)]||h[f]||u[f]||n;return a?r.createElement(m,s(s({ref:t},p),{},{components:a})):r.createElement(m,s({ref:t},p))}));function m(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var n=a.length,s=new Array(n);s[0]=f;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c[h]="string"==typeof e?e:o,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(r),y=a,m=f["".concat(p,".").concat(y)]||f[y]||i[y]||o;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[f]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(r),y=a,m=f["".concat(p,".").concat(y)]||f[y]||i[y]||o;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[f]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),p=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},g=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),c=p(r),g=a,m=c["".concat(s,".").concat(g)]||c[g]||u[g]||i;return r?n.createElement(m,o(o({ref:t},d),{},{components:r})):n.createElement(m,o({ref:t},d))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=g;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:a,o[1]=l;for(var p=2;p=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),p=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},g=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),c=p(r),g=a,m=c["".concat(s,".").concat(g)]||c[g]||u[g]||i;return r?n.createElement(m,o(o({ref:t},d),{},{components:r})):n.createElement(m,o({ref:t},d))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=g;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:a,o[1]=l;for(var p=2;p=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},i="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),i=l(r),y=a,m=i["".concat(p,".").concat(y)]||i[y]||f[y]||o;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[i]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},i="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),i=l(r),y=a,m=i["".concat(p,".").concat(y)]||i[y]||f[y]||o;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=y;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[i]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},h=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},p=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,h=s(e,["components","mdxType","originalType","parentName"]),d=c(n),p=o,m=d["".concat(l,".").concat(p)]||d[p]||u[p]||i;return n?a.createElement(m,r(r({ref:t},h),{},{components:n})):a.createElement(m,r({ref:t},h))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=p;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:o,r[1]=s;for(var c=2;c=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},h=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},p=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,h=s(e,["components","mdxType","originalType","parentName"]),d=c(n),p=o,m=d["".concat(l,".").concat(p)]||d[p]||u[p]||i;return n?a.createElement(m,r(r({ref:t},h),{},{components:n})):a.createElement(m,r({ref:t},h))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=p;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:o,r[1]=s;for(var c=2;c=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},y=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),u=p(n),y=a,m=u["".concat(c,".").concat(y)]||u[y]||d[y]||s;return n?r.createElement(m,o(o({ref:t},l),{},{components:n})):r.createElement(m,o({ref:t},l))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=y;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:a,o[1]=i;for(var p=2;p {\n // Generating keys\n const edKeyPair = Keys.Ed25519.new();\n const { publicKey, privateKey } = edKeyPair;\n\n // Create a hexadecimal representation of the public key\n const accountAddress = publicKey.toHex();\n\n // Get the account hash (Uint8Array) from the public key\n const accountHash = publicKey.toAccountHash();\n\n // Store keys as PEM files\n const publicKeyInPem = edKeyPair.exportPublicKeyInPem();\n const privateKeyInPem = edKeyPair.exportPrivateKeyInPem();\n\n const folder = path.join("./", "casper_keys");\n\n if (!fs.existsSync(folder)) {\n const tempDir = fs.mkdirSync(folder);\n }\n\n fs.writeFileSync(folder + "/" + accountAddress + "_public.pem", publicKeyInPem);\n fs.writeFileSync(folder + "/" + accountAddress + "_private.pem", privateKeyInPem);\n\n return accountAddress;\n};\n\nconst newAccountAddress = createAccountKeys();\n')),(0,s.kt)("p",null,"After generating the keys with this code, you can add them to the ",(0,s.kt)("a",{parentName:"p",href:"https://www.casperwallet.io/"},"Casper Wallet Chrome extension")," and use them to sign your transactions."),(0,s.kt)("h3",{id:"sending-a-transfer"},"Sending a Transfer"),(0,s.kt)("p",null,"This code block shows you how to define and send a transfer on a Casper network. Replace the ",(0,s.kt)("inlineCode",{parentName:"p"},"sender-public-key")," and ",(0,s.kt)("inlineCode",{parentName:"p"},"recipient-public-key")," in the code below."),(0,s.kt)("p",null,"The ",(0,s.kt)("inlineCode",{parentName:"p"},"sendTransfer")," function below will return a ",(0,s.kt)("inlineCode",{parentName:"p"},"transfer-hash")," which you can check on ",(0,s.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/"},"https://testnet.cspr.live/"),"."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const fs = require("fs");\nconst path = require("path");\nconst axios = require("axios");\nconst casperClientSDK = require("casper-js-sdk");\n\nconst { Keys, CasperClient, CLPublicKey, DeployUtil } = require("casper-js-sdk");\n\nconst RPC_API = "http://159.65.203.12:7777/rpc";\nconst STATUS_API = "http://159.65.203.12:8888";\n\nconst sendTransfer = async ({ from, to, amount }) => {\n const casperClient = new CasperClient(RPC_API);\n\n const folder = path.join("./", "casper_keys");\n\n // Read keys from the structure created in #Generating keys\n const signKeyPair = Keys.Ed25519.parseKeyFiles(folder + "/" + from + "_public.pem", folder + "/" + from + "_private.pem");\n\n // networkName can be taken from the status api\n const response = await axios.get(STATUS_API + "/status");\n\n let networkName = null;\n\n if (response.status == 200) {\n networkName = response.data.chainspec_name;\n }\n\n // For native-transfers the payment price is fixed\n const paymentAmount = 100000000;\n\n // transfer_id field in the request to tag the transaction and to correlate it to your back-end storage\n const id = 187821;\n\n // gasPrice for native transfers can be set to 1\n const gasPrice = 1;\n\n // Time that the deploy will remain valid for, in milliseconds\n // The default value is 1800000 ms (30 minutes)\n const ttl = 1800000;\n\n let deployParams = new DeployUtil.DeployParams(signKeyPair.publicKey, networkName, gasPrice, ttl);\n\n // We create a hex representation of the public key with an added prefix\n const toPublicKey = CLPublicKey.fromHex(to);\n\n const session = DeployUtil.ExecutableDeployItem.newTransfer(amount, toPublicKey, null, id);\n\n const payment = DeployUtil.standardPayment(paymentAmount);\n const deploy = DeployUtil.makeDeploy(deployParams, session, payment);\n const signedDeploy = DeployUtil.signDeploy(deploy, signKeyPair);\n\n // Here we are sending the signed deploy\n return await casperClient.putDeploy(signedDeploy);\n};\n\nsendTransfer({\n // Put here the public key of the sender\'s main purse. Note that it needs to have a balance greater than 2.5 CSPR\n from: "",\n\n // Put here the public key of the recipient\'s main purse. This account doesn\'t need to exist. If the key is correctly formatted, the network will create the account when the deploy is sent\n to: "",\n\n // Minimal amount is 2.5 CSPR (1 CSPR = 1,000,000,000 motes)\n amount: 25000000000,\n});\n')),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Note"),": At any moment, you can serialize the deploy from this example to JSON to accomplish whatever you want (store it, send it, etc.)."),(0,s.kt)("p",null,"Here is the code you can use to serialize the deploy:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},"const jsonFromDeploy = DeployUtil.deployToJson(signedDeploy);\n")),(0,s.kt)("p",null,"Then, you can reconstruct the deploy object using this function:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},"const deployFromJson = DeployUtil.deployFromJson(jsonFromDeploy);\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6099],{3905:function(e,t,n){n.d(t,{Zo:function(){return l},kt:function(){return m}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},y=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),u=p(n),y=a,m=u["".concat(c,".").concat(y)]||u[y]||d[y]||s;return n?r.createElement(m,o(o({ref:t},l),{},{components:n})):r.createElement(m,o({ref:t},l))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=y;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:a,o[1]=i;for(var p=2;p {\n // Generating keys\n const edKeyPair = Keys.Ed25519.new();\n const { publicKey, privateKey } = edKeyPair;\n\n // Create a hexadecimal representation of the public key\n const accountAddress = publicKey.toHex();\n\n // Get the account hash (Uint8Array) from the public key\n const accountHash = publicKey.toAccountHash();\n\n // Store keys as PEM files\n const publicKeyInPem = edKeyPair.exportPublicKeyInPem();\n const privateKeyInPem = edKeyPair.exportPrivateKeyInPem();\n\n const folder = path.join("./", "casper_keys");\n\n if (!fs.existsSync(folder)) {\n const tempDir = fs.mkdirSync(folder);\n }\n\n fs.writeFileSync(folder + "/" + accountAddress + "_public.pem", publicKeyInPem);\n fs.writeFileSync(folder + "/" + accountAddress + "_private.pem", privateKeyInPem);\n\n return accountAddress;\n};\n\nconst newAccountAddress = createAccountKeys();\n')),(0,s.kt)("p",null,"After generating the keys with this code, you can add them to the ",(0,s.kt)("a",{parentName:"p",href:"https://www.casperwallet.io/"},"Casper Wallet Chrome extension")," and use them to sign your transactions."),(0,s.kt)("h3",{id:"sending-a-transfer"},"Sending a Transfer"),(0,s.kt)("p",null,"This code block shows you how to define and send a transfer on a Casper network. Replace the ",(0,s.kt)("inlineCode",{parentName:"p"},"sender-public-key")," and ",(0,s.kt)("inlineCode",{parentName:"p"},"recipient-public-key")," in the code below."),(0,s.kt)("p",null,"The ",(0,s.kt)("inlineCode",{parentName:"p"},"sendTransfer")," function below will return a ",(0,s.kt)("inlineCode",{parentName:"p"},"transfer-hash")," which you can check on ",(0,s.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/"},"https://testnet.cspr.live/"),"."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const fs = require("fs");\nconst path = require("path");\nconst axios = require("axios");\nconst casperClientSDK = require("casper-js-sdk");\n\nconst { Keys, CasperClient, CLPublicKey, DeployUtil } = require("casper-js-sdk");\n\nconst RPC_API = "http://159.65.203.12:7777/rpc";\nconst STATUS_API = "http://159.65.203.12:8888";\n\nconst sendTransfer = async ({ from, to, amount }) => {\n const casperClient = new CasperClient(RPC_API);\n\n const folder = path.join("./", "casper_keys");\n\n // Read keys from the structure created in #Generating keys\n const signKeyPair = Keys.Ed25519.parseKeyFiles(folder + "/" + from + "_public.pem", folder + "/" + from + "_private.pem");\n\n // networkName can be taken from the status api\n const response = await axios.get(STATUS_API + "/status");\n\n let networkName = null;\n\n if (response.status == 200) {\n networkName = response.data.chainspec_name;\n }\n\n // For native-transfers the payment price is fixed\n const paymentAmount = 100000000;\n\n // transfer_id field in the request to tag the transaction and to correlate it to your back-end storage\n const id = 187821;\n\n // gasPrice for native transfers can be set to 1\n const gasPrice = 1;\n\n // Time that the deploy will remain valid for, in milliseconds\n // The default value is 1800000 ms (30 minutes)\n const ttl = 1800000;\n\n let deployParams = new DeployUtil.DeployParams(signKeyPair.publicKey, networkName, gasPrice, ttl);\n\n // We create a hex representation of the public key with an added prefix\n const toPublicKey = CLPublicKey.fromHex(to);\n\n const session = DeployUtil.ExecutableDeployItem.newTransfer(amount, toPublicKey, null, id);\n\n const payment = DeployUtil.standardPayment(paymentAmount);\n const deploy = DeployUtil.makeDeploy(deployParams, session, payment);\n const signedDeploy = DeployUtil.signDeploy(deploy, signKeyPair);\n\n // Here we are sending the signed deploy\n return await casperClient.putDeploy(signedDeploy);\n};\n\nsendTransfer({\n // Put here the public key of the sender\'s main purse. Note that it needs to have a balance greater than 2.5 CSPR\n from: "",\n\n // Put here the public key of the recipient\'s main purse. This account doesn\'t need to exist. If the key is correctly formatted, the network will create the account when the deploy is sent\n to: "",\n\n // Minimal amount is 2.5 CSPR (1 CSPR = 1,000,000,000 motes)\n amount: 25000000000,\n});\n')),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},"Note"),": At any moment, you can serialize the deploy from this example to JSON to accomplish whatever you want (store it, send it, etc.)."),(0,s.kt)("p",null,"Here is the code you can use to serialize the deploy:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},"const jsonFromDeploy = DeployUtil.deployToJson(signedDeploy);\n")),(0,s.kt)("p",null,"Then, you can reconstruct the deploy object using this function:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},"const deployFromJson = DeployUtil.deployFromJson(jsonFromDeploy);\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/bd4f9aad.0d6ea978.js b/assets/js/bd4f9aad.fcb71df8.js similarity index 98% rename from assets/js/bd4f9aad.0d6ea978.js rename to assets/js/bd4f9aad.fcb71df8.js index 448fb71554..68c88b6a25 100644 --- a/assets/js/bd4f9aad.0d6ea978.js +++ b/assets/js/bd4f9aad.fcb71df8.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[9753],{3905:function(e,t,n){n.d(t,{Zo:function(){return d},kt:function(){return m}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},u="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),u=p(n),h=r,m=u["".concat(l,".").concat(h)]||u[h]||c[h]||o;return n?a.createElement(m,i(i({ref:t},d),{},{components:n})):a.createElement(m,i({ref:t},d))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:r,i[1]=s;for(var p=2;p=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},u="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),u=p(n),h=r,m=u["".concat(l,".").concat(h)]||u[h]||c[h]||o;return n?a.createElement(m,i(i({ref:t},d),{},{components:n})):a.createElement(m,i({ref:t},d))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:r,i[1]=s;for(var p=2;p=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),d=o,m=u["".concat(c,".").concat(d)]||u[d]||f[d]||a;return n?r.createElement(m,i(i({ref:t},l),{},{components:n})):r.createElement(m,i({ref:t},l))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var p=2;p=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),d=o,m=u["".concat(c,".").concat(d)]||u[d]||f[d]||a;return n?r.createElement(m,i(i({ref:t},l),{},{components:n})):r.createElement(m,i({ref:t},l))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var p=2;p=0||(r[t]=e[t]);return r}(e,a);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var o=n.createContext({}),k=function(e){var a=n.useContext(o),t=a;return e&&(t="function"==typeof e?e(a):i(i({},a),e)),t},m=function(e){var a=k(e.components);return n.createElement(o.Provider,{value:a},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var a=e.children;return n.createElement(n.Fragment,{},a)}},s=n.forwardRef((function(e,a){var t=e.components,r=e.mdxType,l=e.originalType,o=e.parentName,m=p(e,["components","mdxType","originalType","parentName"]),d=k(t),s=r,N=d["".concat(o,".").concat(s)]||d[s]||u[s]||l;return t?n.createElement(N,i(i({ref:a},m),{},{components:t})):n.createElement(N,i({ref:a},m))}));function N(e,a){var t=arguments,r=a&&a.mdxType;if("string"==typeof e||r){var l=t.length,i=new Array(l);i[0]=s;var p={};for(var o in a)hasOwnProperty.call(a,o)&&(p[o]=a[o]);p.originalType=e,p[d]="string"==typeof e?e:r,i[1]=p;for(var k=2;kModuleBytes",id:"modulebytes",level:3},{value:"StoredContractByHash",id:"storedcontractbyhash",level:3},{value:"StoredContractByName",id:"storedcontractbyname",level:3},{value:"StoredVersionContractByHash",id:"storedversioncontractbyhash",level:3},{value:"StoredVersionContractByName",id:"storedversioncontractbyname",level:3},{value:"Transfer",id:"transfer",level:3},{value:"ExecutionEffect",id:"executioneffect",level:2},{value:"ExecutionResult",id:"executionresult",level:2},{value:"FinalizedApprovals",id:"finalizedapprovals",level:2},{value:"GlobalStateIdentifier",id:"globalstateidentifier",level:2},{value:"Group",id:"group",level:2},{value:"Groups",id:"groups",level:3},{value:"JsonBid",id:"jsonbid",level:2},{value:"JsonBids",id:"jsonbids",level:2},{value:"JsonBlock",id:"jsonblock",level:2},{value:"JsonBlockBody",id:"jsonblockbody",level:2},{value:"JsonBlockHeader",id:"jsonblockheader",level:2},{value:"JsonDelegator",id:"jsondelegator",level:2},{value:"JsonEraEnd",id:"jsoneraend",level:2},{value:"JsonEraReport",id:"jsonerareport",level:2},{value:"JsonEraValidators",id:"jsoneravalidators",level:2},{value:"JsonExecutionResult",id:"jsonexecutionresult",level:2},{value:"JsonProof",id:"jsonproof",level:2},{value:"JsonValidatorChanges",id:"jsonvalidatorchanges",level:2},{value:"JsonValidatorStatusChange",id:"jsonvalidatorstatuschange",level:2},{value:"JsonValidatorsWeights",id:"jsonvalidatorweights",level:2},{value:"Merkle_Proof",id:"merkle-proof",level:2},{value:"MinimalBlockInfo",id:"minimalblockinfo",level:2},{value:"NamedArg",id:"namedarg",level:2},{value:"NamedKey",id:"namedkey",level:2},{value:"NextUpgrade",id:"nextupgrade",level:2},{value:"NewValidator",id:"newvalidator",level:2},{value:"Operation",id:"operation",level:2},{value:"OpKind",id:"opkind",level:2},{value:"Parameter",id:"parameter",level:2},{value:"PeerEntry",id:"peerentry",level:2},{value:"PeersMap",id:"peersmap",level:2},{value:"ProtocolVersion",id:"protocolversion",level:2},{value:"PublicKey",id:"publickey",level:2},{value:"PurseIdentifier",id:"purseidentifier",level:2},{value:"ReactorState",id:"reactorstate",level:2},{value:"Reward",id:"reward",level:2},{value:"RuntimeArgs",id:"runtimeargs",level:2},{value:"SeigniorageAllocation",id:"seigniorageallocation",level:2},{value:"Signature",id:"signature",level:2},{value:"StoredValue",id:"storedvalue",level:2},{value:"TimeDiff",id:"timediff",level:2},{value:"Timestamp",id:"timestamp",level:2},{value:"Transfer",id:"transfer",level:2},{value:"TransferAddr",id:"transferaddr",level:2},{value:"Transform",id:"transform",level:2},{value:"TransformEntry",id:"transformentry",level:2},{value:"U128",id:"u128",level:2},{value:"U256",id:"u256",level:2},{value:"U512",id:"u512",level:2},{value:"UnbondingPurse",id:"unbondingpurse",level:2},{value:"URef",id:"uref",level:2},{value:"ValidatorChange",id:"validatorchange",level:2},{value:"ValidatorWeight",id:"validatorweight",level:2},{value:"VestingSchedule",id:"vestingschedule",level:2},{value:"WithdrawPurse",id:"withdrawpurse",level:2}],u={toc:d},s="wrapper";function N(e){var a=e.components,t=(0,r.Z)(e,i);return(0,l.kt)(s,(0,n.Z)({},u,t,{components:a,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"types"},"Types"),(0,l.kt)("p",null,"The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness."),(0,l.kt)("h2",{id:"account"},"Account"),(0,l.kt)("p",null,"Structure representing a user's Account, stored in global state."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#accounthash"},(0,l.kt)("inlineCode",{parentName:"a"},"account_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#actionthresholds"},(0,l.kt)("inlineCode",{parentName:"a"},"action_thresholds")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#associatedkey"},(0,l.kt)("inlineCode",{parentName:"a"},"associated_keys")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"main_purse")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#namedkey"},(0,l.kt)("inlineCode",{parentName:"a"},"named_keys"))))),(0,l.kt)("h2",{id:"accounthash"},"AccountHash"),(0,l.kt)("p",null,"The AccountHash is a 32-byte hash derived from a supported PublicKey. Its role is to standardize keys that can vary in length."),(0,l.kt)("h2",{id:"actionthresholds"},"ActionThresholds"),(0,l.kt)("p",null,"Thresholds that have to be met when executing an action of a certain type."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"deployment"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key_management")))),(0,l.kt)("h2",{id:"activationpoint"},"ActivationPoint"),(0,l.kt)("p",null,"The first era to which the associated protocol version applies."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_id")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#timestamp"},(0,l.kt)("inlineCode",{parentName:"a"},"timestamp"))))),(0,l.kt)("h2",{id:"approval"},"Approval"),(0,l.kt)("p",null,"A struct containing a signature and the public key of the signer."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#signature"},(0,l.kt)("inlineCode",{parentName:"a"},"signature")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"signer"))))),(0,l.kt)("h2",{id:"associatedkey"},"AssociatedKey"),(0,l.kt)("p",null,"A key granted limited permissions to an Account, for purposes such as multisig."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#accounthash"},(0,l.kt)("inlineCode",{parentName:"a"},"account_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"weight")))),(0,l.kt)("h2",{id:"auctionstate"},"AuctionState"),(0,l.kt)("p",null,"Data structure summarizing auction contract data."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonbids"},(0,l.kt)("inlineCode",{parentName:"a"},"bids"))," All bids contained within a vector.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"block_height")," Block height.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsoneravalidators"},(0,l.kt)("inlineCode",{parentName:"a"},"era_validators"))," Era validators.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"state_root_hash"))," Global state hash."))),(0,l.kt)("h2",{id:"availableblockrange"},"AvailableBlockRange"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"low")," The inclusive lower bound of the range.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"high")," The inclusive upper bound of the range."))),(0,l.kt)("h2",{id:"bid"},"Bid"),(0,l.kt)("p",null,"An entry in the validator map."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"bonding_purse"))," The purse that was used for bonding.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"delegation_rate")," The delegation rate.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#delegator"},(0,l.kt)("inlineCode",{parentName:"a"},"delegators"))," The validator's delegators, indexed by their public keys.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"inactive")," ",(0,l.kt)("inlineCode",{parentName:"p"},"true"),' if validator has been "evicted".')),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"staked_amount"))," The amount of tokens staked by a validator (not including delegators).")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_public_key"))," Validator's public key."))),(0,l.kt)("p",null,"Additional Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#vestingschedule"},(0,l.kt)("inlineCode",{parentName:"a"},"vesting_schedule"))," Vesting schedule for a genesis validator. ",(0,l.kt)("inlineCode",{parentName:"li"},"None")," if non-genesis validator.")),(0,l.kt)("h2",{id:"blockhash"},"BlockHash"),(0,l.kt)("p",null,"A cryptographic hash identifying a ",(0,l.kt)("inlineCode",{parentName:"p"},"Block"),"."),(0,l.kt)("h2",{id:"blockidentifier"},"BlockIdentifier"),(0,l.kt)("p",null,"Identifier for possible ways to retrieve a Block."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"Hash"))," Identify and retrieve the Block with its hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Height")," Identify and retrieve the Block with its height."))),(0,l.kt)("h2",{id:"blocksynchronizerstatus"},"BlockSynchronizerStatus"),(0,l.kt)("p",null,"The status of the block synchronizer."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Historical")," The status of syncing a historical block, if any."),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash-blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"block_hash"))," The block hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"block_height")," The height of the block, if known.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"acquisition_state")," The state of acquisition of the data associated with the block.")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Forward")," The status of syncing a forward block, if any."),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash-blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"block_hash"))," The block hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"block_height")," The height of the block, if known.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"acquisition_state")," The state of acquisition of the data associated with the block."))))),(0,l.kt)("h2",{id:"chainspecrawbytes"},"ChainspecRawBytes"),(0,l.kt)("p",null,"The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"chainspec_bytes")," Hex-encoded raw bytes of the current chainspec.toml file.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"maybe_genesis_accounts_bytes")," Hex-encoded raw bytes of the current genesis accounts.toml file.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"maybe_global_state_bytes")," Hex-encoded raw bytes of the current global_state.toml file."))),(0,l.kt)("h2",{id:"contract"},"Contract"),(0,l.kt)("p",null,"A contract struct that can be serialized as a JSON object."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("p",null,(0,l.kt)("a",{parentName:"p",href:"#contractpackagehash"},(0,l.kt)("inlineCode",{parentName:"a"},"contract_package_hash"))),(0,l.kt)("p",null,(0,l.kt)("a",{parentName:"p",href:"#contractwasmhash"},(0,l.kt)("inlineCode",{parentName:"a"},"contract_wasm_hash"))),(0,l.kt)("p",null,(0,l.kt)("a",{parentName:"p",href:"#entrypoint"},(0,l.kt)("inlineCode",{parentName:"a"},"entry_points"))),(0,l.kt)("p",null,(0,l.kt)("a",{parentName:"p",href:"#namedkey"},(0,l.kt)("inlineCode",{parentName:"a"},"named_keys"))),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"protocol_version")),(0,l.kt)("h2",{id:"contracthash"},"ContractHash"),(0,l.kt)("p",null,"The hash address of the contract."),(0,l.kt)("h2",{id:"contractpackge"},"ContractPackage"),(0,l.kt)("p",null,"Contract definition, metadata and security container."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"access_key")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#disabledversions"},(0,l.kt)("inlineCode",{parentName:"a"},"disabled_versions")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#groups"},(0,l.kt)("inlineCode",{parentName:"a"},"groups")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#contractversion"},(0,l.kt)("inlineCode",{parentName:"a"},"versions"))))),(0,l.kt)("h2",{id:"contractpackagehash"},"ContractPackageHash"),(0,l.kt)("p",null,"The hash address of the contract package."),(0,l.kt)("h2",{id:"contractversion"},"ContractVersion"),(0,l.kt)("p",null,"The version of the contract."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#contracthash"},(0,l.kt)("inlineCode",{parentName:"a"},"contract_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"contract_version"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"protocol_version_major")))),(0,l.kt)("h2",{id:"contractwasmhash"},"ContractWasmHash"),(0,l.kt)("p",null,"The hash address of the contract Wasm."),(0,l.kt)("h2",{id:"delegator"},"Delegator"),(0,l.kt)("p",null,'Represents a party delegating their stake to a validator (or "delegatee").'),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"bonding_purse")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"delegator_public_key")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"staked_amount")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_public_key"))))),(0,l.kt)("p",null,"Additional Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#vestingschedule"},(0,l.kt)("inlineCode",{parentName:"a"},"vesting_schedule")))),(0,l.kt)("h2",{id:"deploy"},"Deploy"),(0,l.kt)("p",null,"A Deploy; an item containing a smart contract along with the requester's signature(s)."),(0,l.kt)("p",null,"Required properties:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#approval"},(0,l.kt)("inlineCode",{parentName:"a"},"approvals")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployhash"},(0,l.kt)("inlineCode",{parentName:"a"},"hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployheader"},(0,l.kt)("inlineCode",{parentName:"a"},"header")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#executabledeployitem"},(0,l.kt)("inlineCode",{parentName:"a"},"payment")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#executabledeployitem"},(0,l.kt)("inlineCode",{parentName:"a"},"sessions"))))),(0,l.kt)("h2",{id:"deployhash"},"DeployHash"),(0,l.kt)("p",null,"Hex-encoded Deploy hash."),(0,l.kt)("h2",{id:"deployheader"},"DeployHeader"),(0,l.kt)("p",null,"The header portion of a Deploy."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"account")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"body_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"chain_name")," A user defined string.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployhash"},(0,l.kt)("inlineCode",{parentName:"a"},"dependencies")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"gas_price")," Defined as an integer in UInt64 format.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#timestamp"},(0,l.kt)("inlineCode",{parentName:"a"},"timestamp")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#timediff"},(0,l.kt)("inlineCode",{parentName:"a"},"ttl"))))),(0,l.kt)("h2",{id:"deployinfo"},"DeployInfo"),(0,l.kt)("p",null,"Information relating to the given Deploy."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployhash"},(0,l.kt)("inlineCode",{parentName:"a"},"deploy_hash"))," The relevant Deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#accounthash"},(0,l.kt)("inlineCode",{parentName:"a"},"from"))," Account identifier of the creator of the Deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"gas"))," Gas cost of executing the Deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"source"))," Source purse used for payment of the Deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#transferaddr"},(0,l.kt)("inlineCode",{parentName:"a"},"transfers"))," Transfers performed by the Deploy."))),(0,l.kt)("h2",{id:"dictionaryidentifier"},"DictionaryIdentifier"),(0,l.kt)("p",null,"Options for dictionary item lookups."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"AccountNamedKey")," Lookup a dictionary item via an Account's named keys."),(0,l.kt)("p",{parentName:"li"},"Required Parameters:"),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key")," The Account key as a formatted string whose named keys contain dictionary_name."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"dictionary_name")," The named key under which the dictionary seed URef is stored."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"dictionary_item_key")," The dictionary item key formatted as a string.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"ContractNamedKey")," Lookup a dictionary item via a Contract's named keys."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key")," The contract key as a formatted string whose named keys contains dictionary_name."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"dictionary_name")," The named key under which the dictionary seed URef is stored."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"dictionary_item_key")," The dictionary item key formatted as a string.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"URef")," Lookup a dictionary item via its seed URef."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"seed_uref")," The dictionary's seed URef."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"dictionary_item_key")," The dictionary item key formatted as a string.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Dictionary")," Lookup a dictionary item via its unique key."))),(0,l.kt)("h2",{id:"digest"},"Digest"),(0,l.kt)("p",null,"Hex-encoded hash digest."),(0,l.kt)("h2",{id:"disabledversions"},"DisabledVersions"),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"contract_version"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"protocol_version_major")))),(0,l.kt)("h2",{id:"entrypoint"},"EntryPoint"),(0,l.kt)("p",null,"Metadata describing a callable entry point and its return value, if any. All required parameters should be declared, whereas all non-required parameters should not be declared. Non-required parameters should not be confused with optional parameters."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#entrypointaccess"},(0,l.kt)("inlineCode",{parentName:"a"},"access")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#parameter"},(0,l.kt)("inlineCode",{parentName:"a"},"args")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#entrypointtype"},(0,l.kt)("inlineCode",{parentName:"a"},"entry_point_type")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"name"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#cltype"},(0,l.kt)("inlineCode",{parentName:"a"},"ret"))))),(0,l.kt)("h2",{id:"entrypointaccess"},"EntryPointAccess"),(0,l.kt)("p",null,"Enum describing the possible access control options for a contract entry point."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Public")," A public entry point is callable by any caller.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#group"},(0,l.kt)("inlineCode",{parentName:"a"},"Groups"))," Only callers from the authorized, listed groups may call this entry point. Note: If this list is empty then this entry point is not callable from outside the contract."))),(0,l.kt)("h2",{id:"entrypointype"},"EntryPointType"),(0,l.kt)("p",null,"Context of an entry point execution."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"session")," Executes in the caller's context.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"contract")," Executes in the callee's context."))),(0,l.kt)("h2",{id:"eraid"},"EraID"),(0,l.kt)("p",null,"Era ID newtype."),(0,l.kt)("h2",{id:"erainfo"},"EraInfo"),(0,l.kt)("p",null,"Auction metadata. Intended to be recorded at each era."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#seigniorageallocation-seigniorageallocation"},(0,l.kt)("inlineCode",{parentName:"a"},"seigniorage_allocation"))," Information about a seigniorage allocation.")),(0,l.kt)("h2",{id:"erasummary"},"EraSummary"),(0,l.kt)("p",null,"The summary of an era."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"block_hash"))," The Block hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_id"))," The era id.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#merkle-proof"},(0,l.kt)("inlineCode",{parentName:"a"},"merkle_proof"))," The merkle proof.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"state_root_hash"))," Hex-encoded hash of the state root.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#storedvalue"},(0,l.kt)("inlineCode",{parentName:"a"},"stored_value"))," The StoredValue containing era information."))),(0,l.kt)("h2",{id:"executabledeployitem"},"ExecutableDeployItem"),(0,l.kt)("p",null,"Represents possible variants of an executable Deploy."),(0,l.kt)("h3",{id:"modulebytes"},(0,l.kt)("inlineCode",{parentName:"h3"},"ModuleBytes")),(0,l.kt)("p",null,"Executable specified as raw bytes that represent Wasm code and an instance of ",(0,l.kt)("inlineCode",{parentName:"p"},"RuntimeArgs"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"module_bytes")," Hex-encoded raw Wasm bytes. There are some special cases around passing ",(0,l.kt)("inlineCode",{parentName:"li"},"module_bytes")," for payment code.")),(0,l.kt)("p",null,"Additional Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#runtimeargs"},(0,l.kt)("inlineCode",{parentName:"a"},"args"))," Runtime arguments.")),(0,l.kt)("h3",{id:"storedcontractbyhash"},(0,l.kt)("inlineCode",{parentName:"h3"},"StoredContractByHash")),(0,l.kt)("p",null,"Stored contract referenced by its ",(0,l.kt)("inlineCode",{parentName:"p"},"ContractHash"),", entry point and an instance of ",(0,l.kt)("inlineCode",{parentName:"p"},"RuntimeArgs"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#runtimeargs"},(0,l.kt)("inlineCode",{parentName:"a"},"args"))," Runtime arguments.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"entry_point")," The name of an entry point.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"hash")," A hex-encoded hash."))),(0,l.kt)("h3",{id:"storedcontractbyname"},(0,l.kt)("inlineCode",{parentName:"h3"},"StoredContractByName")),(0,l.kt)("p",null,"Stored contract referenced by a named key existing in the signer's Account context, entry point and an instance of ",(0,l.kt)("inlineCode",{parentName:"p"},"RuntimeArgs"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#runtimeargs"},(0,l.kt)("inlineCode",{parentName:"a"},"args"))," Runtime arguments.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"entry_point")," The name of an entry point.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"name")," A named key."))),(0,l.kt)("h3",{id:"storedversioncontractbyhash"},(0,l.kt)("inlineCode",{parentName:"h3"},"StoredVersionContractByHash")),(0,l.kt)("p",null,"Stored versioned contract referenced by its ",(0,l.kt)("inlineCode",{parentName:"p"},"ContractPackageHash"),", entry point and an instance of ",(0,l.kt)("inlineCode",{parentName:"p"},"RuntimeArgs"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#runtimeargs"},(0,l.kt)("inlineCode",{parentName:"a"},"args"))," Runtime arguments.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"entry_point")," The name of an entry point.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"hash")," A hex-encoded hash."))),(0,l.kt)("p",null,"Additional Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"version")," An optional version of the contract to call. It will default to the highest enabled version if no value is specified.")),(0,l.kt)("h3",{id:"storedversioncontractbyname"},(0,l.kt)("inlineCode",{parentName:"h3"},"StoredVersionContractByName")),(0,l.kt)("p",null,"Stored versioned contract referenced by a named key existing in the signer's Account context, entry point and an instance of ",(0,l.kt)("inlineCode",{parentName:"p"},"RuntimeArgs"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#runtimeargs"},(0,l.kt)("inlineCode",{parentName:"a"},"args"))," Runtime arguments.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"entry_point")," The name of an entry point.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"name")," A named key."))),(0,l.kt)("p",null,"Additional Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"version")," An optional version of the contract to call. It will default to the highest enabled version if no value is specified.")),(0,l.kt)("h3",{id:"transfer"},(0,l.kt)("inlineCode",{parentName:"h3"},"Transfer")),(0,l.kt)("p",null,"A native transfer which does not contain or reference a Wasm code."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#runtimeargs"},(0,l.kt)("inlineCode",{parentName:"a"},"args")))),(0,l.kt)("h2",{id:"executioneffect"},"ExecutionEffect"),(0,l.kt)("p",null,"The journal of execution transforms from a single Deploy."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#oepration"},(0,l.kt)("inlineCode",{parentName:"a"},"operations")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#transformentry"},(0,l.kt)("inlineCode",{parentName:"a"},"transforms"))))),(0,l.kt)("h2",{id:"executionresult"},"ExecutionResult"),(0,l.kt)("p",null,"The result of executing a single Deploy."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Failure")," The result of a failed execution`"),(0,l.kt)("p",{parentName:"li"},"Required Parameters:"),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#executioneffect"},(0,l.kt)("inlineCode",{parentName:"a"},"effect"))),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#transferaddr"},(0,l.kt)("inlineCode",{parentName:"a"},"transfers"))),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"cost"))),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"error_message")," The error message associated with executing the Deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Success")," The result of a successful execution."),(0,l.kt)("p",{parentName:"li"},"Required Parameters:"),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#executioneffect"},(0,l.kt)("inlineCode",{parentName:"a"},"effect"))),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#transferaddr"},(0,l.kt)("inlineCode",{parentName:"a"},"transfers"))),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"cost"))))),(0,l.kt)("h2",{id:"finalizedapprovals"},"FinalizedApprovals"),(0,l.kt)("p",null,"A boolean value that determines whether to return the deploy with the finalized approvals substituted. If ",(0,l.kt)("inlineCode",{parentName:"p"},"false")," or omitted, returns the deploy with the approvals that were originally received by the node."),(0,l.kt)("h2",{id:"globalstateidentifier"},"GlobalStateIdentifier"),(0,l.kt)("p",null,"Identifier for possible ways to query global state."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"BlockHash"))," Query using a Block hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"StateRootHash"))," Query using the state root hash."))),(0,l.kt)("h2",{id:"group"},"Group"),(0,l.kt)("p",null,'A (labelled) "user group". Each entry point of a versioned contract may be associated with one or more user groups which are allowed to call it.'),(0,l.kt)("h3",{id:"groups"},"Groups"),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"group"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"keys"))))),(0,l.kt)("h2",{id:"jsonbid"},"JsonBid"),(0,l.kt)("p",null,"An entry in a founding validator map representing a bid."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"bonding_purse"))," The purse that was used for bonding.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"delegation_rate")," The delegation rate.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsondelegator"},(0,l.kt)("inlineCode",{parentName:"a"},"delegators"))," The delegators.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"inactive")," Is this an inactive validator.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"staked_amount"))," The amount of tokens staked by a validator (not including delegators)."))),(0,l.kt)("h2",{id:"jsonbids"},"JsonBids"),(0,l.kt)("p",null,"A Json representation of a single bid."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonbid"},(0,l.kt)("inlineCode",{parentName:"a"},"bid")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"public_key"))))),(0,l.kt)("h2",{id:"jsonblock"},"JsonBlock"),(0,l.kt)("p",null,"A JSON-friendly representation of ",(0,l.kt)("inlineCode",{parentName:"p"},"Block"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonblockbody"},(0,l.kt)("inlineCode",{parentName:"a"},"body"))," JSON-friendly Block body.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"hash"))," BlockHash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonblockheader"},(0,l.kt)("inlineCode",{parentName:"a"},"header"))," JSON-friendly Block header.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonproof"},(0,l.kt)("inlineCode",{parentName:"a"},"proofs"))," JSON-friendly list of proofs for this Block."))),(0,l.kt)("h2",{id:"jsonblockbody"},"JsonBlockBody"),(0,l.kt)("p",null,"A JSON-friendly representation of ",(0,l.kt)("inlineCode",{parentName:"p"},"Body"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployhash"},(0,l.kt)("inlineCode",{parentName:"a"},"deploy_hashes")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"proposer")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployhash"},(0,l.kt)("inlineCode",{parentName:"a"},"transfer_hashes"))))),(0,l.kt)("h2",{id:"jsonblockheader"},"JsonBlockHeader"),(0,l.kt)("p",null,"JSON representation of a Block header."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"accumulated_seed"))," Accumulated seed.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"body_hash"))," The body hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_id"))," The Block era id.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"height")," The Block height.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"parent_hash"))," The parent hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#protocolversion"},(0,l.kt)("inlineCode",{parentName:"a"},"protocol_version"))," The protocol version.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"random_bit")," Randomness bit.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"state_root_hash"))," The state root hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#timestamp"},(0,l.kt)("inlineCode",{parentName:"a"},"timestamp"))," The Block timestamp."))),(0,l.kt)("p",null,"Additional Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#jsoneraend"},(0,l.kt)("inlineCode",{parentName:"a"},"era_end"))," The era end.")),(0,l.kt)("h2",{id:"jsondelegator"},"JsonDelegator"),(0,l.kt)("p",null,"A delegator associated with the given validator."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"bonding_purse")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"delegatee")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"public_key")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"staked_amount"))))),(0,l.kt)("h2",{id:"jsoneraend"},"JsonEraEnd"),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonerareport"},"`era_report"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#validatorweight"},(0,l.kt)("inlineCode",{parentName:"a"},"next_era_validator_weight"))))),(0,l.kt)("h2",{id:"jsonerareport"},"JsonEraReport"),(0,l.kt)("p",null,"Equivocation and reward information to be included in the terminal Block."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"equivocators")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"inactive_validators")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#reward"},(0,l.kt)("inlineCode",{parentName:"a"},"rewards"))))),(0,l.kt)("h2",{id:"jsoneravalidators"},"JsonEraValidators"),(0,l.kt)("p",null,"The validators for the given era."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_id")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonvalidatorsweights"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_weights"))))),(0,l.kt)("h2",{id:"jsonexecutionresult"},"JsonExecutionResult"),(0,l.kt)("p",null,"The execution result of a single Deploy."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"block_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#executionresult"},(0,l.kt)("inlineCode",{parentName:"a"},"result"))))),(0,l.kt)("h2",{id:"jsonproof"},"JsonProof"),(0,l.kt)("p",null,"A JSON-friendly representation of a proof, i.e. a Block's finality signature."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"public_key")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#signature"},(0,l.kt)("inlineCode",{parentName:"a"},"signature"))))),(0,l.kt)("h2",{id:"jsonvalidatorchanges"},"JsonValidatorChanges"),(0,l.kt)("p",null,"The changes in a validator's status."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"public_key"))," The public key of the validator.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonvalidatorstatuschange"},(0,l.kt)("inlineCode",{parentName:"a"},"status_changes"))," The set of changes to the validator's status."))),(0,l.kt)("h2",{id:"jsonvalidatorstatuschange"},"JsonValidatorStatusChange"),(0,l.kt)("p",null,"A single change to a validator's status in the given era."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_id"))," The era in which the change occurred.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#validatorchange"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_change"))," The change in validator status."))),(0,l.kt)("h2",{id:"jsonvalidatorweights"},"JsonValidatorsWeights"),(0,l.kt)("p",null,"A validator's weight."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"public_key")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"weight"))))),(0,l.kt)("h2",{id:"merkle-proof"},"Merkle_Proof"),(0,l.kt)("p",null,"A merkle proof is a construction created using a merkle trie that allows verification of the associated hashes."),(0,l.kt)("h2",{id:"minimalblockinfo"},"MinimalBlockInfo"),(0,l.kt)("p",null,"Minimal info of a ",(0,l.kt)("inlineCode",{parentName:"p"},"Block"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"creator")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_id")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"height"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"state_root_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#timestamp"},(0,l.kt)("inlineCode",{parentName:"a"},"timestamp"))))),(0,l.kt)("h2",{id:"namedarg"},"NamedArg"),(0,l.kt)("p",null,"Named arguments to a contract."),(0,l.kt)("h2",{id:"namedkey"},"NamedKey"),(0,l.kt)("p",null,"A named key."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key")," The value of the entry: a casper ",(0,l.kt)("inlineCode",{parentName:"p"},"Key")," type.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"name")," The name of the entry."))),(0,l.kt)("h2",{id:"nextupgrade"},"NextUpgrade"),(0,l.kt)("p",null,"Information about the next protocol upgrade."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#activationpoint"},(0,l.kt)("inlineCode",{parentName:"a"},"activation_point")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"protocol_version")))),(0,l.kt)("h2",{id:"newvalidator"},"NewValidator"),(0,l.kt)("p",null,"The public key for the new validator in a redelegation using ",(0,l.kt)("a",{parentName:"p",href:"#unbondingpurse"},"UnbondingPurse"),"."),(0,l.kt)("h2",{id:"operation"},"Operation"),(0,l.kt)("p",null,"An operation performed while executing a Deploy."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key")," The formatted string of the ",(0,l.kt)("inlineCode",{parentName:"p"},"Key"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#opkind"},(0,l.kt)("inlineCode",{parentName:"a"},"kind"))))),(0,l.kt)("h2",{id:"opkind"},"OpKind"),(0,l.kt)("p",null,"The type of operation performed while executing a Deploy."),(0,l.kt)("h2",{id:"parameter"},"Parameter"),(0,l.kt)("p",null,"Parameter to an entry point."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#cltype"},(0,l.kt)("inlineCode",{parentName:"a"},"cl_type")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"name")))),(0,l.kt)("h2",{id:"peerentry"},"PeerEntry"),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"address"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"node_id")))),(0,l.kt)("h2",{id:"peersmap"},"PeersMap"),(0,l.kt)("p",null,"Map of peer IDs to network addresses."),(0,l.kt)("h2",{id:"protocolversion"},"ProtocolVersion"),(0,l.kt)("p",null,"Casper Platform protocol version."),(0,l.kt)("h2",{id:"publickey"},"PublicKey"),(0,l.kt)("p",null,"Hex-encoded cryptographic public key, including the algorithm tag prefix."),(0,l.kt)("h2",{id:"purseidentifier"},"PurseIdentifier"),(0,l.kt)("p",null,"The identifier to obtain the purse corresponding to a balance query. Valid identifiers include:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"main_purse_under_public_key")," The main purse under a provided ",(0,l.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_chain#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"main_purse_under_account_hash")," The main purse under a provided ",(0,l.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_chain#accounthash"},(0,l.kt)("inlineCode",{parentName:"a"},"AccountHash")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"purse_uref")," A specific purse identified by the associated ",(0,l.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_chain#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"URef")),"."))),(0,l.kt)("h2",{id:"reactorstate"},"ReactorState"),(0,l.kt)("p",null,"The state of the reactor, which will return one of the following:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Initialize")," Get all components and reactor state set up on start.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"CatchUp")," Orient to the network and attempt to catch up to tip.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Upgrading")," Running commit upgrade and creating immediate switch block.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"KeepUp")," Stay caught up with tip.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Validate")," Node is currently caught up and is an active validator.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"ShutdownForUpgrade")," Node should be shut down for upgrade."))),(0,l.kt)("h2",{id:"reward"},"Reward"),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"amount"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator"))))),(0,l.kt)("h2",{id:"runtimeargs"},"RuntimeArgs"),(0,l.kt)("p",null,"Represents a collection of arguments passed to a smart contract."),(0,l.kt)("h2",{id:"seigniorageallocation"},"SeigniorageAllocation"),(0,l.kt)("p",null,"Information about a seigniorage allocation."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Validator")," Info about a seigniorage allocation for a validator."),(0,l.kt)("p",{parentName:"li"},"Required Parameters:"),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"amount"))," Allocated amount."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_public_key"))," Validator's public key.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Delegator")," Info about a seigniorage allocation for a delegator."),(0,l.kt)("p",{parentName:"li"},"Require Parameters:"),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"amount"))," Allocated amount."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"delegator_public_key"))," Delegator's public key."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_public_key"))," Validator's public key."))),(0,l.kt)("h2",{id:"signature"},"Signature"),(0,l.kt)("p",null,"Hex-encoded cryptographic signature, including the algorithm tag prefix."),(0,l.kt)("h2",{id:"storedvalue"},"StoredValue"),(0,l.kt)("p",null,"Representation of a value stored in global state. ",(0,l.kt)("inlineCode",{parentName:"p"},"Account"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"Contract")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"ContractPackage")," have their own ",(0,l.kt)("inlineCode",{parentName:"p"},"json_compatibility")," representation (see their docs for further info)."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#clvalue"},(0,l.kt)("inlineCode",{parentName:"a"},"CLValue"))," A Casper-specific value.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#account"},(0,l.kt)("inlineCode",{parentName:"a"},"Account"))," An Account.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"ContractWasm")," A contract's Wasm.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#contract"},(0,l.kt)("inlineCode",{parentName:"a"},"Contract"))," Entry points supported by a contract.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#contractpackage"},(0,l.kt)("inlineCode",{parentName:"a"},"ContractPackage"))," A contract definition, metadata, and security container.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#transfer"},(0,l.kt)("inlineCode",{parentName:"a"},"Transfer"))," A record of a transfer.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployinfo"},(0,l.kt)("inlineCode",{parentName:"a"},"DeployInfo"))," A record of a Deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#erainfo"},(0,l.kt)("inlineCode",{parentName:"a"},"EraInfo"))," Auction metadata.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#bid-bid"},(0,l.kt)("inlineCode",{parentName:"a"},"Bid"))," A bid.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#unbondingpurse"},(0,l.kt)("inlineCode",{parentName:"a"},"Withdraw"))," A withdraw."))),(0,l.kt)("h2",{id:"timediff"},"TimeDiff"),(0,l.kt)("p",null,"Human-readable duration."),(0,l.kt)("h2",{id:"timestamp"},"Timestamp"),(0,l.kt)("p",null,"Timestamp formatted as per RFC 3339."),(0,l.kt)("h2",{id:"transfer"},"Transfer"),(0,l.kt)("p",null,"Represents a transfer from one purse to another."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"amount"))," Transfer amount.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployhash"},(0,l.kt)("inlineCode",{parentName:"a"},"deploy_hash"))," Deploy that created the transfer.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#accounthash"},(0,l.kt)("inlineCode",{parentName:"a"},"from"))," Account from which transfer was executed.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"gas")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"source"))," Source purse.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"target"))," Target purse."))),(0,l.kt)("p",null,"Additional Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"id")," User-defined ID.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#accounthash"},(0,l.kt)("inlineCode",{parentName:"a"},"to"))," Account to which funds are transferred."))),(0,l.kt)("h2",{id:"transferaddr"},"TransferAddr"),(0,l.kt)("p",null,"Hex-encoded transfer address."),(0,l.kt)("h2",{id:"transform"},"Transform"),(0,l.kt)("p",null,"The actual transformation performed while executing a Deploy."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"WriteCLValue")," Write the given ",(0,l.kt)("a",{parentName:"p",href:"#clvalue"},"CLValue")," to global state.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"WriteAccount")," Writes the given ",(0,l.kt)("a",{parentName:"p",href:"#accounthash"},"Account")," to global state.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"WriteDeployInfo")," Writes the given ",(0,l.kt)("a",{parentName:"p",href:"#deployinfo"},"DeployInfo")," to global state.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"WriteEraInfo")," Writes the given ",(0,l.kt)("a",{parentName:"p",href:"#erainfo"},"EraInfo")," to global state.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"WriteTransfer")," Writes the given ",(0,l.kt)("a",{parentName:"p",href:"#transfer"},"Transfer")," to global state.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"WriteBid")," Writes the given ",(0,l.kt)("a",{parentName:"p",href:"#bid"},"Bid")," to global state.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"WriteWithdraw")," Writes the given ",(0,l.kt)("a",{parentName:"p",href:"#unbondingpurse"},"Withdraw")," to global state.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"AddInt32")," Adds the given ",(0,l.kt)("inlineCode",{parentName:"p"},"i32"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"AddUInt64")," Adds the given ",(0,l.kt)("inlineCode",{parentName:"p"},"u64"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"AddUInt128")," Adds the given ",(0,l.kt)("a",{parentName:"p",href:"#u128"},(0,l.kt)("inlineCode",{parentName:"a"},"U128")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"AddUInt256")," Adds the given ",(0,l.kt)("a",{parentName:"p",href:"#u256"},(0,l.kt)("inlineCode",{parentName:"a"},"U256")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"AddUInt512")," Adds the given ",(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"U512")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"AddKeys")," Adds the given collection of ",(0,l.kt)("a",{parentName:"p",href:"#namedkey"},"named keys"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Failure")," A failed transformation, containing an error message."))),(0,l.kt)("h2",{id:"transformentry"},"TransformEntry"),(0,l.kt)("p",null,"A transformation performed while executing a Deploy."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key")," The formatted string of the ",(0,l.kt)("inlineCode",{parentName:"p"},"Key"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#transform"},(0,l.kt)("inlineCode",{parentName:"a"},"transforms"))," The transformation."))),(0,l.kt)("h2",{id:"u128"},"U128"),(0,l.kt)("p",null,"Decimal representation of a 128-bit integer."),(0,l.kt)("h2",{id:"u256"},"U256"),(0,l.kt)("p",null,"Decimal representation of a 256-bit integer."),(0,l.kt)("h2",{id:"u512"},"U512"),(0,l.kt)("p",null,"Decimal representation of a 512-bit integer."),(0,l.kt)("h2",{id:"unbondingpurse"},"UnbondingPurse"),(0,l.kt)("p",null,"Unbonding purse."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"amount"))," Unbonding amount.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"bonding_purse"))," Bonding purse.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_of_creation"))," Era in which the unbonding request was created.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"unbonder_public_key"))," Unbonder's public key.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_public_key"))," The original validator's public key.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#newvalidator"},(0,l.kt)("inlineCode",{parentName:"a"},"new_validator"))," The redelegated validator's public key."))),(0,l.kt)("h2",{id:"uref"},"URef"),(0,l.kt)("p",null,"Hex-encoded, formatted URef."),(0,l.kt)("h2",{id:"validatorchange"},"ValidatorChange"),(0,l.kt)("p",null,"A change to a validator's status between two eras."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Added"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Removed"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Banned"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"CannotPropose"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"SeenAsFaulty")))),(0,l.kt)("h2",{id:"validatorweight"},"ValidatorWeight"),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"weight"))))),(0,l.kt)("h2",{id:"vestingschedule"},"VestingSchedule"),(0,l.kt)("p",null,"Vesting schedule for a genesis validator."),(0,l.kt)("h2",{id:"withdrawpurse"},"WithdrawPurse"),(0,l.kt)("p",null,"Withdraw purse, previously known as unbonding purse prior to 1.5. Withdraw purses remain as historical data."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"amount"))," Unbonding amount.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"bonding_purse"))," Bonding purse.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_of_creation"))," Era in which the unbonding request was created.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"unbonder_public_key"))," Unbonder's public key.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_public_key"))," The original validator's public key."))))}N.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[2614],{3905:function(e,a,t){t.d(a,{Zo:function(){return m},kt:function(){return N}});var n=t(7294);function r(e,a,t){return a in e?Object.defineProperty(e,a,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[a]=t,e}function l(e,a){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);a&&(n=n.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var a=1;a=0||(r[t]=e[t]);return r}(e,a);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var o=n.createContext({}),k=function(e){var a=n.useContext(o),t=a;return e&&(t="function"==typeof e?e(a):i(i({},a),e)),t},m=function(e){var a=k(e.components);return n.createElement(o.Provider,{value:a},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var a=e.children;return n.createElement(n.Fragment,{},a)}},s=n.forwardRef((function(e,a){var t=e.components,r=e.mdxType,l=e.originalType,o=e.parentName,m=p(e,["components","mdxType","originalType","parentName"]),d=k(t),s=r,N=d["".concat(o,".").concat(s)]||d[s]||u[s]||l;return t?n.createElement(N,i(i({ref:a},m),{},{components:t})):n.createElement(N,i({ref:a},m))}));function N(e,a){var t=arguments,r=a&&a.mdxType;if("string"==typeof e||r){var l=t.length,i=new Array(l);i[0]=s;var p={};for(var o in a)hasOwnProperty.call(a,o)&&(p[o]=a[o]);p.originalType=e,p[d]="string"==typeof e?e:r,i[1]=p;for(var k=2;kModuleBytes",id:"modulebytes",level:3},{value:"StoredContractByHash",id:"storedcontractbyhash",level:3},{value:"StoredContractByName",id:"storedcontractbyname",level:3},{value:"StoredVersionContractByHash",id:"storedversioncontractbyhash",level:3},{value:"StoredVersionContractByName",id:"storedversioncontractbyname",level:3},{value:"Transfer",id:"transfer",level:3},{value:"ExecutionEffect",id:"executioneffect",level:2},{value:"ExecutionResult",id:"executionresult",level:2},{value:"FinalizedApprovals",id:"finalizedapprovals",level:2},{value:"GlobalStateIdentifier",id:"globalstateidentifier",level:2},{value:"Group",id:"group",level:2},{value:"Groups",id:"groups",level:3},{value:"JsonBid",id:"jsonbid",level:2},{value:"JsonBids",id:"jsonbids",level:2},{value:"JsonBlock",id:"jsonblock",level:2},{value:"JsonBlockBody",id:"jsonblockbody",level:2},{value:"JsonBlockHeader",id:"jsonblockheader",level:2},{value:"JsonDelegator",id:"jsondelegator",level:2},{value:"JsonEraEnd",id:"jsoneraend",level:2},{value:"JsonEraReport",id:"jsonerareport",level:2},{value:"JsonEraValidators",id:"jsoneravalidators",level:2},{value:"JsonExecutionResult",id:"jsonexecutionresult",level:2},{value:"JsonProof",id:"jsonproof",level:2},{value:"JsonValidatorChanges",id:"jsonvalidatorchanges",level:2},{value:"JsonValidatorStatusChange",id:"jsonvalidatorstatuschange",level:2},{value:"JsonValidatorsWeights",id:"jsonvalidatorweights",level:2},{value:"Merkle_Proof",id:"merkle-proof",level:2},{value:"MinimalBlockInfo",id:"minimalblockinfo",level:2},{value:"NamedArg",id:"namedarg",level:2},{value:"NamedKey",id:"namedkey",level:2},{value:"NextUpgrade",id:"nextupgrade",level:2},{value:"NewValidator",id:"newvalidator",level:2},{value:"Operation",id:"operation",level:2},{value:"OpKind",id:"opkind",level:2},{value:"Parameter",id:"parameter",level:2},{value:"PeerEntry",id:"peerentry",level:2},{value:"PeersMap",id:"peersmap",level:2},{value:"ProtocolVersion",id:"protocolversion",level:2},{value:"PublicKey",id:"publickey",level:2},{value:"PurseIdentifier",id:"purseidentifier",level:2},{value:"ReactorState",id:"reactorstate",level:2},{value:"Reward",id:"reward",level:2},{value:"RuntimeArgs",id:"runtimeargs",level:2},{value:"SeigniorageAllocation",id:"seigniorageallocation",level:2},{value:"Signature",id:"signature",level:2},{value:"StoredValue",id:"storedvalue",level:2},{value:"TimeDiff",id:"timediff",level:2},{value:"Timestamp",id:"timestamp",level:2},{value:"Transfer",id:"transfer",level:2},{value:"TransferAddr",id:"transferaddr",level:2},{value:"Transform",id:"transform",level:2},{value:"TransformEntry",id:"transformentry",level:2},{value:"U128",id:"u128",level:2},{value:"U256",id:"u256",level:2},{value:"U512",id:"u512",level:2},{value:"UnbondingPurse",id:"unbondingpurse",level:2},{value:"URef",id:"uref",level:2},{value:"ValidatorChange",id:"validatorchange",level:2},{value:"ValidatorWeight",id:"validatorweight",level:2},{value:"VestingSchedule",id:"vestingschedule",level:2},{value:"WithdrawPurse",id:"withdrawpurse",level:2}],u={toc:d},s="wrapper";function N(e){var a=e.components,t=(0,r.Z)(e,i);return(0,l.kt)(s,(0,n.Z)({},u,t,{components:a,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"types"},"Types"),(0,l.kt)("p",null,"The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness."),(0,l.kt)("h2",{id:"account"},"Account"),(0,l.kt)("p",null,"Structure representing a user's Account, stored in global state."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#accounthash"},(0,l.kt)("inlineCode",{parentName:"a"},"account_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#actionthresholds"},(0,l.kt)("inlineCode",{parentName:"a"},"action_thresholds")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#associatedkey"},(0,l.kt)("inlineCode",{parentName:"a"},"associated_keys")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"main_purse")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#namedkey"},(0,l.kt)("inlineCode",{parentName:"a"},"named_keys"))))),(0,l.kt)("h2",{id:"accounthash"},"AccountHash"),(0,l.kt)("p",null,"The AccountHash is a 32-byte hash derived from a supported PublicKey. Its role is to standardize keys that can vary in length."),(0,l.kt)("h2",{id:"actionthresholds"},"ActionThresholds"),(0,l.kt)("p",null,"Thresholds that have to be met when executing an action of a certain type."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"deployment"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key_management")))),(0,l.kt)("h2",{id:"activationpoint"},"ActivationPoint"),(0,l.kt)("p",null,"The first era to which the associated protocol version applies."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_id")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#timestamp"},(0,l.kt)("inlineCode",{parentName:"a"},"timestamp"))))),(0,l.kt)("h2",{id:"approval"},"Approval"),(0,l.kt)("p",null,"A struct containing a signature and the public key of the signer."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#signature"},(0,l.kt)("inlineCode",{parentName:"a"},"signature")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"signer"))))),(0,l.kt)("h2",{id:"associatedkey"},"AssociatedKey"),(0,l.kt)("p",null,"A key granted limited permissions to an Account, for purposes such as multisig."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#accounthash"},(0,l.kt)("inlineCode",{parentName:"a"},"account_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"weight")))),(0,l.kt)("h2",{id:"auctionstate"},"AuctionState"),(0,l.kt)("p",null,"Data structure summarizing auction contract data."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonbids"},(0,l.kt)("inlineCode",{parentName:"a"},"bids"))," All bids contained within a vector.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"block_height")," Block height.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsoneravalidators"},(0,l.kt)("inlineCode",{parentName:"a"},"era_validators"))," Era validators.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"state_root_hash"))," Global state hash."))),(0,l.kt)("h2",{id:"availableblockrange"},"AvailableBlockRange"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"low")," The inclusive lower bound of the range.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"high")," The inclusive upper bound of the range."))),(0,l.kt)("h2",{id:"bid"},"Bid"),(0,l.kt)("p",null,"An entry in the validator map."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"bonding_purse"))," The purse that was used for bonding.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"delegation_rate")," The delegation rate.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#delegator"},(0,l.kt)("inlineCode",{parentName:"a"},"delegators"))," The validator's delegators, indexed by their public keys.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"inactive")," ",(0,l.kt)("inlineCode",{parentName:"p"},"true"),' if validator has been "evicted".')),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"staked_amount"))," The amount of tokens staked by a validator (not including delegators).")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_public_key"))," Validator's public key."))),(0,l.kt)("p",null,"Additional Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#vestingschedule"},(0,l.kt)("inlineCode",{parentName:"a"},"vesting_schedule"))," Vesting schedule for a genesis validator. ",(0,l.kt)("inlineCode",{parentName:"li"},"None")," if non-genesis validator.")),(0,l.kt)("h2",{id:"blockhash"},"BlockHash"),(0,l.kt)("p",null,"A cryptographic hash identifying a ",(0,l.kt)("inlineCode",{parentName:"p"},"Block"),"."),(0,l.kt)("h2",{id:"blockidentifier"},"BlockIdentifier"),(0,l.kt)("p",null,"Identifier for possible ways to retrieve a Block."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"Hash"))," Identify and retrieve the Block with its hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Height")," Identify and retrieve the Block with its height."))),(0,l.kt)("h2",{id:"blocksynchronizerstatus"},"BlockSynchronizerStatus"),(0,l.kt)("p",null,"The status of the block synchronizer."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Historical")," The status of syncing a historical block, if any."),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash-blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"block_hash"))," The block hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"block_height")," The height of the block, if known.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"acquisition_state")," The state of acquisition of the data associated with the block.")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Forward")," The status of syncing a forward block, if any."),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash-blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"block_hash"))," The block hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"block_height")," The height of the block, if known.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"acquisition_state")," The state of acquisition of the data associated with the block."))))),(0,l.kt)("h2",{id:"chainspecrawbytes"},"ChainspecRawBytes"),(0,l.kt)("p",null,"The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"chainspec_bytes")," Hex-encoded raw bytes of the current chainspec.toml file.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"maybe_genesis_accounts_bytes")," Hex-encoded raw bytes of the current genesis accounts.toml file.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"maybe_global_state_bytes")," Hex-encoded raw bytes of the current global_state.toml file."))),(0,l.kt)("h2",{id:"contract"},"Contract"),(0,l.kt)("p",null,"A contract struct that can be serialized as a JSON object."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("p",null,(0,l.kt)("a",{parentName:"p",href:"#contractpackagehash"},(0,l.kt)("inlineCode",{parentName:"a"},"contract_package_hash"))),(0,l.kt)("p",null,(0,l.kt)("a",{parentName:"p",href:"#contractwasmhash"},(0,l.kt)("inlineCode",{parentName:"a"},"contract_wasm_hash"))),(0,l.kt)("p",null,(0,l.kt)("a",{parentName:"p",href:"#entrypoint"},(0,l.kt)("inlineCode",{parentName:"a"},"entry_points"))),(0,l.kt)("p",null,(0,l.kt)("a",{parentName:"p",href:"#namedkey"},(0,l.kt)("inlineCode",{parentName:"a"},"named_keys"))),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"protocol_version")),(0,l.kt)("h2",{id:"contracthash"},"ContractHash"),(0,l.kt)("p",null,"The hash address of the contract."),(0,l.kt)("h2",{id:"contractpackge"},"ContractPackage"),(0,l.kt)("p",null,"Contract definition, metadata and security container."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"access_key")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#disabledversions"},(0,l.kt)("inlineCode",{parentName:"a"},"disabled_versions")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#groups"},(0,l.kt)("inlineCode",{parentName:"a"},"groups")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#contractversion"},(0,l.kt)("inlineCode",{parentName:"a"},"versions"))))),(0,l.kt)("h2",{id:"contractpackagehash"},"ContractPackageHash"),(0,l.kt)("p",null,"The hash address of the contract package."),(0,l.kt)("h2",{id:"contractversion"},"ContractVersion"),(0,l.kt)("p",null,"The version of the contract."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#contracthash"},(0,l.kt)("inlineCode",{parentName:"a"},"contract_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"contract_version"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"protocol_version_major")))),(0,l.kt)("h2",{id:"contractwasmhash"},"ContractWasmHash"),(0,l.kt)("p",null,"The hash address of the contract Wasm."),(0,l.kt)("h2",{id:"delegator"},"Delegator"),(0,l.kt)("p",null,'Represents a party delegating their stake to a validator (or "delegatee").'),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"bonding_purse")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"delegator_public_key")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"staked_amount")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_public_key"))))),(0,l.kt)("p",null,"Additional Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#vestingschedule"},(0,l.kt)("inlineCode",{parentName:"a"},"vesting_schedule")))),(0,l.kt)("h2",{id:"deploy"},"Deploy"),(0,l.kt)("p",null,"A Deploy; an item containing a smart contract along with the requester's signature(s)."),(0,l.kt)("p",null,"Required properties:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#approval"},(0,l.kt)("inlineCode",{parentName:"a"},"approvals")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployhash"},(0,l.kt)("inlineCode",{parentName:"a"},"hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployheader"},(0,l.kt)("inlineCode",{parentName:"a"},"header")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#executabledeployitem"},(0,l.kt)("inlineCode",{parentName:"a"},"payment")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#executabledeployitem"},(0,l.kt)("inlineCode",{parentName:"a"},"sessions"))))),(0,l.kt)("h2",{id:"deployhash"},"DeployHash"),(0,l.kt)("p",null,"Hex-encoded Deploy hash."),(0,l.kt)("h2",{id:"deployheader"},"DeployHeader"),(0,l.kt)("p",null,"The header portion of a Deploy."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"account")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"body_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"chain_name")," A user defined string.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployhash"},(0,l.kt)("inlineCode",{parentName:"a"},"dependencies")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"gas_price")," Defined as an integer in UInt64 format.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#timestamp"},(0,l.kt)("inlineCode",{parentName:"a"},"timestamp")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#timediff"},(0,l.kt)("inlineCode",{parentName:"a"},"ttl"))))),(0,l.kt)("h2",{id:"deployinfo"},"DeployInfo"),(0,l.kt)("p",null,"Information relating to the given Deploy."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployhash"},(0,l.kt)("inlineCode",{parentName:"a"},"deploy_hash"))," The relevant Deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#accounthash"},(0,l.kt)("inlineCode",{parentName:"a"},"from"))," Account identifier of the creator of the Deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"gas"))," Gas cost of executing the Deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"source"))," Source purse used for payment of the Deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#transferaddr"},(0,l.kt)("inlineCode",{parentName:"a"},"transfers"))," Transfers performed by the Deploy."))),(0,l.kt)("h2",{id:"dictionaryidentifier"},"DictionaryIdentifier"),(0,l.kt)("p",null,"Options for dictionary item lookups."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"AccountNamedKey")," Lookup a dictionary item via an Account's named keys."),(0,l.kt)("p",{parentName:"li"},"Required Parameters:"),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key")," The Account key as a formatted string whose named keys contain dictionary_name."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"dictionary_name")," The named key under which the dictionary seed URef is stored."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"dictionary_item_key")," The dictionary item key formatted as a string.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"ContractNamedKey")," Lookup a dictionary item via a Contract's named keys."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key")," The contract key as a formatted string whose named keys contains dictionary_name."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"dictionary_name")," The named key under which the dictionary seed URef is stored."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"dictionary_item_key")," The dictionary item key formatted as a string.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"URef")," Lookup a dictionary item via its seed URef."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"seed_uref")," The dictionary's seed URef."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"dictionary_item_key")," The dictionary item key formatted as a string.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Dictionary")," Lookup a dictionary item via its unique key."))),(0,l.kt)("h2",{id:"digest"},"Digest"),(0,l.kt)("p",null,"Hex-encoded hash digest."),(0,l.kt)("h2",{id:"disabledversions"},"DisabledVersions"),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"contract_version"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"protocol_version_major")))),(0,l.kt)("h2",{id:"entrypoint"},"EntryPoint"),(0,l.kt)("p",null,"Metadata describing a callable entry point and its return value, if any. All required parameters should be declared, whereas all non-required parameters should not be declared. Non-required parameters should not be confused with optional parameters."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#entrypointaccess"},(0,l.kt)("inlineCode",{parentName:"a"},"access")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#parameter"},(0,l.kt)("inlineCode",{parentName:"a"},"args")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#entrypointtype"},(0,l.kt)("inlineCode",{parentName:"a"},"entry_point_type")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"name"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#cltype"},(0,l.kt)("inlineCode",{parentName:"a"},"ret"))))),(0,l.kt)("h2",{id:"entrypointaccess"},"EntryPointAccess"),(0,l.kt)("p",null,"Enum describing the possible access control options for a contract entry point."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Public")," A public entry point is callable by any caller.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#group"},(0,l.kt)("inlineCode",{parentName:"a"},"Groups"))," Only callers from the authorized, listed groups may call this entry point. Note: If this list is empty then this entry point is not callable from outside the contract."))),(0,l.kt)("h2",{id:"entrypointype"},"EntryPointType"),(0,l.kt)("p",null,"Context of an entry point execution."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"session")," Executes in the caller's context.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"contract")," Executes in the callee's context."))),(0,l.kt)("h2",{id:"eraid"},"EraID"),(0,l.kt)("p",null,"Era ID newtype."),(0,l.kt)("h2",{id:"erainfo"},"EraInfo"),(0,l.kt)("p",null,"Auction metadata. Intended to be recorded at each era."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#seigniorageallocation-seigniorageallocation"},(0,l.kt)("inlineCode",{parentName:"a"},"seigniorage_allocation"))," Information about a seigniorage allocation.")),(0,l.kt)("h2",{id:"erasummary"},"EraSummary"),(0,l.kt)("p",null,"The summary of an era."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"block_hash"))," The Block hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_id"))," The era id.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#merkle-proof"},(0,l.kt)("inlineCode",{parentName:"a"},"merkle_proof"))," The merkle proof.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"state_root_hash"))," Hex-encoded hash of the state root.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#storedvalue"},(0,l.kt)("inlineCode",{parentName:"a"},"stored_value"))," The StoredValue containing era information."))),(0,l.kt)("h2",{id:"executabledeployitem"},"ExecutableDeployItem"),(0,l.kt)("p",null,"Represents possible variants of an executable Deploy."),(0,l.kt)("h3",{id:"modulebytes"},(0,l.kt)("inlineCode",{parentName:"h3"},"ModuleBytes")),(0,l.kt)("p",null,"Executable specified as raw bytes that represent Wasm code and an instance of ",(0,l.kt)("inlineCode",{parentName:"p"},"RuntimeArgs"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"module_bytes")," Hex-encoded raw Wasm bytes. There are some special cases around passing ",(0,l.kt)("inlineCode",{parentName:"li"},"module_bytes")," for payment code.")),(0,l.kt)("p",null,"Additional Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#runtimeargs"},(0,l.kt)("inlineCode",{parentName:"a"},"args"))," Runtime arguments.")),(0,l.kt)("h3",{id:"storedcontractbyhash"},(0,l.kt)("inlineCode",{parentName:"h3"},"StoredContractByHash")),(0,l.kt)("p",null,"Stored contract referenced by its ",(0,l.kt)("inlineCode",{parentName:"p"},"ContractHash"),", entry point and an instance of ",(0,l.kt)("inlineCode",{parentName:"p"},"RuntimeArgs"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#runtimeargs"},(0,l.kt)("inlineCode",{parentName:"a"},"args"))," Runtime arguments.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"entry_point")," The name of an entry point.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"hash")," A hex-encoded hash."))),(0,l.kt)("h3",{id:"storedcontractbyname"},(0,l.kt)("inlineCode",{parentName:"h3"},"StoredContractByName")),(0,l.kt)("p",null,"Stored contract referenced by a named key existing in the signer's Account context, entry point and an instance of ",(0,l.kt)("inlineCode",{parentName:"p"},"RuntimeArgs"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#runtimeargs"},(0,l.kt)("inlineCode",{parentName:"a"},"args"))," Runtime arguments.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"entry_point")," The name of an entry point.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"name")," A named key."))),(0,l.kt)("h3",{id:"storedversioncontractbyhash"},(0,l.kt)("inlineCode",{parentName:"h3"},"StoredVersionContractByHash")),(0,l.kt)("p",null,"Stored versioned contract referenced by its ",(0,l.kt)("inlineCode",{parentName:"p"},"ContractPackageHash"),", entry point and an instance of ",(0,l.kt)("inlineCode",{parentName:"p"},"RuntimeArgs"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#runtimeargs"},(0,l.kt)("inlineCode",{parentName:"a"},"args"))," Runtime arguments.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"entry_point")," The name of an entry point.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"hash")," A hex-encoded hash."))),(0,l.kt)("p",null,"Additional Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"version")," An optional version of the contract to call. It will default to the highest enabled version if no value is specified.")),(0,l.kt)("h3",{id:"storedversioncontractbyname"},(0,l.kt)("inlineCode",{parentName:"h3"},"StoredVersionContractByName")),(0,l.kt)("p",null,"Stored versioned contract referenced by a named key existing in the signer's Account context, entry point and an instance of ",(0,l.kt)("inlineCode",{parentName:"p"},"RuntimeArgs"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#runtimeargs"},(0,l.kt)("inlineCode",{parentName:"a"},"args"))," Runtime arguments.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"entry_point")," The name of an entry point.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"name")," A named key."))),(0,l.kt)("p",null,"Additional Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"version")," An optional version of the contract to call. It will default to the highest enabled version if no value is specified.")),(0,l.kt)("h3",{id:"transfer"},(0,l.kt)("inlineCode",{parentName:"h3"},"Transfer")),(0,l.kt)("p",null,"A native transfer which does not contain or reference a Wasm code."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#runtimeargs"},(0,l.kt)("inlineCode",{parentName:"a"},"args")))),(0,l.kt)("h2",{id:"executioneffect"},"ExecutionEffect"),(0,l.kt)("p",null,"The journal of execution transforms from a single Deploy."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#oepration"},(0,l.kt)("inlineCode",{parentName:"a"},"operations")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#transformentry"},(0,l.kt)("inlineCode",{parentName:"a"},"transforms"))))),(0,l.kt)("h2",{id:"executionresult"},"ExecutionResult"),(0,l.kt)("p",null,"The result of executing a single Deploy."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Failure")," The result of a failed execution`"),(0,l.kt)("p",{parentName:"li"},"Required Parameters:"),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#executioneffect"},(0,l.kt)("inlineCode",{parentName:"a"},"effect"))),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#transferaddr"},(0,l.kt)("inlineCode",{parentName:"a"},"transfers"))),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"cost"))),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"error_message")," The error message associated with executing the Deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Success")," The result of a successful execution."),(0,l.kt)("p",{parentName:"li"},"Required Parameters:"),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#executioneffect"},(0,l.kt)("inlineCode",{parentName:"a"},"effect"))),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#transferaddr"},(0,l.kt)("inlineCode",{parentName:"a"},"transfers"))),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"cost"))))),(0,l.kt)("h2",{id:"finalizedapprovals"},"FinalizedApprovals"),(0,l.kt)("p",null,"A boolean value that determines whether to return the deploy with the finalized approvals substituted. If ",(0,l.kt)("inlineCode",{parentName:"p"},"false")," or omitted, returns the deploy with the approvals that were originally received by the node."),(0,l.kt)("h2",{id:"globalstateidentifier"},"GlobalStateIdentifier"),(0,l.kt)("p",null,"Identifier for possible ways to query global state."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"BlockHash"))," Query using a Block hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"StateRootHash"))," Query using the state root hash."))),(0,l.kt)("h2",{id:"group"},"Group"),(0,l.kt)("p",null,'A (labelled) "user group". Each entry point of a versioned contract may be associated with one or more user groups which are allowed to call it.'),(0,l.kt)("h3",{id:"groups"},"Groups"),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"group"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"keys"))))),(0,l.kt)("h2",{id:"jsonbid"},"JsonBid"),(0,l.kt)("p",null,"An entry in a founding validator map representing a bid."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"bonding_purse"))," The purse that was used for bonding.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"delegation_rate")," The delegation rate.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsondelegator"},(0,l.kt)("inlineCode",{parentName:"a"},"delegators"))," The delegators.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"inactive")," Is this an inactive validator.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"staked_amount"))," The amount of tokens staked by a validator (not including delegators)."))),(0,l.kt)("h2",{id:"jsonbids"},"JsonBids"),(0,l.kt)("p",null,"A Json representation of a single bid."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonbid"},(0,l.kt)("inlineCode",{parentName:"a"},"bid")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"public_key"))))),(0,l.kt)("h2",{id:"jsonblock"},"JsonBlock"),(0,l.kt)("p",null,"A JSON-friendly representation of ",(0,l.kt)("inlineCode",{parentName:"p"},"Block"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonblockbody"},(0,l.kt)("inlineCode",{parentName:"a"},"body"))," JSON-friendly Block body.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"hash"))," BlockHash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonblockheader"},(0,l.kt)("inlineCode",{parentName:"a"},"header"))," JSON-friendly Block header.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonproof"},(0,l.kt)("inlineCode",{parentName:"a"},"proofs"))," JSON-friendly list of proofs for this Block."))),(0,l.kt)("h2",{id:"jsonblockbody"},"JsonBlockBody"),(0,l.kt)("p",null,"A JSON-friendly representation of ",(0,l.kt)("inlineCode",{parentName:"p"},"Body"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployhash"},(0,l.kt)("inlineCode",{parentName:"a"},"deploy_hashes")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"proposer")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployhash"},(0,l.kt)("inlineCode",{parentName:"a"},"transfer_hashes"))))),(0,l.kt)("h2",{id:"jsonblockheader"},"JsonBlockHeader"),(0,l.kt)("p",null,"JSON representation of a Block header."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"accumulated_seed"))," Accumulated seed.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"body_hash"))," The body hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_id"))," The Block era id.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"height")," The Block height.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"parent_hash"))," The parent hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#protocolversion"},(0,l.kt)("inlineCode",{parentName:"a"},"protocol_version"))," The protocol version.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"random_bit")," Randomness bit.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"state_root_hash"))," The state root hash.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#timestamp"},(0,l.kt)("inlineCode",{parentName:"a"},"timestamp"))," The Block timestamp."))),(0,l.kt)("p",null,"Additional Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#jsoneraend"},(0,l.kt)("inlineCode",{parentName:"a"},"era_end"))," The era end.")),(0,l.kt)("h2",{id:"jsondelegator"},"JsonDelegator"),(0,l.kt)("p",null,"A delegator associated with the given validator."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"bonding_purse")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"delegatee")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"public_key")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"staked_amount"))))),(0,l.kt)("h2",{id:"jsoneraend"},"JsonEraEnd"),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonerareport"},"`era_report"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#validatorweight"},(0,l.kt)("inlineCode",{parentName:"a"},"next_era_validator_weight"))))),(0,l.kt)("h2",{id:"jsonerareport"},"JsonEraReport"),(0,l.kt)("p",null,"Equivocation and reward information to be included in the terminal Block."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"equivocators")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"inactive_validators")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#reward"},(0,l.kt)("inlineCode",{parentName:"a"},"rewards"))))),(0,l.kt)("h2",{id:"jsoneravalidators"},"JsonEraValidators"),(0,l.kt)("p",null,"The validators for the given era."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_id")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonvalidatorsweights"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_weights"))))),(0,l.kt)("h2",{id:"jsonexecutionresult"},"JsonExecutionResult"),(0,l.kt)("p",null,"The execution result of a single Deploy."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"block_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#executionresult"},(0,l.kt)("inlineCode",{parentName:"a"},"result"))))),(0,l.kt)("h2",{id:"jsonproof"},"JsonProof"),(0,l.kt)("p",null,"A JSON-friendly representation of a proof, i.e. a Block's finality signature."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"public_key")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#signature"},(0,l.kt)("inlineCode",{parentName:"a"},"signature"))))),(0,l.kt)("h2",{id:"jsonvalidatorchanges"},"JsonValidatorChanges"),(0,l.kt)("p",null,"The changes in a validator's status."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"public_key"))," The public key of the validator.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#jsonvalidatorstatuschange"},(0,l.kt)("inlineCode",{parentName:"a"},"status_changes"))," The set of changes to the validator's status."))),(0,l.kt)("h2",{id:"jsonvalidatorstatuschange"},"JsonValidatorStatusChange"),(0,l.kt)("p",null,"A single change to a validator's status in the given era."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_id"))," The era in which the change occurred.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#validatorchange"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_change"))," The change in validator status."))),(0,l.kt)("h2",{id:"jsonvalidatorweights"},"JsonValidatorsWeights"),(0,l.kt)("p",null,"A validator's weight."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"public_key")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"weight"))))),(0,l.kt)("h2",{id:"merkle-proof"},"Merkle_Proof"),(0,l.kt)("p",null,"A merkle proof is a construction created using a merkle trie that allows verification of the associated hashes."),(0,l.kt)("h2",{id:"minimalblockinfo"},"MinimalBlockInfo"),(0,l.kt)("p",null,"Minimal info of a ",(0,l.kt)("inlineCode",{parentName:"p"},"Block"),"."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"creator")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_id")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#blockhash"},(0,l.kt)("inlineCode",{parentName:"a"},"hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"height"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#digest"},(0,l.kt)("inlineCode",{parentName:"a"},"state_root_hash")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#timestamp"},(0,l.kt)("inlineCode",{parentName:"a"},"timestamp"))))),(0,l.kt)("h2",{id:"namedarg"},"NamedArg"),(0,l.kt)("p",null,"Named arguments to a contract."),(0,l.kt)("h2",{id:"namedkey"},"NamedKey"),(0,l.kt)("p",null,"A named key."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key")," The value of the entry: a casper ",(0,l.kt)("inlineCode",{parentName:"p"},"Key")," type.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"name")," The name of the entry."))),(0,l.kt)("h2",{id:"nextupgrade"},"NextUpgrade"),(0,l.kt)("p",null,"Information about the next protocol upgrade."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#activationpoint"},(0,l.kt)("inlineCode",{parentName:"a"},"activation_point")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"protocol_version")))),(0,l.kt)("h2",{id:"newvalidator"},"NewValidator"),(0,l.kt)("p",null,"The public key for the new validator in a redelegation using ",(0,l.kt)("a",{parentName:"p",href:"#unbondingpurse"},"UnbondingPurse"),"."),(0,l.kt)("h2",{id:"operation"},"Operation"),(0,l.kt)("p",null,"An operation performed while executing a Deploy."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key")," The formatted string of the ",(0,l.kt)("inlineCode",{parentName:"p"},"Key"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#opkind"},(0,l.kt)("inlineCode",{parentName:"a"},"kind"))))),(0,l.kt)("h2",{id:"opkind"},"OpKind"),(0,l.kt)("p",null,"The type of operation performed while executing a Deploy."),(0,l.kt)("h2",{id:"parameter"},"Parameter"),(0,l.kt)("p",null,"Parameter to an entry point."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#cltype"},(0,l.kt)("inlineCode",{parentName:"a"},"cl_type")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"name")))),(0,l.kt)("h2",{id:"peerentry"},"PeerEntry"),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"address"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"node_id")))),(0,l.kt)("h2",{id:"peersmap"},"PeersMap"),(0,l.kt)("p",null,"Map of peer IDs to network addresses."),(0,l.kt)("h2",{id:"protocolversion"},"ProtocolVersion"),(0,l.kt)("p",null,"Casper Platform protocol version."),(0,l.kt)("h2",{id:"publickey"},"PublicKey"),(0,l.kt)("p",null,"Hex-encoded cryptographic public key, including the algorithm tag prefix."),(0,l.kt)("h2",{id:"purseidentifier"},"PurseIdentifier"),(0,l.kt)("p",null,"The identifier to obtain the purse corresponding to a balance query. Valid identifiers include:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"main_purse_under_public_key")," The main purse under a provided ",(0,l.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_chain#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"PublicKey")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"main_purse_under_account_hash")," The main purse under a provided ",(0,l.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_chain#accounthash"},(0,l.kt)("inlineCode",{parentName:"a"},"AccountHash")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"purse_uref")," A specific purse identified by the associated ",(0,l.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_chain#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"URef")),"."))),(0,l.kt)("h2",{id:"reactorstate"},"ReactorState"),(0,l.kt)("p",null,"The state of the reactor, which will return one of the following:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Initialize")," Get all components and reactor state set up on start.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"CatchUp")," Orient to the network and attempt to catch up to tip.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Upgrading")," Running commit upgrade and creating immediate switch block.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"KeepUp")," Stay caught up with tip.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Validate")," Node is currently caught up and is an active validator.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"ShutdownForUpgrade")," Node should be shut down for upgrade."))),(0,l.kt)("h2",{id:"reward"},"Reward"),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"amount"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator"))))),(0,l.kt)("h2",{id:"runtimeargs"},"RuntimeArgs"),(0,l.kt)("p",null,"Represents a collection of arguments passed to a smart contract."),(0,l.kt)("h2",{id:"seigniorageallocation"},"SeigniorageAllocation"),(0,l.kt)("p",null,"Information about a seigniorage allocation."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Validator")," Info about a seigniorage allocation for a validator."),(0,l.kt)("p",{parentName:"li"},"Required Parameters:"),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"amount"))," Allocated amount."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_public_key"))," Validator's public key.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Delegator")," Info about a seigniorage allocation for a delegator."),(0,l.kt)("p",{parentName:"li"},"Require Parameters:"),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"amount"))," Allocated amount."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"delegator_public_key"))," Delegator's public key."),(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_public_key"))," Validator's public key."))),(0,l.kt)("h2",{id:"signature"},"Signature"),(0,l.kt)("p",null,"Hex-encoded cryptographic signature, including the algorithm tag prefix."),(0,l.kt)("h2",{id:"storedvalue"},"StoredValue"),(0,l.kt)("p",null,"Representation of a value stored in global state. ",(0,l.kt)("inlineCode",{parentName:"p"},"Account"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"Contract")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"ContractPackage")," have their own ",(0,l.kt)("inlineCode",{parentName:"p"},"json_compatibility")," representation (see their docs for further info)."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#clvalue"},(0,l.kt)("inlineCode",{parentName:"a"},"CLValue"))," A Casper-specific value.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#account"},(0,l.kt)("inlineCode",{parentName:"a"},"Account"))," An Account.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"ContractWasm")," A contract's Wasm.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#contract"},(0,l.kt)("inlineCode",{parentName:"a"},"Contract"))," Entry points supported by a contract.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#contractpackage"},(0,l.kt)("inlineCode",{parentName:"a"},"ContractPackage"))," A contract definition, metadata, and security container.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#transfer"},(0,l.kt)("inlineCode",{parentName:"a"},"Transfer"))," A record of a transfer.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployinfo"},(0,l.kt)("inlineCode",{parentName:"a"},"DeployInfo"))," A record of a Deploy.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#erainfo"},(0,l.kt)("inlineCode",{parentName:"a"},"EraInfo"))," Auction metadata.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#bid-bid"},(0,l.kt)("inlineCode",{parentName:"a"},"Bid"))," A bid.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#unbondingpurse"},(0,l.kt)("inlineCode",{parentName:"a"},"Withdraw"))," A withdraw."))),(0,l.kt)("h2",{id:"timediff"},"TimeDiff"),(0,l.kt)("p",null,"Human-readable duration."),(0,l.kt)("h2",{id:"timestamp"},"Timestamp"),(0,l.kt)("p",null,"Timestamp formatted as per RFC 3339."),(0,l.kt)("h2",{id:"transfer"},"Transfer"),(0,l.kt)("p",null,"Represents a transfer from one purse to another."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"amount"))," Transfer amount.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#deployhash"},(0,l.kt)("inlineCode",{parentName:"a"},"deploy_hash"))," Deploy that created the transfer.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#accounthash"},(0,l.kt)("inlineCode",{parentName:"a"},"from"))," Account from which transfer was executed.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"gas")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"source"))," Source purse.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"target"))," Target purse."))),(0,l.kt)("p",null,"Additional Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"id")," User-defined ID.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#accounthash"},(0,l.kt)("inlineCode",{parentName:"a"},"to"))," Account to which funds are transferred."))),(0,l.kt)("h2",{id:"transferaddr"},"TransferAddr"),(0,l.kt)("p",null,"Hex-encoded transfer address."),(0,l.kt)("h2",{id:"transform"},"Transform"),(0,l.kt)("p",null,"The actual transformation performed while executing a Deploy."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"WriteCLValue")," Write the given ",(0,l.kt)("a",{parentName:"p",href:"#clvalue"},"CLValue")," to global state.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"WriteAccount")," Writes the given ",(0,l.kt)("a",{parentName:"p",href:"#accounthash"},"Account")," to global state.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"WriteDeployInfo")," Writes the given ",(0,l.kt)("a",{parentName:"p",href:"#deployinfo"},"DeployInfo")," to global state.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"WriteEraInfo")," Writes the given ",(0,l.kt)("a",{parentName:"p",href:"#erainfo"},"EraInfo")," to global state.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"WriteTransfer")," Writes the given ",(0,l.kt)("a",{parentName:"p",href:"#transfer"},"Transfer")," to global state.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"WriteBid")," Writes the given ",(0,l.kt)("a",{parentName:"p",href:"#bid"},"Bid")," to global state.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"WriteWithdraw")," Writes the given ",(0,l.kt)("a",{parentName:"p",href:"#unbondingpurse"},"Withdraw")," to global state.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"AddInt32")," Adds the given ",(0,l.kt)("inlineCode",{parentName:"p"},"i32"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"AddUInt64")," Adds the given ",(0,l.kt)("inlineCode",{parentName:"p"},"u64"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"AddUInt128")," Adds the given ",(0,l.kt)("a",{parentName:"p",href:"#u128"},(0,l.kt)("inlineCode",{parentName:"a"},"U128")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"AddUInt256")," Adds the given ",(0,l.kt)("a",{parentName:"p",href:"#u256"},(0,l.kt)("inlineCode",{parentName:"a"},"U256")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"AddUInt512")," Adds the given ",(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"U512")),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"AddKeys")," Adds the given collection of ",(0,l.kt)("a",{parentName:"p",href:"#namedkey"},"named keys"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Failure")," A failed transformation, containing an error message."))),(0,l.kt)("h2",{id:"transformentry"},"TransformEntry"),(0,l.kt)("p",null,"A transformation performed while executing a Deploy."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"key")," The formatted string of the ",(0,l.kt)("inlineCode",{parentName:"p"},"Key"),".")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#transform"},(0,l.kt)("inlineCode",{parentName:"a"},"transforms"))," The transformation."))),(0,l.kt)("h2",{id:"u128"},"U128"),(0,l.kt)("p",null,"Decimal representation of a 128-bit integer."),(0,l.kt)("h2",{id:"u256"},"U256"),(0,l.kt)("p",null,"Decimal representation of a 256-bit integer."),(0,l.kt)("h2",{id:"u512"},"U512"),(0,l.kt)("p",null,"Decimal representation of a 512-bit integer."),(0,l.kt)("h2",{id:"unbondingpurse"},"UnbondingPurse"),(0,l.kt)("p",null,"Unbonding purse."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"amount"))," Unbonding amount.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"bonding_purse"))," Bonding purse.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_of_creation"))," Era in which the unbonding request was created.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"unbonder_public_key"))," Unbonder's public key.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_public_key"))," The original validator's public key.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#newvalidator"},(0,l.kt)("inlineCode",{parentName:"a"},"new_validator"))," The redelegated validator's public key."))),(0,l.kt)("h2",{id:"uref"},"URef"),(0,l.kt)("p",null,"Hex-encoded, formatted URef."),(0,l.kt)("h2",{id:"validatorchange"},"ValidatorChange"),(0,l.kt)("p",null,"A change to a validator's status between two eras."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Added"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Removed"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"Banned"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"CannotPropose"))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("inlineCode",{parentName:"p"},"SeenAsFaulty")))),(0,l.kt)("h2",{id:"validatorweight"},"ValidatorWeight"),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"weight"))))),(0,l.kt)("h2",{id:"vestingschedule"},"VestingSchedule"),(0,l.kt)("p",null,"Vesting schedule for a genesis validator."),(0,l.kt)("h2",{id:"withdrawpurse"},"WithdrawPurse"),(0,l.kt)("p",null,"Withdraw purse, previously known as unbonding purse prior to 1.5. Withdraw purses remain as historical data."),(0,l.kt)("p",null,"Required Parameters:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#u512"},(0,l.kt)("inlineCode",{parentName:"a"},"amount"))," Unbonding amount.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#uref"},(0,l.kt)("inlineCode",{parentName:"a"},"bonding_purse"))," Bonding purse.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#eraid"},(0,l.kt)("inlineCode",{parentName:"a"},"era_of_creation"))," Era in which the unbonding request was created.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"unbonder_public_key"))," Unbonder's public key.")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("p",{parentName:"li"},(0,l.kt)("a",{parentName:"p",href:"#publickey"},(0,l.kt)("inlineCode",{parentName:"a"},"validator_public_key"))," The original validator's public key."))))}N.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c305f31a.43db811a.js b/assets/js/c305f31a.f0b2b03b.js similarity index 99% rename from assets/js/c305f31a.43db811a.js rename to assets/js/c305f31a.f0b2b03b.js index 2c39b8f9fa..792e15911e 100644 --- a/assets/js/c305f31a.43db811a.js +++ b/assets/js/c305f31a.f0b2b03b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6646],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=d(n),h=o,m=c["".concat(s,".").concat(h)]||c[h]||u[h]||r;return n?a.createElement(m,i(i({ref:t},p),{},{components:n})):a.createElement(m,i({ref:t},p))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:o,i[1]=l;for(var d=2;d \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-hash \\\n--session-entry-point undelegate \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"delegator:public_key=''\"\n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,r.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,r.kt)("em",{parentName:"li"},"casper-test")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-hash")," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Testnet"),": ",(0,r.kt)("inlineCode",{parentName:"li"},"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Mainnet"),": ",(0,r.kt)("inlineCode",{parentName:"li"},"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"))),(0,r.kt)("ol",{start:6},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-entry-point")," - Name of the entry point that will be used when calling the contract")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"undelegate")," entry point expects three arguments:"),(0,r.kt)("ol",{start:7},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"validator"),": The hexadecimal public key of the validator from whom the tokens will be undelegated"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"amount"),": The number of tokens to be undelegated"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"delegator"),": The hexadecimal public key of the account undelegating tokens from a validator. ",(0,r.kt)("strong",{parentName:"li"},"This key must match the secret key that signs the delegation"))),(0,r.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,r.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#deploy-status"},"Deploy Status")," section for more details."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"undelegate")," entry point on the auction contract has a fixed cost of 2.5 CSPR. There is no minimum amount required for the undelegation call.")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Example:")),(0,r.kt)("p",null,"This example shows an account delegating 100 CSPR:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point undelegate \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='100000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n")),(0,r.kt)("p",null,"Next, ",(0,r.kt)("a",{parentName:"p",href:"#verifying-the-undelegation"},"confirm the undelegation"),"."),(0,r.kt)("h3",{id:"undelegating-compiled-wasm"},"Method 2: Undelegating with Compiled Wasm"),(0,r.kt)("p",null,"As part of this process, you need to ",(0,r.kt)("a",{parentName:"p",href:"/developers/cli/delegate#building-the-delegation-wasm"},"build the casper-node contracts")," that produce the undelegation Wasm."),(0,r.kt)("p",null,"Next, use the Casper CLI client to send a deploy containing the ",(0,r.kt)("inlineCode",{parentName:"p"},"undelegate.wasm")," to the network to initiate the undelegation process."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-path /undelegate.wasm \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"delegator:public_key=''\"\n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,r.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,r.kt)("em",{parentName:"li"},"casper-test")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to where the ",(0,r.kt)("inlineCode",{parentName:"li"},"delegate.wasm")," is located")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"undelegate")," entry point expects three arguments:"),(0,r.kt)("ol",{start:6},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"validator"),": The hexadecimal public key of the validator from whom the tokens will be undelegated"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"amount"),": The number of tokens to be undelegated"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"delegator"),": The hexadecimal public key of the account undelegating tokens from a validator. ",(0,r.kt)("strong",{parentName:"li"},"This key must match the secret key that signs the delegation"))),(0,r.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,r.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#deploy-status"},"Deploy Status")," section for more details."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Example:")),(0,r.kt)("p",null,"This example command uses the Casper Testnet to undelegate 100 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),". However, notice that this method is more expensive than the previous one that calls the undelegate entry point."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 6000000000 \\\n--session-path ~/undelegate.wasm \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='100000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n")),(0,r.kt)("p",null,"Next, ",(0,r.kt)("a",{parentName:"p",href:"#verifying-the-undelegation"},"confirm the undelegation"),"."),(0,r.kt)("h2",{id:"verifying-the-undelegation"},"Verifying the Undelegation"),(0,r.kt)("p",null,"To verify that the undelegation succeeded, you can use the Casper command-line client to generate an RPC request to query the auction state. The subsequent RPC response will confirm that the undelegation request was successfully processed."),(0,r.kt)("p",null,"Here is how you can check the status of the auction to confirm that your bid was withdrawn:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-auction-info \\\n--node-address http://:7777\n")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Request fields"),":"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network")),(0,r.kt)("p",null,"If the public key and the amount are absent from the ",(0,r.kt)("inlineCode",{parentName:"p"},"bids")," structure, we can safely conclude that we have indeed undelegated from the validator."),(0,r.kt)("p",null,"If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been added to your balance:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"https://testnet.cspr.live/"},"Testnet explorer")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"https://cspr.live/"},"Mainnet explorer"))),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Important Note"),": After undelegating tokens from a validator, you must wait for the unbonding period to lapse before redelegating tokens to either the same validator or a different validator."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6646],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return m}});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=d(n),h=o,m=c["".concat(s,".").concat(h)]||c[h]||u[h]||r;return n?a.createElement(m,i(i({ref:t},p),{},{components:n})):a.createElement(m,i({ref:t},p))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:o,i[1]=l;for(var d=2;d \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-hash \\\n--session-entry-point undelegate \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"delegator:public_key=''\"\n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,r.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,r.kt)("em",{parentName:"li"},"casper-test")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-hash")," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Testnet"),": ",(0,r.kt)("inlineCode",{parentName:"li"},"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Mainnet"),": ",(0,r.kt)("inlineCode",{parentName:"li"},"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"))),(0,r.kt)("ol",{start:6},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-entry-point")," - Name of the entry point that will be used when calling the contract")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"undelegate")," entry point expects three arguments:"),(0,r.kt)("ol",{start:7},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"validator"),": The hexadecimal public key of the validator from whom the tokens will be undelegated"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"amount"),": The number of tokens to be undelegated"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"delegator"),": The hexadecimal public key of the account undelegating tokens from a validator. ",(0,r.kt)("strong",{parentName:"li"},"This key must match the secret key that signs the delegation"))),(0,r.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,r.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#deploy-status"},"Deploy Status")," section for more details."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Calling the ",(0,r.kt)("inlineCode",{parentName:"p"},"undelegate")," entry point on the auction contract has a fixed cost of 2.5 CSPR. There is no minimum amount required for the undelegation call.")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Example:")),(0,r.kt)("p",null,"This example shows an account delegating 100 CSPR:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point undelegate \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='100000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n")),(0,r.kt)("p",null,"Next, ",(0,r.kt)("a",{parentName:"p",href:"#verifying-the-undelegation"},"confirm the undelegation"),"."),(0,r.kt)("h3",{id:"undelegating-compiled-wasm"},"Method 2: Undelegating with Compiled Wasm"),(0,r.kt)("p",null,"As part of this process, you need to ",(0,r.kt)("a",{parentName:"p",href:"/developers/cli/delegate#building-the-delegation-wasm"},"build the casper-node contracts")," that produce the undelegation Wasm."),(0,r.kt)("p",null,"Next, use the Casper CLI client to send a deploy containing the ",(0,r.kt)("inlineCode",{parentName:"p"},"undelegate.wasm")," to the network to initiate the undelegation process."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-path /undelegate.wasm \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"delegator:public_key=''\"\n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,r.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,r.kt)("em",{parentName:"li"},"casper-test")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to where the ",(0,r.kt)("inlineCode",{parentName:"li"},"delegate.wasm")," is located")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"undelegate")," entry point expects three arguments:"),(0,r.kt)("ol",{start:6},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"validator"),": The hexadecimal public key of the validator from whom the tokens will be undelegated"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"amount"),": The number of tokens to be undelegated"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"delegator"),": The hexadecimal public key of the account undelegating tokens from a validator. ",(0,r.kt)("strong",{parentName:"li"},"This key must match the secret key that signs the delegation"))),(0,r.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,r.kt)("a",{parentName:"p",href:"/resources/tutorials/beginner/querying-network#deploy-status"},"Deploy Status")," section for more details."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Example:")),(0,r.kt)("p",null,"This example command uses the Casper Testnet to undelegate 100 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),". However, notice that this method is more expensive than the previous one that calls the undelegate entry point."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 6000000000 \\\n--session-path ~/undelegate.wasm \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='100000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n")),(0,r.kt)("p",null,"Next, ",(0,r.kt)("a",{parentName:"p",href:"#verifying-the-undelegation"},"confirm the undelegation"),"."),(0,r.kt)("h2",{id:"verifying-the-undelegation"},"Verifying the Undelegation"),(0,r.kt)("p",null,"To verify that the undelegation succeeded, you can use the Casper command-line client to generate an RPC request to query the auction state. The subsequent RPC response will confirm that the undelegation request was successfully processed."),(0,r.kt)("p",null,"Here is how you can check the status of the auction to confirm that your bid was withdrawn:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-auction-info \\\n--node-address http://:7777\n")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Request fields"),":"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network")),(0,r.kt)("p",null,"If the public key and the amount are absent from the ",(0,r.kt)("inlineCode",{parentName:"p"},"bids")," structure, we can safely conclude that we have indeed undelegated from the validator."),(0,r.kt)("p",null,"If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been added to your balance:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"https://testnet.cspr.live/"},"Testnet explorer")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"https://cspr.live/"},"Mainnet explorer"))),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Important Note"),": After undelegating tokens from a validator, you must wait for the unbonding period to lapse before redelegating tokens to either the same validator or a different validator."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c5563497.4e4e7f6c.js b/assets/js/c5563497.c7eea0a4.js similarity index 99% rename from assets/js/c5563497.4e4e7f6c.js rename to assets/js/c5563497.c7eea0a4.js index 4f45b21aa4..2e31934cc7 100644 --- a/assets/js/c5563497.4e4e7f6c.js +++ b/assets/js/c5563497.c7eea0a4.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[2894],{3905:function(e,t,r){r.d(t,{Zo:function(){return c},kt:function(){return h}});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function s(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),p=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},c=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=p(r),m=n,h=d["".concat(l,".").concat(m)]||d[m]||u[m]||o;return r?a.createElement(h,s(s({ref:t},c),{},{components:r})):a.createElement(h,s({ref:t},c))}));function h(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,s=new Array(o);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[d]="string"==typeof e?e:n,s[1]=i;for(var p=2;p=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),p=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},c=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=p(r),m=n,h=d["".concat(l,".").concat(m)]||d[m]||u[m]||o;return r?a.createElement(h,s(s({ref:t},c),{},{components:r})):a.createElement(h,s({ref:t},c))}));function h(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,s=new Array(o);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[d]="string"==typeof e?e:n,s[1]=i;for(var p=2;p=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var c=a.createContext({}),l=function(e){var t=a.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,i=p(e,["components","mdxType","originalType","parentName"]),u=l(r),d=n,y=u["".concat(c,".").concat(d)]||u[d]||f[d]||o;return r?a.createElement(y,s(s({ref:t},i),{},{components:r})):a.createElement(y,s({ref:t},i))}));function y(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,s=new Array(o);s[0]=d;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[u]="string"==typeof e?e:n,s[1]=p;for(var l=2;l=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var c=a.createContext({}),l=function(e){var t=a.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,i=p(e,["components","mdxType","originalType","parentName"]),u=l(r),d=n,y=u["".concat(c,".").concat(d)]||u[d]||f[d]||o;return r?a.createElement(y,s(s({ref:t},i),{},{components:r})):a.createElement(y,s({ref:t},i))}));function y(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,s=new Array(o);s[0]=d;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[u]="string"==typeof e?e:n,s[1]=p;for(var l=2;l=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),s=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=s(n),m=a,g=u["".concat(c,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(g,l(l({ref:t},p),{},{components:n})):r.createElement(g,l({ref:t},p))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=m;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:a,l[1]=i;for(var s=2;s=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),s=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=s(n),m=a,g=u["".concat(c,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(g,l(l({ref:t},p),{},{components:n})):r.createElement(g,l({ref:t},p))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=m;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:a,l[1]=i;for(var s=2;s=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var p=a.createContext({}),i=function(e){var t=a.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},l=function(e){var t=i(e.components);return a.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=i(r),h=n,m=u["".concat(p,".").concat(h)]||u[h]||f[h]||o;return r?a.createElement(m,c(c({ref:t},l),{},{components:r})):a.createElement(m,c({ref:t},l))}));function m(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,c=new Array(o);c[0]=h;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:n,c[1]=s;for(var i=2;i=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var p=a.createContext({}),i=function(e){var t=a.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},l=function(e){var t=i(e.components);return a.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=i(r),h=n,m=u["".concat(p,".").concat(h)]||u[h]||f[h]||o;return r?a.createElement(m,c(c({ref:t},l),{},{components:r})):a.createElement(m,c({ref:t},l))}));function m(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,c=new Array(o);c[0]=h;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:n,c[1]=s;for(var i=2;i=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=i.createContext({}),l=function(e){var t=i.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},h=function(e){var t=l(e.components);return i.createElement(c.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},u=i.forwardRef((function(e,t){var a=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,h=s(e,["components","mdxType","originalType","parentName"]),d=l(a),u=n,f=d["".concat(c,".").concat(u)]||d[u]||p[u]||r;return a?i.createElement(f,o(o({ref:t},h),{},{components:a})):i.createElement(f,o({ref:t},h))}));function f(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=a.length,o=new Array(r);o[0]=u;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:n,o[1]=s;for(var l=2;l=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=i.createContext({}),l=function(e){var t=i.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},h=function(e){var t=l(e.components);return i.createElement(c.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},u=i.forwardRef((function(e,t){var a=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,h=s(e,["components","mdxType","originalType","parentName"]),d=l(a),u=n,f=d["".concat(c,".").concat(u)]||d[u]||p[u]||r;return a?i.createElement(f,o(o({ref:t},h),{},{components:a})):i.createElement(f,o({ref:t},h))}));function f(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=a.length,o=new Array(r);o[0]=u;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:n,o[1]=s;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},g=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),c=u(r),g=a,m=c["".concat(s,".").concat(g)]||c[g]||d[g]||l;return r?n.createElement(m,i(i({ref:t},p),{},{components:r})):n.createElement(m,i({ref:t},p))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,i=new Array(l);i[0]=g;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[c]="string"==typeof e?e:a,i[1]=o;for(var u=2;u=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},g=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),c=u(r),g=a,m=c["".concat(s,".").concat(g)]||c[g]||d[g]||l;return r?n.createElement(m,i(i({ref:t},p),{},{components:r})):n.createElement(m,i({ref:t},p))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,i=new Array(l);i[0]=g;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[c]="string"==typeof e?e:a,i[1]=o;for(var u=2;u=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var m=n.createContext({}),s=function(t){var e=n.useContext(m),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},p=function(t){var e=s(t.components);return n.createElement(m.Provider,{value:e},t.children)},d="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},k=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,m=t.parentName,p=o(t,["components","mdxType","originalType","parentName"]),d=s(a),k=r,g=d["".concat(m,".").concat(k)]||d[k]||u[k]||l;return a?n.createElement(g,i(i({ref:e},p),{},{components:a})):n.createElement(g,i({ref:e},p))}));function g(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=k;var o={};for(var m in e)hasOwnProperty.call(e,m)&&(o[m]=e[m]);o.originalType=t,o[d]="string"==typeof t?t:r,i[1]=o;for(var s=2;s 50% + F/2 \u2014 see the ",(0,l.kt)("inlineCode",{parentName:"td"},"finality_threshold_fraction")," below) of validator nodes must be running to start the blockchain. This timestamp is also used in seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash. ",(0,l.kt)("br",null),(0,l.kt)("br",null),"If it is an integer, it represents an era ID, meaning the protocol version becomes active at the start of this era."),(0,l.kt)("td",{parentName:"tr",align:null},"9100")))),(0,l.kt)("h2",{id:"network"},"network"),(0,l.kt)("p",null,"The following settings configure the networking layer."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"name"),(0,l.kt)("td",{parentName:"tr",align:null},"Human readable network name for convenience. The state_root_hash of the genesis block is the true identifier. The name influences the genesis hash by contributing to seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash."),(0,l.kt)("td",{parentName:"tr",align:null},"'casper'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"maximum_net_message_size"),(0,l.kt)("td",{parentName:"tr",align:null},"The maximum size of an acceptable networking message in bytes. Any message larger than this will be rejected at the networking level."),(0,l.kt)("td",{parentName:"tr",align:null},"25_165_824")))),(0,l.kt)("h2",{id:"core"},"core"),(0,l.kt)("p",null,"These settings manage the core protocol behavior."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"era_duration"),(0,l.kt)("td",{parentName:"tr",align:null},"Era duration."),(0,l.kt)("td",{parentName:"tr",align:null},"'120min'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"minimum_era_height"),(0,l.kt)("td",{parentName:"tr",align:null},"Minimum number of blocks per era. An era will take longer than ",(0,l.kt)("inlineCode",{parentName:"td"},"era_duration")," if that is necessary to reach the minimum height."),(0,l.kt)("td",{parentName:"tr",align:null},"20")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"minimum_block_time"),(0,l.kt)("td",{parentName:"tr",align:null},"Minimum difference between a block's and its child's timestamp."),(0,l.kt)("td",{parentName:"tr",align:null},"'16384ms'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"validator_slots"),(0,l.kt)("td",{parentName:"tr",align:null},"Number of slots available in the validator auction."),(0,l.kt)("td",{parentName:"tr",align:null},"100")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"finality_threshold_fraction"),(0,l.kt)("td",{parentName:"tr",align:null},"A number between 0 and 1 representing the fault tolerance threshold as a fraction used by the internal finalizer.",(0,l.kt)("br",null),"It is the fraction of validators that would need to equivocate to make two honest nodes see two conflicting blocks as finalized.",(0,l.kt)("br",null),"Let's say this value is F. A higher value F makes it safer to rely on finalized blocks. It also makes it more difficult to finalize blocks, however, and requires strictly more than (F + 1)/2 validators to be working correctly."),(0,l.kt)("td",{parentName:"tr",align:null},"[1, 3]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"start_protocol_version_with_strict",(0,l.kt)("br",null),"_","finality_signatures_required"),(0,l.kt)("td",{parentName:"tr",align:null},"Protocol version from which nodes are required to hold strict finality signatures."),(0,l.kt)("td",{parentName:"tr",align:null},"'1.5.0'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"legacy_required_finality"),(0,l.kt)("td",{parentName:"tr",align:null},"The finality required for legacy blocks. Options are 'Strict', 'Weak', and 'Any'. ",(0,l.kt)("br",null),"Used to determine finality sufficiency for new joiners syncing blocks created in a protocol version before the start protocol version with strict finality signatures."),(0,l.kt)("td",{parentName:"tr",align:null},"'Strict'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"auction_delay"),(0,l.kt)("td",{parentName:"tr",align:null},"Number of eras before an auction defines the set of validators. If a validator bonds with a sufficient bid in era N, it will be a validator in era N + auction_delay + 1."),(0,l.kt)("td",{parentName:"tr",align:null},"1")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"locked_funds_period"),(0,l.kt)("td",{parentName:"tr",align:null},"The period after genesis during which a genesis validator's bid is locked."),(0,l.kt)("td",{parentName:"tr",align:null},"'90days'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"vesting_schedule_period"),(0,l.kt)("td",{parentName:"tr",align:null},"The period in which the genesis validator's bid is released over time after it is unlocked."),(0,l.kt)("td",{parentName:"tr",align:null},"'13 weeks'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"unbonding_delay"),(0,l.kt)("td",{parentName:"tr",align:null},"Default number of eras that need to pass to be able to withdraw unbonded funds."),(0,l.kt)("td",{parentName:"tr",align:null},"7")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"round_seigniorage_rate"),(0,l.kt)("td",{parentName:"tr",align:null},"Round seigniorage rate represented as a fraction of the total supply.",(0,l.kt)("br",null),"- Annual issuance: 8%.",(0,l.kt)("br",null),"- Minimum block time: 2^15 milliseconds.",(0,l.kt)("br",null),"- Ticks per year: 31536000000.",(0,l.kt)("br",null),(0,l.kt)("br",null),"(1+0.08)^((2^15)/31536000000)-1 is expressed as a fractional number below in Python:",(0,l.kt)("br",null),(0,l.kt)("inlineCode",{parentName:"td"},"Fraction((1 + 0.08)**((2**15)/31536000000) - 1).limit_denominator(1000000000)")),(0,l.kt)("td",{parentName:"tr",align:null},"[7, 87535408]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_associated_keys"),(0,l.kt)("td",{parentName:"tr",align:null},"Maximum number of associated keys for a single account."),(0,l.kt)("td",{parentName:"tr",align:null},"100")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_runtime_call_stack_height"),(0,l.kt)("td",{parentName:"tr",align:null},"Maximum height of the contract runtime call stack."),(0,l.kt)("td",{parentName:"tr",align:null},"12")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"minimum_delegation_amount"),(0,l.kt)("td",{parentName:"tr",align:null},"Minimum allowed delegation amount in motes."),(0,l.kt)("td",{parentName:"tr",align:null},"500_000_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"prune_batch_size"),(0,l.kt)("td",{parentName:"tr",align:null},"Global state prune batch size for tip pruning in version 1.4.15. Possible values:",(0,l.kt)("br",null),"- 0 when the feature is OFF",(0,l.kt)("br",null),"- Integer if the feature is ON, representing the number of eras to process per block."),(0,l.kt)("td",{parentName:"tr",align:null},"0")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"strict_argument_checking"),(0,l.kt)("td",{parentName:"tr",align:null},"Enables strict arguments checking when calling a contract; i.e., all non-optional args are provided and they are of the correct ",(0,l.kt)("inlineCode",{parentName:"td"},"CLType"),"."),(0,l.kt)("td",{parentName:"tr",align:null},"false")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"simultaneous_peer_requests"),(0,l.kt)("td",{parentName:"tr",align:null},"Number of simultaneous peer requests."),(0,l.kt)("td",{parentName:"tr",align:null},"5")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"consensus_protocol"),(0,l.kt)("td",{parentName:"tr",align:null},"The consensus protocol to use. Options are 'Zug' or 'Highway'."),(0,l.kt)("td",{parentName:"tr",align:null},"'Highway'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_delegators_per_validator"),(0,l.kt)("td",{parentName:"tr",align:null},"The maximum amount of delegators per validator. If the value is 0, there is no maximum capacity."),(0,l.kt)("td",{parentName:"tr",align:null},"1200")))),(0,l.kt)("h2",{id:"highway"},"highway"),(0,l.kt)("p",null,"These settings configure the Highway Consensus protocol."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"maximum_round_length"),(0,l.kt)("td",{parentName:"tr",align:null},"Highway dynamically chooses its round length between ",(0,l.kt)("inlineCode",{parentName:"td"},"minimum_block_time")," and ",(0,l.kt)("inlineCode",{parentName:"td"},"maximum_round_length"),"."),(0,l.kt)("td",{parentName:"tr",align:null},"'132seconds'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"reduced_reward_multiplier"),(0,l.kt)("td",{parentName:"tr",align:null},"The factor by which rewards for a round are multiplied if the greatest summit has \u226450% quorum, i.e., no finality. Expressed as a fraction (1/5 by default on Mainnet)."),(0,l.kt)("td",{parentName:"tr",align:null},"[1, 5]")))),(0,l.kt)("h2",{id:"deploys"},"deploys"),(0,l.kt)("p",null,"These settings manage deploys and their lifecycle."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_payment_cost"),(0,l.kt)("td",{parentName:"tr",align:null},"The maximum number of motes allowed to be spent during payment. 0 means unlimited."),(0,l.kt)("td",{parentName:"tr",align:null},"'0'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_ttl"),(0,l.kt)("td",{parentName:"tr",align:null},"The duration after the deploy timestamp during which the deploy can be included in a block."),(0,l.kt)("td",{parentName:"tr",align:null},"'18hours'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_dependencies"),(0,l.kt)("td",{parentName:"tr",align:null},"The maximum number of other deploys a deploy can depend on (requiring them to have been executed before it can execute)."),(0,l.kt)("td",{parentName:"tr",align:null},"10")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_block_size"),(0,l.kt)("td",{parentName:"tr",align:null},"Maximum block size in bytes, including deploys contained by the block. 0 means unlimited."),(0,l.kt)("td",{parentName:"tr",align:null},"10_485_760")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_deploy_size"),(0,l.kt)("td",{parentName:"tr",align:null},"Maximum deploy size in bytes. Size is of the deploy when serialized via ToBytes."),(0,l.kt)("td",{parentName:"tr",align:null},"1_048_576")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"block_max_deploy_count"),(0,l.kt)("td",{parentName:"tr",align:null},"The maximum number of non-transfer deploys permitted in a single block."),(0,l.kt)("td",{parentName:"tr",align:null},"50")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"block_max_transfer_count"),(0,l.kt)("td",{parentName:"tr",align:null},"The maximum number of Wasm-less transfer deploys permitted in a single block."),(0,l.kt)("td",{parentName:"tr",align:null},"1250")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"block_max_approval_count"),(0,l.kt)("td",{parentName:"tr",align:null},"The maximum number of approvals permitted in a single block."),(0,l.kt)("td",{parentName:"tr",align:null},"2600")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"block_gas_limit"),(0,l.kt)("td",{parentName:"tr",align:null},"The upper limit of the total gas of all deploys in a block."),(0,l.kt)("td",{parentName:"tr",align:null},"4_000_000_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"payment_args_max_length"),(0,l.kt)("td",{parentName:"tr",align:null},"The limit of length of serialized payment code arguments."),(0,l.kt)("td",{parentName:"tr",align:null},"1024")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"session_args_max_length"),(0,l.kt)("td",{parentName:"tr",align:null},"The limit of length of serialized session code arguments."),(0,l.kt)("td",{parentName:"tr",align:null},"1024")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"native_transfer_minimum_motes"),(0,l.kt)("td",{parentName:"tr",align:null},"The minimum amount in motes for a valid native transfer."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")))),(0,l.kt)("h2",{id:"wasm"},"wasm"),(0,l.kt)("p",null,"The following are Wasm-related settings."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_memory"),(0,l.kt)("td",{parentName:"tr",align:null},"Amount of free memory (in 64 kB pages) each contract can use for its stack."),(0,l.kt)("td",{parentName:"tr",align:null},"64")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_stack_height"),(0,l.kt)("td",{parentName:"tr",align:null},"Max stack height (native WebAssembly stack limiter)."),(0,l.kt)("td",{parentName:"tr",align:null},"500")))),(0,l.kt)("h3",{id:"wasmstorage_costs"},"wasm.storage_costs"),(0,l.kt)("p",null,"These settings manage Wasm storage costs."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"gas_per_byte"),(0,l.kt)("td",{parentName:"tr",align:null},"Gas charged per byte stored in global state."),(0,l.kt)("td",{parentName:"tr",align:null},"630_000")))),(0,l.kt)("h3",{id:"wasmopcode_costs"},"wasm.opcode_costs"),(0,l.kt)("p",null,"The following settings manage the cost table for Wasm opcodes."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"bit"),(0,l.kt)("td",{parentName:"tr",align:null},"Bit operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"300")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"add"),(0,l.kt)("td",{parentName:"tr",align:null},"Arithmetic add operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"210")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"mul"),(0,l.kt)("td",{parentName:"tr",align:null},"Mul operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"240")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"div"),(0,l.kt)("td",{parentName:"tr",align:null},"Div operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"320")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"load"),(0,l.kt)("td",{parentName:"tr",align:null},"Memory load operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"store"),(0,l.kt)("td",{parentName:"tr",align:null},"Memory store operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"4_700")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"const"),(0,l.kt)("td",{parentName:"tr",align:null},"Const store operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"110")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"local"),(0,l.kt)("td",{parentName:"tr",align:null},"Local operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"390")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"global"),(0,l.kt)("td",{parentName:"tr",align:null},"Global operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"390")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"integer_comparison"),(0,l.kt)("td",{parentName:"tr",align:null},"Integer operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"250")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"conversion"),(0,l.kt)("td",{parentName:"tr",align:null},"Conversion operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"420")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"unreachable"),(0,l.kt)("td",{parentName:"tr",align:null},"Unreachable operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"270")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"nop"),(0,l.kt)("td",{parentName:"tr",align:null},"Nop operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"200")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"current_memory"),(0,l.kt)("td",{parentName:"tr",align:null},"Get the current memory operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"290")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"grow_memory"),(0,l.kt)("td",{parentName:"tr",align:null},"Grow memory cost per page (64 kB)."),(0,l.kt)("td",{parentName:"tr",align:null},"240_000")))),(0,l.kt)("h3",{id:"wasmopcode_costscontrol_flow"},"wasm.opcode_costs.control_flow"),(0,l.kt)("p",null,"These settings manage costs for control flow operations."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"block"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"block")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"loop"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"loop")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"if"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"if")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"else"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"else")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"end"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"end")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"br"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"br")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"35_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"br_if"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"br_if")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"35_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"return"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"return")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"select"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"select")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"call"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"call")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"68_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"call_indirect"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"call_indirect")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"68_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"drop"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"drop")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")))),(0,l.kt)("h3",{id:"wasmopcode_costscontrol_flowbr_table"},"wasm.opcode_costs.control_flow.br_table"),(0,l.kt)("p",null,"The following settings manage ",(0,l.kt)("inlineCode",{parentName:"p"},"br_table")," Wasm opcodes."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"cost"),(0,l.kt)("td",{parentName:"tr",align:null},"Fixed cost per ",(0,l.kt)("inlineCode",{parentName:"td"},"br_table")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"35_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"size_multiplier"),(0,l.kt)("td",{parentName:"tr",align:null},"Size of target labels in the ",(0,l.kt)("inlineCode",{parentName:"td"},"br_table")," opcode will be multiplied by ",(0,l.kt)("inlineCode",{parentName:"td"},"size_multiplier"),"."),(0,l.kt)("td",{parentName:"tr",align:null},"100")))),(0,l.kt)("h3",{id:"wasmhost_function_costs"},"wasm.host_function_costs"),(0,l.kt)("p",null,'The following settings specify costs for low-level bindings for host-side ("external") functions. More documentation and host function declarations are located in ',(0,l.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/release-1.5.2/smart_contracts/contract/src/ext_ffi.rs"},"smart_contracts/contract/src/ext_ffi.rs"),"."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"add = { cost = 5_800, arguments = ","[0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"add_associated_key = { cost = 9_000, arguments = ","[0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"add_contract_version = { cost = 200, arguments = ","[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"blake2b = { cost = 200, arguments = ","[0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"call_contract = { cost = 4_500, arguments = ","[0, 0, 0, 0, 0, 420, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"call_versioned_contract = { cost = 4_500, arguments = ","[0, 0, 0, 0, 0, 0, 0, 420, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"create_contract_package_at_hash = { cost = 200, arguments = ","[0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"create_contract_user_group = { cost = 200, arguments = ","[0, 0, 0, 0, 0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"create_purse = { cost = 2_500_000_000, arguments = ","[0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"disable_contract_version = { cost = 200, arguments = ","[0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_balance = { cost = 3_800, arguments = ","[0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_blocktime = { cost = 330, arguments = ","[0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_caller = { cost = 380, arguments = ","[0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_key = { cost = 2_000, arguments = ","[0, 440, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_main_purse = { cost = 1_300, arguments = ","[0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_named_arg = { cost = 200, arguments = ","[0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_named_arg_size = { cost = 200, arguments = ","[0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_phase = { cost = 710, arguments = ","[0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_system_contract = { cost = 1_100, arguments = ","[0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"has_key = { cost = 1_500, arguments = ","[0, 840]"," }"),(0,l.kt)("li",{parentName:"ul"},"is_valid_uref = { cost = 760, arguments = ","[0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"load_named_keys = { cost = 42_000, arguments = ","[0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"new_uref = { cost = 17_000, arguments = ","[0, 0, 590]"," }"),(0,l.kt)("li",{parentName:"ul"},"random_bytes = { cost = 200, arguments = ","[0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"print = { cost = 20_000, arguments = ","[0, 4_600]"," }"),(0,l.kt)("li",{parentName:"ul"},"provision_contract_user_group_uref = { cost = 200, arguments = ","[0, 0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"put_key = { cost = 38_000, arguments = ","[0, 1_100, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"read_host_buffer = { cost = 3_500, arguments = ","[0, 310, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"read_value = { cost = 6_000, arguments = ","[0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"read_value_local = { cost = 5_500, arguments = ","[0, 590, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"remove_associated_key = { cost = 4_200, arguments = ","[0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"remove_contract_user_group = { cost = 200, arguments = ","[0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"remove_contract_user_group_urefs = { cost = 200, arguments = ","[0, 0, 0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"remove_key = { cost = 61_000, arguments = ","[0, 3_200]"," }"),(0,l.kt)("li",{parentName:"ul"},"ret = { cost = 23_000, arguments = ","[0, 420_000]"," }"),(0,l.kt)("li",{parentName:"ul"},"revert = { cost = 500, arguments = ","[0]"," }"),(0,l.kt)("li",{parentName:"ul"},"set_action_threshold = { cost = 74_000, arguments = ","[0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"transfer_from_purse_to_account = { cost = 2_500_000_000, arguments = ","[0, 0, 0, 0, 0, 0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"transfer_from_purse_to_purse = { cost = 82_000, arguments = ","[0, 0, 0, 0, 0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"transfer_to_account = { cost = 2_500_000_000, arguments = ","[0, 0, 0, 0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"update_associated_key = { cost = 4_200, arguments = ","[0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"write = { cost = 14_000, arguments = ","[0, 0, 0, 980]"," }"),(0,l.kt)("li",{parentName:"ul"},"write_local = { cost = 9_500, arguments = ","[0, 1_800, 0, 520]"," }")),(0,l.kt)("h2",{id:"system_costs"},"system_costs"),(0,l.kt)("p",null,"The following settings manage protocol operating costs."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"wasmless_transfer_cost"),(0,l.kt)("td",{parentName:"tr",align:null},"Default gas cost for a wasmless transfer."),(0,l.kt)("td",{parentName:"tr",align:null},"100_000_000")))),(0,l.kt)("h3",{id:"system_costsauction_costs"},"system_costs.auction_costs"),(0,l.kt)("p",null,"These settings manage the costs of calling the ",(0,l.kt)("inlineCode",{parentName:"p"},"auction")," system contract entrypoints."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_era_validators"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"get_era_validators")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_seigniorage_recipients"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"read_seigniorage_recipients")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"add_bid"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"add_bid")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"withdraw_bid"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"withdraw_bid")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"delegate"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"delegate")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"undelegate"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"undelegate")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"run_auction"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"run_auction")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"slash"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"slash")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"distribute"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"distribute")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"withdraw_delegator_reward"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"withdraw_delegator_reward")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"withdraw_validator_reward"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"withdraw_validator_reward")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_era_id"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"read_era_id")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"activate_bid"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"activate_bid")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"redelegate"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"redelegate")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")))),(0,l.kt)("h3",{id:"system_costsmint_costs"},"system_costs.mint_costs"),(0,l.kt)("p",null,"These settings manage the costs of calling the ",(0,l.kt)("inlineCode",{parentName:"p"},"mint")," system contract entrypoints."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"mint"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"mint")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"reduce_total_supply"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"reduce_total_supply")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"create"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"create")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"balance"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"balance")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"transfer"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"transfer")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_base_round_reward"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"read_base_round_reward")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"mint_into_existing_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"mint_into_existing_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")))),(0,l.kt)("h3",{id:"system_costshandle_payment_costs"},"system_costs.handle_payment_costs"),(0,l.kt)("p",null,"These settings manage the costs of calling entrypoints on the ",(0,l.kt)("inlineCode",{parentName:"p"},"handle_payment")," system contract."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_payment_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"get_payment_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"set_refund_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"set_refund_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_refund_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"get_refund_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"finalize_payment"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"finalize_payment")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")))),(0,l.kt)("h3",{id:"system_costsstandard_payment_costs"},"system_costs.standard_payment_costs"),(0,l.kt)("p",null,"These settings manage the costs of calling entrypoints on the ",(0,l.kt)("inlineCode",{parentName:"p"},"standard_payment")," system contract."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"pay"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"pay")," entrypoint and sending an amount to a payment purse."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")))))}g.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[2273],{3905:function(t,e,a){a.d(e,{Zo:function(){return p},kt:function(){return g}});var n=a(7294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var m=n.createContext({}),s=function(t){var e=n.useContext(m),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},p=function(t){var e=s(t.components);return n.createElement(m.Provider,{value:e},t.children)},d="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},k=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,m=t.parentName,p=o(t,["components","mdxType","originalType","parentName"]),d=s(a),k=r,g=d["".concat(m,".").concat(k)]||d[k]||u[k]||l;return a?n.createElement(g,i(i({ref:e},p),{},{components:a})):n.createElement(g,i({ref:e},p))}));function g(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=k;var o={};for(var m in e)hasOwnProperty.call(e,m)&&(o[m]=e[m]);o.originalType=t,o[d]="string"==typeof t?t:r,i[1]=o;for(var s=2;s 50% + F/2 \u2014 see the ",(0,l.kt)("inlineCode",{parentName:"td"},"finality_threshold_fraction")," below) of validator nodes must be running to start the blockchain. This timestamp is also used in seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash. ",(0,l.kt)("br",null),(0,l.kt)("br",null),"If it is an integer, it represents an era ID, meaning the protocol version becomes active at the start of this era."),(0,l.kt)("td",{parentName:"tr",align:null},"9100")))),(0,l.kt)("h2",{id:"network"},"network"),(0,l.kt)("p",null,"The following settings configure the networking layer."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"name"),(0,l.kt)("td",{parentName:"tr",align:null},"Human readable network name for convenience. The state_root_hash of the genesis block is the true identifier. The name influences the genesis hash by contributing to seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash."),(0,l.kt)("td",{parentName:"tr",align:null},"'casper'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"maximum_net_message_size"),(0,l.kt)("td",{parentName:"tr",align:null},"The maximum size of an acceptable networking message in bytes. Any message larger than this will be rejected at the networking level."),(0,l.kt)("td",{parentName:"tr",align:null},"25_165_824")))),(0,l.kt)("h2",{id:"core"},"core"),(0,l.kt)("p",null,"These settings manage the core protocol behavior."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"era_duration"),(0,l.kt)("td",{parentName:"tr",align:null},"Era duration."),(0,l.kt)("td",{parentName:"tr",align:null},"'120min'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"minimum_era_height"),(0,l.kt)("td",{parentName:"tr",align:null},"Minimum number of blocks per era. An era will take longer than ",(0,l.kt)("inlineCode",{parentName:"td"},"era_duration")," if that is necessary to reach the minimum height."),(0,l.kt)("td",{parentName:"tr",align:null},"20")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"minimum_block_time"),(0,l.kt)("td",{parentName:"tr",align:null},"Minimum difference between a block's and its child's timestamp."),(0,l.kt)("td",{parentName:"tr",align:null},"'16384ms'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"validator_slots"),(0,l.kt)("td",{parentName:"tr",align:null},"Number of slots available in the validator auction."),(0,l.kt)("td",{parentName:"tr",align:null},"100")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"finality_threshold_fraction"),(0,l.kt)("td",{parentName:"tr",align:null},"A number between 0 and 1 representing the fault tolerance threshold as a fraction used by the internal finalizer.",(0,l.kt)("br",null),"It is the fraction of validators that would need to equivocate to make two honest nodes see two conflicting blocks as finalized.",(0,l.kt)("br",null),"Let's say this value is F. A higher value F makes it safer to rely on finalized blocks. It also makes it more difficult to finalize blocks, however, and requires strictly more than (F + 1)/2 validators to be working correctly."),(0,l.kt)("td",{parentName:"tr",align:null},"[1, 3]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"start_protocol_version_with_strict",(0,l.kt)("br",null),"_","finality_signatures_required"),(0,l.kt)("td",{parentName:"tr",align:null},"Protocol version from which nodes are required to hold strict finality signatures."),(0,l.kt)("td",{parentName:"tr",align:null},"'1.5.0'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"legacy_required_finality"),(0,l.kt)("td",{parentName:"tr",align:null},"The finality required for legacy blocks. Options are 'Strict', 'Weak', and 'Any'. ",(0,l.kt)("br",null),"Used to determine finality sufficiency for new joiners syncing blocks created in a protocol version before the start protocol version with strict finality signatures."),(0,l.kt)("td",{parentName:"tr",align:null},"'Strict'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"auction_delay"),(0,l.kt)("td",{parentName:"tr",align:null},"Number of eras before an auction defines the set of validators. If a validator bonds with a sufficient bid in era N, it will be a validator in era N + auction_delay + 1."),(0,l.kt)("td",{parentName:"tr",align:null},"1")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"locked_funds_period"),(0,l.kt)("td",{parentName:"tr",align:null},"The period after genesis during which a genesis validator's bid is locked."),(0,l.kt)("td",{parentName:"tr",align:null},"'90days'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"vesting_schedule_period"),(0,l.kt)("td",{parentName:"tr",align:null},"The period in which the genesis validator's bid is released over time after it is unlocked."),(0,l.kt)("td",{parentName:"tr",align:null},"'13 weeks'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"unbonding_delay"),(0,l.kt)("td",{parentName:"tr",align:null},"Default number of eras that need to pass to be able to withdraw unbonded funds."),(0,l.kt)("td",{parentName:"tr",align:null},"7")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"round_seigniorage_rate"),(0,l.kt)("td",{parentName:"tr",align:null},"Round seigniorage rate represented as a fraction of the total supply.",(0,l.kt)("br",null),"- Annual issuance: 8%.",(0,l.kt)("br",null),"- Minimum block time: 2^15 milliseconds.",(0,l.kt)("br",null),"- Ticks per year: 31536000000.",(0,l.kt)("br",null),(0,l.kt)("br",null),"(1+0.08)^((2^15)/31536000000)-1 is expressed as a fractional number below in Python:",(0,l.kt)("br",null),(0,l.kt)("inlineCode",{parentName:"td"},"Fraction((1 + 0.08)**((2**15)/31536000000) - 1).limit_denominator(1000000000)")),(0,l.kt)("td",{parentName:"tr",align:null},"[7, 87535408]")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_associated_keys"),(0,l.kt)("td",{parentName:"tr",align:null},"Maximum number of associated keys for a single account."),(0,l.kt)("td",{parentName:"tr",align:null},"100")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_runtime_call_stack_height"),(0,l.kt)("td",{parentName:"tr",align:null},"Maximum height of the contract runtime call stack."),(0,l.kt)("td",{parentName:"tr",align:null},"12")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"minimum_delegation_amount"),(0,l.kt)("td",{parentName:"tr",align:null},"Minimum allowed delegation amount in motes."),(0,l.kt)("td",{parentName:"tr",align:null},"500_000_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"prune_batch_size"),(0,l.kt)("td",{parentName:"tr",align:null},"Global state prune batch size for tip pruning in version 1.4.15. Possible values:",(0,l.kt)("br",null),"- 0 when the feature is OFF",(0,l.kt)("br",null),"- Integer if the feature is ON, representing the number of eras to process per block."),(0,l.kt)("td",{parentName:"tr",align:null},"0")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"strict_argument_checking"),(0,l.kt)("td",{parentName:"tr",align:null},"Enables strict arguments checking when calling a contract; i.e., all non-optional args are provided and they are of the correct ",(0,l.kt)("inlineCode",{parentName:"td"},"CLType"),"."),(0,l.kt)("td",{parentName:"tr",align:null},"false")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"simultaneous_peer_requests"),(0,l.kt)("td",{parentName:"tr",align:null},"Number of simultaneous peer requests."),(0,l.kt)("td",{parentName:"tr",align:null},"5")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"consensus_protocol"),(0,l.kt)("td",{parentName:"tr",align:null},"The consensus protocol to use. Options are 'Zug' or 'Highway'."),(0,l.kt)("td",{parentName:"tr",align:null},"'Highway'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_delegators_per_validator"),(0,l.kt)("td",{parentName:"tr",align:null},"The maximum amount of delegators per validator. If the value is 0, there is no maximum capacity."),(0,l.kt)("td",{parentName:"tr",align:null},"1200")))),(0,l.kt)("h2",{id:"highway"},"highway"),(0,l.kt)("p",null,"These settings configure the Highway Consensus protocol."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"maximum_round_length"),(0,l.kt)("td",{parentName:"tr",align:null},"Highway dynamically chooses its round length between ",(0,l.kt)("inlineCode",{parentName:"td"},"minimum_block_time")," and ",(0,l.kt)("inlineCode",{parentName:"td"},"maximum_round_length"),"."),(0,l.kt)("td",{parentName:"tr",align:null},"'132seconds'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"reduced_reward_multiplier"),(0,l.kt)("td",{parentName:"tr",align:null},"The factor by which rewards for a round are multiplied if the greatest summit has \u226450% quorum, i.e., no finality. Expressed as a fraction (1/5 by default on Mainnet)."),(0,l.kt)("td",{parentName:"tr",align:null},"[1, 5]")))),(0,l.kt)("h2",{id:"deploys"},"deploys"),(0,l.kt)("p",null,"These settings manage deploys and their lifecycle."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_payment_cost"),(0,l.kt)("td",{parentName:"tr",align:null},"The maximum number of motes allowed to be spent during payment. 0 means unlimited."),(0,l.kt)("td",{parentName:"tr",align:null},"'0'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_ttl"),(0,l.kt)("td",{parentName:"tr",align:null},"The duration after the deploy timestamp during which the deploy can be included in a block."),(0,l.kt)("td",{parentName:"tr",align:null},"'18hours'")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_dependencies"),(0,l.kt)("td",{parentName:"tr",align:null},"The maximum number of other deploys a deploy can depend on (requiring them to have been executed before it can execute)."),(0,l.kt)("td",{parentName:"tr",align:null},"10")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_block_size"),(0,l.kt)("td",{parentName:"tr",align:null},"Maximum block size in bytes, including deploys contained by the block. 0 means unlimited."),(0,l.kt)("td",{parentName:"tr",align:null},"10_485_760")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_deploy_size"),(0,l.kt)("td",{parentName:"tr",align:null},"Maximum deploy size in bytes. Size is of the deploy when serialized via ToBytes."),(0,l.kt)("td",{parentName:"tr",align:null},"1_048_576")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"block_max_deploy_count"),(0,l.kt)("td",{parentName:"tr",align:null},"The maximum number of non-transfer deploys permitted in a single block."),(0,l.kt)("td",{parentName:"tr",align:null},"50")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"block_max_transfer_count"),(0,l.kt)("td",{parentName:"tr",align:null},"The maximum number of Wasm-less transfer deploys permitted in a single block."),(0,l.kt)("td",{parentName:"tr",align:null},"1250")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"block_max_approval_count"),(0,l.kt)("td",{parentName:"tr",align:null},"The maximum number of approvals permitted in a single block."),(0,l.kt)("td",{parentName:"tr",align:null},"2600")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"block_gas_limit"),(0,l.kt)("td",{parentName:"tr",align:null},"The upper limit of the total gas of all deploys in a block."),(0,l.kt)("td",{parentName:"tr",align:null},"4_000_000_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"payment_args_max_length"),(0,l.kt)("td",{parentName:"tr",align:null},"The limit of length of serialized payment code arguments."),(0,l.kt)("td",{parentName:"tr",align:null},"1024")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"session_args_max_length"),(0,l.kt)("td",{parentName:"tr",align:null},"The limit of length of serialized session code arguments."),(0,l.kt)("td",{parentName:"tr",align:null},"1024")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"native_transfer_minimum_motes"),(0,l.kt)("td",{parentName:"tr",align:null},"The minimum amount in motes for a valid native transfer."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")))),(0,l.kt)("h2",{id:"wasm"},"wasm"),(0,l.kt)("p",null,"The following are Wasm-related settings."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_memory"),(0,l.kt)("td",{parentName:"tr",align:null},"Amount of free memory (in 64 kB pages) each contract can use for its stack."),(0,l.kt)("td",{parentName:"tr",align:null},"64")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"max_stack_height"),(0,l.kt)("td",{parentName:"tr",align:null},"Max stack height (native WebAssembly stack limiter)."),(0,l.kt)("td",{parentName:"tr",align:null},"500")))),(0,l.kt)("h3",{id:"wasmstorage_costs"},"wasm.storage_costs"),(0,l.kt)("p",null,"These settings manage Wasm storage costs."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"gas_per_byte"),(0,l.kt)("td",{parentName:"tr",align:null},"Gas charged per byte stored in global state."),(0,l.kt)("td",{parentName:"tr",align:null},"630_000")))),(0,l.kt)("h3",{id:"wasmopcode_costs"},"wasm.opcode_costs"),(0,l.kt)("p",null,"The following settings manage the cost table for Wasm opcodes."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"bit"),(0,l.kt)("td",{parentName:"tr",align:null},"Bit operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"300")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"add"),(0,l.kt)("td",{parentName:"tr",align:null},"Arithmetic add operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"210")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"mul"),(0,l.kt)("td",{parentName:"tr",align:null},"Mul operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"240")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"div"),(0,l.kt)("td",{parentName:"tr",align:null},"Div operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"320")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"load"),(0,l.kt)("td",{parentName:"tr",align:null},"Memory load operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"store"),(0,l.kt)("td",{parentName:"tr",align:null},"Memory store operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"4_700")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"const"),(0,l.kt)("td",{parentName:"tr",align:null},"Const store operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"110")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"local"),(0,l.kt)("td",{parentName:"tr",align:null},"Local operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"390")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"global"),(0,l.kt)("td",{parentName:"tr",align:null},"Global operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"390")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"integer_comparison"),(0,l.kt)("td",{parentName:"tr",align:null},"Integer operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"250")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"conversion"),(0,l.kt)("td",{parentName:"tr",align:null},"Conversion operations multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"420")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"unreachable"),(0,l.kt)("td",{parentName:"tr",align:null},"Unreachable operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"270")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"nop"),(0,l.kt)("td",{parentName:"tr",align:null},"Nop operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"200")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"current_memory"),(0,l.kt)("td",{parentName:"tr",align:null},"Get the current memory operation multiplier."),(0,l.kt)("td",{parentName:"tr",align:null},"290")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"grow_memory"),(0,l.kt)("td",{parentName:"tr",align:null},"Grow memory cost per page (64 kB)."),(0,l.kt)("td",{parentName:"tr",align:null},"240_000")))),(0,l.kt)("h3",{id:"wasmopcode_costscontrol_flow"},"wasm.opcode_costs.control_flow"),(0,l.kt)("p",null,"These settings manage costs for control flow operations."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"block"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"block")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"loop"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"loop")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"if"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"if")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"else"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"else")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"end"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"end")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"br"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"br")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"35_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"br_if"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"br_if")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"35_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"return"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"return")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"select"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"select")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"call"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"call")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"68_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"call_indirect"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"call_indirect")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"68_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"drop"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost for ",(0,l.kt)("inlineCode",{parentName:"td"},"drop")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"440")))),(0,l.kt)("h3",{id:"wasmopcode_costscontrol_flowbr_table"},"wasm.opcode_costs.control_flow.br_table"),(0,l.kt)("p",null,"The following settings manage ",(0,l.kt)("inlineCode",{parentName:"p"},"br_table")," Wasm opcodes."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"cost"),(0,l.kt)("td",{parentName:"tr",align:null},"Fixed cost per ",(0,l.kt)("inlineCode",{parentName:"td"},"br_table")," opcode."),(0,l.kt)("td",{parentName:"tr",align:null},"35_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"size_multiplier"),(0,l.kt)("td",{parentName:"tr",align:null},"Size of target labels in the ",(0,l.kt)("inlineCode",{parentName:"td"},"br_table")," opcode will be multiplied by ",(0,l.kt)("inlineCode",{parentName:"td"},"size_multiplier"),"."),(0,l.kt)("td",{parentName:"tr",align:null},"100")))),(0,l.kt)("h3",{id:"wasmhost_function_costs"},"wasm.host_function_costs"),(0,l.kt)("p",null,'The following settings specify costs for low-level bindings for host-side ("external") functions. More documentation and host function declarations are located in ',(0,l.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/release-1.5.2/smart_contracts/contract/src/ext_ffi.rs"},"smart_contracts/contract/src/ext_ffi.rs"),"."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"add = { cost = 5_800, arguments = ","[0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"add_associated_key = { cost = 9_000, arguments = ","[0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"add_contract_version = { cost = 200, arguments = ","[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"blake2b = { cost = 200, arguments = ","[0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"call_contract = { cost = 4_500, arguments = ","[0, 0, 0, 0, 0, 420, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"call_versioned_contract = { cost = 4_500, arguments = ","[0, 0, 0, 0, 0, 0, 0, 420, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"create_contract_package_at_hash = { cost = 200, arguments = ","[0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"create_contract_user_group = { cost = 200, arguments = ","[0, 0, 0, 0, 0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"create_purse = { cost = 2_500_000_000, arguments = ","[0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"disable_contract_version = { cost = 200, arguments = ","[0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_balance = { cost = 3_800, arguments = ","[0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_blocktime = { cost = 330, arguments = ","[0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_caller = { cost = 380, arguments = ","[0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_key = { cost = 2_000, arguments = ","[0, 440, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_main_purse = { cost = 1_300, arguments = ","[0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_named_arg = { cost = 200, arguments = ","[0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_named_arg_size = { cost = 200, arguments = ","[0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_phase = { cost = 710, arguments = ","[0]"," }"),(0,l.kt)("li",{parentName:"ul"},"get_system_contract = { cost = 1_100, arguments = ","[0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"has_key = { cost = 1_500, arguments = ","[0, 840]"," }"),(0,l.kt)("li",{parentName:"ul"},"is_valid_uref = { cost = 760, arguments = ","[0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"load_named_keys = { cost = 42_000, arguments = ","[0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"new_uref = { cost = 17_000, arguments = ","[0, 0, 590]"," }"),(0,l.kt)("li",{parentName:"ul"},"random_bytes = { cost = 200, arguments = ","[0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"print = { cost = 20_000, arguments = ","[0, 4_600]"," }"),(0,l.kt)("li",{parentName:"ul"},"provision_contract_user_group_uref = { cost = 200, arguments = ","[0, 0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"put_key = { cost = 38_000, arguments = ","[0, 1_100, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"read_host_buffer = { cost = 3_500, arguments = ","[0, 310, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"read_value = { cost = 6_000, arguments = ","[0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"read_value_local = { cost = 5_500, arguments = ","[0, 590, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"remove_associated_key = { cost = 4_200, arguments = ","[0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"remove_contract_user_group = { cost = 200, arguments = ","[0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"remove_contract_user_group_urefs = { cost = 200, arguments = ","[0, 0, 0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"remove_key = { cost = 61_000, arguments = ","[0, 3_200]"," }"),(0,l.kt)("li",{parentName:"ul"},"ret = { cost = 23_000, arguments = ","[0, 420_000]"," }"),(0,l.kt)("li",{parentName:"ul"},"revert = { cost = 500, arguments = ","[0]"," }"),(0,l.kt)("li",{parentName:"ul"},"set_action_threshold = { cost = 74_000, arguments = ","[0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"transfer_from_purse_to_account = { cost = 2_500_000_000, arguments = ","[0, 0, 0, 0, 0, 0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"transfer_from_purse_to_purse = { cost = 82_000, arguments = ","[0, 0, 0, 0, 0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"transfer_to_account = { cost = 2_500_000_000, arguments = ","[0, 0, 0, 0, 0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"update_associated_key = { cost = 4_200, arguments = ","[0, 0, 0]"," }"),(0,l.kt)("li",{parentName:"ul"},"write = { cost = 14_000, arguments = ","[0, 0, 0, 980]"," }"),(0,l.kt)("li",{parentName:"ul"},"write_local = { cost = 9_500, arguments = ","[0, 1_800, 0, 520]"," }")),(0,l.kt)("h2",{id:"system_costs"},"system_costs"),(0,l.kt)("p",null,"The following settings manage protocol operating costs."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"wasmless_transfer_cost"),(0,l.kt)("td",{parentName:"tr",align:null},"Default gas cost for a wasmless transfer."),(0,l.kt)("td",{parentName:"tr",align:null},"100_000_000")))),(0,l.kt)("h3",{id:"system_costsauction_costs"},"system_costs.auction_costs"),(0,l.kt)("p",null,"These settings manage the costs of calling the ",(0,l.kt)("inlineCode",{parentName:"p"},"auction")," system contract entrypoints."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_era_validators"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"get_era_validators")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_seigniorage_recipients"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"read_seigniorage_recipients")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"add_bid"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"add_bid")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"withdraw_bid"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"withdraw_bid")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"delegate"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"delegate")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"undelegate"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"undelegate")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"run_auction"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"run_auction")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"slash"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"slash")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"distribute"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"distribute")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"withdraw_delegator_reward"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"withdraw_delegator_reward")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"withdraw_validator_reward"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"withdraw_validator_reward")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_era_id"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"read_era_id")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"activate_bid"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"activate_bid")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"redelegate"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"redelegate")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")))),(0,l.kt)("h3",{id:"system_costsmint_costs"},"system_costs.mint_costs"),(0,l.kt)("p",null,"These settings manage the costs of calling the ",(0,l.kt)("inlineCode",{parentName:"p"},"mint")," system contract entrypoints."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"mint"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"mint")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"reduce_total_supply"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"reduce_total_supply")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"create"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"create")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"balance"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"balance")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"transfer"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"transfer")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"read_base_round_reward"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"read_base_round_reward")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"mint_into_existing_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"mint_into_existing_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"2_500_000_000")))),(0,l.kt)("h3",{id:"system_costshandle_payment_costs"},"system_costs.handle_payment_costs"),(0,l.kt)("p",null,"These settings manage the costs of calling entrypoints on the ",(0,l.kt)("inlineCode",{parentName:"p"},"handle_payment")," system contract."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_payment_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"get_payment_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"set_refund_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"set_refund_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"get_refund_purse"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"get_refund_purse")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"finalize_payment"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"finalize_payment")," entrypoint."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")))),(0,l.kt)("h3",{id:"system_costsstandard_payment_costs"},"system_costs.standard_payment_costs"),(0,l.kt)("p",null,"These settings manage the costs of calling entrypoints on the ",(0,l.kt)("inlineCode",{parentName:"p"},"standard_payment")," system contract."),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Attribute"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"),(0,l.kt)("th",{parentName:"tr",align:null},"Mainnet Setting"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"pay"),(0,l.kt)("td",{parentName:"tr",align:null},"Cost of calling the ",(0,l.kt)("inlineCode",{parentName:"td"},"pay")," entrypoint and sending an amount to a payment purse."),(0,l.kt)("td",{parentName:"tr",align:null},"10_000")))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d2361378.c78f5bed.js b/assets/js/d2361378.ce17daea.js similarity index 98% rename from assets/js/d2361378.c78f5bed.js rename to assets/js/d2361378.ce17daea.js index 35110321f7..c3ffb6d076 100644 --- a/assets/js/d2361378.c78f5bed.js +++ b/assets/js/d2361378.ce17daea.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[8306],{3905:function(e,t,n){n.d(t,{Zo:function(){return l},kt:function(){return f}});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=a.createContext({}),p=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},l=function(e){var t=p(e.components);return a.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),d=p(n),h=o,f=d["".concat(c,".").concat(h)]||d[h]||u[h]||r;return n?a.createElement(f,s(s({ref:t},l),{},{components:n})):a.createElement(f,s({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,s=new Array(r);s[0]=h;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[d]="string"==typeof e?e:o,s[1]=i;for(var p=2;p=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=a.createContext({}),p=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},l=function(e){var t=p(e.components);return a.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),d=p(n),h=o,f=d["".concat(c,".").concat(h)]||d[h]||u[h]||r;return n?a.createElement(f,s(s({ref:t},l),{},{components:n})):a.createElement(f,s({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,s=new Array(r);s[0]=h;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[d]="string"==typeof e?e:o,s[1]=i;for(var p=2;p=0||(r[a]=e[a]);return r}(e,n);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var o=t.createContext({}),s=function(e){var n=t.useContext(o),a=n;return e&&(a="function"==typeof e?e(n):d(d({},n),e)),a},l=function(e){var n=s(e.components);return t.createElement(o.Provider,{value:n},e.children)},b="mdxType",i={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},p=t.forwardRef((function(e,n){var a=e.components,r=e.mdxType,c=e.originalType,o=e.parentName,l=f(e,["components","mdxType","originalType","parentName"]),b=s(a),p=r,u=b["".concat(o,".").concat(p)]||b[p]||i[p]||c;return a?t.createElement(u,d(d({ref:n},l),{},{components:a})):t.createElement(u,d({ref:n},l))}));function u(e,n){var a=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var c=a.length,d=new Array(c);d[0]=p;var f={};for(var o in n)hasOwnProperty.call(n,o)&&(f[o]=n[o]);f.originalType=e,f[b]="string"==typeof e?e:r,d[1]=f;for(var s=2;saccount_put_deploy_result",id:"account_put_deploy_result",level:3},{value:"speculative_exec",id:"speculative_exec",level:2},{value:"speculative_exec_result",id:"speculative_exec_result",level:3}],i={toc:b},p="wrapper";function u(e){var n=e.components,a=(0,r.Z)(e,d);return(0,c.kt)(p,(0,t.Z)({},i,a,{components:n,mdxType:"MDXLayout"}),(0,c.kt)("h1",{id:"transactional"},"Transactional JSON-RPC Methods"),(0,c.kt)("hr",null),(0,c.kt)("h2",{id:"account-put-deploy"},"account_put_deploy"),(0,c.kt)("p",null,"This is the only means by which users can send their compiled Wasm (as part of a Deploy) to a node on a Casper network. The request takes in the ",(0,c.kt)("a",{parentName:"p",href:"/concepts/design/casper-design/#execution-semantics-deploys"},"Deploy")," as a parameter, prior to sending it to a node on a network for execution."),(0,c.kt)("table",null,(0,c.kt)("thead",{parentName:"table"},(0,c.kt)("tr",{parentName:"thead"},(0,c.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,c.kt)("th",{parentName:"tr",align:null},"Type"),(0,c.kt)("th",{parentName:"tr",align:null},"Description"))),(0,c.kt)("tbody",{parentName:"table"},(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},(0,c.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#deploy"},"deploy")),(0,c.kt)("td",{parentName:"tr",align:null},"Object"),(0,c.kt)("td",{parentName:"tr",align:null},"A Deploy consists of an item containing a smart contract along with the requester's signature(s).")))),(0,c.kt)("blockquote",null,(0,c.kt)("p",{parentName:"blockquote"},(0,c.kt)("strong",{parentName:"p"},"Note"),": You can find a list of ",(0,c.kt)("a",{parentName:"p",href:"/operators/setup/joining/#known-addresses"},"trusted peers")," in the network's configuration file, ",(0,c.kt)("inlineCode",{parentName:"p"},"config.toml"),". Here is an ",(0,c.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/config-example.toml#L131"},"example config.toml"),". You may send deploys to one of the trusted nodes or use them to query other online nodes.")),(0,c.kt)("details",null,(0,c.kt)("summary",null,"Example account_put_deploy request"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": [\n {\n "approvals": [\n {\n "signer": "01f8b29f39c38600ecb3bbb082951e04ab63a4ad4f7c9048a5057e461a5a8d58a5",\n "signature": "019d6ef5c62c80ad4e50df343fba6f0fced17dea4c65e7976f66335ffcfcde2a7f02e928c8507cef3c76c3151e0e9cc9c3f7838b9f7a99ac4be5522ca092841100"\n }\n ],\n "hash": "00a8677713222df88b6988926e0b14adeda6c663957f5075003395da4e5c6888",\n "header": {\n "account": "01f8b29f39c38600ecb3bbb082951e04ab63a4ad4f7c9048a5057e461a5a8d58a5",\n "body_hash": "145ae09d6da5bc290051db8cb7132a41a30473d5900eaaf409d92b666325ca00",\n "chain_name": "casper-net-1",\n "dependencies": [\n "0101010101010101010101010101010101010101010101010101010101010101"\n ],\n "gas_price": 1,\n "timestamp": "2023-09-26T14:07:10.024Z",\n "ttl": "1h"\n },\n "payment": {\n "StoredContractByName": {\n "args": [\n [\n "amount",\n {\n "bytes": "0400f90295",\n "cl_type": "U512"\n }\n ]\n ],\n "entry_point": "example-entry-point",\n "name": "casper-example"\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295"\n }\n ],\n [\n "target",\n {\n "cl_type": "URef",\n "bytes": "09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db07"\n }\n ]\n ]\n }\n }\n }\n ]\n}\n\n'))),(0,c.kt)("h3",{id:"account_put_deploy_result"},(0,c.kt)("inlineCode",{parentName:"h3"},"account_put_deploy_result")),(0,c.kt)("p",null,"The result contains the ",(0,c.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_chain#deployhash"},"deploy_hash"),", which is the primary identifier of a Deploy within a Casper network."),(0,c.kt)("table",null,(0,c.kt)("thead",{parentName:"table"},(0,c.kt)("tr",{parentName:"thead"},(0,c.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,c.kt)("th",{parentName:"tr",align:null},"Type"),(0,c.kt)("th",{parentName:"tr",align:null},"Description"))),(0,c.kt)("tbody",{parentName:"table"},(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},"api_version"),(0,c.kt)("td",{parentName:"tr",align:null},"String"),(0,c.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},(0,c.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#deployhash"},"deploy_hash")),(0,c.kt)("td",{parentName:"tr",align:null},"String"),(0,c.kt)("td",{parentName:"tr",align:null},"A hex-encoded hash of the Deploy as sent.")))),(0,c.kt)("details",null,(0,c.kt)("summary",null,"Example account_put_deploy result"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"\n }\n}\n\n'))),(0,c.kt)("h2",{id:"speculative_exec"},"speculative_exec"),(0,c.kt)("p",null,"The ",(0,c.kt)("inlineCode",{parentName:"p"},"speculative_exec")," endpoint provides a method to execute a ",(0,c.kt)("inlineCode",{parentName:"p"},"Deploy")," without committing its execution effects to global state. By default, ",(0,c.kt)("inlineCode",{parentName:"p"},"speculative_exec")," is disabled on a node. Sending a request to a node with the endpoint disabled will result in an error message. If enabled, ",(0,c.kt)("inlineCode",{parentName:"p"},"speculative_exec")," operates on a separate port from the primary JSON-RPC, using 7778."),(0,c.kt)("p",null,(0,c.kt)("inlineCode",{parentName:"p"},"speculative_exec")," executes a Deploy at a specified block. In the case of this endpoint, the execution effects are not committed to global state. As such, it can be used for observing the execution effects of a Deploy without paying for the execution of the Deploy."),(0,c.kt)("table",null,(0,c.kt)("thead",{parentName:"table"},(0,c.kt)("tr",{parentName:"thead"},(0,c.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,c.kt)("th",{parentName:"tr",align:null},"Type"),(0,c.kt)("th",{parentName:"tr",align:null},"Description"))),(0,c.kt)("tbody",{parentName:"table"},(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},(0,c.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,c.kt)("td",{parentName:"tr",align:null},"Object"),(0,c.kt)("td",{parentName:"tr",align:null},"The block hash or height on top of which to execute the deploy. If not supplied,the most recent block will be used.")),(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},(0,c.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#deploy"},"deploy")),(0,c.kt)("td",{parentName:"tr",align:null},"Object"),(0,c.kt)("td",{parentName:"tr",align:null},"A Deploy consists of an item containing a smart contract along with the requester's signature(s).")))),(0,c.kt)("details",null,(0,c.kt)("summary",null,"Example speculative_exec request"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "jsonrpc": "2.0",\n "method": "speculative_exec",\n "params": {\n "block_identifier": null,\n "deploy": {\n "hash": "b6aa46333fb858deee7f259a5bca581251c6200a5d902aeb1244c3a7169b5971",\n "header": {\n "account": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",\n "timestamp": "2023-05-23T13:32:45.554Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "74db109805bb20de43ef89a5b084544a858908b236601519d5827cd9b7fbb925",\n "dependencies": [],\n "chain_name": "integration-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b",\n "parsed": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010000000000000000",\n "parsed": 0\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",\n "signature": "01c94d517d5bbc8d5c74e0e68b8cb308561ff979a1c91907b56d427cc90156c437726c0b736d17f7303f2db66e405c7e5c8175b8b863703938eff1659766dff808"\n }\n ]\n }\n },\n "id": 6889533540839698701\n}\n\n'))),(0,c.kt)("h3",{id:"speculative_exec_result"},(0,c.kt)("inlineCode",{parentName:"h3"},"speculative_exec_result")),(0,c.kt)("p",null,"The result contains the hash of the targeted block and the results of the execution."),(0,c.kt)("table",null,(0,c.kt)("thead",{parentName:"table"},(0,c.kt)("tr",{parentName:"thead"},(0,c.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,c.kt)("th",{parentName:"tr",align:null},"Type"),(0,c.kt)("th",{parentName:"tr",align:null},"Description"))),(0,c.kt)("tbody",{parentName:"table"},(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},"api_version"),(0,c.kt)("td",{parentName:"tr",align:null},"String"),(0,c.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},(0,c.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockhash"},"block_hash")),(0,c.kt)("td",{parentName:"tr",align:null},"Object"),(0,c.kt)("td",{parentName:"tr",align:null},"The Block hash on top of which the deploy was executed.")),(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},(0,c.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#executionresult"},"execution_results")),(0,c.kt)("td",{parentName:"tr",align:null},"Object"),(0,c.kt)("td",{parentName:"tr",align:null},"The map of Block hash to execution result.")))),(0,c.kt)("details",null,(0,c.kt)("summary",null,"Example speculative_exec result"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "jsonrpc": "2.0",\n "id": -8801853076373554652,\n "result": {\n "api_version": "1.5.0",\n "block_hash": "ff862326b08702a5089d64e32100537b7ff984cac4c0ba6d1c561f7c47125f76",\n "execution_result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "05f0e630ed87",\n "parsed": "583799990000"\n }\n }\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "05f0e630ed87",\n "parsed": "583799990000"\n }\n }\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": "Identity"\n },\n {\n "key": "balance-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "05f0ed2d5887",\n "parsed": "581299990000"\n }\n }\n },\n {\n "key": "balance-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd",\n "transform": {\n "AddUInt512": "2500000000"\n }\n },\n {\n "key": "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612",\n "transform": {\n "WriteTransfer": {\n "deploy_hash": "d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",\n "from": "account-hash-0a9b33af5108c5a6e1067b0ddec6853ce1745d591375d767ac5db680d21845e7",\n "to": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "source": "uref-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678-007",\n "target": "uref-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd-004",\n "amount": "2500000000",\n "gas": "0",\n "id": 0\n }\n }\n },\n {\n "key": "deploy-d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",\n "transfers": [\n "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612"\n ],\n "from": "account-hash-0a9b33af5108c5a6e1067b0ddec6853ce1745d591375d767ac5db680d21845e7",\n "source": "uref-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678-007",\n "gas": "100000000"\n }\n }\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "balance-ecc530e74cf2185936a334aa1e0f07539aa3b33c4b547e71fc4109151755652f",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-ecc530e74cf2185936a334aa1e0f07539aa3b33c4b547e71fc4109151755652f",\n "transform": {\n "AddUInt512": "100000000"\n }\n }\n ]\n },\n "transfers": [\n "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612"\n ],\n "cost": "100000000"\n }\n }\n }\n}\n\n'))))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3617],{3905:function(e,n,a){a.d(n,{Zo:function(){return l},kt:function(){return u}});var t=a(7294);function r(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function c(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function d(e){for(var n=1;n=0||(r[a]=e[a]);return r}(e,n);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var o=t.createContext({}),s=function(e){var n=t.useContext(o),a=n;return e&&(a="function"==typeof e?e(n):d(d({},n),e)),a},l=function(e){var n=s(e.components);return t.createElement(o.Provider,{value:n},e.children)},b="mdxType",i={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},p=t.forwardRef((function(e,n){var a=e.components,r=e.mdxType,c=e.originalType,o=e.parentName,l=f(e,["components","mdxType","originalType","parentName"]),b=s(a),p=r,u=b["".concat(o,".").concat(p)]||b[p]||i[p]||c;return a?t.createElement(u,d(d({ref:n},l),{},{components:a})):t.createElement(u,d({ref:n},l))}));function u(e,n){var a=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var c=a.length,d=new Array(c);d[0]=p;var f={};for(var o in n)hasOwnProperty.call(n,o)&&(f[o]=n[o]);f.originalType=e,f[b]="string"==typeof e?e:r,d[1]=f;for(var s=2;saccount_put_deploy_result",id:"account_put_deploy_result",level:3},{value:"speculative_exec",id:"speculative_exec",level:2},{value:"speculative_exec_result",id:"speculative_exec_result",level:3}],i={toc:b},p="wrapper";function u(e){var n=e.components,a=(0,r.Z)(e,d);return(0,c.kt)(p,(0,t.Z)({},i,a,{components:n,mdxType:"MDXLayout"}),(0,c.kt)("h1",{id:"transactional"},"Transactional JSON-RPC Methods"),(0,c.kt)("hr",null),(0,c.kt)("h2",{id:"account-put-deploy"},"account_put_deploy"),(0,c.kt)("p",null,"This is the only means by which users can send their compiled Wasm (as part of a Deploy) to a node on a Casper network. The request takes in the ",(0,c.kt)("a",{parentName:"p",href:"/concepts/design/casper-design/#execution-semantics-deploys"},"Deploy")," as a parameter, prior to sending it to a node on a network for execution."),(0,c.kt)("table",null,(0,c.kt)("thead",{parentName:"table"},(0,c.kt)("tr",{parentName:"thead"},(0,c.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,c.kt)("th",{parentName:"tr",align:null},"Type"),(0,c.kt)("th",{parentName:"tr",align:null},"Description"))),(0,c.kt)("tbody",{parentName:"table"},(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},(0,c.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#deploy"},"deploy")),(0,c.kt)("td",{parentName:"tr",align:null},"Object"),(0,c.kt)("td",{parentName:"tr",align:null},"A Deploy consists of an item containing a smart contract along with the requester's signature(s).")))),(0,c.kt)("blockquote",null,(0,c.kt)("p",{parentName:"blockquote"},(0,c.kt)("strong",{parentName:"p"},"Note"),": You can find a list of ",(0,c.kt)("a",{parentName:"p",href:"/operators/setup/joining/#known-addresses"},"trusted peers")," in the network's configuration file, ",(0,c.kt)("inlineCode",{parentName:"p"},"config.toml"),". Here is an ",(0,c.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/config-example.toml#L131"},"example config.toml"),". You may send deploys to one of the trusted nodes or use them to query other online nodes.")),(0,c.kt)("details",null,(0,c.kt)("summary",null,"Example account_put_deploy request"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": [\n {\n "approvals": [\n {\n "signer": "01f8b29f39c38600ecb3bbb082951e04ab63a4ad4f7c9048a5057e461a5a8d58a5",\n "signature": "019d6ef5c62c80ad4e50df343fba6f0fced17dea4c65e7976f66335ffcfcde2a7f02e928c8507cef3c76c3151e0e9cc9c3f7838b9f7a99ac4be5522ca092841100"\n }\n ],\n "hash": "00a8677713222df88b6988926e0b14adeda6c663957f5075003395da4e5c6888",\n "header": {\n "account": "01f8b29f39c38600ecb3bbb082951e04ab63a4ad4f7c9048a5057e461a5a8d58a5",\n "body_hash": "145ae09d6da5bc290051db8cb7132a41a30473d5900eaaf409d92b666325ca00",\n "chain_name": "casper-net-1",\n "dependencies": [\n "0101010101010101010101010101010101010101010101010101010101010101"\n ],\n "gas_price": 1,\n "timestamp": "2023-09-26T14:07:10.024Z",\n "ttl": "1h"\n },\n "payment": {\n "StoredContractByName": {\n "args": [\n [\n "amount",\n {\n "bytes": "0400f90295",\n "cl_type": "U512"\n }\n ]\n ],\n "entry_point": "example-entry-point",\n "name": "casper-example"\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295"\n }\n ],\n [\n "target",\n {\n "cl_type": "URef",\n "bytes": "09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db07"\n }\n ]\n ]\n }\n }\n }\n ]\n}\n\n'))),(0,c.kt)("h3",{id:"account_put_deploy_result"},(0,c.kt)("inlineCode",{parentName:"h3"},"account_put_deploy_result")),(0,c.kt)("p",null,"The result contains the ",(0,c.kt)("a",{parentName:"p",href:"/developers/json-rpc/types_chain#deployhash"},"deploy_hash"),", which is the primary identifier of a Deploy within a Casper network."),(0,c.kt)("table",null,(0,c.kt)("thead",{parentName:"table"},(0,c.kt)("tr",{parentName:"thead"},(0,c.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,c.kt)("th",{parentName:"tr",align:null},"Type"),(0,c.kt)("th",{parentName:"tr",align:null},"Description"))),(0,c.kt)("tbody",{parentName:"table"},(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},"api_version"),(0,c.kt)("td",{parentName:"tr",align:null},"String"),(0,c.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},(0,c.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#deployhash"},"deploy_hash")),(0,c.kt)("td",{parentName:"tr",align:null},"String"),(0,c.kt)("td",{parentName:"tr",align:null},"A hex-encoded hash of the Deploy as sent.")))),(0,c.kt)("details",null,(0,c.kt)("summary",null,"Example account_put_deploy result"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"\n }\n}\n\n'))),(0,c.kt)("h2",{id:"speculative_exec"},"speculative_exec"),(0,c.kt)("p",null,"The ",(0,c.kt)("inlineCode",{parentName:"p"},"speculative_exec")," endpoint provides a method to execute a ",(0,c.kt)("inlineCode",{parentName:"p"},"Deploy")," without committing its execution effects to global state. By default, ",(0,c.kt)("inlineCode",{parentName:"p"},"speculative_exec")," is disabled on a node. Sending a request to a node with the endpoint disabled will result in an error message. If enabled, ",(0,c.kt)("inlineCode",{parentName:"p"},"speculative_exec")," operates on a separate port from the primary JSON-RPC, using 7778."),(0,c.kt)("p",null,(0,c.kt)("inlineCode",{parentName:"p"},"speculative_exec")," executes a Deploy at a specified block. In the case of this endpoint, the execution effects are not committed to global state. As such, it can be used for observing the execution effects of a Deploy without paying for the execution of the Deploy."),(0,c.kt)("table",null,(0,c.kt)("thead",{parentName:"table"},(0,c.kt)("tr",{parentName:"thead"},(0,c.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,c.kt)("th",{parentName:"tr",align:null},"Type"),(0,c.kt)("th",{parentName:"tr",align:null},"Description"))),(0,c.kt)("tbody",{parentName:"table"},(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},(0,c.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockidentifier"},"block_identifier")),(0,c.kt)("td",{parentName:"tr",align:null},"Object"),(0,c.kt)("td",{parentName:"tr",align:null},"The block hash or height on top of which to execute the deploy. If not supplied,the most recent block will be used.")),(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},(0,c.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#deploy"},"deploy")),(0,c.kt)("td",{parentName:"tr",align:null},"Object"),(0,c.kt)("td",{parentName:"tr",align:null},"A Deploy consists of an item containing a smart contract along with the requester's signature(s).")))),(0,c.kt)("details",null,(0,c.kt)("summary",null,"Example speculative_exec request"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "jsonrpc": "2.0",\n "method": "speculative_exec",\n "params": {\n "block_identifier": null,\n "deploy": {\n "hash": "b6aa46333fb858deee7f259a5bca581251c6200a5d902aeb1244c3a7169b5971",\n "header": {\n "account": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",\n "timestamp": "2023-05-23T13:32:45.554Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "74db109805bb20de43ef89a5b084544a858908b236601519d5827cd9b7fbb925",\n "dependencies": [],\n "chain_name": "integration-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b",\n "parsed": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010000000000000000",\n "parsed": 0\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",\n "signature": "01c94d517d5bbc8d5c74e0e68b8cb308561ff979a1c91907b56d427cc90156c437726c0b736d17f7303f2db66e405c7e5c8175b8b863703938eff1659766dff808"\n }\n ]\n }\n },\n "id": 6889533540839698701\n}\n\n'))),(0,c.kt)("h3",{id:"speculative_exec_result"},(0,c.kt)("inlineCode",{parentName:"h3"},"speculative_exec_result")),(0,c.kt)("p",null,"The result contains the hash of the targeted block and the results of the execution."),(0,c.kt)("table",null,(0,c.kt)("thead",{parentName:"table"},(0,c.kt)("tr",{parentName:"thead"},(0,c.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,c.kt)("th",{parentName:"tr",align:null},"Type"),(0,c.kt)("th",{parentName:"tr",align:null},"Description"))),(0,c.kt)("tbody",{parentName:"table"},(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},"api_version"),(0,c.kt)("td",{parentName:"tr",align:null},"String"),(0,c.kt)("td",{parentName:"tr",align:null},"The RPC API version.")),(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},(0,c.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#blockhash"},"block_hash")),(0,c.kt)("td",{parentName:"tr",align:null},"Object"),(0,c.kt)("td",{parentName:"tr",align:null},"The Block hash on top of which the deploy was executed.")),(0,c.kt)("tr",{parentName:"tbody"},(0,c.kt)("td",{parentName:"tr",align:null},(0,c.kt)("a",{parentName:"td",href:"/developers/json-rpc/types_chain#executionresult"},"execution_results")),(0,c.kt)("td",{parentName:"tr",align:null},"Object"),(0,c.kt)("td",{parentName:"tr",align:null},"The map of Block hash to execution result.")))),(0,c.kt)("details",null,(0,c.kt)("summary",null,"Example speculative_exec result"),(0,c.kt)("pre",null,(0,c.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "jsonrpc": "2.0",\n "id": -8801853076373554652,\n "result": {\n "api_version": "1.5.0",\n "block_hash": "ff862326b08702a5089d64e32100537b7ff984cac4c0ba6d1c561f7c47125f76",\n "execution_result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "05f0e630ed87",\n "parsed": "583799990000"\n }\n }\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "05f0e630ed87",\n "parsed": "583799990000"\n }\n }\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": "Identity"\n },\n {\n "key": "balance-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "05f0ed2d5887",\n "parsed": "581299990000"\n }\n }\n },\n {\n "key": "balance-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd",\n "transform": {\n "AddUInt512": "2500000000"\n }\n },\n {\n "key": "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612",\n "transform": {\n "WriteTransfer": {\n "deploy_hash": "d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",\n "from": "account-hash-0a9b33af5108c5a6e1067b0ddec6853ce1745d591375d767ac5db680d21845e7",\n "to": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "source": "uref-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678-007",\n "target": "uref-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd-004",\n "amount": "2500000000",\n "gas": "0",\n "id": 0\n }\n }\n },\n {\n "key": "deploy-d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",\n "transfers": [\n "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612"\n ],\n "from": "account-hash-0a9b33af5108c5a6e1067b0ddec6853ce1745d591375d767ac5db680d21845e7",\n "source": "uref-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678-007",\n "gas": "100000000"\n }\n }\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "balance-ecc530e74cf2185936a334aa1e0f07539aa3b33c4b547e71fc4109151755652f",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-ecc530e74cf2185936a334aa1e0f07539aa3b33c4b547e71fc4109151755652f",\n "transform": {\n "AddUInt512": "100000000"\n }\n }\n ]\n },\n "transfers": [\n "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612"\n ],\n "cost": "100000000"\n }\n }\n }\n}\n\n'))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/db0e1f9a.c940cb9f.js b/assets/js/db0e1f9a.acbe0ead.js similarity index 98% rename from assets/js/db0e1f9a.c940cb9f.js rename to assets/js/db0e1f9a.acbe0ead.js index 30b8cacf82..f15919dfe6 100644 --- a/assets/js/db0e1f9a.c940cb9f.js +++ b/assets/js/db0e1f9a.acbe0ead.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[8444],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return m}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),u=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(i.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},k=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=u(n),k=a,m=p["".concat(i,".").concat(k)]||p[k]||d[k]||o;return n?r.createElement(m,l(l({ref:t},c),{},{components:n})):r.createElement(m,l({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=k;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[p]="string"==typeof e?e:a,l[1]=s;for(var u=2;u=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),u=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(i.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},k=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=u(n),k=a,m=p["".concat(i,".").concat(k)]||p[k]||d[k]||o;return n?r.createElement(m,l(l({ref:t},c),{},{components:n})):r.createElement(m,l({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=k;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[p]="string"==typeof e?e:a,l[1]=s;for(var u=2;u=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(n),h=a,m=p["".concat(c,".").concat(h)]||p[h]||f[h]||i;return n?r.createElement(m,o(o({ref:t},u),{},{components:n})):r.createElement(m,o({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:a,o[1]=s;for(var l=2;l=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(n),h=a,m=p["".concat(c,".").concat(h)]||p[h]||f[h]||i;return n?r.createElement(m,o(o({ref:t},u),{},{components:n})):r.createElement(m,o({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:a,o[1]=s;for(var l=2;l=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var d=a.createContext({}),c=function(e){var n=a.useContext(d),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},l=function(e){var n=c(e.components);return a.createElement(d.Provider,{value:n},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},h=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,o=e.originalType,d=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),p=c(t),h=i,b=p["".concat(d,".").concat(h)]||p[h]||u[h]||o;return t?a.createElement(b,r(r({ref:n},l),{},{components:t})):a.createElement(b,r({ref:n},l))}));function b(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var o=t.length,r=new Array(o);r[0]=h;var s={};for(var d in n)hasOwnProperty.call(n,d)&&(s[d]=n[d]);s.originalType=e,s[p]="string"==typeof e?e:i,r[1]=s;for(var c=2;c \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-hash \\\n--session-entry-point add_bid \\\n--session-arg=\"public_key:public_key=''\" \\\n--session-arg=\"amount:u512=''\" \\\n--session-arg=\"delegation_rate:u8=''\"\n")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,o.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,o.kt)("em",{parentName:"li"},"casper-test")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,o.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-hash")," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Testnet"),": ",(0,o.kt)("inlineCode",{parentName:"li"},"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Mainnet"),": ",(0,o.kt)("inlineCode",{parentName:"li"},"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"))),(0,o.kt)("ol",{start:6},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-entry-point")," - Name of the entrypoint that will be used when calling the contract")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"add_bid")," entry point expects three arguments:"),(0,o.kt)("ol",{start:7},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"public key"),": The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"amount"),": The bidding amount"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"delegation_rate"),": Percentage of the rewards that the node operator retains for their services")),(0,o.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"add_bid")," entry point on the auction contract has a fixed cost of 2.5 CSPR.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example:")),(0,o.kt)("p",null,"This example command uses the Casper Testnet to bid 10,000 CSPR for a validating slot:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point add_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[10000 * 1000000000]'\" \\\n--session-arg=\"delegation_rate:u8='10'\"\n")),(0,o.kt)("p",null,"Next, ",(0,o.kt)("a",{parentName:"p",href:"#check-the-status-of-the-bid-in-the-auction"},"check the status of the auction")," to see if you have won a validator slot."),(0,o.kt)("h2",{id:"bonding-compiled-wasm"},"Method 2: Bonding with Compiled Wasm"),(0,o.kt)("p",null,"Another way to send a bonding transaction to the network is via a deploy containing the compiled ",(0,o.kt)("inlineCode",{parentName:"p"},"add_bid.wasm"),". For details, refer to ",(0,o.kt)("a",{parentName:"p",href:"/operators/setup/joining#step-3-build-contracts"},"Building the Required Contracts"),"."),(0,o.kt)("p",null,"The following deploy is a template for sending a bonding request:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address http:// \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name \\\n--payment-amount \\\n--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \\\n--session-arg=\"public_key:public_key=''\" \\\n--session-arg=\"amount:u512=''\" \\\n--session-arg=\"delegation_rate:u8=''\"\n")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,o.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,o.kt)("em",{parentName:"li"},"casper-test")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to the compiled Wasm on your computer")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"add_bid.wasm")," expects three arguments:"),(0,o.kt)("ol",{start:7},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"public_key"),": The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"amount"),": The bidding amount"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"delegation_rate"),": Percentage of the rewards that the node operator retains for their services")),(0,o.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"This method is more expensive than calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"add_bid")," entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example:")),(0,o.kt)("p",null,"Here is an example request to bond using the ",(0,o.kt)("inlineCode",{parentName:"p"},"add_bid.wasm"),". The payment amount specified is 3 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec.toml"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.235.219:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 3000000000 \\\n--session-path ~/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[10000 * 1000000000]'\" \\\n--session-arg=\"delegation_rate:u8='10'\"\n")),(0,o.kt)("p",null,"Next, check the bid status to see if you have won a validator slot."),(0,o.kt)("h2",{id:"check-the-status-of-the-bid-in-the-auction"},"Checking the Bid Status"),(0,o.kt)("p",null,"Since the bid was submitted using a deploy like any other, perform ",(0,o.kt)("inlineCode",{parentName:"p"},"get-deploy")," using the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-client"),", to see the execution status."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address http:// \n")),(0,o.kt)("p",null,"If the bid wins the auction, the public key and associated bonded amount will appear in the auction contract as part of the validator set for a future era. To determine if the bid was accepted, query the auction contract:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-auction-info --node-address http://\n")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Example auction info response"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n"jsonrpc": "2.0",\n"result": {\n "bids": [\n {\n "bid": {\n "bonding_purse": "uref-488a0bbc3c3729f5696965da7a3aeee83805392944e36157909da273255fdb85-007",\n "delegation_rate": 0,\n "delegators": [],\n "release_era": null,\n "reward": "93328432442428418861229954179737",\n "staked_amount": "10000000000000000"\n },\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012"\n },\n {\n "bid": {\n "bonding_purse": "uref-14e128b099b0c3680100520226e6999b322989586cc22db0630db5ec1329f0a7-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "0",\n "staked_amount": "9000000000000000"\n },\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87"\n },\n {\n "bid": {\n "bonding_purse": "uref-6c0bf8cee1c0749dd9766376910867a84b2e826eaf6c118fcb0224c7d8d229dd-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "266185120443441810685787",\n "staked_amount": "100000000"\n },\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f"\n },\n {\n "bid": {\n "bonding_purse": "uref-3880b3daf95f962f57e6a4b1589564abf7deef58a1fb0753d1108316bba7b3d7-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "0",\n "staked_amount": "9000000000000000"\n },\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643"\n },\n {\n "bid": {\n "bonding_purse": "uref-5a777c9cd53456b49eecf25dcc13e12ddff4106175a69f8e24a7c9a4c135df0d-007",\n "delegation_rate": 0,\n "delegators": [],\n "release_era": null,\n "reward": "93328432442428418861229954179737",\n "staked_amount": "10000000000000000"\n },\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e"\n }\n ],\n "block_height": 318,\n "era_validators": [\n {\n "era_id": 20,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 21,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 22,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 23,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n }\n ],\n "state_root_hash": "c16ba80ea200d786008f8100ea79f9cfeb8d7d5ee8b133eda5a50dcf1c7131e8"\n},\n"id": -3624528661787095850\n}\n'))),(0,o.kt)("br",null),(0,o.kt)("p",null,"Note the ",(0,o.kt)("inlineCode",{parentName:"p"},"era_id")," and the ",(0,o.kt)("inlineCode",{parentName:"p"},"validator_weights")," in the response above. The current era is the one with the lowest ID in the ",(0,o.kt)("inlineCode",{parentName:"p"},"era_validators")," array. For a given ",(0,o.kt)("inlineCode",{parentName:"p"},"era_id"),", a set of validators is defined. If the public key associated with a bid appears in the ",(0,o.kt)("inlineCode",{parentName:"p"},"validator_weights")," structure for an era, then the account is bonded in that era."),(0,o.kt)("h2",{id:"losing-bid"},"A Losing Bid"),(0,o.kt)("p",null,"If a bid doesn't win a slot in the auction, it is too low. The resolution is to increase the bid amount. It is possible to submit additional bids, to increase the odds of winning a slot. It is also possible to encourage token holders to delegate stake to you for bonding."),(0,o.kt)("h2",{id:"avoiding-ejection"},"Avoiding Ejection"),(0,o.kt)("p",null,"To stay bonded and avoid ejection, each validator must keep their node running and in sync with the rest of the network. To recover from ejection, you will find more details ",(0,o.kt)("a",{parentName:"p",href:"/operators/becoming-a-validator/recovering"},"here"),"."),(0,o.kt)("h2",{id:"withdrawing-a-bid"},"Withdrawing a Bid"),(0,o.kt)("p",null,"Follow the steps in ",(0,o.kt)("a",{parentName:"p",href:"/operators/becoming-a-validator/unbonding"},"Unbonding")," to withdraw a bid."))}b.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[1301],{3905:function(e,n,t){t.d(n,{Zo:function(){return l},kt:function(){return b}});var a=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function r(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var d=a.createContext({}),c=function(e){var n=a.useContext(d),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},l=function(e){var n=c(e.components);return a.createElement(d.Provider,{value:n},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},h=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,o=e.originalType,d=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),p=c(t),h=i,b=p["".concat(d,".").concat(h)]||p[h]||u[h]||o;return t?a.createElement(b,r(r({ref:n},l),{},{components:t})):a.createElement(b,r({ref:n},l))}));function b(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var o=t.length,r=new Array(o);r[0]=h;var s={};for(var d in n)hasOwnProperty.call(n,d)&&(s[d]=n[d]);s.originalType=e,s[p]="string"==typeof e?e:i,r[1]=s;for(var c=2;c \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-hash \\\n--session-entry-point add_bid \\\n--session-arg=\"public_key:public_key=''\" \\\n--session-arg=\"amount:u512=''\" \\\n--session-arg=\"delegation_rate:u8=''\"\n")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,o.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,o.kt)("em",{parentName:"li"},"casper-test")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,o.kt)("a",{parentName:"li",href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml"},"1.5.1")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-hash")," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Testnet"),": ",(0,o.kt)("inlineCode",{parentName:"li"},"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Mainnet"),": ",(0,o.kt)("inlineCode",{parentName:"li"},"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"))),(0,o.kt)("ol",{start:6},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-entry-point")," - Name of the entrypoint that will be used when calling the contract")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"add_bid")," entry point expects three arguments:"),(0,o.kt)("ol",{start:7},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"public key"),": The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"amount"),": The bidding amount"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"delegation_rate"),": Percentage of the rewards that the node operator retains for their services")),(0,o.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"add_bid")," entry point on the auction contract has a fixed cost of 2.5 CSPR.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example:")),(0,o.kt)("p",null,"This example command uses the Casper Testnet to bid 10,000 CSPR for a validating slot:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point add_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[10000 * 1000000000]'\" \\\n--session-arg=\"delegation_rate:u8='10'\"\n")),(0,o.kt)("p",null,"Next, ",(0,o.kt)("a",{parentName:"p",href:"#check-the-status-of-the-bid-in-the-auction"},"check the status of the auction")," to see if you have won a validator slot."),(0,o.kt)("h2",{id:"bonding-compiled-wasm"},"Method 2: Bonding with Compiled Wasm"),(0,o.kt)("p",null,"Another way to send a bonding transaction to the network is via a deploy containing the compiled ",(0,o.kt)("inlineCode",{parentName:"p"},"add_bid.wasm"),". For details, refer to ",(0,o.kt)("a",{parentName:"p",href:"/operators/setup/joining#step-3-build-contracts"},"Building the Required Contracts"),"."),(0,o.kt)("p",null,"The following deploy is a template for sending a bonding request:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address http:// \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name \\\n--payment-amount \\\n--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \\\n--session-arg=\"public_key:public_key=''\" \\\n--session-arg=\"amount:u512=''\" \\\n--session-arg=\"delegation_rate:u8=''\"\n")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the account paying for the Deploy"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,o.kt)("em",{parentName:"li"},"casper"),". For Testnet, use ",(0,o.kt)("em",{parentName:"li"},"casper-test")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The payment for the Deploy in motes"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to the compiled Wasm on your computer")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"add_bid.wasm")," expects three arguments:"),(0,o.kt)("ol",{start:7},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"public_key"),": The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"amount"),": The bidding amount"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"delegation_rate"),": Percentage of the rewards that the node operator retains for their services")),(0,o.kt)("p",null,"The command will return a deploy hash, which is needed to verify the deploy's processing results."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"This method is more expensive than calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"add_bid")," entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example:")),(0,o.kt)("p",null,"Here is an example request to bond using the ",(0,o.kt)("inlineCode",{parentName:"p"},"add_bid.wasm"),". The payment amount specified is 3 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec.toml"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.235.219:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 3000000000 \\\n--session-path ~/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[10000 * 1000000000]'\" \\\n--session-arg=\"delegation_rate:u8='10'\"\n")),(0,o.kt)("p",null,"Next, check the bid status to see if you have won a validator slot."),(0,o.kt)("h2",{id:"check-the-status-of-the-bid-in-the-auction"},"Checking the Bid Status"),(0,o.kt)("p",null,"Since the bid was submitted using a deploy like any other, perform ",(0,o.kt)("inlineCode",{parentName:"p"},"get-deploy")," using the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-client"),", to see the execution status."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-deploy --node-address http:// \n")),(0,o.kt)("p",null,"If the bid wins the auction, the public key and associated bonded amount will appear in the auction contract as part of the validator set for a future era. To determine if the bid was accepted, query the auction contract:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-auction-info --node-address http://\n")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Example auction info response"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'{\n"jsonrpc": "2.0",\n"result": {\n "bids": [\n {\n "bid": {\n "bonding_purse": "uref-488a0bbc3c3729f5696965da7a3aeee83805392944e36157909da273255fdb85-007",\n "delegation_rate": 0,\n "delegators": [],\n "release_era": null,\n "reward": "93328432442428418861229954179737",\n "staked_amount": "10000000000000000"\n },\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012"\n },\n {\n "bid": {\n "bonding_purse": "uref-14e128b099b0c3680100520226e6999b322989586cc22db0630db5ec1329f0a7-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "0",\n "staked_amount": "9000000000000000"\n },\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87"\n },\n {\n "bid": {\n "bonding_purse": "uref-6c0bf8cee1c0749dd9766376910867a84b2e826eaf6c118fcb0224c7d8d229dd-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "266185120443441810685787",\n "staked_amount": "100000000"\n },\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f"\n },\n {\n "bid": {\n "bonding_purse": "uref-3880b3daf95f962f57e6a4b1589564abf7deef58a1fb0753d1108316bba7b3d7-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "0",\n "staked_amount": "9000000000000000"\n },\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643"\n },\n {\n "bid": {\n "bonding_purse": "uref-5a777c9cd53456b49eecf25dcc13e12ddff4106175a69f8e24a7c9a4c135df0d-007",\n "delegation_rate": 0,\n "delegators": [],\n "release_era": null,\n "reward": "93328432442428418861229954179737",\n "staked_amount": "10000000000000000"\n },\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e"\n }\n ],\n "block_height": 318,\n "era_validators": [\n {\n "era_id": 20,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 21,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 22,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 23,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n }\n ],\n "state_root_hash": "c16ba80ea200d786008f8100ea79f9cfeb8d7d5ee8b133eda5a50dcf1c7131e8"\n},\n"id": -3624528661787095850\n}\n'))),(0,o.kt)("br",null),(0,o.kt)("p",null,"Note the ",(0,o.kt)("inlineCode",{parentName:"p"},"era_id")," and the ",(0,o.kt)("inlineCode",{parentName:"p"},"validator_weights")," in the response above. The current era is the one with the lowest ID in the ",(0,o.kt)("inlineCode",{parentName:"p"},"era_validators")," array. For a given ",(0,o.kt)("inlineCode",{parentName:"p"},"era_id"),", a set of validators is defined. If the public key associated with a bid appears in the ",(0,o.kt)("inlineCode",{parentName:"p"},"validator_weights")," structure for an era, then the account is bonded in that era."),(0,o.kt)("h2",{id:"losing-bid"},"A Losing Bid"),(0,o.kt)("p",null,"If a bid doesn't win a slot in the auction, it is too low. The resolution is to increase the bid amount. It is possible to submit additional bids, to increase the odds of winning a slot. It is also possible to encourage token holders to delegate stake to you for bonding."),(0,o.kt)("h2",{id:"avoiding-ejection"},"Avoiding Ejection"),(0,o.kt)("p",null,"To stay bonded and avoid ejection, each validator must keep their node running and in sync with the rest of the network. To recover from ejection, you will find more details ",(0,o.kt)("a",{parentName:"p",href:"/operators/becoming-a-validator/recovering"},"here"),"."),(0,o.kt)("h2",{id:"withdrawing-a-bid"},"Withdrawing a Bid"),(0,o.kt)("p",null,"Follow the steps in ",(0,o.kt)("a",{parentName:"p",href:"/operators/becoming-a-validator/unbonding"},"Unbonding")," to withdraw a bid."))}b.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/de7cb1a1.9816e830.js b/assets/js/de7cb1a1.840f8a36.js similarity index 99% rename from assets/js/de7cb1a1.9816e830.js rename to assets/js/de7cb1a1.840f8a36.js index 88a0492b28..7af4292dd5 100644 --- a/assets/js/de7cb1a1.9816e830.js +++ b/assets/js/de7cb1a1.840f8a36.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5153],{3905:function(e,t,n){n.d(t,{Zo:function(){return l},kt:function(){return h}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),p=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=p(e.components);return a.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},k=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),k=r,h=u["".concat(c,".").concat(k)]||u[k]||d[k]||o;return n?a.createElement(h,i(i({ref:t},l),{},{components:n})):a.createElement(h,i({ref:t},l))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=k;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:r,i[1]=s;for(var p=2;psecret_key.pem file",id:"generating-the-secret_keypem-file",level:4},{value:"Generating public keys from the secret_key.pem file",id:"generating-public-keys-from-the-secret_keypem-file",level:4},{value:"Generating an Account Hash",id:"generating-an-account-hash",level:2},{value:"Finding the Main Purse URef",id:"purse-uref",level:2},{value:"Using the Casper CLI client",id:"using-the-casper-cli-client",level:3},{value:"Using a block explorer",id:"using-a-block-explorer",level:3}],d={toc:u},k="wrapper";function h(e){var t=e.components,n=(0,r.Z)(e,i);return(0,o.kt)(k,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"accounts-and-cryptographic-keys"},"Accounts and Cryptographic Keys"),(0,o.kt)("p",null,"The Casper blockchain uses an on-chain ",(0,o.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-head"},"account-based model"),", uniquely identified by an ",(0,o.kt)("inlineCode",{parentName:"p"},"AccountHash")," derived from a specific ",(0,o.kt)("inlineCode",{parentName:"p"},"PublicKey"),". The ",(0,o.kt)("inlineCode",{parentName:"p"},"AccountHash")," is a 32-byte hash derived from any of the supported ",(0,o.kt)("inlineCode",{parentName:"p"},"PublicKey")," variants below to standardize keys that can vary in length."),(0,o.kt)("p",null,"By default, a transactional interaction with the blockchain takes the form of a ",(0,o.kt)("inlineCode",{parentName:"p"},"Deploy")," cryptographically signed by the key-pair corresponding to the ",(0,o.kt)("inlineCode",{parentName:"p"},"PublicKey")," used to create the account."),(0,o.kt)("p",null,"The Casper platform supports two types of keys for creating accounts and signing transactions:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"#eddsa-keys"},"Ed25519")," keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"#ecdsa-keys"},"Secp256k1")," keys, which use the Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve; they are 68 bytes long and are also found on the Ethereum blockchain")),(0,o.kt)("p",null,"You can generate keys using both formats, and it is also possible to ",(0,o.kt)("a",{parentName:"p",href:"#working-with-existing-ethereum-keys"},"work with existing Ethereum keys"),"."),(0,o.kt)("p",null,"You can also ",(0,o.kt)("a",{parentName:"p",href:"#generating-an-account-hash"},"generate an account hash")," from a public key with the Casper command-line client."),(0,o.kt)("h2",{id:"creating-accounts-and-keys"},"Creating Accounts and Keys"),(0,o.kt)("p",null,"When you create an account on the Casper blockchain, a cryptographic key-pair will be created when using either the ",(0,o.kt)("a",{parentName:"p",href:"#option-1-key-generation-using-the-casper-client"},"Casper command-line client")," or a block explorer."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"SAVE your keys to a safe place, preferably offline.")),(0,o.kt)("h3",{id:"option-1-key-generation-using-the-casper-client"},"Option 1: Generating keys using the Casper Client"),(0,o.kt)("p",null,"This option describes how you can use the Casper command-line client to set up an account using either key type."),(0,o.kt)("h4",{id:"eddsa-keys"},"EdDSA Keys"),(0,o.kt)("p",null,"The command-line client generates EdDSA keys by default. Use the command below to create the account."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"mkdir ed25519-keys\ncasper-client keygen ed25519-keys/\ntree ed25519-keys/\n")),(0,o.kt)("p",null,"Sample output of the ",(0,o.kt)("inlineCode",{parentName:"p"},"tree")," command shows the contents of the ",(0,o.kt)("em",{parentName:"p"},"ed25519-keys")," folder:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"ed25519-keys/\n\u251c\u2500\u2500 public_key.pem\n\u251c\u2500\u2500 public_key_hex\n\u2514\u2500\u2500 secret_key.pem\n\n0 directories, 3 files\n")),(0,o.kt)("p",null,"Here are some details about the files generated:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"public_key.pem")," is a ",(0,o.kt)("em",{parentName:"li"},"PEM"),"-encoded public key"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"public_key_hex")," is a hexadecimal-encoded string of the public key"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"secret_key.pem")," is the ",(0,o.kt)("em",{parentName:"li"},"PEM"),"-encoded secret key")),(0,o.kt)("p",null,"The public-key-hex for ",(0,o.kt)("inlineCode",{parentName:"p"},"Ed25519")," keys starts with 01 and is 66 bytes long:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cat ed25519-keys/public_key_hex\n011724c5c8e2404ca01c872e1bbd9202a0114e5d143760f685086a5cffe261dabd\n")),(0,o.kt)("h4",{id:"ecdsa-keys"},"ECDSA Keys"),(0,o.kt)("p",null,"To create ",(0,o.kt)("inlineCode",{parentName:"p"},"Secp256k1")," keys, which use the ECDSA algorithm with the P-256 curve, follow these steps:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"mkdir secp256k1-keys\ncasper-client keygen -a secp256k1 secp256k1-keys/\ntree secp256k1-keys/\n")),(0,o.kt)("p",null,"Sample output of the ",(0,o.kt)("inlineCode",{parentName:"p"},"tree")," command shows the contents of the ",(0,o.kt)("em",{parentName:"p"},"secp256k1-keys")," folder:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"secp256k1-keys/\n\u251c\u2500\u2500 public_key.pem\n\u251c\u2500\u2500 public_key_hex\n\u2514\u2500\u2500 secret_key.pem\n\n0 directories, 3 files\n")),(0,o.kt)("p",null,"The public-key-hex for ",(0,o.kt)("inlineCode",{parentName:"p"},"Secp256k1")," keys starts with 02 and is 68 bytes long:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cat secp256k1-keys/public_key_hex\n020287e1a79d0d9f3196391808a8b3e5007895f43cde679e4c960e7e9b92841bb98d\n")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"After generating keys for the account, you may add funds to the account's purse to finish the account creation process.")),(0,o.kt)("h3",{id:"option-2-key-generation-using-a-block-explorer"},"Option 2: Generating keys using a block explorer"),(0,o.kt)("p",null,"This option is available on networks that have a block explorer."),(0,o.kt)("p",null,"For instance, on the official Testnet, the ",(0,o.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/"},"CSPR.live")," block explorer is available, and the following instructions assume you are using it."),(0,o.kt)("p",null,"Start by creating an account using the ",(0,o.kt)("a",{parentName:"p",href:"https://www.casperwallet.io/"},"Casper Wallet"),", ",(0,o.kt)("a",{parentName:"p",href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?support=true"},"Ledger"),", or ",(0,o.kt)("a",{parentName:"p",href:"https://casper.tor.us/"},"Torus Wallet"),"."),(0,o.kt)("admonition",{type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"The Casper Signer has been replaced with the Casper Wallet and will be deprecated. We recommend migrating all your Casper accounts to the Casper Wallet as outlined ",(0,o.kt)("a",{parentName:"p",href:"https://www.casperwallet.io/user-guide/signer-user-start-here"},"here"),".")),(0,o.kt)("h2",{id:"funding-your-account"},"Funding your Account"),(0,o.kt)("p",null,"Once you create your account, you can ",(0,o.kt)("a",{parentName:"p",href:"/developers/prerequisites#funding-an-account"},"fund the account's main purse")," to finish the process of setting it up."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Until you fund your account's main purse, it does not exist on the blockchain.")),(0,o.kt)("h2",{id:"working-with-existing-ethereum-keys"},"Working with Existing Ethereum Keys"),(0,o.kt)("p",null,"You can also use existing Ethereum keys in Casper. Here is an example set of Ethereum keys and their corresponding address:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"Address:0x7863B6F7232D99FF80B74E4C8BB3BEE3BDE0291F\nPublic key:0470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66\nPrivate key:29773906aef3ee1f5868371fd7c50f9092205df26f60e660cafacbf2b95fe086\n")),(0,o.kt)("p",null,"To use existing Ethereum keys, the Casper virtual machine (VM) needs to know that the key is a ",(0,o.kt)("inlineCode",{parentName:"p"},"Secp256k1")," type. To achieve this, we will prefix the public key hex with 02, as shown in the example below."),(0,o.kt)("p",null,"The Casper command-line client provides an example of how this works."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example"),":"),(0,o.kt)("p",null,"The following transaction sends 10 CSPR."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client transfer \\\n--transfer-id 1234567 \\\n--node-address http://localhost:7777 \\\n--chain-name casper \\\n--target-account 020470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66 \\\n--amount 10000000000 \\\n--secret-key \\\n--payment-amount 100000000\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The payment amount varies based on each deploy and network ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),".")),(0,o.kt)("p",null,"The Casper command-line client requires the secret key in ",(0,o.kt)("em",{parentName:"p"},"PEM")," format to send a Deploy from this account. If you want to use existing Ethereum keys with the command-line client, a conversion to ",(0,o.kt)("em",{parentName:"p"},"PEM")," format is needed."),(0,o.kt)("p",null,"The following example is a JS script that generates a ",(0,o.kt)("em",{parentName:"p"},"PEM")," file, using a ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/stacks-network/key-encoder-js"},"key encoder")," and Node.js. To install these components, do the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt install nodejs\nnpm install key-encoder\n")),(0,o.kt)("p",null,"Then create the JS script ",(0,o.kt)("em",{parentName:"p"},"convert-to-pem.js")," using ",(0,o.kt)("em",{parentName:"p"},"vi")," or ",(0,o.kt)("em",{parentName:"p"},"nano"),", and include this content:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-javascript"},'var KeyEncoder = require("key-encoder"),\n keyEncoder = new KeyEncoder.default("secp256k1");\nlet priv_hex = "THE SECRET KEY TO ENCODE";\nlet priv_pem = keyEncoder.encodePrivate(priv_hex, "raw", "pem");\nconsole.log(priv_pem);\n')),(0,o.kt)("p",null,"Then run the script using Node.js and name the secret key."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"node convert-to-pem.js > eth-secret.pem\n")),(0,o.kt)("p",null,"To view the secret key, use ",(0,o.kt)("inlineCode",{parentName:"p"},"cat "),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cat eth-secret.pem\n")),(0,o.kt)("p",null,"Below is the sample output showing the contents of the secret key."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"-----BEGIN EC PRIVATE KEY-----\nMHQCAQEEIBjXY+7xZagzTjL4p8bGWS8FPRcW13mgytdu5c3e556MoAcGBSuBBAAK\noUQDQgAEpV4dVaPeAEaH0VXrQtLzjpGt1pui1q08311em6wDCchGNjzsnOY7stGF\ntlKF2V5RFQn4rzkwipSYnrqaPf1pTA==\n-----END EC PRIVATE KEY-----\n")),(0,o.kt)("h3",{id:"option-3-generating-keys-using-openssl"},"Option 3: Generating keys using OpenSSL"),(0,o.kt)("p",null,"You can generate keys without the Casper client using the ",(0,o.kt)("a",{parentName:"p",href:"https://www.openssl.org/"},"openssl")," cryptography toolkit. The commands below are valid only for generating Ed25519 keys on a Linux operating system."),(0,o.kt)("h4",{id:"generating-the-secret_keypem-file"},"Generating the ",(0,o.kt)("inlineCode",{parentName:"h4"},"secret_key.pem")," file"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"openssl genpkey -algorithm ed25519 -out secret_key.pem\n")),(0,o.kt)("h4",{id:"generating-public-keys-from-the-secret_keypem-file"},"Generating public keys from the ",(0,o.kt)("inlineCode",{parentName:"h4"},"secret_key.pem")," file"),(0,o.kt)("p",null,"For default Ed25519 keys, you can generate the ",(0,o.kt)("inlineCode",{parentName:"p"},"public_key.pem")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"public_key_hex")," using these commands:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'openssl pkey -in secret_key.pem -pubout -out public_key.pem\n\n{ echo -n 01; openssl pkey -outform DER -pubout -in "secret_key.pem" | tail -c +13 | openssl base64 | openssl base64 -d | hexdump -ve \'/1 "%02x" \' | tr -d "/n"; } > public_key_hex\n')),(0,o.kt)("h2",{id:"generating-an-account-hash"},"Generating an Account Hash"),(0,o.kt)("p",null,"To generate the account hash for a public key, use the ",(0,o.kt)("em",{parentName:"p"},"account-address")," option of the Casper client. The argument for the ",(0,o.kt)("em",{parentName:"p"},"public-key")," must be a properly formatted public key. The public key may also be read from a file, which should be one of the two files generated via the ",(0,o.kt)("em",{parentName:"p"},"keygen")," command: ",(0,o.kt)("em",{parentName:"p"},"public_key_hex")," or ",(0,o.kt)("em",{parentName:"p"},"public_key.pem"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client account-address --public-key \n")),(0,o.kt)("h2",{id:"purse-uref"},"Finding the Main Purse URef"),(0,o.kt)("p",null,"You can use the Casper CLI client or a block explorer to find the URef identifying an account's main purse."),(0,o.kt)("h3",{id:"using-the-casper-cli-client"},"Using the Casper CLI client"),(0,o.kt)("p",null,"With the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-client"),", use the ",(0,o.kt)("inlineCode",{parentName:"p"},"get-account-info")," subcommand."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-account-info \\\n--node-address \\\n--public-key \n")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"public-key")," - This must be a properly formatted public key. The public key may instead be read in from a file, in which case, enter the path to the file as the argument. The file should be one of the two public key files generated via the ",(0,o.kt)("inlineCode",{parentName:"li"},"keygen"),' subcommand; "public_key_hex" or "public_key.pem"')),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Sample command and output"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client get-account-info --node-address http://65.21.75.254:7777 --public-key 0202ceafc0aa35f5a7bdda22f65c046b9b30b858459e18d3670f035839ad887fe5db\n{\n "id": -2018234245556346849,\n "jsonrpc": "2.0",\n "result": {\n "account": {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "weight": 1\n }\n ],\n "main_purse": "uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-007",\n "named_keys": []\n },\n "api_version": "1.4.15",\n "merkle_proof": "[29712 hex chars]"\n }\n}\n\n'))),(0,o.kt)("p",null,"Run the following help command for more details:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-account-info --help\n")),(0,o.kt)("h3",{id:"using-a-block-explorer"},"Using a block explorer"),(0,o.kt)("p",null,"Using the block explorer for ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live/"},"Mainnet")," or ",(0,o.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/"},"Testnet"),", open the Account in question, and expand the ",(0,o.kt)("inlineCode",{parentName:"p"},"Raw Data")," section. Look for the ",(0,o.kt)("inlineCode",{parentName:"p"},"main_purse")," field and find the corresponding URef. If you do not see data in the ",(0,o.kt)("inlineCode",{parentName:"p"},"Raw Data")," section, then the account has not been funded yet."),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{src:"/image/design/main_purse_uref.png",alt:"Image showing an account's main purse",width:"500"})))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5153],{3905:function(e,t,n){n.d(t,{Zo:function(){return l},kt:function(){return h}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),p=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=p(e.components);return a.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},k=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),k=r,h=u["".concat(c,".").concat(k)]||u[k]||d[k]||o;return n?a.createElement(h,i(i({ref:t},l),{},{components:n})):a.createElement(h,i({ref:t},l))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=k;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:r,i[1]=s;for(var p=2;psecret_key.pem file",id:"generating-the-secret_keypem-file",level:4},{value:"Generating public keys from the secret_key.pem file",id:"generating-public-keys-from-the-secret_keypem-file",level:4},{value:"Generating an Account Hash",id:"generating-an-account-hash",level:2},{value:"Finding the Main Purse URef",id:"purse-uref",level:2},{value:"Using the Casper CLI client",id:"using-the-casper-cli-client",level:3},{value:"Using a block explorer",id:"using-a-block-explorer",level:3}],d={toc:u},k="wrapper";function h(e){var t=e.components,n=(0,r.Z)(e,i);return(0,o.kt)(k,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"accounts-and-cryptographic-keys"},"Accounts and Cryptographic Keys"),(0,o.kt)("p",null,"The Casper blockchain uses an on-chain ",(0,o.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#accounts-head"},"account-based model"),", uniquely identified by an ",(0,o.kt)("inlineCode",{parentName:"p"},"AccountHash")," derived from a specific ",(0,o.kt)("inlineCode",{parentName:"p"},"PublicKey"),". The ",(0,o.kt)("inlineCode",{parentName:"p"},"AccountHash")," is a 32-byte hash derived from any of the supported ",(0,o.kt)("inlineCode",{parentName:"p"},"PublicKey")," variants below to standardize keys that can vary in length."),(0,o.kt)("p",null,"By default, a transactional interaction with the blockchain takes the form of a ",(0,o.kt)("inlineCode",{parentName:"p"},"Deploy")," cryptographically signed by the key-pair corresponding to the ",(0,o.kt)("inlineCode",{parentName:"p"},"PublicKey")," used to create the account."),(0,o.kt)("p",null,"The Casper platform supports two types of keys for creating accounts and signing transactions:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"#eddsa-keys"},"Ed25519")," keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"#ecdsa-keys"},"Secp256k1")," keys, which use the Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve; they are 68 bytes long and are also found on the Ethereum blockchain")),(0,o.kt)("p",null,"You can generate keys using both formats, and it is also possible to ",(0,o.kt)("a",{parentName:"p",href:"#working-with-existing-ethereum-keys"},"work with existing Ethereum keys"),"."),(0,o.kt)("p",null,"You can also ",(0,o.kt)("a",{parentName:"p",href:"#generating-an-account-hash"},"generate an account hash")," from a public key with the Casper command-line client."),(0,o.kt)("h2",{id:"creating-accounts-and-keys"},"Creating Accounts and Keys"),(0,o.kt)("p",null,"When you create an account on the Casper blockchain, a cryptographic key-pair will be created when using either the ",(0,o.kt)("a",{parentName:"p",href:"#option-1-key-generation-using-the-casper-client"},"Casper command-line client")," or a block explorer."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"SAVE your keys to a safe place, preferably offline.")),(0,o.kt)("h3",{id:"option-1-key-generation-using-the-casper-client"},"Option 1: Generating keys using the Casper Client"),(0,o.kt)("p",null,"This option describes how you can use the Casper command-line client to set up an account using either key type."),(0,o.kt)("h4",{id:"eddsa-keys"},"EdDSA Keys"),(0,o.kt)("p",null,"The command-line client generates EdDSA keys by default. Use the command below to create the account."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"mkdir ed25519-keys\ncasper-client keygen ed25519-keys/\ntree ed25519-keys/\n")),(0,o.kt)("p",null,"Sample output of the ",(0,o.kt)("inlineCode",{parentName:"p"},"tree")," command shows the contents of the ",(0,o.kt)("em",{parentName:"p"},"ed25519-keys")," folder:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"ed25519-keys/\n\u251c\u2500\u2500 public_key.pem\n\u251c\u2500\u2500 public_key_hex\n\u2514\u2500\u2500 secret_key.pem\n\n0 directories, 3 files\n")),(0,o.kt)("p",null,"Here are some details about the files generated:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"public_key.pem")," is a ",(0,o.kt)("em",{parentName:"li"},"PEM"),"-encoded public key"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"public_key_hex")," is a hexadecimal-encoded string of the public key"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"secret_key.pem")," is the ",(0,o.kt)("em",{parentName:"li"},"PEM"),"-encoded secret key")),(0,o.kt)("p",null,"The public-key-hex for ",(0,o.kt)("inlineCode",{parentName:"p"},"Ed25519")," keys starts with 01 and is 66 bytes long:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cat ed25519-keys/public_key_hex\n011724c5c8e2404ca01c872e1bbd9202a0114e5d143760f685086a5cffe261dabd\n")),(0,o.kt)("h4",{id:"ecdsa-keys"},"ECDSA Keys"),(0,o.kt)("p",null,"To create ",(0,o.kt)("inlineCode",{parentName:"p"},"Secp256k1")," keys, which use the ECDSA algorithm with the P-256 curve, follow these steps:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"mkdir secp256k1-keys\ncasper-client keygen -a secp256k1 secp256k1-keys/\ntree secp256k1-keys/\n")),(0,o.kt)("p",null,"Sample output of the ",(0,o.kt)("inlineCode",{parentName:"p"},"tree")," command shows the contents of the ",(0,o.kt)("em",{parentName:"p"},"secp256k1-keys")," folder:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"secp256k1-keys/\n\u251c\u2500\u2500 public_key.pem\n\u251c\u2500\u2500 public_key_hex\n\u2514\u2500\u2500 secret_key.pem\n\n0 directories, 3 files\n")),(0,o.kt)("p",null,"The public-key-hex for ",(0,o.kt)("inlineCode",{parentName:"p"},"Secp256k1")," keys starts with 02 and is 68 bytes long:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cat secp256k1-keys/public_key_hex\n020287e1a79d0d9f3196391808a8b3e5007895f43cde679e4c960e7e9b92841bb98d\n")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"After generating keys for the account, you may add funds to the account's purse to finish the account creation process.")),(0,o.kt)("h3",{id:"option-2-key-generation-using-a-block-explorer"},"Option 2: Generating keys using a block explorer"),(0,o.kt)("p",null,"This option is available on networks that have a block explorer."),(0,o.kt)("p",null,"For instance, on the official Testnet, the ",(0,o.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/"},"CSPR.live")," block explorer is available, and the following instructions assume you are using it."),(0,o.kt)("p",null,"Start by creating an account using the ",(0,o.kt)("a",{parentName:"p",href:"https://www.casperwallet.io/"},"Casper Wallet"),", ",(0,o.kt)("a",{parentName:"p",href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?support=true"},"Ledger"),", or ",(0,o.kt)("a",{parentName:"p",href:"https://casper.tor.us/"},"Torus Wallet"),"."),(0,o.kt)("admonition",{type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"The Casper Signer has been replaced with the Casper Wallet and will be deprecated. We recommend migrating all your Casper accounts to the Casper Wallet as outlined ",(0,o.kt)("a",{parentName:"p",href:"https://www.casperwallet.io/user-guide/signer-user-start-here"},"here"),".")),(0,o.kt)("h2",{id:"funding-your-account"},"Funding your Account"),(0,o.kt)("p",null,"Once you create your account, you can ",(0,o.kt)("a",{parentName:"p",href:"/developers/prerequisites#funding-an-account"},"fund the account's main purse")," to finish the process of setting it up."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Until you fund your account's main purse, it does not exist on the blockchain.")),(0,o.kt)("h2",{id:"working-with-existing-ethereum-keys"},"Working with Existing Ethereum Keys"),(0,o.kt)("p",null,"You can also use existing Ethereum keys in Casper. Here is an example set of Ethereum keys and their corresponding address:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"Address:0x7863B6F7232D99FF80B74E4C8BB3BEE3BDE0291F\nPublic key:0470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66\nPrivate key:29773906aef3ee1f5868371fd7c50f9092205df26f60e660cafacbf2b95fe086\n")),(0,o.kt)("p",null,"To use existing Ethereum keys, the Casper virtual machine (VM) needs to know that the key is a ",(0,o.kt)("inlineCode",{parentName:"p"},"Secp256k1")," type. To achieve this, we will prefix the public key hex with 02, as shown in the example below."),(0,o.kt)("p",null,"The Casper command-line client provides an example of how this works."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Example"),":"),(0,o.kt)("p",null,"The following transaction sends 10 CSPR."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client transfer \\\n--transfer-id 1234567 \\\n--node-address http://localhost:7777 \\\n--chain-name casper \\\n--target-account 020470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66 \\\n--amount 10000000000 \\\n--secret-key \\\n--payment-amount 100000000\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The payment amount varies based on each deploy and network ",(0,o.kt)("a",{parentName:"p",href:"/concepts/glossary/C#chainspec"},"chainspec"),".")),(0,o.kt)("p",null,"The Casper command-line client requires the secret key in ",(0,o.kt)("em",{parentName:"p"},"PEM")," format to send a Deploy from this account. If you want to use existing Ethereum keys with the command-line client, a conversion to ",(0,o.kt)("em",{parentName:"p"},"PEM")," format is needed."),(0,o.kt)("p",null,"The following example is a JS script that generates a ",(0,o.kt)("em",{parentName:"p"},"PEM")," file, using a ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/stacks-network/key-encoder-js"},"key encoder")," and Node.js. To install these components, do the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt install nodejs\nnpm install key-encoder\n")),(0,o.kt)("p",null,"Then create the JS script ",(0,o.kt)("em",{parentName:"p"},"convert-to-pem.js")," using ",(0,o.kt)("em",{parentName:"p"},"vi")," or ",(0,o.kt)("em",{parentName:"p"},"nano"),", and include this content:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-javascript"},'var KeyEncoder = require("key-encoder"),\n keyEncoder = new KeyEncoder.default("secp256k1");\nlet priv_hex = "THE SECRET KEY TO ENCODE";\nlet priv_pem = keyEncoder.encodePrivate(priv_hex, "raw", "pem");\nconsole.log(priv_pem);\n')),(0,o.kt)("p",null,"Then run the script using Node.js and name the secret key."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"node convert-to-pem.js > eth-secret.pem\n")),(0,o.kt)("p",null,"To view the secret key, use ",(0,o.kt)("inlineCode",{parentName:"p"},"cat "),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cat eth-secret.pem\n")),(0,o.kt)("p",null,"Below is the sample output showing the contents of the secret key."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"-----BEGIN EC PRIVATE KEY-----\nMHQCAQEEIBjXY+7xZagzTjL4p8bGWS8FPRcW13mgytdu5c3e556MoAcGBSuBBAAK\noUQDQgAEpV4dVaPeAEaH0VXrQtLzjpGt1pui1q08311em6wDCchGNjzsnOY7stGF\ntlKF2V5RFQn4rzkwipSYnrqaPf1pTA==\n-----END EC PRIVATE KEY-----\n")),(0,o.kt)("h3",{id:"option-3-generating-keys-using-openssl"},"Option 3: Generating keys using OpenSSL"),(0,o.kt)("p",null,"You can generate keys without the Casper client using the ",(0,o.kt)("a",{parentName:"p",href:"https://www.openssl.org/"},"openssl")," cryptography toolkit. The commands below are valid only for generating Ed25519 keys on a Linux operating system."),(0,o.kt)("h4",{id:"generating-the-secret_keypem-file"},"Generating the ",(0,o.kt)("inlineCode",{parentName:"h4"},"secret_key.pem")," file"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"openssl genpkey -algorithm ed25519 -out secret_key.pem\n")),(0,o.kt)("h4",{id:"generating-public-keys-from-the-secret_keypem-file"},"Generating public keys from the ",(0,o.kt)("inlineCode",{parentName:"h4"},"secret_key.pem")," file"),(0,o.kt)("p",null,"For default Ed25519 keys, you can generate the ",(0,o.kt)("inlineCode",{parentName:"p"},"public_key.pem")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"public_key_hex")," using these commands:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'openssl pkey -in secret_key.pem -pubout -out public_key.pem\n\n{ echo -n 01; openssl pkey -outform DER -pubout -in "secret_key.pem" | tail -c +13 | openssl base64 | openssl base64 -d | hexdump -ve \'/1 "%02x" \' | tr -d "/n"; } > public_key_hex\n')),(0,o.kt)("h2",{id:"generating-an-account-hash"},"Generating an Account Hash"),(0,o.kt)("p",null,"To generate the account hash for a public key, use the ",(0,o.kt)("em",{parentName:"p"},"account-address")," option of the Casper client. The argument for the ",(0,o.kt)("em",{parentName:"p"},"public-key")," must be a properly formatted public key. The public key may also be read from a file, which should be one of the two files generated via the ",(0,o.kt)("em",{parentName:"p"},"keygen")," command: ",(0,o.kt)("em",{parentName:"p"},"public_key_hex")," or ",(0,o.kt)("em",{parentName:"p"},"public_key.pem"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client account-address --public-key \n")),(0,o.kt)("h2",{id:"purse-uref"},"Finding the Main Purse URef"),(0,o.kt)("p",null,"You can use the Casper CLI client or a block explorer to find the URef identifying an account's main purse."),(0,o.kt)("h3",{id:"using-the-casper-cli-client"},"Using the Casper CLI client"),(0,o.kt)("p",null,"With the ",(0,o.kt)("inlineCode",{parentName:"p"},"casper-client"),", use the ",(0,o.kt)("inlineCode",{parentName:"p"},"get-account-info")," subcommand."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-account-info \\\n--node-address \\\n--public-key \n")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"public-key")," - This must be a properly formatted public key. The public key may instead be read in from a file, in which case, enter the path to the file as the argument. The file should be one of the two public key files generated via the ",(0,o.kt)("inlineCode",{parentName:"li"},"keygen"),' subcommand; "public_key_hex" or "public_key.pem"')),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Sample command and output"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client get-account-info --node-address http://65.21.75.254:7777 --public-key 0202ceafc0aa35f5a7bdda22f65c046b9b30b858459e18d3670f035839ad887fe5db\n{\n "id": -2018234245556346849,\n "jsonrpc": "2.0",\n "result": {\n "account": {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "weight": 1\n }\n ],\n "main_purse": "uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-007",\n "named_keys": []\n },\n "api_version": "1.4.15",\n "merkle_proof": "[29712 hex chars]"\n }\n}\n\n'))),(0,o.kt)("p",null,"Run the following help command for more details:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-account-info --help\n")),(0,o.kt)("h3",{id:"using-a-block-explorer"},"Using a block explorer"),(0,o.kt)("p",null,"Using the block explorer for ",(0,o.kt)("a",{parentName:"p",href:"https://cspr.live/"},"Mainnet")," or ",(0,o.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/"},"Testnet"),", open the Account in question, and expand the ",(0,o.kt)("inlineCode",{parentName:"p"},"Raw Data")," section. Look for the ",(0,o.kt)("inlineCode",{parentName:"p"},"main_purse")," field and find the corresponding URef. If you do not see data in the ",(0,o.kt)("inlineCode",{parentName:"p"},"Raw Data")," section, then the account has not been funded yet."),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{src:"/image/design/main_purse_uref.png",alt:"Image showing an account's main purse",width:"500"})))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e00654fa.08fe7795.js b/assets/js/e00654fa.0675a786.js similarity index 99% rename from assets/js/e00654fa.08fe7795.js rename to assets/js/e00654fa.0675a786.js index 970c44a16d..298f7fa4ce 100644 --- a/assets/js/e00654fa.08fe7795.js +++ b/assets/js/e00654fa.0675a786.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[7698],{3905:function(e,t,a){a.d(t,{Zo:function(){return d},kt:function(){return h}});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},g=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(a),g=r,h=p["".concat(l,".").concat(g)]||p[g]||u[g]||o;return a?n.createElement(h,i(i({ref:t},d),{},{components:a})):n.createElement(h,i({ref:t},d))}));function h(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=g;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;c=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},g=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(a),g=r,h=p["".concat(l,".").concat(g)]||p[g]||u[g]||o;return a?n.createElement(h,i(i({ref:t},d),{},{components:a})):n.createElement(h,i({ref:t},d))}));function h(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=g;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;c=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),c=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},i=function(e){var t=c(e.components);return a.createElement(p.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,p=e.parentName,i=o(e,["components","mdxType","originalType","parentName"]),u=c(n),m=r,y=u["".concat(p,".").concat(m)]||u[m]||d[m]||s;return n?a.createElement(y,l(l({ref:t},i),{},{components:n})):a.createElement(y,l({ref:t},i))}));function y(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,l=new Array(s);l[0]=m;var o={};for(var p in t)hasOwnProperty.call(t,p)&&(o[p]=t[p]);o.originalType=e,o[u]="string"==typeof e?e:r,l[1]=o;for(var c=2;c 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.')})))?void 0:n.filter(Boolean))?t:[]}(e).map((function(e){var t=e.props;return{value:t.value,label:t.label,attributes:t.attributes,default:t.default}}))}function d(e){var t=e.values,n=e.children;return(0,r.useMemo)((function(){var e=null!=t?t:u(n);return function(e){var t=(0,c.l)(e,(function(e,t){return e.value===t.value}));if(t.length>0)throw new Error('Docusaurus error: Duplicate values "'+t.map((function(e){return e.value})).join(", ")+'" found in . Every value needs to be unique.')}(e),e}),[t,n])}function m(e){var t=e.value;return e.tabValues.some((function(e){return e.value===t}))}function y(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId,s=(0,o.k6)(),l=function(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId;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 null!=a?a:null}({queryString:n,groupId:a});return[(0,p._X)(l),(0,r.useCallback)((function(e){if(l){var t=new URLSearchParams(s.location.search);t.set(l,e),s.replace(Object.assign({},s.location,{search:t.toString()}))}}),[l,s])]}function k(e){var t,n,a,s,l=e.defaultValue,o=e.queryString,p=void 0!==o&&o,c=e.groupId,u=d(e),k=(0,r.useState)((function(){return function(e){var t,n=e.defaultValue,a=e.tabValues;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({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((function(e){return e.value})).join(", ")+". If you intend to show no default tab, use defaultValue={null} instead.");return n}var r=null!=(t=a.find((function(e){return e.default})))?t:a[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:l,tabValues:u})})),h=k[0],b=k[1],f=y({queryString:p,groupId:c}),g=f[0],_=f[1],v=(t=function(e){return e?"docusaurus.tab."+e:null}({groupId:c}.groupId),n=(0,i.Nk)(t),a=n[0],s=n[1],[a,(0,r.useCallback)((function(e){t&&s.set(e)}),[t,s])]),w=v[0],C=v[1],N=function(){var e=null!=g?g:w;return m({value:e,tabValues:u})?e:null}();return(0,r.useLayoutEffect)((function(){N&&b(N)}),[N]),{selectedValue:h,selectValue:(0,r.useCallback)((function(e){if(!m({value:e,tabValues:u}))throw new Error("Can't select invalid tab value="+e);b(e),_(e),C(e)}),[_,C,u]),tabValues:u}}var h=n(2389),b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function f(e){var t=e.className,n=e.block,o=e.selectedValue,p=e.selectValue,c=e.tabValues,i=[],u=(0,l.o5)().blockElementScrollPositionUntilNextRender,d=function(e){var t=e.currentTarget,n=i.indexOf(t),a=c[n].value;a!==o&&(u(t),p(a))},m=function(e){var t,n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":var a,r=i.indexOf(e.currentTarget)+1;n=null!=(a=i[r])?a:i[0];break;case"ArrowLeft":var s,l=i.indexOf(e.currentTarget)-1;n=null!=(s=i[l])?s:i[i.length-1]}null==(t=n)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.Z)("tabs",{"tabs--block":n},t)},c.map((function(e){var t=e.value,n=e.label,l=e.attributes;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:o===t?0:-1,"aria-selected":o===t,key:t,ref:function(e){return i.push(e)},onKeyDown:m,onClick:d},l,{className:(0,s.Z)("tabs__item",b.tabItem,null==l?void 0:l.className,{"tabs__item--active":o===t})}),null!=n?n:t)})))}function g(e){var t=e.lazy,n=e.children,a=e.selectedValue,s=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){var l=s.find((function(e){return e.props.value===a}));return l?(0,r.cloneElement)(l,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},s.map((function(e,t){return(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a})})))}function _(e){var t=k(e);return r.createElement("div",{className:(0,s.Z)("tabs-container",b.tabList)},r.createElement(f,(0,a.Z)({},e,t)),r.createElement(g,(0,a.Z)({},e,t)))}function v(e){var t=(0,h.Z)();return r.createElement(_,(0,a.Z)({key:String(t)},e))}},4139:function(e,t,n){n.r(t),n.d(t,{assets:function(){return d},contentTitle:function(){return i},default:function(){return h},frontMatter:function(){return c},metadata:function(){return u},toc:function(){return m}});var a=n(7462),r=n(3366),s=(n(7294),n(3905)),l=n(4866),o=n(5162),p=["components"],c={},i="SDK Client Library Usage",u={unversionedId:"developers/dapps/sdk/client-library-usage",id:"developers/dapps/sdk/client-library-usage",title:"SDK Client Library Usage",description:"Installing the SDKs",source:"@site/source/docs/casper/developers/dapps/sdk/client-library-usage.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/client-library-usage",permalink:"/developers/dapps/sdk/client-library-usage",draft:!1,editUrl:"https://github.com/casper-network/docs/tree/dev/source/docs/casper/developers/dapps/sdk/client-library-usage.md",tags:[],version:"current",lastUpdatedAt:1707837031,formattedLastUpdatedAt:"Feb 13, 2024",frontMatter:{},sidebar:"developers",previous:{title:"SDK Client Libraries",permalink:"/sdk"},next:{title:"JavaScript/TypeScript SDK",permalink:"/developers/dapps/sdk/script-sdk"}},d={},m=[{value:"Installing the SDKs",id:"installing-the-sdks",level:2},{value:"Creating Accounts",id:"creating-accounts",level:2},{value:"Creating new account keys",id:"creating-new-account-keys",level:3},{value:"Exporting the public key and account hash",id:"exporting-the-public-key-and-account-hash",level:3},{value:"Uploading the secret key from a file",id:"uploading-the-secret-key-from-a-file",level:3},{value:"Transferring CSPR",id:"transferring-cspr",level:2},{value:"Installing Contracts",id:"installing-contracts",level:2},{value:"Staking",id:"staking",level:2},{value:"Calling Contracts",id:"calling-contracts",level:2},{value:"Staking",id:"staking-1",level:2}],y={toc:m},k="wrapper";function h(e){var t=e.components,n=(0,r.Z)(e,p);return(0,s.kt)(k,(0,a.Z)({},y,n,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"sdk-client-library-usage"},"SDK Client Library Usage"),(0,s.kt)("h2",{id:"installing-the-sdks"},"Installing the SDKs"),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("p",null,"Use ",(0,s.kt)("inlineCode",{parentName:"p"},"npm")," or ",(0,s.kt)("inlineCode",{parentName:"p"},"yarn")," to install the ",(0,s.kt)("a",{parentName:"p",href:"https://www.npmjs.com/package/casper-js-sdk"},"casper-js-sdk")," package:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"npm install casper-js-sdk\n")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"yarn install casper-js-sdk\n"))),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("p",null,"Use ",(0,s.kt)("a",{parentName:"p",href:"https://pypi.org/project/pip/"},(0,s.kt)("inlineCode",{parentName:"a"},"pip"))," to install the ",(0,s.kt)("a",{parentName:"p",href:"https://pypi.org/project/pycspr/"},"pycspr")," package:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"pip install pycspr\n"))),(0,s.kt)(o.Z,{value:"rust",label:"Rust",mdxType:"TabItem"},(0,s.kt)("p",null,"Include the casper-client dependency to your ",(0,s.kt)("inlineCode",{parentName:"p"},"Cargo.toml"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre"},'[dependencies]\ncasper-client="1.5.1"\n')),(0,s.kt)("p",null,"and add it to your ",(0,s.kt)("inlineCode",{parentName:"p"},"main.rs"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},"extern crate casper_client;\n")),(0,s.kt)("p",null,"Use types and methods from casper_client:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},"use casper_client::transfer;\nuse casper_client::put_deploy;\n//...\n")),(0,s.kt)("p",null,"as casper_client functions are asynchronous, a tokyo runtime is necessary for testing:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre"},'[dependencies]\ntokio = { version = "^1.27.0", features = ["full"] }\n')))),(0,s.kt)("hr",null),(0,s.kt)("h2",{id:"creating-accounts"},"Creating Accounts"),(0,s.kt)("p",null,"You may use the SDKs to interact with accounts on a Casper network. Accounts can use either an Ed25519 or Secp256k1 digital signature scheme. See the ",(0,s.kt)("a",{parentName:"p",href:"/concepts/accounts-and-keys"},"Accounts and Cryptographic Keys")," page for more details."),(0,s.kt)("h3",{id:"creating-new-account-keys"},"Creating new account keys"),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const { Keys } = require("casper-js-sdk");\nconst keypair = Keys.Ed25519.new();\nconst { publicKey, privateKey } = keypair;\n')),(0,s.kt)("p",null,"Replace ",(0,s.kt)("inlineCode",{parentName:"p"},"Ed25519")," with ",(0,s.kt)("inlineCode",{parentName:"p"},"Secp256K1")," if you wish.")),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},"from pycspr.crypto import KeyAlgorithm, get_key_pair\nkeypair = get_key_pair(KeyAlgorithm.ED25519)\n")),(0,s.kt)("p",null,"Replace ",(0,s.kt)("inlineCode",{parentName:"p"},"ED25519")," with ",(0,s.kt)("inlineCode",{parentName:"p"},"SECP256K1")," if you wish.")),(0,s.kt)(o.Z,{value:"rust",label:"Rust",mdxType:"TabItem"},(0,s.kt)("p",null,"Create a keypair and write the files to a specified ",(0,s.kt)("inlineCode",{parentName:"p"},"PATH"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},' casper_client::keygen::generate_files("PATH", "ED25519", false).unwrap();\n')),(0,s.kt)("p",null,"Replace ",(0,s.kt)("inlineCode",{parentName:"p"},"ED25519")," with ",(0,s.kt)("inlineCode",{parentName:"p"},"SECP256K1")," if you wish."))),(0,s.kt)("h3",{id:"exporting-the-public-key-and-account-hash"},"Exporting the public key and account hash"),(0,s.kt)("p",null,"The ",(0,s.kt)("inlineCode",{parentName:"p"},"keypair")," variable contains the private and public key pair for the account. You can use, read, or export the public key. You may also want access to the account hash, often used within smart contracts on a Casper network. The following methods show how to extract the public key and account hash."),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},"// Create a hexadecimal representation of the public key and account hash.\nconst publicKeyHex = publicKey.toHex();\nconst accountHashHex = publicKey.toAccountHashStr();\n")),(0,s.kt)("p",null,"Note that ",(0,s.kt)("inlineCode",{parentName:"p"},"accountHashHex"),' will be prefixed with the text "account-hash-".')),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},"import pycspr.crypto\n\npublicKeyBytes = keypair.account_key\npublicKeyHex = pycspr.crypto.cl_checksum.encode(publicKeyBytes)\naccountHashBytes = pycspr.crypto.cl_operations.get_account_hash(publicKeyBytes)\naccountHashHex = pycspr.crypto.cl_checksum.encode(accountHashBytes)\n")))),(0,s.kt)("h3",{id:"uploading-the-secret-key-from-a-file"},"Uploading the secret key from a file"),(0,s.kt)("p",null,"To use a specific account, you should not include the private key in the source code; instead, upload the account's secret key from a local file. Update the path to the file in the example below."),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const { Keys } = require("casper-js-sdk");\nconst keypair = Keys.Ed25519.loadKeyPairFromPrivateFile("./secret_key.pem");\n')),(0,s.kt)("p",null,"Replace ",(0,s.kt)("inlineCode",{parentName:"p"},"Ed25519")," with ",(0,s.kt)("inlineCode",{parentName:"p"},"Secp256K1")," if you wish.")),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},'import pycspr\nkeypair = pycspr.parse_private_key(\n "./secret_key.pem",\n pycspr.crypto.KeyAlgorithm.ED25519\n)\n')),(0,s.kt)("p",null,"Replace ",(0,s.kt)("inlineCode",{parentName:"p"},"ED25519")," with ",(0,s.kt)("inlineCode",{parentName:"p"},"SECP256K1")," if you wish.")),(0,s.kt)(o.Z,{value:"rust",label:"Rust",mdxType:"TabItem"},(0,s.kt)("p",null,"In Rust, we don't explicitly import the private key as an object, but instead supply its path as an argument when calling functions:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},'let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./secret_key.pem",\n timestamp:"",\n ...\n};\n')))),(0,s.kt)("hr",null),(0,s.kt)("h2",{id:"transferring-cspr"},"Transferring CSPR"),(0,s.kt)("p",null,"Using the ",(0,s.kt)("inlineCode",{parentName:"p"},"keypair")," created ",(0,s.kt)("a",{parentName:"p",href:"#creating-accounts"},"above"),", you can sign a deploy that transfers CSPR."),(0,s.kt)("p",null,"Replace the ",(0,s.kt)("inlineCode",{parentName:"p"},"NODE_ADDRESS")," and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on ",(0,s.kt)("a",{parentName:"p",href:"https://cspr.live/tools/peers"},"cspr.live")," and for Testnet on ",(0,s.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/tools/peers"},"testnet.cspr.live"),". The RPC port is usually ",(0,s.kt)("inlineCode",{parentName:"p"},"7777"),", but it depends on the network's configuration settings."),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const { CasperClient, DeployUtil } = require("casper-js-sdk");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst receipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c";\n\nconst amount = 2.5e9; // Minimum transfer: 2.5 CSPR\nlet deployParams = new DeployUtil.DeployParams(\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n);\n\nconst session = DeployUtil.ExecutableDeployItem.newTransferWithOptionalTransferId(amount, recipientPublicKeyHex);\n\nconst payment = DeployUtil.standardPayment(0.1e9); // Gas payment in motes: 0.1 CSPR\nconst deploy = DeployUtil.makeDeploy(deployParams, session, payment);\nconst signedDeploy = DeployUtil.signDeploy(deploy, keypair);\n\nconsole.log(await casperClient.putDeploy(signedDeploy));\n'))),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},'import pycspr\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\nrecipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"\nrecipientPublicKeyBytes = pycspr.crypto.cl_checksum.decode(recipientPublicKeyHex)\n\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper" # or "casper-test" for Testnet\n)\n\ndeploy = pycspr.create_transfer(\n params = deployParams,\n amount = int(2.5e9), # Minimum transfer: 2.5 CSPR\n target = recipientPublicKeyBytes\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'))),(0,s.kt)(o.Z,{value:"rust",label:"Rust",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},'extern crate casper_client;\nasync fn send_transfer(){\n let maybe_rpc_id: &str = "";\n let node_address: &str = "http://135.181.216.142:7777";\n let verbosity_level: u64 = 1;\n let amount: &str = "2500000000";\n let target_account: &str = recipient;\n let transfer_id: &str = "1";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test" for testnet\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n let recipient: &str = "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca";\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount(amount);\n let result = casper_client::transfer(maybe_rpc_id, node_address, verbosity_level, amount, target_account, transfer_id, deploy_params, payment_params).await.unwrap();\n println!("Deploy response: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n send_transfer().await;\n}\n')))),(0,s.kt)("p",null,"Once submitted, the above snippet will print the deploy hash in the console."),(0,s.kt)("hr",null),(0,s.kt)("h2",{id:"installing-contracts"},"Installing Contracts"),(0,s.kt)("p",null,"To install a contract on the network, you need to sign and send a deploy containing the compiled Wasm."),(0,s.kt)("p",null,"Replace the ",(0,s.kt)("inlineCode",{parentName:"p"},"NODE_ADDRESS")," and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on ",(0,s.kt)("a",{parentName:"p",href:"https://cspr.live/tools/peers"},"cspr.live")," and for Testnet on ",(0,s.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/tools/peers"},"testnet.cspr.live"),". The RPC port is usually ",(0,s.kt)("inlineCode",{parentName:"p"},"7777"),", but it depends on the network's configuration settings."),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst contract = new Contracts.Contract(casperClient);\n\nconst contractWasm = new Uint8Array(fs.readFileSync("/path/to/contract.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n argument: CLValueBuilder.string("Hello world!"),\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "10000000000", // Gas payment (10 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n [keypair],\n);\n\nconsole.log(await casperClient.putDeploy(deploy));\n'))),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},'import pycspr\nfrom pycspr.types import ModuleBytes, CL_String\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\n\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper" # or "casper-test" for Testnet\n)\npayment = pycspr.create_standard_payment(10000000000) # 10 CSPR\nsession = ModuleBytes(\n module_bytes = pycspr.read_wasm("/path/to/contract.wasm"),\n args = {\n "message": CL_String("Hello world!"),\n }\n)\n\ndeploy = pycspr.create_deploy(deployParams, payment, session)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'))),(0,s.kt)(o.Z,{value:"rust",label:"Rust",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},'extern crate casper_client;\nasync fn put_deploy(){\n let maybe_rpc: &str = "";\n let verbosity: u64 = 1;\n let node_address: &str = "http://135.181.216.142:7777";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test"\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n // Without session args:\n // let session_args: Vec<&str> = Vec::new();\n // With session args:\n let mut session_args: Vec<&str> = Vec::new();\n session_args.push("argument:String=\'hello world\'");\n let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./contract.wasm", session_args, "");\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("10000000000");\n let result = casper_client::put_deploy(maybe_rpc_id, node_address, verbosity_level, deploy_params, session_params, payment_params).await.unwrap();\n println!("Deploy response: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n send_transfer().await;\n}\n')))),(0,s.kt)("p",null,"Once submitted, the above snippet will print the deploy hash in the console."),(0,s.kt)("h2",{id:"staking"},"Staking"),(0,s.kt)("p",null,"Token staking is a fundamental aspect of the Casper Network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network."),(0,s.kt)("p",null,"The delegation functionality is available as a smart contract, which can be found in the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node"},"casper-node")," repository. To delegate tokens, first clone the repository:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/casper-network/casper-node.git\ncd casper-node/\n")),(0,s.kt)("p",null,"Then compile the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/dev/smart_contracts/contracts/client/delegate/src/main.rs"},"delegate contract"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"make setup-rs\nmake build-contract-rs/delegate\n")),(0,s.kt)("p",null,"Now, assuming that you cloned ",(0,s.kt)("inlineCode",{parentName:"p"},"casper-node")," from your project's root directory, ",(0,s.kt)("inlineCode",{parentName:"p"},"cd")," back into it:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"cd ../\n")),(0,s.kt)("p",null,"Now in your dApp's backend (or standalone script), load the ",(0,s.kt)("em",{parentName:"p"},"delegate.wasm"),' file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.'),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst contract = new Contracts.Contract(casperClient);\n\nconst contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n amount: CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR\n delegator: keypair.publicKey,\n validator: CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"),\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "5000000000", // Gas payment (5 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for testnet\n [keypair],\n);\n\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})();\n'))),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},'import pycspr\n\nvalidator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(\n bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n)\n\ndeploy_params = pycspr.create_deploy_parameters(\n account = keypair, # Only the public key is used, see `create_deploy_parameters`\n chain_name = "casper" # or "casper-test" for testnet\n)\n\ndeploy = pycspr.create_validator_delegation(\n params = deploy_params,\n amount = int(500e9), # Minimum delegation amount: 500 CSPR\n public_key_of_delegator = keypair,\n public_key_of_validator = validator_public_key,\n path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'))),(0,s.kt)(o.Z,{value:"rust",label:"Rust",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},'extern crate casper_client;\nasync fn put_deploy(){\n let maybe_rpc: &str = "";\n let verbosity: u64 = 1;\n let node_address: &str = "http://135.181.216.142:7777";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test" for testnet\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n let mut session_args: Vec<&str> = Vec::new();\n session_args.push("amount:U512=\'500000000000\'");\n\n session_args.push("delegator:public_key=\'01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a\'");\n session_args.push("validator:public_key=\'validator_public_key\'");\n\n let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./delegate.wasm", session_args, "");\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("5000000000");\n let result = casper_client::put_deploy(maybe_rpc, node_address, verbosity, deploy_params, session_params, payment_params).await.unwrap();\n println!("Deploy result: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n put_deploy().await;\n}\n')))),(0,s.kt)("p",null,"Once submitted, the above snippet will print the deploy hash in the console."),(0,s.kt)("hr",null),(0,s.kt)("h2",{id:"calling-contracts"},"Calling Contracts"),(0,s.kt)("p",null,"Smart contracts on a Casper network are invoked by calling entry points. See below how to use Casper's SDKs to interact with these entry points and update the global state from a dApp:"),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst contract = new Contracts.Contract(casperClient);\ncontract.setContractHash("hash-a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d");\nconst runtimeArguments = RuntimeArgs.fromMap({\n message: CLValueBuilder.string("Hello world!"),\n});\nconst deploy = contract.callEntrypoint(\n "update_msg",\n runtimeArguments,\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n "1000000000", // 1 CSPR (10^9 Motes)\n [keypair],\n);\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})();\n'))),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},'import pycspr\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper-test"\n)\npayment = pycspr.create_standard_payment(10_000_000_000)\nsession = pycspr.types.StoredContractByHash(\n entry_point = "update_msg",\n hash = bytes.fromhex("a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d"),\n args = {\n "message": pycspr.types.CL_String("Hello world!"),\n }\n)\ndeploy = pycspr.create_deploy(deployParams, payment, session)\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n')))),(0,s.kt)("p",null,"Once submitted, the above snippet will print the deploy hash in the console."),(0,s.kt)("hr",null),(0,s.kt)("h2",{id:"staking-1"},"Staking"),(0,s.kt)("p",null,"Token staking is a fundamental aspect of a Casper network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network."),(0,s.kt)("p",null,"The delegation functionality is available as a smart contract, which can be found in the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node"},"casper-node")," repository. To delegate tokens, first clone the repository:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/casper-network/casper-node.git\ncd casper-node/\n")),(0,s.kt)("p",null,"Then compile the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/dev/smart_contracts/contracts/client/delegate/src/main.rs"},"delegate contract"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"make setup-rs\nmake build-contract-rs/delegate\n")),(0,s.kt)("p",null,"Now, navigate back to your project's root directory. In your dApp's backend (or standalone script), load the ",(0,s.kt)("em",{parentName:"p"},"delegate.wasm"),' file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.'),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst contract = new Contracts.Contract(casperClient);\n\nconst contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n amount: CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR\n delegator: keypair.publicKey,\n validator: CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"),\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "5000000000", // Gas payment (5 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for testnet\n [keypair],\n);\n\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})();\n'))),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},'import pycspr\n\nvalidator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(\n bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n)\n\ndeploy_params = pycspr.create_deploy_parameters(\n account = keypair, # Only the public key is used, see `create_deploy_parameters`\n chain_name = "casper" # or "casper-test" for testnet\n)\n\ndeploy = pycspr.create_validator_delegation(\n params = deploy_params,\n amount = int(500e9), # Minimum delegation amount: 500 CSPR\n public_key_of_delegator = keypair,\n public_key_of_validator = validator_public_key,\n path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n')))),(0,s.kt)("p",null,"Once submitted, the above snippet will print the deploy hash in the console."))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[4080],{3905:function(e,t,n){n.d(t,{Zo:function(){return i},kt:function(){return y}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),c=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},i=function(e){var t=c(e.components);return a.createElement(p.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,p=e.parentName,i=o(e,["components","mdxType","originalType","parentName"]),u=c(n),m=r,y=u["".concat(p,".").concat(m)]||u[m]||d[m]||s;return n?a.createElement(y,l(l({ref:t},i),{},{components:n})):a.createElement(y,l({ref:t},i))}));function y(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,l=new Array(s);l[0]=m;var o={};for(var p in t)hasOwnProperty.call(t,p)&&(o[p]=t[p]);o.originalType=e,o[u]="string"==typeof e?e:r,l[1]=o;for(var c=2;c 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.')})))?void 0:n.filter(Boolean))?t:[]}(e).map((function(e){var t=e.props;return{value:t.value,label:t.label,attributes:t.attributes,default:t.default}}))}function d(e){var t=e.values,n=e.children;return(0,r.useMemo)((function(){var e=null!=t?t:u(n);return function(e){var t=(0,c.l)(e,(function(e,t){return e.value===t.value}));if(t.length>0)throw new Error('Docusaurus error: Duplicate values "'+t.map((function(e){return e.value})).join(", ")+'" found in . Every value needs to be unique.')}(e),e}),[t,n])}function m(e){var t=e.value;return e.tabValues.some((function(e){return e.value===t}))}function y(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId,s=(0,o.k6)(),l=function(e){var t=e.queryString,n=void 0!==t&&t,a=e.groupId;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 null!=a?a:null}({queryString:n,groupId:a});return[(0,p._X)(l),(0,r.useCallback)((function(e){if(l){var t=new URLSearchParams(s.location.search);t.set(l,e),s.replace(Object.assign({},s.location,{search:t.toString()}))}}),[l,s])]}function k(e){var t,n,a,s,l=e.defaultValue,o=e.queryString,p=void 0!==o&&o,c=e.groupId,u=d(e),k=(0,r.useState)((function(){return function(e){var t,n=e.defaultValue,a=e.tabValues;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({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((function(e){return e.value})).join(", ")+". If you intend to show no default tab, use defaultValue={null} instead.");return n}var r=null!=(t=a.find((function(e){return e.default})))?t:a[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:l,tabValues:u})})),h=k[0],b=k[1],f=y({queryString:p,groupId:c}),g=f[0],_=f[1],v=(t=function(e){return e?"docusaurus.tab."+e:null}({groupId:c}.groupId),n=(0,i.Nk)(t),a=n[0],s=n[1],[a,(0,r.useCallback)((function(e){t&&s.set(e)}),[t,s])]),w=v[0],C=v[1],N=function(){var e=null!=g?g:w;return m({value:e,tabValues:u})?e:null}();return(0,r.useLayoutEffect)((function(){N&&b(N)}),[N]),{selectedValue:h,selectValue:(0,r.useCallback)((function(e){if(!m({value:e,tabValues:u}))throw new Error("Can't select invalid tab value="+e);b(e),_(e),C(e)}),[_,C,u]),tabValues:u}}var h=n(2389),b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function f(e){var t=e.className,n=e.block,o=e.selectedValue,p=e.selectValue,c=e.tabValues,i=[],u=(0,l.o5)().blockElementScrollPositionUntilNextRender,d=function(e){var t=e.currentTarget,n=i.indexOf(t),a=c[n].value;a!==o&&(u(t),p(a))},m=function(e){var t,n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":var a,r=i.indexOf(e.currentTarget)+1;n=null!=(a=i[r])?a:i[0];break;case"ArrowLeft":var s,l=i.indexOf(e.currentTarget)-1;n=null!=(s=i[l])?s:i[i.length-1]}null==(t=n)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.Z)("tabs",{"tabs--block":n},t)},c.map((function(e){var t=e.value,n=e.label,l=e.attributes;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:o===t?0:-1,"aria-selected":o===t,key:t,ref:function(e){return i.push(e)},onKeyDown:m,onClick:d},l,{className:(0,s.Z)("tabs__item",b.tabItem,null==l?void 0:l.className,{"tabs__item--active":o===t})}),null!=n?n:t)})))}function g(e){var t=e.lazy,n=e.children,a=e.selectedValue,s=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){var l=s.find((function(e){return e.props.value===a}));return l?(0,r.cloneElement)(l,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},s.map((function(e,t){return(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a})})))}function _(e){var t=k(e);return r.createElement("div",{className:(0,s.Z)("tabs-container",b.tabList)},r.createElement(f,(0,a.Z)({},e,t)),r.createElement(g,(0,a.Z)({},e,t)))}function v(e){var t=(0,h.Z)();return r.createElement(_,(0,a.Z)({key:String(t)},e))}},4139:function(e,t,n){n.r(t),n.d(t,{assets:function(){return d},contentTitle:function(){return i},default:function(){return h},frontMatter:function(){return c},metadata:function(){return u},toc:function(){return m}});var a=n(7462),r=n(3366),s=(n(7294),n(3905)),l=n(4866),o=n(5162),p=["components"],c={},i="SDK Client Library Usage",u={unversionedId:"developers/dapps/sdk/client-library-usage",id:"developers/dapps/sdk/client-library-usage",title:"SDK Client Library Usage",description:"Installing the SDKs",source:"@site/source/docs/casper/developers/dapps/sdk/client-library-usage.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/client-library-usage",permalink:"/developers/dapps/sdk/client-library-usage",draft:!1,editUrl:"https://github.com/casper-network/docs/tree/dev/source/docs/casper/developers/dapps/sdk/client-library-usage.md",tags:[],version:"current",lastUpdatedAt:1708091908,formattedLastUpdatedAt:"Feb 16, 2024",frontMatter:{},sidebar:"developers",previous:{title:"SDK Client Libraries",permalink:"/sdk"},next:{title:"JavaScript/TypeScript SDK",permalink:"/developers/dapps/sdk/script-sdk"}},d={},m=[{value:"Installing the SDKs",id:"installing-the-sdks",level:2},{value:"Creating Accounts",id:"creating-accounts",level:2},{value:"Creating new account keys",id:"creating-new-account-keys",level:3},{value:"Exporting the public key and account hash",id:"exporting-the-public-key-and-account-hash",level:3},{value:"Uploading the secret key from a file",id:"uploading-the-secret-key-from-a-file",level:3},{value:"Transferring CSPR",id:"transferring-cspr",level:2},{value:"Installing Contracts",id:"installing-contracts",level:2},{value:"Staking",id:"staking",level:2},{value:"Calling Contracts",id:"calling-contracts",level:2},{value:"Staking",id:"staking-1",level:2}],y={toc:m},k="wrapper";function h(e){var t=e.components,n=(0,r.Z)(e,p);return(0,s.kt)(k,(0,a.Z)({},y,n,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"sdk-client-library-usage"},"SDK Client Library Usage"),(0,s.kt)("h2",{id:"installing-the-sdks"},"Installing the SDKs"),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("p",null,"Use ",(0,s.kt)("inlineCode",{parentName:"p"},"npm")," or ",(0,s.kt)("inlineCode",{parentName:"p"},"yarn")," to install the ",(0,s.kt)("a",{parentName:"p",href:"https://www.npmjs.com/package/casper-js-sdk"},"casper-js-sdk")," package:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"npm install casper-js-sdk\n")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"yarn install casper-js-sdk\n"))),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("p",null,"Use ",(0,s.kt)("a",{parentName:"p",href:"https://pypi.org/project/pip/"},(0,s.kt)("inlineCode",{parentName:"a"},"pip"))," to install the ",(0,s.kt)("a",{parentName:"p",href:"https://pypi.org/project/pycspr/"},"pycspr")," package:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"pip install pycspr\n"))),(0,s.kt)(o.Z,{value:"rust",label:"Rust",mdxType:"TabItem"},(0,s.kt)("p",null,"Include the casper-client dependency to your ",(0,s.kt)("inlineCode",{parentName:"p"},"Cargo.toml"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre"},'[dependencies]\ncasper-client="1.5.1"\n')),(0,s.kt)("p",null,"and add it to your ",(0,s.kt)("inlineCode",{parentName:"p"},"main.rs"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},"extern crate casper_client;\n")),(0,s.kt)("p",null,"Use types and methods from casper_client:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},"use casper_client::transfer;\nuse casper_client::put_deploy;\n//...\n")),(0,s.kt)("p",null,"as casper_client functions are asynchronous, a tokyo runtime is necessary for testing:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre"},'[dependencies]\ntokio = { version = "^1.27.0", features = ["full"] }\n')))),(0,s.kt)("hr",null),(0,s.kt)("h2",{id:"creating-accounts"},"Creating Accounts"),(0,s.kt)("p",null,"You may use the SDKs to interact with accounts on a Casper network. Accounts can use either an Ed25519 or Secp256k1 digital signature scheme. See the ",(0,s.kt)("a",{parentName:"p",href:"/concepts/accounts-and-keys"},"Accounts and Cryptographic Keys")," page for more details."),(0,s.kt)("h3",{id:"creating-new-account-keys"},"Creating new account keys"),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const { Keys } = require("casper-js-sdk");\nconst keypair = Keys.Ed25519.new();\nconst { publicKey, privateKey } = keypair;\n')),(0,s.kt)("p",null,"Replace ",(0,s.kt)("inlineCode",{parentName:"p"},"Ed25519")," with ",(0,s.kt)("inlineCode",{parentName:"p"},"Secp256K1")," if you wish.")),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},"from pycspr.crypto import KeyAlgorithm, get_key_pair\nkeypair = get_key_pair(KeyAlgorithm.ED25519)\n")),(0,s.kt)("p",null,"Replace ",(0,s.kt)("inlineCode",{parentName:"p"},"ED25519")," with ",(0,s.kt)("inlineCode",{parentName:"p"},"SECP256K1")," if you wish.")),(0,s.kt)(o.Z,{value:"rust",label:"Rust",mdxType:"TabItem"},(0,s.kt)("p",null,"Create a keypair and write the files to a specified ",(0,s.kt)("inlineCode",{parentName:"p"},"PATH"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},' casper_client::keygen::generate_files("PATH", "ED25519", false).unwrap();\n')),(0,s.kt)("p",null,"Replace ",(0,s.kt)("inlineCode",{parentName:"p"},"ED25519")," with ",(0,s.kt)("inlineCode",{parentName:"p"},"SECP256K1")," if you wish."))),(0,s.kt)("h3",{id:"exporting-the-public-key-and-account-hash"},"Exporting the public key and account hash"),(0,s.kt)("p",null,"The ",(0,s.kt)("inlineCode",{parentName:"p"},"keypair")," variable contains the private and public key pair for the account. You can use, read, or export the public key. You may also want access to the account hash, often used within smart contracts on a Casper network. The following methods show how to extract the public key and account hash."),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},"// Create a hexadecimal representation of the public key and account hash.\nconst publicKeyHex = publicKey.toHex();\nconst accountHashHex = publicKey.toAccountHashStr();\n")),(0,s.kt)("p",null,"Note that ",(0,s.kt)("inlineCode",{parentName:"p"},"accountHashHex"),' will be prefixed with the text "account-hash-".')),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},"import pycspr.crypto\n\npublicKeyBytes = keypair.account_key\npublicKeyHex = pycspr.crypto.cl_checksum.encode(publicKeyBytes)\naccountHashBytes = pycspr.crypto.cl_operations.get_account_hash(publicKeyBytes)\naccountHashHex = pycspr.crypto.cl_checksum.encode(accountHashBytes)\n")))),(0,s.kt)("h3",{id:"uploading-the-secret-key-from-a-file"},"Uploading the secret key from a file"),(0,s.kt)("p",null,"To use a specific account, you should not include the private key in the source code; instead, upload the account's secret key from a local file. Update the path to the file in the example below."),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const { Keys } = require("casper-js-sdk");\nconst keypair = Keys.Ed25519.loadKeyPairFromPrivateFile("./secret_key.pem");\n')),(0,s.kt)("p",null,"Replace ",(0,s.kt)("inlineCode",{parentName:"p"},"Ed25519")," with ",(0,s.kt)("inlineCode",{parentName:"p"},"Secp256K1")," if you wish.")),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},'import pycspr\nkeypair = pycspr.parse_private_key(\n "./secret_key.pem",\n pycspr.crypto.KeyAlgorithm.ED25519\n)\n')),(0,s.kt)("p",null,"Replace ",(0,s.kt)("inlineCode",{parentName:"p"},"ED25519")," with ",(0,s.kt)("inlineCode",{parentName:"p"},"SECP256K1")," if you wish.")),(0,s.kt)(o.Z,{value:"rust",label:"Rust",mdxType:"TabItem"},(0,s.kt)("p",null,"In Rust, we don't explicitly import the private key as an object, but instead supply its path as an argument when calling functions:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},'let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./secret_key.pem",\n timestamp:"",\n ...\n};\n')))),(0,s.kt)("hr",null),(0,s.kt)("h2",{id:"transferring-cspr"},"Transferring CSPR"),(0,s.kt)("p",null,"Using the ",(0,s.kt)("inlineCode",{parentName:"p"},"keypair")," created ",(0,s.kt)("a",{parentName:"p",href:"#creating-accounts"},"above"),", you can sign a deploy that transfers CSPR."),(0,s.kt)("p",null,"Replace the ",(0,s.kt)("inlineCode",{parentName:"p"},"NODE_ADDRESS")," and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on ",(0,s.kt)("a",{parentName:"p",href:"https://cspr.live/tools/peers"},"cspr.live")," and for Testnet on ",(0,s.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/tools/peers"},"testnet.cspr.live"),". The RPC port is usually ",(0,s.kt)("inlineCode",{parentName:"p"},"7777"),", but it depends on the network's configuration settings."),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const { CasperClient, DeployUtil } = require("casper-js-sdk");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst receipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c";\n\nconst amount = 2.5e9; // Minimum transfer: 2.5 CSPR\nlet deployParams = new DeployUtil.DeployParams(\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n);\n\nconst session = DeployUtil.ExecutableDeployItem.newTransferWithOptionalTransferId(amount, recipientPublicKeyHex);\n\nconst payment = DeployUtil.standardPayment(0.1e9); // Gas payment in motes: 0.1 CSPR\nconst deploy = DeployUtil.makeDeploy(deployParams, session, payment);\nconst signedDeploy = DeployUtil.signDeploy(deploy, keypair);\n\nconsole.log(await casperClient.putDeploy(signedDeploy));\n'))),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},'import pycspr\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\nrecipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"\nrecipientPublicKeyBytes = pycspr.crypto.cl_checksum.decode(recipientPublicKeyHex)\n\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper" # or "casper-test" for Testnet\n)\n\ndeploy = pycspr.create_transfer(\n params = deployParams,\n amount = int(2.5e9), # Minimum transfer: 2.5 CSPR\n target = recipientPublicKeyBytes\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'))),(0,s.kt)(o.Z,{value:"rust",label:"Rust",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},'extern crate casper_client;\nasync fn send_transfer(){\n let maybe_rpc_id: &str = "";\n let node_address: &str = "http://135.181.216.142:7777";\n let verbosity_level: u64 = 1;\n let amount: &str = "2500000000";\n let target_account: &str = recipient;\n let transfer_id: &str = "1";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test" for testnet\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n let recipient: &str = "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca";\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount(amount);\n let result = casper_client::transfer(maybe_rpc_id, node_address, verbosity_level, amount, target_account, transfer_id, deploy_params, payment_params).await.unwrap();\n println!("Deploy response: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n send_transfer().await;\n}\n')))),(0,s.kt)("p",null,"Once submitted, the above snippet will print the deploy hash in the console."),(0,s.kt)("hr",null),(0,s.kt)("h2",{id:"installing-contracts"},"Installing Contracts"),(0,s.kt)("p",null,"To install a contract on the network, you need to sign and send a deploy containing the compiled Wasm."),(0,s.kt)("p",null,"Replace the ",(0,s.kt)("inlineCode",{parentName:"p"},"NODE_ADDRESS")," and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on ",(0,s.kt)("a",{parentName:"p",href:"https://cspr.live/tools/peers"},"cspr.live")," and for Testnet on ",(0,s.kt)("a",{parentName:"p",href:"https://testnet.cspr.live/tools/peers"},"testnet.cspr.live"),". The RPC port is usually ",(0,s.kt)("inlineCode",{parentName:"p"},"7777"),", but it depends on the network's configuration settings."),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst contract = new Contracts.Contract(casperClient);\n\nconst contractWasm = new Uint8Array(fs.readFileSync("/path/to/contract.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n argument: CLValueBuilder.string("Hello world!"),\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "10000000000", // Gas payment (10 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n [keypair],\n);\n\nconsole.log(await casperClient.putDeploy(deploy));\n'))),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},'import pycspr\nfrom pycspr.types import ModuleBytes, CL_String\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\n\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper" # or "casper-test" for Testnet\n)\npayment = pycspr.create_standard_payment(10000000000) # 10 CSPR\nsession = ModuleBytes(\n module_bytes = pycspr.read_wasm("/path/to/contract.wasm"),\n args = {\n "message": CL_String("Hello world!"),\n }\n)\n\ndeploy = pycspr.create_deploy(deployParams, payment, session)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'))),(0,s.kt)(o.Z,{value:"rust",label:"Rust",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},'extern crate casper_client;\nasync fn put_deploy(){\n let maybe_rpc: &str = "";\n let verbosity: u64 = 1;\n let node_address: &str = "http://135.181.216.142:7777";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test"\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n // Without session args:\n // let session_args: Vec<&str> = Vec::new();\n // With session args:\n let mut session_args: Vec<&str> = Vec::new();\n session_args.push("argument:String=\'hello world\'");\n let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./contract.wasm", session_args, "");\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("10000000000");\n let result = casper_client::put_deploy(maybe_rpc_id, node_address, verbosity_level, deploy_params, session_params, payment_params).await.unwrap();\n println!("Deploy response: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n send_transfer().await;\n}\n')))),(0,s.kt)("p",null,"Once submitted, the above snippet will print the deploy hash in the console."),(0,s.kt)("h2",{id:"staking"},"Staking"),(0,s.kt)("p",null,"Token staking is a fundamental aspect of the Casper Network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network."),(0,s.kt)("p",null,"The delegation functionality is available as a smart contract, which can be found in the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node"},"casper-node")," repository. To delegate tokens, first clone the repository:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/casper-network/casper-node.git\ncd casper-node/\n")),(0,s.kt)("p",null,"Then compile the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/dev/smart_contracts/contracts/client/delegate/src/main.rs"},"delegate contract"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"make setup-rs\nmake build-contract-rs/delegate\n")),(0,s.kt)("p",null,"Now, assuming that you cloned ",(0,s.kt)("inlineCode",{parentName:"p"},"casper-node")," from your project's root directory, ",(0,s.kt)("inlineCode",{parentName:"p"},"cd")," back into it:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"cd ../\n")),(0,s.kt)("p",null,"Now in your dApp's backend (or standalone script), load the ",(0,s.kt)("em",{parentName:"p"},"delegate.wasm"),' file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.'),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst contract = new Contracts.Contract(casperClient);\n\nconst contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n amount: CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR\n delegator: keypair.publicKey,\n validator: CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"),\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "5000000000", // Gas payment (5 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for testnet\n [keypair],\n);\n\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})();\n'))),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},'import pycspr\n\nvalidator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(\n bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n)\n\ndeploy_params = pycspr.create_deploy_parameters(\n account = keypair, # Only the public key is used, see `create_deploy_parameters`\n chain_name = "casper" # or "casper-test" for testnet\n)\n\ndeploy = pycspr.create_validator_delegation(\n params = deploy_params,\n amount = int(500e9), # Minimum delegation amount: 500 CSPR\n public_key_of_delegator = keypair,\n public_key_of_validator = validator_public_key,\n path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'))),(0,s.kt)(o.Z,{value:"rust",label:"Rust",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-rust"},'extern crate casper_client;\nasync fn put_deploy(){\n let maybe_rpc: &str = "";\n let verbosity: u64 = 1;\n let node_address: &str = "http://135.181.216.142:7777";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test" for testnet\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n let mut session_args: Vec<&str> = Vec::new();\n session_args.push("amount:U512=\'500000000000\'");\n\n session_args.push("delegator:public_key=\'01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a\'");\n session_args.push("validator:public_key=\'validator_public_key\'");\n\n let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./delegate.wasm", session_args, "");\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("5000000000");\n let result = casper_client::put_deploy(maybe_rpc, node_address, verbosity, deploy_params, session_params, payment_params).await.unwrap();\n println!("Deploy result: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n put_deploy().await;\n}\n')))),(0,s.kt)("p",null,"Once submitted, the above snippet will print the deploy hash in the console."),(0,s.kt)("hr",null),(0,s.kt)("h2",{id:"calling-contracts"},"Calling Contracts"),(0,s.kt)("p",null,"Smart contracts on a Casper network are invoked by calling entry points. See below how to use Casper's SDKs to interact with these entry points and update the global state from a dApp:"),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst contract = new Contracts.Contract(casperClient);\ncontract.setContractHash("hash-a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d");\nconst runtimeArguments = RuntimeArgs.fromMap({\n message: CLValueBuilder.string("Hello world!"),\n});\nconst deploy = contract.callEntrypoint(\n "update_msg",\n runtimeArguments,\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n "1000000000", // 1 CSPR (10^9 Motes)\n [keypair],\n);\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})();\n'))),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},'import pycspr\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper-test"\n)\npayment = pycspr.create_standard_payment(10_000_000_000)\nsession = pycspr.types.StoredContractByHash(\n entry_point = "update_msg",\n hash = bytes.fromhex("a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d"),\n args = {\n "message": pycspr.types.CL_String("Hello world!"),\n }\n)\ndeploy = pycspr.create_deploy(deployParams, payment, session)\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n')))),(0,s.kt)("p",null,"Once submitted, the above snippet will print the deploy hash in the console."),(0,s.kt)("hr",null),(0,s.kt)("h2",{id:"staking-1"},"Staking"),(0,s.kt)("p",null,"Token staking is a fundamental aspect of a Casper network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network."),(0,s.kt)("p",null,"The delegation functionality is available as a smart contract, which can be found in the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node"},"casper-node")," repository. To delegate tokens, first clone the repository:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/casper-network/casper-node.git\ncd casper-node/\n")),(0,s.kt)("p",null,"Then compile the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/casper-network/casper-node/blob/dev/smart_contracts/contracts/client/delegate/src/main.rs"},"delegate contract"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"make setup-rs\nmake build-contract-rs/delegate\n")),(0,s.kt)("p",null,"Now, navigate back to your project's root directory. In your dApp's backend (or standalone script), load the ",(0,s.kt)("em",{parentName:"p"},"delegate.wasm"),' file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.'),(0,s.kt)(l.Z,{mdxType:"Tabs"},(0,s.kt)(o.Z,{value:"js",label:"JavaScript",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-javascript"},'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst contract = new Contracts.Contract(casperClient);\n\nconst contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n amount: CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR\n delegator: keypair.publicKey,\n validator: CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"),\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "5000000000", // Gas payment (5 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for testnet\n [keypair],\n);\n\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})();\n'))),(0,s.kt)(o.Z,{value:"python",label:"Python",mdxType:"TabItem"},(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-python"},'import pycspr\n\nvalidator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(\n bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n)\n\ndeploy_params = pycspr.create_deploy_parameters(\n account = keypair, # Only the public key is used, see `create_deploy_parameters`\n chain_name = "casper" # or "casper-test" for testnet\n)\n\ndeploy = pycspr.create_validator_delegation(\n params = deploy_params,\n amount = int(500e9), # Minimum delegation amount: 500 CSPR\n public_key_of_delegator = keypair,\n public_key_of_validator = validator_public_key,\n path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n')))),(0,s.kt)("p",null,"Once submitted, the above snippet will print the deploy hash in the console."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e2ffc27a.9220c9f9.js b/assets/js/e2ffc27a.921e2161.js similarity index 99% rename from assets/js/e2ffc27a.9220c9f9.js rename to assets/js/e2ffc27a.921e2161.js index aa9aa00d48..f6fd87857f 100644 --- a/assets/js/e2ffc27a.9220c9f9.js +++ b/assets/js/e2ffc27a.921e2161.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5036],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return m}});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=p(n),h=o,m=d["".concat(s,".").concat(h)]||d[h]||u[h]||r;return n?a.createElement(m,l(l({ref:t},c),{},{components:n})):a.createElement(m,l({ref:t},c))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,l=new Array(r);l[0]=h;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[d]="string"==typeof e?e:o,l[1]=i;for(var p=2;p \\\n --chain-name [NETWORK_NAME]] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [AMOUNT] \\\n --session-path [WASM_FILE_PATH]/[File_Name].wasm\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n\n')),(0,r.kt)("p",null,"Check if the request to the Testnet can be made and get a snapshot of the network with the state root hash:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"\ncasper-client get-state-root-hash --node-address http://78.46.32.13:7777\n\n")),(0,r.kt)("p",null,"You should obtain a response similar to:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": 3323991011802671610,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "state_root_hash": "9b43fd7388559c078f363403972cb079d69786259bf6c5cd9cd7adcc14029d74"\n }\n}\n')),(0,r.kt)("p",null,"An exemplary deploy to the Casper Testnet is as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'\ncasper-client put-deploy \\\n--node-address http://78.46.32.13:7777 \\\n--chain-name casper-test \\\n--secret-key "./keys/secret_key.pem" \\\n--payment-amount 150000000000 \\\n--session-path "./target/wasm32-unknown-unknown/release/cep18.wasm" \\\n--session-arg "name:string=\'CHF Coin\'" \\\n--session-arg "symbol:string=\'CHFC\'" \\\n--session-arg "decimals:u8=\'10\'" \\\n--session-arg "total_supply:u256=\'1000\'"\n\n')),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"Always be mindful of the ",(0,r.kt)("inlineCode",{parentName:"p"},"--secret-key")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"--session-path")," arguments. Path provided to the arguments should always be with regard to the current folder, where the command is executed."),(0,r.kt)("p",{parentName:"admonition"},"The ",(0,r.kt)("inlineCode",{parentName:"p"},"keys")," folder is not a part of the CEP18 folder structure. Optionally you should provide a folder where your keys are stored.")),(0,r.kt)("p",null,"The response from the ",(0,r.kt)("inlineCode",{parentName:"p"},"put-deploy")," command should look like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 5066914343373494745,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "deploy_hash": "19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6"\n }\n}\n\n')),(0,r.kt)("p",null,"Using the ",(0,r.kt)("inlineCode",{parentName:"p"},"deploy_hash")," the state of the deploy can be checked:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"\ncasper-client get-deploy \\\n --node-address http://78.46.32.13:7777 19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6\n\n")),(0,r.kt)("p",null,"In the execution results we can see, that the deploy was successful:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'\n...\n "execution_results": [\n {\n "block_hash": "426a8823c1018e75f8c3823d580116269fd272f20e60561dff0565375a95316d",\n "result": {\n "Success": {\n "cost": "140416131900",\n "effect": {\n "operations": [],\n...\n\n')),(0,r.kt)("p",null,"Be always mindful of the payment amount during the deploy process. If the amount is too small, then the deploy will fail with ",(0,r.kt)("inlineCode",{parentName:"p"},"Out of gas error"),"."),(0,r.kt)("h3",{id:"cep18-contract-clone"},"Query the Entry Points in the CEP-18 contract"),(0,r.kt)("p",null,"Get the state root hash from the network:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address http://78.46.32.13:7777\n")),(0,r.kt)("p",null,"Your response should look similar to:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": 2950480729544096556,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "state_root_hash": "7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705"\n }\n}\n')),(0,r.kt)("p",null,"With the state root hash and the account hash which performed the deploy, you can query the contract arguments."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state --node-address http://78.46.32.13:7777 \\\n--state-root-hash 7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705 \\\n--key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9 \\\n-q "cep18_contract_hash_CHF Coin/name"\n')),(0,r.kt)("p",null,"The above command will query the contract for the name. The template for the query is ",(0,r.kt)("inlineCode",{parentName:"p"},"contract_name/named_key"),"."),(0,r.kt)("p",null,"You will obtain the following response:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -7058786841478812744,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "block_header": null,\n "merkle_proof": "[94526 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "0800000043484620436f696e",\n "cl_type": "String",\n "parsed": "CHF Coin"\n }\n }\n }\n}\n')),(0,r.kt)("p",null,"Try to query the contract for other Named Keys and check how the contract behaves."),(0,r.kt)("h2",{id:"summary"},"Summary"),(0,r.kt)("p",null,"In this tutorial, we:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Explained the ERC20 standard and what the implications are for not using the standard implementations."),(0,r.kt)("li",{parentName:"ul"},"Developed a CEP-18 Rust contract on a Casper network and defined the proper arguments for the deploy."),(0,r.kt)("li",{parentName:"ul"},"Installed the contract on the Testnet"),(0,r.kt)("li",{parentName:"ul"},"Called an entry point on the contract to get the value of the Named Key ",(0,r.kt)("inlineCode",{parentName:"li"},"name"),".")))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5036],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return m}});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=p(n),h=o,m=d["".concat(s,".").concat(h)]||d[h]||u[h]||r;return n?a.createElement(m,l(l({ref:t},c),{},{components:n})):a.createElement(m,l({ref:t},c))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,l=new Array(r);l[0]=h;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[d]="string"==typeof e?e:o,l[1]=i;for(var p=2;p \\\n --chain-name [NETWORK_NAME]] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [AMOUNT] \\\n --session-path [WASM_FILE_PATH]/[File_Name].wasm\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n\n')),(0,r.kt)("p",null,"Check if the request to the Testnet can be made and get a snapshot of the network with the state root hash:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"\ncasper-client get-state-root-hash --node-address http://78.46.32.13:7777\n\n")),(0,r.kt)("p",null,"You should obtain a response similar to:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": 3323991011802671610,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "state_root_hash": "9b43fd7388559c078f363403972cb079d69786259bf6c5cd9cd7adcc14029d74"\n }\n}\n')),(0,r.kt)("p",null,"An exemplary deploy to the Casper Testnet is as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'\ncasper-client put-deploy \\\n--node-address http://78.46.32.13:7777 \\\n--chain-name casper-test \\\n--secret-key "./keys/secret_key.pem" \\\n--payment-amount 150000000000 \\\n--session-path "./target/wasm32-unknown-unknown/release/cep18.wasm" \\\n--session-arg "name:string=\'CHF Coin\'" \\\n--session-arg "symbol:string=\'CHFC\'" \\\n--session-arg "decimals:u8=\'10\'" \\\n--session-arg "total_supply:u256=\'1000\'"\n\n')),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"Always be mindful of the ",(0,r.kt)("inlineCode",{parentName:"p"},"--secret-key")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"--session-path")," arguments. Path provided to the arguments should always be with regard to the current folder, where the command is executed."),(0,r.kt)("p",{parentName:"admonition"},"The ",(0,r.kt)("inlineCode",{parentName:"p"},"keys")," folder is not a part of the CEP18 folder structure. Optionally you should provide a folder where your keys are stored.")),(0,r.kt)("p",null,"The response from the ",(0,r.kt)("inlineCode",{parentName:"p"},"put-deploy")," command should look like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'\n{\n "id": 5066914343373494745,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "deploy_hash": "19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6"\n }\n}\n\n')),(0,r.kt)("p",null,"Using the ",(0,r.kt)("inlineCode",{parentName:"p"},"deploy_hash")," the state of the deploy can be checked:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"\ncasper-client get-deploy \\\n --node-address http://78.46.32.13:7777 19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6\n\n")),(0,r.kt)("p",null,"In the execution results we can see, that the deploy was successful:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'\n...\n "execution_results": [\n {\n "block_hash": "426a8823c1018e75f8c3823d580116269fd272f20e60561dff0565375a95316d",\n "result": {\n "Success": {\n "cost": "140416131900",\n "effect": {\n "operations": [],\n...\n\n')),(0,r.kt)("p",null,"Be always mindful of the payment amount during the deploy process. If the amount is too small, then the deploy will fail with ",(0,r.kt)("inlineCode",{parentName:"p"},"Out of gas error"),"."),(0,r.kt)("h3",{id:"cep18-contract-clone"},"Query the Entry Points in the CEP-18 contract"),(0,r.kt)("p",null,"Get the state root hash from the network:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client get-state-root-hash --node-address http://78.46.32.13:7777\n")),(0,r.kt)("p",null,"Your response should look similar to:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": 2950480729544096556,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "state_root_hash": "7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705"\n }\n}\n')),(0,r.kt)("p",null,"With the state root hash and the account hash which performed the deploy, you can query the contract arguments."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client query-global-state --node-address http://78.46.32.13:7777 \\\n--state-root-hash 7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705 \\\n--key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9 \\\n-q "cep18_contract_hash_CHF Coin/name"\n')),(0,r.kt)("p",null,"The above command will query the contract for the name. The template for the query is ",(0,r.kt)("inlineCode",{parentName:"p"},"contract_name/named_key"),"."),(0,r.kt)("p",null,"You will obtain the following response:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'{\n "id": -7058786841478812744,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "block_header": null,\n "merkle_proof": "[94526 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "0800000043484620436f696e",\n "cl_type": "String",\n "parsed": "CHF Coin"\n }\n }\n }\n}\n')),(0,r.kt)("p",null,"Try to query the contract for other Named Keys and check how the contract behaves."),(0,r.kt)("h2",{id:"summary"},"Summary"),(0,r.kt)("p",null,"In this tutorial, we:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Explained the ERC20 standard and what the implications are for not using the standard implementations."),(0,r.kt)("li",{parentName:"ul"},"Developed a CEP-18 Rust contract on a Casper network and defined the proper arguments for the deploy."),(0,r.kt)("li",{parentName:"ul"},"Installed the contract on the Testnet"),(0,r.kt)("li",{parentName:"ul"},"Called an entry point on the contract to get the value of the Named Key ",(0,r.kt)("inlineCode",{parentName:"li"},"name"),".")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e6ce8647.d7eb5eda.js b/assets/js/e6ce8647.9f5b889e.js similarity index 97% rename from assets/js/e6ce8647.d7eb5eda.js rename to assets/js/e6ce8647.9f5b889e.js index fa84939ad9..db22bc0397 100644 --- a/assets/js/e6ce8647.d7eb5eda.js +++ b/assets/js/e6ce8647.9f5b889e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6871],{3905:function(e,t,r){r.d(t,{Zo:function(){return p},kt:function(){return f}});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),d=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=d(e.components);return n.createElement(l.Provider,{value:t},e.children)},s="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),s=d(r),m=a,f=s["".concat(l,".").concat(m)]||s[m]||u[m]||o;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[s]="string"==typeof e?e:a,i[1]=c;for(var d=2;d=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),d=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=d(e.components);return n.createElement(l.Provider,{value:t},e.children)},s="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),s=d(r),m=a,f=s["".concat(l,".").concat(m)]||s[m]||u[m]||o;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[s]="string"==typeof e?e:a,i[1]=c;for(var d=2;d=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var u=n.createContext({}),c=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(u.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,u=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),l=c(r),m=a,f=l["".concat(u,".").concat(m)]||l[m]||d[m]||o;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[l]="string"==typeof e?e:a,i[1]=s;for(var c=2;c=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var u=n.createContext({}),c=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(u.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,u=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),l=c(r),m=a,f=l["".concat(u,".").concat(m)]||l[m]||d[m]||o;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[l]="string"==typeof e?e:a,i[1]=s;for(var c=2;c=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var u=n.createContext({}),s=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=s(e.components);return n.createElement(u.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,u=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=s(r),m=a,g=c["".concat(u,".").concat(m)]||c[m]||d[m]||o;return r?n.createElement(g,i(i({ref:t},p),{},{components:r})):n.createElement(g,i({ref:t},p))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l[c]="string"==typeof e?e:a,i[1]=l;for(var s=2;s=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var u=n.createContext({}),s=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=s(e.components);return n.createElement(u.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,u=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=s(r),m=a,g=c["".concat(u,".").concat(m)]||c[m]||d[m]||o;return r?n.createElement(g,i(i({ref:t},p),{},{components:r})):n.createElement(g,i({ref:t},p))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l[c]="string"==typeof e?e:a,i[1]=l;for(var s=2;s=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var s=n.createContext({}),u=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=u(a),d=r,h=p["".concat(s,".").concat(d)]||p[d]||g[d]||i;return a?n.createElement(h,o(o({ref:t},c),{},{components:a})):n.createElement(h,o({ref:t},c))}));function h(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:r,o[1]=l;for(var u=2;u=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var s=n.createContext({}),u=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=u(a),d=r,h=p["".concat(s,".").concat(d)]||p[d]||g[d]||i;return a?n.createElement(h,o(o({ref:t},c),{},{components:a})):n.createElement(h,o({ref:t},c))}));function h(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:r,o[1]=l;for(var u=2;u=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var p=r.createContext({}),l=function(e){var t=r.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},i=function(e){var t=l(e.components);return r.createElement(p.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,s=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(a),f=n,g=u["".concat(p,".").concat(f)]||u[f]||h[f]||s;return a?r.createElement(g,o(o({ref:t},i),{},{components:a})):r.createElement(g,o({ref:t},i))}));function g(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var s=a.length,o=new Array(s);o[0]=f;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:n,o[1]=c;for(var l=2;l=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var p=r.createContext({}),l=function(e){var t=r.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},i=function(e){var t=l(e.components);return r.createElement(p.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,s=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(a),f=n,g=u["".concat(p,".").concat(f)]||u[f]||h[f]||s;return a?r.createElement(g,o(o({ref:t},i),{},{components:a})):r.createElement(g,o({ref:t},i))}));function g(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var s=a.length,o=new Array(s);o[0]=f;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:n,o[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),p=u(r),m=a,k=p["".concat(s,".").concat(m)]||p[m]||d[m]||o;return r?n.createElement(k,l(l({ref:t},c),{},{components:r})):n.createElement(k,l({ref:t},c))}));function k(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[p]="string"==typeof e?e:a,l[1]=i;for(var u=2;u=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),p=u(r),m=a,k=p["".concat(s,".").concat(m)]||p[m]||d[m]||o;return r?n.createElement(k,l(l({ref:t},c),{},{components:r})):n.createElement(k,l({ref:t},c))}));function k(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[p]="string"==typeof e?e:a,l[1]=i;for(var u=2;u=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=l(n),h=o,m=d["".concat(c,".").concat(h)]||d[h]||p[h]||r;return n?a.createElement(m,i(i({ref:t},u),{},{components:n})):a.createElement(m,i({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var l=2;l:7777 \\\n--secret-key .pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-path \\\n--session-arg \"deployment-account:account_hash='account-hash-'\"\n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the main account"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the deploy (this example uses the Testnet)"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The cost of the deploy. This example uses 2.5 CSPR, which may need to be adjusted based on the network ",(0,r.kt)("a",{parentName:"li",href:"/concepts/glossary/C#chainspec"},"chainspec"),"."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to the contract Wasm"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-arg")," - The contract takes the account hash of the associated account as an argument labeled ",(0,r.kt)("inlineCode",{parentName:"li"},"deployment-account"),". You can pass this argument using the ",(0,r.kt)("inlineCode",{parentName:"li"},"--session-arg")," flag in the command line client")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Important response fields:")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},'"result"."deploy_hash"')," - the address of the executed deploy, needed to look up additional information about the transfer")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Note"),": Save the returned ",(0,r.kt)("inlineCode",{parentName:"p"},"deploy_hash")," from the output to query information about execution status."),(0,r.kt)("h3",{id:"confirming-execution-and-account-status"},"Confirming Processing and Account Status"),(0,r.kt)("p",null,"Account configuration on a Casper blockchain is stored in a ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/M#merkle-tree"},"Merkle Tree")," and is a snapshot of the blockchain's ",(0,r.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#global-state-head"},"Global State"),". The representation of global state for a given block can be computed by executing the deploys (including transfers) within the block and its ancestors. The root node of the Merkle Tree identifying a particular state is called the ",(0,r.kt)("inlineCode",{parentName:"p"},"state-root-hash")," and is stored in every executed block."),(0,r.kt)("p",null,"To check that the account was configured correctly, you need the ",(0,r.kt)("inlineCode",{parentName:"p"},"state-root-hash")," corresponding to the block that contains your deploy. To obtain the ",(0,r.kt)("inlineCode",{parentName:"p"},"state-root-hash"),", you need to:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"/resources/tutorials/beginner/querying-network#querying-deploys"},"Confirm the execution status of the deploy")," and obtain the hash of the block containing it"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"/resources/tutorials/beginner/querying-network#querying-blocks"},"Query the block containing the deploy")," to obtain the corresponding ",(0,r.kt)("inlineCode",{parentName:"li"},"state_root_hash"))),(0,r.kt)("p",null,"Using the ",(0,r.kt)("inlineCode",{parentName:"p"},"state_root_hash")," and the ",(0,r.kt)("inlineCode",{parentName:"p"},"hex-encoded-public-key")," of the main account, query the network and check the account's configuration."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state \\\n--node-address http://:7777 \\\n--state-root-hash \\\n--key \n")),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example output"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": 1126043166167626077,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "merkle_proof": "2226 chars",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-12dee9fe535bfd8fd335fce1ba1f972f26bb60029a303b310d85419357d18f51",\n "weight": 1\n },\n {\n "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",\n "weight": 1\n }\n ],\n "main_purse": "uref-74b20e9722d3f087f9dc431e9f0fcc6a803c256e005fa45b64a101512001cb78-007",\n "named_keys": []\n }\n }\n }\n}\n'))),(0,r.kt)("p",null,"In the example output, you can see the account hashes listed within the ",(0,r.kt)("inlineCode",{parentName:"p"},"associated_keys")," section. Each key has weight ",(0,r.kt)("inlineCode",{parentName:"p"},"1"),"; since the action threshold for ",(0,r.kt)("inlineCode",{parentName:"p"},"deployment")," is ",(0,r.kt)("inlineCode",{parentName:"p"},"2"),", neither account can sign and send a deploy individually. Thus, the deploy needs to be signed by the secret keys of each account to reach the required threshold."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5962],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return m}});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=l(n),h=o,m=d["".concat(c,".").concat(h)]||d[h]||p[h]||r;return n?a.createElement(m,i(i({ref:t},u),{},{components:n})):a.createElement(m,i({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var l=2;l:7777 \\\n--secret-key .pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-path \\\n--session-arg \"deployment-account:account_hash='account-hash-'\"\n")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"node-address")," - An IP address of a node on the network"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"secret-key")," - The file name containing the secret key of the main account"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"chain-name")," - The chain-name to the network where you wish to send the deploy (this example uses the Testnet)"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"payment-amount")," - The cost of the deploy. This example uses 2.5 CSPR, which may need to be adjusted based on the network ",(0,r.kt)("a",{parentName:"li",href:"/concepts/glossary/C#chainspec"},"chainspec"),"."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-path")," - The path to the contract Wasm"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"session-arg")," - The contract takes the account hash of the associated account as an argument labeled ",(0,r.kt)("inlineCode",{parentName:"li"},"deployment-account"),". You can pass this argument using the ",(0,r.kt)("inlineCode",{parentName:"li"},"--session-arg")," flag in the command line client")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Important response fields:")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},'"result"."deploy_hash"')," - the address of the executed deploy, needed to look up additional information about the transfer")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Note"),": Save the returned ",(0,r.kt)("inlineCode",{parentName:"p"},"deploy_hash")," from the output to query information about execution status."),(0,r.kt)("h3",{id:"confirming-execution-and-account-status"},"Confirming Processing and Account Status"),(0,r.kt)("p",null,"Account configuration on a Casper blockchain is stored in a ",(0,r.kt)("a",{parentName:"p",href:"/concepts/glossary/M#merkle-tree"},"Merkle Tree")," and is a snapshot of the blockchain's ",(0,r.kt)("a",{parentName:"p",href:"/concepts/design/casper-design#global-state-head"},"Global State"),". The representation of global state for a given block can be computed by executing the deploys (including transfers) within the block and its ancestors. The root node of the Merkle Tree identifying a particular state is called the ",(0,r.kt)("inlineCode",{parentName:"p"},"state-root-hash")," and is stored in every executed block."),(0,r.kt)("p",null,"To check that the account was configured correctly, you need the ",(0,r.kt)("inlineCode",{parentName:"p"},"state-root-hash")," corresponding to the block that contains your deploy. To obtain the ",(0,r.kt)("inlineCode",{parentName:"p"},"state-root-hash"),", you need to:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"/resources/tutorials/beginner/querying-network#querying-deploys"},"Confirm the execution status of the deploy")," and obtain the hash of the block containing it"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"/resources/tutorials/beginner/querying-network#querying-blocks"},"Query the block containing the deploy")," to obtain the corresponding ",(0,r.kt)("inlineCode",{parentName:"li"},"state_root_hash"))),(0,r.kt)("p",null,"Using the ",(0,r.kt)("inlineCode",{parentName:"p"},"state_root_hash")," and the ",(0,r.kt)("inlineCode",{parentName:"p"},"hex-encoded-public-key")," of the main account, query the network and check the account's configuration."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"casper-client query-global-state \\\n--node-address http://:7777 \\\n--state-root-hash \\\n--key \n")),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example output"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": 1126043166167626077,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "merkle_proof": "2226 chars",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-12dee9fe535bfd8fd335fce1ba1f972f26bb60029a303b310d85419357d18f51",\n "weight": 1\n },\n {\n "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",\n "weight": 1\n }\n ],\n "main_purse": "uref-74b20e9722d3f087f9dc431e9f0fcc6a803c256e005fa45b64a101512001cb78-007",\n "named_keys": []\n }\n }\n }\n}\n'))),(0,r.kt)("p",null,"In the example output, you can see the account hashes listed within the ",(0,r.kt)("inlineCode",{parentName:"p"},"associated_keys")," section. Each key has weight ",(0,r.kt)("inlineCode",{parentName:"p"},"1"),"; since the action threshold for ",(0,r.kt)("inlineCode",{parentName:"p"},"deployment")," is ",(0,r.kt)("inlineCode",{parentName:"p"},"2"),", neither account can sign and send a deploy individually. Thus, the deploy needs to be signed by the secret keys of each account to reach the required threshold."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f12850af.e9eb2c4f.js b/assets/js/f12850af.66cdc9d4.js similarity index 98% rename from assets/js/f12850af.e9eb2c4f.js rename to assets/js/f12850af.66cdc9d4.js index d1a970928f..08955127d7 100644 --- a/assets/js/f12850af.e9eb2c4f.js +++ b/assets/js/f12850af.66cdc9d4.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[9964],{3905:function(e,t,r){r.d(t,{Zo:function(){return c},kt:function(){return m}});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),l=u(r),f=a,m=l["".concat(s,".").concat(f)]||l[f]||d[f]||o;return r?n.createElement(m,i(i({ref:t},c),{},{components:r})):n.createElement(m,i({ref:t},c))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=f;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[l]="string"==typeof e?e:a,i[1]=p;for(var u=2;u=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),l=u(r),f=a,m=l["".concat(s,".").concat(f)]||l[f]||d[f]||o;return r?n.createElement(m,i(i({ref:t},c),{},{components:r})):n.createElement(m,i({ref:t},c))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=f;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[l]="string"==typeof e?e:a,i[1]=p;for(var u=2;u=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var i=n.createContext({}),l=function(t){var e=n.useContext(i),a=e;return t&&(a="function"==typeof t?t(e):o(o({},e),t)),a},h=function(t){var e=l(t.components);return n.createElement(i.Provider,{value:e},t.children)},p="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},d=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,c=t.originalType,i=t.parentName,h=s(t,["components","mdxType","originalType","parentName"]),p=l(a),d=r,k=p["".concat(i,".").concat(d)]||p[d]||u[d]||c;return a?n.createElement(k,o(o({ref:e},h),{},{components:a})):n.createElement(k,o({ref:e},h))}));function k(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var c=a.length,o=new Array(c);o[0]=d;var s={};for(var i in e)hasOwnProperty.call(e,i)&&(s[i]=e[i]);s.originalType=t,s[p]="string"==typeof t?t:r,o[1]=s;for(var l=2;l=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var i=n.createContext({}),l=function(t){var e=n.useContext(i),a=e;return t&&(a="function"==typeof t?t(e):o(o({},e),t)),a},h=function(t){var e=l(t.components);return n.createElement(i.Provider,{value:e},t.children)},p="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},d=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,c=t.originalType,i=t.parentName,h=s(t,["components","mdxType","originalType","parentName"]),p=l(a),d=r,k=p["".concat(i,".").concat(d)]||p[d]||u[d]||c;return a?n.createElement(k,o(o({ref:e},h),{},{components:a})):n.createElement(k,o({ref:e},h))}));function k(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var c=a.length,o=new Array(c);o[0]=d;var s={};for(var i in e)hasOwnProperty.call(e,i)&&(s[i]=e[i]);s.originalType=t,s[p]="string"==typeof t?t:r,o[1]=s;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(r),d=a,h=u["".concat(p,".").concat(d)]||u[d]||f[d]||o;return r?n.createElement(h,s(s({ref:t},i),{},{components:r})):n.createElement(h,s({ref:t},i))}));function h(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=d;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},i=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),u=l(r),d=a,h=u["".concat(p,".").concat(d)]||u[d]||f[d]||o;return r?n.createElement(h,s(s({ref:t},i),{},{components:r})):n.createElement(h,s({ref:t},i))}));function h(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=d;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var l=2;l=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),c=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(i.Provider,{value:t},e.children)},h="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),h=c(n),d=r,m=h["".concat(i,".").concat(d)]||h[d]||p[d]||o;return n?a.createElement(m,s(s({ref:t},u),{},{components:n})):a.createElement(m,s({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=d;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[h]="string"==typeof e?e:r,s[1]=l;for(var c=2;c=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),c=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(i.Provider,{value:t},e.children)},h="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),h=c(n),d=r,m=h["".concat(i,".").concat(d)]||h[d]||p[d]||o;return n?a.createElement(m,s(s({ref:t},u),{},{components:n})):a.createElement(m,s({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=d;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[h]="string"==typeof e?e:r,s[1]=l;for(var c=2;c=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),l=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=l(e.components);return n.createElement(u.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,u=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),p=l(r),m=o,f=p["".concat(u,".").concat(m)]||p[m]||d[m]||a;return r?n.createElement(f,i(i({ref:t},s),{},{components:r})):n.createElement(f,i({ref:t},s))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var c={};for(var u in t)hasOwnProperty.call(t,u)&&(c[u]=t[u]);c.originalType=e,c[p]="string"==typeof e?e:o,i[1]=c;for(var l=2;l=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),l=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=l(e.components);return n.createElement(u.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,u=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),p=l(r),m=o,f=p["".concat(u,".").concat(m)]||p[m]||d[m]||a;return r?n.createElement(f,i(i({ref:t},s),{},{components:r})):n.createElement(f,i({ref:t},s))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var c={};for(var u in t)hasOwnProperty.call(t,u)&&(c[u]=t[u]);c.originalType=e,c[p]="string"==typeof e?e:o,i[1]=c;for(var l=2;l=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,s=e.mdxType,i=e.originalType,l=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),m=c(n),u=s,h=m["".concat(l,".").concat(u)]||m[u]||d[u]||i;return n?a.createElement(h,r(r({ref:t},p),{},{components:n})):a.createElement(h,r({ref:t},p))}));function h(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var i=n.length,r=new Array(i);r[0]=u;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[m]="string"==typeof e?e:s,r[1]=o;for(var c=2;c\'"` \\\n--session-arg "token_owner:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"\n\n'))),(0,i.kt)("h2",{id:"transferring-nfts-between-users"},"Transferring NFTs Between Users"),(0,i.kt)("p",null,"Below is an example of a ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-client")," command that uses the ",(0,i.kt)("inlineCode",{parentName:"p"},"transfer")," function to transfer ownership of an NFT from one user to another. In this case, we are transferring the previously minted NFT from the user associated with ",(0,i.kt)("inlineCode",{parentName:"p"},"node-2")," to the user associated with ",(0,i.kt)("inlineCode",{parentName:"p"},"node-3"),"."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm'))),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--session-arg \"nft_contract_hash:key='hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'\"")),(0,i.kt)("p",{parentName:"li"},"The contract hash of the CEP-78 NFT Contract associated with the NFT to be transferred.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--session-arg \"source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\"")),(0,i.kt)("p",{parentName:"li"},"The account hash of the user that currently owns the NFT and wishes to transfer it.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--session-arg \"target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'\"")),(0,i.kt)("p",{parentName:"li"},"The account hash of the user that will receive the NFT.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--session-arg \"is_hash_identifier_mode:bool='false'\"")),(0,i.kt)("p",{parentName:"li"},"Argument that the hash identifier mode is ordinal, thereby requiring a ",(0,i.kt)("inlineCode",{parentName:"p"},"token_id")," rather than a ",(0,i.kt)("inlineCode",{parentName:"p"},"token_hash"),".")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--session-arg \"token_id:u64='0'\"")),(0,i.kt)("p",{parentName:"li"},"The ",(0,i.kt)("inlineCode",{parentName:"p"},"token_id")," of the NFT to be transferred."))),(0,i.kt)("details",null,(0,i.kt)("summary",null,(0,i.kt)("b",null,"Casper client command without comments")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem \\\n--session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm \\\n--session-arg "nft_contract_hash:key=\'hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5\'" \\\n--session-arg "source_key:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "target_key:key=\'account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab\'" \\\n--session-arg "is_hash_identifier_mode:bool=\'false\'" \\\n--session-arg "token_id:u64=\'0\'"\n'))),(0,i.kt)("h2",{id:"burning-an-nft"},"Burning an NFT"),(0,i.kt)("p",null,"Below is an example of a ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-client")," command that uses the ",(0,i.kt)("inlineCode",{parentName:"p"},"burn")," function to burn an NFT within a CEP-78 collection. If this command is used, the NFT in question will no longer be accessible by anyone."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem'))),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5")),(0,i.kt)("p",{parentName:"li"},"The session hash corresponding to the NFT's contract hash.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},'--session-entry-point "burn"')),(0,i.kt)("p",{parentName:"li"},"The entrypoint corresponding to the ",(0,i.kt)("inlineCode",{parentName:"p"},"burn")," function.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--session-arg \"token_id:u64='1'\"")),(0,i.kt)("p",{parentName:"li"},"The token ID for the NFT to be burned. If the ",(0,i.kt)("inlineCode",{parentName:"p"},"identifier_mode")," is not set to ",(0,i.kt)("inlineCode",{parentName:"p"},"Ordinal"),", you must provide the ",(0,i.kt)("inlineCode",{parentName:"p"},"token_hash")," instead."))),(0,i.kt)("details",null,(0,i.kt)("summary",null,(0,i.kt)("b",null,"Casper client command without comments")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \\\n--session-entry-point "burn" \\\n--session-arg "token_id:u64=\'1\'"\n'))))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[7022],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return h}});var a=n(7294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,s=e.mdxType,i=e.originalType,l=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),m=c(n),u=s,h=m["".concat(l,".").concat(u)]||m[u]||d[u]||i;return n?a.createElement(h,r(r({ref:t},p),{},{components:n})):a.createElement(h,r({ref:t},p))}));function h(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var i=n.length,r=new Array(i);r[0]=u;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[m]="string"==typeof e?e:s,r[1]=o;for(var c=2;c\'"` \\\n--session-arg "token_owner:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"\n\n'))),(0,i.kt)("h2",{id:"transferring-nfts-between-users"},"Transferring NFTs Between Users"),(0,i.kt)("p",null,"Below is an example of a ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-client")," command that uses the ",(0,i.kt)("inlineCode",{parentName:"p"},"transfer")," function to transfer ownership of an NFT from one user to another. In this case, we are transferring the previously minted NFT from the user associated with ",(0,i.kt)("inlineCode",{parentName:"p"},"node-2")," to the user associated with ",(0,i.kt)("inlineCode",{parentName:"p"},"node-3"),"."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm'))),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--session-arg \"nft_contract_hash:key='hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'\"")),(0,i.kt)("p",{parentName:"li"},"The contract hash of the CEP-78 NFT Contract associated with the NFT to be transferred.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--session-arg \"source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\"")),(0,i.kt)("p",{parentName:"li"},"The account hash of the user that currently owns the NFT and wishes to transfer it.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--session-arg \"target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'\"")),(0,i.kt)("p",{parentName:"li"},"The account hash of the user that will receive the NFT.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--session-arg \"is_hash_identifier_mode:bool='false'\"")),(0,i.kt)("p",{parentName:"li"},"Argument that the hash identifier mode is ordinal, thereby requiring a ",(0,i.kt)("inlineCode",{parentName:"p"},"token_id")," rather than a ",(0,i.kt)("inlineCode",{parentName:"p"},"token_hash"),".")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--session-arg \"token_id:u64='0'\"")),(0,i.kt)("p",{parentName:"li"},"The ",(0,i.kt)("inlineCode",{parentName:"p"},"token_id")," of the NFT to be transferred."))),(0,i.kt)("details",null,(0,i.kt)("summary",null,(0,i.kt)("b",null,"Casper client command without comments")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem \\\n--session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm \\\n--session-arg "nft_contract_hash:key=\'hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5\'" \\\n--session-arg "source_key:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "target_key:key=\'account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab\'" \\\n--session-arg "is_hash_identifier_mode:bool=\'false\'" \\\n--session-arg "token_id:u64=\'0\'"\n'))),(0,i.kt)("h2",{id:"burning-an-nft"},"Burning an NFT"),(0,i.kt)("p",null,"Below is an example of a ",(0,i.kt)("inlineCode",{parentName:"p"},"casper-client")," command that uses the ",(0,i.kt)("inlineCode",{parentName:"p"},"burn")," function to burn an NFT within a CEP-78 collection. If this command is used, the NFT in question will no longer be accessible by anyone."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem'))),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5")),(0,i.kt)("p",{parentName:"li"},"The session hash corresponding to the NFT's contract hash.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},'--session-entry-point "burn"')),(0,i.kt)("p",{parentName:"li"},"The entrypoint corresponding to the ",(0,i.kt)("inlineCode",{parentName:"p"},"burn")," function.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--session-arg \"token_id:u64='1'\"")),(0,i.kt)("p",{parentName:"li"},"The token ID for the NFT to be burned. If the ",(0,i.kt)("inlineCode",{parentName:"p"},"identifier_mode")," is not set to ",(0,i.kt)("inlineCode",{parentName:"p"},"Ordinal"),", you must provide the ",(0,i.kt)("inlineCode",{parentName:"p"},"token_hash")," instead."))),(0,i.kt)("details",null,(0,i.kt)("summary",null,(0,i.kt)("b",null,"Casper client command without comments")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \\\n--session-entry-point "burn" \\\n--session-arg "token_id:u64=\'1\'"\n'))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/fa593e9e.0d6b2eb1.js b/assets/js/fa593e9e.a5fe907b.js similarity index 97% rename from assets/js/fa593e9e.0d6b2eb1.js rename to assets/js/fa593e9e.a5fe907b.js index a362766f1d..319cbac06d 100644 --- a/assets/js/fa593e9e.0d6b2eb1.js +++ b/assets/js/fa593e9e.a5fe907b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5199],{3905:function(e,t,r){r.d(t,{Zo:function(){return p},kt:function(){return h}});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=l(r),f=o,h=u["".concat(c,".").concat(f)]||u[f]||d[f]||a;return r?n.createElement(h,s(s({ref:t},p),{},{components:r})):n.createElement(h,s({ref:t},p))}));function h(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,s=new Array(a);s[0]=f;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:o,s[1]=i;for(var l=2;l=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=l(r),f=o,h=u["".concat(c,".").concat(f)]||u[f]||d[f]||a;return r?n.createElement(h,s(s({ref:t},p),{},{components:r})):n.createElement(h,s({ref:t},p))}));function h(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,s=new Array(a);s[0]=f;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:o,s[1]=i;for(var l=2;l=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),i=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},l=function(e){var t=i(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=i(r),d=a,m=u["".concat(p,".").concat(d)]||u[d]||f[d]||o;return r?n.createElement(m,s(s({ref:t},l),{},{components:r})):n.createElement(m,s({ref:t},l))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=d;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var i=2;i=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),i=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},l=function(e){var t=i(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=i(r),d=a,m=u["".concat(p,".").concat(d)]||u[d]||f[d]||o;return r?n.createElement(m,s(s({ref:t},l),{},{components:r})):n.createElement(m,s({ref:t},l))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=d;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var i=2;i=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var d=n.createContext({}),c=function(e){var t=n.useContext(d),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},l=function(e){var t=c(e.components);return n.createElement(d.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,d=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),p=c(a),m=r,f=p["".concat(d,".").concat(m)]||p[m]||u[m]||o;return a?n.createElement(f,i(i({ref:t},l),{},{components:a})):n.createElement(f,i({ref:t},l))}));function f(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=m;var s={};for(var d in t)hasOwnProperty.call(t,d)&&(s[d]=t[d]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;cruntime::put_key / runtime::get_key",id:"runtimeput_key--runtimeget_key",level:3},{value:"storage::write / storage::read",id:"storagewrite--storageread",level:3},{value:"storage:dictionary_put / storage::dictionary_get",id:"storagedictionary_put--storagedictionary_get",level:3},{value:"Example Code",id:"example-code",level:2},{value:"Example of put_key and storage::write",id:"example-of-put_key-and-storagewrite",level:3},{value:"Example of get_key and storage::read",id:"example-of-get_key-and-storageread",level:3},{value:"Example of dictionary_put and dictionary_get",id:"example-of-dictionary_put-and-dictionary_get",level:3},{value:"Additional Functions for Named Keys",id:"additional-functions-for-named-keys",level:2}],u={toc:p},m="wrapper";function f(e){var t=e.components,a=(0,r.Z)(e,i);return(0,o.kt)(m,(0,n.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"reading-and-writing-to-global-state-using-rust"},"Reading and Writing to Global State using Rust"),(0,o.kt)("p",null,"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language."),(0,o.kt)("p",null,"Essentially, there are three means of storage within the Casper ecosystem. These consist of ",(0,o.kt)("inlineCode",{parentName:"p"},"runtime::put_key"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"storage::write"),"(alongside ",(0,o.kt)("inlineCode",{parentName:"p"},"storage::new_uref")," as explained below) and ",(0,o.kt)("inlineCode",{parentName:"p"},"storage::dictionary_put"),". These stored values can be read using ",(0,o.kt)("inlineCode",{parentName:"p"},"runtime::get_key"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"storage::read")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"storage::dictionary_get"),", respectively. Each method stores data in a specific way, and it's important to understand the differences."),(0,o.kt)("h2",{id:"description-of-functions"},"Description of Functions"),(0,o.kt)("h3",{id:"runtimeput_key--runtimeget_key"},(0,o.kt)("inlineCode",{parentName:"h3"},"runtime::put_key")," / ",(0,o.kt)("inlineCode",{parentName:"h3"},"runtime::get_key")),(0,o.kt)("p",null,"Both the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.put_key.html"},(0,o.kt)("inlineCode",{parentName:"a"},"put_key"))," and ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.get_key.html"},(0,o.kt)("inlineCode",{parentName:"a"},"get_key"))," functions refer to Casper ",(0,o.kt)("inlineCode",{parentName:"p"},"Key")," types as outlined in both the ",(0,o.kt)("a",{parentName:"p",href:"/concepts/serialization-standard#serialization-standard-state-keys"},"Understanding Hash Types")," and ",(0,o.kt)("a",{parentName:"p",href:"/concepts/serialization-standard#serialization-standard-state-keys"},"Serialization Standard"),". These keys are stored within a URef as a ",(0,o.kt)("inlineCode",{parentName:"p"},"Key")," type."),(0,o.kt)("h3",{id:"storagewrite--storageread"},(0,o.kt)("inlineCode",{parentName:"h3"},"storage::write")," / ",(0,o.kt)("inlineCode",{parentName:"h3"},"storage::read")),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.write.html"},(0,o.kt)("inlineCode",{parentName:"a"},"storage::write"))," writes a given value to a previously established URef (created using ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_uref.html"},(0,o.kt)("inlineCode",{parentName:"a"},"storage::new_uref")),"). Unlike ",(0,o.kt)("inlineCode",{parentName:"p"},"put_key"),", this value is not one of the ",(0,o.kt)("inlineCode",{parentName:"p"},"Key")," types listed above, but rather any of the potential ",(0,o.kt)("a",{parentName:"p",href:"https://docs.casperlabs.io/developers/json-rpc/types_cl/#cltype"},(0,o.kt)("inlineCode",{parentName:"a"},"CLType")),"s as outlined. ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.read.html"},(0,o.kt)("inlineCode",{parentName:"a"},"storage::read"))," provides a method to retrieve these values from the associated URef."),(0,o.kt)("h3",{id:"storagedictionary_put--storagedictionary_get"},(0,o.kt)("inlineCode",{parentName:"h3"},"storage:dictionary_put")," / ",(0,o.kt)("inlineCode",{parentName:"h3"},"storage::dictionary_get")),(0,o.kt)("p",null,"For most data storage needs on a Casper network, dictionaries are more efficient and provide lower gas costs than ",(0,o.kt)("inlineCode",{parentName:"p"},"NamedKeys"),". Each dictionary item exists independently, sharing a single dictionary seed URef for reference purposes."),(0,o.kt)("p",null,"More information on dictionaries can be found on the ",(0,o.kt)("a",{parentName:"p",href:"/concepts/dictionaries"},"Reading and Writing to Dictionaries")," page."),(0,o.kt)("h2",{id:"example-code"},"Example Code"),(0,o.kt)("h3",{id:"example-of-put_key-and-storagewrite"},"Example of ",(0,o.kt)("inlineCode",{parentName:"h3"},"put_key")," and ",(0,o.kt)("inlineCode",{parentName:"h3"},"storage::write")),(0,o.kt)("p",null,"This sample code creates a new contract and stores the contract hash in global state using the ",(0,o.kt)("inlineCode",{parentName:"p"},"runtime::put_key")," function."),(0,o.kt)("p",null,"Once the stored value has been initialized, the ",(0,o.kt)("inlineCode",{parentName:"p"},"storage::write")," function overwrites the existing value with ",(0,o.kt)("inlineCode",{parentName:"p"},"true"),". The URef is then stored in the current context as a ",(0,o.kt)("inlineCode",{parentName:"p"},"NamedKey")," titled ",(0,o.kt)("inlineCode",{parentName:"p"},"MY_STORED_VALUE_UREF"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"\n // Store contract hash under a Named key CONTRACT_HASH\n runtime::put_key(CONTRACT_HASH, contract_hash.into());\n\n // Store !MY_STORED_VALUE (false) as init value/type into a new URef\n let my_value_uref = storage::new_uref(!MY_STORED_VALUE);\n\n // Store MY_STORED_VALUE (true) under the URef value\n storage::write(my_value_uref, MY_STORED_VALUE);\n\n // Store the Uref under a Named key MY_STORED_VALUE_UREF\n let my_value_key: Key = my_value_uref.into();\n runtime::put_key(MY_STORED_VALUE_UREF, my_value_key);\n}\n\n")),(0,o.kt)("h3",{id:"example-of-get_key-and-storageread"},"Example of ",(0,o.kt)("inlineCode",{parentName:"h3"},"get_key")," and ",(0,o.kt)("inlineCode",{parentName:"h3"},"storage::read")),(0,o.kt)("p",null,"This example compliments the code sample above by retrieving the ",(0,o.kt)("inlineCode",{parentName:"p"},"CONTRACT_HASH")," using the ",(0,o.kt)("inlineCode",{parentName:"p"},"get_key")," function, before comparing a provided runtime argument ",(0,o.kt)("inlineCode",{parentName:"p"},"ARG_MY_STORED_VALUE")," against the previously stored ",(0,o.kt)("inlineCode",{parentName:"p"},"MY_STORED_VALUE_UREF")," using ",(0,o.kt)("inlineCode",{parentName:"p"},"storage::read"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"\n let my_stored_value_uref: URef = runtime::get_key(MY_STORED_VALUE_UREF)\n .unwrap_or_revert()\n .into_uref()\n .map(|uref| URef::new(uref.addr(), AccessRights::default()))\n .unwrap_or_revert()\n .into_read();\n\n let my_actual_stored_value: bool = storage::read(my_stored_value_uref).unwrap().unwrap();\n\n // Compare my stored value with runtime arg\n let my_expected_stored_value: bool = runtime::get_named_arg(ARG_MY_STORED_VALUE);\n if my_actual_stored_value != my_expected_stored_value {\n // We revert if my stored value is not what is expected from caller argument\n runtime::revert(UserError::StoredValueError);\n }\n\n runtime::print(&my_actual_stored_value.to_string());\n}\n\n")),(0,o.kt)("h3",{id:"example-of-dictionary_put-and-dictionary_get"},"Example of ",(0,o.kt)("inlineCode",{parentName:"h3"},"dictionary_put")," and ",(0,o.kt)("inlineCode",{parentName:"h3"},"dictionary_get")),(0,o.kt)("p",null,"Examples of dictionary usage for storage can be found in the ",(0,o.kt)("em",{parentName:"p"},"Writing Entries into a Dictionary")," section of ",(0,o.kt)("a",{parentName:"p",href:"/concepts/dictionaries#writing-entries-into-a-dictionary"},"Reading and Writing to Dictionaries"),"."),(0,o.kt)("h2",{id:"additional-functions-for-named-keys"},"Additional Functions for Named Keys"),(0,o.kt)("p",null,"The following functions might also be of interest for working with named keys:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_named_keys.html"},"list_named_keys")," - Returns the named keys of the current context"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.has_key.html"},"has_key")," - Returns true if the key exists in the current context\u2019s named keys"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.remove_key.html"},"remove_key")," - Removes the requested ",(0,o.kt)("inlineCode",{parentName:"li"},"NamedKey")," from the current context")))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[4875],{3905:function(e,t,a){a.d(t,{Zo:function(){return l},kt:function(){return f}});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var d=n.createContext({}),c=function(e){var t=n.useContext(d),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},l=function(e){var t=c(e.components);return n.createElement(d.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,d=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),p=c(a),m=r,f=p["".concat(d,".").concat(m)]||p[m]||u[m]||o;return a?n.createElement(f,i(i({ref:t},l),{},{components:a})):n.createElement(f,i({ref:t},l))}));function f(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=m;var s={};for(var d in t)hasOwnProperty.call(t,d)&&(s[d]=t[d]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;cruntime::put_key / runtime::get_key",id:"runtimeput_key--runtimeget_key",level:3},{value:"storage::write / storage::read",id:"storagewrite--storageread",level:3},{value:"storage:dictionary_put / storage::dictionary_get",id:"storagedictionary_put--storagedictionary_get",level:3},{value:"Example Code",id:"example-code",level:2},{value:"Example of put_key and storage::write",id:"example-of-put_key-and-storagewrite",level:3},{value:"Example of get_key and storage::read",id:"example-of-get_key-and-storageread",level:3},{value:"Example of dictionary_put and dictionary_get",id:"example-of-dictionary_put-and-dictionary_get",level:3},{value:"Additional Functions for Named Keys",id:"additional-functions-for-named-keys",level:2}],u={toc:p},m="wrapper";function f(e){var t=e.components,a=(0,r.Z)(e,i);return(0,o.kt)(m,(0,n.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"reading-and-writing-to-global-state-using-rust"},"Reading and Writing to Global State using Rust"),(0,o.kt)("p",null,"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language."),(0,o.kt)("p",null,"Essentially, there are three means of storage within the Casper ecosystem. These consist of ",(0,o.kt)("inlineCode",{parentName:"p"},"runtime::put_key"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"storage::write"),"(alongside ",(0,o.kt)("inlineCode",{parentName:"p"},"storage::new_uref")," as explained below) and ",(0,o.kt)("inlineCode",{parentName:"p"},"storage::dictionary_put"),". These stored values can be read using ",(0,o.kt)("inlineCode",{parentName:"p"},"runtime::get_key"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"storage::read")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"storage::dictionary_get"),", respectively. Each method stores data in a specific way, and it's important to understand the differences."),(0,o.kt)("h2",{id:"description-of-functions"},"Description of Functions"),(0,o.kt)("h3",{id:"runtimeput_key--runtimeget_key"},(0,o.kt)("inlineCode",{parentName:"h3"},"runtime::put_key")," / ",(0,o.kt)("inlineCode",{parentName:"h3"},"runtime::get_key")),(0,o.kt)("p",null,"Both the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.put_key.html"},(0,o.kt)("inlineCode",{parentName:"a"},"put_key"))," and ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.get_key.html"},(0,o.kt)("inlineCode",{parentName:"a"},"get_key"))," functions refer to Casper ",(0,o.kt)("inlineCode",{parentName:"p"},"Key")," types as outlined in both the ",(0,o.kt)("a",{parentName:"p",href:"/concepts/serialization-standard#serialization-standard-state-keys"},"Understanding Hash Types")," and ",(0,o.kt)("a",{parentName:"p",href:"/concepts/serialization-standard#serialization-standard-state-keys"},"Serialization Standard"),". These keys are stored within a URef as a ",(0,o.kt)("inlineCode",{parentName:"p"},"Key")," type."),(0,o.kt)("h3",{id:"storagewrite--storageread"},(0,o.kt)("inlineCode",{parentName:"h3"},"storage::write")," / ",(0,o.kt)("inlineCode",{parentName:"h3"},"storage::read")),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.write.html"},(0,o.kt)("inlineCode",{parentName:"a"},"storage::write"))," writes a given value to a previously established URef (created using ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_uref.html"},(0,o.kt)("inlineCode",{parentName:"a"},"storage::new_uref")),"). Unlike ",(0,o.kt)("inlineCode",{parentName:"p"},"put_key"),", this value is not one of the ",(0,o.kt)("inlineCode",{parentName:"p"},"Key")," types listed above, but rather any of the potential ",(0,o.kt)("a",{parentName:"p",href:"https://docs.casperlabs.io/developers/json-rpc/types_cl/#cltype"},(0,o.kt)("inlineCode",{parentName:"a"},"CLType")),"s as outlined. ",(0,o.kt)("a",{parentName:"p",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.read.html"},(0,o.kt)("inlineCode",{parentName:"a"},"storage::read"))," provides a method to retrieve these values from the associated URef."),(0,o.kt)("h3",{id:"storagedictionary_put--storagedictionary_get"},(0,o.kt)("inlineCode",{parentName:"h3"},"storage:dictionary_put")," / ",(0,o.kt)("inlineCode",{parentName:"h3"},"storage::dictionary_get")),(0,o.kt)("p",null,"For most data storage needs on a Casper network, dictionaries are more efficient and provide lower gas costs than ",(0,o.kt)("inlineCode",{parentName:"p"},"NamedKeys"),". Each dictionary item exists independently, sharing a single dictionary seed URef for reference purposes."),(0,o.kt)("p",null,"More information on dictionaries can be found on the ",(0,o.kt)("a",{parentName:"p",href:"/concepts/dictionaries"},"Reading and Writing to Dictionaries")," page."),(0,o.kt)("h2",{id:"example-code"},"Example Code"),(0,o.kt)("h3",{id:"example-of-put_key-and-storagewrite"},"Example of ",(0,o.kt)("inlineCode",{parentName:"h3"},"put_key")," and ",(0,o.kt)("inlineCode",{parentName:"h3"},"storage::write")),(0,o.kt)("p",null,"This sample code creates a new contract and stores the contract hash in global state using the ",(0,o.kt)("inlineCode",{parentName:"p"},"runtime::put_key")," function."),(0,o.kt)("p",null,"Once the stored value has been initialized, the ",(0,o.kt)("inlineCode",{parentName:"p"},"storage::write")," function overwrites the existing value with ",(0,o.kt)("inlineCode",{parentName:"p"},"true"),". The URef is then stored in the current context as a ",(0,o.kt)("inlineCode",{parentName:"p"},"NamedKey")," titled ",(0,o.kt)("inlineCode",{parentName:"p"},"MY_STORED_VALUE_UREF"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"\n // Store contract hash under a Named key CONTRACT_HASH\n runtime::put_key(CONTRACT_HASH, contract_hash.into());\n\n // Store !MY_STORED_VALUE (false) as init value/type into a new URef\n let my_value_uref = storage::new_uref(!MY_STORED_VALUE);\n\n // Store MY_STORED_VALUE (true) under the URef value\n storage::write(my_value_uref, MY_STORED_VALUE);\n\n // Store the Uref under a Named key MY_STORED_VALUE_UREF\n let my_value_key: Key = my_value_uref.into();\n runtime::put_key(MY_STORED_VALUE_UREF, my_value_key);\n}\n\n")),(0,o.kt)("h3",{id:"example-of-get_key-and-storageread"},"Example of ",(0,o.kt)("inlineCode",{parentName:"h3"},"get_key")," and ",(0,o.kt)("inlineCode",{parentName:"h3"},"storage::read")),(0,o.kt)("p",null,"This example compliments the code sample above by retrieving the ",(0,o.kt)("inlineCode",{parentName:"p"},"CONTRACT_HASH")," using the ",(0,o.kt)("inlineCode",{parentName:"p"},"get_key")," function, before comparing a provided runtime argument ",(0,o.kt)("inlineCode",{parentName:"p"},"ARG_MY_STORED_VALUE")," against the previously stored ",(0,o.kt)("inlineCode",{parentName:"p"},"MY_STORED_VALUE_UREF")," using ",(0,o.kt)("inlineCode",{parentName:"p"},"storage::read"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-rust"},"\n let my_stored_value_uref: URef = runtime::get_key(MY_STORED_VALUE_UREF)\n .unwrap_or_revert()\n .into_uref()\n .map(|uref| URef::new(uref.addr(), AccessRights::default()))\n .unwrap_or_revert()\n .into_read();\n\n let my_actual_stored_value: bool = storage::read(my_stored_value_uref).unwrap().unwrap();\n\n // Compare my stored value with runtime arg\n let my_expected_stored_value: bool = runtime::get_named_arg(ARG_MY_STORED_VALUE);\n if my_actual_stored_value != my_expected_stored_value {\n // We revert if my stored value is not what is expected from caller argument\n runtime::revert(UserError::StoredValueError);\n }\n\n runtime::print(&my_actual_stored_value.to_string());\n}\n\n")),(0,o.kt)("h3",{id:"example-of-dictionary_put-and-dictionary_get"},"Example of ",(0,o.kt)("inlineCode",{parentName:"h3"},"dictionary_put")," and ",(0,o.kt)("inlineCode",{parentName:"h3"},"dictionary_get")),(0,o.kt)("p",null,"Examples of dictionary usage for storage can be found in the ",(0,o.kt)("em",{parentName:"p"},"Writing Entries into a Dictionary")," section of ",(0,o.kt)("a",{parentName:"p",href:"/concepts/dictionaries#writing-entries-into-a-dictionary"},"Reading and Writing to Dictionaries"),"."),(0,o.kt)("h2",{id:"additional-functions-for-named-keys"},"Additional Functions for Named Keys"),(0,o.kt)("p",null,"The following functions might also be of interest for working with named keys:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_named_keys.html"},"list_named_keys")," - Returns the named keys of the current context"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.has_key.html"},"has_key")," - Returns true if the key exists in the current context\u2019s named keys"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.remove_key.html"},"remove_key")," - Removes the requested ",(0,o.kt)("inlineCode",{parentName:"li"},"NamedKey")," from the current context")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/main.d24a7c79.js b/assets/js/main.ade4bc84.js similarity index 93% rename from assets/js/main.d24a7c79.js rename to assets/js/main.ade4bc84.js index 27b4025f63..4ae78c96e9 100644 --- a/assets/js/main.d24a7c79.js +++ b/assets/js/main.ade4bc84.js @@ -1,2 +1,2 @@ -/*! For license information please see main.d24a7c79.js.LICENSE.txt */ -(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[179],{830:function(e,t,n){"use strict";n.d(t,{W:function(){return o}});var r=n(7294);function o(){return r.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},r.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},290:function(e){e.exports=function(){"use strict";function e(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function t(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function n(n){for(var r=1;r=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function o(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e)){var n=[],r=!0,o=!1,a=void 0;try{for(var i,s=e[Symbol.iterator]();!(r=(i=s.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){o=!0,a=e}finally{try{r||null==s.return||s.return()}finally{if(o)throw a}}return n}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function a(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return Promise.resolve().then((function(){s();var t=JSON.stringify(e);return a()[t]})).then((function(e){return Promise.all([e?e.value:t(),void 0!==e])})).then((function(e){var t=o(e,2),r=t[0],a=t[1];return Promise.all([r,a||n.miss(r)])})).then((function(e){return o(e,1)[0]}))},set:function(e,t){return Promise.resolve().then((function(){var o=a();return o[JSON.stringify(e)]={timestamp:(new Date).getTime(),value:t},r().setItem(n,JSON.stringify(o)),t}))},delete:function(e){return Promise.resolve().then((function(){var t=a();delete t[JSON.stringify(e)],r().setItem(n,JSON.stringify(t))}))},clear:function(){return Promise.resolve().then((function(){r().removeItem(n)}))}}}function s(e){var t=a(e.caches),n=t.shift();return void 0===n?{get:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return t().then((function(e){return Promise.all([e,n.miss(e)])})).then((function(e){return o(e,1)[0]}))},set:function(e,t){return Promise.resolve(t)},delete:function(e){return Promise.resolve()},clear:function(){return Promise.resolve()}}:{get:function(e,r){var o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return n.get(e,r,o).catch((function(){return s({caches:t}).get(e,r,o)}))},set:function(e,r){return n.set(e,r).catch((function(){return s({caches:t}).set(e,r)}))},delete:function(e){return n.delete(e).catch((function(){return s({caches:t}).delete(e)}))},clear:function(){return n.clear().catch((function(){return s({caches:t}).clear()}))}}}function c(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{serializable:!0},t={};return{get:function(n,r){var o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}},a=JSON.stringify(n);if(a in t)return Promise.resolve(e.serializable?JSON.parse(t[a]):t[a]);var i=r(),s=o&&o.miss||function(){return Promise.resolve()};return i.then((function(e){return s(e)})).then((function(){return i}))},set:function(n,r){return t[JSON.stringify(n)]=e.serializable?JSON.stringify(r):r,Promise.resolve(r)},delete:function(e){return delete t[JSON.stringify(e)],Promise.resolve()},clear:function(){return t={},Promise.resolve()}}}function l(e){for(var t=e.length-1;t>0;t--){var n=Math.floor(Math.random()*(t+1)),r=e[t];e[t]=e[n],e[n]=r}return e}function u(e,t){return t?(Object.keys(t).forEach((function(n){e[n]=t[n](e)})),e):e}function d(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r0?r:void 0,timeout:n.timeout||t,headers:n.headers||{},queryParameters:n.queryParameters||{},cacheable:n.cacheable}}var m={Read:1,Write:2,Any:3},h=1,g=2,v=3;function b(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:h;return n(n({},e),{},{status:t,lastUpdate:Date.now()})}function y(e){return"string"==typeof e?{protocol:"https",url:e,accept:m.Any}:{protocol:e.protocol||"https",url:e.url,accept:e.accept||m.Any}}var w="GET",k="POST";function _(e,t){return Promise.all(t.map((function(t){return e.get(t,(function(){return Promise.resolve(b(t))}))}))).then((function(e){var n=e.filter((function(e){return function(e){return e.status===h||Date.now()-e.lastUpdate>12e4}(e)})),r=e.filter((function(e){return function(e){return e.status===v&&Date.now()-e.lastUpdate<=12e4}(e)})),o=[].concat(a(n),a(r));return{getTimeout:function(e,t){return(0===r.length&&0===e?1:r.length+3+e)*t},statelessHosts:o.length>0?o.map((function(e){return y(e)})):t}}))}function E(e,t,r,o){var i=[],s=function(e,t){if(e.method!==w&&(void 0!==e.data||void 0!==t.data)){var r=Array.isArray(e.data)?e.data:n(n({},e.data),t.data);return JSON.stringify(r)}}(r,o),c=function(e,t){var r=n(n({},e.headers),t.headers),o={};return Object.keys(r).forEach((function(e){var t=r[e];o[e.toLowerCase()]=t})),o}(e,o),l=r.method,u=r.method!==w?{}:n(n({},r.data),o.data),d=n(n(n({"x-algolia-agent":e.userAgent.value},e.queryParameters),u),o.queryParameters),p=0,f=function t(n,a){var u=n.pop();if(void 0===u)throw{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:T(i)};var f={data:s,headers:c,method:l,url:x(u,r.path,d),connectTimeout:a(p,e.timeouts.connect),responseTimeout:a(p,o.timeout)},m=function(e){var t={request:f,response:e,host:u,triesLeft:n.length};return i.push(t),t},h={onSuccess:function(e){return function(e){try{return JSON.parse(e.content)}catch(t){throw function(e,t){return{name:"DeserializationError",message:e,response:t}}(t.message,e)}}(e)},onRetry:function(r){var o=m(r);return r.isTimedOut&&p++,Promise.all([e.logger.info("Retryable failure",N(o)),e.hostsCache.set(u,b(u,r.isTimedOut?v:g))]).then((function(){return t(n,a)}))},onFail:function(e){throw m(e),function(e,t){var n=e.content,r=e.status,o=n;try{o=JSON.parse(n).message}catch(e){}return function(e,t,n){return{name:"ApiError",message:e,status:t,transporterStackTrace:n}}(o,r,t)}(e,T(i))}};return e.requester.send(f).then((function(e){return function(e,t){return function(e){var t=e.status;return e.isTimedOut||function(e){var t=e.isTimedOut,n=e.status;return!t&&0==~~n}(e)||2!=~~(t/100)&&4!=~~(t/100)}(e)?t.onRetry(e):2==~~(e.status/100)?t.onSuccess(e):t.onFail(e)}(e,h)}))};return _(e.hostsCache,t).then((function(e){return f(a(e.statelessHosts).reverse(),e.getTimeout)}))}function C(e){var t={value:"Algolia for JavaScript (".concat(e,")"),add:function(e){var n="; ".concat(e.segment).concat(void 0!==e.version?" (".concat(e.version,")"):"");return-1===t.value.indexOf(n)&&(t.value="".concat(t.value).concat(n)),t}};return t}function x(e,t,n){var r=S(n),o="".concat(e.protocol,"://").concat(e.url,"/").concat("/"===t.charAt(0)?t.substr(1):t);return r.length&&(o+="?".concat(r)),o}function S(e){return Object.keys(e).map((function(t){return d("%s=%s",t,(n=e[t],"[object Object]"===Object.prototype.toString.call(n)||"[object Array]"===Object.prototype.toString.call(n)?JSON.stringify(e[t]):e[t]));var n})).join("&")}function T(e){return e.map((function(e){return N(e)}))}function N(e){var t=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return n(n({},e),{},{request:n(n({},e.request),{},{headers:n(n({},e.request.headers),t)})})}var L=function(e){var t=e.appId,r=function(e,t,n){var r={"x-algolia-api-key":n,"x-algolia-application-id":t};return{headers:function(){return e===p.WithinHeaders?r:{}},queryParameters:function(){return e===p.WithinQueryParameters?r:{}}}}(void 0!==e.authMode?e.authMode:p.WithinHeaders,t,e.apiKey),a=function(e){var t=e.hostsCache,n=e.logger,r=e.requester,a=e.requestsCache,i=e.responsesCache,s=e.timeouts,c=e.userAgent,l=e.hosts,u=e.queryParameters,d={hostsCache:t,logger:n,requester:r,requestsCache:a,responsesCache:i,timeouts:s,userAgent:c,headers:e.headers,queryParameters:u,hosts:l.map((function(e){return y(e)})),read:function(e,t){var n=f(t,d.timeouts.read),r=function(){return E(d,d.hosts.filter((function(e){return 0!=(e.accept&m.Read)})),e,n)};if(!0!==(void 0!==n.cacheable?n.cacheable:e.cacheable))return r();var a={request:e,mappedRequestOptions:n,transporter:{queryParameters:d.queryParameters,headers:d.headers}};return d.responsesCache.get(a,(function(){return d.requestsCache.get(a,(function(){return d.requestsCache.set(a,r()).then((function(e){return Promise.all([d.requestsCache.delete(a),e])}),(function(e){return Promise.all([d.requestsCache.delete(a),Promise.reject(e)])})).then((function(e){var t=o(e,2);return t[0],t[1]}))}))}),{miss:function(e){return d.responsesCache.set(a,e)}})},write:function(e,t){return E(d,d.hosts.filter((function(e){return 0!=(e.accept&m.Write)})),e,f(t,d.timeouts.write))}};return d}(n(n({hosts:[{url:"".concat(t,"-dsn.algolia.net"),accept:m.Read},{url:"".concat(t,".algolia.net"),accept:m.Write}].concat(l([{url:"".concat(t,"-1.algolianet.com")},{url:"".concat(t,"-2.algolianet.com")},{url:"".concat(t,"-3.algolianet.com")}]))},e),{},{headers:n(n(n({},r.headers()),{"content-type":"application/x-www-form-urlencoded"}),e.headers),queryParameters:n(n({},r.queryParameters()),e.queryParameters)}));return u({transporter:a,appId:t,addAlgoliaAgent:function(e,t){a.userAgent.add({segment:e,version:t})},clearCache:function(){return Promise.all([a.requestsCache.clear(),a.responsesCache.clear()]).then((function(){}))}},e.methods)},A=function(e){return function(t,n){return t.method===w?e.transporter.read(t,n):e.transporter.write(t,n)}},O=function(e){return function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return u({transporter:e.transporter,appId:e.appId,indexName:t},n.methods)}},P=function(e){return function(t,r){var o=t.map((function(e){return n(n({},e),{},{params:S(e.params||{})})}));return e.transporter.read({method:k,path:"1/indexes/*/queries",data:{requests:o},cacheable:!0},r)}},I=function(e){return function(t,o){return Promise.all(t.map((function(t){var a=t.params,i=a.facetName,s=a.facetQuery,c=r(a,["facetName","facetQuery"]);return O(e)(t.indexName,{methods:{searchForFacetValues:D}}).searchForFacetValues(i,s,n(n({},o),c))})))}},R=function(e){return function(t,n,r){return e.transporter.read({method:k,path:d("1/answers/%s/prediction",e.indexName),data:{query:t,queryLanguages:n},cacheable:!0},r)}},M=function(e){return function(t,n){return e.transporter.read({method:k,path:d("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},n)}},D=function(e){return function(t,n,r){return e.transporter.read({method:k,path:d("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:n},cacheable:!0},r)}},F=1,B=2,j=3;function U(e,t,r){var o,a={appId:e,apiKey:t,timeouts:{connect:1,read:2,write:30},requester:{send:function(e){return new Promise((function(t){var n=new XMLHttpRequest;n.open(e.method,e.url,!0),Object.keys(e.headers).forEach((function(t){return n.setRequestHeader(t,e.headers[t])}));var r,o=function(e,r){return setTimeout((function(){n.abort(),t({status:0,content:r,isTimedOut:!0})}),1e3*e)},a=o(e.connectTimeout,"Connection timeout");n.onreadystatechange=function(){n.readyState>n.OPENED&&void 0===r&&(clearTimeout(a),r=o(e.responseTimeout,"Socket timeout"))},n.onerror=function(){0===n.status&&(clearTimeout(a),clearTimeout(r),t({content:n.responseText||"Network request failed",status:n.status,isTimedOut:!1}))},n.onload=function(){clearTimeout(a),clearTimeout(r),t({content:n.responseText,status:n.status,isTimedOut:!1})},n.send(e.data)}))}},logger:(o=j,{debug:function(e,t){return F>=o&&console.debug(e,t),Promise.resolve()},info:function(e,t){return B>=o&&console.info(e,t),Promise.resolve()},error:function(e,t){return console.error(e,t),Promise.resolve()}}),responsesCache:c(),requestsCache:c({serializable:!1}),hostsCache:s({caches:[i({key:"".concat("4.19.1","-").concat(e)}),c()]}),userAgent:C("4.19.1").add({segment:"Browser",version:"lite"}),authMode:p.WithinQueryParameters};return L(n(n(n({},a),r),{},{methods:{search:P,searchForFacetValues:I,multipleQueries:P,multipleSearchForFacetValues:I,customRequest:A,initIndex:function(e){return function(t){return O(e)(t,{methods:{search:M,searchForFacetValues:D,findAnswers:R}})}}}}))}return U.version="4.19.1",U}()},723:function(e,t,n){"use strict";n.d(t,{Z:function(){return f}});var r=n(7294),o=n(7462),a=n(8356),i=n.n(a),s=n(6887),c={"000be755":[function(){return n.e(6688).then(n.bind(n,825))},"@site/source/docs/casper/operators/index.md",825],"007245cc":[function(){return n.e(6321).then(n.bind(n,4151))},"@site/source/docs/casper/concepts/list-auth-keys.md",4151],"0082beea":[function(){return n.e(7280).then(n.bind(n,2226))},"@site/source/docs/casper/concepts/glossary/T.md",2226],"03b7b368":[function(){return n.e(1598).then(n.bind(n,7014))},"@site/source/docs/casper/resources/tokens/cep18/quickstart-guide.md",7014],"04253889":[function(){return n.e(9415).then(n.bind(n,2852))},"@site/source/docs/casper/operators/setup/install-node.md",2852],"043e2a1e":[function(){return n.e(8699).then(n.bind(n,4990))},"@site/source/docs/casper/developers/dapps/sdk/python-sdk.md",4990],"04e20c99":[function(){return n.e(4455).then(n.bind(n,2594))},"@site/source/docs/casper/users/block-explorer.md",2594],"0501e40c":[function(){return n.e(1752).then(n.bind(n,6628))},"@site/source/docs/casper/developers/dapps/index.md",6628],"08478d9e":[function(){return n.e(7156).then(n.bind(n,1921))},"@site/source/docs/casper/operators/setup-network/create-private.md",1921],"08ab7f39":[function(){return n.e(5614).then(n.bind(n,2474))},"@site/source/docs/casper/operators/setup-network/staging-files-for-new-network.md",2474],"09666a94":[function(){return n.e(716).then(n.bind(n,5711))},"@site/source/docs/casper/developers/cli/delegate.md",5711],"09f38b0b":[function(){return n.e(972).then(n.bind(n,3360))},"@site/source/docs/casper/concepts/glossary/P.md",3360],"0b24d6cd":[function(){return n.e(2627).then(n.bind(n,1254))},"@site/source/docs/casper/developers/cli/installing-contracts.md",1254],"0b57706a":[function(){return n.e(5428).then(n.bind(n,9308))},"@site/source/docs/casper/developers/cli/querying-global-state.md",9308],"0b7d75ea":[function(){return n.e(9921).then(n.bind(n,880))},"@site/source/docs/casper/concepts/glossary/I.md",880],"0c853d41":[function(){return n.e(263).then(n.bind(n,7113))},"@site/source/docs/casper/developers/json-rpc/minimal-compliance.md",7113],"0f636bcb":[function(){return n.e(8829).then(n.bind(n,8667))},"@site/source/docs/casper/resources/beginner/aws-node.md",8667],"1011242d":[function(){return n.e(9503).then(n.bind(n,3848))},"@site/source/docs/casper/developers/index.md",3848],"105579ae":[function(){return n.e(6621).then(n.bind(n,1920))},"@site/source/docs/casper/developers/dapps/signing-a-deploy.md",1920],11199349:[function(){return n.e(4896).then(n.bind(n,9453))},"@site/source/docs/casper/resources/beginner/counter/overview.md",9453],"11fbf07d":[function(){return n.e(1677).then(n.bind(n,5415))},"@site/source/docs/casper/concepts/design/casper-design.md",5415],"14c517c6":[function(){return n.e(7378).then(n.bind(n,195))},"@site/source/docs/casper/concepts/glossary/Y.md",195],17896441:[function(){return Promise.all([n.e(532),n.e(6672),n.e(7918)]).then(n.bind(n,580))},"@theme/DocItem",580],"18ef2b36":[function(){return n.e(1547).then(n.bind(n,2634))},"@site/source/docs/casper/resources/build-on-casper.md",2634],"19dcc625":[function(){return n.e(7925).then(n.bind(n,8471))},"@site/source/docs/casper/operators/becoming-a-validator/unbonding.md",8471],"1a4e3797":[function(){return Promise.all([n.e(532),n.e(7920)]).then(n.bind(n,6675))},"@theme/SearchPage",6675],"1afb40fe":[function(){return n.e(870).then(n.bind(n,309))},"@site/source/docs/casper/developers/json-rpc/json-rpc-informational.md",309],"1b581919":[function(){return n.e(7832).then(n.bind(n,160))},"@site/source/docs/casper/operators/becoming-a-validator/recovering.md",160],"1be78505":[function(){return Promise.all([n.e(532),n.e(9514)]).then(n.bind(n,4471))},"@theme/DocPage",4471],"1c22d3ad":[function(){return n.e(5870).then(n.bind(n,8319))},"@site/source/docs/casper/concepts/design/networking-protocol.md",8319],"1c7bd663":[function(){return n.e(3549).then(n.bind(n,1596))},"@site/source/docs/casper/developers/dapps/uref-security.md",1596],"1d7d8775":[function(){return n.e(4372).then(n.bind(n,9903))},"@site/source/docs/casper/concepts/glossary/W.md",9903],"1ddf2da6":[function(){return n.e(9575).then(n.bind(n,2709))},"@site/source/docs/casper/resources/tokens/cep78/js-tutorial.md",2709],"1ea27aee":[function(){return n.e(8717).then(n.bind(n,582))},"@site/source/docs/casper/operators/setup/index.md",582],"1ef5bb94":[function(){return n.e(6061).then(n.bind(n,3478))},"@site/source/docs/casper/developers/writing-onchain-code/calling-contracts.md",3478],21770712:[function(){return n.e(4056).then(n.bind(n,8622))},"@site/source/docs/casper/concepts/deploy-and-deploy-lifecycle.md",8622],"2289c829":[function(){return n.e(8612).then(n.bind(n,8755))},"@site/source/docs/casper/concepts/glossary/Q.md",8755],"22bbf3ab":[function(){return n.e(4809).then(n.bind(n,9503))},"@site/source/docs/casper/concepts/global-state.md",9503],"23dd64d8":[function(){return n.e(6717).then(n.bind(n,1575))},"@site/source/docs/casper/operators/maintenance/archiving-and-restoring.md",1575],"247783bb":[function(){return n.e(9334).then(n.t.bind(n,3769,19))},"/home/runner/work/docs/docs/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],"2747ce3a":[function(){return n.e(2031).then(n.bind(n,9147))},"@site/source/docs/casper/developers/essential-crates.md",9147],"27a494b1":[function(){return n.e(6109).then(n.bind(n,6672))},"@site/source/docs/casper/users/csprlive/testnet-faucet.md",6672],"298ce658":[function(){return n.e(2881).then(n.bind(n,5519))},"@site/source/docs/casper/developers/dapps/speculative-exec.md",5519],"2a99fafe":[function(){return n.e(6263).then(n.bind(n,4849))},"@site/source/docs/casper/resources/beginner/upgrade-contract.md",4849],"2bee511f":[function(){return n.e(8933).then(n.bind(n,5204))},"@site/source/docs/casper/concepts/serialization-standard.md",5204],"2c99ca03":[function(){return n.e(1258).then(n.bind(n,6333))},"@site/source/docs/casper/concepts/design/index.md",6333],"2d6bc0fd":[function(){return n.e(9508).then(n.bind(n,2844))},"@site/source/docs/casper/developers/writing-onchain-code/upgrading-contracts.md",2844],"2f093b46":[function(){return n.e(7214).then(n.bind(n,3122))},"@site/source/docs/casper/users/csprlive/index.md",3122],"303f2c49":[function(){return Promise.all([n.e(532),n.e(2882)]).then(n.bind(n,8438))},"@site/source/docs/casper/developers/dapps/technology-stack.md",8438],"35a30807":[function(){return n.e(8638).then(n.bind(n,5394))},"@site/source/docs/casper/resources/beginner/counter-testnet/overview.md",5394],"3668a89e":[function(){return n.e(9421).then(n.bind(n,1333))},"@site/source/docs/casper/developers/dapps/sdk/index.md",1333],"38517b34":[function(){return n.e(9427).then(n.bind(n,6527))},"@site/source/docs/casper/concepts/glossary/O.md",6527],"39b6f026":[function(){return n.e(2870).then(n.bind(n,7698))},"@site/source/docs/casper/resources/advanced/multi-sig/multi-sig-workflow.md",7698],"3b05c439":[function(){return n.e(299).then(n.bind(n,1091))},"@site/source/docs/casper/concepts/glossary/B.md",1091],"3e3fb99e":[function(){return n.e(9630).then(n.bind(n,1499))},"@site/source/docs/casper/concepts/glossary/C.md",1499],"3e7c0396":[function(){return n.e(1714).then(n.bind(n,9305))},"@site/source/docs/casper/concepts/smart-contracts.md",9305],"3f68fb95":[function(){return n.e(7218).then(n.bind(n,378))},"@site/source/docs/casper/concepts/glossary/F.md",378],"3fe59759":[function(){return n.e(4452).then(n.bind(n,6621))},"@site/source/docs/casper/developers/writing-onchain-code/simple-contract.md",6621],"401abd7a":[function(){return n.e(6661).then(n.bind(n,479))},"@site/source/docs/casper/developers/json-rpc/errors.md",479],"41afe816":[function(){return n.e(3457).then(n.bind(n,6662))},"@site/source/docs/casper/developers/json-rpc/types_cl.md",6662],"4636fedf":[function(){return n.e(8032).then(n.bind(n,1958))},"@site/source/docs/casper/developers/writing-onchain-code/assembly-script.md",1958],"463fc8b8":[function(){return n.e(2807).then(n.bind(n,762))},"@site/source/docs/casper/resources/tokens/cep18/query.md",762],"46ca92b5":[function(){return n.e(5814).then(n.bind(n,9302))},"@site/source/docs/casper/operators/setup/open-files.md",9302],"474a98da":[function(){return n.e(1918).then(n.bind(n,8068))},"@site/source/docs/casper/operators/setup/fast-sync.md",8068],"48b3ccc5":[function(){return n.e(4501).then(n.bind(n,8100))},"@site/source/docs/casper/resources/beginner/counter-testnet/commands.md",8100],"49c9a6f7":[function(){return n.e(5021).then(n.bind(n,7591))},"@site/source/docs/casper/resources/beginner/counter/walkthrough.md",7591],"49d6b5ce":[function(){return n.e(3582).then(n.bind(n,8389))},"@site/source/docs/casper/resources/advanced/index.md",8389],"50ce38df":[function(){return n.e(6146).then(n.bind(n,6630))},"@site/source/docs/casper/resources/beginner/counter/commands.md",6630],"516aae92":[function(){return n.e(9662).then(n.bind(n,4592))},"@site/source/docs/casper/users/csprlive/undelegate-ui.md",4592],"51cfcb69":[function(){return n.e(8788).then(n.bind(n,8311))},"@site/source/docs/casper/concepts/glossary/J.md",8311],"576aa6a1":[function(){return n.e(1268).then(n.bind(n,2227))},"@site/source/docs/casper/developers/dapps/prerequisites.md",2227],"5879a27f":[function(){return n.e(3274).then(n.bind(n,2483))},"@site/source/docs/casper/operators/setup/upgrade.md",2483],"590178a5":[function(){return n.e(4652).then(n.bind(n,4605))},"@site/source/docs/casper/developers/dapps/sdk/csharp-sdk.md",4605],"59b068d1":[function(){return n.e(6385).then(n.t.bind(n,7085,19))},"/home/runner/work/docs/docs/.docusaurus/docusaurus-theme-search-algolia/default/plugin-route-context-module-100.json",7085],"5bab3e27":[function(){return n.e(9189).then(n.bind(n,1156))},"@site/source/docs/casper/concepts/glossary/X.md",1156],"5c51aefb":[function(){return n.e(5715).then(n.bind(n,1014))},"@site/source/docs/casper/resources/quick-start.md",1014],"5c5ab968":[function(){return n.e(3212).then(n.bind(n,1473))},"@site/source/docs/casper/operators/becoming-a-validator/inactive-vs-faulty.md",1473],"5c6c4a57":[function(){return n.e(2570).then(n.bind(n,4))},"@site/source/docs/casper/developers/cli/opcode-costs.md",4],"5e4971e3":[function(){return n.e(3550).then(n.bind(n,7541))},"@site/source/docs/casper/concepts/design/reading-and-writing-to-the-blockchain.md",7541],"5e9f5e1a":[function(){return Promise.resolve().then(n.bind(n,6809))},"@generated/docusaurus.config",6809],"625db580":[function(){return n.e(6315).then(n.bind(n,3049))},"@site/source/docs/casper/concepts/glossary/D.md",3049],"653a68bf":[function(){return n.e(7063).then(n.bind(n,6866))},"@site/source/docs/casper/operators/maintenance/moving-node.md",6866],"6a8ad950":[function(){return n.e(2354).then(n.bind(n,8871))},"@site/source/docs/casper/concepts/economics/runtime.md",8871],"6a94474d":[function(){return n.e(4609).then(n.bind(n,5e3))},"@site/source/docs/casper/users/csprlive/token-transfer.md",5e3],"6af03f69":[function(){return n.e(4316).then(n.bind(n,928))},"@site/source/docs/casper/concepts/economics/consensus.md",928],"6b354c4b":[function(){return n.e(999).then(n.bind(n,3002))},"@site/source/docs/casper/concepts/glossary/V.md",3002],"6eee94da":[function(){return n.e(2388).then(n.bind(n,8219))},"@site/source/docs/casper/developers/dapps/sdk/go-sdk.md",8219],"6f629aff":[function(){return Promise.all([n.e(532),n.e(7413)]).then(n.bind(n,6646))},"@site/src/pages/Demo/Demo.tsx",6646],"6faae04c":[function(){return n.e(6986).then(n.bind(n,5881))},"@site/source/docs/casper/resources/advanced/list-cspr.md",5881],"6fc855ed":[function(){return n.e(1263).then(n.bind(n,4756))},"@site/source/docs/casper/users/ledger/ledger-cspr-live.md",4756],"7157e7af":[function(){return n.e(9212).then(n.bind(n,1056))},"@site/source/docs/casper/concepts/dictionaries.md",1056],"71c4e358":[function(){return n.e(7080).then(n.bind(n,5321))},"@site/source/docs/casper/concepts/glossary/L.md",5321],"71e073ea":[function(){return n.e(7059).then(n.bind(n,1483))},"@site/source/docs/casper/resources/tokens/cep18/tests.md",1483],"72301f79":[function(){return n.e(4970).then(n.bind(n,6916))},"@site/source/docs/casper/resources/advanced/cross-contract.md",6916],"725b7e74":[function(){return n.e(6958).then(n.bind(n,5453))},"@site/source/docs/casper/resources/advanced/multi-sig/other-scenarios.md",5453],"73a8655d":[function(){return n.e(4007).then(n.bind(n,8161))},"@site/source/docs/casper/developers/cli/transfers/verify-transfer.md",8161],"746691fd":[function(){return Promise.all([n.e(532),n.e(7364)]).then(n.bind(n,7620))},"@site/src/pages/Home/Home.tsx",7620],"74bbf90e":[function(){return Promise.all([n.e(532),n.e(5390)]).then(n.bind(n,3235))},"@site/source/docs/casper/developers/prerequisites.md",3235],"74ff8362":[function(){return n.e(1132).then(n.bind(n,6665))},"@site/source/docs/casper/developers/writing-onchain-code/getting-started.md",6665],"77f905e9":[function(){return n.e(5863).then(n.bind(n,6065))},"@site/source/docs/casper/operators/setup/non-root-user.md",6065],"78143ba1":[function(){return n.e(586).then(n.bind(n,1392))},"@site/source/docs/casper/concepts/glossary/M.md",1392],"796e8b5d":[function(){return n.e(3013).then(n.bind(n,831))},"@site/source/docs/casper/resources/tokens/cep78/modalities.md",831],"7adc1d42":[function(){return n.e(9889).then(n.bind(n,363))},"@site/source/docs/casper/developers/writing-onchain-code/testing-session-code.md",363],"7c09a624":[function(){return n.e(6439).then(n.bind(n,2925))},"@site/source/docs/casper/resources/advanced/return-values-tutorial.md",2925],"7d846783":[function(){return n.e(1002).then(n.bind(n,5262))},"@site/source/docs/casper/developers/writing-onchain-code/best-practices.md",5262],"7dc1264b":[function(){return n.e(3174).then(n.bind(n,2487))},"@site/source/docs/casper/resources/advanced/list-auth-keys-tutorial.md",2487],"80eab72b":[function(){return n.e(7562).then(n.bind(n,1169))},"@site/source/docs/casper/developers/cli/transfers/direct-token-transfer.md",1169],"81637ed9":[function(){return n.e(7576).then(n.bind(n,6032))},"@site/source/docs/casper/developers/cli/transfers/index.md",6032],"82798d79":[function(){return n.e(5811).then(n.bind(n,7749))},"@site/source/docs/casper/concepts/economics/gas-concepts.md",7749],84229592:[function(){return n.e(4416).then(n.bind(n,8441))},"@site/source/docs/casper/concepts/callstack.md",8441],"86a6526c":[function(){return n.e(4511).then(n.bind(n,3941))},"@site/source/docs/casper/resources/tokens/cep18/full-tutorial.md",3941],"87ec732b":[function(){return n.e(5607).then(n.bind(n,6382))},"@site/source/docs/casper/concepts/glossary/H.md",6382],"891ef04a":[function(){return n.e(3564).then(n.bind(n,2753))},"@site/source/docs/casper/operators/maintenance/index.md",2753],"8b4531bd":[function(){return n.e(1925).then(n.bind(n,8142))},"@site/source/docs/casper/users/ledger/ledger-live.md",8142],"8c2276de":[function(){return n.e(3608).then(n.bind(n,4148))},"@site/source/docs/casper/resources/advanced/transfer-token-to-contract.md",4148],"8f925d60":[function(){return n.e(4835).then(n.bind(n,4659))},"@site/source/docs/casper/developers/json-rpc/json-rpc-pos.md",4659],"92692c02":[function(){return n.e(3065).then(n.bind(n,3597))},"@site/source/docs/casper/users/ledger/staking-ledger.md",3597],"935f2afb":[function(){return n.e(53).then(n.t.bind(n,1109,19))},"~docs/default/version-current-metadata-prop-751.json",1109],"956d710b":[function(){return n.e(8422).then(n.bind(n,5585))},"@site/source/docs/casper/developers/dapps/setup-nctl.md",5585],"963db545":[function(){return n.e(9065).then(n.bind(n,9970))},"@site/source/docs/casper/developers/dapps/nctl-test.md",9970],"9755a710":[function(){return n.e(8996).then(n.bind(n,1669))},"@site/source/docs/casper/resources/beginner/getting-started-tutorial.md",1669],"9800de81":[function(){return n.e(5477).then(n.bind(n,9824))},"@site/source/docs/casper/resources/tokens/cep18/transfer.md",9824],"99756d1f":[function(){return n.e(8669).then(n.bind(n,7248))},"@site/source/docs/casper/developers/json-rpc/index.md",7248],"9ae83eb2":[function(){return n.e(5240).then(n.bind(n,9533))},"@site/source/docs/casper/operators/setup/basic-node-configuration.md",9533],"9b4bb048":[function(){return n.e(6171).then(n.bind(n,6807))},"@site/source/docs/casper/resources/advanced/multi-sig/index.md",6807],"9c5b046c":[function(){return Promise.all([n.e(532),n.e(319)]).then(n.bind(n,2229))},"@site/source/docs/casper/resources/moving-to-casper.md",2229],"9df8dea5":[function(){return n.e(4685).then(n.bind(n,8467))},"@site/source/docs/casper/resources/tokens/cep78/introduction.md",8467],"9ea0190f":[function(){return n.e(8610).then(n.bind(n,1970))},"@site/source/docs/casper/developers/json-rpc/guidance.md",1970],"9ebdaa52":[function(){return n.e(1710).then(n.bind(n,3198))},"@site/source/docs/casper/developers/dapps/dapp.md",3198],"9ff556dd":[function(){return n.e(3355).then(n.bind(n,3712))},"@site/source/docs/casper/resources/beginner/querying-network.md",3712],a27f3afe:[function(){return n.e(3055).then(n.bind(n,2288))},"@site/source/docs/casper/developers/writing-onchain-code/testing-contracts.md",2288],a2831d13:[function(){return n.e(5826).then(n.bind(n,4070))},"@site/source/docs/casper/resources/tokens/cep78/reverse-lookup.md",4070],a45056cf:[function(){return n.e(6563).then(n.bind(n,5039))},"@site/source/docs/casper/concepts/glossary/E.md",5039],a4f33ee0:[function(){return n.e(1472).then(n.bind(n,5373))},"@site/source/docs/casper/developers/cli/transfers/multisig-deploy-transfer.md",5373],a5ab1e83:[function(){return n.e(7598).then(n.bind(n,3241))},"@site/source/docs/casper/developers/cli/execution-error-codes.md",3241],a628b5be:[function(){return n.e(8541).then(n.bind(n,44))},"@site/source/docs/casper/concepts/economics/staking/concepts.md",44],a6d4c72e:[function(){return Promise.all([n.e(532),n.e(2691)]).then(n.bind(n,9827))},"@site/source/docs/casper/developers/dapps/monitor-and-consume-events.md",9827],a6f4e53a:[function(){return n.e(9989).then(n.bind(n,6755))},"@site/source/docs/casper/developers/cli/redelegate.md",6755],a71eff7a:[function(){return n.e(6988).then(n.bind(n,9874))},"@site/source/docs/casper/developers/cli/calling-contracts.md",9874],a7434565:[function(){return n.e(7645).then(n.t.bind(n,5745,19))},"/home/runner/work/docs/docs/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],a75f1f06:[function(){return n.e(8575).then(n.bind(n,3350))},"@site/source/docs/casper/resources/beginner/counter-testnet/index.md",3350],a86c8182:[function(){return n.e(4266).then(n.bind(n,839))},"@site/source/docs/casper/users/ledger/index.md",839],ac7d7524:[function(){return n.e(984).then(n.bind(n,910))},"@site/source/docs/casper/concepts/design/p2p.md",910],ad025532:[function(){return n.e(2092).then(n.bind(n,4111))},"@site/source/docs/casper/developers/writing-onchain-code/index.md",4111],ad774662:[function(){return n.e(7415).then(n.bind(n,9616))},"@site/source/docs/casper/concepts/glossary/index.md",9616],ae44828e:[function(){return Promise.all([n.e(532),n.e(5779)]).then(n.bind(n,4095))},"@site/source/docs/casper/developers/dapps/template-frontend.md",4095],b0120e2d:[function(){return n.e(1636).then(n.bind(n,5909))},"@site/source/docs/casper/developers/cli/sending-deploys.md",5909],b161625a:[function(){return n.e(420).then(n.bind(n,5607))},"@site/source/docs/casper/developers/writing-onchain-code/contract-vs-session.md",5607],b244b0e9:[function(){return n.e(9041).then(n.bind(n,6372))},"@site/source/docs/casper/concepts/economics/index.md",6372],b2eb857f:[function(){return n.e(4696).then(n.bind(n,4171))},"@site/source/docs/casper/resources/casper-open-source-software.md",4171],b53d104f:[function(){return n.e(3532).then(n.bind(n,529))},"@site/source/docs/casper/concepts/hash-types.md",529],b5850dcd:[function(){return n.e(9352).then(n.bind(n,4701))},"@site/source/docs/casper/developers/writing-onchain-code/writing-session-code.md",4701],b643e154:[function(){return n.e(6776).then(n.bind(n,6557))},"@site/source/docs/casper/concepts/economics/staking/delegation.md",6557],b74af8d8:[function(){return n.e(1942).then(n.bind(n,2658))},"@site/source/docs/casper/operators/setup/node-endpoints.md",2658],b9da5eb7:[function(){return n.e(2733).then(n.bind(n,9108))},"@site/source/docs/casper/concepts/glossary/S.md",9108],bb301b4e:[function(){return n.e(9751).then(n.bind(n,5656))},"@site/source/docs/casper/concepts/glossary/Z.md",5656],bb9efa25:[function(){return n.e(5611).then(n.bind(n,2311))},"@site/source/docs/casper/users/ledger/ledger-setup.md",2311],bbb7efd1:[function(){return n.e(6500).then(n.bind(n,8720))},"@site/source/docs/casper/concepts/glossary/K.md",8720],bc69d55a:[function(){return n.e(6494).then(n.bind(n,7018))},"@site/source/docs/casper/concepts/design/highway.md",7018],bcd2a870:[function(){return n.e(6099).then(n.bind(n,5916))},"@site/source/docs/casper/developers/dapps/sdk/script-sdk.md",5916],bd4f9aad:[function(){return n.e(9753).then(n.bind(n,6979))},"@site/source/docs/casper/operators/setup/joining.md",6979],be8830cf:[function(){return n.e(170).then(n.bind(n,399))},"@site/source/docs/casper/operators/setup-network/genesis.md",399],c2a85b60:[function(){return n.e(2614).then(n.bind(n,2264))},"@site/source/docs/casper/developers/json-rpc/types_chain.md",2264],c305f31a:[function(){return n.e(6646).then(n.bind(n,7207))},"@site/source/docs/casper/developers/cli/undelegate.md",7207],c5563497:[function(){return n.e(2894).then(n.bind(n,298))},"@site/source/docs/casper/concepts/index.md",298],c7849882:[function(){return n.e(9012).then(n.bind(n,2498))},"@site/source/docs/casper/concepts/glossary/R.md",2498],c860f7f3:[function(){return n.e(875).then(n.bind(n,2163))},"@site/source/docs/casper/developers/cli/index.md",2163],ca0cd80e:[function(){return n.e(7711).then(n.bind(n,8455))},"@site/source/docs/casper/concepts/glossary/A.md",8455],cb836585:[function(){return n.e(6834).then(n.bind(n,249))},"@site/source/docs/casper/disclaimer.md",249],cc2b34bc:[function(){return n.e(9470).then(n.bind(n,9709))},"@site/source/docs/casper/users/index.md",9709],d044d178:[function(){return n.e(2273).then(n.bind(n,1792))},"@site/source/docs/casper/operators/setup-network/chain-spec.md",1792],d2361378:[function(){return n.e(8306).then(n.bind(n,494))},"@site/source/docs/casper/concepts/intro-to-dapps.md",494],d45ad3b6:[function(){return n.e(3617).then(n.bind(n,6607))},"@site/source/docs/casper/developers/json-rpc/json-rpc-transactional.md",6607],db0e1f9a:[function(){return n.e(8444).then(n.bind(n,7825))},"@site/source/docs/casper/resources/tokens/index.md",7825],dc0ad5f4:[function(){return n.e(7806).then(n.bind(n,6250))},"@site/source/docs/casper/users/funding-from-exchanges.md",6250],dd0f338d:[function(){return n.e(1301).then(n.bind(n,7030))},"@site/source/docs/casper/operators/becoming-a-validator/bonding.md",7030],de7cb1a1:[function(){return n.e(5153).then(n.bind(n,4925))},"@site/source/docs/casper/concepts/accounts-and-keys.md",4925],e00654fa:[function(){return n.e(7698).then(n.bind(n,4201))},"@site/source/docs/casper/concepts/economics/staking/staking.md",4201],e2fa8c79:[function(){return Promise.all([n.e(532),n.e(4080)]).then(n.bind(n,4139))},"@site/source/docs/casper/developers/dapps/sdk/client-library-usage.md",4139],e2ffc27a:[function(){return n.e(5036).then(n.bind(n,4759))},"@site/source/docs/casper/resources/beginner/cep18.md",4759],e6ce8647:[function(){return n.e(6871).then(n.bind(n,6112))},"@site/source/docs/casper/operators/becoming-a-validator/index.md",6112],e7ae6dc5:[function(){return n.e(5677).then(n.bind(n,3582))},"@site/source/docs/casper/operators/setup/hardware.md",3582],ea7bfaa8:[function(){return n.e(9156).then(n.bind(n,9810))},"@site/source/docs/casper/resources/beginner/index.md",9810],ed14c6f0:[function(){return n.e(4052).then(n.bind(n,4007))},"@site/source/docs/casper/users/csprlive/delegate-ui.md",4007],eda26e2d:[function(){return n.e(3605).then(n.bind(n,7753))},"@site/source/docs/casper/concepts/glossary/G.md",7753],ef563e2a:[function(){return n.e(282).then(n.bind(n,7112))},"@site/source/docs/casper/resources/index.md",7112],efa2c7c1:[function(){return n.e(5962).then(n.bind(n,439))},"@site/source/docs/casper/resources/advanced/two-party-multi-sig.md",439],f12850af:[function(){return n.e(9964).then(n.bind(n,2895))},"@site/source/docs/casper/operators/setup-network/index.md",2895],f14292ab:[function(){return n.e(244).then(n.bind(n,1843))},"@site/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md",1843],f5187c73:[function(){return n.e(9203).then(n.bind(n,6752))},"@site/source/docs/casper/concepts/glossary/N.md",6752],f70cc67e:[function(){return n.e(7594).then(n.bind(n,5114))},"@site/source/docs/casper/resources/beginner/counter-testnet/walkthrough.md",5114],f8b123d7:[function(){return n.e(9669).then(n.bind(n,4953))},"@site/source/docs/casper/resources/beginner/counter/index.md",4953],f8f33652:[function(){return n.e(7022).then(n.bind(n,3928))},"@site/source/docs/casper/resources/tokens/cep78/using-casper-client.md",3928],fa593e9e:[function(){return n.e(5199).then(n.bind(n,488))},"@site/source/docs/casper/concepts/about.md",488],fbd44d32:[function(){return Promise.all([n.e(532),n.e(3803)]).then(n.bind(n,5625))},"@site/src/pages/Playground/Playground.tsx",5625],fcd43aac:[function(){return n.e(6571).then(n.bind(n,4993))},"@site/source/docs/casper/concepts/glossary/U.md",4993],fec0de85:[function(){return n.e(4875).then(n.bind(n,1474))},"@site/source/docs/casper/resources/advanced/storage-workflow.md",1474]};function l(e){var t=e.error,n=e.retry,o=e.pastDelay;return t?r.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):o?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var u=n(9670),d=n(226);function p(e,t){if("*"===e)return i()({loading:l,loader:function(){return n.e(4972).then(n.bind(n,4972))},modules:["@theme/NotFound"],webpack:function(){return[4972]},render:function(e,t){var n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});var a=s[e+"-"+t],p={},f=[],m=[],h=(0,u.Z)(a);return Object.entries(h).forEach((function(e){var t=e[0],n=e[1],r=c[n];r&&(p[t]=r[0],f.push(r[1]),m.push(r[2]))})),i().Map({loading:l,loader:p,modules:f,webpack:function(){return m},render:function(t,n){var i=JSON.parse(JSON.stringify(a));Object.entries(t).forEach((function(t){var n=t[0],r=t[1],o=r.default;if(!o)throw new Error("The page component at "+e+" doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.");"object"!=typeof o&&"function"!=typeof o||Object.keys(r).filter((function(e){return"default"!==e})).forEach((function(e){o[e]=r[e]}));var a=i,s=n.split(".");s.slice(0,-1).forEach((function(e){a=a[e]})),a[s[s.length-1]]=o}));var s=i.__comp;delete i.__comp;var c=i.__context;return delete i.__context,r.createElement(d.z,{value:c},r.createElement(s,(0,o.Z)({},i,n)))}})}var f=[{path:"/Demo/Demo/",component:p("/Demo/Demo/","5e1"),exact:!0},{path:"/Home/Home/",component:p("/Home/Home/","193"),exact:!0},{path:"/Playground/Playground/",component:p("/Playground/Playground/","a6a"),exact:!0},{path:"/search/",component:p("/search/","db4"),exact:!0},{path:"/",component:p("/","229"),routes:[{path:"/",component:p("/","339"),exact:!0,sidebar:"concepts"},{path:"/concepts/",component:p("/concepts/","7c4"),exact:!0,sidebar:"concepts"},{path:"/concepts/accounts-and-keys/",component:p("/concepts/accounts-and-keys/","3ee"),exact:!0,sidebar:"concepts"},{path:"/concepts/callstack/",component:p("/concepts/callstack/","c4d"),exact:!0,sidebar:"concepts"},{path:"/concepts/design/casper-design/",component:p("/concepts/design/casper-design/","8e2"),exact:!0,sidebar:"concepts"},{path:"/concepts/design/highway/",component:p("/concepts/design/highway/","7af"),exact:!0,sidebar:"concepts"},{path:"/concepts/design/networking-protocol/",component:p("/concepts/design/networking-protocol/","12e"),exact:!0},{path:"/concepts/design/p2p/",component:p("/concepts/design/p2p/","e99"),exact:!0,sidebar:"concepts"},{path:"/concepts/design/reading-and-writing-to-the-blockchain/",component:p("/concepts/design/reading-and-writing-to-the-blockchain/","afa"),exact:!0,sidebar:"concepts"},{path:"/concepts/dictionaries/",component:p("/concepts/dictionaries/","b26"),exact:!0,sidebar:"concepts"},{path:"/concepts/economics/concepts/",component:p("/concepts/economics/concepts/","9f8"),exact:!0,sidebar:"concepts"},{path:"/concepts/economics/consensus/",component:p("/concepts/economics/consensus/","890"),exact:!0,sidebar:"concepts"},{path:"/concepts/economics/delegation/",component:p("/concepts/economics/delegation/","e1c"),exact:!0,sidebar:"concepts"},{path:"/concepts/economics/gas-concepts/",component:p("/concepts/economics/gas-concepts/","acc"),exact:!0,sidebar:"concepts"},{path:"/concepts/global-state/",component:p("/concepts/global-state/","a8f"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/A/",component:p("/concepts/glossary/A/","a0e"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/B/",component:p("/concepts/glossary/B/","fe1"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/C/",component:p("/concepts/glossary/C/","bde"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/D/",component:p("/concepts/glossary/D/","522"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/E/",component:p("/concepts/glossary/E/","6aa"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/F/",component:p("/concepts/glossary/F/","e8f"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/G/",component:p("/concepts/glossary/G/","d7e"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/H/",component:p("/concepts/glossary/H/","431"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/I/",component:p("/concepts/glossary/I/","822"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/J/",component:p("/concepts/glossary/J/","76c"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/K/",component:p("/concepts/glossary/K/","ae4"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/L/",component:p("/concepts/glossary/L/","abb"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/M/",component:p("/concepts/glossary/M/","8bf"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/N/",component:p("/concepts/glossary/N/","ab4"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/O/",component:p("/concepts/glossary/O/","5b2"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/P/",component:p("/concepts/glossary/P/","caf"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/Q/",component:p("/concepts/glossary/Q/","32d"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/R/",component:p("/concepts/glossary/R/","864"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/S/",component:p("/concepts/glossary/S/","644"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/T/",component:p("/concepts/glossary/T/","e99"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/U/",component:p("/concepts/glossary/U/","626"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/V/",component:p("/concepts/glossary/V/","968"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/W/",component:p("/concepts/glossary/W/","9a9"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/X/",component:p("/concepts/glossary/X/","e1c"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/Y/",component:p("/concepts/glossary/Y/","0fa"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/Z/",component:p("/concepts/glossary/Z/","af2"),exact:!0,sidebar:"concepts"},{path:"/concepts/hash-types/",component:p("/concepts/hash-types/","60b"),exact:!0,sidebar:"concepts"},{path:"/concepts/intro-to-dapps/",component:p("/concepts/intro-to-dapps/","b7f"),exact:!0,sidebar:"concepts"},{path:"/concepts/list-auth-keys/",component:p("/concepts/list-auth-keys/","8a2"),exact:!0,sidebar:"concepts"},{path:"/concepts/serialization-standard/",component:p("/concepts/serialization-standard/","e94"),exact:!0,sidebar:"concepts"},{path:"/concepts/smart-contracts/",component:p("/concepts/smart-contracts/","e8a"),exact:!0,sidebar:"concepts"},{path:"/counter-testnet/",component:p("/counter-testnet/","a2c"),exact:!0,sidebar:"resources"},{path:"/counter/",component:p("/counter/","200"),exact:!0,sidebar:"resources"},{path:"/deploy-and-deploy-lifecycle/",component:p("/deploy-and-deploy-lifecycle/","552"),exact:!0,sidebar:"concepts"},{path:"/design/",component:p("/design/","2c3"),exact:!0,sidebar:"concepts"},{path:"/developers/",component:p("/developers/","626"),exact:!0,sidebar:"developers"},{path:"/developers/cli/",component:p("/developers/cli/","3ea"),exact:!0,sidebar:"developers"},{path:"/developers/cli/calling-contracts/",component:p("/developers/cli/calling-contracts/","037"),exact:!0,sidebar:"developers"},{path:"/developers/cli/delegate/",component:p("/developers/cli/delegate/","4a8"),exact:!0,sidebar:"developers"},{path:"/developers/cli/execution-error-codes/",component:p("/developers/cli/execution-error-codes/","b5d"),exact:!0,sidebar:"developers"},{path:"/developers/cli/installing-contracts/",component:p("/developers/cli/installing-contracts/","9a3"),exact:!0,sidebar:"developers"},{path:"/developers/cli/opcode-costs/",component:p("/developers/cli/opcode-costs/","1a2"),exact:!0,sidebar:"developers"},{path:"/developers/cli/querying-global-state/",component:p("/developers/cli/querying-global-state/","8f4"),exact:!0,sidebar:"developers"},{path:"/developers/cli/redelegate/",component:p("/developers/cli/redelegate/","df7"),exact:!0,sidebar:"developers"},{path:"/developers/cli/sending-deploys/",component:p("/developers/cli/sending-deploys/","f0b"),exact:!0,sidebar:"developers"},{path:"/developers/cli/transfers/",component:p("/developers/cli/transfers/","cec"),exact:!0,sidebar:"developers"},{path:"/developers/cli/transfers/direct-token-transfer/",component:p("/developers/cli/transfers/direct-token-transfer/","be6"),exact:!0,sidebar:"developers"},{path:"/developers/cli/transfers/multisig-deploy-transfer/",component:p("/developers/cli/transfers/multisig-deploy-transfer/","607"),exact:!0,sidebar:"developers"},{path:"/developers/cli/transfers/verify-transfer/",component:p("/developers/cli/transfers/verify-transfer/","56f"),exact:!0,sidebar:"developers"},{path:"/developers/cli/undelegate/",component:p("/developers/cli/undelegate/","a1f"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/",component:p("/developers/dapps/","3a0"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/dapp/",component:p("/developers/dapps/dapp/","586"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/monitor-and-consume-events/",component:p("/developers/dapps/monitor-and-consume-events/","72d"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/nctl-test/",component:p("/developers/dapps/nctl-test/","cef"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/prerequisites/",component:p("/developers/dapps/prerequisites/","455"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/sdk/client-library-usage/",component:p("/developers/dapps/sdk/client-library-usage/","4de"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/sdk/csharp-sdk/",component:p("/developers/dapps/sdk/csharp-sdk/","77a"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/sdk/go-sdk/",component:p("/developers/dapps/sdk/go-sdk/","f10"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/sdk/python-sdk/",component:p("/developers/dapps/sdk/python-sdk/","6b0"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/sdk/script-sdk/",component:p("/developers/dapps/sdk/script-sdk/","df5"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/setup-nctl/",component:p("/developers/dapps/setup-nctl/","bda"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/signing-a-deploy/",component:p("/developers/dapps/signing-a-deploy/","f7c"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/speculative-exec/",component:p("/developers/dapps/speculative-exec/","fac"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/technology-stack/",component:p("/developers/dapps/technology-stack/","4a2"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/template-frontend/",component:p("/developers/dapps/template-frontend/","f94"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/uref-security/",component:p("/developers/dapps/uref-security/","64d"),exact:!0,sidebar:"developers"},{path:"/developers/essential-crates/",component:p("/developers/essential-crates/","f23"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/",component:p("/developers/json-rpc/","260"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/errors/",component:p("/developers/json-rpc/errors/","eb9"),exact:!0},{path:"/developers/json-rpc/guidance/",component:p("/developers/json-rpc/guidance/","749"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/json-rpc-informational/",component:p("/developers/json-rpc/json-rpc-informational/","365"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/json-rpc-pos/",component:p("/developers/json-rpc/json-rpc-pos/","569"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/json-rpc-transactional/",component:p("/developers/json-rpc/json-rpc-transactional/","ff2"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/minimal-compliance/",component:p("/developers/json-rpc/minimal-compliance/","628"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/types_chain/",component:p("/developers/json-rpc/types_chain/","a78"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/types_cl/",component:p("/developers/json-rpc/types_cl/","cea"),exact:!0,sidebar:"developers"},{path:"/developers/prerequisites/",component:p("/developers/prerequisites/","31c"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/assembly-script/",component:p("/developers/writing-onchain-code/assembly-script/","bb2"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/best-practices/",component:p("/developers/writing-onchain-code/best-practices/","135"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/calling-contracts/",component:p("/developers/writing-onchain-code/calling-contracts/","9f8"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/contract-hash-vs-package-hash/",component:p("/developers/writing-onchain-code/contract-hash-vs-package-hash/","5a9"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/contract-vs-session/",component:p("/developers/writing-onchain-code/contract-vs-session/","8c3"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/getting-started/",component:p("/developers/writing-onchain-code/getting-started/","b25"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/simple-contract/",component:p("/developers/writing-onchain-code/simple-contract/","92e"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/testing-contracts/",component:p("/developers/writing-onchain-code/testing-contracts/","e7c"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/testing-session-code/",component:p("/developers/writing-onchain-code/testing-session-code/","948"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/upgrading-contracts/",component:p("/developers/writing-onchain-code/upgrading-contracts/","bd8"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/writing-session-code/",component:p("/developers/writing-onchain-code/writing-session-code/","d1d"),exact:!0,sidebar:"developers"},{path:"/disclaimer/",component:p("/disclaimer/","2bb"),exact:!0},{path:"/economics/",component:p("/economics/","979"),exact:!0,sidebar:"concepts"},{path:"/glossary/",component:p("/glossary/","470"),exact:!0,sidebar:"concepts"},{path:"/operators/",component:p("/operators/","a3d"),exact:!0,sidebar:"operators"},{path:"/operators/becoming-a-validator/",component:p("/operators/becoming-a-validator/","a7e"),exact:!0,sidebar:"operators"},{path:"/operators/becoming-a-validator/bonding/",component:p("/operators/becoming-a-validator/bonding/","4db"),exact:!0,sidebar:"operators"},{path:"/operators/becoming-a-validator/inactive-vs-faulty/",component:p("/operators/becoming-a-validator/inactive-vs-faulty/","ed3"),exact:!0,sidebar:"operators"},{path:"/operators/becoming-a-validator/recovering/",component:p("/operators/becoming-a-validator/recovering/","e0a"),exact:!0,sidebar:"operators"},{path:"/operators/becoming-a-validator/unbonding/",component:p("/operators/becoming-a-validator/unbonding/","77b"),exact:!0,sidebar:"operators"},{path:"/operators/maintenance/",component:p("/operators/maintenance/","288"),exact:!0,sidebar:"operators"},{path:"/operators/maintenance/archiving-and-restoring/",component:p("/operators/maintenance/archiving-and-restoring/","e07"),exact:!0,sidebar:"operators"},{path:"/operators/maintenance/moving-node/",component:p("/operators/maintenance/moving-node/","d6d"),exact:!0,sidebar:"operators"},{path:"/operators/setup-network/",component:p("/operators/setup-network/","e53"),exact:!0,sidebar:"operators"},{path:"/operators/setup-network/chain-spec/",component:p("/operators/setup-network/chain-spec/","42a"),exact:!0,sidebar:"operators"},{path:"/operators/setup-network/create-private/",component:p("/operators/setup-network/create-private/","091"),exact:!0,sidebar:"operators"},{path:"/operators/setup-network/genesis/",component:p("/operators/setup-network/genesis/","b69"),exact:!0,sidebar:"operators"},{path:"/operators/setup-network/staging-files-for-new-network/",component:p("/operators/setup-network/staging-files-for-new-network/","55c"),exact:!0,sidebar:"operators"},{path:"/operators/setup/",component:p("/operators/setup/","d17"),exact:!0,sidebar:"operators"},{path:"/operators/setup/basic-node-configuration/",component:p("/operators/setup/basic-node-configuration/","cb3"),exact:!0,sidebar:"operators"},{path:"/operators/setup/fast-sync/",component:p("/operators/setup/fast-sync/","092"),exact:!0,sidebar:"operators"},{path:"/operators/setup/hardware/",component:p("/operators/setup/hardware/","9f3"),exact:!0,sidebar:"operators"},{path:"/operators/setup/install-node/",component:p("/operators/setup/install-node/","6c3"),exact:!0,sidebar:"operators"},{path:"/operators/setup/joining/",component:p("/operators/setup/joining/","96f"),exact:!0,sidebar:"operators"},{path:"/operators/setup/node-endpoints/",component:p("/operators/setup/node-endpoints/","f3f"),exact:!0,sidebar:"operators"},{path:"/operators/setup/non-root-user/",component:p("/operators/setup/non-root-user/","277"),exact:!0,sidebar:"operators"},{path:"/operators/setup/open-files/",component:p("/operators/setup/open-files/","e18"),exact:!0,sidebar:"operators"},{path:"/operators/setup/upgrade/",component:p("/operators/setup/upgrade/","a91"),exact:!0,sidebar:"operators"},{path:"/resources/",component:p("/resources/","0b0"),exact:!0,sidebar:"resources"},{path:"/resources/advanced/list-auth-keys-tutorial/",component:p("/resources/advanced/list-auth-keys-tutorial/","a38"),exact:!0,sidebar:"resources"},{path:"/resources/advanced/multi-sig/",component:p("/resources/advanced/multi-sig/","dfb"),exact:!0,sidebar:"resources"},{path:"/resources/advanced/multi-sig/multi-sig-workflow/",component:p("/resources/advanced/multi-sig/multi-sig-workflow/","250"),exact:!0,sidebar:"resources"},{path:"/resources/advanced/multi-sig/other-scenarios/",component:p("/resources/advanced/multi-sig/other-scenarios/","15d"),exact:!0,sidebar:"resources"},{path:"/resources/beginner/counter-testnet/commands/",component:p("/resources/beginner/counter-testnet/commands/","2a1"),exact:!0,sidebar:"resources"},{path:"/resources/beginner/counter-testnet/overview/",component:p("/resources/beginner/counter-testnet/overview/","573"),exact:!0,sidebar:"resources"},{path:"/resources/beginner/counter-testnet/walkthrough/",component:p("/resources/beginner/counter-testnet/walkthrough/","6a1"),exact:!0,sidebar:"resources"},{path:"/resources/beginner/counter/commands/",component:p("/resources/beginner/counter/commands/","bfe"),exact:!0,sidebar:"resources"},{path:"/resources/beginner/counter/overview/",component:p("/resources/beginner/counter/overview/","31a"),exact:!0,sidebar:"resources"},{path:"/resources/beginner/counter/walkthrough/",component:p("/resources/beginner/counter/walkthrough/","43f"),exact:!0,sidebar:"resources"},{path:"/resources/build-on-casper/casper-open-source-software/",component:p("/resources/build-on-casper/casper-open-source-software/","8ca"),exact:!0,sidebar:"resources"},{path:"/resources/build-on-casper/introduction/",component:p("/resources/build-on-casper/introduction/","1d5"),exact:!0,sidebar:"resources"},{path:"/resources/moving-to-casper/",component:p("/resources/moving-to-casper/","bac"),exact:!0,sidebar:"resources"},{path:"/resources/quick-start/",component:p("/resources/quick-start/","8cc"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/",component:p("/resources/tokens/","9ac"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep18/full-tutorial/",component:p("/resources/tokens/cep18/full-tutorial/","c34"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep18/query/",component:p("/resources/tokens/cep18/query/","66d"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep18/quickstart-guide/",component:p("/resources/tokens/cep18/quickstart-guide/","307"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep18/tests/",component:p("/resources/tokens/cep18/tests/","486"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep18/transfer/",component:p("/resources/tokens/cep18/transfer/","0b5"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/introduction/",component:p("/resources/tokens/cep78/introduction/","a87"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/js-tutorial/",component:p("/resources/tokens/cep78/js-tutorial/","13e"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/modalities/",component:p("/resources/tokens/cep78/modalities/","d32"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/reverse-lookup/",component:p("/resources/tokens/cep78/reverse-lookup/","320"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/using-casper-client/",component:p("/resources/tokens/using-casper-client/","f9c"),exact:!0,sidebar:"resources"},{path:"/resources/tutorials/advanced/",component:p("/resources/tutorials/advanced/","dd4"),exact:!0,sidebar:"resources"},{path:"/resources/tutorials/advanced/cross-contract/",component:p("/resources/tutorials/advanced/cross-contract/","f70"),exact:!0,sidebar:"resources"},{path:"/resources/tutorials/advanced/list-cspr/",component:p("/resources/tutorials/advanced/list-cspr/","0d0"),exact:!0},{path:"/resources/tutorials/advanced/return-values-tutorial/",component:p("/resources/tutorials/advanced/return-values-tutorial/","c60"),exact:!0,sidebar:"resources"},{path:"/resources/tutorials/advanced/storage-workflow/",component:p("/resources/tutorials/advanced/storage-workflow/","0b5"),exact:!0,sidebar:"resources"},{path:"/resources/tutorials/advanced/transfer-token-to-contract/",component:p("/resources/tutorials/advanced/transfer-token-to-contract/","373"),exact:!0,sidebar:"resources"},{path:"/resources/tutorials/advanced/two-party-multi-sig/",component:p("/resources/tutorials/advanced/two-party-multi-sig/","097"),exact:!0,sidebar:"resources"},{path:"/resources/tutorials/beginner/",component:p("/resources/tutorials/beginner/","f91"),exact:!0,sidebar:"resources"},{path:"/resources/tutorials/beginner/aws-node/",component:p("/resources/tutorials/beginner/aws-node/","47a"),exact:!0,sidebar:"resources"},{path:"/resources/tutorials/beginner/cep18/",component:p("/resources/tutorials/beginner/cep18/","2b1"),exact:!0,sidebar:"resources"},{path:"/resources/tutorials/beginner/getting-started-tutorial/",component:p("/resources/tutorials/beginner/getting-started-tutorial/","530"),exact:!0,sidebar:"resources"},{path:"/resources/tutorials/beginner/querying-network/",component:p("/resources/tutorials/beginner/querying-network/","42e"),exact:!0,sidebar:"resources"},{path:"/resources/tutorials/beginner/upgrade-contract/",component:p("/resources/tutorials/beginner/upgrade-contract/","ecc"),exact:!0,sidebar:"resources"},{path:"/runtime/",component:p("/runtime/","e9a"),exact:!0,sidebar:"concepts"},{path:"/sdk/",component:p("/sdk/","808"),exact:!0,sidebar:"developers"},{path:"/staking/",component:p("/staking/","537"),exact:!0,sidebar:"concepts"},{path:"/users/",component:p("/users/","14f"),exact:!0,sidebar:"users"},{path:"/users/block-explorer/",component:p("/users/block-explorer/","b18"),exact:!0,sidebar:"users"},{path:"/users/csprlive/",component:p("/users/csprlive/","99a"),exact:!0,sidebar:"users"},{path:"/users/delegate-ui/",component:p("/users/delegate-ui/","0e9"),exact:!0,sidebar:"users"},{path:"/users/funding-from-exchanges/",component:p("/users/funding-from-exchanges/","9fd"),exact:!0,sidebar:"users"},{path:"/users/ledger/",component:p("/users/ledger/","3fd"),exact:!0,sidebar:"users"},{path:"/users/ledger/ledger-cspr-live/",component:p("/users/ledger/ledger-cspr-live/","631"),exact:!0,sidebar:"users"},{path:"/users/ledger/ledger-live/",component:p("/users/ledger/ledger-live/","497"),exact:!0,sidebar:"users"},{path:"/users/staking-ledger/",component:p("/users/staking-ledger/","31c"),exact:!0,sidebar:"users"},{path:"/users/testnet-faucet/",component:p("/users/testnet-faucet/","32e"),exact:!0,sidebar:"users"},{path:"/users/token-transfer/",component:p("/users/token-transfer/","132"),exact:!0,sidebar:"users"},{path:"/users/undelegate-ui/",component:p("/users/undelegate-ui/","474"),exact:!0,sidebar:"users"},{path:"/workflow/ledger-setup/",component:p("/workflow/ledger-setup/","247"),exact:!0,sidebar:"users"},{path:"/writing-contracts/",component:p("/writing-contracts/","06b"),exact:!0,sidebar:"developers"}]},{path:"*",component:p("*")}]},8934:function(e,t,n){"use strict";n.d(t,{_:function(){return o},t:function(){return a}});var r=n(7294),o=r.createContext(!1);function a(e){var t=e.children,n=(0,r.useState)(!1),a=n[0],i=n[1];return(0,r.useEffect)((function(){i(!0)}),[]),r.createElement(o.Provider,{value:a},t)}},9383:function(e,t,n){"use strict";var r=n(7294),o=n(3935),a=n(3727),i=n(405),s=n(412),c=[n(6657),n(2497),n(3310),n(8320),n(6445)],l=n(723),u=n(6550),d=n(8790);function p(e){var t=e.children;return r.createElement(r.Fragment,null,t)}var f=n(7462),m=n(5742),h=n(2263),g=n(4996),v=n(6668),b=n(833),y=n(4711),w=n(9727),k=n(3320),_=n(197);function E(){var e=(0,h.Z)().i18n,t=e.defaultLocale,n=e.localeConfigs,o=(0,y.l)();return r.createElement(m.Z,null,Object.entries(n).map((function(e){var t=e[0],n=e[1].htmlLang;return r.createElement("link",{key:t,rel:"alternate",href:o.createUrl({locale:t,fullyQualified:!0}),hrefLang:n})})),r.createElement("link",{rel:"alternate",href:o.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}))}function C(e){var t=e.permalink,n=(0,h.Z)().siteConfig.url,o=function(){var e=(0,h.Z)().siteConfig.url,t=(0,u.TH)().pathname;return e+(0,g.Z)(t)}(),a=t?""+n+t:o;return r.createElement(m.Z,null,r.createElement("meta",{property:"og:url",content:a}),r.createElement("link",{rel:"canonical",href:a}))}function x(){var e=(0,h.Z)().i18n.currentLocale,t=(0,v.L)(),n=t.metadata,o=t.image;return r.createElement(r.Fragment,null,r.createElement(m.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),o&&r.createElement(b.d,{image:o}),r.createElement(C,null),r.createElement(E,null),r.createElement(_.Z,{tag:k.HX,locale:e}),r.createElement(m.Z,null,n.map((function(e,t){return r.createElement("meta",(0,f.Z)({key:t},e))}))))}var S=new Map;function T(e){if(S.has(e.pathname))return Object.assign({},e,{pathname:S.get(e.pathname)});if((0,d.f)(l.Z,e.pathname).some((function(e){return!0===e.route.exact})))return S.set(e.pathname,e.pathname),e;var t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return S.set(e.pathname,t),Object.assign({},e,{pathname:t})}var N=n(8934),L=n(8940),A=n(4578);function O(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = '+e+" "+("/"===e?" (default value)":"")+'

\n

We suggest trying baseUrl =

\n\n'}(e)).replace(/\\r\\n\\r\\n\\r\\n"},{"name":"Telegram","url":"https://t.me/casperblockchain","iconId":"f67b2fe0-fde1-4371-940a-9acc7da00f2d","icon":"\\r\\n\\r\\n\\r\\n"},{"name":"Linkedin","url":"https://www.linkedin.com/company/casper-association/","iconId":"0cf3d428-0682-4382-904d-4a5e18ae694c","icon":"\\n\\n\\n"},{"name":"Twitter","url":"https://twitter.com/Casper_Network","iconId":"017ea5c5-741e-4b5a-91fb-d5f439946b97","icon":"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"},{"name":"YouTube","url":"https://www.youtube.com/c/CasperNetwork","iconId":"615848bb-0505-4278-8b84-c8e29ebf6f15","icon":"\\n\\n\\n"},{"name":"Github","url":"https://github.com/casper-network","iconId":"f5b7b421-38b9-44d8-af76-831a900b3538","icon":"\\r\\n\\r\\n\\r\\n"},{"name":"Newsletter","url":"https://developer.casper.network/newsletter","iconId":"1a0bfb41-c992-4850-896a-8c7231128d97","icon":""}],"footerData":[{"languageCode":"en-us","logoId":"c36a9c08-16d2-49b2-9c1c-e465e12e349a","title":"Join our Community","description":null,"logo":"","bottomLinks":[{"title":"Terms of Use","type":"internal","url":"/terms-of-use","children":[],"openInNewTab":true},{"title":"Privacy Policy","type":"internal","url":"/privacy-policy","children":[],"openInNewTab":false},{"title":"Legal Disclaimer","type":"external","url":"https://docs.casper.network/disclaimer/","children":[],"openInNewTab":false}],"columns":[],"manage_cookies_text":"Manage Cookies"}],"navTree":[{"languages_code":{"code":"en-US"},"login_text":"Log In","search_placeholder":"Search Portal","logo":"","navigation_tree":{"items":[{"id":"f28f74f3-5286-4146-9d45-e81b700e9f9c","url":"","title":"Learn","children":[{"id":"c914c832-9ac6-415c-b422-76284d45b701","url":"","title":"Learning Resources","children":[{"id":"d17e1fda-82f2-44e6-beb7-b044350a9409","url":"/about-casper","title":"About Casper","children":[{"id":"f3eeac76-19a9-4ce8-8cd6-d970fc2fa3df","url":"/macro-trends-for-casper","title":"Macro trends for Casper","children":[],"isColumn":false,"link_type":"internal","external_link":false,"open_in_new_tab":false},{"id":"09b52cdf-1252-48fe-a21f-c340e1942c33","url":"https://docs.casper.network/resources/build-on-casper/introduction/","title":"Why Build On Casper","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":false},{"id":"98417826-0632-4275-8d57-de99c5aba3d7","url":"https://casper.network/en-us/casper","title":"The Casper Network","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true}],"isColumn":false,"link_type":"internal","external_link":false,"open_in_new_tab":false},{"id":"153616eb-e8c8-4b1a-bb06-86324bceefec","url":"https://docs.casper.network/concepts/","title":"Casper Concepts","children":[],"isColumn":false,"link_type":"external","external_link":true,"open_in_new_tab":false},{"id":"1ef75755-63bc-45a7-b269-e179111da531","url":"/overview","title":"Portal Overview","children":[{"id":"f5ca7855-c646-4ee0-9b17-8af66db919d6","url":"/portal-roadmap","title":"Portal Roadmap","children":[],"isColumn":false,"link_type":"internal","open_in_new_tab":false}],"isColumn":false,"link_type":"internal","open_in_new_tab":false}],"isColumn":true,"external_link":false,"open_in_new_tab":false},{"id":"ed13df3b-1600-4c63-a7bb-5e441067bbaa","url":"","title":"Learning tools","children":[{"id":"cec50b44-4cb1-47c9-9db5-491b823b7206","url":"https://docs.casper.network/","title":"Documentation","children":[],"isColumn":false,"link_type":"external","external_link":true,"open_in_new_tab":false},{"id":"d123c2ff-305f-4de8-ae80-23837809b7f8","url":"https://docs.casper.network/developers/prerequisites/","title":"Development Prerequisites","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":false},{"id":"87e8af66-1d31-49ce-85c3-69bb7e2d1bd7","url":"https://docs.casper.network/developers/writing-onchain-code/getting-started/","title":"Getting Started With Rust","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":false}],"isColumn":true,"external_link":false,"open_in_new_tab":false}],"isColumn":false,"external_link":false,"open_in_new_tab":false},{"id":"36c38af5-8fab-458d-ab93-5a8f70dcac55","url":"","title":"Build","children":[{"id":"d4ea490a-4a73-40b1-ab1e-5f6f86b7a198","url":"","title":"Builder Resources","children":[{"id":"ca23651b-7044-4573-9bfc-3d92a2f4b900","url":"https://docs.casper.network/resources/tutorials/beginner/","title":"Tutorials","children":[],"isColumn":false,"link_type":"external","external_link":true,"open_in_new_tab":false},{"id":"0d780f74-f9cd-41cb-9837-789afa6e1788","url":"https://docs.casper.network/resources/quick-start/","title":"Quickstart Guide","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":false},{"id":"e382f760-cf2f-4610-80b7-90f301f3e32c","url":"https://docs.casper.network/resources/build-on-casper/casper-open-source-software/","title":"Ecosystem Open-Source Software","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":false},{"id":"5802e26e-2f6f-4f33-97c0-6a0d752d4c08","url":"https://support.casperlabs.io/hc/en-gb","title":"Support","children":[],"isColumn":false,"link_type":"external","external_link":true,"open_in_new_tab":true}],"isColumn":true,"external_link":false,"open_in_new_tab":false},{"id":"42f4fa70-be10-4080-be14-87ebad2ad9da","url":"","title":"Builder Tools","children":[{"id":"783f6be3-f54a-4365-8107-ab7582752d62","url":"https://docs.casper.network/sdk/","title":"SDK Client Libraries","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":false},{"id":"8742dce4-8f93-4597-be2a-27380d252392","url":"https://docs.casper.network/developers/json-rpc/","title":"JSON-RPC API","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":false}],"isColumn":true,"link_type":"internal","open_in_new_tab":false}],"isColumn":false,"external_link":false,"open_in_new_tab":false},{"id":"2d013e3f-856c-40a4-9372-ba1b290437f2","url":"","title":"Blockchain","children":[{"id":"437bd889-31da-4d61-8a30-74c5de9ac7d0","url":"","title":"Blockchain Resources","children":[{"id":"bac27077-6919-4285-8155-9114b4733da8","url":"https://docs.casper.network/operators/setup/","title":"Set Up a Casper Node","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":false},{"id":"4626ad02-8b92-4dda-b3fb-6fef40b71959","url":"https://docs.casper.network/operators/becoming-a-validator/","title":"Become a Validator","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":false},{"id":"936cacbd-d4b3-407a-9e95-c5530d52ecb0","url":"https://docs.casper.network/operators/setup-network/","title":"Setting up a Private Network","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":false}],"isColumn":true,"link_type":"internal","open_in_new_tab":false},{"id":"4fe23eb8-f68f-4862-ad7d-d5e625e6c76b","url":null,"title":"Block Explorers","children":[{"id":"874ecfe8-3965-41e8-ae0a-4d6bac96d7fc","url":"https://cspr.live/","title":"cspr.live","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true},{"id":"bcdd804c-723d-4675-b5fb-3c4df4933fc3","url":"https://casper-trench.vercel.app/","title":"cspr.info","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true}],"isColumn":true,"link_type":"external","open_in_new_tab":false},{"id":"036e28fe-0866-4a10-b60b-3f7c95da46e0","url":null,"title":"Wallets","children":[{"id":"a159c7ea-afa0-4041-a8e3-1ff9786a7ef3","url":"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?support=true","title":"Ledger","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true},{"id":"9d906be4-0392-4d04-81bd-44b6b75846bf","url":"https://casper.tor.us/","title":"Tor.us","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true},{"id":"88d18f1c-87e9-42c1-b168-6f3d750203be","url":"https://www.casperwallet.io/","title":"Casper Wallet","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true},{"id":"355e4465-3983-41ac-8193-277151ab9be0","url":"https://casperdash.io/","title":"CasperDash","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true}],"isColumn":true,"link_type":"external","open_in_new_tab":false},{"id":"6b705d25-d8bb-4c1e-af6c-860f2e392d55","url":null,"title":"Tools","children":[{"id":"668bd760-3f1e-49b5-9db6-b213639655e5","url":"https://nownodes.io/nodes/casper-cspr","title":"NOWNodes","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true},{"id":"e5e8218a-daf0-402f-b126-0bb3fac5b66e","url":"https://casperholders.io/","title":"Casper Holders","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true}],"isColumn":true,"link_type":"external","open_in_new_tab":false}],"isColumn":false,"link_type":"internal","open_in_new_tab":false},{"id":"aaa36ff9-35b1-40f1-9e6a-fbb1975418da","url":"","title":"Community","children":[{"id":"8b2d140a-68da-4413-a437-e56305b585ab","url":"https://casperholders.io/","title":"Community Links","children":[{"id":"c26510b9-39a1-48ac-b644-4df2a2760d13","url":"https://casper.network/","title":"Casper Association","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true},{"id":"b742d75b-fab7-4c8d-934d-d2c787313848","url":"https://www.casperlabs.io/","title":"Casper Labs","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true}],"isColumn":true,"link_type":"external","open_in_new_tab":false},{"id":"68aff598-da66-4178-889b-928f251ecc8b","url":null,"title":"Community Latest","children":[{"id":"22a4b6d6-936c-49fa-b4f8-3afb85e763df","url":"https://medium.com/casperblockchain","title":"Dev Blog","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true},{"id":"565066c4-f4ef-4c53-afa2-271f529904d2","url":"https://casper.network/en-us/lp/accelerate-grant-program","title":"Grants","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true},{"id":"3e925a6d-e293-4b31-91b5-efd87404b46f","url":"https://www.meetup.com/casper-network/","title":"Dev Events","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true},{"id":"0cd44593-5503-4af5-9ca3-a7f3fd828d70","url":"/community","title":"Community Guidelines","children":[],"isColumn":false,"link_type":"internal","open_in_new_tab":false}],"isColumn":true,"link_type":"external","open_in_new_tab":false}],"isColumn":false,"link_type":"internal","open_in_new_tab":false},{"id":"18620319-6aa7-4ecc-aa4f-4608ad856d4d","url":"","title":"Catalyst","children":[{"id":"17d2f129-e56e-4546-9c75-24f62158274c","url":null,"title":"Catalyst Links","children":[{"id":"ceb6598b-744c-4ff6-a311-3048161369a3","url":"https://casper.network/en-us/lp/accelerate-grant-program","title":"Grants","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true},{"id":"25811fc2-e3c7-40bf-bd5b-d63c95f58ee4","url":"/dev-rewards","title":"Dev Rewards","children":[],"isColumn":false,"link_type":"internal","open_in_new_tab":false}],"isColumn":true,"link_type":"internal","open_in_new_tab":false}],"isColumn":false,"link_type":"internal","open_in_new_tab":false}]}}],"footerTree":[{"title":null,"description":null,"manage_cookies_text":null,"logo":null,"bottom_links":[],"languages_code":{"code":"es-ES"},"footer_tree":null},{"title":"Join our Community","description":null,"manage_cookies_text":"Manage Cookies","logo":{"id":"c36a9c08-16d2-49b2-9c1c-e465e12e349a","title":"Casper Wordmark White"},"bottom_links":[{"link_id":{"title":"Terms of Use","type":"internal","url":"/terms-of-use","open_in_new_tab":true}},{"link_id":{"title":"Privacy Policy","type":"internal","url":"/privacy-policy","open_in_new_tab":null}},{"link_id":{"title":"Legal Disclaimer","type":"external","url":"https://docs.casper.network/disclaimer/","open_in_new_tab":null}}],"languages_code":{"code":"en-US"},"footer_tree":{"items":[{"id":"a345bd65-fc86-45c1-bfea-c51bc9310fb5","url":"","title":"Resources","children":[{"id":"5d22fcdf-a0a8-427b-8cd2-5aa1097ca935","url":"about-casper","title":"About Casper","children":[],"isColumn":false,"link_type":"internal","open_in_new_tab":false},{"id":"fa6bfb9e-53cd-48eb-b4f4-97937cabf2ab","url":"https://staging.docs.casper.network/","title":"Documentation","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":false},{"id":"2b89e467-2baa-4e79-afeb-a288cd004d54","url":"https://staging.docs.casper.network/resources/quick-start/","title":"Getting started tutorial","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":false},{"id":"8b806b36-9bda-46c1-83b3-9dffd3874449","url":"https://casper.network/en-us/lp/ecosystem/","title":"Casper Ecosystem","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true},{"id":"3003f82a-4d5c-4f5c-8bf3-374e13789d9a","url":"https://support.casperlabs.io/hc/en-gb","title":"Support","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true}],"isColumn":true,"link_type":"internal","open_in_new_tab":false},{"id":"a7baeeb2-5b18-4851-90b0-34b328128885","url":"","title":"Casper Community","children":[{"id":"78cd747d-fcc0-42e0-9a29-0c27c9d150dc","url":"https://casper.network/en-us/","title":"Casper Assocciation","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true},{"id":"0aa01371-b7ea-4f11-8455-721b12acf839","url":"https://www.casperlabs.io/","title":"Casper Labs","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true},{"id":"5372cd5e-fc0a-44c4-ab79-d2a7af3c192c","url":"https://medium.com/casperblockchain","title":"Dev Blog","children":[],"isColumn":false,"link_type":"external","open_in_new_tab":true}],"isColumn":true,"link_type":"internal","open_in_new_tab":false}]}}]}},"docusaurus-plugin-cookiesbanner":{"default":{"cookieData":[{"languageCode":"en-us","manage_body":"

Because we respect your right to privacy, you can choose not to allow some types of cookies. Find out more about each category below and change our default settings as you choose. Keep in mind that blocking some types of cookies may impact our ability to deliver and improve our services. When you\'re ready, click on \\"Confirm My Choices\\" and remember, you can always change your mind later. If you want to learn more about cookies and why we use them, visit our Privacy Policy.

","manage_title":"We care about your privacy","notice_body":"

We use cookies to customize and improve the content shown to you, making sure you get the best online experience. By clicking \\"Allow All\\", we can continue to deliver an ideal web experience. If you prefer, you can choose to continue with \\"Manage Cookies\\", but keep in mind that blocking some types of cookies may impact our ability to show content. If you want to learn more about cookies and why we use them, visit our Privacy Policy page. You may review and change your choices at any time. 

","notice_title":"Before you start","manage_button_text":"Manage Cookies","accept_all_button_text":"Allow All","confirm_button_text":"Confirm Choices","items":[{"required":true,"parameter":"necessary","title":"Necessary Cookies","description":"

These cookies are necessary to maintain our services and cannot be switched off. They are usually only set in response to actions made by you. You can set your browser to block or alert you about these cookies, but that can make some parts of the site not work. These cookies do not store any personally identifiable information.

"},{"required":false,"parameter":"performance","title":"Performance Cookies","description":"

These cookies allow us to count visits and traffic so we can collect insights like which pages are the most popular and see how visitors move around the site. All information these cookies collect is aggregated and therefore, anonymous. If you do not allow these cookies, we will not be able to provide you with a tailored experience.

"},{"required":false,"parameter":"functional","title":"Functional Cookies","description":"

These cookies enable the website to provide enhanced functionality and personalization. They may be set by us or by third-party providers whose services we have added to our pages. If you do not allow these cookies, some or all of these services may not function properly.

"},{"required":false,"parameter":"marketing","title":"Marketing Cookies","description":"

When you accept marketing cookies, you give us your consent to place cookies on your device to provide you with relevant content that fits your interests. These cookies may be set through our site by our advertising partners or by us to build a profile of your interests and show you relevant content. To deliver content that fits your interests on our site, we will use your interactions together with the personal information you have provided to us. To present you with relevant content on third-party sites, we will share this information and a customer identifier such as an encrypted email address or device ID with third parties, such as advertising platforms and social networks. To make the content as interesting as possible, we may link this data across the different devices you use. If you choose not to accept marketing cookies, we will not place such cookies on your device and you may experience less relevant content from us.

"}]}]}},"docusaurus-plugin-google-tag-manager":{"default":{"containerId":"GTM-MD4L5VM","id":"default"}},"docusaurus-plugin-content-docs":{"default":{"path":"/","versions":[{"name":"current","label":"Next","isLast":true,"path":"/","mainDocId":"concepts/about","docs":[{"id":"concepts/about","path":"/","sidebar":"concepts"},{"id":"concepts/accounts-and-keys","path":"/concepts/accounts-and-keys","sidebar":"concepts"},{"id":"concepts/callstack","path":"/concepts/callstack","sidebar":"concepts"},{"id":"concepts/deploy-and-deploy-lifecycle","path":"/deploy-and-deploy-lifecycle","sidebar":"concepts"},{"id":"concepts/design/casper-design","path":"/concepts/design/casper-design","sidebar":"concepts"},{"id":"concepts/design/highway","path":"/concepts/design/highway","sidebar":"concepts"},{"id":"concepts/design/index","path":"/design","sidebar":"concepts"},{"id":"concepts/design/networking-protocol","path":"/concepts/design/networking-protocol"},{"id":"concepts/design/p2p","path":"/concepts/design/p2p","sidebar":"concepts"},{"id":"concepts/design/reading-and-writing-to-the-blockchain","path":"/concepts/design/reading-and-writing-to-the-blockchain","sidebar":"concepts"},{"id":"concepts/dictionaries","path":"/concepts/dictionaries","sidebar":"concepts"},{"id":"concepts/economics/consensus","path":"/concepts/economics/consensus","sidebar":"concepts"},{"id":"concepts/economics/gas-concepts","path":"/concepts/economics/gas-concepts","sidebar":"concepts"},{"id":"concepts/economics/index","path":"/economics","sidebar":"concepts"},{"id":"concepts/economics/runtime","path":"/runtime","sidebar":"concepts"},{"id":"concepts/economics/staking/concepts","path":"/concepts/economics/concepts","sidebar":"concepts"},{"id":"concepts/economics/staking/delegation","path":"/concepts/economics/delegation","sidebar":"concepts"},{"id":"concepts/economics/staking/staking","path":"/staking","sidebar":"concepts"},{"id":"concepts/global-state","path":"/concepts/global-state","sidebar":"concepts"},{"id":"concepts/glossary/A","path":"/concepts/glossary/A","sidebar":"concepts"},{"id":"concepts/glossary/B","path":"/concepts/glossary/B","sidebar":"concepts"},{"id":"concepts/glossary/C","path":"/concepts/glossary/C","sidebar":"concepts"},{"id":"concepts/glossary/D","path":"/concepts/glossary/D","sidebar":"concepts"},{"id":"concepts/glossary/E","path":"/concepts/glossary/E","sidebar":"concepts"},{"id":"concepts/glossary/F","path":"/concepts/glossary/F","sidebar":"concepts"},{"id":"concepts/glossary/G","path":"/concepts/glossary/G","sidebar":"concepts"},{"id":"concepts/glossary/H","path":"/concepts/glossary/H","sidebar":"concepts"},{"id":"concepts/glossary/I","path":"/concepts/glossary/I","sidebar":"concepts"},{"id":"concepts/glossary/index","path":"/glossary","sidebar":"concepts"},{"id":"concepts/glossary/J","path":"/concepts/glossary/J","sidebar":"concepts"},{"id":"concepts/glossary/K","path":"/concepts/glossary/K","sidebar":"concepts"},{"id":"concepts/glossary/L","path":"/concepts/glossary/L","sidebar":"concepts"},{"id":"concepts/glossary/M","path":"/concepts/glossary/M","sidebar":"concepts"},{"id":"concepts/glossary/N","path":"/concepts/glossary/N","sidebar":"concepts"},{"id":"concepts/glossary/O","path":"/concepts/glossary/O","sidebar":"concepts"},{"id":"concepts/glossary/P","path":"/concepts/glossary/P","sidebar":"concepts"},{"id":"concepts/glossary/Q","path":"/concepts/glossary/Q","sidebar":"concepts"},{"id":"concepts/glossary/R","path":"/concepts/glossary/R","sidebar":"concepts"},{"id":"concepts/glossary/S","path":"/concepts/glossary/S","sidebar":"concepts"},{"id":"concepts/glossary/T","path":"/concepts/glossary/T","sidebar":"concepts"},{"id":"concepts/glossary/U","path":"/concepts/glossary/U","sidebar":"concepts"},{"id":"concepts/glossary/V","path":"/concepts/glossary/V","sidebar":"concepts"},{"id":"concepts/glossary/W","path":"/concepts/glossary/W","sidebar":"concepts"},{"id":"concepts/glossary/X","path":"/concepts/glossary/X","sidebar":"concepts"},{"id":"concepts/glossary/Y","path":"/concepts/glossary/Y","sidebar":"concepts"},{"id":"concepts/glossary/Z","path":"/concepts/glossary/Z","sidebar":"concepts"},{"id":"concepts/hash-types","path":"/concepts/hash-types","sidebar":"concepts"},{"id":"concepts/index","path":"/concepts/","sidebar":"concepts"},{"id":"concepts/intro-to-dapps","path":"/concepts/intro-to-dapps","sidebar":"concepts"},{"id":"concepts/list-auth-keys","path":"/concepts/list-auth-keys","sidebar":"concepts"},{"id":"concepts/serialization-standard","path":"/concepts/serialization-standard","sidebar":"concepts"},{"id":"concepts/smart-contracts","path":"/concepts/smart-contracts","sidebar":"concepts"},{"id":"developers/cli/calling-contracts","path":"/developers/cli/calling-contracts","sidebar":"developers"},{"id":"developers/cli/delegate","path":"/developers/cli/delegate","sidebar":"developers"},{"id":"developers/cli/execution-error-codes","path":"/developers/cli/execution-error-codes","sidebar":"developers"},{"id":"developers/cli/index","path":"/developers/cli/","sidebar":"developers"},{"id":"developers/cli/installing-contracts","path":"/developers/cli/installing-contracts","sidebar":"developers"},{"id":"developers/cli/opcode-costs","path":"/developers/cli/opcode-costs","sidebar":"developers"},{"id":"developers/cli/querying-global-state","path":"/developers/cli/querying-global-state","sidebar":"developers"},{"id":"developers/cli/redelegate","path":"/developers/cli/redelegate","sidebar":"developers"},{"id":"developers/cli/sending-deploys","path":"/developers/cli/sending-deploys","sidebar":"developers"},{"id":"developers/cli/transfers/direct-token-transfer","path":"/developers/cli/transfers/direct-token-transfer","sidebar":"developers"},{"id":"developers/cli/transfers/index","path":"/developers/cli/transfers/","sidebar":"developers"},{"id":"developers/cli/transfers/multisig-deploy-transfer","path":"/developers/cli/transfers/multisig-deploy-transfer","sidebar":"developers"},{"id":"developers/cli/transfers/verify-transfer","path":"/developers/cli/transfers/verify-transfer","sidebar":"developers"},{"id":"developers/cli/undelegate","path":"/developers/cli/undelegate","sidebar":"developers"},{"id":"developers/dapps/dapp","path":"/developers/dapps/dapp","sidebar":"developers"},{"id":"developers/dapps/index","path":"/developers/dapps/","sidebar":"developers"},{"id":"developers/dapps/monitor-and-consume-events","path":"/developers/dapps/monitor-and-consume-events","sidebar":"developers"},{"id":"developers/dapps/nctl-test","path":"/developers/dapps/nctl-test","sidebar":"developers"},{"id":"developers/dapps/prerequisites","path":"/developers/dapps/prerequisites","sidebar":"developers"},{"id":"developers/dapps/sdk/client-library-usage","path":"/developers/dapps/sdk/client-library-usage","sidebar":"developers"},{"id":"developers/dapps/sdk/csharp-sdk","path":"/developers/dapps/sdk/csharp-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/go-sdk","path":"/developers/dapps/sdk/go-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/index","path":"/sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/python-sdk","path":"/developers/dapps/sdk/python-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/script-sdk","path":"/developers/dapps/sdk/script-sdk","sidebar":"developers"},{"id":"developers/dapps/setup-nctl","path":"/developers/dapps/setup-nctl","sidebar":"developers"},{"id":"developers/dapps/signing-a-deploy","path":"/developers/dapps/signing-a-deploy","sidebar":"developers"},{"id":"developers/dapps/speculative-exec","path":"/developers/dapps/speculative-exec","sidebar":"developers"},{"id":"developers/dapps/technology-stack","path":"/developers/dapps/technology-stack","sidebar":"developers"},{"id":"developers/dapps/template-frontend","path":"/developers/dapps/template-frontend","sidebar":"developers"},{"id":"developers/dapps/uref-security","path":"/developers/dapps/uref-security","sidebar":"developers"},{"id":"developers/essential-crates","path":"/developers/essential-crates","sidebar":"developers"},{"id":"developers/index","path":"/developers","sidebar":"developers"},{"id":"developers/json-rpc/errors","path":"/developers/json-rpc/errors"},{"id":"developers/json-rpc/guidance","path":"/developers/json-rpc/guidance","sidebar":"developers"},{"id":"developers/json-rpc/index","path":"/developers/json-rpc/","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-informational","path":"/developers/json-rpc/json-rpc-informational","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-pos","path":"/developers/json-rpc/json-rpc-pos","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-transactional","path":"/developers/json-rpc/json-rpc-transactional","sidebar":"developers"},{"id":"developers/json-rpc/minimal-compliance","path":"/developers/json-rpc/minimal-compliance","sidebar":"developers"},{"id":"developers/json-rpc/types_chain","path":"/developers/json-rpc/types_chain","sidebar":"developers"},{"id":"developers/json-rpc/types_cl","path":"/developers/json-rpc/types_cl","sidebar":"developers"},{"id":"developers/prerequisites","path":"/developers/prerequisites","sidebar":"developers"},{"id":"developers/writing-onchain-code/assembly-script","path":"/developers/writing-onchain-code/assembly-script","sidebar":"developers"},{"id":"developers/writing-onchain-code/best-practices","path":"/developers/writing-onchain-code/best-practices","sidebar":"developers"},{"id":"developers/writing-onchain-code/calling-contracts","path":"/developers/writing-onchain-code/calling-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/contract-hash-vs-package-hash","path":"/developers/writing-onchain-code/contract-hash-vs-package-hash","sidebar":"developers"},{"id":"developers/writing-onchain-code/contract-vs-session","path":"/developers/writing-onchain-code/contract-vs-session","sidebar":"developers"},{"id":"developers/writing-onchain-code/getting-started","path":"/developers/writing-onchain-code/getting-started","sidebar":"developers"},{"id":"developers/writing-onchain-code/index","path":"/writing-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/simple-contract","path":"/developers/writing-onchain-code/simple-contract","sidebar":"developers"},{"id":"developers/writing-onchain-code/testing-contracts","path":"/developers/writing-onchain-code/testing-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/testing-session-code","path":"/developers/writing-onchain-code/testing-session-code","sidebar":"developers"},{"id":"developers/writing-onchain-code/upgrading-contracts","path":"/developers/writing-onchain-code/upgrading-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/writing-session-code","path":"/developers/writing-onchain-code/writing-session-code","sidebar":"developers"},{"id":"disclaimer","path":"/disclaimer"},{"id":"operators/becoming-a-validator/bonding","path":"/operators/becoming-a-validator/bonding","sidebar":"operators"},{"id":"operators/becoming-a-validator/inactive-vs-faulty","path":"/operators/becoming-a-validator/inactive-vs-faulty","sidebar":"operators"},{"id":"operators/becoming-a-validator/index","path":"/operators/becoming-a-validator/","sidebar":"operators"},{"id":"operators/becoming-a-validator/recovering","path":"/operators/becoming-a-validator/recovering","sidebar":"operators"},{"id":"operators/becoming-a-validator/unbonding","path":"/operators/becoming-a-validator/unbonding","sidebar":"operators"},{"id":"operators/index","path":"/operators","sidebar":"operators"},{"id":"operators/maintenance/archiving-and-restoring","path":"/operators/maintenance/archiving-and-restoring","sidebar":"operators"},{"id":"operators/maintenance/index","path":"/operators/maintenance/","sidebar":"operators"},{"id":"operators/maintenance/moving-node","path":"/operators/maintenance/moving-node","sidebar":"operators"},{"id":"operators/setup-network/chain-spec","path":"/operators/setup-network/chain-spec","sidebar":"operators"},{"id":"operators/setup-network/create-private","path":"/operators/setup-network/create-private","sidebar":"operators"},{"id":"operators/setup-network/genesis","path":"/operators/setup-network/genesis","sidebar":"operators"},{"id":"operators/setup-network/index","path":"/operators/setup-network/","sidebar":"operators"},{"id":"operators/setup-network/staging-files-for-new-network","path":"/operators/setup-network/staging-files-for-new-network","sidebar":"operators"},{"id":"operators/setup/basic-node-configuration","path":"/operators/setup/basic-node-configuration","sidebar":"operators"},{"id":"operators/setup/fast-sync","path":"/operators/setup/fast-sync","sidebar":"operators"},{"id":"operators/setup/hardware","path":"/operators/setup/hardware","sidebar":"operators"},{"id":"operators/setup/index","path":"/operators/setup/","sidebar":"operators"},{"id":"operators/setup/install-node","path":"/operators/setup/install-node","sidebar":"operators"},{"id":"operators/setup/joining","path":"/operators/setup/joining","sidebar":"operators"},{"id":"operators/setup/node-endpoints","path":"/operators/setup/node-endpoints","sidebar":"operators"},{"id":"operators/setup/non-root-user","path":"/operators/setup/non-root-user","sidebar":"operators"},{"id":"operators/setup/open-files","path":"/operators/setup/open-files","sidebar":"operators"},{"id":"operators/setup/upgrade","path":"/operators/setup/upgrade","sidebar":"operators"},{"id":"resources/advanced/cross-contract","path":"/resources/tutorials/advanced/cross-contract","sidebar":"resources"},{"id":"resources/advanced/index","path":"/resources/tutorials/advanced/","sidebar":"resources"},{"id":"resources/advanced/list-auth-keys-tutorial","path":"/resources/advanced/list-auth-keys-tutorial","sidebar":"resources"},{"id":"resources/advanced/list-cspr","path":"/resources/tutorials/advanced/list-cspr"},{"id":"resources/advanced/multi-sig/index","path":"/resources/advanced/multi-sig/","sidebar":"resources"},{"id":"resources/advanced/multi-sig/multi-sig-workflow","path":"/resources/advanced/multi-sig/multi-sig-workflow","sidebar":"resources"},{"id":"resources/advanced/multi-sig/other-scenarios","path":"/resources/advanced/multi-sig/other-scenarios","sidebar":"resources"},{"id":"resources/advanced/return-values-tutorial","path":"/resources/tutorials/advanced/return-values-tutorial","sidebar":"resources"},{"id":"resources/advanced/storage-workflow","path":"/resources/tutorials/advanced/storage-workflow","sidebar":"resources"},{"id":"resources/advanced/transfer-token-to-contract","path":"/resources/tutorials/advanced/transfer-token-to-contract","sidebar":"resources"},{"id":"resources/advanced/two-party-multi-sig","path":"/resources/tutorials/advanced/two-party-multi-sig","sidebar":"resources"},{"id":"resources/beginner/aws-node","path":"/resources/tutorials/beginner/aws-node","sidebar":"resources"},{"id":"resources/beginner/cep18","path":"/resources/tutorials/beginner/cep18","sidebar":"resources"},{"id":"resources/beginner/counter-testnet/commands","path":"/resources/beginner/counter-testnet/commands","sidebar":"resources"},{"id":"resources/beginner/counter-testnet/index","path":"/counter-testnet","sidebar":"resources"},{"id":"resources/beginner/counter-testnet/overview","path":"/resources/beginner/counter-testnet/overview","sidebar":"resources"},{"id":"resources/beginner/counter-testnet/walkthrough","path":"/resources/beginner/counter-testnet/walkthrough","sidebar":"resources"},{"id":"resources/beginner/counter/commands","path":"/resources/beginner/counter/commands","sidebar":"resources"},{"id":"resources/beginner/counter/index","path":"/counter","sidebar":"resources"},{"id":"resources/beginner/counter/overview","path":"/resources/beginner/counter/overview","sidebar":"resources"},{"id":"resources/beginner/counter/walkthrough","path":"/resources/beginner/counter/walkthrough","sidebar":"resources"},{"id":"resources/beginner/getting-started-tutorial","path":"/resources/tutorials/beginner/getting-started-tutorial","sidebar":"resources"},{"id":"resources/beginner/index","path":"/resources/tutorials/beginner/","sidebar":"resources"},{"id":"resources/beginner/querying-network","path":"/resources/tutorials/beginner/querying-network","sidebar":"resources"},{"id":"resources/beginner/upgrade-contract","path":"/resources/tutorials/beginner/upgrade-contract","sidebar":"resources"},{"id":"resources/build-on-casper","path":"/resources/build-on-casper/introduction","sidebar":"resources"},{"id":"resources/casper-open-source-software","path":"/resources/build-on-casper/casper-open-source-software","sidebar":"resources"},{"id":"resources/index","path":"/resources/","sidebar":"resources"},{"id":"resources/moving-to-casper","path":"/resources/moving-to-casper","sidebar":"resources"},{"id":"resources/quick-start","path":"/resources/quick-start","sidebar":"resources"},{"id":"resources/tokens/cep18/full-tutorial","path":"/resources/tokens/cep18/full-tutorial","sidebar":"resources"},{"id":"resources/tokens/cep18/query","path":"/resources/tokens/cep18/query","sidebar":"resources"},{"id":"resources/tokens/cep18/quickstart-guide","path":"/resources/tokens/cep18/quickstart-guide","sidebar":"resources"},{"id":"resources/tokens/cep18/tests","path":"/resources/tokens/cep18/tests","sidebar":"resources"},{"id":"resources/tokens/cep18/transfer","path":"/resources/tokens/cep18/transfer","sidebar":"resources"},{"id":"resources/tokens/cep78/introduction","path":"/resources/tokens/cep78/introduction","sidebar":"resources"},{"id":"resources/tokens/cep78/js-tutorial","path":"/resources/tokens/cep78/js-tutorial","sidebar":"resources"},{"id":"resources/tokens/cep78/modalities","path":"/resources/tokens/cep78/modalities","sidebar":"resources"},{"id":"resources/tokens/cep78/reverse-lookup","path":"/resources/tokens/cep78/reverse-lookup","sidebar":"resources"},{"id":"resources/tokens/cep78/using-casper-client","path":"/resources/tokens/using-casper-client","sidebar":"resources"},{"id":"resources/tokens/index","path":"/resources/tokens/","sidebar":"resources"},{"id":"users/block-explorer","path":"/users/block-explorer","sidebar":"users"},{"id":"users/csprlive/delegate-ui","path":"/users/delegate-ui","sidebar":"users"},{"id":"users/csprlive/index","path":"/users/csprlive/","sidebar":"users"},{"id":"users/csprlive/testnet-faucet","path":"/users/testnet-faucet","sidebar":"users"},{"id":"users/csprlive/token-transfer","path":"/users/token-transfer","sidebar":"users"},{"id":"users/csprlive/undelegate-ui","path":"/users/undelegate-ui","sidebar":"users"},{"id":"users/funding-from-exchanges","path":"/users/funding-from-exchanges","sidebar":"users"},{"id":"users/index","path":"/users/","sidebar":"users"},{"id":"users/ledger/index","path":"/users/ledger/","sidebar":"users"},{"id":"users/ledger/ledger-cspr-live","path":"/users/ledger/ledger-cspr-live","sidebar":"users"},{"id":"users/ledger/ledger-live","path":"/users/ledger/ledger-live","sidebar":"users"},{"id":"users/ledger/ledger-setup","path":"/workflow/ledger-setup/","sidebar":"users"},{"id":"users/ledger/staking-ledger","path":"/users/staking-ledger","sidebar":"users"}],"draftIds":[],"sidebars":{"concepts":{"link":{"path":"/concepts/","label":"concepts/index"}},"developers":{"link":{"path":"/developers","label":"developers/index"}},"operators":{"link":{"path":"/operators","label":"operators/index"}},"resources":{"link":{"path":"/resources/","label":"resources/index"}},"users":{"link":{"path":"/users/","label":"users/index"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}'),s=n(7529),c=JSON.parse('{"docusaurusVersion":"2.4.1","siteVersion":"1.0.4","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.4.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.4.1"},"docusaurus-plugin-google-gtag":{"type":"package","name":"@docusaurus/plugin-google-gtag","version":"2.4.1"},"docusaurus-plugin-google-tag-manager":{"type":"package","name":"@docusaurus/plugin-google-tag-manager","version":"2.4.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.4.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.1"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"2.4.1"},"docusaurus-plugin-sass":{"type":"package","name":"docusaurus-plugin-sass","version":"0.2.5"},"docusaurus-plugin-navdata":{"type":"package","name":"docusaurus-plugin-navdata","version":"0.1.0"},"docusaurus-plugin-cookiesbanner":{"type":"package","name":"docusaurus-plugin-cookiesbanner","version":"0.1.0"}}}'),l={siteConfig:o.default,siteMetadata:c,globalData:a,i18n:i,codeTranslations:s},u=r.createContext(l);function d(e){var t=e.children;return r.createElement(u.Provider,{value:l},t)}},4763:function(e,t,n){"use strict";n.d(t,{Z:function(){return f}});var r=n(4578),o=n(7294),a=n(412),i=n(5742),s=n(8780),c=n(9686);function l(e){var t=e.error,n=e.tryAgain;return o.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"}},o.createElement("h1",{style:{fontSize:"3rem"}},"This page crashed"),o.createElement("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"}},"Try again"),o.createElement(u,{error:t}))}function u(e){var t=e.error,n=(0,s.getErrorCausalChain)(t).map((function(e){return e.message})).join("\n\nCause:\n");return o.createElement("p",{style:{whiteSpace:"pre-wrap"}},n)}function d(e){var t=e.error,n=e.tryAgain;return o.createElement(f,{fallback:function(){return o.createElement(l,{error:t,tryAgain:n})}},o.createElement(i.Z,null,o.createElement("title",null,"Page Error")),o.createElement(c.Z,null,o.createElement(l,{error:t,tryAgain:n})))}var p=function(e){return o.createElement(d,e)},f=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={error:null},n}(0,r.Z)(t,e);var n=t.prototype;return n.componentDidCatch=function(e){a.Z.canUseDOM&&this.setState({error:e})},n.render=function(){var e=this,t=this.props.children,n=this.state.error;if(n){var r,o={error:n,tryAgain:function(){return e.setState({error:null})}};return(null!=(r=this.props.fallback)?r:p)(o)}return null!=t?t:null},t}(o.Component)},412:function(e,t){"use strict";var n="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,r={canUseDOM:n,canUseEventListeners:n&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:n&&"IntersectionObserver"in window,canUseViewport:n&&"screen"in window};t.Z=r},5742:function(e,t,n){"use strict";n.d(t,{Z:function(){return a}});var r=n(7294),o=n(405);function a(e){return r.createElement(o.ql,e)}},9960:function(e,t,n){"use strict";n.d(t,{Z:function(){return h}});var r=n(7462),o=n(3366),a=n(7294),i=n(3727),s=n(8780),c=n(2263),l=n(3919),u=n(412),d=a.createContext({collectLink:function(){}});var p=n(4996),f=["isNavLink","to","href","activeClassName","isActive","data-noBrokenLinkCheck","autoAddBaseUrl"];function m(e,t){var n,m,h=e.isNavLink,g=e.to,v=e.href,b=e.activeClassName,y=e.isActive,w=e["data-noBrokenLinkCheck"],k=e.autoAddBaseUrl,_=void 0===k||k,E=(0,o.Z)(e,f),C=(0,c.Z)().siteConfig,x=C.trailingSlash,S=C.baseUrl,T=(0,p.C)().withBaseUrl,N=(0,a.useContext)(d),L=(0,a.useRef)(null);(0,a.useImperativeHandle)(t,(function(){return L.current}));var A=g||v;var O,P=(0,l.Z)(A),I=null==A?void 0:A.replace("pathname://",""),R=void 0!==I?(O=I,_&&function(e){return e.startsWith("/")}(O)?T(O):O):void 0;R&&P&&(R=(0,s.applyTrailingSlash)(R,{trailingSlash:x,baseUrl:S}));var M=(0,a.useRef)(!1),D=h?i.OL:i.rU,F=u.Z.canUseIntersectionObserver,B=(0,a.useRef)(),j=function(){M.current||null==R||(window.docusaurus.preload(R),M.current=!0)};(0,a.useEffect)((function(){return!F&&P&&null!=R&&window.docusaurus.prefetch(R),function(){F&&B.current&&B.current.disconnect()}}),[B,R,F,P]);var U=null!=(n=null==(m=R)?void 0:m.startsWith("#"))&&n,Z=!R||!P||U;return Z||w||N.collectLink(R),Z?a.createElement("a",(0,r.Z)({ref:L,href:R},A&&!P&&{target:"_blank",rel:"noopener noreferrer"},E)):a.createElement(D,(0,r.Z)({},E,{onMouseEnter:j,onTouchStart:j,innerRef:function(e){L.current=e,F&&e&&P&&(B.current=new window.IntersectionObserver((function(t){t.forEach((function(t){e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(B.current.unobserve(e),B.current.disconnect(),null!=R&&window.docusaurus.prefetch(R))}))})),B.current.observe(e))},to:R},h&&{isActive:y,activeClassName:b}))}var h=a.forwardRef(m)},5999:function(e,t,n){"use strict";n.d(t,{Z:function(){return c},I:function(){return s}});var r=n(7294);function o(e,t){var n=e.split(/(\{\w+\})/).map((function(e,n){if(n%2==1){var r=null==t?void 0:t[e.slice(1,-1)];if(void 0!==r)return r}return e}));return n.some((function(e){return(0,r.isValidElement)(e)}))?n.map((function(e,t){return(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e})).filter((function(e){return""!==e})):n.join("")}var a=n(7529);function i(e){var t,n,r=e.id,o=e.message;if(void 0===r&&void 0===o)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return null!=(t=null!=(n=a[null!=r?r:o])?n:o)?t:r}function s(e,t){return o(i({message:e.message,id:e.id}),t)}function c(e){var t=e.children,n=e.id,a=e.values;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");var s=i({message:t,id:n});return r.createElement(r.Fragment,null,o(s,a))}},9935:function(e,t,n){"use strict";n.d(t,{m:function(){return r}});var r="default"},3919:function(e,t,n){"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.d(t,{Z:function(){return o},b:function(){return r}})},4996:function(e,t,n){"use strict";n.d(t,{C:function(){return i},Z:function(){return s}});var r=n(7294),o=n(2263),a=n(3919);function i(){var e=(0,o.Z)().siteConfig,t=e.baseUrl,n=e.url,i=(0,r.useCallback)((function(e,r){return function(e,t,n,r){var o=void 0===r?{}:r,i=o.forcePrependBaseUrl,s=void 0!==i&&i,c=o.absolute,l=void 0!==c&&c;if(!n||n.startsWith("#")||(0,a.b)(n))return n;if(s)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;var u=n.startsWith(t)?n:t+n.replace(/^\//,"");return l?e+u:u}(n,t,e,r)}),[n,t]);return{withBaseUrl:i}}function s(e,t){return void 0===t&&(t={}),(0,i().withBaseUrl)(e,t)}},2263:function(e,t,n){"use strict";n.d(t,{Z:function(){return a}});var r=n(7294),o=n(8940);function a(){return(0,r.useContext)(o._)}},8084:function(e,t,n){"use strict";n.d(t,{OD:function(){return a},eZ:function(){return i}});var r=n(2263),o=n(9935);function a(e,t){void 0===t&&(t={});var n=(0,r.Z)().globalData[e];if(!n&&t.failfast)throw new Error('Docusaurus plugin global data not found for "'+e+'" plugin.');return n}function i(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});var r=a(e),i=null==r?void 0:r[t];if(!i&&n.failfast)throw new Error('Docusaurus plugin global data not found for "'+e+'" plugin with id "'+t+'".');return i}},2389:function(e,t,n){"use strict";n.d(t,{Z:function(){return a}});var r=n(7294),o=n(8934);function a(){return(0,r.useContext)(o._)}},9670:function(e,t,n){"use strict";n.d(t,{Z:function(){return o}});var r=function(e){return"object"==typeof e&&!!e&&Object.keys(e).length>0};function o(e){var t={};return function e(n,o){Object.entries(n).forEach((function(n){var a=n[0],i=n[1],s=o?o+"."+a:a;r(i)?e(i,s):t[s]=i}))}(e),t}},226:function(e,t,n){"use strict";n.d(t,{_:function(){return o},z:function(){return a}});var r=n(7294),o=r.createContext(null);function a(e){var t=e.children,n=e.value,a=r.useContext(o),i=(0,r.useMemo)((function(){return function(e){var t=e.parent,n=e.value;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}var r=Object.assign({},t.data,null==n?void 0:n.data);return{plugin:t.plugin,data:r}}({parent:a,value:n})}),[a,n]);return r.createElement(o.Provider,{value:i},t)}},4104:function(e,t,n){"use strict";n.d(t,{Iw:function(){return h},gA:function(){return d},WS:function(){return p},_r:function(){return l},Jo:function(){return g},zh:function(){return u},yW:function(){return m},gB:function(){return f}});var r=n(6550),o=n(8084);var a=function(e){return e.versions.find((function(e){return e.isLast}))};function i(e,t){var n=a(e);return[].concat(e.versions.filter((function(e){return e!==n})),[n]).find((function(e){return!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})}))}function s(e,t){var n,o,a=i(e,t),s=null==a?void 0:a.docs.find((function(e){return!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})}));return{activeVersion:a,activeDoc:s,alternateDocVersions:s?(n=s.id,o={},e.versions.forEach((function(e){e.docs.forEach((function(t){t.id===n&&(o[e.name]=t)}))})),o):{}}}var c={},l=function(){var e;return null!=(e=(0,o.OD)("docusaurus-plugin-content-docs"))?e:c},u=function(e){return(0,o.eZ)("docusaurus-plugin-content-docs",e,{failfast:!0})};function d(e){return void 0===e&&(e={}),function(e,t,n){void 0===n&&(n={});var o=Object.entries(e).sort((function(e,t){return t[1].path.localeCompare(e[1].path)})).find((function(e){var n=e[1];return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),a=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!a&&n.failfast)throw new Error("Can't find active docs plugin for \""+t+'" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: '+Object.values(e).map((function(e){return e.path})).join(", "));return a}(l(),(0,r.TH)().pathname,e)}function p(e){void 0===e&&(e={});var t=d(e),n=(0,r.TH)().pathname;if(t)return{activePlugin:t,activeVersion:i(t.pluginData,n)}}function f(e){return u(e).versions}function m(e){var t=u(e);return a(t)}function h(e){return s(u(e),(0,r.TH)().pathname)}function g(e){return function(e,t){var n=a(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(u(e),(0,r.TH)().pathname)}},6657:function(e,t,n){"use strict";n.r(t);var r={onRouteDidUpdate:function(e){var t=e.location,n=e.previousLocation;!n||t.pathname===n.pathname&&t.search===n.search&&t.hash===n.hash||setTimeout((function(){window.gtag("event","page_view",{page_title:document.title,page_location:window.location.href,page_path:t.pathname+t.search+t.hash})}))}};t.default=r},8320:function(e,t,n){"use strict";n.r(t);var r=n(4865),o=n.n(r);o().configure({showSpinner:!1});var a={onRouteUpdate:function(e){var t=e.location,n=e.previousLocation;if(n&&t.pathname!==n.pathname){var r=window.setTimeout((function(){o().start()}),200);return function(){return window.clearTimeout(r)}}},onRouteDidUpdate:function(){o().done()}};t.default=a},3310:function(e,t,n){"use strict";n.r(t);var r,o,a=n(7410),i=n(6809);r=a.Z,o=i.default.themeConfig.prism.additionalLanguages,globalThis.Prism=r,o.forEach((function(e){n(4294)("./prism-"+e)})),delete globalThis.Prism},9471:function(e,t,n){"use strict";n.d(t,{Z:function(){return a}});var r=n(7294),o={iconExternalLink:"iconExternalLink_nPIU"};function a(e){var t=e.width,n=void 0===t?13.5:t,a=e.height,i=void 0===a?13.5:a;return r.createElement("svg",{width:n,height:i,"aria-hidden":"true",viewBox:"0 0 24 24",className:o.iconExternalLink},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},9686:function(e,t,n){"use strict";n.d(t,{Z:function(){return Jn}});var r=n(7294),o=n(6010),a=n(4763),i=n(833),s=n(7462),c=n(6550),l=n(5999),u=n(5936),d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){var e=(0,r.useRef)(null),t=(0,c.k6)().action,n=(0,r.useCallback)((function(e){e.preventDefault();var t,n=null!=(t=document.querySelector("main:first-of-type"))?t:document.getElementById(d);n&&p(n)}),[]);return(0,u.S)((function(n){var r=n.location;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}var m=(0,l.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){var t,n=null!=(t=e.children)?t:m,o=f(),a=o.containerRef,i=o.onClick;return r.createElement("div",{ref:a,role:"region","aria-label":m},r.createElement("a",(0,s.Z)({},e,{href:"#"+d,onClick:i}),n))}var g=n(5281),v=n(9727),b={skipToContent:"skipToContent_fXgn"};function y(){return r.createElement(h,{className:b.skipToContent})}var w=n(6668),k=n(9689),_=n(3366),E=["width","height","color","strokeWidth","className"];function C(e){var t=e.width,n=void 0===t?21:t,o=e.height,a=void 0===o?21:o,i=e.color,c=void 0===i?"currentColor":i,l=e.strokeWidth,u=void 0===l?1.2:l,d=(e.className,(0,_.Z)(e,E));return r.createElement("svg",(0,s.Z)({viewBox:"0 0 15 15",width:n,height:a},d),r.createElement("g",{stroke:c,strokeWidth:u},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}var x={closeButton:"closeButton_CVFx"};function S(e){return r.createElement("button",(0,s.Z)({type:"button","aria-label":(0,l.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,o.Z)("clean-btn close",x.closeButton,e.className)}),r.createElement(C,{width:14,height:14,strokeWidth:3.1}))}var T={content:"content_knG7"};function N(e){var t=(0,w.L)().announcementBar.content;return r.createElement("div",(0,s.Z)({},e,{className:(0,o.Z)(T.content,e.className),dangerouslySetInnerHTML:{__html:t}}))}var L={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function A(){var e=(0,w.L)().announcementBar,t=(0,k.nT)(),n=t.isActive,o=t.close;if(!n)return null;var a=e.backgroundColor,i=e.textColor,s=e.isCloseable;return r.createElement("div",{className:L.announcementBar,style:{backgroundColor:a,color:i},role:"banner"},s&&r.createElement("div",{className:L.announcementBarPlaceholder}),r.createElement(N,{className:L.announcementBarContent}),s&&r.createElement(S,{onClick:o,className:L.announcementBarClose}))}var O=n(3163),P=n(2466);var I=n(9688),R=n(3102),M=r.createContext(null);function D(e){var t,n,o,a,i,s,c,l=e.children,u=(t=(0,O.e)(),n=(0,R.HY)(),o=(0,r.useState)(!1),a=o[0],i=o[1],s=null!==n.component,c=(0,I.D9)(s),(0,r.useEffect)((function(){s&&!c&&i(!0)}),[s,c]),(0,r.useEffect)((function(){s?t.shown||i(!0):i(!1)}),[t.shown,s]),(0,r.useMemo)((function(){return[a,i]}),[a]));return r.createElement(M.Provider,{value:u},l)}function F(e){if(e.component){var t=e.component;return r.createElement(t,e.props)}}function B(){var e=(0,r.useContext)(M);if(!e)throw new I.i6("NavbarSecondaryMenuDisplayProvider");var t=e[0],n=e[1],o=(0,r.useCallback)((function(){return n(!1)}),[n]),a=(0,R.HY)();return(0,r.useMemo)((function(){return{shown:t,hide:o,content:F(a)}}),[o,a,t])}var j={searchBox:"searchBox_H2mL"};function U(e){var t=e.children,n=e.className;return r.createElement("div",{className:(0,o.Z)(n,j.searchBox)},t)}var Z=n(196),z=n(1931),H={sideBarWrapper:"sideBarWrapper_pBNs",showingAnnouncer:"showingAnnouncer_f0Ab",docSearchContainer:"docSearchContainer_wO8u"};function $(e){var t,n,a,i,s=e.header,c=e.primaryMenu,l=e.secondaryMenu,u=B().shown,d=((0,w.L)().navbar.items.find((function(e){return"search"===e.type})),r.useRef(null)),p=r.useRef(null),f=z.Z?document.querySelectorAll('*[class^="announcementBar_"]')[0]:null,m=z.Z?document.querySelectorAll('*[class^="navbar_wrapper"]')[0]:null;return f&&(d.current=f,i=(0,Z.Z)(d,"0px"),n=d.current.offsetHeight),m&&(p.current=m,a=p.current.offsetHeight),r.createElement("div",{className:"navbar-sidebar "+H.sideBarWrapper+" "+(i?H.showingAnnouncer:""),style:(t={},t["--announcerHeight"]=(n||0)+"px",t["--siteNavbarMobileHeight"]=(a||0)+"px",t)},s,r.createElement("div",{className:(0,o.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":u})},r.createElement("div",{className:"navbar-sidebar__item menu"},c),r.createElement("div",{className:"navbar-sidebar__item menu"},l)))}var q=n(9960),V=n(4996),W=n(3919),G=n(8022),K=n(9471),Y=["activeBasePath","activeBaseRegex","to","href","label","html","isDropdownLink","prependBaseUrlToHref"];function Q(e){var t=e.activeBasePath,n=e.activeBaseRegex,o=e.to,a=e.href,i=e.label,c=e.html,l=e.isDropdownLink,u=e.prependBaseUrlToHref,d=(0,_.Z)(e,Y),p=(0,V.Z)(o),f=(0,V.Z)(t),m=(0,V.Z)(a,{forcePrependBaseUrl:!0}),h=i&&a&&!(0,W.Z)(a),g=c?{dangerouslySetInnerHTML:{__html:c}}:{children:r.createElement(r.Fragment,null,i,h&&r.createElement(K.Z,l&&{width:12,height:12}))};return a?r.createElement(q.Z,(0,s.Z)({href:u?m:a},d,g)):r.createElement(q.Z,(0,s.Z)({to:p,isNavLink:!0},(t||n)&&{isActive:function(e,t){return n?(0,G.F)(n,t.pathname):t.pathname.startsWith(f)}},d,g))}var X=["className","isDropdownItem"],J=["className","isDropdownItem"],ee=["mobile","position"];function te(e){var t=e.className,n=e.isDropdownItem,a=void 0!==n&&n,i=(0,_.Z)(e,X),c=r.createElement(Q,(0,s.Z)({className:(0,o.Z)(a?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:a},i));return a?r.createElement("li",null,c):c}function ne(e){var t=e.className,n=(e.isDropdownItem,(0,_.Z)(e,J));return r.createElement("li",{className:"menu__list-item"},r.createElement(Q,(0,s.Z)({className:(0,o.Z)("menu__link",t)},n)))}function re(e){var t,n=e.mobile,o=void 0!==n&&n,a=(e.position,(0,_.Z)(e,ee)),i=o?ne:te;return r.createElement(i,(0,s.Z)({},a,{activeClassName:null!=(t=a.activeClassName)?t:o?"menu__link--active":"navbar__link--active"}))}var oe=n(7186),ae=n(8596),ie=n(2263);var se=["items","position","className","onClick"],ce=["items","className","position","onClick"],le=["mobile"];function ue(e,t){return e.some((function(e){return function(e,t){return!!(0,ae.Mg)(e.to,t)||!!(0,G.F)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)}))}function de(e){var t,n=e.items,a=e.position,i=e.className,c=(e.onClick,(0,_.Z)(e,se)),l=(0,r.useRef)(null),u=(0,r.useState)(!1),d=u[0],p=u[1];return(0,r.useEffect)((function(){var e=function(e){l.current&&!l.current.contains(e.target)&&p(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),function(){document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[l]),r.createElement("div",{ref:l,className:(0,o.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===a,"dropdown--show":d})},r.createElement(Q,(0,s.Z)({"aria-haspopup":"true","aria-expanded":d,role:"button",href:c.to?void 0:"#",className:(0,o.Z)("navbar__link",i)},c,{onClick:c.to?void 0:function(e){return e.preventDefault()},onKeyDown:function(e){"Enter"===e.key&&(e.preventDefault(),p(!d))}}),null!=(t=c.children)?t:c.label),r.createElement("ul",{className:"dropdown__menu"},n.map((function(e,t){return r.createElement(Ye,(0,s.Z)({isDropdownItem:!0,activeClassName:"dropdown__link--active"},e,{key:t}))}))))}function pe(e){var t,n,a=e.items,i=e.className,l=(e.position,e.onClick),u=(0,_.Z)(e,ce),d=(n=(0,ie.Z)().siteConfig.baseUrl,(0,c.TH)().pathname.replace(n,"/")),p=ue(a,d),f=(0,oe.u)({initialState:function(){return!p}}),m=f.collapsed,h=f.toggleCollapsed,g=f.setCollapsed;return(0,r.useEffect)((function(){p&&g(!p)}),[d,p,g]),r.createElement("li",{className:(0,o.Z)("menu__list-item",{"menu__list-item--collapsed":m})},r.createElement(Q,(0,s.Z)({role:"button",className:(0,o.Z)("menu__link menu__link--sublist menu__link--sublist-caret",i)},u,{onClick:function(e){e.preventDefault(),h()}}),null!=(t=u.children)?t:u.label),r.createElement(oe.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:m},a.map((function(e,t){return r.createElement(Ye,(0,s.Z)({mobile:!0,isDropdownItem:!0,onClick:l,activeClassName:"menu__link--active"},e,{key:t}))}))))}function fe(e){var t=e.mobile,n=void 0!==t&&t,o=(0,_.Z)(e,le),a=n?pe:de;return r.createElement(a,o)}var me=n(4711),he=["width","height"];function ge(e){var t=e.width,n=void 0===t?20:t,o=e.height,a=void 0===o?20:o,i=(0,_.Z)(e,he);return r.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:n,height:a,"aria-hidden":!0},i),r.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}var ve="iconLanguage_nlXk",be=["mobile","dropdownItemsBefore","dropdownItemsAfter"];function ye(){return r.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},r.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var we=n(830),ke=["translations"];function _e(){return _e=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var Se="Ctrl";var Te=r.forwardRef((function(e,t){var n=e.translations,o=void 0===n?{}:n,a=xe(e,ke),i=o.buttonText,s=void 0===i?"Search":i,c=o.buttonAriaLabel,l=void 0===c?"Search":c,u=Ee((0,r.useState)(null),2),d=u[0],p=u[1];return(0,r.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?p("\u2318"):p(Se))}),[]),r.createElement("button",_e({type:"button",className:"DocSearch DocSearch-Button","aria-label":l},a,{ref:t}),r.createElement("span",{className:"DocSearch-Button-Container"},r.createElement(we.W,null),r.createElement("span",{className:"DocSearch-Button-Placeholder"},s)),r.createElement("span",{className:"DocSearch-Button-Keys"},null!==d&&r.createElement(r.Fragment,null,r.createElement("kbd",{className:"DocSearch-Button-Key"},d===Se?r.createElement(ye,null):d),r.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))})),Ne=n(5742),Le=n(6177),Ae=n(239),Oe=n(3320);var Pe=n(3935),Ie={button:{buttonText:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,l.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,l.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,l.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,l.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,l.I)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,l.I)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,l.I)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,l.I)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,l.I)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,l.I)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,l.I)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,l.I)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,l.I)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,l.I)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})},Re=["contextualSearch","externalUrlRegex"],Me=null;function De(e){var t=e.hit,n=e.children;return r.createElement(q.Z,{to:t.url},n)}function Fe(e){var t=e.state,n=e.onClose,o=(0,Le.M)();return r.createElement(q.Z,{to:o(t.query),onClick:n},r.createElement(l.Z,{id:"theme.SearchBar.seeAll",values:{count:t.context.nbHits}},"See all {count} results"))}function Be(e){var t,o,a,i,l,u=e.contextualSearch,d=e.externalUrlRegex,p=(0,_.Z)(e,Re),f=(0,ie.Z)().siteMetadata,m=(0,Ae.l)(),h=["language:"+(a=(0,Oe._q)()).locale,a.tags.map((function(e){return"docusaurus_tag:"+e}))],g=null!=(t=null==(o=p.searchParameters)?void 0:o.facetFilters)?t:[],v=u?(i=g,[].concat((l=function(e){return"string"==typeof e?[e]:e})(h),l(i))):g,b=Object.assign({},p.searchParameters,{facetFilters:v}),y=(0,c.k6)(),w=(0,r.useRef)(null),k=(0,r.useRef)(null),E=(0,r.useState)(!1),C=E[0],x=E[1],S=(0,r.useState)(void 0),T=S[0],N=S[1],L=(0,r.useCallback)((function(){return Me?Promise.resolve():Promise.all([n.e(3719).then(n.bind(n,3719)),Promise.all([n.e(532),n.e(6945)]).then(n.bind(n,6945)),Promise.all([n.e(532),n.e(8894)]).then(n.bind(n,8894))]).then((function(e){var t=e[0].DocSearchModal;Me=t}))}),[]),A=(0,r.useCallback)((function(){L().then((function(){w.current=document.createElement("div"),document.body.insertBefore(w.current,document.body.firstChild),x(!0)}))}),[L,x]),O=(0,r.useCallback)((function(){var e;x(!1),null==(e=w.current)||e.remove()}),[x]),P=(0,r.useCallback)((function(e){L().then((function(){x(!0),N(e.key)}))}),[L,x,N]),I=(0,r.useRef)({navigate:function(e){var t=e.itemUrl;(0,G.F)(d,t)?window.location.href=t:y.push(t)}}).current,R=(0,r.useRef)((function(e){return p.transformItems?p.transformItems(e):e.map((function(e){return Object.assign({},e,{url:m(e.url)})}))})).current,M=(0,r.useMemo)((function(){return function(e){return r.createElement(Fe,(0,s.Z)({},e,{onClose:O}))}}),[O]),D=(0,r.useCallback)((function(e){return e.addAlgoliaAgent("docusaurus",f.docusaurusVersion),e}),[f.docusaurusVersion]);return function(e){var t=e.isOpen,n=e.onOpen,o=e.onClose,a=e.onInput,i=e.searchButtonRef;r.useEffect((function(){function e(e){var r;(27===e.keyCode&&t||"k"===(null===(r=e.key)||void 0===r?void 0:r.toLowerCase())&&(e.metaKey||e.ctrlKey)||!function(e){var t=e.target,n=t.tagName;return t.isContentEditable||"INPUT"===n||"SELECT"===n||"TEXTAREA"===n}(e)&&"/"===e.key&&!t)&&(e.preventDefault(),t?o():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||n()),i&&i.current===document.activeElement&&a&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&a(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[t,n,o,a,i])}({isOpen:C,onOpen:A,onClose:O,onInput:P,searchButtonRef:k}),r.createElement(r.Fragment,null,r.createElement(Ne.Z,null,r.createElement("link",{rel:"preconnect",href:"https://"+p.appId+"-dsn.algolia.net",crossOrigin:"anonymous"})),r.createElement(Te,{onTouchStart:L,onFocus:L,onMouseOver:L,onClick:A,ref:k,translations:Ie.button}),C&&Me&&w.current&&(0,Pe.createPortal)(r.createElement(Me,(0,s.Z)({onClose:O,initialScrollY:window.scrollY,initialQuery:T,navigator:I,transformItems:R,hitComponent:De,transformSearchClient:D},p.searchPagePath&&{resultsFooterComponent:M},p,{searchParameters:b,placeholder:Ie.placeholder,translations:Ie.modal})),w.current))}function je(){var e=(0,ie.Z)().siteConfig;return r.createElement(Be,e.themeConfig.algolia)}var Ue=n(4104),Ze=n(3438),ze=["docId","label","docsPluginId"];var He=["sidebarId","label","docsPluginId"];var $e=["label","to","docsPluginId"];var qe=n(373),Ve=["mobile","docsPluginId","dropdownActiveClassDisabled","dropdownItemsBefore","dropdownItemsAfter"],We=function(e){return e.docs.find((function(t){return t.id===e.mainDocId}))};var Ge={default:re,localeDropdown:function(e){var t=e.mobile,n=e.dropdownItemsBefore,o=e.dropdownItemsAfter,a=(0,_.Z)(e,be),i=(0,ie.Z)().i18n,u=i.currentLocale,d=i.locales,p=i.localeConfigs,f=(0,me.l)(),m=(0,c.TH)(),h=m.search,g=m.hash,v=d.map((function(e){var n=""+("pathname://"+f.createUrl({locale:e,fullyQualified:!1}))+h+g;return{label:p[e].label,lang:p[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===u?t?"menu__link--active":"dropdown__link--active":""}})),b=[].concat(n,v,o),y=t?(0,l.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):p[u].label;return r.createElement(fe,(0,s.Z)({},a,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(ge,{className:ve}),y),items:b}))},search:function(e){var t=e.mobile,n=e.className;return t?null:r.createElement(U,{className:n},r.createElement(je,null))},dropdown:fe,html:function(e){var t=e.value,n=e.className,a=e.mobile,i=void 0!==a&&a,s=e.isDropdownItem,c=void 0!==s&&s,l=c?"li":"div";return r.createElement(l,{className:(0,o.Z)({navbar__item:!i&&!c,"menu__list-item":i},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){var t=e.docId,n=e.label,o=e.docsPluginId,a=(0,_.Z)(e,ze),i=(0,Ue.Iw)(o).activeDoc,c=(0,Ze.vY)(t,o);return null===c?null:r.createElement(re,(0,s.Z)({exact:!0},a,{isActive:function(){return(null==i?void 0:i.path)===c.path||!(null==i||!i.sidebar)&&i.sidebar===c.sidebar},label:null!=n?n:c.id,to:c.path}))},docSidebar:function(e){var t=e.sidebarId,n=e.label,o=e.docsPluginId,a=(0,_.Z)(e,He),i=(0,Ue.Iw)(o).activeDoc,c=(0,Ze.oz)(t,o).link;if(!c)throw new Error('DocSidebarNavbarItem: Sidebar with ID "'+t+"\" doesn't have anything to be linked to.");return r.createElement(re,(0,s.Z)({exact:!0},a,{isActive:function(){return(null==i?void 0:i.sidebar)===t},label:null!=n?n:c.label,to:c.path}))},docsVersion:function(e){var t=e.label,n=e.to,o=e.docsPluginId,a=(0,_.Z)(e,$e),i=(0,Ze.lO)(o)[0],c=null!=t?t:i.label,l=null!=n?n:function(e){return e.docs.find((function(t){return t.id===e.mainDocId}))}(i).path;return r.createElement(re,(0,s.Z)({},a,{label:c,to:l}))},docsVersionDropdown:function(e){var t=e.mobile,n=e.docsPluginId,o=e.dropdownActiveClassDisabled,a=e.dropdownItemsBefore,i=e.dropdownItemsAfter,u=(0,_.Z)(e,Ve),d=(0,c.TH)(),p=d.search,f=d.hash,m=(0,Ue.Iw)(n),h=(0,Ue.gB)(n),g=(0,qe.J)(n).savePreferredVersionName,v=h.map((function(e){var t,n=null!=(t=m.alternateDocVersions[e.name])?t:We(e);return{label:e.label,to:""+n.path+p+f,isActive:function(){return e===m.activeVersion},onClick:function(){return g(e.name)}}})),b=[].concat(a,v,i),y=(0,Ze.lO)(n)[0],w=t&&b.length>1?(0,l.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):y.label,k=t&&b.length>1?void 0:We(y).path;return b.length<=1?r.createElement(re,(0,s.Z)({},u,{mobile:t,label:w,to:k,isActive:o?function(){return!1}:void 0})):r.createElement(fe,(0,s.Z)({},u,{mobile:t,label:w,to:k,items:b,isActive:o?function(){return!1}:void 0}))}},Ke=["type"];function Ye(e){var t=e.type,n=(0,_.Z)(e,Ke),o=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),a=Ge[o];if(!a)throw new Error('No NavbarItem component found for type "'+t+'".');return r.createElement(a,n)}function Qe(){var e=(0,O.e)(),t=(0,w.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map((function(t,n){return r.createElement(Ye,(0,s.Z)({mobile:!0},t,{onClick:function(){return e.toggle()},key:n}))})))}function Xe(e){return r.createElement("button",(0,s.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(l.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function Je(){var e=0===(0,w.L)().navbar.items.length,t=B();return r.createElement(r.Fragment,null,!e&&r.createElement(Xe,{onClick:function(){return t.hide()}}),t.content)}function et(){var e,t=(0,O.e)();return void 0===(e=t.shown)&&(e=!0),(0,r.useEffect)((function(){return document.body.style.overflow=e?"hidden":"visible",function(){document.body.style.overflow="visible"}}),[e]),t.shouldRender?r.createElement($,{primaryMenu:r.createElement(Qe,null),secondaryMenu:r.createElement(Je,null)}):null}var tt={navBarWrapper:"navBarWrapper_phG8",navbarHideable:"navbarHideable_jvwV",navbarHidden:"navbarHidden_nLSi"};function nt(e){var t=e.children,n=(0,w.L)().navbar,a=n.hideOnScroll,i=n.style,s=(0,O.e)(),c=function(e){var t=(0,r.useState)(e),n=t[0],o=t[1],a=(0,r.useRef)(!1),i=(0,r.useRef)(0),s=(0,r.useCallback)((function(e){null!==e&&(i.current=e.getBoundingClientRect().height)}),[]);return(0,P.RF)((function(t,n){var r=t.scrollY;if(e)if(r=s?o(!1):r+l0?l.map((function(e,t){var n,o,a;return(null==(n=e._highlightResult)||null==(n=n.title)||null==(n=n.matchedWords)?void 0:n.length)>0||(null==(o=e._highlightResult)||null==(o=o.internal)||null==(o=o.content)||null==(o=o.matchedWords)?void 0:o.length)>0?r.createElement("a",{key:e.objectID+"-"+t,href:v(e),className:yt.results_container_hit},r.createElement("div",{className:yt.results_container_hit_link},r.createElement("svg",{width:"22",height:"22",viewBox:"0 0 22 22",fill:"none",xmlns:"http://www.w3.org/2000/svg"},r.createElement("path",{d:"M21.6499 19.8884L14.6937 12.9321C15.7731 11.5366 16.3571 9.83036 16.3571 8.03571C16.3571 5.8875 15.5187 3.87321 14.0026 2.35446C12.4865 0.835714 10.4669 0 8.32136 0C6.17582 0 4.15618 0.838393 2.64011 2.35446C1.12136 3.87054 0.285645 5.8875 0.285645 8.03571C0.285645 10.1812 1.12404 12.2009 2.64011 13.717C4.15618 15.2357 6.17314 16.0714 8.32136 16.0714C10.116 16.0714 11.8196 15.4875 13.2151 14.4107L20.1714 21.3643C20.1918 21.3847 20.216 21.4009 20.2426 21.4119C20.2693 21.423 20.2979 21.4287 20.3267 21.4287C20.3556 21.4287 20.3841 21.423 20.4108 21.4119C20.4375 21.4009 20.4617 21.3847 20.4821 21.3643L21.6499 20.1991C21.6703 20.1787 21.6865 20.1545 21.6976 20.1278C21.7086 20.1012 21.7143 20.0726 21.7143 20.0438C21.7143 20.0149 21.7086 19.9863 21.6976 19.9597C21.6865 19.933 21.6703 19.9088 21.6499 19.8884ZM12.5642 12.2786C11.4285 13.4116 9.92314 14.0357 8.32136 14.0357C6.71957 14.0357 5.21422 13.4116 4.0785 12.2786C2.94547 11.1429 2.32136 9.6375 2.32136 8.03571C2.32136 6.43393 2.94547 4.92589 4.0785 3.79286C5.21422 2.65982 6.71957 2.03571 8.32136 2.03571C9.92314 2.03571 11.4312 2.65714 12.5642 3.79286C13.6973 4.92857 14.3214 6.43393 14.3214 8.03571C14.3214 9.6375 13.6973 11.1455 12.5642 12.2786Z",fill:"#F4F4F4"})),function(e){var t,n,o,a,i,s,c,l,u;return(null==(t=e._highlightResult)||null==(t=t.title)||null==(t=t.matchedWords)?void 0:t.length)>0?r.createElement("span",{className:"noWrap "+yt.hitWeighTitle,dangerouslySetInnerHTML:{__html:null==(o=e._highlightResult)||null==(o=o.title)?void 0:o.value}}):(null==(n=e._highlightResult)||null==(n=n.internal)||null==(n=n.content)||null==(n=n.matchedWords)?void 0:n.length)>0?r.createElement("span",{className:yt.hitContent+" noWrap"},r.createElement("p",null,null==(a=e._highlightResult)||null==(a=a.title)?void 0:a.value),r.createElement("small",{className:"noWrap",dangerouslySetInnerHTML:{__html:(c=null==(i=e._highlightResult)||null==(i=i.internal)||null==(i=i.content)?void 0:i.value,l=c.indexOf(""),u=c.substring(0,l).split(" "),(u.length<=4?u.join(" "):"... "+u.slice(u.length-4,u.length).join(" "))+" "+c.substring(l))}})):r.createElement("span",{className:yt.hitContent+" noWrap"},null==(s=e._highlightResult)||null==(s=s.title)?void 0:s.value)}(e)),r.createElement("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg"},r.createElement("path",{d:"M3.98382 4.74747L4.77142 15.886C4.77773 15.9712 4.81404 16.0517 4.87559 16.1133L6.27244 17.5101C6.38924 17.6269 6.58812 17.5354 6.57549 17.3712L5.84629 7.04557L15.0829 16.2821C15.1523 16.3516 15.266 16.3516 15.3354 16.2821L16.2824 15.3351C16.3519 15.2657 16.3519 15.152 16.2824 15.0826L7.04742 5.84759L17.3731 6.57679C17.5388 6.58784 17.6288 6.39054 17.512 6.27375L16.0678 4.82954C16.0378 4.79955 15.9967 4.78061 15.9541 4.77904L4.74774 3.98354C4.64559 3.97641 4.54309 3.99129 4.44718 4.02716C4.35126 4.06303 4.26416 4.11906 4.19175 4.19147C4.11934 4.26388 4.06331 4.35099 4.02744 4.4469C3.99156 4.54282 3.97669 4.64531 3.98382 4.74747Z",fill:"#F4F4F4"}))):e.lvl0?r.createElement("div",{className:yt.results_container_hit,key:e.objectID+"-"+t},r.createElement("div",{className:yt.results_container_hit_link},r.createElement("svg",{width:"22",height:"22",viewBox:"0 0 22 22",fill:"none",xmlns:"http://www.w3.org/2000/svg"},r.createElement("path",{d:"M21.6499 19.8884L14.6937 12.9321C15.7731 11.5366 16.3571 9.83036 16.3571 8.03571C16.3571 5.8875 15.5187 3.87321 14.0026 2.35446C12.4865 0.835714 10.4669 0 8.32136 0C6.17582 0 4.15618 0.838393 2.64011 2.35446C1.12136 3.87054 0.285645 5.8875 0.285645 8.03571C0.285645 10.1812 1.12404 12.2009 2.64011 13.717C4.15618 15.2357 6.17314 16.0714 8.32136 16.0714C10.116 16.0714 11.8196 15.4875 13.2151 14.4107L20.1714 21.3643C20.1918 21.3847 20.216 21.4009 20.2426 21.4119C20.2693 21.423 20.2979 21.4287 20.3267 21.4287C20.3556 21.4287 20.3841 21.423 20.4108 21.4119C20.4375 21.4009 20.4617 21.3847 20.4821 21.3643L21.6499 20.1991C21.6703 20.1787 21.6865 20.1545 21.6976 20.1278C21.7086 20.1012 21.7143 20.0726 21.7143 20.0438C21.7143 20.0149 21.7086 19.9863 21.6976 19.9597C21.6865 19.933 21.6703 19.9088 21.6499 19.8884ZM12.5642 12.2786C11.4285 13.4116 9.92314 14.0357 8.32136 14.0357C6.71957 14.0357 5.21422 13.4116 4.0785 12.2786C2.94547 11.1429 2.32136 9.6375 2.32136 8.03571C2.32136 6.43393 2.94547 4.92589 4.0785 3.79286C5.21422 2.65982 6.71957 2.03571 8.32136 2.03571C9.92314 2.03571 11.4312 2.65714 12.5642 3.79286C13.6973 4.92857 14.3214 6.43393 14.3214 8.03571C14.3214 9.6375 13.6973 11.1455 12.5642 12.2786Z",fill:"#F4F4F4"})),r.createElement("div",{className:yt.docElement},null==(a=function(e){var t=[],n=function(n){Array.isArray(e[n])?e[n].forEach((function(e){t.push(b(e,n))})):t.push(b(e[n],n))};for(var r in e)n(r);return t}(e))?void 0:a.map((function(e){return e})))),r.createElement("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg"},r.createElement("path",{d:"M3.98382 4.74747L4.77142 15.886C4.77773 15.9712 4.81404 16.0517 4.87559 16.1133L6.27244 17.5101C6.38924 17.6269 6.58812 17.5354 6.57549 17.3712L5.84629 7.04557L15.0829 16.2821C15.1523 16.3516 15.266 16.3516 15.3354 16.2821L16.2824 15.3351C16.3519 15.2657 16.3519 15.152 16.2824 15.0826L7.04742 5.84759L17.3731 6.57679C17.5388 6.58784 17.6288 6.39054 17.512 6.27375L16.0678 4.82954C16.0378 4.79955 15.9967 4.78061 15.9541 4.77904L4.74774 3.98354C4.64559 3.97641 4.54309 3.99129 4.44718 4.02716C4.35126 4.06303 4.26416 4.11906 4.19175 4.19147C4.11934 4.26388 4.06331 4.35099 4.02744 4.4469C3.99156 4.54282 3.97669 4.64531 3.98382 4.74747Z",fill:"#F4F4F4"}))):void 0})):r.createElement("span",null,"No results found")),o&&o.length>4&&o.length>l.length&&r.createElement("button",{className:"halfTitleEyebrow "+yt.showMore+" "+(p&&yt.hiddenResults),onClick:function(e){e.stopPropagation(),u(o)}},"Show more"))}var kt=["mousedown","touchstart"],_t=function(e,t){var n=function(n){var r;r=n.target,e.current&&e.current.contains(r)||t()};(0,r.useEffect)((function(){for(var e=0,t=kt;e0))}),[m,C]),bt("keydown",(function(e){"Escape"===e.key&&(h(""),A())})),_t(g,(function(e){return y(e)})),r.createElement("div",{ref:g,tabIndex:-1,className:Et.container,onFocus:function(){return y(!0)}},r.createElement(r.Fragment,null,r.createElement("input",{id:"inputSearch",tabIndex:0,className:Et.container_input,onChange:function(e){clearTimeout(a),a=setTimeout((function(){_(!1);var t=e.target.value;h(t),t?(T(!0),function(e){for(var t,n=[],r=(0,vt.Z)(i);!(t=r()).done;){var o=t.value;n.push(o.client.search(e,{hitsPerPage:o.client.indexName===N?4:d}))}Promise.allSettled(n).then((function(e){for(var t={},n=function(){var n=[],o=i[r].base,a=e[r];if("fulfilled"===a.status){var s=a.value.hits;s=s.map((function(e){return Object.assign({},e,{basePath:o,path:o?o+e.path:e.path})})),n=[].concat(n,s),t[""+i[r].client.indexName]=n}else console.log(a.reason.name+" "+a.reason.message)},r=0;r0&&r.createElement("div",{className:Et.search_link+" halfTitleEyebrow"},r.createElement("a",{href:"/search?q="+m},"Show all documentation results")))))}function xt(e){e.index;var t,n,o,a=e.placeholder,i=e.locale,s=e.siteUrl,c=(0,ie.Z)().siteConfig,l=[];if(null!=(t=c.themeConfig.algolia)&&t.indexName&&null!=(n=c.themeConfig.algolia)&&n.appId&&null!=(o=c.themeConfig.algolia)&&o.apiKey){var u,d,p=(0,r.useMemo)((function(){var e,t;return gt()(null==(e=c.themeConfig.algolia)?void 0:e.appId,null==(t=c.themeConfig.algolia)?void 0:t.apiKey)}),[]),f={base:null,client:Object.assign({},p,{search:function(e){return e.every((function(e){var t=e.params;return!t||!t.query}))?Promise.resolve({results:e.map((function(){return{hits:[],nbHits:0,nbPages:0,page:0,processingTimeMS:0,hitsPerPage:0,exhaustiveNbHits:!1,query:"",params:""}}))}):p.search(e)}}).initIndex(null!=(u=null==(d=c.themeConfig.algolia)?void 0:d.indexName)?u:"casperlabs")};l.push(f)}if(c.customFields.siteAlgoliaIndexName&&c.customFields.siteAlgoliaAppId&&c.customFields.siteAlgoliaApiKey){var m,h=(0,r.useMemo)((function(){return gt()(c.customFields.siteAlgoliaAppId,c.customFields.siteAlgoliaApiKey)}),[]),g={base:null,client:Object.assign({},h,{search:function(e){return e.every((function(e){var t=e.params;return!t||!t.query}))?Promise.resolve({results:e.map((function(){return{hits:[],nbHits:0,nbPages:0,page:0,processingTimeMS:0,hitsPerPage:0,exhaustiveNbHits:!1,query:"",params:""}}))}):h.search(e)}}).initIndex(null!=(m=c.customFields.siteAlgoliaIndexName)?m:"casper")};l.push(g)}return r.createElement(r.Fragment,null,r.createElement(Ct,{searchIndexes:l,locale:i.toLocaleLowerCase(),placeholder:a,hitsPerIndex:20,siteUrl:s}))}var St=n(5756),Tt=n(6115),Nt="navbar_list_Eh3d",Lt="navbar_list_container_CEpj",At="navbar_list_container_button_RjV_",Ot="navbar_list_item_dCM_",Pt="isActive_lDox",It="fullWidth_l5eY",Rt={dropdown_column:"dropdown_column_ArdK",linkGroup:"linkGroup_hKbv",linkList:"linkList_LhRK"},Mt={link:"link_c3fA",onlyTitle:"onlyTitle_ArpA"};function Dt(e){var t,n,o,a,i,s,c=e.locale,l=e.closeNavBarHandler,u=e.link,d=(0,ie.Z)().siteConfig.customFields,p=function(e){var t=d.siteUrl,n=t.endsWith("/")?t.slice(0,-1):t,r=e.startsWith("/")?e.slice(1):e;return d.defaultExternalLocales===c?n+"/"+r:n+"/"+c+"/"+r};return r.createElement("li",{className:Mt.link+" "+(u&&u.id&&0===(null==(t=u.children)?void 0:t.length)?Mt.onlyTitle:"")},r.createElement("span",null,(o=(n=u).title,a=n.open_in_new_tab,i=n.link_type,s=n.url,"internal"===i?r.createElement("a",{key:""+o,href:p(s),onClick:function(){return l()}},o):r.createElement("a",{key:""+o,href:s,target:a?"_blank":"_self"},o))),u&&u.id&&u.children&&r.createElement("ul",{className:Mt.asd+" noWrap"},u.children.map((function(e,t){return r.createElement(Dt,{key:"column_group_link_"+t,link:e,closeNavBarHandler:l,locale:c})}))))}function Ft(e){var t=e.column,n=e.locale,o=e.closeNavBarHandler;return r.createElement("div",{className:Rt.dropdown_column},r.createElement("div",{className:Rt.linkGroup},r.createElement("span",{className:"halfTitleEyebrow noWrap"},t.title),r.createElement("ul",{className:"primaryParagraph noWrap "+Rt.linkList},t&&t.children.map((function(e,t){return r.createElement(Dt,{locale:n,key:"column_group_link_"+t,link:e,closeNavBarHandler:o})})))))}var Bt={wrapper:"wrapper_DxEr",dropdown_container:"dropdown_container_NlvG"};function jt(e){var t,n=e.content,o=e.locale,a=e.closeNavBarHandler,i=e.left;return r.createElement("div",{className:""+Bt.wrapper,style:(t={},t["--left"]=i+"px",t),onClick:function(e){return e.stopPropagation()}},r.createElement("div",{className:Bt.dropdown_container},n&&n.children.map((function(e,t){return r.createElement(Ft,{key:"column_"+t,column:e,closeNavBarHandler:a,locale:o,groups:[]})}))))}var Ut=n(4578);function Zt(e,t){return e.replace(new RegExp("(^|\\s)"+t+"(?:\\s|$)","g"),"$1").replace(/\s+/g," ").replace(/^\s*|\s*$/g,"")}var zt=!1,Ht=r.createContext(null),$t=function(e){return e.scrollTop},qt="unmounted",Vt="exited",Wt="entering",Gt="entered",Kt="exiting",Yt=function(e){function t(t,n){var r;r=e.call(this,t,n)||this;var o,a=n&&!n.isMounting?t.enter:t.appear;return r.appearStatus=null,t.in?a?(o=Vt,r.appearStatus=Wt):o=Gt:o=t.unmountOnExit||t.mountOnEnter?qt:Vt,r.state={status:o},r.nextCallback=null,r}(0,Ut.Z)(t,e),t.getDerivedStateFromProps=function(e,t){return e.in&&t.status===qt?{status:Vt}:null};var n=t.prototype;return n.componentDidMount=function(){this.updateStatus(!0,this.appearStatus)},n.componentDidUpdate=function(e){var t=null;if(e!==this.props){var n=this.state.status;this.props.in?n!==Wt&&n!==Gt&&(t=Wt):n!==Wt&&n!==Gt||(t=Kt)}this.updateStatus(!1,t)},n.componentWillUnmount=function(){this.cancelNextCallback()},n.getTimeouts=function(){var e,t,n,r=this.props.timeout;return e=t=n=r,null!=r&&"number"!=typeof r&&(e=r.exit,t=r.enter,n=void 0!==r.appear?r.appear:t),{exit:e,enter:t,appear:n}},n.updateStatus=function(e,t){if(void 0===e&&(e=!1),null!==t)if(this.cancelNextCallback(),t===Wt){if(this.props.unmountOnExit||this.props.mountOnEnter){var n=this.props.nodeRef?this.props.nodeRef.current:Pe.findDOMNode(this);n&&$t(n)}this.performEnter(e)}else this.performExit();else this.props.unmountOnExit&&this.state.status===Vt&&this.setState({status:qt})},n.performEnter=function(e){var t=this,n=this.props.enter,r=this.context?this.context.isMounting:e,o=this.props.nodeRef?[r]:[Pe.findDOMNode(this),r],a=o[0],i=o[1],s=this.getTimeouts(),c=r?s.appear:s.enter;!e&&!n||zt?this.safeSetState({status:Gt},(function(){t.props.onEntered(a)})):(this.props.onEnter(a,i),this.safeSetState({status:Wt},(function(){t.props.onEntering(a,i),t.onTransitionEnd(c,(function(){t.safeSetState({status:Gt},(function(){t.props.onEntered(a,i)}))}))})))},n.performExit=function(){var e=this,t=this.props.exit,n=this.getTimeouts(),r=this.props.nodeRef?void 0:Pe.findDOMNode(this);t&&!zt?(this.props.onExit(r),this.safeSetState({status:Kt},(function(){e.props.onExiting(r),e.onTransitionEnd(n.exit,(function(){e.safeSetState({status:Vt},(function(){e.props.onExited(r)}))}))}))):this.safeSetState({status:Vt},(function(){e.props.onExited(r)}))},n.cancelNextCallback=function(){null!==this.nextCallback&&(this.nextCallback.cancel(),this.nextCallback=null)},n.safeSetState=function(e,t){t=this.setNextCallback(t),this.setState(e,t)},n.setNextCallback=function(e){var t=this,n=!0;return this.nextCallback=function(r){n&&(n=!1,t.nextCallback=null,e(r))},this.nextCallback.cancel=function(){n=!1},this.nextCallback},n.onTransitionEnd=function(e,t){this.setNextCallback(t);var n=this.props.nodeRef?this.props.nodeRef.current:Pe.findDOMNode(this),r=null==e&&!this.props.addEndListener;if(n&&!r){if(this.props.addEndListener){var o=this.props.nodeRef?[this.nextCallback]:[n,this.nextCallback],a=o[0],i=o[1];this.props.addEndListener(a,i)}null!=e&&setTimeout(this.nextCallback,e)}else setTimeout(this.nextCallback,0)},n.render=function(){var e=this.state.status;if(e===qt)return null;var t=this.props,n=t.children,o=(t.in,t.mountOnEnter,t.unmountOnExit,t.appear,t.enter,t.exit,t.timeout,t.addEndListener,t.onEnter,t.onEntering,t.onEntered,t.onExit,t.onExiting,t.onExited,t.nodeRef,(0,_.Z)(t,["children","in","mountOnEnter","unmountOnExit","appear","enter","exit","timeout","addEndListener","onEnter","onEntering","onEntered","onExit","onExiting","onExited","nodeRef"]));return r.createElement(Ht.Provider,{value:null},"function"==typeof n?n(e,o):r.cloneElement(r.Children.only(n),o))},t}(r.Component);function Qt(){}Yt.contextType=Ht,Yt.propTypes={},Yt.defaultProps={in:!1,mountOnEnter:!1,unmountOnExit:!1,appear:!1,enter:!0,exit:!0,onEnter:Qt,onEntering:Qt,onEntered:Qt,onExit:Qt,onExiting:Qt,onExited:Qt},Yt.UNMOUNTED=qt,Yt.EXITED=Vt,Yt.ENTERING=Wt,Yt.ENTERED=Gt,Yt.EXITING=Kt;var Xt=Yt,Jt=function(e,t){return e&&t&&t.split(" ").forEach((function(t){return r=t,void((n=e).classList?n.classList.remove(r):"string"==typeof n.className?n.className=Zt(n.className,r):n.setAttribute("class",Zt(n.className&&n.className.baseVal||"",r)));var n,r}))},en=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o0&&r.createElement(Sn,{links:n}),logo:o&&r.createElement(An,{logo:o}),copyright:t&&r.createElement(On,{copyright:t})}))}var $n=r.memo(Hn),qn=(0,I.Qc)([dn.S,k.pl,P.OC,qe.L5,i.VC,function(e){var t=e.children;return r.createElement(R.n2,null,r.createElement(O.M,null,r.createElement(D,null,t)))}]);function Vn(e){var t=e.children;return r.createElement(qn,null,t)}var Wn=n(8780),Gn={errorBoundaryError:"errorBoundaryError_a6uf"};function Kn(e){return r.createElement("button",(0,s.Z)({type:"button"},e),r.createElement(l.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error"},"Try again"))}function Yn(e){var t=e.error,n=(0,Wn.getErrorCausalChain)(t).map((function(e){return e.message})).join("\n\nCause:\n");return r.createElement("p",{className:Gn.errorBoundaryError},n)}r.Component;function Qn(e){var t=e.error,n=e.tryAgain;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(l.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("div",{className:"margin-vert--lg"},r.createElement(Kn,{onClick:n,className:"button button--primary shadow--lw"})),r.createElement("hr",null),r.createElement("div",{className:"margin-vert--md"},r.createElement(Yn,{error:t})))))}var Xn={mainWrapper:"mainWrapper_z2l0"};function Jn(e){var t=e.children,n=e.noFooter,s=e.wrapperClassName,c=e.title,l=e.description;return(0,v.t)(),r.createElement(Vn,null,r.createElement(i.d,{title:c,description:l}),r.createElement(y,null),r.createElement(A,null),r.createElement(vn,null),r.createElement("div",{id:d,className:(0,o.Z)(g.k.wrapper.main,Xn.mainWrapper,s)},r.createElement(a.Z,{fallback:function(e){return r.createElement(Qn,e)}},t)),!n&&r.createElement($n,null))}},1327:function(e,t,n){"use strict";n.d(t,{Z:function(){return f}});var r=n(7462),o=n(3366),a=n(7294),i=n(9960),s=n(4996),c=n(2263),l=n(6668),u=n(941),d=["imageClassName","titleClassName"];function p(e){var t=e.logo,n=e.alt,r=e.imageClassName,o={light:(0,s.Z)(t.src),dark:(0,s.Z)(t.srcDark||t.src)},i=a.createElement(u.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?a.createElement("div",{className:r},i):i}function f(e){var t,n=(0,c.Z)().siteConfig.title,u=(0,l.L)().navbar,f=u.title,m=u.logo,h=e.imageClassName,g=e.titleClassName,v=(0,o.Z)(e,d),b=(0,s.Z)((null==m?void 0:m.href)||"/"),y=f?"":n,w=null!=(t=null==m?void 0:m.alt)?t:y;return a.createElement(i.Z,(0,r.Z)({to:b},v,(null==m?void 0:m.target)&&{target:m.target}),m&&a.createElement(p,{logo:m,alt:w,imageClassName:h}),null!=f&&a.createElement("b",{className:g},f))}},197:function(e,t,n){"use strict";n.d(t,{Z:function(){return a}});var r=n(7294),o=n(5742);function a(e){var t=e.locale,n=e.version,a=e.tag,i=t;return r.createElement(o.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),a&&r.createElement("meta",{name:"docusaurus_tag",content:a}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),a&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:a}))}},941:function(e,t,n){"use strict";n.d(t,{Z:function(){return d}});var r=n(7462),o=n(3366),a=n(7294),i=n(6010),s=n(2389),c=n(2949),l={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"},u=["sources","className","alt"];function d(e){var t=(0,s.Z)(),n=(0,c.I)().colorMode,d=e.sources,p=e.className,f=e.alt,m=(0,o.Z)(e,u),h=t?"dark"===n?["dark"]:["light"]:["light","dark"];return a.createElement(a.Fragment,null,h.map((function(e){return a.createElement("img",(0,r.Z)({key:e,src:d[e],alt:f,className:(0,i.Z)(l.themedImage,l["themedImage--"+e],p)},m))})))}},7186:function(e,t,n){"use strict";n.d(t,{z:function(){return y},u:function(){return u}});var r=n(7462),o=n(3366),a=n(7294),i=n(412);var s=["collapsed"],c=["lazy"],l="ease-in-out";function u(e){var t=e.initialState,n=(0,a.useState)(null!=t&&t),r=n[0],o=n[1],i=(0,a.useCallback)((function(){o((function(e){return!e}))}),[]);return{collapsed:r,setCollapsed:o,toggleCollapsed:i}}var d={display:"none",overflow:"hidden",height:"0px"},p={display:"block",overflow:"visible",height:"auto"};function f(e,t){var n=t?d:p;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function m(e){if(window.matchMedia("(prefers-reduced-motion: reduce)").matches)return 1;var t=e/36;return Math.round(10*(4+15*Math.pow(t,.25)+t/5))}function h(e){var t=e.collapsibleRef,n=e.collapsed,r=e.animation,o=(0,a.useRef)(!1);(0,a.useEffect)((function(){var e,a=t.current;function i(){var e,t,n,o=(n=a.scrollHeight,{transition:"height "+(null!=(e=null==r?void 0:r.duration)?e:m(n))+"ms "+(null!=(t=null==r?void 0:r.easing)?t:l),height:n+"px"});a.style.transition=o.transition,a.style.height=o.height}if(!o.current)return f(a,n),void(o.current=!0);return a.style.willChange="height",e=requestAnimationFrame((function(){n?(i(),requestAnimationFrame((function(){a.style.height=d.height,a.style.overflow=d.overflow}))):(a.style.display="block",requestAnimationFrame((function(){i()})))})),function(){return cancelAnimationFrame(e)}}),[t,n,r])}function g(e){if(!i.Z.canUseDOM)return e?d:p}function v(e){var t=e.as,n=void 0===t?"div":t,r=e.collapsed,o=e.children,i=e.animation,s=e.onCollapseTransitionEnd,c=e.className,l=e.disableSSRStyle,u=(0,a.useRef)(null);return h({collapsibleRef:u,collapsed:r,animation:i}),a.createElement(n,{ref:u,style:l?void 0:g(r),onTransitionEnd:function(e){"height"===e.propertyName&&(f(u.current,r),null==s||s(r))},className:c},o)}function b(e){var t=e.collapsed,n=(0,o.Z)(e,s),i=(0,a.useState)(!t),c=i[0],l=i[1],u=(0,a.useState)(t),d=u[0],p=u[1];return(0,a.useLayoutEffect)((function(){t||l(!0)}),[t]),(0,a.useLayoutEffect)((function(){c&&p(t)}),[c,t]),c?a.createElement(v,(0,r.Z)({},n,{collapsed:d})):null}function y(e){var t=e.lazy,n=(0,o.Z)(e,c),r=t?b:v;return a.createElement(r,n)}},9689:function(e,t,n){"use strict";n.d(t,{nT:function(){return m},pl:function(){return f}});var r=n(7294),o=n(2389),a=n(12),i=n(9688),s=n(6668),c=(0,a.WA)("docusaurus.announcement.dismiss"),l=(0,a.WA)("docusaurus.announcement.id"),u=function(){return"true"===c.get()},d=function(e){return c.set(String(e))},p=r.createContext(null);function f(e){var t=e.children,n=function(){var e=(0,s.L)().announcementBar,t=(0,o.Z)(),n=(0,r.useState)((function(){return!!t&&u()})),a=n[0],i=n[1];(0,r.useEffect)((function(){i(u())}),[]);var c=(0,r.useCallback)((function(){d(!0),i(!0)}),[]);return(0,r.useEffect)((function(){if(e){var t=e.id,n=l.get();"annoucement-bar"===n&&(n="announcement-bar");var r=t!==n;l.set(t),r&&d(!1),!r&&u()||i(!1)}}),[e]),(0,r.useMemo)((function(){return{isActive:!!e&&!a,close:c}}),[e,a,c])}();return r.createElement(p.Provider,{value:n},t)}function m(){var e=(0,r.useContext)(p);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},2949:function(e,t,n){"use strict";n.d(t,{I:function(){return g},S:function(){return h}});var r=n(7294),o=n(412),a=n(9688),i=n(12),s=n(6668),c=r.createContext(void 0),l="theme",u=(0,i.WA)(l),d={light:"light",dark:"dark"},p=function(e){return e===d.dark?d.dark:d.light},f=function(e){return o.Z.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e)},m=function(e){u.set(p(e))};function h(e){var t=e.children,n=function(){var e=(0,s.L)().colorMode,t=e.defaultMode,n=e.disableSwitch,o=e.respectPrefersColorScheme,a=(0,r.useState)(f(t)),i=a[0],c=a[1];(0,r.useEffect)((function(){n&&u.del()}),[n]);var h=(0,r.useCallback)((function(e,n){void 0===n&&(n={});var r=n.persist,a=void 0===r||r;e?(c(e),a&&m(e)):(c(o?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:t),u.del())}),[o,t]);(0,r.useEffect)((function(){document.documentElement.setAttribute("data-theme",p(i))}),[i]),(0,r.useEffect)((function(){if(!n){var e=function(e){if(e.key===l){var t=u.get();null!==t&&h(p(t))}};return window.addEventListener("storage",e),function(){return window.removeEventListener("storage",e)}}}),[n,h]);var g=(0,r.useRef)(!1);return(0,r.useEffect)((function(){if(!n||o){var e=window.matchMedia("(prefers-color-scheme: dark)"),t=function(){window.matchMedia("print").matches||g.current?g.current=window.matchMedia("print").matches:h(null)};return e.addListener(t),function(){return e.removeListener(t)}}}),[h,n,o]),(0,r.useMemo)((function(){return{colorMode:i,setColorMode:h,get isDarkTheme(){return i===d.dark},setLightTheme:function(){h(d.light)},setDarkTheme:function(){h(d.dark)}}}),[i,h])}();return r.createElement(c.Provider,{value:n},t)}function g(){var e=(0,r.useContext)(c);if(null==e)throw new a.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:function(e,t,n){"use strict";n.d(t,{J:function(){return b},L5:function(){return g},Oh:function(){return y}});var r=n(7294),o=n(4104),a=n(9935),i=n(6668),s=n(3438),c=n(9688),l=n(12),u=function(e){return"docs-preferred-version-"+e},d={save:function(e,t,n){(0,l.WA)(u(e),{persistence:t}).set(n)},read:function(e,t){return(0,l.WA)(u(e),{persistence:t}).get()},clear:function(e,t){(0,l.WA)(u(e),{persistence:t}).del()}},p=function(e){return Object.fromEntries(e.map((function(e){return[e,{preferredVersionName:null}]})))};var f=r.createContext(null);function m(){var e=(0,o._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((function(){return Object.keys(e)}),[e]),a=(0,r.useState)((function(){return p(n)})),s=a[0],c=a[1];return(0,r.useEffect)((function(){c(function(e){var t=e.pluginIds,n=e.versionPersistence,r=e.allDocsData;return Object.fromEntries(t.map((function(e){return[e,(t=e,o=d.read(t,n),r[t].versions.some((function(e){return e.name===o}))?{preferredVersionName:o}:(d.clear(t,n),{preferredVersionName:null}))];var t,o})))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]),[s,(0,r.useMemo)((function(){return{savePreferredVersion:function(e,n){d.save(e,t,n),c((function(t){var r;return Object.assign({},t,((r={})[e]={preferredVersionName:n},r))}))}}}),[t])]}function h(e){var t=e.children,n=m();return r.createElement(f.Provider,{value:n},t)}function g(e){var t=e.children;return s.cE?r.createElement(h,null,t):r.createElement(r.Fragment,null,t)}function v(){var e=(0,r.useContext)(f);if(!e)throw new c.i6("DocsPreferredVersionContextProvider");return e}function b(e){var t;void 0===e&&(e=a.m);var n=(0,o.zh)(e),i=v(),s=i[0],c=i[1],l=s[e].preferredVersionName;return{preferredVersion:null!=(t=n.versions.find((function(e){return e.name===l})))?t:null,savePreferredVersionName:(0,r.useCallback)((function(t){c.savePreferredVersion(e,t)}),[c,e])}}function y(){var e=(0,o._r)(),t=v()[0];var n=Object.keys(e);return Object.fromEntries(n.map((function(n){return[n,(r=n,a=e[r],i=t[r].preferredVersionName,null!=(o=a.versions.find((function(e){return e.name===i})))?o:null)];var r,o,a,i})))}},1116:function(e,t,n){"use strict";n.d(t,{V:function(){return c},b:function(){return s}});var r=n(7294),o=n(9688),a=Symbol("EmptyContext"),i=r.createContext(a);function s(e){var t=e.children,n=e.name,o=e.items,a=(0,r.useMemo)((function(){return n&&o?{name:n,items:o}:null}),[n,o]);return r.createElement(i.Provider,{value:a},t)}function c(){var e=(0,r.useContext)(i);if(e===a)throw new o.i6("DocsSidebarProvider");return e}},3163:function(e,t,n){"use strict";n.d(t,{M:function(){return d},e:function(){return p}});var r=n(7294),o=n(3102),a=n(7524),i=n(1980),s=n(6668),c=n(9688),l=r.createContext(void 0);function u(){var e,t=(e=(0,o.HY)(),0===(0,s.L)().navbar.items.length&&!e.component),n=(0,a.i)(),c=!t&&"mobile"===n,l=(0,r.useState)(!1),u=l[0],d=l[1];(0,i.Rb)((function(){if(u)return d(!1),!1}));var p=(0,r.useCallback)((function(){d((function(e){return!e}))}),[]);return(0,r.useEffect)((function(){"desktop"===n&&d(!1)}),[n]),(0,r.useMemo)((function(){return{disabled:t,shouldRender:c,toggle:p,shown:u}}),[t,c,p,u])}function d(e){var t=e.children,n=u();return r.createElement(l.Provider,{value:n},t)}function p(){var e=r.useContext(l);if(void 0===e)throw new c.i6("NavbarMobileSidebarProvider");return e}},3102:function(e,t,n){"use strict";n.d(t,{HY:function(){return s},Zo:function(){return c},n2:function(){return i}});var r=n(7294),o=n(9688),a=r.createContext(null);function i(e){var t=e.children,n=(0,r.useState)({component:null,props:null});return r.createElement(a.Provider,{value:n},t)}function s(){var e=(0,r.useContext)(a);if(!e)throw new o.i6("NavbarSecondaryMenuContentProvider");return e[0]}function c(e){var t=e.component,n=e.props,i=(0,r.useContext)(a);if(!i)throw new o.i6("NavbarSecondaryMenuContentProvider");var s=i[1],c=(0,o.Ql)(n);return(0,r.useEffect)((function(){s({component:t,props:c})}),[s,t,c]),(0,r.useEffect)((function(){return function(){return s({component:null,props:null})}}),[s]),null}},9727:function(e,t,n){"use strict";n.d(t,{h:function(){return o},t:function(){return a}});var r=n(7294),o="navigation-with-keyboard";function a(){(0,r.useEffect)((function(){function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),function(){document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},6177:function(e,t,n){"use strict";n.d(t,{K:function(){return s},M:function(){return c}});var r=n(7294),o=n(2263),a=n(1980),i="q";function s(){return(0,a.Nc)(i)}function c(){var e=(0,o.Z)().siteConfig,t=e.baseUrl,n=e.themeConfig.algolia.searchPagePath;return(0,r.useCallback)((function(e){return""+t+n+"?"+i+"="+encodeURIComponent(e)}),[t,n])}},7524:function(e,t,n){"use strict";n.d(t,{i:function(){return l}});var r=n(7294),o=n(412),a={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function s(){return o.Z.canUseDOM?window.innerWidth>i?a.desktop:a.mobile:a.ssr}var c=!1;function l(){var e=(0,r.useState)((function(){return c?"ssr":s()})),t=e[0],n=e[1];return(0,r.useEffect)((function(){function e(){n(s())}var t=c?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),function(){window.removeEventListener("resize",e),clearTimeout(t)}}),[]),t}},5281:function(e,t,n){"use strict";n.d(t,{k:function(){return r}});var r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:function(e){return"theme-admonition-"+e}},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:function(e){return"theme-doc-sidebar-item-category-level-"+e},docSidebarItemLinkLevel:function(e){return"theme-doc-sidebar-item-link-level-"+e}},blog:{}}},3438:function(e,t,n){"use strict";n.d(t,{Wl:function(){return f},_F:function(){return g},cE:function(){return p},hI:function(){return _},lO:function(){return y},oz:function(){return w},s1:function(){return b},vY:function(){return k}});var r=n(7855),o=n(7294),a=n(6550),i=n(8790),s=n(4104),c=n(373),l=n(1116),u=n(7392),d=n(8596),p=!!s._r;function f(e){if(e.href)return e.href;for(var t,n=(0,r.Z)(e.items);!(t=n()).done;){var o=t.value;if("link"===o.type)return o.href;if("category"===o.type){var a=f(o);if(a)return a}}}var m=function(e,t){return void 0!==e&&(0,d.Mg)(e,t)},h=function(e,t){return e.some((function(e){return g(e,t)}))};function g(e,t){return"link"===e.type?m(e.href,t):"category"===e.type&&(m(e.href,t)||h(e.items,t))}function v(e){var t=e.sidebarItems,n=e.pathname,o=e.onlyCategories,a=void 0!==o&&o,i=[];return function e(t){for(var o,s=(0,r.Z)(t);!(o=s()).done;){var c=o.value;if("category"===c.type&&((0,d.Mg)(c.href,n)||e(c.items))||"link"===c.type&&(0,d.Mg)(c.href,n))return a&&"category"!==c.type||i.unshift(c),!0}return!1}(t),i}function b(){var e,t=(0,l.V)(),n=(0,a.TH)().pathname;return!1!==(null==(e=(0,s.gA)())?void 0:e.pluginData.breadcrumbs)&&t?v({sidebarItems:t.items,pathname:n}):null}function y(e){var t=(0,s.Iw)(e).activeVersion,n=(0,c.J)(e).preferredVersion,r=(0,s.yW)(e);return(0,o.useMemo)((function(){return(0,u.j)([t,n,r].filter(Boolean))}),[t,n,r])}function w(e,t){var n=y(t);return(0,o.useMemo)((function(){var t=n.flatMap((function(e){return e.sidebars?Object.entries(e.sidebars):[]})),r=t.find((function(t){return t[0]===e}));if(!r)throw new Error("Can't find any sidebar with id \""+e+'" in version'+(n.length>1?"s":"")+" "+n.map((function(e){return e.name})).join(", ")+'".\nAvailable sidebar ids are:\n- '+t.map((function(e){return e[0]})).join("\n- "));return r[1]}),[e,n])}function k(e,t){var n=y(t);return(0,o.useMemo)((function(){var t=n.flatMap((function(e){return e.docs})),r=t.find((function(t){return t.id===e}));if(!r){if(n.flatMap((function(e){return e.draftIds})).includes(e))return null;throw new Error("Couldn't find any doc with id \""+e+'" in version'+(n.length>1?"s":"")+' "'+n.map((function(e){return e.name})).join(", ")+'".\nAvailable doc ids are:\n- '+(0,u.j)(t.map((function(e){return e.id}))).join("\n- "))}return r}),[e,n])}function _(e){var t=e.route,n=e.versionMetadata,r=(0,a.TH)(),o=t.routes,s=o.find((function(e){return(0,a.LX)(r.pathname,e)}));if(!s)return null;var c=s.sidebar,l=c?n.docsSidebars[c]:void 0;return{docElement:(0,i.H)(o),sidebarName:c,sidebarItems:l}}},2128:function(e,t,n){"use strict";n.d(t,{p:function(){return o}});var r=n(2263);function o(e){var t=(0,r.Z)().siteConfig,n=t.title,o=t.titleDelimiter;return null!=e&&e.trim().length?e.trim()+" "+o+" "+n:n}},1980:function(e,t,n){"use strict";n.d(t,{Nc:function(){return l},Rb:function(){return s},_X:function(){return c}});var r=n(7294),o=n(6550),a=n(1688),i=n(9688);function s(e){!function(e){var t=(0,o.k6)(),n=(0,i.zX)(e);(0,r.useEffect)((function(){return t.block((function(e,t){return n(e,t)}))}),[t,n])}((function(t,n){if("POP"===n)return e(t,n)}))}function c(e){return t=function(t){return null===e?null:new URLSearchParams(t.location.search).get(e)},n=(0,o.k6)(),(0,a.useSyncExternalStore)(n.listen,(function(){return t(n)}),(function(){return t(n)}));var t,n}function l(e){var t,n,a=null!=(t=c(e))?t:"",i=(n=(0,o.k6)(),(0,r.useCallback)((function(e,t,r){var o=new URLSearchParams(n.location.search);t?o.set(e,t):o.delete(e),(null!=r&&r.push?n.push:n.replace)({search:o.toString()})}),[n]));return[a,(0,r.useCallback)((function(t,n){i(e,t,n)}),[i,e])]}},7392:function(e,t,n){"use strict";function r(e,t){return void 0===t&&(t=function(e,t){return e===t}),e.filter((function(n,r){return e.findIndex((function(e){return t(e,n)}))!==r}))}function o(e){return Array.from(new Set(e))}n.d(t,{j:function(){return o},l:function(){return r}})},833:function(e,t,n){"use strict";n.d(t,{FG:function(){return p},d:function(){return u},VC:function(){return f}});var r=n(7294),o=n(6010),a=n(5742),i=n(226);function s(){var e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var c=n(4996),l=n(2128);function u(e){var t=e.title,n=e.description,o=e.keywords,i=e.image,s=e.children,u=(0,l.p)(t),d=(0,c.C)().withBaseUrl,p=i?d(i,{absolute:!0}):void 0;return r.createElement(a.Z,null,t&&r.createElement("title",null,u),t&&r.createElement("meta",{property:"og:title",content:u}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),o&&r.createElement("meta",{name:"keywords",content:Array.isArray(o)?o.join(","):o}),p&&r.createElement("meta",{property:"og:image",content:p}),p&&r.createElement("meta",{name:"twitter:image",content:p}),s)}var d=r.createContext(void 0);function p(e){var t=e.className,n=e.children,i=r.useContext(d),s=(0,o.Z)(i,t);return r.createElement(d.Provider,{value:s},r.createElement(a.Z,null,r.createElement("html",{className:s})),n)}function f(e){var t=e.children,n=s(),a="plugin-"+n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,""),i="plugin-id-"+n.plugin.id;return r.createElement(p,{className:(0,o.Z)(a,i)},t)}},9688:function(e,t,n){"use strict";n.d(t,{i6:function(){return f},Qc:function(){return h},zX:function(){return d},D9:function(){return p},Ql:function(){return m}});var r=n(6528),o=n(4578);function a(e){return a=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},a(e)}var i=n(9611);function s(e,t,n){return s=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}()?Reflect.construct.bind():function(e,t,n){var r=[null];r.push.apply(r,t);var o=new(Function.bind.apply(e,r));return n&&(0,i.Z)(o,n.prototype),o},s.apply(null,arguments)}function c(e){var t="function"==typeof Map?new Map:void 0;return c=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,r)}function r(){return s(e,arguments,a(this).constructor)}return r.prototype=Object.create(e.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),(0,i.Z)(r,e)},c(e)}var l=n(7294),u=n(412).Z.canUseDOM?l.useLayoutEffect:l.useEffect;function d(e){var t=(0,l.useRef)(e);return u((function(){t.current=e}),[e]),(0,l.useCallback)((function(){return t.current.apply(t,arguments)}),[])}function p(e){var t=(0,l.useRef)();return u((function(){t.current=e})),t.current}var f=function(e){function t(t,n){var o,a,i;return(i=e.call(this)||this).name="ReactContextError",i.message="Hook "+(null!=(o=null==(a=i.stack)||null==(a=a.split("\n")[1])||null==(a=a.match((0,r.Z)(/at (?:\w+\.)?(\w+)/,{name:1})))?void 0:a.groups.name)?o:"")+" is called outside the <"+t+">. "+(null!=n?n:""),i}return(0,o.Z)(t,e),t}(c(Error));function m(e){var t=Object.entries(e);return t.sort((function(e,t){return e[0].localeCompare(t[0])})),(0,l.useMemo)((function(){return e}),t.flat())}function h(e){return function(t){var n=t.children;return l.createElement(l.Fragment,null,e.reduceRight((function(e,t){return l.createElement(t,null,e)}),n))}}},8022:function(e,t,n){"use strict";function r(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}n.d(t,{F:function(){return r}})},8596:function(e,t,n){"use strict";n.d(t,{Mg:function(){return i},Ns:function(){return s}});var r=n(7294),o=n(723),a=n(2263);function i(e,t){var n=function(e){var t;return null==(t=!e||e.endsWith("/")?e:e+"/")?void 0:t.toLowerCase()};return n(e)===n(t)}function s(){var e=(0,a.Z)().siteConfig.baseUrl;return(0,r.useMemo)((function(){return function(e){var t=e.baseUrl;function n(e){return e.path===t&&!0===e.exact}function r(e){return e.path===t&&!e.exact}return function e(t){if(0!==t.length)return t.find(n)||e(t.filter(r).flatMap((function(e){var t;return null!=(t=e.routes)?t:[]})))}(e.routes)}({routes:o.Z,baseUrl:e})}),[e])}},2466:function(e,t,n){"use strict";n.d(t,{Ct:function(){return f},OC:function(){return c},RF:function(){return d},o5:function(){return p}});var r=n(7294),o=n(412),a=n(2389),i=n(9688);var s=r.createContext(void 0);function c(e){var t,n=e.children,o=(t=(0,r.useRef)(!0),(0,r.useMemo)((function(){return{scrollEventsEnabledRef:t,enableScrollEvents:function(){t.current=!0},disableScrollEvents:function(){t.current=!1}}}),[]));return r.createElement(s.Provider,{value:o},n)}function l(){var e=(0,r.useContext)(s);if(null==e)throw new i.i6("ScrollControllerProvider");return e}var u=function(){return o.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null};function d(e,t){void 0===t&&(t=[]);var n=l().scrollEventsEnabledRef,o=(0,r.useRef)(u()),a=(0,i.zX)(e);(0,r.useEffect)((function(){var e=function(){if(n.current){var e=u();a(e,o.current),o.current=e}},t={passive:!0};return e(),window.addEventListener("scroll",e,t),function(){return window.removeEventListener("scroll",e,t)}}),[a,n].concat(t))}function p(){var e,t,n,o=l(),a=(e=(0,r.useRef)({elem:null,top:0}),t=(0,r.useCallback)((function(t){e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,r.useCallback)((function(){var t=e.current,n=t.elem,r=t.top;if(!n)return{restored:!1};var o=n.getBoundingClientRect().top-r;return o&&window.scrollBy({left:0,top:o}),e.current={elem:null,top:0},{restored:0!==o}}),[]),(0,r.useMemo)((function(){return{save:t,restore:n}}),[n,t])),i=(0,r.useRef)(void 0),s=(0,r.useCallback)((function(e){a.save(e),o.disableScrollEvents(),i.current=function(){var e=a.restore().restored;if(i.current=void 0,e){window.addEventListener("scroll",(function e(){o.enableScrollEvents(),window.removeEventListener("scroll",e)}))}else o.enableScrollEvents()}}),[o,a]);return(0,r.useLayoutEffect)((function(){queueMicrotask((function(){return null==i.current?void 0:i.current()}))})),{blockElementScrollPositionUntilNextRender:s}}function f(){var e=(0,r.useRef)(null),t=(0,a.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:function(n){e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),function(){}}(n):function(e){var t=null,n=document.documentElement.scrollTop>e;return function r(){var o=document.documentElement.scrollTop;(n&&o>e||!n&&o0?(M(!1),B(!0)):(M(!0),B(!1),P(!0)),Y)for(var o,i=function(){var e=o.value,r=n.find((function(t){return t.name===e.parameter}));t.push({name:e.parameter,value:r&&r.value||e.required})},s=(0,r.Z)(Y.items);!(o=s()).done;)i();Z(t)}),[]),(0,i.useEffect)((function(){document&&document.body&&O&&Y?document.body.classList.add("preventScrollDocument"):document.body.classList.remove("preventScrollDocument")}),[O]),i.createElement(i.Fragment,null,Y&&i.createElement("div",{className:l+" "+(O?"":_),ref:z},R&&i.createElement("div",{className:u},i.createElement("h2",null,null==Y?void 0:Y.notice_title),i.createElement("div",{dangerouslySetInnerHTML:{__html:null!=(e=null==Y?void 0:Y.notice_body)?e:""},className:"primaryParagraph"}),i.createElement("div",{className:p},i.createElement("button",{onClick:function(){M(!1),B(!0)},className:f},null!=(t=null==Y?void 0:Y.manage_button_text)?t:""),i.createElement("button",{onClick:function(){var e=null==Y?void 0:Y.items.map((function(e){return{name:e.parameter,value:!0}}));a.set("cookie-prefs",JSON.stringify(e),{expires:365}),window.location.reload()}},null!=(n=null==Y?void 0:Y.accept_all_button_text)?n:""))),F&&i.createElement("div",{className:d},i.createElement("h2",null,null==Y?void 0:Y.manage_title),i.createElement("div",{dangerouslySetInnerHTML:{__html:null!=(o=null==Y?void 0:Y.manage_body)?o:""},className:"primaryParagraph "+m}),i.createElement("div",{className:h},null==Y||null==(N=Y.items)?void 0:N.map((function(e){var t,n,r,o,a;return i.createElement("div",{key:e.title,className:g},i.createElement("div",{className:b},i.createElement("p",{className:"primaryParagraph"},null==e?void 0:e.title),i.createElement("input",{type:"checkbox",id:"cookie-"+(null==e?void 0:e.title),className:y,disabled:null!=(t=null==e?void 0:e.required)&&t,checked:(r=e.parameter,a=U.find((function(e){return e.name===r})),null!=(o=null==a?void 0:a.value)&&o),onChange:function(){G(e.parameter)}}),i.createElement("label",{htmlFor:"cookie-"+(null==e?void 0:e.title),tabIndex:0,className:" "+w+" "+(null!=e&&e.required?k:""),onKeyUp:function(t){return function(e,t){"enter"===e.key.toLocaleLowerCase()&&G(t)}(t,e.parameter)}},c.Z.check)),i.createElement("div",{dangerouslySetInnerHTML:{__html:null!=(n=null==e?void 0:e.description)?n:""},className:"secondaryParagraph "+v}))}))),i.createElement("div",{className:p},i.createElement("button",{onClick:function(){var e=U.map((function(e){return{name:e.name,value:e.value}}));a.set("cookie-prefs",JSON.stringify(e)),window.location.reload()}},null!=(L=null==Y?void 0:Y.confirm_button_text)?L:"")))))}},6010:function(e,t,n){"use strict";function r(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t=0;p--){var f=i[p];"."===f?a(i,p):".."===f?(a(i,p),d++):d&&(a(i,p),d--)}if(!l)for(;d--;d)i.unshift("..");!l||""===i[0]||i[0]&&o(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m},s=n(8776);function c(e){return"/"===e.charAt(0)?e:"/"+e}function l(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function f(e,t,n,o){var a;"string"==typeof e?(a=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var a=t.indexOf("?");return-1!==a&&(n=t.substr(a),t=t.substr(0,a)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),a.state=t):(void 0===(a=(0,r.Z)({},e)).pathname&&(a.pathname=""),a.search?"?"!==a.search.charAt(0)&&(a.search="?"+a.search):a.search="",a.hash?"#"!==a.hash.charAt(0)&&(a.hash="#"+a.hash):a.hash="",void 0!==t&&void 0===a.state&&(a.state=t));try{a.pathname=decodeURI(a.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+a.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(a.key=n),o?a.pathname?"/"!==a.pathname.charAt(0)&&(a.pathname=i(a.pathname,o.pathname)):a.pathname=o.pathname:a.pathname||(a.pathname="/"),a}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var a="function"==typeof e?e(t,n):e;"string"==typeof a?"function"==typeof r?r(a,o):o(!0):o(!1!==a)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,o):n.push(o),d({action:r,location:o,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",o=f(e,t,h(),w.location);u.confirmTransitionTo(o,r,n,(function(e){e&&(w.entries[w.index]=o,d({action:r,location:o}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t
'};function o(e,t,n){return en?n:e}function a(e){return 100*(-1+e)}function i(e,t,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+a(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+a(e)+"%,0)"}:{"margin-left":a(e)+"%"}).transition="all "+t+"ms "+n,o}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,r.minimum,1),n.status=1===e?null:e;var a=n.render(!t),l=a.querySelector(r.barSelector),u=r.speed,d=r.easing;return a.offsetWidth,s((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),c(l,i(e,u,d)),1===e?(c(a,{transition:"none",opacity:1}),a.offsetWidth,setTimeout((function(){c(a,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var o,i=t.querySelector(r.barSelector),s=e?"-100":a(n.status||0),l=document.querySelector(r.parent);return c(i,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&f(o),l!=document.body&&u(l,"nprogress-custom-parent"),l.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),c=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,o=e.length,a=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((r=e[o]+a)in n)return r;return t}function o(e){return e=n(e),t[e]||(t[e]=r(e))}function a(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,r,o=arguments;if(2==o.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&a(e,n,r);else a(e,o[1],o[2])}}();function l(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;l(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);l(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(o="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=o)},7418:function(e){"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(o){return!1}}()?Object.assign:function(e,o){for(var a,i,s=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),c=1;c=d.reach);E+=_.value.length,_=_.next){var C=_.value;if(t.length>e.length)return;if(!(C instanceof o)){var x,S=1;if(b){if(!(x=a(k,E,e,v))||x.index>=e.length)break;var T=x.index,N=x.index+x[0].length,L=E;for(L+=_.value.length;T>=L;)L+=(_=_.next).value.length;if(E=L-=_.value.length,_.value instanceof o)continue;for(var A=_;A!==t.tail&&(Ld.reach&&(d.reach=R);var M=_.prev;if(P&&(M=c(t,M,P),E+=P.length),l(t,M,S),_=c(t,M,new o(p,g?r.tokenize(O,g):O,y,O)),I&&c(t,_,I),S>1){var D={cause:p+","+m,reach:R};i(e,t,n,_.prev,E,D),d&&D.reach>d.reach&&(d.reach=D.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function c(e,t,n){var r=t.next,o={value:n,prev:t,next:r};return t.next=o,r.prev=o,e.length++,o}function l(e,t,n){for(var r=t.next,o=0;o"+a.content+""},r}(),r=n;n.default=n,r.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},r.languages.markup.tag.inside["attr-value"].inside.entity=r.languages.markup.entity,r.languages.markup.doctype.inside["internal-subset"].inside=r.languages.markup,r.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(r.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:r.languages[t]},n.cdata=/^$/i;var o={"included-cdata":{pattern://i,inside:n}};o["language-"+t]={pattern:/[\s\S]+/,inside:r.languages[t]};var a={};a[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:o},r.languages.insertBefore("markup","cdata",a)}}),Object.defineProperty(r.languages.markup.tag,"addAttribute",{value:function(e,t){r.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:r.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),r.languages.html=r.languages.markup,r.languages.mathml=r.languages.markup,r.languages.svg=r.languages.markup,r.languages.xml=r.languages.extend("markup",{}),r.languages.ssml=r.languages.xml,r.languages.atom=r.languages.xml,r.languages.rss=r.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var o=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],a=r.variable[1].inside,i=0;i]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},r.languages.c=r.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),r.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),r.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},r.languages.c.string],char:r.languages.c.char,comment:r.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:r.languages.c}}}}),r.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete r.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(r),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(r),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},o={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:o,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:o})}(r),r.languages.javascript=r.languages.extend("clike",{"class-name":[r.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),r.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,r.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:r.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:r.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:r.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:r.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:r.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),r.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:r.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),r.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),r.languages.markup&&(r.languages.markup.tag.addInlined("script","javascript"),r.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),r.languages.js=r.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(r),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",o=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),a=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+o+"|"+a+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(a),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(r),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,o=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),a=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+o+a+"(?:"+o+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+o+a+")(?:"+o+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+o+")"+a+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+o+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n",quot:'"'},c=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(r),r.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:r.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},r.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n0)){var s=p(/^\{$/,/^\}$/);if(-1===s)continue;for(var c=n;c=0&&f(l,"variable-input")}}}}function u(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,o=r.inside["interpolation-punctuation"],a=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function s(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function c(t,n,r){var o={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",o),o.tokens=e.tokenize(o.code,o.grammar),e.hooks.run("after-tokenize",o),o.tokens}function l(t){var n={};n["interpolation-punctuation"]=o;var a=e.tokenize(t,n);if(3===a.length){var i=[1,1];i.push.apply(i,c(a[1],e.languages.javascript,"javascript")),a.splice.apply(a,i)}return new e.Token("interpolation",a,r.alias,t)}function u(t,n,r){var o=e.tokenize(t,{interpolation:{pattern:RegExp(a),lookbehind:!0}}),i=0,u={},d=c(o.map((function(e){if("string"==typeof e)return e;for(var n,o=e.content;-1!==t.indexOf(n=s(i++,r)););return u[n]=o,n})).join(""),n,r),p=Object.keys(u);return i=0,function e(t){for(var n=0;n=p.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var o=p[i],a="string"==typeof r?r:r.content,s=a.indexOf(o);if(-1!==s){++i;var c=a.substring(0,s),d=l(u[o]),f=a.substring(s+o.length),m=[];if(c&&m.push(c),m.push(d),f){var h=[f];e(h),m.push.apply(m,h)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var g=r.content;Array.isArray(g)?e(g):e([g])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function p(e){return"string"==typeof e?e:Array.isArray(e)?e.map(p).join(""):p(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,o=n.length;r]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(r),function(e){function t(e,t){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r*\.{3}(?:[^{}]|)*\})/.source;function a(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return o})),RegExp(e,t)}o=a(o).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=a(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:a(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:a(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},s=function(t){for(var n=[],r=0;r0&&n[n.length-1].tagName===i(o.content[0].content[1])&&n.pop():"/>"===o.content[o.content.length-1].content||n.push({tagName:i(o.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===o.type&&"{"===o.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===o.type&&"}"===o.content?n[n.length-1].openedBraces--:a=!0),(a||"string"==typeof o)&&n.length>0&&0===n[n.length-1].openedBraces){var c=i(o);r0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(c=i(t[r-1])+c,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",c,null,c)}o.content&&"string"!=typeof o.content&&s(o.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||s(e.tokens)}))}(r),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],o=[];/^\w+$/.test(n)||o.push(/\w+/.exec(n)[0]),"diff"===n&&o.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:o,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(r),r.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},r.languages.go=r.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),r.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete r.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,o,a){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof a&&!a(e))return e;for(var o,s=i.length;-1!==n.code.indexOf(o=t(r,s));)++s;return i[s]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var o=0,a=Object.keys(n.tokenStack);!function i(s){for(var c=0;c=a.length);c++){var l=s[c];if("string"==typeof l||l.content&&"string"==typeof l.content){var u=a[o],d=n.tokenStack[u],p="string"==typeof l?l:l.content,f=t(r,u),m=p.indexOf(f);if(m>-1){++o;var h=p.substring(0,m),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),v=p.substring(m+f.length),b=[];h&&b.push.apply(b,i([h])),b.push(g),v&&b.push.apply(b,i([v])),"string"==typeof l?s.splice.apply(s,[c,1].concat(b)):l.content=b}}else l.content&&i(l.content)}return s}(n.tokens)}}}})}(r),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(r),r.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},r.languages.webmanifest=r.languages.json,r.languages.less=r.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),r.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),r.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},r.languages.objectivec=r.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete r.languages.objectivec["class-name"],r.languages.objc=r.languages.objectivec,r.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},r.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},r.languages.python["string-interpolation"].inside.interpolation.inside.rest=r.languages.python,r.languages.py=r.languages.python,r.languages.reason=r.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),r.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete r.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(r),r.languages.scss=r.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),r.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),r.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),r.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),r.languages.scss.atrule.inside.rest=r.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(r),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(r),r.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/},t.Z=r},767:function(){!function(e){for(var t=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|)*\*\//.source,n=0;n<2;n++)t=t.replace(//g,(function(){return t}));t=t.replace(//g,(function(){return/[^\s\S]/.source})),e.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+t),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(Prism)},4294:function(e,t,n){var r={"./prism-rust":767};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=4294},2703:function(e,t,n){"use strict";var r=n(414);function o(){}function a(){}a.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,a,i){if(i!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:o};return n.PropTypes=n,n}},5697:function(e,t,n){e.exports=n(2703)()},414:function(e){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:function(e,t,n){"use strict";var r=n(7294),o=n(7418),a=n(3840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n