From 81dff208ff04e6ca6e08b00855394b6e118986df Mon Sep 17 00:00:00 2001 From: guigou Date: Tue, 6 Aug 2024 18:11:43 +0200 Subject: [PATCH] Create the verified contract for the dAppStaking --- ink/Cargo.toml | 1 + ink/contracts/dapp_staking/Cargo.toml | 28 +++ ink/contracts/dapp_staking/convert.py | 35 ++++ ink/contracts/dapp_staking/lib.rs | 171 ++++++++++++++++++ .../dapp_staking/rust-toolchain.toml | 11 ++ 5 files changed, 246 insertions(+) create mode 100644 ink/contracts/dapp_staking/Cargo.toml create mode 100644 ink/contracts/dapp_staking/convert.py create mode 100644 ink/contracts/dapp_staking/lib.rs create mode 100644 ink/contracts/dapp_staking/rust-toolchain.toml diff --git a/ink/Cargo.toml b/ink/Cargo.toml index 517ee85..934281d 100644 --- a/ink/Cargo.toml +++ b/ink/Cargo.toml @@ -3,4 +3,5 @@ members = [ "logics", "contracts/lotto", "integration_tests", + "contracts/dapp_staking", ] \ No newline at end of file diff --git a/ink/contracts/dapp_staking/Cargo.toml b/ink/contracts/dapp_staking/Cargo.toml new file mode 100644 index 0000000..5136cc5 --- /dev/null +++ b/ink/contracts/dapp_staking/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "lotto_dapp_staking" +version = "1.0.0" +authors = ["guigou"] +edition = "2021" + +[dependencies] +ink = { version = "5.0.0", default-features = false} +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } +scale-info = { version = "2", default-features = false, features = ["derive"], optional = true } + +[lib] +path = "lib.rs" + +[features] +default = ["std"] +std = [ + "ink/std", + "scale/std", + "scale-info/std", +] +ink-as-dependency = [] + +[profile.release] +overflow-checks = false + +[profile.dev] +overflow-checks = false diff --git a/ink/contracts/dapp_staking/convert.py b/ink/contracts/dapp_staking/convert.py new file mode 100644 index 0000000..428dce4 --- /dev/null +++ b/ink/contracts/dapp_staking/convert.py @@ -0,0 +1,35 @@ +# Convert wasm contract to standard_input_json +# Example +# python convert.py --manifest xx.toml + +import argparse +import os +import json + +parser = argparse.ArgumentParser(description='Print all files in the specified directory') + +parser.add_argument('--manifest', type=str, default="Cargo.toml", help='manifest path') +parser.add_argument('--exclude', type=str, nargs='+', default=[], help='exclude folder') + +args = parser.parse_args() +extension = ["rs", "toml"] +exclude = [".idea", ".git", "target"] + args.exclude +includeFiles = ["Cargo.lock"] + +inputJson = { + "manifest-path": args.manifest, + "contracts": {} +} + +for root, dirs, files in os.walk("."): + dirs[:] = [d for d in dirs if d not in exclude] + for file in files: + if file.endswith(tuple(extension)) or file in includeFiles: + filePath = os.path.join(root, file) + with open(filePath, 'r') as f: + contents = f.read() + if contents == "": + continue + inputJson["contracts"][filePath.lstrip("./")] = contents + +print(json.dumps(inputJson, sort_keys=True, indent=4, separators=(',', ':'))) \ No newline at end of file diff --git a/ink/contracts/dapp_staking/lib.rs b/ink/contracts/dapp_staking/lib.rs new file mode 100644 index 0000000..630a0ef --- /dev/null +++ b/ink/contracts/dapp_staking/lib.rs @@ -0,0 +1,171 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +#[ink::contract] +pub mod lotto_dapp_staking { + + type AccountId20 = [u8; 20]; + + /// Event emitted when ownership is transferred + #[ink(event)] + pub struct OwnershipTransferred { + #[ink(topic)] + contract: AccountId, + previous: Option, + new: Option, + } + + #[ink(event)] + pub struct ILoveAstar { + #[ink(topic)] + sender: AccountId, + } + + #[ink(event)] + pub struct ILoveLucky { + #[ink(topic)] + sender: AccountId, + } + + /// Errors occurred in the contract + #[derive(Debug, Eq, PartialEq, scale::Encode, scale::Decode)] + #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] + pub enum ContractError { + CallerIsNotOwner, + NewOwnerIsNotSet, + } + + /// Contract storage + #[ink(storage)] + #[derive(Default)] + pub struct Contract { + pub owner: Option, + pub substrate_address: Option, + pub zk_evm_address: Option, + } + + impl Contract { + #[ink(constructor)] + pub fn new() -> Self { + let mut instance = Self::default(); + let caller = instance.env().caller(); + // set the owner of this contract + instance.inner_set_ownership(Some(caller)); + instance + } + + #[ink(message)] + pub fn owner(&self) -> Option { + self.owner + } + + #[ink(message)] + pub fn renounce_ownership(&mut self) -> Result<(), ContractError> { + // check caller is the owner + self.ensure_owner()?; + // remove owner + self.inner_set_ownership(None); + Ok(()) + } + + #[ink(message)] + pub fn transfer_ownership( + &mut self, + new_owner: Option, + ) -> Result<(), ContractError> { + // check caller is the owner + self.ensure_owner()?; + // check the new owner is set + if new_owner.is_none() { + return Err(ContractError::NewOwnerIsNotSet); + } + // set the new owner + self.inner_set_ownership(new_owner); + Ok(()) + } + + fn ensure_owner(&self) -> Result<(), ContractError> { + if self.owner != Some(self.env().caller()) { + return Err(ContractError::CallerIsNotOwner); + } + Ok(()) + } + + fn inner_set_ownership(&mut self, new_owner: Option) { + let old_owner = self.owner; + self.owner = new_owner; + // emit an event + self.env().emit_event(OwnershipTransferred { + contract: self.env().account_id(), + previous: old_owner, + new: new_owner, + }); + } + + #[ink(message)] + pub fn set_code(&mut self, code_hash: Hash) -> Result<(), ContractError> { + // check caller is the owner + self.ensure_owner()?; + + self.env().set_code_hash(&code_hash).unwrap_or_else(|err| { + panic!( + "Failed to `set_code_hash` to {:?} due to {:?}", + code_hash, err + ) + }); + + Ok(()) + } + + #[ink(message)] + pub fn set_substrate_address(&mut self, address: AccountId) -> Result<(), ContractError> { + // check caller is the owner + self.ensure_owner()?; + // set the address + self.substrate_address = Some(address); + Ok(()) + } + + #[ink(message)] + pub fn get_substrate_address(&mut self) -> Option { + self.substrate_address + } + + #[ink(message)] + pub fn lotto_is_deployed_on_astar_substrate(&mut self) -> bool { + self.substrate_address.is_some() + } + + #[ink(message)] + pub fn set_zk_evm_address(&mut self, address: AccountId20) -> Result<(), ContractError> { + // check caller is the owner + self.ensure_owner()?; + // set the address + self.zk_evm_address = Some(address); + Ok(()) + } + + #[ink(message)] + pub fn get_zk_evm_address(&mut self) -> Option { + self.zk_evm_address + } + + #[ink(message)] + pub fn lotto_is_deployed_on_astar_zk_evm(&mut self) -> bool { + self.zk_evm_address.is_some() + } + + #[ink(message)] + pub fn send_love_to_astar(&mut self) { + self.env().emit_event(ILoveAstar { + sender: self.env().caller(), + }); + } + + #[ink(message)] + pub fn send_love_to_lucky(&mut self) { + self.env().emit_event(ILoveLucky { + sender: self.env().caller(), + }); + } + } +} diff --git a/ink/contracts/dapp_staking/rust-toolchain.toml b/ink/contracts/dapp_staking/rust-toolchain.toml new file mode 100644 index 0000000..1feced0 --- /dev/null +++ b/ink/contracts/dapp_staking/rust-toolchain.toml @@ -0,0 +1,11 @@ +[toolchain] +channel = "1.77.2" +components = [ + "rustc", + "cargo", + "rustfmt", + "rust-src", + "clippy", +] +targets = ["wasm32-unknown-unknown"] +profile = "minimal"