1(window.webpackJsonp=window.webpackJsonp||[]).push([[4],{173:function(t,e,a){"use strict";a.r(e);var n=a(0),s=Object(n.a)({},function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticClass:"content"},[t._m(0),t._v(" "),t._m(1),t._v(" "),a("p",[t._v("The entire state of your Lotion application is held in a single state tree; one big JavaScript object. The structure of the data in this state tree is up to you.")]),t._v(" "),a("p",[t._v("Events will happen (eg. users submitting transactions, new blocks being created) which will trigger a set of handlers for that specific event type, and these handlers may mutate the state tree.")]),t._v(" "),a("p",[t._v("Under the hood, your state tree is kept in a "),a("a",{attrs:{href:"https://en.wikipedia.org/wiki/Merkle_tree",target:"_blank",rel:"noopener noreferrer"}},[t._v("Merkle tree"),a("OutboundLink")],1),t._v(" by the "),a("a",{attrs:{href:"https://github.com/mappum/merk",target:"_blank",rel:"noopener noreferrer"}},[t._v("merk"),a("OutboundLink")],1),t._v(" module, so even if your state tree grows very large, your application won't slow down. This also enables efficient queries of arbitrary subtrees of the state.")]),t._v(" "),t._m(2),t._v(" "),a("p",[t._v("Transactions are how users interact with your application. A transaction is a JavaScript object that describes a change to your application state.")]),t._v(" "),t._m(3),t._v(" "),t._m(4),t._v(" "),a("p",[t._v("Before any transaction reaches your application's middleware stack, the validators of your application have already reached consensus about a global ordering for the transactions.")]),t._v(" "),t._m(5),t._v(" "),a("p",[t._v("Block handlers are functions that can mutate the application state or validator set. They're invoked once per Tendermint block.")]),t._v(" "),t._m(6),t._v(" "),t._m(7),t._v(" "),t._m(8),t._v(" "),a("p",[t._v("A "),a("code",[t._v("context")]),t._v(" parameter is available for accessing metadata about the the blockchain, such as "),a("a",{attrs:{href:"https://tendermint.com/docs/spec/consensus/bft-time.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("BFT time"),a("OutboundLink")],1),t._v(", block height, or validator set data from Tendermint.")]),t._v(" "),t._m(9),t._v(" "),a("p",[t._v("In Ethereum, applications exist in a single namespace, which makes interoperability between applications very easy. To call another contract's method, you just need to know its address.")]),t._v(" "),a("p",[t._v("In Lotion, we have a convention of treating the hash of the "),a("a",{attrs:{href:"https://tendermint.com/docs/tendermint-core/using-tendermint.html#initialize",target:"_blank",rel:"noopener noreferrer"}},[t._v("genesis.json"),a("OutboundLink")],1),t._v(" from Tendermint as our application's global identifier. See an example of how we make use of this in the next section.")]),t._v(" "),t._m(10),t._v(" "),a("p",[t._v("Lotion comes with a pure JavaScript light client. The "),a("a",{attrs:{href:"https://github.com/keppel/lotion-connect",target:"_blank",rel:"noopener noreferrer"}},[t._v("lotion-connect"),a("OutboundLink")],1),t._v(" can be used to query for the latest application state and send transactions from Node or the browser.")]),t._v(" "),a("p",[t._v("You can connect to an application using its GCI without knowing the IP of a full node in advance. The client will attempt to reach a full node for the application through the Bittorrent DHT, multicast DNS, and peer exchange servers.")]),t._v(" "),a("p",[t._v("The light client uses a "),a("a",{attrs:{href:"https://github.com/mappum/proxmise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Proxmise-based"),a("OutboundLink")],1),t._v(" API, so an efficient query of a state subtree might look like this:")]),t._v(" "),t._m(11),t._m(12),t._v(" "),a("p",[t._v("Lotion is a tool for writing Cosmos zones. Once the design for IBC has been finalized, you will be able to connect Lotion apps with apps written in any other IBC-compatible framework.")])])},[function(){var t=this.$createElement,e=this._self._c||t;return e("h1",{attrs:{id:"concepts"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#concepts","aria-hidden":"true"}},[this._v("#")]),this._v(" Concepts")])},function(){var t=this.$createElement,e=this._self._c||t;return e("h2",{attrs:{id:"the-state-tree"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#the-state-tree","aria-hidden":"true"}},[this._v("#")]),this._v(" The State Tree")])},function(){var t=this.$createElement,e=this._self._c||t;return e("h2",{attrs:{id:"transaction-handlers"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#transaction-handlers","aria-hidden":"true"}},[this._v("#")]),this._v(" Transaction Handlers")])},function(){var t=this.$createElement,e=this._self._c||t;return e("p",[this._v("A transaction handler is a function which maps a "),e("code",[this._v("(state, transaction)")]),this._v(" pair to a deterministic state mutation.")])},function(){var t=this.$createElement,e=this._self._c||t;return e("p",[this._v("For many small applications, a single handler is all you need. For larger applications, you can build up a stack of transaction handling middleware through multiple calls to "),e("code",[this._v("app.use(fn)")])])},function(){var t=this.$createElement,e=this._self._c||t;return e("h2",{attrs:{id:"block-handlers"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#block-handlers","aria-hidden":"true"}},[this._v("#")]),this._v(" Block Handlers")])},function(){var t=this.$createElement,e=this._self._c||t;
1return e("h2",{attrs:{id:"initializers"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#initializers","aria-hidden":"true"}},[this._v("#")]),this._v(" Initializers")])},function(){var t=this.$createElement,e=this._self._c||t;return e("p",[this._v("Initializers are functions that can set up your initial state. They take "),e("code",[this._v("(initialState, context)")]),this._v(" and should mutate your state accordingly. These functions will always be invoked before any transactions are processed.")])},function(){var t=this.$createElement,e=this._self._c||t;return e("h2",{attrs:{id:"context-object"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#context-object","aria-hidden":"true"}},[this._v("#")]),this._v(" Context Object")])},function(){var t=this.$createElement,e=this._self._c||t;return e("h2",{attrs:{id:"global-chain-identifier-gci"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#global-chain-identifier-gci","aria-hidden":"true"}},[this._v("#")]),this._v(" Global Chain Identifier (GCI)")])},function(){var t=this.$createElement,e=this._self._c||t;return e("h2",{attrs:{id:"light-clients"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#light-clients","aria-hidden":"true"}},[this._v("#")]),this._v(" Light Clients")])},function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" connect "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'lotion'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" state "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("connect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("GCI")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" myBalance "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" state"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("accounts"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("myAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("balance\n")])])])},function(){var t=this.$createElement,e=this._self._c||t;return e("h2",{attrs:{id:"ibc-and-cosmos-interoperability"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#ibc-and-cosmos-interoperability","aria-hidden":"true"}},[this._v("#")]),this._v(" IBC and Cosmos Interoperability")])}],!1,null,null,null);s.options.__file="advanced.md";e.default=s.exports}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.