diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..9e414095 Binary files /dev/null and b/.DS_Store differ diff --git a/token-factory/.DS_Store b/token-factory/.DS_Store new file mode 100644 index 00000000..f8b88e84 Binary files /dev/null and b/token-factory/.DS_Store differ diff --git a/token-factory/.gitignore b/token-factory/.gitignore new file mode 100755 index 00000000..8de8f877 --- /dev/null +++ b/token-factory/.gitignore @@ -0,0 +1,9 @@ +# Ignore build artifacts from the local tests sub-crate. +/target/ + +# Ignore backup files creates by cargo fmt. +**/*.rs.bk + +# Remove Cargo.lock when creating an executable, leave it for libraries +# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock +Cargo.lock diff --git a/token-factory/Cargo.toml b/token-factory/Cargo.toml new file mode 100755 index 00000000..2da685a0 --- /dev/null +++ b/token-factory/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "TokenFactory" +version = "0.1.0" +authors = ["[Luciano Otto Rodrigues] [https://github.com/Lucianoottor]"] +edition = "2024" + +[dependencies] +ink = { version = "6.0.0-beta.1", default-features = false, features = ["unstable-hostfn"] } +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } +scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } +SimpleToken = { path = "SimpleToken", default-features = false, features = ["ink-as-dependency"] } # we have to pass the other contract as dependency + + +[lib] +path = "lib.rs" + +[features] +default = ["std"] +std = [ + "ink/std", + "SimpleToken/std" # enable std for the dependency +] +ink-as-dependency = [] +e2e-tests = [] + +[package.metadata.ink-lang] +abi = "ink" + +[lints.rust.unexpected_cfgs] +level = "warn" +check-cfg = [ + 'cfg(ink_abi, values("ink", "sol", "all"))' +] diff --git a/token-factory/SimpleToken/.DS_Store b/token-factory/SimpleToken/.DS_Store new file mode 100644 index 00000000..de619f3c Binary files /dev/null and b/token-factory/SimpleToken/.DS_Store differ diff --git a/token-factory/SimpleToken/.gitignore b/token-factory/SimpleToken/.gitignore new file mode 100755 index 00000000..8de8f877 --- /dev/null +++ b/token-factory/SimpleToken/.gitignore @@ -0,0 +1,9 @@ +# Ignore build artifacts from the local tests sub-crate. +/target/ + +# Ignore backup files creates by cargo fmt. +**/*.rs.bk + +# Remove Cargo.lock when creating an executable, leave it for libraries +# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock +Cargo.lock diff --git a/token-factory/SimpleToken/Cargo.toml b/token-factory/SimpleToken/Cargo.toml new file mode 100755 index 00000000..04743f99 --- /dev/null +++ b/token-factory/SimpleToken/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "SimpleToken" +version = "0.1.0" +authors = ["[Luciano Otto Rodrigues] [https://github.com/Lucianoottor]"] +edition = "2024" + +[dependencies] +ink = { version = "6.0.0-beta.1", default-features = false, features = ["unstable-hostfn"] } +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } +scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } + +[dev-dependencies] +ink_e2e = { version = "6.0.0-beta.1" } + +[lib] +path = "lib.rs" + +[features] +default = ["std"] +std = [ + "ink/std", +] +ink-as-dependency = [] +e2e-tests = [] + +[package.metadata.ink-lang] +abi = "ink" + +[lints.rust.unexpected_cfgs] +level = "warn" +check-cfg = [ + 'cfg(ink_abi, values("ink", "sol", "all"))' +] diff --git a/token-factory/SimpleToken/lib.rs b/token-factory/SimpleToken/lib.rs new file mode 100755 index 00000000..81a566b8 --- /dev/null +++ b/token-factory/SimpleToken/lib.rs @@ -0,0 +1,27 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +#[ink::contract] +pub mod SimpleToken { + + use ink::storage::Mapping; + + + #[ink(storage)] + pub struct SimpleToken { + balances: Mapping + } + + impl SimpleToken { + #[ink(constructor)] + pub fn new(initial_supply: Balance) -> Self { + let mut new = Mapping::new(); + new.insert(ink::env::caller(), &initial_supply); + Self { balances: new } + } + + #[ink(message)] + pub fn balance_of(&self, owner: ink::Address) -> Balance { + self.balances.get(&owner).unwrap_or(0) + } + } +} diff --git a/token-factory/lib.rs b/token-factory/lib.rs new file mode 100755 index 00000000..e601c3ce --- /dev/null +++ b/token-factory/lib.rs @@ -0,0 +1,49 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +// Factory contract that can deploy instances of the SimpleToken contract +// It uses cross-contract calls to instantiate new token contracts and factory pattern + +#[ink::contract] +mod TokenFactory { + + use ink::storage::StorageVec; + use ink::prelude::vec::Vec; + use SimpleToken::SimpleTokenRef; + + #[ink(storage)] + pub struct TokenFactory { + token_code_hash: ink::H256, + children: StorageVec, + } + + impl TokenFactory { + + #[ink(constructor)] + pub fn new(token_code_hash: ink::H256) -> Self { + Self { + token_code_hash, + children: StorageVec::new(), + } + } + + // Creates a new instance of the SimpleToken contract with the initial parameter + #[ink(message)] + pub fn create_token(&mut self, initial_supply: Balance) { + let token_instance = SimpleTokenRef::new(initial_supply) // Here happens the cross-contract call, we promise to deploy a new SimpleToken and we will store its address to our mapping "children", so the factory can track the deployed tokens + .code_hash(self.token_code_hash) // We provide the code hash of the SimpleToken contract to instantiate it, ensuring that the correct contract code is used + .salt_bytes(None) + .instantiate(); + let token_address = ink::ToAddr::to_addr(&token_instance); + self.children.push(&token_address); + } + + #[ink(message)] + pub fn list_tokens(&self) -> Vec { + let mut tokens = Vec::new(); + for i in 0..self.children.len() { + tokens.push(self.children.get(i).unwrap()); + } + tokens + } + } +}