Skip to content

Latest commit

 

History

History

dz_11

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

Условие (Overview)

Дан смарт-контракт KittenRegistry, содержащий уникальные идентификаторы котов (catID) и отслеживающий их владельцев. Исходники приаттачены.

Необходимо написать смарт-контракт питомника KittyShelter, умеющий принимать кота “на хранение” на определенный период времени. В результате, на период времени <time> (секунд) с момента вызова, владельцем кота становится смарт-контракт KittyShelter. Пользователь может забрать своего кота только по истечении времени <time>. Никто, кроме исходного владельца, не должен иметь возможности забрать чужого кота.

Требования (Requirements)

  1. Смарт-контракт KittyShelter должен взаимодействовать с одним KittenRegistry по указанному адресу (адрес можно захардкодить или указать в конструкторе).
  2. У смарт-контракта должно быть две (обязательных) функции с такой сигнатурой:
    function storeKitty(uint256 catId, uint256 time) public
    function retrieveKitty(uint256 catId) public
  3. Один пользователь может оставить неограниченное количество котов в KittyShelter.
  4. Пользователь не может забрать кота раньше срока.
  5. Кот остается у смарт-контракта до тех пор, пока его не заберут. Пользователь должен сам “прийти” за котом, вызвав функцию retrieveKitty.
  6. Забрать кота может только тот пользователь, который его отдал.

Формат сдачи

Результатом проделанной работы будет исходный код смарт-контракта “KittyShelter”. Как бонус, можно предоставить адрес рабочего контракта в тестовой сети Ropsten.

Тестовые данные (Use case)

Боб уезжает в отпуск и хочет оставить своего кота Барсика (catId=0x01) в приюте (KittyShelter address=0x010c) на 2 недели. Для этого Боб:

  1. Разрешает приюту забрать у него кота вызовом KittenRegistry.approve(0x010c, 0x01)
  2. Обращается в приют, чтобы тот забрал у него кота KittyShelter.storeKitty(0x01, 14 days)
  3. Смарт-контракт приюта переводит себе кота Боба. Теперь кот безопасно хранится в приюте до истечения 14 дней с момента отъезда Боба.
  4. Через 14 дней, Боб обращается к приюту за своим котом KittyShelter.retrieveKitty(0x01). Смарт-контракт отправляет Барсика обратно Бобу.
    • Боб вернулся раньше и хочет забрать кота - приют не отдает кота, пока не истек срок хранения.
    • Алиса решила попытаться украсть Барсика, обратившись в приют - приют не отдает кота чужим людям.

Примечания (Tips/Notes)

catID - простой пример неделимой (non-fungible) монеты соответствующей стандарту ERC-721, почитать про который можно тут http://erc721.org/

Для проверки работы смарт-контрактов в сети Ropsten существует смарт-контракт PetShop. У него всего одна функция: PetShop.BuyAKitten(). Функция не принимает параметров, но при её вызове нужно оплатить 0.5 Ether (за кота). В результате её выполнения вызывающий станет владельцем нового, случайного кота. Функция возвращает CAT id полученного кота. Разработанный в ходе решения задания смарт-контракт можно задеплоить в ту же тестовую сеть и протестировать его работу с полученным из PetShop котом.

Адрес KittenRegistry в сети Ropsten: 0xf59459AE845116c5b0d5401E656073d0BfDCec73
Адрес PetShop в сети Ropsten: 0x8BE44B86b1817D6a4e26EF1C78c5d3bb517ee441

Для разработки можно использовать IDE remix https://remix.ethereum.org.
Для доступа к сети Ropsten - расширение metamask https://metamask.io/.
Запускать собственную сеть не нужно.
Для получения монет в тестовой сети можно использовать https://faucet.ropsten.be/ и https://faucet.metamask.io/

Для вызова функций смарт-контрактов из тестовой сети, в Remix, на вкладке run можно выбрать нужный контракт из выпадающего списка и вместо deploy - выбрать пункт at address, предварительно указав адрес в соседнем поле. (Note: Новый интерфейс отличается визуально, но поля такие же)

pic_11_1

Обзор решения

Тестирование с исходным KittenRegistry

Деплоим PatShop из файла KittenRegistry
pic1

Копируем адрес задеплоенного PatShop и используем его в качестве данных конструктора для деплоя KittenRegistry из файла KittenRegistry
Таким образом база данных зарегистрированных животных привязывается к магазину
pic2

Деплоим написанный код контракта для животных
pic3

Используем функцию SetKittenRegistry с адресом KittenRegistry, чтобы после покупки, кот сразу регистрировался в базе данных
pic4

Вводим нужную сумму для покупки и приобретаем по очереди 2 кота
pic5

При попытке проверить баланс котов по адресу кошелька, с которого производилась оплата, видим, что котов в базе данных действительно два
pic6

Регистрируем базу данных котов в созданном нами контракте
pic7

В базе данных указываем адрес контракта и "нулевого" кота тем самым разрешая будущий перевод
pic8

То же самое делаем с "первым" котом
pic9

Отправляем на хранение "нулевого" кота с временем 0, чтобы его можно было сразу же забрать
pic10

"Первого" кота отправляем с временем 1, чтобы его нельзя было забрать сразу
pic11

Успешно забираем первого кота
pic12

И видим, что забрать второго кота пока нельзя, т.к. срок хранения не истек. Т.е. весь функционал работает верно
pic13

Тестирование контракта в сети Ropsten

Для начала нужно загрузить написанный контракт в сеть Ropsten. Для этого меняем тип окружения на Inject Web3. В процессе разворачивания контракта автоматически происходит подключение к Metamask с запросом на одобрение операции.
pic1

По окончанию получаем адрес контракта в сети
pic5

Деплоим по адресу в сети контракт магазина
pic2

Указываем нужную сумму для покупки и приобретаем по очереди 2 кота. В процессе приобретения автоматически происходит подключение к Metamask с запросом на одобрение операции.
pic3

Деплоим по адресу в сети наш контракт
pic4

Так же по адресу в сети деплоим KittenRegistry
pic6

Проверяем баланc котов на счету, с которого они были приобретены и видим, что котов действительно два
pic7

Открываем информацию по транзакциям с покупкой котов
pic8

И запоминаем id купленного первого кота
pic9

И второго кота
pic10

В базе данных указываем адрес нашего контракта в сети и первого кота с индексом 24 тем самым разрешая будущий перевод..
К сожалению дальнейший тест не возможен, поскольку контракт регистрации перевода не принимает транзакцию. Изучение логов контракта показывает, что последнюю подтвержденную транзакцию он провел более 700 дней назад.
pic11

pic12

pic13

Оценка результата

60 из 100
Ошибки в реализации и внесенные исправления

Ссылки

Цикл уроков по solidity - https://remix.ethereum.org/#optimize=false&runs=200&evmVersion=null&version=soljson-v0.8.11+commit.d7f03943.js
Размещение контракта в сети - https://vc.ru/crypto/28314-sozdaem-svoy-erc20-token-na-baze-ethereum-za-2-minuty