Browse Source

Better AddressState behaviour.

cl-refactor
Gav Wood 11 years ago
parent
commit
d682499743
  1. 28
      alethzero/MainWin.cpp
  2. 4
      eth/main.cpp
  3. 8
      libethereum/AddressState.cpp
  4. 39
      libethereum/AddressState.h
  5. 100
      libethereum/State.cpp
  6. 64
      libethereum/State.h
  7. 8
      libqethereum/QEthereum.cpp
  8. 16
      neth/main.cpp

28
alethzero/MainWin.cpp

@ -254,11 +254,11 @@ QString Main::pretty(eth::Address _a) const
{
h256 n;
if (h160 nameReg = (u160)state().contractStorage(c_config, 0))
n = state().contractStorage(nameReg, (u160)(_a));
if (h160 nameReg = (u160)state().storage(c_config, 0))
n = state().storage(nameReg, (u160)(_a));
if (!n)
n = state().contractStorage(m_nameReg, (u160)(_a));
n = state().storage(m_nameReg, (u160)(_a));
if (n)
{
@ -291,11 +291,11 @@ Address Main::fromString(QString const& _a) const
memset(n.data() + sn.size(), 0, 32 - sn.size());
if (_a.size())
{
if (h160 nameReg = (u160)state().contractStorage(c_config, 0))
if (h256 a = state().contractStorage(nameReg, n))
if (h160 nameReg = (u160)state().storage(c_config, 0))
if (h256 a = state().storage(nameReg, n))
return right160(a);
if (h256 a = state().contractStorage(m_nameReg, n))
if (h256 a = state().storage(m_nameReg, n))
return right160(a);
}
if (_a.size() == 40)
@ -428,7 +428,7 @@ void Main::refresh(bool _override)
{
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(i.second).c_str()).arg(r).arg((unsigned)state().transactionsFrom(i.first)), ui->accounts))
->setData(Qt::UserRole, QByteArray((char const*)i.first.data(), Address::size));
if (st.isContractAddress(i.first))
if (st.addressHasCode(i.first))
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(i.second).c_str()).arg(r).arg((unsigned)st.transactionsFrom(i.first)), ui->contracts))
->setData(Qt::UserRole, QByteArray((char const*)i.first.data(), Address::size));
@ -455,7 +455,7 @@ void Main::refresh(bool _override)
.arg(render(t.safeSender()))
.arg(render(t.receiveAddress))
.arg((unsigned)t.nonce)
.arg(st.isContractAddress(t.receiveAddress) ? '*' : '-') :
.arg(st.addressHasCode(t.receiveAddress) ? '*' : '-') :
QString("%2 +> %3: %1 [%4]")
.arg(formatBalance(t.value).c_str())
.arg(render(t.safeSender()))
@ -481,7 +481,7 @@ void Main::refresh(bool _override)
.arg(render(t.safeSender()))
.arg(render(t.receiveAddress))
.arg((unsigned)t.nonce)
.arg(st.isContractAddress(t.receiveAddress) ? '*' : '-') :
.arg(st.addressHasCode(t.receiveAddress) ? '*' : '-') :
QString(" %2 +> %3: %1 [%4]")
.arg(formatBalance(t.value).c_str())
.arg(render(t.safeSender()))
@ -509,7 +509,7 @@ void Main::refresh(bool _override)
->setData(Qt::UserRole, QByteArray((char const*)i.address().data(), Address::size));
totalBalance += b;
totalGavCoinBalance += st.contractStorage(gavCoin, (u160)i.address());
totalGavCoinBalance += st.storage(gavCoin, (u160)i.address());
}
ui->balance->setText(QString::fromStdString(toString(totalGavCoinBalance) + " GAV | " + formatBalance(totalBalance)));
@ -609,10 +609,10 @@ void Main::on_contracts_currentItemChanged()
auto h = h160((byte const*)hba.data(), h160::ConstructFromPointer);
stringstream s;
auto storage = state().contractStorage(h);
auto storage = state().storage(h);
for (auto const& i: storage)
s << "@" << showbase << hex << i.first << "&nbsp;&nbsp;&nbsp;&nbsp;" << showbase << hex << i.second << "<br/>";
s << "<h4>Body Code</h4>" << disassemble(state().contractCode(h));
s << "<h4>Body Code</h4>" << disassemble(state().code(h));
ui->contractInfo->appendHtml(QString::fromStdString(s.str()));
}
m_client->unlock();
@ -753,7 +753,7 @@ void Main::on_data_textChanged()
s = s.mid(1);
}
ui->code->setHtml(QString::fromStdString(htmlDump(m_data)));
if (m_client->postState().isContractAddress(fromString(ui->destination->currentText())))
if (m_client->postState().addressHasCode(fromString(ui->destination->currentText())))
{
ui->gas->setMinimum((qint64)state().callGas(m_data.size(), 1));
if (!ui->gas->isEnabled())
@ -922,7 +922,7 @@ void Main::on_debug_clicked()
bool ok = true;
while (ok)
{
m_history.append(WorldState({m_currentExecution->vm().curPC(), m_currentExecution->vm().gas(), m_currentExecution->vm().stack(), m_currentExecution->vm().memory(), m_currentExecution->state().contractStorage(m_currentExecution->ext().myAddress)}));
m_history.append(WorldState({m_currentExecution->vm().curPC(), m_currentExecution->vm().gas(), m_currentExecution->vm().stack(), m_currentExecution->vm().memory(), m_currentExecution->state().storage(m_currentExecution->ext().myAddress)}));
ok = !m_currentExecution->go(1);
}
initDebugger();

4
eth/main.cpp

@ -112,8 +112,8 @@ string pretty(h160 _a, eth::State _st)
{
string ns;
h256 n;
if (h160 nameReg = (u160)_st.contractStorage(c_config, 0))
n = _st.contractStorage(nameReg, (u160)(_a));
if (h160 nameReg = (u160)_st.storage(c_config, 0))
n = _st.storage(nameReg, (u160)(_a));
if (n)
{
std::string s((char const*)n.data(), 32);

8
libethereum/AddressState.cpp

@ -23,11 +23,3 @@
#include "CommonEth.h"
using namespace std;
using namespace eth;
AddressState::AddressState(u256 _balance, u256 _nonce, bytesConstRef _code):
m_isAlive(true),
m_isComplete(true),
m_balance(_balance),
m_nonce(_nonce),
m_code(_code.toBytes())
{}

39
libethereum/AddressState.h

@ -27,16 +27,15 @@
namespace eth
{
// TODO: Don't pre-cache all of storage.
// TODO: Document.
class AddressState
{
public:
AddressState(): m_isAlive(false), m_isComplete(false), m_balance(0), m_nonce(0) {}
AddressState(u256 _balance, u256 _nonce, h256 _contractRoot, h256 _codeHash): m_isAlive(true), m_isComplete(_codeHash == EmptySHA3 && !_contractRoot), m_balance(_balance), m_nonce(_nonce), m_storageRoot(_contractRoot), m_codeHash(_codeHash) {}
AddressState(u256 _balance, u256 _nonce, bytesConstRef _code);
AddressState(): m_isAlive(false), m_balance(0), m_nonce(0) {}
AddressState(u256 _balance, u256 _nonce, h256 _contractRoot, h256 _codeHash): m_isAlive(true), m_balance(_balance), m_nonce(_nonce), m_storageRoot(_contractRoot), m_codeHash(_codeHash) {}
void kill() { m_isAlive = false; m_storage.clear(); m_codeHash = EmptySHA3; m_storageRoot = h256(); m_balance = 0; m_nonce = 0; }
void kill() { m_isAlive = false; m_storageOverlay.clear(); m_codeHash = EmptySHA3; m_storageRoot = h256(); m_balance = 0; m_nonce = 0; }
bool isAlive() const { return m_isAlive; }
u256& balance() { return m_balance; }
@ -47,29 +46,33 @@ public:
u256 const& nonce() const { return m_nonce; }
void incNonce() { m_nonce++; }
bool isComplete() const { return m_isComplete; }
std::map<u256, u256>& setIsComplete(bytesConstRef _code) { m_isComplete = true; m_storageRoot = h256(); m_code = _code.toBytes(); return m_storage; }
h256 oldRoot() const { assert(!isComplete()); return m_storageRoot; }
std::map<u256, u256>& memory() { return m_storage; }
std::map<u256, u256> const& memory() const { assert(isComplete()); return m_storage; }
h256 oldRoot() const { assert(m_storageOverlay.empty()); return m_storageRoot; }
std::map<u256, u256> const& storage() const { return m_storageOverlay; }
void setStorage(u256 _p, u256 _v) { m_storageOverlay[_p] = _v; }
bool isFreshCode() const { return !m_codeHash; }
h256 codeHash() const { assert(m_codeHash); return m_codeHash; }
bytes const& code() const { assert(isComplete()); return m_code; }
bool freshCode() const { return !m_codeHash && m_isComplete; }
void setCode(bytesConstRef _code) { assert(freshCode()); m_code = _code.toBytes(); }
bytes const& code() const { assert(m_codeHash == EmptySHA3 || !m_codeHash || m_codeCache.size()); return m_codeCache; }
void setCode(bytesConstRef _code) { assert(!m_codeHash); m_codeCache = _code.toBytes(); }
void noteCode(bytesConstRef _code) { assert(sha3(_code) == m_codeHash); m_codeCache = _code.toBytes(); }
private:
bool m_isAlive;
bool m_isComplete;
bool m_gotCode;
u256 m_balance;
u256 m_nonce;
/// The base storage root. Used with the state DB to give a base to the storage. m_storageOverlay is overlaid on this and takes precedence for all values set.
h256 m_storageRoot;
h256 m_codeHash; // if 0 and m_isComplete, has been created and needs to be inserted.
/// If 0 then we're in the limbo where we're running the initialisation code. We expect a setCode() at some point later.
/// If EmptySHA3, then m_code, which should be empty, is valid.
/// If anything else, then m_code is valid iff it's not empty, otherwise, State::ensureCached() needs to be called with the correct args.
h256 m_codeHash;
// TODO: change to unordered_map.
std::map<u256, u256> m_storage;
bytes m_code;
std::map<u256, u256> m_storageOverlay;
bytes m_codeCache;
};
}

100
libethereum/State.cpp

@ -116,12 +116,12 @@ State& State::operator=(State const& _s)
return *this;
}
void State::ensureCached(Address _a, bool _requireMemory, bool _forceCreate) const
void State::ensureCached(Address _a, bool _requireCode, bool _forceCreate) const
{
ensureCached(m_cache, _a, _requireMemory, _forceCreate);
ensureCached(m_cache, _a, _requireCode, _forceCreate);
}
void State::ensureCached(std::map<Address, AddressState>& _cache, Address _a, bool _requireMemory, bool _forceCreate) const
void State::ensureCached(std::map<Address, AddressState>& _cache, Address _a, bool _requireCode, bool _forceCreate) const
{
auto it = _cache.find(_a);
if (it == _cache.end())
@ -139,14 +139,8 @@ void State::ensureCached(std::map<Address, AddressState>& _cache, Address _a, bo
bool ok;
tie(it, ok) = _cache.insert(make_pair(_a, s));
}
if (_requireMemory && !it->second.isComplete())
{
// Populate memory.
TrieDB<h256, Overlay> memdb(const_cast<Overlay*>(&m_db), it->second.oldRoot()); // promise we won't alter the overlay! :)
map<u256, u256>& mem = it->second.setIsComplete(it->second.codeHash() == EmptySHA3 ? bytesConstRef() : bytesConstRef(m_db.lookup(it->second.codeHash())));
for (auto const& i: memdb)
mem[i.first] = RLP(i.second).toInt<u256>();
}
if (_requireCode && it != _cache.end() && !it->second.isFreshCode())
it->second.noteCode(it->second.codeHash() == EmptySHA3 ? bytesConstRef() : bytesConstRef(m_db.lookup(it->second.codeHash())));
}
void State::commit()
@ -496,22 +490,22 @@ MineInfo State::mine(uint _msTimeout)
return ret;
}
bool State::isNormalAddress(Address _id) const
bool State::addressInUse(Address _id) const
{
ensureCached(_id, false, false);
auto it = m_cache.find(_id);
if (it == m_cache.end())
return false;
return it->second.codeHash() == EmptySHA3;
return true;
}
bool State::isContractAddress(Address _id) const
bool State::addressHasCode(Address _id) const
{
ensureCached(_id, false, false);
auto it = m_cache.find(_id);
if (it == m_cache.end())
return false;
return it->second.codeHash() != EmptySHA3;
return it->second.isFreshCode() || it->second.codeHash() != EmptySHA3;
}
u256 State::balance(Address _id) const
@ -563,38 +557,60 @@ u256 State::transactionsFrom(Address _id) const
return it->second.nonce();
}
u256 State::contractStorage(Address _id, u256 _memory) const
u256 State::storage(Address _id, u256 _memory) const
{
ensureCached(_id, false, false);
auto it = m_cache.find(_id);
if (it == m_cache.end() || it->second.codeHash() == EmptySHA3)
return 0;
else if (it->second.isComplete())
{
auto mit = it->second.memory().find(_memory);
if (mit == it->second.memory().end())
// Account doesn't exist - exit now.
if (it == m_cache.end())
return 0;
// See if it's in the account's storage cache.
auto mit = it->second.storage().find(_memory);
if (mit != it->second.storage().end())
return mit->second;
}
// Memory not cached - just grab one item from the DB rather than cache the lot.
// Not in the storage cache - go to the DB.
TrieDB<h256, Overlay> memdb(const_cast<Overlay*>(&m_db), it->second.oldRoot()); // promise we won't change the overlay! :)
string ret = memdb.at(_memory);
return ret.size() ? RLP(ret).toInt<u256>() : 0;
string payload = memdb.at(_memory);
u256 ret = payload.size() ? RLP(payload).toInt<u256>() : 0;
it->second.setStorage(_memory, ret);
return ret;
}
map<u256, u256> const& State::contractStorage(Address _contract) const
map<u256, u256> State::storage(Address _id) const
{
if (!isContractAddress(_contract))
return EmptyMapU256U256;
ensureCached(_contract, true, true);
return m_cache[_contract].memory();
map<u256, u256> ret;
ensureCached(_id, false, false);
auto it = m_cache.find(_id);
if (it != m_cache.end())
{
// Pull out all values from trie storage.
if (it->second.oldRoot())
{
TrieDB<h256, Overlay> memdb(const_cast<Overlay*>(&m_db), it->second.oldRoot()); // promise we won't alter the overlay! :)
ret = it->second.storage();
for (auto const& i: memdb)
ret[i.first] = RLP(i.second).toInt<u256>();
}
// Then merge cached storage over the top.
for (auto const& i: it->second.storage())
if (i.second)
ret.insert(i);
else
ret.erase(i.first);
}
return ret;
}
bytes const& State::contractCode(Address _contract) const
bytes const& State::code(Address _contract) const
{
if (!isContractAddress(_contract))
if (!addressHasCode(_contract))
return EmptyBytes;
ensureCached(_contract, true, true);
ensureCached(_contract, true, false);
return m_cache[_contract].code();
}
@ -665,10 +681,10 @@ void Executive::call(Address _receiveAddress, Address _senderAddress, u256 _valu
// cnote << "Transferring" << formatBalance(_value) << "to receiver.";
m_s.addBalance(_receiveAddress, _value);
if (m_s.isContractAddress(_receiveAddress))
if (m_s.addressHasCode(_receiveAddress))
{
m_vm = new VM(_gas);
m_ext = new ExtVM(m_s, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &m_s.contractCode(_receiveAddress));
m_ext = new ExtVM(m_s, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &m_s.code(_receiveAddress));
}
else
m_endGas = _gas;
@ -677,11 +693,11 @@ void Executive::call(Address _receiveAddress, Address _senderAddress, u256 _valu
void Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _init, Address _origin)
{
m_newAddress = right160(sha3(rlpList(_sender, m_s.transactionsFrom(_sender) - 1)));
while (m_s.isContractAddress(m_newAddress) || m_s.isNormalAddress(m_newAddress))
while (m_s.addressInUse(m_newAddress))
m_newAddress = (u160)m_newAddress + 1;
// Set up new account...
m_s.m_cache[m_newAddress] = AddressState(0, 0, bytesConstRef());
m_s.m_cache[m_newAddress] = AddressState(0, 0, h256(), h256());
// Execute _init.
m_vm = new VM(_gas);
@ -780,10 +796,10 @@ bool State::call(Address _receiveAddress, Address _senderAddress, u256 _value, u
// cnote << "Transferring" << formatBalance(_value) << "to receiver.";
addBalance(_receiveAddress, _value);
if (isContractAddress(_receiveAddress))
if (addressHasCode(_receiveAddress))
{
VM vm(*_gas);
ExtVM evm(*this, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &contractCode(_receiveAddress));
ExtVM evm(*this, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &code(_receiveAddress));
bool revert = false;
try
@ -826,11 +842,11 @@ h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas,
_origin = _sender;
Address newAddress = right160(sha3(rlpList(_sender, transactionsFrom(_sender) - 1)));
while (isContractAddress(newAddress) || isNormalAddress(newAddress))
while (addressInUse(newAddress))
newAddress = (u160)newAddress + 1;
// Set up new account...
m_cache[newAddress] = AddressState(0, 0, {});
m_cache[newAddress] = AddressState(0, 0, h256(), h256());
// Execute _init.
VM vm(*_gas);

64
libethereum/State.h

@ -164,11 +164,11 @@ public:
void execute(bytes const& _rlp) { return execute(&_rlp); }
void execute(bytesConstRef _rlp);
/// Check if the address is a valid normal (non-contract) account address.
bool isNormalAddress(Address _address) const;
/// Check if the address is in use.
bool addressInUse(Address _address) const;
/// Check if the address is a valid contract's address.
bool isContractAddress(Address _address) const;
/// Check if the address contains executable code.
bool addressHasCode(Address _address) const;
/// Get an account's balance.
/// @returns 0 if the address has never been used.
@ -184,17 +184,21 @@ public:
*/
void subBalance(Address _id, bigint _value);
/// Get the value of a memory position of a contract.
/// Get the value of a storage position of an account.
/// @returns 0 if no contract exists at that address.
u256 contractStorage(Address _contract, u256 _memory) const;
u256 storage(Address _contract, u256 _memory) const;
/// Get the memory of a contract.
/// Set the value of a storage position of an account.
void setStorage(Address _contract, u256 _location, u256 _value) { m_cache[_contract].setStorage(_location, _value); }
/// Get the storage of an account.
/// @note This is expensive. Don't use it unless you need to.
/// @returns std::map<u256, u256> if no contract exists at that address.
std::map<u256, u256> const& contractStorage(Address _contract) const;
std::map<u256, u256> storage(Address _contract) const;
/// Get the code of a contract.
/// Get the code of an account.
/// @returns bytes() if no contract exists at that address.
bytes const& contractCode(Address _contract) const;
bytes const& code(Address _contract) const;
/// Note that the given address is sending a transaction and thus increment the associated ticker.
void noteSending(Address _id);
@ -226,10 +230,10 @@ private:
/// If _requireMemory is true, grab the full memory should it be a contract item.
/// If _forceCreate is true, then insert a default item into the cache, in the case it doesn't
/// exist in the DB.
void ensureCached(Address _a, bool _requireMemory, bool _forceCreate) const;
void ensureCached(Address _a, bool _requireCode, bool _forceCreate) const;
/// Retrieve all information about a given address into a cache.
void ensureCached(std::map<Address, AddressState>& _cache, Address _a, bool _requireMemory, bool _forceCreate) const;
void ensureCached(std::map<Address, AddressState>& _cache, Address _a, bool _requireCode, bool _forceCreate) const;
/// Commit all changes waiting in the address cache to the DB.
void commit();
@ -295,20 +299,15 @@ public:
ExtVMFace(_myAddress, _caller, _origin, _value, _gasPrice, _data, _code, _s.m_previousBlock, _s.m_currentBlock, _s.m_currentNumber), m_s(_s), m_origCache(_s.m_cache)
{
m_s.ensureCached(_myAddress, true, true);
m_store = &(m_s.m_cache[_myAddress].memory());
}
u256 store(u256 _n)
{
auto i = m_store->find(_n);
return i == m_store->end() ? 0 : i->second;
return m_s.storage(myAddress, _n);
}
void setStore(u256 _n, u256 _v)
{
if (_v)
(*m_store)[_n] = _v;
else
m_store->erase(_n);
m_s.setStorage(myAddress, _n, _v);
}
h160 create(u256 _endowment, u256* _gas, bytesConstRef _code)
@ -379,12 +378,6 @@ inline std::ostream& operator<<(std::ostream& _out, State const& _s)
{
_out << (d.count(i.first) ? "[ ! " : "[ * ") << "]" << i.first << ": " << std::dec << i.second.nonce() << "@" << i.second.balance();
if (i.second.codeHash() != EmptySHA3)
{
if (i.second.isComplete())
{
_out << std::endl << i.second.memory();
}
else
{
_out << " *" << i.second.oldRoot();
TrieDB<h256, Overlay> memdb(const_cast<Overlay*>(&_s.m_db), i.second.oldRoot()); // promise we won't alter the overlay! :)
@ -396,7 +389,6 @@ inline std::ostream& operator<<(std::ostream& _out, State const& _s)
}
_out << std::endl << mem;
}
}
_out << std::endl;
}
return _out;
@ -413,20 +405,20 @@ void commit(std::map<Address, AddressState> const& _cache, DB& _db, TrieDB<Addre
RLPStream s(4);
s << i.second.balance() << i.second.nonce();
if (i.second.isComplete())
{
if (i.second.memory().empty())
s << h256();
if (i.second.storage().empty())
s << i.second.oldRoot();
else
{
TrieDB<h256, DB> storageDB(&_db);
storageDB.init();
for (auto const& j: i.second.memory())
TrieDB<h256, DB> storageDB(&_db, i.second.oldRoot());
for (auto const& j: i.second.storage())
if (j.second)
storageDB.insert(j.first, rlp(j.second));
else
storageDB.remove(j.first);
s << storageDB.root();
}
if (i.second.freshCode())
if (i.second.isFreshCode())
{
h256 ch = sha3(i.second.code());
_db.insert(ch, &i.second.code());
@ -434,9 +426,7 @@ void commit(std::map<Address, AddressState> const& _cache, DB& _db, TrieDB<Addre
}
else
s << i.second.codeHash();
}
else
s << i.second.oldRoot() << i.second.codeHash();
_state.insert(i.first, &s.out());
}
}

8
libqethereum/QEthereum.cpp

@ -127,7 +127,7 @@ u256 QmlEthereum::balanceAt(Address _a) const
bool QmlEthereum::isContractAt(Address _a) const
{
return client()->postState().isContractAddress(_a);
return client()->postState().addressHasCode(_a);
}
bool QmlEthereum::isMining() const
@ -248,7 +248,7 @@ QVariant QEthereum::balanceAt(QVariant _a) const
QVariant QEthereum::storageAt(QVariant _a, QVariant _p) const
{
return toQJS(client()->postState().contractStorage(to<Address>(_a), to<u256>(_p)));
return toQJS(client()->postState().storage(to<Address>(_a), to<u256>(_p)));
}
u256 QEthereum::balanceAt(Address _a) const
@ -258,12 +258,12 @@ u256 QEthereum::balanceAt(Address _a) const
bool QEthereum::isContractAt(QVariant _a) const
{
return client()->postState().isContractAddress(to<Address>(_a));
return client()->postState().addressHasCode(to<Address>(_a));
}
bool QEthereum::isContractAt(Address _a) const
{
return client()->postState().isContractAddress(_a);
return client()->postState().addressHasCode(_a);
}
bool QEthereum::isMining() const

16
neth/main.cpp

@ -136,8 +136,8 @@ string pretty(h160 _a, eth::State _st)
{
string ns;
h256 n;
if (h160 nameReg = (u160)_st.contractStorage(c_config, 0))
n = _st.contractStorage(nameReg, (u160)(_a));
if (h160 nameReg = (u160)_st.storage(c_config, 0))
n = _st.storage(nameReg, (u160)(_a));
if (n)
{
std::string s((char const*)n.data(), 32);
@ -731,11 +731,11 @@ int main(int argc, char** argv)
c.lock();
auto h = h160(fromHex(rechex));
stringstream s;
auto mem = c.state().contractStorage(h);
auto mem = c.state().storage(h);
for (auto const& i: mem)
s << "@" << showbase << hex << i.first << " " << showbase << hex << i.second << endl;
s << endl << disassemble(c.state().contractCode(h));
s << endl << disassemble(c.state().code(h));
string outFile = getDataDir() + "/" + rechex + ".evm";
ofstream ofs;
@ -773,7 +773,7 @@ int main(int argc, char** argv)
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())) + " " + (st.addressHasCode(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)
@ -791,7 +791,7 @@ int main(int argc, char** argv)
{
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) + "]";
ss = toString(toHex(t.safeSender().asArray())) + " " + (st.addressHasCode(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);
@ -813,7 +813,7 @@ int main(int argc, char** argv)
mvwaddnstr(addswin, y++, x, ss.c_str(), width / 2 - 4);
scrollok(addswin, true);
if (st.isContractAddress(r))
if (st.addressHasCode(r))
{
ss = toString(r) + " : " + toString(formatBalance(i.second)) + " [" + toString((unsigned)st.transactionsFrom(i.first)) + "]";
mvwaddnstr(contractswin, cc++, x, ss.c_str(), qwidth);
@ -850,7 +850,7 @@ int main(int argc, char** argv)
stringstream ssb;
u256 balance = c.state().balance(us.address());
Address gavCoin("91a10664d0cd489085a7a018beb5245d4f2272f1");
u256 totalGavCoinBalance = st.contractStorage(gavCoin, (u160)us.address());
u256 totalGavCoinBalance = st.storage(gavCoin, (u160)us.address());
ssb << "Balance: " << formatBalance(balance) << " | " << totalGavCoinBalance << " GAV";
mvwprintw(consolewin, 0, x, ssb.str().c_str());

Loading…
Cancel
Save