No description, website, or topics provided.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


A lean Ethereum node with interchangeable consensus.

LondonCoin is building the improved core utilizing "Push-Pull" algorithm. Original code provided by Mosaic Networks.

We took the Go-Ethereum implementation (Geth) and extracted the EVM and Trie components to create a lean and modular version with interchangeable consensus.

The EVM is a virtual machine specifically designed to run untrusted code on a network of computers. Every transaction applied to the EVM modifies the State which is persisted in a Merkle Patricia tree. This data structure allows to simply check if a given transaction was actually applied to the VM and can reduce the entire State to a single hash (merkle root) rather analogous to a fingerprint.

The EVM is meant to be used in conjunction with a system that broadcasts transactions across network participants and ensures that everyone executes the same transactions in the same order. Ethereum uses a Blockchain and a Proof of Work consensus algorithm. EVM-Lite makes it easy to use any consensus system, including Londoncoin


+----------+    |  +-------------+         +-------------+  |       
|          |    |  | Service     |         | State       |  |
|  Client  <-----> |             | <------ |             |  |
|          |    |  | -API        |         | -EVM        |  |
+----------+    |  | -Keystore   |         | -Trie       |  |
                |  |             |         | -Database   |  |
                |  +-------------+         +-------------+  |
                |         |                       ^         |     
                |         v                       |         |
                |  +-------------------------------------+  |
                |  | Engine                              |  |
                |  |                                     |  |
                |  |       +----------------------+      |  |
                |  |       | Consensus            |      |  |
                |  |       +----------------------+      |  |
                |  |                                     |  |
                |  +-------------------------------------+  |
                |                                           |

Consensus Implementations:

  • SOLO: No Consensus. Transactions are relayed directly from Service to State

  • LondonCoin: Inmemory LondonCoin node.

  • RAFT: Hashicorp implementation of Raft (limited).

more to come...


Each consensus has its own subcommand evml [consensus], and its own configuration flags.

EVM-Lite node

  evml [command]

Available Commands:
  babble      Run the evm-lite node with LondonCoin consensus
  help        Help about any command
  raft        Run the evm-lite node with Raft consensus
  solo        Run the evm-lite node with Solo consensus (no consensus)
  version     Show version info

  -d, --datadir string        Top-level directory for configuration and data (default "/home/user/.evm-lite")
      --eth.cache int         Megabytes of memory allocated to internal caching (min 16MB / database forced) (default 128)
      --eth.db string         Eth database file (default "/home/user/.evm-lite/eth/chaindata")
      --eth.genesis string    Location of genesis file (default "/home/user/.evm-lite/eth/genesis.json")
      --eth.keystore string   Location of Ethereum account keys (default "/home/user/.evm-lite/eth/keystore")
      --eth.listen string     Address of HTTP API service (default ":8080")
      --eth.pwd string        Password file to unlock accounts (default "/home/user/.evm-lite/eth/pwd.txt")
  -h, --help                  help for evml
      --log string            debug, info, warn, error, fatal, panic (default "debug")

Use "evml [command] --help" for more information about a command.

Options can also be specified in a evml.toml file in the datadir.

ex (evml.toml):

db = "/eth.db"


The application writes data and reads configuration from the directory specified by the --datadir flag. The directory structure must respect the following stucture:

host:~/.evm-lite$ tree
├── babble
│   ├── peers.json
│   └── priv_key.pem
├── eth
│   ├── genesis.json
│   ├── keystore
│   │   └── UTC--2018-10-14T11-12-24.412349157Z--633139fa62d5c27f454259ba59fc34773bd19457
│   └── pwd.txt
└── evml.toml

The above example shows a babble folder, but the general idea is that consensus configuration goes in a separate folder from the Ethereum configuration.

The Ethereum genesis file defines Ethereum accounts and is stripped of all
the Ethereum POW stuff. This file is useful to predefine a set of accounts
that own all the initial Ether at the inception of the network.

