Compile and deploy
Now we will create a test that compiles, signs and deploys the counter app on a locally running essential-server
.
Start by adding the imports you will need.
#![allow(unused)] fn main() { use essential_app_utils::{compile::compile_pint_project, local_server::setup_server}; use counter_app::App; use essential_types::{PredicateAddress, Word}; }
Add a tokio test because we are using async code.
#![allow(unused)] fn main() { #[tokio::test] async fn test_counter() { } }
Run a local essential-server
in the background.
Note that this requires that the
essential-server
binary be your$PATH
. See the installation section for more details.
#![allow(unused)] fn main() { #[tokio::test] async fn test_counter() { let (addr, _server) = setup_server().await.unwrap(); } }
Compile
Compile the pint project.
Note that this requires that the
pint
binary be your$PATH
. See the installation section for more details.
#![allow(unused)] fn main() { #[tokio::test] async fn test_counter() { // ... let counter = compile_pint_project( concat!(env!("CARGO_MANIFEST_DIR"), "/../contract").into(), ) .await .unwrap(); } }
Create the PredicateAddress
. This is the ContentAddress
of the overall contract and the ContentAddress
if the predicate.
#![allow(unused)] fn main() { #[tokio::test] async fn test_counter() { // ... let contract_address = essential_hash::contract_addr::from_contract(&counter); let predicate_address = essential_hash::content_addr(&counter.predicates[0]); let predicate_address = PredicateAddress { contract: contract_address, predicate: predicate_address, }; } }
Our contract only has a single predicate but other contracts can have multiple predicates and therefor multiple
PredicateAddress
s.
Sign and deploy
Using the essential-wallet
create a temporary wallet and a new key for alice
using the Secp256k1
scheme.
This is the key that you will use to sign the contract before deploying it.
#![allow(unused)] fn main() { #[tokio::test] async fn test_counter() { // ... let mut wallet = essential_wallet::Wallet::temp().unwrap(); wallet .new_key_pair("alice", essential_wallet::Scheme::Secp256k1) .unwrap(); } }
Note that the
essential-wallet
has not been audited and is only for testing purposes. In this test we create a temporary key that is deleted at the end of the test.
To interact with the hostedessential-server
you will want to create a key pair that's stored locally usingessential-wallet
.
Our wallet is just a convenience for testing.
Sign and deploy the contract using alice
's key.
#![allow(unused)] fn main() { #[tokio::test] async fn test_counter() { // ... essential_deploy_contract::sign_and_deploy(addr.clone(), "alice", &mut wallet, counter) .await .unwrap(); } }
Now we are done getting everything setup and deployed.
In the next section we will interact with the deployed contract.
Check your `tests/counter.rs` matches this.
#![allow(unused)] fn main() { use essential_app_utils::{compile::compile_pint_project, local_server::setup_server}; use counter_app::App; use essential_types::{PredicateAddress, Word}; #[tokio::test] async fn test_counter() { let (addr, _server) = setup_server().await.unwrap(); let counter = compile_pint_project( concat!(env!("CARGO_MANIFEST_DIR"), "/../contract").into(), ) .await .unwrap(); let contract_address = essential_hash::contract_addr::from_contract(&counter); let predicate_address = essential_hash::content_addr(&counter.predicates[0]); let predicate_address = PredicateAddress { contract: contract_address, predicate: predicate_address, }; let mut wallet = essential_wallet::Wallet::temp().unwrap(); wallet .new_key_pair("alice", essential_wallet::Scheme::Secp256k1) .unwrap(); essential_deploy_contract::sign_and_deploy(addr.clone(), "alice", &mut wallet, counter) .await .unwrap(); } }