Retirar ethereum de un contrato inteligente (devolver al remitente)

Digamos que tengo una aplicación descentralizada que permite a las personas comprar algún objeto a un precio arbitrario.

El usuario 1 compra el objeto por 1 eth. Unos momentos después, el usuario 2 compra el mismo artículo. ¿Cómo puedo monitorear este evento y devolver automáticamente la cantidad apropiada de etherium al usuario 2? Esto es lo que tengo hasta ahora:

contract Adoption {
    address[16] public adopters;

    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 == 1 ether);
        adopters[petId] = msg.sender;
        returnEth();
        return petId;
        //return value;
    }
    // Retrieving the adopters
    function getAdopters() public view returns (address[16]) {
        return adopters;
    }


}
Tu segunda pregunta no tiene relación con la primera. Sugeriría hacerla como una nueva pregunta. (Es difícil para otros beneficiarse de su pregunta o responderla si está oculta dentro de otra pregunta).

Respuestas (1)

Leyendo entre líneas, creo que está diciendo que el usuario 2 no debería poder comprar el artículo que el usuario 1 ya compró.

Si ese es el caso, entonces la llamada que hizo el usuario 2 para comprar el artículo debería fallar. No ha compartido la función que se utiliza para realizar una compra, pero debería revertir la transacción si el artículo ya se vendió.

¿Qué sucede si la transacción aún está siendo confirmada?
Una transacción que no ha sido confirmada está esperando. No tiene ningún efecto. Cuando finalmente se procese, tendrá éxito (si es el primero en comprar el artículo) o fallará.
Esa es buena información, pero aún me gustaría saber cómo enviar ether a los usuarios del contrato. ¿Debo actualizar mi pregunta original?
es <address>.transfer(<amount>)solo
Entonces, ¿funcionaría teóricamente mi código original, si se llamara en el momento adecuado?
Para su código original, si el Usuario A envía 1 éter a la función, entonces transfiere 1 éter al Usuario A. Si por alguna razón no desea simplemente revertir la transacción, entonces esta parece una buena manera de reembolsar la transferencia. éter.
bueno. Si quisiera llamar a esa función dentro de mi contrato (es la misma a la que respondió en mi última pregunta), ¿cómo lo haría con web3js? Simplemente no quiero enviar spam a StackExchange con preguntas.
Para llamarlo desde otra función en su contrato, simplemente haga returnEth();. Si su pregunta es "¿Cómo llamo a una función desde web3.js?" eso no parece relacionado. Hágalo como una nueva pregunta, pero primero, lea un tutorial, tal vez incluso el mío: programtheblockchain.com/posts/2017/12/13/… . (Sin embargo, creo que tal vez estés usando Truffle. Si es así, mira un tutorial para eso).
así que no hablaré más sobre web3js, pero si llamo a returnEth(); en mi contrato existente, eth se deduce de mi billetera metamask pero no se devuelve. ¿Sabes por qué puede estar pasando esto?
No. Llamar directamente returnEth()nunca debería reducir la cantidad de éter en la cuenta de la persona que llama. Incluso si transferfalla, la transacción se revertirá, por lo que no se moverá el éter.
1 eth se deduce de su billetera de la función adopt() en mi pregunta anterior. returnEth() se llama desde adopt(), pero parece que no funciona.
Tendría que compartir el código real que está usando (supongo que el código actual para adoptesas llamadas returnEth).
actualicé mi pregunta con el código completo
El código en su pregunta funciona bien para mí. Tenga en cuenta que las tarifas de gas se aplican sin importar qué, por lo que el saldo de éter de la cuenta debería disminuir una pequeña cantidad con cada transacción. Pero si empiezo con 100 ether y envío 1 ether a adopt(), termino con >99.99999999 ether después de la llamada.