Skip to content

Instantly share code, notes, and snippets.

@usersolidity
Last active December 26, 2019 01:01
Show Gist options
  • Save usersolidity/cd1ed3a36454e81f4c1a4f8229a2f7e8 to your computer and use it in GitHub Desktop.
Save usersolidity/cd1ed3a36454e81f4c1a4f8229a2f7e8 to your computer and use it in GitHub Desktop.
Votación
pragma solidity >=0.4.22 <0.7.0;
/*
solcjs --bin Contrato.sol
//solc --userdoc --devdoc ex1.sol
/*Structure Proposal*/
contract Ballot{
struct Voter{
uint weigth; //peso del voto de cada Votante. Al ser posible la delegación tiene sentido este peso
bool voted; // true si votó false en caso contrario
address delegate; //dirección de a quien se delega el voto.
uint vote; // identificador de la pruesta por la cual votó el votante
}
struct Proposal{
bytes32 name; //nombre de la propuesta
uint voteCount; //peso del voto de cada Votante. Al ser posible la delegación tiene sentido este peso
}
address public chairperson; //dueño de la votacion
mapping (address => Voter) public voters; //lista votantes
Proposal[] public proposals; //lista de propuestas
///@author userSolidity
/// @notice constructor del Contrato donde se le pasan el conjunto de nombres de propuestas
/// @dev constructor del contrato dueño chairpairson (msg.sender)
///recorre la lista que se pasa por parámetro, se recorre la lista de propuestas y se inicializa el nombre de la misma
// y el valor de voteCount (cantidad de votos a 0)
//Why string instead of bytes32?
///Use string for arbitrary-length string (UTF-8) data that's longer than 32 bytes. Frontends can decode a long string easier using methods like web3.toAscii or UTF-8 (when issues are fixed), instead of implementing the logic of UTF-8 decoding a series of bytes32.
/// @param proposalNames lista de nombres de las propuestas
/// @notice para probar desde Remix : ["0x63616e6469646174653100000000000000000000000000000000000000000000","0x6332000000000000000000000000000000000000000000000000000000000000","0x6333000000000000000000000000000000000000000000000000000000000000"]
/// notar que podrìíia instanciarse con vacio tambien
constructor(bytes32[] memory proposalNames) public {
chairperson = msg.sender;//el dueño de la creación es creador
voters[chairperson].weigth = 1; //le da derecho a votar al owner
//notar que esto es porque no se puede asignar el autovoto mas adelante en los permisos. recorre la lista de nombres y los va asignando a la lista
for (uint i = 0; i < proposalNames.length; i++){
proposals.push(Proposal({
name: proposalNames[i],
voteCount: 0
}));
}
}
/*_____________________________________________*/
// Scenario 1: Dar Derecho a Voto
// Como Chairman
// dado el escenario de votación
// cuando comience la subasta
// entonces se deben inicializar las propuestas
// y se deben asignar el derecho de votación al votante.
/*_____________________________________________*/
//TODO PASAR A UN ARCHIVO DE CONTANTES
string constant ERROR_ONLYOWNER = "Solo el dueño puede darDerecho a voto";
string constant ERROR_ONLYONEVOTE = "The voter already voted";
string constant ERROR_WEIGTHOFVOTE = " No Vote Weigth";
//@author userSolidity
/// @notice el derecho a voto se asigna de a un votante
/// @dev asignar en la lista de votantes,en la posición del voter el peso de 1 para habilitar la votación
/// @param voter dirección del votante a darle el derecho de votación
/// return -
// pre solo el chairman puede dar el derecho a votar
// pre el votante no puede haber votado
// post se da el peso del voto = 1 al votante para poder realizar la votacion
function giveRightToVote(address voter) public isOnlyOwner{
require(!voters[voter].voted,ERROR_ONLYONEVOTE); // pasarlos a modifier
require(voters[voter].weigth == 0, ERROR_WEIGTHOFVOTE);
voters[voter].weigth = 1;
}
//TODO Categorizar para despues ver todos los modificadores
modifier isOnlyOwner (){
require(chairperson == msg.sender,ERROR_ONLYOWNER);
_;
}
/*_____________________________________________*/
// Scenario 2: Delegar Voto
// Como votante
// dado el escenario de votación
// cuando despues de comenzada la misma
// entonces debo poder delegar mi voto a otro votante
// y se deben asignar el derecho de votación que tenía al delegado
/*_____________________________________________*/
///@author userSolidity
///@notice se delega la votación por parte de un votante
///@dev
///@param _to dirección del votante a delegar el voto
///return
///visibilidad publica
///pre el votante no votó previamente
///pre el votante no se puede delegar el voto a él mismo
///pre no se presente un loop de delegación, es decir que uno delegue a otro y ese otro también lo delegue
///post se asigna la delegación con el peso de votación que tiene el votante.
/*_____________________________________________*/
string constant ERROR_ALREADYVOTED= "You already voted";
string constant ERROR_LOOPDELEGATION = "Found loop delegation";
address constant NULL_ADDRESS = address(0);
function delegate(address _to) public {
Voter storage sender = voters[msg.sender];
require(!sender.voted, ERROR_ALREADYVOTED);
require(_to != msg.sender, ERROR_NOTSELFDELEGATION);
//loop check que
while(voters[_to].delegate != NULL_ADDRESS){ //recorre toda la colección de votantes y ve quien a quien fueron delegados
address other = voters[_to].delegate; //address de la persona a quien se delega. Notar que en el ejemplo de solidity
//Avoid assigning to function parameters es decir que cuando pone to= voters[to].delegate lo esta reasignando
require(other!=msg.sender, ERROR_LOOPDELEGATION);
}
sender.voted = true;
sender.delegate = _to;
Voter storage delegate_ = voters[_to];
//hay dos posibles escenarios que al que se le delegó el voto votó o no .
if( delegate_.voted){
//Si votó , se obtiene a que propuesta votó y se incremente el peso del voto
//notar que si bien queda un poco incosistente o sea el peso sigue quedando en el votante
proposals[delegate_.vote].voteCount += sender.weigth;
}else{
//Si no votó, se agrega el peso al delegado para el voto.
delegate_.weigth += sender.weigth;
}
sender.weigth = 0; // agregaría esto para que quede mas consistente
}
string constant ERROR_NOTSELFDELEGATION = "Self delegation is disallowed";
/*_____________________________________________*/
// Scenario 3: Votar
// Como votante
// dado el escenario de votación
// cuando despues de comenzada la misma
// entonces debo poder votar a una Propuesta
// y se deben quedar sin la posibilidad de poder volver a votar.
/*_____________________________________________*/
///@author userSolidity
///@notice se ejerce el derecho a voto
///@dev se asigna la votación
///@param _proposal identificador de la propuesta de la lista de propuestas de Proposals
///return -
///visibilidad publica
///pre el votante no votó previamente
///pre tenga un peso de votación > 0
///post se incrementa la cantidad de votos de esa propuesta
///post se actualiza el estado de la votación del votante
///post el peso de votación queda en 0.
/*_____________________________________________*/
//TODO Controlar que el id de la propuesta este en el rango con un require
function vote(uint _proposal) public {
Voter storage sender = voters[msg.sender];
require(!sender.voted,"ERROR_ONLYONEVOTE");
require(sender.weigth != 0, ERROR_WEIGTHOFVOTE);
sender.voted = true;
sender.vote = _proposal;
proposals[_proposal].voteCount += sender.weigth;
sender.weigth = 0;
}
}
/*_____________________________________________*/
//User history
// Scenario 1:
// As an [actor]
// Given [context]
// And [some more context]
// When [event]
// Then [outcome]
// And [another outcome]
/*_____________________________________________*/
///@author userSolidity
///@notice Es una versión inicial de prueba de estructura
///@dev All function calls are currently implemented without side effects
///@param
///@return
/*_____________________________________________*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment