Я следил за учебным пособием 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; ^--------^
Текущий владелец не является неизменным. Для того, чтобы изменить его, просто вызовите 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
массиве, с адресов наPet
s, предыдущий код не работает. Это проблема с задаванием нескольких вопросов одновременно и попыткой повторить разработку в одном вопросе: обновленная версия не отражает исходный вопрос.Расти Шеклфорд
pets[petId].owner.send(your_amount)
. Все, что я пытаюсь здесь сделать, это скомпилировать предложенные вами изменения.Тюдор Константин
pets[petId] = Pet({owner: msg.sender, price: 100})
Расти Шеклфорд
require(msg.value >= pets[petId].price * 0.5);
инструкция по-прежнему не компилируется с той же ошибкой 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