Sign inSign up

hotmoka/mokamint-node

By hotmoka

Updated 3 months ago

A node of a blockchain based on proof of space over Mokamint, with smart contracts in Takamaka.

Image
Networking
Languages & frameworks
Internet of things
0

1.5K

hotmoka/mokamint-node repository overview

Mokamint and Hotmoka

This image provides a Hotmoka node of a blockchain based on the Mokamint proof of space engine (https://github.com/Mokamint-chain/mokamint). Consensus is achieved through a competition where a node is more likely to win and mine the next node if it allocates a larger plot file on its file system.

Hotmoka is the abstract definition of a device that can store objects (data structures) in its persistent memory (its state) and can execute, on those objects, code written in a subset of Java called Takamaka. Such a device is called a Hotmoka node and such programs are known as smart contracts. It is well true that Hotmoka nodes can be different from the nodes of a blockchain (for instance, they can be an Internet of Things device); however, the most prominent application of Hotmoka nodes is, at the moment, the construction of blockchains whose nodes are Hotmoka nodes.

Every Hotmoka node has its own persistent state, that contains code and objects. Since Hotmoka nodes are made for running Java code, the code inside their state is kept in the standard jar format used by Java, while objects are just a collection of values for their fields, with a class tag that identifies whose class they belong to and a reference (the classpath) to the jar where that class is defined. While a device of an Internet of Thing network is the sole responsible for its own state, things are different if a Hotmoka node is part of a blockchain. There, the state is synchronized and identical across all nodes of the blockchain.

The following instructions provide information on how to create Hotmoka nodes of a blockchain whose consensus is based on the Mokamint proof of space engine.

NOTE: the following instructions let you join the mainnet of Hotmoka. If you want to join the testnet, instead, just replace lipari.hotmoka.io:8030 with panarea.hotmoka.io:8030 below.


Join an existing blockchain, by spawning a new node that clones an existing node

This is the most typical situation. Namely, you want to join an existing blockchain, with a node that mines new blocks and receives blocks created by the other peers. This docker image provides a script for this situation. This script includes the creation of a local miner as well, or otherwise your node would not be able to mine new blocks. Because of this, the scripts deal with two key pairs: the former identifies the node, and is kept inside the machine running the script, and the latter identifies the miner, it can be stored elsewhere and only its public key is needed here.

The process is consequently split in two:

  • configure the node (config-clone)
  • run the node (go)

Each phase is the execution of a script inside this docker image. The script config-clone is meant to be run only once, while go can be run, stopped and run again, whenever you want to start or stop a node. You can also pause it and unpause it. The reason for splitting the process in two scripts is that it allows one to manually edit the configuration created by config-clone before running the node, although we won't show this here. Moreover, having distinct scripts allows go to be stopped and run again, repeatedly, whenever you want to stop and restart a node.

The following instructions assume that you have a reliable internet connection. If the connection is too slow, or flickering, or if it disconnects for some time, the synchronization of the node will likely fail.

Configure the node: config-clone

This script creates the configuration directory of a node that joins an existing Hotmoka blockchain based on the Mokamint proof of space engine. For that, you must specify the URI of a node of this blockchain, from where the configuration information will be fetched.

The first thing to do is to create a key pair for the miner of the new node that you want to start. You can do this by running the container and the moka command inside it:

docker run -it --rm --name hotmoka hotmoka/mokamint-node:1.12.4 /bin/bash

and inside the container:

hotmoka@afbef35bce14:~$ moka keys create --name miner.pem --password

When prompted, enter the password that you prefer or just leave it blank. The output will be something like:

Enter value for --password (the password that will be needed later to use the key pair): 
The new key pair has been written into "miner.pem":
* public key: CBSW5keMkZ5wuupC4S4c1KbtbWzdsAzbeNseY3E9v5o4 (ed25519, base58)
* public key: ph0y5d0xREYKFZOYMC+AROXf/0+h9He6clCt9rbIcec= (ed25519, base64)
* Tendermint-like address: 21476455E6E2277C88090F063A9DC05E3190E4A3

This will create a key pair miner.pem inside the running container. In another shell, you can transfer the key pair to your local machine:

docker cp hotmoka:/home/hotmoka/miner.pem .

At this point, delete the key pair from the container and exit the container:

hotmoka@afbef35bce14:~$ rm miner.pem
hotmoka@afbef35bce14:~$ exit

You can finally run the script that configures the node. Use it the base58-encoded public key of the key pair that you have created above. Specify ws://lipari.hotmoka.io:8030 as the URI of a node of the blockchain to join: this node is part of the Hotmoka mainnet and is maintained by Hotmoka itself. Specify the size of the plot file to use for the proof of space: the larger, the more blocks will be created by your node, but also more disk space will be allocated for mining. We will use two volumes: chain will contain the actual blockchain data and hotmoka_mokamint will contain the configuration information created for the node. By using volumes, we can share that information across successive invocations of docker:

docker run -it --rm -e PUBLIC_KEY_MINER_BASE58=CBSW5keMkZ5wuupC4S4c1KbtbWzdsAzbeNseY3E9v5o4 -e MOKAMINT_PUBLIC_SERVICE_URI=ws://lipari.hotmoka.io:8030 -e PLOT_SIZE=4000 -v chain:/home/hotmoka/chain -v hotmoka_mokamint:/home/hotmoka/hotmoka_mokamint hotmoka/mokamint-node:1.12.4 config-clone

Note that the script above will create another key pair (and ask you about the relative password), that will be kept inside the container. This key pair identifies the node and will be used to sign the blocks that the node will create. It must remain inside the container, although you may want to extract a copy from the container to your local host.

Run the node: go

After configuring the node, you can run it with the go script:

docker run -it --log-driver local --rm --name hotmoka -p 8001:8001 -p 8025:8025 -p 8030:8030 -p 127.0.0.1:8031:8031 -v chain:/home/hotmoka/chain -v hotmoka_mokamint:/home/hotmoka/hotmoka_mokamint hotmoka/mokamint-node:1.12.4 go

The command above allows connections to the ports:

  • 8001: this is the port where the Hotmoka node is published by default; it can be used to contact the node, install and run smart contracts;
  • 8025: this is the port where mining services can connect by default; mining services help your node produce new blocks; note that this requires to open a remote miner in your node, listening at port 8025;
  • 8030: this is the port where Mokamint can be reached for public queries, by default;
  • 8031: this is the port where Mokamint can be reached for restricted operations, by default; note the we have restricted its access to localhost only, since we do not want our Mokamint node to be freely reconfigured remotely.

After the command above, you should see that the node will start up and begin synchronizing from ws://lipari.hotmoka.io:8030. This will take some time (hours, days, weeks...) depending on the age of the cloned blockchain and on the speed of your internet connection. You can leave the container in the backrground by entering ctrl+p, ctrl+q, as always in docker.

You can then monitor the progress of the synchronization by entering the running container and executing the mokamint-node command:

docker exec -it hotmoka /bin/bash

and then

hotmoka@e41eda9afd3b:~$ mokamint-node chain ls 10

You can also see the manifest of the node, that is identical to that of any other node of the joined blockchain:

hotmoka@e41eda9afd3b:~$ moka nodes manifest show
Reconfigure a node

If you want to reconfigure a node, for instance because you want to resize its plot file, you can stop the node (docker stop hotmoka), rerun the config-clone script and then the go script. Note however that, by default, config-clone will create a new node.pem key pair to identify the node and will erase the directory where the blockchain is kept. Therefore, you will end up with two node key pairs (the old one and the new one), while it would be normally easier to recycle the old key pair and consolidate all earnings in that same key pair. Moreover, the chain directory will have to be downloaded again, from scratch, with a long synchronization, when go will be invoked. To avoid these problems, we suggest that, when rerunning the config-clone script, you set the environment variables -e KEEP_NODE_PEM=true and -e KEEP_CHAIN=true in the docker invocation.

Migrate a node

What identifies a node is its key pair, used to sign the blocks that it creates. If you ran either config-clone or config-new, these scripts will have created a node.pem key pair file inside the configuration directory of the docker container, to identify the node. It might happen that you want to migrate that node, i.e., you might want to move it into another machine, for instance because it has a larger disk space or a better internet connection. In order to keep the identity of the node, you need to recycle the same node.pem that was used in the previous machine. But running config-clone in the new machine will created a new node.pem and you will end up with two key pairs, that of the old node and that of the new node. This is typically problematic, since you will have some coins collected while mining with the old key pair and other coins collected while mining with the new key pair. Instead, you normally want to keep the old node.pem and consolidate all earnings into that same key pair.

Assume then that you have copied the key pair node.pem of the old node in your working directory of the new machine. Remember that you can extract it from the old node, running in the old machine, with

docker cp hotmoka:/home/hotmoka/hotmoka_mokamint/node.pem .

In the new machine, create the container, but do not start it yet:

docker create -it --rm --name hotmoka -e KEEP_NODE_PEM=true -e PUBLIC_KEY_MINER_BASE58=CBSW5keMkZ5wuupC4S4c1KbtbWzdsAzbeNseY3E9v5o4 -e MOKAMINT_PUBLIC_SERVICE_URI=ws://lipari.hotmoka.io:8030 -e PLOT_SIZE=4000 -v chain:/home/hotmoka/chain
-v hotmoka_mokamint:/home/hotmoka/hotmoka_mokamint hotmoka/mokamint-node:1.12.4 config-clone

Of course, use the plot size that you prefer instead of 4000. Note that we have given a name to the container (hotmoka) and that we asked to keep the existing node.pem key pair. Moreover, we are always using the same public key for the local miner of the new node as well, so that we also consolidate all earnings for the local miner. After creating the container in the new machine, let us inject the desired node.pem inside it:

docker cp node.pem hotmoka:/home/hotmoka/hotmoka_mokamint/

We can start the container hotmoka now: it will use the injected node.pem, instead of creating a new one, since we used -e KEEP_NODE_PEM=true when we created that container above:

docker start --attach -i hotmoka

This will start the container and create the configuration. When it will complete, you can run the migrated node, in the new machine, with the go script. It will perform an initial synchronization and then start mining, with the same identity as the old node.


Update a node

If you want to update the version of a running node, you must first stop it and then restart the new version:

docker stop hotmoka
docker rm hotmoka

then run the new version of the node as explained above for the go command.


Start a brand new blockchain, by spawning its first node

This situation is much rarer. It occurs when you want to start a brand new blockchain from scratch, by minting its genesis block and initializing its store. Later, other nodes can join the new blockchain with the technique described above.

This docker image provides a script for starting a brand new blockchain. This script includes the creation of a local miner as well, or otherwise your node would not be able to mine new blocks. Because of this, the scripts deal with two key pairs: the former identifies the node, and is kept inside the machine running the script, and the latter identifies the miner, it can be stored elsewhere and only its public key is needed here.

The process is consequently split in three:

  • configure the node (config-new)
  • initialize the node (init)
  • run the node (go)

Each phase is the execution of a script inside this docker image. The scripts config-new and init are meant to be run only once, while go can be run, stopped and run again, whenever you want to start or stop a node. You can also pause it and unpause it. The reason for splitting the process in three scripts is that it allows one to manually edit the configuration created by config-new before initializing and running the node, although we won't show this here. Moreover, having distinct scripts allows go to be stopped and run again, repeatedly, whenever you want to stop and restart a node.

Configure the node: config-new

The configuration requires the creation of a brand new key pair that will identify the miner of the node. Follow the instructions above for creating the miner.pem key pair file. Moreover, you will need another key pair, for the gamete account. This is an account of Hotmoka that holds all cryptocurrency minted at start-up. It can also be used for providing cryptocurrency for free, if your node allows a free faucet. In any case, you need a key pair for the gamete account as well. Therefore, follow the instructions above and create gamete.pem as well.

You can now configure the node, specifying the public key of the miner and that of the gamete:

docker run -it --rm -e PUBLIC_KEY_MINER_BASE58=CBSW5keMkZ5wuupC4S4c1KbtbWzdsAzbeNseY3E9v5o4 -e PUBLIC_KEY_GAMETE_BASE64="ilHobNusVPO0dE8j47tpcErMylFwKkaZOhby0c4FWmY=" -e PLOT_SIZE=5000 -e CHAIN_ID=whale -e TARGET_BLOCK_CREATION_TIME=10000 -v chain:/home/hotmoka/chain -v hotmoka_mokamint:/home/hotmoka/hotmoka_mokamint hotmoka/mokamint-node:1.12.4 config-new

Note that the public key of the miner is reported in base58, while that of the gamete is reported in base64, currently. The target block creation time, in milliseconds, is the average time between the creation of two successive blocks. The chain identifier identifies the new network and must be used, for instance, in the transaction requests sent to the Hotmoka nodes of the network.

The script above will prompt for the password of the key pair used for signing the new blocks. Enter your chosen password or just leave it blank. The script will configure the node and create a plot file for its miner.

Initialize the node: init

The initialization of the node consists in the execution of a few initial transactions that create the genesis block, the manifest and the gas station of the node. You can do this with:

docker run -it --rm -v chain:/home/hotmoka/chain -v hotmoka_mokamint:/home/hotmoka/hotmoka_mokamint hotmoka/mokamint-node:1.12.4 init

This should take a few seconds. You should see the logs of the executed transactions, until the script terminates.

Run the node: go

Once the node has been configured and initialized, you can run it. Follow for this the instructions reported above for the go script.


Source Code

Mokamint and Hotmoka are open-source projects whose code is maintained on Github: https://github.com/Hotmoka/hotmoka and https://github.com/Mokamint-chain/mokamint.

License

Mokamint and Hotmoka are licensed under the Apache-2.0 open-source license.

Further Information

You can see all options of the scripts in this image by executing:

docker run -it --rm hotmoka/mokamint-node:1.12.4 info

Tutorial

The above Github page of Hotmoka contains a detailed tutorial about Hotmoka, its use, the creation of smart contracts in Takamaka and their execution. The tutorial is also available in PDF version under the releases section of the Github project and can also be read online.

Tag summary

Content type

Image

Digest

sha256:b17181ab3

Size

274.9 MB

Last updated

3 months ago

docker pull hotmoka/mokamint-node:1.12.4