Skip to content

Commit

Permalink
initialized socket code
Browse files Browse the repository at this point in the history
  • Loading branch information
gretzke committed Nov 4, 2019
1 parent 1d1f8f6 commit 79b8216
Show file tree
Hide file tree
Showing 9 changed files with 724 additions and 0 deletions.
3 changes: 3 additions & 0 deletions socket_py/credentials.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nodeAddr = "Address of node"
privateKey = "Ethereum private key"
address = "Ethereum address belonging to private key"
40 changes: 40 additions & 0 deletions socket_py/qt/Socket_python.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#-------------------------------------------------
#
# Project created by QtCreator 2019-08-20T08:38:25
#
#-------------------------------------------------

QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Socket_python
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0

CONFIG += c++11

SOURCES += \
main.cpp \
mainwindow.cpp

HEADERS += \
mainwindow.h

FORMS += \
mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
336 changes: 336 additions & 0 deletions socket_py/qt/Socket_python.pro.user

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions socket_py/qt/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

return a.exec();
}
14 changes: 14 additions & 0 deletions socket_py/qt/mainwindow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}

MainWindow::~MainWindow()
{
delete ui;
}
22 changes: 22 additions & 0 deletions socket_py/qt/mainwindow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();

private:
Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H
79 changes: 79 additions & 0 deletions socket_py/qt/mainwindow.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>480</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(50, 50, 50);</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QLabel" name="nodeInfoLabel">
<property name="geometry">
<rect>
<x>435</x>
<y>439</y>
<width>351</width>
<height>31</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">color: white; font-size:18px</string>
</property>
<property name="text">
<string>Currently not connected to node</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
<widget class="QPushButton" name="closeButton">
<property name="geometry">
<rect>
<x>720</x>
<y>10</y>
<width>64</width>
<height>64</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">color: transparent; border: none</string>
</property>
<property name="text">
<string>X</string>
</property>
</widget>
<widget class="QLabel" name="infoLabel">
<property name="geometry">
<rect>
<x>85</x>
<y>20</y>
<width>630</width>
<height>90</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">color:white; font-size:36px</string>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:40pt; font-weight:600; font-style:italic;&quot;&gt;Blockchain Smart Outlet&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
175 changes: 175 additions & 0 deletions socket_py/socket.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# ui libraries
from PyQt5.QtGui import QPalette, QFont
from PyQt5.QtCore import QThread, QObject, pyqtSignal, pyqtSlot, Qt, QEvent, QSize
from PyQt5.QtWidgets import QApplication, QMainWindow, QScrollerProperties, QScroller, QListWidgetItem

# ethereum library
from eth_account.messages import encode_defunct
from web3.middleware import geth_poa_middleware
from web3.exceptions import TransactionNotFound
from web3 import Web3
from ui_mainwindow import Ui_MainWindow

# websockets
import websockets
import asyncio
from socket import socket, AF_INET, SOCK_DGRAM

# utility libraries
import operator
import sys
from enum import Enum
import json
from json import JSONDecodeError
import credentials

DEBUG = False

# credentials
nodeAddr = credentials.nodeAddr
contract_abi = '[{"constant":false,"inputs":[{"name":"_newPrice","type":"uint256"}],"name":"changePrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"},{"name":"_signature","type":"bytes"}],"name":"closeChannel","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"initializePaymentChannel","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"timeOutChannel","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_pricePerSecond","type":"uint256"},{"name":"_expirationDuration","type":"uint256"},{"name":"_minDeposit","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"customer","type":"address"},{"indexed":true,"name":"start","type":"uint256"},{"indexed":true,"name":"maxValue","type":"uint256"},{"indexed":false,"name":"end","type":"uint256"}],"name":"InitializedPaymentChannel","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":true,"name":"value","type":"uint256"},{"indexed":true,"name":"expired","type":"bool"},{"indexed":false,"name":"duration","type":"uint256"}],"name":"ClosedPaymentChannel","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"oldPrice","type":"uint256"},{"indexed":true,"name":"newPrice","type":"uint256"}],"name":"PriceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":true,"name":"amount","type":"uint256"}],"name":"Withdrawal","type":"event"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balances","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"channelActive","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"channelCustomer","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"channelExpired","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"creationTimeStamp","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"customerNonces","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"expirationDate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"expirationDuration","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxValue","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minDeposit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pricePerSecond","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_value","type":"uint256"},{"name":"_signature","type":"bytes"}],"name":"verifySignature","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}]'

etherPriceEUR = 300
web3 = Web3(Web3.HTTPProvider(nodeAddr))
# inject the poa compatibility middleware to the innermost layer
web3.middleware_onion.inject(geth_poa_middleware, layer=0)

