Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to develop ethernet intelligent contract with Python and Flask framework

2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

Today, I will talk to you about how to use Python and Flask framework to develop an intelligent contract for Ethernet Fang. many people may not know much about it. in order to make you understand better, the editor has summarized the following for you. I hope you can get something according to this article.

Storing data in a database is an integral part of any software application. No matter how to control the database, there is a master control of the data. Block chain technology stores data in blocks within a block chain network. Therefore, as long as a node is synchronized with the network, they get a copy of the data in the block. Therefore, there is no specific data master in this technology.

We will write a smart contract (which I will explain further) to retain user data on the blockchain. We will use python web3, web3's python library, to develop and deploy smart contracts. Once we deploy a smart contract on the blockchain. We will use flask API to interact with smart contracts to store some data / information. We store it on the block chain, and it is immutable.

Environmental requirements

Python 3.6

Installation

1. Create a python virtual environment.

Virtualenv localizes your Python packages in your project's virtual environment, rather than forcing you to install them on a system-wide basis.

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

two。 Now we need an ethernet test chain like Ganache.

Ganache is a personal block chain developed by Etay Fong that can be used to deploy contracts, develop applications and run tests.

$npm install-g ganache-cli

3. Install python web3

Web3.py is a python library for interacting with ethernet. Its API is derived from Web3.js Javascript API and should be familiar to people who have used web3.js.

$pip3 install web3

4.Flask

Flask is a lightweight framework for python.

$pip3 install flask

5.Flask Restful

Flask-RESTful is an extension of Flask, adding support for quickly building REST API.

$pip3 install flask-restful

Flask Marshmallow

Flask marshmallow is an object serialization / deserialization library.

$pip3 install flask-marshmallow starts the ethersquare test block chain server

To deploy a smart contract, we should start the test ethernet Fong server. We are using ganache for testing. Type the following command in the terminal:

$ganache-cli

Ganache provides us with 10 default test accounts, each with 100 fake ether for trading. We will use these accounts to deploy and set various values in the contract.

We can see the price and limitations of gas as well as the host:port on which ganache is deployed. We need this when we deploy the contract.

Create a user.sol file

Now we will write smart contracts in Solidity. Solidity is the language for writing smart contracts on ethereum. Smart contracts include optional validation functions for the data we will store on the blockchain, data and getter methods, and setter methods to access the data.

For example, to register for attendance on the block chain, you will have a set of user objects. It will have access to the user's getter,setter method. Since each user can only mark attendance once a day, you need a validation function to check, and smart contracts are very similar to applications that we usually develop in any other language.

In the following file, we use the getter,setter function to build a simple user contract.

1. Declare the solidity compiler version in the .sol file.

Pragma solidity ^ 0.4.21

Learn about the compiler version you are using.

$solidity  -  version

two。 Import the library file Import library. We should use the library for common utility functions. Libraries can be compiled only once and used repeatedly (click here to get some good library resources).

Import "stringUtils.sol"

3. Declare the contract for the user

Contract userRecords {}

4. Now, for the basic demo, we will store information about the user's name and gender. Therefore, initialize these two variables with the struct and enum data types.

/ / enumerate type variables to store user gender enum genderType {male, female} / / We will store the actual user object struct user {string name; genderType gender;} in the Ethernet Fong contract

5. Now we will declare a user object of type user (struct). You can also declare it as public so that it can be accessed from outside the contract (click here for visible scope).

User user_obj

6. Now add the getter,setter method for the user object. We will keep each user's information on the block chain. We should always expose this method because we will access them from outside the contract.

/ / set user public functions / / this is similar to persistent objects 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 functions / / this is similar to getting objects from db. Function getUser () public returns (string, string) {return (user_obj.name, getGenderToString (user_obj.gender));}

7. Notice that we use two internal functions, getGenderFromString () and getGenderToString (). Let's add this internal function. Declare them internal because we will not use them outside.

/ / Internal function function getGenderFromString (string gender) internal returns (genderType) {if (StringUtils.equal (gender, "male")) {return genderType.male;} else {return genderType.female;}} / / internal function (string) {if (gender = = genderType.male) {return "male";} else {return "female" to convert genderType enumerations into strings from string }}

We are using the stringUtils.equal () library function. Because this version of solidity does not support string comparison using (= =).

8. Now our user.sol file contract is as follows:

Pragma solidity ^ 0.4.21 stringUtils.sol / import library fileimport "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));} use the python script to compile and deploy the solidity file.

