Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thor and accounts #7

Merged
merged 12 commits into from
Oct 31, 2024
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ The [src](src) directory provides a list of lessons with exercises and solutions
* [User's keys and address.](src/3.Keys_Addresses_Wallets/Keys.md)
* [User's keys and address from mnemonic words - BIP39.](src/3.Keys_Addresses_Wallets/BIP39.md)
* [One key to rule them all: hierarchic deterministic keys and wallets - BIP32.](src/3.Keys_Addresses_Wallets/BIP32.md)
4.
* [Thor networks - 'mainnet', 'testnet' and 'solo'](src/4.Accounts/Thor.md)


The lessons show snippet of code beginning with the remarks starting with `// STEP <n>: `,
those refer to the complete code in the file haning the same name of the file of the lesson with the suffix `.ts` or `.mts`
those refer to the complete code in the file naming the same name of the file of the lesson with the suffix `.ts` or `.mts`

## License

Expand All @@ -27,4 +30,4 @@ This project is licensed under the [MIT license](LICENSE.md).
## Contact information

- Discord https://discord.com/invite/vechain
- Support https://support.vechain.org
- Support https://support.vechain.org
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@
"license": "MIT",
"description": "VeChain SDK Tutorial for NodeJS.",
"dependencies": {
"@vechain/sdk-network": "1.0.0-beta.32"
"@vechain/sdk-network": "1.0.0-beta.32",
"bignumber.js": "^9.1.1"
},
"devDependencies": {
"@commitlint/config-conventional": "^19.5.0",
"@eslint/js": "^9.12.0",
"commitlint": "^19.5.0",
"eslint": "^9.12.0",
"eslint-config-love": "^v87.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-config-standard-with-typescript": "^43.0.1",
"eslint-plugin-import": "^2.31.0",
Expand Down
17 changes: 17 additions & 0 deletions src/1.Hello_World/FinancialMath.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Lesson 1 - Part 2

# Financial Math

JavaScript (JS) was designed as front-end language.

The JS `number` type implements the 64 bits [Double Precision Floating Point](https://en.wikipedia.org/wiki/Double-precision_floating-point_format)
representation as the `double` type common in *C#*, *Java?Kotlin* and *Rust/Zig* programming languages.
This representation approximates the real value with less precision as the value moves to the edge of
the information can be represented in 8 bytes,

String doesn't oblige to approximation.



https://mikemcl.github.io/bignumber.js/

34 changes: 34 additions & 0 deletions src/1.Hello_World/FinancialMath.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { FixedPointNumber } from '@vechain/sdk-core';
import { BigNumber } from 'bignumber.js';

let x = FixedPointNumber.of(123.456789);
let y = FixedPointNumber.of('123.456789');
console.log(
`FPN value ${x} from number is ${x.isEqual(y) ? '' : 'not'}equal to ${y} from string.`
);
console.log(`Cast FPN value to number is ${x.n}.`);
console.log(`Cast FPN value to bigint is ${x.bi}.`);

x = FixedPointNumber.of(1);
y = FixedPointNumber.of(3);
let r = x.div(y);
console.log(
`FPN value = ${r}; JS value = ${x.n / y.n}; BigNumber value = ${BigNumber(x.n).div(y.n)}.`
);
x = x.dp(80); // must be updated
r = x.div(y);
console.log(`${r}`);

const dp = 20;
for (let n = 0; n <= 8; n++) {
x = FixedPointNumber.of(n, BigInt(dp));
r = x.sqrt();
console.log(`${n}, ${r};\t${Math.sqrt(n)};\t${BigNumber(n).dp(dp).sqrt()}`);
}

// let dp = 20;
// for(let n = 0; n <= 8; n ++) {
// x = FixedPointNumber.of(n, BigInt(dp));
// r = x.sqrt();
// console.log(`${n}, ${r};\t${Math.sqrt(n)};\t${BigNumber(n).dp(dp).sqrt()}`);
// }
2 changes: 1 addition & 1 deletion src/1.Hello_World/HelloWorld.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Lesson 1
## Lesson 1 - Part 1

# Hello World!

Expand Down
147 changes: 147 additions & 0 deletions src/4.Accounts/Thor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
## Lesson 4 - Part 1

# Thor networks - 'mainnet', 'testnet' and 'solo'

VeChain develops and provides the **[Thor](https://docs.vechain.org/core-concepts/networks)** blockchain networks.

The **[mainnet](https://docs.vechain.org/core-concepts/networks/mainnet)**
refers to the live, operational version of a blockchain network.
It is the real, functioning blockchain network that is open to the public
and used by participants to conduct actual transactions, store data, and execute smart contracts.

The **[testnet](https://docs.vechain.org/core-concepts/networks/testnet)**
is a testing environment where developers and users can experiment prior
to deploying code to the blockchain production network, referred to as **mainnet**.
The **testnet** is essentially a separate blockchain networks that
mirrors the functionality of the **mainnet** but is isolated from it.

The **Thor** **[solo](https://docs.vechain.org/core-concepts/networks/thor-solo-node)** is a local
instance of **Thor** operating a single node that independently maintains and validates the entire blockchain network.
In other words, a **solo** node does not rely on other nodes for validation and verification of transactions and blocks.
Instead, it performs all the necessary tasks on its own.
Therefore, running a Thor **solo** node is essentially running the VeChainThor node software but not connecting it
to other network participants in **mainnet** or **testnet**.

The **solo** node network instance is very convenient to develop and test software for the VeChain Thor network
without the need to be connected to **testnet** for the development, everything can be done in local.

The following of this tutorial uses **Thor solo** to show how to develop software for the VeChain networks.

## Start and stop Thor 'solo'

The link at [How to run a Thor 'solo' node network](https://docs.vechain.org/how-to-run-a-node/how-to-run-a-thor-solo-node)
explains how to install and configure a Thor **solo** network.

The most convenient way to run a **solo** node network is to run it in a
**[docker](https://docs.vechain.org/how-to-run-a-node/how-to-run-a-thor-solo-node#docker-containerized-convenience)**
container.

The following guides shows how to install
- **[docker](https://docs.docker.com/get-started/get-docker/)**
and **[docker compose](https://docs.docker.com/compose/install/)**, or
- **[docker desktop](https://docs.docker.com/desktop/)**
in your computer.

Once **docker** and **docker compose** or **docker desktop** - that includes **docker compose** - are installed,

1. move to the directory of the SDK, conventionally referred as `<vechain-sdk-js>` in this document;
2. to start **solo** open the [CLI](https://en.wikipedia.org/wiki/Command-line_interface) shell and type
```shell
docker compose -f docker-compose.thor.yml up -d --wait
```
3. and to stop **solo**, type in shell
```shell
docker compose -f docker-compose.thor.yml down
```
.

## Start and stop Thor 'solo' with `yarn`

Since you are reading this tutorial, there are excellent chances you read it to develop software with the help of the
SDK, hence you should have already installed both
- [Node.js](https://nodejs.org/en/learn/getting-started/how-to-install-nodejs), and
- [Yarn](https://classic.yarnpkg.com/en/docs/install), hence

you can start **solo** typing in the shell

```shell
yarn start-thor-solo
```

and stop it later typing in the shell

```shell
yarn stop-thor-solo
```
.

Supposing the SDK is installed in the `<vechain-sdk-js>` directory,
the file at `<vechain-sdk-js/package.json` shows in the `scripts` tag the **docker compose** files the
two commands `start-thor-solo` and `stop-thor-solo` invoke.

This is the way to start and stop **solo** suggested to follow the next lessons.

## What an 'account' is

In Thor terminology, an external owned account is a relation between an address - created because a pair of keys
owned by a user - and funds.
An account is created first when a
[transaction is written](https://docs.vechain.org/developer-resources/how-to-build-on-vechain/write-data/transactions)
in the blockchain.

But what happens when a Thor network bootstraps for the first time, when nothing exists yet in the blockchain?
When nothing exists yet, everything is still possible.

## Bootstrapping Thor 'solo'

The first block of the blockchain is called **genesis** block and has address `0`.
When Thor bootstraps and the genesis block doesn't exist in the blockchain nor instructions are received by
peers node to synchronize the blockchain, the node checks if launched with the
`--genesis` option as explained in
[How to run a Thor solo node]()https://docs.vechain.org/how-to-run-a-node/how-to-run-a-thor-solo-node.
This `--genesis` options points to a JSON structured file where the - so called - primordial accounts are defined
associating addresses and their attributes, like
**balance** in [VET](https://docs.vechain.org/introduction-to-vechain/dual-token-economic-model/vechain-vet) and
**energy** in [VTHO](https://docs.vechain.org/introduction-to-vechain/dual-token-economic-model/vethor-vtho).

How to [configure your genesis file](https://docs.vechain.org/how-to-run-a-node/custom-network#configure-your-genesis-file)
describes the structure of the **genesis** file.

Supposing the SDK is installed in the `<vechain-sdk-js>` directory,
the file at `<vechain-sdk-js>/docker-compose.rpc-proxy.yml` shows how **docker compose** bootstraps **solo**
with the `--gensis` option reading how to build the genesis block from the file at
`<vechain-sdk-js>/docker/rpc-proxy/config/genesis.json`.

The file at `<vechain-sdk-js>/docker-compose.thor.yml` is what `yarn start-thor-solo` invokes, the launched
**solo** instance has ten full funded accounts.

**_NOTE:_** it's worth to mention, if not evident, the code building the **genesis** block is part of Thor, not of the SDK.

In the following lessons of this tutorial you will play with these primordial accounts and you will transfer **balance**
and **energy** funds from them to the accounts you will create.

```mermaid
---
title: Thor bootstrap
---
flowchart TD
start((Start))
is_to_synch{{Sync with peer nodes?}}
synchronize[[Synchronize with peers node.]]
has_genesis_block{{Has genesis block?}}
has_genesis_option{{Has --genesis option?}}
read_genesis[[Read the genesis.json file.]]
build_genesis[[Build the genesis block.]]
run(((Run)))
start --> is_to_synch
is_to_synch -->|yes|synchronize
is_to_synch -->|no| has_genesis_block
synchronize --> has_genesis_block
has_genesis_block -->|no|has_genesis_option
has_genesis_block -->|yes|run
has_genesis_option -->|yes|read_genesis
read_genesis --> build_genesis
has_genesis_option -->|no|run
build_genesis --> run
```