CircleChain Architecture
CircleChain is assets management platform based on blockchain technology which originates in bitcoin. Bitcoin is client application based on blockchain and p2p protocol, which stored data in local pc. CircleChain is different fro bitcoin, it's cloud distributed p2p and blockchain system. It stores data in cloud storage and provides cloud blockchain and wallet service to manage assets. CircleChain will be more extensive than bitcoin.
The whole architecture
The whoe architecture includes the following items:
-
API
-
Services and Events
-
Background Jobs
-
Configure Center
-
Storage Layer
API Layer
There are APIs:
- user api: public user apis of CircleChain
- wallet api: public wallet apis of CircleChain
- block api: public block apis of CircleChain
- clouder api: clouder inner apis of CircleChain
- miner api: miner inner apis of CircleChain
APIs
CircleChain APIs are all Restful style interfaces,data encoded in JSON format,The request and response headerContent-type
is "application/json".
User APIs
These Apis are public user apis.
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:
send register verify code before create user account. If you enter email, then your email account will receive the verify code email. If you enter phone, then you will receive verify code sms code.
Note: at the present, the phone is not supported in global market. only email is supported.
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 register api.
Note: at the present, the phone is not supported in global market. only email is supported.
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:
send login verify code before login. If you enter email, then your email account will receive the verify code email. If you enter phone, then you will receive verify code sms code.
Note: at the present, the phone is not supported in global market. only email is supported.
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. when success, you should store sessionKey
in your local file and keep it secret. the sessionKey
is used to invoke other apis as logined user by setting the headers:
{
"AuthorizationV2": <sessionKey>
}
Note: at the present, the phone is not supported in global market. only email is supported.
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
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:
send set pay password verify code before setting pay password. If you enter email, then your email account will receive the verify code email. If you enter phone, then you will receive verify code sms code.
Note: at the present, the phone is not supported in global market. only email is supported.
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. |
Note: at the present, the phone is not supported in global market. only email is supported.
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 set pay password.
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:
check the user wether set the pay 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. |
Note: at the present, the phone is not supported in global market. only email is supported.
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
send set reset login password verify code. If you enter email, then your email account will receive the verify code email. If you enter phone, then you will receive verify code sms code.
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 |
Note: at the present, the phone is not supported in global market. only email is supported.
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 reset login password api.
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 |
String | optional | user email | |
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 |
Note: at the present, the phone is not supported in global market. only email is supported.
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
save or update user info
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 |
String | optional | user email | |
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:
get user info for the logged 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 | optional | user phone |
String | optional | user email | |
sex | Byte | optional | 1: man 0 woman |
icon | String | optional | user icon |
address | String | required | user address |
description | String | optional | description |
Note: at the present, the phone is not supported in global market. only email is supported.
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
add contact in user's contacts. At present, we only support add phone contacts.
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 | optional | user phone |
String | optional | user email | |
sex | Byte | optional | 1: man 0 woman |
icon | String | optional | user icon |
address | String | required | user address |
description | String | optional | description |
Description:
list user contacts. we only support phone contacts at the present.
Wallet APIs
These apis are for wallet service.
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:
Create the wallet for the logged user. each user could create 3 wallets at most.
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:
list wallet by phone. If phone set phone, list the wallet of the logged user.
Note: at the present, the phone is not supported in global market. only email is supported. So please not set phone parameter for global usage.
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:
get the balance for the 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 get the blance for the address list.
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:
list the logged user's wallet spent info.
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:
list the logged user's wallet assets(including balance, ownership and identity) info.
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:
get the user asset infos by address and the 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:
get the public key hash from the 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.At the present, the phone is not supported in global market. only email is supported.
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
send token, ownership or identity assets to someone
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.At the present, the phone is not supported in global market. only email is supported.
Response:
name | type | required | description |
---|---|---|---|
status | Integer | required | 200 - success, others failure |
message | String | required | the message |
data | Boolean | optional | success or failure |
Description:
pay coins to someone
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:
search my 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:
search my transactions by time
Block APIs
These apis for public block apis for block services without user login.
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:
get block hash list by base height and the remote node ipPort, each in 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:
get block by block 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:
get block header list by blockchain height, each in 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:
get blocktails hash list by blockchain height, each in 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:
get blocktails 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:
get transaction 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 get transaction 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:
search all the transactions relevant to the txId.
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:
search tx by address and minOutput 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:
search utxos by address and minOutput key
Clouder APIs
These apis are inner apis for clouders.
All the request and response content type is "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:
the api is obsoleted
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:
the api batch get the block hash list whose batch size if 100.
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:
The api provides the function of fetching block by its block 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 get block header list by the current block height, each in 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:
broadcast the mined block data in circle chain 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:
brandcast transaction api
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 broadcast transaction list api.
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:
get Blocktails 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:
get Blocktails by block hash
Miner APIs
These are miner innner apis which provide miner service.
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:
retrieve miner ipPort list
Service and Event Layer
Service and Common lib Layer includes:
- Clouder Service
- Provides clouder services: implementation of inner clouder apis, including block search, heartbeat, tx and block broadcast service etc.
- Miner Service
- Provides Miner services: implementation of inner miner apis, including search miner list etc.
- Wallet Service
- Provides wallet services: implementation of public wallet apis, including wallet creation, search assets, pay, send assets etc.
- Blocktails Service
- Provides block tails services: implementation of block tails apis.
- NodeInfo Service
- Node Info service, provides node search, node info storage services.
- Blockchain lib
- Blockchain public library, which provides core blockchain functions.
Events:
- BlockEvent
- When cloud or miner node received valid block, or miner node mined block success, blockEvent will be broadcast.
- TransactionEvent
- When cloud or miner node received valid transaction, transaction event will be broadcast.
- TransPoolEvent
- Only miner node can create transPool event. When transpool is full or the waiting time for transpool is timeout, the transpool event will be broadcast.
Jobs on background
Background Jobs:
- Heartbeat Job
- Heartbeat job will synchronized node info with neighbour nodes. The next heartbeat will start in 10 seconds after this job is done.
- MinerTask Job
- MinerTask can only be executed by miner nodes. The next job is executed in 10 minutes after the job is done.
- SyncBlock Task Job
- SyncBlock task will be executed in 5 minutes after last task is done. When the node block height is lower than the max height of neighbours, the syncblock task will be started.
Configure Center
Configure Center includes:
- Async Thread Pool configure: default thread pool
- Path configure: configure path api
- Block configure: init blockchain instance configure.
- SyncBlock Task configure: check the task should be started or not.
- BlockStorage Configure: configure block storage instance.
- WalletStorage Configure: configure wallet storage instance.
- MinerTask Configure: check the node whether start miner task or not.
- Wallet Configure: wallet instance init configure.
- Node configure: the node configure which includes role, mobile, encrypted password etc.
Storage Layer
Storage Layer includes:
- BlockStorage Service
- Block stroage service which supports store the big data in cloud storage.
- BockCopyStorage Service
- Block copy service, which provide copy block service.
- WalletStorage Service
- Wallet storage service, support cloud wallet service.
Service and Event Layer
Services of Clouder node
Clouder node service,inner service for ClouderController, There is Class diagrams here:
The mechanism of Transaction broadcasting
The process of transaction broadcasting to neighbor nodes:
- Search node info from circle_node_info order by id desc with id with Long.MAX_VALUE
- When the batch is not empty, send the valid transaction info to the batch of neighbor nodes.
- When the current batch is sent, search the next batch of nodes with the mininum id of the current batch of nodes.
- If the next batch is not empty, continue with step 2, or stop the broadcasting.
Broadcasting blockchain
The process of blockchain broadcasting to neighbor nodes:
- Search node info from circle_node_info order by id desc with id with Long.MAX_VALUE
- When the batch is not empty, send the valid block info to the batch of neighbor nodes.
- When the current batch is sent, search the next batch of nodes with the mininum id of the current batch of nodes.
- If the next batch is not empty, continue with step 2, or stop the broadcasting.
Services of miner node
Miner node service, inner service, provides functions for miner apis. Here is the class diagram:
Services of wallet node
Wallet service, inner service, provides functions for wallet apis. Here is the class diagram:
Libs of blockchain
The blockchain library provide common and basic functions:
Functions of Transaction
The transaction of blockchain library includes four functions:
1)coinBase transaction
2)coin transaction
3)ownership transaction
4)identity transaction
The coinBase transaction includes coin coinBase, ownership coinBase and identity coinBase.
Functions of Block
Block functions inludes block and blockchain functions. It includes as follows:
- The construction of Block including gensis block and normal block.
- Block search
- Block copy
- Block serialization and deserialization
The block functions includes:
- Init blockchain
- Gensis Block creation
- Add new Block
- Iteration of blockchain
- UTXO search
- Spent assets search
- Search transaction by transaction id in blockchain.
- Search block by block hash or transaction id in blockchain
- Sign transaction
Functions of Crypto
The crypto functions of blockchain includes:
- User address is global unique and anonymous, one wallet can only generate one unique address. One registed user with unique mobile phone can generate most 3 wallet. wallet has public key, public key will be transformed to public key hash by ripeMD160Hash and some simple extractions, and public key hash will be transformed to address by encoded by Base58.
- The id of block and its transactions are sha256 double hash of their own data.
- The output includes lockscript, the lockscript is generated by P2PKH protocol which can only be unlocked by the right user's secret key.
- The input includes unlock script, the unlock script is generated by the signature with the key of the input and user's secret key. the unlock script and lock script will be combined and executed in CircleChain script engine.
- All the assets transactions will be processed with the same algorithm and process with coin transation.
- When upload assets, the assets will be signed by user's public key and encrypted with RSA with user's RSA password. When user download the raw assets from cloud, first to check the right signature and then try to decrypt the data with RSA password.
Functions of Mining block
Blockchain module includes miner's mine block function, there are two mining block styles: single-thread and multi-thread.
There is the single-thread algorithm codes here:
// single thread mine sample.
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;
}
}
// this.getBlock is mined success!
There is the multi-thread mining algorithm codes:
int mineThreadCount = Runtime.getRuntime().availableProcessors() + 1; // 服务器CPU核数+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);
}
Functions of wallet
Wallet includes wallet package, wallet and address functions and concepts.
Wallet Package:Only one cell phone can register for one wallet package.
Wallet:A wallet package contains at most 3 wallets. A wallet includes public key and private key, a public key generate a public address, and a public address generate a public key hash. A public key hash is used to lock transaction and private key is to used to generate unlock script to unlock lockscript.
Address:User use address to exchange token and assets. A public key is used to generate the address.
Wallet Service includes the following functions:
- Wallet assets query function.
- Token transaction
- Assets transaction
Service of forking chain
Blocktails Service is designed to resolve the blockchain forking problem. When there are at least two blocks mined in the same second, the blockchain forks. The miner will store the forked block in the circle_block and put the forking info in circle_block_tails. When there are at least two minded block at the same seconds, the system will select the earliest block as master block default and store the master info in circle_block_tails.
The system stores the every block in circle_block, it must update the circle_block_tails table and update master info according to the rule of the max height and eariest mine block time.
Principles of design
The master block selection algorithm is as followings:
- search all the master blocktails info by height desc limit 1
- when the blocktails is not null, the blocktails' block is the master block.
The circle_block_tails table:
Fields | Type | Description |
---|---|---|
height | Long | the height in blockchain |
hash | String | the hash of the current block |
hash_crc32 | Integer | crc32 value of block hash |
prev_hash | String | the previous hash of the current block |
is_master | Boolean | the flag which shows the block is master or not |
The forking info is stored in circle_block_tails table.
The mechanism of forking process
When the broadcast block arrives at the miner node, the broadcast block has the same block height with the top block of blockchain and its mined block timestamp is equal or even earlier than the top block in seconds, then the broadcast block cannot be confirmed to be invalid, it should be added to circle_block. So the blockchain forks. the forking info of blockchain will be updated in circle_block_tails. In order to confirm the block, the forking block depth should be at least 6 or more.
So the blockchain confirmation depth is 6, when block confirmation is 6, the block can be master block, it can never be changed and deleted. If the block confirmation depth is less than 6, there is an possible that the block is slave block because of block forking.
Services of node info
The circle node info service provides neighbor node info storage, data services for heartbeat, block and transaction broadcast etc.
Table of node info
The table circle_node_info info:
Fields | Type | Description |
---|---|---|
public_ip | String | public ip |
local_ip | String | inner ip |
version | String | version |
role | String | Role:CLOUDER clouder node MINER miner node. Only two roles here. |
protol_version | String | Protocol version |
port | Integer | the server port |
public_key | String | the node public key, the one represents the node. |
base_height | Integer | The top height of the circle node blockchain |
visit_count | Integer | the node visited count, default 0 |
create_time | Long | create time in milliseconds |
update_time | Long | update time in milliseconds |
The table provides data service for broadcast heartbeat, block and transaction, sync circle node info and sync block etc.
Jobs of background
Heartbeat task
The node will synchronize the node info with its most 100 neighbor nodes in every 10 seconds.跳。
The mechanism of heartbeat broadcasting
Every query will search at most 100 least visit miners in circle_node_info table. After every heartbeat search, increase the visit count of these least visit miners. So the next query least visit miners will include other unvisited or less visit miners.
Here is the broadcast algorithm codes:
List<BaseNodeInfo> baseNodeInfoList = nodeInfoService.queryLeastVisitMiners(); // query least visit 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 the least visit miners.
}
The Mine Block Task
The miner's mine block task will check the mine block condition every 10 minutes after the task is finished. When the condition returns true, the mine block task will be started. The condition includes the following items:
- check the span time between the last mined block time is larger than MAX_WAIT_TIME(60s)
- check the received the transactions in transation pool is larger than MAX_BLOCK_TX_SIZE(2048)
If the condition fits any one the two items, the mine block will be started.
The design of miner
See more details on Blockchain libraray.
The mechanism of broadcasting block
The mechanism is the same as the heartbeat broadcasting.
Note: Only the miners will have broadcast block task, the clouder and other ones haven't.
SyncBlock Task
The syncBlock task will start in every 5 minutes after the last syncBlock task.
The syncBlock mechanism
The mechanism of syncBlock includes the following steps:
- Search max height node info in circle_node_info table and find it.
- In the loop, sync block data from the max height node by public ip and port, starting from its own base node height in 100 items.
- When the sync block is finished, break the loop from the sync block.
Configure Center
Configure of async thread pool
default thread pool configure:
core_pool_size: 5
max_pool_size: 10
queue_capacity: 100
Path Configure
The outer api path configure:
path configure
## 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 config
The blockchain init 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;
}
}
SyncBlock config
SyncBlock configuration includes check the node height with neighbours, configure the intervals of syncblocks etc.
In junit profile, the syncblock task is not started.
How to select neighbor nodes and syncblock algorithm
There is the java code sample here to describe how to select neighbor nodes and its algorithm: Here is the select neighbor nodes 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 heigth node has no public ip, nodeInfo:{}!", JSON.toJSONString(maxHeightNodeInfo));
return 0;
}
Here is the syncblock algorithm code:
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 configure
blockchain instance configuration
Configure of wallet storage
wallet instance configuration
Configure of Miner Task
Miner task configuration includes check node whether is miner node, start the miner task when the node is miner node etc.
Configure of wallet
The instance of wallet configuration
Configure of node info
node info configureation, includes role, mobile, and encrypted password etc.
Storage Layer
Service of blockchain storage
Blockchain storage service which supports big data storage.
Interfaces
Blockchain storage service includes the following apis:
- init and destroy
- void init(): init
- void close(): destroy
- block search
- String getFirstBlockHash()
- String getLastBlockHash()
- Block getBlock()
- String getPrevBlockHash(String blockHash)
- boolean blockExists(String blockHash)
- Long getHeight(String blockHash)
- Long getBlockHeightByTxId(byte[] txId)
- Block getBlockByTxId(byte[] txId)
- add block to blockchain
- boolean addBlock(Block block)
- UTXO functions
- Map
getChainstateBucket(): search local UTXO mapping - void cleanChainStateBucket(): clear local UTXO data
- void putUTXOs(String txIdHexStr, TXOutput[] utxos): save UTXO in local storage
- TXOutput[] getUserUTXOs(byte[] pubKeyHash): search UTXO by pubkeyHash
- TXOutput[] getUTXOs(String txIdHexStr): search transaction UTXOs by transaction id
- int deleteUTXOs(String txIdHexStr): delete UTXO by transaction id
- transation search
- Transaction findTransaction(byte[] txId)
- List
transactionFilterByTypeSet(List txIdList, Set typeSet): filter transaction id list by transaction type set.
Blockchain copy service
The blockchain copy service provides copy service.
Details
The copy block service doesn't check the valid block and its transactions, because it concerns that the data input is all valid in default.
Interfaces
- boolean copyBlock(Block block): copy block data in database without any check and validation
- boolean copyBlockTail(CircleBlockTails circleBlockTails): copy block tails data in database with any check and validation
Wallet storage service
Wallet storage service provides wallet data storage service, which supports big data storage in cloud and local wallet storage.
Interfaces
There are unified apis for local and cloud storage apis:
- init and destroy
- void init(): init resource
-
void close(): close resource
-
initWalletPackage
- void initWalletPackage(WalletPackage walletPackage): Wallet package init method
- void updateWalletPackage(WalletPackage walletPackage):update wallet package
- WalletPackageConfig
- WalletPackageConfig getWalletPackageConfigByAddress(String address):get wallet package config by address
- WalletPackageConfig getWalletPackageConfigByPhone(String phone):get wallet package config by phone
- WalletPackageConfig getWalletPackageConfigByUid(String uid):get wallet package config by uid
- boolean saveOrUpdatePhone(String phone, WalletPackageConfig config):save or update wallet package config 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 config by uid
- boolean updateWalletPackageConfig(WalletPackageConfig config):save or update wallet package by config
Cloud Wallet Service
Cloud wallet service provides cloud wallet services, which store your personal wallet data including private key in cloud server. You only use H5 page to use the cloud wallet services including query personal token and assets, make transactions etc. The cloud wallet server is the most high secure server in the world, you don't need to worry that your personal assets will be lost and stolen. Even your valuable data were lost, You would be compensated by our company(shc ltd.).
Local Wallet Service
Local Wallet Service provides local wallet services, which cannot store your private keys in the cloud. You must store and backup your private key and local wallet data. If your private key and local wallet data is lost or stolen, You will be responsible for yourself.