Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/contracts-e2e-tests-and-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,15 @@ jobs:
target-key: e2e-contracts
cargo-key: e2e-contracts
cache-version: v3
cargo-targets: e2e-tests-contracts/target/
cargo-targets: |
e2e-tests/target/
contracts/access_control/target/
contracts/button/target/
contracts/game_token/target/
contracts/marketplace/target/
contracts/simple_dex/target/
contracts/ticket_token/target/
contracts/wrapped_azero/target/

- name: Install cargo-contract
run: |
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion aleph-client/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion aleph-client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "aleph_client"
version = "1.9.0"
version = "1.10.0"
edition = "2021"
license = "Apache 2.0"

Expand Down
73 changes: 73 additions & 0 deletions aleph-client/src/contract/convertible_value.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use std::ops::Deref;

use anyhow::{bail, Result};
use contract_transcode::Value;
use sp_core::crypto::Ss58Codec;

use crate::AccountId;

/// Temporary wrapper for converting from [Value] to primitive types.
///
/// ```
/// # #![feature(assert_matches)]
/// # #![feature(type_ascription)]
/// # use std::assert_matches::assert_matches;
/// # use anyhow::{anyhow, Result};
/// # use aleph_client::{AccountId, contract::ConvertibleValue};
/// use contract_transcode::Value;
///
/// assert_matches!(ConvertibleValue(Value::UInt(42)).try_into(), Ok(42));
/// assert_matches!(ConvertibleValue(Value::Bool(true)).try_into(), Ok(true));
/// assert_matches!(
/// ConvertibleValue(Value::Literal("5H8cjBBzCJrAvDn9LHZpzzJi2UKvEGC9VeVYzWX5TrwRyVCA".to_string())).
/// try_into(): Result<AccountId>,
/// Ok(_)
/// );
/// assert_matches!(
/// ConvertibleValue(Value::String("not a number".to_string())).try_into(): Result<u128>,
/// Err(_)
/// );
/// ```
#[derive(Debug, Clone)]
pub struct ConvertibleValue(pub Value);

impl Deref for ConvertibleValue {
type Target = Value;

fn deref(&self) -> &Value {
&self.0
}
}

impl TryFrom<ConvertibleValue> for bool {
type Error = anyhow::Error;

fn try_from(value: ConvertibleValue) -> Result<bool, Self::Error> {
match value.0 {
Value::Bool(value) => Ok(value),
_ => bail!("Expected {:?} to be a boolean", value.0),
}
}
}

impl TryFrom<ConvertibleValue> for u128 {
type Error = anyhow::Error;

fn try_from(value: ConvertibleValue) -> Result<u128, Self::Error> {
match value.0 {
Value::UInt(value) => Ok(value),
_ => bail!("Expected {:?} to be an integer", value.0),
}
}
}

impl TryFrom<ConvertibleValue> for AccountId {
type Error = anyhow::Error;

fn try_from(value: ConvertibleValue) -> Result<AccountId, Self::Error> {
match value.0 {
Value::Literal(value) => Ok(AccountId::from_ss58check(&value)?),
_ => bail!("Expected {:?} to be a string", value),
}
}
}
44 changes: 25 additions & 19 deletions aleph-client/src/contract/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@
//!
//! ```no_run
//! # use anyhow::{Result, Context};
//! # use sp_core::crypto::AccountId32;
//! # use aleph_client::AccountId;
//! # use aleph_client::{Connection, SignedConnection};
//! # use aleph_client::contract::ContractInstance;
//! # use aleph_client::contract::util::to_u128;
//! #
//! #[derive(Debug)]
//! struct PSP22TokenInstance {
//! contract: ContractInstance,
//! }
//!
//! impl PSP22TokenInstance {
//! fn new(address: AccountId32, metadata_path: &Option<String>) -> Result<Self> {
//! fn new(address: AccountId, metadata_path: &Option<String>) -> Result<Self> {
//! let metadata_path = metadata_path
//! .as_ref()
//! .context("PSP22Token metadata not set.")?;
Expand All @@ -25,26 +24,26 @@
//! })
//! }
//!
//! fn transfer(&self, conn: &SignedConnection, to: AccountId32, amount: u128) -> Result<()> {
//! fn transfer(&self, conn: &SignedConnection, to: AccountId, amount: u128) -> Result<()> {
//! self.contract.contract_exec(
//! conn,
//! "PSP22::transfer",
//! vec![to.to_string().as_str(), amount.to_string().as_str(), "0x00"].as_slice(),
//! )
//! }
//!
//! fn balance_of(&self, conn: &Connection, account: AccountId32) -> Result<u128> {
//! to_u128(self.contract.contract_read(
//! fn balance_of(&self, conn: &Connection, account: AccountId) -> Result<u128> {
//! self.contract.contract_read(
//! conn,
//! "PSP22::balance_of",
//! &vec![account.to_string().as_str()],
//! )?)
//! )?.try_into()
//! }
//! }
//! ```

mod convertible_value;
pub mod event;
pub mod util;

