Initial Commit

This commit is contained in:
hu55a1n1 2023-11-14 07:30:48 -08:00
commit 80d1498a67
13 changed files with 560 additions and 0 deletions

View file

@ -0,0 +1,4 @@
[alias]
wasm = "build --release --lib --target wasm32-unknown-unknown"
unit-test = "test --lib"
schema = "run --bin schema"

View file

@ -0,0 +1,75 @@
# Based on https://github.com/actions-rs/example/blob/master/.github/workflows/quickstart.yml
on: [push, pull_request]
name: Basic
jobs:
test:
name: Test Suite
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2
- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: 1.60.0
target: wasm32-unknown-unknown
override: true
- name: Run unit tests
uses: actions-rs/cargo@v1
with:
command: unit-test
args: --locked
env:
RUST_BACKTRACE: 1
- name: Compile WASM contract
uses: actions-rs/cargo@v1
with:
command: wasm
args: --locked
env:
RUSTFLAGS: "-C link-arg=-s"
lints:
name: Lints
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2
- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: 1.60.0
override: true
components: rustfmt, clippy
- name: Run cargo fmt
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Run cargo clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: -- -D warnings
- name: Generate Schema
uses: actions-rs/cargo@v1
with:
command: schema
args: --locked
- name: Schema Changes
# fails if any changes not committed
run: git diff --exit-code schema

View file

@ -0,0 +1,35 @@
name: release wasm
on:
release:
types: [created]
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2
- name: Install cargo-run-script
uses: actions-rs/cargo@v1
with:
command: install
args: cargo-run-script
- name: Run cargo optimize
uses: actions-rs/cargo@v1
with:
command: run-script
args: optimize
- name: Get release ID
id: get_release
uses: bruceadams/get-release@v1.2.3
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Upload optimized wasm
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ./artifacts/*.wasm
tag: ${{ github.ref }}
overwrite: true
file_glob: true

16
bisenzone-cw-mvp/.gitignore vendored Normal file
View file

@ -0,0 +1,16 @@
# Build results
/target
/schema
# Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327)
.cargo-ok
# Text file backups
**/*.rs.bk
# macOS
.DS_Store
# IDEs
*.iml
.idea

View file

