Design¶
In this document we explain our implementation of the MONET Hub; in particular the mechanism that dictates who can participate in the consensus system, and how to make participants accountable for their actions. Before deliberating on an implementation, it is important to have a clear picture of the desired outcome. So we will start by reiterating the role of the Hub in MONET, and outline its principal requirements. We then visit the spectrum of potential implementations before explaining our choice of a permissioned Byzantine Fault Tolerant (BFT) consensus algorithm coupled to the Ethereum Virtual Machine (EVM). Lastly we weigh up the pros and cons of Proof of Stake (PoS), and explain our decision to implement Proof of Authoriry (PoA) for the time being.
MONET and the MONET Hub¶
MONET’s mission is to boost the adoption of peer-to-peer architectures by enabling mobile devices to connect directly to one another in dynamic ad-hoc networks. We believe that a new generation of applications will emerge from this technology. The real force behind MONET, which makes it original and disruptive, is the concept of Mobile Ad-Hoc Blockchains, and the open-source software which implements it; particularly Babble, the powerful consensus algorithm which is suitable for mobile deployments due to its speed, bandwidth efficiency, and leaderlessness.
We anticipate that many MONET applications will require a common set of services to persist non-transient data, carry information across ad-hoc blockchains, and facilitate peer-discovery. So we set out to build the MONET Hub, an additional public utility that provides these services. In the spirit of open architecture, MONET doesn’t rely on any central authority, so anyone is free to implement their own alternative, but the MONET Hub is there to offer a reliable, fast, and secure solution to kickstart the system.
As such, the qualitative requirements of the Hub are:
- Speed: It should support thousands of commands per second, with latencies under one second.
- Finality: Results from the hub should be definitive, without the possibility of being arbitrarily overridden in the future.
- Availability: It should provide a continuous service in the face of network failures or isolated disruptions.
- Cost: As we want to lower the barrier to entry for developers, using the Hub should be cheaper than rolling out one’s own solution.
- Security: The hub should provide a trusted source of data and computation, with measures guarding against information loss, data manipulation, or censorship.
- Governance: The set of entities controlling this utility should be transparent, with a mechanism to add or remove participants, and keep them accountable for their actions.
- Flexibility: It should be possible and relatively easy to update the software, recover from failures, and adapt to changes.
Spectrum of possible Implementations¶
From a simple web-service hosted on a privately-owned server, to a public global blockchain like Ethereum, there are many potential ways to implement this service. However, given our requirements, a simple server scores pretty low in all categories (except perhaps speed and flexibility), and global public blockchains are too slow, too hard to update, and usually provide only probabilistic finality, which is not acceptable.
Somewhere in the middle lies a category of distributed systems consisting of relatively small clusters of servers maintaining identical copies of an application via sophisticated communication routines and consensus algorithms. Within this category, there are instances where the entire cluster is controlled by a single entity, and others where each replica is controlled by a different entity.
Modern blockchain projects, including cryptocurrencies like Facebook’s Libra and the Cosmos Atom, adopt the second variant, where nodes are controlled by different entities. A naive implementation would render them vulnerable to malicious actors trying to subvert the system; hence they require strong consensus algorithms, commonly referred to as Byzantine Fault Tolerant (BFT), and a reputation system to incentivize good behavior and punish malicious actors.
Given the requirements stated in the previous section, we believe that the MONET Hub falls in the same category, and requires a permissioned BFT system.
Ethereum with Babble Consensus¶
We have developed the Monet Toolchain, a complete set of software tools for
setting up and using the MONET Hub. This includes monetd
, the software
daemon that powers nodes on the MONET Hub.
To build monetd
, we used our own BFT consensus algorithm, Babble, because it is fast, leaderless,
and offers finality. For the application state and smart-contract platform, we
use the Ethereum Virtual Mahcine (EVM) via EVM-Lite, which is a stripped down
version of Go-Ethereum.
The EVM is a security-oriented 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 Babble.
The remaining question is how to govern the validator-set, and what to use as a reputation system to punish or incentivise participants to behave correctly.
PoS and PoA¶
A BFT consensus algorithm ensures that a distributed system remains available and consistent in adversarial conditions, with some nodes exhibiting arbitrary failures or malicious behavior, as long as a majority of participants are functioning correctly (actually ⅔). Any trust in the system therefore depends on the ability to legitimise this assumption. What is needed is a mechanism to ensure, with a high degree of confidence, that at least two thirds of participants in the consensus system are functioning correctly at all times. The problem is two-fold: who gets to be a participant, and how are participants incentivised to behave correctly? Not surprisingly, the most convincing answers revolve around money or reputational risk.
In a Proof of Stake (PoS) arrangement, participants are required to lock a significant portion of their assets (usually the blockchain’s built-in token), and respect an extended un-bonding period when they want to leave. At any given time, the validator set is defined by the top N stakers, where N is the desired size of the validator-set. If they are caught undermining the network, this deposit is destroyed. Hence, participants are deterred from cheating. Additionally, participants are usually programmatically compensated for actively participating in securing the network. Hence they are incentivised to act correctly. A nice feature of PoS is that, being a very capitalistic model, it is relatively open; anyone can participate without asking for permission, as long as they put up a stake.
In Proof of Authority (PoA), the stake is tied to reputational risk. It relies on the natural aversion of most humans to tarnish their own reputation. The list of allowed validators is governed by a whitelist. The whitelist is amended through a voting process among existing whitelisted entities. This scheme is less anonymous or open than PoS but has deep roots. The trust of a PoA system rests on the initial group of participants because any amendment to the list has to gather consensus from them; so the trust (or distrust) is carried over as the validator-set evolves. In a system like Babble, the most serious offence consists in signing two different blocks at the same height. Evidence of this can be packaged into an irrefutable proof, and used to punish the guilty participants.
Proof of Stake opens exciting opportunities for a variety of stakeholders, and these economic incentives are excellent for the industry as they drive innovation. That being said, we are of the opinion that it is too early to ascertain the resilience of PoS in the face of decisive attacks, as current production deployments are very recent, and the theoretical arguments alone are not sufficiently convincing (although they sound quite reasonable). We are keeping an eye on PoS systems, hoping that they withstand the test of time. In the meantime, we have opted to implement PoA, to roll out a reliable version of the MONET Hub, with an eye on extending to PoS in a coordinated software update later down the road.
Conclusion¶
The MONET Hub is a pivotal utility that facilitates the creation of mobile ad-hoc blockchains, and the emergence of a new breed of decentralised applications. To maximise the performance, security, and flexibility of this system, we have opted to build the Monet Toolchain, a smart-contract platform based on the Ethereum Virtual Machine and a state-of-the-art BFT consensus algorithm, Babble. To govern the validator-set involved in the consensus algorithm, we have chosen to implement a Proof of Authority system, with the idea of extending to Proof of Stake when more evidence of its efficacy becomes available.
Overview¶
This document describes the tools for operating a Monet Toolchain node, and a couple of important concepts regarding the account model. In other documents, we provide guidance on using these tools to perform common tasks, as well as a complete reference of commands and API functions.
Tools¶
Monetd¶
monetd is the server process that connects to other nodes, participates in the consensus algorithm, and maintains its own copy of the application state. Additionaly, the giverny program facilitates the creation of local Monet Toolchain networks for testing purposes. We don’t expect most people to use giverny as it is mostly a development tool.
monetd and giverny are written in Go, and reside in the same github repository because they share significant source code. Please follow the installation instructions to get started.
Monetcli¶
monetcli is the client-side program that interacts with a running Monet
Toolchain node, and enables users to make transfers, query accounts, deploy and
call smart-contracts, or participate in the PoA governance mechanism.
monetcli
is a Node.js project. It can be
installed easily with npm install -g monetcli
.
Accounts¶
What is an account?¶
The Monet Toolchain, and thus MONET, uses the same account model as Ethereum. Accounts represent identities of external agents and are associated with a balance (and storage for Contract accounts). They rely on public key cryptography to sign transactions so that the EVM can securely validate the identity of a transaction sender.
Using the same account model as Ethereum doesn’t mean that existing Ethereum accounts automatically have the same balance in MONET (or vice versa). In Ethereum, balances are denoted in Ether, the cryptocurrency maintained by the public Ethereum network. On the other hand, every MONET network (even a single node network) maintains a completely separate ledger and may use any name for the corresponding coin. The official MONET token is Tenom.
What follows is mostly inspired from the Ethereum Docs:
Accounts are objects in the EVM State. They come in two types: Externally owned accounts, and Contract accounts. Externally owned accounts have a balance, and Contract accounts have a balance and storage. The EVM State is the state of all accounts which is updated with every transaction. The underlying consensus engine ensures that every participant in a Monet Toolchain network processes the same transactions in the same order, thereby arriving at the same State. The use of Contract accounts with the EVM makes it possible to deploy and use SmartContracts which we will explore in another document.
What is an account file?¶
This is best explained in the Ethereum Docs:
Every account is defined by a pair of keys, a private key, and public key. Accounts are indexed by their address which is derived from the public key by taking the last 20 bytes. Every private key/address pair is encoded in a keyfile. Keyfiles are JSON text files which you can open and view in any text editor. The critical component of the keyfile, your account’s private key, is always encrypted, and it is encrypted with the password you enter when you create the account.
Transactions¶
A transaction is a signed data package that contains instructions for the EVM. It can contain instructions to move coins from one account to another, create a new Contract account, or call an existing Contract account. Transactions are encoded using the custom Ethereum scheme, RLP, and contain the following fields:
- The recipient of the message.
- A signature identifying the sender and proving their intention to send the transaction.
- The number of coins to transfer from the sender to the recipient.
- An optional data field, which can contain the message sent to a contract.
- A STARTGAS value, representing the maximum number of computational steps the transaction execution is allowed to take.
- a GASPRICE value, representing the fee the sender is willing to pay for gas. One unit of gas corresponds to the execution of one atomic instruction, i.e., a computational step.
Installing monetd¶
Versioning¶
monetd
versions follow semantic versioning. As we
are still in the 0.x range, different versions might contain undocumented
and/or breaking changes. At this stage, the prefered way of installing
monetd
is building from source, or using our public Docker images.
Docker¶
Docker images of monetd
are available from the mosaicnetworks
organisation. Use the latest
tag for the latest released version. The
advantage of using Docker containers is that they come packaged with all the
necessary binary files, including solc, and contain an isolated running
environment where monetd
is sure to run.
Example: Mount a configuration directory, and run a node from inside a
monetd
container.
docker run --rm -v ~/.monet:/.monet mosaicnetworks/monetd run
Building From Source¶
Dependencies¶
The key components of the Monet Toolchain, which powers the MONET Hub, are written in Golang. Hence, the first step is to install Go version 1.9 or above, which is both the programming language and a CLI tool for managing Go code. Go is very opinionated and requires defining a workspace where all Go code resides. The simplest test of a Go installation is:
$ go version
monetd
uses Glide to manage
dependencies.
$ curl https://glide.sh/get | sh
Solidity Compiler¶
The Monet Toolchain uses Proof of Authority (PoA) to manage the validator set. This is implemented using a smart-contract written in Solidity, with the corresponding EVM bytecode set in the genesis file. For every newly defined network, the smart-contract needs to be recompiled because it embeds the initial whitelist. Hence, the Solidity compiler (solc) is a requirement to define a new network and produce the appropriate genesis file.
Please refer to the solidity compiler installation instructions.
Attention: The Node.js version of the compiler is not supported. Do not
install via npm install solc
.
Other requirements¶
Bash scripts used in this project assume the use of GNU versions of coreutils. Please ensure you have GNU versions of these programs installed:-
example for macOS:
# --with-default-names makes the `sed` and `awk` commands default to gnu sed and gnu awk respectively.
brew install gnu-sed gawk --with-default-names
Installation¶
Clone the repository in the appropriate GOPATH subdirectory:
$ mkdir -p $GOPATH/src/github.com/mosaicnetworks/
$ cd $GOPATH/src/github.com/mosaicnetworks
[...]/mosaicnetworks$ git clone https://github.com/mosaicnetworks/monetd.git
Run the following command to download all dependencies and put them in the vendor folder.
[...]/monetd$ make vendor
Then build and install:
[...]/monetd$ make install
Getting Started¶
In this document we explain how to run a single node and how to use
monetcli
to interact with it. In another section, we will explain how to
join an existing network. For details about any command, please refer to the
specification.
Creating A Single Node Network¶
In short, run the following three commands to start a standalone node:
$ monetd keys new node0
$ monetd config build node0
$ monetd run
The keys new
command will prompt us for a password, and generate a new
encrypted keyfile in the default keystore ~/.monet/keystore
. We identified
our key with the node0
moniker.
The config build
command takes our key, and generates a minimal network
configuration with a single validator node, and a prefunded account. Again, the
configuration is written to ~/.monet
. [1]
Finally, the run
command starts a monetd node, which will default to using
the configuration files in ~/.monet
. [1]
Using monetcli¶
Let’s use monetcli
to query the newly created node. First of all, install
monetcli
with npm install -g monetcli
.
While monetd
is still running, open another terminal and start monetcli
in interactive mode:
$monetcli i
__ __ _ ____ _ ___
| \/ | ___ _ __ ___ | |_ / ___| | | |_ _|
| |\/| | / _ \ | '_ \ / _ \ | __| | | | | | |
| | | | | (_) | | | | | | __/ | |_ | |___ | |___ | |
|_| |_| \___/ |_| |_| \___| \__| \____| |_____| |___|
Mode: Interactive
Data Dir: /home/user/.monet
Config File: /home/user/.monet/monetcli.toml
Keystore: /home/user/.monet/keystore
Commands:
help [command...] Provides help for a given command.
exit Exits application.
accounts create [options] Creates an encrypted keypair locally
accounts get [options] [address] Fetches account details from a connected node
accounts list [options] List all accounts in the local keystore directory
accounts update [options] [address] Update passphrase for a local account
accounts import [options] Import an encrypted keyfile to the keystore
config set [options] Set values of the configuration inside the data directory
config view [options] Output current configuration file
poa check [options] [address] Check whether an address is on the whitelist
poa info [options] Display Proof of Authority information
poa nominate [options] [address] Nominate an address to proceed to election
poa nomineelist [options] List nominees for a connected node
poa vote [options] [address] Vote for an nominee currently in election
poa whitelist [options] List whitelist entries for a connected node
transfer [options] Initiate a transfer of token(s) to an address
info [options] Display information about node
version [options] Display current version of cli
debug Toggle debug mode
clear Clear output on screen
Type info
to check the status of the node:
monetcli$ info
.-------------------------------------.
| Key | Value |
|------------------------|------------|
| consensus_events | 0 |
| consensus_transactions | 0 |
| events_per_second | 0.00 |
| id | 1022922485 |
| last_block_index | -1 |
| last_consensus_round | nil |
| moniker | node0 |
| num_peers | 1 |
| round_events | 0 |
| rounds_per_second | 0.00 |
| state | Babbling |
| sync_rate | 1.00 |
| transaction_pool | 0 |
| type | babble |
| undetermined_events | 0 |
'-------------------------------------'
Type accounts list
to get a list of accounts in the keystore, and the
balance associated with them.
monetcli$ accounts list
.---------------------------------------------------------------------------------------.
| Moniker | Address | Balance | Nonce |
|---------|--------------------------------------------|------------------------|-------|
| node0 | 0xa10aae5609643848fF1Bceb76172652261dB1d6c | 1234567890000000000000 | 0 |
'---------------------------------------------------------------------------------------'
So we have a prefunded account. The same account is used as a validator in
Babble, and as a Tenom-holding account in the ledger. This is the same account,
node0, that we created in the previous steps, with the encrypted private key
residing in ~/.monet/keystore
.
Now, let’s create a new key using monetcli
, and transfer some tokens to it.
monetcli$ accounts create
? Moniker: node1
? Output Path: /home/user/.monet/keystore
? Passphrase: [hidden]
? Re-enter passphrase: [hidden]
{"version":3,"id":"89970faf-8754-468e-903c-c9d3248a08cc","address":"960c13654c477ac1d2d7f8fc7ae84d93a2225257","crypto":{"ciphertext":"7aac819c1bed442d778
97b690e5c2f14416589c7bdd6bdd2b5df5d03584ce0ec","cipherparams":{"iv":"3d15a67d76293c3b7123f2bde76ba120"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams"
:{"dklen":32,"salt":"730dd67f175a77c9833a230e334719292cbb735607795b1b84484e3d04783510","n":8192,"r":8,"p":1},"mac":"7535c31c277a698207d278cd1f1df90747463
e390b822cfef7d2faf8f1fa1809"}}
Like monetd keys new
this command created a new key and wrote the encrypted
keyfile in ~/.monet/keystore. Let’s double check that the key was created:
monetcli$ accounts list
.---------------------------------------------------------------------------------------.
| Moniker | Address | Balance | Nonce |
|---------|--------------------------------------------|------------------------|-------|
| node0 | 0xa10aae5609643848fF1Bceb76172652261dB1d6c | 1234567890000000000000 | 0 |
| node1 | 0x960c13654c477ac1d2d7f8fc7ae84d93a2225257 | 0 | 0 |
'---------------------------------------------------------------------------------------'
Now, let’s transfer 100 tokens to it.
monetcli$ transfer
? From: node0 (1,234,567,890,000,000,000,000)
? Enter password: [hidden]
? To 0x960c13654c477ac1d2d7f8fc7ae84d93a2225257
? Value: 100
? Gas: 1000000
? Gas Price: 0
{
"from": "0xa10aae5609643848fF1Bceb76172652261dB1d6c",
"to": "0x960c13654c477ac1d2d7f8fc7ae84d93a2225257",
"value": 100,
"gas": 1000000,
"gasPrice": 0
}
? Submit transaction Yes
Transaction submitted successfully.
Finally, we can check the account balances again to verify the outcome of the transfer:
monetcli$ accounts list
.---------------------------------------------------------------------------------------.
| Moniker | Address | Balance | Nonce |
|---------|--------------------------------------------|------------------------|-------|
| node0 | 0xa10aae5609643848fF1Bceb76172652261dB1d6c | 1234567889999999999900 | 1 |
| node1 | 0x960c13654c477ac1d2d7f8fc7ae84d93a2225257 | 100 | 0 |
'---------------------------------------------------------------------------------------'
[1] | (1, 2) This location is for Linux instances. Mac and Windows uses a different
path. The path for your instance can be ascertain with this command:
monetd config location |
Tests¶
Included in the monetd distribution are numerous tests. There are unit tests, which test individual components, and end to end tests.
Unit Tests¶
These can be run as follows:
[...]/monetd$ make test
Monetd Tests
? .../monetd/cmd/giverny [no test files]
? .../monetd/cmd/giverny/commands [no test files]
? .../monetd/cmd/giverny/commands/keys [no test files]
? .../monetd/cmd/giverny/commands/network [no test files]
? .../monetd/cmd/giverny/commands/server [no test files]
? .../monetd/cmd/giverny/commands/transactions [no test files]
? .../monetd/cmd/giverny/configuration [no test files]
? .../monetd/cmd/monetd [no test files]
? .../monetd/cmd/monetd/commands [no test files]
? .../monetd/cmd/monetd/commands/config [no test files]
? .../monetd/cmd/monetd/commands/keys [no test files]
ok .../monetd/src/babble 0.077s
ok .../monetd/src/common 0.003s
? .../monetd/src/config [no test files]
? .../monetd/src/configuration [no test files]
? .../monetd/src/contract [no test files]
? .../monetd/src/crypto [no test files]
? .../monetd/src/docker [no test files]
? .../monetd/src/files [no test files]
? .../monetd/src/peers [no test files]
? .../monetd/src/types [no test files]
? .../monetd/src/version [no test files]
EVM-Lite Tests
? .../vendor/.../evm-lite/src/common [no test files]
? .../vendor/.../evm-lite/src/config [no test files]
? .../vendor/.../evm-lite/src/consensus [no test files]
? .../vendor/.../evm-lite/src/consensus/solo [no test files]
ok .../vendor/.../evm-lite/src/currency 0.003s
? .../vendor/.../evm-lite/src/engine [no test files]
? .../vendor/.../evm-lite/src/service [no test files]
ok .../vendor/.../evm-lite/src/state 3.148s
? .../vendor/.../evm-lite/src/version [no test files]
Babble Tests
ok .../vendor/.../babble/src/babble 0.149s
ok .../vendor/.../babble/src/common 0.024s
? .../vendor/.../babble/src/config [no test files]
? .../vendor/.../babble/src/crypto [no test files]
ok .../vendor/.../babble/src/crypto/keys 0.097s
ok .../vendor/.../babble/src/hashgraph 11.385s
? .../vendor/.../babble/src/mobile [no test files]
ok .../vendor/.../babble/src/net 0.092s
ok .../vendor/.../babble/src/node 36.339s
ok .../vendor/.../babble/src/peers 0.082s
? .../vendor/.../babble/src/proxy [no test files]
ok .../vendor/.../babble/src/proxy/dummy 0.038s
ok .../vendor/.../babble/src/proxy/inmem 0.037s
ok .../vendor/.../babble/src/proxy/socket 0.043s
? .../vendor/.../babble/src/proxy/socket/app [no test files]
? .../vendor/.../babble/src/proxy/socket/babble [no test files]
? .../vendor/.../babble/src/service [no test files]
? .../vendor/.../babble/src/version [no test files]
They will take some seconds to run. If any test fails an error message will be displayed.
End to End Tests¶
End to end tests are in the subfolder e2e
of the repository. All tests
can be run as follows:
[...]/monetd/e2e$ make tests
An individual test can be run as follows:
[...]/monetd/e2e$ make test TEST=crowdfundnet
To prevent the test net being destroyed on completion, add NOSTOP=nostop
:
[...]/monetd/e2e$ make test TEST=transfer_03_10 NOSTOP=nostop
Tests output logs to ...monetd/e2e/tests/<TESTNAME>.out
Transfer Tests¶
As well as standalone tests, the transaction generation tools can be used against extant networks.
You can get the list of options (and defaults) by using the --help
or
-h
option:
$ e2e/tools/build-trans.sh -h
e2e/tools/build-trans.sh [-v] [--accounts=10] [--transactions=200] [--faucet="Faucet"] [--faucet-config-dir=] [--prefix=Test] [--node-name=Node] [--node-host=172.77.5.11] [--node-port=8080] [--config-dir=/home/jon/.monettest] [--temp-dir=/tmp] [-h|--help]
- -v turns on verbose output
- –accounts=10 sets the number of accounts to transfer tokens between
- –transactions=200 sets the number of transactions to generate
- –faucet=”Faucet” sets the account to fund the transfers
- –faucet-config-dir= where the faucet account is stored.
$HOME/.monet/keystore
or$HOME/.giverny/networks/<net name>/keystore
are the likely values - –prefix=Test is the prefix for the moniker of the accounts for transfers
- –node-name=Node is the Node Name
- –node-host=172.77.5.11 is the Node address
- –node-port=8080 is the port for EVM-Lite endpoints
- –config-dir=/home/user/.monettest is the config directory to use
Joining a Network¶
This section describes how to join an existing network that is already running, such as the one created in Getting Started.
Here’s a summary of the steps required to join an existing network built with the Monet Toolchain:
$ monetd keys new node1
$ monetd config pull [address]:[port] --key node1
$ monetcli poa nominate -h [address] -p [port] --from [node1 address] --pwd [password file for node1 key] --moniker node1 [node1 address]
# wait to be accepted in the whitelist, which can be checked with
$ monetd poa whitelist
# or
$ monetd poa nomineelist
$ monetd run
Where [address] and [port] correspond to the endpoint of an existing peer in the network.
This scenario is designed to be run on a machine other than the one that is running the existing node.
Create An Account¶
We need to generate a new key-pair for our account:
$ monetd keys new node1
Passphrase:
Repeat passphrase:
Address: 0x5a735fC1235ce1E60eb5f9B9BCacb643a9Da27F4
Pull the Configuration From an Existing Node¶
We now pull the monetd
configuration files from an existing peer. The
syntax for this command is:
$ monetd config pull [peer] [--key] [--address]
The peer parameter is the address/IP of an existing node on the network. The network’s configuration is requested from this peer. If the address does not specify a port, the default API port (8080) is assumed.
We also need to specify the IP address of our own node. For a live network that
would clearly be a public IP address, but for an exploratory testnet, we would
recommend using an internal IP address. On Linux ifconfig
will give you IP
address information. This can be set by using the –address flag. If not
specified monetd
will pick the first non-loopback address.
The --key
parameter specifies the keyfile to use by moniker.
Thus we need to run the following command, but replace 192.168.1.5:8080
with the endpoint of the existing peer.
$ monetd config pull 192.168.1.5:8080 --key node1
Apply to Join the Network¶
If we tried to run monetd
at this stage, it would not be allowed to join
the other node because it isn’t whitelisted yet. So we need to apply to the
whitelist first.
We do so with the monetcli poa nominate
command. The syntax is:
$ monetcli poa nominate -h <existing node> --from <moniker> --moniker <nominee moniker> --pwd <passphrase file> <nominee address>
But we can also do it interactively. On the existing instance (node0), run the following interactive ``monetcli`` session:
monetcli i
__ __ _ ____ _ ___
| \/ | ___ _ __ ___ | |_ / ___| | | |_ _|
| |\/| | / _ \ | '_ \ / _ \ | __| | | | | | |
| | | | | (_) | | | | | | __/ | |_ | |___ | |___ | |
|_| |_| \___/ |_| |_| \___| \__| \____| |_____| |___|
Mode: Interactive
Data Dir: /home/user/.monet
Config File: /home/user/.monet/monetcli.toml
Keystore: /home/user/.monet/keystore
Commands:
[...]
monetcli$ poa nominate
? From: node0
? Passphrase: [hidden]
? Nominee: 0x960c13654c477ac1d2d7f8fc7ae84d93a2225257
? Moniker: node1
You (0xa10aae5609643848ff1bceb76172652261db1d6c) nominated 'node1' (0x960c13654c477ac1d2d7f8fc7ae84d93a2225257)
monetcli$ poa nomineelist
.------------------------------------------------------------------------------.
| Moniker | Address | Up Votes | Down Votes |
|---------|--------------------------------------------|----------|------------|
| Node1 | 0x960c13654c477ac1d2d7f8fc7ae84d93a2225257 | 0 | 0 |
'------------------------------------------------------------------------------'
Now that, we have applied to the whitelist (via node0), we need all the entities in the current whitelist to vote for us. At the moment, only node0 is in the whitelist, so let’s cast a vote.
monetcli$ poa whitelist
.------------------------------------------------------.
| Moniker | Address |
|---------|--------------------------------------------|
| Node0 | 0xa10aae5609643848ff1bceb76172652261db1d6c |
'------------------------------------------------------'
monetcli$ poa vote
? From: node0
? Passphrase: [hidden]
? Nominee: 0x960c13654c477ac1d2d7f8fc7ae84d93a2225257
? Verdict: Yes
You (0xa10aae5609643848ff1bceb76172652261db1d6c) voted 'Yes' for '0x960c13654c477ac1d2d7f8fc7ae84d93a2225257'.
Election completed with the nominee being 'Accepted'.
monet$ poa whitelist
.------------------------------------------------------.
| Moniker | Address |
|---------|--------------------------------------------|
| Node0 | 0xa10aae5609643848ff1bceb76172652261db1d6c |
| Node1 | 0x960c13654c477ac1d2d7f8fc7ae84d93a2225257 |
'------------------------------------------------------'
Finaly node1 made it into the whitelist.
Starting the Node¶
To start node1, run the simple monetd run
command. You should be able see
the JoinRequest going through consensus, and being accepted by the PoA
contract.
$ monetd run
Transaction Fees¶
Every operation that modifies the state (transfer, smart-contract creation,
smart-contract call, etc.) carries a cost. Within the EVM, this cost is
denominated in gas. For example, a simple transfer costs 21000 gas. When users
create and submit transactions, they can set the maximum amount of gas they want
to spend, and how much om
(10^-18 Tenom) they are willing to pay per unit of
gas consumed. Therefore, if their transaction is applied, it will cost them a
transaction fee of gas-price * gas-consumed
, which is capped by gas-price
* gas-max
.
Transaction fees serve a dual purpose: to incentivise validators, and to prevent denial of service attacks.
Distribution Among Validators¶
Every transaction applied to the EVM is associated with a coinbase address (possibly empty), which receives the transaction fee. In monetd, we have implemented a system that fairly and securily distributes fees among validators.
Upon committing a Babble block, we fetch the corresponding validator-set from Babble. Then we use the block hash to obtain a pseudo-random number which we use to select a peer from the validator-set. This peer will receive all the transaction fees from that block. This system is fair and secure because the selection process is evenly distributed and it is impossible for malicious validators to game it by manipulating the block hash.
Minimum Gas Price¶
Validators running a monetd node can set a minimum gas price, via the
eth.min-gas-price
configuration flag, to refuse broadcasting transactions
with lower gas-prices. To send a transaction via a node, the transaction creator
must set the gas price to a value greater or equal to that node’s minimum gas
price. Note that this filtering is done at the service layer, so it will not
prevent other nodes from including cheaper transactions.
Monetd API¶
monetd
exposes an HTTP API at the address specified by the --api-listen
flag. This document contains the API specification with some basic examples
using curl. For API clients (javascript libraries, CLI, and GUI), please refer
to Monet CLI
Get Account¶
Retrieve information about any account.
GET /account/{address}
returns: JsonAccount
type JsonAccount struct {
Address string `json:"address"`
Balance *big.Int `json:"balance"`
Nonce uint64 `json:"nonce"`
Code string `json:"bytecode"`
}
Example:
host:~$ curl http://localhost:8080/account/0xa10aae5609643848fF1Bceb76172652261dB1d6c -s | jq
{
"address": "0xa10aae5609643848fF1Bceb76172652261dB1d6c",
"balance": 1234567890000000000000,
"nonce": 0,
"bytecode": ""
}
Call¶
Call a smart-contract READONLY function. These calls will NOT modify the EVM state, and the data does NOT need to be signed.
POST /call
data: JSON SendTxArgs
returns: JSON JsonCallRes
type SendTxArgs struct {
From common.Address `json:"from"`
To *common.Address `json:"to"`
Gas uint64 `json:"gas"`
GasPrice *big.Int `json:"gasPrice"`
Value *big.Int `json:"value"`
Data string `json:"data"`
Nonce *uint64 `json:"nonce"`
}
type JsonCallRes struct {
Data string `json:"data"`
}
Example:
curl http://localhost:8080/call \
-d '{"constant":true,"to":"0xabbaabbaabbaabbaabbaabbaabbaabbaabbaabba","value":0,"data":"0x8f82b8c4","gas":1000000,"gasPrice":0,"chainId":1}' \
-H "Content-Type: application/json" \
-X POST -s | jq
{
"data": "0x0000000000000000000000000000000000000000000000000000000000000001"
}
Submit Transaction¶
Send a SIGNED, NON-READONLY transaction. The client is left to compose a transaction, sign it and RLP encode it. The resulting bytes, represented as a Hex string, are passed to this method to be forwarded to the EVM. This is a SYNCHRONOUS operation; it waits for the transaction to go through consensus and returns the transaction receipt.
POST /rawtx
data: STRING Hex representation of the raw transaction bytes
returns: JSON JsonReceipt
type JsonTxRes struct {
TxHash string `json:"txHash"`
}
type JsonReceipt struct {
Root common.Hash `json:"root"`
TransactionHash common.Hash `json:"transactionHash"`
From common.Address `json:"from"`
To *common.Address `json:"to"`
GasUsed uint64 `json:"gasUsed"`
CumulativeGasUsed uint64 `json:"cumulativeGasUsed"`
ContractAddress common.Address `json:"contractAddress"`
Logs []*ethTypes.Log `json:"logs"`
LogsBloom ethTypes.Bloom `json:"logsBloom"`
Status uint64 `json:"status"`
}
Example:
host:~$ curl -X POST http://localhost:8080/rawtx 0xf86904808398968094f7cd2ba6892341e568e9d825c4bdc2bd53b7524189031b9d1340ad2500008026a04eb7420aa52a1955d26ffb16d3a8cb8d969ae0eb6d75bb5076599c42a788e08da0178b3ddb264cdcc624121f55a95ae45de119bc44a0a85b721d8958b7ebe0553a -s | json_pp
{
"root": "0xda4529d2bc5e8b438edee4463637eb91d5490edb50d15e786e8d5276f2a2c8f4",
"transactionHash": "0x3f5682786828d26946e12a08a858b6dd805d1ea8f7d39d93f1d4d5393b23f710",
"from": "0x888980abf63d4133482e50bf8233f307e3c2b941",
"to": "0xf7cd2ba6892341e568e9d825c4bdc2bd53b75241",
"gasUsed": 21000,
"cumulativeGasUsed": 21000,
"contractAddress": "0x0000000000000000000000000000000000000000",
"logs": [],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status": 1
}
Get Receipt¶
Get a transaction receipt. When a transaction is applied to the EVM, a receipt is saved to record if/how the transaction affected the state. This contains such information as the address of a newly created contract, how much gas was use, and the EVM Logs produced by the execution of the transaction.
GET /tx/{tx_hash}
returns: JSON JsonReceipt
Example:
host:~$ curl http://localhost:8080/tx/0x96764078446cfbaec6265f173fb5a2411b7c272052640bca622252494a74dbb4 -s | jq
{
"root": "0x348c230578e27e20a10924e925f7cddb28279561b52cab7b31750c6d4716ac21",
"transactionHash": "0x96764078446cfbaec6265f173fb5a2411b7c272052640bca622252494a74dbb4",
"from": "0xa10aae5609643848ff1bceb76172652261db1d6c",
"to": "0xa10aae5609643848ff1bceb76172652261db1d6c",
"gasUsed": 21000,
"cumulativeGasUsed": 21000,
"contractAddress": "0x0000000000000000000000000000000000000000",
"logs": [],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status": 0
}
Info¶
Get information about a Babble instance.
GET /info
returns: JSON map
Example:
host:-$ curl http://localhost:8080/info | jq
{
"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"
}
POA¶
Get details of the PoA smart-contract.
GET /poa
returns: JsonContract
type JsonContract struct {
Address common.Address `json:"address"`
ABI string `json:"abi"`
}
Example (trunctated output):
host:-$ curl http://localhost:8080/poa | jq
{
"address": "0xabbaabbaabbaabbaabbaabbaabbaabbaabbaabba",
"abi": "[\n\t{\n\t\t\"constant\": true,\n\t\t\"inputs\"...]"
}
Genesis.json¶
This endpoint returns the content of the genesis.json file in JSON format. This allows new nodes to pull the genesis file from an existing peer.
GET /genesis
returns: JSON Genesis
type Genesis struct {
Alloc AccountMap
Poa PoaMap
}
type AccountMap map[string]struct {
Code string
Storage map[string]string
Balance string
Authorising bool
}
type PoaMap struct {
Address string
Balance string
Abi string
Code string
}
Example (truncated output):
host:-$ curl://http://locahost:8080/genesis | jq
{
"Alloc": {
"a10aae5609643848ff1bceb76172652261db1d6c": {
"Code": "",
"Storage": null,
"Balance": "1234567890000000000000",
"Authorising": false
}
},
"Poa": {
"Address": "0xaBBAABbaaBbAABbaABbAABbAABbaAbbaaBbaaBBa",
"Balance": "",
"Abi": "[\n\t{\n\t\t\"constant\": ...]",
"Code": "6080604052600436106101095..."
}
}
Block¶
Get a Babble Block by index.
GET /block/{index}
returns: JSON Block
type Block struct {
Body BlockBody
Signatures map[string]string
}
type BlockBody struct {
Index int
RoundReceived int
StateHash []byte
FrameHash []byte
PeersHash []byte
Transactions [][]byte
InternalTransactions []InternalTransaction
InternalTransactionReceipts []InternalTransactionReceipt
}
Example:
host:-$ curl http://locahost:8080/block/0 | jq
{
"Body": {
"Index": 0,
"RoundReceived": 1,
"StateHash": "VY6jFi7P5bIajdWvwZU2jU0q3KXDcp1sFx7Ye6kl1/k=",
"FrameHash": "Nek4dF0ybGZQ1XEuJQrjmPtNrfPLAtGU4sTQSSB2iKM=",
"PeersHash": "Gv+YqIq56l6LZWdhAsx0XEB4gjZluMaziv7hCXT5b9k=",
"Transactions": [
"+GSAgIMPQkCUq7qruqu6q7qruqu6q7qruqu6q7qAhOHHOSoloGCfTsLEOcMMXDX1W/78zpaZTXXK8BSR1Q8cCqicSrExoDv/0YGlpaGMJO8B6ZAJ/WAiEOKG00uzF8piaCvW3GHH"
],
"InternalTransactions": [],
"InternalTransactionReceipts": []
},
"Signatures": {
"0X04F91D4429AE73229141F960B70CD2E83BF39D6EBF1B951C4E65BA9F0EE7FA2365C859CC9BF856709F78F0B9DD6BFBA450BFC7B8123197616D22E6EA8693201800": "2gtf6rkdc0q29n1isef0x2fib64qlf075uybtva6558r8onv31|2gnym6xat1ok68nqtsymcpg4x9ihj1ouwab8inode5m8eb82tb"
}
}
Current Peers¶
Get Babble’s current peer-set.
Get /peers
returns: []Peer
type Peer struct {
NetAddr string
PubKeyHex string
Moniker string
}
Example:
$host:-$ curl http://localhost:8080/peers | jq
[
{
"NetAddr": "192.168.1.3:1337",
"PubKeyHex": "0X04F91D4429AE73229141F960B70CD2E83BF39D6EBF1B951C4E65BA9F0EE7FA2365C859CC9BF856709F78F0B9DD6BFBA450BFC7B8123197616D22E6EA8693201800",
"Moniker": "node0"
}
]
POA Smart Contract¶
This document describes the requirements for a smart-contract to implement POA
in a Monet Toolchain hub. The default contract supplied with monetd
already
meets these requirements.
Solidity¶
Version¶
The first line of the contract is a pragma specifying the solidity version
required. Currently this is set to greater than or equal to 0.4.22
.
pragma solidity >=0.4.22;
Constructor¶
The contract is embedded in the genesis block. This means that there is no conventional constructor. It is possible to add a hook to payable function calls to set an initial state if it has not already been initialised.
Modifier¶
checkAuthorisedModifier
is used to restrict access to payable functions.
The internals of that function could be ameneded to your new scheme.
CheckAuthorised¶
Babble calls the following function to verify whether a peer making a join request is authorised. Any replacement smart-contract will need to implement this function.
function checkAuthorised(address _address) public view returns (bool)
Payable calls¶
Functions that the client tools expect to be present.
function submitNominee (address _nomineeAddress, bytes32 _moniker) public payable checkAuthorisedModifier(msg.sender)
function castNomineeVote(address _nomineeAddress, bool _accepted) public payable checkAuthorisedModifier(msg.sender) returns (bool decided, bool voteresult)
Decision Function¶
This function decides when a vote is complete. Currently it requires all people on the whitelist to approve. It is anticipated that some form of majority voting would be implemented to prevent paralysis if a peer drops out.
function checkForNomineeVoteDecision(address _nomineeAddress) private returns (bool decided, bool voteresult)
Information Calls¶
The following information calls are available:
function getNomineeElection(address _address) public view returns (address nominee, address proposer, uint yesVotes, uint noVotes)
function getNomineeCount() public view returns (uint count)
function getNomineeAddressFromIdx(uint idx) public view returns (address NomineeAddress)
function getNomineeElectionFromIdx(uint idx) public view returns (address nominee, address proposer, uint yesVotes, uint noVotes)
function getCurrentNomineeVotes(address _address) public view returns (uint yes, uint no)
function getWhiteListCount() public view returns (uint count)
function getWhiteListAddressFromIdx(uint idx) public view returns (address WhiteListAddress)
function getYesVoteCount(address _nomineeAddress) public view returns (uint count)
function getYesVoterFromIdx(address _nomineeAddress, uint _idx) public view returns (address voter)
function getNoVoteCount(address _nomineeAddress) public view returns (uint count)
function getNoVoterFromIdx(address _nomineeAddress, uint _idx) public view returns (address voter)
function getMoniker(address _address) public view returns (bytes32 moniker)
Events¶
The following events are emitted by the smart contract. It is envisaged that the same events would be emitted by any replacement contract.
/// @notice Event emitted when the vote was reached a decision
/// @param _nominee The address of the nominee
/// @param _yesVotes The total number of yes votes cast for the nominee to date
/// @param _noVotes The total number of no votes cast for the nominee to date
/// @param _accepted The decision, true for added to the whitelist, false for rejected
event NomineeDecision(
address indexed _nominee,
uint _yesVotes,
uint _noVotes,
bool indexed _accepted
);
/// @notice Event emitted when a nominee vote is cast
/// @param _nominee The address of the nominee
/// @param _voter The address of the person who cast the vote
/// @param _yesVotes The total number of yes votes cast for the nominee to date
/// @param _noVotes The total number of no votes cast for the nominee to date
/// @param _accepted The vote, true for accept, false for rejected
event NomineeVoteCast(
address indexed _nominee,
address indexed _voter,
uint _yesVotes,
uint _noVotes,
bool indexed _accepted
);
/// @notice Event emitted when a nominee is proposed
/// @param _nominee The address of the nominee
/// @param _proposer The address of the person who proposed the nominee
event NomineeProposed(
address indexed _nominee,
address indexed _proposer
);
/// @notice Event emitted to announce a moniker
/// @param _address The address of the user
/// @param _moniker The moniker of the user
event MonikerAnnounce(
address indexed _address,
bytes32 indexed _moniker
);
Generated Genesis Whitelist Section¶
The template contract has a block of code delimited by the commments
//GENERATED GENESIS BEGIN
and //GENERATED GENESIS END
. In the
monetd config build
command that block of code is replaced with generated
code. That code is customised to include the initial authorised peers list in
the genesis block.
A sample generated block is included below.
//GENERATED GENESIS BEGIN
address constant initWhitelist0 = 0xDc3062F7E88C456c2aD6EeaAc2D6Da4034F6CD7C;
bytes32 constant initWhitelistMoniker0 = "node0";
address constant initWhitelist1 = 0xdB77c5DBb8c39a82F131252853000E8691a772E1;
bytes32 constant initWhitelistMoniker1 = "node1";
address constant initWhitelist2 = 0xe9fa241921dF673E932B173C1a41bc532Db4C330;
bytes32 constant initWhitelistMoniker2 = "node2";
function processGenesisWhitelist() private
{
addToWhitelist(initWhitelist0, initWhitelistMoniker0);
addToWhitelist(initWhitelist1, initWhitelistMoniker1);
addToWhitelist(initWhitelist2, initWhitelistMoniker2);
}
function isGenesisWhitelisted(address _address) pure private returns (bool)
{
return ( ( initWhitelist0 == _address ) || ( initWhitelist1 == _address ) || ( initWhitelist2 == _address ) );
}
//GENERATED GENESIS END
The following functions must be defined in the generated block as they are referenced in the non-generated code.
function processGenesisWhitelist() private
function isGenesisWhitelisted(address _address) pure private returns (bool)
Giverny Examples¶
For reference, the options for giverny network new
:
[..monetd] $ giverny help network new
giverny network build
Usage:
giverny network new [network_name] [flags]
Flags:
--generate-pass generate pass phrases
-h, --help help for new
--initial-ip string initial IP address of range
--initial-peers int number of initial peers
--names string file containing node configurations
--no-build disables the automatic build of a new network
--no-save-pass don't save pass phrase entered on command line
-n, --nodes int number of nodes in this configuration (default -1)
--pass string file containing a passphrase
Global Flags:
-g, --giverny-data-dir string Top-level giverny directory for configuration and data (default "/home/jon/.giverny")
-m, --monet-data-dir string Top-level monetd directory for configuration and data (default "/home/jon/.monet")
-v, --verbose verbose messages
Development Test Networks¶
To make commands repeatable, and to reflect code changes, the following commands can be prefixed to all the commands below:
make installgiv; rm -rf ~/.giverny/networks/test9;
The command above rebuilds the giverny
app and removes the network
test9``allow the ``new
commands to be run repeatedly. If you do not remove
the previous network test9
before running giverny network new
then the
command aborts. The make installgiv
is only required if you are making code
changes.
Adding -v
or --verbose
to each of these commands gives addition
information and progress messages in the command output.
New¶
8 node network, 4 initial peers, named from prebaked list of names, generated passphrases.
giverny network new test9 --generate-pass --names sampledata/names.txt --nodes 8 --initial-peers 4 -v
3 node network with named nodes, 2 initial peers. Passphrased prompted for on the command line and used for all key files.
make installgiv; rm -rf ~/.giverny/networks/test9; giverny network new test9 --save-pass --names sampledata/withnodes.txt --nodes 3 --initial-peers 2 -v
The withnodes.txt file is interesting as it shows the expanded syntax:
Jon,192.168.1.18,1T,true
Martin,192.168.1.3,1G,true
Kevin,192.168.1.16,1M,false
Export Network¶
The export command writes the configuration of one or more nodes to a zip file.
To export the configuration of all nodes in a network, type this:
$ giverny network export test9
Take a look in ~/.giverny/exports
. [1] There should be numerous files
named test9_[node].zip
. These can be applied to monetd
directly on the
same instance by:
$ giverny network import test9 Danu --from-exports
Alternatively you can use a secondary channel such as slack or e-mail to send that zip file and then load it — without changing the name of the file:
$ giverny network import test9 Danu --dir ~/Downloads
Or you can use giverny server and pull it directly. Assuming that you have run
giverny server start
on the instance you ran the exports you can:
$ giverny network import test9 Danu --server 192.168.1.4
[1] | This location is for Linux instances. Mac and Windows uses a different
path. The path for your instance can be ascertain with this command:
giverny network location |
Monetd Configuration¶
All the configuration required to run a node is stored under a directory with a
very specific structure. By default, monetd
will look for this directory in
$HOME/.monet
[1] (on Linux), but it is possible to override this with the
--datadir
flag.
The directory must respect the following stucture:
host:~/.monet$ tree
├── babble
│ ├── peers.genesis.json
│ ├── peers.json
│ └── priv_key
├── eth
│ ├── genesis.json
│ └── poa
│ ├── compile.toml
│ ├── contract0.abi
│ └── contract0.sol
├── keystore
│ ├── node0.json
├── monetd.toml
You would not normally need to access these configuration files directly. The
monetd config
tool provides a CLI interfaces to set up a network. The
command monetd config location --expanded
provides further details of the
filepaths used for your instance.
Eth¶
The eth/genesis.json
file defines prefunded accounts in the state, as well
as the POA smart-contract. This file is useful to predefine a set of accounts
that own all the initial tokens at the inception of the network. In addition,
the poa
section contains information about the POA smart-contract.
Example genesis.json
defining one prefunded account (the ABI and bytecode
of the smart-contract have been truncated):
{
"alloc": {
"a10aae5609643848ff1bceb76172652261db1d6c": {
"balance": "1234567890000000000000",
"moniker": "node0"
}
},
"poa": {
"address": "0xaBBAABbaaBbAABbaABbAABbAABbaAbbaaBbaaBBa",
"abi": "[\n\t{\n\t\t\"constant\": true, ... ]",
"code": "6080604052600436106101095760003560e01c8063..."
}
}
Babble¶
- babble/genesis.peers.json: defines Babble’s initial peer-set.
- babble/peers.json: defines Babble’s current peer-set
- babble/priv_key: contains the validator’s private key for Babble.
Run Options¶
Options pertaining to the operation of the node are read from the [datadir]/monetd.toml file, or overwritten by the following flags. It is envisaged that you would not need to use these flags in a production environment.
Flags:
--api-listen string IP:PORT of HTTP API service (default ":8080")
--babble.bootstrap bootstrap Babble from database
--babble.cache-size int number of items in LRU caches (default 50000)
--babble.heartbeat duration heartbeat timer milliseconds (time between gossips) (default 200ms)
--babble.listen string IP:PORT of Babble node (default "192.168.1.3:1337")
--babble.max-pool int max number of pool connections (default 2)
--babble.sync-limit int max number of Events per sync (default 1000)
--babble.timeout duration TCP timeout milliseconds (default 1s)
--eth.cache int megabytes of memory allocated to internal caching (min 16MB / database forced) (default 128)
--eth.min-gas-price string minimum gasprice of transactions submitted through this node (ex 1K, 1M, 1G, etc.) (default "0")
-h, --help help for run
Global Flags:
-d, --datadir string top-level directory for configuration and data (default "/home/martin/.monet")
-v, --verbose verbose output
Example of a monet.toml file:
datadir = "/home/user/.monet"
verbose = "false"
api-listen = ":8080"
[babble]
listen = "192.168.1.3:1337"
heartbeat = "500ms"
timeout = "1s"
cache-size = 50000
sync-limit = 1000
max-pool = 2
bootstrap = false
[eth]
cache = 128
[1] | This location is for Linux instances. Mac and Windows uses a different
path. The path for your instance can be ascertain with this command:
monetd config location |
Monetd Reference¶
monetd
provides the core commands needed to configure and run a node. It
has context sensitive help accessed either by running monetd help
or by
adding a -h
parameter to the relevant command.
[..monetd] $ monetd help
Monetd is the daemon component of the Monet Toolchain; a distributed
smart-contract platform based on the Ethereum Virtual Machine and Babble
consensus.
The minimal quickstart configuration is:
$ monetd config clear
$ monetd keys new node0
$ monetd config build node0
$ monetd run
See the documentation at https://monetd.readthedocs.io/ for further information.
Usage:
monetd [command]
Available Commands:
config manage configuration
help Help about any command
keys manage keys
run run a node
version show version info
Flags:
-d, --datadir string top-level directory for configuration and data (default "/home/jon/.monet")
-h, --help help for monetd
-v, --verbose verbose output
Use "monetd [command] --help" for more information about a command.
There are 5 subcommands. help
is described above. The other 4 commands are
described in separate sections below:
- help — show help for the command and subcommands
- version — shows the current version of monetd and subsystems
- keys — creates and manages keys
- config — creates and manages configurations
- run — runs the monet daemon, i.e. starts a node
Global Parameters¶
Global Parameters are available for all subcommands.
- -d, –datadir string — overrides the default location of the configuration files
- -h, –help — help command as discussed above
- -v, –verbose — turns on verbose messages. Defaults to false.
Version¶
The version
subcommand outputs the version number for monetd
,
EVM-Lite
, Babble
and Geth
.
If you compile your own tools, the suffices are the GIT branch and the GIT commit hash.
[..monetd] $ monetd version
Monetd Version: 0.2.3
EVM-Lite Version: 0.3.3-
Babble Version: 0.5.5-
Geth Version: 1.8.27
Keys¶
The keys
subcommand is used to manage Monet Toolchain keys. There are 4
subcommands, each described in a seperate section below:
- inspect — inspect a keyfile
- list — list keyfiles
- new — create a new keyfile
- update — change the passphrase on a keyfile
The keys
subcommand writes and reads keys from the keystore
sub-folder
in the monetd
configuration folder. You can see the location for your
instance with this command:
$ monetd config location -x
The help for the keys command is:
[..monetd] $ monetd keys help
Manage keys in the [datadir]/keystore folder.
Note that other Monet tools, like monetcli and monet-wallet, use the same
default [datadir]/keystore.
+------------------------------------------------------------------------------+
| Please take all the necessary precautions to secure these files and remember |
| the passwords, as it will be impossible to recover the keys without them. |
+------------------------------------------------------------------------------+
Keys are associated with monikers and encrypted in password-protected files in
[datadir]/keystore/[moniker].json. Keyfiles contain JSON encoded objects, which
Ethereum users will recognise as the de-facto Ethereum keyfile format. Indeed,
Monet and the underlying consensus algorithm, Babble, use the same type of keys
as Ethereum. A key can be used to run a validator node, or to control an account
with a token balance.
Usage:
monetd keys [command]
Available Commands:
inspect inspect a keyfile
list list keyfiles
new create a new keyfile
update change the passphrase on a keyfile
Flags:
-h, --help help for keys
--json output JSON instead of human-readable format
--passfile string file containing the passphrase
Global Flags:
-d, --datadir string top-level directory for configuration and data (default "/home/jon/.monet")
-v, --verbose verbose output
Use "monetd keys [command] --help" for more information about a command.
Parameters¶
All of the keys subcommands support the --passfile
flag. This allows you to
pass the path to a plain text file containing the passphrase for your key. This
removes the interactive prompt to enter the passphrase that is the default
mechanism.
Monikers¶
Keys generated by monetd
have a moniker associated with them. The moniker
is used to manage the keys as it is far more user friendly that an Ethereum
address or public key.
New¶
The new
subcommand generates a new key pair and associates it with the
specified moniker. You will be prompted for a passphrase which is used to
encrypt the keyfile. It writes the encrypted keyfile to the monetd keystore
area by default. The moniker must be unique within your keystore. If you
attempt to create a duplicate, the command will abort with an error.
[..monetd] $ monetd help keys new
Generate a new key identified by [moniker].
The keyfile will be written to [datadir]/keystore/[moniker].json. If the
--passfile flag is not specified, the user will be prompted to enter the
passphrase manually.
Usage:
monetd keys new [moniker] [flags]
Flags:
-h, --help help for new
Global Flags:
-d, --datadir string top-level directory for configuration and data (default "/home/jon/.monet")
--json output JSON instead of human-readable format
--passfile string file containing the passphrase
-v, --verbose verbose output
Inspect¶
[..monetd] $ monetd help keys display
Manage keys in the [datadir]/keystore folder.
Note that other Monet tools, like monetcli and monet-wallet, use the same
default [datadir]/keystore.
+------------------------------------------------------------------------------+
| Please take all the necessary precautions to secure these files and remember |
| the passwords, as it will be impossible to recover the keys without them. |
+------------------------------------------------------------------------------+
Keys are associated with monikers and encrypted in password-protected files in
[datadir]/keystore/[moniker].json. Keyfiles contain JSON encoded objects, which
Ethereum users will recognise as the de-facto Ethereum keyfile format. Indeed,
Monet and the underlying consensus algorithm, Babble, use the same type of keys
as Ethereum. A key can be used to run a validator node, or to control an account
with a token balance.
Usage:
monetd keys [command]
Available Commands:
inspect inspect a keyfile
list list keyfiles
new create a new keyfile
update change the passphrase on a keyfile
Flags:
-h, --help help for keys
--json output JSON instead of human-readable format
--passfile string file containing the passphrase
Global Flags:
-d, --datadir string top-level directory for configuration and data (default "/home/jon/.monet")
-v, --verbose verbose output
Use "monetd keys [command] --help" for more information about a command.
A sample session showing the command usage with and without the --private
parameter.
$ monetd keys inspect node0 --private
Passphrase:
Address: 0x02f6f3D24E447218d396C14F3B47f9Ea369DADf9
Public key: 0481d3528eec6138f8428932e4fe99571a4f77bd79ae13219540b0a929014cb490a4e5ced2f9e651b531522c2567b6dc5de75d485193615e768b8aa1190603d2c2
Private key: bc553aaa7e55c5d0f58f6897ba9bffdb88233c420da622d363f2fe4bd6d78df1
$ monetd keys inspect node0
Passphrase:
Address: 0x02f6f3D24E447218d396C14F3B47f9Ea369DADf9
Public key: 0481d3528eec6138f8428932e4fe99571a4f77bd79ae13219540b0a929014cb490a4e5ced2f9e651b531522c2567b6dc5de75d485193615e768b8aa1190603d2c2
Update¶
The update
subcommand allows you to change the passphrase for an encrypted
key file. You are prompted for the old passphrase, then you need to enter, and
confirm, the new passphrase.
You can suppress the prompts by specifying the --passfile
parameter to
supply the current passphrase and --new-passphrase
to supply the new
passphrase.
[..monetd] $ monetd help keys update
Change the passphrase on a keyfile.
If --passfile is not specified, the user will be prompted to enter the current
passphrase manually. Likewise, if --new-passfile is not specified, the user will
be prompted to input and confirm the new password.
Usage:
monetd keys update [moniker] [flags]
Flags:
-h, --help help for update
--new-passfile string the file containing the new passphrase
Global Flags:
-d, --datadir string top-level directory for configuration and data (default "/home/jon/.monet")
--json output JSON instead of human-readable format
--passfile string file containing the passphrase
-v, --verbose verbose output
An example session updating the passphrase for a key:
$ monetd keys update node0
Passphrase:
Please provide a new passphrase
Passphrase:
Repeat passphrase:
List¶
The list
subcommand outputs a list of monikers corresponding to the
keyfiles in the keystore. These are the valid monikers that can be specified to
other monetd
commands.
[..monetd] $ monetd help keys list
List keyfiles in [datadir]/keystore.
Usage:
monetd keys list [flags]
Flags:
-h, --help help for list
Global Flags:
-d, --datadir string top-level directory for configuration and data (default "/home/jon/.monet")
--json output JSON instead of human-readable format
--passfile string file containing the passphrase
-v, --verbose verbose output
An example session:
$ monetd keys list
node0
node1
node2
Config¶
The config
subcommand initialises the configuration for a monetd
node.
The folder can be overridden by the --datadir
parameter. The configuration
commands create all the files necessary for a node to join an existing network
or to create a new one.
There are 5 subcommands each described in a separate section below:
- clear — backup and clear configuration folder
- contract — display poa contract
- location — show the location of the configuration files
- build — create the configuration for a single-node network
- pull — pull the configuration files from a node
The two most common scenarios are:
- config build - config build creates the configuration for a single-node
- network, based on one of the keys in [datadir]/keystore.
This is a quick and easy way to get started with
monetd
. See Getting Started.
- config pull - config pull is used to join an existing network. It fetches the
- configuration from one of the existing nodes. See Joining a Network.
For more complex scenarios, please refer to Giverny Reference, which is a specialised Monet Toolchain configuration tool.
Clear¶
The clear
subcommand safely clears any previous monetd
configurations.
It renames the previous configuration with a .~n~
suffix, where n is the
lowest integer where the resultant filename does not already exist.
The configurations are renamed and not deleted to avoid the potential for inadvertent deletion of keys.
$ monetd config clear
Renaming /home/user/.monet to /home/user/.monet.~1~
Contract¶
The contract
subcommand generates the Solidity source for a POA smart
contract with the supplied node as the sole entry on the initial whitelist.
This command is not used in the standard workflow, but is provided as a
convenient mechanism to retrieve the solidity source.
[..monetd] $ monetd help config contract
Display the PoA smart contract.
Outputs the standard monetd contract, configured with [moniker] in the initial
whitelist.
Usage:
monetd config contract [moniker] [flags]
Flags:
-h, --help help for contract
Global Flags:
-d, --datadir string top-level directory for configuration and data (default "/home/jon/.monet")
-v, --verbose verbose output
A sample session is as follows. The contract is written to stdout, so you will probably wish to redirect it to a file or a pager.
$ monetd config contract node0 | more
pragma solidity >=0.4.22;
/// @title Proof of Authority Whitelist Contract
...
Location¶
The location
subcommand displays the path to the configuration folder. With
the --expanded
parameter, a list of directories and configuration files are
output.
[..monetd] $ monetd help config location
Show the location of the monetd configuration files. If --expanded is specified,
a detailed list of configuration files and directories is returned.
Usage:
monetd config location [flags]
Flags:
-x, --expanded show expanded information
-h, --help help for location
Global Flags:
-d, --datadir string top-level directory for configuration and data (default "/home/jon/.monet")
-v, --verbose verbose output
$ monetd config location
/home/user/.monet
$ monetd config location --expanded
Config root : /home/user/.monet
Babble Dir : /home/user/.monet/babble
EVM-Lite Dir : /home/user/.monet/eth
Keystore Dir : /home/user/.monet/keystore
Config File : /home/user/.monet/monet.toml
Wallet Config : /home/user/.monet/wallet.toml
Peers : /home/user/.monet/babble/peers.json
Genesis Peers : /home/user/.monet/babble/peers.genesis.json
Genesis File : /home/user/.monet/eth/genesis.json
Build¶
The build
subcommand initialises the bare-bones configuration to start
monetd
. It uses one of the accounts from the keystore to define a network
consisting of a unique node, which is automatically added to the PoA whitelist.
Additionally, all the accounts in [datadir]/keystore are credited with a large
amount of tokens in the genesis file. This command is mostly used for testing.
If the --address
flag is omitted, the first non-loopback address for this
instance is used.
[..monetd] $ monetd help config build
Create the configuration for a single-node network.
Use the keystore account identified by [moniker] to define a network with a
single node. All the accounts in [datadir]/keystore are also credited with a
large number of tokens in the genesis file. This command is mostly used for
testing. If the --address flag is omitted, the first non-loopback address is
used.
Usage:
monetd config build [moniker] [flags]
Flags:
--address string IP/hostname of this node (default "192.168.1.10")
-h, --help help for build
--passfile string file containing the passphrase
Global Flags:
-d, --datadir string top-level directory for configuration and data (default "/home/jon/.monet")
-v, --verbose verbose output
Pull¶
The pull
subcommand is used to join an existing network. It takes the
address of a running peer, and downloads the following set of files into the
configuration directory [datadir]:
- babble/peers.json : The current validator-set
- babble/peers.genesis.json : The initial validator-set
- eth/genesis.json : The genesis file
It also builds all the other configuration files required to run a monetd node. If the peer specified does not include a port, the default gossip port (1337) is used.
[..monetd] $ monetd help config pull
The pull subcommand is used to join an existing network. It takes the address
(host:port) of a running node, and downloads the following set of files into the
configuration directory [datadir]:
- babble/peers.json : The current validator-set
- babble/peers.genesis.json : The initial validator-set
- eth/genesis.json : The genesis file
Additionally, this command configures the key and network address of the new
node. The --key flag identifies a keyfile by moniker, which is expected to be in
the keystore. If --passfile is not specified, the user will be prompted to enter
the passphrase manually. If the --address flag is omitted, the first
non-loopback address is used.
Usage:
monetd config pull [host:port] [flags]
Examples:
monetd config pull "192.168.5.1:8080"
Flags:
--address string IP/hostname of this node (default "192.168.1.10")
-h, --help help for pull
--key string moniker of the key to use for this node (default "Jon")
--passfile string file containing the passphrase
Global Flags:
-d, --datadir string top-level directory for configuration and data (default "/home/jon/.monet")
-v, --verbose verbose output
Run¶
The run
subcommands starts the monetd node running. Whilst there are legacy
parameters --babble.*
and --eth.*
, we strongly recommend that they are
not used. The equivalent changes can be made in the configuration files.
[..monetd] $ monetd help run
Run a node.
Use the --datadir flag (-d) to set the node's data directory ($HOME/.monet by
default on Linux). It should contain a set of files defining the network that
this node is attempting to join or create. Please refer to the 'monetd config'
command to manage this configuration. Further options pertaining to the
operation of monetd can be specified in a monetd.toml file, within the data
directory, or overwritten by the following flags:
Usage:
monetd run [flags]
Flags:
--api-listen string IP:PORT of HTTP API service (default ":8080")
--babble.bootstrap bootstrap Babble from database
--babble.cache-size int number of items in LRU caches (default 50000)
--babble.heartbeat duration heartbeat timer milliseconds (time between gossips) (default 200ms)
--babble.listen string IP:PORT of Babble node (default "192.168.1.10:1337")
--babble.max-pool int max number of pool connections (default 2)
--babble.moniker string friendly name
--babble.sync-limit int max number of Events per sync (default 1000)
--babble.timeout duration TCP timeout milliseconds (default 1s)
--eth.cache int megabytes of memory allocated to internal caching (min 16MB / database forced) (default 128)
--eth.min-gas-price string minimum gasprice of transactions submitted through this node (ex 1K, 1M, 1G, etc.) (default "0")
-h, --help help for run
Global Flags:
-d, --datadir string top-level directory for configuration and data (default "/home/jon/.monet")
-v, --verbose verbose output
Giverny Reference¶
giverny
is the advanced configuration tool for the Monet Toolchain.
The current subcommands are:
- help — help
- version — outputs version information
- keys — key management tools
- server — configuration server management
- network — configure and build networks
- transactions — generate test transactions sets
Global Flag¶
The --verbose
flag, or -v
for short, turns on extended messages for
each giverny
command.
Help¶
giverny
has context sensitive help accessed either by
running giverny help
or by adding a -h
parameter to the relevant
command.
Version¶
The version
subcommand outputs the version number for monetd
,
EVM-Lite
, Babble
and Geth
.
If you compile your own tools, the suffices are the GIT branch and the GIT commit hash.
[..monetd] $ giverny version
Monetd Version: 0.2.3-develop-1e0abf7d
EVM-Lite Version: 0.3.3-develop
Babble Version: 0.5.5-develop
Geth Version: 1.8.27
Keys¶
The keys
subcommand offers tools to manage keys.
Keys Flags¶
In addition to the --verbose
flag, the keys
subcommand defines
addtional flags as follows:
Global Flags:
-g, --giverny-data-dir string Top-level giverny directory for configuration and data (default "/home/jon/.giverny")
-m, --monet-data-dir string Top-level monetd directory for configuration and data (default "/home/jon/.monet")
-v, --verbose verbose messages
Use "giverny keys [command] --help" for more information about a command.
Import¶
The import
subcommand is used to import a pre-existing key pair into the
monetd
keystore, assigning the given moniker and setting a passphrase.
[..monetd] $ giverny help keys import
Import keys to [moniker] from private key file [keyfile].
Usage:
giverny keys import [moniker] [keyfile] [flags]
Flags:
-h, --help help for import
Global Flags:
-g, --giverny-data-dir string Top-level giverny directory for configuration and data (default "/home/jon/.giverny")
--json output JSON instead of human-readable format
-m, --monet-data-dir string Top-level monetd directory for configuration and data (default "/home/jon/.monet")
--passfile string the file that contains the passphrase for the keyfile
-v, --verbose verbose messages
Generate¶
The generate
subcommand is used to bulk generate key pairs for a test net.
The --prefix
parameter defines a prefix for the account monikers. Then the
--min-suffix
and --max-suffix
define the range of accounts names.
E.g. --prefix=Acc --min-suffix=1 --max-suffix=3
would generate accounts:
Acc1
, Acc2
and Acc3
.
[..monetd] $ giverny help keys generate
The generate sub command is intended only for test nets. It generates a
number of key pairs and places them in the current monet keystore. The
accounts are names <prefix><suffix> where prefix is set by --prefix (default
"Account") and suffix is a number between --min-suffix and --max-suffix
inclusive. The defaults are 1 and 5.
Usage:
giverny keys generate [flags]
Flags:
-h, --help help for generate
--max-suffix int maximum suffix for account monikers (default 5)
--min-suffix int minimum suffix for account monikers (default 1)
--prefix string prefix for account monikers (default "Account")
Global Flags:
-g, --giverny-data-dir string Top-level giverny directory for configuration and data (default "/home/jon/.giverny")
--json output JSON instead of human-readable format
-m, --monet-data-dir string Top-level monetd directory for configuration and data (default "/home/jon/.monet")
--passfile string the file that contains the passphrase for the keyfile
-v, --verbose verbose messages
Server¶
The server
subcommand is used for adminstering a REST server used to
co-ordinate configurations between multiple nodes prior to the initial node of
a network.
The server listens on port 8088. It writes logs to
~/.giverny/server/server.pid
. [1]
For usage examples, see the recipes for setting up networks.
Start¶
To start the server in the foreground:
$ giverny server start
To start the server in the background:
$ giverny server start --background
Network¶
The network
command is used to build complex monet networks. The new
command generates the nodes and keys for a network, and automatically calls
the build
command which generates and builds genesis.json
and
peers.json
files. You can adjust the network by editting the
network.toml
file. The location
command outputs the relevant paths.
The push
command is used to push a giverny network node configuration to a
docker or actual node so it can be used by monetd
. start
, stop
and
status
are used to manage the docker instance.
The network name and node names must contain only standard letters (i.e. no accented versions), digits (0–9) or underscores (_).
Location¶
The giverny network location
subcommand takes a single optional parameter
network_name
. If the network is specified it outputs the location of key
files and folders for that network. If not, only the root giverny configuration
folder is output.
Example without a network name:
$ giverny network location
/home/user/.giverny
Example with a network specified:
$ giverny network location node7
Network : node7
Giverny Config Dir : /home/user/.giverny
Giverny Networks Dir : /home/user/.giverny/networks/node7
Giverny KeyStore Dir : /home/user/.giverny/networks/node7/keystore
Peers JSON : /home/user/.giverny/networks/node7/peers.json
Genesis JSON : /home/user/.giverny/networks/node7/genesis.json
Monetd TOML : /home/user/.giverny/networks/node7/monetd.toml
Network TOML : /home/user/.giverny/networks/node7/network.toml
New¶
The new
subcommand creates a new test network configuration. It also
invokes the build command automatically, unless the --no-build
parameter
is specified.
Syntax¶
[..monetd] $ giverny help network new
giverny network build
Usage:
giverny network new [network_name] [flags]
Flags:
--generate-pass generate pass phrases
-h, --help help for new
--initial-ip string initial IP address of range
--initial-peers int number of initial peers
--names string file containing node configurations
--no-build disables the automatic build of a new network
--no-save-pass don't save pass phrase entered on command line
-n, --nodes int number of nodes in this configuration (default -1)
--pass string file containing a passphrase
Global Flags:
-g, --giverny-data-dir string Top-level giverny directory for configuration and data (default "/home/jon/.giverny")
-m, --monet-data-dir string Top-level monetd directory for configuration and data (default "/home/jon/.monet")
-v, --verbose verbose messages
Nodes¶
The number of nodes in this network is specified by the
--nodes [int]
parameter. The --initial-peers [int]
parameter specifies
the number of initial peers. If not set it assumes that all nodes are in the
initial peer set.
IP Addresses¶
An initial IP address is supplied using the --initial-ip
parameter. It is
assumed the IP address range will be assigned by simply incrementing the last
octet of the IP address for each node. N.B. the first node will be assigned the
actual IP supplied by the initial-ip
parameter.
Node Names¶
The default node names are a standard prefix of node with a unique integer
suffix. You can override the default and supply a list of node names, which are
used in the order supplied, via the --names
parameter.
Node names must contain only standard Latin alphabet characters (ie a–z or A–Z with no accents), underscores (_), or digits (0–9).
Pass Phrases¶
There are numerous pass phrase flags for the new
subcommand.
--pass [passfile]
— uses the given pass phrase file for all nodes--generate-pass
— generates a unique passphrase for each key pair and writes it to a file nodename.txt in the network configuration keystore directory--no-save-pass
— suppresses saving pass phrases in the network configuration keystore directory
The typical use case scenarios for these flags would be:
- None specified — you are prompted to enter the passphrase for each node which is saved
--pass
only — the specified pass phrase is used, and saved in the config folder--pass
and--no-save-pass
— the specified pass phrase is used and not saved in the config folder--generate-pass
only — pass phrases are generated and saved--no-save-pass
only — you are prompted to enter the passphrase for each node, which is not saved in the config folder
Build¶
By default giverny network new
will run giverny network build
automatically. This can be disabled by specifying the -no-build
flag.
Examples¶
An example of the new subcommand:
$ giverny network new test11 --names sampledata/names.txt --nodes 7 --pass sampledata/pwd.txt --initial-peers 3 --initial-ip 192.168.1.19
Build¶
The giverny network build
subcommand takes a configuration created by the
new
subcommand and builds peers.json
and genesis.json
files.
build
can be run repeatably safely. It is envisaged that users will edit
the network.toml
file to adjust token allocations or change addresses.
--no-generate-keys
disables the creation of any keys not already in the
keystore.
A “built” network will have a file structure like this:
test7
├── compile.toml
├── contract0.abi
├── contract0.sol
├── genesis.json
├── keystore
│ ├── Amelia.json
│ ├── Amelia.txt
│ ├── Becky.json
│ ├── Becky.txt
│ ├── Chloe.json
│ ├── Chloe.txt
│ ├── Danu.json
│ ├── Danu.txt
├── monetd.toml
├── network.toml
└── peers.json
Export¶
The export
subcommand takes a configuration that has been generated and
exports it to the exports subfolder of the giverny configuration folders as a
zip file. The network export
command has a mandatory network name
parameter, and optionally one or more node names. If the node names are
omitted, all of the nodes for that network are exported.
Thus to export node nodename
:
$ giverny network export nodename
On Linux this writes to $HOME/.giverny/exports/nodename_<account>.zip
where there is one file for each account defined in the network.
Import¶
The import
subcommand takes a configuration previously exported by the
export
and configures monetd
to use the new configuration. You will
always need to specify a network name and a node name for the import. The
source for the import can be configured thus:
--from-exports
— from the exports subfolder in the giverny configuration folders. This is the default output location for theexport
command.--server
— from a giverny server. The giverny server will look in the exports subfolder in the giverny configuration folders on the instance it is running on. N.B. do not run the giverny server on any instance with live key pairs or sensitive configuration, as it may be exposed.--dir
— specify the folder the export zip is in. Do not rename the zip file. This is used when a secondary channel is used to communicate the keys.
[1] | (1, 2) This location is for Linux instances. Mac and Windows uses a different
path. The path for your instance can be ascertain with this command:
giverny network location |
List¶
The list
subcommand lists the configured network names.
$ giverny network list
benchmark
benchnet
bulktransfers
Dump¶
The dump
subcommand outputs the nodes in a named network in bar delimited
format as below:
giverny network dump crowdfundnet
Amelia|172.77.5.10|0x7bBE1Df184142709d5B99C5788982D0bEE5d1167|true|false
Becky|172.77.5.11|0xC6a29c6378C20eA9E868EdD3538Ba58d09318f81|true|false
Chloe|172.77.5.12|0x7b225252dEe5aDa558a233c7B8B654Ef366EBe61|true|false
Danu|172.77.5.13|0xC0d14Ed110045d7A401ecC9E57628D55e56Fd4c4|true|false
Add¶
The add
subcommand adds a node to the specified network. The resultant
network will then need to be built using the build
subcommand.
[..monetd] $ giverny help network add
giverny network add
Usage:
giverny network add [network_name] [node_name] [moniker] [flags]
Flags:
--generate-pass generate pass phrases
-h, --help help for add
--initial-ip string IP
--no-save-pass don't save pass phrase entered on command line
--pass string filename of a file containing a passphrase
Global Flags:
-g, --giverny-data-dir string Top-level giverny directory for configuration and data (default "/home/jon/.giverny")
-m, --monet-data-dir string Top-level monetd directory for configuration and data (default "/home/jon/.monet")
-v, --verbose verbose messages
Start¶
The start
subcommand starts a docker network. Individual nodes are not
started unless the --start-nodes
parameter is specified. If the
--force-network
parameter is set, then the network is forced down if it
is already running.
[..monetd] $ giverny help network start
giverny network start
Starts a network. Does not start individual nodes. The --force-network parameter
stops and restarts the network.
Usage:
giverny network start [network] [flags]
Flags:
--force-network force network down if already exists
-h, --help help for start
--start-nodes start nodes
--use-existing use existing network if already exists
Global Flags:
-g, --giverny-data-dir string Top-level giverny directory for configuration and data (default "/home/jon/.giverny")
-m, --monet-data-dir string Top-level monetd directory for configuration and data (default "/home/jon/.monet")
-v, --verbose verbose messages
Stop¶
The stop
subcommand stops a docker network and all the nodes within it.
[..monetd] $ giverny help network stop
giverny network stop
Stop a node and all the nodes within it.
Usage:
giverny network stop [network] [node] [flags]
Flags:
-h, --help help for stop
--remove stop and remove node
Global Flags:
-g, --giverny-data-dir string Top-level giverny directory for configuration and data (default "/home/jon/.giverny")
-m, --monet-data-dir string Top-level monetd directory for configuration and data (default "/home/jon/.monet")
-v, --verbose verbose messages
Status¶
The status
subcommand shows the docker network status
$ giverny network status
Networks
crowdfundnet 663db79442357cb8814b7ff40076abdd6479a2f5b24ab7087deceaf07913999a bridge
none 257f919e7203933bb10aadf17637552b16acb5490b5c8141815e2f19c01ff1fe null
bridge 37b969bb113d1707ce01328803bc57d0dc86bb349f617112d242f82ade0ada76 bridge
host b89aa9c3a413c14af09cbab6b3ee4450c2cf1cfdbc0449cb28d1f73e4c296d8b host
Containers
/Danu a67496705d1e5bf6dc0b92a7c4ec69d6c055dc2d08a3193d0e2f5c0fde74564b Up 10 seconds
/Chloe d7da80c6e3c7b92a61975208d72e5d4864d5c5b31bb67859d3c1bbb3feb38b43 Up 11 seconds
/Becky dbe47cb5ff517f47f18c4307c09de95ef86fe75279657e342d3bcfee2d6f1a1e Up 11 seconds
/Amelia 0f08e59ef698aecc62b2c6945d8c351c7902c90f13e6c4828ef9ab7c9ee27ec3 Up 12 seconds
Push¶
The push
subcommand creates a named node on a built docker network. If
the docker network has not yet been build, there is no need to push the node.
[..monetd] $ giverny help network push
giverny network push
Usage:
giverny network push [network] [node] [flags]
Flags:
-h, --help help for push
Global Flags:
-g, --giverny-data-dir string Top-level giverny directory for configuration and data (default "/home/jon/.giverny")
-m, --monet-data-dir string Top-level monetd directory for configuration and data (default "/home/jon/.monet")
-v, --verbose verbose messages
Transactions¶
The transaction commands are used to generate transactions sets for end to end testing of networks.
Generate¶
The generate
subcommand is used to generate transaction sets from the
network.toml
file.
The following flags can be set:
--count int number of tranactions to generate (default 20)
--faucet string faucet account moniker (default "Faucet")
-h, --help help for generate
--ips string ips.dat file path
-n, --network string network name
--surplus int additional credit to allocate each account from the faucet above the bare minimum (default 1000000)
Solo¶
The solo
subcommand is used to generate transactions sets from a single
funded account. Look in e2e/tools/build-trans.sh
for an end to end example
using the solo
command.
[..monetd] $ giverny help transactions solo
Solo transactions generate a transaction set without needing access
to the network toml file. You just need a well funded faucet account.
The additional accounts can be generated using giverny keys generate
Usage:
giverny transactions solo [flags]
Flags:
--accounts string comma separated account list
--count int number of tranactions to solo (default 20)
--faucet string faucet account moniker (default "Faucet")
-h, --help help for solo
--max-trans-value int maximum transaction value (default 10)
--output string output file (default "trans.json")
--surplus int additional credit to allocate each account from the faucet above the bare minimum (default 1000000)
Global Flags:
-g, --giverny-data-dir string Top-level giverny directory for configuration and data (default "/home/jon/.giverny")
-m, --monet-data-dir string Top-level monetd directory for configuration and data (default "/home/jon/.monet")
-v, --verbose verbose messages
Licences¶
The Monet Toolchain is an open source project, licensed under the MIT License (TLDR version). The software is provided as-is and we are not liable. We use many other libraries to build the Toolchain. This section presents the output of Glice for the Monet Toolchain. Glice reports on the licences used within a golang project.
The 3 tables are for the monetd,
EVM-Lite and Babble repositories respectively. These
tables are the output from glice -r
, which only looks one level deep. These
tables are for information only and are not legal advice.
monetd
:
DEPENDENCY REPOURL LICENSE github.com/AndreasBriese/bbloom github.com/btcsuite/btcd github.com/dgraph-io/badger github.com/dgryski/go-farm github.com/docker/docker github.com/ethereum/go-ethereum github.com/fatih/color github.com/fsnotify/fsnotify github.com/golang/protobuf github.com/gorilla/mux github.com/hashicorp/hcl github.com/magiconair/properties github.com/mattn/go-colorable github.com/mattn/go-isatty github.com/mgutz/ansi github.com/mitchellh/mapstructure github.com/mosaicnetworks/babble github.com/mosaicnetworks/evm-lite github.com/pelletier/go-toml github.com/pkg/errors github.com/sirupsen/logrus github.com/spf13/afero github.com/spf13/cast github.com/spf13/cobra github.com/spf13/jwalterweatherman github.com/spf13/pflag github.com/spf13/viper github.com/ugorji/go github.com/x-cray/logrus-prefixed-formatter golang.org/x/crypto/ssh/terminal golang.org/x/net/internal/timeseries golang.org/x/net/trace golang.org/x/sys/unix golang.org/x/text/transform golang.org/x/text/unicode/norm gopkg.in/yaml.v2 https://github.com/AndreasBriese/bbloom https://github.com/btcsuite/btcd https://github.com/dgraph-io/badger https://github.com/dgryski/go-farm https://github.com/docker/docker https://github.com/ethereum/go-ethereum https://github.com/fatih/color https://github.com/fsnotify/fsnotify https://github.com/golang/protobuf https://github.com/gorilla/mux https://github.com/hashicorp/hcl https://github.com/magiconair/properties https://github.com/mattn/go-colorable https://github.com/mattn/go-isatty https://github.com/mgutz/ansi https://github.com/mitchellh/mapstructure https://github.com/mosaicnetworks/babble https://github.com/mosaicnetworks/evm-lite https://github.com/pelletier/go-toml https://github.com/pkg/errors https://github.com/sirupsen/logrus https://github.com/spf13/afero https://github.com/spf13/cast https://github.com/spf13/cobra https://github.com/spf13/jwalterweatherman https://github.com/spf13/pflag https://github.com/spf13/viper https://github.com/ugorji/go https://github.com/x-cray/logrus-prefixed-formatter https://go.googlesource.com/crypto https://go.googlesource.com/net https://go.googlesource.com/net https://go.googlesource.com/sys https://go.googlesource.com/text https://go.googlesource.com/text Other isc Apache-2.0 Other Apache-2.0 LGPL-3.0 MIT bsd-3-clause bsd-3-clause bsd-3-clause MPL-2.0 Other MIT MIT MIT MIT MIT MIT MIT bsd-2-clause MIT Apache-2.0 MIT Apache-2.0 MIT bsd-3-clause MIT MIT MIT
EVM-Lite
:
DEPENDENCY REPOURL LICENSE github.com/sirupsen/logrus golang.org/x/crypto/ssh/terminal golang.org/x/sys/unix github.com/ethereum/go-ethereum https://github.com/sirupsen/logrus https://go.googlesource.com/crypto https://go.googlesource.com/sys https://github.com/ethereum/go-ethereum MIT
LGPL-3.0
Babble
:
DEPENDENCY REPOURL LICENSE github.com/AndreasBriese/bbloom github.com/btcsuite/btcd github.com/btcsuite/fastsha256 github.com/dgraph-io/badger github.com/dgryski/go-farm github.com/fsnotify/fsnotify github.com/golang/protobuf github.com/hashicorp/hcl github.com/magiconair/properties github.com/mitchellh/mapstructure github.com/pelletier/go-toml github.com/pkg/errors github.com/sirupsen/logrus github.com/spf13/afero github.com/spf13/cast github.com/spf13/cobra github.com/spf13/jwalterweatherman github.com/spf13/pflag github.com/spf13/viper github.com/ugorji/go golang.org/x/crypto/ssh/terminal golang.org/x/net/internal/timeseries golang.org/x/net/trace golang.org/x/sys/unix golang.org/x/text/transform golang.org/x/text/unicode/norm gopkg.in/yaml.v2 github.com/rifflock/lfshook https://github.com/AndreasBriese/bbloom https://github.com/btcsuite/btcd https://github.com/btcsuite/fastsha256 https://github.com/dgraph-io/badger https://github.com/dgryski/go-farm https://github.com/fsnotify/fsnotify https://github.com/golang/protobuf https://github.com/hashicorp/hcl https://github.com/magiconair/properties https://github.com/mitchellh/mapstructure https://github.com/pelletier/go-toml https://github.com/pkg/errors https://github.com/sirupsen/logrus https://github.com/spf13/afero https://github.com/spf13/cast https://github.com/spf13/cobra https://github.com/spf13/jwalterweatherman https://github.com/spf13/pflag https://github.com/spf13/viper https://github.com/ugorji/go https://go.googlesource.com/crypto https://go.googlesource.com/net https://go.googlesource.com/net https://go.googlesource.com/sys https://go.googlesource.com/text https://go.googlesource.com/text
Other isc Other Apache-2.0 Other bsd-3-clause bsd-3-clause MPL-2.0 Other MIT MIT bsd-2-clause MIT Apache-2.0 MIT Apache-2.0 MIT bsd-3-clause MIT MIT
MIT
FAQ¶
General¶
What is the difference between MONET, MONET Hub, Monet Toolchain and monetd
?¶
monetd
is the daemon that runs a node on a blockchain. monetd
is also a
repository on Github. The
repository also hosts giverny
which implements advanced configuration
options.
The Monet Toolchain consists of the monetd
repository, plus additional
software, noticeably monetcli.
Together these repositories provide a complete suite of tools for running a
blockchain. Whilst the Monet Toolchain was initially developed for the MONET
Hub, it has been designed to be easily used by other projects.
The MONET Hub is a specific blockchain running on the Monet Toolchain software.
MONET is the whole ecosystem containing the MONET Hub, and mobile adhoc blockchains that use the MONET Hub to persist state.
Why Giverny?¶
Whilst the name MONET is derived from Mosaic Networks, Giverny was famously the home of Claude Monet and inspiration for many of his most renowned works.
The Monet Toolchain¶
The Monet Toolchain provides software to run and interact with a distributed smart-contract platform based on EVM-Lite and Babble consensus.
It underpins the MONET Hub, which is an important part of the MONET project, but is licensed under the MIT license and available for use in other projects. You can read more about MONET in the whitepaper.