-
Notifications
You must be signed in to change notification settings - Fork 2
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
CEP-78 #410
CEP-78 #410
Changes from all commits
31aef8b
c00f941
17bd2e8
70bf5f2
abc8b1d
116987e
4eccc45
f4b17b3
4aca069
ca7e6a7
637fdbe
e5d7166
00cdaee
2949e1b
039e933
facb85c
961f3c1
24fa20e
af5e8e5
622ac03
3865982
f9f740e
32489d4
dd33780
bd86080
0aef4cb
297bb72
5aadae9
958dd73
7aae548
ff35352
acd62a9
958a817
7dda987
67c04cf
a777639
f561155
9be2222
f653b6e
29adf33
08e3f49
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,7 +49,7 @@ pub trait ContractContext { | |
/// | ||
/// * `dictionary_name` - The name of the dictionary. | ||
/// * `key` - The key to retrieve the value for. | ||
fn get_dictionary_value(&self, dictionary_name: &str, key: &str) -> Option<Bytes>; | ||
fn get_dictionary_value(&self, dictionary_name: &str, key: &[u8]) -> Option<Bytes>; | ||
|
||
/// Sets the key value behind a named dictionary. | ||
/// | ||
|
@@ -58,7 +58,13 @@ pub trait ContractContext { | |
/// * `dictionary_name` - The name of the dictionary. | ||
/// * `key` - The key to set the value for. | ||
/// * `value` - The value to set. | ||
fn set_dictionary_value(&self, dictionary_name: &str, key: &str, value: CLValue); | ||
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. Why only changed in dictionaries, what about named keys? |
||
fn set_dictionary_value(&self, dictionary_name: &str, key: &[u8], value: CLValue); | ||
|
||
/// Removes the named key from the storage. | ||
/// | ||
/// # Arguments | ||
/// * `dictionary_name` - The name of the dictionary. | ||
fn remove_dictionary(&self, dictionary_name: &str); | ||
|
||
/// Retrieves the address of the caller. | ||
fn caller(&self) -> Address; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -104,13 +104,12 @@ impl ContractEnv { | |
} | ||
|
||
/// Retrieves the value associated with the given named key from the named dictionary in the contract storage. | ||
pub fn get_dictionary_value<T: FromBytes + CLTyped, U: AsRef<str>, V: AsRef<str>>( | ||
pub fn get_dictionary_value<T: FromBytes + CLTyped, U: AsRef<str>>( | ||
&self, | ||
dictionary_name: U, | ||
key: V | ||
key: &[u8] | ||
) -> Option<T> { | ||
let dictionary_name = dictionary_name.as_ref(); | ||
let key = key.as_ref(); | ||
let bytes = self | ||
.backend | ||
.borrow() | ||
|
@@ -123,14 +122,13 @@ impl ContractEnv { | |
} | ||
|
||
/// Sets the value associated with the given named key in the named dictionary in the contract storage. | ||
pub fn set_dictionary_value<T: CLTyped + ToBytes, U: AsRef<str>, V: AsRef<str>>( | ||
pub fn set_dictionary_value<T: CLTyped + ToBytes, U: AsRef<str>>( | ||
&self, | ||
dictionary_name: U, | ||
key: V, | ||
key: &[u8], | ||
Comment on lines
+125
to
+128
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. Tip Codebase Verification The examination of the
Given these observations, the error handling for Recommendation: Review the error handling strategies used in different environments for
Analysis chainEnsure consistent error handling for Scripts ExecutedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Description: Verify consistent error handling for `set_dictionary_value` across the project.
# Test: Search for the function usage. Expect: Consistent error handling.
rg --type rust $'set_dictionary_value'
Length of output: 1715 Script: #!/bin/bash
# Description: Examine the implementations and usages of `set_dictionary_value` to verify error handling.
# Search for the function implementations and their surrounding code to check error handling mechanisms.
rg --type rust -C 10 "fn set_dictionary_value"
# Search for usages of `set_dictionary_value` and check how errors are handled or propagated.
rg --type rust -C 10 "set_dictionary_value\("
Length of output: 27173 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. DEEP RABBIT 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. @kubaplas, it seems like my previous message might have come as a surprise! If there's any part of the analysis you'd like to discuss further or if you have specific questions about the error handling strategies in different environments, feel free to let me know. I'm here to help! |
||
value: T | ||
) { | ||
let dictionary_name = dictionary_name.as_ref(); | ||
let key = key.as_ref(); | ||
let cl_value = CLValue::from_t(value) | ||
.map_err(|_| Formatting) | ||
.unwrap_or_revert(self); | ||
|
@@ -139,6 +137,12 @@ impl ContractEnv { | |
.set_dictionary_value(dictionary_name, key, cl_value); | ||
} | ||
|
||
/// Removes the dictionary from the contract storage. | ||
pub fn remove_dictionary<U: AsRef<str>>(&self, dictionary_name: U) { | ||
let dictionary_name = dictionary_name.as_ref(); | ||
self.backend.borrow().remove_dictionary(dictionary_name); | ||
} | ||
Comment on lines
+140
to
+144
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. Tip Codebase Verification The investigation into the
These differences seem justified based on the specific needs and contexts of each module. Therefore, while the implementations are not identical, they are consistent in purpose and adapted to their respective environments. Analysis chainVerify that Scripts ExecutedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Description: Verify consistent implementation of `remove_dictionary` across different modules.
# Test: Search for the function usage. Expect: Consistent implementation.
rg --type rust $'remove_dictionary'
Length of output: 1254 |
||
|
||
/// Returns the address of the caller of the contract. | ||
pub fn caller(&self) -> Address { | ||
let backend = self.backend.borrow(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
//! Deploys a CEP-78 contract, mints an nft token and transfers it to another address. | ||
use std::str::FromStr; | ||
|
||
use odra::args::Maybe; | ||
use odra::casper_types::U256; | ||
use odra::host::{Deployer, HostEnv, HostRef, HostRefLoader}; | ||
use odra::Address; | ||
use odra_modules::cep78::modalities::{ | ||
EventsMode, MetadataMutability, NFTIdentifierMode, NFTKind, NFTMetadataKind, OwnershipMode | ||
}; | ||
use odra_modules::cep78::token::{Cep78HostRef, Cep78InitArgs}; | ||
use odra_modules::cep78::utils::InitArgsBuilder; | ||
|
||
const CEP78_METADATA: &str = r#"{ | ||
"name": "John Doe", | ||
"token_uri": "https://www.barfoo.com", | ||
"checksum": "940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb" | ||
}"#; | ||
const CASPER_CONTRACT_ADDRESS: &str = | ||
"hash-d4b8fa492d55ac7a515c0c6043d72ba43c49cd120e7ba7eec8c0a330dedab3fb"; | ||
const ODRA_CONTRACT_ADDRESS: &str = | ||
"hash-3d35238431c5c6fa1d7df70d73bfc2efd5a03fd5af99ab8c7828a56b2f330274"; | ||
const RECIPIENT_ADDRESS: &str = | ||
"hash-7821386ecdda83ff100379a06558b69a675d5a170d1c5bf5fbe9fd35262d091f"; | ||
|
||
fn main() { | ||
let env = odra_casper_livenet_env::env(); | ||
|
||
// Deploy new contract. | ||
let mut token = deploy_contract(&env); | ||
println!("Token address: {}", token.address().to_string()); | ||
|
||
// Uncomment to load existing contract. | ||
// let mut token = load_contract(&env, CASPER_CONTRACT_ADDRESS); | ||
// println!("Token name: {}", token.get_collection_name()); | ||
|
||
env.set_gas(3_000_000_000u64); | ||
let owner = env.caller(); | ||
let recipient = | ||
Address::from_str(RECIPIENT_ADDRESS).expect("Should be a valid recipient address"); | ||
// casper contract may return a result or not, so deserialization may fail and it's better to use `try_transfer`/`try_mint`/`try_burn` methods | ||
let _ = token.try_mint(owner, CEP78_METADATA.to_string(), Maybe::None); | ||
println!("Owner's balance: {:?}", token.balance_of(owner)); | ||
println!("Recipient's balance: {:?}", token.balance_of(recipient)); | ||
let token_id = token.get_number_of_minted_tokens() - 1; | ||
let _ = token.try_transfer(Maybe::Some(token_id), Maybe::None, owner, recipient); | ||
|
||
println!("Owner's balance: {:?}", token.balance_of(owner)); | ||
println!("Recipient's balance: {:?}", token.balance_of(recipient)); | ||
} | ||
Comment on lines
+26
to
+50
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. Improve error handling and avoid hardcoded values. Consider enhancing the error handling around |
||
|
||
/// Loads a Cep78 contract. | ||
pub fn load_contract(env: &HostEnv, address: &str) -> Cep78HostRef { | ||
let address = Address::from_str(address).expect("Should be a valid contract address"); | ||
Cep78HostRef::load(env, address) | ||
} | ||
|
||
/// Deploys a Cep78 contract. | ||
pub fn deploy_contract(env: &HostEnv) -> Cep78HostRef { | ||
let name: String = String::from("PlascoinCollection with CES"); | ||
let symbol = String::from("CEP78-PLS-CES"); | ||
let receipt_name = String::from("PlascoinReceipt"); | ||
|
||
let init_args = InitArgsBuilder::default() | ||
.collection_name(name) | ||
.collection_symbol(symbol) | ||
.total_token_supply(1_000) | ||
.ownership_mode(OwnershipMode::Transferable) | ||
.nft_metadata_kind(NFTMetadataKind::CEP78) | ||
.identifier_mode(NFTIdentifierMode::Ordinal) | ||
.nft_kind(NFTKind::Digital) | ||
.metadata_mutability(MetadataMutability::Mutable) | ||
.receipt_name(receipt_name) | ||
.events_mode(EventsMode::CES) | ||
.build(); | ||
|
||
env.set_gas(400_000_000_000u64); | ||
Cep78HostRef::deploy(env, init_args) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure this works by running a livenet example of cep-18 against original contract implementation.