pragma solidity>=0.4.22 <0.6.0; import './ERC721.sol'; import './AddressUtils.sol'; import './ERC721TokenReceiver.sol'; import './SafeMath.sol'; contract copyright is ERC721 { using AddressUtils for address; using SafeMath for uint256; bytes4 constant MAGIC_ON_ERC721_RECEIVED = 0x150b7a02; //owner->tokenId mapping(address => uint256) _ownerTokenCount; //tokenId->owner mapping(uint256 => address) _tokenOwner; //tokenId->Approval mapping(uint256 => address) _tokenApprovals; mapping(address => mapping(address => bool)) _operatorApprovals; //цифровой актив struct Asset { bytes32 contentHash; //хеш контента string copyrightTran; //права на использование string tran; //транзакция string name; //название } Asset[] public assets; constructor() public {}
modifier canTransfer(uint _tokenId) {
address tokenOwner = _tokenOwner[_tokenId];
require(msg.sender == tokenOwner || msg.sender == _getApproved(_tokenId) || _operatorApprovals[tokenOwner][msg.sender]);
_;
}
modifier canOperate(uint256 _tokenId) {
address tokenOwner = _tokenOwner[_tokenId];
require(msg.sender == tokenOwner || _operatorApprovals[tokenOwner][msg.sender]);
_;
}
modifier validToken(uint256 _tokenId) {
require(_tokenOwner[_tokenId] != address(0));
_;
}
function balanceOf(address _owner) external view returns (uint256) {
require(address(0) != _owner);
return _ownerTokenCount[_owner];
}
function ownerOf(uint256 _tokenId) external view returns (address) {
address owner = _tokenOwner[_tokenId];
require(address(0) != owner);
return owner;
}
function _transfer(address _to, uint _tokenId) private {
address tokenOwner = _tokenOwner[_tokenId];
clearApproval(_tokenId); //*
removeToken(tokenOwner, _tokenId); //*
addToken(_to, _tokenId); //*
emit Transfer(tokenOwner, _to, _tokenId);
} функция clearApproval(uint256 _tokenId) приватный {
if (_tokenApprovals[_tokenId] != address(0)) {
delete(_tokenApprovals[_tokenId]);
}
}
функция removeToken(address _from, uint _tokenId) приватный {
require(_tokenOwner[_tokenId] == _from);
assert(_ownerTokenCount[_from] > 0);
}```markdown
_ownerTokenCount[_from] = _ownerTokenCount[_from] - 1; delete(_tokenOwner[_tokenId]); }
функция addToken(address _to, uint _tokenId) приватный {
require(_tokenOwner[_tokenId] == address(0));
_tokenOwner[_tokenId] = _to;
_ownerTokenCount[_to] = _ownerTokenCount[_to].add(1);
}
//безопасный трансфер
функция _safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes memory _data) приватный canTransfer(_tokenId) validToken(_tokenId) {
address tokenOwner = _tokenOwner[_tokenId];
require(_to != address(0));
_transfer(_to, _tokenId);
// безопасный трансфер или нет?
if (_to.isContract()) {
bytes4 retval = ERC721TokenReceiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data);
require(retval == MAGIC_ON_ERC721_RECEIVED);
}
}
//безопасный трансфер
функция safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata _data) внешний payable {
_safeTransferFrom(_from, _to, _tokenId, _data);
}
//безопасный трансфер
функция safeTransferFrom(address _from, address _to, uint256 _tokenId) внешний payable {
_safeTransferFrom(_from, _to, _tokenId, "");
}
//трансфер
функция transferFrom(address _from, address _to, uint256 _tokenId) canTransfer(_tokenId) validToken(_tokenId) внешний payable {
address tokenOwner = _tokenOwner[_tokenId];
require(_to != address(0));
_transfer(_to, _tokenId);
}
//подтверждение
функция approve(address _approved, uint256 _tokenId) validToken(_tokenId) внешний {
address tokenOwner = _tokenOwner[_tokenId];
require(_approved != address(0));
_tokenApprovals[_tokenId] = _approved;
} // получение подтверждения
function _getApproved(uint256 _tokenId) validToken(_tokenId) private view returns (address) {
return _tokenApprovals[_tokenId];
}
// установка подтверждения для всех
function setApprovalForAll(address _operator, bool _approved) external {
require(_operator != address(0));
require(_ownerTokenCount[_operator] > 0);
_operatorApprovals[msg.sender][_operator] = _approved;
}
// получение подтверждения
function getApproved(uint256 _tokenId) external view returns (address) {
return _getApproved(_tokenId);
} // проверка подтверждения для всех
function isApprovedForAll(address _owner, address _operator) external view returns (bool) {
return _operatorApprovals[_owner][_operator];
}
// событие нового актива
event newAsset(bytes32 _hash, address _owner, uint256 _tokenId);
// регистрация
function _newAsset(bytes32 _hash, string memory _data) private returns (uint256) {
Asset memory a = Asset(_hash, "", "", "", _data);
uint256 tokenId = assets.push(a) - 1;
emit newAsset(_hash, msg.sender, tokenId);
return tokenId;
}
// создание
function mint(bytes32 _hash, string calldata _data) external {
uint256 tokenId = _newAsset(_hash, _data);
_ownerTokenCount[msg.sender] = _ownerTokenCount[msg.sender].add(1);
_tokenOwner[tokenId] = msg.sender;
}
// соединение строк
function strConcat(string memory _a, string memory _b) private returns (string memory) {
bytes memory _ba = bytes(_a);
bytes memory _bb = bytes(_b);
string memory ret = new string(_ba.length + _bb.length);
bytes memory bret = bytes(ret);
uint k = 0;
for (uint i = 0; i < _ba.length; i++) bret[k++] = _ba[i];
for (uint i = 0; i < _bb.length; i++) bret[k++] = _bb[i];
return string(ret);
}
// копирование записи
function copyRecode(string memory _recode, uint256 _tokenId) public payable returns (string memory) {
string memory yuan = assets[_tokenId].copyrightTran;
string memory xin = strConcat(yuan, _recode);
assets[_tokenId].copyrightTran = xin;
return xin;
}
// запись активов
function assRecode(string memory _tran, uint256 _tokenId) public payable returns (string memory) {
string memory yuan = assets[_tokenId].tran;
string memory xin = strConcat(yuan, _tran);
assets[_tokenId].tran = xin;
return xin;
}
// получение записи авторских прав
function getCopyrecode(uint256 _tokenId) public view returns (string memory) {
return assets[_tokenId].copyrightTran;
} функция getAssRecode(uint256 _tokenId) public view возвращает(string memory) {
возвращает assets[_tokenId].tran;
}
}
# ERC721.sol
pragma solidity>=0.4.22 <0.6.0;
интерфейс ERC721 {
событие Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
событие Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
событие ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
//_owner de token shuliang
функция balanceOf(address _owner) external view возвращает (uint256);
//token de zhuren функция ownerOf(uint256 _tokenId) внешний просмотр возвращает (адрес);
//безопасный перевод
функция safeTransferFrom(адрес _from, адрес _to, uint256 _tokenId, bytes calldata _data) внешний payable;
функция safeTransferFrom(адрес _from, адрес _to, uint256 _tokenId) внешний payable;
//перевод
функция transferFrom(адрес _from, адрес _to, uint256 _tokenId) внешний payable;
//разрешение
функция approve(адрес _approved, uint256 _tokenId) внешний;
//разрешение для всех
функция setApprovalForAll(адрес _operator, bool _approved) внешний;
функция getApproved(uint256 _tokenId) внешний просмотр возвращает (адрес);
функция isApprovedForAll(адрес _owner, адрес _operator) внешний просмотр возвращает (bool);
}
# ERC721TokenReceiver.sol
pragma solidity>=0.4.22 <0.6.0;
/**
* @dev ERC-721 интерфейс для принятия безопасных переводов. См. https://goo.gl/pc9yoS.
*/
интерфейс ERC721TokenReceiver {
/**
* @dev Обработка получения NFT. ERC721 умный контракт вызывает эту функцию у получателя после `transfer`.
* Возврат чего-либо кроме волшебного значения должен привести к откату транзакции.
*/
функция onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) внешний pure возвращает(bytes4);
} * Возвращает `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` если не выброшено исключение.
* @notice Адрес контракта всегда является отправителем сообщения. Приложение-кошелек/брокер/аукцион должно реализовать интерфейс кошелька, если оно будет принимать безопасные переводы.
* @param _operator Адрес, вызвавший функцию `safeTransferFrom`.
* @param _from Адрес, ранее владевший токеном.
* @param _tokenId Идентификатор NFT, который передается.
* @param _data Дополнительные данные без определенного формата.
*/
function onERC721Received(
address _operator,
address _from,
uint256 _tokenId,
bytes calldata _data
) external override returns (bytes4);
}# AddressUtils.sol
/**
*
@dev Библиотека вспомогательных встроенных функций для адресов.
*/
library AddressUtils {
/**
* @dev Возвращает, является ли целевой адрес контрактом.
* @param _addr Адрес для проверки.
*/
function isContract(address _addr) internal view returns (bool) {
uint256 size;
/**
* XXX В настоящее время лучшего способа проверить, является ли адрес контрактом,
* чем проверить размер кода в этом адресе, нет.
* Подробнее см. https://ethereum.stackexchange.com/a/14016/36603.
* TODO: Перепроверить это перед релизом Серенити, так как все адреса будут
* являться контрактами тогда.
*/
assembly { size := extcodesize(_addr) }
// solium-disable-line security/no-inline-assembly
return size > 0;
}
}
# SafeMath.sol
pragma solidity>=0.4.22 <0.6.0;
/**
* @dev Математические операции с проверками на ошибки, которые выбрасывают исключение при ошибке.
*/* Эта библиотека основана на исходном коде по адресу https://goo.gl/iyQsmU.
*/
library SafeMath {
/**
* @dev Умножает два числа, выбрасывает исключение при переполнении.
* @param _a Первый множитель.
* @param _b Второй множитель.
*/
function mul( uint256 _a, uint256 _b ) internal pure returns (uint256) {
if (_a == 0) {
return 0;
}
uint256 c = _a * _b;
assert(c / _a == _b);
return c;
}
/**
* @dev Целочисленное деление двух чисел, отбрасывает дробную часть.
* @param _a Делимое.
* @param _b Делитель.
*/
function div( uint256 _a, uint256 _b ) internal pure returns (uint256) {
uint256 c = _a / _b;
// assert(b > 0);
// Solidity автоматически выбрасывает исключение при делении на ноль
// assert(a == b * c + a % b);
// В этом случае это всегда верно
return c;
}
/**
* @dev Вычитает одно число из другого, выбрасывает исключение при переполнении (т. е. если вычитаемое больше уменьшаемого).
* @param _a Уменьшаемое.
* @param _b Вычитаемое.
*/
function sub( uint256 _a, uint256 _b ) internal pure returns (uint256) {
assert(_b <= _a);
return _a - _b;
}
/**
* @dev Складывает два числа, выбрасывает исключение при переполнении.
* @param _a Первое число.
* @param _b Второе число.
*/
function add( uint256 _a, uint256 _b ) internal pure returns (uint256) {
uint256 c = _a + _b;
assert(c >= _a);
return c;
}
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )