From e8a1e3b46dccb5aab18395de1eea6db4d44d54d3 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 4 Apr 2014 15:24:38 -0400 Subject: [PATCH] API cleanups and some renaming. --- alethzero/MainWin.cpp | 30 ++++++++++++++++++------------ eth/main.cpp | 6 +++--- libethereum/Client.cpp | 4 ++-- libethereum/Client.h | 8 ++++---- libethereum/ExtVMFace.h | 15 ++++++++------- libethereum/State.cpp | 20 +++++++++++++------- libethereum/State.h | 17 ++++++++--------- libethereum/VM.h | 24 ++++++++++++------------ test/vm.cpp | 32 +++++++++++++++++--------------- walleth/MainWin.cpp | 4 ++-- 10 files changed, 87 insertions(+), 73 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index d093387a4..c5d0b2841 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -126,7 +126,7 @@ inline h256 fromAddress(Address _a) QString Main::pretty(eth::Address _a) const { - if (h256 n = state().contractMemory(m_nameReg, fromAddress(_a))) + if (h256 n = state().contractStorage(m_nameReg, fromAddress(_a))) { std::string s((char const*)n.data(), 32); if (s.find_first_of('\0') != string::npos) @@ -153,8 +153,8 @@ Address Main::fromString(QString const& _a) const memcpy(n.data(), sn.data(), sn.size()); memset(n.data() + sn.size(), 0, 32 - sn.size()); if (_a.size()) - if (h256 a = state().contractMemory(m_nameReg, n)) - return left160(a); + if (h256 a = state().contractStorage(m_nameReg, n)) + return right160(a); if (_a.size() == 40) return Address(fromHex(_a.toStdString())); else @@ -296,7 +296,7 @@ void Main::refresh(bool _override) QString("%2 +> %3: %1 [%4]") .arg(formatBalance(t.value).c_str()) .arg(render(t.safeSender())) - .arg(render(left160(sha3(rlpList(t.safeSender(), t.nonce))))) + .arg(render(right160(sha3(rlpList(t.safeSender(), t.nonce))))) .arg((unsigned)t.nonce); ui->transactionQueue->addItem(s); } @@ -322,7 +322,7 @@ void Main::refresh(bool _override) QString(" %2 +> %3: %1 [%4]") .arg(formatBalance(t.value).c_str()) .arg(render(t.safeSender())) - .arg(render(left160(sha3(rlpList(t.safeSender(), t.nonce))))) + .arg(render(right160(sha3(rlpList(t.safeSender(), t.nonce))))) .arg((unsigned)t.nonce); QListWidgetItem* txItem = new QListWidgetItem(s, ui->blocks); txItem->setData(Qt::UserRole, QByteArray((char const*)h.data(), h.size)); @@ -405,7 +405,7 @@ void Main::on_blocks_currentItemChanged() s << "

" << h << "[" << txi << "]

"; s << "
From: " << pretty(ss).toStdString() << " " << ss; if (tx.isCreation()) - s << "
Creates: " << pretty(left160(th)).toStdString() << " " << left160(th); + s << "
Creates: " << pretty(right160(th)).toStdString() << " " << right160(th); else s << "
To: " << pretty(tx.receiveAddress).toStdString() << " " << tx.receiveAddress; s << "
Value: " << formatBalance(tx.value) << ""; @@ -445,7 +445,7 @@ void Main::on_contracts_currentItemChanged() auto h = h160((byte const*)hba.data(), h160::ConstructFromPointer); stringstream s; - auto mem = state().contractMemory(h); + auto mem = state().contractStorage(h); for (auto const& i: mem) s << "@" << showbase << hex << i.first << "    " << showbase << hex << i.second << "
"; s << "
Code:"; @@ -520,7 +520,7 @@ void Main::on_data_textChanged() while (s.size()) { QRegExp r("@?\"(.*)\"(.*)"); - QRegExp h("([a-fA-F0-9][a-fA-F0-9])(.*)"); + QRegExp h("@?(0x)?(([a-fA-F0-9][a-fA-F0-9])+)(.*)"); if (r.exactMatch(s)) { for (auto i: r.cap(1)) @@ -534,8 +534,14 @@ void Main::on_data_textChanged() } else if (h.exactMatch(s)) { - m_data.push_back(fromHex(h.cap(1).toStdString())[0]); - s = h.cap(2); + if (s[0] == '@') + { + bytes bs = fromHex(h.cap(2).toStdString()); + + for (auto b: bs) + m_data.push_back(b); + } + s = h.cap(4); } else s = s.mid(1); @@ -669,9 +675,9 @@ void Main::on_send_clicked() m_client->unlock(); Secret s = i.secret(); if (isCreation()) - m_client->transact(s, value(), gasPrice(), ui->gas->value(), m_data, m_init); + m_client->transact(s, value(), m_data, m_init, ui->gas->value(), gasPrice()); else - m_client->transact(s, value(), gasPrice(), ui->gas->value(), fromString(ui->destination->text()), m_data); + m_client->transact(s, value(), fromString(ui->destination->text()), m_data, ui->gas->value(), gasPrice()); refresh(); return; } diff --git a/eth/main.cpp b/eth/main.cpp index 5701962f1..71217bb69 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -522,7 +522,7 @@ int main(int argc, char** argv) Address dest = h160(fromHex(rechex)); bytes data; - c.transact(secret, amount, gasPrice, gas, dest, data); + c.transact(secret, amount, dest, data, gas, gasPrice); } else if (cmd == "send") { @@ -533,7 +533,7 @@ int main(int argc, char** argv) iss >> rechex >> amount >> gasPrice >> gas; Address dest = h160(fromHex(rechex)); - c.transact(us.secret(), amount, gasPrice, gas, dest, bytes()); + c.transact(us.secret(), amount, dest, bytes(), gas, gasPrice); } else if (cmd == "inspect") { @@ -548,7 +548,7 @@ int main(int argc, char** argv) auto h = h160(fromHex(rechex)); stringstream s; - auto mem = c.state().contractMemory(h); + auto mem = c.state().contractStorage(h); u256 next = 0; unsigned numerics = 0; bool unexpectedNumeric = false; diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 9c50e7e83..630a845ad 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -140,7 +140,7 @@ void Client::stopMining() m_doMine = false; } -void Client::transact(Secret _secret, u256 _value, u256 _gasPrice, u256 _gas, Address _dest, bytes const& _data) +void Client::transact(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) { lock_guard l(m_lock); Transaction t; @@ -156,7 +156,7 @@ void Client::transact(Secret _secret, u256 _value, u256 _gasPrice, u256 _gas, Ad m_changed = true; } -void Client::transact(Secret _secret, u256 _endowment, u256 _gasPrice, u256 _gas, bytes const& _code, bytes const& _init) +void Client::transact(Secret _secret, u256 _endowment, bytes const& _code, bytes const& _init, u256 _gas, u256 _gasPrice) { lock_guard l(m_lock); Transaction t; diff --git a/libethereum/Client.h b/libethereum/Client.h index 39fb7f5d7..d2a670df5 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -83,11 +83,11 @@ public: /// Destructor. ~Client(); - /// Submits the given transaction. - void transact(Secret _secret, u256 _value, u256 _gasPrice, u256 _gas, Address _dest, bytes const& _data); + /// Submits the given message-call transaction. + void transact(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo); - /// Submits a new contract. - void transact(Secret _secret, u256 _endowment, u256 _gasPrice, u256 _gas, bytes const& _code, bytes const& _init); + /// Submits a new contract-creation transaction. + void transact(Secret _secret, u256 _endowment, bytes const& _code, bytes const& _init = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo); /// Makes the given call. Nothing is recorded into the state. TODO // bytes call(Secret _secret, u256 _amount, u256 _gasPrice, Address _dest, u256 _gas, bytes _data = bytes()); diff --git a/libethereum/ExtVMFace.h b/libethereum/ExtVMFace.h index 3d05ef514..11d03722b 100644 --- a/libethereum/ExtVMFace.h +++ b/libethereum/ExtVMFace.h @@ -41,12 +41,13 @@ public: currentNumber(_currentNumber) {} - ExtVMFace(Address _myAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, bytesConstRef _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, uint _currentNumber): + ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, uint _currentNumber): myAddress(_myAddress), - txSender(_txSender), - txValue(_txValue), + caller(_caller), + origin(_origin), + value(_value), gasPrice(_gasPrice), - txData(_txData), + data(_data), code(_code), previousBlock(_previousBlock), currentBlock(_currentBlock), @@ -72,11 +73,11 @@ public: #pragma warning(pop) Address myAddress; - Address txSender; + Address caller; Address origin; - u256 txValue; + u256 value; u256 gasPrice; - bytesConstRef txData; + bytesConstRef data; bytesConstRef code; BlockInfo previousBlock; ///< The current block's information. BlockInfo currentBlock; ///< The current block's information. diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 298c5387b..23ad0cbd1 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -566,7 +566,7 @@ u256 State::transactionsFrom(Address _id) const return it->second.nonce(); } -u256 State::contractMemory(Address _id, u256 _memory) const +u256 State::contractStorage(Address _id, u256 _memory) const { ensureCached(_id, false, false); auto it = m_cache.find(_id); @@ -585,7 +585,7 @@ u256 State::contractMemory(Address _id, u256 _memory) const return ret.size() ? RLP(ret).toInt() : 0; } -map const& State::contractMemory(Address _contract) const +map const& State::contractStorage(Address _contract) const { if (!isContractAddress(_contract)) return EmptyMapU256U256; @@ -676,15 +676,18 @@ void State::execute(bytesConstRef _rlp) m_transactionSet.insert(t.sha3()); } -bool State::call(Address _receiveAddress, Address _sendAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256* _gas, bytesRef _out) +bool State::call(Address _receiveAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256* _gas, bytesRef _out, Address _originAddress) { + if (!_originAddress) + _originAddress = _senderAddress; + cnote << "Transferring" << formatBalance(_value) << "to receiver."; addBalance(_receiveAddress, _value); if (isContractAddress(_receiveAddress)) { VM vm(*_gas); - ExtVM evm(*this, _receiveAddress, _sendAddress, _value, _gasPrice, _data, &contractCode(_receiveAddress)); + ExtVM evm(*this, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &contractCode(_receiveAddress)); bool revert = false; try @@ -721,9 +724,12 @@ bool State::call(Address _receiveAddress, Address _sendAddress, u256 _value, u25 return true; } -h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, bytesConstRef _init) +h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, bytesConstRef _init, Address _origin) { - Address newAddress = left160(sha3(rlpList(_sender, transactionsFrom(_sender) - 1))); + if (!_origin) + _origin = _sender; + + Address newAddress = right160(sha3(rlpList(_sender, transactionsFrom(_sender) - 1))); while (isContractAddress(newAddress) || isNormalAddress(newAddress)) newAddress = (u160)newAddress + 1; @@ -732,7 +738,7 @@ h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas, // Execute _init. VM vm(*_gas); - ExtVM evm(*this, newAddress, _sender, _endowment, _gasPrice, bytesConstRef(), _init); + ExtVM evm(*this, newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init); bool revert = false; try diff --git a/libethereum/State.h b/libethereum/State.h index 60a2329ef..6a5485df2 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -147,11 +147,11 @@ public: /// Get the value of a memory position of a contract. /// @returns 0 if no contract exists at that address. - u256 contractMemory(Address _contract, u256 _memory) const; + u256 contractStorage(Address _contract, u256 _memory) const; /// Get the memory of a contract. /// @returns std::map if no contract exists at that address. - std::map const& contractMemory(Address _contract) const; + std::map const& contractStorage(Address _contract) const; /// Get the code of a contract. /// @returns bytes() if no contract exists at that address. @@ -207,13 +207,12 @@ private: // We assume all instrinsic fees are paid up before this point. /// Execute a contract-creation transaction. - h160 create(Address _txSender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, bytesConstRef _init); - h160 create(Transaction const& _t, Address _sender, u256* _gas); + h160 create(Address _txSender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, bytesConstRef _init, Address _originAddress = Address()); /// Execute a call. /// @a _gas points to the amount of gas to use for the call, and will lower it accordingly. /// @returns false if the call ran out of gas before completion. true otherwise. - bool call(Address _myAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256* _gas, bytesRef _out); + bool call(Address _myAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256* _gas, bytesRef _out, Address _originAddress = Address()); /// Sets m_currentBlock to a clean state, (i.e. no change from m_previousBlock). void resetCurrent(); @@ -253,8 +252,8 @@ private: class ExtVM: public ExtVMFace { public: - ExtVM(State& _s, Address _myAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, bytesConstRef _code): - ExtVMFace(_myAddress, _txSender, _txValue, _gasPrice, _txData, _code, _s.m_previousBlock, _s.m_currentBlock, _s.m_currentNumber), m_s(_s), m_origCache(_s.m_cache) + ExtVM(State& _s, Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code): + 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()); @@ -278,12 +277,12 @@ public: // Increment associated nonce for sender. m_s.noteSending(myAddress); - return m_s.create(myAddress, _endowment, gasPrice, _gas, _code, _init); + return m_s.create(myAddress, _endowment, gasPrice, _gas, _code, _init, origin); } bool call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256* _gas, bytesRef _out) { - return m_s.call(_receiveAddress, myAddress, _txValue, gasPrice, _txData, _gas, _out); + return m_s.call(_receiveAddress, myAddress, _txValue, gasPrice, _txData, _gas, _out, origin); } u256 balance(Address _a) { return m_s.balance(_a); } diff --git a/libethereum/VM.h b/libethereum/VM.h index a011abba6..6a8984bfe 100644 --- a/libethereum/VM.h +++ b/libethereum/VM.h @@ -36,14 +36,15 @@ namespace eth // Currently we just pull out the right (low-order in BE) 160-bits. inline Address asAddress(u256 _item) { - return left160(h256(_item)); + return right160(h256(_item)); } inline u256 fromAddress(Address _a) { - h256 ret; - memcpy(&ret, &_a, sizeof(_a)); - return ret; + return (u160)_a; +// h256 ret; +// memcpy(&ret, &_a, sizeof(_a)); +// return ret; } /** @@ -300,8 +301,7 @@ template eth::bytesConstRef eth::VM::go(Ext& _ext, uint64_t _steps) m_stack.push_back(fromAddress(_ext.myAddress)); break; case Instruction::ORIGIN: - // TODO get originator from ext. - m_stack.push_back(fromAddress(_ext.txSender)); + m_stack.push_back(fromAddress(_ext.origin)); break; case Instruction::BALANCE: { @@ -310,27 +310,27 @@ template eth::bytesConstRef eth::VM::go(Ext& _ext, uint64_t _steps) break; } case Instruction::CALLER: - m_stack.push_back(fromAddress(_ext.txSender)); + m_stack.push_back(fromAddress(_ext.caller)); break; case Instruction::CALLVALUE: - m_stack.push_back(_ext.txValue); + m_stack.push_back(_ext.value); break; case Instruction::CALLDATALOAD: { require(1); - if ((unsigned)m_stack.back() + 32 < _ext.txData.size()) - m_stack.back() = (u256)*(h256 const*)(_ext.txData.data() + (unsigned)m_stack.back()); + if ((unsigned)m_stack.back() + 32 < _ext.data.size()) + m_stack.back() = (u256)*(h256 const*)(_ext.data.data() + (unsigned)m_stack.back()); else { h256 r; for (unsigned i = (unsigned)m_stack.back(), e = (unsigned)m_stack.back() + 32, j = 0; i < e; ++i, ++j) - r[j] = i < _ext.txData.size() ? _ext.txData[i] : 0; + r[j] = i < _ext.data.size() ? _ext.data[i] : 0; m_stack.back() = (u256)r; } break; } case Instruction::CALLDATASIZE: - m_stack.push_back(_ext.txData.size()); + m_stack.push_back(_ext.data.size()); break; case Instruction::GASPRICE: m_stack.push_back(_ext.gasPrice); diff --git a/test/vm.cpp b/test/vm.cpp index 959b0c692..a0b268639 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -40,7 +40,7 @@ public: FakeExtVM() {} FakeExtVM(BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, uint _currentNumber): - ExtVMFace(Address(), Address(), 0, 1, bytesConstRef(), bytesConstRef(), _previousBlock, _currentBlock, _currentNumber) + ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytesConstRef(), _previousBlock, _currentBlock, _currentNumber) {} u256 store(u256 _n) @@ -81,24 +81,24 @@ public: return right160(t.sha3(false)); } - bool call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256* _gas, bytesRef _txOut) + bool call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256* _gas, bytesRef _out) { Transaction t; - t.value = _txValue; + t.value = _value; t.gasPrice = gasPrice; t.gas = *_gas; - t.data = _txData.toVector(); + t.data = _data.toVector(); t.receiveAddress = _receiveAddress; txs.push_back(t); - (void)_txOut; + (void)_out; return true; } - void setTransaction(Address _txSender, u256 _txValue, u256 _gasPrice, bytes const& _txData) + void setTransaction(Address _caller, u256 _value, u256 _gasPrice, bytes const& _data) { - txSender = _txSender; - txValue = _txValue; - txData = &_txData; + caller = origin = _caller; + value = _value; + data = &_data; gasPrice = _gasPrice; } void setContract(Address _myAddress, u256 _myBalance, u256 _myNonce, bytes const& _code, map const& _storage) @@ -251,11 +251,12 @@ public: { mObject ret; ret["address"] = toString(myAddress); - ret["sender"] = toString(txSender); - push(ret, "value", txValue); + ret["caller"] = toString(caller); + ret["origin"] = toString(origin); + push(ret, "value", value); push(ret, "gasPrice", gasPrice); mArray d; - for (auto const& i: txData) + for (auto const& i: data) push(d, i); ret["data"] = d; return ret; @@ -264,13 +265,14 @@ public: void importExec(mObject& _o) { myAddress = Address(_o["address"].get_str()); - txSender = Address(_o["sender"].get_str()); - txValue = toInt(_o["value"]); + caller = Address(_o["caller"].get_str()); + origin = Address(_o["origin"].get_str()); + value = toInt(_o["value"]); gasPrice = toInt(_o["gasPrice"]); thisTxData.clear(); for (auto const& j: _o["data"].get_array()) thisTxData.push_back(toByte(j)); - txData = &thisTxData; + data = &thisTxData; } mArray exportTxs() diff --git a/walleth/MainWin.cpp b/walleth/MainWin.cpp index c456b6d77..44315cac4 100644 --- a/walleth/MainWin.cpp +++ b/walleth/MainWin.cpp @@ -176,12 +176,12 @@ unsigned QEthereum::peerCount() const void QEthereum::transact(Secret _secret, u256 _amount, u256 _gasPrice, u256 _gas, QByteArray _code, QByteArray _init) { - client()->transact(_secret, _amount, _gasPrice, _gas, bytes(_code.data(), _code.data() + _code.size()), bytes(_init.data(), _init.data() + _init.size())); + client()->transact(_secret, _amount, bytes(_code.data(), _code.data() + _code.size()), bytes(_init.data(), _init.data() + _init.size()), _gas, _gasPrice); } void QEthereum::transact(Secret _secret, Address _dest, u256 _amount, u256 _gasPrice, u256 _gas, QByteArray _data) { - client()->transact(_secret, _amount, _gasPrice, _gas, _dest, bytes(_data.data(), _data.data() + _data.size())); + client()->transact(_secret, _amount, _dest, bytes(_data.data(), _data.data() + _data.size()), _gas, _gasPrice); } Main::Main(QWidget *parent) :