1. In the following python script, we need to instantiate the python-web3 test Ethernet Fong node. We will set ganche url as the test ethernet node. We will use the following w3 object to deploy the contract.

From web3 import Web3# web3.py instancew3 = Web3 (Web3.HTTPProvider ("http://127.0.0.1:8545"))

two。 Now we will compile the solidity code. To compile the solidity code, we use py-solc, which is the python extension for the solidity compiler.

From solc import compile_files# compiles all contract files contracts = compile_files (['user.sol',' stringUtils.sol']) # separate main file and linked file main_contract = contracts.pop ("user.sol:userRecords") library_link = contracts.pop ("stringUtils.sol:StringUtils")

3. Whenever the .sol file is compiled with the import statement. We also need to link to the deployment address of the import file and the master contract. Therefore, for all links to deployment, first compile it (if you have already deployed and then save the address) see the bin of the master contract below.

When you compile the master contract, if you see its bin section, you will find the _ stringUtils.sol:StringUtils _ of the library we are importing (it can also be used for contracts). In this section, we should replace it by the library address before the contract is deployed.

4. Then we associate the library address with the main contract.

From solc import link_codedef deploy_contract (contract_interface): # instantiation and deployment contract contract = w3.eth.contract (abi=contract_interface ['abi'] Bytecode=contract_interface ['bin']) # get the transaction hash from the deployed contract tx_hash = contract.deploy (transaction= {' from': w3.eth.accounts [1]}) # get the tx receipt to get the contract address tx_receipt = w3.eth.getTransactionReceipt (tx_hash) return tx_receipt ['contractAddress'] library_address = {"stringUtils.sol:StringUtils" : deploy_contract (library_link)} main_contract ['bin'] = link_code (main_contract [' bin'] Library_address)

The linked bin of the main contract is shown in the following figure:

You will see that the bin of the imported library has been added.

5. Now deploy the master contract using our w3 object. Deploy using the default address of ethereum account {'from':w3.eth.accounts [1]}.

Def deploy_contract (contract_interface): # instantiation and deployment contract contract = w3.eth.contract (abi=contract_interface ['abi'] Bytecode=contract_interface ['bin']) # get the transaction hash from the deployed contract tx_hash = contract.deploy (transaction= {' from': w3.eth.accounts [1]}) # get the tx receipt to get the contract address tx_receipt = w3.eth.getTransactionReceipt (tx_hash) return tx_receipt ['contractAddress'] contract_address = deploy_contract (main_contract)

You will see the following line in the tab running the ganache test server:

This is the same as the information obtained in tx_receipt after the contract deployment.

6. Now store abi and contract_address in the json file. So that we can use it later in flask api to store the user objects in the contract.

# add abi (application binary interface) and transaction receipt with open ('data.json', 'w') as outfile: data = {"abi": main_contract [' abi'], "contract_address": deploy_contract (main_contract)} json.dump (data, outfile, indent=4, sort_keys=True) to the json file

7. Now our complete script is as follows:

Import jsonfrom web3 import Web3from solc import compile_files, link_code, compile_source# web3.py instancew3 = Web3 (Web3.HTTPProvider ("http://127.0.0.1:8545"))def deploy_contract (contract_interface): # Instantiate and deploy contract contract = w3.eth.contract (abi=contract_interface ['abi']) Bytecode=contract_interface ['bin']) # Get transaction hash from deployed contract tx_hash = contract.deploy (transaction {' from':w3.eth.accounts [1]}) # Get tx receipt to get contract address tx_receipt = w3.eth.getTransactionReceipt (tx_hash) return tx_receipt ['contractAddress'] # compile all contract filescontracts = compile_files ([' user.sol']) 'stringUtils.sol']) # separate main file and link filemain_contract = contracts.pop ("user.sol:userRecords") library_link = contracts.pop ("stringUtils.sol:StringUtils") # print bin part in console you will see' stringUtils' in that we need to link library address in that bin code.# to that we have to deploy library code first then link itlibrary_address = {"stringUtils.sol:StringUtils": deploy_contract (library_link)} main_contract ['bin'] = link_code (main_contract [' bin']) Library_address) # add abi (application binary interface) and transaction reciept in json filewith open ('data.json', 'w') as outfile: data = {"abi": main_contract [' abi'], "contract_address": deploy_contract (main_contract)} json.dump (data, outfile, indent=4, sort_keys=True) create flask api to store different values for users

