In this tutorial, we’re going to set up a development environment. We are going to deploy a full stack of the core blockchain and connect the Web UI to the blockchain. By the end of the tutorial, you will be able to:
Send confidential Commands and Queries
Get a ready-to-hack version of Phala Network for building your confidential DApps
A full Phala Network stack has three components, with an optional Javascript SDK. The core components are available at Phala-Network/phala-blockchain:
phala-node: The Substrate blockchain node
pRuntime: The TEE runtime. Contracts run in pRuntime
pherry: The Substrate-TEE bridge relayer. Connects the blockchain and pRuntime
The Javascript SDK is at Phala-Network/js-sdk. The Web UI based on our SDK needs to connect to both the blockchain and the pRuntime to send Commands and Queries.
Setting up
In this tutorial, we assume the operating system is Ubuntu 22.04. Other Linux distributions should also work, but the instructions or commands may vary. 4 cores and 8GB RAM is the minimal requirement to build the project including the core blockchain.
The Apple M-Series chips do not support the deployment of a local testnet at this time. If you are using a machine with these chips, you will have to deploy to the Phala PoC6 Testnet.
In this section, you will deploy your local testnet using the DevPHAse CLI Tool. First, you will need to create a new workspace folder on your system and execute the following:
When using npm, you will see conflicting/duplicated packages. yarn will not have these errors. Until this problem is solved, it is best to use yarn.
Currently, npm and npx commands do not work and will report an error invalid format for V0 (detected) contract metadata. Opt to use yarn until the problem is resolved.
Your directory will be initiated with all required files and template Flipper contract.
- .devphase/ # devPHAse cache directory
- contracts/ # here you store your contracts
- flipper/ # template Flipper contract
- Cargo.toml # rust project file
- lib.rs # contract source
- scripts/ # scripts which you can all with devPHAse environment
- deploy.ts # sample deployment script
- get-logs.ts # sample demonstrating how to get contract logs
- tests/ # here you store e2e tests for contracts
- flipper/ # flipper related test suite
- flipper.test.ts # flipper tests example
3) Prepare environment
yarndevphasecheck
npxdevphasecheck
This command will ensure the proper stack (node, pruntime, pherry) is ready to run. Download stack from official repository. Verify dependencies.
You will see a new directory called stacks/ has been created
- stacks/ # here all prepared stacks will be stored
- nightly-2024-03-07/ # bases on your configuration it will latest available stack or any specific you choose
- phala-node # node binary
- pherry # pherry binary
- pruntime # pruntime binary
- *.so.* # multiple requried libs
- *.contract # system contracts
compile contract (only flipper in this case) and save output to ./contracts/flipper/target
copy contract artificats
generate typescript bindings which you can use in scripts and tests
New files:
- artifacts/ # here devPHAse will store compiled contract artifacts
- flipper/ # specific contract
- flipper.contract
- flipper.json
- flipper.wasm
- typings/ # here devPHAse will store ts bindings
- Flipper.ts
5) Run tests
Currently, npm and npx commands do not work and will report an error invalid format for V0 (detected) contract metadata. Opt to use yarn until the problem is resolved.
yarndevphasecontracttest-tflipper
yarndevphasecontracttest-tflipper-m3
npxdevphasecontracttest-tflipper
yarn devphase contract test -t flipper -m 3
devPHAse in default config will:
check stack dependencies
start local stack
configure local environment (with minimal required deps)
execute tests
save logs into files
Output:
yarndevphasecontracttest-tflipper[StackBinaryDownloader] Preparing Phala stack release nightly-2024-03-13✔Checkingreleasesdirectory✔Checkingtargetreleasebinaries[Test] Global setup start[Test] Preparing dev stack[StackManager] Starting stack nightly-2024-03-13✔Startnodecomponent✔StartpRuntimecomponent✔Startpherrycomponent[Test] Init API[Test] Setup environment[StackSetupService] Starting stack setup with default version✔Fetchworkerinfo✔Loadsystemcontracts↓Registerworker [skipped]✔Registergatekeeper✔UploadPinksystemcode✔Verifycluster✔Createcluster✔Waitforclustertobeready✔Addworkerendpoint✔CreatesystemcontractAPI[Test] Global setup done[Test] Starting testsFlipperdefaultconstructor✔Shouldbecreatedwithproperintialvalue✔Shouldbeabletoflipvalue (2572ms)newconstructor✔Shouldbecreatedwithproperintialvalue[Test] Global teardown start[Test] Internal clean up[Test] Stopping stack[Test] Global teardown done3passing (27s)[StackManager] pherry exited[StackManager] pruntime exited[StackManager] node exitedDonein33.00s.
yarndevphasecontracttest-tflipper-m3[StackBinaryDownloader] Preparing Phala stack release nightly-2024-03-13✔Checkingreleasesdirectory✔Checkingtargetreleasebinaries[Test] Global setup start[Test] Preparing dev stack[StackManager] Starting stack nightly-2024-03-13✔Startnodecomponent✔StartpRuntimecomponent✔Startpherrycomponent[Test] Init API[Test] Setup environment[StackSetupService] Starting stack setup with default version✔Fetchworkerinfo✔Loadsystemcontracts↓Registerworker [skipped]✔Registergatekeeper✔UploadPinksystemcode✔Verifycluster✔Createcluster✔Waitforclustertobeready✔Addworkerendpoint✔CreatesystemcontractAPI✔Deploytokenomicdriver✔DeploySideVMdriver✔CalculateloggerservercontractID✔Preparechainforloggerserver✔Deployloggerserver[Test] Global setup done[Test] Starting testsFlipperdefaultconstructor✔ShouldbecreatedwithproperintialvalueLogsfrompinkserver:#366 TX info Resource uploaded to cluster, by 8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48 (5FHneW46...), type=InkCode, hash=0xcbf8151426f6ce308a875a1c5cc6e2a4f4c0bca3be4371a15b0d25bcca336f55#376 EST info instantiated#392 TX info instantiated✔Shouldbeabletoflipvalue (2636ms)Logsfrompinkserver:#402 EST info instantiated#422 TX info instantiatednewconstructor✔ShouldbecreatedwithproperintialvalueLogsfrompinkserver:#456 EST info instantiated#473 TX info instantiated[Test] Global teardown start[Test] Internal clean up[Test] Stopping stack[Test] Global teardown done3passing (54s)[StackManager] pherry exited[StackManager] pruntime exited[StackManager] node exitedDonein59.67s.
New directories created for logs.
- logs/ # here devPHAse will store execution logs
- 2024-03-07T16:09:43.421Z/ # single execution
- node.log
- pherry.log
- pruntime.log
- pink_logger.log # if stack setup with logger here all logs will be stored
Running tests this way is nice but only if it is single execution. If you are developing new feature it may be required to continuously test it. In this case default procedure is time-consuming, because setting up stack takes ~40s.
Nothing blocks you from using the same running node for multiple tests.
6) Long-running local environment
This command will start and keep running all stack components. However, network is not configured yet to accept contracts.
Currently, npm and npx commands do not work and will report an error invalid format for V0 (detected) contract metadata. Opt to use yarn until the problem is resolved.
yarndevphasestackrun--save-logs
npxdevphasestackrun--save-logs
7) Configure network
Now let's configure the network to enable your local environment to deploy a Phat Contract and collect logs.
Currently, npm and npx commands do not work and will report an error invalid format for V0 (detected) contract metadata. Opt to use yarn until the problem is resolved.
yarndevphasestacksetup-m3
npxdevphasestacksetup-m3
Output:
yarndevphasestacksetup-m3[StackSetupService] Starting stack setup with default version✔Fetchworkerinfo✔Loadsystemcontracts↓Registerworker [skipped]✔Registergatekeeper✔UploadPinksystemcode✔Verifycluster✔Createcluster✔Waitforclustertobeready✔Addworkerendpoint✔CreatesystemcontractAPI✔Deploytokenomicdriver✔DeploySideVMdriver✔CalculateloggerservercontractID✔Preparechainforloggerserver✔Deployloggerserver[StackSetup] Stack is ready[StackSetup] Cluster Id[StackSetup] 0x0000000000000000000000000000000000000000000000000000000000000001Donein38.52s.
Now all required network components should be ready for Phat Contract deployment.
8) Run tests using long-running local environment
-e flag will make devPHAse to execute test without setting up temporary stack but using existing one.
Currently, npm and npx commands do not work and will report an error invalid format for V0 (detected) contract metadata. Opt to use yarn until the problem is resolved.
yarndevphasecontracttest-tflipper-e
npxdevphasecontracttest-tflipper-e
Output:
yarndevphasecontracttest-tflipper-e[Test] Global setup start[Test] Init API[Test] Setup environment[StackSetupService] Starting stack setup with default version✔Fetchworkerinfo✔Loadsystemcontracts↓Registerworker [skipped]↓Registergatekeeper [skipped]↓UploadPinksystemcode [skipped]✔Verifycluster↓Createcluster [skipped]✔Waitforclustertobeready↓Addworkerendpoint [skipped]✔CreatesystemcontractAPI[Test] Global setup done[Test] Starting testsFlipperdefaultconstructor✔ShouldbecreatedwithproperintialvalueLogsfrompinkserver:#996 TX info Resource uploaded to cluster, by 8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48 (5FHneW46...), type=InkCode, hash=0xcbf8151426f6ce308a875a1c5cc6e2a4f4c0bca3be4371a15b0d25bcca336f55#999 EST info instantiated#1007 TX info instantiated✔Shouldbeabletoflipvalue (2390ms)Logsfrompinkserver:#1009 EST info instantiated#1021 TX info instantiatednewconstructor✔ShouldbecreatedwithproperintialvalueLogsfrompinkserver:#1036 EST info instantiated#1044 TX info instantiated[Test] Global teardown start[Test] Internal clean up[Test] Global teardown done3passing (18s)Donein24.33s.
9) Running Scripts
DevPHAse will run script on specified environment. If environment provides a PinkLogger - logs will be saved locally.
Using the contract ID from the previous script 0x8e132d6bdebe37824b31df98669063d52d25d7eb0c40358c7f0e47876bc8a879 modify contractIds variable in scripts/get-logs.ts then execute the script to get logs.
The Phala-Network/phala-blockchain repository always contains the latest build instructions, at the time of writing (December 26, 2022), we use the following commands to set up development environment:
# First clone the repository
git clone https://github.com/Phala-Network/phala-blockchain.git
# Change to the repository directory
cd phala-blockchain
# Install system dependencies:
sudo apt install -y build-essential pkg-config libssl-dev protobuf-compiler
# Install Rust
curl https://sh.rustup.rs -sSf | sh
# Install dependencies for Substrate development
git submodule update --init
sh ./scripts/init.sh
# Installl LLVM 14
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
./llvm.sh 14
Then run the following command to build the Phala blockchain:
cargo build --release
It takes approximately 20 minutes to complete the building process on a laptop equipped with an AMD Ryzen 7 4700U processor with 8 cores, 8 threads, and 32GB of RAM.
Start the local testnet
We have a dedicate set of scripts to get the blockchain to run, checkout out this page for full details. For simplicity we can start as simple as follows:
We might want to clean up runtime data to have to clean starting environment, from the root of the phala-blockchain project, run this to clean things up:
./scripts/run/clear-pruntime.sh
Then go ahead and run these 3 commands in 3 separate terminals:
As the above figure shows, we first click the green dot at the upper-right cornor to set the RPC Endpoint to ws://localhost:19944, or ws://localhost:9944 if you start the chain via the devPHAse approach, and change the PRuntime field accordingly.
Don’t forget to claim some Test-PHAs, they’re required to deploy Phat Contracts and send transactions.