use std::{
fmt::{Debug, Formatter},
Expand All @@ -54,36 +53,37 @@ use std::{
use ac_primitives::ExtrinsicParams;
use anyhow::{anyhow, Context, Result};
use contract_metadata::ContractMetadata;
use contract_transcode::{ContractMessageTranscoder, Value};
use contract_transcode::ContractMessageTranscoder;
pub use convertible_value::ConvertibleValue;
use ink_metadata::{InkProject, MetadataVersioned};
use serde_json::{from_reader, from_str, from_value, json};
use sp_core::{crypto::AccountId32, Pair};
use sp_core::Pair;
use substrate_api_client::{compose_extrinsic, GenericAddress, XtStatus};

use crate::{try_send_xt, AnyConnection, SignedConnection};
use crate::{try_send_xt, AccountId, AnyConnection, SignedConnection};

/// Represents a contract instantiated on the chain.
pub struct ContractInstance {
address: AccountId32,
address: AccountId,
ink_project: InkProject,
}

impl ContractInstance {
const MAX_READ_GAS: u64 = 500000000000u64;
const MAX_GAS: u64 = 10000000000u64;
const MAX_GAS: u64 = 100000000000u64;
const PAYABLE_VALUE: u64 = 0u64;
const STORAGE_FEE_LIMIT: Option<u128> = None;

/// Creates a new contract instance under `address` with metadata read from `metadata_path`.
pub fn new(address: AccountId32, metadata_path: &str) -> Result<Self> {
pub fn new(address: AccountId, metadata_path: &str) -> Result<Self> {
Ok(Self {
address,
ink_project: load_metadata(metadata_path)?,
})
}

/// The address of this contract instance.
pub fn address(&self) -> &AccountId32 {
pub fn address(&self) -> &AccountId {
&self.address
}

Expand All @@ -93,7 +93,11 @@ impl ContractInstance {
}

/// Reads the value of a read-only, 0-argument call via RPC.
pub fn contract_read0<C: AnyConnection>(&self, conn: &C, message: &str) -> Result<Value> {
pub fn contract_read0<C: AnyConnection>(
&self,
conn: &C,
message: &str,
) -> Result<ConvertibleValue> {
self.contract_read(conn, message, &[])
}

Expand All @@ -103,7 +107,7 @@ impl ContractInstance {
conn: &C,
message: &str,
args: &[&str],
) -> Result<Value> {
) -> Result<ConvertibleValue> {
let payload = self.encode(message, args)?;
let request = self.contract_read_request(&payload);
let response = conn
Expand Down Expand Up @@ -166,10 +170,12 @@ impl ContractInstance {
ContractMessageTranscoder::new(&self.ink_project).encode(message, args)
}

fn decode_response(&self, from: &str, contract_response: &str) -> Result<Value> {
fn decode_response(&self, from: &str, contract_response: &str) -> Result<ConvertibleValue> {
let contract_response = contract_response.trim_start_matches("0x");
let bytes = hex::decode(contract_response)?;
ContractMessageTranscoder::new(&self.ink_project).decode_return(from, &mut bytes.as_slice())
ContractMessageTranscoder::new(&self.ink_project)
.decode_return(from, &mut bytes.as_slice())
.map(ConvertibleValue)
}
}

Expand Down
48 changes: 0 additions & 48 deletions aleph-client/src/contract/util.rs

This file was deleted.

1 change: 1 addition & 0 deletions aleph-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use ac_primitives::{PlainTipExtrinsicParamsBuilder, SubstrateDefaultSignedExtra}
pub use account::{get_free_balance, locks};
pub use balances::total_issuance;
use codec::{Decode, Encode};
pub use contract_transcode;
pub use debug::print_storages;
pub use elections::{
get_committee_seats, get_current_era_non_reserved_validators,
Expand Down
2 changes: 1 addition & 1 deletion bin/cliain/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct ContractOptions {
#[clap(long, default_value = "0")]
pub balance: u128,
/// The gas limit enforced when executing the constructor
#[clap(long, default_value = "1_000_000_000")]
#[clap(long, default_value = "1000000000")]
pub gas_limit: u64,
/// The maximum amount of balance that can be charged/reserved from the caller to pay for the storage consumed
#[clap(long)]
Expand Down
2 changes: 1 addition & 1 deletion contracts/button/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod errors;
use ink_lang as ink;

#[ink::contract]
mod button_game {
pub mod button_game {
use access_control::{roles::Role, traits::AccessControlled, ACCESS_CONTROL_PUBKEY};
use game_token::MINT_SELECTOR;
use ink_env::{
Expand Down
5 changes: 4 additions & 1 deletion contracts/env/dev
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ export AUTHORITY_SEED=//Alice
export LIFETIME=20

# mint this many ticket tokens
export TICKET_BALANCE=100
export TICKET_BALANCE=100000000

# initial price of ticket on the marketplace
export INITIAL_PRICE=69

# use dev-only hacks, like allowing the authority to mint game tokens on demand
export ENV_NAME=dev
3 changes: 3 additions & 0 deletions contracts/env/fe-benjamin
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ export TICKET_BALANCE=100

# initial price of ticket on the marketplace
export INITIAL_PRICE=69

# serious environment with no hacks
ENV_NAME=prod
3 changes: 3 additions & 0 deletions contracts/scripts/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ function deploy_button_game {
cd "$CONTRACTS_PATH"/access_control

cargo contract call --url "$NODE" --contract "$ACCESS_CONTROL" --message grant_role --args "$AUTHORITY" 'Owner('"$contract_address"')' --suri "$AUTHORITY_SEED" --skip-confirm
if [ "$ENV_NAME" = "dev" ]; then
cargo contract call --url "$NODE" --contract "$ACCESS_CONTROL" --message grant_role --args "$AUTHORITY" 'Minter('"$game_token"')' --suri "$AUTHORITY_SEED" --skip-confirm
fi
cargo contract call --url "$NODE" --contract "$ACCESS_CONTROL" --message grant_role --args "$contract_address" 'Admin('"$marketplace"')' --suri "$AUTHORITY_SEED" --skip-confirm
cargo contract call --url "$NODE" --contract "$ACCESS_CONTROL" --message grant_role --args "$contract_address" 'Minter('"$game_token"')' --suri "$AUTHORITY_SEED" --skip-confirm

Expand Down
Loading