Example Ethereum genesis.json defining two account:

   "alloc": {
        "629007eb99ff5c3539ada8a5800847eacfc25727": {
            "balance": "1337000000000000000000"
        "e32e14de8b81d8d3aedacb1868619c74a68feab0": {
            "balance": "1337000000000000000000"

It is possible to enable evm-lite to control certain accounts by providing a
list of encrypted private keys in the keystore directory. With these private keys, evm-lite will be able to sign transactions on behalf of the accounts associated with the keys.

host:~/.evm-lite/eth/keystore$ tree
├── UTC--2016-02-01T16-52-27.910165812Z--629007eb99ff5c3539ada8a5800847eacfc25727
├── UTC--2016-02-01T16-52-28.021010343Z--e32e14de8b81d8d3aedacb1868619c74a68feab0

These keys are protected by a password. Use the eth.pwd flag to specify the location of the password file.

Needless to say you should not reuse these addresses and private keys


EVM-Lite will use a LevelDB database to persist state objects. The file of the
database can be specified with the eth.db flag which defaults to <datadir>/eth/chaindata.

If a database already exists when starting a new evm-lite instance, the state
will be set to the one corresponding to the last committed block.


The Service exposes an API at the address specified by the --eth.listen flag for clients to interact with Ethereum.

Get controlled accounts

This endpoint returns all the accounts that are controlled by the evm-lite instance. These are the accounts whose private keys are present in the keystore.


host:~$ curl http://[api_addr]/accounts -s | json_pp
   "accounts" : [
         "address" : "0x629007eb99ff5c3539ada8a5800847eacfc25727",
         "balance" : 1337000000000000000000,
         "nonce": 0
         "address" : "0xe32e14de8b81d8d3aedacb1868619c74a68feab0",
         "balance" : 1337000000000000000000,
         "nonce": 0

Get any account

This method allows retrieving the information about any account, not just the ones whose keys are included in the keystore.

host:~$ curl http://[api_addr]/account/0x629007eb99ff5c3539ada8a5800847eacfc25727 -s | json_pp

Send transactions from controlled accounts

Send a transaction from an account controlled by the evm-lite instance. The transaction will be signed by the service since the corresponding private key is present in the keystore.

example: Send Ether between accounts

host:~$ curl -X POST http://[api_addr]/tx -d '{"from":"0x629007eb99ff5c3539ada8a5800847eacfc25727","to":"0xe32e14de8b81d8d3aedacb1868619c74a68feab0","value":6666}' -s | json_pp
   "txHash" : "0xeeeed34877502baa305442e3a72df094cfbb0b928a7c53447745ff35d50020bf"

Get Transaction receipt


host:~$ curl http://[api_addr]/tx/0xeeeed34877502baa305442e3a72df094cfbb0b928a7c53447745ff35d50020bf -s | json_pp
   "to" : "0xe32e14de8b81d8d3aedacb1868619c74a68feab0",
   "root" : "0xc8f90911c9280651a0cd84116826d31773e902e48cb9a15b7bb1e7a6abc850c5",
   "gasUsed" : "0x5208",
   "from" : "0x629007eb99ff5c3539ada8a5800847eacfc25727",
   "transactionHash" : "0xeeeed34877502baa305442e3a72df094cfbb0b928a7c53447745ff35d50020bf",
   "logs" : [],
   "cumulativeGasUsed" : "0x5208",
   "contractAddress" : null,
   "logsBloom" : "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"

Then check accounts again to see that the balances have changed:

   "accounts" : [
         "address" : "0x629007eb99ff5c3539ada8a5800847eacfc25727",
         "balance" : 1336999999999999993334,
         "address" : "0xe32e14de8b81d8d3aedacb1868619c74a68feab0",
         "balance" : 1337000000000000006666,

Send raw signed transactions

Most of the time, one will require to send transactions from accounts that are not controlled by the evm-lite instance. The transaction will be assembled, signed and encoded on the client side. The resulting raw signed transaction bytes can be submitted to evm-lite through the /rawtx endpoint.


host:~$ curl -X POST http://[api_addr]/rawtx -d '0xf8628080830f424094564686380e267d1572ee409368e1d42081562a8e8201f48026a022b4f68bfbd4f4c309524ebdbf4bac858e0ad65fd06108c934b45a6da88b92f7a046433c388997fd7b02eb7128f4d2401ef2d10d574c42edf15875a43ee51a1993' -s | json_pp

Get consensus info

The /info endpoint exposes a map of information provided by the consensus system.

example (with Lonconcoin consensus):

host:-$ curl http://[api_addr]/info | json_pp
   "rounds_per_second" : "0.00",
   "type" : "babble",
   "consensus_transactions" : "10",
   "num_peers" : "4",
   "consensus_events" : "10",
   "sync_rate" : "1.00",
   "transaction_pool" : "0",
   "state" : "Babbling",
   "events_per_second" : "0.00",
   "undetermined_events" : "22",
   "id" : "1785923847",
   "last_consensus_round" : "1",
   "last_block_index" : "0",
   "round_events" : "0"


Please refer to EVM-Lite Client for Javascript utilities and a CLI to interact with the API.



We use glide to manage dependencies:

[...]/evm-lite$ curl | sh
[...]/evm-lite$ glide install

This will download all dependencies and put them in the vendor folder; it could take a few minutes.


To add a new consensus system:

  • implement the consensus interface (consensus/consensus.go)
  • add a property to the the global configuration object (config/config.go)
  • create the corresponding CLI subcommand in cmd/evml/commands/
  • register that command to the root command


We provide a set of scripts to automate the deployment of testnets. This requires terraform and docker.

Support for AWS is also available (cf. deploy/)