diff --git a/README.md b/README.md index 238fb4f0c..7ca2ac9ee 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,25 @@ # Starcoin CookBook -Learn how to build on Starcoin, the document URL: https://starcoinorg.github.io/starcoin-cookbook/ +Learn how to build on Starcoin, the document URL: + +* [https://starcoinorg.github.io/starcoin-cookbook/](https://starcoinorg.github.io/starcoin-cookbook/) +* [https://starcoin-cookbook.4everland.app/](https://starcoin-cookbook.4everland.app/) ### How to contribute -First off, thanks for taking the time to contribute! Contributions are what makes the open-source community such an amazing place to learn, inspire, and create. Any contributions you make will benefit everybody else and are **greatly appreciated**. +First off, thanks for taking the time to contribute! Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make will benefit everybody else and are **greatly appreciated**. Contributions in the following are welcome: 1. Ask a question about "How to develop on Starcoin", "How to use Move", etc. [Ask Question](https://github.com/starcoinorg/starcoin-cookbook/issues/new?assignees=&labels=question&template=02_QUESTION.md&title=%5Bquestion%5D). -2. Report a document bug. [Document Bug Report](https://github.com/starcoinorg/starcoin-cookbook/issues/new?assignees=&labels=bug&template=01_BUG_REPORT.md&title=%5Bbug%5D). -3. Submit a document suggestion. [Document improvement](https://github.com/starcoinorg/starcoin-cookbook/issues/new?assignees=&labels=doc&template=03_DOC_IMPROVEMENT.md&title=%5Bdoc%5D). -4. Contributing to write document. You can learn more about contributing to the Starcoin Cookbook by reading our [Contribution Guide](./docs/100-miscellaneous/99-contributing.md) |[贡献指南](./i18n/zh/docusaurus-plugin-content-docs/current/100-miscellaneous/99-contributing.md) +2. Report a documentation bug. [Document Bug Report](https://github.com/starcoinorg/starcoin-cookbook/issues/new?assignees=&labels=bug&template=01_BUG_REPORT.md&title=%5Bbug%5D). +3. Submit a documentation suggestion. [Document improvement](https://github.com/starcoinorg/starcoin-cookbook/issues/new?assignees=&labels=doc&template=03_DOC_IMPROVEMENT.md&title=%5Bdoc%5D). +4. Contributing to writing documents. You can learn more about contributing to the Starcoin Cookbook by reading our [Contribution Guide](./docs/100-miscellaneous/99-contributing.md) |[贡献指南](./i18n/zh/docusaurus-plugin-content-docs/current/100-miscellaneous/99-contributing.md) You can view our [Code of Conduct](./CODE_OF_CONDUCT.md). -## Support + +### Support Reach out to the maintainer at one of the following places: diff --git a/docs/01-intro.md b/docs/01-intro.md index caa532cdc..9f8cb700e 100644 --- a/docs/01-intro.md +++ b/docs/01-intro.md @@ -1,4 +1,13 @@ - # Starcoin CookBook Intro -TODO introduce starcoin cookbook \ No newline at end of file +The goal of the Starcoin Cookbook is to provide a full-stack learning resource for developers to learn how to develop on Starcoin. + +It contains three main sections. + +1. Knowledge about the Starcoin blockchain. Learn how to run nodes, understand blocks, transactions and state. +2. Knowledge about the Move programming language and the StarcoinFramework. Learn how to write, test, and deploy Move smart contracts. Learn about the features offered by StarcoinFramework. +3. Knowledge about Web3. Learn how DApps interact with smart contracts, how to call the Starcoin chain's RPC API, etc. + +These learning resources are mainly related to Starcoin, but they can also be used as general learning resources for blockchain and smart contracts, because the smart contract blockchains are similar in technical principles. + +This document is still being improved, and welcome to improve it [Contribution Guide](./miscellaneous/contributing). diff --git a/docs/02-getting-started/02-setup/02-starcoin-console.md b/docs/02-getting-started/02-setup/02-starcoin-console.md index ccc7910fb..27a8330dd 100644 --- a/docs/02-getting-started/02-setup/02-starcoin-console.md +++ b/docs/02-getting-started/02-setup/02-starcoin-console.md @@ -81,7 +81,7 @@ Refer to [the second method in the startup console](#method-two). Note: In Windows, the path to the IPC file is different. ```shell -starcoin.exe -c \\.\\pipe\starcoin\dev\starcoin.ipc console +starcoin.exe -c \\.\pipe\starcoin\dev\starcoin.ipc console ``` ### via WebSocket diff --git a/docs/02-getting-started/02-setup/05-fast-sync-data.md b/docs/02-getting-started/02-setup/05-fast-sync-data.md index ad2c35740..60990551c 100644 --- a/docs/02-getting-started/02-setup/05-fast-sync-data.md +++ b/docs/02-getting-started/02-setup/05-fast-sync-data.md @@ -1,5 +1,137 @@ # How to sync the block and state faster -TODO -1. Download block and import local. -2. Download the database snapshot and import local. +Usually, starting a new main network node will automatically synchronize block data, and this process is very long. + +Next, we will introduce how to use the data export tool provided by the Starcoin toolchains to speed up the speed of new nodes synchronizing block data, and how to synchronize the state of the chain. + +## Download and install + +Download the corresponding precompiled [Starcoin toolchains](https://github.com/starcoinorg/starcoin/releases) according to the system you are using. +If you have already [downloaded and installed](https://starcoinorg.github.io/starcoin-cookbook/docs/getting-started/install/) `starcoin`, you can skip this step. + +```shell +# Take Ubuntu as an example +wget https://github.com/starcoinorg/starcoin/releases/download/v1.11.10/starcoin-ubuntu-latest.zip + +# Unzip +unzip starcoin-ubuntu-latest.zip + +# Enter the decompression directory and check +cd starcoin-artifacts/ +./starcoin_db_exporter -h +``` + +Tip: If you use it frequently, it is recommended to add it to the PATH environment variable. + +## Sync block data + +If a new full node is started, it is usually to download the main network block data of other nodes to the new node, and start the node with the downloaded block data. +Downloaded (exported) block data is stored on a CSV file for easy data exchange and storage. + + +### Export block + +The `export-block-range` subcommand is used to export block data. + +```shell +# Create a directory to store the block data exported from the node +mkdir ~/bak + +# export block +./starcoin_db_exporter export-block-range -i ~/.starcoin/main/ -s 1 -e 10000 -n main -o ~/bak +``` + +- `-i` Specifies the data directory for the node. +- `-s` Specifies the starting height of block data. +- `-e` Specifies the end height of the block data. +- `-n` Specifies the network. +- `-o` Specifies the directory to store the exported data. + +After the export, you can see that the export file is `~/bak/block_1_10000.csv` in the `~/bak` directory. + +### Import block + +The `apply-block` subcommand is used to import block data. + +```shell +./starcoin_db_exporter apply-block -i block_1_10000.csv -n main -o ~/.starcoin/main/ +``` + +- `-i` Specifies the path to the CSV file to import block data. +- `-n` Specifies the network. +- `-o` Specifies the data directory for the node. + +### Import block data using script (recommended) + +The `import_block.sh` script is provided in the `starcoin` repository, and the precompiled version is also packaged with the corresponding script. +It is more convenient to import block data using a script instead of having to export and import manually. + +```shell +./import_block.sh main ~/.starcoin/main +``` + +This script accepts two parameters, parameter 1 specifies the network name, such as `main`, `barnard`, `proxima` or `halley`, and parameter 2 specifies the directory where the data is stored, such as `~/.starcoin/main` or any custom path. +This script will skip the existing blocks, and each time a block is acquired, the progress will be automatically updated. +After the script is interrupted and executed, the import will continue at the original height. + +After executing the script, the mainnet block data will be automatically downloaded to the `~/.starcoin/main` directory and imported. +Wait for the download and import to complete, then you can run a new node with these block data. + +Note: To use this script, make sure `starcoin_db_exporter` and `import_block.sh` are in the same path. + +## Status of the sync chain + +The `starcoin_db_exporter` command provides a snapshot function of offline export and import of `main`, `barnard`, `proxima`, `halley` networks, which is convenient to quickly build a blockchain network. + +### Export snapshot + +The `export-snapshot` subcommand is used to export snapshots. + +**Normal export:** + +```shell +# Create a directory for storing snapshot data exported from the node +mkdir ~/snapshot + +# Export snapshot +./starcoin_db_exporter export-snapshot -i ~/.starcoin/main -n main -o ~/snapshot +``` + +- `-i` Specifies the data directory for the node. +- `-n` Specifies the network. +- `-o` Specifies the directory where the exported snapshots are stored. + +**Incremental export:** + +```shell +./starcoin_db_exporter export-snapshot -i ~/.starcoin/main -n main -o ~/snapshot -t true +``` + +Use the `-t` option to specify whether to use incremental export, `true` to enable, `false` to disable. +If you want to use incremental export, you need to ensure that there are old snapshots in the `~/snapshot` directory. +For example, the original snapshot height in the `~/snapshot` directory is `1-400w`, and now you need to export snapshots with a height of `1-500w`. +If incremental export is used, the subsequent `400w-500w` snapshots will be exported first, and then merged with the original snapshots to save time. + +### Import snapshot + +The `apply-snapshot` subcommand is used to import snapshots. + +```shell +./starcoin_db_exporter apply-snapshot -i ~/snapshot -n main -o ~/.starcoin/main +``` + +- `-i` Specifies the directory where snapshots are stored. +- `-n` Specifies the network. +- `-o` Specifies the data directory for the node. + +### Import snapshots using a script + +The `import_snapshot.sh` script is provided in the [`starcoin`](https://github.com/starcoinorg/starcoin/blob/master/scripts/import_snapshot.sh) repository, and the precompiled version is also packaged with the corresponding script. + +```shell +./import_snapshot.sh main ~/snapshot/ ~/.starcoin/main +``` + +This script needs to pass 3 parameters, parameter 1 specifies the name of the network, parameter 2 specifies the storage path of the snapshot, and parameter 3 specifies the data directory of the node. + +Note: To use this script, make sure `starcoin_db_exporter` and `import_snapshot.sh` are in the same path. diff --git a/docs/02-getting-started/02-setup/06-main-network.md b/docs/02-getting-started/02-setup/06-main-network.md index e55625845..6e968a7c7 100644 --- a/docs/02-getting-started/02-setup/06-main-network.md +++ b/docs/02-getting-started/02-setup/06-main-network.md @@ -1,20 +1,223 @@ # How to participate in the main network -TODO -1. Introduce the main network. -2. Run node and join test network. +## Introduction +On May 18, 2021, Starcoin held a global press conference, and under the spotlight, announced the launch of the main network. +This is a milestone moment, which means that the ship Starcoin has officially set sail in the blue ocean of blockchain. +## Windows joins main network +**1. Start** -## Join main network +```shell +starcoin.exe --net main ^ + --disable-metrics true ^ + --node-name starcoin-main ^ + --data-dir D:\starcoin\data ^ + --logger-disable-file true ^ + --stratum-address 0.0.0.0 --stratum-port 9880 +``` + +- `--net`: Specifies the network. +- `--disable-metrics`: Whether to disable the metrics monitoring service, `true` to disable, `false` not to disable. +- `--node-name`: The node name is only used for display. You can choose a unique name according to your own preferences. If not specified, it will be randomly generated. +- `--data-dir`: The data storage directory, it is recommended to choose a path that is easy to find. +- `--logger-disable-file`: Whether to disable the file log collector, `true` to disable, `false` not to disable. +- `--stratum-address`: Specify the address of the mining pool, the default is `0.0.0.0`. +- `--stratum-port`: Specify the port number of the mining pool, the default is `9880`. + +After entering the above command in the cmd window of Windows, press Enter, and the node will start to synchronize the block data, just wait for the synchronization to complete. + +**2. View the IPC file path** + +Drag the sidebar to the top with the mouse, and you can see that the output shows the storage path of the IPC file: + +```shell +2022-05-23T16:40:06.642907500+08:00 INFO - Ipc file path: "\\\\.\\pipe\\starcoin\\main\\starcoin.ipc + +# IPC file path is: +\\\\.\\pipe\\starcoin\\main\\starcoin.ipc +``` + +**3. View node synchronization progress** + +If you want to know the progress of the node synchronization data, you can open a new cmd window at this time and use the IPC file to connect to the Starcoin console: + +```shell +starcoin.exe -c \\.\pipe\starcoin\main\starcoin.ipc console +``` + +In the Starcoin console enter: + +```shell +node sync status +``` + +Some key information can be found in the output JSON data. +The synchronization is completed when `chain_status.head.number` and `state.Synchronizing.target.number` are equal. + +**4. View default account** + +Each newly started node is initialized with a default account with an empty password. + +```shell +# View the default account and find the account address +account default +``` + +**5. Export the private key of the default account** + +```shell +account export
+``` + +Note: Please keep the private key safe! + +**6. Exit the console** ```shell -starcoin -n main +exit ``` -The default network is main, so also just run: +## Linux joins main network (recommendation) + +**1. Start** ```shell starcoin -``` \ No newline at end of file +``` + +The `starcoin` command uses the `main` network by default, the mining client is disabled by default, the mining pool is not listened by default, and the data directory defaults to `.starcoin/main` under the main directory. + +```shell +# Data directory, ubuntu is the username of the demo, please change it according to your actual situation +2022-05-24T10:07:29.069207121+08:00 INFO - Final data-dir is : "/home/ubuntu/.starcoin/main" + +# IPC file path +2022-05-24T10:07:29.061062410+08:00 INFO - Ipc file path: "/home/ubuntu/.starcoin/main/starcoin.ipc" +``` + +**2. View node synchronization progress** + +Open a new command line window and enter: + +```shell +starcoin -c ~/.starcoin/main/starcoin.ipc console +``` + +In the Starcoin console enter: + +```shell +node sync status +``` + +Some key information can be found in the output JSON data. +The synchronization is completed when `chain_status.head.number` and `state.Synchronizing.target.number` are equal. + +**3. View default account** + +Each newly started node is initialized with a default account with an empty password. + +```shell +# View the default account and find the account address +account default +``` + +**4. Export the private key of the default account** + +```shell +account export
+``` + +Note: Please keep the private key safe! + +**5. Exit the console** + +```shell +exit +``` + +## Docker joins main network + +**1. Pull the [Docker image](https://hub.docker.com/r/starcoin/starcoin/)** + +```shell +docker pull starcoin/starcoin:latest +``` + +If you want to use a specific version, you can change the pull tag, such as `v1.11.9`: + +```shell +docker pull starcoin/starcoin:v1.11.9 +``` + +**2. Start** + +The `starcoin` binaries are in the `/starcoin` directory in the mirror. + +```shell +docker run --name starcoin -v ~/.starcoin/:/root/.starcoin/ --network host starcoin/starcoin:latest /starcoin/starcoin +``` + +- `--name`: Specifies the container name. +- `-v`: Bind mounted volume for persisting data in Docker. +- `--network`: Let the network of the Docker container be attached to the host, and the two can communicate with each other. + +**3. Connect to the Starcoin console via Docker** + +Open a new command line window and enter: + +```shell +docker run --rm -it -v ~/.starcoin/:/root/.starcoin/ starcoin/starcoin:latest /starcoin/starcoin -c /root/.starcoin/main/starcoin.ipc console +``` + +- `--rm`: Automatically remove the container when exiting the Starcoin console. +- `-it`: Enter the container interactively, assigning a pseudo terminal. + +If you don't want to start a new container, you can directly access the container that started Starcoin: + +```shell +docker container exec -it starcoin bash + +/starcoin/starcoin -c /root/.starcoin/main/starcoin.ipc console +``` + +**4. View node synchronization progress** + +Open a new command line window and enter: + +```shell +starcoin -c ~/.starcoin/main/starcoin.ipc console +``` + +In the Starcoin console enter: + +```shell +node sync status +``` + +Some key information can be found in the output JSON data. +The synchronization is completed when `chain_status.head.number` and `state.Synchronizing.target.number` are equal. + +**5. View default account** + +Each newly started node is initialized with a default account with an empty password. + +```shell +# View the default account and find the account address +account default +``` + +**6. Export the private key of the default account** + +```shell +account export
+``` + +Note: Please keep the private key safe! + +**7. Exit the console** + +```shell +exit +``` diff --git a/docs/02-getting-started/02-setup/07-private-network.md b/docs/02-getting-started/02-setup/07-private-network.md index a8883eeae..84f2820f0 100644 --- a/docs/02-getting-started/02-setup/07-private-network.md +++ b/docs/02-getting-started/02-setup/07-private-network.md @@ -1,10 +1,78 @@ -# Creating your own private Starcoin network +# How to create a custom Starcoin network +`starcoin` supports running a user-defined blockchain network, which is convenient for users to build a private chain for testing or secondary development. -`starcoin` supports run a user-defined blockchain network, allowing users to build private chain for testing or development. +## Introduction +There are six built-in networks in `starcoin`, namely: `test, dev, halley, proxima, barnard, main`. -TODO -1. Introduce the difference between networks. -2. Introduce the init process of a chain. -3. Introduce the progress run a new network. +`test` and `dev` are for local development, `halley`, `proxima` and `barnard` are the test networks, and the `main` network is the official network. + +Next, we will introduce how to build the Starcoin private network. + +## Initialize custom network + +The `starcoin_generator` command is used to generate genesis configuration files and genesis blocks. + +### Generate genesis configuration file + +```shell +starcoin_generator -n : --genesis-config genesis_config +``` + +- The `genesis_config` subcommand is used to generate the genesis configuration file. +- To initialize and run a custom blockchain network, you need to use the `-n, --net` option to specify the name of the chain and the id of the chain. The parameters are concatenated by `:`. + - `CHAIN_NAME` represents the name of the chain, which will be used as the name of the data directory. + - `CHAIN_ID` represents the id of the chain, of type `u8`. +- `--genesis_config` specifies the configuration file used to generate the genesis block. The parameter can use the built-in blockchain network name, indicating that the network configuration is reused, such as `halley`; it can also be the path of the configuration file. + +For example, to generate a custom network named `my_chain` with id `123`: + +```shell +starcoin_generator -n my_chain:123 --genesis-config halley genesis_config +``` + +This command uses the built-in `halley` network configuration as a template and generates a configuration file named `genesis_config.json` in the `~/.starcoin/my_chain` directory. +Parameters in the `~/.starcoin/my_chain/genesis_config.json` file can be modified with an editor. + +Note: If you don't want the configuration file to be generated in the default `~/.starcoin/` directory, you can also specify the directory with the `-d` option. + +### Generate genesis block + +The `genesis` subcommand is used to generate the genesis block. + +```shell +starcoin_generator -n my_chain:123 genesis +``` + +This command generates the genesis block according to the genesis configuration file generated earlier. + +The genesis configuration file in the above example is `~/.starcoin/my_chain/genesis_config.json`. Of course, you can also place the `genesis_config.json` file in another location and specify it with an absolute path, for example: + +```shell +starcoin_generator -n my_chain:123 --genesis-config /data/conf/my_chain/genesis_config.json genesis +``` + +## Running custom network nodes + +Use the following command to start a custom network node: + +```shell +starcoin -n my_chain:123 console +``` + +## Form a custom network cluster + +After starting a node, you can find the node's address in the log or standard output, which might look like this: + +```shell +2022-05-25T11:27:10.201604911+00:00 INFO - Self address is: /ip4/127.0.0.1/tcp/9840/p2p/12D3KooWR1p3uxnWZ2rv5mZ3Sw2i8z3gabxNEHjgkPDC2pkk19Vp +``` + +Specify the first node as the seed node by `--seed`, and then start other nodes to form a network. + +Note: Multiple nodes must use the same genesis configuration file to generate genesis blocks in order to form a network. + +```shell +starcoin -n my_chain:123 --seed /ip4/127.0.0.1/tcp/9840/p2p/12D3KooWR1p3uxnWZ2rv5mZ3Sw2i8z3gabxNEHjgkPDC2pkk19Vp console +``` diff --git a/docs/02-getting-started/03-accounts/3.multisig-account.md b/docs/02-getting-started/03-accounts/3.multisig-account.md index bd1958e3a..46219d522 100644 --- a/docs/02-getting-started/03-accounts/3.multisig-account.md +++ b/docs/02-getting-started/03-accounts/3.multisig-account.md @@ -111,7 +111,7 @@ starcoin% account import-multisig --pubkey 0xf423c3d02ac400037a40e8dbbf8b3c3e454 The `--pubkey` option specifies that `generate-keypair` generates a public key instead of the personal account's public key, the `--prikey` option specifies the private key generated by `generate-keypair` instead of the personal account's private key, and the `-t` option specifies the number of signatures required, ie `threshold`. -After executing the above commands on the three consoles, you will find that the three commands all generate the same multi-signature account information: +After executing the above commands on the three consoles, you will find that the three commands all generate the same multi-signature account information (Causion: `priv_key` of the three multi-sig account is different, see the next section): ```bash { @@ -127,9 +127,9 @@ After executing the above commands on the three consoles, you will find that the **Understand the public and private keys of multi-signature accounts:** -You can see that the public key of this multi-signature account is very long. -In fact, the private key of a multi-signature account is spliced from multiple single-signature private keys, each of which holds `1/n`, and the public key of a multi-signature account is spliced from the public keys generated by multiple single-signature private keys. -The multisig public key is public, and everyone holds the same multisig public key. +public key: You can see that the public key of this multi-signature account is very long. It is the combination of the public keys generated by multiple single-signature private keys. Everyone holds the same multisig public key. + +private key: The private key of a multi-signature account is the combination of multiple single-signature private keys, each of which holds `1/n`. Run `account export 0x8afd731146fbc206d56265adedb4b50a` in three consoles separately, to check private keys and compare them. View multi-signature accounts: diff --git a/docs/02-getting-started/03-accounts/4.rotate-authentication-key.md b/docs/02-getting-started/03-accounts/4.rotate-authentication-key.md index 2c67172a3..7982f5662 100644 --- a/docs/02-getting-started/03-accounts/4.rotate-authentication-key.md +++ b/docs/02-getting-started/03-accounts/4.rotate-authentication-key.md @@ -1,138 +1,323 @@ ---- -sidebar_position: 4 ---- +# Rotate Authentication Key -# Rotate authentication key +This article guides you on how to complete a private key reset for your account on the Starcoin blockchain. -## Prerequisite +Usage scenarios. -Let's say you've run up a starcoin dev node locally and get a default account. +1. for resetting the account private key and keeping the address +2. to reset an account to a multi-signature account and keep the address (just use the multi-signature account private key) -And `authentication key` id generated from `private key` ,so you need to get the corresponding `authentication key` and `private key` +## Preparation -## Get get the corresponding from accont A +Start a `starcoin` dev node and connect it. See [Using the starcoin console](../setup/starcoin-usage) .) for detailed steps. . -```shell -starcoin% account show 0x1590e52ca72c5acbf4ec931b5938ed77 +## Steps + +There are two ways to reset the account auth key. + +1. replace it step by step using the commands provided by `starcoin` +2. use the `rotate-authentication-key` command to replace it directly + +Option 2 is a more convenient way to package all the commands in Option 1. Option 1 is more clear and controllable. + +### Option 1: Step-by-step execution + +- Prepare new account A +- Execute the auth key replacement contract: use the auth key of account A to replace the auth key of account B +- Delete accounts A, B +- Use A's private key and B's address to dump into the account to complete B's private key replacement + +#### Prepare a new account + +Create a new account A. + +```bash +starcoin% account create -p my-pass +{ + "ok": { + "address": "0xc04c62b99fd053ac31d21d6e06619aed", + "is_default": false, + "is_readonly": false, + "public_key": "0x58ede5ef970b9995268409e289a40ab0dc9e51e5c06a9e4934b5ef74d48795fe", + "receipt_identifier": "stc1pcpxx9wvl6pf6cvwjr4hqvcv6a5fwhx2t" + } +} +``` + +Get account A's auth key: + +```bash +starcoin% account show 0xc04c62b99fd053ac31d21d6e06619aed { "ok": { "account": { - "address": "0x1590e52ca72c5acbf4ec931b5938ed77", + "address": "0xc04c62b99fd053ac31d21d6e06619aed", "is_default": false, "is_readonly": false, - "public_key": "0x933f027809d9280f192542507a67fafc7d0efa73d1db62302a197dc65eccf1fd", - "receipt_identifier": "stc1pzkgw2t9893dvha8vjvd4jw8dwum9tul2" + "public_key": "0x58ede5ef970b9995268409e289a40ab0dc9e51e5c06a9e4934b5ef74d48795fe", + "receipt_identifier": "stc1pcpxx9wvl6pf6cvwjr4hqvcv6a5fwhx2t" }, - "auth_key": "0xda3c8d088d4d339c5708f2ee0255dc931590e52ca72c5acbf4ec931b5938ed77", + "auth_key": "0x39353fabc51eb1b472c2c5ef6e74c91bc04c62b99fd053ac31d21d6e06619aed", "balances": {}, "sequence_number": null } } -starcoin% account export 0x1590e52ca72c5acbf4ec931b5938ed77 -p my-pass +``` + +Get account A's private key: + +```bash +starcoin% account export 0xc04c62b99fd053ac31d21d6e06619aed -p my-pass { "ok": { - "account": "0x1590e52ca72c5acbf4ec931b5938ed77", - "private_key": "0xf657971795bfe49026d224ece814ecc31169f93ca709a7b6fc962aa6b3bd5a83" + "account": "0xc04c62b99fd053ac31d21d6e06619aed", + "private_key": "0x92e13795c658f40ead01db2b3a7ed351b07d85d92bb0f03a9b04364f6de487c9" } } ``` -## Replace account B with the new authentication key +#### Execute rotate authentication key script function -we assume that the new `authentication key` is the `0xda3c8d088d4d339c5708f2ee0255dc931590e52ca72c5acbf4ec931b5938ed77` -and `the private key` is the `0xf657971795bfe49026d224ece814ecc31169f93ca709a7b6fc962aa6b3bd5a83` -and the address for account B is the `0xb91e6eb2a4a5b92fd08a016ad72fc8c5` +Get account B's info: -```shell -starcoin% account show 0xb91e6eb2a4a5b92fd08a016ad72fc8c5 +```bash +starcoin% account show 0xdaf8e186dc97ee9ba6971b08115d4dc2 { "ok": { "account": { - "address": "0xb91e6eb2a4a5b92fd08a016ad72fc8c5", + "address": "0xdaf8e186dc97ee9ba6971b08115d4dc2", "is_default": false, "is_readonly": false, - "public_key": "0xc507993eb4e2b88b4b377009ceeda99565193ca454cde2d790b75d62af43b32f", - "receipt_identifier": "stc1phy0xav4y5kujl5y2q94dwt7gc527m4lk" + "public_key": "0x2a20e0bd8a26e6ed50a4dbba839ed1dbd99806d38c9c606646c9db6836ea0040", + "receipt_identifier": "stc1pmtuwrpkujlhfhf5hrvypzh2dcgyadtcw" }, - "auth_key": "0xd568f4733aac09e88b21e1b1758acdfab91e6eb2a4a5b92fd08a016ad72fc8c5", - "balances": {}, - "sequence_number": null + "auth_key": "0x38992286a9a2256ae4a659d5c46bb877daf8e186dc97ee9ba6971b08115d4dc2", + "balances": { + "0x00000000000000000000000000000001::STC::STC": 101000000 + }, + "sequence_number": 0 } } ``` -Then,unlock the account B and send a transaction to rotate the authentication key +execute `rotate_authentication_key`: -```shell -starcoin% account unlock -p my-pass 0xb91e6eb2a4a5b92fd08a016ad72fc8c5 +```bash +starcoin% account execute-function -s 0xdaf8e186dc97ee9ba6971b08115d4dc2 --function 0x1::Account::rotate_authentication_key --arg x"39353fabc51eb1b472c2c5ef6e74c91bc04c62b99fd053ac31d21d6e06619aed" -b +``` + +After execution: + +```bash +starcoin% account show 0xdaf8e186dc97ee9ba6971b08115d4dc2 { "ok": { - "address": "0xb91e6eb2a4a5b92fd08a016ad72fc8c5", - "is_default": false, - "is_readonly": false, - "public_key": "0xc507993eb4e2b88b4b377009ceeda99565193ca454cde2d790b75d62af43b32f", - "receipt_identifier": "stc1phy0xav4y5kujl5y2q94dwt7gc527m4lk" + "account": { + "address": "0xdaf8e186dc97ee9ba6971b08115d4dc2", + "is_default": false, + "is_readonly": false, + "public_key": "0x2a20e0bd8a26e6ed50a4dbba839ed1dbd99806d38c9c606646c9db6836ea0040", + "receipt_identifier": "stc1pmtuwrpkujlhfhf5hrvypzh2dcgyadtcw" + }, + "auth_key": "0x38992286a9a2256ae4a659d5c46bb877daf8e186dc97ee9ba6971b08115d4dc2", + "balances": { + "0x00000000000000000000000000000001::STC::STC": 100941419 + }, + "sequence_number": 1 } } -starcoin% account execute-function -s 0xb91e6eb2a4a5b92fd08a016ad72fc8c5 --function 0x1::Account::rotate_authentication_key --arg x"da3c8d088d4d339c5708f2ee0255dc931590e52ca72c5acbf4ec931b5938ed77" -b ``` -now,we change the authentication key and private key of the account B -if you send a transaction now +Remove account A and B: -```shell -starcoin% account transfer -s 0xb91e6eb2a4a5b92fd08a016ad72fc8c5 -r 0x1590e52ca72c5acbf4ec931b5938ed77 -v 10000 -b +```bash +starcoin% account remove 0xc04c62b99fd053ac31d21d6e06619aed -p my-pass +{ + "ok": { + "address": "0xc04c62b99fd053ac31d21d6e06619aed", + "is_default": false, + "is_readonly": false, + "public_key": "0x58ede5ef970b9995268409e289a40ab0dc9e51e5c06a9e4934b5ef74d48795fe", + "receipt_identifier": "stc1pcpxx9wvl6pf6cvwjr4hqvcv6a5fwhx2t" + } +} +starcoin% account remove 0xdaf8e186dc97ee9ba6971b08115d4dc2 -p my-pass +{ + "ok": { + "address": "0xdaf8e186dc97ee9ba6971b08115d4dc2", + "is_default": false, + "is_readonly": false, + "public_key": "0x2a20e0bd8a26e6ed50a4dbba839ed1dbd99806d38c9c606646c9db6836ea0040", + "receipt_identifier": "stc1pmtuwrpkujlhfhf5hrvypzh2dcgyadtcw" + } +} ``` -you will get the result `INVALID_AUTH_KEY` -so you need to reimport the account B +Import account by account A's private key & account B's address: -```shell -starcoin% account remove 0xb91e6eb2a4a5b92fd08a016ad72fc8c5 -p my-pass +```bash +starcoin% account import -i 0x92e13795c658f40ead01db2b3a7ed351b07d85d92bb0f03a9b04364f6de487c9 0xdaf8e186dc97ee9ba6971b08115d4dc2 { "ok": { - "address": "0xb91e6eb2a4a5b92fd08a016ad72fc8c5", + "address": "0xdaf8e186dc97ee9ba6971b08115d4dc2", "is_default": false, "is_readonly": false, - "public_key": "0xc507993eb4e2b88b4b377009ceeda99565193ca454cde2d790b75d62af43b32f", - "receipt_identifier": "stc1phy0xav4y5kujl5y2q94dwt7gc527m4lk" + "public_key": "0x58ede5ef970b9995268409e289a40ab0dc9e51e5c06a9e4934b5ef74d48795fe", + "receipt_identifier": "stc1pmtuwrpkujlhfhf5hrvypzh2dcgyadtcw" } } -starcoin% account import -i 0xf657971795bfe49026d224ece814ecc31169f93ca709a7b6fc962aa6b3bd5a83 -p my-pass 0xb91e6eb2a4a5b92fd08a016ad72fc8c5 ``` -now I can show the accout B infomation and and use the new `authentication key` to send transaction +In account B's latest info, we'll find auth key has been rotated: -```shell -starcoin% account show 0xb91e6eb2a4a5b92fd08a016ad72fc8c5 +```bash +starcoin% account show 0xdaf8e186dc97ee9ba6971b08115d4dc2 { "ok": { "account": { - "address": "0xb91e6eb2a4a5b92fd08a016ad72fc8c5", + "address": "0xdaf8e186dc97ee9ba6971b08115d4dc2", "is_default": false, "is_readonly": false, - "public_key": "0x933f027809d9280f192542507a67fafc7d0efa73d1db62302a197dc65eccf1fd", - "receipt_identifier": "stc1phy0xav4y5kujl5y2q94dwt7gc527m4lk" + "public_key": "0x58ede5ef970b9995268409e289a40ab0dc9e51e5c06a9e4934b5ef74d48795fe", + "receipt_identifier": "stc1pmtuwrpkujlhfhf5hrvypzh2dcgyadtcw" }, - "auth_key": "0xda3c8d088d4d339c5708f2ee0255dc931590e52ca72c5acbf4ec931b5938ed77", + "auth_key": "0x39353fabc51eb1b472c2c5ef6e74c91bc04c62b99fd053ac31d21d6e06619aed", "balances": { - "0x00000000000000000000000000000001::STC::STC": 99999941419 + "0x00000000000000000000000000000001::STC::STC": 100941419 }, "sequence_number": 1 } } -starcoin% account unlock -p my-pass 0xb91e6eb2a4a5b92fd08a016ad72fc8c5 +``` + +To check the account, we initiate a transfer from account B: + +```bash +starcoin% account transfer -s 0xdaf8e186dc97ee9ba6971b08115d4dc2 -r 0xacff0c9a785004cdadec02ab76d44f32 -v 10000 -b +``` + +The latest account info of A & B: + +```bash +starcoin% account show 0xdaf8e186dc97ee9ba6971b08115d4dc2 +{ + "ok": { + "account": { + "address": "0xdaf8e186dc97ee9ba6971b08115d4dc2", + "is_default": false, + "is_readonly": false, + "public_key": "0x58ede5ef970b9995268409e289a40ab0dc9e51e5c06a9e4934b5ef74d48795fe", + "receipt_identifier": "stc1pmtuwrpkujlhfhf5hrvypzh2dcgyadtcw" + }, + "auth_key": "0x39353fabc51eb1b472c2c5ef6e74c91bc04c62b99fd053ac31d21d6e06619aed", + "balances": { + "0x00000000000000000000000000000001::STC::STC": 100646888 + }, + "sequence_number": 2 + } +} +starcoin% account show 0xacff0c9a785004cdadec02ab76d44f32 +{ + "ok": { + "account": { + "address": "0xacff0c9a785004cdadec02ab76d44f32", + "is_default": false, + "is_readonly": false, + "public_key": "0xfedc9c99956e25a66a5780922ada3fc8f70cff4f7f4ee87436fab64e727cd09b", + "receipt_identifier": "stc1p4nlsexnc2qzvmt0vq24hd4z0xg0dqv6e" + }, + "auth_key": "0x6c871cf1618930b492fcd4fc56d9b5d7acff0c9a785004cdadec02ab76d44f32", + "balances": { + "0x00000000000000000000000000000001::STC::STC": 10000 + }, + "sequence_number": 0 + } +} +``` + +### Option 2:rotate-authentication-key cmd + +Account waiting for rotation: + +```bash +starcoin% account show 0x19b757b48a015ee035c03d01254d977d +{ + "ok": { + "account": { + "address": "0x19b757b48a015ee035c03d01254d977d", + "is_default": false, + "is_readonly": false, + "public_key": "0xf3ebe5f3b54f670d128b23ac48451ce4901b61c91a2fa3dffd42d36b8686f6b2", + "receipt_identifier": "stc1prxm40dy2q90wqdwq85qj2nvh05t82esr" + }, + "auth_key": "0x45dfd6aee42561ebef18f7efadea276319b757b48a015ee035c03d01254d977d", + "balances": { + "0x00000000000000000000000000000001::STC::STC": 100000000 + }, + "sequence_number": 0 + } +} +``` + +Generating new keypair: + +```bash +starcoin% account generate-keypair +{ + "ok": [ + { + "address": "0x1876d22b496bf344ab22b4f2fad63226", + "auth_key": "0x6e90f703921b70d637e0c6ab4bf329da1876d22b496bf344ab22b4f2fad63226", + "private_key": "0xe44035658755709e7567d1ee34c8563400fae6362efe4d8ea4dc1a6fa13f8a79", + "public_key": "0xff23b3c540ac5040846ccd2664fec13d9470ebfb4cb42afd5f25be2c5e0c00d5", + "receipt_identifier": "stc1prpmdy26fd0e5f2ezkne0443jychq0vzt" + } + ] +} +``` + +Executing `rotate-authentication-key` cmd, please also change default account to any other address before execute. + +```bash +starcoin% account rotate-authentication-key 0x19b757b48a015ee035c03d01254d977d -i 0xe44035658755709e7567d1ee34c8563400fae6362efe4d8ea4dc1a6fa13f8a79 --password my-pass +txn 0x1d97effb8f8e2b598bd67e70047c2b9862e6d0cb823e77f8173dcaa546733be8 submitted. { "ok": { - "address": "0xb91e6eb2a4a5b92fd08a016ad72fc8c5", + "address": "0x19b757b48a015ee035c03d01254d977d", "is_default": false, "is_readonly": false, - "public_key": "0x933f027809d9280f192542507a67fafc7d0efa73d1db62302a197dc65eccf1fd", - "receipt_identifier": "stc1phy0xav4y5kujl5y2q94dwt7gc527m4lk" + "public_key": "0xff23b3c540ac5040846ccd2664fec13d9470ebfb4cb42afd5f25be2c5e0c00d5", + "receipt_identifier": "stc1prxm40dy2q90wqdwq85qj2nvh05t82esr" + } +} + +starcoin% account show 0x19b757b48a015ee035c03d01254d977d +{ + "ok": { + "account": { + "address": "0x19b757b48a015ee035c03d01254d977d", + "is_default": false, + "is_readonly": false, + "public_key": "0xff23b3c540ac5040846ccd2664fec13d9470ebfb4cb42afd5f25be2c5e0c00d5", + "receipt_identifier": "stc1prxm40dy2q90wqdwq85qj2nvh05t82esr" + }, + "auth_key": "0x6e90f703921b70d637e0c6ab4bf329da1876d22b496bf344ab22b4f2fad63226", + "balances": { + "0x00000000000000000000000000000001::STC::STC": 99941419 + }, + "sequence_number": 1 } } -starcoin% account transfer -s 0xb91e6eb2a4a5b92fd08a016ad72fc8c5 -r 0x1590e52ca72c5acbf4ec931b5938ed77 -v 10000 -b ``` -Finally,we change the authenticaton key of accout B wihtout account address change -# change an account to a multi-sign account by rotate the authentication key. \ No newline at end of file +#### Caution + +Considering that the local state consistency with the on-chain state may be interrupted by unexpected failures, thus not getting the return value of the command, we need the means to recover. There are three cases of no return value as follows. + +1. auth key has not been replaced: re-execute the command +2. `INVALID_AUTH_KEY` error: Remove the account and re-import it with a new key manually. This is caused by an abnormal exit when removing the account. +3. `account not existed` error: Re-import with a new key manually. This is caused by an abnormal exit when importing the account. + +### Change an account to a multi-sign account by rotating the authentication key + +TODO After [refactor multi-sign](https://github.com/starcoinorg/starcoin/issues/3411) done. diff --git a/docs/02-getting-started/03-accounts/5.use-starmask.md b/docs/02-getting-started/03-accounts/5.use-starmask.md index ea363eb9a..a0cd0742d 100644 --- a/docs/02-getting-started/03-accounts/5.use-starmask.md +++ b/docs/02-getting-started/03-accounts/5.use-starmask.md @@ -1,5 +1,104 @@ ---- -sidebar_position: 5 ---- +# StarMask Introduction -# Use StarMask or Other wallets \ No newline at end of file +StarMask is a wallet extension that runs in a web browser (Chrome, Firefox or Edge). +It is a wallet for interacting with the Starcoin blockchain. It is easy to use and test, and can connect to multiple Starcoin nodes. +StarMask can be used to store and manage Starcoin's on-chain assets, and users can participate in Starcoin's on-chain governance directly through StarMask, including voting, IDO, SWAP, and more. + +## Download and Installation + +### Online Installation + +You can install StarMask from Chrome App Store, currently only Chrome is supported, if you are using other browsers, please refer to [Offline Installation](#offline-installation). + +1. Installation + + Search for `StarMask` in the [Chrome App Store](https://chrome.google.com/webstore/search/StarMask), and click `Add to Chrome` to finish the installation. + +2. How to update your wallet manually + + Type `chrome://extensions/` in the Chrome address bar, and turn on the `Developer mode` in the upper right corner of the page. + The `Update` button will appear at the top left of the page, click the button to update. + +3. Detailed Installation Guide + + For more detailed installation guide, please follow this [Installation Guide - Chrome](https://github.com/starcoinorg/starmask-extension/blob/main/docs/en/how-to-install.md). + +### Offline Installation + +This section describes how to get StarMask wallet in major browsers (Chrome, Firefox and Edge) via offline installation. + +#### Download + +Visit StarMask's [GitHub repository](https://github.com/starcoinorg/starmask-extension) and download the [latest release](https://github.com/starcoinorg/starmask-extension/releases/latest) for the corresponding browser. + +:::note + +The current releases are Chrome version and Firefox version, for Microsoft Edge, you can use Chrome version for now. + +::: + +#### Installation - Chrome + +Open Chrome, type `chrome://extensions/` in the address bar, and turn on `Developer mode` in the upper right corner of the page. +Drag and drop the downloaded zip file into Chrome to complete the installation. + +After installation, click the `Extensions` icon in the top right corner of Chrome and click `Pin` icon to add StarMask to the `Toolbar` for easy access. + +#### Installation - Firefox + +Open Firefox browser, click the `Menu` button in the upper right corner, select `Add-ons and themes`, click the little gear at the top of the current page (`Tools for all add-ons`), select `Debug Add-ons`, click `Load Temporary Add-on...`, select the StarMask zip file you just downloaded, then you finish the installation. + +You can also type `about:debugging#/runtime/this-firefox` in the Firefox browser address bar, click `Load Temporary Add-on...`, select the StarMask package to finish the installation. + +For more detailed installation guide, please refer to [Installation Guide - Firefox Browser](https://github.com/starcoinorg/starmask-extension/blob/main/docs/en/how-to-install-firefox.md). + +#### Installation - Edge + +Open Edge browser, type `edge://extensions/` in the address bar, turn on the `Developer mode` on the left side, drag and drop the downloaded StarMask zip file into Edge, and you will have the StarMask installed in Edge. + +## Create Wallet + +After StarMask is installed, the welcome page will open automatically. If the welcome page is not shown, you can also open it by clicking on the StatMask icon on the toolbar. +You will need to read and accept the User Agreement and then enter **Password** to create a new Starcoin wallet. + +Click on `Get Started`, click on `Create a Wallet`, click on `I Agree` and enter your password. + +:::tip + +This password is used to control the access of StarMask, for example, when others use your computer, they need to know the password in order to access to StarMask. + +::: + +After setting the password, StarMask will generate a wallet for you and lead you to secret backup phrase page, click `Lock` icon to display a mnemonic of 12 words. +These secret backup phrases can be used on all compatible wallets for recovery. +If you forget your wallet password or have problems with your computer, simply use these 12 words to reset your wallet password or recover your wallet from another device. + +:::caution + +It is recommended to backup these 12 mnemonics on multiple pieces of paper and keep them in 2 to 3 separate places. +e.g., a safe, locked drawer, or other place where you can keep these papers secure. +The value of the paper is equal to the value of the digital assets you hold on the Starcoin blockchain. +If someone else has access to these 12 mnemonics, they can steal your digital assets, so be sure to keep them safe! +In general, it is not recommended to upload screenshots or text files of the secret backup phrase to a network drive or other online device. +If you want to save them on an offline encrypted device, you can click `Download this Secret Backup` on the right side of the page, then move the file to an encrypted storage and make sure there is no backup on your current computer! + +::: + +After you are sure that you have saved the secret backup phrase (mnemonics) correctly, click `Next`, click words according to the order you just saved, and click `Confirm`. +Once you've verified, you've completed the wallet creation process and enjoy your journey on the Starcoin blockchain! + +## Using the Wallet + +Once you have created your wallet, you will be taken to your account page, where StarMask will display an overview of your Starcoin account. + +The Starcoin icon is displayed on the top row of the account page, which shows the Starcoin network to which your wallet is currently connected (by default, the "Starcoin Main" is displayed) and a colorful icon (to distinguish between multiple accounts). + +Clicking on the StarMask icon in the browser toolbar at this point brings up a page that is basically the same as the StarMask extension page. +The only difference is that the StarMask wallet popup page will have a Web3 connection status icon on the left side of the second row. +If your wallet is connected to a Web3 page, it will display `Connected` and you can click on it to see the details. + +In the middle of the second row is the account name (default is `Account1`) and the Starcoin address of the account (e.g. `0xeD49...683e`). +`Account Options` is shown on the right side of second row. + +The middle of the third row shows the number of STC tokens currently held by the account, and a `Send` button for sending tokens. +At the bottom, there are three tabs for `Assets`, `NFTs` and `Activity`. diff --git a/docs/02-getting-started/04-mining/01-mining.md b/docs/02-getting-started/04-mining/01-mining.md index 53b1e7d07..10ea09ac1 100644 --- a/docs/02-getting-started/04-mining/01-mining.md +++ b/docs/02-getting-started/04-mining/01-mining.md @@ -1,3 +1,93 @@ +# mining client + ## starcoin miner -TODO: Translate from Chinese. +`starcoin_miner` is the mining client provided by Starcoin. +The `starcoin_miner` command line tool is used to remotely connect to the Starcoin node, and provides the ability to mine with CPU and connect to the stc-mini mining machine. + +### Usage + +```shell +`starcoin_miner` [OPTIONS] + +USAGE: + starcoin_miner [OPTIONS] --user + +FLAGS: + -h, --help Prints help information + -V, --version Prints version information + +OPTIONS: + -p, --plugin-path + -a, --server [default: 127.0.0.1:9870] + -n, --thread-num [default: 1] + -u, --user +``` + +### Connect to a node to mine with CPU + +When starting the Starcoin node locally, we can run the following command to specify the mining user alice to start 4 threads to connect to the local node for mining. + +```shell +starcoin_miner --user alice -n 4 +``` + +After startup, you can see the following information in the console: + +```shell +Miner client Total seals found: 3 +starcoin-miner-cpu-worker-0 ⠦ [00:00:00] Hash rate: 20 Seals found: 17 +starcoin-miner-cpu-worker-1 ⠦ [00:00:00] Hash rate: 21 Seals found: 17 +starcoin-miner-cpu-worker-2 ⠤ [00:00:00] Hash rate: 20 Seals found: 16 +starcoin-miner-cpu-worker-3 ⠤ [00:00:00] Hash rate: 20 Seals found: 16 +2020-10-28T09:09:53.006852+08:00 INFO - Seal found 16718533681172480617 +``` + +In the log, you can see the total number of seals dug up, the computing power of each thread, and the newly calculated seals and other information. + +## stc-box + +stc-box is the current mainstream miner of Starcoin. +No need to install additional client or software, it can be set through the miner webpage. +For the configuration method, please refer to the [configuration of the mining pool](https://www.yuque.com/bixinkelekuangchi/stoxms/knlyf3). + +## stc-mini + +### Windows environment usage steps + +1. Install driver +2. Install the software: [Starcoin mining client](https://github.com/starcoinorg/starcoin_mini_miner/releases/) +3. Connect the miner to the computer. +4. Update firmware: After the software recognizes the miner, click to update the firmware. [Download the Starcoin mini miner firmware](https://github.com/starcoinorg/starcoin_mini_miner/releases/download/v0.0.2/starcoin_mini_miner_recovery_v0.0.2.bin) and upload it. +5. Set up the mining pool: Open the Starcoin Miner software, click the set up mining pool icon, enter the mining pool name, port number, user name, miner password, and click OK. +6. Start mining: Click to start the mining machine, and after a while, you can see that the computing power is generated to prove that the device has started to work. +7. Switch mining pool: Select the machine to stop mining, set the mining pool, and start mining. + +### Notes + +- Before use, please try to avoid placing the miner in an environment with poor air circulation and high temperature, otherwise it may cause abnormal work or even damage to the equipment. +- Please ensure that the network is unobstructed before use, otherwise the rejection rate will increase and affect the computing power of the machine. +- Do not overclock without permission when using it, otherwise the chip will be damaged and the consequences will be at your own risk. +- The client software only supports windows system temporarily, please refer to [starcoin mint usb solver](https://github.com/fikgol/usbsolver) for non-windows system users to use this miner. + +# Mining pool related + +For the mining pool protocol of starcoin, please refer to the [starcoin stratum protocol](https://github.com/starcoinorg/starcoin/blob/master/stratum/stratum_mining_protocol.md). + +## Join the mining pool + +- Set [Cola Pool (recommended)](https://www.yuque.com/docs/share/5c5ae94a-3ed4-4dab-98ca-62baf17891e0) +- Connect to [Poolin Pool (recommended)](https://help.poolin.com/hc/zh-cn/articles/360060982092) +- Connect to [ViaBTC mining pool](https://support.viabtc.com/hc/zh-cn/articles/900005939326) +- Connect [Elephant Pool](https://www.dxpool.com/help/zh/starcoin-mining-toturial) +- Connect to [fishpond](https://blog.f2pool.com/zh/mining-tutorial/stc) + +## Self-built mining pool + +A stratum server is implemented inside the Starcoin node, through which users can build their own mining pool for mining. +When starting the Starcoin node, the stratum server will monitor the local address 0.0.0.0:9880 by default, and mine by connecting to a mining client that supports starcoin stratum. +When starting a Starcoin node, you can set the address and port of the stratum server through the parameters `--stratum-address` and `--stratum-port`. like: + +```shell +./starcoin -n main --stratum-port 9880 --stratum-address 127.0.0.1 +``` diff --git a/docs/02-getting-started/04-mining/README.md b/docs/02-getting-started/04-mining/README.md index 50b128a99..38bcade29 100644 --- a/docs/02-getting-started/04-mining/README.md +++ b/docs/02-getting-started/04-mining/README.md @@ -1,3 +1,3 @@ -# 挖矿并了解挖矿协议 +# Mining and understanding the mining protocol -这个章节你可以了解如何使用 starcoin 的命令行工具,矿机,矿池进行挖矿。以及挖矿的相关协议。 +In this chapter, you can learn how to use Starcoin's command-line tools, mining machines, mining pools for mining, and mining related protocols. diff --git a/docs/02-getting-started/04-mining/_category_.yaml b/docs/02-getting-started/04-mining/_category_.yaml new file mode 100644 index 000000000..374989697 --- /dev/null +++ b/docs/02-getting-started/04-mining/_category_.yaml @@ -0,0 +1 @@ +label: "Mining" diff --git a/docs/03-move/01-prepare-move-env.md b/docs/03-move/01-prepare-move-env.md index 7ddfff3c7..170c46334 100644 --- a/docs/03-move/01-prepare-move-env.md +++ b/docs/03-move/01-prepare-move-env.md @@ -1,31 +1,40 @@ # Setting up Move develop environment -## Installation +## Install mpm +Move Package Manager(mpm) is a command line tool to develop move projects, like Cargo for Rust, or NPM for NodeJS. -1. Run [`dev_setup.sh`](https://github.com/starcoinorg/starcoin-framework/blob/main/scripts/dev_setup.sh)(automated installation script) of starcoin-framework, which contains the move prover environment setup +### Install using the convenience script +1. Run [`scripts/dev_setup.sh`](https://github.com/starcoinorg/starcoin-framework/blob/main/scripts/dev_setup.sh)(automated installation script) of starcoin-framework, which contains mpm, Rust, PATH config and the move prover environment setup. ``` curl -s https://raw.githubusercontent.com/starcoinorg/starcoin-framework/main/scripts/dev_setup.sh | bash /dev/stdin -b -t ``` -2. Download from the release page of [starcoiorg/starcoin](https://github.com/starcoinorg/starcoin). +The command above will install mpm and Rust to default location. It also set the PATH env. Check more arguments in shell script. -3. +### Install from binary +Download `mpm-[your_os]-latest.zip` from the release page of [starcoiorg/starcoin](https://github.com/starcoinorg/starcoin), unarchive it and add it to PATH env. + +### Install from source + +From local source code ``` $ git clone https://github.com/starcoinorg/starcoin.git -$ cargo install --path starcoin/vm/move-package-manager +$ cd starcoin +$ cargo install --path vm/move-package-manager ``` -4. +Or from remote git repo ``` $ cargo install --git https://github.com/starcoinorg/starcoin move-package-manager --bin mpm ``` -This will install the `mpm` binary in your Cargo binary directory. On macOS and Linux this is usually *~/.cargo/bin*. You'll want to make sure this location is in your `PATH` environment variable. +This will install the `mpm` binary in your Cargo binary directory. On macOS and Linux this is usually *~/.cargo/bin/*. You'll want to make sure this location is in your `PATH` environment variable. +### Summary Now you should be able to run the `mpm`: ``` $ mpm -move-package-manager 1.11.7-rc +move-package-manager 1.11.11 Starcoin Core Dev CLI frontend for the Move compiler and VM @@ -34,8 +43,12 @@ USAGE: ... ``` +## Install IDE plugin -# Set up env for move prover. +### VS Code +Search `starcoin-ide` in Extensions. + +## Set up env for move prover 1. Run [`dev_setup.sh`](https://github.com/starcoinorg/starcoin-framework/blob/main/scripts/dev_setup.sh)(automated installation script) of starcoin-framework ``` @@ -45,4 +58,3 @@ USAGE: When the above command is executed, type `boogie /version` and if the output is similar to "Boogie program verifier version X.X.X", then the installation has been successful. Note that currently Move Prover can only run under UNIX-based operating systems (e.g. Linux, macOS). Windows users can run it by installing WSL. - diff --git a/docs/03-move/11-quick-start.md b/docs/03-move/11-quick-start.md new file mode 100644 index 000000000..2c7f5d795 --- /dev/null +++ b/docs/03-move/11-quick-start.md @@ -0,0 +1,7 @@ +# Quick Start + +draft,To be done + +In this first tutorial, we'll implement a simple coin and show off some of the ways that Move helps write correct code when creating, manipulating, and destroying coins. + +Let's get started! diff --git a/docs/04-web3/01-starmask/01-onboarding-library.md b/docs/04-web3/01-starmask/01-onboarding-library.md new file mode 100644 index 000000000..183a38860 --- /dev/null +++ b/docs/04-web3/01-starmask/01-onboarding-library.md @@ -0,0 +1,186 @@ +# Onboarding Library + +As an Starcoin enabled site developer, sending users offsite to install StarMask presents challenges. Most notably, you must inform the user to return to your site and refresh their browser after the installation. Your site will detect the user's newly installed StarMask extension only after that refresh. We at StarMask care deeply about user experience, and we knew that this workflow needed to be improved. + +StarMask now provides a [starmask-onboarding library](https://github.com/starcoinorg/starmask-onboarding) designed to improve and simplify the onboarding experience. The new library exposes an API to initiate the onboarding process. In the process, it registers your site as the origin of the onboarding request. StarMask will check for this origin after the user completes the onboarding flow. If it finds an origin, the final confirmation button of the StarMask onboarding flow will indicate that the user will be redirected back to your site. + +## Getting Started + +1. Install `@starcoin/starmask-onboarding` using npm or yarn. + +2. Import the Onboarding Library or include it in your page. + +```javascript +// As an ES6 module +import StarMaskOnboarding from "@starcoin/starmask-onboarding"; +// Or as an ES5 module +const StarMaskOnboarding = require("@starcoin/starmask-onboarding"); +``` + +If you'd prefer you can instead include the prebuilt ES5 bundle that ships with the library: + +```html + +``` + +3. Create a new instance of the Onboarding library + +```javascript +const onboarding = new StarMaskOnboarding(); +``` + +4. Start the onboarding process in response to a user event (e.g. a button click). + +```javascript +onboarding.startOnboarding(); +``` + +## Examples + +### Basic Usage + +```javascript +const onboarding = new StarMaskOnboarding(); +onboarding.startOnboarding(); +``` + +### Using React + +```jsx +import StarMaskOnboarding from "@starcoin/starmask-onboarding"; +import React from "react"; + +const ONBOARD_TEXT = "Click here to install StarMask!"; +const CONNECT_TEXT = "Connect"; +const CONNECTED_TEXT = "Connected"; + +export function OnboardingButton() { + const [buttonText, setButtonText] = React.useState(ONBOARD_TEXT); + const [isDisabled, setDisabled] = React.useState(false); + const [accounts, setAccounts] = React.useState([]); + const onboarding = React.useRef(); + + React.useEffect(() => { + if (!onboarding.current) { + onboarding.current = new StarMaskOnboarding(); + } + }, []); + + React.useEffect(() => { + if (StarMaskOnboarding.isStarMaskInstalled()) { + if (accounts.length > 0) { + setButtonText(CONNECTED_TEXT); + setDisabled(true); + onboarding.current?.stopOnboarding(); + } else { + setButtonText(CONNECT_TEXT); + setDisabled(false); + } + } + }, [accounts]); + + React.useEffect(() => { + function handleNewAccounts(newAccounts) { + setAccounts(newAccounts); + } + if (StarMaskOnboarding.isStarMaskInstalled()) { + window.starcoin + .request({ method: "stc_requestAccounts" }) + .then(handleNewAccounts); + window.starcoin.on("accountsChanged", handleNewAccounts); + return () => { + window.starcoin.removeListener("accountsChanged", handleNewAccounts); + }; + } + }, []); + + const onClick = () => { + if (StarMaskOnboarding.isStarMaskInstalled()) { + window.starcoin + .request({ method: "stc_requestAccounts" }) + .then((newAccounts) => setAccounts(newAccounts)); + } else { + onboarding.current?.startOnboarding(); + } + }; + return ( + + ); +} +``` + +### Using TypeScript + +We ship our TypeScript types with `@starcoin/starmask-onboarding`. +Modifying the above example to get type safety when using the `onboarding` library is simple: + +```jsx + -const onboarding = React.useRef(); + +const onboarding = React.useRef(); +``` + +Doing this step will give you editor auto-completion for the methods exposed by the library, and helpful documentation. + +![Editor Highlighting](../../../static/img/onboarding-library-1.png) + +### Using Vanilla Javascript + HTML + +```html + + + + StarMask Onboarding Example + + + +

Sample Dapp

+ + + + + +``` + +## Onboarding Diagram + +Here is a diagram of the interactions between the onboarding library, the forwarder, and the extension: + +![Onboarding Library Diagram](../../../static/img/onboarding-diagram.png) diff --git a/docs/04-web3/01-starmask/02-starcoin-provider.md b/docs/04-web3/01-starmask/02-starcoin-provider.md new file mode 100644 index 000000000..bb87fafb8 --- /dev/null +++ b/docs/04-web3/01-starmask/02-starcoin-provider.md @@ -0,0 +1,299 @@ +# Starcoin Provider API + +:::tip Recommended Reading +We recommend that all web3 site developers read the [Basic Usage](#basic-usage) section. +::: + +StarMask injects a global API into websites visited by its users at `window.starcoin`. +This API allows websites to request users' Starcoin accounts, read data from blockchains the user is connected to, and suggest that the user sign messages and transactions. +The presence of the provider object indicates an Starcoin user. + +We recommend using [`@starcoin/starmask-onboarding`](https://npmjs.com/package/@starcoin/starmask-onboarding) to detect our provider injected at `window.starcoin`, on any platform or browser. + +```javascript +// This function detects most providers injected at window.starcoin +import StarMaskOnboarding from "@starcoin/starmask-onboarding"; + +const { isStarMaskInstalled } = StarMaskOnboarding; + +if (!isStarMaskInstalled()) { + console.log("Please install StarMask!"); +} +``` + +The Starcoin JavaScript provider API is specified by [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193). + +## Basic Usage + +For any non-trivial Starcoin web application — a.k.a. dapp, web3 site etc. — to work, you will have to: + +- Detect the Starcoin provider (`window.starcoin`) +- Detect which Starcoin network the user is connected to +- Get the user's Starcoin account(s) + +The snippet at the top of this page is sufficient for detecting the provider. +You can learn how to accomplish the other two by reviewing the snippet in the [Using the Provider section](#using-the-provider). + +The provider API is all you need to create a full-featured web3 application. + +## Chain IDs + +These are the IDs of the Starcoin chains that StarMask supports by default. + +| Hex | Decimal | Network | +| ---- | ------- | ------------------------------- | +| 0x1 | 1 | Starcoin Main Network (Mainnet) | +| 0xfb | 251 | Barnard Test Network | +| 0xfc | 252 | Proxima Test Network | +| 0xfd | 253 | Halley Test Network | + +## Properties + +### starcoin.isStarMask + +:::warning Note +This property is non-standard. Non-StarMask providers may also set this property to `true`. +::: + +`true` if the user has StarMask installed. + +## Methods + +### starcoin.isConnected() + +:::tip Tip +Note that this method has nothing to do with the user's accounts. + +You may often encounter the word "connected" in reference to whether a web3 site can access the user's accounts. +In the provider interface, however, "connected" and "disconnected" refer to whether the provider can make RPC requests to the current chain. +::: + +```typescript +starcoin.isConnected(): boolean; +``` + +Returns `true` if the provider is connected to the current chain, and `false` otherwise. + +If the provider is not connected, the page will have to be reloaded in order for connection to be re-established. +Please see the [`connect`](#connect) and [`disconnect`](#disconnect) events for more information. + +### starcoin.request(args) + +```typescript +interface RequestArguments { + method: string; + params?: unknown[] | object; +} + +starcoin.request(args: RequestArguments): Promise; +``` + +Use `request` to submit RPC requests to Starcoin via StarMask. +It returns a `Promise` that resolves to the result of the RPC method call. + +The `params` and return value will vary by RPC method. +In practice, if a method has any `params`, they are almost always of type `Array`. + +If the request fails for any reason, the Promise will reject with an [Starcoin RPC Error](#errors). + +StarMask supports most standardized Starcoin RPC methods, in addition to a number of methods that may not be supported by other wallets. +See the StarMask [RPC API documentation](./03-rpc-api.md) for details. + +#### Example + +```javascript +params: [ + "0xeb9a0d1628fddba79b932ced2623b1a415000000000000000218351d311d32201149a4df2a9fc2db8a1043726f7373436861696e536372697074116c6f636b5f776974685f7374635f66656500062f2e307831383335316433313164333232303131343961346466326139666332646238613a3a584554483a3a584554480802000000000000001514208d1ae5bb7fd323ce6386c443473ed660825d4610c05e9de71a000000000000000000000010404b4c000000000000000000000000001001000000000000000000000000000000809698000000000001000000000000000d3078313a3a5354433a3a5354434eb90f6200000000fb0020a972a04aefbace3686e1889c47976ca664ad9f9384293c6b291811fc2870e2ba40b7d36db7f70149c7614cb9535a5d56ff052bcd74dfc3578f1b3586d80913fdc5ca4785a78b5d11c7bfecb86c0a0c56c3945d39b8c759115a2be61f5d82ba1e08", +]; + +starcoin + .request({ + method: "txpool.submit_hex_transaction", + params, + }) + .then((result) => { + // The result varies by RPC method. + // For example, this method will return a transaction hash hexadecimal string on success. + }) + .catch((error) => { + // If the request fails, the Promise will reject with an error. + }); +``` + +## Events + +The StarMask provider implements the [Node.js `EventEmitter`](https://nodejs.org/api/events.html) API. +This sections details the events emitted via that API. +There are innumerable `EventEmitter` guides elsewhere, but you can listen for events like this: + +```javascript +starcoin.on("accountsChanged", (accounts) => { + // Handle the new accounts, or lack thereof. + // "accounts" will always be an array, but it can be empty. +}); + +starcoin.on("chainChanged", (chainId) => { + // Handle the new chain. + // Correctly handling chain changes can be complicated. + // We recommend reloading the page unless you have good reason not to. + window.location.reload(); +}); +``` + +Also, don't forget to remove listeners once you are done listening to them (for example on component unmount in React): + +```javascript +function handleAccountsChanged(accounts) { + // ... +} + +starcoin.on("accountsChanged", handleAccountsChanged); + +// Later + +starcoin.removeListener("accountsChanged", handleAccountsChanged); +``` + +The first argument of the `starcoin.removeListener` is the event name and the second argument is the reference to the same function which has passed to `starcoin.on` for the event name mentioned in the first argument. + +### connect + +```typescript +interface ConnectInfo { + chainId: string; +} + +starcoin.on('connect', handler: (connectInfo: ConnectInfo) => void); +``` + +The StarMask provider emits this event when it first becomes able to submit RPC requests to a chain. +We recommend using a `connect` event handler and the [`starcoin.isConnected()` method](#starcoin-isconnected) in order to determine when/if the provider is connected. + +### disconnect + +```typescript +starcoin.on('disconnect', handler: (error: ProviderRpcError) => void); +``` + +The StarMask provider emits this event if it becomes unable to submit RPC requests to any chain. +In general, this will only happen due to network connectivity issues or some unforeseen error. + +Once `disconnect` has been emitted, the provider will not accept any new requests until the connection to the chain has been re-established, which requires reloading the page. +You can also use the [`starcoin.isConnected()` method](#starcoin-isconnected) to determine if the provider is disconnected. + +### accountsChanged + +```typescript +starcoin.on('accountsChanged', handler: (accounts: Array) => void); +``` + +The StarMask provider emits this event whenever the return value of the `stc_accounts` RPC method changes. +`stc_accounts` returns an array that is either empty or contains a single account address. +The returned address, if any, is the address of the most recently used account that the caller is permitted to access. +Callers are identified by their URL _origin_, which means that all sites with the same origin share the same permissions. + +This means that `accountsChanged` will be emitted whenever the user's exposed account address changes. + +### chainChanged + +:::tip Tip +See the [Chain IDs section](#chain-ids) for StarMask's default chains and their chain IDs. +::: + +```typescript +starcoin.on('chainChanged', handler: (chainId: string) => void); +``` + +The StarMask provider emits this event when the currently connected chain changes. + +All RPC requests are submitted to the currently connected chain. +Therefore, it's critical to keep track of the current chain ID by listening for this event. + +We _strongly_ recommend reloading the page on chain changes, unless you have good reason not to. + +```javascript +starcoin.on("chainChanged", (_chainId) => window.location.reload()); +``` + + + +## Errors + +All errors thrown or returned by the StarMask provider follow this interface: + +```typescript +interface ProviderRpcError extends Error { + message: string; + code: number; + data?: unknown; +} +``` + +The [`starcoin.request(args)` method](#starcoin-request-args) throws errors eagerly. +You can often use the error `code` property to determine why the request failed. + + + +## Using the Provider + +This snippet explains how to accomplish the three most common requirements for web3 sites: + +- Detect the Starcoin provider (`window.starcoin`) +- Detect which Starcoin network the user is connected to +- Get the user's Starcoin account(s) + +<<< @/docs/snippets/handleProvider.js + + diff --git a/docs/04-web3/01-starmask/03-rpc-api.md b/docs/04-web3/01-starmask/03-rpc-api.md new file mode 100644 index 000000000..dfed1b613 --- /dev/null +++ b/docs/04-web3/01-starmask/03-rpc-api.md @@ -0,0 +1,511 @@ +# RPC API + +StarMask uses the [`starcoin.request(args)` method](./02-starcoin-provider.md#starcoin-request-args) to wrap an RPC API. + +The API is based on an interface exposed by all Starcoin clients, along with a growing number of methods that may or may not be supported by other wallets. + +:::tip Tip +All RPC method requests can return errors. +Make sure to handle errors for every call to `starcoin.request(args)`. +::: + +:::tip Try +Starcoin Methods +Visit our [API Playground](https://starcoin.org/en/developers/dapp/rpc/rpc_document/) +::: + + + +## Restricted Methods + +StarMask introduced Web3 Wallet Permissions via [EIP-2255](https://eips.ethereum.org/EIPS/eip-2255). +In this permissions system, each RPC method is either _restricted_ or _unrestricted_. +If a method is restricted, the caller must have the corresponding permission in order to call it. +Unrestricted methods, meanwhile, have no corresponding permission. Some of them still rely upon permissions to succeed though (e.g. the signing methods require that you have the `stc_accounts` permission for the signer account), and some require confirmation by the user (e.g. `wallet_addStarcoinChain`). + +More permissions will be added in the future. + +Under the hood, permissions are plain, JSON-compatible objects, with a number of fields that are mostly used internally by StarMask. +The following interface lists the fields that may be of interest to consumers: + +```typescript +interface Web3WalletPermission { + // The name of the method corresponding to the permission + parentCapability: string; + + // The date the permission was granted, in UNIX epoch time + date?: number; +} +``` + +If you're interested in learning more about the theory behind this _capability_-inspired permissions system, we encourage you to take a look at [EIP-2255](https://eips.ethereum.org/EIPS/eip-2255). + +### `stc_requestAccounts` + +:::tip EIP-1102 +This method is specified by [EIP-1102](https://eips.ethereum.org/EIPS/eip-1102). + +Under the hood, it calls [`wallet_requestPermissions`](#wallet-requestpermissions) for the `stc_accounts` permission. +Since `stc_accounts` is currently the only permission, this method is all you need for now. +::: + +#### Returns + +`string[]` - An array of a single, hexadecimal Starcoin address string. + +#### Description + +Requests that the user provides an Starcoin address to be identified by. +Returns a Promise that resolves to an array of a single Starcoin address string. +If the user denies the request, the Promise will reject with a `4001` error. + +The request causes a StarMask popup to appear. +You should only request the user's accounts in response to user action, such as a button click. +You should always disable the button that caused the request to be dispatched, while the request is still pending. + +If you can't retrieve the user's account(s), you should encourage the user to initiate an account request. + +#### Example + +```javascript +document.getElementById("connectButton", connect); + +function connect() { + starcoin + .request({ method: "stc_requestAccounts" }) + .then(handleAccountsChanged) + .catch((error) => { + if (error.code === 4001) { + // EIP-1193 userRejectedRequest error + console.log("Please connect to StarMask."); + } else { + console.error(error); + } + }); +} +``` + +### `wallet_getPermissions` + +#### Returns + +`Web3WalletPermission[]` - An array of the caller's permissions. + +#### Description + +Gets the caller's current permissions. +Returns a Promise that resolves to an array of `Web3WalletPermission` objects. +If the caller has no permissions, the array will be empty. + +### `wallet_requestPermissions` + +#### Parameters + +- `Array` + + 0. `RequestedPermissions` - The requested permissions. + +```typescript +interface RequestedPermissions { + [methodName: string]: {}; // an empty object, for future extensibility +} +``` + +#### Returns + +`Web3WalletPermission[]` - An array of the caller's permissions. + +#### Description + +Requests the given permissions from the user. +Returns a Promise that resolves to a non-empty array of `Web3WalletPermission` objects, corresponding to the caller's current permissions. +If the user denies the request, the Promise will reject with a `4001` error. + +The request causes a StarMask popup to appear. +You should only request permissions in response to user action, such as a button click. + +#### Example + +```javascript +document.getElementById("requestPermissionsButton", requestPermissions); + +function requestPermissions() { + starcoin + .request({ + method: "wallet_requestPermissions", + params: [{ stc_accounts: {} }], + }) + .then((permissions) => { + const accountsPermission = permissions.find( + (permission) => permission.parentCapability === "stc_accounts" + ); + if (accountsPermission) { + console.log("stc_accounts permission successfully requested!"); + } + }) + .catch((error) => { + if (error.code === 4001) { + // EIP-1193 userRejectedRequest error + console.log("Permissions needed to continue."); + } else { + console.error(error); + } + }); +} +``` + +## Unrestricted Methods + +### `stc_decrypt` + +#### Parameters + +- `Array` + + 0. `string` - An encrypted message. + 1. `string` - The address of the Starcoin account that can decrypt the message. + +#### Returns + +`string` - The decrypted message. + +#### Description + +Requests that StarMask decrypts the given encrypted message. +The message must have been encrypted using the public encryption key of the given Starcoin address. +Returns a Promise that resolves to the decrypted message, or rejects if the decryption attempt fails. + +See [`stc_getEncryptionPublicKey`](#stc-getencryptionpublickey) for more information. + +#### Example + +```javascript +starcoin + .request({ + method: "stc_decrypt", + params: [encryptedMessage, accounts[0]], + }) + .then((decryptedMessage) => + console.log("The decrypted message is:", decryptedMessage) + ) + .catch((error) => console.log(error.message)); +``` + +### `stc_getEncryptionPublicKey` + +#### Parameters + +- `Array` + + 0. `string` - The address of the Starcoin account whose encryption key should be retrieved. + +#### Returns + +`string` - The public encryption key of the specified Starcoin account. + +#### Description + +Requests that the user shares their public encryption key. +Returns a Promise that resolve to the public encryption key, or rejects if the user denied the request. + +The public key is computed from entropy associated with the specified user account, using the [`nacl`](https://github.com/dchest/tweetnacl-js) implementation of the `X25519_XSalsa20_Poly1305` algorithm. + +#### Example + +```javascript +let encryptionPublicKey; + +starcoin + .request({ + method: "stc_getEncryptionPublicKey", + params: [accounts[0]], // you must have access to the specified account + }) + .then((result) => { + encryptionPublicKey = result; + }) + .catch((error) => { + if (error.code === 4001) { + // EIP-1193 userRejectedRequest error + console.log("We can't encrypt anything without the key."); + } else { + console.error(error); + } + }); +``` + +#### Encrypting + +The point of the encryption key is of course to encrypt things. +Here's an example of how to encrypt a message using [`eth-sig-util`](https://github.com/StarMask/eth-sig-util): + +```javascript +const stcUtil = require("@starcoin/stc-util"); +const sigUtil = require("@metamask/eth-sig-util"); + +const encryptedMessage = stcUtil.bufferToHex( + Buffer.from( + JSON.stringify( + sigUtil.encrypt({ + publicKey: encryptionPublicKey, + data: "hello world!", + version: "x25519-xsalsa20-poly1305", + }) + ), + "utf8" + ) +); +``` + +### `wallet_addStarcoinChain` + +:::tip EIP-3085 +This method is specified by [EIP-3085](https://eips.ethereum.org/EIPS/eip-3085). +::: + +#### Parameters + +- `Array` + + 0. `AddStarcoinChainParameter` - Metadata about the chain that will be added to StarMask. + +For the `rpcUrls` and `blockExplorerUrls` arrays, at least one element is required, and only the first element will be used. + +```typescript +interface AddStarcoinChainParameter { + chainId: string; // A 0x-prefixed hexadecimal string + chainName: string; + nativeCurrency: { + name: string; + symbol: string; // 2-6 characters long + decimals: 18; + }; + rpcUrls: string[]; + blockExplorerUrls?: string[]; + iconUrls?: string[]; // Currently ignored. +} +``` + +#### Returns + +`null` - The method returns `null` if the request was successful, and an error otherwise. + +#### Description + +Creates a confirmation asking the user to add the specified chain to StarMask. +The user may choose to switch to the chain once it has been added. + +As with any method that causes a confirmation to appear, `wallet_addStarcoinChain` +should **only** be called as a result of direct user action, such as the click of a button. + +StarMask stringently validates the parameters for this method, and will reject the request +if any parameter is incorrectly formatted. +In addition, StarMask will automatically reject the request under the following circumstances: + +- If the RPC endpoint doesn't respond to RPC calls. +- If the RPC endpoint returns a different chain ID when `chain.id` is called. +- If the chain ID corresponds to any default StarMask chains. + +StarMask does not yet support chains with native currencies that do not have 18 decimals, +but may do so in the future. + +#### Usage with `wallet_switchStarcoinChain` + +We recommend using this method with [`wallet_addStarcoinChain`](#wallet-addStarcoinchain): + +```javascript +try { + await starcoin.request({ + method: "wallet_switchStarcoinChain", + params: [{ chainId: "0xf00" }], + }); +} catch (switchError) { + // This error code indicates that the chain has not been added to StarMask. + if (switchError.code === 4902) { + try { + await starcoin.request({ + method: "wallet_addStarcoinChain", + params: [ + { + chainId: "0xf00", + chainName: "...", + rpcUrls: ["https://..."] /* ... */, + }, + ], + }); + } catch (addError) { + // handle "add" error + } + } + // handle other "switch" errors +} +``` + +### `wallet_switchStarcoinChain` + +:::tip EIP-3326 +This method is specified by [EIP-3326](https://ethereum-magicians.org/t/eip-3326-wallet-switchethereumchain). +::: + +#### Parameters + +- `Array` + + 0. `SwitchStarcoinChainParameter` - Metadata about the chain that StarMask will switch to. + +```typescript +interface SwitchEthereumChainParameter { + chainId: string; // A 0x-prefixed hexadecimal string +} +``` + +#### Returns + +`null` - The method returns `null` if the request was successful, and an error otherwise. + +If the error code (`error.code`) is `4902`, then the requested chain has not been added by StarMask, and you have to request to add it via [`wallet_addStarcoinChain`](#wallet-addstarcoinchain). + +#### Description + +:::tip Tip +See [above](#usage-with-wallet-switchstarcoinchain) for how to use this method with `wallet_addStarcoinChain`. +::: + +Creates a confirmation asking the user to switch to the chain with the specified `chainId`. + +As with any method that causes a confirmation to appear, `wallet_switchStarcoinChain` +should **only** be called as a result of direct user action, such as the click of a button. + +StarMask will automatically reject the request under the following circumstances: + +- If the chain ID is malformed +- If the chain with the specified chain ID has not been added to StarMask + +### `wallet_registerOnboarding` + +:::tip Tip +As an API consumer, you are unlikely to have to call this method yourself. + +TODO: fix some bugs, until translate zh +::: + +#### Returns + +`boolean` - `true` if the request was successful, `false` otherwise. + +#### Description + +Registers the requesting site with StarMask as the initiator of onboarding. +Returns a Promise that resolves to `true`, or rejects if there's an error. + +This method is intended to be called after StarMask has been installed, but before the StarMask onboarding has completed. +You can use this method to inform StarMask that you were the one that suggested installing StarMask. +This lets StarMask redirect the user back to your site after onboarding has completed. + +Instead of calling this method directly, you should use the [`@starcoin/starmask-onboarding` library](https://github.com/starcoinorg/starmask-onboarding). + +### `wallet_watchAsset` + +:::tip EIP-747 +This method is specified by [EIP-747](https://eips.ethereum.org/EIPS/eip-747). +::: + +#### Parameters + +- `WatchAssetParams` - The metadata of the asset to watch. + +<<< @/docs/snippets/WatchAssetParams.ts + +#### Returns + +`boolean` - `true` if the the token was added, `false` otherwise. + +#### Description + +Requests that the user tracks the token in StarMask. +Returns a `boolean` indicating if the token was successfully added. + +Most Starcoin wallets support some set of tokens, usually from a centrally curated registry of tokens. +`wallet_watchAsset` enables web3 application developers to ask their users to track tokens in their wallets, at runtime. +Once added, the token is indistinguishable from those added via legacy methods, such as a centralized registry. + +#### Example + +```javascript +starcoin + .request({ + method: "wallet_watchAsset", + params: { + type: "ERC20", + options: { + address: "0xb60e8dd61c5d32be8058bb8eb970870f07233155", + symbol: "FOO", + decimals: 18, + image: "https://foo.io/token-image.svg", + }, + }, + }) + .then((success) => { + if (success) { + console.log("FOO successfully added to wallet!"); + } else { + throw new Error("Something went wrong."); + } + }) + .catch(console.error); +``` + +## Mobile Specific RPC Methods + +### `wallet_scanQRCode` + +#### Parameters + +- `Array` + + 0. `string` - (optional) A regular expression for matching arbitrary QR code strings + +#### Returns + +`string` - The string corresponding to the scanned QR code. + +#### Description + +Requests that the user scans a QR code using their device camera. +Returns a Promise that resolves to a string, matching either: + +1. The regex parameter, if provided +2. An starcoin address, if no regex parameter was provided + +If neither condition is met, the Promise will reject with an error. + +StarMask previously introduced this feature per the proposed [EIP-945](https://github.com/ethereum/EIPs/issues/945). +The functionality was temporarily removed before being reintroduced as this RPC method. + +#### Example + +```javascript +starcoin + .request({ + method: "wallet_scanQRCode", + // The regex string must be valid input to the RegExp constructor, if provided + params: ["\\D"], + }) + .then((result) => { + console.log(result); + }) + .catch((error) => { + console.log(error); + }); +``` diff --git a/docs/04-web3/01-starmask/README.md b/docs/04-web3/01-starmask/README.md new file mode 100644 index 000000000..aa1019aa4 --- /dev/null +++ b/docs/04-web3/01-starmask/README.md @@ -0,0 +1,11 @@ +# StarMask + +## Guide + + + +## API Reference + + + + diff --git a/docs/04-web3/01-starmask/_category_.yaml b/docs/04-web3/01-starmask/_category_.yaml new file mode 100644 index 000000000..5270374c0 --- /dev/null +++ b/docs/04-web3/01-starmask/_category_.yaml @@ -0,0 +1 @@ +label: "StarMask Docs" diff --git a/docs/04-web3/01-web3-introduction.md b/docs/04-web3/01-web3-introduction.md deleted file mode 100644 index f43dc24ac..000000000 --- a/docs/04-web3/01-web3-introduction.md +++ /dev/null @@ -1 +0,0 @@ -# Web3, DApp and Starcoin \ No newline at end of file diff --git a/docs/04-web3/02-starcoin-json-rpc.md b/docs/04-web3/02-starcoin-json-rpc.md index df9c8a56e..94213e610 100644 --- a/docs/04-web3/02-starcoin-json-rpc.md +++ b/docs/04-web3/02-starcoin-json-rpc.md @@ -1 +1,25 @@ -# Starcoin json rpc \ No newline at end of file +# Starcoin Json RPC + +> `account.*` and `node_manager.*` is not public on Main/Barnard/Proxima/Halley networks. They are only accessable while you enable `public` on your local node. + +## [account](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/account.json) + +## [chain](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/chain.json) + +## [contract_api](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/contract_api.json) + +## [debug](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/debug.json) + +## [miner](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/miner.json) + +## [network_manager](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/network_manager.json) + +## [node](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/node.json) + +## [node_manager](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/node_manager.json) + +## [state](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/state.json) + +## [sync_manager](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/sync_manager.json) + +## [txpool](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/txpool.json) diff --git a/docs/04-web3/04-interacting-with-the-contract.md b/docs/04-web3/04-interacting-with-the-contract.md index d7749b234..ded85b2c5 100644 --- a/docs/04-web3/04-interacting-with-the-contract.md +++ b/docs/04-web3/04-interacting-with-the-contract.md @@ -1,8 +1,206 @@ # Interaction with the contract by RPC and SDK -TODO +Generally, there are 4 steps for a dapp to interact with the Starcoin blockchain: -1. write to contract, execute a transaction -2. read to contract -3. watch events -4. view resource \ No newline at end of file +1. Connect to StarMask +2. Generate the rawUserTransaction hex string while calling the contract with params +3. Wake up the StarMask and asking the user to confirm the transaction +4. Wait until the transaction was confirmed on the Starcoin blockchian, and display the result + +Let's explain each steps in details with examples from [starmask-test-dapp](https://github.com/starcoinorg/starmask-test-dapp). + +## 1. Connect to StarMask + +To interact with the Chrome extension StarMask, a Dapp must check wether it is installed or not: + +```js +import StarMaskOnboarding from "@starcoin/starmask-onboarding"; + +const { isStarMaskInstalled } = StarMaskOnboarding; + +let onboarding; +try { + onboarding = new StarMaskOnboarding({ forwarderOrigin }); +} catch (error) { + console.error(error); +} + +const onClickInstall = () => { + onboardButton.innerText = "Onboarding in progress"; + onboardButton.disabled = true; + onboarding.startOnboarding(); +}; + +if (!isStarMaskInstalled()) { + onboardButton.innerText = "Click here to install StarMask!"; + onboardButton.onclick = onClickInstall; + onboardButton.disabled = false; +} else if (isStarMaskConnected()) { + onboardButton.innerText = "Connected"; + onboardButton.disabled = true; + if (onboarding) { + onboarding.stopOnboarding(); + } +} +``` + +If StarMask is installed, it will inject a global object `window.starcoin` into the Dapp, then we can use it to connect to StarMask, +and get the connected account address: + +```js +const handleNewAccounts = (newAccounts) => { + accounts = newAccounts; + accountsDiv.innerHTML = accounts; +}; + +const onClickConnect = async () => { + try { + const newAccounts = await window.starcoin.request({ + method: "stc_requestAccounts", + }); + handleNewAccounts(newAccounts); + } catch (error) { + console.error(error); + } +}; +``` + +## 2. Generate the rawUserTransaction hex string while calling the contract with params + +If we want to call a contract(execute a transaction), for example, `0x1::TransferScripts::peer_to_peer_v2` can transfer any amount of any token to others. + +First, we need to confirm the contract's params number and type. + +[here](https://github.com/starcoinorg/starcoin-framework/blob/main/sources/TransferScripts.move#L15) is the source code of `0x1::TransferScripts::peer_to_peer_v2`: + +``` +public(script) fun peer_to_peer_v2(account: signer, payee: address, amount: u128) { +``` + +omit the first param(type is `signer`), we need to pass 2 params while calling this contract on dapp: + +1. `payee`, type is `address` +2. `amount`, type is `u128` + +Second, we need to generate the scriptFunction while calling the contract with the corresponding params. + +There are two ways to generate the scriptFunction. One is `utils.tx.encodeScriptFunction`: + +```js +import { utils } from "@starcoin/starcoin"; + +const functionId = "0x1::TransferScripts::peer_to_peer_v2"; +const strTypeArgs = ["0x1::STC::STC"]; +const tyArgs = utils.tx.encodeStructTypeTags(strTypeArgs); + +const toAccount = document.getElementById("toAccountInput").value; + +const BIG_NUMBER_NANO_STC_MULTIPLIER = new BigNumber("1000000000"); +const sendAmountSTC = new BigNumber( + String(document.getElementById("amountInput").value), + 10 +); +const sendAmountNanoSTC = sendAmountSTC.times(BIG_NUMBER_NANO_STC_MULTIPLIER); +const sendAmountHex = `0x${sendAmountNanoSTC.toString(16)}`; + +// Multiple BcsSerializers should be used in different closures, otherwise, the latter will be contaminated by the former. +const amountSCSHex = (function () { + const se = new bcs.BcsSerializer(); + se.serializeU128(BigInt(sendAmountNanoSTC.toString(10))); + return hexlify(se.getBytes()); +})(); + +const args = [arrayify(toAccount), arrayify(amountSCSHex)]; + +const scriptFunction = utils.tx.encodeScriptFunction(functionId, tyArgs, args); +``` + +> Check [BCS in JS SDK](./05-understanding-resource-and-bcs/02-bcs-in-js.md) for more details. + +If we don't want to manually generate the bcs of each element of array typeArgs and args, we can use `utils.tx.encodeScriptFunctionByResolve` directly. + +```js +const functionId = "0x1::TransferScripts::peer_to_peer_v2"; +const tyArgs = ["0x1::STC::STC"]; +const toAccount = document.getElementById("toAccountInput").value; +const BIG_NUMBER_NANO_STC_MULTIPLIER = new BigNumber("1000000000"); +const sendAmountSTC = new BigNumber( + String(document.getElementById("amountInput").value), + 10 +); +const sendAmountNanoSTC = sendAmountSTC.times(BIG_NUMBER_NANO_STC_MULTIPLIER); +const args = [toAccount, sendAmountSTC]; + +const nodeUrl = nodeUrlMap[window.starcoin.networkVersion]; + +const scriptFunction = await utils.tx.encodeScriptFunctionByResolve( + functionId, + tyArgs, + args, + nodeUrl +); +``` + +Finally, geneate the rawUserTransaction hex string: + +```js +const payloadInHex = (function () { + const se = new bcs.BcsSerializer(); + scriptFunction.serialize(se); + return hexlify(se.getBytes()); +})(); +``` + +## 3. Wake up the StarMask and asking the user to confirm the transaction + +```js +const txParams = { + data: payloadInHex, +}; + +const transactionHash = await starcoinProvider + .getSigner() + .sendUncheckedTransaction(txParams); +``` + +The StarMask will pop up a transaction confirm page, display the estimated gas fee in the `DETAILS` tab ,and the scriptFunction params and the hex string in the `DATA` tab. + +![starmask-confirm](../../static/img/dapp/starmask-confirm.png) + +User can either `Reject` or `Confirm` this transaction. + +> Tips: before user click either of these two buttons, the Dapp should display a Loading status. + +## 4. Wait until the transaction was confirmed on the Starcoin blockchian, and display the result + +A transaction must be confirmed by enough nodes, we can change this in the constant variable `MAX_CONFIRMED_NODES`. +We need to display a loading status, and long polling the staus of the transaction using `transactionHash`, and check the confirmations of the response, and cancle the loading status until confirmations is equal to or larger than `MAX_CONFIRMED_NODES`. + +```js +const MAX_CONFIRMED_NODES = 6; +contractStatus2.innerHTML = `Transaction is waiting confirmed `; +let timer = setInterval(async () => { + const txnInfo = await starcoinProvider.getTransactionInfo(transactionHash); + if (txnInfo.status === "Executed") { + contractStatus2.innerHTML = `Transaction ${txnInfo.confirmations} confirmed `; + if (txnInfo.confirmations >= MAX_CONFIRMED_NODES) { + clearInterval(timer); + contractStatus2.innerHTML = "Call Completed"; + callContractButton.disabled = false; + } + } +}, 3000); +``` +:::tip Tip +If StarMask connect to a dev network, you may need to generate new blocks manually. Run dev gen-block in console up to MAX_CONFIRMED_NODES times and see what happens. +::: + +## Reference + +- [Starcoin JS SDK](https://starcoin.org/zh/developer/sdk/javascript/) + +- [StarMask Test Dapp](https://github.com/starcoinorg/starmask-test-dapp). + +- [Developing Dapp with React](https://github.com/starcoinorg/starcoin-test-dapp-react) + +- [Developing Dapp with Vue3](https://starcoin.org/zh/developers/others/how_to_use_vue_to_develop_dapp/) diff --git a/docs/04-web3/05-understanding-resource-and-bcs/01-bcs.md b/docs/04-web3/05-understanding-resource-and-bcs/01-bcs.md new file mode 100644 index 000000000..53ef1bf3c --- /dev/null +++ b/docs/04-web3/05-understanding-resource-and-bcs/01-bcs.md @@ -0,0 +1,277 @@ +# Binary Canonical Serialization (BCS) + +BCS (formerly "Libra Canonical Serialization" or LCS) is a serialization format developed +in the context of the [Diem](https://diem.com) blockchain. + +BCS was designed with the following main goals in mind: + +* provide good performance and concise (binary) representations; +* support a rich set of data types commonly used in Rust; +* enforce canonical serialization, meaning that every value of a given type should have a single valid representation. + +BCS also aims to mitigate the consequence of malicious inputs by enforcing well-defined limits +on large or nested containers during (de)serialization. + +## Rust Implementation + +This crate provides a Rust implementation of BCS as an encoding format for the [Serde library](https://serde.rs). +As such, this implementation covers most data types supported by Serde -- including user-defined structs, +tagged variants (Rust enums), tuples, and maps -- excluding floats, single unicode characters (char), and sets. + +BCS is also available in other programming languages, thanks to the separate project [serde-reflection](https://github.com/novifinancial/serde-reflection). + +## Application to Cryptography + +The BCS format guarantees canonical serialization, meaning that for any given data type, there +is a one-to-one correspondance between in-memory values and valid byte representations. + +In the context of a cryptographic application, canonical serialization has several benefits: + +* It provides a natural and reliable way to associate in-memory values to cryptographic hashes. +* It allows the signature of a message to be defined equivalently as the signature of the serialized bytes or as the signature of the in-memory value. + +Note that BCS ensures canonical serialization for each data type separately. The data type of a serialized value +must be enforced by the application itself. This requirement is typically fulfilled +using unique hash seeds for each data type. (See [Diem's cryptographic library](https://github.com/diem/diem/blob/master/crypto/crypto/src/hash.rs) for an example.) + +## Backwards Compatibility + +By design, BCS does not provide implicit versioning or backwards/forwards compatibility, therefore +applications must carefully plan in advance for adhoc extension points: + +* Enums may be used for explicit versioning and backward compatibility (e.g. extensible query interfaces). +* In some cases, data fields of type `Vec` may also be added to allow (future) unknown payloads in serialized form. + +## Detailed Specifications + +BCS supports the following data types: + +* Booleans +* Signed 8-bit, 16-bit, 32-bit, 64-bit, and 128-bit integers +* Unsigned 8-bit, 16-bit, 32-bit, 64-bit, and 128-bit integers +* Option +* Unit (an empty value) +* Fixed and variable length sequences +* UTF-8 Encoded Strings +* Tuples +* Structures (aka "structs") +* Externally tagged enumerations (aka "enums") +* Maps + +BCS is not a self-describing format. +As such, in order to deserialize a message, one must know the message type and layout ahead of time. + +Unless specified, all numbers are stored in little endian, two's complement format. + +### Recursion and Depth of BCS Data + +Recursive data-structures (e.g. trees) are allowed. However, because of the possibility of stack +overflow during (de)serialization, the *container depth* of any valid BCS data cannot exceed the constant +`MAX_CONTAINER_DEPTH`. Formally, we define *container depth* as the number of structs and enums traversed +during (de)serialization. + +This definition aims to minimize the number of operations while ensuring that +(de)serialization of a known BCS format cannot cause arbitrarily large stack allocations. + +As an example, if `v1` and `v2` are values of depth `n1` and `n2`, + +* a struct value `Foo { v1, v2 }` has depth `1 + max(n1, n2)`; +* an enum value `E::Foo { v1, v2 }` has depth `1 + max(n1, n2)`; +* a pair `(v1, v2)` has depth `max(n1, n2)`; +* the value `Some(v1)` has depth `n1`. + +All string and integer values have depths `0`. + +### Booleans and Integers + +|Type |Original data |Hex representation |Serialized bytes | +|--- |--- |--- |--- | +|Boolean |True / False |0x01 / 0x00 |01 / 00 | +|8-bit signed integer |-1 |0xFF |FF | +|8-bit unsigned integer |1 |0x01 |01 | +|16-bit signed integer |-4660 |0xEDCC |CC ED | +|16-bit unsigned integer |4660 |0x1234 |34 12 | +|32-bit signed integer |-305419896 |0xEDCBA988 |88 A9 CB ED | +|32-bit unsigned integer |305419896 |0x12345678 |78 56 34 12 | +|64-bit signed integer |-1311768467750121216 |0xEDCBA98754321100 |00 11 32 54 87 A9 CB ED | +|64-bit unsigned integer |1311768467750121216 |0x12345678ABCDEF00 |00 EF CD AB 78 56 34 12 | + +### ULEB128-Encoded Integers + +The BCS format also uses the [ULEB128 encoding](https://en.wikipedia.org/wiki/LEB128) internally +to represent unsigned 32-bit integers in two cases where small values are usually expected: +(1) lengths of variable-length sequences and (2) tags of enum values (see the corresponding +sections below). + +|Type |Original data |Hex representation |Serialized bytes | +|--- |--- |--- |--- | +|ULEB128-encoded u32-integer|2^0 = 1 |0x00000001 |01 | +| |2^7 = 128 |0x00000080 |80 01 | +| |2^14 = 16384 |0x00004000 |80 80 01 | +| |2^21 = 2097152 |0x00200000 |80 80 80 01 | +| |2^28 = 268435456 |0x10000000 |80 80 80 80 01 | +| |9487 |0x0000250f |8f 4a | + +In general, a ULEB128 encoding consists of a little-endian sequence of base-128 (7-bit) +digits. Each digit is completed into a byte by setting the highest bit to 1, except for the +last (highest-significance) digit whose highest bit is set to 0. + +In BCS, the result of decoding ULEB128 bytes is required to fit into a 32-bit unsigned +integer and be in canonical form. For instance, the following values are rejected: +* 80 80 80 80 80 01 (2^36) is too large. +* 80 80 80 80 10 (2^33) is too large. +* 80 00 is not a minimal encoding of 0. + +### Optional Data + +Optional or nullable data either exists in its full representation or does not. BCS represents +this as a single byte representing the presence `0x01` or absence `0x00` of data. If the data +is present then the serialized form of that data follows. For example: + +```rust +let some_data: Option = Some(8); +assert_eq!(to_bytes(&some_data)?, vec![1, 8]); + +let no_data: Option = None; +assert_eq!(to_bytes(&no_data)?, vec![0]); +``` + +### Fixed and Variable Length Sequences + +Sequences can be made of up of any BCS supported types (even complex structures) but all +elements in the sequence must be of the same type. If the length of a sequence is fixed and +well known then BCS represents this as just the concatenation of the serialized form of each +individual element in the sequence. If the length of the sequence can be variable, then the +serialized sequence is length prefixed with a ULEB128-encoded unsigned integer indicating +the number of elements in the sequence. All variable length sequences must be +`MAX_SEQUENCE_LENGTH` elements long or less. + +```rust +let fixed: [u16; 3] = [1, 2, 3]; +assert_eq!(to_bytes(&fixed)?, vec![1, 0, 2, 0, 3, 0]); + +let variable: Vec = vec![1, 2]; +assert_eq!(to_bytes(&variable)?, vec![2, 1, 0, 2, 0]); + +let large_variable_length: Vec<()> = vec![(); 9_487]; +assert_eq!(to_bytes(&large_variable_length)?, vec![0x8f, 0x4a]); +``` + +### Strings + +Only valid UTF-8 Strings are supported. BCS serializes such strings as a variable length byte +sequence, i.e. length prefixed with a ULEB128-encoded unsigned integer followed by the byte +representation of the string. + +```rust +// Note that this string has 10 characters but has a byte length of 24 +let utf8_str = "çå∞≠¢õß∂ƒ∫"; +let expecting = vec![ + 24, 0xc3, 0xa7, 0xc3, 0xa5, 0xe2, 0x88, 0x9e, 0xe2, 0x89, 0xa0, 0xc2, + 0xa2, 0xc3, 0xb5, 0xc3, 0x9f, 0xe2, 0x88, 0x82, 0xc6, 0x92, 0xe2, 0x88, 0xab, +]; +assert_eq!(to_bytes(&utf8_str)?, expecting); +``` + +### Tuples + +Tuples are typed composition of objects: `(Type0, Type1)` + +Tuples are considered a fixed length sequence where each element in the sequence can be a +different type supported by BCS. Each element of a tuple is serialized in the order it is +defined within the tuple, i.e. [tuple.0, tuple.2]. + +```rust +let tuple = (-1i8, "diem"); +let expecting = vec![0xFF, 4, b'd', b'i', b'e', b'm']; +assert_eq!(to_bytes(&tuple)?, expecting); +``` + + +### Structures + +Structures are fixed length sequences consisting of fields with potentially different types. +Each field within a struct is serialized in the order specified by the canonical structure +definition. Structs can exist within other structs and as such, BCS recurses into each struct +and serializes them in order. There are no labels in the serialized format, the struct ordering +defines the organization within the serialization stream. + +```rust +#[derive(Serialize)] +struct MyStruct { + boolean: bool, + bytes: Vec, + label: String, +} + +#[derive(Serialize)] +struct Wrapper { + inner: MyStruct, + name: String, +} + +let s = MyStruct { + boolean: true, + bytes: vec![0xC0, 0xDE], + label: "a".to_owned(), +}; +let s_bytes = to_bytes(&s)?; +let mut expecting = vec![1, 2, 0xC0, 0xDE, 1, b'a']; +assert_eq!(s_bytes, expecting); + +let w = Wrapper { + inner: s, + name: "b".to_owned(), +}; +let w_bytes = to_bytes(&w)?; +assert!(w_bytes.starts_with(&s_bytes)); + +expecting.append(&mut vec![1, b'b']); +assert_eq!(w_bytes, expecting); +``` + +### Externally Tagged Enumerations + +An enumeration is typically represented as a type that can take one of potentially many +different variants. In BCS, each variant is mapped to a variant index, a ULEB128-encoded 32-bit unsigned +integer, followed by serialized data if the type has an associated value. An +associated type can be any BCS supported type. The variant index is determined based on the +ordering of the variants in the canonical enum definition, where the first variant has an index +of `0`, the second an index of `1`, etc. + +```rust +#[derive(Serialize)] +enum E { + Variant0(u16), + Variant1(u8), + Variant2(String), +} + +let v0 = E::Variant0(8000); +let v1 = E::Variant1(255); +let v2 = E::Variant2("e".to_owned()); + +assert_eq!(to_bytes(&v0)?, vec![0, 0x40, 0x1F]); +assert_eq!(to_bytes(&v1)?, vec![1, 0xFF]); +assert_eq!(to_bytes(&v2)?, vec![2, 1, b'e']); +``` + +If you need to serialize a C-style enum, you should use a primitive integer type. + +### Maps (Key / Value Stores) + +Maps are represented as a variable-length, sorted sequence of `(Key, Value)` tuples. Keys must be +unique and the tuples sorted by increasing lexicographical order on the BCS bytes of each key. +The representation is otherwise similar to that of a variable-length sequence. In particular, +it is preceded by the number of tuples, encoded in ULEB128. + +```rust +let mut map = HashMap::new(); +map.insert(b'e', b'f'); +map.insert(b'a', b'b'); +map.insert(b'c', b'd'); + +let expecting = vec![(b'a', b'b'), (b'c', b'd'), (b'e', b'f')]; + +assert_eq!(to_bytes(&map)?, to_bytes(&expecting)?); +``` diff --git a/docs/04-web3/05-understanding-resource-and-bcs/02-bcs-in-js.md b/docs/04-web3/05-understanding-resource-and-bcs/02-bcs-in-js.md new file mode 100644 index 000000000..4f799846f --- /dev/null +++ b/docs/04-web3/05-understanding-resource-and-bcs/02-bcs-in-js.md @@ -0,0 +1,298 @@ +# BCS in JS SDK + +JS SDK Repo: [starcoin.js](https://github.com/starcoinorg/starcoin.js) + +## Type Inheritance Diagram + +| types | directory | +| ---------------- | --------------------------------------- | +| js(client level) | src/types/index.ts | +| starcoin_types | src/lib/runtime/starcoin_types/index.ts | +| onchain_events | src/lib/runtime/onchain_events/index.ts | +| bcs | src/lib/runtime/bcs/index.ts | +| serde | src/lib/runtime/serde/index.ts | + +## Examples + +### `Bytes` + +```js +import { bcs } from "@starcoin/starcoin"; + +const token = "0x00000000000000000000000000000001::STC::STC"; +console.log(token); +/* +0x00000000000000000000000000000001::STC::STC +*/ +const tokenUint8Array = new Uint8Array(Buffer.from(token)); +console.log(tokenUint8Array); +/* +Uint8Array(44) [ + 48, 120, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 49, 58, 58, 83, 84, 67, 58, + 58, 83, 84, 67 + ] +*/ +console.log(toHexString(tokenUint8Array)); +/* +0x307830303030303030303030303030303030303030303030303030303030303030313a3a5354433a3a535443 +*/ +const se = new BcsSerializer(); +se.serializeBytes(tokenUint8Array); +console.log(se.getBytes()); +/* +Uint8Array(45) [ + 44, 48, 120, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 49, 58, 58, 83, 84, 67, 58, 58, 83, 84, + 67 + ] +*/ +const tokenHex = toHexString(se.getBytes()); +console.log(tokenHex); +/* +0x2c307830303030303030303030303030303030303030303030303030303030303030313a3a5354433a3a535443 +*/ +``` + +the Uint8Array of `se.getBytes()` has one element `44` at first position more than the Uint8Array of `tokenUint8Array`(length=44), and the hex of `44` is `2c`. + +### `string` + +```js +import { bcs } from "@starcoin/starcoin"; +import { hexlify } from "@ethersproject/bytes"; + +const token = "0x00000000000000000000000000000001::STC::STC"; +console.log(token); +/* +0x00000000000000000000000000000001::STC::STC +*/ +const se = new BcsSerializer(); +se.serializeStr(token); +console.log(se.getBytes()); +/* +Uint8Array(45) [ + 44, 48, 120, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 49, 58, 58, 83, 84, 67, 58, 58, 83, 84, + 67 + ] +*/ +const tokenHex = hexlify(se.getBytes()); +console.log(tokenHex); +/* +0x2c307830303030303030303030303030303030303030303030303030303030303030313a3a5354433a3a535443 +*/ +``` + +In fact, `se.serializeStr` transfer parameter's type from `string` to `Uint8Array` and calls `se.serializeBytes` internally. + +### `U64` + +```js +import { bcs } from "@starcoin/starcoin"; +import { hexlify } from "@ethersproject/bytes"; + +const toChainId = 251; +console.log(toChainId); +/* +251 +*/ +const se = new BcsSerializer(); +se.serializeU64(toChainId); +console.log(se.getBytes()); +/* +Uint8Array(8) [ + 251, 0, 0, 0, + 0, 0, 0, 0 + ] +*/ +const toChainIdHex = hexlify(se.getBytes()); +console.log(toChainIdHex); +/* +0xfb00000000000000 +*/ +``` + +### `U128` + +```js +import { bcs } from "@starcoin/starcoin"; +import { hexlify } from "@ethersproject/bytes"; + +const toChainId = 251; +console.log(toChainId); +/* +251 +*/ +const se = new BcsSerializer(); +se.serializeU128(toChainId); +console.log(se.getBytes()); +/* +Uint8Array(16) [ + 251, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 + ] +*/ +const toChainIdHex = hexlify(se.getBytes()); +console.log(toChainIdHex); +/* +0xfb000000000000000000000000000000 +*/ +``` + +### `Bool` + +```js +import { bcs } from "@starcoin/starcoin"; +import { hexlify } from "@ethersproject/bytes"; + +const vote = true; +console.log(vote); +/* +true +*/ +const se = new BcsSerializer(); +se.serializeBool(vote); +console.log(se.getBytes()); +/* +Uint8Array(1) [ 1 ] +*/ +const voteHex = hexlify(se.getBytes()); +console.log(voteHex); +/* +0x01 +*/ +``` + +### `Vector` + +```js +import { starcoin_types, utils } from "@starcoin/starcoin"; +import { hexlify, isHexString } from "@ethersproject/bytes"; + +const value = "çå∞≠¢õß∂ƒ∫"; +const valueBytes = new Uint8Array(Buffer.from(value)); +console.log(valueBytes); +/* +Uint8Array(24) [ + 195, 167, 195, 165, 226, + 136, 158, 226, 137, 160, + 194, 162, 195, 181, 195, + 159, 226, 136, 130, 198, + 146, 226, 136, 171 + ] +*/ +const { length } = valueBytes; +const list: Seq = []; +for (let i = 0; i < length; i++) { + list.push(valueBytes[i]); +} +console.log(list); +/* +[ + 195, 167, 195, 165, 226, + 136, 158, 226, 137, 160, + 194, 162, 195, 181, 195, + 159, 226, 136, 130, 198, + 146, 226, 136, 171 + ] +*/ +const se = new BcsSerializer(); + +starcoin_types.Helpers.serializeVectorU8(list, se); +console.log(se.getBytes()); +/* +Uint8Array(25) [ + 24, 195, 167, 195, 165, 226, + 136, 158, 226, 137, 160, 194, + 162, 195, 181, 195, 159, 226, + 136, 130, 198, 146, 226, 136, + 171 + ] +*/ +const hex = hexlify(se.getBytes()); +console.log(hex); +/* +0x18c3a7c3a5e2889ee289a0c2a2c3b5c39fe28882c692e288ab +*/ +``` + +### `Vector>` + +Array of strings. + +```js +import { starcoin_types, utils } from "@starcoin/starcoin"; +import { hexlify, isHexString } from "@ethersproject/bytes"; + +const proofs = [ + "0x8e942cfc78768a015a18657d8da260ce16744136cea62a9dd17159a9f0dc5110", +]; +const se = new BcsSerializer(); +se.serializeLen(proofs.length); +proofs.forEach((proof) => { + se.serializeBytes(utls.hex.fromHexString(proof)); +}); +console.log(se.getBytes()); +/* +Uint8Array(34) [ + 1, 32, 142, 148, 44, 252, 120, 118, + 138, 1, 90, 24, 101, 125, 141, 162, + 96, 206, 22, 116, 65, 54, 206, 166, + 42, 157, 209, 113, 89, 169, 240, 220, + 81, 16 + ] +*/ +const hex = hexlify(se.getBytes()); +console.log(hex); +/* +0x01208e942cfc78768a015a18657d8da260ce16744136cea62a9dd17159a9f0dc5110 +*/ +``` + +we can split the hex string into 3 part: + +- `01`: the hex string of number 1, the length of array `proofs` +- `20`: the hex string of number 32, the length of string proofs[0] +- `8e942cfc78768a015a18657d8da260ce16744136cea62a9dd17159a9f0dc5110`: the hex string of proofs[0], in this case, is proofs[0] itself. + +### `Vector` + +Array of U128. + +```js +import { starcoin_types, utils } from "@starcoin/starcoin"; +import { hexlify, isHexString } from "@ethersproject/bytes"; + +const amountArray = [100000000]; +const se = new BcsSerializer(); +se.serializeLen(amountArray.length); +amountArray.forEach((amount) => { + se.serializeU128(amount); +}); +console.log(se.getBytes()); +/* +Uint8Array(17) [ + 1, 0, 225, 245, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 + ] +*/ +const hex = hexlify(se.getBytes()); +console.log(hex); +/* +0x0100e1f505000000000000000000000000 +*/ +``` + +we can split the hex string into 2 part: + +- `01`: the hex string of number 1, the length of array `amountArray` +- `00e1f505000000000000000000000000`: the hex string of amount 100000000, which type is U128 diff --git a/docs/04-web3/05-understanding-resource-and-bcs.md b/docs/04-web3/05-understanding-resource-and-bcs/README.md similarity index 100% rename from docs/04-web3/05-understanding-resource-and-bcs.md rename to docs/04-web3/05-understanding-resource-and-bcs/README.md diff --git a/docs/04-web3/05-understanding-resource-and-bcs/_category_.yaml b/docs/04-web3/05-understanding-resource-and-bcs/_category_.yaml new file mode 100644 index 000000000..a005eef7d --- /dev/null +++ b/docs/04-web3/05-understanding-resource-and-bcs/_category_.yaml @@ -0,0 +1 @@ +label: "Understanding resource and BCS" diff --git a/docs/04-web3/README.md b/docs/04-web3/README.md index 069bd6d96..7e789a96b 100644 --- a/docs/04-web3/README.md +++ b/docs/04-web3/README.md @@ -1,14 +1,189 @@ -# How to build DApp on Starcoin +# How to Dapp +We’ll show you how to build your first decentralized application, or Dapps in this document. We’ll also guide you through Dapp development process instructions. +## Dapp Development Process Instructions -:::note +Any Dapp on public blockchain from frontend to smart contracts, has mian steps as we show in figure 1. -TODO +![dapp_1](../../static/img/dapp/dapp_1.png) -This document is a overview guide, is a reorg of Cookbook's move and web3 charpters. +The decentralized network we use in this document is Startcoin. Key components that have been used in figure 1: -Migrate [https://starcoin.org/en/developer/how_to_dapp/how_to_dapp/](https://starcoin.org/en/developer/how_to_dapp/how_to_dapp/) document from starcoin.org and replace the contents with links to Cookbook's chapters. +1. Frontend user interface -Chinese version: [https://starcoin.org/zh/developer/how_to_dapp/how_to_dapp/](https://starcoin.org/zh/developer/how_to_dapp/how_to_dapp/) -::: +2. SDK tools are used to interact with the Starcoin blockchain + +3. Browser extension Starmask is an alternative way to interact with the Starcoin blockchain + +4. Nodes on Starcoin blockchain + +5. Smart contracts on Starcoin blockchain + +Some programming tools we used in key components we mentioned in figure1 are shown in figure2: + +![dapp_2](../../static/img/dapp/dapp_2.png) + +First, We will explain some concepts that developers may concern, Then we will cover more details about each programming tool. + +1. Practical Dapp: You will get intuitive knowledge of what a decentralized application is. For a front-end developer, this will be a good choice to explore Dapp. +2. StarMask API: In some Dapp development scenarios, such as digital signatures, the Starmask API will be called to complete interactions with users and blockchain. StarMask is a software cryptocurrency wallet used to interact with the Starcoin blockchain. +3. SDK is one way to interact with Starcoin blockchain. Developers can choose one SDK which suits your needs. SDKs for Starcoin are: + - JS SDK + - Java SDK + - Python SDK + - Go SDK + - Dart SDK +4. RPC API and Starcoin Nodes : You can access all services and interfaces of Nodes via RPC interface, it’s the fastest way to interact with Starcoin for developers or SDK. +5. Smart Contracts: Move is used to implement and deploy smart contracts on Starcoin, all users on Starcoin can reuse these smart contracts. + +Next, we’ll explore further about each concept we have learned in figure 2. If there is a certain part that you're interested in, you can skip to it. + +## Practical Dapp + +It’s an easy decentralized application, it’s designed for you to get started. You will get a quick feel of what Dapp is and how it interacts with Starcoin. For a developer, you can build your own Dapp or check the code structure through viewing its source code. + +- Test Dapp Link: https://starmask-test-dapp.starcoin.org/Github +- Github Link: https://github.com/starcoinorg/starmask-test-dapp + +## StarMask + +Starmask is not only used to manage your digital assets, but another way to interact with Starcoin blockchain. Here is one example, users create digital signature for each transaction in Dapp, then submit this transaction to Txpool which in remote nodes. + +- Installation Link: https://github.com/starcoinorg/starmask-extension/blob/main/docs/how-to-install.md +- User Guides Link:https://github.com/starcoinorg/starmask-extension/blob/main/docs/en/how-to-use.md + +## SDK + +Another way to interact with Starcoin is SDK. Starcoin now supports multi-language SDKs. SDK provides a programming interaction with nodes on Starcoin. + +1. JS SDK + +- Developer Documentation Link: https://starcoin.org/zh/developer/sdk/javascript/ +- Source Code Link: https://github.com/starcoinorg/starcoin.js + +2. Java SDK + +- Developer Documentation Link: https://github.com/starcoinorg/starcoin-java#readme +- Source Code Link: https://github.com/starcoinorg/starcoin-java + +3. Python SDK + +- Developer Documentation Link: https://starcoin-sdk-python.readthedocs.io +- Source Code Link: https://github.com/starcoinorg/starcoin-sdk-python + +4. Go SDK + +- Developer Documentation Link: https://github.com/starcoinorg/starcoin-go/blob/main/README.md +- Source Code Link: https://github.com/starcoinorg/starcoin-go + +5. Dart SDK + +- Source Code Link: https://github.com/starcoinorg/starcoin.dart + +## Starcoin Nodes and RPC API + +You can interact with Starcoin nodes using StarMask or SDK on Starcoin blockchain. The stability of nodes is essential to add Dapp transactions on Starcoin blockchain. Starcoin nodes include necessary APIs which you’ll use on Starcoin blockchain. + +1. Networks + Starcoin has appropriate networks to satisfy the needs in various stages of development. We have five networks: Dev, Test, Halley, Proxima,Barnard,Main. + +- Dev: It’s used for local Dapp development +- Test: It’s used for unit and integrated test +- Halley: Always use the latest version of Stdlib, Genesis Block will be reset immediately and data will be cleaned up whenever there is a update for Stdlib +- Proxima: It’s used to run tests before Dapp launch, data will be cleaned up periodically +- Barnard: It’s also used to run tests before Dapp launch, but it’s different from Proxima, we do not remove data, it’s your responsibility to ensure smart contracts are still compatible. +- Main: Main Starcoin network + +2. Nodes Installation Methods + To install on Windows,Mac, and Linux, download pre-compiled binary from [downloads](https://github.com/starcoinorg/starcoin/releases) pages. + +- Build Starcoin with source code, [Guides](https://starcoin.org/zh/developer/setup/build/) +- Run inside Docker container, [Guides](https://starcoin.org/zh/developer/setup/run_by_docker/) + +3. Run Starcoin + The approach is a little bit different due to different node installation methods. + +- Run inside Docker container, [Guides](https://starcoin.org/zh/developer/setup/run_by_docker/) +- Pre-compiled binary, [Guides](https://starcoin.org/zh/developer/setup/runnetwork/) + You need to change the `-n` parameter to use different networks. + +4. Console + Starcoin console is a command line interface for running Starcoin nodes. You can view nodes’ state using a simple command.[Guides](https://starcoin.org/zh/developer/cli/console/) +5. Command Line Document + Starcoin has lots of commands, some useful commands are: + +- account: account-related command +- chain: chain-related command +- node: node-related command +- state: state-related command + Check [here](https://starcoin.org/zh/developer/cli/) to view more commands. + +6. RPC Protocol + You also can connect to Starcoin nodes via the RPC interface. It’s a great programming way to access nodes on a chain, SDK is one example. Check [RPC protocol document](https://starcoin.org/zh/developer/rpc/rpc_document/) to get more information. +7. More about Starcoin + If you are a developer and want to get more details about Starcoin. We recommend you check these links: + +- Key concept: https://starcoin.org/zh/developer/key_concepts/ +- SIPs: https://starcoin.org/zh/developer/sips/ +- Source code: https://github.com/starcoinorg/starcoin + +## Move + +Currently, Starcoin is the first one public blockchain that can run Move smart contracts. + +1. [Move Book](https://move-book.com/).Check [Move introduction](https://developers.diem.com/docs/move/move-start-here/move-introduction) to learn more about Move. +2. IDE + +- Starcoin IDE: https://marketplace.visualstudio.com/items?itemName=starcoinorg.starcoin-ide +- Move-Package-Manager: It’s a lightweight tool to test, deploy Move smart contracts.[Download](https://github.com/starcoinorg/guide-to-move-package-manager) + +3. Test + You can test your Move smart contracts with different test types. + +- Unit test: [Guides](https://github.com/diem/diem/blob/main/language/changes/4-unit-testing.md) +- Functional Test: To run a functional test, make sure to initialize Starcoin first. +- [Guides](https://starcoin.org/zh/developer/functional_test/functional_test/) + - [Examples](https://github.com/starcoinorg/starcoin/tree/master/vm/functional-tests/tests/testsuite) + +4. Compile and Deploy + There are multiple ways to compile and deploy Move smart contracts on Starcoin blockchain. Make sure that you have chosen appropriate networks! + +- Console: [Guides](https://starcoin.org/en/developer/tutorials/deploy_move_contract/) +- Starmask-test-dapp: Contract blob hex functionality. [Guides](https://starmask-test-dapp.starcoin.org/) +- Move-Package-Manager: [Guides](https://github.com/starcoinorg/guide-to-move-package-manager) + +5. More [example](https://starcoin.org/zh/developer/move/example/) about Move + +## Stdlib and Protocols + +Starcoin has been created using Move language, it also has Stdlib features. Please check our [source code](https://github.com/starcoinorg/starcoin/tree/master/vm/stdlib/modules).Starcoin has defined variety protocols in Stdlib, some protocols will be shown in figure 3. +![](../../static/img/dapp/pb.jpg) + +1. DAO protocolDAO + protocol is a basic protocol in Stdlib, you can govern blockchain well via DAO protocol. Here is a [governable contract upgrade](https://starcoin.org/zh/developer/blog/starcoin_stdlib_upgrade) example. +2. NFT Protocol + +- [NFT protocol introduction](https://starcoin.org/zh/developer/protocols/starcoin_nft/) +- [SIP22](https://github.com/starcoinorg/sips/blob/master/sip-22/index.zh.md) +- Source Code + - https://github.com/starcoinorg/starcoin-framework/tree/main/sources/NFT.move + - https://github.com/starcoinorg/starcoin-framework/tree/main/sources/MerkleNFT.move + 3: Stdlib [Guides](https://starcoin.org/zh/developer/stdlib/stdlib/) + +## Other Develop Tools + +1. Official website + Visit [our website](https://starcoin.org) to get more information, such as white paper, developer documents and tools, toolchain,latest news about Starcoin. +2. Faucet + You will need STC(native cryptocurrency of this platform) when you run tests, such as paying gas fees. As a developer, you can apply for STC in Barnad network. + +- Barnad: https://faucet.starcoin.org/barnard + +3. Explorer + Explorer is a complementary tool to chain. We suggest that you use [stcscan](https://stcscan.io/) as blockchain explorer. + +4. Voting DappVoting Dapp is another developer tool,it’s used to manage Starcoin blockchain. A developer can create a proposal, we will take a public,equal and formal vote in our community on the Voting Dapp. Your proposal will be approved with more votes in favour. + +5. Starcoin logos and icons + Download Link: https://starcoin.org/downloads/logo.zip⁣ diff --git a/docs/100-miscellaneous/99-contributing.md b/docs/100-miscellaneous/99-contributing.md index 52ecaa80c..8639153e8 100644 --- a/docs/100-miscellaneous/99-contributing.md +++ b/docs/100-miscellaneous/99-contributing.md @@ -1,37 +1,97 @@ # Contribution Guide -### Installation +## How to Contribute +### 1. Clone the Cookbook + +Fork the Starcoin Cookbook repo to make a copy of this cookbook in your account. Then **clone** that repo to your development environment and navigate to the local repo. + +```bash +git clone git@github.com:your-username/starcoin-cookbook.git +cd starcoin-cookbook ``` + +### 2. Installing Packages + +Node.js and yarn are required to build this cookbook, read the [yarn installation page](https://yarnpkg.com/getting-started/install) for details. + +Execute the following command in the project root to install the packages and dependencies. + +```bash $ yarn ``` -### Local Development +### 3. Running the Development Server -``` +```bash $ yarn start ``` This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. -### Build +English locale is used by default. Start your localized site in dev mode, using the locale of your choice: +```bash +$ yarn start --locale zh ``` + +:::tip Tip +Available locales defined in `docusaurus.config.js`. +::: + +### 4. Build + +This command generates static content into the `/build` directory and can be served using any static contents hosting service. + +```bash $ yarn build ``` -This command generates static content into the `build` directory and can be served using any static contents hosting service. +The default BaseUrl is `/starcoin-cookbook`, if you want to change it, you can specify it via environment variable before build. -Then run serve to serving build directory at http://localhost:3000/starcoin-cookbook/ ``` +$ export BASE_URL='/' +``` + +(2) Run the following command, which will start a web service locally. + +Then run serve to serving build directory at `http://localhost:3000/starcoin-cookbook/`. + + +```bash $ yarn serve ``` +If you specify the BASE_URL environment variable as `/`, the address will be: `http://localhost:3000/`. -:::note +## Guidelines + +### File Structure Guidelines + +1. A numerical prefix is required in the directory name and file, e.g., `01-build.md`, which indicates the order of the document in the sidebar. +2. `kebab-case` naming convention is used in directory and file names. +3. The `README.md` in each directory is the front page of the directory. +4. The `_category_.yaml` is the configuration file for a directory, in which the `label` property is the title of this directory showing in the sidebar. +5. The default documents are in English, translations can be found in `i18n//docusaurus-plugin-content-docs/current`. Translations should use the same file name as the English docs. + +### Document Style Guidelines -This document needs to be improved. +:::note -* Translate from Chinese document +The Chinese version is following additional document conventions, read the Chinese document style for details. ::: + +## FAQ + +1. How to translate a section (directory)? + + Adding Chinese translation for example. Run the following command after adding a new section (directory): + + ```bash + $ yarn write-translations --locale zh + ``` + + Changes are made to `i18n/zh/docusaurus-plugin-content-docs/current.json`, and new directory name is added. Editing the file to add translation. + + Change `zh` to the corresponding language code for other languages. diff --git a/docs/98-reference/01-cli/03-starcoin-db-exporter.md b/docs/98-reference/01-cli/03-starcoin-db-exporter.md new file mode 100644 index 000000000..f690bf883 --- /dev/null +++ b/docs/98-reference/01-cli/03-starcoin-db-exporter.md @@ -0,0 +1 @@ +# starcoin_db_exporter diff --git a/docusaurus.config.js b/docusaurus.config.js index 856f0ef3a..2344adfe7 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -4,12 +4,14 @@ const lightCodeTheme = require('prism-react-renderer/themes/github'); const darkCodeTheme = require('prism-react-renderer/themes/dracula'); +const baseUrl = process.env.BASE_URL || '/starcoin-cookbook/'; + /** @type {import('@docusaurus/types').Config} */ const config = { title: 'Starcoin Cookbook', tagline: 'How to developing on starcoin', url: 'https://starcoinorg.github.io', - baseUrl: '/starcoin-cookbook/', + baseUrl: baseUrl, onBrokenLinks: 'throw', onBrokenMarkdownLinks: 'warn', favicon: '/img/favicon.ico', diff --git a/examples/my-token/README.md b/examples/my-token/README.md index 087a03283..5874c9d21 100644 --- a/examples/my-token/README.md +++ b/examples/my-token/README.md @@ -1,4 +1,4 @@ # Move contract examples -1. [MyCounter](./my_counter) a simple Move module example. -2. [MyToken](./my_token) a simple User defined Coin example. +1. [MyCounter](../my-counter) a simple Move module example. +2. [MyToken](../my-token) a simple User defined Coin example. diff --git a/i18n/zh/docusaurus-plugin-content-docs/current.json b/i18n/zh/docusaurus-plugin-content-docs/current.json index 73027d950..14161ec3d 100644 --- a/i18n/zh/docusaurus-plugin-content-docs/current.json +++ b/i18n/zh/docusaurus-plugin-content-docs/current.json @@ -4,7 +4,7 @@ "description": "The label for version current" }, "sidebar.tutorialSidebar.category.Getting Started": { - "message": "入门", + "message": "新手入门", "description": "The label for category Getting Started in sidebar tutorialSidebar" }, "sidebar.tutorialSidebar.category.Download and Install": { @@ -23,60 +23,64 @@ "message": "Move 和智能合约开发", "description": "The label for category Move and SmartContract Development in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.Advance Move Development": { - "message": "Advance Move Development", - "description": "The label for category Advance Move Development in sidebar tutorialSidebar" - }, - "sidebar.tutorialSidebar.category.Move Spec Language and Move Prover": { - "message": "Move Spec Language and Move Prover", - "description": "The label for category Move Spec Language and Move Prover in sidebar tutorialSidebar" - }, - "sidebar.tutorialSidebar.category.Web3 and DApp Development": { - "message": "Web3 and DApp Development", - "description": "The label for category Web3 and DApp Development in sidebar tutorialSidebar" + "sidebar.tutorialSidebar.category.Move Language": { + "message": "Move 语言", + "description": "The label for category Move Language in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.Concepts": { - "message": "Concepts", - "description": "The label for category Concepts in sidebar tutorialSidebar" + "sidebar.tutorialSidebar.category.Starcoin Move Framework": { + "message": "Starcoin Move Framework", + "description": "The label for category Starcoin Move Framework in sidebar tutorialSidebar" }, "sidebar.tutorialSidebar.category.How to test Move Module": { - "message": "How to test Move Module", + "message": "如何测试 Move Module", "description": "The label for category How to test Move Module in sidebar tutorialSidebar" }, "sidebar.tutorialSidebar.category.More Move Examples": { - "message": "More Move Examples", + "message": "更多 Move 例子", "description": "The label for category More Move Examples in sidebar tutorialSidebar" }, + "sidebar.tutorialSidebar.category.Advance Move Development": { + "message": "Move 高级开发", + "description": "The label for category Advance Move Development in sidebar tutorialSidebar" + }, "sidebar.tutorialSidebar.category.Move Specification Language and Move Prover": { "message": "Move 规范语言和 Move Prover", "description": "The label for category Move Specification Language and Move Prover in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.Miscellaneous": { - "message": "杂项", - "description": "The label for category Miscellaneous in sidebar tutorialSidebar" + "sidebar.tutorialSidebar.category.Web3 and DApp Development": { + "message": "Web3 和 DApp 开发", + "description": "The label for category Web3 and DApp Development in sidebar tutorialSidebar" }, "sidebar.tutorialSidebar.category.Reference": { - "message": "Reference", + "message": "参考", "description": "The label for category Reference in sidebar tutorialSidebar" }, + "sidebar.tutorialSidebar.category.CLI": { + "message": "命令行界面(CLI)", + "description": "The label for category CLI in sidebar tutorialSidebar" + }, "sidebar.tutorialSidebar.category.StarcoinFramework": { "message": "StarcoinFramework", "description": "The label for category StarcoinFramework in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.CLI": { - "message": "CLI", - "description": "The label for category CLI in sidebar tutorialSidebar" + "sidebar.tutorialSidebar.category.Concepts": { + "message": "概念", + "description": "The label for category Concepts in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.Move Language": { - "message": "Move 语言", - "description": "The label for category Move Language in sidebar tutorialSidebar" + "sidebar.tutorialSidebar.category.Miscellaneous": { + "message": "杂项", + "description": "The label for category Miscellaneous in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.Starcoin Move Framework": { - "message": "Starcoin Move Framework", - "description": "The label for category Starcoin Move Framework in sidebar tutorialSidebar" + "sidebar.tutorialSidebar.category.Understanding resource and BCS": { + "message": "理解 resource 和 BCS", + "description": "The label for category Understanding resource and BCS in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.Mining": { + "message": "挖矿", + "description": "The label for category Mining in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.mining": { - "message": "mining", - "description": "The label for category mining in sidebar tutorialSidebar" + "sidebar.tutorialSidebar.category.StarMask Docs": { + "message": "StarMask Docs", + "description": "The label for category StarMask Docs in sidebar tutorialSidebar" } } diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/01-intro.md b/i18n/zh/docusaurus-plugin-content-docs/current/01-intro.md new file mode 100644 index 000000000..6d035a0a5 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/current/01-intro.md @@ -0,0 +1,11 @@ +# Starcoin CookBook 介绍 + +Starcoin Cookbook 的目标是提供一个全栈的学习资料,方便开发者学习如何在 Starcoin 上进行开发。它主要包含三部分内容: + +1. 关于 Starcoin 区块链本身的知识。了解如何运行节点,理解区块,交易以及状态。 +2. 关于 Move 智能合约编程语言以及 StarcoinFramework 的知识。学习如何编写,测试以及部署 Move 智能合约。了解 StarcoinFramework 提供的能力。 +3. 关于 Web3 相关的知识。学习 DApp 怎样和智能合约交互,怎样调用 Starcoin 链的 RPC API 等。 + +这些学习材料主要和 Starcoin 相关,但也可以作为区块链和智能合约的通用学习材料,因为主要的智能合约区块链在技术原理上是相通的。 + +本文档还在完善中,欢迎一起改进,参看[贡献指南](./miscellaneous/contributing)。 diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/02-setup/02-starcoin-console.md b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/02-setup/02-starcoin-console.md index fc3262805..5b1bdad18 100644 --- a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/02-setup/02-starcoin-console.md +++ b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/02-setup/02-starcoin-console.md @@ -81,7 +81,7 @@ starcoin -c starcoin.ipc console 注意:在 Windows 中,IPC 文件所在路径不同。 ```cmd -starcoin.exe -c \\.\\pipe\starcoin\dev\starcoin.ipc console +starcoin.exe -c \\.\pipe\starcoin\dev\starcoin.ipc console ``` ### 通过 WebSocket diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/02-setup/05-fast-sync-data.md b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/02-setup/05-fast-sync-data.md new file mode 100644 index 000000000..31d6e9c95 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/02-setup/05-fast-sync-data.md @@ -0,0 +1,134 @@ +# 如何更快地同步块和状态。 + +通常,启动一个新的 `main` 网络节点,就会自动同步区块数据,而这个过程是非常漫长的。 + +接下来将介绍如何通过 Starcoin 工具链提供的数据导出工具来加快新节点同步区块数据的速度,以及如何同步链的状态。 + +## 下载和安装 + +根据你所使用的系统下载相应预编译的 [Starcoin 工具链](https://github.com/starcoinorg/starcoin/releases),如果你已经完成了 `starcoin` 的[下载和安装](https://starcoinorg.github.io/starcoin-cookbook/docs/getting-started/install/),那么可以跳过这一步。 + +```shell +# 以 Ubuntu 为例 +wget https://github.com/starcoinorg/starcoin/releases/download/v1.11.10/starcoin-ubuntu-latest.zip + +# 解压 +unzip starcoin-ubuntu-latest.zip + +# 进入解压目录,检查 +cd starcoin-artifacts/ +./starcoin_db_exporter -h +``` + +提示:如果经常使用,推荐添加到 `PATH` 环境变量中。 + +## 同步区块数据 + +如果启动一个新的全节点,通常是下载其他节点的主网区块数据到新节点,并以下载的区块数据启动节点。 +下载(导出)的区块数据存储在 CSV 文件上,方便数据交换和存储。 + +### 导出块 + +`export-block-range` 子命令用于导出区块数据。 + +```shell +# 创建一个目录用于存放从节点导出的区块数据 +mkdir ~/bak + +# 导出区块 +./starcoin_db_exporter export-block-range -i ~/.starcoin/main/ -s 1 -e 10000 -n main -o ~/bak +``` + +- `-i` 指定节点的数据目录。 +- `-s` 指定区块数据的起始高度。 +- `-e` 指定区块数据的结束高度。 +- `-n` 指定网络。 +- `-o` 指定存放导出数据的目录。 + +导出结束后,在 `~/bak` 目录下可以看到导出文件为 `~/bak/block_1_10000.csv`。 + + +### 导入块 + +`apply-block` 子命令用于导入区块数据。 + +```shell +./starcoin_db_exporter apply-block -i block_1_10000.csv -n main -o ~/.starcoin/main/ +``` + +- `-i` 指定导入区块数据的 CSV 文件路径。 +- `-n` 指定网络。 +- `-o` 指定节点的数据目录。 + +### 使用脚本导入区块数据(推荐) + +`starcoin` 的仓库中提供了 [`import_block.sh`](https://github.com/starcoinorg/starcoin/blob/master/scripts/import_block.sh) 脚本,预编译版本也打包有相应的脚本。 +使用脚本导入区块数据会更加便利,而不必手动导出和导入。 + +```shell +./import_block.sh main ~/.starcoin/main +``` + +这个脚本接收两个参数,参数1指定网络名称,例如 `main`, `barnard`, `proxima` 或 `halley`,参数2指定数据存储的目录,例如 `~/.starcoin/main` 或任意自定义的路径。 +这个脚本会跳过已经有的区块,每获取一个区块都会自动更新进度,中断脚本后再执行会接着原来的高度继续导入。 + +执行脚本后,就会自动下载主网区块数据到 `~/.starcoin/main` 目录并导入。 +等待下载并导入完成,就可以使用这些区块数据运行新的节点了。 + +注意:使用这个脚本必须保证 `starcoin_db_exporter` 和 `import_block.sh` 在同一路径下。 + +## 同步链的状态 + +`starcoin_db_exporter` 命令提供了离线导出导入 `main, barnard, proxima, halley` 网络的快照功能,便于快速的搭建区块链网络。 + +### 导出快照 + +`export-snapshot` 子命令用于导出快照。 + +**正常导出:** + +```shell +# 创建一个目录用于存放从节点导出的快照数据 +mkdir ~/snapshot + +# 导出快照 +./starcoin_db_exporter export-snapshot -i ~/.starcoin/main -n main -o ~/snapshot +``` + +- `-i` 指定节点的数据目录。 +- `-n` 指定网络。 +- `-o` 指定存放导出快照的目录。 + +**增量导出:** + +```shell +./starcoin_db_exporter export-snapshot -i ~/.starcoin/main -n main -o ~/snapshot -t true +``` + +通过 `-t` 选项指定是否使用增量导出,`true` 启用,`false` 禁用。 +如果要使用增量导出,需要保证 `~/snapshot` 目录下有旧的快照,比如原来 `~/snapshot` 目录下的快照高度为 `1-400w`,现在需要导 `1-500w` 高度的快照。 +如果使用了增量导出,则先会把后面 `400w-500w` 高度的快照导出,再与原来的快照合并,以此来节省时间。 + +### 导入快照 + +`apply-snapshot` 子命令用于导入快照。 + +```shell +./starcoin_db_exporter apply-snapshot -i ~/snapshot -n main -o ~/.starcoin/main +``` + +- `-i` 指定存放快照的目录。 +- `-n` 指定网络。 +- `-o` 指定节点的数据目录。 + +### 使用脚本导入快照 + +`starcoin` 的仓库中提供了 [`import_snapshot.sh`](https://github.com/starcoinorg/starcoin/blob/master/scripts/import_snapshot.sh) 脚本,预编译版本也打包有相应的脚本。 + +```shell +./import_snapshot.sh main ~/snapshot/ ~/.starcoin/main +``` + +这个脚本需要传递3个参数,参数1指定网路的名称,参数2指定快照的存储路径,参数3指定节点的数据目录。 + +注意:使用这个脚本必须保证 `starcoin_db_exporter` 和 `import_snapshot.sh` 在同一路径下。 diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/02-setup/06-main-network.md b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/02-setup/06-main-network.md index 3e8bc78ca..6ac04f16d 100644 --- a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/02-setup/06-main-network.md +++ b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/02-setup/06-main-network.md @@ -1,18 +1,214 @@ -# 如何参与 main 网络 +# 如何参与主网络 -TODO -1. Introduce the main network. -2. Run node and join test network. +## 简介 -## 加入 main 网络 +2021年5月18日,Starcoin 举行全球发布会,在聚光灯的照耀下,宣布启动主网。 +这是一个里程碑时刻,意味着 Starcoin 这艘船舶,在区块链的蓝海里,正式扬帆起航。 + +## Windows 加入主网络 + +**1. 启动** + +```shell +starcoin.exe --net main ^ + --disable-metrics true ^ + --node-name starcoin-main ^ + --data-dir D:\starcoin\data ^ + --logger-disable-file true ^ + --stratum-address 0.0.0.0 --stratum-port 9880 +``` + +- `--net`:指定网络。 +- `--disable-metrics`:是否要禁用指标监控服务,`true` 禁用,`false` 不禁用。 +- `--node-name`:节点名称,仅用于显示,可根据自己的喜好取个有特色的名字。若不指定,则随机生成。 +- `--data-dir`:数据存放目录,建议选择一个容易查找的路径。 +- `--logger-disable-file`:是否要禁用文件日志采集器,`true` 禁用,`false` 不禁用。 +- `--stratum-address`:指定矿池地址,默认为 `0.0.0.0`。 +- `--stratum-port`:指定矿池端口号,默认为 `9880`。 + +在 Windows 的 cmd 窗口输入上述命令后,回车,节点就开始同步区块数据了,等待同步完成即可。 + +**2. 查看 IPC 文件路径** + +用鼠标拖拽侧边栏到顶部,可以看到输出中显示有 IPC 文件的存放路径: + +```shell +2022-05-23T16:40:06.642907500+08:00 INFO - Ipc file path: "\\\\.\\pipe\\starcoin\\main\\starcoin.ipc + +# IPC 文件路径为: +\\\\.\\pipe\\starcoin\\main\\starcoin.ipc +``` + +**3. 查看节点同步进度** + +如果想知道节点同步数据的进度,此时可以再打开一个新的 cmd 窗口,用 IPC 文件来连接到 Starcoin 控制台: + +```shell +starcoin.exe -c \\.\pipe\starcoin\main\starcoin.ipc console +``` + +在 Starcoin 控制台中输入: + +```shell +node sync status +``` + +在输出的 JSON 数据中可以找到一些关键信息,`chain_status.head.number` 和 `state.Synchronizing.target.number` 相等时,同步才完成。 + +**4. 查看默认账号** + +每个新启动的节点,都初始化有一个默认账户,密码为空。 + +```shell +# 查看默认账户,找到账户地址 +account default +``` + +**5. 导出默认账户的私钥** -你可以使用下面的命令加入 main 网络: ```shell -starcoin -n main +account export
``` -默认的网络就是是 main,所以也可以直接运行: +注意:请妥善保管好私钥! + +**6. 退出控制台** + +```shell +exit +``` + +## Linux 加入主网络(推荐) + +**1. 启动** ```shell starcoin -``` \ No newline at end of file +``` + +`starcoin` 命令,默认使用 `main` 网络,默认禁用挖矿客户端,默认不监听矿池,数据目录默认为主目录下的 `.starcoin/main`。 + +```shell +# 数据目录,ubuntu 是演示的用户名,请根据你的实际情况变更 +2022-05-24T10:07:29.069207121+08:00 INFO - Final data-dir is : "/home/ubuntu/.starcoin/main" + +# IPC 文件路径 +2022-05-24T10:07:29.061062410+08:00 INFO - Ipc file path: "/home/ubuntu/.starcoin/main/starcoin.ipc" +``` + +**2. 查看节点同步进度** + +打开一个新的命令行窗口,输入: + +```shell +starcoin -c ~/.starcoin/main/starcoin.ipc console +``` + +在 Starcoin 控制台中输入: + +```shell +node sync status +``` + +在输出的 JSON 数据中可以找到一些关键信息,`chain_status.head.number` 和 `state.Synchronizing.target.number` 相等时,同步才完成。 + +**3. 查看默认账号** + +每个新启动的节点,都初始化有一个默认账户,密码为空。 + +```shell +# 查看默认账户,找到账户地址 +account default +``` + +**4. 导出默认账户的私钥** + +```shell +account export
+``` + +注意:请妥善保管好私钥! + +**5. 退出控制台** + +```shell +exit +``` + +## Docker 加入主网络 + +**1. 拉取 [Docker 镜像](https://hub.docker.com/r/starcoin/starcoin/)** + +```shell +docker pull starcoin/starcoin:latest +``` + +如果你想使用指定版本,可以更改拉取的标签,比如 `v1.11.9`: + +```shell +docker pull starcoin/starcoin:v1.11.9 +``` + +**2. 启动** + +`starcoin` 的二进制文件在镜像中的 `/starcoin` 目录下。 + +```shell +docker run --name starcoin -v ~/.starcoin/:/root/.starcoin/ --network host starcoin/starcoin:latest /starcoin/starcoin +``` + +- `--name`:指定容器名称。 +- `-v`:绑定挂载卷,用于持久化 Docker 中的数据。 +- `--network`:让 Docker 容器的网络附属在主机上,两者互通。 + +**3. 通过 Docker 连接到 Starcoin 控制台** + +打开一个新的命令行窗口,输入: + +```shell +docker run --rm -it -v ~/.starcoin/:/root/.starcoin/ starcoin/starcoin:latest /starcoin/starcoin -c /root/.starcoin/main/starcoin.ipc console +``` + +- `--rm`:退出 Starcoin 控制台时,自动移除容器。 +- `-it`:交互式进入容器,分配虚拟终端。 + +如果不想启用新的容器,可以直接接入启动 Starcoin 的容器: + +```shell +docker container exec -it starcoin bash + +/starcoin/starcoin -c /root/.starcoin/main/starcoin.ipc console +``` + +**4. 查看节点同步进度** + +在 Starcoin 控制台中输入: + +```shell +node sync status +``` + +在输出的 JSON 数据中可以找到一些关键信息,`chain_status.head.number` 和 `state.Synchronizing.target.number` 相等时,同步才完成。 + +**5. 查看默认账号** + +每个新启动的节点,都初始化有一个默认账户,密码为空。 + +```shell +# 查看默认账户,找到账户地址 +account default +``` + +**6. 导出默认账户的私钥** + +```shell +account export
+``` + +注意:请妥善保管好私钥! + +**7. 退出控制台** + +```shell +exit +``` diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/02-setup/07-private-network.md b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/02-setup/07-private-network.md new file mode 100644 index 000000000..66b60b36c --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/02-setup/07-private-network.md @@ -0,0 +1,79 @@ +# 如何创建自定义的 Starcoin 网络 + +`starcoin` 支持运行一个用户自定义区块链网络,方便用户搭建私有链进行测试或者二次开发。 + +## 简介 + +`starcoin` 内置有六种网络,分别是:`test, dev, halley, proxima, barnard, main`。 + +`test` 和 `dev` 用于本地开发,`halley`、`proxima` 和 `barnard` 是测试网络,`main` 网络是正式网络。 + +接下来将介绍如何搭建 Starcoin 私有网络。 + +## 初始化自定义网络 + +`starcoin_generator` 命令用于生成创世(genesis)配置文件和创世区块。 + +### 生成创世配置文件 + +```shell +starcoin_generator -n : --genesis-config genesis_config +``` + +- `genesis_config` 子命令用于生成创世配置文件。 +- 初始化和运行自定义区块链网络,都需要使用 `-n, --net` 选项指定链的名称和链的 id,参数由 `:` 拼接而成。 + - `CHAIN_NAME` 表示链的名字,这个名字会用作数据目录的名称。 + - `CHAIN_ID` 表示链的 id,类型为 `u8`。 +- `--genesis_config` 指定生成创世块所使用的配置文件,参数可以使用内置的区块链网络名称,表示复用该网络配置,比如 `halley`;也可以是配置文件的路径。 + +例如要生成一个名为 `my_chain`,id 为 `123` 的自定义网络: + +```shell +starcoin_generator -n my_chain:123 --genesis-config halley genesis_config +``` + +该命令将内置的 `halley` 网络配置作为模板,生成一个名为 `genesis_config.json` 配置文件在 `~/.starcoin/my_chain` 目录下。 +可以用编辑器修改 `~/.starcoin/my_chain/genesis_config.json` 文件中的参数。 + +注:如果不想配置文件生成在默认的 `~/.starcoin/` 目录下,也可以通过 `-d` 选项指定目录。 + +### 生成创世区块 + +`genesis` 子命令用于生成创世区块。 + +```shell +starcoin_generator -n my_chain:123 genesis +``` + +该命令根据前面生成的创世配置文件来生成创世区块。 + +上面例子中的创世配置文件是 `~/.starcoin/my_chain/genesis_config.json`。 +当然,也可以将 `genesis_config.json` 文件放置在其他位置,然后通过绝对路径指定,比如: + +```shell +starcoin_generator -n my_chain:123 --genesis-config /data/conf/my_chain/genesis_config.json genesis +``` + +## 运行自定义网络节点 + +使用如下命令即可启动自定义网络节点: + +```shell +starcoin -n my_chain:123 console +``` + +## 组建自定义网络集群 + +在启动了一个节点后,你可以在日志或标准输出中找到节点的地址,它可能如下所示: + +```shell +2022-05-25T11:27:10.201604911+00:00 INFO - Self address is: /ip4/127.0.0.1/tcp/9840/p2p/12D3KooWR1p3uxnWZ2rv5mZ3Sw2i8z3gabxNEHjgkPDC2pkk19Vp +``` + +通过 `--seed` 指定第一个节点作为种子节点,然后再启动其他节点,即可组成一个网络。 + +注意:多个节点必须使用同一套创世配置文件来生成创世区块,才能组成一个网络。 + +```shell +starcoin -n my_chain:123 --seed /ip4/127.0.0.1/tcp/9840/p2p/12D3KooWR1p3uxnWZ2rv5mZ3Sw2i8z3gabxNEHjgkPDC2pkk19Vp console +``` diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/03-accounts/1.account-manage.md b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/03-accounts/1.account-manage.md index 542c72630..3b344f211 100644 --- a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/03-accounts/1.account-manage.md +++ b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/03-accounts/1.account-manage.md @@ -1,12 +1,12 @@ # 账号管理 -Starcoin 节点内置了一个去中心化的钱包,用户可以通过账号相关的接口以及命令来管理自己的账号。 +Starcoin 节点内置了一个去中心化的钱包,用户可以通过账号相关的接口以及命令来管理自己的账户。 -节点启动的时候,会自动创建一个默认账号,默认密码为空。 -默认账号可以通过账号相关的命令进行变更。 +节点启动的时候,会自动创建一个默认账户,默认密码为空。 +默认账户可以通过账户相关的命令进行变更。 以下命令需要连接到控制台进行操作,连接方式请参看[如何与 Starcoin 控制台交互](../setup/starcoin-console)。 - 1. 创建账号 + 1. 创建账户 ```bash starcoin% account create -p @@ -21,7 +21,7 @@ starcoin% account create -p } ``` -2. 查看账号 +2. 查看账户 ```bash starcoin% account show 0xf096a2a61d3042774187a462a5394537 @@ -50,12 +50,28 @@ starcoin% account show 0xf096a2a61d3042774187a462a5394537 > 注意,创建账户只是在 Starcoin 节点里创建一对密钥,并不会更新链的状态,所以 `balance` 和 `sequence_number` 此时还是空的。以上信息都属于公开信息,只有私钥是需要用户保密的。 -3. 查看账号列表 +3. 查看账户列表 ```bash starcoin% account list ``` +这个命令会列出当前节点上的所有账户。 + +如果在本地的 `dev` 网络使用这个命令,那么在列出的账户列表中可以看到如下账户的信息: + +```bash + { + "address": "0x0000000000000000000000000a550c18", + "is_default": false, + "is_readonly": false, + "public_key": "0xb9c6ee1630ef3e711144a648db06bbb2284f7274cfbee53ffcee503cc1a49200aef3f4a4b8eca1dfc343361bf8e436bd42de9259c04b8314eb8e2054dd6e82ab01", + "receipt_identifier": "stc1pqqqqqqqqqqqqqqqqqqqq54gvrqzaqnvx" + }, +``` + +`0x0000000000000000000000000a550c18` 这个账户地址是 Starcoin 基金会的地址,同时也是内置在 `dev` 网络的水龙头地址。 + 4. 查看或者变更默认账号 查看默认账号地址: diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/03-accounts/3.multisig-account.md b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/03-accounts/3.multisig-account.md index cca730c91..ae0eb3949 100644 --- a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/03-accounts/3.multisig-account.md +++ b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/03-accounts/3.multisig-account.md @@ -111,7 +111,7 @@ starcoin% account import-multisig --pubkey 0xf423c3d02ac400037a40e8dbbf8b3c3e454 `--pubkey` 选项指定 `generate-keypair` 生成公钥而不是个人账户的公钥,`--prikey` 选项指定 `generate-keypair` 生成的私钥而不是个人账户的私钥,`-t` 选项指定所需的签名数,即 `threshold`。 -分别在三个控制台执行完上述命令后,你会发现,三个命令都生成了相同的多签账户信息: +分别在三个控制台执行完上述命令后,你会发现,三个命令都生成了相同的**多签账户**信息(注意:私钥不同,见下文说明): ```bash { @@ -127,9 +127,10 @@ starcoin% account import-multisig --pubkey 0xf423c3d02ac400037a40e8dbbf8b3c3e454 **理解多签账户的公钥和私钥:** -可以看到这个多签账户的公钥非常长。 -实际上,多签账户的私钥是由多个单签私钥拼接而成,每个人掌握 `1/n`,多签账户的公钥是由多个单签私钥生成的公钥拼接而成。 -多签公钥是公开的,每个人都持有相同的多签公钥。 +公钥:可以看到这个多签账户的公钥非常长,是由多个单签私钥生成的公钥拼接而成。多签公钥是公开的,每个人都持有相同的多签公钥。 + +私钥:多签账户的私钥是由多个单签私钥拼接而成,每个人掌握 `1/n`。可以分别在三个console中执行 `account export 0x8afd731146fbc206d56265adedb4b50a` 查看每个人掌握的私钥并进行对比。 + 查看多签账户: diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/03-accounts/4.rotate-authentication-key.md b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/03-accounts/4.rotate-authentication-key.md index 597edef61..dd9b2a884 100644 --- a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/03-accounts/4.rotate-authentication-key.md +++ b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/03-accounts/4.rotate-authentication-key.md @@ -1,25 +1,35 @@ -# 重置账号私钥 +# 重置账户私钥 -这篇文章指导你如何在 starcoin 区块链上完成对账号的私钥重置。 +这篇文章指导你如何在 Starcoin 区块链上完成对账户的私钥重置。 -可用于重置账号私钥并保留地址的场景。 +使用场景: -## 准备工作 +1. 用于重置账户私钥并保留地址 +2. 将账户重置成多签账户并保留地址(使用多签账户私钥即可) -1. 启动一个 starcoin dev 节点并连接。详细步骤请查阅[使用 starcoin 控制台](../setup/starcoin-usage)。 +## 准备工作 +1. 启动一个 `starcoin` dev 节点并连接。详细步骤请查阅[使用 starcoin 控制台](../setup/starcoin-usage)。 ## 操作步骤 -- 准备新账号 A -- 执行 auth key 替换合约:使用账号 A 的 auth key 替换 B 的 auth key -- 删除账号 A ,B -- 使用 A 的私钥与 B 的地址倒入账号,完成 B 的私钥替换 +我们有两种方法实现重置账户 auth key: + +1. 使用 `starcoin` 提供的操作命令逐步完成替换 +2. 使用 `rotate-authentication-key` 命令直接完成替换 + +其中方案二对方案一各条命令进行了打包操作,更为便捷。方案一则更加清晰可控。 +### 方案一:分步执行 -### 准备新账号 +- 准备新账户 A +- 执行 auth key 替换合约:使用账户 A 的 auth key 替换 B 的 auth key +- 删除账户 A ,B +- 使用 A 的私钥与 B 的地址倒入账户,完成 B 的私钥替换 -创建新账号 A: +#### 准备新账户 + +创建新账户 A: ```bash starcoin% account create -p my-pass @@ -34,7 +44,7 @@ starcoin% account create -p my-pass } ``` -获取账号 A 的 auth key: +获取账户 A 的 auth key: ```bash starcoin% account show 0xc04c62b99fd053ac31d21d6e06619aed @@ -54,7 +64,7 @@ starcoin% account show 0xc04c62b99fd053ac31d21d6e06619aed } ``` -获取账号 A 的 private key: +获取账户 A 的 private key: ```bash starcoin% account export 0xc04c62b99fd053ac31d21d6e06619aed -p my-pass @@ -66,9 +76,9 @@ starcoin% account export 0xc04c62b99fd053ac31d21d6e06619aed -p my-pass } ``` -### 执行 auth key 替换合约 +#### 执行 auth key 替换合约 -查看账号 B (待替换账号): +查看账户 B (待替换账户): ```bash starcoin% account show 0xdaf8e186dc97ee9ba6971b08115d4dc2 @@ -90,13 +100,13 @@ starcoin% account show 0xdaf8e186dc97ee9ba6971b08115d4dc2 } ``` -执行 rotate_authentication_key: +执行 `rotate_authentication_key`: ```bash starcoin% account execute-function -s 0xdaf8e186dc97ee9ba6971b08115d4dc2 --function 0x1::Account::rotate_authentication_key --arg x"39353fabc51eb1b472c2c5ef6e74c91bc04c62b99fd053ac31d21d6e06619aed" -b ``` -执行后账号 B 的状态: +执行后账户 B 的状态: ```bash starcoin% account show 0xdaf8e186dc97ee9ba6971b08115d4dc2 @@ -118,7 +128,7 @@ starcoin% account show 0xdaf8e186dc97ee9ba6971b08115d4dc2 } ``` -移除账号 A 与 B: +移除账户 A 与 B: ```bash starcoin% account remove 0xc04c62b99fd053ac31d21d6e06619aed -p my-pass @@ -143,7 +153,7 @@ starcoin% account remove 0xdaf8e186dc97ee9ba6971b08115d4dc2 -p my-pass } ``` -根据 A 账号的私钥, B 账号的地址(原地址)导入账号: +根据 A 账户的私钥, B 账户的地址(原地址)导入账户: ```bash starcoin% account import -i 0x92e13795c658f40ead01db2b3a7ed351b07d85d92bb0f03a9b04364f6de487c9 0xdaf8e186dc97ee9ba6971b08115d4dc2 @@ -158,7 +168,7 @@ starcoin% account import -i 0x92e13795c658f40ead01db2b3a7ed351b07d85d92bb0f03a9b } ``` -查看 B 账号的最新状态,我们可以发现 B 账号已经完成了 auth key 的替换: +查看 B 账户的最新状态,我们可以发现 B 账户已经完成了 auth key 的替换: ```bash starcoin% account show 0xdaf8e186dc97ee9ba6971b08115d4dc2 @@ -180,13 +190,13 @@ starcoin% account show 0xdaf8e186dc97ee9ba6971b08115d4dc2 } ``` -为了检验账号,我们从 B 账号发起一笔转账: +为了检验账户,我们从 B 账户发起一笔转账: ```bash starcoin% account transfer -s 0xdaf8e186dc97ee9ba6971b08115d4dc2 -r 0xacff0c9a785004cdadec02ab76d44f32 -v 10000 -b ``` -查看两个账号的最新情况: +查看两个账户的最新情况: ```bash starcoin% account show 0xdaf8e186dc97ee9ba6971b08115d4dc2 @@ -224,3 +234,90 @@ starcoin% account show 0xacff0c9a785004cdadec02ab76d44f32 } } ``` + +### 方案二:rotate-authentication-key 命令 + +待替换账户: + +```bash +starcoin% account show 0x19b757b48a015ee035c03d01254d977d +{ + "ok": { + "account": { + "address": "0x19b757b48a015ee035c03d01254d977d", + "is_default": false, + "is_readonly": false, + "public_key": "0xf3ebe5f3b54f670d128b23ac48451ce4901b61c91a2fa3dffd42d36b8686f6b2", + "receipt_identifier": "stc1prxm40dy2q90wqdwq85qj2nvh05t82esr" + }, + "auth_key": "0x45dfd6aee42561ebef18f7efadea276319b757b48a015ee035c03d01254d977d", + "balances": { + "0x00000000000000000000000000000001::STC::STC": 100000000 + }, + "sequence_number": 0 + } +} +``` + +创建新的密钥对: + +```bash +starcoin% account generate-keypair +{ + "ok": [ + { + "address": "0x1876d22b496bf344ab22b4f2fad63226", + "auth_key": "0x6e90f703921b70d637e0c6ab4bf329da1876d22b496bf344ab22b4f2fad63226", + "private_key": "0xe44035658755709e7567d1ee34c8563400fae6362efe4d8ea4dc1a6fa13f8a79", + "public_key": "0xff23b3c540ac5040846ccd2664fec13d9470ebfb4cb42afd5f25be2c5e0c00d5", + "receipt_identifier": "stc1prpmdy26fd0e5f2ezkne0443jychq0vzt" + } + ] +} +``` + +直接完成 auth key 的替换,原账户的重新导入。 + +```bash +starcoin% account rotate-authentication-key 0x19b757b48a015ee035c03d01254d977d -i 0xe44035658755709e7567d1ee34c8563400fae6362efe4d8ea4dc1a6fa13f8a79 --password my-pass +txn 0x1d97effb8f8e2b598bd67e70047c2b9862e6d0cb823e77f8173dcaa546733be8 submitted. +{ + "ok": { + "address": "0x19b757b48a015ee035c03d01254d977d", + "is_default": false, + "is_readonly": false, + "public_key": "0xff23b3c540ac5040846ccd2664fec13d9470ebfb4cb42afd5f25be2c5e0c00d5", + "receipt_identifier": "stc1prxm40dy2q90wqdwq85qj2nvh05t82esr" + } +} + +starcoin% account show 0x19b757b48a015ee035c03d01254d977d +{ + "ok": { + "account": { + "address": "0x19b757b48a015ee035c03d01254d977d", + "is_default": false, + "is_readonly": false, + "public_key": "0xff23b3c540ac5040846ccd2664fec13d9470ebfb4cb42afd5f25be2c5e0c00d5", + "receipt_identifier": "stc1prxm40dy2q90wqdwq85qj2nvh05t82esr" + }, + "auth_key": "0x6e90f703921b70d637e0c6ab4bf329da1876d22b496bf344ab22b4f2fad63226", + "balances": { + "0x00000000000000000000000000000001::STC::STC": 99941419 + }, + "sequence_number": 1 + } +} +``` + +#### 注意事项 + +考虑到本地状态与链上状态一致性可能会被意外故障打断,从而得不到命令的返回值,我们需要恢复手段。无返回值共有如下三种情况: + +1. auth key 并未被替换:重新执行命令 +2. `INVALID_AUTH_KEY` 错误:删除账户并使用新的密钥重新导入即可。这是由于 remove 账户时异常退出导致的。 +3. `account not existed` 错误:使用新的密钥重新导入即可。这是由于 import 账户时异常退出导致的。 + +### 重置一般账户为多签账户 + +TODO [多签重构](https://github.com/starcoinorg/starcoin/issues/3411)完成后补充 \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/03-accounts/5.use-starmask.md b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/03-accounts/5.use-starmask.md new file mode 100644 index 000000000..912326faa --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/03-accounts/5.use-starmask.md @@ -0,0 +1,101 @@ +# StarMask 入门 + +StarMask 是一款基于浏览器扩展的钱包,它运行在 Web 浏览器(Chrome、Firefox 或 Edge)中。 +StarMask 是用于与 Starcoin 区块链进行交互的软件加密货币钱包,使用这个钱包和进行各项测试都很容易,可以连接多种 Starcoin 节点。 +StarMask 可用于存储和管理 Starcoin 的链上资产,用户可以通过 StarMask 直接参与 Starcoin 的链上治理,包括投票、IDO、SWAP 等等。 + +## 下载与安装 + +### 在线安装 + +在线安装即从 Chrome 应用商店安装,目前仅支持 Chrome 浏览器,如果使用其它浏览器,请参考[离线安装](#离线安装). + +1. 安装 + +在 [Chrome 应用商店](https://chrome.google.com/webstore/search/StarMask?hl=zh-CN)搜 +索 `StarMask`,点击`添加至 Chrome`,即可完成安装。 + +2. 如何手动更新钱包 + +在 Chrome 浏览器地址栏输入 `chrome://extensions/`,开启页面右上角的 `开发者模式`。 +在当前页的左上方就会出现`更新`按钮,点击更新即可。 + +3. 图文参考 + +更详细的图文安装步骤,请参考[安装指南 - Chrome 浏览器](https://github.com/starcoinorg/starmask-extension/blob/main/docs/zh/how-to-install.md)。 + +### 离线安装 + +这一小节中,主要介绍如何通过离线安装在主流的浏览器(Chrome、Firefox 和 Edge)中使用 StarMask 钱包。 + +#### 下载 + +访问 StarMask 的 [GitHub 仓库](https://github.com/starcoinorg/starmask-extension),下载对应浏览器的[最新发布版本](https://github.com/starcoinorg/starmask-extension/releases/latest)。 + +注:目前发布的版本有 Chrome 版本 和 Firefox 版本,对于 Edge 浏览器,可以暂时使用 Chrome 版本。 + +#### 安装 - Chrome + +打开 Chrome 浏览器,在地址栏输入 `chrome://extensions/`,开启页面右上角的 `开发者模式`。 +将在载好的压缩包拖拽到 Chrome 中,即可完成安装。 + +安装完成后,点击 Chrome 浏览器右上角的`扩展程序`图标,点击`固定` StarMask,即可将其固定到`工具栏`,方便使用 StarMask。 + +#### 安装 - Firefox + +打开 Firefox 浏览器,点击右上角的`打开应用程序菜单`按钮,选择`扩展和主题`,点击当前页面上方的小齿轮(`用于所有附加组件的工具`),选择`调试附加组件`,点击`临时载入附加组件`,选择刚才下载好的 StarMask 压缩包,即可完成安装。 + +也可以在 Firefox 浏览器的地址栏输入 `about:debugging#/runtime/this-firefox`,点击`临时载入附加组件`,选择 StarMask 压缩包,即可完成安装。 + +更详细的图文安装步骤,请参考[安装指南 - Firefox 浏览器](https://github.com/starcoinorg/starmask-extension/blob/main/docs/zh/how-to-install-firefox.md)。 + +#### 安装 - Edge + +打开 Edge 浏览器,在地址栏输入 `edge://extensions/`,开启左侧的`开发人员选项`,将下载好的 StarMask 压缩包拖拽到 Edge 中,即可完成安装。 + +## 创建钱包 + +StarMask 安装完成后,它会自动打开欢迎页面。如果没有自动打开,也可以点击工具栏上的 StatMask 图标。 +点击这个图标就能开始使用 StarMask 了,你需要先阅读和接受用户使用协议,然后输入**密码**来创建新的 Starcoin 钱包。 + +点击`开始使用`,点击`创建钱包`,点击`我同意`,输入密码。 + +:::tip 提示 + +这个密码是用来控制对 StarMask 软件的使用,例如当他人使用你的电脑时,需要知道密码才能对 StarMask 进行操作。 + +::: + +设置完密码后,StarMask 会为你生成一个钱包并进入助记词页面,点击`小锁`就会显示由12个英文单词组成的助记词密语。 +这些助记词可用在所有的兼容钱包上进行钱包恢复。 +如果你忘记了钱包密码或是电脑出问题了,只需要使用这12个单词就可以重置钱包密码或在其它设备完成钱包的恢复。 + +:::caution 注意 + +建议把这12个助记词备份在多张纸上,并分别保存在2~3个不同的地方。 +例如保险柜、上锁的抽屉或其它能保证这些记录着助记词的纸张安全的地方。 +这些纸的价值等同于你在 Starcoin 链上所持有的数字货币的价值。 +如果他人获得了这12个助记词,就可以窃取你的数字货币,请务必妥善保管! +通常,不建议将助记词截图、文本文件上传到网盘或其他联网设备进行保存,而应该选择纸张或者离线的加密硬盘进行保存。 +如果你想使用离线加密设备的方式保存,可以点击页面左侧`下载账户助记词`,将其移动到加密存储介质后,确保在当前的电脑上没有任何备份! + +::: + +在你确定已经正确保存了助记词之后,点击`下一步`,按照刚才的助记词序列点击助记词,点击`确认`。 +完成助记词校验后,就完成了钱包创建的所有流程了,愉快地开始 Starcoin 链上之旅吧! + +## 使用钱包 + +完成钱包的创建后,就会进入账户页面,StarMask 会显示你的 Starcoin 账户的概览信息。 + +在账户页面第一栏左侧显示 Starcoin 图标,左侧显示的是当前钱包连接的 Starcoin 网络(默认显示“Starcoin 主网络”)和一个彩色的图标(用于在多个账户之间进行区分)。 + +此时点击浏览器工具栏上的 StarMask 图标,弹出的页面和 StarMask 扩展页基本一致。 +唯一区别是,StarMask 钱包弹出页的第二栏左侧会有一个 Web3 网页连接状态按钮。 +如果你的钱包连接上某个 Web3 网页,则会显示`已连接`,点开后可以查看详情。 + +第二栏中间显示的是账户名称(默认是 `Account1`)和账户的 Starcoin 地址(例如:`0xeD49…683e`)。 +第二栏右侧显示的是`账户选项`。 + +第三栏中间显示当前账户所持有的 STC 代币数量,以及一个用于发送代币的`发送`按钮。 +在下方有三个按钮分别是`资产`、`NFT` 和`活动`。 diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/04-mining/01-mining.md b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/04-mining/01-mining.md index ba8cfb08f..2f2feaafb 100644 --- a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/04-mining/01-mining.md +++ b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/04-mining/01-mining.md @@ -1,8 +1,10 @@ # 挖矿客户端 + ## starcoin miner -starcoin miner 为 starcoin 提供的挖矿客户端。 -`starcoin_miner` 命令行工具用于远程连接到 starcoin 节点,并提供 cpu 挖矿, -连接 stc-mini 矿机挖矿的能力。 + +`starcoin_miner` 为 Starcoin 提供的挖矿客户端。 +`starcoin_miner` 命令行工具用于远程连接到 Starcoin 节点,并提供 CPU 挖矿,连接 stc-mini 矿机挖矿的能力。 + ### 使用方法 ```shell @@ -22,15 +24,15 @@ OPTIONS: -u, --user ``` +### 连接到节点利用 CPU 进行挖矿 -### 连接到节点利用 cpu 进行挖矿 -当本地启动了 starcoin node 时,我们可以运行如下命令,指定挖矿用户 alice 启动 4 个线程连接到本地节点进行挖矿。 +当本地启动 Starcoin 节点时,我们可以运行如下命令来指定挖矿用户 alice 启动 4 个线程连接到本地节点进行挖矿。 ```shell starcoin_miner --user alice -n 4 ``` -启动后可以看到 console 中有如下信息: +启动后可以看到 console 中有如下信息: ```shell Miner client Total seals found: 3 @@ -39,15 +41,19 @@ starcoin-miner-cpu-worker-1 ⠦ [00:00:00] Hash rate: 21 Seals found: 17 starcoin-miner-cpu-worker-2 ⠤ [00:00:00] Hash rate: 20 Seals found: 16 starcoin-miner-cpu-worker-3 ⠤ [00:00:00] Hash rate: 20 Seals found: 16 2020-10-28T09:09:53.006852+08:00 INFO - Seal found 16718533681172480617 - ``` + 日志中可以看到挖到的 seals 总数,每个线程的算力,以及新计算得出的 seal 等信息。 ## stc-box -stc-box 为 starcoin 目前主流矿机。不需要安装额外的客户端或软件,可通过矿机网页进行设置。 + +stc-box 为 Starcoin 目前主流矿机。不需要安装额外的客户端或软件,可通过矿机网页进行设置。 配置方式可参考 [配置矿池可参考](https://www.yuque.com/bixinkelekuangchi/stoxms/knlyf3) + ## stc-mini + ### windows 环境使用步骤 + 1. 安装驱动 2. 安装软件:[Starcoin 挖矿客户端](https://github.com/starcoinorg/starcoin_mini_miner/releases/) 3. 将矿机与电脑相连。 @@ -57,14 +63,18 @@ stc-box 为 starcoin 目前主流矿机。不需要安装额外的客户端或 7. 切换矿池:选择机器停止挖矿,设置矿池,开始挖矿。 ### 注意事项 + * 使用前请尽量避免将矿机放置在空气流通性差和温度过高的环境下运行,否则可能导致工作异常甚至造成设备损坏。 * 使用前请保证网络通畅,否则会造成拒绝率上升影响机器算力。 * 使用时请勿私自超频,否则会导致芯片损坏,后果自负。 * 该客户端软件暂时仅支持 windows 系统, 非 windows 系统用户使用此矿机请参考:[starcoin mint usb solver](https://github.com/fikgol/usbsolver) # 矿池相关 + starcoin 的矿池协议参考 [starcoin stratum protocol](https://github.com/starcoinorg/starcoin/blob/master/stratum/stratum_mining_protocol.md)。 + ## 加入矿池 + * 设置 [可乐矿池(推荐)](https://www.yuque.com/docs/share/5c5ae94a-3ed4-4dab-98ca-62baf17891e0) * 连接 [币印矿池 (推荐)](https://help.poolin.com/hc/zh-cn/articles/360060982092) * 连接 [ViaBTC 矿池](https://support.viabtc.com/hc/zh-cn/articles/900005939326) @@ -72,12 +82,12 @@ starcoin 的矿池协议参考 [starcoin stratum protocol](https://github.com/st * 连接 [鱼池矿池](https://blog.f2pool.com/zh/mining-tutorial/stc) ## 自建矿池 -starcoin node 内部实现了一个 stratum server ,用户可以通过其实现自建矿池进行挖矿。 -启动 starcoin node 时,stratum server 将会默认监听本机地址 0.0.0.0:9880,通过 -连接支持starcoin stratum 的挖矿客户端进行挖矿。启动 starcoin node 时,可以通过参 -数 --stratum-address 以及 --stratum-port 来设置 stratum server 的地址和端口。 -如 + +Starcoin 节点内部实现了一个 stratum server,用户可以通过其实现自建矿池进行挖矿。 +启动 Starcoin 节点时,stratum server 将会默认监听本机地址 0.0.0.0:9880,通过连接支持 starcoin stratum 的挖矿客户端进行挖矿。 +启动 Starcoin 节点时,可以通过参数 `--stratum-address` 以及 `--stratum-port` 来设置 stratum server 的地址和端口。 +如: ``` shell - ./starcoin -n main --stratum-port 9880 --stratum-address 127.0.0.1 +./starcoin -n main --stratum-port 9880 --stratum-address 127.0.0.1 ``` diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/04-mining/README.md b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/04-mining/README.md new file mode 100644 index 000000000..5d8626754 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/current/02-getting-started/04-mining/README.md @@ -0,0 +1,3 @@ +# 挖矿并了解挖矿协议 + +这个章节你可以了解如何使用 Starcoin 的命令行工具,矿机,矿池进行挖矿,以及挖矿的相关协议。 diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/03-move/01-prepare-move-env.md b/i18n/zh/docusaurus-plugin-content-docs/current/03-move/01-prepare-move-env.md index 59615be7f..e41ce6125 100644 --- a/i18n/zh/docusaurus-plugin-content-docs/current/03-move/01-prepare-move-env.md +++ b/i18n/zh/docusaurus-plugin-content-docs/current/03-move/01-prepare-move-env.md @@ -1,31 +1,46 @@ # 设置 Move 开发环境 -## 下载 +## 安装 mpm -1. 运行 starcoin-framework 下的 [`dev_setup.sh`](https://github.com/starcoinorg/starcoin-framework/blob/main/scripts/dev_setup.sh)(自动化安装脚本),它包含了 mpm 的安装以及 move-prover 的依赖安装: +Move Package Manager(mpm)是一个命令行工具,用于开发 Move 项目。可以类比 Rust 的 Cargo,或 NodeJS 的 npm。 + +选择下面的一种方法安装 + +### 通过安装脚本安装 + +运行 starcoin-framework 下的 [`scripts/dev_setup.sh`](https://github.com/starcoinorg/starcoin-framework/blob/main/scripts/dev_setup.sh)(自动化安装脚本),它包含了 mpm、Rust、环境变量配置以及 Move Prover 工具的依赖安装: ``` -curl -s https://raw.githubusercontent.com/starcoinorg/starcoin-framework/main/scripts/dev_setup.sh | bash /dev/stdin -b -t +curl -s https://raw.githubusercontent.com/starcoinorg/starcoin-framework/main/scripts/dev_setup.sh | bash /dev/stdin -b -t -p ``` -2. 从 [starcoiorg/starcoin](https://github.com/starcoinorg/starcoin) 的发布页面下载 +上面的给定的参数会在默认位置安装 mpm、Rust的安装,并配置环境变量。更多参数可以打开脚本文件查看。 + +### 通过预编译二进制包安装 + +从 [starcoiorg/starcoin](https://github.com/starcoinorg/starcoin) 的发布页面下载 `mpm-[your_os]-latest.zip` 并解压,然后手动添加到 PATH。 + +### 从源码编译安装 -3. +可以从本地源码 ``` $ git clone https://github.com/starcoinorg/starcoin.git -$ cargo install --path starcoin/vm/move-package-manager +$ cd starcoin +$ cargo install --path vm/move-package-manager ``` -4. +也可以从git仓库源码 ``` $ cargo install --git https://github.com/starcoinorg/starcoin move-package-manager --bin mpm ``` -这将在 Cargo 二进制目录中安装 `mpm` 二进制文件。在 macOS和 Linux 上,这个目录通常是 *~/.Cargo/bin*。你需要确保该位置在你的 `PATH` 环境变量中。 +这将在 Cargo 的 bin 目录中安装 `mpm` 二进制文件。在 macOS 和 Linux 上,这个目录通常是 *~/.Cargo/bin/*。你需要确保该位置在你的 `PATH` 环境变量中。 + +### 小结 现在,你应该能够运行 `mpm`: ``` $ mpm -move-package-manager 1.11.7-rc +move-package-manager 1.11.11 Starcoin Core Dev CLI frontend for the Move compiler and VM @@ -33,7 +48,15 @@ USAGE: mpm [OPTIONS] ... ``` -# 设置 Move Prover 环境 + +## 安装 IDE 插件 + +### VS Code + +在插件市场中搜索 starcoin-ide。点击安装即可。 + + +## 设置 Move Prover 环境 1. 运行 starcoin-framework 下的 dev_setup.sh(自动化安装脚本) @@ -42,4 +65,4 @@ USAGE: ``` 当上面的命令执行完毕时,输入 `boogie /version`,如果输出类似 "Boogie program verifier version X.X.X",那么安装已经成功。 -注意,目前 Move Prover 只能在 UNIX 系操作系统下运行(例如 Linux、macOS)。 Windows 用户可以通过安装 WSL 来运行。 \ No newline at end of file +注意,目前 Move Prover 只能在类 UNIX 操作系统下运行(例如 Linux、macOS)。 Windows 用户可以通过安装 WSL 来运行。 diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/03-move/03-understanding-ability.md b/i18n/zh/docusaurus-plugin-content-docs/current/03-move/03-understanding-ability.md index 54316502b..710054abd 100644 --- a/i18n/zh/docusaurus-plugin-content-docs/current/03-move/03-understanding-ability.md +++ b/i18n/zh/docusaurus-plugin-content-docs/current/03-move/03-understanding-ability.md @@ -1,7 +1,158 @@ -# 认识 Abilities +# 认识 Ability -Move 的类型系统非常灵活,每种类型都可以被四种限制符所修饰。这四种限制符我们称之为 abilities,它们定义了类型的值是否可以被复制、丢弃和存储。 +Move 具有独特的类型系统 —— 非常灵活和可定制,每种类型最多可以拥有4种能力(Ability)。 +这4种能力分别被4个限定符所修饰,它们定义了类型的值是否可以被复制、丢弃和存储。 -> 这四种 abilities 限制符分别是: Copy, Drop, Store 和 Key。 +> 这四种能力(Ability)的限制符分别是:`copy`,`drop`,`store` 和 `key`, -关于它们的详细介绍可以在 《Move 编程语言》的 [Abilities](https://move-book.com/cn/advanced-topics/types-with-abilities.html) 一节中找到。 \ No newline at end of file +它们的功能分别是: + +- `copy` - 被修饰的值可以被复制。 +- `drop` - 被修饰的值在作用域结束时可以被丢弃。 +- `key` - 被修饰的值可以作为键值对全局状态进行访问。 +- `store` - 被修饰的值可以被存储到全局状态。 + +## Ability 语法 + +基本类型和内建类型的能力是预先定义好的并且不可改变:integers,vector,addresses 和 boolean 类型的值先天具有 copy,drop 和 store 能力。 + +然而,结构体的能力可以由开发者按照下面的语法进行添加: + +``` +struct NAME has ABILITY [, ABILITY] { [FIELDS] } +``` + +下面是一些例子: + +``` +module Library { + + // each ability has matching keyword + // multiple abilities are listed with comma + struct Book has store, copy, drop { + year: u64 + } + + // single ability is also possible + struct Storage has key { + books: vector + } + + // this one has no abilities + struct Empty {} +} +``` + +## 不带能力限定符的结构体 + +在进入能力的具体用法之前,我们不妨先来看一下,如果结构体不带任何能力会发生什么? + +``` +module Country { + struct Country { + id: u8, + population: u64 + } + + public fun new_country(id: u8, population: u64): Country { + Country { id, population } + } +} +``` + +``` +script { + use {{sender}}::Country; + + fun main() { + Country::new_country(1, 1000000); + } +} +``` + +运行上面的代码会报如下错误: + +``` +error: + ┌── scripts/main.move:5:9 ─── + │ + 5 │ Country::new_country(1, 1000000); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Cannot ignore values without the 'drop' ability. The value must be used + │ +``` + +方法 `Country::new_country()` 创建了一个值,这个值没有被传递到任何其它地方,所以它应该在函数结束时被丢弃。 +但是 Country 类型没有 Drop 能力,所以运行时报错了。现在让我们加上 Drop 限制符试试看。 + +## drop + +按照能力(Ability)的语法我们为这个结构体增加 drop 能力,这个结构体的所有实例将可以被丢弃。 + +``` +module Country { + struct Country has drop { // has + id: u8, + population: u64 + } + // ... +} +``` + +现在,Country 可以被丢弃了,代码也可以成功执行了。 + +``` +script { + use {{sender}}::Country; + + fun main() { + Country::new_country(1, 1000000); // value is dropped + } +} +``` + +注意 Destructuring 并不需要 drop 能力。 + +## copy + +我们学习了如何创建一个结构体 Country 并在函数结束时丢弃它。 +但是如果我们想要复制一个结构体呢?默认情况下结构体是按值传递的,制造一个结构体的副本需要借助关键字 copy (我们会在 下一章 更加深入的学习): + +``` +script { + use {{sender}}::Country; + + fun main() { + let country = Country::new_country(1, 1000000); + let _ = copy country; + } +} +``` + +``` + ┌── scripts/main.move:6:17 ─── + │ + 6 │ let _ = copy country; + │ ^^^^^^^^^^^^ Invalid 'copy' of owned value without the 'copy' ability + │ +``` + +正如所料,缺少 copy 能力限定符的类型在进行复制时会报错: + +``` +module Country { + struct Country has drop, copy { // see comma here! + id: u8, + population: u64 + } + // ... +} +``` + +修改后的代码就可以成功执行了。 + +## 小结 + +基本类型缺省具有 store,copy 和 drop 限制。 +缺省情况下结构体不带任何限制符。 +copy 和 drop 限制符定义了一个值是否可以被复制和丢弃。 +一个结构体有可能带有所有4种限制符。 diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/03-move/11-quick-start.md b/i18n/zh/docusaurus-plugin-content-docs/current/03-move/11-quick-start.md new file mode 100644 index 000000000..518c91621 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/current/03-move/11-quick-start.md @@ -0,0 +1,586 @@ +# 快速开始 + +在这个小教程中,我们实现一个简单的计数器,来展示 Move 是如何通过代码来管理资源的。 +这篇文档涉及的内容包括背景知识、写代码、如何编译、如何发布到链上、如何调用。 +完整的代码仓库在[这里](https://github.com/starcoinorg/starcoin-cookbook/tree/main/examples/my-counter)。 + +提前准备: + +1. 需要按照[如何设置本地开发网络](./02-getting-started/02-setup/03-dev-network.md)搭建 dev 网络,并通过 Starcoin 控制台连接到 dev 网络。 +2. 按照[账号管理](./02-getting-started/03-accounts/1.account-manage.md)创建一个账号或者使用已有账号,并且给账号里转一点 STC。 +3. 通过[第一笔链上交易](./02-getting-started/03-accounts/2.first-transaction.md)对 transaction 有基本理解。 + +下面先介绍一下必备的工具和项目结构。 +接下来将介绍一些必备工具和项目结构。 + +## mpm 命令行工具以及项目结构 + +在开始写代码之前,我们先安装 mpm(Move Package Manager)命令行工具,并且简单介绍一下 Move 项目的结构。 + +安装方法见[设置 Move 开发环境](./01-prepare-move-env.md). + +现在,可以通过 mpm 创建一个新项目 + +``` shell +$ mpm package new my-counter +``` + +可以看到生成的目录结构 + +``` +my-counter +├── Move.toml +└── sources/ +``` + +- `sources/` - 存放 Move 模块(`module`)的目录。 +- `Move.toml` - manifest 文件:定义包的元数据、依赖,以及命名地址。 + +:::tip Move 模块 +`module` 是定义**结构体类型**和操作结构体的**函数**的库。*(可以借助其他编程语言的“类 class”概念来帮助理解)*。 + +`module` 会被发布到发布者的地址下,`module` 中的入口方法(entry functions)可以被大家调用执行。 +*(可以借助函数计算平台 —— 如 AWS Lambda —— 上发布函数、调用函数来帮助理解)* +::: + +有 Move.toml 文件和 `sources/` 目录的项目,会被认为是一个 [Move 包(Move Package)](./02-move-language/01-packages.md)。 + +## 创建 MyCounter 模块 + +我们将要创建的 module 命名为 MyCounter,在本文中,使用笔者本地 dev 网络的一个账户地址 `0xcada49d6a37864931afb639203501695` 来演示,我们会将 MyCounter 发布到这个地址。 + +### 第一版代码 + +在 MyCounter 模块中,我们定义一个新类型结构体 Counter,包含有一个字段 value,代表这个计数器触发的次数。 +value 的类型是 u64,也就是无符号64位整型。 + +下面是 MyCounter module 的第一版代码 + +```move title="my-counter/sources/MyCounter.move" +module 0xcada49d6a37864931afb639203501695::MyCounter { + struct Counter { + value: u64, + } +} +``` + +module 的定义语法是 `module
::`。 + +由于这个地址太长,可以在 Move.toml 文件中设置一个命名地址(named address),做到在 Move 项目中全局替换。 + +```toml title="my-counter/Move.toml" {5,6} +[package] +name = "my-counter" +version = "0.0.1" + +[addresses] +MyCounter = "0xcada49d6a37864931afb639203501695" +... +``` + +:::note 提示 +高亮的代码块是有变化的或是需要注意的部分。 +::: + +这样,第一版代码可以写为: + +```move title="my-counter/sources/MyCounter.move" {1} +module MyCounter::MyCounter { + struct Counter { + value: u64, + } +} +``` + +前面的 MyCounter 是地址,后面是 MyCounter 是 module 标识符。 + +接着我们编译代码: + +```shell +$ mpm package build + +BUILDING my-counter +``` + +没有报错,说明没有问题。 + +### 初始化方法 init + +接着我们定一个初始化方法,创建一个 Counter 实例,并“移动(move)”到调用者账号的存储空间下。 + +```move title="my-counter/sources/MyCounter.move" {6-8} +module MyCounter::MyCounter { + struct Counter { + value: u64, + } + + public fun init(account: &signer) { + move_to(account, Counter { value: 0 }); + } +} +``` + +这里的 `move_to(&signer,T)` 是一个内置方法,作用是将类型为 `T` 的资源添加到账号 `signer` 的地址下的存储空间(尖括号在这里是范型)。 + +:::info 更多信息 +这里的存储空间是 `GlobalState`,可以先简单理解为 存放账号的`资源`和`module代码`的地方。 +更多信息可以查阅[概念-状态](../99-concepts/04-state.md)。也可以跳过这里。 +::: + +在第6行的 init 函数的参数 `account: &signer`,中的 signer 是 Move 的内置类型。 +想要将资源放到调用者的账户地址下,需要将 &signer 参数传递给函数。 +`&signer` 数据类型代表当前 transaction 的发起者(函数的调用者,可以是任何账户)。 + +:::info 帮你理解 —— signer +`signer` 就像是 linux 下的 uid 一样的东西。登陆 linux 系统后,你输入的所有命令,都被认为是“这个已登陆的**经过认证**的用户”操作的。 +关键来了,这个认证过程不是在运行的命令、程序中做的,而是开机后由操作系统完成的。 + +对应到 Move 中,这个认证过程就是和其他区块链系统类似的、我们熟知的“私钥签名 公钥验证”的过程。 +在带有 `&signer` 参数的函数执行时,发起者的身份已经被 Starcoin 区块链认证过了。 +::: + +我们试着编译一下: + +```shell +$ mpm package build + +BUILDING my-counter +error[E05001]: ability constraint not satisfied + ┌─ ./sources/MyCounter.move:7:9 + │ +2 │ struct Counter { + │ ------- To satisfy the constraint, the 'key' ability would need to be added here + · +7 │ move_to(account, Counter { value: 0 }); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ The type 'MyCounter::MyCounter::Counter' does not have the ability 'key' + │ Invalid call of 'move_to' +``` + +出错了!提示我们 "ability constraint not satisfied", 下面还有一句 "The type 'MyCounter::MyCounter::Counter' does not have the ability 'key'"。 +编译器告诉我们 'MyCounter::MyCounter::Counter' 这个资源类型缺少 `key` ability,所以不能用 `move_to` 添加到账户地址下。 + +这里涉及到了 move 的 ability 特性。 + +:::tip 概念 —— ability +Move语言是面向资源的语言,核心是资源的管理。 +针对资源拥有什么“**能力**”,Move 编程语言抽象了资源的四个属性——可复制(copy)、可索引(key)、可丢弃(drop)、可储存(store)。 +通过这四个属性的不同组合,用户可以方便的定义出任何能力的资源。 +比如用户可以通过 key + copy + drop + store 的组合定义出一个普通的信息类型,通过 key + store 的组合定义出一个资产类型——例如 NFT ——没有 copy 属性可以保证 NFT 不能被随意的复制,提升了安全性。 + +四种 ability: + +* copy: 表示该值是否可以被复制 +* drop: 表示该值是否可以在作用域结束时可以被丢弃 +* key: 表示该值是否可以作为全局状态的键进行访问 +* store: 表示该值是否可以被存储到全局状态 + +通过给资源赋予不同的能力,Move 虚拟机可以从根本上保证「资源」只能转移(move),至于能否拷贝、修改、丢弃,看资源的具体能力。 +如果强行拷贝、修改或者丢弃,代码编译会出错,根本没有机会运行。 + +更多信息可以参考:[认识 Ability](./03-understanding-ability.md) 章节。 +::: + +一般来说我们认为,**有 `key` ability 的结构体,就是资源**。 + +我们修改代码,按照提示添加 `key` ability。 + +```move title="my-counter/sources/MyCounter.move" {2} +module MyCounter::MyCounter { + struct Counter has key, store { + value: u64, + } + + public fun init(account: &signer) { + move_to(account, Counter { value: 0 }); + } +} +``` + +此时再次编译可以通过。 + +### 计数器加一的方法 incr + +现在给 Counter 资源添加一个方法,`incr`。 + +```move title="my-counter/sources/MyCounter.move" {3,13-16} +module MyCounter::MyCounter { + + use StarcoinFramework::Signer; + + struct Counter has key { + value: u64, + } + + public fun init(account: &signer) { + move_to(account, Counter { value: 0 }); + } + + public fun incr(account: &signer) { + let counter = borrow_global_mut(Signer::address_of(account)); + counter.value = counter.value + 1 + } +} +``` + +注意第3行我们引用了一个依赖 —— [StarcoinFramwork](https://github.com/starcoinorg/starcoin-framework)。 +可以认为是 Starcoin 的 Stdlib 标准库。我们需要使用库中的 Signer::address_of(&signer) 方法来提取 signer 的地址。 + +为了添加依赖到项目中,修改 Move.toml 文件 + +```toml title="my-counter/Move.toml" {6,9-10} +[package] +name = "my-counter" +version = "0.0.1" + +[addresses] +StarcoinFramework = "0x1" +MyCounter = "0xcada49d6a37864931afb639203501695" + +[dependencies] +StarcoinFramework = {git = "https://github.com/starcoinorg/starcoin-framework.git", rev="cf1deda180af40a8b3e26c0c7b548c4c290cd7e7"} +``` + + +第16行有个新方法 `borrow_global_mut`,和前文的 `move_to` 一样,都是操作操作账户地址的存储空间上资源的内置方法。 + +:::tip 加油站 —— 资源的操作方法 +1. `move_to(&signer, T)`:发布、添加类型为 T 的资源到 signer 的地址下。 +2. `move_from(address): T`:从地址下删除类型为 T 的资源并返回这个资源。 +3. `borrow_global(address): &T`:返回地址 address 下类型为 T 的资源的不可变引用(immutable reference)。 +4. `borrow_global_mut(address): &mut T`:返回地址 address 下类型为 T 的资源的可变引用(mutable reference)。 +5. `exists(address): bool`:判断地址 address 下是否有类型为 T 的资源 + +要使用这些方法,资源 T 必须定义在当前 module。 +**这确保了资源只会被定义资源的 module 提供的 API 方法来操作**。 +参数 address 和 signer 代表了类型为 T 的资源存储的地址。 +::: + +然后我们试着编译一下: + +``` +$ mpm package build + +BUILDING StarcoinFramework +BUILDING my-counter +error[E04020]: missing acquires annotation + ┌─ ./sources/MyCounter.move:14:23 + │ +14 │ let counter = borrow_global_mut(Signer::address_of(account)); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ The call acquires 'MyCounter::MyCounter::Counter', but the 'acquires' list for the current function does not contain this type. It must be present in the calling context's acquires list + │ Invalid call to borrow_global_mut. +``` + +哦!又出错了。报错信息提示了我们第十四行的调用“需要” Counter 结构,但是没有在函数定义的 `acquires list` 中列出。 + +这里我们引入 `acquire` 的概念。 + +:::tip 概念 +当一个函数用 `move_from()`、`borrow_global()`、`borrow_global_mut()` 访问资源时,函数必须要显示声明需要“**获取**”哪种资源。 +这会被 Move 的类型系统确保对资源的引用是安全的、不存在悬空引用。 +::: + +修改后的代码如下 +```move title="my-counter/sources/MyCounter.move" {13} +module MyCounter::MyCounter { + + use StarcoinFramework::Signer; + + struct Counter has key { + value: u64, + } + + public fun init(account: &signer) { + move_to(account, Counter { value: 0 }); + } + + public fun incr(account: &signer) acquires Counter { + let counter = borrow_global_mut(Signer::address_of(account)); + counter.value = counter.value + 1 + } +} +``` + +现在可以编译通过了。 + +下面我们编写可以通过控制台直接调用执行的函数。 + +### 编写可调用的 script function + +前面编写的两个 `public fun` init 和 incr 两个函数是不能直接在控制台中调用执行的。需要使用 入口方法(entry function)来调用。 + +目前在 Move 中,入口方法是通过 `script function` 来实现的,写作 `public(script) fun`。 + +这里引入了函数可见性(visibility)的概念,不同的可见性决定了函数可以从何处被调用。(下面的 概念tip 可以先跳过) + +:::tip 概念——函数可见性 +| 可见性 | 写做 | 说明 | +| -------------- | ------------------ | ----------- | +| internal | fun | 也可以叫 private,只能在同一个 module 内调用 | +| public | public fun | 可以被任一 module 内的函数调用 | +| **public script** | public(script) fun | script function 是 module 中的入口方法 ,可以**通过控制台发起一个transaction 来调用**,就像本地执行脚本一样(不过代码已经被存在了链上的 module 地址下)。 | +| public friend | public(friend) fun | 可以被同一 module 内调用,可以被加入到 `friend list` 的可信任 module 调用 | +::: + +下面,我们编写对应 init 和 incr 函数的 script function。 + +```move title="my-counter/sources/MyCounter.move" {18-24} +module MyCounter::MyCounter { + + use StarcoinFramework::Signer; + + struct Counter has key, store, drop { + value: u64, + } + + public fun init(account: &signer) { + move_to(account, Counter { value: 0 }); + } + + public fun incr(account: &signer) acquires Counter { + let counter = borrow_global_mut(Signer::address_of(account)); + counter.value = counter.value + 1 + } + + public(script) fun init_counter(account: signer) { + Self::init(&account); + } + + public(script) fun incr_counter(account: signer) acquires Counter { + Self::incr(&account); + } +} +``` + +唯一需要说明的就是 `Self` 指代当前 module。 + +现在,我们将 module 发布到链上,并尝试调用。 + +## 发布到链上并调用 + +### 发布到链上 + +运行 mpm release 命令 +```shell +$ mpm release + +Packaging Modules: + 0xcada49d6a37864931afb639203501695::MyCounter +Release done: release/my-counter.v0.0.1.blob, package hash: 0x31b36a1cd0fd13e84034a02e9972f68f1c9b1cde1c9dfbe7ac69f32f6fc6dafa +``` + +它将打包编译 module,获得二进制包。 + +前文中我们准备了地址为 0xcada49d6a37864931afb639203501695 的账户,如果没有余额,可以通过 `dev get-coin` 命令获取一些测试币。 +现在将编译好的 module 部署到这个账户地址下。 + +```starcoin title="starcoin控制台" {1,3,5} +starcoin% account unlock 0xcada49d6a37864931afb639203501695 -p [your_pass_or_ignore] + +starcoin% dev deploy /path/to/my-counter/release/my-counter.v0.0.1.blob -s 0xcada49d6a37864931afb639203501695 -b + +txn 0xf60662ba0ac3373c28f827a0ac9d9db6667c3921056905356aa5414b3bf3df09 submitted. +{ + "ok": { + "dry_run_output": { + "events": [], + "explained_status": "Executed", + "gas_used": "7800", + "status": "Executed", + "write_set": [ + { + "access_path": "0x00000000000000000000000000000001/1/0x00000000000000000000000000000001::TransactionFee::TransactionFee<0x00000000000000000000000000000001::STC::STC>", + "action": "Value", + "value": { + "Resource": { + "json": { + "fee": { + "value": 292331 + } + }, + "raw": "0xeb750400000000000000000000000000" + } + } + }, +... +``` + +-s 即 --sender 是发送者,-b 是 blocking,阻塞等待命令执行完成。 + +第五行的 txn 0xf60662... submitted. 说明将 module 发布到地址下的操作,也是一个链上的 transaction。 + +此时我们可以查看代码在链上的存储, + +```starcoin title="starcoin控制台" {1} +starcoin% state list code 0xcada49d6a37864931afb639203501695 + +{ + "ok": { + "codes": { + "MyCounter": { + "abi": { + "module_name": { + "address": "0xcada49d6a37864931afb639203501695", + "name": "MyCounter" + }, + ... +} +``` + +可以看到 0xcada49d6a37864931afb639203501695 地址下只有 MyCounter 这一个 code。 + +:::note state 命令 +state 命令是用来查看账户地址下的数据的。可以在控制台中输入 `state --help` 查看更多帮助。 +::: + +### 调用 init_counter 初始化资源 + +使用 `account execute-function` 命令来执行一个 script function。现在我们调用 init_counter 方法,将 Counter 资源初始化到调用者的地址下。 + +```starcoin title="starcoin控制台" {1} +starcoin% account execute-function --function 0xcada49d6a37864931afb639203501695::MyCounter::init_counter -s 0xcada49d6a37864931afb639203501695 -b + +txn 0x032c0eda779157e0ef3949338c3b3e4e6528c7720776d02c2cb0ddd64804f1c2 submitted. +{ + "ok": { + "dry_run_output": { + "events": [], + "explained_status": "Executed", + "gas_used": "11667", + "status": "Executed", + "write_set": [ +... +} +``` + +init_counter 函数中,我们初始化了一个 Counter 对象(资源),然后 move_to 到了调用者地址下。 +让我们看看这个资源是否存在。使用 `state list resource
` 命令查看给定地址下的资源列表。 + +```starcoin title="starcoin控制台" {1} +starcoin% state list resource 0xcada49d6a37864931afb639203501695 + +{ + ...(输出很多,我们观察最后一部分) + "0xcada49d6a37864931afb639203501695::MyCounter::Counter": { + "json": { + "value": 0 + }, + "raw": "0x0000000000000000" + } +} +``` + +可以看到地址 0xcada49d6a37864931afb639203501695 下有了 `0xcada49d6a37864931afb639203501695::MyCounter::Counter` 这个类型的资源,内容是 `"value": 0`。 + +可能有小伙伴会疑惑为什么 Counter 资源类型名要写这么长,下面先帮大家回忆一下 FQN 的概念。 + +:::tip 概念——完整名称 FQN +Fully Qualified Name(FQN) 是一种计算机术语,是在一个调用上下文中,对一个资源(对象、函数、域名、文件)名称的无歧义定义。举例来说: + +1. linux 的绝对路径名 `/path/to/file` 就是 fully qualified file name,相对的 `./to/file` 是一个相对路径地址。 +2. 域名系统中,`google.com.` 是一个 fully qualified domain name,注意最后的 `.`。意味着这个域名不要继续被递归解析。 + +那么对应到 Move 语言中,资源类型是发布到某个地址下的,属于这个地址。 +地址 0x001 可以创建一个 Counter 类型的资源,地址 0x002 也可以创建一个 Counter 类型的资源,要区分两个 Counter,就需要带上地址和模块名。 + +``` +
:::: +``` +::: + +### 调用 incr_counter 递增计数器 + +下面调用另一个函数 incr_counter 尝试对计数器加一。 + +```starcoin title="starcoin控制台" {1} +starcoin% account execute-function --function 0xcada49d6a37864931afb639203501695::MyCounter::incr_counter -s 0xcada49d6a37864931afb639203501695 -b + +txn 0x032c0eda779157e0ef3949338c3b3e4e6528c7720776d02c2cb0ddd64804f1c2 submitted. +... +``` + +再次查看资源,有了前面 FQN 的概念,这次我们换一个命令,用 `state get resource
[RESOURCE_TYPE]` 查看 ADDRESS 下特定的资源类型。 + +```starcoin title="starcoin控制台" {1} +starcoin% state get resource 0xcada49d6a37864931afb639203501695 0xcada49d6a37864931afb639203501695::MyCounter::Counter + +{ + "ok": { + "json": { + "value": 1 + }, + "raw": "0x0100000000000000" + } +} +``` + +可以看到计数器的值 value 变为了 1。 + +### 另一个账号调用 + +前面的例子中,我们用了同一个地址 0xcada49d6a37864931afb639203501695 来发布 module、创建 Counter 资源类型(dev deploy),以及调用函数添加计数器(account execute-function)。 + +我们再换一个账号来初始化计数器和自增计数器。假设本地的一个账号为 0x012ABC + +```starcoin title="starcoin控制台" +starcoin% account execute-function -s 0x012ABC --function 0xb19b07b76f00a8df445368a91c0547cc::MyCounter::init_counter -b + +starcoin% state get resource 0x012ABC 0xcada49d6a37864931afb639203501695::MyCounter::Counter +``` + +读者可以自行观察 0x012ABC 下资源的变化。 + + +:::info 历史 —— script 和 script function +为了防止大家在别处看的教程中有 `script` 出现而搞迷惑,这里简单说一下历史由来。*这部分内容可以跳过*。 + +我们用 Python 的 pip 或者 Node.js 的 npm 来辅助理解。 + +在 pip 和 npm 这样的中心化包管理托管平台出现之前,我们想安装一个包,需要 `setup.py install /path/to/package`。 +这样子当然不便于包的分发传播与索引。后来有了 pip 我们是怎么做的呢,包作者先将自己的包打包上传到 pip 仓库,pip会存储包并建立索引。 +普通用户只需要 `pip install package_name` 即可。pip 工具会帮你根据 package_name 下载源码,然后执行安装。这两种方式安装包其实是一样的。 + +现在对应到 Move 中。在 script function 出现之前是只有 script 的,script 写在和 sources/ 平级的 scripts/ 目录下。 + +script 就像是本地的 python包,script可以被编译为字节码,要调用 script 时,需要创建一个 transaction,payload 中带上编译好的字节码,script就可以被 node 上的 Move虚拟机执行了。对应在 starcoin 控制台中是 + +``` +starcoin% account execute-script +``` + +`script function` 作为 `script` 的替代,[被添加到了 Move 语言中](https://github.com/move-language/move/commit/e0a3acb7d5e3f5dbc07ee76b47dd05229584d4d0)。 +类比于保存在 pip 仓库中的软件包。script function 会在 module 中一起发布到一个地址下(就像包作者把软件包发布在pip中一样)。 +此时,要调用 script,需要创建一个 transaction,payload 中指向已经发布的代码的地址即可。对应到 starcoin 控制台中是 + +``` +starcoin% account execute-function --function <0x地址>::<模块>::<函数> --arg xxx +``` + +当然,Move 也是一门正在演进的语言,`public(script) fun` [正在被 `public entry` 取代](https://github.com/move-language/move/pull/186),让我们拭目以待。 + +总结一下: + +1. `script` 可能会被废弃,推荐用 `script function` 做入口方法。 +2. 下个版本的 Move 会用 `public entry fun` 替代 `public(script) fun` +::: + +## 何去何从 + +恭喜你,你已经完成了一个简单合约的编写、部署和调用的全流程。 + +完整的代码仓库在[这里](https://github.com/starcoinorg/starcoin-cookbook/tree/main/examples/my-counter)。 + +接下来, +* 你可以通过 [Move 语言](./move-language/)系统的学习 Move 语言 +* 查看[更多 Move 例子] +* 了解[如何 Debug/测试 Move module](./97-move-test/01-move-unit-test.md) +* 了解 [Starcoin Move Framework](./starcoin-framework/) +* 可以通过 [Move高级开发] 学习高级 Move. +* 了解 [Move 规范语言 和 Move Prover](./100-move-prover/01-move-spec-language.md) 开发更安全的 Move 应用 +* 探索 [Move 包管理器](./04-move-package-manager.md)的更多功能 + +或者,你可以直接进入 Dapp 的世界, +* [Web3 和 DApp 开发](../web3/) diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/04-web3/01-starmask/01-onboarding-library.md b/i18n/zh/docusaurus-plugin-content-docs/current/04-web3/01-starmask/01-onboarding-library.md new file mode 100644 index 000000000..ee740ddbc --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/current/04-web3/01-starmask/01-onboarding-library.md @@ -0,0 +1,192 @@ +# 入门库 + +作为支持 Starcoin 的网站开发人员,将用户发送到异地安装 StarMask 会带来挑战。 +最值得注意的是,您必须通知用户在安装后返回您的站点并刷新他们的浏览器。 +只有在刷新之后,您的站点才会检测到用户新安装的 StarMask 扩展。 +我们 StarMask 非常关心用户体验,我们知道这个工作流程需要改进。 + +StarMask 现在提供了一个 starmask 入门库,旨在改善和简化入门体验。 +新库公开了一个 API 来启动入门流程。在此过程中,它将您的站点注册为入门请求的来源。 +StarMask 将在用户完成入门流程后检查此来源。 +如果找到来源,StarMask 入门流程的最终确认按钮将指示用户将被重定向回您的站点。 + +## 开始使用 + +1. 使用 npm 或 yarn 安装 `@starcoin/starmask-onboarding`。 + +2. 导入入门库或将其包含在您的页面中。 + +```javascript +// 作为一个 ES6 模块 +import StarMaskOnboarding from "@starcoin/starmask-onboarding"; +// 或者作为一个 ES5 模块 +const StarMaskOnboarding = require("@starcoin/starmask-onboarding"); +``` + +如果您愿意,可以改为包含库附带的预构建 ES5 包: + +```html + +``` + +3. 创建 Onboarding 库的新实例 + +```javascript +const onboarding = new StarMaskOnboarding(); +``` + +4. 响应用户事件(例如,单击按钮)启动入门流程。 + +```javascript +onboarding.startOnboarding(); +``` + +## 例子 + +### 基本用法 + +```javascript +const onboarding = new StarMaskOnboarding(); +onboarding.startOnboarding(); +``` + +### 使用 React + +```jsx +import StarMaskOnboarding from "@starcoin/starmask-onboarding"; +import React from "react"; + +const ONBOARD_TEXT = "Click here to install StarMask!"; +const CONNECT_TEXT = "Connect"; +const CONNECTED_TEXT = "Connected"; + +export function OnboardingButton() { + const [buttonText, setButtonText] = React.useState(ONBOARD_TEXT); + const [isDisabled, setDisabled] = React.useState(false); + const [accounts, setAccounts] = React.useState([]); + const onboarding = React.useRef(); + + React.useEffect(() => { + if (!onboarding.current) { + onboarding.current = new StarMaskOnboarding(); + } + }, []); + + React.useEffect(() => { + if (StarMaskOnboarding.isStarMaskInstalled()) { + if (accounts.length > 0) { + setButtonText(CONNECTED_TEXT); + setDisabled(true); + onboarding.current?.stopOnboarding(); + } else { + setButtonText(CONNECT_TEXT); + setDisabled(false); + } + } + }, [accounts]); + + React.useEffect(() => { + function handleNewAccounts(newAccounts) { + setAccounts(newAccounts); + } + if (StarMaskOnboarding.isStarMaskInstalled()) { + window.starcoin + .request({ method: "stc_requestAccounts" }) + .then(handleNewAccounts); + window.starcoin.on("accountsChanged", handleNewAccounts); + return () => { + window.starcoin.removeListener("accountsChanged", handleNewAccounts); + }; + } + }, []); + + const onClick = () => { + if (StarMaskOnboarding.isStarMaskInstalled()) { + window.starcoin + .request({ method: "stc_requestAccounts" }) + .then((newAccounts) => setAccounts(newAccounts)); + } else { + onboarding.current?.startOnboarding(); + } + }; + return ( + + ); +} +``` + +### 使用 TypeScript + +我们使用 `@starcoin/starmask-onboarding` 发布我们的 TypeScript 类型。 +在使用 `onboarding` 库时修改上面的示例以获得类型安全很简单: + +```jsx + -const onboarding = React.useRef(); + +const onboarding = React.useRef(); +``` + +执行此步骤将为您提供库公开的方法的编辑器自动完成功能,并提供有用的文档。 + +![Editor Highlighting](../../../../../../static/img/onboarding-library-1.png) + +### 使用 Vanilla Javascript + HTML + +```html + + + + StarMask Onboarding Example + + + +

Sample Dapp

+ + + + + +``` + +## Onboarding Diagram + +这是载入库、转发器和扩展程序之间的交互图: + +![Onboarding Library Diagram](../../../../../../static/img/onboarding-diagram.png) diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/04-web3/02-starcoin-json-rpc.md b/i18n/zh/docusaurus-plugin-content-docs/current/04-web3/02-starcoin-json-rpc.md new file mode 100644 index 000000000..8f6123501 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/current/04-web3/02-starcoin-json-rpc.md @@ -0,0 +1,25 @@ +# Starcoin Json RPC + +> `account.*` 和 `node_manager.*` 在 主网和 Barnard/Proxima/Halley 等测试网上不可访问。 只有你自己搭建的节点启动时设置了 public 才能访问。 + +## [account](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/account.json) + +## [chain](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/chain.json) + +## [contract_api](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/contract_api.json) + +## [debug](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/debug.json) + +## [miner](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/miner.json) + +## [network_manager](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/network_manager.json) + +## [node](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/node.json) + +## [node_manager](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/node_manager.json) + +## [state](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/state.json) + +## [sync_manager](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/sync_manager.json) + +## [txpool](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/starcoinorg/starcoin/master/rpc/generated_rpc_schema/txpool.json) diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/04-web3/04-interacting-with-the-contract.md b/i18n/zh/docusaurus-plugin-content-docs/current/04-web3/04-interacting-with-the-contract.md new file mode 100644 index 000000000..d7749b234 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/current/04-web3/04-interacting-with-the-contract.md @@ -0,0 +1,8 @@ +# Interaction with the contract by RPC and SDK + +TODO + +1. write to contract, execute a transaction +2. read to contract +3. watch events +4. view resource \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/04-web3/05-understanding-resource-and-bcs/01-bcs.md b/i18n/zh/docusaurus-plugin-content-docs/current/04-web3/05-understanding-resource-and-bcs/01-bcs.md new file mode 100644 index 000000000..ab01e4edb --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/current/04-web3/05-understanding-resource-and-bcs/01-bcs.md @@ -0,0 +1,256 @@ +# 二进制规范序列化(BCS) + +BCS(以前称为“Libra Canonical Serialization”或 LCS)是在 [Diem](https://diem.com) 区块链的背景下开发的一种序列化格式。 + +BCS 的设计考虑了以下主要目标: + +* 提供良好的性能和简洁的(二进制)表示; +* 支持丰富的 Rust 常用数据类型; +* 强制规范序列化,这意味着给定类型的每个值都应该有一个有效的表示。 + +BCS 还旨在通过在(反)序列化期间对大型或嵌套容器实施明确定义的限制来减轻恶意输入的后果。 + +## Rust 实现 + +这个 crate 提供了 BCS 的 Rust 实现作为 [Serde 库](https://serde.rs)的编码格式。 +因此,此实现涵盖了 Serde 支持的大多数数据类型——包括用户定义的结构、标记变体(Rust 枚举)、元组和映射——不包括浮点数、单个 Unicode 字符(char)和集合。 + +由于单独的项目 [serde-reflection](https://github.com/novifinancial/serde-reflection),BCS 也可用于其他编程语言。 + +## 应用于密码学 + +BCS 格式保证规范的序列化,这意味着对于任何给定的数据类型,内存中的值和有效的字节表示之间存在一对一的对应关系。 + +在加密应用程序的上下文中,规范序列化有几个好处: + +* 它提供了一种自然而可靠的方法来将内存中的值与加密哈希相关联。 +* 它允许将消息的签名等效地定义为序列化字节的签名或内存中值的签名。 + +请注意,BCS 分别确保每种数据类型的规范序列化。 +序列化值的数据类型必须由应用程序本身强制执行。 +通常使用每种数据类型的唯一哈希种子来满足此要求。(有关示例,请参见 [Diem 的密码库](https://github.com/diem/diem/blob/master/crypto/crypto/src/hash.rs)。) + +## 向后兼容性 + +根据设计,BCS 不提供隐式版本控制或向后/向前兼容性,因此应用程序必须提前仔细计划临时扩展点: + +* 枚举可用于显式版本控制和向后兼容性(例如可扩展查询接口)。 +* 在某些情况下,还可以添加 `Vec` 类型的数据字段以允许(未来)序列化形式的未知有效负载。 + +## 详细规格 + +BCS 支持以下数据类型: + +* 布尔值(Booleans) +* 有符号 8 位(Signed 8-bit)、16 位、32 位、64 位和 128 位整数(integers) +* 无符号 8 位(Unsigned 8-bit)、16 位、32 位、64 位和 128 位整数(integers) +* 选项(Option) +* 单位(Unit)(空值) +* 固定和可变长度序列(Fixed and variable length sequences) +* UTF-8 编码字符串 +* 元组(Tuples) +* 结构(Structures)(又名“structs”) +* 外部标记的枚举(Externally tagged enumerations)(又名“enums”) +* 映射(Maps) + +BCS 不是一种自我描述的格式。 + +因此,为了反序列化消息,必须提前知道消息类型和布局。 + +除非指定,否则所有数字都以 little endian、二进制补码格式存储。 + +### BCS 数据的递归和深度 + +允许使用递归数据结构(例如树)。 +但是,由于(反)序列化过程中可能发生堆栈溢出,任何有效 BCS 数据的容器深度都不能超过常量 `MAX_CONTAINER_DEPTH`。 +形式上,我们将容器深度定义为(反)序列化期间遍历的结构和枚举的数量。 + +此定义旨在最小化操作数量,同时确保已知 BCS 格式的(反)序列化不会导致任意大的堆栈分配。 + +例如,如果 `v1` 和 `v2` 是深度 `n1` 和 `n2` 的值, + +* 结构值 `Foo { v1, v2 }` 的深度为 `1 + max(n1, n2)`; +* 枚举值 `E::Foo { v1, v2 }` 的深度为 `1 + max(n1, n2)`; +* 一对 `(v1, v2)` 的深度为 `max(n1, n2)`; +* `Some(v1)` 的值具有深度 `n1`。 + +所有字符串和整数值的深度都为 `0`。 + +### 布尔值和整数 + +|Type |Original data |Hex representation |Serialized bytes | +|--- |--- |--- |--- | +|Boolean |True / False |0x01 / 0x00 |01 / 00 | +|8-bit signed integer |-1 |0xFF |FF | +|8-bit unsigned integer |1 |0x01 |01 | +|16-bit signed integer |-4660 |0xEDCC |CC ED | +|16-bit unsigned integer |4660 |0x1234 |34 12 | +|32-bit signed integer |-305419896 |0xEDCBA988 |88 A9 CB ED | +|32-bit unsigned integer |305419896 |0x12345678 |78 56 34 12 | +|64-bit signed integer |-1311768467750121216 |0xEDCBA98754321100 |00 11 32 54 87 A9 CB ED | +|64-bit unsigned integer |1311768467750121216 |0x12345678ABCDEF00 |00 EF CD AB 78 56 34 12 | + +### ULEB128 编码整数 + +BCS 格式还在内部使用 [ULEB128 编码](https://en.wikipedia.org/wiki/LEB128)来表示无符号 32 位整数,这两种情况通常需要小值:(1) 可变长度序列的长度和 (2) 枚举值的标记(请参阅下面的相应部分)。 + +|Type |Original data |Hex representation |Serialized bytes | +|--- |--- |--- |--- | +|ULEB128-encoded u32-integer|2^0 = 1 |0x00000001 |01 | +| |2^7 = 128 |0x00000080 |80 01 | +| |2^14 = 16384 |0x00004000 |80 80 01 | +| |2^21 = 2097152 |0x00200000 |80 80 80 01 | +| |2^28 = 268435456 |0x10000000 |80 80 80 80 01 | +| |9487 |0x0000250f |8f 4a | + +通常,ULEB128 编码由基本128(7位)数字的小序列组成。 +每个数字都通过将最高位设置为1来完成为一个字节,除了最后一个(最高)数字的数字将最高位设置为0。 + +在BCS中,需要解码 ULEB128 字节的结果才能适合32位无符号整数并处于规范形式。例如,以下值被拒绝: + +* 80 80 80 80 80 01 (2^36) 太大。 +* 80 80 80 80 10 (2^33) 太大。 +* 80 00 不是 0 的最小编码。 + +### 可选数据 + +可选或可为空的数据要么以其完整表示形式存在,要么不存在。 +BCS 将其表示为单个字节,表示数据的存在 `0x01` 或不存在 `0x00`。如果数据存在,则该数据的序列化形式如下。例如: + +```rust +let some_data: Option = Some(8); +assert_eq!(to_bytes(&some_data)?, vec![1, 8]); + +let no_data: Option = None; +assert_eq!(to_bytes(&no_data)?, vec![0]); +``` + +### 固定和可变长度序列 + +序列可以由任何 BCS 支持的类型(甚至是复杂结构)组成,但序列中的所有元素必须属于同一类型。 +如果序列的长度是固定的并且众所周知,那么 BCS 将其表示为序列中每个单独元素的序列化形式的串联。 +如果序列的长度是可变的,则序列化序列的长度以 ULEB128 编码的无符号整数为前缀,指示序列中元素的数量。 +所有可变长度序列的长度必须为 `MAX_SEQUENCE_LENGTH` 个元素或更少。 + +```rust +let fixed: [u16; 3] = [1, 2, 3]; +assert_eq!(to_bytes(&fixed)?, vec![1, 0, 2, 0, 3, 0]); + +let variable: Vec = vec![1, 2]; +assert_eq!(to_bytes(&variable)?, vec![2, 1, 0, 2, 0]); + +let large_variable_length: Vec<()> = vec![(); 9_487]; +assert_eq!(to_bytes(&large_variable_length)?, vec![0x8f, 0x4a]); +``` + +### 字符串 + +仅支持有效的 UTF-8 字符串。 +BCS 将此类字符串序列化为可变长度字节序列,即长度以 ULEB128 编码的无符号整数为前缀,后跟字符串的字节表示。 + +```rust +// Note that this string has 10 characters but has a byte length of 24 +let utf8_str = "çå∞≠¢õß∂ƒ∫"; +let expecting = vec![ + 24, 0xc3, 0xa7, 0xc3, 0xa5, 0xe2, 0x88, 0x9e, 0xe2, 0x89, 0xa0, 0xc2, + 0xa2, 0xc3, 0xb5, 0xc3, 0x9f, 0xe2, 0x88, 0x82, 0xc6, 0x92, 0xe2, 0x88, 0xab, +]; +assert_eq!(to_bytes(&utf8_str)?, expecting); +``` + +### 元组 + +元组是对象的类型组合:`(Type0,Type1)` + +元组被认为是一个固定长度的序列,其中序列中的每个元素都可以是 BCS 支持的不同类型。 +元组的每个元素都按照它在元组中定义的顺序进行序列化,即 [tuple.0, tuple.2]。 + +```rust +let tuple = (-1i8, "diem"); +let expecting = vec![0xFF, 4, b'd', b'i', b'e', b'm']; +assert_eq!(to_bytes(&tuple)?, expecting); +``` + +### 结构 + +结构是由可能具有不同类型的字段组成的固定长度序列。 +结构中的每个字段都按照规范结构定义指定的顺序进行序列化。 +结构可以存在于其他结构中,因此,BCS 递归到每个结构中并按顺序序列化它们。 +序列化格式中没有标签,结构排序定义了序列化流中的组织。 + +```rust +#[derive(Serialize)] +struct MyStruct { + boolean: bool, + bytes: Vec, + label: String, +} + +#[derive(Serialize)] +struct Wrapper { + inner: MyStruct, + name: String, +} + +let s = MyStruct { + boolean: true, + bytes: vec![0xC0, 0xDE], + label: "a".to_owned(), +}; +let s_bytes = to_bytes(&s)?; +let mut expecting = vec![1, 2, 0xC0, 0xDE, 1, b'a']; +assert_eq!(s_bytes, expecting); + +let w = Wrapper { + inner: s, + name: "b".to_owned(), +}; +let w_bytes = to_bytes(&w)?; +assert!(w_bytes.starts_with(&s_bytes)); + +expecting.append(&mut vec![1, b'b']); +assert_eq!(w_bytes, expecting); +``` + +### 外部标记的枚举 + +枚举通常表示为可以采用许多不同变体之一的类型。 +在 BCS 中,每个变体都映射到变体索引,即 ULEB128 编码的 32 位无符号整数,如果类型具有关联值,则后跟序列化数据。 +关联类型可以是任何 BCS 支持的类型。 +变体索引是根据规范枚举定义中变体的顺序确定的,其中第一个变体的索引为 `0`,第二个变体的索引为 `1`,依此类推。 + +```rust +#[derive(Serialize)] +enum E { + Variant0(u16), + Variant1(u8), + Variant2(String), +} + +let v0 = E::Variant0(8000); +let v1 = E::Variant1(255); +let v2 = E::Variant2("e".to_owned()); + +assert_eq!(to_bytes(&v0)?, vec![0, 0x40, 0x1F]); +assert_eq!(to_bytes(&v1)?, vec![1, 0xFF]); +assert_eq!(to_bytes(&v2)?, vec![2, 1, b'e']); +``` + +如果您需要序列化 C 风格的枚举,您应该使用原始整数类型。 + +### 映射(键/值存储) + +映射表示为 `(键, 值)` 元组的可变长度、排序序列。 +键必须是唯一的,并且元组按每个键的 BCS 字节的字典顺序递增排序。 +该表示在其他方面类似于可变长度序列的表示。特别是,它前面是元组的数量,用 ULEB128 编码。 + +```rust +let mut map = HashMap::new(); +map.insert(b'e', b'f'); +map.insert(b'a', b'b'); +map.insert(b'c', b'd'); + +let expecting = vec![(b'a', b'b'), (b'c', b'd'), (b'e', b'f')]; + +assert_eq!(to_bytes(&map)?, to_bytes(&expecting)?); +``` diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/04-web3/README.md b/i18n/zh/docusaurus-plugin-content-docs/current/04-web3/README.md new file mode 100644 index 000000000..3803b8194 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/current/04-web3/README.md @@ -0,0 +1,234 @@ +# Dapp 开发指南 + +本文档通过介绍 Dapp 的整体开发流程,讲解开发过程中涉及的相关知识以及工具链,帮助您基于 Starcoin 快速构建属于自己的 Dapp。 + +## 开发流程 + +任何公链的 Dapp,从前端页面开始,最终调用到链上部署的智能合约,都包含以下的主要环节: + +![dapp_1](../../../../../static/img/dapp/dapp_1.png) + +这里以 Starcoin 为例进行讲解,上图涉及到的主要组件有: + +1. 交互入口页面; +2. 跟链节点通讯的 SDK; +3. 也可能通过浏览器插件钱包 StarMask 跟链的节点通讯(实际上,StarMask 也是调用了 JS 的 SDK); +4. 启动链的节点; +5. 链上部署的合约; + +上面提到的每一步都涉及到相关的知识和可用的工具,如下图所示: + +![dapp_2](../../../../../static/img/dapp/dapp_2.png) + +这里按从左到右的顺序,先简单介绍一下开发者比较关心的内容(后面会展开介绍): + +1. 入门 Dapp:适合想快速了解和体验 Dapp,或者想开发 Dapp 页面的前端开发者; +2. StarMask API:Dapp 开发中经常会遇到签名等场景,需要调用浏览器插件钱包 StarMask 的 API,与钱包进行交互,完成用户操作以及常见的链交互; +3. SDK:SDK 是跟链交互的另一种常用方式,Starcoin 包含多语言版本的 SDK,开发者可以根据自己的需求选择对应版本的 SDK: + 1. JS SDK + 2. Java SDK + 3. Python SDK + 4. Go SDK + 5. Dart SDK +4. Starcoin 节点 RPC 接口:包含了 Starcoin 节点对外的所有服务和对应接口,开发者或者 SDK 可以通过这些接口跟链进行交互; +5. Move 智能合约:开发者通过 Move 语言将逻辑表达出来并部署到 Starcoin 链上,供所有的用户调用; + +以上是基于 Starcoin 开发 Dapp 可能涉及的主要环节和内容的简单介绍,下面将进一步对每一个环节展开来介绍。如果您只对其中的某一部分或者某一个环节感兴趣,可以直接跳转到对应的内容。 + +## 入门 Dapp + +这是一个简单的入门 Dapp,也是用户真正能够使用和感受 Dapp 的产品入口。您可以通过它快速地了解什么是 Dapp,感受 Dapp 如何跟链进行交互。如果您是开发人员,还可以通过查看它的源代码,了解一个简单的 Dapp 的代码结构,快速上手构建属于自己的 Dapp。 + +- 体验入口:https://starmask-test-dapp.starcoin.org/ + +- 代码仓库:https://github.com/starcoinorg/starmask-test-dapp + +## StarMask + +StarMask 是 Starcoin 官方发布的浏览器插件钱包,不仅是用户管理链上数字资产的一种方式,也是 Dapp 跟链上进行交互的一种选择。例如,用户对 Dapp 的交易进行签名,并将签名后的交易提交到远程节点的 Txpool 中。这里带您深入了解一下 StarMask: + +- 安装指南:https://github.com/starcoinorg/starmask-extension/blob/main/docs/how-to-install.md + +- 使用指南:https://github.com/starcoinorg/starmask-extension/blob/main/docs/zh/how-to-use.md + +## SDK + +跟链交互,除了 StarMask 这种方式,还可以选择 SDK 的方式。Starcoin 官方提供了多个语言版本的 SDK,以方便开发者通过编程的方式跟 Starcoin 节点进行交互。以下是 Starcoin 支持的 SDK: + +1. JS SDK + + - 开发者文档:https://starcoin.org/zh/developer/sdk/javascript/ + - 源代码:https://github.com/starcoinorg/starcoin.js + +2. Java SDK + + - 开发者文档:https://github.com/starcoinorg/starcoin-java#readme + - 源代码:https://github.com/starcoinorg/starcoin-java + +3. Python SDK + + - 开发者文档:https://starcoin-sdk-python.readthedocs.io + - 源代码:https://github.com/starcoinorg/starcoin-sdk-python + +4. Go SDK + + - 开发者文档:https://github.com/starcoinorg/starcoin-go/blob/main/README.md + - 源代码:https://github.com/starcoinorg/starcoin-go + +5. Dart SDK + + - 源代码:https://github.com/starcoinorg/starcoin.dart + +## Starcoin 节点&RPC 接口 + +在 Dapp 的整个生命周期中,不管是使用 StarMask 还是使用 SDK 跟链交互,最终都是在跟分布式网络里面的一个 Starcoin 节点通信。所以,一个稳定的 Starcoin 节点是 Dapp 交易能够打包上链的必要条件。Starcoin 节点对链下环境提供了统一必要的接口,这里深入介绍一下 Starcoin 节点: + +1. 选择网络 + + Starcoin 根据目标的不同,设计了多个不同的网络,覆盖了开发周期的每个阶段。包括 Dev、Test、Halley、Proxima、Barnard、Main: + + - Dev:用于本地开发 + - Test:用于单元测试和集成测试 + - Halley:总是运行 Stdlib 的 latest 版本,如果 Stdlib 变更则会立刻重置 Genesis Block, 清理原来的数据 + - Proxima:用于 Dapp 上线前测试,会定期清数据 + - Barnard:用于 Dapp 上线前测试,不删除数据,必须兼容性升级 + - Main:Starcoin 主网 + + 在启动 Starcoin 节点前,建议先根据自己的需求,选择不同的网络。 + +2. 节点安装 + + Starcoin 有多种安装方式([查看详情](https://starcoin.org/zh/developer/setup/install/)) + + - 根据不同的平台,下载对应的二进制,Starcoin 同时支持 Windows、Mac 和 Linux。[下载链接](https://github.com/starcoinorg/starcoin/releases) + - 源代码编译成二进制,[操作指南](https://starcoin.org/zh/developer/setup/build/) + - 通过 Docker 安装,[操作指南](https://starcoin.org/zh/developer/setup/run_by_docker/) + +3. 运行节点 + + 根据前面「节点安装」的不同,节点运行方式也稍微有点区别 + + - Docker 运行,[操作指南](https://starcoin.org/zh/developer/setup/run_by_docker/) + - 二进制运行,[操作指南](https://starcoin.org/zh/developer/setup/runnetwork/) + + 不管是通过哪种方式运行,需要修改-n 参数选择符合自己需求的网络。 + +4. 控制台 + + Starcoin 节点运行过程中,经常需要通过控制台连接上节点,以命令行的形式查看运行状态。Starcoin 提供了 console 命令用于连接节点,[操作指南](https://starcoin.org/zh/developer/cli/console/) + +5. 命令行操作文档 + + Starcoin 支持了丰富的命令,常用的命令如下: + + - account:账号相关的命令 + - chain:链相关的命令 + - node:节点相关的命令 + - state:状态相关的命令 + + 还有很多其他的命令,查看[更多详情](https://starcoin.org/zh/developer/cli/) + +6. RPC 协议 + + 前面介绍了跟节点相关的信息,重点介绍了通过控制台的方式访问 Starcoin 节点。实际上,还可以通过 RPC 接口的形式来访问 Starcoin 节点。可以说,这是通过编程来访问节点的最佳方式,SDK 正是通过这些 RPC 接口跟节点进行交互。这里是详细的[RPC 协议文档](https://starcoin.org/zh/developer/rpc/rpc_document/),开发者在必要的时候,可以查看 RPC 详情进行编程。 + +7. 运行原理 + + 如果您是开发者,想进一步了解 Starcoin 的原理,可以从以下方面入手: + + - 关键概念:https://starcoin.org/zh/developer/key_concepts/ + - SIPs:https://starcoin.org/zh/developer/sips/ + - 源代码:https://github.com/starcoinorg/starcoin + +## Move + +Starcoin 是第一个支持 Move 智能合约的无许可公链。 + +在区块链的场景下,开源是常态。相比过去中心化场景,对智能合约开发者来说,既要实现业务,又要兼顾安全,无疑是一个非常大的挑战。而 DeFi 等场景的安全,又显得尤为重要。正是基于这些考虑,智能合约语言 Move 把安全当成首要设计目标,从语言层面对金融场景进行安全加固,开箱即用,极大程度地降低智能合约开发者的门槛。可以说,Move 是目前唯一不影响货币功能的智能合约。 + +Move 语法简单,安全特性开箱即用,能够做到轻松上手。对于想要编写 Move 合约的开发者,Starcoin 准备了非常丰富的开发教程,完善的开发工具。 + +1. Move 教程: + +- 《[Move book](https://move-book.com/cn/index.html)》中文版 +- Move 基础篇:https://weibo.com/l/wblive/p/show/1022:2321324653445776015474 +- Move 进阶篇:https://weibo.com/l/wblive/p/show/1022:2321324655638159687840 +- Move & Dapp 实战:https://weibo.com/l/wblive/p/show/1022:2321324658455788257683 +- Move 开发实战:https://weibo.com/l/wblive/p/show/1022:2321324661355444568427 +- Move 语言设计思路:https://weibo.com/l/wblive/p/show/1022:2321324661515499208925 +- Move & DeFi 开发:https://weibo.com/tv/show/1042211:4664043403935862 +- Move & DeFi 安全:https://weibo.com/tv/show/1042211:4672003286958120 +- Move 为 DeFi 而生:https://learnblockchain.cn/article/2636 +- Move 中文社区 :https://www.movelang.io/ + +2. IDE: + +- Starcoin IDE:https://marketplace.visualstudio.com/items?itemName=starcoinorg.starcoin-ide +- Move-Package-Manager:这是一个非常轻量级的测试、发布 Move 合约的工具,[下载链接和操作指南](https://github.com/starcoinorg/guide-to-move-package-manager) + +3. 测试 + + Move 支持多种测试方案 + + - Unit Test:[指南](https://github.com/diem/diem/blob/main/language/changes/4-unit-testing.md) + - Speck Test:语法跟 UT 差不多,主要区别是 ST 会预先初始化链 + - [使用指南](https://github.com/starcoinorg/guide-to-move-package-manager/) + - [参考例子](https://github.com/starcoinorg/starcoin-framework/tree/main/spectests) + +4. 编译&部署 + + 合约完成之后,需要编译并部署到 Starcoin 的链上。部署合约也有多种方式: + + - 控制台:[操作指南](https://starcoin.org/en/developer/tutorials/deploy_move_contract/) + - starmask-test-dapp:Contract blob hex 功能,[操作入口](https://starmask-test-dapp.starcoin.org/) + - Move-Package-Manager:[move package manager 指南](https://github.com/starcoinorg/guide-to-move-package-manager) + + 这里需要注意的是,选择合适的网络进行部署。 + +5. Move[入门例子](https://starcoin.org/zh/developer/move/example/) + +## Stdlib & 协议 + +Starcoin 有 Stdlib 特性,完全使用 Move 语言开发,感兴趣的朋友可以[查看源代码](https://github.com/starcoinorg/starcoin/tree/master/vm/stdlib/modules)。 + +Starcoin 在 Stdlib 中定义了多种常用协议,如下图所示(更多协议在陆续制定中): + +![dapp_1](../../../../../static/img/dapp/pb.jpg) + +1. DAO 协议 + + DAO 协议是 Stdlib 中一个基础的协议,通过 DAO 协议能够很好的进行链上治理。这里是通过[链上治理进行代码升级](https://starcoin.org/zh/developer/blog/starcoin_stdlib_upgrade)的例子。 + +2. NFT 协议 + + - [协议介绍](https://starcoin.org/zh/developer/protocols/starcoin_nft/) + - [SIP22](https://github.com/starcoinorg/sips/blob/master/sip-22/index.zh.md) + - 源代码 + - https://github.com/starcoinorg/starcoin-framework/tree/main/sources/NFT.move + - https://github.com/starcoinorg/starcoin-framework/tree/main/sources/MerkleNFT.move + +3. Stdlib[使用指南](https://starcoin.org/zh/developer/stdlib/stdlib/) + +## 其他开发者工具 + +1. 官网 + + Starcoin 的[官网](https://starcoin.org/zh/)。通过官网能获取到非常多的信息,比如白皮书、开发者、工具链、Starcoin 最新动态等等。 + +2. 水龙头 + + 在测试过程中免不了需要测试网的 STC,比如支付 gas。开发者可以通过 Starcoin 提供的不同网络(暂时只开放 Barnad)的水龙头申请 STC: + + - Barnard:https://faucet.starcoin.org/barnard + +3. 浏览器 + + 浏览器也是常用的开发者工具,是链的一个补充。Starcoin 常用的浏览器是[stcscan](https://stcscan.io/)。 + +4. 投票 Dapp + + 投票 Dapp 也是常用的开发者工具,是 Starcoin 链上治理的入口。开发者可以通过这个 Dapp 发起自己的提案,社区会进行通过这个 Dapp 进行公开、公平、公正地投票,只有投票通过才能在链上执行。 + +5. Starcoin logos && icons + + 下载地址: https://starcoin.org/downloads/logo.zip⁣ diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/100-miscellaneous/99-contributing.md b/i18n/zh/docusaurus-plugin-content-docs/current/100-miscellaneous/99-contributing.md index d7ace06d1..da6424fb4 100644 --- a/i18n/zh/docusaurus-plugin-content-docs/current/100-miscellaneous/99-contributing.md +++ b/i18n/zh/docusaurus-plugin-content-docs/current/100-miscellaneous/99-contributing.md @@ -13,9 +13,9 @@ cd starcoin-cookbook 2. 安装 -你的机器上需要预先安装好 nodejs 以及 yarn,安装方式请参看 [yarnpkg](https://yarnpkg.com/getting-started/install)。 +你的机器上需要预先安装好 Node.js 以及 yarn,安装方式请参看 [yarnpkg](https://yarnpkg.com/getting-started/install)。 -然后在项目目录下运行: +然后在项目目录下运行下面的语句安装依赖: ```bash $ yarn @@ -29,6 +29,16 @@ $ yarn $ yarn start ``` +这样子默认是启动英文版。如果想热加载其他语言版本,比如中文zh,可以 + +```bash +$ yarn start --locale zh +``` + +:::tip 提示 +可选的 locales 标识在 `docusaurus.config.js` 中定义。 +::: + 此命令将自动打开浏览器并跳转到文档首页,当你编写或者修改文档时浏览器会自动刷新。 4. 完整构建文档并浏览 @@ -39,13 +49,19 @@ $ yarn start $ yarn build ``` +默认构建出的文档的 BaseUrl 是 `/starcoin-cookbook`, 如果你想改变它,可以在 build 之前通过环境变量指定。 + +``` +$ export BASE_URL='/' +``` + (2)运行以下命令,将在本地启动一个 Web 服务: ```bash $ yarn serve ``` -在浏览器中打开地址 `http://localhost:3000/starcoin-cookbook/`,就可以看到完整的文档。 +在浏览器中打开地址 `http://localhost:3000/starcoin-cookbook/`,就可以看到完整的文档。如果你指定了 BASE_URL 环境变量为 `/`,地址将是:`http://localhost:3000/`。 5. 提交 Pull Request diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/98-reference/01-cli/03-starcoin-db-exporter.md b/i18n/zh/docusaurus-plugin-content-docs/current/98-reference/01-cli/03-starcoin-db-exporter.md new file mode 100644 index 000000000..9b1af90e6 --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/current/98-reference/01-cli/03-starcoin-db-exporter.md @@ -0,0 +1,156 @@ +# `starcoin_db_exporter` 帮助信息 + +```shell +USAGE: + db-exporter [SUBCOMMAND] + +OPTIONS: + -h, --help Print help information + +SUBCOMMANDS: + apply-block apply block range + apply-snapshot apply snapshot + checkkey starcoin db check key + export-block-range export block range + export-snapshot export snapshot + exporter starcoin db exporter + gen-block-transactions gen block transactions + help Print this message or the help of the given subcommand(s) + startup-info-back startup info back +``` + +### `starcoin_db_exporter apply-block` 详述 + +**用法:** + +```shell +# starcoin_db_exporter apply-block 选项 检验器 +starcoin_db_exporter apply-block [OPTIONS] --net --to-path --input-path [VERIFIER] +``` + +**选项:** + +```shell +# 结构描述 + +- 选项 + - 选项原文描述 + - 选项通俗解释 +``` + +- `-h, --help` + - Print help information + - 打印帮助信息。 + +- `-i, --input-path ` + - input file, like accounts.csv + - 指定导入区块数据的 CSV 文件路径,例如:`block_1_10000.csv`。 + +- `-n, --net ` + - Chain Network + - 指定网络,例如:`main`。 + +- `-o, --to-path ` + - starcoin node db path. like ~/.starcoin/main + - 指定节点的数据目录路径,例如:`~/.starcoin/main`。 + +- `-w, --watch` + - Watch metrics logs + - 查看监控日志信息。 + +- 校验器(可选) + - ` Verify type: Basic, Consensus, Full, None, eg [possible values: basic, consensus, full, none]` + +注意:`-i`, `-n`, `-o` 是必选选项,其余的是可选选项,检验器也是可选的,有4种类型校验器,分别是 `basic`,`consensus`,`full`,`none`。 + +### `starcoin_db_exporter apply-snapshot` 详述 + +**用法:** + +```shell +starcoin_db_exporter apply-snapshot --net --to-path --input-path +``` + +**选项:** + +- `-h, --help` + - Print help information + - 打印帮助信息。 + +- `-i, --input-path ` + - input_path, manifest.csv in this dir + - 指定快照的存储路径。 + +- `-n, --net ` + - Chain Network + - 指定网络,例如:`main`。 + +- `-o, --to-path ` + - starcoin node db path. like ~/.starcoin/main + - 指定节点的数据目录路径,例如:`~/.starcoin/main`。 + +### `starcoin_db_exporter export-block-range` 详述 + +**用法:** + +```shell +starcoin_db_exporter export-block-range --net --output --db-path --start --end +``` + +**选项:** + +- `-e, --end ` + - 指定导出区块数据的起始高度。 + +- `-h, --help` + - Print help information + - 打印帮助信息。 + +- `-i, --db-path ` + - starcoin node db path. like ~/.starcoin/main + - 指定节点的数据目录路径,例如:`~/.starcoin/main`。 + +- `-n, --net ` + - Chain Network, like main, proxima + - 指定网络,例如:`main`。 + +- `-o, --output ` + - output dir, like ~/, output filename like ~/block_start_end.csv + - 指定区块数据的导出目录或文件,如果指定一个目录,文件名会根据高度参数自动生成,如:`~/block_start_end.csv`。 + +- `-s, --start ` + - 指定导出区块数据的结束高度。 + +注:`-n`,`-i`,`-o`,`-s`,`-e` 为必选选项。 + +### `starcoin_db_exporter export-snapshot` 详述 + +**用法:** + +```shell +starcoin_db_exporter export-snapshot [OPTIONS] --net --output --db-path +``` + +**选项:** + +- `-h, --help` + - Print help information + - 打印帮助信息。 + +- `-i, --db-path ` + - starcoin node db path. like ~/.starcoin/main + - 指定节点的数据目录路径,例如:`~/.starcoin/main`。 + +- `-n, --net ` + - Chain Network, like main, proxima + - 指定网络,例如:`main`。 + +- `-o, --output ` + - output dir, like ~/, manifest.csv will write in output dir + - 指定导出快照的存储目录。 + +- `-t, --increment ` + - enable increment export snapshot + - 指定是否启用增量导出,`true` 启用,`false` 禁用。 + +注:`-n`,`-o`,`-i` 是必选选项。 diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/99-concepts/04-state.md b/i18n/zh/docusaurus-plugin-content-docs/current/99-concepts/04-state.md index 5f7bf750d..85e3fa8be 100644 --- a/i18n/zh/docusaurus-plugin-content-docs/current/99-concepts/04-state.md +++ b/i18n/zh/docusaurus-plugin-content-docs/current/99-concepts/04-state.md @@ -1,4 +1,168 @@ # 状态 -交易或区块执行的最终结果由状态表示。账本状态,即Starcoin区块链的全局状态,包含链上所有账户的状态。 +需要先了解下 [SMT](05-smt.md) 。 +## 状态的实现 + +在 Starcoin 中,区块 ( `Block` ) 由一些交易 ( `Transaction` ) 组成,对一个区块的执行就是对区块内交易的执行。 +交易执行的结果由状态表示。这里采用的全局状态,包含链上所有账户的最新状态和历史状态。 +状态实际上就是账户地址 ( `AccountAddress` ) 到账户状态 ( `AccountState` ) 的映射。 +Starcoin 中状态是一颗2级的 SMT 树,如下图所示。 + +![two_level_state.png](../../../../../static/img/state/two_level_state.png) + +状态是 `AccountAddress` 到 `AccountState` 的映射,随着新的 `Block` 的执行 , `AccountState` 会变化,由于需要保留历史状态相关的证明,这里使用了 SMT 这一数据结构。 +为了方便这里把 `AccountAddress` 到 `AccountState` 的状态称为 `Account SMT`。如图中显示这里 `(AccountAddress, AccountState)` 存储在 `Account SMT` 的 `Leaf` 节点上。 +在图中就是 `Account SMT` 的根节点是 `Root_Hash`,这里对应 `BlockHeader` 中的 `state_root`。 +在 Starcoin 中 `AccountAddress` 不同于以太坊个人账户和合约账户是分开的,合约是部署在个人账户下。`AccountState` 分为两部分,分别是合约代码 ( `Code` ) 和 资源 ( `Resource` )。 +`Code` 就是账号下合约代码, `Resource` 就是类似有哪些 Token (比如 STC )。 +新 `Block` 执行, `Code` 状态和 `Resource` 状态都可能会改变。 +这样 `Code` 状态用了一棵 SMT 记为 `Code SMT`, `Resource` 状态用了一棵 SMT 记为 `Resource SMT`。 +`AccountState` 状态分为 `Code SMT` 和 `Rescoure SMT`,这样每次执行新 `Block` 后,先存储 `Code SMT` 和 `Resource SMT`, `AccountState` 只用存储 `Code SMT` 和 `Resource SMT` 的根节点。 +在图中分别为 `Code_Root_Hash1` 和 `Res_Root_Hash1`。 +当然这应该是一个事务的过程。 + +## 状态在 Starcoin 中对应代码 + +在 Starcoin 中 `Account SMT` 定义为 `ChainStateDB` +```rust +pub struct ChainStateDB { + store: Arc, + ///global state tree. + state_tree: StateTree, +} + +pub struct StateTree { + storage: Arc, + storage_root_hash: RwLock, +} + +pub enum DataType { + CODE, + RESOURCE, +} + +pub struct AccountState { + storage_roots: Vec>, +} + +struct AccountStateObject { + code_tree: Mutex>>, + resource_tree: Mutex>, + store: Arc, +} +``` +这里 `store` 对应存储的 `KvStore`, `ChainStateDB` 的成员 `state_tree` 对应 `AccountAddreee` -> `AccountState` 的 `Account SMT` 树。 +`StateTree` 的成员 `storage_root_hash` 对应 `SMT` 的根节点。 +`AccountState` 有2个 `HashValue` 元素,对应图中 `Code_Root_Hash1` 和 `Res_Root_Hash1`,也就是 `AccountStateObject` 中的 `code_tree` 和 `resource_tree` 的根节点。 +`AccountStateObject` 的成员 `code_tree` 对应 `ModuleName` -> `Vec` 的 `Code SMT` 。。 +`AccountStateObject` 的成员 `resource_tree` 对应 `StructTag` -> `Vec` 的 `Resource SMT` 。 +`ModuleName` 类似于 `Account1` (对应 starcoin-framework 里面的模块 https://github.com/starcoinorg/starcoin-framework/tree/v11/sources)。 +`struct_tag` 类似于 `0x00000000000000000000000000000001::Account::Account`。 + +可见 Starcoin 中状态是一个2级的 SMT 结构,`ChainStateDB` 对应一级 SMT , `AccountStateObject` 对应两个二级 SMT 。 + +## StateTree API 说明 + +### new +```rust +pub fn new(state_storage: Arc, state_root_hash: Option) -> Self; +``` +创建 `StateTree`, 这里 `state_storage` 对应 `KvStore`,`state_root_hash` 对应 `SMT` 的根节点, 后面的更新查找都是基于这个根节点的 SMT 。 + +### put +```rust +pub fn put(&self, key: K, value: Vec); +pub struct StateTree { + storage: Arc, + storage_root_hash: RwLock, + updates: RwLock>>, + cache: Mutex>, +} +``` +将要更新的 `(key, value)` 缓存在 `StateTree` 的成员 `updates` ,这里并没有参与 `SMT` 的计算 + +### remove +```rust +pub fn remove(&self, key: &K); +``` +一种 `value` 为 `NONE` 的特殊的 `put` 操作。 + +### commit +```rust + pub fn commit(&self) -> Result; +``` +将缓存于 `updates` 的 `(key, value)` 取出,参与到 SMT 更新中,并计算新的根节点。 +这里会将新产生的 `SMT Node`, 生成的 `(Hash(Node), Encode(Node))` 缓存在 `StateTree` 的 +成员 `cache` 中。 + +### flush +```rust + pub fn flush(&self) -> Result<()>; +``` +将 `StateTree` 成员 `cache` 中的 `(Hash(Node), Encode(Node))` 写到 `KvStore` 中。 + +### get +```rust +pub fn get(&self, key: &K) -> Result>>; +``` +查找 `StateTree` 中 `key` 对应 `value`。 先检查 `StateTree` 成员 `update` 缓存中是否有,有直接返回。 +没有按照 `SMT` 中 `get_with_proof` 流程。 + +### get_with_proof +```rust +pub fn get_with_proof(&self, key: &K) -> Result<(Option>, SparseMerkleProof)>; +``` +获取 `proof`[proof](07-proof.md) 待补充 + +## ChainStateDB API 说明 + +### new +```rust +pub fn new(store: Arc, root_hash: Option) -> Self; +``` +类似 `StateTree new` 生成根节点为 `root_hash` 的 `SMT`。 + +### get_account_state_object +```rust + fn get_account_state_object( + &self, + account_address: &AccountAddress, + create: bool, +) -> Result>; +``` +获取 `account_address` 对应的 `Code SMT` 和 `Resource SMT`。 +先根据 `Account SMT` 获取 `account_address` 对应的 `AccountState`, +再根据 `AccountState` 的 `Code_Root_Hash` 和 `Res_Root_Hash` 生成对应的 `Code SMT` 和 `Resource SMT`。 + +### get_with_proof +```rust +fn get_with_proof(&self, access_path: &AccessPath) -> Result; +``` +获取 `proof`, [proof](07-proof.md) 待补充 + +## StateView 相关 + +```rust +pub enum DataPath { + Code(#[schemars(with = "String")] ModuleName), + Resource(#[schemars(with = "String")] StructTag), +} + +pub struct AccessPath { + pub address: AccountAddress, + pub path: DataPath, +} +fn get(&self, access_path: &AccessPath) -> Result>>; +``` +给 `vm` 提供状态信息查询接口, `AccountAddress` 查找对应的 `AccountStateObject`,再生成 +`Code Tree` 和 `Resource Tree`, `AccessPath` 成员 `path` 对应为 `ModuleName` 由 `Code Tree` 提供查找, +否则 `Resource Tree` 提供查找。 + +## 幂等性相关 +`StateTree` 幂等性由 `SMT` 保证, `ChainStateDB` 幂等性由 `StateTree` 保证。 + + +## 资源 + +[draw.io](../../../../../static/state.drawio) \ No newline at end of file diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/99-concepts/05-smt.md b/i18n/zh/docusaurus-plugin-content-docs/current/99-concepts/05-smt.md index 1ae04addc..927fbf076 100644 --- a/i18n/zh/docusaurus-plugin-content-docs/current/99-concepts/05-smt.md +++ b/i18n/zh/docusaurus-plugin-content-docs/current/99-concepts/05-smt.md @@ -25,7 +25,7 @@ State 包括合约代码( CODE )和资源( RESOURCE ),余额相关信息都在 #### Merkle Tree 到SMT -在 Starcoin中 Hash 的计算都是基于 sha3_256 计算来的, 所以这颗树是2的256次方个元素 +在 Starcoin 中 Hash 的计算都是基于 sha3_256 ( Hash Struct 会加入 prefix 文末会给出示例代码) 计算来的, 所以这颗树是2的256次方个元素 下图显示了 Merkle Tree到 SMT的两个优化 ![three_smt](../../../../../static/img/smt/three_smt.png) 图1是一个 Merkle Tree,图2优化将空子树用 PlaceHolder (方格)代替, 节省了空间, @@ -223,10 +223,32 @@ StaleNodeIndex 中 stale_since_version 是这次新产生的根节点 Hash, no ```rust pub fn get_with_proof(&self, key: &K) -> Result<(Option>, SparseMerkleProof)> ``` -获取 Key 对应的 Value 的值,如果存在并返回对应的 Merkle Proof 证明 +获取 Key 对应的 Value 的值,如果存在并返回对应的 Merkle Proof 证明。 +[proof](07-proof.md) 待补充。 + +### Starcoin 中 sha3_256 Struct 示例代码 +```rust +let buf = hex::decode( +"0xfa000000000000007b161ceeef010000000000000000000000000000000000000000000000000000" +.strip_prefix("0x").unwrap() +).unwrap(); +let blob = Blob::from(buf); +let salt_prefix: &[u8] = b"STARCOIN::Blob"; +let ser = bcs::to_bytes(&blob)?; +let salt = [ +HashValue::sha3_256_of(salt_prefix).as_slice(), +ser.as_slice(), +] +.concat(); +let hash = HashValue::sha3_256_of(&salt[..]); +``` + +### 参考文档 -参考文档: https://developers.diem.com/papers/jellyfish-merkle-tree/2021-01-14.pdf + https://westar.io/blog/jellyfish-merkle-tree-in-libra/ -相关资源[draw.io](../../../../../static/smt.drawio) +### 相关资源 + +[draw.io](../../../../../static/smt.drawio) diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/99-concepts/07-proof.md b/i18n/zh/docusaurus-plugin-content-docs/current/99-concepts/07-proof.md new file mode 100644 index 000000000..28fd7d1de --- /dev/null +++ b/i18n/zh/docusaurus-plugin-content-docs/current/99-concepts/07-proof.md @@ -0,0 +1,15 @@ +# Proof + +All of the data in the Starcoin Blockchain is stored in a single-versioned distributed database. Proof is used to determine whether a transaction or block or state is included in the blockchain. + + +In a blockchain, the client does not need to trust the entity from which it is receiving data. A client could query for the state of an account, ask whether a specific transaction or a specific block was processed, and so on. As with other Merkle trees, the ledger history can provide an O(log n)-sized proof of a specific transaction object, where _n_ is the total number of transactions processed. + +:::node + +* Block Accumulator Proof +* Transaction Accumulator Proof +* State Proof +* Event Proof + +::: \ No newline at end of file diff --git a/src/pages/index.js b/src/pages/index.js index 2753665fa..395a1a2b9 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -29,8 +29,8 @@ export default function Home() { const {siteConfig} = useDocusaurusContext(); return ( + title={`${siteConfig.title}`} + description="Learn how to developing on starcoin">
diff --git a/static/img/dapp/dapp_1.png b/static/img/dapp/dapp_1.png new file mode 100644 index 000000000..80eef1378 Binary files /dev/null and b/static/img/dapp/dapp_1.png differ diff --git a/static/img/dapp/dapp_2.png b/static/img/dapp/dapp_2.png new file mode 100644 index 000000000..79c149bab Binary files /dev/null and b/static/img/dapp/dapp_2.png differ diff --git a/static/img/dapp/pb.jpg b/static/img/dapp/pb.jpg new file mode 100644 index 000000000..46eac861b Binary files /dev/null and b/static/img/dapp/pb.jpg differ diff --git a/static/img/dapp/starmask-confirm.png b/static/img/dapp/starmask-confirm.png new file mode 100644 index 000000000..616945daa Binary files /dev/null and b/static/img/dapp/starmask-confirm.png differ diff --git a/static/img/favicon-32x32.png b/static/img/favicon-32x32.png new file mode 100644 index 000000000..24f905fad Binary files /dev/null and b/static/img/favicon-32x32.png differ diff --git a/static/img/favicon.ico b/static/img/favicon.ico index b394d05f1..aad469db5 100644 Binary files a/static/img/favicon.ico and b/static/img/favicon.ico differ diff --git a/static/img/logo.svg b/static/img/logo.svg index bada6c1d7..40fbbb864 100644 --- a/static/img/logo.svg +++ b/static/img/logo.svg @@ -1 +1 @@ -coin-1 \ No newline at end of file + \ No newline at end of file diff --git a/static/img/onboarding-diagram.png b/static/img/onboarding-diagram.png new file mode 100644 index 000000000..87af72b66 Binary files /dev/null and b/static/img/onboarding-diagram.png differ diff --git a/static/img/onboarding-library-1.png b/static/img/onboarding-library-1.png new file mode 100644 index 000000000..1d5847ac7 Binary files /dev/null and b/static/img/onboarding-library-1.png differ diff --git a/static/img/state/two_level_state.png b/static/img/state/two_level_state.png new file mode 100644 index 000000000..979630ae2 Binary files /dev/null and b/static/img/state/two_level_state.png differ diff --git a/static/onboarding-diagram.drawio b/static/onboarding-diagram.drawio new file mode 100644 index 000000000..6b37a3c59 --- /dev/null +++ b/static/onboarding-diagram.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/static/state.drawio b/static/state.drawio new file mode 100644 index 000000000..07e55d86d --- /dev/null +++ b/static/state.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file