From a3cba3d034718b7f010bc3cdefacd95d91499c54 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 2 Jul 2018 13:20:05 -0400 Subject: [PATCH] Documented contract --- contracts/SpaceshipMarketplace.sol | 28 ++++++++---- contracts/SpaceshipToken.sol | 70 +++++++++++++++++------------- 2 files changed, 60 insertions(+), 38 deletions(-) diff --git a/contracts/SpaceshipMarketplace.sol b/contracts/SpaceshipMarketplace.sol index 84ec4db..b8fa916 100644 --- a/contracts/SpaceshipMarketplace.sol +++ b/contracts/SpaceshipMarketplace.sol @@ -4,6 +4,7 @@ import "./SpaceshipToken.sol"; import "zeppelin-solidity/contracts/token/ERC721/ERC721Holder.sol"; +/// @title Escrow para compra venta del token contract SpaceshipMarketplace is ERC721Holder { // Esta estructura guarda informacion sobre las ventas @@ -13,27 +14,32 @@ contract SpaceshipMarketplace is ERC721Holder { address owner; } - SpaceshipToken token; + SpaceshipToken public token; Sale[] public sales; - mapping(uint => uint) spaceshipToSale; + mapping(uint => uint) public spaceshipToSale; event NewSale(uint indexed spaceshipId, uint price, uint saleId); + event ShipSold(uint indexed spaceshipId, uint price, address indexed oldOwner, address indexed newOwner); - - constructor(SpaceshipToken _token) public { - token = _token; + /// @notice Constructor + /// @param _token Direccion del token + constructor(address _token) public { + token = SpaceshipToken(_token); } - function buy(uint _saleId) payable { + /// @notice Comprar token + /// @param _saleId Id de la venta que se desea + function buy(uint _saleId) public payable { Sale storage s = sales[_saleId]; // TODO: descomentar esto para evitar que el dueno compre su propia nave // require(s.owner != msg.sender); require(msg.value >= s.price); + // Devolvemos el sobrante uint refund = msg.value - s.price; if(refund > 0) msg.sender.transfer(refund); @@ -47,14 +53,16 @@ contract SpaceshipMarketplace is ERC721Holder { token.approve(msg.sender, s.spaceshipId); token.safeTransferFrom(address(this), msg.sender, s.spaceshipId); - // Eliminamos la venta // TODO: reorder + // Eliminamos la venta delete spaceshipToSale[s.spaceshipId]; - Sale replacer = sales[sales.length - 1]; sales[_saleId] = replacer; sales.length--; } + /// @notice Publicar token para venta + /// @param _spaceshipId Id del token + /// @param _price Precio de venta function forSale(uint _spaceshipId, uint _price){ // Solo se pueden vender tus propias naves require(token.ownerOf(_spaceshipId) == msg.sender); @@ -68,6 +76,7 @@ contract SpaceshipMarketplace is ERC721Holder { owner: msg.sender }); + // Agregamos el token a la lista de vtokens en venta uint saleId = sales.push(s) - 1; spaceshipToSale[_spaceshipId] = saleId; @@ -75,6 +84,8 @@ contract SpaceshipMarketplace is ERC721Holder { emit NewSale(_spaceshipId, _price, saleId); } + /// @notice Retirar token de listado de venta + /// @param _spaceshipId Id del token function withdraw(uint _spaceshipId){ require(sales[spaceshipToSale[_spaceshipId]].owner == msg.sender); @@ -86,6 +97,7 @@ contract SpaceshipMarketplace is ERC721Holder { token.safeTransferFrom(address(this), msg.sender, _spaceshipId); } + /// @notice Cantidad de tokens a la venta function nSale() public view returns(uint) { return sales.length; } diff --git a/contracts/SpaceshipToken.sol b/contracts/SpaceshipToken.sol index 4c48f5b..e59a2de 100644 --- a/contracts/SpaceshipToken.sol +++ b/contracts/SpaceshipToken.sol @@ -1,15 +1,14 @@ pragma solidity 0.4.24; import "zeppelin-solidity/contracts/token/ERC721/ERC721Token.sol"; -import 'zeppelin-solidity/contracts/ownership/Ownable.sol'; +import "zeppelin-solidity/contracts/ownership/Ownable.sol"; -/** - @title Contrato base para Mexico Workshop - @dev En Status tambien hablamos espanol ;) - */ + +/// @title Contrato base para Mexico Workshop +/// @dev En Status tambien hablamos espanol ;) contract SpaceshipToken is ERC721Token("CryptoSpaceships", "CST"), Ownable { - /// @dev Estructura que representa nuestra nave spacial + // Estructura que representa nuestra nave spacial struct Spaceship { bytes metadataHash; // IPFS Hash uint8 energy; @@ -23,8 +22,13 @@ contract SpaceshipToken is ERC721Token("CryptoSpaceships", "CST"), Ownable { // Precio de las naves mapping(uint => uint) public spaceshipPrices; uint[] public shipsForSale; - mapping(uint => uint) indexes; // shipId => shipForSale + mapping(uint => uint) public indexes; // shipId => shipForSale + /// @notice Crear un tocken + /// @param _metadataHash IPFS hash que contiene la metadata del token + /// @param _energy Atributo: Energia + /// @param _lasers Atributo: Lasers + /// @param _price Precio de venta del token function mint(bytes _metadataHash, uint8 _energy, uint8 _lasers, @@ -52,10 +56,14 @@ contract SpaceshipToken is ERC721Token("CryptoSpaceships", "CST"), Ownable { _mint(address(this), spaceshipId); } - function shipsForSaleN() public view returns(uint){ + /// @notice Obtener cantidad de naves a la venta + /// @return Cantidad + function shipsForSaleN() public view returns(uint) { return shipsForSale.length; } + /// @notice Comprar nave + /// @param _spaceshipId Id del token a comprar function buySpaceship(uint _spaceshipId) public payable { // Solo se pueden comprar las naves cuyo dueno sea el contrato require(ownerOf(_spaceshipId) == address(this)); @@ -63,55 +71,57 @@ contract SpaceshipToken is ERC721Token("CryptoSpaceships", "CST"), Ownable { // Se debe enviar al menos el precio de la nave require(msg.value != 0); - // Transferimos la - // Approbamos directamente para evitar tener que crear una transaccion extra + // Approvamos directamente para evitar tener que crear una transaccion extra + // y luego enviamos la nave a quien origino la transaccion tokenApprovals[_spaceshipId] = msg.sender; safeTransferFrom(address(this), msg.sender, _spaceshipId); // La eliminamos de la lista para venta + // Esto se ve un poco mas complicado de lo necesario, + // Pero es para borrar elementos del arreglo de forma eficiente uint256 replacer = shipsForSale[shipsForSale.length - 1]; uint256 pos = indexes[_spaceshipId]; shipsForSale[pos] = replacer; indexes[replacer] = pos; shipsForSale.length--; - + + // Reembolsamos el sobrante uint refund = msg.value - spaceshipPrices[_spaceshipId]; - if(refund > 0) + if (refund > 0) msg.sender.transfer(refund); } - function withdrawBalance() external onlyOwner { + /// @notice Retirar balance por compras hechas + function withdrawBalance() public onlyOwner { owner.transfer(address(this).balance); } - function getAttributes(uint _spaceshipId) public view returns ( - uint8 energy, - uint8 lasers, - uint8 shield - ){ - Spaceship storage s = spaceships[_spaceshipId]; - - energy = s.energy; - lasers = s.lasers; - shield = s.shield; - } - - - // Obtain metadata - + /// @notice Obtener metadata + /// @param _spaceshipId Id del token + /// @return Direccion desde donde obtener la metadata function tokenURI(uint256 _spaceshipId) public view returns (string) { Spaceship storage s = spaceships[_spaceshipId]; return strConcat("https://ipfs.io/ipfs/", string(s.metadataHash)); } + /// @notice Concatenar strings + /// @dev La concatenacion por strings por ahora debe hacerse manual o usando librerias + /// @param _a Primer string + /// @param _b Segundo string + /// @return String concatenado function strConcat(string _a, string _b) private returns (string) { bytes memory _ba = bytes(_a); bytes memory _bb = bytes(_b); string memory ab = new string(_ba.length + _bb.length); bytes memory bab = bytes(ab); uint k = 0; - for (uint i = 0; i < _ba.length; i++) bab[k++] = _ba[i]; - for (i = 0; i < _bb.length; i++) bab[k++] = _bb[i]; + + for (uint i = 0; i < _ba.length; i++) + bab[k++] = _ba[i]; + + for (i = 0; i < _bb.length; i++) + bab[k++] = _bb[i]; + return string(bab); }