✨ Lotion ✨
Smooth, easy blockchain apps. Powered by Tendermint consensus.
Lotion is a new way to create blockchain apps in JavaScript, which aims to make writing new blockchains fast and fun. It builds on top of Tendermint using the ABCI protocol. Lotion lets you write secure, scalable applications that can easily interoperate with other blockchains on the Cosmos Network using IBC.
Lotion itself is a tiny framework; its true power comes from the network of small, focused modules built upon it. Adding a fully-featured cryptocurrency to your blockchain, for example, takes only a few lines of code.
Note: the security of this code has not yet been evaluated. If you expect your app to secure real value, please use Cosmos SDK instead.
Installation
Lotion requires node v7.6.0 or higher.
$ npm install lotion
Usage
app.js
:
let lotion = require('lotion')
let app = lotion({
initialState: {
count: 0
}
})
app.use(function (state, tx) {
if(state.count === tx.nonce) {
state.count++
}
})
app.listen(3000)
run node app.js
, then:
$ curl http://localhost:3000/state
# { "count": 0 }
$ curl http://localhost:3000/txs -d '{ "nonce": 0 }'
# { "ok": true }
$ curl http://localhost:3000/state
# { "count": 1 }
Introduction
Lotion lets you build blockchains. At any moment in time, the whole state of your blockchain is represented by a single JavaScript object called the state
.
Users will create transactions
: JavaScript objects that tell the application how to mutate the blockchain's state
.
Every user who runs your Lotion app will interact with the same blockchain. Anyone can create a transaction
, and it will automagically find its way to everyone else running the app and mutate their state
. Everyone's state
objects will constantly be kept in sync with each other.
A Lotion application is often a single function of signature (state, tx)
which mutates your blockchain's state
in response to a transaction tx
. Both are just objects.
This cosmic wizardry is made possible by a magic piece of software named Tendermint which exists specifically for synchronizing state machines across networks.
Blockchains and Tendermint
The goal of a blockchain is to represent a single state being concurrently edited. In order to avoid conflicts between concurrent edits, it represents the state as a ledger: a series of transformations (transactions) applied to an initial state. The blockchain must allow all connected nodes to agree about which transformations are valid, and their ordering within the ledger.
To accomplish this, a blockchain is composed of three protocols: the network protocol, consensus protocol, and transaction protocol.
The network protocol is how nodes in the network tell each other about new transactions, blocks, and other nodes; usually a p2p gossip network.
The consensus protocol is the set of rules that nodes should follow to determine which particular ordered set of transformations should be in the ledger at a given moment. In Bitcoin, the chain with the highest difficulty seen by a node is treated as authoritatively correct.
The transaction protocol describes what makes transactions valid, and how they should mutate the blockchain's state.
When you're writing a Lotion app, you're only responsible for writing the transaction protocol. Under the hood, Tendermint is handling the consensus and network protocols. When you start your lotion app, a Tendermint node is also started which will handle all of the communication with other nodes running your lotion app.
Examples
name | description |
---|---|
lotion-chat | chat and collaborative haikus on lotion |
lotion-coin | cryptocurrency on lotion |
Contributors
Lotion is a cosmic journey for the mind brought to you by:
Judd 💻 📖 🤔 |
Matt Bell 💻 🤔 |
Jordan Bibla 🎨 |
Gautier Marin 📝 |
---|
Contributions of any kind welcome!
API
let app = require('lotion')(opts)
Create a new Lotion app.
Here are the default options for opts
which you can override:
{
devMode: false, // set this true to wipe blockchain data between runs
initialState: {}, // initial blockchain state
keys: '', // path to keys.json. generates own keys if not specified.
genesis: '', // path to genesis.json. generates new one if not specified.
peers: [], // array of '<host>:<p2pport>' of initial tendermint nodes to connect to. does automatic peer discovery if not specified.
logTendermint: false, // if true, shows all output from the underlying tendermint process
createEmptyBlocks: true, // if false, Tendermint will not create empty blocks which may result in a reduced blockchain file size
lite: false, // whether to run in light client mode. if true, must also specify a target.
target: null, // '<host>:<rpcport>' of target to connect to and light client verify
p2pPort: 46658, // port to use for tendermint peer connections
tendermintPort: 46657 // port to use for tendermint rpc
}
app.use(function(state, tx, chainInfo) { ... })
Register a transaction handler. Given a state
and tx
object, mutate state
accordingly.
Transaction handlers will be called for every transaction, in the same order you passed them to app.use()
.
Transaction handlers must be deterministic: for a given set of state
/tx
/chainInfo
inputs, you must mutate state
in the same way.
chainInfo
is an object like:
{
height: 42, // number of blocks committed so far. usually 1 new block per second.
validators: {
'<some pub key hex>' : 20, // voting power distribution for validators. requires understanding tendermint.
'<other pub key hex>': 147 // it's ok if you're not sure what this means, this is usually hidden from you.
}
}
If you'd like to change how much voting power a validator should have, simply mutate chainInfo.validators[pubKey] at any point!
app.useBlock(function(state, chainInfo) { ... })
Add middleware to be called once per block, even if there haven't been any transactions. Should mutate state
, see above to read more about chainInfo
.
Most things that you'd use a block handler for can and should be done as transactions
.
app.listen(port)
Starts Lotion app, exposes http server on port
.
HTTP API
Lotion exposes a few endpoints for interacting with your blockchain. Lotion only listens for connections from localhost. The HTTP API is how you should connect to your Lotion blockchain to your UI -- the UI and Lotion app should run on the same machine.
GET /state
This will return your app's most recent state as JSON.
$ curl http://localhost:3000/state
# {"count": 0}
POST /txs
Create a new transaction and submit it to the network.
$ curl http://localhost:3000/txs -d '{}'
# {"state": {"count": 1},"ok": true}
GET /txs
Returns an array of transactions that have been committed to the blockchain.
$ curl http://localhost:3000/txs
# [{"count": 0}]
GET /info
Get some info about the node, such as its validator public key.
$ curl http://localhost:3000/info
# {"pubKey":"4D9471998DC5A60463B5CF219E4410521112CF578FFAD17C652AEC5D393297C2"}
GET,POST /tendermint/*
Proxies to underlying tendermint node.
Links
- go read more at https://lotionjs.com!
License
MIT