#solidity
Вопрос:
Что это за функция и как она используется bytes calldata _data
в этой контрактной функции?
/**
Mint a batch of tokens into existence and send them to the `_recipient`
address. In order to mint an item, its item group must first have been
created. Minting an item must obey both the fungibility and size cap of its
group.
@param _recipient The address to receive all NFTs within the newly-minted
group.
@param _ids The item IDs for the new items to create.
@param _amounts The amount of each corresponding item ID to create.
@param _data Any associated data to use on items minted in this transaction.
*/
function mintBatch(address _recipient, uint256[] calldata _ids,
uint256[] calldata _amounts, bytes calldata _data)
external virtual {
require(_recipient != address(0),
"ERC1155: mint to the zero address");
require(_ids.length == _amounts.length,
"ERC1155: ids and amounts length mismatch");
// Validate and perform the mint.
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), _recipient, _ids, _amounts,
_data);
// Loop through each of the batched IDs to update storage of special
// balances and circulation balances.
for (uint256 i = 0; i < _ids.length; i ) {
require(_hasItemRight(_ids[i], MINT),
"Super1155: you do not have the right to mint that item");
// Retrieve the group ID from the given item `_id` and check mint.
uint256 shiftedGroupId = (_ids[i] amp; GROUP_MASK);
uint256 groupId = shiftedGroupId >> 128;
uint256 mintedItemId = _mintChecker(_ids[i], _amounts[i]);
// Update storage of special balances and circulating values.
balances[mintedItemId][_recipient] = balances[mintedItemId][_recipient]
.add(_amounts[i]);
groupBalances[groupId][_recipient] = groupBalances[groupId][_recipient]
.add(_amounts[i]);
totalBalances[_recipient] = totalBalances[_recipient].add(_amounts[i]);
mintCount[mintedItemId] = mintCount[mintedItemId].add(_amounts[i]);
circulatingSupply[mintedItemId] = circulatingSupply[mintedItemId]
.add(_amounts[i]);
itemGroups[groupId].mintCount = itemGroups[groupId].mintCount
.add(_amounts[i]);
itemGroups[groupId].circulatingSupply =
itemGroups[groupId].circulatingSupply.add(_amounts[i]);
}
// Emit event and handle the safety check.
emit TransferBatch(operator, address(0), _recipient, _ids, _amounts);
_doSafeBatchTransferAcceptanceCheck(operator, address(0), _recipient, _ids,
_amounts, _data);
}
Ответ №1:
calldata
это специальное расположение данных, содержащее аргументы функции, доступные только для параметров внешнего вызова функций. Calldata-это немодифицируемая, непостоянная область, в которой хранятся аргументы функций, и поведение в основном похоже memory
.
Если вы можете, попробуйте использовать calldata
в качестве местоположения данных, потому что это позволит избежать копирования, а также гарантирует, что данные не могут быть изменены. Массивы и структуры с calldata
расположением данных также могут быть возвращены из функций, но выделить такие типы невозможно.
Теперь что касается bytes
: это просто переменный тип, который содержит последовательность байтов от 1 до 32.
А что касается фактического параметра и его значения в контракте, я нашел контракт, на который вы ссылаетесь, и его дополнительные данные без определенного формата, похоже, это также необязательный параметр.
Примечание:
До версии 0.6.9 расположение данных для аргументов ссылочного типа ограничивалось calldata
внешними функциями, memory
общедоступными функциями и memory
либо storage
внутренними, либо частными. Теперь memory
и calldata
разрешены во всех функциях, независимо от их видимости.
До версии 0.5.0 расположение данных могло быть опущено и по умолчанию размещалось в разных местах в зависимости от типа переменной, типа функции и т. Д., Но теперь все сложные типы должны указывать явное расположение данных.
Для получения более подробной calldata
информации перейдите сюда.
Для получения более подробной bytes
информации перейдите сюда.
Для получения более подробной информации о фактическом контракте перейдите сюда.