Once you upload a file to ipfs
, it is theoretically available to anyone who knows its hash. So, it's not possible to restrict the access to the file.
What is possible, is to encrypt the file in some way and only give the decryption key/password to the group of people you want to be able to access it.
Have a look at this awesome ipfs resources.
The projects that seem to best suit your requirements are:
ipfs-add-from-encrypted: This script takes a file or directroy as input, uses tar if a directory and GPG AES256 symmetric encryption with the password you provide and adds it to IPFS and returns the IPFS hash.
ipfsecret: Encrypt and decrypt IPFS files with a secret passphrase.
For your second question: it would be best to have a locally running ipfs node, but fortunately that's not required. Recently, cloudflare launched a set of hosted ipfs gateways which anybody can use.
You did not set the TokenURI for NFT, so when NFT gets the URI, BaseURI + TokenID is used.Look at the source code.
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
return string(abi.encodePacked(base, tokenId.toString()));
}
It returns the URI: https://gateway.pinata.cloud/ipfs/0
This, of course, is not ideal, the ideal URI should be: https://gateway.pinata.cloud/ipfs/Qmf43nycxRXdwdq3GqT7SKU3MvRyBvbpjzufzZR8ASkMGb
I think you see the reason for the problem here.
The next thing you need to do is call _setTokenUri to store the CID from IPFS so that you can get the correct IPFS link when reading the NFT.
/**
* @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
This function is an internal function, and you should provide an external function to use it, but security must be taken care of, or anyone can modify it!
Best Answer
Upload a folder with all the images and json files inside. The folder's URI is going to be your baseURI. You can also upload images in a different folder from json. But you should know that if you change the content of the folder, the folder URI is going to change too.