You only need to deploy the contract once. But with its address, you will store data over and over again. Similarly, in the world of db, you only need to define the model / schema once, but you will add different lines / documents to the db.

We will use flask post api to get the user's user information and return success.

From flask import Flask, Response, request, jsonifyfrom marshmallow import Schema, fields, ValidationErrordef check_gender (data): valid_list = ["male", "female"] if data not in valid_list: raise ValidationError ('Invalid gender. Valid choices are'+ valid_list) # For api validationsclass UserSchema (Schema): name = fields.String (required=True) gender = fields.String (required=True, validate=check_gender) # Initializing flask appapp = Flask (_ name__) # api to set new user every api call@app.route ("/ blockchain/user", methods= ['POST']) def user (): body = request.get_json () result, error = UserSchema () load (body) if error: return jsonify (error) 422 return jsonify ({"data": result})

Since this is not a flask tutorial, I will not elaborate on this point. If you are not familiar with flask, you can take a look at this flask tutorial. Our API users will take data from the client (curl request) and validate it and return it to the client (curl request)

two。 Now we will initialize the web3 object to communicate with the deployed user contract.

From web3 import Web3# web3.py instancew3 = Web3 (Web3.HTTPProvider ("http://127.0.0.1:8545"))

3. Now we will get the abi and contract address previously stored in the data.json file.

With open ("data.json",'r') as f: datastore = json.load (f) abi = datastore ["abi"] contract_address = datastore ["contract_address"]

4. Select the default account address for the transaction. Set a new value for the user each time in the contract. You will take some gas out of your wallet.

W3.eth.defaultAccount = w3.eth.accounts [1]

5. Finally, you will set the value that api gets when calling the user object in the ethernet contract.

App.route ("/ blockchain/user", methods= ['POST']) def user (): # Create the contract instance with the newly-deployed address user = w3.eth.contract (address=contract_address, abi=abi) body = request.get_json () result, error = UserSchema () .load (body) if error: return jsonify (error), 422 tx_hash = user.functions.setUser (result [' name']) Result ['gender']) tx_hash = tx_hash.transact () # Wait for transaction to be mined... W3.eth.waitForTransactionReceipt (tx_hash) user_data = user.functions.getUser () .call () return jsonify ({"data": user_data}), 200

We first used abi and contract_address to get the deployment contract.

User = w3.eth.contract (address=contract_address, abi=abi)

We can then use the contract instance to call any contract public function. After setting the value for the user, we will expose it to the public using the transact method. This will add a new user value in the etherland block.

Tx_hash = user.functions.setUser (result ['name'], result [' gender']) .transact ()

Now we can use the call method to get the value that has been set in the contract, which calls the contract function without adding any blocks to the chunk chain.

User_data = user.functions.getUser () .call ()

The final code for our api file is as follows. Save it as app.py.

Import jsonfrom flask import Flask, Response, request, jsonifyfrom marshmallow import Schema, fields, ValidationErrorfrom web3 import Web3# web3.py instancew3 = Web3 (Web3.HTTPProvider ("http://127.0.0.1:8545"))w3.eth.defaultAccount = w3.eth.accounts [1] # Get stored abi and contract_addresswith open (" data.json ") 'r') as f: datastore = json.load (f) abi = datastore ["abi"] contract_address = datastore ["contract_address"] def check_gender (data): valid_list = ["male", "female"] if data not in valid_list: raise ValidationError ('Invalid gender. Valid choices are'+ valid_list) # For api validationsclass UserSchema (Schema): name = fields.String (required=True) gender = fields.String (required=True, validate=check_gender) # Initializing flask appapp = Flask (_ _ name__) # api to set new user every api call@app.route ("/ blockchain/user", methods= ['POST']) def user (): # Create the contract instance with the newly-deployed address user = w3.eth.contract (address=contract_address Abi=abi) body = request.get_json () result, error = UserSchema (). Load (body) if error: return jsonify (error), 422 tx_hash = user.functions.setUser (result ['name'], result [' gender']). Transact () # Wait for transaction to be mined... Receipt = w3.eth.waitForTransactionReceipt (tx_hash) user_data = user.functions.getUser () .call () return jsonify ({"data": user_data})

Run the following command to start the server.

FLASK_APP=app.py flask run uses curl to call api$ curl-H "Content-Type: application/json"-request POST-d'{"name": "John Doe", "gender": "male"} 'http://localhost:5000/blockchain/user after reading the above, do you have any further understanding of how to develop ethernet smart contracts with Python and Flask framework? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report