Alex payup (#1)

* payup method work-in progress

buisness is the owner of the contract--> requests the amount on the bill--> the customer interacts with the same contract to pay the bill

* added payup funtion and other stuff related to that in other files

* pay_up works

* attempting bill splitting

* trying to deploy

* map and payer count works

* added demo video

* final product. Transfering funds not perfected

Co-authored-by: alex324998301 <102430172+alex324998301@users.noreply.github.com>
Co-authored-by: alex324998301 <abdullah.syed@ryerson.ca>
Co-authored-by: BiPhan4 <bi.phan@ryerson.ca>
This commit is contained in:
Array in a Matrix 2022-03-27 09:34:43 -04:00 committed by GitHub
parent ce7f2fc6be
commit c2e75206df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 135 additions and 132 deletions

View file

@ -1,3 +1,2 @@
# DefiHackathon-2022 # DefiHackathon-2022
Demo video: https://youtu.be/kMNxAIWr4T8
Hello

View file

@ -17,7 +17,7 @@
} }
}, },
"instantiateMsg": { "instantiateMsg": {
"count": 0 "bill": 20000000
} }
} }
} }

View file

@ -103,6 +103,7 @@ dependencies = [
"cosmwasm-storage", "cosmwasm-storage",
"cw-storage-plus", "cw-storage-plus",
"cw2", "cw2",
"cw20",
"schemars", "schemars",
"serde", "serde",
"thiserror", "thiserror",
@ -163,10 +164,24 @@ name = "cw-storage-plus"
version = "0.8.1" version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1e867b9972b83b32e00e878dfbff48299ba26618dabeb19b9c56fae176dc225" checksum = "c1e867b9972b83b32e00e878dfbff48299ba26618dabeb19b9c56fae176dc225"
dependencies = [
"cosmwasm-std",
"cw-storage-plus",
"schemars",
"serde",
]
[[package]]
name = "cw0"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d759bb5418a3bdf091e1f1be17de2a15d95d2be4fee28045c2e461f4c6d9d1ca"
dependencies = [ dependencies = [
"cosmwasm-std", "cosmwasm-std",
"schemars", "schemars",
"serde", "serde",
"thiserror",
] ]
[[package]] [[package]]
@ -181,6 +196,18 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "cw20"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac49b013ca1e355fd988cc1926acc9a16d7fd45cfb595ee330455582a788b100"
dependencies = [
"cosmwasm-std",
"cw0",
"schemars",
"serde",
]
[[package]] [[package]]
name = "der" name = "der"
version = "0.4.1" version = "0.4.1"

View file

@ -44,6 +44,7 @@ cosmwasm-std = { version = "0.16.2" }
cosmwasm-storage = { version = "0.16.0" } cosmwasm-storage = { version = "0.16.0" }
cw-storage-plus = "0.8.0" cw-storage-plus = "0.8.0"
cw2 = "0.8.1" cw2 = "0.8.1"
cw20 = "0.9.0"
schemars = "0.8.3" schemars = "0.8.3"
serde = { version = "1.0.127", default-features = false, features = ["derive"] } serde = { version = "1.0.127", default-features = false, features = ["derive"] }
thiserror = { version = "1.0.26" } thiserror = { version = "1.0.26" }

View file

@ -0,0 +1 @@
20828f78f4b256f0563c2fbb65b5361504f948dd4910dfe54e981aa5670f73a8 counter.wasm

View file

@ -0,0 +1 @@
07b18dc271100d7c375e9ff1de8a767899ffa745dd52dbaa0ce9ab587346d78e ./target/wasm32-unknown-unknown/release/counter.wasm

Binary file not shown.

View file

@ -3,7 +3,7 @@ use std::fs::create_dir_all;
use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; use cosmwasm_schema::{export_schema, remove_schemas, schema_for};
use counter::msg::{CountResponse, ExecuteMsg, InstantiateMsg, QueryMsg}; use counter::msg::{totalPayersResponse, ExecuteMsg, InstantiateMsg, QueryMsg};
use counter::state::State; use counter::state::State;
fn main() { fn main() {
@ -16,5 +16,5 @@ fn main() {
export_schema(&schema_for!(ExecuteMsg), &out_dir); export_schema(&schema_for!(ExecuteMsg), &out_dir);
export_schema(&schema_for!(QueryMsg), &out_dir); export_schema(&schema_for!(QueryMsg), &out_dir);
export_schema(&schema_for!(State), &out_dir); export_schema(&schema_for!(State), &out_dir);
export_schema(&schema_for!(CountResponse), &out_dir); export_schema(&schema_for!(totalPayersResponse), &out_dir);
} }

View file

@ -1,11 +1,12 @@
#[cfg(not(feature = "library"))] #[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point; use cosmwasm_std::entry_point;
use cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cosmwasm_std::{Order, Uint128, Coin, BankMsg, CosmosMsg, Uint256, to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Api, Addr};
use cw2::set_contract_version; use cw2::set_contract_version;
use crate::error::ContractError; use crate::error::ContractError;
use crate::msg::{CountResponse, ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::msg::{ExecuteMsg, InstantiateMsg, totalPayersResponse, QueryMsg, self};
use crate::state::{State, User, STATE, CUSTOMERS}; use crate::state::{State, STATE, BALANCES};
// version info for migration info // version info for migration info
const CONTRACT_NAME: &str = "crates.io:counter"; const CONTRACT_NAME: &str = "crates.io:counter";
@ -19,16 +20,18 @@ pub fn instantiate(
msg: InstantiateMsg, msg: InstantiateMsg,
) -> Result<Response, ContractError> { ) -> Result<Response, ContractError> {
let state = State { let state = State {
count: msg.count, storeowner: info.sender.clone(),
owner: info.sender.clone(), bill: msg.bill,
TotalPayers: 0,
}; };
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
STATE.save(deps.storage, &state)?; STATE.save(deps.storage, &state)?;
Ok(Response::new() Ok(Response::new()
.add_attribute("method", "instantiate") .add_attribute("method", "instantiate")
.add_attribute("owner", info.sender) .add_attribute("owner", info.sender)
.add_attribute("count", msg.count.to_string())) )
} }
#[cfg_attr(not(feature = "library"), entry_point)] #[cfg_attr(not(feature = "library"), entry_point)]
@ -39,120 +42,84 @@ pub fn execute(
msg: ExecuteMsg, msg: ExecuteMsg,
) -> Result<Response, ContractError> { ) -> Result<Response, ContractError> {
match msg { match msg {
ExecuteMsg::Increment {} => try_increment(deps), ExecuteMsg::Payup {} => try_payup(deps, info),
ExecuteMsg::Reset { count } => try_reset(deps, info, count), ExecuteMsg::Createaccounts {} => create_accounts(deps, info),
//ExecuteMsg::EnterCustomer {} => try_enter_address(deps, info),
}
} }
pub fn try_enter_address(deps: DepsMut, info: MessageInfo, entering_address: String) -> Result<Response, ContractError>{ }
let entry_address = deps.api.addr_validate(&entering_address)?; pub fn create_accounts(deps: DepsMut, info: MessageInfo) -> Result<Response, ContractError> {
let paid = false;
//load and save with extra key argument let address = deps.api.addr_validate(&info.sender.to_string())?;
let empty = CUSTOMERS.may_load(deps.storage, &str.to_string()); BALANCES.save(deps.storage, &address, &paid)?;
Ok(Response::new()) Ok(Response::new())
} }
pub fn try_payup(deps: DepsMut, info: MessageInfo) -> Result<Response, ContractError> {
let all: StdResult<Vec<_>> = BALANCES
.range(deps.storage, None, None, Order::Ascending)
.collect();
pub fn try_increment(deps: DepsMut) -> Result<Response, ContractError> {
STATE.update(deps.storage, |mut state| -> Result<_, ContractError> { STATE.update(deps.storage, |mut state| -> Result<_, ContractError> {
state.count += 1; state.TotalPayers += all.unwrap_or_default().len() as i32;
Ok(state) Ok(state)
})?; })?;
Ok(Response::new().add_attribute("method", "try_increment")) let config = STATE.load(deps.storage)?;
let deposit_amount: Uint128 = info
.funds
.iter()
.find(|c| c.denom == "uluna")
.map(|c| Uint128::from(c.amount))
.unwrap_or_else(Uint128::zero);
if deposit_amount.is_zero() {
return Err(ContractError::ZeroDeposit {});
} }
pub fn try_reset(deps: DepsMut, info: MessageInfo, count: i32) -> Result<Response, ContractError> {
STATE.update(deps.storage, |mut state| -> Result<_, ContractError> { let msg = CosmosMsg::Bank(BankMsg::Send {
if info.sender != state.owner { to_address: config.storeowner.to_string(),
return Err(ContractError::Unauthorized {}); amount: vec![
} Coin {
state.count = count; denom: "uluna".to_string(),
Ok(state) amount: deposit_amount,
})?; },
Ok(Response::new().add_attribute("method", "reset")) ],
});
return Ok(Response::new().add_message(msg));;
} }
#[cfg_attr(not(feature = "library"), entry_point)] #[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> { pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg { match msg {
QueryMsg::GetCount {} => to_binary(&query_count(deps)?), QueryMsg::QueryPayers {} => to_binary(&QueryPayers(deps)?),
} }
} }
fn query_count(deps: Deps) -> StdResult<CountResponse> { pub fn QueryPayers(deps: Deps) -> StdResult<totalPayersResponse> {
let state = STATE.load(deps.storage)?; let state = STATE.load(deps.storage)?;
Ok(CountResponse { count: state.count }) Ok(totalPayersResponse { payers: state.TotalPayers})
} }
#[cfg(test)] /*
mod tests {
use super::*;
use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};
use cosmwasm_std::{coins, from_binary};
#[test] for index in 0..state.TotalPayers{
fn proper_initialization() { let config = STATE.load(deps.storage)?;
let mut deps = mock_dependencies(&[]); let to_be_paid: (state.bill)*(1/(state.TotalPayers));
let msg = InstantiateMsg { count: 17 }; let Divided_Amount: Uint = BALANCES[index];
let info = mock_info("creator", &coins(1000, "earth")); let deposit_amount: Uint128 = info
.funds
.iter()
.find(|c| c.denom == "uluna")
.map(|c| Uint128::from(c.amount))
.unwrap_or_else(Uint128::zero);
// we can just call .unwrap() to assert this was a success if deposit_amount.is_zero() {
let res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); return Err(ContractError::ZeroDeposit {});
assert_eq!(0, res.messages.len());
// it worked, let's query the state
let res = query(deps.as_ref(), mock_env(), QueryMsg::GetCount {}).unwrap();
let value: CountResponse = from_binary(&res).unwrap();
assert_eq!(17, value.count);
} }
#[test] }*/
fn increment() {
let mut deps = mock_dependencies(&coins(2, "token"));
let msg = InstantiateMsg { count: 17 };
let info = mock_info("creator", &coins(2, "token"));
let _res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap();
// beneficiary can release it
let info = mock_info("anyone", &coins(2, "token"));
let msg = ExecuteMsg::Increment {};
let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap();
// should increase counter by 1
let res = query(deps.as_ref(), mock_env(), QueryMsg::GetCount {}).unwrap();
let value: CountResponse = from_binary(&res).unwrap();
assert_eq!(18, value.count);
}
#[test]
fn reset() {
let mut deps = mock_dependencies(&coins(2, "token"));
let msg = InstantiateMsg { count: 17 };
let info = mock_info("creator", &coins(2, "token"));
let _res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap();
// beneficiary can release it
let unauth_info = mock_info("anyone", &coins(2, "token"));
let msg = ExecuteMsg::Reset { count: 5 };
let res = execute(deps.as_mut(), mock_env(), unauth_info, msg);
match res {
Err(ContractError::Unauthorized {}) => {}
_ => panic!("Must return unauthorized error"),
}
// only the original creator can reset the counter
let auth_info = mock_info("creator", &coins(2, "token"));
let msg = ExecuteMsg::Reset { count: 5 };
let _res = execute(deps.as_mut(), mock_env(), auth_info, msg).unwrap();
// should now be 5
let res = query(deps.as_ref(), mock_env(), QueryMsg::GetCount {}).unwrap();
let value: CountResponse = from_binary(&res).unwrap();
assert_eq!(5, value.count);
}
}

