-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Welcome to the test_NFT wiki!
// Идентификатор лицензии SPDX: только AGPL-3.0 прагматическая надежность >=0,10,0;
/// @notice Современная, минималистичная и экономичная реализация ERC-721. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) абстрактный контракт ERC721 { ////////////////////////////////////////////////// ////////////// СОБЫТИЯ /////////////////////////////////////////////////// /////////////
Передача события (индексированный адрес, индексированный адрес, индексированный идентификатор uint256);
Утверждение события (индексированный адрес владельца, индексированный адрес отправителя, индексированный идентификатор uint256);
событие ApprovalForAll (владелец индексированного адреса, оператор индексированного адреса, одобрено bool);
/*///////////////////////////////////////////////// //////////////
ХРАНЕНИЕ МЕТАДАННЫХ/ЛОГИКА
/////////////////////////////////////////////////// ////////////*/
строковое публичное имя;
строковый общедоступный символ;
функция tokenURI(uint256 id) виртуальный возврат общедоступного просмотра (строковая память);
/*///////////////////////////////////////////////// //////////////
ERC721 БАЛАНС/ХРАНЕНИЕ ВЛАДЕЛЬЦА
/////////////////////////////////////////////////// ////////////*/
отображение (uint256 => адрес) внутренний _ownerOf;
отображение (адрес => uint256) внутренний _balanceOf;
function OwnerOf(uint256 id) Виртуальный возврат публичного просмотра (владелец адреса) {
require((владелец = _ownerOf[id]) != адрес(0), "NOT_MINTED");
}
function BalanceOf(владелец адреса) виртуальный возврат публичного просмотра (uint256) {
require(владелец!= адрес(0), "ZERO_ADDRESS");
вернуть _balanceOf[владелец];
}
/*///////////////////////////////////////////////// //////////////
ХРАНЕНИЕ ОДОБРЕНИЯ ERC721
/////////////////////////////////////////////////// ////////////*/
отображение (uint256 => адрес) public getApproved;
сопоставление (адрес => сопоставление (адрес => bool)) public isApprovedForAll;
/*///////////////////////////////////////////////// //////////////
КОНСТРУКТОР
/////////////////////////////////////////////////// ////////////*/
конструктор (строковая память _имя, строковая память _символ) {
имя = _имя;
символ = _символ;
}
/*///////////////////////////////////////////////// //////////////
ЛОГИКА ERC721
/////////////////////////////////////////////////// ////////////*/
функция утверждения (адрес отправителя, идентификатор uint256) public virtual {
владелец адреса = _ownerOf[id];
require(msg.sender == владелец || isApprovedForAll[владелец][msg.sender], "NOT_AUTHORIZED");
getApproved[id] = покупатель;
излучать утверждение (владелец, плательщик, идентификатор);
}
функция setApprovalForAll (оператор адреса, одобрено bool) public virtual {
isApprovedForAll[msg.sender][оператор] = одобрено;
испустить ApprovalForAll(msg.sender, оператор, одобрено);
}
функция TransferFrom(
адрес откуда,
Отправить,
идентификатор uint256
) публичный виртуальный {
require(from == _ownerOf[id], "WRONG_FROM");
require(to != адрес(0), "INVALID_RECIPIENT");
требовать(
msg.sender == из || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],
"НЕ_АВТОРИЗИРОВАНО"
);
// Недополнение баланса отправителя невозможно, поскольку мы проверяем наличие
// право собственности указано выше, и баланс получателя не может быть переполнен.
снят флажок {
_balanceOf[из]--;
_balanceOf[to]++;
}
_ownerOf[id] = кому;
удалить getApproved[id];
испустить Transfer(from, to, id);
}
функция SafeTransferFrom(
адрес откуда,
Отправить,
идентификатор uint256
) публичный виртуальный {
TransferFrom (от, до, идентификатор);
требовать(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
ERC721TokenReceiver.onERC721Received.селектор,
"UNSAFE_RECIPIENT"
);
}
функция SafeTransferFrom(
адрес откуда,
Отправить,
идентификатор uint256,
байты данных вызова
) публичный виртуальный {
TransferFrom (от, до, идентификатор);
требовать(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
ERC721TokenReceiver.onERC721Received.селектор,
"UNSAFE_RECIPIENT"
);
}
/*///////////////////////////////////////////////// //////////////
ЛОГИКА ERC165
/////////////////////////////////////////////////// ////////////*/
функция supportInterface(bytes4 InterfaceId) виртуальный возврат публичного просмотра (bool) {
возвращаться
идентификатор интерфейса == 0x01ffc9a7 || // Идентификатор интерфейса ERC165 для ERC165
идентификатор интерфейса == 0x80ac58cd || // Идентификатор интерфейса ERC165 для ERC721
идентификатор интерфейса == 0x5b5e139f; // Идентификатор интерфейса ERC165 для метаданных ERC721
}
/*///////////////////////////////////////////////// //////////////
ВНУТРЕННЯЯ ЛОГИКА ОТМЕНЫ/ЗАЖИГАНИЯ
/////////////////////////////////////////////////// ////////////*/
функция _mint (адрес, идентификатор uint256) внутренний виртуальный {
require(to != адрес(0), "INVALID_RECIPIENT");
require(_ownerOf[id] == адрес(0), "ALREADY_MINTED");
// Переполнение счетчика невероятно нереально.
снят флажок {
_balanceOf[to]++;
}
_ownerOf[id] = кому;
испустить Transfer (адрес (0), кому, идентификатор);
}
функция _burn(uint256 id) внутренний виртуальный {
владелец адреса = _ownerOf[id];
require(владелец!= адрес(0), "NOT_MINTED");
// Проверка владения выше гарантирует отсутствие переполнения.
снят флажок {
_balanceOf[владелец]--;
}
удалить _ownerOf[id];
удалить getApproved[id];
испускать Transfer(владелец, адрес(0), идентификатор);
}
/*///////////////////////////////////////////////// //////////////
ВНУТРЕННЯЯ ЛОГИКА БЕЗОПАСНОСТИ MINT
/////////////////////////////////////////////////// ////////////*/
функция _safeMint (адрес, идентификатор uint256) внутренний виртуальный {
_mint (кому, идентификатор);
требовать(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, адрес(0), id, "") ==
ERC721TokenReceiver.onERC721Received.селектор,
"UNSAFE_RECIPIENT"
);
}
функция _safeMint(
Отправить,
идентификатор uint256,
байты данных памяти
) внутренний виртуальный {
_mint (кому, идентификатор);
требовать(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, адрес(0), идентификатор, данные) ==
ERC721TokenReceiver.onERC721Received.селектор,
"UNSAFE_RECIPIENT"
);
}
}
/// @notice Общий интерфейс для контракта, который правильно принимает токены ERC721. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) абстрактный контракт ERC721TokenReceiver { функция onERC721Received( адрес, адрес, уинт256, байты данных вызова ) внешние виртуальные возвраты (байты4) { вернуть ERC721TokenReceiver.onERC721Received.selector; } }