Отследить владельца и цену в Ethereum Pet Shop

Я следил за учебным пособием Ethereum Pet Shop , и я очарован тем, как все это работает.

Однако у меня есть несколько вопросов.

Прежде чем я углублюсь в это, вот код:

прочность прагмы ^0,4,17;

contract Adoption {
    Pet[16] pets;

    struct Pet {
        address owner;
        uint256 price;
    }

    function returnEth() public payable {
    msg.sender.transfer(msg.value);
    }
    // Adopting a pet
    function adopt(uint petId) public payable returns (uint) {
        require(petId >= 0 && petId <= 15);
        require(msg.value >= pets[petId]['price'] * 0.5);
        pets[petId] = Pet({owner: msg.sender, price: 100});
        return petId;
        //return value;
    }
    // Retrieving the adopters
    function getAdopters() public view returns (Pet[16]) {
        return pets;
    }


}

Насколько я понимаю, всего 16 питомцев с числовыми идентификаторами от 0 до 15 включительно. Я также понимаю, что только один человек может «владеть» домашним животным одновременно.

Является ли нынешний владелец домашнего животного неизменным? Если да, то как изменить это свойство?

Предположим, что после того, как пользователь «купит» питомца, я хочу изменить цену питомца на 0,5 * начальная цена, где в initalPriceнастоящее время не существует. Остаток eth в контракте затем возвращается первому покупателю. Как бы выглядела эта логика?

Я предполагаю, что я объявлю какую-то переменную initialPriceгде-нибудь в своем контракте, которая initialPriceбудет равна какому-то произвольному значению в wei, а затем добавлю что-то похожее на следующую строку:

require(msg.value == initialPrice * .5);

Как бы я тогда вернул оставшийся eth предыдущему владельцу?

Пожалуйста, дайте мне знать, если что-то из этого неясно.

Редактировать: я пытался использовать код с первого ответа, но не могу скомпилировать контракт. Ошибка, которую я получаю, приведена ниже:

Adoption.sol:19:17: TypeError: Type address is not implicitly convertible to expected type struct Adoption.Pet storage ref. pets[petId] = msg.sender; ^--------^

Ответы (1)

Текущий владелец не является неизменным. Для того, чтобы изменить его, просто вызовите adopt()функцию с другого адреса.

Что касается цены, ваш подход работает, если вы хотите иметь одинаковую цену для всех домашних животных. Чтобы иметь разные цены для разных питомцев, вы можете определить pet struct, например:

struct Pet {
  address owner;
  uint256 price;
}

и вместо того, чтобы хранить усыновителей, таких как address[16] public adopters;, сохраните их как:

Pet[16] pets;

Затем потребуйте, чтобы цена была больше или равна, price * .5и в конечном итоге увеличьте цену:

require(msg.value >= pets[petId].price * 0.5);
pets[petId].price = pets[petId].price * 0.5;

Для того, чтобы отправить средства предыдущему владельцу, вы можете отправить их перед установкой нового владельца:

pets[petId].owner.send(your_amount)
Используя этот код, у меня возникает следующая ошибка при компиляции. TypeError: Indexed expression has to be a type, mapping or array (is struct Adoption.Pet storage ref) require(msg.value >= pets[petId]['price'] * 0.5);Новичок в Solidity, поэтому я не уверен, как подойти к отладке. Есть идеи?
Цена должна быть uint256что ли, а не адрес, как сейчас. Я сейчас не за компьютером и не могу редактировать свой ответ.
uint price;внутри структуры по-прежнему приводит к той же ошибке.
Любая идея, почему это происходит?
Пожалуйста, задайте другой вопрос, показав полный код смарт-контракта, который у вас есть до сих пор, и конкретную проблему. Если вы считаете, что мое предложение относительно того, как подойти к проблеме, является хорошим, примите этот ответ как решение этого вопроса.
код моего контракта находится в вопросе, и я бы принял ваш ответ, если бы он скомпилировался.
Ваш старый код контракта находится в вопросе. В новом коде контракта должен быть новый вопрос.
В любом случае, я обновил код, посмотрим, скомпилируется ли он сейчас.
Это не. Я обновил свой исходный вопрос с вашими изменениями (возможно, я что-то делаю неправильно) вместе с ошибкой, которую я получаю в консоли. Извините, если я не ясен.
Пожалуйста, внимательно посмотрите на обновления, которые я внес в свой код, потому что есть некоторые обновления, которые не отражены в вашем обновленном смарт-контракте. Кроме того, ошибка, которую вы получаете сейчас, связана с тем, что вы назначаете адрес чему-то, что ожидает структуру Pet. Поскольку вы изменили элементы, хранящиеся в adoptersмассиве, с адресов на Pets, предыдущий код не работает. Это проблема с задаванием нескольких вопросов одновременно и попыткой повторить разработку в одном вопросе: обновленная версия не отражает исходный вопрос.
Насколько я могу судить, единственное изменение, которое не отражено, — это отсутствие pets[petId].owner.send(your_amount). Все, что я пытаюсь здесь сделать, это скомпилировать предложенные вами изменения.
попробуй сpets[petId] = Pet({owner: msg.sender, price: 100})
кажется, что это работает, но require(msg.value >= pets[petId].price * 0.5);инструкция по-прежнему не компилируется с той же ошибкой TypeError.
что именно говорит тот же TypeError ?
Я заменил pets[petId].price = pets[petId].price * 0.5;на ваше изменение, которое было pets[petId] = Pet({owner: msg.sender, price: 100}). Строка require(msg.value >= pets[petId].price * 0.5);по-прежнему не компилируется, и я вижу ту же ошибку, что и раньше. Ничто не говорит «тот же TypeError». Вот что я вижу (тот же TypeError):TypeError: Indexed expression has to be a type, mapping or array (is struct Adoption.Pet storage ref) require(msg.value >= pets[petId]['price'] * 0.5);
попробуй сrequire(msg.value >= pets[petId].price * 0.5)
TypeError: Operator * not compatible with types uint256 and rational_const 1/2