Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CW-1155 to implement EIP 1155 #27

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 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
26 changes: 26 additions & 0 deletions Cargo.lock

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

5 changes: 5 additions & 0 deletions contracts/cw1155-base/.cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[alias]
wasm = "build --release --target wasm32-unknown-unknown"
wasm-debug = "build --target wasm32-unknown-unknown"
unit-test = "test --lib"
schema = "run --example schema"
38 changes: 38 additions & 0 deletions contracts/cw1155-base/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[package]
name = "cw1155-base"
version = "0.10.0"
authors = ["Ethan Frey <[email protected]>"]
edition = "2018"
description = "Basic implementation cw1155 NFTs"
license = "Apache-2.0"
repository = "https://github.com/CosmWasm/cw-plus"
homepage = "https://cosmwasm.com"
documentation = "https://docs.cosmwasm.com"

exclude = [
# Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication.
"artifacts/*",
]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
crate-type = ["cdylib", "rlib"]

[features]
# for more explicit tests, cargo test --features=backtraces
backtraces = ["cosmwasm-std/backtraces"]
# use library feature to disable all instantiate/execute/query exports
library = []

[dependencies]
cw0 = { version = "0.10.0" }
cw2 = { version = "0.10.0" }
cw1155 = { path = "../../packages/cw1155", version = "0.10.0" }
cw-storage-plus = { version = "0.10.0" }
cosmwasm-std = { version = "1.0.0-beta" }
schemars = "0.8.1"
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
thiserror = { version = "1.0.23" }

[dev-dependencies]
cosmwasm-schema = { version = "1.0.0-beta" }
14 changes: 14 additions & 0 deletions contracts/cw1155-base/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Cw721_base
JakeHartnell marked this conversation as resolved.
Show resolved Hide resolved
Copyright (C) 2020-2021 Confio OÜ

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
71 changes: 71 additions & 0 deletions contracts/cw1155-base/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Cw1155 Basic

This is a basic implementation of a cw1155 NFT contract. It implements
the [CW1155 spec](../../packages/cw1155/README.md) and is designed to
be deployed as is, or imported into other contracts to easily build
cw1155-compatible NFTs with custom logic.

Implements:

- [x] CW1155 Base
- [x] Metadata extension
- [ ] Enumerable extension (AllTokens done, but not Tokens - requires [#81](https://github.com/CosmWasm/cw-plus/issues/81))

## Implementation

The `ExecuteMsg` and `QueryMsg` implementations follow the [CW1155 spec](../../packages/cw1155/README.md) and are described there.
Beyond that, we make a few additions:

* `InstantiateMsg` takes name and symbol (for metadata), as well as a **Minter** address. This is a special address that has full
power to mint new NFTs (but not modify existing ones)
* `ExecuteMsg::Mint{token_id, owner, token_uri, amount, token_extension}` - creates a new token with given owner and (optional) metadata. It can only be called by
the Minter set in `instantiate`.
* `QueryMsg::Minter{}` - returns the minter address for this contract.

It requires all tokens to have defined metadata in the standard format (with no extensions). For generic NFTs this may
often be enough.

The *Minter* can either be an external actor (eg. web server, using PubKey) or another contract. If you just want to customize
the minting behavior but not other functionality, you could extend this contract (importing code and wiring it together)
or just create a custom contract as the owner and use that contract to Mint.

If provided, it is expected that the _token_uri_ points to a JSON file following the [ERC721 Metadata JSON Schema](https://eips.ethereum.org/EIPS/eip-721).

## Running this contract

You will need Rust 1.44.1+ with `wasm32-unknown-unknown` target installed.

You can run unit tests on this via:

`cargo test`

Once you are happy with the content, you can compile it to wasm via:

```
RUSTFLAGS='-C link-arg=-s' cargo wasm
cp ../../target/wasm32-unknown-unknown/release/cw20_base.wasm .
ls -l cw20_base.wasm
sha256sum cw20_base.wasm
sgoya marked this conversation as resolved.
Show resolved Hide resolved
```

Or for a production-ready (optimized) build, run a build command in the
the repository root: https://github.com/CosmWasm/cw-plus#compiling.

## Importing this contract

You can also import much of the logic of this contract to build another
CW721-compliant contract, such as tradable names, crypto kitties,
or tokenized real estate.
sgoya marked this conversation as resolved.
Show resolved Hide resolved

Basically, you just need to write your handle function and import
`cw721_base::contract::handle_transfer`, etc and dispatch to them.
This allows you to use custom `ExecuteMsg` and `QueryMsg` with your additional
calls, but then use the underlying implementation for the standard cw721
messages you want to support. The same with `QueryMsg`. You will most
likely want to write a custom, domain-specific `instantiate`.

**TODO: add example when written**

For now, you can look at [`cw20-staking`](../cw20-staking/README.md)
for an example of how to "inherit" cw20 functionality and combine it with custom logic.
The process is similar for cw721.
sgoya marked this conversation as resolved.
Show resolved Hide resolved
37 changes: 37 additions & 0 deletions contracts/cw1155-base/examples/schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use std::env::current_dir;
use std::fs::create_dir_all;

use cosmwasm_schema::{export_schema, export_schema_with_title, remove_schemas, schema_for};

use cw1155::{
AllNftInfoResponse, ApprovedForAllResponse, ContractInfoResponse, NftInfoResponse,
NumTokensResponse, OwnerOfResponse, TokensResponse,
};
use cw1155_base::{ExecuteMsg, Extension, InstantiateMsg, MinterResponse, QueryMsg};

fn main() {
let mut out_dir = current_dir().unwrap();
out_dir.push("schema");
create_dir_all(&out_dir).unwrap();
remove_schemas(&out_dir).unwrap();

export_schema(&schema_for!(InstantiateMsg), &out_dir);
export_schema_with_title(&schema_for!(ExecuteMsg<Extension>), &out_dir, "ExecuteMsg");
export_schema(&schema_for!(QueryMsg), &out_dir);
export_schema_with_title(
&schema_for!(AllNftInfoResponse<Extension>),
&out_dir,
"AllNftInfoResponse",
);
export_schema(&schema_for!(ApprovedForAllResponse), &out_dir);
export_schema(&schema_for!(ContractInfoResponse), &out_dir);
export_schema(&schema_for!(MinterResponse), &out_dir);
export_schema_with_title(
&schema_for!(NftInfoResponse<Extension>),
&out_dir,
"NftInfoResponse",
);
export_schema(&schema_for!(NumTokensResponse), &out_dir);
export_schema(&schema_for!(OwnerOfResponse), &out_dir);
export_schema(&schema_for!(TokensResponse), &out_dir);
}
Loading