CryptoFace
Open development: Blockchain Avatars
Slack Status
face
eyes
hair
clothes
backs
 
 

please wait...

Are you sure?

The all current changes will be lost.

Ok
Cancel
Ok
Waiting for blockchain transaction processing...
Your balance:
Avatars number you can create:
Ok
Cancel
*You can use Metamask extension for better security
Close
Live contract
Recent faces
Specification
our smart contract is open for your review and recommendations
pragma solidity ^0.4.3;

contract Avatars {
    
    uint avatarsCount = 0;

    struct Avatar {
        uint id;
        
        /**
         * Avatar's owner.
         */ 
        address owner;
        
        /**
         * First byte is gender, 1 / 0 for male / female. 
         * Then every byte describe choosen avatar part. 
         * The order is : backs, clothes, ears, eyebrows, eyesfront, eyesiris, faceshape, glasses, hair, mouth, nose, beard, mustache. 
         */ 
        bytes32 shapes;
        
        /**
         * Each 3 bytes describe color for 5 first shapes.
         */
        bytes32 colorsPrimary;
        
        /**
         * Each 3 bytes describe color for 8 last shapes.
         */
        bytes32 colorsSecondary;
        
        /**
         * Each byte describes up/down position for every shape. 
         * High nibble depicts the sign of number, 1 - up, 0 - down.
         * Low nibble shows number of steps to move the shape in selected direction.
         * 
         */
        bytes32 positions;
    }
    
    mapping(bytes32 => Avatar) avatars;
    
    /**
     * Stores an avatar on the blockchain.
     * Throws if avatar with such shapes combination is already exists.
     * 
     * @param shapes - hex string, depicts gender and combinations of shapes.
     * @param colorsPrimary - hex string, colors of the first 5 shapes.
     * @param colorsSecondary - hex string, colors of the last 8 shapes.
     * @param positions - hex string, up/down positions of all shapes
     * 
     * @return Hash of the avatar.
     */
    function register(string shapes, string colorsPrimary, string colorsSecondary, string positions) returns (bytes32 avatarHash) {
        bytes32 shapesBytes = strToBytes(shapes);
        bytes32 colorsPrimaryBytes = strToBytes(colorsPrimary);
        bytes32 colorsSecondaryBytes = strToBytes(colorsSecondary);
        bytes32 positionsBytes = strToBytes(positions);

        // unique by shapes composition
        bytes32 hash = sha3(shapes);

        Avatar memory existingAvatar = avatars[hash];
        if (existingAvatar.id != 0)
            throw;
        
        Avatar memory avatar = Avatar(++avatarsCount, msg.sender, 
            shapesBytes,
            colorsPrimaryBytes,
            colorsSecondaryBytes,
            positionsBytes);

        avatars[hash] = avatar;
        return hash;
    }
    
    /**
     * Returns an avatar by it's hash.
     * Throws if avatar is not exists.
     */ 
    function get(bytes32 avatarHash) constant returns (bytes32 shapes, bytes32 colorsPrimary, bytes32 colorsSecondary, bytes32 positions) {
        Avatar memory avatar = getAvatar(avatarHash);
        
        shapes = avatar.shapes;
        colorsPrimary = avatar.colorsPrimary;
        colorsSecondary = avatar.colorsSecondary;
        positions = avatar.positions;
    }
    
    /**
     * Returns an avatar owner address by avatar's hash.
     * Throws if avatar is not exists.
     */ 
    function getOwner(bytes32 avatarHash) constant returns (address) {
        Avatar memory avatar = getAvatar(avatarHash);
        return avatar.owner;
    }
    
        
    /**
     * Returns if avatar of the given hash exists.
     */ 
    function isExists(bytes32 avatarHash) constant returns (bool) {
        Avatar memory avatar = avatars[avatarHash];
        if (avatar.id == 0)
            return false;
            
        return true;
    }
    
    /**
     * Returns an avatar by it's hash.
     * Throws if avatar is not exists.
     */ 
    function getAvatar(bytes32 avatarHash) private constant returns (Avatar) {
        Avatar memory avatar = avatars[avatarHash];
        if (avatar.id == 0)
	       throw;
	       
        return avatar;
    }
    
    /**
     * @dev Low level function.
     * Converts string to bytes32 array.
     * Throws if string length is more than 32 bytes
     * 
     * @param str string
     * @return bytes32 representation of str
     */
    function strToBytes(string str) constant private returns (bytes32 ret) {
        // var g = bytes(str).length;
        // if (bytes(str).length > 32) throw;
        
        assembly {
            ret := mload(add(str, 32))
        }
    } 
}
This is a part of the crypto.camp development.
We would like to hear your thoughts about everything: texts, code, design, content, etc.
visit our main site to learn more