{"id":26991953,"url":"https://github.com/nuls-io/nuls-chainbox","last_synced_at":"2025-04-03T22:17:45.485Z","repository":{"id":97722581,"uuid":"192838012","full_name":"nuls-io/nuls-chainbox","owner":"nuls-io","description":"NULS ChianBox Blockchain Engine","archived":false,"fork":false,"pushed_at":"2024-02-02T11:39:08.000Z","size":10142,"stargazers_count":31,"open_issues_count":6,"forks_count":18,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-04-24T12:34:49.772Z","etag":null,"topics":["blockchain","blockchain-technology","nuls","nuls-blockchain"],"latest_commit_sha":null,"homepage":"https://github.com/nuls-io/nuls-chainbox","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nuls-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-06-20T02:54:42.000Z","updated_at":"2024-04-24T12:34:49.772Z","dependencies_parsed_at":"2023-03-14T22:46:27.454Z","dependency_job_id":null,"html_url":"https://github.com/nuls-io/nuls-chainbox","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuls-io%2Fnuls-chainbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuls-io%2Fnuls-chainbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuls-io%2Fnuls-chainbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuls-io%2Fnuls-chainbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nuls-io","download_url":"https://codeload.github.com/nuls-io/nuls-chainbox/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247086007,"owners_count":20881160,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","blockchain-technology","nuls","nuls-blockchain"],"created_at":"2025-04-03T22:17:44.928Z","updated_at":"2025-04-03T22:17:45.477Z","avatar_url":"https://github.com/nuls-io.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NULS ChainBox Developer Guide\n\nNULS ChianBox Blockchain Engine\n\n## What is NULS ChainBox?\n\nChainBox is an out-of-the-box solution for blockchain development. It encapsulates six underlying modules: ledger, accounts, transactions, blocks, consensus, and network. ChainBox eliminates the necessity for direct blockchain experience and the need to understand distributed data storage, point-to-point transmission, consensus mechanisms, and encryption algorithms. Developers can focus on creating independent business modules based on standard communication protocols, forming a brand new application chain in minutes with ChainBox.\n\n## Why Choose ChainBox?\n\nNULS ChainBox is designed to help enterprises or application developers build blockchain applications effortlessly, allowing them to concentrate on their own business implementations without worrying about the complex technology underlying blockchains.\n\n## Key Features\n\nEssentially, NULS ChainBox is an extension of NULS 2.0 aiming to be a one-stop blockchain development platform. It has three core features:\n\n- Quick setup of the development environment.\n- Lowering the threshold of application development by using templates.\n- Reducing the difficulty of integration with NULS provided templates by utilizing provided scripts and one-click generation of executable programs.\n\n## Quick Start\n\nIn the following ChainBox example, you will learn how to quickly build a blockchain application that provides encrypted message services.\n\n### 1. Environment Preparation\n\n- Linux or MacOS\n- Git\n- Maven\n- JDK 11\n\nJava must be set in the $PATH environment variable.\n\n### 2. Get NULS ChainBox Repository\n\nOpen the terminal and run the following command:\n\n```bash\ngit clone https://github.com/nuls-io/nuls-chainbox.git chainbox\n```\n\n### 3. Building Encrypted Message Module\n\nChange the directory to the `example` directory:\n\n```bash\ncd example   # enter the example folder\n```\n\nRun the command to build an example module:\n\n```bash\npackage    # execute the build script (provided by the template)\n```\n\nThe following output indicates the success of the build:\n\n```bash\n============ PACKAGE FINISH 🍺🍺🍺🎉🎉🎉 ===============\n```\n\nIf the build is successful, you will find the `outer` folder generated in `example`.\n\n\u003e PS: If you want to know the detailed design of the module, please refer to the [Message Module Design](./developeModule.md)\n\n### 4. Integrate the Encrypted Message Module into ChainBox\n\nGo back to the `chainbox` root directory:\n\n```bash\ncd ..\n```\n\nRun the command to integrate the encryption module into the NULS 2.0 runtime environment:\n\n```bash\ntools -p example\n```\n\nThe following output indicates the success of the integration:\n\n```bash\n============ PACKAGE FINISH 🍺🍺🍺🎉🎉🎉 ===============\n```\n\nThe `NULS-WALLET` folder will be created in the `chainbox` directory. It contains the NULS 2.0 running program integrated with the encrypted message module, and support directories such as Logs, and scripts.\n\nIf multiple nodes are deployed on different machines, it is recommended to modify the following two parameters in the `NULS-WALLET/.default-config.ncf` configuration file.\n\n```bash\n# Minimum number of linking nodes. If the number of linking nodes is lower than this parameter, it will continue to wait.\nminNodeAmount=0\n\n# Seed node block address\nseedNodes=tNULSeBaMkrt4z9FYEkkR9D6choPVvQr94oYZp\n\n# Seed node block address password\npassword=nuls123456\n```\n\n### 5. Start Your Node\n\nExecute the following command in the `NULS-WALLET` directory:\n\n```bash\nstart-dev\nnuls.ncf is created by default-config.ncf.\nPlease re-execute the startup program.\n```\n\nThe `nuls.ncf` is created during the first execution of the command. Re-enter the command:\n\n```bash\nstart-dev\n```\n\nThe following output indicates that the ChainBox modules are starting:\n\n```bash\nLOG PATH    : ~/NULS-WALLET/Logs\nDATA PATH   : ~/NULS-WALLET/data\nCONFIG FILE : ~/NULS-WALLET/nuls.ncf\nDEBUG       : 0\nJAVA_HOME   : /Library/java/JavaVirtualMachines/jdk-11.0.2.jdk/Contents/Home\njava version \"11.0.2\" 2019-01-15 LTS\nJava(TM) SE Runtime Environment 18.9 (build 11.0.2+9-LTS)\nJava HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.2+9-LTS, mixed mode)\n\n====================\nNULS-WALLET STARTING\n====================\n```\n\nCheck the startup status using the following command:\n\n```bash\ncheck-status\n```\n\nThe following output indicates that all the modules of the node have been successfully started. Notice the module 'mail-example' is included.\n\n```bash\n==================MODULE PROCESS====================\naccount PROCESS IS START\nblock PROCESS IS START\nconsensus PROCESS IS START\nledger PROCESS IS START\nnetwork PROCESS IS START\ntransaction PROCESS IS START\n==================RPC READY MODULE==================\naccount RPC READY\nblock RPC READY\nconsensus RPC READY\nledger RPC READY\nnetwork RPC READY\ntransaction RPC READY\n======================READY MODULE==================\naccount STATE IS READY\nblock STATE IS READY\nconsensus STATE IS READY\nledger STATE IS READY\nnetwork STATE IS READY\ntransaction STATE IS READY\n================TRY RUNNING MODULE==================\naccount TRY RUNNING\nblock TRY RUNNING\nconsensus TRY RUNNING\nledger TRY RUNNING\nnetwork TRY RUNNING\ntransaction TRY RUNNING\n===================RUNNING MODULE===================\naccount STATE IS RUNNING\nblock STATE IS RUNNING\nconsensus STATE IS RUNNING\nledger STATE IS RUNNING\nnetwork STATE IS RUNNING\ntransaction STATE IS RUNNING\n==================NULS WALLET STATE=================\n==========================\nNULS WALLET IS RUNNING\n==========================\n```\n\n### 6. Start Creating Blocks and Other Housekeeping\n\nNow that the node is started, also referred to as the 'seed node', we need to import the default block address of the seed node so that the node can begin to produce blocks.\n\nFirst start the command line interface:\n\nFirst enter the command line\n\n```bash\ncmd\n...\nModule:cmd-client\n...\nwaiting nuls-wallet base module ready\nnuls\u003e\u003e\u003e\n```\n\nNext, you must import the block address of the seed node. This is very important. If you miss this step or enter the wrong details, the seed node will not begin building blocks, and 'mail-example' will not work.\n\nEnter:\n\n```bash\nimport b54db432bba7e13a6c4a28f65b925b18e63bcb79143f7b894fa735d5d3d09db5\n```\n\nWhen prompted, provide the Password: `nuls123456`\n\n```bash\nPlease enter the password (password is between 8 and 20 inclusive of numbers and letters), If you do not want to set a password, return directly.\nEnter your password: **********\nPlease confirm new password: **********\ntNULSeBaMkrt4z9FYEkkR9D6choPVvQr94\n\n\n### 7. Get NULS Accounts for 'mail-example'\n\nTo facilitate testing, two accounts have been set up for sending and receiving messages. The addresses are pre-defined in the genesis block. Please enter any password for these accounts.\n\n```plaintext\nnuls\u003e\u003e\u003e import 477059f40708313626cccd26f276646e4466032cabceccbf571a7c46f954eb75\nPlease enter the password (password is between 8 and 20 inclusive of numbers and letters), If you do not want to set a password, return directly.\nEnter your password: **********\nPlease confirm the new password: **********\ntNULSeBaMnrs6JKrCy6TQdzYJZkMZJDng7QAsD\n\nnuls\u003e\u003e\u003e import 8212e7ba23c8b52790c45b0514490356cd819db15d364cbe08659b5888339e78\nPlease enter the password (password is between 8 and 20 inclusive of numbers and letters), If you do not want to set a password, return directly.\nEnter your password: **********\nPlease confirm the new password: **********\ntNULSeBaMrbMRiFAUeeAt6swb4xVBNyi81YL24\n```\n\nFor testing the 'mail-example', the accounts 'tNULSeBaMnrs6JKrCy6TQdzYJZkMZJDng7QAsD' and 'tNULSeBaMrbMRiFAUeeAt6swb4xVBNyi81YL24' are now available.\n\n### 8. Testing 'mail-example'\n\n1. Navigate to the `NULS-WALLET/Modules/Nuls/mail-example/1.0.0` directory.\n\n2. Open `mail-test.html` with a browser. This test page allows you to perform the following functions:\n\n    a. Associate a sender/receiver with a NULS address. The sender/receiver can be an email address or any other identifier.\n\n    b. Set the sender/receiver for one NULS account and enter the password of the account used. The hash value of this transaction will be returned if the submission is successful. Repeat the same process for the second NULS account.\n\n    Example:\n    ```plaintext\n    asd@nuls.io (associated with tNULSeBaMnrs6JKrCy6TQdzYJZkMZJDng7QAsD)\n    l24@nuls.io (associated with tNULSeBaMrbMRiFAUeeAt6swb4xVBNyi81YL24)\n    ```\n\n    c. Send a message from 'asd@nuls.io' to 'l24@nuls.io'. Enter the receiver's address (asd@nuls.io), the sender's account address, and the sender's account password. The hash value of this transaction will be returned if the submission is successful.\n\n3. After waiting for about 10 seconds (to ensure that the transaction has been confirmed), the content of the message can be viewed by the hash value of the message sent. Only the sender and the receiver have permission to view it.\n\n4. Here is the decrypted sent message, as provided by 'mail-example':\n    ```json\n    {\n        \"sendermessageAddress\": \"asd@nuls.io\",\n        \"receivermessageAddress\": \"24@nuls.io\",\n        \"title\": \"this is title\",\n        \"content\": \"NULS 666.\",\n        \"sender\": \"tNULSeBaMnrs6JKrCy6TQdzYJZkMZJDng7QAsD\",\n        \"date\": 1561365228904\n    }\n    ```\n\n## ChainBox Guide\n\n### Directory Structure of ChainBox\n#### tools\nThe script tools download packages and repositories, integrate packages, etc. ([Command Parameter Document](#cmd-doc)).\n\n#### document\nThe document directory contains documentation for the six core modules that make up the basic blockchain program. These documents are currently in Chinese. If you are interested in finding out more about these topics, consider using Google Translate.\n\n#### example\nAn example module program source code for encrypted mail developed based on a Java module template. The example directory includes source code, test.html, package script, module.ncf, README.md.\n\n#### rpc-debug-tool\nBasic module RPC interface debugging tool.\n\n#### NULS_WALLET: the NULS2.0 run environment\n\nThe NULS2.0 running environment contains all necessary files for the most basic blockchain program. It includes the six core modules: account, ledger, block, network, transaction, consensus (PoC).\n\nTo add additional functionality, such as cross-chain transfer, modify the configuration file, nuls.ncf, and rebuild NULS_WALLET. ([Complete Configuration List](https://github.com/nuls-io/nuls-v2/blob/develop/useguide.md#nulsncf-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6)).\n\nTo integrate your own business module(s) into Chainbox, modify the NULS2.0 run environment using the script 'tools'. More information is provided in the next section.\n\n### tools\nThe script 'tools' is used to download templates and repositories and to build the NULS2.0 run environment.\n\n```plaintext\ntools -h\nDesc: NULS-engine script\nUsage: ./tools\n   -t \u003clanguage\u003e [folder name] Get the module program module of the specified development language\n\u003clanguage\u003e development language, such as java\n[folder name] Download to the directory with the specified name\n   -r \u003cfolder name\u003e Retrieve the business module code and execute the package to compile\n   -l View a list of supported templates\n   -n [base module name...] Get the NULS2.0 runtime environment (pull from the nuls-v2/nuls-engine branch) By default, 6 core modules are built, and optional modules can be added by passing in optional module names.\n   -p [business module directory...] build NULS2.0 wallet\n   -a add a base module\n   -d remove a base module\n   -s View the configured list of base modules to be packaged\n   -i \u003cpackage.ncf\u003e specifies the configuration file of the base module to be packaged\n   -o \u003cfolder path\u003e specifies the output directory\n   -h View help\n```\n\nThe following `tools -p` option checks the current environment, then pulls NULS2.0 code from the GitHub repository, executes 'package' to complete the NULS2.0 compilation and packaging, and writes the runnable program and support directories to the NULS_WALLET directory.\n\n```plaintext\ntools -p\n```\n\nWhen you see the following, `tools -p` has successfully completed:\n\n```plaintext\n============ .../.NULS2.0/NULS-WALLET-RUNTIME PACKAGE FINISH 🍺🍺🍺🎉🎉🎉 ===============\n```\n\nTo start and complete the configuration of ChainBox, execute steps 5 and 6 of the 'Quick Start' section.\n\n\n#### NULS-WALLET Directory Structure\n##### start-dev\n- Start node.\n##### stop-dev\n- Stop node.\n##### check-status\n- Check the operating status of each module.\n##### cmd\n- Command line startup script.\n##### create-address\n- Create NULS account and return account address and private key.\n\n```\n./create-address\nJAVA_HOME:/Library/Java/JavaVirtualMachines/jdk-11.0.2.jdk/Contents/Home\njava version \"11.0.2\" 2019-01-15 LTS\nJava(TM) SE Runtime Environment 18.9 (build 11.0.2+9-LTS)\nJava HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.2+9-LTS, mixed mode)\n\n.../NULS_WALLET/nuls.ncf\nService Manager URL: ws://127.0.0.1:7771\nchainId:2\nnumber:1\n====================================================================================================\naddress   :tNULSeBaMtrzD4kChZPfEAFLRqX18n7UrrbY1s\nprivateKey:f67877e994d6bd0ef23e0aaf0f8c6b62edf5dc636ff5b6981666c4632499bc56\n====================================================================================================\n```\n\n\n##### nuls.ncf\n- Configuration file (created after running the start-dev script for the first time).\n##### More Usage Reference ([NULS2.0 Wallet User Manual](https://github.com/nuls-io/nuls-v2/blob/develop/useguide.md))\n\n### How to Develop Your Own Module (Also Called 'Business Module')\nNULS2.0 is a distributed microservice architecture  written in the JAVA language. It consists of multiple modules, each of which communicates via the websocket protocol. NULS 2.0 defines a standard [module communication protocol](https://github.com/nuls-io/nuls-v2-docs/blob/master/design-zh-CHS/r.rpc-tool-websocket%E8%AE%BE%E8%AE%A1v1.3.md), which can be implemented in various development languages to communicate with other modules.\nTo interact with the blockchain your business module registers it's transaction type(s) at startup.  Your business module  stores its own business data in the transaction's txData, and  passes the assembled transaction  to the transaction module which will manage the verification of the transaction, and, if correct, stores the transaction in a packed queue which is subsequently processed by the block module.\n#### Creating a Transaction Process\n![node creation transaction](./chainbox/createTX.jpg)\n#### Processing Network Transaction Process\n![Processing Webcast Transactions](./chainbox/network.jpg)\n\nAs you can see from the figure, there are four main things you need to do:\n1. Register your own transaction type to the blockchain. A transaction type represents a unique write to the blockchain. For example,  mail-example has 2 types: a. create mail address, where details about the mail address are written to the ledger, b. send mail, where the details about the email message are written to the ledger.).\n2. Assemble the transaction data and create the new transaction.\n3. Verify that the business data in the transaction is valid.\n4. Save the business data in the transaction to the node database.\n\nOf course, in addition to the above 4 steps, business data needs to be used according to specific business needs.\n\nHere are the above 4 steps in detail.\n\nEach type of transaction in the business module is  registered with the transaction module with a unique transaction value, called transaction type.  These values are 200 and above (integer). The value needs to be unique within this occurrence of ChainBox.  The transaction type is used to distinguish the callback function of the processed transaction. The registration transaction interface provided by the transaction module is called when the business module is started (please refer to 'mail-example'). When the transaction module gets a transaction to be processed, the transaction, including the transaction data and business data, will be verified according to the transaction type. In addition to verification, there are two functions: commitTx (save transaction business data) and rollbackTx (rollback transaction business data).\n\nThe contents of a transaction include transaction type, timestamp, CoinData, txData, remarks, and signature. CoinData includes transfer data, transfer accounts, transfer accounts, transfer amounts, asset information, and so on. The txData contains business data. The business module stores its own business data in txData according to the business design. The signature field signs all transaction data by an elliptic curve algorithm to ensure that the data is not skewed during transmission. After the assembly is complete, the transaction module interface is called to create the transaction.\n\nWhen the transaction module gets the transaction, it checks whether the parameters of the transaction data is correct, then checks whether the account balance is sufficient to pay the transaction fee, and then verifies the nonce value of the account (using an algorithm that guarantees that the balance is not reused by controlling the transaction order ). After the verification is passed, the callback function of the business verification is found according to the transaction type, and the transaction business data is verified.\n\nFinally, when the transaction is added to the block and the block has been confirmed, a callback function for storing the business data will be found through the transaction type, and the business module is notified to ‘backup’ the data. In some cases, block rollback may occur. When the block is rolled back, the transaction data is also matched to the corresponding transaction rollback callback function to roll back the business data.\n\nThe above are the core steps required for  new transaction type. The three interfaces for verifying transactions, saving business data, and rolling back business data are implemented by the business module.\n\n### Communicate with Other Modules\nNULS 2.0 uses a microservices architecture, and modules communicate using [websocket](https://en.wikipedia.org/wiki/WebSocket). The links to all modules are governed by Nulstar and the process is as follows:\n\n![](./chainbox/pic01.jpg)\n\nAll modules are started by the ServiceManager. After startup, each module (also referred to as service module)  establishes a connection with the ServiceManager module. This handshake is completed according to protocol. After the handshake is successful, the module is registered with the ServiceManager. The purpose of the registration is to tell the ServiceManager its connection mode, the provided interface protocol, and which modules it relies on.\n#### Establish Connection\nThe connection is established using the standard websocket protocol. After the connection is established, the module can send a packet (interface request) to any module and receive the other party's data packet. Note: All requests are asynchronous  non-blocking.\n#### Handshake with ServiceManager\nAfter establishing a connection with the ServiceManager, the module sends a NegotiateConnection object. The module can process other requests only when the negotiation is successful. Otherwise, the module receives the NegotiateConnectionResponse message with the status set to 0 (failed) and immediately disconnect.\nThe NegotiateConnection message consists of two fields:\n\n- CompressionAlgorithm (default: zlib): A String representing the algorithm that will be used to receive and send messages if CompressionRate is greater than zero. The default is zlib, which is supported in most development languages.\n- CompressionRate: An integer between 0 and 9 that establishes the level of compression at which messages should be sent and received for this connection. 0 means no compression, and 9 is maximum compression.\n\n\n\n\nExample:\n\n```json\n    {\n        \"MessageID\": \"15622130397455\",\n        \"Timestamp\": \"1562213039745\",\n        \"TimeZone\": \"9\",\n        \"MessageType\": \"NegotiateConnection\",\n        \"MessageData\": {\n            \"Abbreviation\": \"ledger\",\n            \"ProtocolVersion\": \"0.1\",\n            \"CompressionAlgorithm\": \"zlib\",\n            \"CompressionRate\": \"0\"\n        }\n    }\n```\nAfter the handshake is successful, the ServiceManager sends a NegotiateConnectionResponse object to the service module. It consists of two fields:\n\n- NegotiationStatus: Unsigned small integer value, 0 if negotiation failed, 1 if successful\n- NegotiationComment: A string value that describes what went wrong when rejecting the connection.\n\nExample:\n\n```json\n{\n    \"MessageID\": \"156221303974612033\",\n    \"Timestamp\": \"1562213039759\",\n    \"TimeZone\": \"9\",\n    \"MessageType\": \"NegotiateConnectionResponse\",\n    \"MessageData\": {\n        \"RequestID\": \"15622130397455\",\n        \"NegotiationStatus\": \"1\",\n        \"NegotiationComment\": \"Connection true!\"\n    }\n}\n```\n\n#### registerAPI (Registration Module)\nAfter the handshake with the ServiceManager is successful, the RegisterAPI request is sent by the registering module to the ServiceManager to complete the registration. The ServiceManager will obtain the connection information and interface method of the module through this request. The ServiceManager determines whether the registering module meets the normal working conditions by analyzing whether it's provided list of \"dependency\" module(s) exist. (See example.)\n\nExample:\n\n```\n{\n    \"MessageID\": \"15622130392482\",\n    \"Timestamp\": \"1562213039248\",\n    \"TimeZone\": \"9\",\n    \"MessageType\": \"Request\",\n    \"MessageData\": {\n        \"RequestAck\": \"0\",\n        \"SubscriptionEventCounter\": \"0\",\n        \"SubscriptionPeriod\": \"0\",\n        \"SubscriptionRange\": \"0\",\n        \"ResponseMaxSize\": \"0\",\n        \"RequestMethods\": {\n            \"RegisterAPI\": {\n                \"Methods\": [\n                    {\n                        \"MethodName\": \"getAssetsById\",\n                        \"MethodDescription\": \"清除所有账户未确认交易\",\n                        \"MethodMinEvent\": \"0\",\n                        \"MethodMinPeriod\": \"0\",\n                        \"MethodScope\": \"public\",\n                        \"Parameters\": [\n                            {\n                                \"ParameterName\": \"chainId\",\n                                \"ParameterType\": \"\",\n                                \"ParameterValidRange\": \"[1-65535]\",\n                                \"ParameterValidRegExp\": \"\"\n                            },\n                            {\n                                \"ParameterName\": \"assetIds\",\n                                \"ParameterType\": \"\",\n                                \"ParameterValidRange\": \"\",\n                                \"ParameterValidRegExp\": \"\"\n                            }\n                        ]\n                    }\n                ],\n                \"Dependencies\": {\n                    \"block\": \"1.0\",\n                    \"network\": \"1.0\"\n                },\n                \"ConnectionInformation\": {\n                    \"IP\": \"192.168.0.197\",\n                    \"Port\": \"17880\"\n                },\n                \"ModuleDomain\": \"Nuls\",\n                \"ModuleRoles\": {\n                    \"ledger\": [\n                        \"1.0\"\n                    ]\n                },\n                \"ModuleVersion\": \"1.0\",\n                \"Abbreviation\": \"ledger\",\n                \"ModuleName\": \"ledger\"\n            }\n        }\n    }\n}\n```\nWhen the ServiceManager determines that the dependency modules have been started, it returns a response to the registering module that contains the way the dependent modules are linked.\n\nExample:\n\n```\n{\n    \"MessageID\": \"1562213039283455\",\n    \"Timestamp\": \"1562213039283\",\n    \"TimeZone\": \"9\",\n    \"MessageType\": \"Response\",\n    \"MessageData\": {\n        \"RequestID\": \"15622130392482\",\n        \"ResponseProcessingTime\": \"2\",\n        \"ResponseStatus\": 0,\n        \"ResponseComment\": \"success\",\n        \"ResponseMaxSize\": \"0\",\n        \"ResponseData\": {\n            \"RegisterAPI\": {\n                \"Dependencies\": {\n                    \"consensus\": {\n                        \"IP\": \"192.168.0.197\",\n                        \"Port\": \"18735\"\n                    },\n                    \"ledger\": {\n                        \"IP\": \"192.168.0.197\",\n                        \"Port\": \"17880\"\n                    },\n                    \"nuls-module-explorer\": {\n                        \"IP\": \"192.168.0.197\",\n                        \"Port\": \"10130\"\n                    },\n                    \"kernel\": {\n                        \"IP\": \"0.0.0.0\",\n                        \"Port\": \"7771\"\n                    },\n                    \"block\": {\n                        \"IP\": \"192.168.0.197\",\n                        \"Port\": \"13437\"\n                    },\n                    \"transaction\": {\n                        \"IP\": \"192.168.0.197\",\n                        \"Port\": \"14026\"\n                    },\n                    \"account\": {\n                        \"IP\": \"192.168.0.197\",\n                        \"Port\": \"15121\"\n                    },\n                    \"network\": {\n                        \"IP\": \"192.168.0.197\",\n                        \"Port\": \"15481\"\n                    }\n                }\n            }\n        },\n        \"ResponseErrorCode\": null\n    }\n}\n```\n***After the registering module obtains the link mode of the dependent module, it can establish a connection with  other business module(s) and obtain the connected business module's interface that is available for other business modules. *** is this clear and complete? ***\n\n#### Calling Other Module Interfaces\nBefore calling the interface of other modules, it is also necessary to complete the operation of establishing a websocket connection and shaking hands with the module. After the handshake is completed, the Request  is sent to the module.\n\nExample:\n\n```\n{\n    \"MessageID\": \"156222086356134\",\n    \"Timestamp\": \"1562220863561\",\n    \"TimeZone\": \"9\",\n    \"MessageType\": \"Request\",\n    \"MessageData\": {\n        \"RequestAck\": \"0\",\n        \"SubscriptionEventCounter\": \"0\",\n        \"SubscriptionPeriod\": \"0\",\n        \"SubscriptionRange\": \"0\",\n        \"ResponseMaxSize\": \"0\",\n        \"RequestMethods\": {\n            \"ac_createAccount\": {\n                \"chainId\": 2,\n                \"count\": 1,\n                \"password\": \"nuls123456\"\n            }\n        }\n    }\n}\n```\nThe content of RequestMethods is the requested parameter, and the outer data is the protocol layer. After the business module is processed, the Response object is sent, and the processing result and the result data are returned.\n\nExample:\n\n```\n{\n    \"MessageID\": \"156222086367037\",\n    \"Timestamp\": \"1562220863664\",\n    \"TimeZone\": \"9\",\n    \"MessageType\": \"Response\",\n    \"MessageData\": {\n        \"RequestID\": \"156222086356134\",\n        \"ResponseProcessingTime\": \"107\",\n        \"ResponseStatus\": 0,\n        \"ResponseComment\": \"success\",\n        \"ResponseMaxSize\": \"0\",\n        \"ResponseData\": {\n            \"ac_createAccount\": {\n                \"list\": [\n                    \"tNULSeBaMkef3L6EsMcigwT1C1uebzfsj63jd3\"\n                ]\n            }\n        },\n        \"ResponseErrorCode\": null\n    }\n}\n```\n#### Reference Document:\n* [Websocket-Tool Design Document](https://github.com/nuls-io/nuls-v2-docs/blob/master/design-zh-EN/r.rpc-tool-websocket%E8%AE%BE%E8%AE%A1v1.3.md)\n* [Nulstar Module Specification](https://github.com/nuls-io/Nulstar/blob/master/Documents/Nulstar%20-%20Documentation%20-%20Module%20Specification.pdf)\n* [Basic Module Interface Document](#doclist)\n\n### Get Module Development Templates for Various Development Languages\nIn theory, as long as the connection is established between the business module and another module using the websocket, information can be exchanged between the two modules according to the agreed protocol. In order to reduce the difficulty of module development, NULS provides quick start templates for java, with the intention of providing other language templates in the future.  Developers only need to use a template. The development of the business module can be completed by inserting specific business logic code at  specified locations in the template.\n\nAll template can be listed using the tools script.\n\n```\ntools -l\njava-module\nnuls-module-explorer\nnuls-module-sdk-provider\nnuls-module-web-wallet\nnuls-module-helloworld\n```\n\nA template can be downloaded using:\n\n```\ntools -t java-module\n```\nAfter the execution is completed, the directory 'java-module' is created in the current directory, and the common development tools can be imported to start the development business. There will be corresponding usage documents in each template.\n### Module Debugging Method\nIn the module development process, you need to coordinate with the ChainBox. After obtaining the NULS2.0 runtime environment, execute the start-mykernel script (start-dev) to start the NULS2.0 basic module. The Service Manager is accessible via URL: ws://127.0.0.1:7771. The  developing module will register with the Service Manager. After completing the registration, the developing module can get the communication address of each dependent module and call each module's interface. The program is deployed to production when finished; the business module needs to be integrated into the NULS2.0 runtime environment. Then the entire package is deployed to the production environment which may include other external nodes.\n1. The packaged executable program should be placed in the outer directory of the module development directory.\n2. The outer directory must have a configuration file named Module.ncf (note M capitalization). The contents of the file are as follows (using java as an example):\n\n```\n[Core]\nLanguage=JAVA # Indicate the development language\nManaged=1 # 1 means the module starts with the node program, 0 means manual start\n\n[Libraries]\nJRE=11.0.2 # Module Operating Environment Version\n\n[Script]\nScripted=1 # Whether to use script to start 1 means yes\nStartScript=start # Start the module script (start must be in the outer directory)\nStopScript=stop # Stop the module script (stop must be in the outer directory)\n\n```\n3. The module can be started and stopped by the script configured in 2\n\n\u003e The above convention has been completed in the module development template.\n\n## Appendix\n### \u003cspan id=\"cmd-doc\"\u003eTools Script Manual\u003c/span\u003e\n\n### Getting the NULS2.0 Runtime Environment\n- **Command:** `tools -p`\n- **Parameter List:** None\n- **Example:**\n  ```bash\n  tools -p\n  ```\n\n### Get the Specified Language Module Development Template\n- **Command:** `tools -t \u003clanguage\u003e [out folder]`\n- **Parameter List:**\n  | Parameter | Description |\n  | --- | --- |\n  | `\u003clanguage\u003e` | Language Template Name |\n  | `[out folder]` | Output folder name |\n- **Example:**\n  ```bash\n  tools -t java-demo\n  ```\n\n### View a List of Available Templates\n- **Command:** `tools -l`\n- **Parameter List:** None\n- **Example:**\n  ```bash\n  tools -l\n  ```\n\n### Integrating Modules into the NULS 2.0 Runtime Environment\n- **Command:** `tools -p \u003cmodule folder\u003e`\n- **Parameter List:**\n  | Parameter | Description |\n  | --- | --- |\n  | `\u003cmodule folder\u003e` | Module folder name |\n- **Example:**\n  ```bash\n  tools -p mail-example nuls-helloworld-template\n  ```\n\n\n### \u003cspan id=\"registerTx\"\u003eBusiness Module Interface Protocol\u003c/span\u003e\n\nThe business module must implement three callback functions for interaction with the transaction module. These functions are invoked by the transaction module via the WebSocket, sharing identical parameters but with distinct names.\n\n#### Transaction Verification\n- **Command Name:** `txValidator`\n\n  This function is utilized by the service module to validate `txData` and check if data such as `coinData` adheres to business requirements. If the validation fails, the transaction module will discard the transaction.\n\n#### Saving Transaction Business Data\n- **Command Name:** `txCommit`\n\n  This function is responsible for storing business data from the transaction into the local node database or executing corresponding business logic processing. Transactions reaching this step are exclusively consensus data.\n\n#### Rolling Back Transaction Business Data\n- **Command Name:** `txRollback`\n\n  This callback function is triggered when a block rollback occurs. In this function, the business module should clear business data associated with the transaction or execute corresponding reverse processing.\n\n#### Callback Function Parameter List\n| Parameter Name | Type | Description |\n| --- | --- | --- |\n| `chainId` | `int` | Chain ID (to differentiate data sources when nodes run multiple chains) |\n| `txList` | `list` | List of transactions |\n| `blockHeader` | `object` | Block header |\n\n#### Deserialization, [Common Agreement]()\nThe data of the two parameters txList and blockHeader are transmitted in the form of hexadecimal data. First, the hexadecimal is converted into a byte array, and then deserialized into structured data according to different rules.\n##### [Transaction](https://github.com/nuls-io/nuls-v2/blob/master/common/nuls-base/src/main/java/io/nuls/base/data/Transaction.java)\nThe txList stores a list of Transaction objects. Each item is a serialized Transaction object into a hexadecimal string. Deserializing txList first from [General Protocol](https://github.com/nuls-io/nuls-v2-docs/blob/master/design-zh-CHS/r.rpc-tool-websocket%E8%AE%BE%E8%AE%A1v1.3.md) takes the value of the txList parameter, which is a string array of json, and then iterates through the array to get the serialized value of a single Transaction object. Convert the serialized value to a byte array. Then take the corresponding data values ​​one by one from the byte array.\nThe rules for reading data in a byte array are as follows:\n1. 2 bytes store unsigned 16-bit int to save the transaction type.\n2. 4 bytes store unsigned 32-bit int to save transaction timestamp (January 1, 1970 to the current number of seconds)\n3. Variable length type storage remark string, see [variable length type reading method](#Variable Length Type Storage Structure)\n4. Become a type store txData string, business custom, but still need to be converted into a byte array.\n5. The variable length type stores the coinData string, which is the hexadecimal string after the serialData object is serialized. See [CoinData Deserialization Method](#CoinData)\n6. The variable length type stores the transaction signature string, which is a hexadecimal string serialized by the TransactionSignature object.\n\n##### \u003cspan id=\"CoinData\"\u003e[CoinData](https://github.com/nuls-io/nuls-v2/blob/master/common/nuls-base/src/main/java/io/nuls/base/data/CoinData.java)\u003c/span\u003e\nThe CoinData object stores the relationship between the deposit and withdrawal of a transaction. A transaction withdrawal account and a deposit account support a many-to-many relationship. As long as the total withdrawal amount is greater than or equal to the total deposit amount plus the commission transaction, it can be established.\n1. The [varint](https://learnmeabitcoin.com/glossary/varint) type stores the list of gold account information.\n2. Store the gold account information list in order. The deposit account information is CoinFrom object. Note that the CoinFrom object is not processed in hexadecimal string.\n3. [varint](https://learnmeabitcoin.com/glossary/varint) Type The number of lists of deposit account information.\n4. Store the deposit account information list in order. The deposit account information is CoinTo object. Note that the CoinTo object is not processed in hexadecimal string.\n\n##### \u003cspan id=\"CoinFrom\"\u003e[CoinFrom](https://github.com/nuls-io/nuls-v2/blob/master/common/nuls-base/src/main/java/io/nuls/base/data/CoinFrom.java)\u003c/span\u003e\n1. Variable length type storage account address. [Address Serialization Code](https://github.com/nuls-io/nuls-v2/blob/master/common/nuls-base/src/main/java/io/nuls/base/basic/AddressTool.java )\n2. 2 bytes store unsigned 16-bit int to save the asset chain id.\n3. 2 bytes store unsigned 16-bit int to save the asset id.\n4. 32 bytes store the numeric data of the BigInteger type to save the amount of gold assets.\n5. Variable length type storage account nonce value.\n6. 1 byte storage lock status (for consensus).\n\n##### \u003cspan id=\"CoinTo\"\u003e[CoinTo](https://github.com/nuls-io/nuls-v2/blob/master/common/nuls-base/src/main/java/io/nuls/base/data/CoinTo.java)\u003c/span\u003e\n1. Variable length type storage account address. [Address Serialization Code](https://github.com/nuls-io/nuls-v2/blob/master/common/nuls-base/src/main/java/io/nuls/base/basic/AddressTool.java )\n2. 2 bytes store unsigned 16-bit int to save the asset chain id.\n3. 2 bytes store unsigned 16-bit int to save the asset id.\n4. 32 bytes store the numeric data of the BigInteger type to save the amount of gold assets.\n5. 8 bytes store signed 64-bit long save lock time (time to lock assets).\n\n##### \u003cspan id=\"TransactionSignature\"\u003e[TransactionSignature](https://github.com/nuls-io/nuls-v2/blob/master/common/nuls-base/src/main/java/io/nuls/base/signture/TransactionSignature.java)\u003c/span\u003e\nThere will be multiple signatures in front of the transaction, so the TransactionSignature stores the list of signature data. Multiple signatures are stored sequentially in a byte array. In the case of deserialization, it is rotated in turn.\n1. 1 byte stores the public key length.\n2. Public key data (length is obtained according to 1).\n3. Variable length type stores signature data.\n\n##### \u003cspan id=\"BlockHeader\"\u003e[BlockHeader](https://github.com/nuls-io/nuls-v2/blob/master/common/nuls-base/src/main/java/io/nuls/base/data/BlockHeader.java)\u003c/span\u003e\nBlockHeader is a block header object, which mainly stores the hash value of the previous block, the root hash value of [merkle tree](https://en.wikipedia.org/wiki/Merkle_tree), the block timestamp, the block height, and the block. Total number of transactions, block signatures, and extended data.\nSerialization rules:\n1. 32 bytes store the hash value of the previous block.\n2. 32 bytes store the hash value of the merkle root.\n3. 4 bytes store unsigned 32-bit int to save the block timestamp (from January 1, 1970 to the current number of seconds).\n4. 4 bytes store unsigned 32-bit int to save block height.\n5. 4 bytes store unsigned 32-bit int to save the total number of transactions in the current block.\n6. Variable length type storage extension data.\n7. The variable length type stores the transaction signature string, which is the hexadecimal string serialized by the BlockSignature object.\n\n##### \u003cspan id=\"BlockSignature\"\u003e[BlockSignature](https://github.com/nuls-io/nuls-v2/blob/master/common/nuls-base/src/main/java/io/nuls/base/signture/BlockSignature.java)\u003c/span\u003e\n1. 1 byte stores the public key length.\n2. Public key data (length is obtained according to 1).\n3. Variable length type stores signature data.\n\n##### \u003cspan id=\"Variable Length Type Storage Structure\"\u003e Variable Length Type Storage Structure\u003c/span\u003e\nThe variable length type consists of two parts. The first part is the length of the byte occupied by the varint type storage data, and the second part is the data part. The way to read the variable length type structure is to read the varint data first and read the corresponding length of the business data.\n1. [varint](https://learnmeabitcoin.com/glossary/varint) type stores the length of the byte array.\n2. Convert the business data into a byte array and store it.\n\n\n\n\n### Module Template List\n* [Java Module Development Template](https://github.com/nuls-io/nuls-module-template-java)\n* [Blockchain Browser Template](https://github.com/nuls-io/nuls-module-explorer)\n\n### \u003cspan id=\"doclist\"\u003eDocument List\u003c/span\u003e\n* [Java Module development template usage documentation](https://github.com/nuls-io/nuls-module-template-java)\n* [Encrypted Mail Sample Module Design Document](https://github.com/CQBeer/nuls-chainbox/blob/master/example/%E6%A8%A1%E5%9D%97%E8%AE%BE%E8%AE%A1%E6%96%87%E6%A1%A3.md)\n* [Account Module RPC Interface Document](https://github.com/nuls-io/nuls-chainbox/blob/master/document/account.md)\n* [Book module RPC interface document](https://github.com/nuls-io/nuls-chainbox/blob/master/document/ledger.md)\n* [Transaction Module RPC Interface Document](https://github.com/nuls-io/nuls-chainbox/blob/master/document/transaction.md)\n* [Block module RPC interface document](https://github.com/nuls-io/nuls-chainbox/blob/master/document/block.md)\n* [Consensus Module RPC Interface Document](https://github.com/nuls-io/nuls-chainbox/blob/master/document/consensus.md)\n* [Network Module RPC Interface Document](https://github.com/nuls-io/nuls-chainbox/blob/master/document/network.md)\n\n  \n## Contribute to NULS\nWe are committed to making blockchain technology simpler and our slogan is \"NULS Making It Easier to Innovate\".\n\nGet to know NULS developers\nhttps://nuls.io/developer\n\nYou are welcome to contribute to NULS! We sincerely invite developers with rich experience in the blockchain field to join the NULS technology community.\nhttps://nuls.io/community\n\nDocumentation：https://docs.nuls.io\n\nNULS Brand Assets: https://nuls.io/brand-assets\n\n\n\n## License\n\nNULS is released under the [MIT](http://opensource.org/licenses/MIT) license.\nModules added in the future may be release under different license, will specified in the module library path.\n\n## Community\n\n- Website: https://nuls.io\n- Twitter: https://twitter.com/nuls\n- Discord:https://discord.gg/aRCwbj47WN\n- Telegram: https://t.me/Nulsio\n- Medium: https://nuls.medium.com\n- Forum: https://forum.nuls.io\n- GitHub: https://github.com/nuls-io\n\n  #### \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnuls-io%2Fnuls-chainbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnuls-io%2Fnuls-chainbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnuls-io%2Fnuls-chainbox/lists"}