# include <QtNetwork/QNetworkReply>
# include <QtQuick/QQuickView>
//#include <QtQml/QQmlContext>
//#include <QtQml/QQmlEngine>
# include <QtQml/QtQml>
# include <QtWidgets/QMessageBox>
# include <QtWidgets/QInputDialog>
# include <QtGui/QClipboard>
# include <QtCore/QtCore>
# include <libethereum/Dagger.h>
# include <libethereum/Client.h>
# include <libethereum/Instruction.h>
# include <libethereum/FileSystem.h>
# include <libethereum/PeerServer.h>
# include "BuildInfo.h"
# include "MainWin.h"
# include "ui_Main.h"
using namespace std ;
// types
using eth : : bytes ;
using eth : : bytesConstRef ;
using eth : : h160 ;
using eth : : h256 ;
using eth : : u160 ;
using eth : : u256 ;
using eth : : u256s ;
using eth : : Address ;
using eth : : BlockInfo ;
using eth : : Client ;
using eth : : Instruction ;
using eth : : KeyPair ;
using eth : : NodeMode ;
using eth : : PeerInfo ;
using eth : : RLP ;
using eth : : Secret ;
using eth : : Transaction ;
// functions
using eth : : toHex ;
using eth : : assemble ;
using eth : : compileLisp ;
using eth : : disassemble ;
using eth : : formatBalance ;
using eth : : fromHex ;
using eth : : right160 ;
using eth : : simpleDebugOut ;
using eth : : toLog2 ;
using eth : : toString ;
using eth : : units ;
// vars
using eth : : g_logPost ;
using eth : : g_logVerbosity ;
using eth : : c_instructionInfo ;
Main : : Main ( QWidget * parent ) :
QMainWindow ( parent ) ,
ui ( new Ui : : Main )
{
setWindowFlags ( Qt : : Window ) ;
ui - > setupUi ( this ) ;
setWindowIcon ( QIcon ( " :/Ethereum.png " ) ) ;
g_qmlMain = this ;
m_client . reset ( new Client ( " Walleth " , Address ( ) , eth : : getDataDir ( ) + " /Walleth " ) ) ;
g_qmlClient = m_client . get ( ) ;
qRegisterMetaType < eth : : u256 > ( " eth::u256 " ) ;
qRegisterMetaType < eth : : KeyPair > ( " eth::KeyPair " ) ;
qRegisterMetaType < eth : : Secret > ( " eth::Secret " ) ;
qRegisterMetaType < eth : : Address > ( " eth::Address " ) ;
qRegisterMetaType < QmlAccount * > ( " QmlAccount* " ) ;
qRegisterMetaType < QmlEthereum * > ( " QmlEthereum* " ) ;
qmlRegisterType < QmlEthereum > ( " org.ethereum " , 1 , 0 , " Ethereum " ) ;
qmlRegisterType < QmlAccount > ( " org.ethereum " , 1 , 0 , " Account " ) ;
qmlRegisterSingletonType < QmlU256Helper > ( " org.ethereum " , 1 , 0 , " Balance " , QmlEthereum : : constructU256Helper ) ;
qmlRegisterSingletonType < QmlKeyHelper > ( " org.ethereum " , 1 , 0 , " Key " , QmlEthereum : : constructKeyHelper ) ;
/*
ui - > librariesView - > setModel ( m_libraryMan ) ;
ui - > graphsView - > setModel ( m_graphMan ) ;
*/
m_view = new QQuickView ( ) ;
// QQmlContext* context = m_view->rootContext();
// context->setContextProperty("u256", new U256Helper(this));
m_view - > setSource ( QUrl ( " qrc:/Simple.qml " ) ) ;
QWidget * w = QWidget : : createWindowContainer ( m_view ) ;
m_view - > setResizeMode ( QQuickView : : SizeRootObjectToView ) ;
ui - > fullDisplay - > insertWidget ( 0 , w ) ;
m_view - > create ( ) ;
// m_timelinesItem = m_view->rootObject()->findChild<TimelinesItem*>("timelines");
readSettings ( ) ;
refresh ( ) ;
m_refreshNetwork = new QTimer ( this ) ;
connect ( m_refreshNetwork , SIGNAL ( timeout ( ) ) , SLOT ( refreshNetwork ( ) ) ) ;
m_refreshNetwork - > start ( 1000 ) ;
connect ( this , SIGNAL ( changed ( ) ) , SLOT ( refresh ( ) ) ) ;
connect ( & m_webCtrl , & QNetworkAccessManager : : finished , [ & ] ( QNetworkReply * _r )
{
m_servers = QString : : fromUtf8 ( _r - > readAll ( ) ) . split ( " \n " , QString : : SkipEmptyParts ) ;
if ( m_servers . size ( ) )
{
ui - > net - > setChecked ( true ) ;
on_net_triggered ( true ) ;
}
} ) ;
QNetworkRequest r ( QUrl ( " http://www.ethereum.org/servers.poc " + QString ( ETH_QUOTED ( ETH_VERSION ) ) . section ( ' . ' , 1 , 1 ) + " .txt " ) ) ;
r . setHeader ( QNetworkRequest : : UserAgentHeader , " Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1712.0 Safari/537.36 " ) ;
m_webCtrl . get ( r ) ;
srand ( time ( 0 ) ) ;
startTimer ( 200 ) ;
statusBar ( ) - > addPermanentWidget ( ui - > balance ) ;
statusBar ( ) - > addPermanentWidget ( ui - > peerCount ) ;
statusBar ( ) - > addPermanentWidget ( ui - > blockCount ) ;
}
Main : : ~ Main ( )
{
writeSettings ( ) ;
}
void Main : : timerEvent ( QTimerEvent * )
{
if ( m_client - > changed ( ) )
changed ( ) ;
}
void Main : : on_about_triggered ( )
{
QMessageBox : : about ( this , " About Walleth PoC- " + QString ( ETH_QUOTED ( ETH_VERSION ) ) . section ( ' . ' , 1 , 1 ) , " Walleth/v " ETH_QUOTED ( ETH_VERSION ) " / " ETH_QUOTED ( ETH_BUILD_TYPE ) " / " ETH_QUOTED ( ETH_BUILD_PLATFORM ) " - " ETH_QUOTED ( ETH_COMMIT_HASH ) " \n By Gav Wood, 2014. \n Based on a design by Vitalik Buterin. \n \n Team Ethereum++ includes: Tim Hughes, Eric Lombrozo, Marko Simovic, Alex Leverington and several others. " ) ;
}
void Main : : writeSettings ( )
{
QSettings s ( " ethereum " , " walleth " ) ;
QByteArray b ;
b . resize ( sizeof ( Secret ) * m_myKeys . size ( ) ) ;
auto p = b . data ( ) ;
for ( auto i : m_myKeys )
{
memcpy ( p , & ( i . secret ( ) ) , sizeof ( Secret ) ) ;
p + = sizeof ( Secret ) ;
}
s . setValue ( " address " , b ) ;
s . setValue ( " upnp " , ui - > upnp - > isChecked ( ) ) ;
s . setValue ( " clientName " , m_clientName ) ;
s . setValue ( " idealPeers " , m_idealPeers ) ;
s . setValue ( " port " , m_port ) ;
if ( client ( ) - > peerServer ( ) )
{
bytes d = client ( ) - > peerServer ( ) - > savePeers ( ) ;
m_peers = QByteArray ( ( char * ) d . data ( ) , ( int ) d . size ( ) ) ;
}
s . setValue ( " peers " , m_peers ) ;
s . setValue ( " geometry " , saveGeometry ( ) ) ;
s . setValue ( " windowState " , saveState ( ) ) ;
}
void Main : : readSettings ( )
{
QSettings s ( " ethereum " , " walleth " ) ;
restoreGeometry ( s . value ( " geometry " ) . toByteArray ( ) ) ;
restoreState ( s . value ( " windowState " ) . toByteArray ( ) ) ;
QByteArray b = s . value ( " address " ) . toByteArray ( ) ;
if ( b . isEmpty ( ) )
m_myKeys . append ( KeyPair : : create ( ) ) ;
else
{
h256 k ;
for ( unsigned i = 0 ; i < b . size ( ) / sizeof ( Secret ) ; + + i )
{
memcpy ( & k , b . data ( ) + i * sizeof ( Secret ) , sizeof ( Secret ) ) ;
m_myKeys . append ( KeyPair ( k ) ) ;
}
}
//m_eth->setAddress(m_myKeys.last().address());
m_peers = s . value ( " peers " ) . toByteArray ( ) ;
ui - > upnp - > setChecked ( s . value ( " upnp " , true ) . toBool ( ) ) ;
m_clientName = s . value ( " clientName " , " " ) . toString ( ) ;
m_idealPeers = s . value ( " idealPeers " , 5 ) . toInt ( ) ;
m_port = s . value ( " port " , 30303 ) . toInt ( ) ;
}
void Main : : refreshNetwork ( )
{
auto ps = client ( ) - > peers ( ) ;
ui - > peerCount - > setText ( QString : : fromStdString ( toString ( ps . size ( ) ) ) + " peer(s) " ) ;
}
eth : : State const & Main : : state ( ) const
{
return ui - > preview - > isChecked ( ) ? client ( ) - > postState ( ) : client ( ) - > state ( ) ;
}
void Main : : refresh ( )
{
eth : : ClientGuard l ( client ( ) ) ;
auto const & st = state ( ) ;
auto d = client ( ) - > blockChain ( ) . details ( ) ;
auto diff = BlockInfo ( client ( ) - > blockChain ( ) . block ( ) ) . difficulty ;
ui - > blockCount - > setText ( QString ( " #%1 @%3 T%2 " ) . arg ( d . number ) . arg ( toLog2 ( d . totalDifficulty ) ) . arg ( toLog2 ( diff ) ) ) ;
m_keysChanged = false ;
u256 totalBalance = 0 ;
for ( auto i : m_myKeys )
{
u256 b = st . balance ( i . address ( ) ) ;
totalBalance + = b ;
}
ui - > balance - > setText ( QString : : fromStdString ( formatBalance ( totalBalance ) ) ) ;
}
void Main : : on_net_triggered ( bool _auto )
{
string n = " Walleth/v " ETH_QUOTED ( ETH_VERSION ) ;
if ( m_clientName . size ( ) )
n + = " / " + m_clientName . toStdString ( ) ;
n + = " / " ETH_QUOTED ( ETH_BUILD_TYPE ) " / " ETH_QUOTED ( ETH_BUILD_PLATFORM ) ;
client ( ) - > setClientVersion ( n ) ;
if ( ui - > net - > isChecked ( ) )
{
if ( _auto )
{
QString s = m_servers [ rand ( ) % m_servers . size ( ) ] ;
client ( ) - > startNetwork ( m_port , s . section ( ' : ' , 0 , 0 ) . toStdString ( ) , s . section ( ' : ' , 1 ) . toInt ( ) , NodeMode : : Full , m_idealPeers , std : : string ( ) , ui - > upnp - > isChecked ( ) ) ;
}
else
client ( ) - > startNetwork ( m_port , string ( ) , 0 , NodeMode : : Full , m_idealPeers , std : : string ( ) , ui - > upnp - > isChecked ( ) ) ;
if ( m_peers . size ( ) )
client ( ) - > peerServer ( ) - > restorePeers ( bytesConstRef ( ( byte * ) m_peers . data ( ) , m_peers . size ( ) ) ) ;
}
else
client ( ) - > stopNetwork ( ) ;
}
void Main : : on_connect_triggered ( )
{
if ( ! ui - > net - > isChecked ( ) )
{
ui - > net - > setChecked ( true ) ;
on_net_triggered ( ) ;
}
bool ok = false ;
QString s = QInputDialog : : getItem ( this , " Connect to a Network Peer " , " Enter a peer to which a connection may be made: " , m_servers , m_servers . count ( ) ? rand ( ) % m_servers . count ( ) : 0 , true , & ok ) ;
if ( ok & & s . contains ( " : " ) )
{
string host = s . section ( " : " , 0 , 0 ) . toStdString ( ) ;
unsigned short port = s . section ( " : " , 1 ) . toInt ( ) ;
client ( ) - > connect ( host , port ) ;
}
}
void Main : : on_mine_triggered ( )
{
if ( ui - > mine - > isChecked ( ) )
{
client ( ) - > setAddress ( m_myKeys . last ( ) . address ( ) ) ;
client ( ) - > startMining ( ) ;
}
else
client ( ) - > stopMining ( ) ;
}
void Main : : on_create_triggered ( )
{
m_myKeys . append ( KeyPair : : create ( ) ) ;
m_keysChanged = true ;
}
// extra bits needed to link on VS
# ifdef _MSC_VER
// include moc file, ofuscated to hide from automoc
# include \
" moc_MainWin.cpp "
// specify library dependencies, it's easier to do here than in the project since we can control the "d" debug suffix
# ifdef _DEBUG
# define QTLIB(x) x"d.lib"
# else
# define QTLIB(x) x".lib"
# endif
# pragma comment(lib, QTLIB("Qt5PlatformSupport"))
# pragma comment(lib, QTLIB("Qt5Core"))
# pragma comment(lib, QTLIB("Qt5GUI"))
# pragma comment(lib, QTLIB("Qt5Widgets"))
# pragma comment(lib, QTLIB("Qt5Network"))
# pragma comment(lib, QTLIB("Qt5Quick"))
# pragma comment(lib, QTLIB("Qt5Declarative"))
# pragma comment(lib, QTLIB("Qt5Qml"))
# pragma comment(lib, QTLIB("qwindows"))
# pragma comment(lib, "Imm32.lib")
# pragma comment(lib, "opengl32.lib")
# pragma comment(lib, "winmm.lib")
# endif