View file

@ -8,6 +8,9 @@ pub enum ContractError {
#[error("Unauthorized")] #[error("Unauthorized")]
Unauthorized {}, Unauthorized {},
#[error("you cant deposit $0")]
ZeroDeposit {},
// Add any other custom errors you like here. // Add any other custom errors you like here.
// Look at https://docs.rs/thiserror/1.0.21/thiserror/ for details. // Look at https://docs.rs/thiserror/1.0.21/thiserror/ for details.
} }

View file

@ -3,28 +3,29 @@ use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct InstantiateMsg { pub struct InstantiateMsg {
pub count: i32, //what do we initialize? pub bill: i32,
} }
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum ExecuteMsg { pub enum ExecuteMsg {
Increment {}, Payup {},
Reset { count: i32 }, Createaccounts{}
EnterCustomer { entering_address: String}
//we will get user address and names. Then divide bill. Then take money from users and put into our own contract.
//
} }
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum QueryMsg { pub enum QueryMsg {
// GetCount returns the current count as a json-encoded number // GetCount returns the current count as a json-encoded number
GetCount {}, QueryPayers{},
} }
//We define a custom struct for each query response //We define a custom struct for each query response
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct CountResponse { pub struct totalPayersResponse {
pub count: i32, pub payers: i32,
} }
//initiate balances?