privateKey = bytes.fromhex(credentials.privateKey)
address = web3.toChecksumAddress(credentials.address)

# global thread and ui variables
window = None
app = None


class State(Enum):
disconnected = 0
connected_P = 1
connected_S = 2
initialized_P = 3
initialized_S = 4
active_P = 5
active_S = 6
closed = 7


# Main window class
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)

# load ui file
self.ui = Ui_MainWindow()
self.ui.setupUi(self)

# start main thread
self.node_thread = Node()
self.node_thread.start()

# connect button handlers
self.ui.closeButton.clicked.connect(self.close)

def closeEvent(self, event):
# cleanup and end threads
try:
self.node_thread.threadActive = False
self.node_thread.wait()
except:
pass
try:
self.ws_thread.threadActive = False
self.ws_thread.wait()
except:
pass
# GPIO.cleanup()
event.accept() # let the window close

def terminateThread(self, process):
try:
thread = operator.attrgetter(process)(self)
if thread.threadActive:
thread.threadActive = False
thread.quit()
if (thread.wait(1000) == False):
thread.terminate()
thread.wait()
except AttributeError:
# thread was not created yet
pass

def connectWS(self):
self.updateInfoCenter('')
self.updateInfo('Searching for smart sockets...')

# start websocket
self.ws_thread = WSConnection()
self.ws_thread.start()


# ethereum node functionality
class Node(QThread):
def __init__(self, parent=window):
super(Node, self).__init__(parent)
global window
self.threadActive = False

if web3.isConnected():
self.threadActive = True
else:
window.ui.nodeInfoLabel.setText("Not connected to Node")

def run(self):
global window
i = 0
while self.threadActive:
i += 1
# check if node is up to date once per second
syncing = web3.eth.syncing
if syncing is False:
blockNumber = web3.eth.blockNumber
# TODO remove str(i)
window.ui.nodeInfoLabel.setText(
"Blocknumber: " + str(blockNumber)
)

else:
window.ui.nodeInfoLabel.setText(
"Syncing: " + str(syncing.currentBlock) +
"/" + str(syncing.highestBlock)
)

QThread().sleep(5)


# websocket thread
class WSConnection(QThread):
def __init__(self, parent=window):
super(WSConnection, self).__init__(parent)
self.threadActive = False

def run(self):
pass


def main():
global window
global app

# start window and ui
app = QApplication(sys.argv)
window = MainWindow()

# show ui
# window.showFullScreen()
if DEBUG:
window.show()
else:
# show app in fullscreen and hide cursor on RPi
window.showFullScreen()
app.setOverrideCursor(Qt.BlankCursor)

sys.exit(app.exec_())


if __name__ == "__main__":
main()
44 changes: 44 additions & 0 deletions socket_py/ui_mainwindow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'qt/mainwindow.ui',
# licensing of 'qt/mainwindow.ui' applies.
#
# Created: Mon Nov 4 22:01:21 2019
# by: pyside2-uic running on PySide2 5.13.1
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 480)
MainWindow.setStyleSheet("background-color: rgb(50, 50, 50);")
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
self.nodeInfoLabel = QtWidgets.QLabel(self.centralWidget)
self.nodeInfoLabel.setGeometry(QtCore.QRect(435, 439, 351, 31))
self.nodeInfoLabel.setStyleSheet("color: white; font-size:18px")
self.nodeInfoLabel.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.nodeInfoLabel.setObjectName("nodeInfoLabel")
self.closeButton = QtWidgets.QPushButton(self.centralWidget)
self.closeButton.setGeometry(QtCore.QRect(720, 10, 64, 64))
self.closeButton.setStyleSheet("color: transparent; border: none")
self.closeButton.setObjectName("closeButton")
self.infoLabel = QtWidgets.QLabel(self.centralWidget)
self.infoLabel.setGeometry(QtCore.QRect(85, 20, 630, 90))
self.infoLabel.setStyleSheet("color:white; font-size:36px")
self.infoLabel.setAlignment(QtCore.Qt.AlignCenter)
self.infoLabel.setObjectName("infoLabel")
MainWindow.setCentralWidget(self.centralWidget)

self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)

def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "MainWindow", None, -1))
self.nodeInfoLabel.setText(QtWidgets.QApplication.translate("MainWindow", "Currently not connected to node", None, -1))
self.closeButton.setText(QtWidgets.QApplication.translate("MainWindow", "X", None, -1))
self.infoLabel.setText(QtWidgets.QApplication.translate("MainWindow", "<html><head/><body><p><span style=\" font-size:40pt; font-weight:600; font-style:italic;\">Blockchain Smart Outlet</span></p></body></html>", None, -1))

0 comments on commit 79b8216

Please sign in to comment.