Skip to content

Instantly share code, notes, and snippets.

@ernestognw
Created August 27, 2018 15:48
Show Gist options
  • Save ernestognw/7182707c5fb6d84a55c1a14f8c290e5f to your computer and use it in GitHub Desktop.
Save ernestognw/7182707c5fb6d84a55c1a14f8c290e5f to your computer and use it in GitHub Desktop.
pragma solidity ^0.4.24;
// Agro Market Place
// Este es un contrato para abrir subastas de productos agropecuarios
// basados en Tokens de compra.
// ¿Cómo funciona?
// Existen 3 vistas de usuario:
// - El administrador o publicante de la subasta (quien deploya el contrato)
// - El productor, quien coloca sus cosechas en el contrato
// - El comprador, quien hace ofertas por los productos
// El ciclo de vida del contrato se divide en 3 etapas
// 1.- Primero, se deploya el contrato, y los compradores pueden comprar tokens,
// mientras que los productores pueden colocar sus cosechas en la plataforma.
// 2.- Después, el administrador inicia la subasta, y ahora los compradores pueden colocar
// ofertas, y poseer la cosecha deseada sólo si han hecho la oferta más alta
// (Si alguien gana una cosecha ofreciendo más, los tokens pasados son devueltos al
// ofertante anterior)
// 3.- El administrador cierra la subasta, y el productor puede transferir sus tokens
// ganados a su cuenta, y luego canjearlos por ether.
contract AgroMarket {
//Defino variables
bool public isAuctionStarted; // Determina si ya inició la subasta
bool public isAuctionFinished; // Determina si ya terminó la subasta
address marketPlace; // Dirección del publicante de la subasta
uint price = 1 finney; // Precio por token
mapping (address => batch) public batches; // Lista de cosechas por usuario (productor)
mapping (address => uint) public agroTokens; // Lista de tokens por comprador
// Estructura de datos para una cosecha publicada
struct batch {
string name;
uint kilograms;
uint price;
address finalOwner;
}
constructor(){
marketPlace = msg.sender;
isAuctionStarted = false;
isAuctionFinished = false;
}
//Defino modificadores
// Sólo puede hacerlo el publicante
modifier onlyMarketPlace(){
if(marketPlace != msg.sender)
revert();
_;
}
// Sólo puede ocurrir si no ha empezado la subasta
modifier onlyIfNotStarted(){
if(isAuctionStarted == true)
revert();
_;
}
// Sólo puede ocurrir si no ha terminado la subasta
modifier onlyIfNotFinished(){
if(isAuctionFinished == true)
revert();
_;
}
// Sólo puede ocurrir si ya ha comenzado la subasta
modifier onlyIfStarted(){
if(isAuctionStarted == false)
revert();
_;
}
// Sólo puede ocurrir si ya terminó la subasta
modifier onlyIfFinished(){
if(isAuctionFinished == false)
revert();
_;
}
//Defino funciones
// Comprar tokens (antes de que termine la subasta)
function buyTokens(uint _tokensToBuy) payable onlyIfNotFinished(){
uint amount = _tokensToBuy * price;
if (amount < msg.value){
revert();
}
if (msg.value != amount){
msg.sender.transfer(msg.value - amount);
}
agroTokens[msg.sender] += _tokensToBuy;
}
//Publicar una cosecha (antes de iniciar la subasta)
function placeBatch(uint _kilograms, string _name) onlyIfNotStarted(){
batches[msg.sender].name = _name;
batches[msg.sender].kilograms = _kilograms;
}
// Empezar la subasta (sólo puede hacerlo el publicante)
function startAuction() onlyMarketPlace() {
isAuctionStarted = true;
}
// Comprar una cosecha (sólo se puede si ya se empezó la subasta)
function buyBatch(uint _offer, address _batchToBuy) onlyIfStarted(){
if(_offer < batches[_batchToBuy].price || _offer > agroTokens[msg.sender]){
revert();
}
if (batches[_batchToBuy].finalOwner != 0){
agroTokens[batches[_batchToBuy].finalOwner] += batches[_batchToBuy].price;
}
agroTokens[msg.sender] -= _offer;
batches[_batchToBuy].price = _offer;
batches[_batchToBuy].finalOwner = msg.sender;
}
//Finalizar la subasta
function finishAuction() onlyMarketPlace() {
isAuctionFinished = true;
}
//Transferir ganancias al productor
function transferProfit() onlyIfFinished(){
if (batches[msg.sender].price == 0){
revert();
}
agroTokens[msg.sender] += batches[msg.sender].price;
batches[msg.sender].price = 0;
}
// Canjear sus tokens por ether
function refundTokens(uint _tokensToRefund) payable{
if (agroTokens[msg.sender] < _tokensToRefund) {
revert();
}
agroTokens[msg.sender] -= _tokensToRefund;
msg.sender.transfer(_tokensToRefund * price);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment