-
Notifications
You must be signed in to change notification settings - Fork 0
precompile erc 721 only owner_of #104
Changes from all commits
8a0bc02
0fe9a63
7ebabef
e964668
aba874e
80dd172
9604f6c
390359b
64c449a
5dafd9f
e92faae
21d6842
e06adce
3869690
d514f88
2efff92
0357938
cec3cbf
b0c10ce
1420c21
d0c4ce7
aa84dde
7e49dae
0ec72a7
9be1a5b
2427e0d
4625aad
d858bf0
6c65ddd
1c9e12a
c7ec2ee
c39efbd
9dc0c14
b9bba2d
a39432c
c4cd42f
89af0a0
c6c7810
5cfb2b5
fa612ab
0568c47
b31f1db
9a4f100
09738af
daf2910
bd47de2
907ca7e
10557aa
6d38abe
daef051
f71eef7
15123db
4b0ec80
df59324
2fbd144
96d7374
5bf67b0
2bf2171
9e1bf8d
88e1314
2aa2681
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,15 +4,19 @@ | |
| /// Learn more about FRAME and the core library of Substrate FRAME pallets: | ||
| /// <https://docs.substrate.io/reference/frame-pallets/> | ||
| pub use pallet::*; | ||
| use sp_core::H160; | ||
|
|
||
| mod functions; | ||
| pub mod traits; | ||
|
|
||
| #[frame_support::pallet] | ||
| pub mod pallet { | ||
| use crate::functions::convert_asset_id_to_owner; | ||
|
|
||
| use super::*; | ||
| use frame_support::pallet_prelude::{OptionQuery, ValueQuery, *}; | ||
| use frame_system::pallet_prelude::*; | ||
| use sp_core::{H160, U256}; | ||
|
|
||
| /// Collection id type | ||
| /// TODO: use 256 bits | ||
|
|
@@ -83,6 +87,89 @@ pub mod pallet { | |
| Self::do_create_collection(owner) | ||
| } | ||
| } | ||
|
|
||
| impl<T: Config> traits::Erc721 for Pallet<T> { | ||
| fn owner_of(collection_id: CollectionId, asset_id: U256) -> Result<H160, &'static str> { | ||
| match OwnerOfCollection::<T>::get(collection_id) { | ||
| Some(_) => Ok(convert_asset_id_to_owner(asset_id)), | ||
| None => Err("Collection does not exist"), | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// `ASSET_PRECOMPILE_ADDRESS_PREFIX` is a predefined prefix used to identify collection addresses. | ||
| /// | ||
| /// All addresses that start with this prefix are considered as collection addresses. | ||
| /// Since `CollectionId` is represented as a `u64`, it leaves these bits free to be | ||
| /// utilized for such a prefix. | ||
| /// | ||
| /// Usage of this prefix provides a consistent and recognizable pattern for distinguishing | ||
| /// collection addresses from other types of addresses in the system. | ||
| pub const ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[0xff; 12]; | ||
|
|
||
| /// Enum representing possible errors related to collections. | ||
| #[derive(Debug, PartialEq)] | ||
| pub enum CollectionError { | ||
| /// Error indicating that the provided address does not have the correct prefix. | ||
| InvalidPrefix, | ||
| } | ||
|
|
||
| /// Converts a `CollectionId` into an `H160` address format. | ||
| /// | ||
| /// This function takes the given `CollectionId`, which is assumed to be a `u64`, | ||
| /// and maps it into an `H160` address, prepending it with the `ASSET_PRECOMPILE_ADDRESS_PREFIX`. | ||
| /// | ||
| /// # Arguments | ||
| /// | ||
| /// * `collection_id`: The ID of the collection to be converted. | ||
| /// | ||
| /// # Returns | ||
| /// | ||
| /// * An `H160` representation of the collection ID. | ||
| pub fn collection_id_to_address(collection_id: CollectionId) -> H160 { | ||
|
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. this is really unidiomatic for Rust and Substrate, generally. Either create a trait for all these functions, sth like they are also missing comments
Member
Author
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. it'll be adressed : #116 |
||
| let mut bytes = [0u8; 20]; | ||
| bytes[12..20].copy_from_slice(&collection_id.to_be_bytes()); | ||
| for (i, byte) in ASSET_PRECOMPILE_ADDRESS_PREFIX.iter().enumerate() { | ||
| bytes[i] = *byte; | ||
| } | ||
| H160(bytes) | ||
| } | ||
|
|
||
| /// Converts an `H160` address into a `CollectionId` format. | ||
| /// | ||
| /// This function takes the given `H160` address, checks for the correct prefix, and extracts | ||
| /// the `CollectionId` from it. If the prefix is incorrect, it returns a `CollectionError::InvalidPrefix` error. | ||
| /// | ||
| /// # Arguments | ||
| /// | ||
| /// * `address`: The `H160` address to be converted. | ||
| /// | ||
| /// # Returns | ||
| /// | ||
| /// * A `Result` which is either the `CollectionId` or an error indicating the address is invalid. | ||
| pub fn address_to_collection_id(address: H160) -> Result<CollectionId, CollectionError> { | ||
| if &address.0[0..12] != ASSET_PRECOMPILE_ADDRESS_PREFIX { | ||
| return Err(CollectionError::InvalidPrefix); | ||
| } | ||
| let id_bytes: [u8; 8] = address.0[12..].try_into().unwrap(); | ||
| Ok(CollectionId::from_be_bytes(id_bytes)) | ||
| } | ||
|
|
||
| /// Checks if a given `H160` address is a collection address. | ||
| /// | ||
| /// This function examines the prefix of the given `H160` address to determine if it is a | ||
| /// collection address, based on the `ASSET_PRECOMPILE_ADDRESS_PREFIX`. | ||
| /// | ||
| /// # Arguments | ||
| /// | ||
| /// * `address`: The `H160` address to be checked. | ||
| /// | ||
| /// # Returns | ||
| /// | ||
| /// * A boolean indicating if the address is a collection address. | ||
| pub fn is_collection_address(address: H160) -> bool { | ||
| &address.to_fixed_bytes()[0..12] == ASSET_PRECOMPILE_ADDRESS_PREFIX | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -1,3 +1,5 @@ | ||||||||
| use sp_core::{H160, U256}; | ||||||||
|
|
||||||||
| use crate::CollectionId; | ||||||||
|
|
||||||||
| /// The `CollectionManager` trait provides an interface for managing collections in a | ||||||||
|
|
@@ -25,3 +27,22 @@ pub trait CollectionManager<AccountId> { | |||||||
| /// Create collection | ||||||||
| fn create_collection(owner: AccountId) -> Result<CollectionId, &'static str>; | ||||||||
| } | ||||||||
|
|
||||||||
|
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. documentation
Member
Author
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. sgtm 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. it is missing documentation. you can use the comments to leave |
||||||||
| /// `Erc721` Trait | ||||||||
| /// | ||||||||
| /// This trait provides an interface for handling ERC721 tokens, a standard for non-fungible tokens on the blockchain. | ||||||||
| pub trait Erc721 { | ||||||||
| /// Retrieves the owner of a specific asset in a collection. | ||||||||
| /// | ||||||||
| /// # Parameters | ||||||||
| /// | ||||||||
| /// * `collection_id`: An identifier for the collection to which the asset belongs. | ||||||||
| /// * `asset_id`: The unique identifier for the asset within the specified collection. | ||||||||
| /// | ||||||||
| /// # Returns | ||||||||
| /// | ||||||||
| /// * A `Result` which is: | ||||||||
| /// - `Ok(H160)`: Returns the Ethereum address (`H160`) of the owner of the asset. | ||||||||
| /// - `Err(&'static str)`: Returns an error message if the asset owner could not be determined. | ||||||||
| fn owner_of(collection_id: CollectionId, asset_id: U256) -> Result<H160, &'static str>; | ||||||||
|
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. also forgot to mention that it's not a good practice to use
Member
Author
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. yes totally agree.
Member
Author
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. it will be addressed here : #116 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.
Suggested change
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. sth like this
Member
Author
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. |
||||||||
| } | ||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| [package] | ||
| name = "pallet-evm-erc721" | ||
| version = "0.0.1" | ||
| edition = "2021" | ||
|
|
||
| [dependencies] | ||
| parity-scale-codec = { workspace = true, features = [ | ||
| "derive", | ||
| ] } | ||
| scale-info = { workspace = true, features = [ | ||
| "derive", | ||
| ] } | ||
|
|
||
| # Frontier | ||
| fp-evm = { workspace = true } | ||
| pallet-evm = { workspace = true } | ||
|
|
||
| # Substrate | ||
| frame-support = { workspace = true } | ||
| sp-arithmetic = { workspace = true } | ||
| sp-core = { workspace = true } | ||
| sp-runtime = { workspace = true } | ||
| sp-std = { workspace = true } | ||
|
|
||
| # Local pallet | ||
| pallet-living-assets-ownership = { workspace = true } | ||
|
|
||
| # Utils | ||
| precompile-utils = { workspace = true } | ||
| precompile-utils-macro = { workspace = true } | ||
|
|
||
| num_enum = { workspace = true } | ||
|
|
||
| [dev-dependencies] | ||
| evm = { workspace = true } | ||
| hex = { version = "0.4.3" } | ||
| precompile-utils = { workspace = true, features = ["testing"]} | ||
|
|
||
| [features] | ||
| default = ["std"] | ||
| std = [ | ||
| # Frontier | ||
| "fp-evm/std", | ||
| "pallet-evm/std", | ||
| "sp-core/std", | ||
| "sp-runtime/std", | ||
| "sp-std/std", | ||
| "pallet-living-assets-ownership/std", | ||
| "num_enum/std", | ||
| "frame-support/std", | ||
| "sp-arithmetic/std", | ||
| "precompile-utils/std", | ||
| "parity-scale-codec/std", | ||
| "scale-info/std", | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| // derived from OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) | ||
| pragma solidity >=0.8.3; | ||
|
|
||
| interface IERC721 { | ||
| /** | ||
| * @dev See {IERC721Metadata-tokenURI}. | ||
| */ | ||
| function tokenURI(uint256 _tokenId) external view returns (string memory); | ||
|
|
||
| function ownerOf(uint256 _tokenId) external view returns (address); | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.