The first week's assignment of Web3Rover has ended, and a total of 35 assignments were received, accounting for about 40% of the learners, which is considered a good initial achievement of the intermediate threshold, low number of participants, and high participation goals.
This assignment consists of two questions and one additional question, with a total of 10+10+5=25 points. Both 25 points and 20 points answers account for 11.4%, and there are no 0 points.
Below are the reference answers:
1. Identify an unnecessary variable in the obolus contract used for the entrance exam.#
A: mintRate. This was actually a mistake on my part. I originally wanted to set a price to prevent people from minting a large amount on the testnet, but then I realized that there was no cost for getting water on the testnet, so setting it low would be meaningless, and setting it high (more than what can be obtained at once) would affect genuine learners. So in the end, I canceled the pricing but forgot to delete this variable.
Some students answered ObolusSliver's ID for this question, but I don't know why. Although this variable doesn't need to be defined, using it directly in the code is considered using a magic number, which is not recommended.
2. Explain how the obolus contract ensures that a wallet can only have one.#
A: There are actually three places for this question, so only one person actually answered all of them (but I also consider it correct if the second one is not answered).
First place: require(balanceOf(msg.sender, ObolusSliver) == 0, "You already have one Obolus.");
This ensures that the number of ObolusSliver in the wallet is 0 before minting.
The key point here is ERC1155's balanceOf(address, tokenId)
, which is what I mentioned earlier, you can use 0 directly, but using it as a magic number is not recommended.
Second place: require(amount == 1, "Wrong amount. Should be 1");
This ensures that only one can be minted each time.
Third place: require(address(0) == from, "You can not give your Obolus to others.");
This is the most easily overlooked line of code in the answers, in _beforeTokenTransfer
. If you think about it carefully, you will know that with only the above two requirements, it is not possible to prevent the situation where "after minting, the token is transferred to another wallet that already has a token, resulting in a holding of more than 1".
So this line of code directly restricts anyone from transferring the token except for the address 0. As for why it is restricted to address 0, it is actually a good thinking question - have you ever thought about where the minting of this NFT comes from?
3. (Additional question) Explain why ERC1155 is not suitable for pfp projects with different traits.#
There are actually many things that can be said about this question, but the core is that ERC1155 uses a double-layer mapping to implement a contract that can store multiple types of tokens, where token refers to both NFT and FT.
The biggest difference between the tokenID of ERC1155 and ERC721 is that in 1155, one tokenID represents one type of token. In 721, because there is only one type of token in total, the tokenID represents the number of each individual token.
In this exam, we used 1155, and you can see that there is only one tokenID, ObolusSliver (which is 0), which represents that this erc1155 only contains one type of token. And if you delve into the ObolusSliver token, each token itself does not have its own number, meaning it is no different from others. This design is actually to be compatible with FT, where under the default erc1155 interface, ft and nft can behave the same.
In summary, ERC1155 specifies multiple types of tokens, and the tokenID is used to mark different types of tokens. Even if each token of the same type, including NFT, has no difference in numbering. On the other hand, ERC721 can only contain one type of token, and the tokenID is used to mark the number of each individual token.
Ultimately, the trait system of 721 relies entirely on the tokenID to allocate metadata. This design difference also means that in erc1155, because tokens of the same type have no difference in numbering by default, there is no way to assign different metadata to each token of the same type.
Of course, none of this is absolute. In fact, developers can add their own logic to record the ID of each token in each type under 1155, but it requires more work and more gas consumption.
Our official Twitter: