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

Frameworks

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.
email 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.
email 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.
email 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.
email 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.
email 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.
email 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.
email 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
email 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
wechat 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
email 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
wechat 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
email 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
email 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
email 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
email 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 get AddressTxInfo data, you will get the data minOutputKey.

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 data outputs which is TXOutputPO 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:

clouder classes

The mechanism of Transaction broadcasting

The process of transaction broadcasting to neighbor nodes:

  1. Search node info from circle_node_info order by id desc with id with Long.MAX_VALUE
  2. When the batch is not empty, send the valid transaction info to the batch of neighbor nodes.
  3. When the current batch is sent, search the next batch of nodes with the mininum id of the current batch of nodes.
  4. 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:

  1. Search node info from circle_node_info order by id desc with id with Long.MAX_VALUE
  2. When the batch is not empty, send the valid block info to the batch of neighbor nodes.
  3. When the current batch is sent, search the next batch of nodes with the mininum id of the current batch of nodes.
  4. 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:

miner class

Services of wallet node

Wallet service, inner service, provides functions for wallet apis. Here is the class diagram:

wallet class

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:

  1. The construction of Block including gensis block and normal block.
  2. Block search
  3. Block copy
  4. Block serialization and deserialization

The block functions includes:

  1. Init blockchain
  2. Gensis Block creation
  3. Add new Block
  4. Iteration of blockchain
  5. UTXO search
  6. Spent assets search
  7. Search transaction by transaction id in blockchain.
  8. Search block by block hash or transaction id in blockchain
  9. 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:

  1. Wallet assets query function.
  2. Token transaction
  3. 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:

  1. search all the master blocktails info by height desc limit 1
  2. 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:

  1. check the span time between the last mined block time is larger than MAX_WAIT_TIME(60s)
  2. 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:

  1. Search max height node info in circle_node_info table and find it.
  2. 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.
  3. 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.