@ -0,0 +1,85 @@
# CosmWasm Starter Pack
This is a template to build smart contracts in Rust to run inside a
[Cosmos SDK](https://github.com/cosmos/cosmos-sdk) module on all chains that enable it.
To understand the framework better, please read the overview in the
[cosmwasm repo](https://github.com/CosmWasm/cosmwasm/blob/master/README.md),
and dig into the [cosmwasm docs](https://www.cosmwasm.com).
This assumes you understand the theory and just want to get coding.
## Creating a new repo from template
Assuming you have a recent version of Rust and Cargo installed
(via [rustup](https://rustup.rs/)),
then the following should get you a new repo to start a contract:
Install [cargo-generate](https://github.com/ashleygwilliams/cargo-generate) and cargo-run-script.
Unless you did that before, run this line now:
```sh
cargo install cargo-generate --features vendored-openssl
cargo install cargo-run-script
```
Now, use it to create your new contract.
Go to the folder in which you want to place it and run:
**Latest**
```sh
cargo generate --git https://github.com/CosmWasm/cw-template.git --name PROJECT_NAME
```
For cloning minimal code repo:
```sh
cargo generate --git https://github.com/CosmWasm/cw-template.git --name PROJECT_NAME -d minimal=true
```
You will now have a new folder called `PROJECT_NAME` (I hope you changed that to something else)
containing a simple working contract and build system that you can customize.
## Create a Repo
After generating, you have a initialized local git repo, but no commits, and no remote.
Go to a server (eg. github) and create a new upstream repo (called `YOUR-GIT-URL` below).
Then run the following:
```sh
# this is needed to create a valid Cargo.lock file (see below)
cargo check
git branch -M main
git add .
git commit -m 'Initial Commit'
git remote add origin YOUR-GIT-URL
git push -u origin main
```
## CI Support
We have template configurations for both [GitHub Actions](.github/workflows/Basic.yml)
and [Circle CI](.circleci/config.yml) in the generated project, so you can
get up and running with CI right away.
One note is that the CI runs all `cargo` commands
with `--locked` to ensure it uses the exact same versions as you have locally. This also means
you must have an up-to-date `Cargo.lock` file, which is not auto-generated.
The first time you set up the project (or after adding any dep), you should ensure the
`Cargo.lock` file is updated, so the CI will test properly. This can be done simply by
running `cargo check` or `cargo unit-test`.
## Using your project
Once you have your custom repo, you should check out [Developing](./Developing.md) to explain
more on how to run tests and develop code. Or go through the
[online tutorial](https://docs.cosmwasm.com/) to get a better feel
of how to develop.
[Publishing](./Publishing.md) contains useful information on how to publish your contract
to the world, once you are ready to deploy it on a running blockchain. And
[Importing](./Importing.md) contains information about pulling in other contracts or crates
that have been published.
Please replace this README file with information about your specific project. You can keep
the `Developing.md` and `Publishing.md` files as useful references, but please set some
proper description in the README.

View file

@ -0,0 +1,11 @@
use cosmwasm_schema::write_api;
use cw_mtcs::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
fn main() {
write_api! {
instantiate: InstantiateMsg,
execute: ExecuteMsg,
query: QueryMsg,
}
}

View file

@ -0,0 +1,156 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult};
use cw2::set_contract_version;
use crate::error::ContractError;
use crate::msg::{ExecuteMsg, GetCountResponse, InstantiateMsg, QueryMsg};
use crate::state::{State, STATE};
// version info for migration info
const CONTRACT_NAME: &str = "crates.io:cw-mtcs";
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
deps: DepsMut,
_env: Env,
info: MessageInfo,
msg: InstantiateMsg,
) -> Result<Response, ContractError> {
let state = State {
count: msg.count,
owner: info.sender.clone(),
};
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
STATE.save(deps.storage, &state)?;
Ok(Response::new()
.add_attribute("method", "instantiate")
.add_attribute("owner", info.sender)
.add_attribute("count", msg.count.to_string()))
}
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
deps: DepsMut,
_env: Env,
info: MessageInfo,
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
match msg {
ExecuteMsg::Increment {} => execute::increment(deps),
ExecuteMsg::Reset { count } => execute::reset(deps, info, count),
}
}
pub mod execute {
use super::*;
pub fn increment(deps: DepsMut) -> Result<Response, ContractError> {
STATE.update(deps.storage, |mut state| -> Result<_, ContractError> {
state.count += 1;
Ok(state)
})?;
Ok(Response::new().add_attribute("action", "increment"))
}
pub fn reset(deps: DepsMut, info: MessageInfo, count: i32) -> Result<Response, ContractError> {
STATE.update(deps.storage, |mut state| -> Result<_, ContractError> {
if info.sender != state.owner {
return Err(ContractError::Unauthorized {});
}
state.count = count;
Ok(state)
})?;
Ok(Response::new().add_attribute("action", "reset"))
}
}
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::GetCount {} => to_json_binary(&query::count(deps)?),
}
}
pub mod query {
use super::*;
pub fn count(deps: Deps) -> StdResult<GetCountResponse> {
let state = STATE.load(deps.storage)?;
Ok(GetCountResponse { count: state.count })
}
}
#[cfg(test)]
mod tests {
use super::*;
use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};
use cosmwasm_std::{coins, from_json};
#[test]
fn proper_initialization() {
let mut deps = mock_dependencies();
let msg = InstantiateMsg { count: 17 };
let info = mock_info("creator", &coins(1000, "earth"));
// we can just call .unwrap() to assert this was a success
let res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap();
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: GetCountResponse = from_json(&res).unwrap();
assert_eq!(17, value.count);
}
#[test]
fn increment() {
let mut deps = mock_dependencies();
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: GetCountResponse = from_json(&res).unwrap();
assert_eq!(18, value.count);
}
#[test]
fn reset() {
let mut deps = mock_dependencies();
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: GetCountResponse = from_json(&res).unwrap();
assert_eq!(5, value.count);
}
}

View file

@ -0,0 +1,13 @@
use cosmwasm_std::StdError;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum ContractError {
#[error("{0}")]
Std(#[from] StdError),
#[error("Unauthorized")]
Unauthorized {},
// Add any other custom errors you like here.
// Look at https://docs.rs/thiserror/1.0.21/thiserror/ for details.
}

View file

@ -0,0 +1,47 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use cosmwasm_std::{
to_json_binary, Addr, CosmosMsg, CustomQuery, Querier, QuerierWrapper, StdResult, WasmMsg,
WasmQuery,
};
use crate::msg::{ExecuteMsg, GetCountResponse, QueryMsg};
/// CwTemplateContract is a wrapper around Addr that provides a lot of helpers
/// for working with this.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct CwTemplateContract(pub Addr);
impl CwTemplateContract {
pub fn addr(&self) -> Addr {
self.0.clone()
}
pub fn call<T: Into<ExecuteMsg>>(&self, msg: T) -> StdResult<CosmosMsg> {
let msg = to_json_binary(&msg.into())?;
Ok(WasmMsg::Execute {
contract_addr: self.addr().into(),
msg,
funds: vec![],
}
.into())
}
/// Get Count
pub fn count<Q, T, CQ>(&self, querier: &Q) -> StdResult<GetCountResponse>
where
Q: Querier,
T: Into<String>,
CQ: CustomQuery,
{
let msg = QueryMsg::GetCount {};
let query = WasmQuery::Smart {
contract_addr: self.addr().into(),
msg: to_json_binary(&msg)?,
}
.into();
let res: GetCountResponse = QuerierWrapper::<CQ>::new(querier).query(&query)?;
Ok(res)
}
}

View file

@ -0,0 +1,71 @@
#[cfg(test)]
mod tests {
use crate::helpers::CwTemplateContract;
use crate::msg::InstantiateMsg;
use cosmwasm_std::{Addr, Coin, Empty, Uint128};
use cw_multi_test::{App, AppBuilder, Contract, ContractWrapper, Executor};
pub fn contract_template() -> Box<dyn Contract<Empty>> {
let contract = ContractWrapper::new(
crate::contract::execute,
crate::contract::instantiate,
crate::contract::query,
);
Box::new(contract)
}
const USER: &str = "USER";
const ADMIN: &str = "ADMIN";
const NATIVE_DENOM: &str = "denom";
fn mock_app() -> App {
AppBuilder::new().build(|router, _, storage| {
router
.bank
.init_balance(
storage,
&Addr::unchecked(USER),
vec![Coin {
denom: NATIVE_DENOM.to_string(),
amount: Uint128::new(1),
}],
)
.unwrap();
})
}
fn proper_instantiate() -> (App, CwTemplateContract) {
let mut app = mock_app();
let cw_template_id = app.store_code(contract_template());
let msg = InstantiateMsg { count: 1i32 };
let cw_template_contract_addr = app
.instantiate_contract(
cw_template_id,
Addr::unchecked(ADMIN),
&msg,
&[],
"test",
None,
)
.unwrap();
let cw_template_contract = CwTemplateContract(cw_template_contract_addr);
(app, cw_template_contract)
}
mod count {
use super::*;
use crate::msg::ExecuteMsg;
#[test]
fn count() {
let (mut app, cw_template_contract) = proper_instantiate();
let msg = ExecuteMsg::Increment {};
let cosmos_msg = cw_template_contract.call(msg).unwrap();
app.execute(Addr::unchecked(USER), cosmos_msg).unwrap();
}
}
}

View file

@ -0,0 +1,8 @@
pub mod contract;
mod error;
pub mod helpers;
pub mod integration_tests;
pub mod msg;
pub mod state;
pub use crate::error::ContractError;

View file

@ -0,0 +1,26 @@
use cosmwasm_schema::{cw_serde, QueryResponses};
#[cw_serde]
pub struct InstantiateMsg {
pub count: i32,
}
#[cw_serde]
pub enum ExecuteMsg {
Increment {},
Reset { count: i32 },
}
#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg {
// GetCount returns the current count as a json-encoded number
#[returns(GetCountResponse)]
GetCount {},
}
// We define a custom struct for each query response
#[cw_serde]
pub struct GetCountResponse {
pub count: i32,
}

View file

@ -0,0 +1,13 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use cosmwasm_std::Addr;
use cw_storage_plus::Item;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct State {
pub count: i32,
pub owner: Addr,
}
pub const STATE: Item<State> = Item::new("state");