pragma solidity ^0.4.17; contract Auction { // Data // Estructura para mantener los detalles del ítem struct Item { uint itemId; // id del ítem uint[] itemTokens; // tokens apostados por el ítem } // Estructura para mantener los detalles de las personas struct Person { uint remainingTokens; // tokens restantes con el postor uint personId; // también sirve como tokenId address addr; // dirección del postor } mapping(address => Person) tokenDetails; // dirección a persona Person [4] bidders; // Array que contiene 4 objetos Person Item [3] public items; // Array que contiene 3 objetos Item address[3] public winners; // Array para la dirección de los ganadores address public beneficiary; // propietario del contrato inteligente uint bidderCount = 0; // contador // Funciones function Auction() public payable { // constructor // Parte 1 Tarea 1. Inicializar beneficiario con la dirección del propietario del contrato inteligente beneficiary = msg.sender; uint[] memory emptyArray; items[0] = Item({itemId: 0, itemTokens: emptyArray}); // Parte 1 Tarea 2. Inicializar dos ítems con índices 1 y 2 items[1] = Item({itemId: 1, itemTokens: emptyArray}); items[2] = Item({itemId: 2, itemTokens: emptyArray}); } function register() public payable { bidders[bidderCount].personId = bidderCount; // Parte 1 Tarea 3. Inicializar la dirección del postor bidders[bidderCount].addr = msg.sender; bidders[bidderCount].remainingTokens = 5; // solo 5 tokens tokenDetails[msg.sender] = bidders[bidderCount]; bidderCount++; } function bid(uint _itemId, uint _count) public payable { /* Apuesta tokens a un ítem particular. Argumentos: _itemId -- uint, id del ítem _count -- uint, cantidad de tokens a apostar por el ítem */ // Parte 1 Tarea 4. Implementar las tres condiciones a continuación. require(tokenDetails[msg.sender].remainingTokens >= _count); require(tokenDetails[msg.sender].remainingTokens > 0); require(_itemId < 3); // Parte 1 Tarea 5. Decrementar remainingTokens por la cantidad de tokens apostados y almacenar el valor en la variable balance uint balance = tokenDetails[msg.sender].remainingTokens - _count; tokenDetails[msg.sender].remainingTokens = balance; bidders[tokenDetails[msg.sender].personId].remainingTokens = balance; // actualizando el mismo balance en el mapa de postores Item storage bidItem = items[_itemId]; for(uint i = 0; i < _count; i++) { bidItem.itemTokens.push(tokenDetails[msg.sender].personId); } } // Parte 2 Tarea 1. Crear un modificador llamado "onlyOwner" para asegurar que solo el propietario pueda revelar los ganadores modifier onlyOwner { require(msg.sender == beneficiary); _; } function revealWinners() public onlyOwner { /* Iterar sobre todos los ítems presentes en la subasta. Si al menos una persona ha hecho una oferta, seleccionar aleatoriamente el ganador */ for (uint id = 0; id < 3; id++) { Item storage currentItem = items[id]; if (currentItem.itemTokens.length != 0) { // generar un número aleatorio desde el número de bloque uint randomIndex = (block.number / currentItem.itemTokens.length) % currentItem.itemTokens.length; // Obtener el tokenId ganador uint winnerId = currentItem.itemTokens[randomIndex]; // Parte 1 Tarea 6. Asignar a los ganadores. winners[id] = bidders[winnerId].addr; } } } // Métodos varios: Los métodos a continuación se utilizan para asistir en la calificación. Por favor, NO LOS CAMBIE. function getPersonDetails(uint id) public constant returns (uint, uint, address) { return (bidders[id].remainingTokens, bidders[id].personId, bidders[id].addr); } }
0.4.18