¿Cómo garantizar un valor único en el mapeo (como un apodo único para la dirección)?

Estoy creando un contrato inteligente donde quiero que cada cuenta tenga un apodo/nombre único adjunto a la dirección. Aquí hay un código de ejemplo:

mapping (address => string) members;
function isMember() constant returns bool() {
    return members[msg.sender] != "";
}

function register(string _name) {
    if (members[msg.sender] != "") {
        throw("Already registered");
    }

    /* now check if name is already taken...
    foreach (name : members) {
        if (name == _name) {
            throw();
        }
    }
    */
}

¿Es posible utilizar mappingpara garantizar que cada apodo/nombre ingresado en los miembros sea único? ¿O mi mejor curso de acción sería crear otra propiedad que solo contenga una lista de nicks que ya están en uso? ¿Cuál es el mejor enfoque desde el punto de vista del uso de gas (considerando que iterar listas enormes debería incurrir en costos más altos)?

Respuestas (1)

Cambié su stringpara bytes32evitar un desafío adicional de hacer esto con cadenas, para mayor claridad.

pragma solidity ^0.4.20;

contract Checker {

    mapping (address => bytes32) members; // using bytes32 instead of string
    mapping (bytes32 => bool) isTaken;

    function isMember(address member) public view returns(bool isIndeed) {
        return (members[member] != 0);
    }

    function isSet(bytes32 name) public view returns(bool isIndeed) {
        return (isTaken[name]);
    }

    function register(bytes32 _name) public returns(bool success){
        require(members[msg.sender] == "");
        require(!isSet(_name));
        members[msg.sender] = _name;
        isTaken[_name] = true;
        return true;
    }

}

Espero eso ayude.

¿No debería ser "isNotSet" en lugar de "isSet" para la verificación?
No me parece. El valor predeterminado isTakenes false, por lo que no se toma . Entonces, si isTaken[index] == falseentonces isSet == false. Es un pequeño garabato rápido, así que si hay un error, explíquelo. Gracias.
pero no requerirá (isSet[_name]) fallar si isSet devuelve falso?
Buena atrapada. Ahora lo veo. Debe ser require(!isSet(..., no establecer. Lo arreglé en el ejemplo.