(image)

Programming Hotmoka
A tutorial on Hotmoka and smart contracts in Takamaka

8.2 Disk nodes

The Hotmoka nodes of the previous sections form a real blockchain. They are perfect for deploying a blockchain where we can program smart contracts in Takamaka. Nevertheless, they are slow for debugging: transactions are committed every few seconds, by default. Hence, if we want to see the result of a transaction, we have to wait for some seconds at least. Moreover, Tendermint does not allow one to see the effects of each single transaction, in a simple way. For testing, debugging and didactical purposes, it would be simpler to have a light node that behaves like a blockchain, allows access to blocks and transactions as text files, but is not a blockchain. This is the goal of the DiskNodes. They are not part of an actual blockchain since they do not propagate transactions in a peer-to-peer network, on which consensus is imposed. But they are very handy because they allow one to inspect, very easily, the requests sent to the node and the corresponding responses.

You can start a disk Hotmoka node, with an open faucet, exactly as you did, in the previous sections for a Mokamint or Tendermint node, but using the moka nodes disk init command instead of moka nodes [mokamint|tendermint] init. You do not need any Mokamint or Tendermint configuration this time, but still need a key to control the gamete of the node, that you can create exactly as for the previous Hotmoka nodes. You then specify the Base58-encoded public key when starting the node:

moka nodes disk init ~/.m2/repository/io/hotmoka/io-takamaka-code/1.8.1/io-takamaka-code-1.8.1.jar --public-key-of-gamete=GUHhy8j8qiXcGjdGdSNqCFJjGTpyN6QyQn6BXCQ8aF3W --open-unsigned-faucet
The following service has been published:
 * ws://localhost:8001: the API of this Hotmoka node


The owner of the key pair of the gamete can bind it now to its address with:
  moka keys bind file_containing_the_key_pair_of_the_gamete --password --url url_of_this_Hotmoka_node
or with:
  moka keys bind file_containing_the_key_pair_of_the_gamete --password --reference e020a52ee08fd0d8a19a26f1ad06f3f999fef96b6db0d7d0f4ba32f0b0a174b7#0


Press the enter key to stop this process and close this node:

Then, in another shell, you can bind the gamete and open the flow of the faucet, as we did for the other kinds of Hotmoka nodes.

You should have noticed any apparent difference with the previous kinds of Hotmoka nodes, but for the fact that this node is faster, its default chain identifier is the empty string and it has no validators. Blocks and transactions are inside the chain directory, that this time contains a nice textual representation of requests and responses:

tree chain/hotmoka/store
chain/hotmoka/store
|-- b1
| `-- 0-68e90e2868751a3f22fd5fad3ceef377b91b3e52fdd30705f57505e22902ce40
| |-- request.txt
| `-- response.txt
|-- b2
| `-- 0-e020a52ee08fd0d8a19a26f1ad06f3f999fef96b6db0d7d0f4ba32f0b0a174b7
| |-- request.txt
| `-- response.txt
|-- b3
| `-- 0-7d8bf225f8d940b12b6ec5bdfdd27a4934303d5a625f6f40085298d3b6bd0528
| |-- request.txt
| `-- response.txt
|-- b4
| `-- 0-ace80463d22a329dd42881000dfdd06490b574e67732d141eaa8ed12702927cb
| |-- request.txt
| `-- response.txt
|-- b5
| `-- 0-bfb48958275c8f7242868fed2fbce6fb936f01e07738a522ee9a11bc4cf000ff
| |-- request.txt
| `-- response.txt
`-- b6
    |-- 0-734de09401f29e9c34551e13611c31676676d07a11e8f8ed01095038dbd6388b
    | |-- request.txt
    | `-- response.txt
    `-- 1-1e1b85af2622777e7292efe60c1f0af313876b7182b10db04b19757804d23318
         |-- request.txt
         `-- response.txt

The exact ids and the number of these transactions will be different in your computer.

There are blocks b0,…,b7, each containing a variable number of transactions. Each transaction is reported with its id and the pair request/response that the node has computed for it. They are text files, that you can open to understand what is happening inside the node.

The transactions shown above are those that have initialized the node and opened the faucet. The last transaction inside the last block is a reward transaction, that distributes the earnings of the block to the (zero, for disk nodes) validators and increases block height and number of transactions in the manifest.

Spend some time looking at the request.txt and response.txt files. For instance, the transaction inside b2 should be the one that created the gamete account. Print its request.txt file:

cat chain/hotmoka/store/b2/0-*/request.txt
GameteCreationTransactionRequestImpl:
  class path: 68e90e2868751a3f22fd5fad3ceef377b91b3e52fdd30705f57505e22902ce40
  initialAmount: 10000000000000000000000000000
  publicKey: 5dzgK1HUMZNkCpOy4gxIcG+4kAaseppBpFixr6kg3EE=

You can see that this is a request to create a gamete: it specifies the initial amount of crypto coins held in the gamete and the public key of the gamete, which is what we passed when we initialized the node (in base64 format, since it is more compact, in general). Print its response now:

cat chain/hotmoka/store/b2/0-*/response.txt
GameteCreationTransactionResponseImpl:
  gamete: e020a52ee08fd0d8a19a26f1ad06f3f999fef96b6db0d7d0f4ba32f0b0a174b7#0
  updates:
    <e020a52ee08fd0d8a19a26f1ad06f3f999fef96b6db0d7d0f4ba32f0b0a174b7#0.class|io.takamaka.code.lang.Gamete|@68e90e2868751a3f22fd5fad3ceef377b91b3e52fdd30705f57505e22902ce40>
    <e020a52ee08fd0d8a19a26f1ad06f3f999fef96b6db0d7d0f4ba32f0b0a174b7#0|io.takamaka.code.lang.Contract.balance:java.math.BigInteger|10000000000000000000000000000>
    <e020a52ee08fd0d8a19a26f1ad06f3f999fef96b6db0d7d0f4ba32f0b0a174b7#0|io.takamaka.code.lang.ExternallyOwnedAccount.nonce:java.math.BigInteger|0>
    <e020a52ee08fd0d8a19a26f1ad06f3f999fef96b6db0d7d0f4ba32f0b0a174b7#0|io.takamaka.code.lang.ExternallyOwnedAccount.publicKey:java.lang.String|"5dzgK1HUMZNkCpOy4gxIcG+4kAaseppBpFixr6kg3EE=">
    <e020a52ee08fd0d8a19a26f1ad06f3f999fef96b6db0d7d0f4ba32f0b0a174b7#0|io.takamaka.code.lang.Gamete.maxFaucet:java.math.BigInteger|0>

You can see that this response reports the storage reference of the gamete that has been created. Moreover, responses typically report a set of updates, as in this case. Updates are the side-effects on the state of the node, induced by the transaction. Each update is a triple, that specifies a change in the value of a field of a storage object. In this case, the updates describe the initial state of the gamete object; for instance, an update states that the balance of the gamete has been set to the initial supply for the node; another states that the maxFaucet field of the gamete has been set to 0: this might be modified later through a transaction triggered by the moka nodes faucet command.