Skip to content
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

ERC721 URIstorage extension implementation #1019

Open
gerceboss opened this issue Jun 24, 2024 · 12 comments · May be fixed by #1031
Open

ERC721 URIstorage extension implementation #1019

gerceboss opened this issue Jun 24, 2024 · 12 comments · May be fixed by #1031

Comments

@gerceboss
Copy link

Hey , I recently needed to implement dynamic nfts in Cairo but oppenzepelin doesn't provide it as ERC721's extension they do in solidity.
I have implemented dynamic nft myself in the project .

Would like to work on implementing
ERC721URIstorage extension.

@andrew-fleming
Copy link
Collaborator

Hey, @gerceboss! Thanks for opening this issue. I think this would be a great addition to the library! We'd be happy to review and support a PR :)

@gerceboss
Copy link
Author

Hey @andrew-fleming , can you guide a bit on how the structure must be? How and in which files should I structure the component ?

@andrew-fleming
Copy link
Collaborator

can you guide a bit on how the structure must be?

Sure!

How and in which files should I structure the component ?

Regarding which files, I'd say the structure should be something like this:

token
  └── erc721
        ├── extensions.cairo
        └── extensions
                └── erc721_uri_storage.cairo (component in here)

Regarding how the component itself should be structured, you can take a look at how the erc20_votes extension is defined as a template. I imagine the component should define a URIStorage implementation of IERC721Metadata with the new token_uri behavior as well as an InternalImpl with set_token_uri

@gerceboss
Copy link
Author

Okay,great !! Will do that

@gerceboss
Copy link
Author

@andrew-fleming, can you please confirm the tests that will be needed for this extension? And also suggest other tests than these?

  1. test_initialiser()
  2. test_set_token_uri()
  3. test_token_uri()

@andrew-fleming
Copy link
Collaborator

Hey, @gerceboss. Yes to those tests. Assuming the extension behaves like the OZ Solidity implementation, you can use the Solidity tests as a guide: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/test/token/ERC721/extensions/ERC721URIStorage.test.js

@gerceboss
Copy link
Author

@andrew-fleming , while testing, there is a problem as the branch I pushed the changes on my forked repository is different, it does not resolves and throws this error:

error: Identifier not found.
use openzeppelin::tests::mocks::erc721_uri_storage_mocks::ERC721URIstorageMock;
                                ^**********************^

error: Identifier not found.
use openzeppelin::token::erc721::extensions::ERC721URIstorageComponent;
                                 ^********^

Can you help on how I run the tests?

@andrew-fleming
Copy link
Collaborator

andrew-fleming commented Jun 28, 2024

It's hard to identify without seeing the code. Did you make them visible by adding:

  • pub(crate) mod erc721_uri_storage_mocks; to tests/mocks.cairo?
  • pub mod extensions; to token/erc721.cairo?

If this isn't it, kindly link your branch and I'll take a look

@gerceboss
Copy link
Author

Hey @andrew-fleming,

    impl ERC721URIstorage<
        TContractState,
        +HasComponent<TContractState>,
        +SRC5Component::HasComponent<TContractState>,
        +ERC721Component::HasComponent<TContractState>,
        +Drop<TContractState>
    > of IERC721URIstorage<ComponentState<TContractState>> {

I currently implement the functionality like this and the IERC721URIstorage implements following:

    fn name(self: @TState) -> ByteArray;
    fn symbol(self: @TState) -> ByteArray;
    fn token_uri(self: @TState,token_id:u256)->ByteArray;(changed implementation)
    fn set_token_uri(ref self: TState,token_id:u256,_token_uri:ByteArray);

I am stuck on how I implement the name and the symbol functionalities.

@andrew-fleming
Copy link
Collaborator

Hey! You can use get_dep_component! to read from dependencies:

    impl ERC721URIStorage<
        ...
        impl ERC721: ERC721Component::HasComponent<TContractState>
    > of IERC721Metadata<ComponentState<TContractState>> {
        fn name(self: @ComponentState<TContractState>) -> ByteArray {
            let erc721 = get_dep_component!(self, ERC721);
            erc721.ERC721_name.read()
        }
        ...
    }

Also, I'm not sure we need a new interface for URI storage. We're just adding an implementation of IERC721Metadata

@gerceboss gerceboss reopened this Jul 1, 2024
@andrew-fleming
Copy link
Collaborator

Should we? If a project wants this to be an external fn, they can create an external fn in the contract itself and implement whatever permissions with it. That's a very specific case and as a library, I don't think that's for us to do. The URI storage extension should just support storing and reading a unique URI per token. Generally, URIs are set when they're minted

@gerceboss
Copy link
Author

gerceboss commented Jul 1, 2024

@andrew-fleming ,I have implemented the tests and included the mock contract and the test file in the needed files. It compiles but when I run scarb test the tests are still not running, I am unable to find the reason for that. I am opening a PR , can you help me do that there?

@gerceboss gerceboss linked a pull request Jul 1, 2024 that will close this issue
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: 🏗 In progress
Development

Successfully merging a pull request may close this issue.

2 participants