├── .env.example ├── requirements.txt ├── .gitignore ├── contracts ├── Greeter.sol └── Greeter.json ├── README.md ├── templates └── index.html ├── static └── css │ └── style.css ├── LICENSE └── app.py /.env.example: -------------------------------------------------------------------------------- 1 | PRIVATE_KEY= 2 | RPC_URL= 3 | CONTRACT_ADDRESS= -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | flask~=2.0.0 2 | web3==5.22.0 3 | simplejson~=3.17.2 4 | python-dotenv~=0.21.0 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build and Release Folders 2 | bin-debug/ 3 | bin-release/ 4 | [Oo]bj/ 5 | [Bb]in/ 6 | 7 | # Other files and folders 8 | .settings/ 9 | __pycache__/ 10 | # Executables 11 | *.swf 12 | *.air 13 | *.ipa 14 | *.apk 15 | .env 16 | *.env -------------------------------------------------------------------------------- /contracts/Greeter.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.16; 3 | 4 | contract Greeter { 5 | string greeting = "Hello Web3 Devs!"; 6 | 7 | function setGreeting(string memory _greeting) public { 8 | greeting = _greeting; 9 | } 10 | 11 | function getGreeting() public view returns (string memory) { 12 | return greeting; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python-Dapp 2 | 3 | web3.py based dapp 4 | 5 | #### Steps: 6 | 7 | 1. Deploy your contract on your preferred network(update `RPC_URL` accordingly) and get the contract address. 8 | 9 | 2. Create `.env` file in the root directory with below parameters: 10 | 11 | ``` 12 | PRIVATE_KEY= 13 | RPC_URL= 14 | CONTRACT_ADDRESS= 15 | ``` 16 | 17 | 3. Install dependencies and run app: 18 | 19 | ```bash 20 | pip install -r requirements.txt 21 | 22 | python app.py # open http://localhost:8000 23 | 24 | ``` 25 | -------------------------------------------------------------------------------- /contracts/Greeter.json: -------------------------------------------------------------------------------- 1 | { 2 | "abi": [ 3 | { 4 | "inputs": [], 5 | "name": "getGreeting", 6 | "outputs": [ 7 | { 8 | "internalType": "string", 9 | "name": "", 10 | "type": "string" 11 | } 12 | ], 13 | "stateMutability": "view", 14 | "type": "function" 15 | }, 16 | { 17 | "inputs": [ 18 | { 19 | "internalType": "string", 20 | "name": "_greeting", 21 | "type": "string" 22 | } 23 | ], 24 | "name": "setGreeting", 25 | "outputs": [], 26 | "stateMutability": "nonpayable", 27 | "type": "function" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Greeter Dapp 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

{{greeting }}

14 |
15 |
16 | 17 |
18 |
19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /static/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #f6f5f7; 3 | display: flex; 4 | justify-content: center; 5 | align-items: center; 6 | flex-direction: column; 7 | font-family: 'Montserrat', sans-serif; 8 | height: 100vh; 9 | margin: -20px 0 50px; 10 | } 11 | input { 12 | background-color: #eee; 13 | border: none; 14 | padding: 12px 15px; 15 | margin: 8px 0; 16 | width: 100%; 17 | } 18 | .button{ 19 | border-radius: 20px; 20 | border: 1px solid #FF4B2B; 21 | background-color: #FF4E2B; 22 | color: #FFFFFF; 23 | font-size: 12px; 24 | font-weight: bold; 25 | padding: 12px 45px; 26 | letter-spacing: 1px; 27 | text-transform: uppercase; 28 | 29 | transition: transform 80ms ease-in; 30 | } 31 | .button:hover{ 32 | opacity: 0.4; 33 | } 34 | .main { 35 | background: #FF416C; 36 | background: -webkit-linear-gradient(to right, #FF4B2B, #FF416C); 37 | background: linear-gradient(to right, #FF4B2B, #FF416C); 38 | background-repeat: no-repeat; 39 | background-position: 0 0; 40 | color: #FFFFFF; 41 | width: 30%; 42 | height: 45%; 43 | transform: translateX(0); 44 | transition: transform 0.6s ease-in-out; 45 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Salman Dabbakuti 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | from dotenv import load_dotenv 4 | from web3 import Web3, Account, HTTPProvider 5 | from flask import Flask, render_template, request 6 | 7 | # load environment variables from .env file 8 | load_dotenv('.env') 9 | 10 | # web3.py instance 11 | w3 = Web3(HTTPProvider(os.environ.get('RPC_URL'))) 12 | print('Web3 Connected:',w3.isConnected()) 13 | 14 | # account setup 15 | private_key= os.environ.get('PRIVATE_KEY') #private key of the account 16 | public_key = Account.from_key(private_key) 17 | account_address = public_key.address 18 | 19 | # Contract instance 20 | contract_artifacts_file = json.load(open('./contracts/Greeter.json')) 21 | abi = contract_artifacts_file['abi'] 22 | contract_address = os.environ.get('CONTRACT_ADDRESS') 23 | contract_instance = w3.eth.contract(abi=abi, address=contract_address) 24 | 25 | app = Flask(__name__) 26 | 27 | @app.route("/") 28 | def index(): 29 | greeting = contract_instance.functions.getGreeting().call() 30 | return render_template("index.html", greeting=greeting) 31 | 32 | @app.route("/setGreeting" , methods=['POST']) 33 | def set_greeting(): 34 | greeting_input = request.form.get("greeting") 35 | tx = contract_instance.functions.setGreeting(greeting_input).buildTransaction({'nonce': w3.eth.get_transaction_count(account_address)}) 36 | signed_tx = w3.eth.account.sign_transaction(tx, private_key) 37 | tx_hash= w3.eth.send_raw_transaction(signed_tx.rawTransaction) 38 | print('Transaction submitted:', tx_hash.hex()) 39 | w3.eth.wait_for_transaction_receipt(tx_hash) 40 | greeting = contract_instance.functions.getGreeting().call() 41 | return render_template("index.html", greeting=greeting) 42 | 43 | if __name__ == '__main__': 44 | app.run(port=8000, host='localhost') 45 | --------------------------------------------------------------------------------