Skip to content

Instantly share code, notes, and snippets.

@elranu
Created June 21, 2019 20:49
Show Gist options
  • Save elranu/6634e959bd91dc207aa2d2b0147198b2 to your computer and use it in GitHub Desktop.
Save elranu/6634e959bd91dc207aa2d2b0147198b2 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=undefined&optimize=false&gist=
pragma solidity 0.5.4;
contract IHasAdmin {
function isAdmin(address accountAddress) public view returns (bool);
}
pragma solidity 0.5.4;
import "./SecuredStoppable.sol";
import "./StringUtils.sol";
contract LicenciaNacionalDeConducir is SecuredStoppable {
struct Licencia {
uint256 tramite;
bool estado;
uint32 otorgamiento;
uint32 vencimiento;
string clase;
}
struct Licenciado {
bool registered;
uint256 dni;
string nombres;
string apellidos;
string domicilio;
uint32 fechaDeNacimiento;
Licencia[] licencias;
}
mapping(uint256 => Licenciado) private _licenciados;
function emitirLicencia(uint256 dni, string memory nombres, string memory apellidos, string memory domicilio,
uint32 fechaDeNacimiento, uint256 tramite, uint32 fechaOtorgamiento,
uint32 fechaDeVencimiento, string memory clase) public onlyAdmin onlyEnabled
{
require(dni > 0, "El dni debe ser mayor a 0");
crearOActualizarLicenciado(dni, nombres, apellidos, domicilio, fechaDeNacimiento);
Licencia memory licencia = Licencia(tramite, true, fechaOtorgamiento, fechaDeVencimiento, clase);
_licenciados[dni].licencias.push(licencia);
}
function validarEstado(uint256 dni) public view returns (bool)
{
if(!_licenciados[dni].registered) return false;
uint index = _licenciados[dni].licencias.length-1;
return _licenciados[dni].licencias[index].estado;
}
function revocarLicencia(uint256 dni) public {
require(_licenciados[dni].registered, "No se puede revocar una lincencia que no existe");
uint index = _licenciados[dni].licencias.length-1;
_licenciados[dni].licencias[index].estado = false;
}
function restablecerLicencia(uint256 dni) public {
require(_licenciados[dni].registered, "No se puede restablecer una lincencia que no existe");
uint index = _licenciados[dni].licencias.length-1;
_licenciados[dni].licencias[index].estado = true;
}
function obtenerLicenciado(uint256 dni) public view returns (string memory, string memory, string memory, uint32) {
require(_licenciados[dni].registered, "No se puede revocar una lincencia que no existe");
return (_licenciados[dni].nombres, _licenciados[dni].apellidos, _licenciados[dni].domicilio, _licenciados[dni].fechaDeNacimiento);
}
function crearOActualizarLicenciado(uint256 dni, string memory nombres, string memory apellidos,
string memory domicilio, uint32 fechaDeNacimiento) private
{
if(_licenciados[dni].registered)
{
uint index = _licenciados[dni].licencias.length-1;
require(_licenciados[dni].fechaDeNacimiento == fechaDeNacimiento, "La fecha de nacimiento es diferente a la original");
require(_licenciados[dni].licencias[index].estado == true, "No se puede renovar una licencia cuando la última esta rovcada");
if(!StringUtils.equal(_licenciados[dni].nombres,nombres)) _licenciados[dni].nombres = nombres;
if(!StringUtils.equal(_licenciados[dni].apellidos, apellidos)) _licenciados[dni].apellidos = apellidos;
if(!StringUtils.equal(_licenciados[dni].domicilio, domicilio)) _licenciados[dni].domicilio = domicilio;
}
else
{
_licenciados[dni].registered = true;
_licenciados[dni].nombres = nombres;
_licenciados[dni].apellidos = apellidos;
_licenciados[dni].domicilio = domicilio;
_licenciados[dni].fechaDeNacimiento = fechaDeNacimiento;
}
}
}
{
"accounts": {
"account{0}": "0x18e6f69d632b81e2ee4bb2af462fe8532599ee39"
},
"linkReferences": {},
"transactions": [
{
"timestamp": 1561135704695,
"record": {
"value": "0",
"parameters": [
"28111000"
],
"to": "created{undefined}",
"name": "revocarLicencia",
"inputs": "(uint256)",
"type": "function",
"from": "account{0}"
}
},
{
"timestamp": 1561143881084,
"record": {
"value": "0",
"parameters": [
"28111002"
],
"to": "created{undefined}",
"name": "revocarLicencia",
"inputs": "(uint256)",
"type": "function",
"from": "account{0}"
}
},
{
"timestamp": 1561143906719,
"record": {
"value": "0",
"parameters": [
"28111002"
],
"to": "created{undefined}",
"name": "revocarLicencia",
"inputs": "(uint256)",
"type": "function",
"from": "account{0}"
}
},
{
"timestamp": 1561144643438,
"record": {
"value": "0",
"parameters": [
"28000111",
"Karina Lurdes",
"Rabanito ",
"Calle AzulyOro 11",
"19800505",
"3343243232",
"20190615",
"20220615",
"B1"
],
"to": "created{undefined}",
"name": "emitirLicencia",
"inputs": "(uint256,string,string,string,uint32,uint256,uint32,uint32,string)",
"type": "function",
"from": "account{0}"
}
}
],
"abis": {}
}
pragma solidity 0.5.4;
import "./IHasAdmin.sol";
contract Secured is IHasAdmin {
uint256 private _count;
mapping(address => bool) private _admins;
constructor() public {
_count = 1;
_admins[msg.sender] = true;
}
modifier onlyAdmin() {
require(_admins[msg.sender]);
_;
}
function isAdmin(address accountAddress) public view returns (bool)
{
return _admins[accountAddress];
}
function addAdmin(address accountAddress) public onlyAdmin {
require(!_admins[accountAddress]);
_count++;
_admins[accountAddress] = true;
}
function removeAdmin(address accountAddress) public onlyAdmin {
require(_count > 1);
require(_admins[accountAddress]);
_count--;
delete _admins[accountAddress];
}
function transferAdmin(address fromAddress, address toAddress) public onlyAdmin {
require(_admins[fromAddress]);
require(!_admins[toAddress]);
delete _admins[fromAddress];
_admins[toAddress] = true;
}
}
pragma solidity 0.5.4;
import "./Secured.sol";
contract SecuredStoppable is Secured {
bool private _isEnabled;
modifier onlyEnabled() {
require(_isEnabled);
_;
}
function isEnabled() public view returns (bool) {
return _isEnabled;
}
function setEnabled() public onlyAdmin {
require(!_isEnabled);
_isEnabled = true;
}
function setDisabled() public onlyAdmin {
require(_isEnabled);
_isEnabled = false;
}
}
pragma solidity 0.5.4;
library StringUtils {
/// @dev Does a byte-by-byte lexicographical comparison of two strings.
/// @return a negative number if `_a` is smaller, zero if they are equal
/// and a positive numbe if `_b` is smaller.
function compare(string memory _a, string memory _b) public pure returns (int) {
bytes memory a = bytes(_a);
bytes memory b = bytes(_b);
uint minLength = a.length;
if (b.length < minLength) minLength = b.length;
//@todo unroll the loop into increments of 32 and do full 32 byte comparisons
for (uint i = 0; i < minLength; i ++)
if (a[i] < b[i])
return -1;
else if (a[i] > b[i])
return 1;
if (a.length < b.length)
return -1;
else if (a.length > b.length)
return 1;
else
return 0;
}
/// @dev Compares two strings and returns true iff they are equal.
function equal(string memory _a, string memory _b) public pure returns (bool) {
return compare(_a, _b) == 0;
}
/// @dev Finds the index of the first occurrence of _needle in _haystack
function indexOf(string memory _haystack, string memory _needle) public pure returns (int)
{
bytes memory h = bytes(_haystack);
bytes memory n = bytes(_needle);
if(h.length < 1 || n.length < 1 || (n.length > h.length))
return -1;
else if(h.length > (2**128 -1)) // since we have to be able to return -1 (if the char isn't found or input error), this function must return an "int" type with a max length of (2^128 - 1)
return -1;
else
{
uint subindex = 0;
for (uint i = 0; i < h.length; i ++)
{
if (h[i] == n[0]) // found the first char of b
{
subindex = 1;
while(subindex < n.length && (i + subindex) < h.length && h[i + subindex] == n[subindex]) // search until the chars don't match or until we reach the end of a or b
{
subindex++;
}
if(subindex == n.length)
return int(i);
}
}
return -1;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment