In this first part of the tutorial we are going to create the smart contract that handles the registration of users; then we are going to deploy the smart contract to the blockchain using Truffle.

If you missed the introduction and you want to know what this tutorial is about, please read the intro.

This part of tutorial is divided into three sections:

  1. Set up of the truffle environment.
  2. Smart contract development.
  3. Deploy the smart contract to the blockchain.

Note before you start: if you are using Windows you must use Power Shell as terminal.

Set up of the truffle environment

First let’s create the project folder called ethereum-vuejs-dapp, then open the terminal in the folder just created and run the following command:

$ truffle init

This command initializes the truffle project and creates the following items:

  • contracts: folder containing the smart contracts written in Solidity.
  • migrations: folder containing the files that take care of the deployment.
  • test: folder containing the files for testing the smart contracts.
  • truffle.js: file that contains the list of blockchain networks where you can deploy your contracts.

Let’s add the details of our blockchain network to the file truffle.js. So first start Ganache and, once it runs, check the host and the port as shown below.

Ethereum Vue - Ganache host and port settings

Now paste the following code in truffle.js:

module.exports = {
	networks: {
		ganache: {
			host: "127.0.0.1",
			port: 7545,
			network_id: "*"
		}
	}
};

IMPORTANT: make sure that the host and the port of the code pasted in truffle.js match with the settings displayed in Ganache.

Smart contract development

As described in the introduction, the main features of our dApp are:

  • Let users resister their profiles.
  • The owner of a profile is the only person who can edit his own information.

The following information of a user’s profile is going to be stored in the blockchain:

  • Name of the owner.
  • Status.
  • When the profile has been created and updated.

What we need is to store the list of the users and associate each user with an account address (or wallet address).

The smart contract must provide a set of functions that:

  • Let the user register his profile.
  • Let the owner of a profile update his details.
  • Get the list of users and their details.
  • Check if the user is already registered.

Below is the code of the smart contract (you can find it on GitHub as well).

pragma solidity ^0.4.21;


contract Users {
    // data structure that stores a user
    struct User {
        string name;
        bytes32 status;
        address walletAddress;
        uint createdAt;
        uint updatedAt;
    }

    // it maps the user's wallet address with the user ID
    mapping (address => uint) public usersIds;

    // Array of User that holds the list of users and their details
    User[] public users;

    // event fired when an user is registered
    event newUserRegistered(uint id);

    // event fired when the user updates his status or name
    event userUpdateEvent(uint id);


    // Modifier: check if the caller of the smart contract is registered
    modifier checkSenderIsRegistered {
    	require(isRegistered());
    	_;
    }


    /**
     * Constructor function
     */
    function Users() public {
        // NOTE: the first user MUST be emtpy
        addUser(0x0, "", "");

        // Some dummy data
        addUser(0x333333333333, "Leo Brown", "Available");
        addUser(0x111111111111, "John Doe", "Very happy");
        addUser(0x222222222222, "Mary Smith", "Not in the mood today");
    }


    /**
     * Function to register a new user.
     *
     * @param userName 		The displaying name
     * @param status        The status of the user
     */
    function registerUser(string userName, bytes32 status) public
    returns(uint)
    {
    	return addUser(msg.sender, userName, status);
    }


    /**
     * Add a new user. This function must be private because an user
     * cannot insert another user on behalf of someone else.
     *
     * @param wAddr 		Address wallet of the user
     * @param userName		Displaying name of the user
     * @param status    	Status of the user
     */
    function addUser(address wAddr, string userName, bytes32 status) private
    returns(uint)
    {
        // checking if the user is already registered
        uint userId = usersIds[wAddr];
        require (userId == 0);

        // associating the user wallet address with the new ID
        usersIds[wAddr] = users.length;
        uint newUserId = users.length++;

        // storing the new user details
        users[newUserId] = User({
        	name: userName,
        	status: status,
        	walletAddress: wAddr,
        	createdAt: now,
        	updatedAt: now
        });

        // emitting the event that a new user has been registered
        emit newUserRegistered(newUserId);

        return newUserId;
    }


    /**
     * Update the user profile of the caller of this method.
     * Note: the user can modify only his own profile.
     *
     * @param newUserName	The new user's displaying name
     * @param newStatus 	The new user's status
     */
    function updateUser(string newUserName, bytes32 newStatus) checkSenderIsRegistered public
    returns(uint)
    {
    	// An user can modify only his own profile.
    	uint userId = usersIds[msg.sender];

    	User storage user = users[userId];

    	user.name = newUserName;
    	user.status = newStatus;
    	user.updatedAt = now;

    	emit userUpdateEvent(userId);

    	return userId;
    }


    /**
     * Get the user's profile information.
     *
     * @param id 	The ID of the user stored on the blockchain.
     */
    function getUserById(uint id) public view
    returns(
    	uint,
    	string,
    	bytes32,
    	address,
    	uint,
    	uint
    ) {
    	// checking if the ID is valid
    	require( (id > 0) || (id <= users.length) );

    	User memory i = users[id];

    	return (
    		id,
    		i.name,
    		i.status,
    		i.walletAddress,
    		i.createdAt,
    		i.updatedAt
    	);
    }


    /**
     * Return the profile information of the caller.
     */
    function getOwnProfile() checkSenderIsRegistered public view
    returns(
    	uint,
    	string,
    	bytes32,
    	address,
    	uint,
    	uint
    ) {
    	uint id = usersIds[msg.sender];

    	return getUserById(id);
    }


    /**
     * Check if the user that is calling the smart contract is registered.
     */
    function isRegistered() public view returns (bool)
    {
    	return (usersIds[msg.sender] != 0);
    }


    /**
     * Return the number of total registered users.
     */
    function totalUsers() public view returns (uint)
    {
        return users.length;
    }

}

Deploy the smart contract to the blockchain

It’s time to deploy the smart contract to the blockchain! Make sure that your blockchain is running and the file truffle.js is properly set as explained before.

Go to the folder migration and create a file called 2_migrate_users.js.
The migration filename has a number as prefix and a description as suffix. The numbered prefix is required in order to record whether the migration ran successfully and the suffix just describes what the file is about.

Copy and paste the following code inside the file 2_migrate_users.js:

var Users = artifacts.require("./Users.sol");

module.exports = function(deployer) {
    deployer.deploy(Users);
};

Now let’s open the terminal in the project folder ethereum-vuejs-dapp and run the command:

$ truffle console ––network ganache

Once the truffle console is running, type the following command:

>> migrate ––reset ––compile-all

This command compiles all smart contracts and deploys the smart contracts to the blockchain.

If everything went fine, on the console you should see a message as follows:

Compiling .\contracts\Migrations.sol...
Compiling .\contracts\Users.sol...
Writing artifacts to .\build\contracts

Using network 'ganache'.

Running migration: 1_initial_migration.js
  Replacing Migrations...
  ... 0x18edd24941e9b7edfae4966af544d5413e31622da90cecae2d3153635a7ffba2
  Migrations: 0xcac26201ab3b38d2f0f9b56f81a8897dfe036da6
Saving successful migration to network...
  ... 0x125c70f37e143b13acb4827dda16e8571758402db81c08a3a2ae27573910105f
Saving artifacts...
Running migration: 2_migrate_users.js
  Replacing Users...
  ... 0x043c2cf363da321b8a1ec06672f12fd794bf894342fa51100250bc6975806385
  Users: 0x782b9ce19fe792ed3c4ccbfb439ab59ddc5369f2
Saving successful migration to network...
  ... 0x9e56386f94093c4f56f6b84190503376363f15a6d16661e7bfaa8fefe1b4be1f
Saving artifacts...
truffle(ganache)>

After the deployment you will see on Ganache some new transactions in the transaction list.

Ethereum Vue - Ganache transactions

In the second part of the tutorial we will build the dApp interface using Vue JS and interact with the smart contracts through the interface.

The second part of the tutorial is on the way… see you soon! _