aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaweł Bylica <pawel.bylica@imapp.pl>2014-11-21 00:15:43 +0800
committerPaweł Bylica <pawel.bylica@imapp.pl>2014-11-21 00:15:43 +0800
commit14366250c513859777046f96cecb41651c70d498 (patch)
tree5699ad27822972c7add956f31f43d844879d40c3
parent07e60499672e4db5054dad15adb4422fe2322006 (diff)
parenta879115143aa61ff13cc914ef8be76e8ee67a6f4 (diff)
downloaddexon-solidity-14366250c513859777046f96cecb41651c70d498.tar.gz
dexon-solidity-14366250c513859777046f96cecb41651c70d498.tar.zst
dexon-solidity-14366250c513859777046f96cecb41651c70d498.zip
Merge branch 'develop' into develop-evmcc
Conflicts: test/vm.cpp
-rw-r--r--TestHelper.cpp1
-rw-r--r--jsonrpc.cpp66
-rw-r--r--recursiveCreateFiller.json35
-rw-r--r--solidityCompiler.cpp2
-rw-r--r--solidityEndToEndTest.cpp226
-rw-r--r--solidityNameAndTypeResolution.cpp38
-rw-r--r--vm.cpp15
-rw-r--r--webthreestubclient.h85
8 files changed, 447 insertions, 21 deletions
diff --git a/TestHelper.cpp b/TestHelper.cpp
index 7f8c519f..31696da0 100644
--- a/TestHelper.cpp
+++ b/TestHelper.cpp
@@ -380,6 +380,7 @@ void executeTests(const string& _name, const string& _testPathAppendix, std::fun
{
BOOST_ERROR("Failed test with Exception: " << _e.what());
}
+ break;
}
}
diff --git a/jsonrpc.cpp b/jsonrpc.cpp
index 4c748a95..d17c5a59 100644
--- a/jsonrpc.cpp
+++ b/jsonrpc.cpp
@@ -237,7 +237,73 @@ BOOST_AUTO_TEST_CASE(jsonrpc_transact)
BOOST_CHECK_EQUAL(jsToDecimal(balanceString2), "750000000000000000");
BOOST_CHECK_EQUAL(txAmount, balance2);
}
+
+
+BOOST_AUTO_TEST_CASE(simple_contract)
+{
+ cnote << "Testing jsonrpc contract...";
+ KeyPair kp = KeyPair::create();
+ web3->ethereum()->setAddress(kp.address());
+ jsonrpcServer->setAccounts({kp});
+
+ dev::eth::mine(*(web3->ethereum()), 1);
+
+ char const* sourceCode = "contract test {\n"
+ " function f(uint a) returns(uint d) { return a * 7; }\n"
+ "}\n";
+
+ string compiled = jsonrpcClient->eth_solidity(sourceCode);
+
+ Json::Value create;
+ create["code"] = compiled;
+ string contractAddress = jsonrpcClient->eth_transact(create);
+ dev::eth::mine(*(web3->ethereum()), 1);
+ Json::Value call;
+ call["to"] = contractAddress;
+ call["data"] = "0x00000000000000000000000000000000000000000000000000000000000000001";
+ string result = jsonrpcClient->eth_call(call);
+ BOOST_CHECK_EQUAL(result, "0x0000000000000000000000000000000000000000000000000000000000000007");
+}
+
+BOOST_AUTO_TEST_CASE(contract_storage)
+{
+ cnote << "Testing jsonrpc contract storage...";
+ KeyPair kp = KeyPair::create();
+ web3->ethereum()->setAddress(kp.address());
+ jsonrpcServer->setAccounts({kp});
+
+ dev::eth::mine(*(web3->ethereum()), 1);
+
+ char const* sourceCode = R"(
+ contract test {
+ uint hello;
+ function writeHello(uint value) returns(bool d){
+ hello = value;
+ return true;
+ }
+ }
+ )";
+
+ string compiled = jsonrpcClient->eth_solidity(sourceCode);
+
+ Json::Value create;
+ create["code"] = compiled;
+ string contractAddress = jsonrpcClient->eth_transact(create);
+ dev::eth::mine(*(web3->ethereum()), 1);
+
+ Json::Value transact;
+ transact["to"] = contractAddress;
+ transact["data"] = "0x00000000000000000000000000000000000000000000000000000000000000003";
+ jsonrpcClient->eth_transact(transact);
+ dev::eth::mine(*(web3->ethereum()), 1);
+
+ Json::Value storage = jsonrpcClient->eth_storageAt(contractAddress);
+ BOOST_CHECK_EQUAL(storage.getMemberNames().size(), 1);
+ for (auto name: storage.getMemberNames())
+ BOOST_CHECK_EQUAL(storage[name].asString(), "0x03");
+}
+
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE_END()
diff --git a/recursiveCreateFiller.json b/recursiveCreateFiller.json
new file mode 100644
index 00000000..0d18fb7a
--- /dev/null
+++ b/recursiveCreateFiller.json
@@ -0,0 +1,35 @@
+{
+ "recursiveCreate": {
+ "env": {
+ "previousHash": "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+ "currentNumber": "0",
+ "currentGasLimit": "10000000",
+ "currentDifficulty": "256",
+ "currentTimestamp": 1,
+ "currentCoinbase": "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+ },
+ "pre": {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87": {
+ "balance": "20000000",
+ "nonce": 0,
+ "code": "{(CODECOPY 0 0 32)(CREATE 0 0 32)}",
+ "storage": {}
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
+ "balance": "1000000000000000000",
+ "nonce": 0,
+ "code": "",
+ "storage": {}
+ }
+ },
+ "transaction": {
+ "nonce": "0",
+ "gasPrice": "1",
+ "gasLimit": "465224",
+ "to": "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value": "100000",
+ "secretKey": "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "data": ""
+ }
+ }
+}
diff --git a/solidityCompiler.cpp b/solidityCompiler.cpp
index 054ad329..e0635b6a 100644
--- a/solidityCompiler.cpp
+++ b/solidityCompiler.cpp
@@ -128,8 +128,6 @@ BOOST_AUTO_TEST_CASE(different_argument_numbers)
byte(Instruction::JUMP),
byte(Instruction::JUMPDEST),
// stack here: ret e h f(1,2,3)
- byte(Instruction::DUP2),
- byte(Instruction::POP),
byte(Instruction::SWAP1),
// stack here: ret e f(1,2,3) h
byte(Instruction::POP),
diff --git a/solidityEndToEndTest.cpp b/solidityEndToEndTest.cpp
index d905646c..4e68103a 100644
--- a/solidityEndToEndTest.cpp
+++ b/solidityEndToEndTest.cpp
@@ -32,6 +32,9 @@ using namespace std;
namespace dev
{
+/// Provider another overload for toBigEndian to encode arguments and return values.
+inline bytes toBigEndian(bool _value) { return bytes({byte(_value)}); }
+
namespace solidity
{
namespace test
@@ -137,6 +140,7 @@ private:
m_output = executive.out().toVector();
}
+protected:
Address m_contractAddress;
eth::State m_state;
u256 const m_gasPrice = 100 * eth::szabo;
@@ -496,6 +500,228 @@ BOOST_AUTO_TEST_CASE(state_smoke_test)
BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0x3)));
}
+BOOST_AUTO_TEST_CASE(simple_mapping)
+{
+ char const* sourceCode = "contract test {\n"
+ " mapping(uint8 => uint8) table;\n"
+ " function get(uint8 k) returns (uint8 v) {\n"
+ " return table[k];\n"
+ " }\n"
+ " function set(uint8 k, uint8 v) {\n"
+ " table[k] = v;\n"
+ " }\n"
+ "}";
+ compileAndRun(sourceCode);
+
+ BOOST_CHECK(callContractFunction(0, bytes({0x00})) == bytes({0x00}));
+ BOOST_CHECK(callContractFunction(0, bytes({0x01})) == bytes({0x00}));
+ BOOST_CHECK(callContractFunction(0, bytes({0xa7})) == bytes({0x00}));
+ callContractFunction(1, bytes({0x01, 0xa1}));
+ BOOST_CHECK(callContractFunction(0, bytes({0x00})) == bytes({0x00}));
+ BOOST_CHECK(callContractFunction(0, bytes({0x01})) == bytes({0xa1}));
+ BOOST_CHECK(callContractFunction(0, bytes({0xa7})) == bytes({0x00}));
+ callContractFunction(1, bytes({0x00, 0xef}));
+ BOOST_CHECK(callContractFunction(0, bytes({0x00})) == bytes({0xef}));
+ BOOST_CHECK(callContractFunction(0, bytes({0x01})) == bytes({0xa1}));
+ BOOST_CHECK(callContractFunction(0, bytes({0xa7})) == bytes({0x00}));
+ callContractFunction(1, bytes({0x01, 0x05}));
+ BOOST_CHECK(callContractFunction(0, bytes({0x00})) == bytes({0xef}));
+ BOOST_CHECK(callContractFunction(0, bytes({0x01})) == bytes({0x05}));
+ BOOST_CHECK(callContractFunction(0, bytes({0xa7})) == bytes({0x00}));
+}
+
+BOOST_AUTO_TEST_CASE(mapping_state)
+{
+ char const* sourceCode = "contract Ballot {\n"
+ " mapping(address => bool) canVote;\n"
+ " mapping(address => uint) voteCount;\n"
+ " mapping(address => bool) voted;\n"
+ " function getVoteCount(address addr) returns (uint retVoteCount) {\n"
+ " return voteCount[addr];\n"
+ " }\n"
+ " function grantVoteRight(address addr) {\n"
+ " canVote[addr] = true;\n"
+ " }\n"
+ " function vote(address voter, address vote) returns (bool success) {\n"
+ " if (!canVote[voter] || voted[voter]) return false;\n"
+ " voted[voter] = true;\n"
+ " voteCount[vote] = voteCount[vote] + 1;\n"
+ " return true;\n"
+ " }\n"
+ "}\n";
+ compileAndRun(sourceCode);
+ class Ballot
+ {
+ public:
+ u256 getVoteCount(u160 _address) { return m_voteCount[_address]; }
+ void grantVoteRight(u160 _address) { m_canVote[_address] = true; }
+ bool vote(u160 _voter, u160 _vote)
+ {
+ if (!m_canVote[_voter] || m_voted[_voter]) return false;
+ m_voted[_voter] = true;
+ m_voteCount[_vote]++;
+ return true;
+ }
+ private:
+ map<u160, bool> m_canVote;
+ map<u160, u256> m_voteCount;
+ map<u160, bool> m_voted;
+ } ballot;
+
+ auto getVoteCount = bind(&Ballot::getVoteCount, &ballot, _1);
+ auto grantVoteRight = bind(&Ballot::grantVoteRight, &ballot, _1);
+ auto vote = bind(&Ballot::vote, &ballot, _1, _2);
+ testSolidityAgainstCpp(0, getVoteCount, u160(0));
+ testSolidityAgainstCpp(0, getVoteCount, u160(1));
+ testSolidityAgainstCpp(0, getVoteCount, u160(2));
+ // voting without vote right shourd be rejected
+ testSolidityAgainstCpp(2, vote, u160(0), u160(2));
+ testSolidityAgainstCpp(0, getVoteCount, u160(0));
+ testSolidityAgainstCpp(0, getVoteCount, u160(1));
+ testSolidityAgainstCpp(0, getVoteCount, u160(2));
+ // grant vote rights
+ testSolidityAgainstCpp(1, grantVoteRight, u160(0));
+ testSolidityAgainstCpp(1, grantVoteRight, u160(1));
+ // vote, should increase 2's vote count
+ testSolidityAgainstCpp(2, vote, u160(0), u160(2));
+ testSolidityAgainstCpp(0, getVoteCount, u160(0));
+ testSolidityAgainstCpp(0, getVoteCount, u160(1));
+ testSolidityAgainstCpp(0, getVoteCount, u160(2));
+ // vote again, should be rejected
+ testSolidityAgainstCpp(2, vote, u160(0), u160(1));
+ testSolidityAgainstCpp(0, getVoteCount, u160(0));
+ testSolidityAgainstCpp(0, getVoteCount, u160(1));
+ testSolidityAgainstCpp(0, getVoteCount, u160(2));
+ // vote without right to vote
+ testSolidityAgainstCpp(2, vote, u160(2), u160(1));
+ testSolidityAgainstCpp(0, getVoteCount, u160(0));
+ testSolidityAgainstCpp(0, getVoteCount, u160(1));
+ testSolidityAgainstCpp(0, getVoteCount, u160(2));
+ // grant vote right and now vote again
+ testSolidityAgainstCpp(1, grantVoteRight, u160(2));
+ testSolidityAgainstCpp(2, vote, u160(2), u160(1));
+ testSolidityAgainstCpp(0, getVoteCount, u160(0));
+ testSolidityAgainstCpp(0, getVoteCount, u160(1));
+ testSolidityAgainstCpp(0, getVoteCount, u160(2));
+}
+
+BOOST_AUTO_TEST_CASE(mapping_state_inc_dec)
+{
+ char const* sourceCode = "contract test {\n"
+ " uint value;\n"
+ " mapping(uint => uint) table;\n"
+ " function f(uint x) returns (uint y) {\n"
+ " value = x;\n"
+ " if (x > 0) table[++value] = 8;\n"
+ " if (x > 1) value--;\n"
+ " if (x > 2) table[value]++;\n"
+ " return --table[value++];\n"
+ " }\n"
+ "}\n";
+ compileAndRun(sourceCode);
+
+ u256 value = 0;
+ map<u256, u256> table;
+ auto f = [&](u256 const& _x) -> u256
+ {
+ value = _x;
+ if (_x > 0)
+ table[++value] = 8;
+ if (_x > 1)
+ value --;
+ if (_x > 2)
+ table[value]++;
+ return --table[value++];
+ };
+ testSolidityAgainstCppOnRange(0, f, 0, 5);
+}
+
+BOOST_AUTO_TEST_CASE(multi_level_mapping)
+{
+ char const* sourceCode = "contract test {\n"
+ " mapping(uint => mapping(uint => uint)) table;\n"
+ " function f(uint x, uint y, uint z) returns (uint w) {\n"
+ " if (z == 0) return table[x][y];\n"
+ " else return table[x][y] = z;\n"
+ " }\n"
+ "}\n";
+ compileAndRun(sourceCode);
+
+ map<u256, map<u256, u256>> table;
+ auto f = [&](u256 const& _x, u256 const& _y, u256 const& _z) -> u256
+ {
+ if (_z == 0) return table[_x][_y];
+ else return table[_x][_y] = _z;
+ };
+ testSolidityAgainstCpp(0, f, u256(4), u256(5), u256(0));
+ testSolidityAgainstCpp(0, f, u256(5), u256(4), u256(0));
+ testSolidityAgainstCpp(0, f, u256(4), u256(5), u256(9));
+ testSolidityAgainstCpp(0, f, u256(4), u256(5), u256(0));
+ testSolidityAgainstCpp(0, f, u256(5), u256(4), u256(0));
+ testSolidityAgainstCpp(0, f, u256(5), u256(4), u256(7));
+ testSolidityAgainstCpp(0, f, u256(4), u256(5), u256(0));
+ testSolidityAgainstCpp(0, f, u256(5), u256(4), u256(0));
+}
+
+BOOST_AUTO_TEST_CASE(structs)
+{
+ char const* sourceCode = "contract test {\n"
+ " struct s1 {\n"
+ " uint8 x;\n"
+ " bool y;\n"
+ " }\n"
+ " struct s2 {\n"
+ " uint32 z;\n"
+ " s1 s1data;\n"
+ " mapping(uint8 => s2) recursive;\n"
+ " }\n"
+ " s2 data;\n"
+ " function check() returns (bool ok) {\n"
+ " return data.z == 1 && data.s1data.x == 2 && \n"
+ " data.s1data.y == true && \n"
+ " data.recursive[3].recursive[4].z == 5 && \n"
+ " data.recursive[4].recursive[3].z == 6 && \n"
+ " data.recursive[0].s1data.y == false && \n"
+ " data.recursive[4].z == 9;\n"
+ " }\n"
+ " function set() {\n"
+ " data.z = 1;\n"
+ " data.s1data.x = 2;\n"
+ " data.s1data.y = true;\n"
+ " data.recursive[3].recursive[4].z = 5;\n"
+ " data.recursive[4].recursive[3].z = 6;\n"
+ " data.recursive[0].s1data.y = false;\n"
+ " data.recursive[4].z = 9;\n"
+ " }\n"
+ "}\n";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction(0) == bytes({0x00}));
+ BOOST_CHECK(callContractFunction(1) == bytes());
+ BOOST_CHECK(callContractFunction(0) == bytes({0x01}));
+}
+
+BOOST_AUTO_TEST_CASE(constructor)
+{
+ char const* sourceCode = "contract test {\n"
+ " mapping(uint => uint) data;\n"
+ " function test() {\n"
+ " data[7] = 8;\n"
+ " }\n"
+ " function get(uint key) returns (uint value) {\n"
+ " return data[key];"
+ " }\n"
+ "}\n";
+ compileAndRun(sourceCode);
+ map<u256, byte> data;
+ data[7] = 8;
+ auto get = [&](u256 const& _x) -> u256
+ {
+ return data[_x];
+ };
+ testSolidityAgainstCpp(0, get, u256(6));
+ testSolidityAgainstCpp(0, get, u256(7));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/solidityNameAndTypeResolution.cpp b/solidityNameAndTypeResolution.cpp
index f46ad673..930bba0e 100644
--- a/solidityNameAndTypeResolution.cpp
+++ b/solidityNameAndTypeResolution.cpp
@@ -121,6 +121,44 @@ BOOST_AUTO_TEST_CASE(reference_to_later_declaration)
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
+BOOST_AUTO_TEST_CASE(struct_definition_directly_recursive)
+{
+ char const* text = "contract test {\n"
+ " struct MyStructName {\n"
+ " address addr;\n"
+ " MyStructName x;\n"
+ " }\n"
+ "}\n";
+ BOOST_CHECK_THROW(parseTextAndResolveNames(text), ParserError);
+}
+
+BOOST_AUTO_TEST_CASE(struct_definition_indirectly_recursive)
+{
+ char const* text = "contract test {\n"
+ " struct MyStructName1 {\n"
+ " address addr;\n"
+ " uint256 count;\n"
+ " MyStructName2 x;\n"
+ " }\n"
+ " struct MyStructName2 {\n"
+ " MyStructName1 x;\n"
+ " }\n"
+ "}\n";
+ BOOST_CHECK_THROW(parseTextAndResolveNames(text), ParserError);
+}
+
+BOOST_AUTO_TEST_CASE(struct_definition_recursion_via_mapping)
+{
+ char const* text = "contract test {\n"
+ " struct MyStructName1 {\n"
+ " address addr;\n"
+ " uint256 count;\n"
+ " mapping(uint => MyStructName1) x;\n"
+ " }\n"
+ "}\n";
+ BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
+}
+
BOOST_AUTO_TEST_CASE(type_inference_smoke_test)
{
char const* text = "contract test {\n"
diff --git a/vm.cpp b/vm.cpp
index 67f08837..03e03566 100644
--- a/vm.cpp
+++ b/vm.cpp
@@ -310,6 +310,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
auto startTime = std::chrono::high_resolution_clock::now();
u256 gas;
+ bool vmExceptionOccured = false;
try
{
output = vm->go(fev, fev.simpleTrace()).toVector();
@@ -323,7 +324,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
catch (VMException const& _e)
{
cnote << "VM did throw an exception: " << diagnostic_information(_e);
- gas = 0;
+ vmExceptionOccured = true;
}
catch (Exception const& _e)
{
@@ -370,13 +371,20 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
{
o["env"] = mValue(fev.exportEnv());
o["exec"] = mValue(fev.exportExec());
+ if (!vmExceptionOccured)
+ {
o["post"] = mValue(fev.exportState());
o["callcreates"] = fev.exportCallCreates();
o["out"] = "0x" + toHex(output);
fev.push(o, "gas", gas);
}
+ }
else
{
+ if (o.count("post") > 0) // No exceptions expected
+ {
+ BOOST_CHECK(!vmExceptionOccured);
+
BOOST_REQUIRE(o.count("post") > 0);
BOOST_REQUIRE(o.count("callcreates") > 0);
BOOST_REQUIRE(o.count("out") > 0);
@@ -388,7 +396,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
checkOutput(output, o);
- BOOST_CHECK_EQUAL(toInt(o["gas"]), gas);
+ BOOST_CHECK_EQUAL(toInt(o["gas"]), gas);
if (outOfGas)
BOOST_CHECK_MESSAGE(gas == 0, "Remaining gas not 0 in out-of-gas state");
@@ -416,6 +424,9 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
checkAddresses<std::map<Address, std::tuple<u256, u256, std::map<u256, u256>, bytes> > >(test.addresses, fev.addresses);
BOOST_CHECK(test.callcreates == fev.callcreates);
}
+ else // Exception expected
+ BOOST_CHECK(vmExceptionOccured);
+ }
}
}
diff --git a/webthreestubclient.h b/webthreestubclient.h
index 179c620a..f5fee4c0 100644
--- a/webthreestubclient.h
+++ b/webthreestubclient.h
@@ -179,14 +179,13 @@ p.append(param3);
}
- std::string eth_compile(const std::string& param1) throw (jsonrpc::JsonRpcException)
+ Json::Value eth_compilers() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
- p.append(param1);
-
- Json::Value result = this->client->CallMethod("eth_compile",p);
- if (result.isString())
- return result.asString();
+ p = Json::nullValue;
+ Json::Value result = this->client->CallMethod("eth_compilers",p);
+ if (result.isArray())
+ return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
@@ -217,26 +216,26 @@ p.append(param3);
}
- std::string eth_gasPrice() throw (jsonrpc::JsonRpcException)
+ Json::Value eth_filterLogs(const int& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
- p = Json::nullValue;
- Json::Value result = this->client->CallMethod("eth_gasPrice",p);
- if (result.isString())
- return result.asString();
+ p.append(param1);
+
+ Json::Value result = this->client->CallMethod("eth_filterLogs",p);
+ if (result.isArray())
+ return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
- Json::Value eth_getMessages(const int& param1) throw (jsonrpc::JsonRpcException)
+ std::string eth_gasPrice() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
- p.append(param1);
-
- Json::Value result = this->client->CallMethod("eth_getMessages",p);
- if (result.isArray())
- return result;
+ p = Json::nullValue;
+ Json::Value result = this->client->CallMethod("eth_gasPrice",p);
+ if (result.isString())
+ return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
@@ -267,6 +266,19 @@ p.append(param3);
}
+ Json::Value eth_logs(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
+ {
+ Json::Value p;
+ p.append(param1);
+
+ Json::Value result = this->client->CallMethod("eth_logs",p);
+ if (result.isArray())
+ return result;
+ else
+ throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
+
+ }
+
bool eth_mining() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
@@ -329,6 +341,19 @@ p.append(param3);
}
+ std::string eth_serpent(const std::string& param1) throw (jsonrpc::JsonRpcException)
+ {
+ Json::Value p;
+ p.append(param1);
+
+ Json::Value result = this->client->CallMethod("eth_serpent",p);
+ if (result.isString())
+ return result.asString();
+ else
+ throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
+
+ }
+
bool eth_setCoinbase(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
@@ -381,6 +406,19 @@ p.append(param3);
}
+ std::string eth_solidity(const std::string& param1) throw (jsonrpc::JsonRpcException)
+ {
+ Json::Value p;
+ p.append(param1);
+
+ Json::Value result = this->client->CallMethod("eth_solidity",p);
+ if (result.isString())
+ return result.asString();
+ else
+ throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
+
+ }
+
std::string eth_stateAt(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
@@ -395,6 +433,19 @@ p.append(param2);
}
+ Json::Value eth_storageAt(const std::string& param1) throw (jsonrpc::JsonRpcException)
+ {
+ Json::Value p;
+ p.append(param1);
+
+ Json::Value result = this->client->CallMethod("eth_storageAt",p);
+ if (result.isObject())
+ return result;
+ else
+ throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
+
+ }
+
std::string eth_transact(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;