Browse Source

PoC-7: Reversion of 0-hashes, empty-list hashes and sha3('') -> ''

cl-refactor
Gav Wood 10 years ago
parent
commit
15013a3e88
  1. 1
      alethzero/MainWin.cpp
  2. 4
      libdevcrypto/SHA3.cpp
  3. 1
      libdevcrypto/SHA3.h
  4. 6
      libdevcrypto/TrieDB.h
  5. 10
      libethcore/BlockInfo.cpp
  6. 2
      libethcore/CommonEth.cpp
  7. 4
      libethereum/BlockChain.cpp
  8. 3
      libethereum/Client.cpp
  9. 4
      libethereum/State.cpp
  10. 6
      libethereum/State.h
  11. 3
      libethereum/Transaction.cpp
  12. 9
      libethereum/Transaction.h
  13. 23
      libevm/VM.h
  14. 6
      libevmface/Instruction.cpp
  15. 3
      libevmface/Instruction.h
  16. 4
      test/MemTrie.cpp
  17. 6
      test/TrieHash.cpp
  18. 3
      test/crypto.cpp
  19. 1
      test/state.cpp
  20. 7
      test/vm.cpp

1
alethzero/MainWin.cpp

@ -1784,6 +1784,7 @@ void Main::on_debug_clicked()
t.gasPrice = gasPrice(); t.gasPrice = gasPrice();
t.gas = ui->gas->value(); t.gas = ui->gas->value();
t.data = m_data; t.data = m_data;
t.type = isCreation() ? Transaction::ContractCreation : Transaction::MessageCall;
t.receiveAddress = isCreation() ? Address() : fromString(ui->destination->currentText()); t.receiveAddress = isCreation() ? Address() : fromString(ui->destination->currentText());
t.sign(s); t.sign(s);
auto r = t.rlp(); auto r = t.rlp();

4
libdevcrypto/SHA3.cpp

