I've been following along with the Ethereum Pet Shop tutorial, and I'm fascinated by how all of this works.

I have a few questions, though.

Before I get into it, here's the code:

pragma solidity ^0.4.17;

contract Adoption {
    Pet[16] pets;

    struct Pet {
        address owner;
        uint256 price;

    function returnEth() public payable {
    // 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;


I understand that there are 16 total pets, with numeric IDs ranging from 0-15, inclusive. I also understand that only one person is able to "own" a pet at one time.

Is the current owner of a pet immutable? If so, how do I change this property?

Let's say that after a user "buys" a pet, I want to change the price of the pet to .5 * initialPrice, where initalPrice does not currently exist. The remaining balance in eth in the contract is then returned to the first buyer. What would that logic look like?

I assume I'd declare some variable initialPrice somewhere in my contract, such that initialPrice is equal to some arbitrary value in wei, and then add something similar to the following line:

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

How would I then return the remaining eth to the previous owner?

Please let me know if any of this is unclear.

Edit: I've been trying to use the code from the first, answer, but am unable to compile the contract. The error I'm getting is below:

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

1 Answer 1


The current owner is not immutable. In order to change it, simply call the adopt() function from a different address.

Regarding the price, your approach works if you want to have the same price for all the pets. In order to have different prices for different pets, you could define a pet struct, like this:

struct Pet {
  address owner;
  uint256 price;

and instead of storing the adopters like address[16] public adopters;, keep them like:

Pet[16] pets;

Then require the price to be greater or equal to price * .5 and eventually increase the price:

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

In order to send funds to the previous owner, you can send them before setting the new owner:

  • Using that code, I have the following error when compiling. 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); New to Solidity so I'm not sure how to approach debugging. Any ideas? Feb 15, 2018 at 21:34
  • The price has to be uint256 or something and not an address as it is now. I am not at computer right now and can't edit my answer. Feb 15, 2018 at 21:37
  • uint price; within the struct still results in the same error. Feb 15, 2018 at 22:02
  • any idea why that's happening? Feb 15, 2018 at 23:42
  • Please ask another question, showing the full smart contract code that you have until now and a specific issue. If you think my suggestion regarding how to approach the problem is good, please accept this answer as the solution to this question. Feb 16, 2018 at 5:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.