Consider the following Solidity snippet querying balances of tokens in an ERC-1155 contract. What will be the output of the balances array?
contract Test {
function getBalances(address erc1155, address user) public view returns (uint256[] memory) {
uint256[] memory ids = new uint256[](3);
ids[0] = 1;
ids[1] = 2;
ids[2] = 3;
return IERC1155(erc1155).balanceOfBatch(_fillArray(user, 3), ids);
}
function _fillArray(address user, uint256 length) internal pure returns (address[] memory) {
address[] memory arr = new address[](length);
for (uint256 i = 0; i < length; i++) {
arr[i] = user;
}
return arr;
}
}
interface IERC1155 {
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);
}Remember that balanceOfBatch returns balances in the order of the input arrays.
The balanceOfBatch function returns balances for each pair of (account, id). Since the _fillArray creates an array of the same user repeated, the balances correspond to token IDs 1, 2, and 3 for that user. Given the contract state, the balances are [10, 0, 5].
ERC-1155 is a multi-token standard. What key feature makes it different from ERC-20 and ERC-721?
Think about how many token types can be managed by one contract.
ERC-1155 allows a single contract to manage multiple token types, including fungible, non-fungible, or semi-fungible tokens. This is unlike ERC-20 (fungible only) and ERC-721 (non-fungible only) which require separate contracts per token type.
Given this Solidity code snippet for batch transfer, why does the transaction revert?
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public {
require(ids.length == amounts.length, "IDs and amounts length mismatch");
for (uint256 i = 0; i < ids.length; i++) {
require(balanceOf(from, ids[i]) >= amounts[i], "Insufficient balance");
_balances[ids[i]][from] -= amounts[i];
_balances[ids[i]][to] += amounts[i];
}
emit TransferBatch(msg.sender, from, to, ids, amounts);
}ERC-1155 safe transfers require acceptance checks when sending to contracts.
ERC-1155 mandates calling _doSafeBatchTransferAcceptanceCheck after updating balances to ensure the recipient contract implements the receiver interface. Without this, transfers to contracts revert.
What is the syntax error in this mint function snippet?
function mint(address to, uint256 id, uint256 amount, bytes memory data) public {
require(to != address(0), "Mint to zero address");
_balances[id][to] += amount;
emit TransferSingle(msg.sender, address(0), to, id, amount);
_doSafeTransferAcceptanceCheck(msg.sender, address(0), to, id, amount, data);
}Check each line for missing punctuation.
The line _balances[id][to] += amount is missing a semicolon at the end, causing a syntax error.
An ERC-1155 contract mints tokens in batch with the following call:
mintBatch(user, [1,2,3,4], [10,0,5,7], "0x")
What is the length of the balances array returned by balanceOfBatch when querying for user balances of token IDs [1,2,3,4]?
The length of the balances array matches the number of token IDs queried.
The balanceOfBatch function returns an array with one balance per token ID queried. Since 4 token IDs are queried, the balances array length is 4.