diff --git a/eth/main.cpp b/eth/main.cpp index 49eac8876..1520e86c4 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -441,9 +441,8 @@ int main(int argc, char** argv) #endif else if (cmd == "address") { - cout << "Current address:" << endl; - const char* addchr = toHex(us.address().asArray()).c_str(); - cout << addchr << endl; + cout << "Current address:" << endl + << toHex(us.address().asArray()) << endl; } else if (cmd == "secret") { diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 3beb423de..f872e0581 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -194,7 +194,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) else { FunctionType const& function = dynamic_cast(*_functionCall.getExpression().getType()); - std::vector> arguments = _functionCall.getArguments(); + vector> arguments = _functionCall.getArguments(); if (asserts(arguments.size() == function.getParameterTypes().size())) BOOST_THROW_EXCEPTION(InternalCompilerError()); @@ -227,50 +227,23 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) break; } case Location::EXTERNAL: + case Location::BARE: { - unsigned dataOffset = 1; // reserve one byte for the function index - for (unsigned i = 0; i < arguments.size(); ++i) - { - arguments[i]->accept(*this); - Type const& type = *function.getParameterTypes()[i]; - appendTypeConversion(*arguments[i]->getType(), type); - unsigned const numBytes = type.getCalldataEncodedSize(); - if (numBytes == 0 || numBytes > 32) - BOOST_THROW_EXCEPTION(CompilerError() - << errinfo_sourceLocation(arguments[i]->getLocation()) - << errinfo_comment("Type " + type.toString() + " not yet supported.")); - bool const leftAligned = type.getCategory() == Type::Category::STRING; - CompilerUtils(m_context).storeInMemory(dataOffset, numBytes, leftAligned); - dataOffset += numBytes; - } - //@todo only return the first return value for now - Type const* firstType = function.getReturnParameterTypes().empty() ? nullptr : - function.getReturnParameterTypes().front().get(); - unsigned retSize = firstType ? firstType->getCalldataEncodedSize() : 0; - // CALL arguments: outSize, outOff, inSize, inOff, value, addr, gas (stack top) - m_context << u256(retSize) << u256(0) << u256(dataOffset) << u256(0) << u256(0); - _functionCall.getExpression().accept(*this); // pushes addr and function index - m_context << u256(0) << eth::Instruction::MSTORE8 - << u256(25) << eth::Instruction::GAS << eth::Instruction::SUB - << eth::Instruction::CALL - << eth::Instruction::POP; // @todo do not ignore failure indicator - if (retSize > 0) - { - bool const leftAligned = firstType->getCategory() == Type::Category::STRING; - CompilerUtils(m_context).loadFromMemory(0, retSize, leftAligned); - } + FunctionCallOptions options; + options.bare = function.getLocation() == Location::BARE; + options.obtainAddress = [&]() { _functionCall.getExpression().accept(*this); }; + appendExternalFunctionCall(function, arguments, options); break; } case Location::SEND: - m_context << u256(0) << u256(0) << u256(0) << u256(0); - arguments.front()->accept(*this); - //@todo might not be necessary - appendTypeConversion(*arguments.front()->getType(), *function.getParameterTypes().front(), true); - _functionCall.getExpression().accept(*this); - m_context << u256(25) << eth::Instruction::GAS << eth::Instruction::SUB - << eth::Instruction::CALL - << eth::Instruction::POP; + { + FunctionCallOptions options; + options.bare = true; + options.obtainAddress = [&]() { _functionCall.getExpression().accept(*this); }; + options.obtainValue = [&]() { arguments.front()->accept(*this); }; + appendExternalFunctionCall(FunctionType({}, {}, Location::EXTERNAL), {}, options); break; + } case Location::SUICIDE: arguments.front()->accept(*this); //@todo might not be necessary @@ -292,19 +265,11 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) {Location::SHA256, 2}, {Location::RIPEMD160, 3}}; u256 contractAddress = contractAddresses.find(function.getLocation())->second; - // @todo later, combine this code with external function call - for (unsigned i = 0; i < arguments.size(); ++i) - { - arguments[i]->accept(*this); - appendTypeConversion(*arguments[i]->getType(), *function.getParameterTypes()[i], true); - // @todo move this once we actually use memory - CompilerUtils(m_context).storeInMemory(i * 32); - } - m_context << u256(32) << u256(0) << u256(arguments.size() * 32) << u256(0) << u256(0) - << contractAddress << u256(500) //@todo determine actual gas requirement - << eth::Instruction::CALL - << eth::Instruction::POP; - CompilerUtils(m_context).loadFromMemory(0); + FunctionCallOptions options; + options.bare = true; + options.obtainAddress = [&]() { m_context << contractAddress; }; + options.packDensely = false; + appendExternalFunctionCall(function, arguments, options); break; } default: @@ -326,11 +291,9 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) IntegerType(0, IntegerType::Modifier::ADDRESS), true); m_context << eth::Instruction::BALANCE; } - else if (member == "send") - { + else if (member == "send" || member.substr(0, min(member.size(), 4)) == "call") appendTypeConversion(*_memberAccess.getExpression().getType(), IntegerType(0, IntegerType::Modifier::ADDRESS), true); - } else BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid member access to integer.")); break; @@ -587,6 +550,53 @@ void ExpressionCompiler::appendHighBitsCleanup(IntegerType const& _typeOnStack) m_context << ((u256(1) << _typeOnStack.getNumBits()) - 1) << eth::Instruction::AND; } +void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functionType, + vector> const& _arguments, + FunctionCallOptions const& _options) +{ + if (asserts(_arguments.size() == _functionType.getParameterTypes().size())) + BOOST_THROW_EXCEPTION(InternalCompilerError()); + + unsigned dataOffset = _options.bare ? 0 : 1; // reserve one byte for the function index + for (unsigned i = 0; i < _arguments.size(); ++i) + { + _arguments[i]->accept(*this); + Type const& type = *_functionType.getParameterTypes()[i]; + appendTypeConversion(*_arguments[i]->getType(), type); + unsigned const numBytes = _options.packDensely ? type.getCalldataEncodedSize() : 32; + if (numBytes == 0 || numBytes > 32) + BOOST_THROW_EXCEPTION(CompilerError() + << errinfo_sourceLocation(_arguments[i]->getLocation()) + << errinfo_comment("Type " + type.toString() + " not yet supported.")); + bool const leftAligned = type.getCategory() == Type::Category::STRING; + CompilerUtils(m_context).storeInMemory(dataOffset, numBytes, leftAligned); + dataOffset += numBytes; + } + //@todo only return the first return value for now + Type const* firstType = _functionType.getReturnParameterTypes().empty() ? nullptr : + _functionType.getReturnParameterTypes().front().get(); + unsigned retSize = firstType ? firstType->getCalldataEncodedSize() : 0; + if (!_options.packDensely && retSize > 0) + retSize = 32; + // CALL arguments: outSize, outOff, inSize, inOff, value, addr, gas (stack top) + m_context << u256(retSize) << u256(0) << u256(dataOffset) << u256(0); + if (_options.obtainValue) + _options.obtainValue(); + else + m_context << u256(0); + _options.obtainAddress(); + if (!_options.bare) + m_context << u256(0) << eth::Instruction::MSTORE8; + m_context << u256(25) << eth::Instruction::GAS << eth::Instruction::SUB + << eth::Instruction::CALL + << eth::Instruction::POP; // @todo do not ignore failure indicator + if (retSize > 0) + { + bool const leftAligned = firstType->getCategory() == Type::Category::STRING; + CompilerUtils(m_context).loadFromMemory(0, retSize, leftAligned); + } +} + ExpressionCompiler::LValue::LValue(CompilerContext& _compilerContext, LValueType _type, Type const& _dataType, unsigned _baseStackOffset): m_context(&_compilerContext), m_type(_type), m_baseStackOffset(_baseStackOffset), diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h index c0b173d46..0bba211ce 100644 --- a/libsolidity/ExpressionCompiler.h +++ b/libsolidity/ExpressionCompiler.h @@ -20,6 +20,7 @@ * Solidity AST to EVM bytecode compiler for expressions. */ +#include #include #include #include @@ -83,6 +84,25 @@ private: //// Appends code that cleans higher-order bits for integer types. void appendHighBitsCleanup(IntegerType const& _typeOnStack); + /// Additional options used in appendExternalFunctionCall. + struct FunctionCallOptions + { + FunctionCallOptions() {} + /// Invoked to copy the address to the stack + std::function obtainAddress; + /// Invoked to copy the ethe value to the stack (if not specified, value is 0). + std::function obtainValue; + /// If true, do not prepend function index to call data + bool bare = false; + /// If false, use calling convention that all arguments and return values are packed as + /// 32 byte values with padding. + bool packDensely = true; + }; + + /// Appends code to call a function of the given type with the given arguments. + void appendExternalFunctionCall(FunctionType const& _functionType, std::vector> const& _arguments, + FunctionCallOptions const& _options = FunctionCallOptions()); + /** * Helper class to store and retrieve lvalues to and from various locations. * All types except STACK store a reference in a slot on the stack, STACK just diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 00e530c3f..c2d488418 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -193,9 +193,18 @@ u256 IntegerType::literalValue(Literal const& _literal) const } const MemberList IntegerType::AddressMemberList = - MemberList({{"balance", make_shared(256)}, - {"send", make_shared(TypePointers({make_shared(256)}), - TypePointers(), FunctionType::Location::SEND)}}); + MemberList({{"balance", + make_shared(256)}, + {"callstring32", + make_shared(TypePointers({make_shared(32)}), + TypePointers(), FunctionType::Location::BARE)}, + {"callstring32string32", + make_shared(TypePointers({make_shared(32), + make_shared(32)}), + TypePointers(), FunctionType::Location::BARE)}, + {"send", + make_shared(TypePointers({make_shared(256)}), + TypePointers(), FunctionType::Location::SEND)}}); shared_ptr StaticStringType::smallestTypeForLiteral(string const& _literal) { @@ -424,6 +433,8 @@ unsigned FunctionType::getSizeOnStack() const return 1; case Location::EXTERNAL: return 2; + case Location::BARE: + return 1; default: return 0; } diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 8e93bd31d..807e60c74 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -296,8 +296,9 @@ class FunctionType: public Type public: /// The meaning of the value(s) on the stack referencing the function: /// INTERNAL: jump tag, EXTERNAL: contract address + function index, + /// BARE: contract address (non-abi contract call) /// OTHERS: special virtual function, nothing on the stack - enum class Location { INTERNAL, EXTERNAL, SEND, SHA3, SUICIDE, ECRECOVER, SHA256, RIPEMD160 }; + enum class Location { INTERNAL, EXTERNAL, SEND, SHA3, SUICIDE, ECRECOVER, SHA256, RIPEMD160, BARE }; virtual Category getCategory() const override { return Category::FUNCTION; } explicit FunctionType(FunctionDefinition const& _function, bool _isInternal = true); diff --git a/test/stInitCodeTestFiller.json b/test/stInitCodeTestFiller.json new file mode 100644 index 000000000..76d8f7957 --- /dev/null +++ b/test/stInitCodeTestFiller.json @@ -0,0 +1,302 @@ +{ + "TransactionContractCreation" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x600a80600c6000396000f200600160008035811a8100", + "gasLimit" : "599", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "1" + } + }, + + + "NotEnoughCashContractCreation" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "2", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x600a80600c6000396000f200600160008035811a8100", + "gasLimit" : "599", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "1" + } + }, + + "OutOfGasContractCreation" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x600a80600c6000396000f200600160008035811a8100", + "gasLimit" : "590", + "gasPrice" : "3", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "1" + } + }, + + "TransactionSuicideInitCode" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x600a80600c6000396000fff2ffff600160008035811a81", + "gasLimit" : "1000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "1" + } + }, + + "TransactionStopInitCode" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x600a80600c600039600000f20000600160008035811a81", + "gasLimit" : "1000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "1" + } + }, + + "TransactionCreateSuicideContract" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x600a80600c6000396000f200ff600160008035811a81", + "gasLimit" : "1000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "1" + } + }, + + "CallTheContractToCreateEmptyContract" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "balance": "0", + "nonce": 0, + "code": "{(CREATE 0 0 32)}", + "storage": {} + }, + + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x00", + "gasLimit" : "10000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "1" + } + }, + + "CallRecursiveContract" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "balance": "0", + "nonce": 0, + "code": "{[[ 2 ]](ADDRESS)(CODECOPY 0 0 32)(CREATE 0 0 32)}", + "storage": {} + }, + + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x00", + "gasLimit" : "10000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "1" + } + }, + + "CallTheContractToCreateContractWithInitCode" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "balance": "10000", + "nonce": 0, + "code": "{[[ 2 ]](ADDRESS)(CODECOPY 0 0 32)(CREATE 0 0 32)}", + "storage": {} + }, + + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x00", + "gasLimit" : "10000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "1" + } + } +} diff --git a/test/stTransactionTestFiller.json b/test/stTransactionTestFiller.json new file mode 100644 index 000000000..260e7953f --- /dev/null +++ b/test/stTransactionTestFiller.json @@ -0,0 +1,191 @@ +{ + "EmptyTransaction" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "", + "gasPrice" : "", + "nonce" : "", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "" + } + }, + + "TransactionSendingToEmpty" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "1", + "nonce" : "", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "" + } + }, + + + "TransactionSendingToZero" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "1", + "nonce" : "", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000000", + "value" : "1" + } + }, + + + "TransactionToItself" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "1", + "nonce" : "", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "1" + } + }, + + + "TransactionToItselfNotEnoughFounds" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1101", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "600", + "gasPrice" : "1", + "nonce" : "", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "502" + } + }, + + + "TransactionFromCoinbaseNotEnoughFounds" : { + "env" : { + "currentCoinbase" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1100", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "600", + "gasPrice" : "1", + "nonce" : "", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "502" + } + } +} diff --git a/test/state.cpp b/test/state.cpp index e1d5def6a..f183c4813 100644 --- a/test/state.cpp +++ b/test/state.cpp @@ -135,6 +135,11 @@ BOOST_AUTO_TEST_CASE(stRecursiveCreate) dev::test::executeTests("stRecursiveCreate", "/StateTests", dev::test::doStateTests); } +BOOST_AUTO_TEST_CASE(stInitCodeTest) +{ + dev::test::executeTests("stInitCodeTest", "/StateTests", dev::test::doStateTests); +} + BOOST_AUTO_TEST_CASE(stSpecialTest) { dev::test::executeTests("stSpecialTest", "/StateTests", dev::test::doStateTests);