Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into paymaster
Browse files Browse the repository at this point in the history
  • Loading branch information
CostinCarabas committed Oct 3, 2023
2 parents 0c3d5a8 + d23e2a8 commit 64c591f
Show file tree
Hide file tree
Showing 286 changed files with 7,594 additions and 3,556 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ members = [

"contracts/adder",
"contracts/adder/meta",
"contracts/adder/interact",
"contracts/esdt-transfer-with-fee",
"contracts/esdt-transfer-with-fee/meta",
"contracts/bonding-curve-contract",
Expand Down Expand Up @@ -41,6 +42,7 @@ members = [
"contracts/liquid-locking/meta",
"contracts/multisig",
"contracts/multisig/meta",
"contracts/multisig/interact",
"contracts/mystery-box",
"contracts/mystery-box/meta",
"contracts/nft-minter",
Expand Down
2 changes: 1 addition & 1 deletion contracts/adder/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/target/

# The mxpy output
output
/output*/

# Mandos test trace
trace*.scen.json
3 changes: 3 additions & 0 deletions contracts/adder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Adder

`Adder` is a simple Smart Contract.
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# Pem files are used for interactions, but shouldn't be committed
*.pem

# Be very careful not to commit your own .pem files.
# Alice and Bob are public, do NEVER use them on the mainnet.
!alice.pem
!bob.pem

# Temporary storage of deployed contract address, so we can preserve the context between executions.
multisig_address.txt
state.toml

# Trace file of interactor tooling
interactor_trace.scen.json
27 changes: 27 additions & 0 deletions contracts/adder/interact/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[[bin]]
name = "adder-interact"
path = "src/adder_interact.rs"

[package]
name = "adder-interact"
version = "0.0.0"
authors = ["Ovidiu Stinga <[email protected]>"]
edition = "2021"
publish = false

[dependencies]
toml = "0.7.2"

[dependencies.clap]
version = "4.1.0"
features = ["derive", "cargo"]

[dependencies.serde]
version = "1.0"
features = ["derive"]

[dependencies.adder]
path = ".."

[dependencies.multiversx-sc-snippets]
version = "0.43.3"
1 change: 1 addition & 0 deletions contracts/adder/interact/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gateway = 'https://testnet-gateway.multiversx.com'
199 changes: 199 additions & 0 deletions contracts/adder/interact/src/adder_interact.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
mod adder_interact_cli;
mod adder_interact_config;
mod adder_interact_state;

use adder::ProxyTrait;
use adder_interact_config::Config;
use adder_interact_state::State;
use clap::Parser;
use multiversx_sc_snippets::{
env_logger,
multiversx_sc::{storage::mappers::SingleValue, types::Address},
multiversx_sc_scenario::{
api::StaticApi,
bech32,
mandos_system::ScenarioRunner,
num_bigint::BigUint,
scenario_format::interpret_trait::{InterpretableFrom, InterpreterContext},
scenario_model::{
BytesValue, ScCallStep, ScDeployStep, ScQueryStep, Scenario, TransferStep, TxExpect,
},
standalone::retrieve_account_as_scenario_set_state,
test_wallets, ContractInfo,
},
tokio, Interactor, StepBuffer,
};

const INTERACTOR_SCENARIO_TRACE_PATH: &str = "interactor_trace.scen.json";

#[tokio::main]
async fn main() {
env_logger::init();

let mut adder_interact = AdderInteract::init().await;

let cli = adder_interact_cli::InteractCli::parse();
match &cli.command {
Some(adder_interact_cli::InteractCliCommand::Add(args)) => {
adder_interact.add(args.value).await;
},
Some(adder_interact_cli::InteractCliCommand::Deploy) => {
adder_interact.deploy().await;
},
Some(adder_interact_cli::InteractCliCommand::Feed) => {
adder_interact.feed_contract_egld().await;
},
Some(adder_interact_cli::InteractCliCommand::MultiDeploy(args)) => {
adder_interact.multi_deploy(&args.count).await;
},
Some(adder_interact_cli::InteractCliCommand::Sum) => {
adder_interact.print_sum().await;
},
None => {},
}
}

#[allow(unused)]
struct AdderInteract {
interactor: Interactor,
wallet_address: Address,
adder_code: BytesValue,
state: State,
}

impl AdderInteract {
async fn init() -> Self {
let config = Config::load_config();
let mut interactor = Interactor::new(config.gateway())
.await
.with_tracer(INTERACTOR_SCENARIO_TRACE_PATH)
.await;
let wallet_address = interactor.register_wallet(test_wallets::mike());
let adder_code =
BytesValue::interpret_from("file:../output/adder.wasm", &InterpreterContext::default());

Self {
interactor,
wallet_address,
adder_code,
state: State::load_state(),
}
}

async fn set_state(&mut self) {
println!("wallet address: {}", bech32::encode(&self.wallet_address));
let scenario_raw = retrieve_account_as_scenario_set_state(
Config::load_config().gateway().to_string(),
bech32::encode(&self.wallet_address),
true,
)
.await;

let scenario = Scenario::interpret_from(scenario_raw, &InterpreterContext::default());

self.interactor.pre_runners.run_scenario(&scenario);
self.interactor.post_runners.run_scenario(&scenario);
}

async fn deploy(&mut self) {
self.set_state().await;

self.interactor
.sc_deploy_use_result(
ScDeployStep::new()
.call(self.state.default_adder().init(BigUint::from(0u64)))
.from(&self.wallet_address)
.code(&self.adder_code),
|new_address, tr| {
tr.result.unwrap_or_else(|err| {
panic!(
"deploy failed: status: {}, message: {}",
err.status, err.message
)
});

let new_address_bech32 = bech32::encode(&new_address);
println!("new address: {new_address_bech32}");

let new_address_expr = format!("bech32:{new_address_bech32}");
self.state.set_adder_address(&new_address_expr);
},
)
.await;
}

async fn multi_deploy(&mut self, count: &u8) {
if *count == 0 {
println!("count must be greater than 0");
return;
}

self.set_state().await;
println!("deploying {count} contracts...");

let mut steps = Vec::new();
for _ in 0..*count {
let typed_sc_deploy = ScDeployStep::new()
.call(self.state.default_adder().init(0u32))
.from(&self.wallet_address)
.code(&self.adder_code)
.gas_limit("70,000,000");

steps.push(typed_sc_deploy);
}

self.interactor
.multi_sc_exec(StepBuffer::from_sc_deploy_vec(&mut steps))
.await;

for step in steps.iter() {
// warning: multi deploy not yet fully supported
// only works with last deployed address
// will be addressed in future versions
let new_deployed_address = step.response().new_deployed_address.clone();
if let Some(new_address) = new_deployed_address {
let new_address_bech32 = bech32::encode(&new_address);
println!("new address: {new_address_bech32}");
} else {
println!("deploy failed");
return;
}
}
}

async fn feed_contract_egld(&mut self) {
let _ = self
.interactor
.transfer(
TransferStep::new()
.from(&self.wallet_address)
.to(self.state.adder())
.egld_value("0,050000000000000000"),
)
.await;
}

async fn add(&mut self, value: u64) {
self.interactor
.sc_call(
ScCallStep::new()
.call(self.state.adder().add(value))
.from(&self.wallet_address)
.expect(
TxExpect::ok().additional_error_message("performing add failed with: "),
),
)
.await;

println!("successfully performed add");
}

async fn print_sum(&mut self) {
self.interactor
.sc_query_use_result(ScQueryStep::new().call(self.state.adder().sum()), |tr| {
let sum: SingleValue<BigUint> = tr.result.unwrap();
println!("sum: {}", sum.into());
})
.await;
}
}
39 changes: 39 additions & 0 deletions contracts/adder/interact/src/adder_interact_cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use clap::{Args, Parser, Subcommand};

/// Adder Interact CLI
#[derive(Default, PartialEq, Eq, Debug, Parser)]
#[command(version, about)]
#[command(propagate_version = true)]
pub struct InteractCli {
#[command(subcommand)]
pub command: Option<InteractCliCommand>,
}

/// Adder Interact CLI Commands
#[derive(Clone, PartialEq, Eq, Debug, Subcommand)]
pub enum InteractCliCommand {
#[command(name = "add", about = "Add value")]
Add(AddArgs),
#[command(name = "deploy", about = "Deploy contract")]
Deploy,
#[command(name = "feed", about = "Feed contract EGLD")]
Feed,
#[command(name = "multi-deploy", about = "Multiple deploy contracts")]
MultiDeploy(MultiDeployArgs),
#[command(name = "sum", about = "Print sum")]
Sum,
}

#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
pub struct AddArgs {
/// The value to add
#[arg(short = 'v', long = "value", verbatim_doc_comment)]
pub value: u64,
}

#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
pub struct MultiDeployArgs {
/// The number of contracts to deploy
#[arg(short = 'c', long = "count", verbatim_doc_comment)]
pub count: u8,
}
26 changes: 26 additions & 0 deletions contracts/adder/interact/src/adder_interact_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use serde::Deserialize;
use std::io::Read;

/// Config file
const CONFIG_FILE: &str = "config.toml";

/// Adder Interact configuration
#[derive(Debug, Deserialize)]
pub struct Config {
gateway: String,
}

impl Config {
// Deserializes config from file
pub fn load_config() -> Self {
let mut file = std::fs::File::open(CONFIG_FILE).unwrap();
let mut content = String::new();
file.read_to_string(&mut content).unwrap();
toml::from_str(&content).unwrap()
}

// Returns the gateway
pub fn gateway(&self) -> &str {
&self.gateway
}
}
Loading

0 comments on commit 64c591f

Please sign in to comment.