View file

@ -1,23 +1,20 @@
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use cosmwasm_std::Addr; use cosmwasm_std::{Uint128, Addr};
use cw_storage_plus::{Item, Map}; //import map and figure out how to use it use cw_storage_plus::{Item, Map};
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct State { pub struct State {
pub count: i32, pub storeowner: Addr,
pub owner: Addr, pub bill: i32,
} pub TotalPayers: i32,
pub struct User {
pub name: String,
pub address: Addr,
} }
pub const STATE: Item<State> = Item::new("state"); pub const STATE: Item<State> = Item::new("state");
pub const CUSTOMERS: Map<&str, User> = Map::new("customers"); pub const BALANCES: Map<&Addr, bool> = Map::new("balance");
/* /*
add states: add states:

View file

@ -2,11 +2,8 @@
// to populate secret in CI environment instead of hardcoding // to populate secret in CI environment instead of hardcoding
module.exports = { module.exports = {
custom_tester_1: { testnet: {
mnemonic: mnemonic:
"shiver position copy catalog upset verify cheap library enjoy extend second peasant basic kit polar business document shrug pass chuckle lottery blind ecology stand", "cactus wash reveal certain neck guard finger dash tired injury piece remember never load illness off butter lumber velvet off allow control anger return",
},
custom_tester_2: {
privateKey: "fGl1yNoUnnNUqTUXXhxH9vJU0htlz9lWwBt3fQw+ixw=",
}, },
}; };

View file

@ -1 +1,10 @@
{} {
"localterra": {
"counter": {
"codeId": "13",
"contractAddresses": {
"default": "terra1dazgw2z5sxe7hgt43p0e3xyljnu45tlzwraccz"
}
}
}
}