Gav Wood
11 years ago
99 changed files with 1383 additions and 865 deletions
@ -1,36 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file CryptoHeaders.h
|
|||
* @author Tim Hughes <tim@twistedfury.com> |
|||
* @date 2014 |
|||
*/ |
|||
#pragma once |
|||
|
|||
// need to leave this one disabled
|
|||
#pragma GCC diagnostic ignored "-Wunused-function" |
|||
|
|||
#pragma warning(push) |
|||
#pragma warning(disable:4100 4244) |
|||
#pragma GCC diagnostic push |
|||
#pragma GCC diagnostic ignored "-Wconversion" |
|||
#pragma GCC diagnostic ignored "-Wunused-parameter" |
|||
#include <sha.h> |
|||
#include <sha3.h> |
|||
#include <ripemd.h> |
|||
#include <secp256k1/secp256k1.h> |
|||
#pragma warning(pop) |
|||
#pragma GCC diagnostic pop |
@ -1,27 +1,40 @@ |
|||
#pragma once |
|||
|
|||
#include <exception> |
|||
#include "CommonIO.h" |
|||
#include "CommonData.h" |
|||
#include "FixedHash.h" |
|||
#include <libethsupport/Exceptions.h> |
|||
|
|||
namespace eth |
|||
{ |
|||
|
|||
class Exception: public std::exception |
|||
{ |
|||
public: |
|||
virtual std::string description() const { return typeid(*this).name(); } |
|||
virtual char const* what() const noexcept { return typeid(*this).name(); } |
|||
}; |
|||
|
|||
class BadHexCharacter: public Exception {}; |
|||
class NotEnoughCash: public Exception {}; |
|||
|
|||
class RLPException: public Exception {}; |
|||
class BadCast: public RLPException {}; |
|||
class BadRLP: public RLPException {}; |
|||
class NoNetworking: public Exception {}; |
|||
class NoUPnPDevice: public Exception {}; |
|||
class RootNotFound: public Exception {}; |
|||
class GasPriceTooLow: public Exception {}; |
|||
class BlockGasLimitReached: public Exception {}; |
|||
class NoSuchContract: public Exception {}; |
|||
class ContractAddressCollision: public Exception {}; |
|||
class FeeTooSmall: public Exception {}; |
|||
class TooMuchGasUsed: public Exception {}; |
|||
class ExtraDataTooBig: public Exception {}; |
|||
class InvalidSignature: public Exception {}; |
|||
class InvalidTransactionFormat: public Exception { public: InvalidTransactionFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid transaction format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } }; |
|||
class InvalidBlockFormat: public Exception { public: InvalidBlockFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } }; |
|||
class InvalidBlockHeaderFormat: public Exception { public: InvalidBlockHeaderFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block header format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } }; |
|||
class InvalidUnclesHash: public Exception {}; |
|||
class InvalidUncle: public Exception {}; |
|||
class UncleNotAnUncle: public Exception {}; |
|||
class DuplicateUncleNonce: public Exception {}; |
|||
class InvalidStateRoot: public Exception {}; |
|||
class InvalidTransactionsHash: public Exception { public: InvalidTransactionsHash(h256 _head, h256 _real): m_head(_head), m_real(_real) {} h256 m_head; h256 m_real; virtual std::string description() const { return "Invalid transactions hash: header says: " + toHex(m_head.ref()) + " block is:" + toHex(m_real.ref()); } }; |
|||
class InvalidTransaction: public Exception {}; |
|||
class InvalidDifficulty: public Exception {}; |
|||
class InvalidGasLimit: public Exception {}; |
|||
class InvalidMinGasPrice: public Exception { public: InvalidMinGasPrice(u256 _provided = 0, u256 _limit = 0): provided(_provided), limit(_limit) {} u256 provided; u256 limit; virtual std::string description() const { return "Invalid minimum gas price (provided: " + toString(provided) + " limit:" + toString(limit) + ")"; } }; |
|||
class InvalidTransactionGasUsed: public Exception {}; |
|||
class InvalidTransactionStateRoot: public Exception {}; |
|||
class InvalidTimestamp: public Exception {}; |
|||
class InvalidNonce: public Exception { public: InvalidNonce(u256 _required = 0, u256 _candidate = 0): required(_required), candidate(_candidate) {} u256 required; u256 candidate; virtual std::string description() const { return "Invalid nonce (r: " + toString(required) + " c:" + toString(candidate) + ")"; } }; |
|||
class InvalidBlockNonce: public Exception { public: InvalidBlockNonce(h256 _h = h256(), h256 _n = h256(), u256 _d = 0): h(_h), n(_n), d(_d) {} h256 h; h256 n; u256 d; virtual std::string description() const { return "Invalid nonce (h: " + toString(h) + " n:" + toString(n) + " d:" + toString(d) + ")"; } }; |
|||
class InvalidParentHash: public Exception {}; |
|||
class InvalidNumber: public Exception {}; |
|||
class InvalidContractAddress: public Exception {}; |
|||
|
|||
} |
|||
|
@ -0,0 +1,232 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file Instruction.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "Instruction.h" |
|||
|
|||
#include "CommonEth.h" |
|||
using namespace std; |
|||
using namespace eth; |
|||
|
|||
const std::map<std::string, Instruction> eth::c_instructions = |
|||
{ |
|||
{ "STOP", Instruction::STOP }, |
|||
{ "ADD", Instruction::ADD }, |
|||
{ "SUB", Instruction::SUB }, |
|||
{ "MUL", Instruction::MUL }, |
|||
{ "DIV", Instruction::DIV }, |
|||
{ "SDIV", Instruction::SDIV }, |
|||
{ "MOD", Instruction::MOD }, |
|||
{ "SMOD", Instruction::SMOD }, |
|||
{ "EXP", Instruction::EXP }, |
|||
{ "NEG", Instruction::NEG }, |
|||
{ "LT", Instruction::LT }, |
|||
{ "GT", Instruction::GT }, |
|||
{ "SLT", Instruction::SLT }, |
|||
{ "SGT", Instruction::SGT }, |
|||
{ "EQ", Instruction::EQ }, |
|||
{ "NOT", Instruction::NOT }, |
|||
{ "AND", Instruction::AND }, |
|||
{ "OR", Instruction::OR }, |
|||
{ "XOR", Instruction::XOR }, |
|||
{ "BYTE", Instruction::BYTE }, |
|||
{ "SHA3", Instruction::SHA3 }, |
|||
{ "ADDRESS", Instruction::ADDRESS }, |
|||
{ "BALANCE", Instruction::BALANCE }, |
|||
{ "ORIGIN", Instruction::ORIGIN }, |
|||
{ "CALLER", Instruction::CALLER }, |
|||
{ "CALLVALUE", Instruction::CALLVALUE }, |
|||
{ "CALLDATALOAD", Instruction::CALLDATALOAD }, |
|||
{ "CALLDATASIZE", Instruction::CALLDATASIZE }, |
|||
{ "CALLDATACOPY", Instruction::CALLDATACOPY }, |
|||
{ "CODESIZE", Instruction::CODESIZE }, |
|||
{ "CODECOPY", Instruction::CODECOPY }, |
|||
{ "GASPRICE", Instruction::GASPRICE }, |
|||
{ "PREVHASH", Instruction::PREVHASH }, |
|||
{ "COINBASE", Instruction::COINBASE }, |
|||
{ "TIMESTAMP", Instruction::TIMESTAMP }, |
|||
{ "NUMBER", Instruction::NUMBER }, |
|||
{ "DIFFICULTY", Instruction::DIFFICULTY }, |
|||
{ "GASLIMIT", Instruction::GASLIMIT }, |
|||
{ "POP", Instruction::POP }, |
|||
{ "DUP", Instruction::DUP }, |
|||
{ "SWAP", Instruction::SWAP }, |
|||
{ "MLOAD", Instruction::MLOAD }, |
|||
{ "MSTORE", Instruction::MSTORE }, |
|||
{ "MSTORE8", Instruction::MSTORE8 }, |
|||
{ "SLOAD", Instruction::SLOAD }, |
|||
{ "SSTORE", Instruction::SSTORE }, |
|||
{ "JUMP", Instruction::JUMP }, |
|||
{ "JUMPI", Instruction::JUMPI }, |
|||
{ "PC", Instruction::PC }, |
|||
{ "MEMSIZE", Instruction::MEMSIZE }, |
|||
{ "GAS", Instruction::GAS }, |
|||
{ "PUSH1", Instruction::PUSH1 }, |
|||
{ "PUSH2", Instruction::PUSH2 }, |
|||
{ "PUSH3", Instruction::PUSH3 }, |
|||
{ "PUSH4", Instruction::PUSH4 }, |
|||
{ "PUSH5", Instruction::PUSH5 }, |
|||
{ "PUSH6", Instruction::PUSH6 }, |
|||
{ "PUSH7", Instruction::PUSH7 }, |
|||
{ "PUSH8", Instruction::PUSH8 }, |
|||
{ "PUSH9", Instruction::PUSH9 }, |
|||
{ "PUSH10", Instruction::PUSH10 }, |
|||
{ "PUSH11", Instruction::PUSH11 }, |
|||
{ "PUSH12", Instruction::PUSH12 }, |
|||
{ "PUSH13", Instruction::PUSH13 }, |
|||
{ "PUSH14", Instruction::PUSH14 }, |
|||
{ "PUSH15", Instruction::PUSH15 }, |
|||
{ "PUSH16", Instruction::PUSH16 }, |
|||
{ "PUSH17", Instruction::PUSH17 }, |
|||
{ "PUSH18", Instruction::PUSH18 }, |
|||
{ "PUSH19", Instruction::PUSH19 }, |
|||
{ "PUSH20", Instruction::PUSH20 }, |
|||
{ "PUSH21", Instruction::PUSH21 }, |
|||
{ "PUSH22", Instruction::PUSH22 }, |
|||
{ "PUSH23", Instruction::PUSH23 }, |
|||
{ "PUSH24", Instruction::PUSH24 }, |
|||
{ "PUSH25", Instruction::PUSH25 }, |
|||
{ "PUSH26", Instruction::PUSH26 }, |
|||
{ "PUSH27", Instruction::PUSH27 }, |
|||
{ "PUSH28", Instruction::PUSH28 }, |
|||
{ "PUSH29", Instruction::PUSH29 }, |
|||
{ "PUSH30", Instruction::PUSH30 }, |
|||
{ "PUSH31", Instruction::PUSH31 }, |
|||
{ "PUSH32", Instruction::PUSH32 }, |
|||
{ "CREATE", Instruction::CREATE }, |
|||
{ "CALL", Instruction::CALL }, |
|||
{ "RETURN", Instruction::RETURN }, |
|||
{ "SUICIDE", Instruction::SUICIDE } |
|||
}; |
|||
|
|||
const std::map<Instruction, InstructionInfo> eth::c_instructionInfo = |
|||
{ // Add, Args, Ret
|
|||
{ Instruction::STOP, { "STOP", 0, 0, 0 } }, |
|||
{ Instruction::ADD, { "ADD", 0, 2, 1 } }, |
|||
{ Instruction::SUB, { "SUB", 0, 2, 1 } }, |
|||
{ Instruction::MUL, { "MUL", 0, 2, 1 } }, |
|||
{ Instruction::DIV, { "DIV", 0, 2, 1 } }, |
|||
{ Instruction::SDIV, { "SDIV", 0, 2, 1 } }, |
|||
{ Instruction::MOD, { "MOD", 0, 2, 1 } }, |
|||
{ Instruction::SMOD, { "SMOD", 0, 2, 1 } }, |
|||
{ Instruction::EXP, { "EXP", 0, 2, 1 } }, |
|||
{ Instruction::NEG, { "NEG", 0, 1, 1 } }, |
|||
{ Instruction::LT, { "LT", 0, 2, 1 } }, |
|||
{ Instruction::GT, { "GT", 0, 2, 1 } }, |
|||
{ Instruction::SLT, { "SLT", 0, 2, 1 } }, |
|||
{ Instruction::SGT, { "SGT", 0, 2, 1 } }, |
|||
{ Instruction::EQ, { "EQ", 0, 2, 1 } }, |
|||
{ Instruction::NOT, { "NOT", 0, 1, 1 } }, |
|||
{ Instruction::AND, { "AND", 0, 2, 1 } }, |
|||
{ Instruction::OR, { "OR", 0, 2, 1 } }, |
|||
{ Instruction::XOR, { "XOR", 0, 2, 1 } }, |
|||
{ Instruction::BYTE, { "BYTE", 0, 2, 1 } }, |
|||
{ Instruction::SHA3, { "SHA3", 0, 2, 1 } }, |
|||
{ Instruction::ADDRESS, { "ADDRESS", 0, 0, 1 } }, |
|||
{ Instruction::BALANCE, { "BALANCE", 0, 1, 1 } }, |
|||
{ Instruction::ORIGIN, { "ORIGIN", 0, 0, 1 } }, |
|||
{ Instruction::CALLER, { "CALLER", 0, 0, 1 } }, |
|||
{ Instruction::CALLVALUE, { "CALLVALUE", 0, 0, 1 } }, |
|||
{ Instruction::CALLDATALOAD, { "CALLDATALOAD", 0, 1, 1 } }, |
|||
{ Instruction::CALLDATASIZE, { "CALLDATASIZE", 0, 0, 1 } }, |
|||
{ Instruction::CALLDATACOPY, { "CALLDATACOPY", 0, 3, 0 } }, |
|||
{ Instruction::CODESIZE, { "CODESIZE", 0, 0, 1 } }, |
|||
{ Instruction::CODECOPY, { "CODECOPY", 0, 3, 0 } }, |
|||
{ Instruction::GASPRICE, { "GASPRICE", 0, 0, 1 } }, |
|||
{ Instruction::PREVHASH, { "PREVHASH", 0, 0, 1 } }, |
|||
{ Instruction::COINBASE, { "COINBASE", 0, 0, 1 } }, |
|||
{ Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1 } }, |
|||
{ Instruction::NUMBER, { "NUMBER", 0, 0, 1 } }, |
|||
{ Instruction::DIFFICULTY, { "DIFFICULTY", 0, 0, 1 } }, |
|||
{ Instruction::GASLIMIT, { "GASLIMIT", 0, 0, 1 } }, |
|||
{ Instruction::POP, { "POP", 0, 1, 0 } }, |
|||
{ Instruction::DUP, { "DUP", 0, 1, 2 } }, |
|||
{ Instruction::SWAP, { "SWAP", 0, 2, 2 } }, |
|||
{ Instruction::MLOAD, { "MLOAD", 0, 1, 1 } }, |
|||
{ Instruction::MSTORE, { "MSTORE", 0, 2, 0 } }, |
|||
{ Instruction::MSTORE8, { "MSTORE8", 0, 2, 0 } }, |
|||
{ Instruction::SLOAD, { "SLOAD", 0, 1, 1 } }, |
|||
{ Instruction::SSTORE, { "SSTORE", 0, 2, 0 } }, |
|||
{ Instruction::JUMP, { "JUMP", 0, 1, 0 } }, |
|||
{ Instruction::JUMPI, { "JUMPI", 0, 2, 0 } }, |
|||
{ Instruction::PC, { "PC", 0, 0, 1 } }, |
|||
{ Instruction::MEMSIZE, { "MEMSIZE", 0, 0, 1 } }, |
|||
{ Instruction::GAS, { "GAS", 0, 0, 1 } }, |
|||
{ Instruction::PUSH1, { "PUSH1", 1, 0, 1 } }, |
|||
{ Instruction::PUSH2, { "PUSH2", 2, 0, 1 } }, |
|||
{ Instruction::PUSH3, { "PUSH3", 3, 0, 1 } }, |
|||
{ Instruction::PUSH4, { "PUSH4", 4, 0, 1 } }, |
|||
{ Instruction::PUSH5, { "PUSH5", 5, 0, 1 } }, |
|||
{ Instruction::PUSH6, { "PUSH6", 6, 0, 1 } }, |
|||
{ Instruction::PUSH7, { "PUSH7", 7, 0, 1 } }, |
|||
{ Instruction::PUSH8, { "PUSH8", 8, 0, 1 } }, |
|||
{ Instruction::PUSH9, { "PUSH9", 9, 0, 1 } }, |
|||
{ Instruction::PUSH10, { "PUSH10", 10, 0, 1 } }, |
|||
{ Instruction::PUSH11, { "PUSH11", 11, 0, 1 } }, |
|||
{ Instruction::PUSH12, { "PUSH12", 12, 0, 1 } }, |
|||
{ Instruction::PUSH13, { "PUSH13", 13, 0, 1 } }, |
|||
{ Instruction::PUSH14, { "PUSH14", 14, 0, 1 } }, |
|||
{ Instruction::PUSH15, { "PUSH15", 15, 0, 1 } }, |
|||
{ Instruction::PUSH16, { "PUSH16", 16, 0, 1 } }, |
|||
{ Instruction::PUSH17, { "PUSH17", 17, 0, 1 } }, |
|||
{ Instruction::PUSH18, { "PUSH18", 18, 0, 1 } }, |
|||
{ Instruction::PUSH19, { "PUSH19", 19, 0, 1 } }, |
|||
{ Instruction::PUSH20, { "PUSH20", 20, 0, 1 } }, |
|||
{ Instruction::PUSH21, { "PUSH21", 21, 0, 1 } }, |
|||
{ Instruction::PUSH22, { "PUSH22", 22, 0, 1 } }, |
|||
{ Instruction::PUSH23, { "PUSH23", 23, 0, 1 } }, |
|||
{ Instruction::PUSH24, { "PUSH24", 24, 0, 1 } }, |
|||
{ Instruction::PUSH25, { "PUSH25", 25, 0, 1 } }, |
|||
{ Instruction::PUSH26, { "PUSH26", 26, 0, 1 } }, |
|||
{ Instruction::PUSH27, { "PUSH27", 27, 0, 1 } }, |
|||
{ Instruction::PUSH28, { "PUSH28", 28, 0, 1 } }, |
|||
{ Instruction::PUSH29, { "PUSH29", 29, 0, 1 } }, |
|||
{ Instruction::PUSH30, { "PUSH30", 30, 0, 1 } }, |
|||
{ Instruction::PUSH31, { "PUSH31", 31, 0, 1 } }, |
|||
{ Instruction::PUSH32, { "PUSH32", 32, 0, 1 } }, |
|||
{ Instruction::CREATE, { "CREATE", 0, 3, 1 } }, |
|||
{ Instruction::CALL, { "CALL", 0, 7, 1 } }, |
|||
{ Instruction::RETURN, { "RETURN", 0, 2, 0 } }, |
|||
{ Instruction::SUICIDE, { "SUICIDE", 0, 1, 0} } |
|||
}; |
|||
|
|||
string eth::disassemble(bytes const& _mem) |
|||
{ |
|||
stringstream ret; |
|||
uint numerics = 0; |
|||
for (auto it = _mem.begin(); it != _mem.end(); ++it) |
|||
{ |
|||
byte n = *it; |
|||
auto iit = c_instructionInfo.find((Instruction)n); |
|||
if (numerics || iit == c_instructionInfo.end() || (byte)iit->first != n) // not an instruction or expecting an argument...
|
|||
{ |
|||
if (numerics) |
|||
numerics--; |
|||
ret << "0x" << hex << (int)n << " "; |
|||
} |
|||
else |
|||
{ |
|||
auto const& ii = iit->second; |
|||
ret << ii.name << " "; |
|||
numerics = ii.additional; |
|||
} |
|||
} |
|||
return ret.str(); |
|||
} |
@ -0,0 +1,152 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file Instruction.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <libethsupport/Common.h> |
|||
#include "Exceptions.h" |
|||
|
|||
namespace boost { namespace spirit { class utree; } } |
|||
namespace sp = boost::spirit; |
|||
|
|||
namespace eth |
|||
{ |
|||
|
|||
// TODO: Update comments.
|
|||
|
|||
/// Virtual machine bytecode instruction.
|
|||
enum class Instruction: uint8_t |
|||
{ |
|||
STOP = 0x00, ///< halts execution
|
|||
ADD, |
|||
MUL, |
|||
SUB, |
|||
DIV, |
|||
SDIV, |
|||
MOD, |
|||
SMOD, |
|||
EXP, |
|||
NEG, |
|||
LT, |
|||
GT, |
|||
SLT, |
|||
SGT, |
|||
EQ, |
|||
NOT, |
|||
|
|||
AND = 0x10, |
|||
OR, |
|||
XOR, |
|||
BYTE, |
|||
|
|||
SHA3 = 0x20, |
|||
|
|||
ADDRESS = 0x30, |
|||
BALANCE, |
|||
ORIGIN, |
|||
CALLER, |
|||
CALLVALUE, |
|||
CALLDATALOAD, |
|||
CALLDATASIZE, |
|||
CALLDATACOPY, |
|||
CODESIZE, |
|||
CODECOPY, |
|||
GASPRICE, |
|||
|
|||
PREVHASH = 0x40, |
|||
COINBASE, |
|||
TIMESTAMP, |
|||
NUMBER, |
|||
DIFFICULTY, |
|||
GASLIMIT, |
|||
|
|||
POP = 0x50, |
|||
DUP, |
|||
SWAP, |
|||
MLOAD, |
|||
MSTORE, |
|||
MSTORE8, |
|||
SLOAD, |
|||
SSTORE, |
|||
JUMP, |
|||
JUMPI, |
|||
PC, |
|||
MEMSIZE, |
|||
GAS, |
|||
|
|||
PUSH1 = 0x60, |
|||
PUSH2, |
|||
PUSH3, |
|||
PUSH4, |
|||
PUSH5, |
|||
PUSH6, |
|||
PUSH7, |
|||
PUSH8, |
|||
PUSH9, |
|||
PUSH10, |
|||
PUSH11, |
|||
PUSH12, |
|||
PUSH13, |
|||
PUSH14, |
|||
PUSH15, |
|||
PUSH16, |
|||
PUSH17, |
|||
PUSH18, |
|||
PUSH19, |
|||
PUSH20, |
|||
PUSH21, |
|||
PUSH22, |
|||
PUSH23, |
|||
PUSH24, |
|||
PUSH25, |
|||
PUSH26, |
|||
PUSH27, |
|||
PUSH28, |
|||
PUSH29, |
|||
PUSH30, |
|||
PUSH31, |
|||
PUSH32, |
|||
|
|||
CREATE = 0xf0, |
|||
CALL, |
|||
RETURN, |
|||
SUICIDE = 0xff |
|||
}; |
|||
|
|||
/// Information structure for a particular instruction.
|
|||
struct InstructionInfo |
|||
{ |
|||
char const* name; ///< The name of the instruction.
|
|||
int additional; ///< Additional items required in memory for this instructions (only for PUSH).
|
|||
int args; ///< Number of items required on the stack for this instruction (and, for the purposes of ret, the number taken from the stack).
|
|||
int ret; ///< Number of items placed (back) on the stack by this instruction, assuming args items were removed.
|
|||
}; |
|||
|
|||
/// Information on all the instructions.
|
|||
extern const std::map<Instruction, InstructionInfo> c_instructionInfo; |
|||
|
|||
/// Convert from string mnemonic to Instruction type.
|
|||
extern const std::map<std::string, Instruction> c_instructions; |
|||
|
|||
/// Convert from EVM code to simple EVM assembly language.
|
|||
std::string disassemble(bytes const& _mem); |
|||
|
|||
} |
@ -1,73 +0,0 @@ |
|||
#pragma once |
|||
|
|||
#include <type_traits> |
|||
#include <cassert> |
|||
#include <vector> |
|||
#include <string> |
|||
|
|||
#pragma warning(push) |
|||
#pragma warning(disable: 4100 4267) |
|||
#include <leveldb/db.h> |
|||
#pragma warning(pop) |
|||
|
|||
namespace eth |
|||
{ |
|||
|
|||
template <class _T> |
|||
class vector_ref |
|||
{ |
|||
public: |
|||
typedef _T value_type; |
|||
typedef _T element_type; |
|||
typedef typename std::conditional<std::is_const<_T>::value, typename std::remove_const<_T>::type, _T>::type mutable_value_type; |
|||
|
|||
vector_ref(): m_data(nullptr), m_count(0) {} |
|||
vector_ref(_T* _data, size_t _count): m_data(_data), m_count(_count) {} |
|||
vector_ref(std::string* _data): m_data((_T*)_data->data()), m_count(_data->size() / sizeof(_T)) {} |
|||
vector_ref(typename std::conditional<std::is_const<_T>::value, std::vector<typename std::remove_const<_T>::type> const*, std::vector<_T>*>::type _data): m_data(_data->data()), m_count(_data->size()) {} |
|||
vector_ref(typename std::conditional<std::is_const<_T>::value, std::string const&, std::string&>::type _data): m_data((_T*)_data.data()), m_count(_data.size() / sizeof(_T)) {} |
|||
vector_ref(leveldb::Slice const& _s): m_data(_s.data()), m_count(_s.size() / sizeof(_T)) {} |
|||
|
|||
explicit operator bool() const { return m_data && m_count; } |
|||
|
|||
bool contentsEqual(std::vector<mutable_value_type> const& _c) const { return _c.size() == m_count && !memcmp(_c.data(), m_data, m_count); } |
|||
std::vector<mutable_value_type> toVector() const { return std::vector<mutable_value_type>(m_data, m_data + m_count); } |
|||
std::vector<unsigned char> toBytes() const { return std::vector<unsigned char>((unsigned char const*)m_data, m_data + m_count * sizeof(_T)); } |
|||
std::string toString() const { return std::string((char const*)m_data, ((char const*)m_data) + m_count); } |
|||
template <class _T2> operator vector_ref<_T2>() const { assert(m_count * sizeof(_T) / sizeof(_T2) * sizeof(_T2) / sizeof(_T) == m_count); return vector_ref<_T2>((_T2*)m_data, m_count * sizeof(_T) / sizeof(_T2)); } |
|||
|
|||
_T* data() const { return m_data; } |
|||
size_t count() const { return m_count; } |
|||
size_t size() const { return m_count; } |
|||
bool empty() const { return !m_count; } |
|||
vector_ref<_T> next() const { return vector_ref<_T>(m_data + m_count, m_count); } |
|||
vector_ref<_T> cropped(size_t _begin, size_t _count = ~size_t(0)) const { if (m_data && _begin + std::max(size_t(0), _count) <= m_count) return vector_ref<_T>(m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count); else return vector_ref<_T>(); } |
|||
void retarget(_T const* _d, size_t _s) { m_data = _d; m_count = _s; } |
|||
void retarget(std::vector<_T> const& _t) { m_data = _t.data(); m_count = _t.size(); } |
|||
|
|||
_T* begin() { return m_data; } |
|||
_T* end() { return m_data + m_count; } |
|||
_T const* begin() const { return m_data; } |
|||
_T const* end() const { return m_data + m_count; } |
|||
|
|||
_T& operator[](size_t _i) { assert(m_data); assert(_i < m_count); return m_data[_i]; } |
|||
_T const& operator[](size_t _i) const { assert(m_data); assert(_i < m_count); return m_data[_i]; } |
|||
|
|||
bool operator==(vector_ref<_T> const& _cmp) const { return m_data == _cmp.m_data && m_count == _cmp.m_count; } |
|||
bool operator!=(vector_ref<_T> const& _cmp) const { return !operator==(); } |
|||
|
|||
operator leveldb::Slice() const { return leveldb::Slice((char const*)m_data, m_count * sizeof(_T)); } |
|||
|
|||
void reset() { m_data = nullptr; m_count = 0; } |
|||
|
|||
private: |
|||
_T* m_data; |
|||
size_t m_count; |
|||
}; |
|||
|
|||
template<class _T> vector_ref<_T const> ref(_T const& _t) { return vector_ref<_T const>(&_t, 1); } |
|||
template<class _T> vector_ref<_T> ref(_T& _t) { return vector_ref<_T>(&_t, 1); } |
|||
template<class _T> vector_ref<_T const> ref(std::vector<_T> const& _t) { return vector_ref<_T const>(&_t); } |
|||
template<class _T> vector_ref<_T> ref(std::vector<_T>& _t) { return vector_ref<_T>(&_t); } |
|||
|
|||
} |
@ -1,48 +0,0 @@ |
|||
#pragma once |
|||
|
|||
#include <libethcore/Exceptions.h> |
|||
|
|||
namespace eth |
|||
{ |
|||
|
|||
class VMException: public Exception {}; |
|||
class StepsDone: public VMException {}; |
|||
class BreakPointHit: public VMException {}; |
|||
class BadInstruction: public VMException {}; |
|||
class OutOfGas: public VMException {}; |
|||
class StackTooSmall: public VMException { public: StackTooSmall(u256 _req, u256 _got): req(_req), got(_got) {} u256 req; u256 got; }; |
|||
class OperandOutOfRange: public VMException { public: OperandOutOfRange(u256 _min, u256 _max, u256 _got): mn(_min), mx(_max), got(_got) {} u256 mn; u256 mx; u256 got; }; |
|||
|
|||
class NotEnoughCash: public Exception {}; |
|||
|
|||
class GasPriceTooLow: public Exception {}; |
|||
class BlockGasLimitReached: public Exception {}; |
|||
class NoSuchContract: public Exception {}; |
|||
class ContractAddressCollision: public Exception {}; |
|||
class FeeTooSmall: public Exception {}; |
|||
class TooMuchGasUsed: public Exception {}; |
|||
class ExtraDataTooBig: public Exception {}; |
|||
class InvalidSignature: public Exception {}; |
|||
class InvalidTransactionFormat: public Exception { public: InvalidTransactionFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid transaction format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } }; |
|||
class InvalidBlockFormat: public Exception { public: InvalidBlockFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } }; |
|||
class InvalidBlockHeaderFormat: public Exception { public: InvalidBlockHeaderFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block header format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } }; |
|||
class InvalidUnclesHash: public Exception {}; |
|||
class InvalidUncle: public Exception {}; |
|||
class UncleNotAnUncle: public Exception {}; |
|||
class DuplicateUncleNonce: public Exception {}; |
|||
class InvalidStateRoot: public Exception {}; |
|||
class InvalidTransactionsHash: public Exception { public: InvalidTransactionsHash(h256 _head, h256 _real): m_head(_head), m_real(_real) {} h256 m_head; h256 m_real; virtual std::string description() const { return "Invalid transactions hash: header says: " + toHex(m_head.ref()) + " block is:" + toHex(m_real.ref()); } }; |
|||
class InvalidTransaction: public Exception {}; |
|||
class InvalidDifficulty: public Exception {}; |
|||
class InvalidGasLimit: public Exception {}; |
|||
class InvalidMinGasPrice: public Exception { public: InvalidMinGasPrice(u256 _provided = 0, u256 _limit = 0): provided(_provided), limit(_limit) {} u256 provided; u256 limit; virtual std::string description() const { return "Invalid minimum gas price (provided: " + toString(provided) + " limit:" + toString(limit) + ")"; } }; |
|||
class InvalidTransactionGasUsed: public Exception {}; |
|||
class InvalidTransactionStateRoot: public Exception {}; |
|||
class InvalidTimestamp: public Exception {}; |
|||
class InvalidNonce: public Exception { public: InvalidNonce(u256 _required = 0, u256 _candidate = 0): required(_required), candidate(_candidate) {} u256 required; u256 candidate; virtual std::string description() const { return "Invalid nonce (r: " + toString(required) + " c:" + toString(candidate) + ")"; } }; |
|||
class InvalidBlockNonce: public Exception { public: InvalidBlockNonce(h256 _h = h256(), h256 _n = h256(), u256 _d = 0): h(_h), n(_n), d(_d) {} h256 h; h256 n; u256 d; virtual std::string description() const { return "Invalid nonce (h: " + toString(h) + " n:" + toString(n) + " d:" + toString(d) + ")"; } }; |
|||
class InvalidParentHash: public Exception {}; |
|||
class InvalidNumber: public Exception {}; |
|||
class InvalidContractAddress: public Exception {}; |
|||
|
|||
} |
@ -0,0 +1,68 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
|
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") |
|||
|
|||
aux_source_directory(. SRC_LIST) |
|||
|
|||
set(EXECUTABLE ethsupport) |
|||
|
|||
if(APPLE) |
|||
# set(CMAKE_INSTALL_PREFIX ../lib) |
|||
add_library(${EXECUTABLE} SHARED ${SRC_LIST}) |
|||
else() |
|||
add_library(${EXECUTABLE} ${SRC_LIST}) |
|||
endif() |
|||
if (UNIX) |
|||
FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework locale) |
|||
endif() |
|||
file(GLOB HEADERS "*.h") |
|||
|
|||
include_directories(..) |
|||
include_directories(${MINIUPNPC_ID}) |
|||
include_directories(${LEVELDB_ID}) |
|||
|
|||
target_link_libraries(${EXECUTABLE} secp256k1) |
|||
target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) |
|||
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) |
|||
target_link_libraries(${EXECUTABLE} gmp) |
|||
|
|||
|
|||
if(${TARGET_PLATFORM} STREQUAL "w64") |
|||
include_directories(/usr/x86_64-w64-mingw32/include/cryptopp) |
|||
target_link_libraries(${EXECUTABLE} cryptopp) |
|||
target_link_libraries(${EXECUTABLE} boost_system-mt-s) |
|||
target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) |
|||
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) |
|||
target_link_libraries(${EXECUTABLE} iphlpapi) |
|||
target_link_libraries(${EXECUTABLE} ws2_32) |
|||
target_link_libraries(${EXECUTABLE} mswsock) |
|||
target_link_libraries(${EXECUTABLE} shlwapi) |
|||
elseif (APPLE) |
|||
# Latest mavericks boost libraries only come with -mt |
|||
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) |
|||
target_link_libraries(${EXECUTABLE} boost_system-mt) |
|||
target_link_libraries(${EXECUTABLE} boost_filesystem-mt) |
|||
target_link_libraries(${EXECUTABLE} boost_thread-mt) |
|||
find_package(Threads REQUIRED) |
|||
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) |
|||
elseif (UNIX) |
|||
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) |
|||
target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) |
|||
target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) |
|||
target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) |
|||
target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) |
|||
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) |
|||
else () |
|||
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) |
|||
target_link_libraries(${EXECUTABLE} boost_system) |
|||
target_link_libraries(${EXECUTABLE} boost_filesystem) |
|||
target_link_libraries(${EXECUTABLE} boost_thread) |
|||
find_package(Threads REQUIRED) |
|||
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) |
|||
endif () |
|||
|
|||
message("Installation path: ${CMAKE_INSTALL_PREFIX}") |
|||
|
|||
install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) |
|||
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) |
|||
|
@ -0,0 +1,70 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
|
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") |
|||
|
|||
aux_source_directory(. SRC_LIST) |
|||
|
|||
set(EXECUTABLE evm) |
|||
|
|||
if(APPLE) |
|||
# set(CMAKE_INSTALL_PREFIX ../lib) |
|||
add_library(${EXECUTABLE} SHARED ${SRC_LIST}) |
|||
else() |
|||
add_library(${EXECUTABLE} ${SRC_LIST}) |
|||
endif() |
|||
if (UNIX) |
|||
FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework locale) |
|||
endif() |
|||
file(GLOB HEADERS "*.h") |
|||
|
|||
include_directories(..) |
|||
include_directories(${MINIUPNPC_ID}) |
|||
include_directories(${LEVELDB_ID}) |
|||
|
|||
target_link_libraries(${EXECUTABLE} ethcore) |
|||
target_link_libraries(${EXECUTABLE} ethsupport) |
|||
target_link_libraries(${EXECUTABLE} secp256k1) |
|||
target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) |
|||
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) |
|||
target_link_libraries(${EXECUTABLE} gmp) |
|||
|
|||
|
|||
if(${TARGET_PLATFORM} STREQUAL "w64") |
|||
include_directories(/usr/x86_64-w64-mingw32/include/cryptopp) |
|||
target_link_libraries(${EXECUTABLE} cryptopp) |
|||
target_link_libraries(${EXECUTABLE} boost_system-mt-s) |
|||
target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) |
|||
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) |
|||
target_link_libraries(${EXECUTABLE} iphlpapi) |
|||
target_link_libraries(${EXECUTABLE} ws2_32) |
|||
target_link_libraries(${EXECUTABLE} mswsock) |
|||
target_link_libraries(${EXECUTABLE} shlwapi) |
|||
elseif (APPLE) |
|||
# Latest mavericks boost libraries only come with -mt |
|||
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) |
|||
target_link_libraries(${EXECUTABLE} boost_system-mt) |
|||
target_link_libraries(${EXECUTABLE} boost_filesystem-mt) |
|||
target_link_libraries(${EXECUTABLE} boost_thread-mt) |
|||
find_package(Threads REQUIRED) |
|||
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) |
|||
elseif (UNIX) |
|||
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) |
|||
target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) |
|||
target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) |
|||
target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) |
|||
target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) |
|||
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) |
|||
else () |
|||
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) |
|||
target_link_libraries(${EXECUTABLE} boost_system) |
|||
target_link_libraries(${EXECUTABLE} boost_filesystem) |
|||
target_link_libraries(${EXECUTABLE} boost_thread) |
|||
find_package(Threads REQUIRED) |
|||
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) |
|||
endif () |
|||
|
|||
message("Installation path: ${CMAKE_INSTALL_PREFIX}") |
|||
|
|||
install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) |
|||
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) |
|||
|
@ -0,0 +1,70 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
|
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") |
|||
|
|||
aux_source_directory(. SRC_LIST) |
|||
|
|||
set(EXECUTABLE lll) |
|||
|
|||
if(APPLE) |
|||
# set(CMAKE_INSTALL_PREFIX ../lib) |
|||
add_library(${EXECUTABLE} SHARED ${SRC_LIST}) |
|||
else() |
|||
add_library(${EXECUTABLE} ${SRC_LIST}) |
|||
endif() |
|||
if (UNIX) |
|||
FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework locale) |
|||
endif() |
|||
file(GLOB HEADERS "*.h") |
|||
|
|||
include_directories(..) |
|||
include_directories(${MINIUPNPC_ID}) |
|||
include_directories(${LEVELDB_ID}) |
|||
|
|||
target_link_libraries(${EXECUTABLE} ethcore) |
|||
target_link_libraries(${EXECUTABLE} ethsupport) |
|||
target_link_libraries(${EXECUTABLE} secp256k1) |
|||
target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) |
|||
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) |
|||
target_link_libraries(${EXECUTABLE} gmp) |
|||
|
|||
|
|||
if(${TARGET_PLATFORM} STREQUAL "w64") |
|||
include_directories(/usr/x86_64-w64-mingw32/include/cryptopp) |
|||
target_link_libraries(${EXECUTABLE} cryptopp) |
|||
target_link_libraries(${EXECUTABLE} boost_system-mt-s) |
|||
target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) |
|||
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) |
|||
target_link_libraries(${EXECUTABLE} iphlpapi) |
|||
target_link_libraries(${EXECUTABLE} ws2_32) |
|||
target_link_libraries(${EXECUTABLE} mswsock) |
|||
target_link_libraries(${EXECUTABLE} shlwapi) |
|||
elseif (APPLE) |
|||
# Latest mavericks boost libraries only come with -mt |
|||
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) |
|||
target_link_libraries(${EXECUTABLE} boost_system-mt) |
|||
target_link_libraries(${EXECUTABLE} boost_filesystem-mt) |
|||
target_link_libraries(${EXECUTABLE} boost_thread-mt) |
|||
find_package(Threads REQUIRED) |
|||
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) |
|||
elseif (UNIX) |
|||
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) |
|||
target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) |
|||
target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) |
|||
target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) |
|||
target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) |
|||
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) |
|||
else () |
|||
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) |
|||
target_link_libraries(${EXECUTABLE} boost_system) |
|||
target_link_libraries(${EXECUTABLE} boost_filesystem) |
|||
target_link_libraries(${EXECUTABLE} boost_thread) |
|||
find_package(Threads REQUIRED) |
|||
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) |
|||
endif () |
|||
|
|||
message("Installation path: ${CMAKE_INSTALL_PREFIX}") |
|||
|
|||
install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) |
|||
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) |
|||
|
@ -0,0 +1,61 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file Compiler.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "Compiler.h" |
|||
#include "Parser.h" |
|||
#include "CompilerState.h" |
|||
#include "CodeFragment.h" |
|||
|
|||
using namespace std; |
|||
using namespace eth; |
|||
|
|||
bytes eth::compileLLL(string const& _s, vector<string>* _errors) |
|||
{ |
|||
try |
|||
{ |
|||
CompilerState cs; |
|||
bytes ret = CodeFragment::compile(_s, cs).code(); |
|||
for (auto i: cs.treesToKill) |
|||
killBigints(i); |
|||
return ret; |
|||
} |
|||
catch (Exception const& _e) |
|||
{ |
|||
if (_errors) |
|||
_errors->push_back(_e.description()); |
|||
} |
|||
catch (std::exception) |
|||
{ |
|||
if (_errors) |
|||
_errors->push_back("Parse error."); |
|||
} |
|||
return bytes(); |
|||
} |
|||
|
|||
string eth::parseLLL(string const& _src) |
|||
{ |
|||
sp::utree o; |
|||
parseTreeLLL(_src, o); |
|||
ostringstream ret; |
|||
debugOutAST(ret, o); |
|||
killBigints(o); |
|||
return ret.str(); |
|||
} |
@ -0,0 +1,35 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file Compiler.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <string> |
|||
#include <vector> |
|||
#include <libethsupport/Common.h> |
|||
|
|||
namespace eth |
|||
{ |
|||
|
|||
std::string parseLLL(std::string const& _src); |
|||
bytes compileLLL(std::string const& _s, std::vector<std::string>* _errors = nullptr); |
|||
|
|||
} |
|||
|
@ -0,0 +1,37 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file CompilerState.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "CompilerState.h" |
|||
|
|||
using namespace std; |
|||
using namespace eth; |
|||
|
|||
CodeFragment const& CompilerState::getDef(std::string const& _s) |
|||
{ |
|||
if (defs.count(_s)) |
|||
return defs.at(_s); |
|||
else if (args.count(_s)) |
|||
return args.at(_s); |
|||
else if (outers.count(_s)) |
|||
return outers.at(_s); |
|||
else |
|||
return NullCodeFragment; |
|||
} |
@ -0,0 +1,49 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file CompilerState.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <boost/spirit/include/support_utree.hpp> |
|||
#include "CodeFragment.h" |
|||
|
|||
namespace eth |
|||
{ |
|||
|
|||
struct Macro |
|||
{ |
|||
std::vector<std::string> args; |
|||
boost::spirit::utree code; |
|||
std::map<std::string, CodeFragment> env; |
|||
}; |
|||
|
|||
struct CompilerState |
|||
{ |
|||
CodeFragment const& getDef(std::string const& _s); |
|||
|
|||
std::map<std::string, unsigned> vars; |
|||
std::map<std::string, CodeFragment> defs; |
|||
std::map<std::string, CodeFragment> args; |
|||
std::map<std::string, CodeFragment> outers; |
|||
std::map<std::string, Macro> macros; |
|||
std::vector<boost::spirit::utree> treesToKill; |
|||
}; |
|||
|
|||
} |
@ -0,0 +1,91 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file Parser.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "Parser.h" |
|||
|
|||
#include <boost/spirit/include/qi.hpp> |
|||
#include <boost/spirit/include/phoenix.hpp> |
|||
#include <boost/spirit/include/support_utree.hpp> |
|||
#include <libethcore/CommonEth.h> |
|||
|
|||
using namespace std; |
|||
using namespace eth; |
|||
namespace qi = boost::spirit::qi; |
|||
namespace px = boost::phoenix; |
|||
namespace sp = boost::spirit; |
|||
|
|||
void eth::killBigints(sp::utree const& _this) |
|||
{ |
|||
switch (_this.which()) |
|||
{ |
|||
case sp::utree_type::list_type: for (auto const& i: _this) killBigints(i); break; |
|||
case sp::utree_type::any_type: delete _this.get<bigint*>(); break; |
|||
default:; |
|||
} |
|||
} |
|||
|
|||
void eth::parseTreeLLL(string const& _s, sp::utree& o_out) |
|||
{ |
|||
using qi::ascii::space; |
|||
typedef sp::basic_string<std::string, sp::utree_type::symbol_type> symbol_type; |
|||
typedef string::const_iterator it; |
|||
|
|||
qi::rule<it, qi::ascii::space_type, sp::utree()> element; |
|||
qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"'; |
|||
qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;())") + '\0'))]; |
|||
qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" @[]{}:();\"\x01-\x1f\x7f") + '\0'))]; |
|||
qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> *qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]]; |
|||
qi::rule<it, bigint()> integer = intstr; |
|||
qi::rule<it, bigint()> multiplier = qi::lit("wei")[qi::_val = 1] | qi::lit("szabo")[qi::_val = szabo] | qi::lit("finney")[qi::_val = finney] | qi::lit("ether")[qi::_val = ether]; |
|||
qi::rule<it, qi::ascii::space_type, bigint()> quantity = integer[qi::_val = qi::_1] >> -multiplier[qi::_val *= qi::_1]; |
|||
qi::rule<it, qi::ascii::space_type, sp::utree()> atom = quantity[qi::_val = px::construct<sp::any_ptr>(px::new_<bigint>(qi::_1))] | (str | strsh)[qi::_val = qi::_1] | symbol[qi::_val = qi::_1]; |
|||
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> seq = '{' > *element > '}'; |
|||
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> mload = '@' > element; |
|||
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sload = qi::lit("@@") > element; |
|||
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element; |
|||
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element; |
|||
qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 2)] | mload[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 1)] | sstore[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 4)] | mstore[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 3)] | seq[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 5)]; |
|||
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> list = '(' > *element > ')'; |
|||
element = atom | list | extra; |
|||
|
|||
string s; |
|||
s.reserve(_s.size()); |
|||
bool incomment = false; |
|||
bool instring = false; |
|||
bool insstring = false; |
|||
for (auto i: _s) |
|||
{ |
|||
if (i == ';' && !instring && !insstring) |
|||
incomment = true; |
|||
else if (i == '\n') |
|||
incomment = instring = insstring = false; |
|||
else if (i == '"' && !insstring) |
|||
instring = !instring; |
|||
else if (i == '\'') |
|||
insstring = true; |
|||
else if (i == ' ') |
|||
insstring = false; |
|||
if (!incomment) |
|||
s.push_back(i); |
|||
} |
|||
qi::phrase_parse(s.cbegin(), s.cend(), element, space, o_out); |
|||
} |
|||
|
@ -0,0 +1,38 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file Parser.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <string> |
|||
#include <vector> |
|||
#include <libethsupport/Common.h> |
|||
|
|||
namespace boost { namespace spirit { class utree; } } |
|||
namespace sp = boost::spirit; |
|||
|
|||
namespace eth |
|||
{ |
|||
|
|||
void killBigints(sp::utree const& _this); |
|||
void parseTreeLLL(std::string const& _s, sp::utree& o_out); |
|||
|
|||
} |
|||
|
@ -0,0 +1,56 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
|
|||
aux_source_directory(. SRC_LIST) |
|||
|
|||
include_directories(..) |
|||
#link_directories(../libethsupport) |
|||
#link_directories(../libethcore) |
|||
#link_directories(../liblll) |
|||
|
|||
set(EXECUTABLE lllc) |
|||
|
|||
add_executable(${EXECUTABLE} ${SRC_LIST}) |
|||
|
|||
if (JSONRPC_LS) |
|||
add_definitions(-DETH_JSONRPC) |
|||
include_directories(${JSONRPC_ID}) |
|||
target_link_libraries(${EXECUTABLE} ${JSONRPC_LS}) |
|||
endif () |
|||
|
|||
if (READLINE_LS) |
|||
add_definitions(-DETH_READLINE) |
|||
include_directories(${READLINE_ID}) |
|||
target_link_libraries(${EXECUTABLE} ${READLINE_LS}) |
|||
endif () |
|||
|
|||
if (${TARGET_PLATFORM} STREQUAL "w64") |
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") |
|||
target_link_libraries(${EXECUTABLE} gcc) |
|||
target_link_libraries(${EXECUTABLE} gdi32) |
|||
target_link_libraries(${EXECUTABLE} ws2_32) |
|||
target_link_libraries(${EXECUTABLE} mswsock) |
|||
target_link_libraries(${EXECUTABLE} shlwapi) |
|||
target_link_libraries(${EXECUTABLE} iphlpapi) |
|||
target_link_libraries(${EXECUTABLE} cryptopp) |
|||
target_link_libraries(${EXECUTABLE} boost_system-mt-s) |
|||
target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) |
|||
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) |
|||
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) |
|||
elseif (UNIX) |
|||
else () |
|||
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) |
|||
target_link_libraries(${EXECUTABLE} boost_system) |
|||
target_link_libraries(${EXECUTABLE} boost_filesystem) |
|||
find_package(Threads REQUIRED) |
|||
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) |
|||
endif () |
|||
|
|||
target_link_libraries(${EXECUTABLE} lll) |
|||
target_link_libraries(${EXECUTABLE} ethcore) |
|||
target_link_libraries(${EXECUTABLE} ethsupport) |
|||
target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) |
|||
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) |
|||
target_link_libraries(${EXECUTABLE} gmp) |
|||
|
|||
install( TARGETS ${EXECUTABLE} DESTINATION bin ) |
|||
|
@ -0,0 +1,106 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file main.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* Ethereum client. |
|||
*/ |
|||
|
|||
#include <fstream> |
|||
#include <iostream> |
|||
#include <liblll/Compiler.h> |
|||
#include <libethsupport/CommonIO.h> |
|||
#include <libethsupport/CommonData.h> |
|||
#include "BuildInfo.h" |
|||
using namespace std; |
|||
using namespace eth; |
|||
|
|||
void help() |
|||
{ |
|||
cout |
|||
<< "Usage lllc [OPTIONS] <file>" << endl |
|||
<< "Options:" << endl |
|||
<< " -h,--help Show this help message and exit." << endl |
|||
<< " -V,--version Show the version and exit." << endl; |
|||
exit(0); |
|||
} |
|||
|
|||
void version() |
|||
{ |
|||
cout << "LLLC, the Lovely Little Language Compiler " << ETH_QUOTED(ETH_VERSION) << endl; |
|||
cout << " By Gav Wood, (c) 2014." << endl; |
|||
cout << "Build: " << ETH_QUOTED(ETH_BUILD_PLATFORM) << "/" << ETH_QUOTED(ETH_BUILD_TYPE) << endl; |
|||
exit(0); |
|||
} |
|||
|
|||
enum Mode { Binary, Hex, ParseTree }; |
|||
|
|||
int main(int argc, char** argv) |
|||
{ |
|||
string infile; |
|||
Mode mode = Hex; |
|||
|
|||
for (int i = 1; i < argc; ++i) |
|||
{ |
|||
string arg = argv[i]; |
|||
if (arg == "-h" || arg == "--help") |
|||
help(); |
|||
else if (arg == "-b" || arg == "--binary") |
|||
mode = Binary; |
|||
else if (arg == "-h" || arg == "--hex") |
|||
mode = Hex; |
|||
else if (arg == "-t" || arg == "--parse-tree") |
|||
mode = ParseTree; |
|||
else if (arg == "-V" || arg == "--version") |
|||
version(); |
|||
else |
|||
infile = argv[i]; |
|||
} |
|||
|
|||
string src; |
|||
if (infile.empty()) |
|||
{ |
|||
string s; |
|||
while (!cin.eof()) |
|||
{ |
|||
getline(cin, s); |
|||
src.append(s); |
|||
} |
|||
} |
|||
else |
|||
src = asString(contents(infile)); |
|||
|
|||
if (src.empty()) |
|||
cerr << "Empty file." << endl; |
|||
else if (mode == Binary || mode == Hex) |
|||
{ |
|||
vector<string> errors; |
|||
auto bs = compileLLL(src, &errors); |
|||
if (mode == Hex) |
|||
cout << toHex(bs) << endl; |
|||
else if (mode == Binary) |
|||
cout.write((char const*)bs.data(), bs.size()); |
|||
for (auto const& i: errors) |
|||
cerr << i << endl; |
|||
} |
|||
else if (mode == ParseTree) |
|||
{ |
|||
cout << parseLLL(src) << endl; |
|||
} |
|||
|
|||
return 0; |
|||
} |
Loading…
Reference in new issue