@ -20,8 +20,9 @@
*/ */
#include "SHA3.h" #include "SHA3.h"
#include "CryptoPP.h"
#include <libdevcore/RLP.h>
#include "CryptoPP.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
@ -29,6 +30,7 @@ namespace dev
{ {
h256 EmptySHA3 = sha3(bytesConstRef()); h256 EmptySHA3 = sha3(bytesConstRef());
h256 ZeroRLPSHA3 = sha3(rlp(bytesConstRef()));
std::string sha3(std::string const& _input, bool _hex) std::string sha3(std::string const& _input, bool _hex)
{ {

1
libdevcrypto/SHA3.h

@ -57,6 +57,7 @@ inline h256 sha3(bytes const& _input) { return sha3(bytesConstRef((bytes*)&_inpu
inline h256 sha3(std::string const& _input) { return sha3(bytesConstRef(_input)); } inline h256 sha3(std::string const& _input) { return sha3(bytesConstRef(_input)); }
extern h256 EmptySHA3; extern h256 EmptySHA3;
extern h256 ZeroRLPSHA3;
// Other crypto convenience routines // Other crypto convenience routines

6
libdevcrypto/TrieDB.h

@ -74,7 +74,7 @@ public:
void init(); void init();
void setRoot(h256 _root) void setRoot(h256 _root)
{ {
m_root = _root == h256() ? c_shaNull : _root; m_root = _root;
if (m_root == c_shaNull && !m_db->exists(m_root)) if (m_root == c_shaNull && !m_db->exists(m_root))
init(); init();
@ -82,14 +82,14 @@ public:
if (!node(m_root).size()) if (!node(m_root).size())
BOOST_THROW_EXCEPTION(RootNotFound()); BOOST_THROW_EXCEPTION(RootNotFound());
} }
bool haveRoot(h256 _root, bool _enforceRefs = true) { return _root == h256() ? true : m_db->lookup(_root, _enforceRefs).size(); } bool haveRoot(h256 _root, bool _enforceRefs = true) { return _root == c_shaNull ? true : m_db->lookup(_root, _enforceRefs).size(); }
/// True if the trie is uninitialised (i.e. that the DB doesn't contain the root node). /// True if the trie is uninitialised (i.e. that the DB doesn't contain the root node).
bool isNull() const { return !node(m_root).size(); } bool isNull() const { return !node(m_root).size(); }
/// True if the trie is initialised but empty (i.e. that the DB contains the root node which is empty). /// True if the trie is initialised but empty (i.e. that the DB contains the root node which is empty).
bool isEmpty() const { return m_root == c_shaNull && node(m_root).size(); } bool isEmpty() const { return m_root == c_shaNull && node(m_root).size(); }
h256 root() const { assert(node(m_root).size()); h256 ret = (m_root == c_shaNull ? h256() : m_root); /*std::cout << "Returning root as " << ret << " (really " << m_root << ")" << std::endl;*/ return ret; } // patch the root in the case of the empty trie. TODO: handle this properly. h256 root() const { assert(node(m_root).size()); /*std::cout << "Returning root as " << ret << " (really " << m_root << ")" << std::endl;*/ return m_root; } // patch the root in the case of the empty trie. TODO: handle this properly.
void debugPrint() {} void debugPrint() {}

10
libethcore/BlockInfo.cpp

@ -60,11 +60,9 @@ auto static const c_sha3EmptyList = sha3(RLPEmptyList);
void BlockInfo::fillStream(RLPStream& _s, bool _nonce) const void BlockInfo::fillStream(RLPStream& _s, bool _nonce) const
{ {
_s.appendList(_nonce ? 13 : 12) << parentHash; _s.appendList(_nonce ? 13 : 12)
_s.append(sha3Uncles == c_sha3EmptyList ? h256() : sha3Uncles, false, true); << parentHash << sha3Uncles << coinbaseAddress << stateRoot << transactionsRoot
_s << coinbaseAddress; << difficulty << number << minGasPrice << gasLimit << gasUsed << timestamp << extraData;
_s.append(stateRoot, false, true).append(transactionsRoot, false, true);
_s << difficulty << number << minGasPrice << gasLimit << gasUsed << timestamp << extraData;
if (_nonce) if (_nonce)
_s << nonce; _s << nonce;
} }
@ -83,8 +81,6 @@ void BlockInfo::populateFromHeader(RLP const& _header, bool _checkNonce)
{ {
parentHash = _header[field = 0].toHash<h256>(); parentHash = _header[field = 0].toHash<h256>();
sha3Uncles = _header[field = 1].toHash<h256>(); sha3Uncles = _header[field = 1].toHash<h256>();
if (sha3Uncles == h256())
sha3Uncles = c_sha3EmptyList;
coinbaseAddress = _header[field = 2].toHash<Address>(); coinbaseAddress = _header[field = 2].toHash<Address>();
stateRoot = _header[field = 3].toHash<h256>(); stateRoot = _header[field = 3].toHash<h256>();
transactionsRoot = _header[field = 4].toHash<h256>(); transactionsRoot = _header[field = 4].toHash<h256>();

2
libethcore/CommonEth.cpp

@ -34,7 +34,7 @@ namespace dev
namespace eth namespace eth
{ {
const unsigned c_protocolVersion = 36; const unsigned c_protocolVersion = 37;
const unsigned c_databaseVersion = 3; const unsigned c_databaseVersion = 3;
static const vector<pair<u256, string>> g_units = static const vector<pair<u256, string>> g_units =

4
libethereum/BlockChain.cpp

@ -101,8 +101,8 @@ bytes BlockChain::createGenesisBlock()
stateRoot = state.root(); stateRoot = state.root();
} }
block.appendList(13) << h256() << bytes() << h160(); block.appendList(13)
block.append(stateRoot, false, true) << bytes() << c_genesisDifficulty << 0 << 0 << 1000000 << 0 << (unsigned)0 << string() << sha3(bytes(1, 42)); << h256() << c_shaNull << h160() << stateRoot << c_shaNull << c_genesisDifficulty << 0 << 0 << 1000000 << 0 << (unsigned)0 << string() << sha3(bytes(1, 42));
block.appendRaw(RLPEmptyList); block.appendRaw(RLPEmptyList);
block.appendRaw(RLPEmptyList); block.appendRaw(RLPEmptyList);
return block.out(); return block.out();

3
libethereum/Client.cpp

@ -325,6 +325,7 @@ void Client::transact(Secret _secret, u256 _value, Address _dest, bytes const& _
t.value = _value; t.value = _value;
t.gasPrice = _gasPrice; t.gasPrice = _gasPrice;
t.gas = _gas; t.gas = _gas;
t.type = Transaction::MessageCall;
t.receiveAddress = _dest; t.receiveAddress = _dest;
t.data = _data; t.data = _data;
t.sign(_secret); t.sign(_secret);
@ -348,6 +349,7 @@ bytes Client::call(Secret _secret, u256 _value, Address _dest, bytes const& _dat
t.value = _value; t.value = _value;
t.gasPrice = _gasPrice; t.gasPrice = _gasPrice;
t.gas = _gas; t.gas = _gas;
t.type = Transaction::ContractCreation;
t.receiveAddress = _dest; t.receiveAddress = _dest;
t.data = _data; t.data = _data;
t.sign(_secret); t.sign(_secret);
@ -373,6 +375,7 @@ Address Client::transact(Secret _secret, u256 _endowment, bytes const& _init, u2
t.value = _endowment; t.value = _endowment;
t.gasPrice = _gasPrice; t.gasPrice = _gasPrice;
t.gas = _gas; t.gas = _gas;
t.type = Transaction::ContractCreation;
t.receiveAddress = Address(); t.receiveAddress = Address();
t.data = _init; t.data = _init;
t.sign(_secret); t.sign(_secret);

4
libethereum/State.cpp

@ -353,9 +353,9 @@ void State::ensureCached(std::map<Address, AddressState>& _cache, Address _a, bo
RLP state(stateBack); RLP state(stateBack);
AddressState s; AddressState s;
if (state.isNull()) if (state.isNull())
s = AddressState(0, 0, h256(), EmptySHA3); s = AddressState(0, 0, ZeroRLPSHA3, EmptySHA3);
else else
s = AddressState(state[0].toInt<u256>(), state[1].toInt<u256>(), state[2].toHash<h256>(), state[3].isEmpty() ? EmptySHA3 : state[3].toHash<h256>()); s = AddressState(state[0].toInt<u256>(), state[1].toInt<u256>(), state[2].toHash<h256>(), state[3].toHash<h256>());
bool ok; bool ok;
tie(it, ok) = _cache.insert(make_pair(_a, s)); tie(it, ok) = _cache.insert(make_pair(_a, s));
} }

6
libethereum/State.h

@ -367,14 +367,8 @@ void commit(std::map<Address, AddressState> const& _cache, DB& _db, TrieDB<Addre
{ {
h256 ch = sha3(i.second.code()); h256 ch = sha3(i.second.code());
_db.insert(ch, &i.second.code()); _db.insert(ch, &i.second.code());
if (i.second.code().size())
s << ch; s << ch;
else
s << "";
} }
else
if (i.second.codeHash() == EmptySHA3)
s << "";
else else
s << i.second.codeHash(); s << i.second.codeHash();

3
libethereum/Transaction.cpp

@ -39,6 +39,7 @@ Transaction::Transaction(bytesConstRef _rlpData, bool _checkSender)
nonce = rlp[field = 0].toInt<u256>(); nonce = rlp[field = 0].toInt<u256>();
gasPrice = rlp[field = 1].toInt<u256>(); gasPrice = rlp[field = 1].toInt<u256>();
gas = rlp[field = 2].toInt<u256>(); gas = rlp[field = 2].toInt<u256>();
type = rlp[field = 3].isEmpty() ? ContractCreation : MessageCall;
receiveAddress = rlp[field = 3].toHash<Address>(); receiveAddress = rlp[field = 3].toHash<Address>();
value = rlp[field = 4].toInt<u256>(); value = rlp[field = 4].toInt<u256>();
data = rlp[field = 5].toBytes(); data = rlp[field = 5].toBytes();
@ -88,7 +89,7 @@ void Transaction::fillStream(RLPStream& _s, bool _sig) const
{ {
_s.appendList((_sig ? 3 : 0) + 6); _s.appendList((_sig ? 3 : 0) + 6);
_s << nonce << gasPrice << gas; _s << nonce << gasPrice << gas;
if (receiveAddress) if (type == MessageCall)
_s << receiveAddress; _s << receiveAddress;
else else
_s << ""; _s << "";

9
libethereum/Transaction.h

@ -32,13 +32,20 @@ namespace eth
struct Transaction struct Transaction
{ {
enum Type
{
ContractCreation,
MessageCall
};
Transaction() {} Transaction() {}
Transaction(bytesConstRef _rlp, bool _checkSender = false); Transaction(bytesConstRef _rlp, bool _checkSender = false);
Transaction(bytes const& _rlp, bool _checkSender = false): Transaction(&_rlp, _checkSender) {} Transaction(bytes const& _rlp, bool _checkSender = false): Transaction(&_rlp, _checkSender) {}
bool operator==(Transaction const& _c) const { return receiveAddress == _c.receiveAddress && value == _c.value && data == _c.data; } bool operator==(Transaction const& _c) const { return type == _c.type && (type == ContractCreation || receiveAddress == _c.receiveAddress) && value == _c.value && data == _c.data; }
bool operator!=(Transaction const& _c) const { return !operator==(_c); } bool operator!=(Transaction const& _c) const { return !operator==(_c); }
Type type; ///< True if this is a contract-creation transaction. F
u256 nonce; ///< The transaction-count of the sender. u256 nonce; ///< The transaction-count of the sender.
u256 value; ///< The amount of ETH to be transferred by this transaction. Called 'endowment' for contract-creation transactions. u256 value; ///< The amount of ETH to be transferred by this transaction. Called 'endowment' for contract-creation transactions.
Address receiveAddress; ///< The receiving address of the transaction. Address receiveAddress; ///< The receiving address of the transaction.

23
libevm/VM.h

@ -236,7 +236,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
case Instruction::PUSH31: case Instruction::PUSH31:
case Instruction::PUSH32: case Instruction::PUSH32:
break; break;
case Instruction::NEG: case Instruction::BNOT:
case Instruction::NOT: case Instruction::NOT:
case Instruction::CALLDATALOAD: case Instruction::CALLDATALOAD:
case Instruction::EXTCODESIZE: case Instruction::EXTCODESIZE:
@ -262,6 +262,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
case Instruction::XOR: case Instruction::XOR:
case Instruction::BYTE: case Instruction::BYTE:
case Instruction::JUMPI: case Instruction::JUMPI:
case Instruction::SIGNEXTEND:
require(2); require(2);
break; break;
case Instruction::ADDMOD: case Instruction::ADDMOD:
@ -368,8 +369,8 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
m_stack.back() = (u256)boost::multiprecision::powm((bigint)base, (bigint)expon, bigint(2) << 256); m_stack.back() = (u256)boost::multiprecision::powm((bigint)base, (bigint)expon, bigint(2) << 256);
break; break;
} }
case Instruction::NEG: case Instruction::BNOT:
m_stack.back() = ~(m_stack.back() - 1); m_stack.back() = ~m_stack.back();
break; break;
case Instruction::LT: case Instruction::LT:
m_stack[m_stack.size() - 2] = m_stack.back() < m_stack[m_stack.size() - 2] ? 1 : 0; m_stack[m_stack.size() - 2] = m_stack.back() < m_stack[m_stack.size() - 2] ? 1 : 0;
@ -420,6 +421,22 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
m_stack.pop_back(); m_stack.pop_back();
m_stack.pop_back(); m_stack.pop_back();
break; break;
case Instruction::SIGNEXTEND:
{
unsigned k = m_stack[m_stack.size() - 2];
if (k > 31)
m_stack[m_stack.size() - 2] = m_stack.back();
else
{
u256 b = m_stack.back();
if ((b >> (k * 8)) & 0x80)
for (int i = 31; i > k; --i)
b |= (u256(0xff) << i);
m_stack[m_stack.size() - 2] = b;
}
m_stack.pop_back();
break;
}
case Instruction::SHA3: case Instruction::SHA3:
{ {
unsigned inOff = (unsigned)m_stack.back(); unsigned inOff = (unsigned)m_stack.back();

6
libevmface/Instruction.cpp

@ -39,7 +39,7 @@ const std::map<std::string, Instruction> dev::eth::c_instructions =
{ "MOD", Instruction::MOD }, { "MOD", Instruction::MOD },
{ "SMOD", Instruction::SMOD }, { "SMOD", Instruction::SMOD },
{ "EXP", Instruction::EXP }, { "EXP", Instruction::EXP },
{ "NEG", Instruction::NEG }, { "BNOT", Instruction::BNOT },
{ "LT", Instruction::LT }, { "LT", Instruction::LT },
{ "GT", Instruction::GT }, { "GT", Instruction::GT },
{ "SLT", Instruction::SLT }, { "SLT", Instruction::SLT },
@ -52,6 +52,7 @@ const std::map<std::string, Instruction> dev::eth::c_instructions =
{ "BYTE", Instruction::BYTE }, { "BYTE", Instruction::BYTE },
{ "ADDMOD", Instruction::ADDMOD }, { "ADDMOD", Instruction::ADDMOD },
{ "MULMOD", Instruction::MULMOD }, { "MULMOD", Instruction::MULMOD },
{ "SIGNEXTEND", Instruction::SIGNEXTEND },
{ "SHA3", Instruction::SHA3 }, { "SHA3", Instruction::SHA3 },
{ "ADDRESS", Instruction::ADDRESS }, { "ADDRESS", Instruction::ADDRESS },
{ "BALANCE", Instruction::BALANCE }, { "BALANCE", Instruction::BALANCE },
@ -166,7 +167,7 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::MOD, { "MOD", 0, 2, 1 } }, { Instruction::MOD, { "MOD", 0, 2, 1 } },
{ Instruction::SMOD, { "SMOD", 0, 2, 1 } }, { Instruction::SMOD, { "SMOD", 0, 2, 1 } },
{ Instruction::EXP, { "EXP", 0, 2, 1 } }, { Instruction::EXP, { "EXP", 0, 2, 1 } },
{ Instruction::NEG, { "NEG", 0, 1, 1 } }, { Instruction::BNOT, { "BNOT", 0, 1, 1 } },
{ Instruction::LT, { "LT", 0, 2, 1 } }, { Instruction::LT, { "LT", 0, 2, 1 } },
{ Instruction::GT, { "GT", 0, 2, 1 } }, { Instruction::GT, { "GT", 0, 2, 1 } },
{ Instruction::SLT, { "SLT", 0, 2, 1 } }, { Instruction::SLT, { "SLT", 0, 2, 1 } },
@ -179,6 +180,7 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::BYTE, { "BYTE", 0, 2, 1 } }, { Instruction::BYTE, { "BYTE", 0, 2, 1 } },
{ Instruction::ADDMOD, { "ADDMOD", 0, 3, 1 } }, { Instruction::ADDMOD, { "ADDMOD", 0, 3, 1 } },
{ Instruction::MULMOD, { "MULMOD", 0, 3, 1 } }, { Instruction::MULMOD, { "MULMOD", 0, 3, 1 } },
{ Instruction::SIGNEXTEND, { "SIGNEXTEND", 0, 2, 1 } },
{ Instruction::SHA3, { "SHA3", 0, 2, 1 } }, { Instruction::SHA3, { "SHA3", 0, 2, 1 } },
{ Instruction::ADDRESS, { "ADDRESS", 0, 0, 1 } }, { Instruction::ADDRESS, { "ADDRESS", 0, 0, 1 } },
{ Instruction::BALANCE, { "BALANCE", 0, 1, 1 } }, { Instruction::BALANCE, { "BALANCE", 0, 1, 1 } },

3
libevmface/Instruction.h

@ -44,7 +44,7 @@ enum class Instruction: uint8_t
MOD, ///< modulo remainder operation MOD, ///< modulo remainder operation
SMOD, ///< signed modulo remainder operation SMOD, ///< signed modulo remainder operation
EXP, ///< exponential operation EXP, ///< exponential operation
NEG, ///< negation operation BNOT, ///< bitwise not
LT, ///< less-than comparision LT, ///< less-than comparision
GT, ///< greater-than comparision GT, ///< greater-than comparision
SLT, ///< signed less-than comparision SLT, ///< signed less-than comparision
@ -58,6 +58,7 @@ enum class Instruction: uint8_t
BYTE, ///< retrieve single byte from word BYTE, ///< retrieve single byte from word
ADDMOD, ///< unsigned modular addition ADDMOD, ///< unsigned modular addition
MULMOD, ///< unsigned modular multiplication MULMOD, ///< unsigned modular multiplication
SIGNEXTEND, ///< extend length of signed integer
SHA3 = 0x20, ///< compute SHA3-256 hash SHA3 = 0x20, ///< compute SHA3-256 hash
ADDRESS = 0x30, ///< get address of currently executing account ADDRESS = 0x30, ///< get address of currently executing account

4
test/MemTrie.cpp

@ -437,12 +437,12 @@ MemTrie::~MemTrie()
h256 MemTrie::hash256() const h256 MemTrie::hash256() const
{ {
return m_root ? m_root->hash256() : h256(); return m_root ? m_root->hash256() : sha3(dev::rlp(bytesConstRef()));
} }
bytes MemTrie::rlp() const bytes MemTrie::rlp() const
{ {
return m_root ? m_root->rlp() : bytes(); return m_root ? m_root->rlp() : dev::rlp(bytesConstRef());
} }
void MemTrie::debugPrint() void MemTrie::debugPrint()

6
test/TrieHash.cpp

@ -162,7 +162,7 @@ h256 hash256(StringMap const& _s)
{ {
// build patricia tree. // build patricia tree.
if (_s.empty()) if (_s.empty())
return h256(); return sha3(rlp(""));
HexMap hexMap; HexMap hexMap;
for (auto i = _s.rbegin(); i != _s.rend(); ++i) for (auto i = _s.rbegin(); i != _s.rend(); ++i)
hexMap[asNibbles(i->first)] = i->second; hexMap[asNibbles(i->first)] = i->second;
@ -175,7 +175,7 @@ bytes rlp256(StringMap const& _s)
{ {
// build patricia tree. // build patricia tree.
if (_s.empty()) if (_s.empty())
return bytes(); return rlp("");
HexMap hexMap; HexMap hexMap;
for (auto i = _s.rbegin(); i != _s.rend(); ++i) for (auto i = _s.rbegin(); i != _s.rend(); ++i)
hexMap[asNibbles(i->first)] = i->second; hexMap[asNibbles(i->first)] = i->second;
@ -188,7 +188,7 @@ h256 hash256(u256Map const& _s)
{ {
// build patricia tree. // build patricia tree.
if (_s.empty()) if (_s.empty())
return h256(); return sha3(rlp(""));
HexMap hexMap; HexMap hexMap;
for (auto i = _s.rbegin(); i != _s.rend(); ++i) for (auto i = _s.rbegin(); i != _s.rend(); ++i)
hexMap[asNibbles(toBigEndianString(i->first))] = asString(rlp(i->second)); hexMap[asNibbles(toBigEndianString(i->first))] = asString(rlp(i->second));

3
test/crypto.cpp

@ -341,6 +341,7 @@ BOOST_AUTO_TEST_CASE(eth_keypairs)
{ {
eth::Transaction t; eth::Transaction t;
t.nonce = 0; t.nonce = 0;
t.type = eth::Transaction::MessageCall;
t.receiveAddress = h160(fromHex("944400f4b88ac9589a0f17ed4671da26bddb668b")); t.receiveAddress = h160(fromHex("944400f4b88ac9589a0f17ed4671da26bddb668b"));
t.value = 1000; t.value = 1000;
auto rlp = t.rlp(false); auto rlp = t.rlp(false);
@ -369,6 +370,7 @@ int cryptoTest()
{ {
eth::Transaction t; eth::Transaction t;
t.nonce = 0; t.nonce = 0;
t.type = eth::Transaction::MessageCall;
t.receiveAddress = h160(fromHex("944400f4b88ac9589a0f17ed4671da26bddb668b")); t.receiveAddress = h160(fromHex("944400f4b88ac9589a0f17ed4671da26bddb668b"));
t.value = 1000; t.value = 1000;
auto rlp = t.rlp(false); auto rlp = t.rlp(false);
@ -397,6 +399,7 @@ int cryptoTest()
Transaction t; Transaction t;
t.nonce = 0; t.nonce = 0;
t.value = 1; // 1 wei. t.value = 1; // 1 wei.
t.type = eth::Transaction::MessageCall;
t.receiveAddress = toAddress(sha3("123")); t.receiveAddress = toAddress(sha3("123"));
bytes sig64 = toBigEndian(t.vrs.r) + toBigEndian(t.vrs.s); bytes sig64 = toBigEndian(t.vrs.r) + toBigEndian(t.vrs.s);

1
test/state.cpp

@ -68,6 +68,7 @@ int stateTest()
Transaction t; Transaction t;
t.nonce = s.transactionsFrom(myMiner.address()); t.nonce = s.transactionsFrom(myMiner.address());
t.value = 1000; // 1e3 wei. t.value = 1000; // 1e3 wei.
t.type = eth::Transaction::MessageCall;
t.receiveAddress = me.address(); t.receiveAddress = me.address();
t.sign(myMiner.secret()); t.sign(myMiner.secret());
assert(t.sender() == myMiner.address()); assert(t.sender() == myMiner.address());

7
test/vm.cpp

@ -56,14 +56,13 @@ h160 FakeExtVM::create(u256 _endowment, u256* _gas, bytesConstRef _init, OnOpFun
get<3>(addresses[ret]) = m_s.code(ret); get<3>(addresses[ret]) = m_s.code(ret);
} }
t.receiveAddress = ret; t.type = eth::Transaction::ContractCreation;
callcreates.push_back(t); callcreates.push_back(t);
return ret; return ret;
} }
bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256* _gas, bytesRef _out, OnOpFunc const&, Address _myAddressOverride, Address _codeAddressOverride) bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256* _gas, bytesRef _out, OnOpFunc const&, Address _myAddressOverride, Address _codeAddressOverride)
{ {
u256 contractgas = 0xffff; u256 contractgas = 0xffff;
Transaction t; Transaction t;
@ -71,6 +70,7 @@ bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data,
t.gasPrice = gasPrice; t.gasPrice = gasPrice;
t.gas = *_gas; t.gas = *_gas;
t.data = _data.toVector(); t.data = _data.toVector();
t.type = eth::Transaction::MessageCall;
t.receiveAddress = _receiveAddress; t.receiveAddress = _receiveAddress;
callcreates.push_back(t); callcreates.push_back(t);
@ -384,7 +384,7 @@ mArray FakeExtVM::exportCallCreates()
for (Transaction const& tx: callcreates) for (Transaction const& tx: callcreates)
{ {
mObject o; mObject o;
o["destination"] = toString(tx.receiveAddress); o["destination"] = tx.type == Transaction::ContractCreation ? "" : toString(tx.receiveAddress);
push(o, "gasLimit", tx.gas); push(o, "gasLimit", tx.gas);
push(o, "value", tx.value); push(o, "value", tx.value);
o["data"] = "0x" + toHex(tx.data); o["data"] = "0x" + toHex(tx.data);
@ -403,6 +403,7 @@ void FakeExtVM::importCallCreates(mArray& _callcreates)
BOOST_REQUIRE(tx.count("destination") > 0); BOOST_REQUIRE(tx.count("destination") > 0);
BOOST_REQUIRE(tx.count("gasLimit") > 0); BOOST_REQUIRE(tx.count("gasLimit") > 0);
Transaction t; Transaction t;
t.type = tx["destination"].get_str().empty() ? Transaction::ContractCreation : Transaction::MessageCall;
t.receiveAddress = Address(tx["destination"].get_str()); t.receiveAddress = Address(tx["destination"].get_str());
t.value = toInt(tx["value"]); t.value = toInt(tx["value"]);
t.gas = toInt(tx["gasLimit"]); t.gas = toInt(tx["gasLimit"]);

Loading…
Cancel
Save