Storing data in a database is an integral part of any software application.Whoever has the control of that database is a master of that data. Blockchain technology stores data into the block inside blockchain network.So whenever some node syncs to the network they will get the copy of the data in the block. So there is no particular master of the data in this technology.

In this tutorial, we will write a smart contract(I will explain this further) for persisting user data on the blockchain. We will use python web3(python library for web3) for making and deploying smart contract. Once we have deployed smart contract on the blockchain. We will interact with smart contract using flask API to store some data/information. We are storing that on blockchain so that it will be immutable.

“Ethereum smart contract deployment flow” by Neha Ghogale

Requirements:

Python 3.6

I nstallation:

Create a python virtual environment.

Virtualenv keeps your Python packages in a virtual environment localized to your project, instead of forcing you to install your packages system-wide.

$ virtualenv -p /usr/bin/python3.6 venv

$ source venv/bin/activate

2. Now we need ethereum test chain like ganache.

Ganache is a personal blockchain for Ethereum development you can use to deploy contracts, develop your applications, and run tests.

$ npm install -g ganache-cli

3. Install python web3.

Web3.py is a python library for interacting with ethereum. Its API is derived from the Web3.js Javascript API and should be familiar to anyone who has used web3.js.

$ pip3 install web3

4. Flask:

Flask is a microframework for Python

$ pip3 install flask

5. Flask Restful

Flask-RESTful is an extension for Flask that adds support for quickly building REST APIs.

$ pip3 install flask-restful

6. Flask Marshmallow

Flask marshmallow is an object serialization/deserialization library

$ pip3 install flask-marshmallow

Start Ethereum Test blockchain server.

To deploy smart contract we should start test ethereum server. We are using ganache for testing. Type below command in terminal.

$ ganache-cli

Ganache Account Address

Ganache gives us 10 default test accounts with 100 fake ethers in each account for transaction. We will use these accounts for deploying and setting values in contracts.

Ganache port

We can see the gas prize and limit along with host:port on which ganache is deployed. We will need this while deploying contract.

Create user.sol file

Now we will write the smart contract in solidity.Solidity is the language to write smart contract on ethereum.Smart contract consists of data which we are going to store on blockchain with optional validation functions on the data and getter, setter method for accessing data.

For example, to make an attendance register on blockchain you will have an array of user objects.It will have the getter, setter method for accessing user.Since each user can mark her attendance only once per day, you need a validation function to check it.The smart contract is very similar to the application which we normally develop in any other language.

In below file, we are building simple user contract with the getter, setter functions.

Declare solidity compiler version in .sol file.

pragma solidity ^0.4.21;

To know which compiler version used

$ solidity — version

2. Import library file. we should use libraries for common utility functions.Libraries are only compiled once and used again and again(click here for some good library resources).

import “stringUtils.sol”;

3. Declare contract for user

contract userRecords {}

4. Now for the basic demo, we are going to store name and gender information about the user. So initialize this two variables using struct and enum data types.

// enum type variable to store user gender

enum genderType { male, female }

// Actual user object which we will store in ethereum contract

struct user{

string name; genderType gender;

}

5. Now we will declare user object of type user(struct). You can also declare it as public to access it from outside the contract(For visibility scope click here).

user user_obj;

6. Now add getter, setter methods for the user object. We are going to persist every user’s information on blockchain.We should always make this method public as we will access them from outside the contract.

// set user public function

// This is similar to persisting object in db.

function setUser(string name, string gender) public {

genderType gender_type = getGenderFromString(gender);

user_obj = user({name:name, gender: gender_type});

} // get user public function

// This is similar to getting object from db.

function getUser() public returns (string, string) {

return (user_obj.name, getGenderToString(user_obj.gender));

}

7. Notice that we are using two internal helper functions getGenderFromString() and getGenderToString(). Lets add this internal functions. Declare them internal as we are not going to use them outside.

// Internal function to convert genderType enum from string

function getGenderFromString(string gender) internal returns(genderType) {

if(StringUtils.equal(gender, "male")) {

return genderType.male;

} else {

return genderType.female;

}

} // Internal function to convert genderType enum to string

function getGenderToString(genderType gender) internal returns (string) {

if(gender == genderType.male) {

return "male";

} else {

return "female";

}

}

We are using stringUtils.equal() library function. As this version of solidity doesn’t support string compare using (==).

8. Now our contract that is user.sol file will look like below:

pragma solidity ^0.4.21;

// import library file

import "stringUtils.sol"; contract userRecords {

// enum type variable to store user gender

enum genderType { male, female };

// Actual user object which we will store

struct user{

string name;

genderType gender;

}

// user object

user user_obj;

//Internal function to conver genderType enum from string

function getGenderFromString(string gender) internal returns (genderType) {

if(StringUtils.equal(gender, "male")) {

return genderType.male;

} else {

return genderType.female;

}

} //Internal function to convert genderType enum to string

function getGenderToString(genderType gender) internal returns (string) {

if(gender == genderType.male) {

return "male";

} else {

return "female";

}

} // set user public function

// This is similar to persisting object in db.

function setUser(string name, string gender) public {

genderType gender_type = getGenderFromString(gender);

user_obj = user({name:name, gender: gender_type});

}



// get user public function

// This is similar to getting object from db.

function getUser() public returns (string, string) {

return (user_obj.name, getGenderToString(user_obj.gender));

}

}

Compile and deploy above solidity file using python script.

In the below python script we need to instantiate test ethereum node using python-web3. We are setting ganche url as a test ethereum node. We will use below w3 object for deploying contract.

from web3 import Web3

# web3.py instance

w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:8545"))

2. Now we will compile solidity code. To compile solidity code we are using py-solc that is python extension for solidity compiler.

from solc import compile_files # compile all contract files

contracts = compile_files(['user.sol', 'stringUtils.sol']) # separate main file and link file

main_contract = contracts.pop("user.sol:userRecords")

library_link = contracts.pop("stringUtils.sol:StringUtils")

3. Whenever you compile a .sol file with the import statement. We also need to link deploy address of the import file along with the main contract. So for that deploy all links first by compiling it(If already deployed then save the address) See below image main contract bin.