@ -163,8 +163,29 @@ void Transact::on_destination_currentTextChanged(QString)
// updateFee();
}
static std : : string toString ( TransactionException _te )
{
switch ( _te )
{
case TransactionException : : Unknown : return " Unknown error " ;
case TransactionException : : InvalidSignature : return " Permanent Abort: Invalid transaction signature " ;
case TransactionException : : InvalidNonce : return " Transient Abort: Invalid transaction nonce " ;
case TransactionException : : NotEnoughCash : return " Transient Abort: Not enough cash to pay for transaction " ;
case TransactionException : : OutOfGasBase : return " Permanent Abort: Not enough gas to consider transaction " ;
case TransactionException : : BlockGasLimitReached : return " Transient Abort: Gas limit of block reached " ;
case TransactionException : : BadInstruction : return " VM Error: Attempt to execute invalid instruction " ;
case TransactionException : : BadJumpDestination : return " VM Error: Attempt to jump to invalid destination " ;
case TransactionException : : OutOfGas : return " VM Error: Out of gas " ;
case TransactionException : : OutOfStack : return " VM Error: VM stack limit reached during execution " ;
case TransactionException : : StackUnderflow : return " VM Error: Stack underflow " ;
default : ; return std : : string ( ) ;
}
}
void Transact : : rejigData ( )
{
if ( ! ethereum ( ) )
return ;
if ( isCreation ( ) )
{
string src = ui - > data - > toPlainText ( ) . toStdString ( ) ;
@ -226,26 +247,61 @@ void Transact::rejigData()
}
}
QString errs ;
qint64 gasNeeded = 0 ;
if ( errors . size ( ) )
{
errs = " <h4>Errors</h4> " ;
for ( auto const & i : errors )
errs . append ( " <div style= \" border-left: 6px solid #c00; margin-top: 2px \" > " + QString : : fromStdString ( i ) . toHtmlEscaped ( ) + " </div> " ) ;
}
else
{
if ( true )
{
auto s = findSecret ( value ( ) + ethereum ( ) - > gasLimitRemaining ( ) * gasPrice ( ) ) ;
if ( ! s )
errs + = " <div class= \" error \" ><span class= \" icon \" >ERROR</span> No single account contains enough gas.</div> " ;
// TODO: use account with most balance anyway.
else
{
ExecutionResult er = ethereum ( ) - > create ( s , value ( ) , m_data , ethereum ( ) - > gasLimitRemaining ( ) , gasPrice ( ) ) ;
gasNeeded = ( qint64 ) er . gasUsed ;
auto base = ( qint64 ) Interface : : txGas ( m_data , 0 ) ;
errs + = QString ( " <div class= \" info \" ><span class= \" icon \" >INFO</span> Gas required: %1 base, %2 init</div> " ) . arg ( base ) . arg ( ( qint64 ) er . gasUsed - base ) ;
if ( er . excepted ! = TransactionException : : None )
errs + = " <div class= \" error \" ><span class= \" icon \" >ERROR</span> " + QString : : fromStdString ( toString ( er . excepted ) ) + " </div> " ;
if ( er . codeDeposit = = CodeDeposit : : Failed )
errs + = " <div class= \" error \" ><span class= \" icon \" >ERROR</span> Code deposit failed due to insufficient gas</div> " ;
}
}
else
gasNeeded = ( qint64 ) Interface : : txGas ( m_data , 0 ) ;
}
ui - > code - > setHtml ( errs + lll + solidity + " <h4>Code</h4> " + QString : : fromStdString ( disassemble ( m_data ) ) . toHtmlEscaped ( ) + " <h4>Hex</h4> " Div ( Mono ) + QString : : fromStdString ( toHex ( m_data ) ) + " </div> " ) ;
ui - > gas - > setMinimum ( ( qint64 ) Interface : : txGas ( m_data , 0 ) ) ;
if ( ! ui - > gas - > isEnabled ( ) )
ui - > gas - > setValue ( m_backupGas ) ;
if ( ui - > gas - > value ( ) = = ui - > gas - > minimum ( ) )
{
ui - > gas - > setMinimum ( gasNeeded ) ;
ui - > gas - > setValue ( gasNeeded ) ;
}
else
ui - > gas - > setMinimum ( gasNeeded ) ;
// if (!ui->gas->isEnabled())
// ui->gas->setValue(m_backupGas);
ui - > gas - > setEnabled ( true ) ;
if ( ui - > gas - > value ( ) = = ui - > gas - > minimum ( ) & & ! src . empty ( ) )
ui - > gas - > setValue ( ( int ) ( m_ethereum - > postState ( ) . gasLimitRemaining ( ) / 10 ) ) ;
// if (ui->gas->value() == ui->gas->minimum() && !src.empty())
// ui->gas->setValue((int)(m_ethereum->postState().gasLimitRemaining() / 10));
}
else
{
auto base = ( qint64 ) Interface : : txGas ( m_data , 0 ) ;
m_data = parseData ( ui - > data - > toPlainText ( ) . toStdString ( ) ) ;
auto to = m_context - > fromString ( ui - > destination - > currentText ( ) ) ;
QString natspec ;
if ( ethereum ( ) - > codeAt ( to , 0 ) . size ( ) )
QString errs ;
if ( ethereum ( ) - > codeAt ( to , PendingBlock ) . size ( ) )
{
string userNotice = m_natSpecDB - > getUserNotice ( ethereum ( ) - > postState ( ) . codeHash ( to ) , m_data ) ;
if ( userNotice . empty ( ) )
@ -255,7 +311,35 @@ void Transact::rejigData()
NatspecExpressionEvaluator evaluator ;
natspec = evaluator . evalExpression ( QString : : fromStdString ( userNotice ) ) ;
}
ui - > gas - > setMinimum ( ( qint64 ) Interface : : txGas ( m_data , 1 ) ) ;
qint64 gasNeeded = 0 ;
if ( true )
{
auto s = findSecret ( value ( ) + ethereum ( ) - > gasLimitRemaining ( ) * gasPrice ( ) ) ;
if ( ! s )
errs + = " <div class= \" error \" ><span class= \" icon \" >ERROR</span> No single account contains enough gas.</div> " ;
// TODO: use account with most balance anyway.
else
{
ExecutionResult er = ethereum ( ) - > call ( s , value ( ) , to , m_data , ethereum ( ) - > gasLimitRemaining ( ) , gasPrice ( ) ) ;
gasNeeded = ( qint64 ) er . gasUsed ;
errs + = QString ( " <div class= \" info \" ><span class= \" icon \" >INFO</span> Gas required: %1 base, %2 exec</div> " ) . arg ( base ) . arg ( ( qint64 ) er . gasUsed - base ) ;
if ( er . excepted ! = TransactionException : : None )
errs + = " <div class= \" error \" ><span class= \" icon \" >ERROR</span> " + QString : : fromStdString ( toString ( er . excepted ) ) + " </div> " ;
}
}
else
gasNeeded = ( qint64 ) Interface : : txGas ( m_data , 0 ) ;
if ( ui - > gas - > value ( ) = = ui - > gas - > minimum ( ) )
{
ui - > gas - > setMinimum ( gasNeeded ) ;
ui - > gas - > setValue ( gasNeeded ) ;
}
else
ui - > gas - > setMinimum ( gasNeeded ) ;
if ( ! ui - > gas - > isEnabled ( ) )
ui - > gas - > setValue ( m_backupGas ) ;
ui - > gas - > setEnabled ( true ) ;
@ -265,50 +349,57 @@ void Transact::rejigData()
natspec + = " Destination not a contract. " ;
if ( ui - > gas - > isEnabled ( ) )
m_backupGas = ui - > gas - > value ( ) ;
ui - > gas - > setValue ( ( qint64 ) Interface : : txGas ( m_data ) ) ;
ui - > gas - > setMinimum ( base ) ;
ui - > gas - > setValue ( base ) ;
ui - > gas - > setEnabled ( false ) ;
}
ui - > code - > setHtml ( " <h3>NatSpec</h3> " + natspec + " <h3>Dump</h3> " + QString : : fromStdString ( dev : : memDump ( m_data , 8 , true ) ) + " <h3>Hex</h3> " + Div ( Mono ) + QString : : fromStdString ( toHex ( m_data ) ) + " </div> " ) ;
ui - > code - > setHtml ( errs + " <h3>NatSpec</h3> " + natspec + " <h3>Dump</h3> " + QString : : fromStdString ( dev : : memDump ( m_data , 8 , true ) ) + " <h3>Hex</h3> " + Div ( Mono ) + QString : : fromStdString ( toHex ( m_data ) ) + " </div> " ) ;
}
updateFee ( ) ;
}
Secret Transact : : findSecret ( u256 _totalReq ) const
{
if ( ethereum ( ) )
for ( auto const & i : m_myKeys )
if ( ethereum ( ) - > balanceAt ( i . address ( ) , PendingBlock ) > = _totalReq )
return i . secret ( ) ;
return Secret ( ) ;
}
void Transact : : on_send_clicked ( )
{
u256 totalReq = value ( ) + fee ( ) ;
for ( auto const & i : m_myKeys )
if ( ethereum ( ) - > balanceAt ( i . address ( ) , 0 ) > = totalReq )
{
Secret s = i . secret ( ) ;
if ( isCreation ( ) )
Secret s = findSecret ( value ( ) + fee ( ) ) ;
if ( ! s )
{
QMessageBox : : critical ( this , " Transaction Failed " , " Couldn't make transaction: no single account contains at least the required amount. " ) ;
return ;
}
if ( isCreation ( ) )
{
// If execution is a contract creation, add Natspec to
// a local Natspec LEVELDB
ethereum ( ) - > submitTransaction ( s , value ( ) , m_data , ui - > gas - > value ( ) , gasPrice ( ) ) ;
string src = ui - > data - > toPlainText ( ) . toStdString ( ) ;
if ( sourceIsSolidity ( src ) )
try
{
// If execution is a contract creation, add Natspec to
// a local Natspec LEVELDB
ExecutionResult er = ethereum ( ) - > create ( s , value ( ) , m_data , ui - > gas - > value ( ) , gasPrice ( ) ) ;
ethereum ( ) - > submitTransaction ( s , value ( ) , m_data , ui - > gas - > value ( ) , gasPrice ( ) ) ;
string src = ui - > data - > toPlainText ( ) . toStdString ( ) ;
if ( sourceIsSolidity ( src ) )
try
{
dev : : solidity : : CompilerStack compiler ( true ) ;
m_data = compiler . compile ( src , ui - > optimize - > isChecked ( ) ) ;
for ( string const & s : compiler . getContractNames ( ) )
{
h256 contractHash = compiler . getContractCodeHash ( s ) ;
m_natSpecDB - > add ( contractHash , compiler . getMetadata ( s , dev : : solidity : : DocumentationType : : NatspecUser ) ) ;
}
}
catch ( . . . )
{
}
close ( ) ;
return ;
dev : : solidity : : CompilerStack compiler ( true ) ;
m_data = compiler . compile ( src , ui - > optimize - > isChecked ( ) ) ;
for ( string const & s : compiler . getContractNames ( ) )
{
h256 contractHash = compiler . getContractCodeHash ( s ) ;
m_natSpecDB - > add ( contractHash , compiler . getMetadata ( s , dev : : solidity : : DocumentationType : : NatspecUser ) ) ;
}
}
else
ethereum ( ) - > submitTransaction ( s , value ( ) , m_context - > fromString ( ui - > destination - > currentText ( ) ) , m_data , ui - > gas - > value ( ) , gasPrice ( ) ) ;
return ;
}
QMessageBox : : critical ( this , " Transaction Failed " , " Couldn't make transaction: no single account contains at least the required amount. " ) ;
catch ( . . . )
{
}
}
else
ethereum ( ) - > submitTransaction ( s , value ( ) , m_context - > fromString ( ui - > destination - > currentText ( ) ) , m_data , ui - > gas - > value ( ) , gasPrice ( ) ) ;
close ( ) ;
}
void Transact : : on_debug_clicked ( )