Dueño de la pista y precio en Ethereum Pet Shop

He estado siguiendo el tutorial de Ethereum Pet Shop y estoy fascinado por cómo funciona todo esto.

Sin embargo, tengo algunas preguntas.

Antes de entrar en esto, aquí está el código:

solidez de pragma ^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;
    }


}

Entiendo que hay 16 mascotas en total, con identificaciones numéricas que van del 0 al 15, inclusive. También entiendo que solo una persona puede "poseer" una mascota a la vez.

¿El dueño actual de una mascota es inmutable? Si es así, ¿cómo cambio esta propiedad?

Digamos que después de que un usuario "compre" una mascota, quiero cambiar el precio de la mascota a .5 * precio inicial, donde initalPriceactualmente no existe. El saldo restante en eth en el contrato luego se devuelve al primer comprador. ¿Cómo sería esa lógica?

Supongo que declararía alguna variable initialPriceen algún lugar de mi contrato, de modo que initialPricesea igual a algún valor arbitrario en wei, y luego agregaría algo similar a la siguiente línea:

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

¿Cómo devolvería el eth restante al propietario anterior?

Por favor, hágamelo saber si algo de esto no está claro.

Editar: he estado tratando de usar el código desde la primera respuesta, pero no puedo compilar el contrato. El error que estoy recibiendo es el siguiente:

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

Respuestas (1)

El propietario actual no es inmutable. Para cambiarlo, simplemente llame a la adopt()función desde una dirección diferente.

En cuanto al precio, su enfoque funciona si desea tener el mismo precio para todas las mascotas. Para tener diferentes precios para diferentes mascotas, podrías definir un pet struct, como este:

struct Pet {
  address owner;
  uint256 price;
}

y en lugar de almacenar a los adoptantes como address[16] public adopters;, mantenlos como:

Pet[16] pets;

Luego requiere que el precio sea mayor o igual price * .5y eventualmente aumente el precio:

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

Para enviar fondos al propietario anterior, puede enviarlos antes de configurar el nuevo propietario:

pets[petId].owner.send(your_amount)
Usando ese código, tengo el siguiente error al compilar. 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);Nuevo en Solidity, así que no estoy seguro de cómo abordar la depuración. ¿Algunas ideas?
El precio tiene que ser uint256o algo y no una dirección como lo es ahora. No estoy en la computadora en este momento y no puedo editar mi respuesta.
uint price;dentro de la estructura todavía da como resultado el mismo error.
¿alguna idea de por qué está pasando eso?
Haga otra pregunta, mostrando el código de contrato inteligente completo que tiene hasta ahora y un problema específico. Si cree que mi sugerencia sobre cómo abordar el problema es buena, acepte esta respuesta como la solución a esta pregunta.
el código de mi contrato está en la pregunta, y aceptaría su respuesta si se compilara.
su antiguo código de contrato está en la pregunta. El nuevo código de contrato debería tener una nueva pregunta.
De todos modos, he actualizado el código, mira si compila ahora.
no es asi. Actualicé mi pregunta original con sus cambios (tal vez estoy haciendo algo incorrectamente) junto con el error que aparece en la consola. Lo siento si no estoy siendo claro.
Eche un vistazo más de cerca a las actualizaciones que hice en mi código, porque hay algunas actualizaciones que no se reflejan en su contrato inteligente actualizado. Además, el error que recibe ahora se debe a que está asignando una dirección a algo que espera una Petestructura. Dado que cambió las cosas que almacena en la adoptersmatriz de direcciones a Pets, el código anterior no funciona. Ese es el problema de hacer varias preguntas a la vez y tratar de iterar el desarrollo en una sola pregunta: la versión actualizada no refleja la pregunta original.
Por lo que puedo decir, el único cambio que no se refleja es la ausencia de pets[petId].owner.send(your_amount). Todo lo que intento hacer aquí es recopilar los cambios sugeridos.
prueba conpets[petId] = Pet({owner: msg.sender, price: 100})
eso parece funcionar, pero la require(msg.value >= pets[petId].price * 0.5);declaración aún no se compila con el mismo TypeError.
¿Qué dice exactamente el mismo TypeError ?
Reemplacé pets[petId].price = pets[petId].price * 0.5;con su cambio, que era pets[petId] = Pet({owner: msg.sender, price: 100}). La línea require(msg.value >= pets[petId].price * 0.5);aún no se compila y veo el mismo error anterior. Nada dice "el mismo TypeError". Esto es lo que estoy viendo (el mismo 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);
prueba conrequire(msg.value >= pets[petId].price * 0.5)
TypeError: Operator * not compatible with types uint256 and rational_const 1/2