Skip to content

Commit

Permalink
Merge pull request #151 from Concordium/init-contract-estimates
Browse files Browse the repository at this point in the history
Builders for deploying modules and initializing contracts.
  • Loading branch information
abizjak authored Feb 2, 2024
2 parents b18dc70 + 984616b commit 87e971f
Show file tree
Hide file tree
Showing 5 changed files with 685 additions and 156 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## Unreleased changes

## 4.1.0

- Add `ContractInitBuilder` for more ergonomic initialization of new smart
contract instances.

## 4.0.0

- Add a `From<&AccountInfo>` instance for `AccountAccessStructure` to ease verification of signatures using `GetAccountInfo` response.
Expand Down
101 changes: 49 additions & 52 deletions examples/init-update-contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,15 @@
use anyhow::Context;
use clap::AppSettings;
use concordium_rust_sdk::{
common::{types::TransactionTime, SerdeDeserialize, SerdeSerialize},
common::{SerdeDeserialize, SerdeSerialize},
contract_client::{ContractClient, ContractInitBuilder, ViewError},
endpoints,
smart_contracts::{
common as concordium_std,
common::{Amount, ContractAddress, OwnedContractName, OwnedReceiveName, Serial},
common::{Amount, ContractAddress, Serial},
},
types::{
smart_contracts::{ModuleReference, OwnedParameter},
transactions::{send, InitContractPayload, UpdateContractPayload},
AccountInfo, WalletAccount,
},
v2::{self, BlockIdentifier},
types::{smart_contracts::ModuleReference, WalletAccount},
v2,
};
use std::path::PathBuf;
use structopt::*;
Expand Down Expand Up @@ -81,6 +78,8 @@ impl std::str::FromStr for Weather {
}
}

enum WeatherContractMarker {}

#[tokio::main(flavor = "multi_thread")]
async fn main() -> anyhow::Result<()> {
let app = {
Expand All @@ -89,62 +88,60 @@ async fn main() -> anyhow::Result<()> {
App::from_clap(&matches)
};

let mut client = v2::Client::new(app.endpoint).await?;
let client = v2::Client::new(app.endpoint).await?;

// load account keys and sender address from a file
let keys: WalletAccount =
let account: WalletAccount =
WalletAccount::from_json_file(app.keys_path).context("Could not parse the keys file.")?;

// Get the initial nonce at the last finalized block.
let acc_info: AccountInfo = client
.get_account_info(&keys.address.into(), BlockIdentifier::LastFinal)
.await?
.response;

let nonce = acc_info.account_nonce;
// set expiry to now + 5min
let expiry: TransactionTime =
TransactionTime::from_seconds((chrono::Utc::now().timestamp() + 300) as u64);

let tx = match app.action {
match app.action {
Action::Init {
weather,
module_ref: mod_ref,
} => {
let param = OwnedParameter::from_serial(&weather)
.expect("Known to not exceed parameter size limit.");
let payload = InitContractPayload {
amount: Amount::zero(),
let builder = ContractInitBuilder::<WeatherContractMarker>::dry_run_new_instance(
client,
account.address,
mod_ref,
init_name: OwnedContractName::new_unchecked("init_weather".to_string()),
param,
};

send::init_contract(&keys, keys.address, nonce, expiry, payload, 10000u64.into())
"weather",
Amount::zero(),
&weather,
)
.await?;
println!(
"The maximum amount of NRG allowed for the transaction is {}.",
builder.current_energy()
);
let handle = builder.send(&account).await?;
println!("Transaction {handle} submitted. Waiting for finalization.");
let (contract_client, events) = handle.wait_for_finalization().await?;
println!(
"Initialized a new smart contract instance at address {}.",
contract_client.address
);
println!("The following events were generated.");
for event in events {
println!("{event}");
}
}
Action::Update { weather, address } => {
let message = OwnedParameter::from_serial(&weather)
.expect("Known to not exceed parameter size limit.");
let payload = UpdateContractPayload {
amount: Amount::zero(),
address,
receive_name: OwnedReceiveName::new_unchecked("weather.set".to_string()),
message,
};

send::update_contract(&keys, keys.address, nonce, expiry, payload, 10000u64.into())
let mut contract_client =
ContractClient::<WeatherContractMarker>::create(client, address).await?;
let builder = contract_client
.dry_run_update::<_, ViewError>("set", Amount::zero(), account.address, &weather)
.await?;
println!(
"The maximum amount of execution NRG allowed for the transaction is {}.",
builder.current_energy()
);
let handle = builder.send(&account).await?;
println!("Transaction {handle} submitted. Waiting for finalization.");
let result = handle.wait_for_finalization().await?;
println!(
"Update smart contract instance. It cost {}CCD.",
result.cost
);
}
};

// submit the transaction to the chain
let transaction_hash = client.send_account_transaction(tx).await?;
println!(
"Transaction {} submitted (nonce = {}).",
transaction_hash, nonce,
);
let (bh, bs) = client.wait_until_finalized(&transaction_hash).await?;
println!("Transaction finalized in block {}.", bh);
println!("The outcome is {:#?}", bs);

Ok(())
}
16 changes: 11 additions & 5 deletions examples/v2_contract_deploy_init_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
use anyhow::Context;
use clap::AppSettings;
use concordium_rust_sdk::{
common::{self, types::TransactionTime, SerdeDeserialize, SerdeSerialize},
common::{types::TransactionTime, SerdeDeserialize, SerdeSerialize},
contract_client::ModuleDeployBuilder,
smart_contracts::{
common as concordium_std,
common::Amount,
Expand Down Expand Up @@ -180,10 +181,15 @@ async fn main() -> anyhow::Result<()> {
send::update_contract(&keys, keys.address, nonce, expiry, payload, 10000u64.into())
}
Action::Deploy { module_path } => {
let contents = std::fs::read(module_path).context("Could not read contract module.")?;
let payload: WasmModule =
common::Deserial::deserial(&mut std::io::Cursor::new(contents))?;
send::deploy_module(&keys, keys.address, nonce, expiry, payload)
let module =
WasmModule::from_file(&module_path).context("Could not read contract module.")?;
let builder =
ModuleDeployBuilder::dry_run_module_deploy(client, keys.address, module).await?;
let handle = builder.send(&keys).await?;
println!("Module deployment transaction {handle} submitted.");
let result = handle.wait_for_finalization().await?;
println!("Module {} deployed.", result.module_reference);
return Ok(());
}
};

Expand Down
Loading

0 comments on commit 87e971f

Please sign in to comment.