CircleChain Architecture
CircleChain is an asset management platform based on blockchain technology that originates from Bitcoin. While Bitcoin is a client application based on blockchain and P2P protocol that stores data locally, CircleChain is a cloud-based distributed P2P and blockchain system. It stores data in cloud storage and provides cloud blockchain and wallet services to manage digital assets. CircleChain extends beyond Bitcoin's capabilities with enhanced features and scalability.
Overall Architecture
The complete architecture includes the following components:
- API Layer - RESTful interfaces for external communication
- Services and Events Layer - Core business logic and event handling
- Background Jobs - Scheduled tasks and maintenance operations
- Configuration Center - System configuration management
- Storage Layer - Data persistence and cloud storage services
API Layer
The API layer consists of the following interfaces:
- User APIs - Public user management interfaces for CircleChain
- Wallet APIs - Public wallet management interfaces for CircleChain
- Block APIs - Public blockchain data access interfaces
- Clouder APIs - Internal clouder node communication interfaces
- Miner APIs - Internal miner node communication interfaces
API Specifications
All CircleChain APIs follow RESTful design principles with data encoded in JSON format. The request and response headers use Content-Type: application/json
.
User APIs
These APIs provide public user management functionality.
sendRegisterVerifyCode
Path: /user/v1/node/register/send-verify-code
Method: POST
Request:
name | type | required | description |
---|---|---|---|
phone | String | optional | Phone and email should not be empty either. |
String | optional | Phone and email should not be empty either. |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
Sends a verification code before creating a user account. If an email is provided, the verification code will be sent via email. If a phone number is provided, the verification code will be sent via SMS.
register
Path: /user/v1/node/register
Method: POST
Request:
name | type | required | description |
---|---|---|---|
phone | String | optional | Phone and email should not be empty either. |
String | optional | Phone and email should not be empty either. | |
passwordInput1 | String | required | password |
passwordInput2 | String | required | password confirmed, should be the same with passwordInput2 |
verifyCode | String | required | the verify code sent by api sendRegisterVerifyCode |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
User registration API for creating new accounts.
sendVerifyCode
Path: /user/v1/node/send-verify-code
Method: POST
Request:
name | type | required | description |
---|---|---|---|
phone | String | optional | Phone and email should not be empty either. |
String | optional | Phone and email should not be empty either. |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
Sends a verification code before user login. If an email is provided, the verification code will be sent via email. If a phone number is provided, the verification code will be sent via SMS.
login
Path: /user/v1/node/login
Method: POST
Request:
name | type | required | description |
---|---|---|---|
phone | String | optional | Phone and email should not be empty either. |
String | optional | Phone and email should not be empty either. | |
verifyCode | String | optional | the verify code sent by api sendVerifyCode , the verifyCode and password you select one to input |
password | String | optional | the password for login, the verifyCode and password you select one to input |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | UserLoginResult | optional | user login result data |
UserLoginResult:
name | type | required | description |
---|---|---|---|
userId | String | required | user id |
sessionKey | String | required | the session key |
sex | byte | optional | the sex |
success | Boolean | required | success or failure |
Description:
User login API. Upon successful authentication, store the sessionKey
securely in your local storage. The sessionKey
is used to authenticate subsequent API calls as a logged-in user by setting the following header:
{
"AuthorizationV2": "<sessionKey>"
}
logout
Path: /user/v1/node/logout
Method: POST
Request:
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
User logout API to terminate the current session.
sendPayVerifyCode
Path: /user/v1/node/pay/send-verify-code
Method: POST
Request:
name | type | required | description |
---|---|---|---|
phone | String | optional | Phone and email should not be empty either. |
String | optional | Phone and email should not be empty either. |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
Sends a verification code before setting a payment password. If an email is provided, the verification code will be sent via email. If a phone number is provided, the verification code will be sent via SMS.
setPayPassword
Path: /user/v1/node/pay/set-password
Method: POST
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
name | type | required | description |
---|---|---|---|
account | AccountPO | required | account |
verifyCode | String | required | the verify code sent by sendPayVerifyCode |
password | String | required | the new pay password. |
AccountPO:
name | type | required | description |
---|---|---|---|
phone | String | optional | Phone and email should not be empty either. |
String | optional | Phone and email should not be empty either. | |
encryptedPassword | String | Optional | the password encrypted by user public key, it can be empty here. |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
Sets the user's payment password for transaction authorization.
havePayPassword
Path: /user/v1/node/have-pay-password
Method: GET
Request:
Request header: { AuthorizationV2: "<sessionKey>" }
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | have or not set. |
Description:
Checks whether the user has set a payment password.
sendResetPasswordVerifyCode
Path: /user/v1/node/reset-password/send-verify-code
Method: POST
Request:
name | type | required | description |
---|---|---|---|
phone | String | optional | Phone and email should not be empty either. |
String | optional | Phone and email should not be empty either. |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
Sends a verification code for resetting the login password. If an email is provided, the verification code will be sent via email. If a phone number is provided, the verification code will be sent via SMS.
resetPassword
Path: /user/v1/node/reset-password
Method: POST
Request:
name | type | required | description |
---|---|---|---|
account | AccountPO | required | account |
verifyCode | String | required | the verify code sent by sendResetPasswordVerifyCode |
password1 | String | required | new login password |
password2 | String | required | password confirmed |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
Resets the user's login password.
saveOrUpdateUserInfo
Path: /user/v1/node/save-or-update-userinfo
Method: POST
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
name | type | required | description |
---|---|---|---|
userId | String | required | user id |
name | String | required | user name |
phone | String | optional | user phone |
sex | Byte | optional | 1: man 0 woman |
icon | String | optional | user icon |
address | String | optional | user address |
motherLang | Integer | required | 0 English 1 Chinese 2 Japanese 3 French 4 German 5 Italian 6 Korea 7 Thai |
String | optional | wechat account | |
entWechat | String | optional | enterprise WeChat account |
dingtalk | String | optional | dingtalk account |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
Saves or updates user profile information.
getUserInfoPO
Path: /user/v1/node/get-user-info
Method: GET
Request:
Request header: { AuthorizationV2: "<sessionKey>" }
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | UserInfoPO | optional | user info data |
UserInfoPO:
name | type | required | description |
---|---|---|---|
userId | String | required | user id |
name | String | required | user name |
phone | String | optional | user phone |
sex | Byte | optional | 1: man 0 woman |
icon | String | optional | user icon |
address | String | optional | user address |
motherLang | Integer | required | 0 English 1 Chinese 2 Japanese 3 French 4 German 5 Italian 6 Korea 7 Thai |
String | optional | wechat account | |
entWechat | String | optional | enterprise WeChat account |
dingtalk | String | optional | dingtalk account |
Description:
Retrieves user information for the currently logged-in user.
addContacts
Path: /user/v1/node/add-contacts
Method: POST
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
name | type | required | description |
---|---|---|---|
name | String | required | user name |
phone | String | required | user phone |
sex | Byte | optional | 1: man 0 woman |
icon | String | optional | user icon |
address | String | required | user address |
description | String | optional | description |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
Adds a contact to the user's contact list. Currently, only phone contacts are supported.
listContacts
Path: /user/v1/node/list-contacts
Method: GET
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | contact data list |
ContactPO:
name | type | required | description |
---|---|---|---|
name | String | required | user name |
phone | String | required | user phone |
sex | Byte | optional | 1: man 0 woman |
icon | String | optional | user icon |
address | String | required | user address |
description | String | optional | description |
Description:
Lists user contacts. Currently, only phone contacts are supported.
Wallet APIs
These APIs provide wallet management services.
createWallet
Path: /wallet/v1/node/createWallet
Method: POST
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | String | optional | address of the wallet |
Description:
Creates a wallet for the logged-in user. Each user can create up to 3 wallets.
listWallet
Path: /wallet/v1/node/listWallet
Method: GET
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
name | type | required | description |
---|---|---|---|
phone | String | optional | list the phone's address. If not set, list his own address. |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | address of the wallet |
Description:
Lists wallets by phone number. If a phone number is provided, it lists the wallets of the logged-in user.
getBalanceOfAddress
Path: /wallet/v1/node/getBalanceOfAddress
Method: GET
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
name | type | required | description |
---|---|---|---|
address | String | required | the address |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Long | optional | The balance value for the address |
Description:
Retrieves the balance for the specified address.
getBalanceByAddressList
Path: /wallet/v1/node/getBalanceByAddressList
Method: GET
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
name | type | required | description |
---|---|---|---|
addressList | String | required | the address list join by "," |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | The balance value for the address |
BalanceVO:
name | type | required | description |
---|---|---|---|
confirmed | Long | required | confirmed balance |
unconfirmed | Long | required | unconfirmed balance |
Description:
Batch retrieves balances for a list of addresses.
getBalanceOfWallet
Path: /wallet/v1/node/getBalanceOfWallet
Method: GET
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | The balance value for the address |
WalletSpentInfo:
name | type | required | description |
---|---|---|---|
address | String | required | address |
balance | Long | required | the balance |
spent | Long | required | the spent balance |
Description:
Lists the logged-in user's wallet spending information.
getAssetsOfWallet
Path: /wallet/v1/node/getBalanceOfWallet
Method: GET
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | AssetsInfo | optional | The balance value for the address |
AssetsInfo:
name | type | required | description |
---|---|---|---|
balance | Long | required | the total balance of the user |
IdentityNum | Integer | required | the count of identity assets |
ownershipNum | Integer | required | the count of ownership assets |
walletNum | Integer | required | the count of wallets |
Description:
Lists the logged-in user's wallet assets (including balance, ownership, and identity information).
getAssetsOfAddress
Path: /wallet/v1/node/getAssetsOfAddress
Method: GET
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
name | type | required | description |
---|---|---|---|
address | String | required | the address |
type | Integer | required | the asset type: 1 ownership, 2 identity |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | The balance value for the address |
AddressAssetsInfo:
name | type | required | description |
---|---|---|---|
address | String | required | the address |
type | Integer | required | asset type: 1 ownership, 2 identity |
txId | String | required | the transaction id |
idx | Integer | required | the output index of the transaction |
value | String | required | the asset value, encoding with hex |
doubleHashHex | String | optional | the asset data double hash hex data |
Description:
Retrieves user asset information by address and asset type.
getPubKeyHashFromAddress
Path: /wallet/v1/node/getPubKeyHashFromAddress
Method: GET
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
name | type | requred | description |
---|---|---|---|
address | String | required | the address |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | String | optional | public key hash encoding hex string |
Description:
Retrieves the public key hash from the specified address.
sendTo
Path: /wallet/v1/node/sendTo
Method: POST
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
name | type | required | description |
---|---|---|---|
from | String | required | the from address |
address | String | required | the to address |
receivePhone | String | optional | received phone |
String | optional | received email | |
transContent | TransactionContentPO | required | the transfer content data |
payPassword | String | required | the payment password |
TransactionContentPO:
name | type | required | description |
---|---|---|---|
type | Integer | required | the transaction type: 1 ownership, 2 identity |
valueHex | String | optional | value encoding in hex string, deprecated. |
uuid | String | optional | the uuid for the asset |
hash | String | optinal | the asset data hash data |
note: If the received phone or email not empty, and then make sure the
address
address belongs to it.
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
Sends tokens, ownership, or identity assets to another user.
pay
Path: /wallet/v1/node/pay
Method: POST
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
name | type | required | description |
---|---|---|---|
from | String | required | the from address |
to | String | required | the to address |
receivePhone | String | optional | received phone |
String | optional | received email | |
value | Long | required | the balance value |
payPassword | String | required | the payment password |
note: If the received phone or email not empty, and then make sure the
to
address belongs to it.
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
Transfers coins to another user.
searchTxByType
Path: /wallet/v1/node/searchTxByType
Method: GET
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
name | type | required | description |
---|---|---|---|
type | Integer | required | 0 balance 1 ownership 2 identity |
pageNo | Integer | optional | default 1 |
pageSize | Integer | optional | default 10 |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | transaction info list. |
TransactionInfo:
name | type | required | description |
---|---|---|---|
fromAddress | String | required | the from address |
toAddress | String | required | the to address |
txId | String | required | the transaction id |
idx | Integer | required | the output index of the transaction |
txType | Integer | required | the transactfion type: 0 balance, 1 ownership, 2 identity |
inOut | String | required | IN: input, OUT: output |
value | String | required | the balance/asset value |
timestamp | String | required | the transaction create timestamp in the 'YYYY-mm-dd HH:MM:SS' date format |
Description:
Searches for transactions by type.
searchTxByTime
Path: /wallet/v1/node/searchTxByTime
Method: GET
Request header: { AuthorizationV2: "<sessionKey>" }
Request:
name | type | required | description |
---|---|---|---|
startTime | Long | required | the stat time in milliseconds |
endTime | Long | required | the end time in milliseconds. |
pageNo | Integer | optional | default 1 |
pageSize | Integer | optional | default 10 |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | transaction info list. |
TransactionInfo details see the above.
Description:
Searches for transactions by time range.
Block APIs
These APIs provide public blockchain data access without requiring user authentication.
getBlockHashList
Path: /block/v1/node/get-block-hashList
Method: GET
Request:
name | type | required | description |
---|---|---|---|
baseHeight | Long | required | The start height |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | block hash list |
Description:
Retrieves a list of block hashes by base height and remote node IP:port, with batches of 100 items.
getBlock
Path: /block/v1/node/get-block
Method: GET
Request:
name | type | required | description |
---|---|---|---|
hash | String | required | the block hash |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | BlockPO | optional | block hash list |
BlockPO:
name | type | required | description |
---|---|---|---|
header | BlockHeaderPO | required | block header |
dataHexStr | String | required | block data hex string |
Description:
Retrieves a block by its hash.
getBlockHeaderList
Path: /block/v1/node/get-block-header-list
Method: GET
Request:
name | type | required | description |
---|---|---|---|
baseHeight | Long | required | The start height |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | block header list |
BlockHeaderPO:
name | type | required | description |
---|---|---|---|
hash | String | required | block hash |
minedTimestamp | Long | required | the mined timestamp |
version | String | required | the version |
height | Long | required | the height of the block |
prevBlockHash | String | required | the previous block hash |
merkleTreeRoot | String | required | the merkle tree root |
minerIpPort | String | optional | the miner ipPort |
minerInfo | String | optional | the miner info |
timeStamp | Long | required | the block create timestamp |
difficulty | Long | required | the difficulty of the block |
nonce | Long | required | the nonce. |
Description:
Retrieves a list of block headers by blockchain height, with batches of 100 items.
getBlockData
Path: /block/v1/node/get-block-data
Method: GET
Request:
name | type | required | description |
---|---|---|---|
hash | String | required | the block hash |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | String | optional | the block data encoding in hex string |
Description:
get block data by block hash
getBlockTailsHashList
Path: /block/v1/node/get-blocktails-hashList
Method: GET
Request:
name | type | required | description |
---|---|---|---|
baseHeight | Long | required | the start height to get |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | block tails hash list |
Description:
Retrieves block tails hash list by blockchain height, with batches of 100 items.
getBlockTailsPO
Path: /block/v1/node/get-blocktails-po
Method: GET
Request:
name | type | required | description |
---|---|---|---|
hash | Long | required | the block hash |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | BlockTailsPO | optional | block tails data |
BlockTailsPO:
name | type | required | description |
---|---|---|---|
height | Long | required | the block height |
hash | String | required | the block hash |
hashCrc32 | Integer | required | the block hash crc32 value |
prevHash | String | required | the previous block hash |
isMaster | Byte | required | 0 slave 1 master |
Description:
Retrieves block tails by block hash.
getTxByTxId
Path: /block/v1/node/gettx-by-txid
Method: GET
Request:
name | type | required | description |
---|---|---|---|
txIdStr | String | required | tx id hex string |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | TransactionDetail | optional | transaction detail. |
TransactionDetail:
name | type | required | description |
---|---|---|---|
blockHash | String | required | block hash |
height | Long | required | the block height |
txIdHexStr | String | required | the transaction id |
type | Integer | required | the transaction type: 0 balance, 1 ownership, 2 identity |
inputs | List |
required | inputs of transaction |
outputs | List |
required | outputs of transaction |
createTime | Long | required | the create time for the transaction |
minedTimestamp | Long | required | the block mined timestamp |
sendersPubKeyHash | List |
required | the sender public key hash list |
receiversPubKeyHash | List |
required | the receiver public key hash list |
confirmations | Long | required | the confirmation of the block. |
TXInputPO:
name | type | required | description |
---|---|---|---|
txIdStr | String | required | tx id hex string |
txOutputIndex | Integer | required | the output index for the transaction |
unlockScript | String | required | the unlock script encoding hex string |
value | String | required | the value |
serialNO | Integer | required | the serial NO. |
addressList | List |
required | the inputs' address list. |
TXOutputPO:
name | type | required | description |
---|---|---|---|
txIdStr | String | required | tx id hex string |
idx | Integer | required | the output index for the transaction |
status | Integer | required | Status: 0 unspent, 1 spent |
value | String | required | the value |
lockScript | String | required | the lock script encoding hex string |
addressList | List |
required | the outputs' address list. |
Description:
Retrieves transaction details by transaction ID.
getTransactionsByTxIdList
Path: /block/v1/node/gettx-by-txid-list
Method: POST
Request:
name | type | required | description |
---|---|---|---|
txIdList | List |
required | tx id list |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | transaction details |
TransactionDetail: more detail see above.
Description:
Batch retrieves transactions by transaction ID list.
searchTxByTxId
Path: /block/v1/node/search-tx-by-txid
Method: GET
Request:
name | type | required | description |
---|---|---|---|
txIdStr | String | required | tx id hex string |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | transaction details |
Description:
Searches for all transactions related to the specified transaction ID.
searchTxByAddress
Path: /block/v1/node/search-tx-by-address
Method: GET
Request:
name | type | required | description |
---|---|---|---|
address | String | required | the address |
minOutputKey | String | optional | Default "" |
limit | Integer | optional | Default 100 |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | AddressTxInfo | optional | address transaction info data |
AddressTxInfo:
name | type | required | description |
---|---|---|---|
address | String | required | the address |
pubKeyHash | String | required | public key hash |
txDetailList | List |
required | Transaction detail list |
minOutputKey | String | required | the minOutputKey for next query |
TransactionDetail: more details see above.
Note: the
minOutputKey
value should be set after your query in the first time. When you getAddressTxInfo
data, you will get the dataminOutputKey
.
Description:
Searches for transactions by address and minimum output key.
searchUtxos
Path: /block/v1/node/search-utxos
Method: GET
Request:
name | type | required | description |
---|---|---|---|
address | String | required | the address |
minOutputKey | String | optional | Default "" |
limit | Integer | optional | Default 100 |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | AddressUTXOInfo | optional | address transaction info data |
AddressUTXOInfo:
name | type | required | description |
---|---|---|---|
address | String | required | the address |
pubKeyHash | String | required | public key hash |
outputs | List |
required | the uxto outputs. |
TxOutputPO: more detail see above
Note: the minOutputKey value should be set after your query in the first time. When you get
AddressUTXOInfo
data, you will get the dataoutputs
which isTXOutputPO
type. The outputs list is sort by output db id asc. So you will get the minOutputKey for the next query by the following code:
TXOutputPO lastItem = outputs.get(outputs.size() - 1);
String minOutputKey = lastItem.getTxIdStr() + ":" + lastItem.getTxOutputIndex();
Description:
Searches for UTXOs (Unspent Transaction Outputs) by address and minimum output key.
Clouder APIs
These APIs are internal APIs for clouder nodes.
All requests and responses use Content-Type: application/json
.
heartbeat
Path: /coulder/v1/node/heartbeat
Method: POST
Request:
name | type | required | description |
---|---|---|---|
requestId | String | optional | |
version | String | required | such as '1.0.0' |
role | String | required | CLOUDER, MINER |
protolVersion | String | required | such as '1.0.0' |
publicIP | String | required | |
localIP | String | required | |
port | Integer | required | such as 80 |
ipPort | String | required | such as '123.23.45.23:80' |
heartBeatPO | HeartBeatPO | required |
HeartBeatPO:
name | type | required | description |
---|---|---|---|
baseHeight | Long | required | the base height of the node |
ipPortList | List |
required | the neighbors ipPort list of the node |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the mesage |
data | HeartBeatInfo | optional | the heartbeat info data |
HeartBeatInfo:
name | type | required | description |
---|---|---|---|
heartBeatPO | HeartBeatPO | required | heartbeat po |
publicIP | String | required | public ip |
localIP | String | required | local ip |
port | Integer | required | such as 80 |
publicKey | String | required | public key hex string |
heartBeanSign | String | required | the sign data for the hearbeatPO |
Description:
This API is deprecated.
getBlockHashList
Path: /coulder/v1/node/getBlockHashList
Mthod: GET
Request:
name | type | required | description |
---|---|---|---|
baseHeight | Integer | required | the start height |
ipPort | String | required | the remote node ipPort, such as '123.23.45.23:80' |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | the block hash list |
Description:
This API retrieves block hash lists in batches of 100 items.
getBlock
Path: /coulder/v1/node/getBlock
Mthod: GET
Request:
name | type | required | description |
---|---|---|---|
hash | String | required | the block hash |
ipPort | String | required | the remote node ipPort |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | BlockPO | optional | the block data. |
BlockPO:
name | type | required | description |
---|---|---|---|
header | BlockHeaderPO | required | block header |
dataHexStr | String | required | block data hex string |
BlockHeaderPO:
name | type | required | description |
---|---|---|---|
hash | String | required | block hash |
minedTimestamp | Long | required | the mined timestamp |
version | String | required | the version |
height | Long | required | the height of the block |
prevBlockHash | String | required | the previous block hash |
merkleTreeRoot | String | required | the merkle tree root |
minerIpPort | String | optional | the miner ipPort |
minerInfo | String | optional | the miner info |
timeStamp | Long | required | the block create timestamp |
difficulty | Long | required | the difficulty of the block |
nonce | Long | required | the nonce. |
Description:
This API provides functionality for fetching blocks by their hash.
getBlockHeaderList
Path: /coulder/v1/node/getBlockHeaderList
Method: GET
Request:
name | type | required | description |
---|---|---|---|
baseHeight | Long | required | the start height to get block header list |
ipPort | String | required | the remote node ipPort |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | the list of block headers |
Description:
Batch retrieves block header lists by current block height, with batches of 100 items.
getBlockData
Path: /coulder/v1/node/getBlockData
Method: GET
Request:
name | type | required | description |
---|---|---|---|
hash | String | required | the block hash |
ipPort | String | required | the remote node ipPort |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | String | optional | the block data encoding in hex string |
Description:
get block data by block hash
broadcastMinedBlock
Path: /coulder/v1/node/broadcastMinedBlock
Method: POST
Request:
name | type | required | description |
---|---|---|---|
Block | BlockPO | required | the block data |
minerPublicKey | String | required | the miner public key |
minerPublicIP | String | required | the miner public ip |
blockSign | String | required | the block hash signed by the miner private key |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | String | optional | the result string |
Description:
Broadcasts the mined block data across CircleChain clusters.
brandcastTransaction
Path: /coulder/v1/node/broadcastTransaction
Method: POST
Request:
name | type | required | description |
---|---|---|---|
transaction | TransactionPO | required | Transaction data |
TransactionPO:
name | type | required | description |
---|---|---|---|
txIdHexStr | String | required | the transaction id hex string |
type | Integer | required | the transaction type: 0 balance, 1 ownership, 2 identity |
inputsHexStr | String | required | the inputs hex string |
outputsHexStr | String | required | the outputs hex string |
createTime | Long | required | the create time of the transaction |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | String | optional | transaction id hex string |
Description:
Broadcasts transaction data across the network.
broadcastTransactionList
Path: /coulder/v1/node/broadcastTransactionList
Method: POST
Request:
name | type | required | description |
---|---|---|---|
transactionList | List |
required | Transaction list data |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | transaction id hex string list |
Description:
Batch broadcasts transaction list across the network.
getBlockTailsHashList
Path: /coulder/v1/node/getBlockTailsHashList
Method: GET
Request:
name | type | required | description |
---|---|---|---|
baseHeight | Long | required | the start height to get |
ipPort | String | required | the remote node's ipPort |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | block tails hash list |
Description:
Retrieves block tails hash list by blockchain height.
getBlockTailsPO
Path: /coulder/v1/node/getBlockTailsPO
Method: GET
Request:
name | type | required | description |
---|---|---|---|
hash | Long | required | the block hash |
ipPort | String | required | the remote node's ipPort |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | BlockTailsPO | optional | block tails data |
BlockTailsPO:
name | type | required | description |
---|---|---|---|
height | Long | required | the block height |
hash | String | required | the block hash |
hashCrc32 | Integer | required | the block hash crc32 value |
prevHash | String | required | the previous block hash |
isMaster | Byte | required | 0 slave 1 master |
Description:
Retrieves block tails by block hash.
Miner APIs
These are internal miner APIs that provide mining services.
retrieveMinerIpPortList
Path: /miner/v1/node/retrieveMinerIpPortList
Method: POST
Request:
name | type | required | description |
---|---|---|---|
version | String | required | 0.0.1 |
role | String | required | CLOUDER, MINER etc |
protolVersion | String | required | 1.0.0 |
publicIP | String | required | public ip |
localIP | String | required | local ip |
port | Integer | required | the port |
publicKey | String | optional | the node's public key |
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | List |
optional | the ipPort list |
Description:
Retrieves the list of miner IP:port addresses.
Service and Event Layer
The Service and Common Library Layer includes:
- Clouder Service
- Provides clouder services: implementation of internal clouder APIs, including block search, heartbeat, transaction and block broadcast services.
- Miner Service
- Provides mining services: implementation of internal miner APIs, including miner list search functionality.
- Wallet Service
- Provides wallet services: implementation of public wallet APIs, including wallet creation, asset search, payments, and asset transfers.
- Blocktails Service
- Provides block tails services: implementation of block tails APIs for fork management.
- NodeInfo Service
- Node information service, provides node search and node information storage services.
- Blockchain Library
- Core blockchain library that provides fundamental blockchain functions.
Events:
- BlockEvent
- Broadcast when a cloud or miner node receives a valid block, or when a miner node successfully mines a block.
- TransactionEvent
- Broadcast when a cloud or miner node receives a valid transaction.
- TransPoolEvent
- Only miner nodes can create transaction pool events. Broadcast when the transaction pool is full or when the transaction pool waiting time expires.
Background Jobs
Background Jobs:
- Heartbeat Job
- Synchronizes node information with neighbor nodes. The next heartbeat starts 10 seconds after the current job completes.
- MinerTask Job
- Can only be executed by miner nodes. The next job executes 10 minutes after the current job completes.
- SyncBlock Task Job
- Executes 5 minutes after the last task completes. Starts when the node's block height is lower than the maximum height of neighbors.
Configuration Center
The Configuration Center includes:
- Async Thread Pool Configuration - Default thread pool settings
- Path Configuration - API endpoint path configuration
- Block Configuration - Blockchain instance initialization configuration
- SyncBlock Task Configuration - Determines whether sync tasks should be started
- BlockStorage Configuration - Block storage instance configuration
- WalletStorage Configuration - Wallet storage instance configuration
- MinerTask Configuration - Determines whether the node should start mining tasks
- Wallet Configuration - Wallet instance initialization configuration
- Node Configuration - Node configuration including role, mobile, encrypted password, etc.
Storage Layer
The Storage Layer includes:
- BlockStorage Service
- Block storage service that supports storing large data in cloud storage.
- BlockCopyStorage Service
- Block copy service that provides block replication functionality.
- WalletStorage Service
- Wallet storage service that supports cloud wallet functionality.
Service and Event Layer
Clouder Node Services
Clouder node services provide internal services for ClouderController. The class diagram is shown below:
Transaction Broadcasting Mechanism
The process of broadcasting transactions to neighbor nodes:
- Search node information from
circle_node_info
table ordered by ID descending, starting withLong.MAX_VALUE
- When the batch is not empty, send valid transaction information to the batch of neighbor nodes
- When the current batch is sent, search for the next batch of nodes using the minimum ID from the current batch
- If the next batch is not empty, continue with step 2; otherwise, stop broadcasting
Blockchain Broadcasting
The process of broadcasting blockchain data to neighbor nodes:
- Search node information from
circle_node_info
table ordered by ID descending, starting withLong.MAX_VALUE
- When the batch is not empty, send valid block information to the batch of neighbor nodes
- When the current batch is sent, search for the next batch of nodes using the minimum ID from the current batch
- If the next batch is not empty, continue with step 2; otherwise, stop broadcasting
Miner Node Services
Miner node services provide internal services and functions for miner APIs. The class diagram is shown below:
Wallet Node Services
Wallet services provide internal services and functions for wallet APIs. The class diagram is shown below:
Blockchain Libraries
The blockchain library provides common and basic functions:
Transaction Functions
The blockchain library includes four types of transactions:
- Coinbase Transaction - Mining rewards and new coin creation
- Coin Transaction - Standard cryptocurrency transfers
- Ownership Transaction - Digital asset ownership transfers
- Identity Transaction - Digital identity management
The coinbase transaction includes coin coinbase, ownership coinbase, and identity coinbase transactions.
Block Functions
Block functions include block and blockchain operations. The following capabilities are provided:
- Block Construction - Including genesis block and normal block creation
- Block Search - Locating blocks by various criteria
- Block Copy - Block replication functionality
- Block Serialization/Deserialization - Data format conversion
The block functions include:
- Blockchain Initialization - Setting up the blockchain
- Genesis Block Creation - Creating the first block
- New Block Addition - Adding blocks to the chain
- Blockchain Iteration - Traversing the blockchain
- UTXO Search - Finding unspent transaction outputs
- Spent Assets Search - Locating spent assets
- Transaction Search by ID - Finding transactions in the blockchain
- Block Search by Hash or Transaction ID - Locating blocks
- Transaction Signing - Cryptographic signature generation
Cryptographic Functions
The blockchain's cryptographic functions include:
-
Address Generation: User addresses are globally unique and anonymous. Each wallet generates one unique address. A registered user with a unique mobile phone can generate up to 3 wallets. Each wallet has a public key that is transformed to a public key hash using RIPEMD160 and additional processing, then encoded to an address using Base58 encoding.
-
Block and Transaction IDs: Block and transaction IDs are generated using SHA256 double hashing of their respective data.
-
Output Locking: Transaction outputs include lock scripts generated using the P2PKH (Pay-to-Public-Key-Hash) protocol, which can only be unlocked by the correct user's private key.
-
Input Unlocking: Transaction inputs include unlock scripts generated by signing with the input's key and the user's private key. The unlock script and lock script are combined and executed in the CircleChain script engine.
-
Asset Transaction Processing: All asset transactions are processed using the same algorithm and process as coin transactions.
-
Asset Security: When uploading assets, they are signed with the user's public key and encrypted using RSA with the user's RSA password. When downloading raw assets from the cloud, the system first verifies the signature and then decrypts the data using the RSA password.
Block Mining Functions
The blockchain module includes the miner's block mining function with two mining styles: single-thread and multi-thread.
Single-thread Mining Algorithm:
// Single-thread mining example
for (long i = 0; i < Long.MAX_VALUE; i++) {
this.getBlock().setNonce(nonce);
String shaHex = this.getBlock().computeHash();
BigInteger shaHexValue = new BigInteger(shaHex, 16);
log.debug("nonce:{}, shaHexValue:{}, target:{}", nonce, shaHexValue, this.target);
if (shaHexValue.compareTo(this.target) < 0) {
break;
}
}
// Block mining successful!
Multi-thread Mining Algorithm:
int mineThreadCount = Runtime.getRuntime().availableProcessors() + 1; // CPU cores + 1
CircleMiner[] array = new CircleMiner[mineThreadCount];
Long span = Long.MAX_VALUE / mineThreadCount;
for (int i = 0; i < mineThreadCount; i++) {
BigInteger end = BigInteger.valueOf(i + 1L).multiply(BigInteger.valueOf(span));
if (end.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
end = BigInteger.valueOf(Long.MAX_VALUE);
}
Range<Long> nonceRange = Range.between(i * span, end.longValue());
array[i] = new CircleMiner(nonceRange, minerAddress, repoType);
}
List<CompletableFuture<Block>> fList = Lists.newArrayListWithExpectedSize(array.length);
for (CircleMiner miner : array) {
CompletableFuture<Block> bF = CompletableFuture.supplyAsync(() -> {
try {
Block copyOfBlock = Block.deepCopy(unminedBlock);
Block b = miner.mineBlock(copyOfBlock, repoType);
if (b != null) {
log.info("mined block:{}", b.toString());
return b;
}
} catch (Exception e) {
log.error("mineBlock exception", e);
minedSuccess.compareAndSet(true, false);
}
return null;
}, threadPool);
fList.add(bF);
}
Wallet Functions
The wallet system includes wallet packages, individual wallets, and address functions and concepts.
Wallet Package: Only one mobile phone can register for one wallet package.
Wallet: A wallet package contains at most 3 wallets. Each wallet includes a public key and private key pair. The public key generates a public address, and the public address generates a public key hash. The public key hash is used to lock transactions, and the private key is used to generate unlock scripts to unlock lock scripts.
Address: Users use addresses to exchange tokens and assets. A public key is used to generate the address.
Wallet Service Functions:
- Wallet Assets Query - Query wallet assets and balances
- Token Transactions - Handle cryptocurrency transfers
- Asset Transactions - Manage digital asset transfers
Blockchain Fork Management Service
The Blocktails Service is designed to resolve blockchain forking issues. When two or more blocks are mined in the same second, the blockchain forks. The miner stores the forked blocks in the circle_block
table and records the forking information in circle_block_tails
. When multiple blocks are mined in the same second, the system selects the earliest block as the master block by default and stores the master information in circle_block_tails
.
The system stores every block in circle_block
and must update the circle_block_tails
table and master information according to the rules of maximum height and earliest block mining time.
Design Principles
The master block selection algorithm is as follows:
- Search for all master blocktails information ordered by height descending, limit 1
- When the blocktails is not null, the blocktails' block is the master block
The circle_block_tails
table structure:
Fields | Type | Description |
---|---|---|
height | Long | The height in the blockchain |
hash | String | The hash of the current block |
hash_crc32 | Integer | CRC32 value of the block hash |
prev_hash | String | The previous hash of the current block |
is_master | Boolean | Flag indicating if the block is master |
The forking information is stored in the circle_block_tails
table.
Forking Process Mechanism
When a broadcast block arrives at a miner node, if the broadcast block has the same block height as the top block of the blockchain and its mined block timestamp is equal to or earlier than the top block (in seconds), then the broadcast block cannot be confirmed as invalid and should be added to circle_block
. This causes the blockchain to fork. The forking information of the blockchain will be updated in circle_block_tails
. To confirm a block, the forking block depth should be at least 6 or more.
The blockchain confirmation depth is 6. When block confirmation reaches 6, the block can become a master block and can never be changed or deleted. If the block confirmation depth is less than 6, there is a possibility that the block is a slave block due to blockchain forking.
Node Information Services
The CircleChain node information service provides neighbor node information storage and data services for heartbeat, block, and transaction broadcasting.
Node Information Table
The circle_node_info
table structure:
Fields | Type | Description |
---|---|---|
public_ip | String | Public IP address |
local_ip | String | Internal IP address |
version | String | Node version |
role | String | Role: CLOUDER (clouder node) or MINER (miner node) |
protol_version | String | Protocol version |
port | Integer | Server port |
public_key | String | Node public key that represents the node |
base_height | Integer | The top height of the CircleChain node blockchain |
visit_count | Integer | Node visit count, default 0 |
create_time | Long | Creation time in milliseconds |
update_time | Long | Update time in milliseconds |
This table provides data services for broadcasting heartbeat, blocks, and transactions, as well as synchronizing CircleChain node information and blocks.
Background Jobs
Heartbeat Task
The node synchronizes node information with up to 100 neighbor nodes every 10 seconds.
Heartbeat Broadcasting Mechanism
Every query searches for up to 100 least-visited miners in the circle_node_info
table. After each heartbeat search, the visit count of these least-visited miners is increased. This ensures that the next query for least-visited miners will include other unvisited or less-visited miners.
Broadcast Algorithm:
List<BaseNodeInfo> baseNodeInfoList = nodeInfoService.queryLeastVisitMiners(); // Query least-visited miners
log.info("searched {} miners to heartbeat", baseNodeInfoList.size());
if (CollectionUtils.isNotEmpty(baseNodeInfoList)) {
syncSendHeartBeat(baseNodeInfoList);
List<String> publicIpList = baseNodeInfoList.stream().map(BaseNodeInfo::getPublicIP)
.collect(Collectors.toList());
nodeInfoService.addVisitCountOfNeighbors(publicIpList); // Increase visit count of least-visited miners
}
Block Mining Task
The miner's block mining task checks the mining conditions every 10 minutes after the task completes. When the conditions are met, the mining task starts. The conditions include the following criteria:
- The time span since the last mined block is greater than
MAX_WAIT_TIME
(60 seconds) - The number of transactions in the transaction pool is greater than
MAX_BLOCK_TX_SIZE
(2048)
If either condition is met, the block mining task will be started.
Miner Design
See more details in the Blockchain Library section.
Block Broadcasting Mechanism
The mechanism is the same as the heartbeat broadcasting.
Note: Only miner nodes have the block broadcasting task; clouder nodes and others do not.
Block Synchronization Task
The block synchronization task starts every 5 minutes after the last synchronization task completes.
Block Synchronization Mechanism
The block synchronization mechanism includes the following steps:
- Search for the maximum height node information in the
circle_node_info
table - In a loop, synchronize block data from the maximum height node using public IP and port, starting from the node's own base height in batches of 100 items
- When block synchronization is finished, break the loop
Configuration Center
Async Thread Pool Configuration
Default thread pool configuration:
core_pool_size: 5
max_pool_size: 10
queue_capacity: 100
Path Configuration
External API path configuration:
API Path Configuration
## Clouder APIs
path.blockHashListPath=/clouder/v1/node/getBlockHashList
path.blockPath=/clouder/v1/node/getBlock
path.blockHeaderListPath=/clouder/v1/node/getBlockHeaderList
path.blockDataPath=/clouder/v1/node/getBlockData
path.blockTailsHashListPath=/clouder/v1/node/getBlockTailsHashList
path.blockTailsPOPath=/clouder/v1/node/getBlockTailsPO
path.heartbeatPath=/clouder/v1/node/heartbeat
path.broadcastMinedBlock=/clouder/v1/node/broadcastMinedBlock
path.broadcastTransaction=/clouder/v1/node/broadcastTransaction
## Miner APIs
path.minerIpPortList=/miner/v1/node/retrieveMinerIpPortList
## Wallet APIs
path.initWalletPackage=/wallet/v1/node/initWalletPackage
path.createWallet=/wallet/v1/node/createWallet
path.listWallet=/wallet/v1/node/listWallet
path.listPubkey=/wallet/v1/node/listPubkey
path.balanceOfAddress=/wallet/v1/node/getBalanceOfAddress
path.balanceOfWallet=/wallet/v1/node/getBalanceOfWallet
path.pubKeyHashFromAddress=/wallet/v1/node/getPubKeyHashFromAddress
path.sendTo=/wallet/v1/node/sendTo
path.requestCharge=/wallet/v1/node/requestCharge
## Block APIs
path.blockchainHashListPath=/block/v1/node/get-block-hashlist
path.blockchainPath=/block/v1/node/get-block
path.blockchainHeaderListPath=/block/v1/node/get-block-header-list
path.blockchainDataPath=/block/v1/node/get-block-data
path.blockchainTailsHashListPath=/block/v1/node/get-blocktails-hashlist
path.blockchainTailsPOPath=/block/v1/node/get-blocktails-po
Blockchain Configuration
The blockchain initialization code:
public class BlockchainConfig {
@Bean(name = "blockchain")
@DependsOn("blockCloudRepository")
public Blockchain getBlockchain() {
Blockchain blockchain = null;
try {
blockchain = Blockchain.initBlockchain(RepoType.CLOUD_STORE);
} catch (Exception e) {
log.error("initBlockchain error!", e);
blockchain = Blockchain.createGenesisBlockchain(RepoType.CLOUD_STORE);
}
return blockchain;
}
}
Block Synchronization Configuration
Block synchronization configuration includes checking node height with neighbors and configuring synchronization intervals.
In the JUnit profile, the block synchronization task is not started.
Neighbor Node Selection and Block Synchronization Algorithm
The following Java code samples describe how to select neighbor nodes and implement the synchronization algorithm:
Neighbor Node Selection Algorithm:
BaseNodeInfo maxHeightNodeInfo = clouderService.getMaxHeightInNeighbors();
if (Objects.isNull(maxHeightNodeInfo)) {
log.warn("there is no max height node!");
return 0;
}
BaseNodeInfo myNodeInfo = clouderService.getMyBaseNodeInfo();
if (myNodeInfo.getBaseHeight() >= maxHeightNodeInfo.getBaseHeight()) {
log.warn("my node height {} is not less than neighbor {}!", myNodeInfo.getBaseHeight(),
maxHeightNodeInfo.getBaseHeight());
return 0;
}
if (!NetworkUtils.isValidPublicIP(maxHeightNodeInfo.getPublicIP())) {
log.warn("max height node has no public ip, nodeInfo:{}!", JSON.toJSONString(maxHeightNodeInfo));
return 0;
}
Block Synchronization Algorithm:
BaseResponse<List<String>> result = clouderApiClient.getBlockHashList(baseHeight, ipPort);
List<String> hashList = result.getData();
for (String hash : hashList) {
BaseResponse<BlockPO> blockResult = clouderApiClient.getBlock(hash, ipPort);
if (blockResult != null && blockResult.isOk()) {
BlockPO blockPO = blockResult.getData();
Block block = blockPO.convert2Block();
if (!BlockValidator.verifyBlock(blockchain, block, RepoType.CLOUD_STORE)) {
log.error("block {} is invalid, discard it...", block.getHash());
continue;
}
blockCopyRepository.copyBlock(block);
} else {
log.error("cannot get block from ipPort: {}", ipPort);
}
}
Blockchain Configuration
Blockchain instance configuration settings.
Wallet Storage Configuration
Wallet instance configuration settings.
Miner Task Configuration
Miner task configuration includes checking whether the node is a miner node and starting the mining task when the node is a miner node.
Wallet Configuration
Wallet instance configuration settings.
Node Information Configuration
Node information configuration includes role, mobile, and encrypted password settings.
Storage Layer
Blockchain Storage Service
Blockchain storage service that supports big data storage.
Interfaces
The blockchain storage service includes the following APIs:
Initialization and Cleanup:
-
void init()
: Initialize the service -
void close()
: Clean up resources
Block Search:
-
String getFirstBlockHash()
: Get the first block hash -
String getLastBlockHash()
: Get the last block hash -
Block getBlock()
: Get a block -
String getPrevBlockHash(String blockHash)
: Get the previous block hash -
boolean blockExists(String blockHash)
: Check if a block exists -
Long getHeight(String blockHash)
: Get block height -
Long getBlockHeightByTxId(byte[] txId)
: Get block height by transaction ID -
Block getBlockByTxId(byte[] txId)
: Get block by transaction ID
Block Addition:
boolean addBlock(Block block)
: Add a block to the blockchain
UTXO Functions:
-
Map<String, byte[]> getChainstateBucket()
: Search local UTXO mapping -
void cleanChainStateBucket()
: Clear local UTXO data -
void putUTXOs(String txIdHexStr, TXOutput[] utxos)
: Save UTXOs in local storage -
TXOutput[] getUserUTXOs(byte[] pubKeyHash)
: Search UTXOs by public key hash -
TXOutput[] getUTXOs(String txIdHexStr)
: Search transaction UTXOs by transaction ID -
int deleteUTXOs(String txIdHexStr)
: Delete UTXOs by transaction ID
Transaction Search:
-
Transaction findTransaction(byte[] txId)
: Find a transaction -
List<String> transactionFilterByTypeSet(List<String> txIdList, Set<Integer> typeSet)
: Filter transaction ID list by transaction type set
Blockchain Copy Service
The blockchain copy service provides block replication functionality.
Details
The copy block service does not validate blocks and their transactions, as it assumes that all input data is valid by default.
Interfaces
-
boolean copyBlock(Block block)
: Copy block data to the database without any validation -
boolean copyBlockTail(CircleBlockTails circleBlockTails)
: Copy block tails data to the database without validation
Wallet Storage Service
The wallet storage service provides wallet data storage functionality, supporting both cloud and local wallet storage for big data.
Interfaces
There are unified APIs for local and cloud storage:
Initialization and Cleanup:
-
void init()
: Initialize resources -
void close()
: Clean up resources
Wallet Package Management:
-
void initWalletPackage(WalletPackage walletPackage)
: Initialize wallet package -
void updateWalletPackage(WalletPackage walletPackage)
: Update wallet package
Wallet Package Configuration:
-
WalletPackageConfig getWalletPackageConfigByAddress(String address)
: Get wallet package configuration by address -
WalletPackageConfig getWalletPackageConfigByPhone(String phone)
: Get wallet package configuration by phone -
WalletPackageConfig getWalletPackageConfigByUid(String uid)
: Get wallet package configuration by UID -
boolean saveOrUpdatePhone(String phone, WalletPackageConfig config)
: Save or update wallet package configuration by phone and config -
boolean saveOrUpdateAddress(String address, WalletPackageConfig config)
: Save or update wallet package by address and config -
boolean saveOrUpdateUid(WalletPackageConfig config)
: Save or update wallet configuration by UID -
boolean updateWalletPackageConfig(WalletPackageConfig config)
: Save or update wallet package configuration
Cloud Wallet Service
The cloud wallet service provides cloud-based wallet functionality, storing your personal wallet data including private keys on secure cloud servers. You can access cloud wallet services through H5 pages to query personal tokens and assets, make transactions, etc.
The cloud wallet server is among the most highly secure servers in the world. You don't need to worry about your personal assets being lost or stolen. Even if your valuable data were lost, you would be compensated by our company (SHC Ltd.).
Local Wallet Service
The Local Wallet Service provides local wallet functionality that does not store your private keys in the cloud. You must store and backup your private keys and local wallet data yourself. If your private keys and local wallet data are lost or stolen, you will be responsible for the consequences.