General information: https://coldstack.atlassian.net/wiki/spaces/CS/pages/66977793/Blockchain
To setup rust, see instructions below.
To build:
cargo build --release
docker build -t privatechain .
docker tag privatechain coldstack/privatechain:latest
docker push coldstack/privatechain
Docker image built and pushed in a github worflow. See .github/workflows/publish-docker.yml
Tag name should correspond to spec_version
(see runtime
upgrades for details).
Run in dev mode
docker run coldstack/privatechain --dev --ws-external
Run with volume:
# Set permissions
chown 1000.1000 /your/host/directory -R
# Run
docker run -v /your/host/directory:/data coldstack/privatechain --dev --ws-external
Expose web service port:
docker run -p 9944:9944 coldstack/privatechain --dev --ws-external
First build and then
./test/test.sh
Node.js client for blockchain is https://polkadot.js.org/docs/api/
You start by initializing api
object (see docs). Then you can access storage
items and send transactions
Ethereum address. In blockchain runtime it is represented as Vec<u8>
. It is
returned from api as Uint8Array
. You can pass it to api as Uint8Array
,
Buffer
or hex-encoded string. Note that hex-encoded string must start with
leading '0x'
. Length is 20 bytes.
32-bytes long hash. In blockchain runtime it is represented as Vec<u8>
. It is
returned from api as Uint8Array
. You can pass it to api as Uint8Array
,
Buffer
or hex-encoded string. Note that hex-encoded string must start with
leading '0x'
.
Built-in substrate type
https://polkadot.js.org/docs/api/start/types.basics#working-with-optiontype
https://polkadot.js.org/docs/api/start/types.basics#working-with-numbers
Most of data in blockchain is stored in storage maps. Storage map support the following operations:
- get value by key
- get all entries
See docs https://polkadot.js.org/docs/api/start/api.query
All storage functions are async and return value wrapped to promise
Admin account key. Constant value that is set in genesis.
Constant value equal to total issuance of ColdStack token in Ethereum.
Locked funds
Balance of address
URL of node for given address
Substrate account of file node by eth address
eth address of file node by substrate account
Substrate account of billing node by eth address
eth address of billing node by substrate account
Get seed of gateway node by gateway node address
api.tx.coldStack.upload(
user_eth_address: ETHAddress,
file_name_hash: Hash,
file_size_bytes: number,
file_contents_hash: Hash,
gateway_eth_address: Hash,
)
api.tx.coldStack.download(
user_eth_address: ETHAddress,
file_name_hash: Hash,
file_size_bytes: number,
file_contents_hash: Hash,
gateway_eth_address: Hash,
)
api.tx.coldStack.delete(
user_eth_address: ETHAddress,
file_name_hash: Hash,
)
api.tx.coldStack.deposit(
account: ETHAddress,
value: number,
)
api.tx.coldStack.withdraw(
account: ETHAddress,
value: number,
)
api.tx.coldStack.transfer(
from: ETHAddress,
to: ETHAddress,
value: number,
)
api.tx.coldStack.grantFilePermission(
eth_address: ETHAddress,
account_id: AccountId,
node_url: string,
)
api.tx.coldStack.grantBillingPermission(
eth_address: ETHAddress,
account_id: AccountId,
node_url: string,
)
api.tx.coldStack.revokeFilePermission(
eth_address: ETHAddress,
)
api.tx.coldStack.revokeBillingPermission(
eth_address: ETHAddress,
)
api.tx.coldStack.registerGatewayNode(
node_eth_address: ETHAddress,
seed_eth_address: Option<ETHAddress>,
node_url: string,
)
const {u8aToString} = require('@polkadot/util/u8a/toString')
const api = await ApiPromise.create({
provider: wsProvider,
types: {
Gateway: {
address: 'Vec<u8>',
seedAddress: 'Option<Vec<u8>>',
storage: 'u8',
},
},
})
async function gatewayNodes(){
const nodeEntries = await api.query.coldStack.gateways.entries()
return Promise.all(nodeEntries.map(async ([_, gateway]) => {
const nodeAddress = gateway.address.toString('hex')
return {
nodeAddress,
seedAddress: gateway.seedAddress.isNone ? null : gateway.seedAddress.toString('hex'),
storage: gateway.storage.toNumber(),
url: u8aToString(await api.query.coldStack.nodeURLs(nodeAddress)),
}
}))
}
Returns:
[
{
nodeAddress: '0x6666666666666666666666666666666666666666',
seedAddress: '0x2222222222222222222222222222222222222222',
storage: 1,
url: 'http://gateway_sec.test'
},
{
nodeAddress: '0x2222222222222222222222222222222222222222',
seedAddress: null,
storage: 2,
url: 'http://gateway_seed.test'
}
]
where
nodeAddress
: ETH address of gateway nodeseedAddress
: ETH address of seed node for this gateway node.null
if node is a seed node itself.url
: URL of node
Blockchain runtime (including ColdStack-specific code) could be upgraded by API
call, without redeploying blockchain nodes. See
https://substrate.dev/docs/en/tutorials/forkless-upgrade to learn mode about
runtime upgrades. Note that you must bump spec_version
in
./runtime/src/lib.rs to trigger runtime upgrade.
To see some examples of runtime upgrades please checkout branch
runtime_upgrade_examples
(see
README
for details)
Blockchain is build with
substrate-validator-set
pallet. It allows adding validators dynamically. See add-validator-test
branch to see examples.
Repository is forked from Substrate Node Template.