-
Notifications
You must be signed in to change notification settings - Fork 27
PoW Cw721 #697
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
PoW Cw721 #697
Changes from 10 commits
e11d97b
c8953e6
6e9ea18
dde31a6
feb0aa6
59f3110
b3682d1
c053ef6
bee0921
9771873
9437432
309cf93
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| [alias] | ||
| wasm = "build --release --target wasm32-unknown-unknown" | ||
| unit-test = "test --lib" | ||
| schema = "run --example schema" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| [package] | ||
| name = "andromeda-pow-cw721" | ||
| version = "0.1.0-beta" | ||
| authors = ["Mitar Djakovic <[email protected]>"] | ||
| edition = "2021" | ||
| rust-version = "1.75.0" | ||
|
|
||
| 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. | ||
| "contract.wasm", | ||
| "hash.txt", | ||
| ] | ||
|
|
||
| # 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 = [] | ||
| testing = ["cw-multi-test", "andromeda-testing"] | ||
|
|
||
|
|
||
| [dependencies] | ||
| cosmwasm-std = { workspace = true } | ||
| cosmwasm-schema = { workspace = true } | ||
| cw-storage-plus = { workspace = true } | ||
| cw-utils = { workspace = true } | ||
| cw721 = { workspace = true } | ||
| cw721-base = { workspace = true } | ||
| sha2 = { version = "0.10.8" } | ||
| test-case = { workspace = true } | ||
| # hex = { version = "0.4.3" } | ||
|
|
||
| andromeda-std = { workspace = true } | ||
| andromeda-non-fungible-tokens = { workspace = true } | ||
|
|
||
| [target.'cfg(not(target_arch = "wasm32"))'.dependencies] | ||
| cw-multi-test = { workspace = true, optional = true } | ||
| andromeda-testing = { workspace = true, optional = true } | ||
| cw-orch = { workspace = true } | ||
| # cw-orch-daemon = "0.24.2" | ||
|
|
||
| [dev-dependencies] | ||
| andromeda-app = { workspace = true } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| use andromeda_non_fungible_tokens::pow_cw721::{ExecuteMsg, InstantiateMsg, QueryMsg}; | ||
| use cosmwasm_schema::write_api; | ||
|
|
||
| fn main() { | ||
| write_api! { | ||
| instantiate: InstantiateMsg, | ||
| query: QueryMsg, | ||
| execute: ExecuteMsg | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| #[cfg(not(feature = "library"))] | ||
| use cosmwasm_std::entry_point; | ||
| use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError}; | ||
|
|
||
| use andromeda_non_fungible_tokens::pow_cw721::{ExecuteMsg, InstantiateMsg, QueryMsg}; | ||
| use andromeda_std::{ | ||
| ado_base::{ | ||
| permissioning::{LocalPermission, Permission}, | ||
| InstantiateMsg as BaseInstantiateMsg, MigrateMsg, | ||
| }, | ||
| ado_contract::ADOContract, | ||
| common::{context::ExecuteContext, encode_binary}, | ||
| error::ContractError, | ||
| }; | ||
|
|
||
| use crate::execute::handle_execute; | ||
| use crate::query::{query_linked_cw721_address, query_pow_nft}; | ||
| use crate::state::LINKED_CW721_ADDRESS; | ||
|
|
||
| const CONTRACT_NAME: &str = "crates.io:andromeda-pow-cw721"; | ||
| const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); | ||
|
|
||
| pub const MINT_POW_NFT_ACTION: &str = "MINT_POW_NFT"; | ||
|
|
||
| #[cfg_attr(not(feature = "library"), entry_point)] | ||
| pub fn instantiate( | ||
| deps: DepsMut, | ||
| env: Env, | ||
| info: MessageInfo, | ||
| msg: InstantiateMsg, | ||
| ) -> Result<Response, ContractError> { | ||
| let inst_resp = ADOContract::default().instantiate( | ||
| deps.storage, | ||
| env.clone(), | ||
| deps.api, | ||
| &deps.querier, | ||
| info, | ||
| BaseInstantiateMsg { | ||
| ado_type: CONTRACT_NAME.to_string(), | ||
| ado_version: CONTRACT_VERSION.to_string(), | ||
| kernel_address: msg.kernel_address, | ||
| owner: msg.owner, | ||
| }, | ||
mdjakovic0920 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| )?; | ||
|
|
||
| LINKED_CW721_ADDRESS.save(deps.storage, &msg.linked_cw721_address)?; | ||
|
|
||
| // Set mint PoW NFT action permission | ||
| if let Some(authorized_origin_minter_addresses) = msg.authorized_origin_minter_addresses { | ||
| if !authorized_origin_minter_addresses.is_empty() { | ||
| ADOContract::default().permission_action(MINT_POW_NFT_ACTION, deps.storage)?; | ||
| } | ||
|
|
||
| for origin_minter_address in authorized_origin_minter_addresses { | ||
| let addr = origin_minter_address.get_raw_address(&deps.as_ref())?; | ||
| ADOContract::set_permission( | ||
| deps.storage, | ||
| MINT_POW_NFT_ACTION, | ||
| addr, | ||
| Permission::Local(LocalPermission::Whitelisted(None)), | ||
| )?; | ||
| } | ||
| } | ||
|
|
||
| Ok(inst_resp) | ||
| } | ||
|
|
||
| #[cfg_attr(not(feature = "library"), entry_point)] | ||
| pub fn execute( | ||
| deps: DepsMut, | ||
| env: Env, | ||
| info: MessageInfo, | ||
| msg: ExecuteMsg, | ||
| ) -> Result<Response, ContractError> { | ||
| let ctx = ExecuteContext::new(deps, info, env); | ||
| match msg { | ||
| ExecuteMsg::AMPReceive(pkt) => { | ||
| ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) | ||
| } | ||
| _ => handle_execute(ctx, msg), | ||
| } | ||
| } | ||
|
|
||
| #[cfg_attr(not(feature = "library"), entry_point)] | ||
| pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result<Binary, ContractError> { | ||
| match msg { | ||
| QueryMsg::GetPowNFT { token_id } => encode_binary(&query_pow_nft(deps, token_id)?), | ||
| QueryMsg::GetLinkedCw721Address {} => encode_binary(&query_linked_cw721_address(deps)?), | ||
| _ => ADOContract::default().query(deps, env, msg), | ||
| } | ||
| } | ||
|
|
||
| #[cfg_attr(not(feature = "library"), entry_point)] | ||
| pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, ContractError> { | ||
| if msg.result.is_err() { | ||
| return Err(ContractError::Std(StdError::generic_err( | ||
| msg.result.unwrap_err(), | ||
| ))); | ||
| } | ||
|
|
||
| Ok(Response::default()) | ||
| } | ||
|
|
||
| #[cfg_attr(not(feature = "library"), entry_point)] | ||
| pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> { | ||
| ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,187 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use andromeda_non_fungible_tokens::{ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| cw721::{ExecuteMsg as AndrCw721ExecuteMsg, TokenExtension}, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pow_cw721::{ExecuteMsg, PowNFTInfo}, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use andromeda_std::{ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ado_contract::ADOContract, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| amp::AndrAddr, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| common::{actions::call_action, context::ExecuteContext, encode_binary}, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| error::ContractError, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use cosmwasm_std::{Binary, CosmosMsg, Event, Response, WasmMsg}; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use sha2::{Digest, Sha256}; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::contract::MINT_POW_NFT_ACTION; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::state::{LINKED_CW721_ADDRESS, POW_NFT}; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result<Response, ContractError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let action_response = call_action( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| &mut ctx.deps, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| &ctx.info, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| &ctx.env, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| &ctx.amp_ctx, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| msg.as_ref(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| )?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
mdjakovic0920 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| let res = match msg { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ExecuteMsg::MintPowNFT { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| owner, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| token_id, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| token_uri, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| extension, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| base_difficulty, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } => execute_mint_pow_nft(ctx, owner, token_id, token_uri, extension, base_difficulty), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ExecuteMsg::SubmitProof { token_id, solution } => { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| execute_submit_proof(ctx, token_id, solution) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| _ => ADOContract::default().execute(ctx, msg), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(res | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .add_submessages(action_response.messages) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .add_attributes(action_response.attributes) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .add_events(action_response.events)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| fn execute_mint_pow_nft( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| mut ctx: ExecuteContext, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| owner: AndrAddr, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| token_id: String, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| token_uri: Option<String>, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| extension: TokenExtension, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| base_difficulty: u64, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Result<Response, ContractError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||
mdjakovic0920 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if base_difficulty == 0 || base_difficulty > 128 { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return Err(ContractError::CustomError { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| msg: "Base difficulty must be between 1 and 128".to_string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| let sender = ctx.info.sender; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| ADOContract::default().is_permissioned( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ctx.deps.branch(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ctx.env.clone(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| MINT_POW_NFT_ACTION, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| sender.clone(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| )?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if POW_NFT | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .may_load(ctx.deps.storage, token_id.clone())? | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .is_some() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return Err(ContractError::CustomError { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| msg: format!("Token ID {} already exists", token_id), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| let owner_addr = owner.get_raw_address(&ctx.deps.as_ref())?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let cw721_address = LINKED_CW721_ADDRESS.load(ctx.deps.storage)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
mdjakovic0920 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| let addr = cw721_address | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .get_raw_address(&ctx.deps.as_ref())? | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .to_string(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let mint_msg = CosmosMsg::Wasm(WasmMsg::Execute { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| contract_addr: addr, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| msg: encode_binary(&AndrCw721ExecuteMsg::Mint { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| token_id: token_id.clone(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| owner: owner_addr.to_string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| token_uri, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| extension, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| })?, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| funds: vec![], | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| let block_height = ctx.env.block.height; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut hasher = Sha256::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| hasher.update(block_height.to_be_bytes()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let last_hash = hasher.finalize().to_vec(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
mdjakovic0920 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| let pow_nft_info = PowNFTInfo { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| owner: owner_addr, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| level: 1_u64, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| last_hash: Binary(last_hash), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| difficulty: base_difficulty, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| POW_NFT.save(ctx.deps.storage, token_id, &pow_nft_info)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(Response::new() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .add_message(mint_msg) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .add_attribute("method", "mint_pow_nft") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .add_attribute("sender", sender)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| fn execute_submit_proof( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ctx: ExecuteContext, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| token_id: String, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| solution: u128, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Result<Response, ContractError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let sender = ctx.info.sender; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut pow_nft = POW_NFT | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .load(ctx.deps.storage, token_id.clone()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .map_err(|_| ContractError::NFTNotFound {})?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
mdjakovic0920 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut hasher = Sha256::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| hasher.update(&pow_nft.last_hash); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| hasher.update(&solution.to_be_bytes()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let hash = hasher.finalize(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| let hash_value = u128::from_be_bytes(hash[0..16].try_into().unwrap()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let threshold = u128::MAX >> (pow_nft.difficulty as u32); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+131
to
+133
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Handle potential panics when converting hash bytes to The use of Apply this diff to handle the error: let hash_value = u128::from_be_bytes(hash[0..16].try_into().unwrap());
+// Change to:
+let hash_value = u128::from_be_bytes(hash[0..16].try_into().map_err(|_| ContractError::CustomError {
+ msg: "Failed to convert hash bytes to u128.".to_string(),
+})?);
mdjakovic0920 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if hash_value > threshold { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return Err(ContractError::CustomError { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| msg: "Proof does not meet difficulty".to_string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| pow_nft.difficulty = if pow_nft.difficulty >= 2 { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let next_difficulty = (pow_nft.difficulty as f64 * 1.5) as u64; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if next_difficulty > 128 { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return Err(ContractError::CustomError { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| msg: format!( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "Max difficulty is 128. Next difficulty will be over 128. Current level: {:?}", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pow_nft.level | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| next_difficulty | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+140
to
+151
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid using floating-point arithmetic in smart contracts. The difficulty adjustment uses floating-point arithmetic, which can lead to non-deterministic behavior and precision issues in smart contracts. It's recommended to use integer arithmetic to ensure deterministic and precise calculations. Apply this diff to adjust the difficulty calculation: pow_nft.difficulty = if pow_nft.difficulty >= 2 {
- let next_difficulty = (pow_nft.difficulty as f64 * 1.5) as u64;
+ let next_difficulty = pow_nft.difficulty * 3 / 2;
if next_difficulty > 128 {
return Err(ContractError::CustomError {
msg: format!(This change replaces the floating-point multiplication with integer arithmetic, ensuring consistent behavior across different platforms. 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| 2 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| pow_nft.level += 1; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| let block_height = ctx.env.block.height; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let nonce = ctx | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .env | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .transaction | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .ok_or_else(|| ContractError::CustomError { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| msg: "Transaction info not available".to_string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| })?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut hasher = Sha256::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| hasher.update(&pow_nft.last_hash); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| hasher.update(&solution.to_be_bytes()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| hasher.update(&block_height.to_be_bytes()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| hasher.update(&nonce.index.to_be_bytes()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let hash = hasher.finalize(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pow_nft.last_hash = Binary(hash.to_vec()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| POW_NFT.save(ctx.deps.storage, token_id.clone(), &pow_nft)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(Response::new() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .add_attribute("method", "submit_proof") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .add_attribute("sender", sender) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .add_attribute("token_id", token_id.clone()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .add_attribute("new_level", pow_nft.level.to_string()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .add_attribute("new_difficulty", pow_nft.difficulty.to_string()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .add_event( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Event::new("pow_nft_level_up") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .add_attribute("token_id", token_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .add_attribute("new_level", pow_nft.level.to_string()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .add_attribute("new_difficulty", pow_nft.difficulty.to_string()), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| )) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.