@ -20,10 +20,6 @@
* Ethereum client .
*/
# include <ncurses.h>
# undef OK
# include <form.h>
# undef OK
# include <thread>
# include <chrono>
# include <fstream>
@ -76,27 +72,6 @@ void help()
exit ( 0 ) ;
}
void interactiveHelp ( )
{
cout
< < " Commands: " < < endl
< < " netstart <port> Starts the network sybsystem on a specific port. " < < endl
< < " netstop Stops the network subsystem. " < < endl
< < " connect <addr> <port> Connects to a specific peer. " < < endl
< < " minestart Starts mining. " < < endl
< < " minestop Stops mining. " < < endl
< < " address Gives the current address. " < < endl
< < " secret Gives the current secret " < < endl
< < " block Gives the current block height. " < < endl
< < " balance Gives the current balance. " < < endl
< < " peers List the peers that are connected " < < endl
< < " transact Execute a given transaction. " < < endl
< < " send Execute a given transaction with current secret. " < < endl
< < " contract Create a new contract with current secret. " < < endl
< < " inspect <contract> Dumps a contract to <APPDATA>/<contract>.evm. " < < endl
< < " exit Exits the application. " < < endl ;
}
string credits ( bool _interactive = false )
{
std : : ostringstream ccout ;
@ -149,142 +124,11 @@ string pretty(h160 _a, eth::State _st)
return ns ;
}
namespace nc
{
class nc_window_streambuf : public std : : streambuf
{
public :
nc_window_streambuf ( WINDOW * p , std : : ostream & os , unsigned long cursesAttr = 0 ) ;
nc_window_streambuf ( WINDOW * p , unsigned long _cursesAttr = 0 ) ;
nc_window_streambuf ( nc_window_streambuf const & _rhs ) ;
virtual ~ nc_window_streambuf ( ) ;
nc_window_streambuf & operator = ( nc_window_streambuf const & _rhs ) ;
virtual int overflow ( int c ) ;
virtual int sync ( ) ;
private :
void copy ( nc_window_streambuf const & _rhs ) ;
WINDOW * m_pnl ;
unsigned long m_flags ;
std : : ostream * m_os ;
std : : streambuf * m_old ;
} ;
nc_window_streambuf : : nc_window_streambuf ( WINDOW * p , unsigned long _cursesAttr ) :
m_pnl ( p ) ,
m_flags ( _cursesAttr ) ,
m_os ( 0 ) ,
m_old ( 0 )
{
// Tell parent class that we want to call overflow() for each
// input char:
setp ( 0 , 0 ) ;
setg ( 0 , 0 , 0 ) ;
scrollok ( p , true ) ;
mvwinch ( p , 0 , 0 ) ;
}
nc_window_streambuf : : nc_window_streambuf ( WINDOW * _p , std : : ostream & _os , unsigned long _cursesAttr ) :
m_pnl ( _p ) ,
m_flags ( _cursesAttr ) ,
m_os ( & _os ) ,
m_old ( _os . rdbuf ( ) )
{
setp ( 0 , 0 ) ;
setg ( 0 , 0 , 0 ) ;
_os . rdbuf ( this ) ;
scrollok ( _p , true ) ;
mvwinch ( _p , 0 , 0 ) ;
}
void nc_window_streambuf : : copy ( nc_window_streambuf const & _rhs )
{
if ( this ! = & _rhs )
{
m_pnl = _rhs . m_pnl ;
m_flags = _rhs . m_flags ;
m_os = _rhs . m_os ;
m_old = _rhs . m_old ;
}
}
nc_window_streambuf : : nc_window_streambuf ( nc_window_streambuf const & _rhs ) :
std : : streambuf ( )
{
copy ( _rhs ) ;
}
nc_window_streambuf & nc_window_streambuf : : operator = ( nc_window_streambuf const & _rhs )
{
copy ( _rhs ) ;
return * this ;
}
nc_window_streambuf : : ~ nc_window_streambuf ( )
{
if ( m_os )
m_os - > rdbuf ( m_old ) ;
}
int nc_window_streambuf : : overflow ( int c )
{
int ret = c ;
if ( c ! = EOF )
{
int x = 0 ;
int y = 0 ;
int mx = 0 ;
int my = 0 ;
getyx ( m_pnl , y , x ) ;
getmaxyx ( m_pnl , my , mx ) ;
( void ) my ;
if ( y < 1 )
y = 1 ;
if ( x < 2 )
x = 2 ;
if ( x > mx - 4 )
{
y + + ;
x = 2 ;
}
if ( m_flags )
{
wattron ( m_pnl , m_flags ) ;
if ( mvwaddch ( m_pnl , y , x + + , ( chtype ) c ) = = ERR )
ret = EOF ;
wattroff ( m_pnl , m_flags ) ;
}
else if ( mvwaddch ( m_pnl , y , x + + , ( chtype ) c ) = = ERR )
ret = EOF ;
}
if ( c = = EOF ) // || std::isspace(c)
if ( sync ( ) = = EOF )
ret = EOF ;
return ret ;
}
int nc_window_streambuf : : sync ( )
{
if ( stdscr & & m_pnl )
return ( wrefresh ( m_pnl ) = = ERR ) ? EOF : 0 ;
return EOF ;
}
}
vector < string > form_dialog ( vector < string > _sfields , vector < string > _lfields , vector < string > _bfields , int _cols , int _rows , string _post_form ) ;
int main ( int argc , char * * argv )
{
unsigned short listenPort = 30303 ;
string remoteHost ;
unsigned short remotePort = 30303 ;
bool interactive = false ;
string dbPath ;
eth : : uint mining = ~ ( eth : : uint ) 0 ;
NodeMode mode = NodeMode : : Full ;
@ -345,8 +189,6 @@ int main(int argc, char** argv)
coinbase = h160 ( fromHex ( argv [ + + i ] ) ) ;
else if ( ( arg = = " -s " | | arg = = " --secret " ) & & i + 1 < argc )
us = KeyPair ( h256 ( fromHex ( argv [ + + i ] ) ) ) ;
else if ( arg = = " -i " | | arg = = " --interactive " )
interactive = true ;
else if ( ( arg = = " -d " | | arg = = " --path " | | arg = = " --db-path " ) & & i + 1 < argc )
dbPath = argv [ + + i ] ;
else if ( ( arg = = " -m " | | arg = = " --mining " ) & & i + 1 < argc )
@ -394,716 +236,17 @@ int main(int argc, char** argv)
Client c ( " Ethereum(++) / " + clientName + " v " ETH_QUOTED(ETH_VERSION) " / " ETH_QUOTED(ETH_BUILD_TYPE) " / " ETH_QUOTED(ETH_BUILD_PLATFORM), coinbase, dbPath) ;
cout < < credits ( ) ;
if ( interactive )
{
std : : ostringstream ccout ;
// Initialize ncurses
const char * chr ;
char * str = new char [ 255 ] ;
int width ;
int height ;
int y = 0 ;
int x = 2 ;
string cmd ;
WINDOW * mainwin , * consolewin , * logwin , * blockswin , * pendingwin , * addswin , * contractswin , * peerswin ;
if ( ! ( mainwin = initscr ( ) ) )
{
cerr < < " Error initialising ncurses. " ;
return - 1 ;
}
getmaxyx ( mainwin , height , width ) ;
int qheight = height * 3 / 5 ;
int qwidth = width / 4 - 4 ;
nonl ( ) ;
cbreak ( ) ;
timeout ( 30000 ) ;
echo ( ) ;
keypad ( mainwin , true ) ;
// Initialize color pairs
start_color ( ) ;
init_pair ( 1 , COLOR_WHITE , COLOR_BLACK ) ;
init_pair ( 2 , COLOR_RED , COLOR_BLACK ) ;
init_pair ( 3 , 7 , COLOR_BLACK ) ;
use_default_colors ( ) ;
logwin = newwin ( height * 2 / 5 - 2 , width * 2 / 3 , qheight , 0 ) ;
nc : : nc_window_streambuf outbuf ( logwin , std : : cout ) ;
g_logVerbosity = 1 ; // Force verbosity level for now
consolewin = newwin ( qheight , width / 4 , 0 , 0 ) ;
nc : : nc_window_streambuf coutbuf ( consolewin , ccout ) ;
blockswin = newwin ( qheight , width / 4 , 0 , width / 4 ) ;
pendingwin = newwin ( height * 1 / 5 , width / 4 , 0 , width * 2 / 4 ) ;
peerswin = newwin ( height * 2 / 5 , width / 4 , height * 1 / 5 , width * 2 / 4 ) ;
addswin = newwin ( height * 2 / 5 - 2 , width / 3 , qheight , width * 2 / 3 ) ;
contractswin = newwin ( qheight , width / 4 , 0 , width * 3 / 4 ) ;
int vl = qheight - 4 ;
wsetscrreg ( consolewin , 1 , vl ) ;
wsetscrreg ( blockswin , 1 , vl ) ;
wsetscrreg ( pendingwin , 1 , vl ) ;
wsetscrreg ( peerswin , 1 , vl ) ;
wsetscrreg ( addswin , 1 , vl ) ;
wsetscrreg ( contractswin , 1 , vl ) ;
mvwprintw ( mainwin , 1 , 1 , " > " ) ;
wresize ( mainwin , 3 , width ) ;
mvwin ( mainwin , height - 3 , 0 ) ;
wmove ( mainwin , 1 , 4 ) ;
if ( ! remoteHost . empty ( ) )
c . startNetwork ( listenPort , remoteHost , remotePort , mode , peers , publicIP , upnp ) ;
while ( true )
{
wclrtobot ( consolewin ) ;
wclrtobot ( pendingwin ) ;
wclrtobot ( peerswin ) ;
wclrtobot ( addswin ) ;
wclrtobot ( contractswin ) ;
ccout < < credits ( true ) ;
// Prompt
wmove ( mainwin , 1 , 4 ) ;
getstr ( str ) ;
string s ( str ) ;
istringstream iss ( s ) ;
iss > > cmd ;
// Address
ccout < < " Address: " < < endl ;
chr = toHex ( us . address ( ) . asArray ( ) ) . c_str ( ) ;
ccout < < chr < < endl < < endl ;
mvwprintw ( mainwin , 1 , 1 , " > " ) ;
clrtoeol ( ) ;
if ( s . length ( ) > 1 )
{
ccout < < " > " ;
ccout < < str < < endl ;
}
if ( cmd = = " netstart " )
{
eth : : uint port ;
iss > > port ;
c . startNetwork ( ( short ) port ) ;
}
else if ( cmd = = " connect " )
{
string addr ;
eth : : uint port ;
iss > > addr > > port ;
c . connect ( addr , ( short ) port ) ;
}
else if ( cmd = = " netstop " )
c . stopNetwork ( ) ;
else if ( cmd = = " minestart " )
c . startMining ( ) ;
else if ( cmd = = " minestop " )
c . stopMining ( ) ;
else if ( cmd = = " address " )
{
ccout < < " Current address: " < < endl ;
const char * addchr = toHex ( us . address ( ) . asArray ( ) ) . c_str ( ) ;
ccout < < addchr < < endl ;
}
else if ( cmd = = " secret " )
{
ccout < < " Current secret: " < < endl ;
const char * addchr = toHex ( us . secret ( ) . asArray ( ) ) . c_str ( ) ;
ccout < < addchr < < endl ;
}
else if ( cmd = = " block " )
{
eth : : uint n = c . blockChain ( ) . details ( ) . number ;
ccout < < " Current block # " ;
const char * addchr = toString ( n ) . c_str ( ) ;
ccout < < addchr < < endl ;
}
else if ( cmd = = " peers " )
{
for ( auto it : c . peers ( ) )
cout < < it . host < < " : " < < it . port < < " , " < < it . clientVersion < < " , "
< < std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( it . lastPing ) . count ( ) < < " ms "
< < endl ;
}
else if ( cmd = = " balance " )
{
u256 balance = c . state ( ) . balance ( us . address ( ) ) ;
ccout < < " Current balance: " < < endl ;
const char * addchr = toString ( balance ) . c_str ( ) ;
ccout < < addchr < < endl ;
}
else if ( cmd = = " transact " )
{
vector < string > s ;
s . push_back ( " Address " ) ;
vector < string > l ;
l . push_back ( " Amount " ) ;
l . push_back ( " Gas price " ) ;
l . push_back ( " Gas " ) ;
vector < string > b ;
b . push_back ( " Secret " ) ;
b . push_back ( " Data " ) ;
c . lock ( ) ;
vector < string > fields = form_dialog ( s , l , b , height , width , cmd ) ;
c . unlock ( ) ;
int fs = fields . size ( ) ;
if ( fs < 6 )
{
if ( fs > 0 )
cwarn < < " Missing parameter " ;
}
else
{
fields [ 0 ] . erase ( std : : remove ( fields [ 0 ] . begin ( ) , fields [ 0 ] . end ( ) , ' ' ) , fields [ 0 ] . end ( ) ) ;
fields [ 4 ] . erase ( std : : remove ( fields [ 4 ] . begin ( ) , fields [ 4 ] . end ( ) , ' ' ) , fields [ 4 ] . end ( ) ) ;
fields [ 5 ] . erase ( std : : find_if ( fields [ 5 ] . rbegin ( ) , fields [ 5 ] . rend ( ) , std : : bind1st ( std : : not_equal_to < char > ( ) , ' ' ) ) . base ( ) , fields [ 5 ] . end ( ) ) ;
int size = fields [ 0 ] . length ( ) ;
u256 amount = atoll ( fields [ 1 ] . c_str ( ) ) ;
u256 gasPrice = atoll ( fields [ 2 ] . c_str ( ) ) ;
u256 gas = atoll ( fields [ 3 ] . c_str ( ) ) ;
string sechex = fields [ 4 ] ;
string sdata = fields [ 5 ] ;
int ssize = fields [ 4 ] . length ( ) ;
if ( size < 40 )
{
if ( size > 0 )
cwarn < < " Invalid address length: " < < size ;
}
else if ( amount < 0 )
cwarn < < " Invalid amount: " < < amount ;
else if ( gasPrice < c_minGasPrice )
cwarn < < " Minimum gas price is " < < c_minGasPrice ;
else if ( gas < c_minGas )
cwarn < < " Minimum gas amount is " < < c_minGas ;
else if ( ssize < 40 )
{
if ( ssize > 0 )
cwarn < < " Invalid secret length: " < < ssize ;
}
else
{
Secret secret = h256 ( fromHex ( sechex ) ) ;
Address dest = h160 ( fromHex ( fields [ 0 ] ) ) ;
bytes data = asBytes ( sdata ) ;
c . transact ( secret , amount , dest , data , gas , gasPrice ) ;
}
}
}
else if ( cmd = = " send " )
{
vector < string > s ;
s . push_back ( " Address " ) ;
vector < string > l ;
l . push_back ( " Amount " ) ;
vector < string > b ;
c . lock ( ) ;
vector < string > fields = form_dialog ( s , l , b , height , width , cmd ) ;
c . unlock ( ) ;
int fs = fields . size ( ) ;
if ( fs < 2 )
{
if ( fs > 0 )
cwarn < < " Missing parameter " ;
}
else
{
fields [ 0 ] . erase ( std : : remove ( fields [ 0 ] . begin ( ) , fields [ 0 ] . end ( ) , ' ' ) , fields [ 0 ] . end ( ) ) ;
int size = fields [ 0 ] . length ( ) ;
u256 amount = atoll ( fields [ 1 ] . c_str ( ) ) ;
if ( size < 40 )
{
if ( size > 0 )
cwarn < < " Invalid address length: " < < size ;
}
else if ( amount < = 0 )
cwarn < < " Invalid amount: " < < amount ;
else
{
u256 gasPrice = c_minGasPrice ;
u256 gas = c_minGas ;
Address dest = h160 ( fromHex ( fields [ 0 ] ) ) ;
c . transact ( us . secret ( ) , amount , dest , bytes ( ) , gas , gasPrice ) ;
}
}
}
else if ( cmd = = " contract " )
{
vector < string > s ;
vector < string > l ;
l . push_back ( " Endowment " ) ;
l . push_back ( " Gas price " ) ;
l . push_back ( " Gas " ) ;
vector < string > b ;
b . push_back ( " Code " ) ;
b . push_back ( " Init " ) ;
c . lock ( ) ;
vector < string > fields = form_dialog ( s , l , b , height , width , cmd ) ;
c . unlock ( ) ;
int fs = fields . size ( ) ;
if ( fs < 5 )
{
if ( fs > 0 )
cwarn < < " Missing parameter " ;
}
else
{
u256 endowment = atoll ( fields [ 0 ] . c_str ( ) ) ;
u256 gas = atoll ( fields [ 2 ] . c_str ( ) ) ;
u256 gasPrice = atoll ( fields [ 1 ] . c_str ( ) ) ;
if ( endowment < 0 )
cwarn < < " Invalid endowment " ;
else if ( gasPrice < c_minGasPrice )
cwarn < < " Minimum gas price is " < < c_minGasPrice ;
else if ( gas < c_minGas )
cwarn < < " Minimum gas amount is " < < c_minGas ;
else
{
fields [ 3 ] . erase ( std : : find_if ( fields [ 3 ] . rbegin ( ) , fields [ 3 ] . rend ( ) , std : : bind1st ( std : : not_equal_to < char > ( ) , ' ' ) ) . base ( ) , fields [ 3 ] . end ( ) ) ;
fields [ 4 ] . erase ( std : : find_if ( fields [ 4 ] . rbegin ( ) , fields [ 4 ] . rend ( ) , std : : bind1st ( std : : not_equal_to < char > ( ) , ' ' ) ) . base ( ) , fields [ 4 ] . end ( ) ) ;
string scode = fields [ 3 ] ;
string sinit = fields [ 4 ] ;
int size = scode . length ( ) ;
cout < < " Code: " < < endl < < scode < < endl ;
cout < < " Init: " < < endl < < sinit < < endl ;
cout < < " Code size: " < < size < < endl ;
if ( size < 1 )
cwarn < < " No code submitted " ;
else
{
eth : : bytes code = assemble ( scode ) ;
cout < < " Assembled: " < < endl < < code < < endl ;
eth : : bytes init = assemble ( sinit ) ;
cout < < " Init: " < < endl < < init < < endl ;
c . transact ( us . secret ( ) , endowment , code , init , gas , gasPrice ) ;
}
}
}
}
else if ( cmd = = " inspect " )
{
string rechex ;
iss > > rechex ;
if ( rechex . length ( ) ! = 40 )
cwarn < < " Invalid address length " ;
else
{
c . lock ( ) ;
auto h = h160 ( fromHex ( rechex ) ) ;
stringstream s ;
auto mem = c . state ( ) . contractStorage ( h ) ;
u256 next = 0 ;
unsigned numerics = 0 ;
bool unexpectedNumeric = false ;
for ( auto const & i : mem )
{
if ( next < i . first )
{
unsigned j ;
for ( j = 0 ; j < = numerics & & next + j < i . first ; + + j )
s < < ( j < numerics | | unexpectedNumeric ? " 0 " : " STOP " ) ;
unexpectedNumeric = false ;
numerics - = min ( numerics , j ) ;
if ( next + j < i . first )
s < < " \n @ " < < showbase < < hex < < i . first < < " " ;
}
else if ( ! next )
s < < " @ " < < showbase < < hex < < i . first < < " " ;
auto iit = c_instructionInfo . find ( ( Instruction ) ( unsigned ) i . second ) ;
if ( numerics | | iit = = c_instructionInfo . end ( ) | | ( u256 ) ( unsigned ) iit - > first ! = i . second ) // not an instruction or expecting an argument...
{
if ( numerics )
numerics - - ;
else
unexpectedNumeric = true ;
s < < " " < < showbase < < hex < < i . second ;
}
else
{
auto const & ii = iit - > second ;
s < < " " < < ii . name ;
numerics = ii . additional ;
}
next = i . first + 1 ;
}
string outFile = getDataDir ( ) + " / " + rechex + " .evm " ;
ofstream ofs ;
ofs . open ( outFile , ofstream : : binary ) ;
ofs . write ( s . str ( ) . c_str ( ) , s . str ( ) . length ( ) ) ;
ofs . close ( ) ;
c . unlock ( ) ;
}
}
else if ( cmd = = " help " )
interactiveHelp ( ) ;
else if ( cmd = = " exit " )
break ;
// Clear cmd at each pass
cmd = " " ;
// Blocks
auto const & st = c . state ( ) ;
auto const & bc = c . blockChain ( ) ;
y = 1 ;
for ( auto h = bc . currentHash ( ) ; h ! = bc . genesisHash ( ) ; h = bc . details ( h ) . parent )
{
auto d = bc . details ( h ) ;
string s = " # " + std : : to_string ( d . number ) + ' ' + toString ( h ) ; // .abridged();
mvwaddnstr ( blockswin , y + + , x , s . c_str ( ) , qwidth ) ;
for ( auto const & i : RLP ( bc . block ( h ) ) [ 1 ] )
{
Transaction t ( i . data ( ) ) ;
string ss ;
ss = t . receiveAddress ?
" " + toString ( toHex ( t . safeSender ( ) . asArray ( ) ) ) + " " + ( st . isContractAddress ( t . receiveAddress ) ? ' * ' : ' - ' ) + " > " + toString ( t . receiveAddress ) + " : " + toString ( formatBalance ( t . value ) ) + " [ " + toString ( ( unsigned ) t . nonce ) + " ] " :
" " + toString ( toHex ( t . safeSender ( ) . asArray ( ) ) ) + " +> " + toString ( right160 ( t . sha3 ( ) ) ) + " : " + toString ( formatBalance ( t . value ) ) + " [ " + toString ( ( unsigned ) t . nonce ) + " ] " ;
mvwaddnstr ( blockswin , y + + , x , ss . c_str ( ) , qwidth - 2 ) ;
if ( y > qheight - 2 )
break ;
}
if ( y > qheight - 2 )
break ;
}
// Pending
y = 1 ;
auto aps = c . pending ( ) ;
for ( auto const & t : aps )
{
string ss ;
if ( t . receiveAddress )
ss = toString ( toHex ( t . safeSender ( ) . asArray ( ) ) ) + " " + ( st . isContractAddress ( t . receiveAddress ) ? ' * ' : ' - ' ) + " > " + toString ( t . receiveAddress ) + " : " + toString ( formatBalance ( t . value ) ) + " " + " [ " + toString ( ( unsigned ) t . nonce ) + " ] " ;
else
ss = toString ( toHex ( t . safeSender ( ) . asArray ( ) ) ) + " +> " + toString ( right160 ( t . sha3 ( ) ) ) + " : " + toString ( formatBalance ( t . value ) ) + " [ " + toString ( ( unsigned ) t . nonce ) + " ] " ;
mvwaddnstr ( pendingwin , y + + , x , ss . c_str ( ) , qwidth ) ;
if ( y > qheight - 4 )
break ;
}
// Contracts and addresses
y = 1 ;
int cc = 1 ;
auto acs = st . addresses ( ) ;
for ( auto const & i : acs )
{
auto r = i . first ;
string ss ;
ss = toString ( r ) + pretty ( r , st ) + " : " + toString ( formatBalance ( i . second ) ) + " [ " + toString ( ( unsigned ) st . transactionsFrom ( i . first ) ) + " ] " ;
mvwaddnstr ( addswin , y + + , x , ss . c_str ( ) , width / 2 - 4 ) ;
scrollok ( addswin , true ) ;
if ( st . isContractAddress ( r ) )
{
ss = toString ( r ) + " : " + toString ( formatBalance ( i . second ) ) + " [ " + toString ( ( unsigned ) st . transactionsFrom ( i . first ) ) + " ] " ;
mvwaddnstr ( contractswin , cc + + , x , ss . c_str ( ) , qwidth ) ;
if ( cc > qheight - 2 )
break ;
}
if ( y > height * 2 / 5 - 2 )
break ;
}
// Peers
y = 1 ;
string psc ;
string pss ;
auto cp = c . peers ( ) ;
psc = toString ( cp . size ( ) ) + " peer(s) " ;
for ( PeerInfo const & i : cp )
{
pss = toString ( chrono : : duration_cast < chrono : : milliseconds > ( i . lastPing ) . count ( ) ) + " ms - " + i . host + " : " + toString ( i . port ) + " - " + i . clientVersion ;
mvwaddnstr ( peerswin , y + + , x , pss . c_str ( ) , qwidth ) ;
if ( y > height * 2 / 5 - 4 )
break ;
}
box ( consolewin , 0 , 0 ) ;
box ( blockswin , 0 , 0 ) ;
box ( pendingwin , 0 , 0 ) ;
box ( peerswin , 0 , 0 ) ;
box ( addswin , 0 , 0 ) ;
box ( contractswin , 0 , 0 ) ;
box ( mainwin , 0 , 0 ) ;
// Balance
stringstream ssb ;
u256 balance = c . state ( ) . balance ( us . address ( ) ) ;
Address gavCoin ( " 91a10664d0cd489085a7a018beb5245d4f2272f1 " ) ;
u256 totalGavCoinBalance = st . contractStorage ( gavCoin , ( u160 ) us . address ( ) ) ;
ssb < < " Balance: " < < formatBalance ( balance ) < < " | " < < totalGavCoinBalance < < " GAV " ;
mvwprintw ( consolewin , 0 , x , ssb . str ( ) . c_str ( ) ) ;
// Block
mvwprintw ( blockswin , 0 , x , " Block # " ) ;
eth : : uint n = c . blockChain ( ) . details ( ) . number ;
chr = toString ( n ) . c_str ( ) ;
mvwprintw ( blockswin , 0 , 10 , chr ) ;
// Pending
string pc ;
pc = " Pending: " + toString ( c . pending ( ) . size ( ) ) ;
mvwprintw ( pendingwin , 0 , x , pc . c_str ( ) ) ;
// Contracts
string sc = " Contracts: " ;
sc + = toString ( cc - 1 ) ;
mvwprintw ( contractswin , 0 , x , sc . c_str ( ) ) ;
// Peers
mvwprintw ( peerswin , 0 , x , " Peers: " ) ;
chr = toString ( c . peers ( ) . size ( ) ) . c_str ( ) ;
mvwprintw ( peerswin , 0 , 9 , chr ) ;
// Mining flag
if ( c . isMining ( ) )
mvwprintw ( consolewin , qheight - 1 , width / 4 - 11 , " Mining ON " ) ;
else
mvwprintw ( consolewin , qheight - 1 , width / 4 - 12 , " Mining OFF " ) ;
wmove ( consolewin , 1 , x ) ;
// Addresses
string ac ;
ac = " Addresses: " + toString ( acs . size ( ) ) ;
mvwprintw ( addswin , 0 , x , ac . c_str ( ) ) ;
wrefresh ( consolewin ) ;
wrefresh ( blockswin ) ;
wrefresh ( pendingwin ) ;
wrefresh ( peerswin ) ;
wrefresh ( addswin ) ;
wrefresh ( contractswin ) ;
wrefresh ( mainwin ) ;
}
delwin ( addswin ) ;
delwin ( contractswin ) ;
delwin ( peerswin ) ;
delwin ( pendingwin ) ;
delwin ( blockswin ) ;
delwin ( consolewin ) ;
delwin ( logwin ) ;
delwin ( mainwin ) ;
endwin ( ) ;
refresh ( ) ;
}
else
cout < < " Address: " < < endl < < toHex ( us . address ( ) . asArray ( ) ) < < endl ;
c . startNetwork ( listenPort , remoteHost , remotePort , mode , peers , publicIP , upnp ) ;
eth : : uint n = c . blockChain ( ) . details ( ) . number ;
if ( mining )
c . startMining ( ) ;
while ( true )
{
cout < < " Address: " < < endl < < toHex ( us . address ( ) . asArray ( ) ) < < endl ;
c . startNetwork ( listenPort , remoteHost , remotePort , mode , peers , publicIP , upnp ) ;
eth : : uint n = c . blockChain ( ) . details ( ) . number ;
if ( mining )
c . startMining ( ) ;
while ( true )
{
if ( c . blockChain ( ) . details ( ) . number - n = = mining )
c . stopMining ( ) ;
this_thread : : sleep_for ( chrono : : milliseconds ( 100 ) ) ;
}
if ( c . blockChain ( ) . details ( ) . number - n = = mining )
c . stopMining ( ) ;
this_thread : : sleep_for ( chrono : : milliseconds ( 100 ) ) ;
}
return 0 ;
}
void print_in_middle ( WINDOW * win , int starty , int startx , int width , string str , chtype color )
{
int length ;
int x = 0 ;
int y = 0 ;
float temp ;
if ( startx ! = 0 )
x = startx ;
if ( starty ! = 0 )
y = starty ;
if ( width = = 0 )
width = 80 ;
length = str . length ( ) ;
temp = ( width - length ) / 2 ;
x = startx + ( int ) temp ;
wattron ( win , color ) ;
mvwprintw ( win , y , x , " %s " , str . c_str ( ) ) ;
wattroff ( win , color ) ;
refresh ( ) ;
}
vector < string > form_dialog ( vector < string > _sv , vector < string > _lv , vector < string > _bv , int _cols , int _rows , string _post_form )
{
vector < string > vs ;
WINDOW * form_win ;
int _sfields = _sv . size ( ) ;
int _lfields = _lv . size ( ) ;
int _bfields = _bv . size ( ) ;
int maxfields = _sfields + _lfields + _bfields ;
FIELD * field [ maxfields ] ;
int ch ;
int starty = 6 ;
int height = _cols ;
int width = _rows ;
// Initialize the fields
int si ;
int li ;
int bi = 0 ;
vector < int > labels ;
for ( si = 0 ; si < _sfields ; + + si )
{
starty + + ; // Leave room for our labels, no window yet so that or fake fields...
field [ si ] = new_field ( 1 , 40 , starty + + , 1 , 0 , 0 ) ;
labels . push_back ( starty ) ;
set_field_back ( field [ si ] , A_UNDERLINE ) ;
set_field_type ( field [ si ] , TYPE_ALNUM , 40 ) ;
}
for ( li = _sfields ; li < _sfields + _lfields ; + + li )
{
starty + + ;
field [ li ] = new_field ( 1 , 64 , starty + + , 1 , 3 , 0 ) ;
labels . push_back ( starty ) ;
set_field_back ( field [ li ] , A_UNDERLINE ) ;
}
for ( bi = _sfields + _lfields ; bi < maxfields ; + + bi )
{
starty + + ;
field [ bi ] = new_field ( 5 , 72 , starty + + , 1 , 0 , 0 ) ;
labels . push_back ( starty ) ;
field_opts_off ( field [ bi ] , O_STATIC ) ;
set_field_back ( field [ bi ] , A_UNDERLINE ) ;
starty + = 4 ;
}
field [ maxfields ] = NULL ;
// Create the form and post it
FORM * form = new_form ( field ) ;
// Calculate the area required for the form
scale_form ( form , & _rows , & _cols ) ;
// Create the window to be associated with the form
form_win = newwin ( _rows + 4 , _cols + 8 , ( height / 2 - _rows / 2 - 2 ) , ( width / 2 - _cols / 2 - 2 ) ) ;
// Set main window and sub window
set_form_win ( form , form_win ) ;
set_form_sub ( form , derwin ( form_win , _rows , _cols , 2 , 2 ) ) ;
nodelay ( form_win , true ) ;
keypad ( form_win , true ) ;
noecho ( ) ;
timeout ( 0 ) ;
box ( form_win , 0 , 0 ) ;
print_in_middle ( form_win , 1 , 0 , _cols , _post_form , COLOR_PAIR ( 2 ) ) ;
post_form ( form ) ;
// Set labels
int ca = 0 ;
int cf ;
for ( cf = 0 ; cf < _sfields ; + + cf )
{
wattron ( form_win , COLOR_PAIR ( 3 ) ) ;
mvwprintw ( form_win , labels [ ca ] , 3 , _sv [ cf ] . c_str ( ) ) ;
wattroff ( form_win , COLOR_PAIR ( 3 ) ) ;
ca + + ;
}
for ( cf = 0 ; cf < _lfields ; + + cf )
{
wattron ( form_win , COLOR_PAIR ( 3 ) ) ;
mvwprintw ( form_win , labels [ ca ] , 3 , _lv [ cf ] . c_str ( ) ) ;
mvwprintw ( form_win , labels [ ca ] + 1 , _cols - 1 , " wei " ) ;
wattroff ( form_win , COLOR_PAIR ( 3 ) ) ;
ca + + ;
}
for ( cf = 0 ; cf < _bfields ; + + cf )
{
wattron ( form_win , COLOR_PAIR ( 3 ) ) ;
mvwprintw ( form_win , labels [ ca ] , 3 , _bv [ cf ] . c_str ( ) ) ;
wattroff ( form_win , COLOR_PAIR ( 3 ) ) ;
ca + + ;
}
wrefresh ( form_win ) ;
print_in_middle ( form_win , 3 , 0 , _cols , string ( " Use the TAB key to switch between fields. " ) , COLOR_PAIR ( 1 ) ) ;
print_in_middle ( form_win , 4 , 0 , _cols , string ( " Use UP, DOWN arrow keys to switch between lines. " ) , COLOR_PAIR ( 1 ) ) ;
print_in_middle ( form_win , 6 , 0 , _cols , string ( " Press ENTER to submit the form and ESC to cancel. " ) , COLOR_PAIR ( 1 ) ) ;
refresh ( ) ;
while ( ( ch = wgetch ( form_win ) ) ! = 27 & & ch ! = 13 ) // KEY_F(1))
{
switch ( ch )
{
case 9 : // Tab
form_driver ( form , REQ_NEXT_FIELD ) ;
form_driver ( form , REQ_END_LINE ) ;
break ;
case KEY_DOWN :
form_driver ( form , REQ_NEXT_LINE ) ;
break ;
case KEY_UP :
form_driver ( form , REQ_PREV_LINE ) ;
break ;
case KEY_LEFT :
form_driver ( form , REQ_LEFT_CHAR ) ;
break ;
case KEY_RIGHT :
form_driver ( form , REQ_RIGHT_CHAR ) ;
break ;
case KEY_BACKSPACE : // Backspace
case KEY_DC :
case KEY_DL :
case 127 :
form_driver ( form , REQ_DEL_PREV ) ;
wrefresh ( form_win ) ;
break ;
case KEY_ENTER : // Enter
case 13 :
case 27 : // Esc
break ;
default :
form_driver ( form , ch ) ;
break ;
}
}
if ( form_driver ( form , REQ_VALIDATION ) ! = E_OK )
cwarn < < " Validation error " ;
int fi ;
for ( fi = 0 ; fi < maxfields ; + + fi )
free_field ( field [ fi ] ) ;
free_form ( form ) ;
unpost_form ( form ) ;
echo ( ) ;
timeout ( 30000 ) ;
delwin ( form_win ) ;
if ( ch = = 13 )
for ( int fi = 0 ; fi < maxfields ; + + fi )
vs . push_back ( field_buffer ( field [ fi ] , 0 ) ) ;
return vs ;
}