Browse Source

Merge branch 'develop' of https://github.com/ethereum/cpp-ethereum into mix_cm

cl-refactor
arkpar 10 years ago
parent
commit
cde600bdb4
  1. 1
      README.md
  2. 6
      alethzero/Main.ui
  3. 64
      alethzero/MainWin.cpp
  4. 1
      alethzero/MainWin.h
  5. 9
      libdevcrypto/Common.cpp
  6. 2
      libethereum/BlockChain.cpp
  7. 34
      libjsqrc/ethereumjs/dist/ethereum.js
  8. 8
      libjsqrc/ethereumjs/dist/ethereum.js.map
  9. 2
      libjsqrc/ethereumjs/dist/ethereum.min.js
  10. 4
      libjsqrc/ethereumjs/lib/abi.js
  11. 29
      libjsqrc/ethereumjs/lib/contract.js
  12. 1
      libjsqrc/ethereumjs/lib/web3.js
  13. 33
      libsolidity/CompilerStack.cpp
  14. 3
      libsolidity/CompilerStack.h
  15. 43
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  16. 4
      libweb3jsonrpc/WebThreeStubServerBase.h
  17. 6
      libweb3jsonrpc/abstractwebthreestubserver.h
  18. 1
      libweb3jsonrpc/spec.json
  19. 41
      standard.js

1
README.md

@ -6,6 +6,7 @@ By Gav Wood, 2014.
----------|---------|-----|-------- ----------|---------|-----|--------
develop | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20develop%20branch)](http://build.ethdev.com/builders/Linux%20C%2B%2B%20develop%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=OSX%20C%2B%2B%20develop%20branch)](http://build.ethdev.com/builders/OSX%20C%2B%2B%20develop%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Windows%20C%2B%2B%20develop%20branch)](http://build.ethdev.com/builders/Windows%20C%2B%2B%20develop%20branch/builds/-1) develop | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20develop%20branch)](http://build.ethdev.com/builders/Linux%20C%2B%2B%20develop%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=OSX%20C%2B%2B%20develop%20branch)](http://build.ethdev.com/builders/OSX%20C%2B%2B%20develop%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Windows%20C%2B%2B%20develop%20branch)](http://build.ethdev.com/builders/Windows%20C%2B%2B%20develop%20branch/builds/-1)
master | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20master%20branch)](http://build.ethdev.com/builders/Linux%20C%2B%2B%20master%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=OSX%20C%2B%2B%20master%20branch)](http://build.ethdev.com/builders/OSX%20C%2B%2B%20master%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Windows%20C%2B%2B%20master%20branch)](http://build.ethdev.com/builders/Windows%20C%2B%2B%20master%20branch/builds/-1) master | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20master%20branch)](http://build.ethdev.com/builders/Linux%20C%2B%2B%20master%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=OSX%20C%2B%2B%20master%20branch)](http://build.ethdev.com/builders/OSX%20C%2B%2B%20master%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Windows%20C%2B%2B%20master%20branch)](http://build.ethdev.com/builders/Windows%20C%2B%2B%20master%20branch/builds/-1)
evmjit | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20develop%20evmjit)](http://build.ethdev.com/builders/Linux%20C%2B%2B%20develop%20evmjit/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=OSX%20C%2B%2B%20develop%20evmjit)](http://build.ethdev.com/builders/OSX%20C%2B%2B%20develop%20evmjit/builds/-1) | N/A
[![Stories in Ready](https://badge.waffle.io/ethereum/cpp-ethereum.png?label=ready&title=Ready)](http://waffle.io/ethereum/cpp-ethereum) [![Stories in Ready](https://badge.waffle.io/ethereum/cpp-ethereum.png?label=ready&title=Ready)](http://waffle.io/ethereum/cpp-ethereum)

6
alethzero/Main.ui

@ -148,6 +148,7 @@
<addaction name="importKey"/> <addaction name="importKey"/>
<addaction name="importKeyFile"/> <addaction name="importKeyFile"/>
<addaction name="exportKey"/> <addaction name="exportKey"/>
<addaction name="killAccount"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="loadJS"/> <addaction name="loadJS"/>
</widget> </widget>
@ -2067,6 +2068,11 @@ font-size: 14pt</string>
<string>Use &amp;LLVM-EVM</string> <string>Use &amp;LLVM-EVM</string>
</property> </property>
</action> </action>
<action name="killAccount">
<property name="text">
<string>&amp;Kill Account</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<customwidgets> <customwidgets>

64
alethzero/MainWin.cpp

@ -112,7 +112,7 @@ QString contentsOfQResource(string const& res)
} }
//Address c_config = Address("661005d2720d855f1d9976f88bb10c1a3398c77f"); //Address c_config = Address("661005d2720d855f1d9976f88bb10c1a3398c77f");
Address c_newConfig = Address("661005d2720d855f1d9976f88bb10c1a3398c77f"); Address c_newConfig = Address("c6d9d2cd449a754c494264e1809c50e34d64562b");
//Address c_nameReg = Address("ddd1cea741d548f90d86fb87a3ae6492e18c03a1"); //Address c_nameReg = Address("ddd1cea741d548f90d86fb87a3ae6492e18c03a1");
Main::Main(QWidget *parent) : Main::Main(QWidget *parent) :
@ -788,6 +788,7 @@ void Main::on_importKeyFile_triggered()
} }
} }
cnote << k.address();
if (std::find(m_myKeys.begin(), m_myKeys.end(), k) == m_myKeys.end()) if (std::find(m_myKeys.begin(), m_myKeys.end(), k) == m_myKeys.end())
{ {
if (m_myKeys.empty()) if (m_myKeys.empty())
@ -1992,16 +1993,71 @@ bool beginsWith(Address _a, bytes const& _b)
void Main::on_create_triggered() void Main::on_create_triggered()
{ {
bool ok = true; bool ok = true;
QString s = QInputDialog::getText(this, "Special Beginning?", "If you want a special key, enter some hex digits that it should begin with.\nNOTE: The more you enter, the longer generation will take.", QLineEdit::Normal, QString(), &ok); enum { NoVanity = 0, FirstTwo, FirstTwoNextTwo, FirstThree, FirstFour, StringMatch };
QStringList items = {"No vanity (instant)", "Two pairs first (a few seconds)", "Two pairs first and second (a few minutes)", "Three pairs first (a few minutes)", "Four pairs first (several hours)", "Specific hex string"};
unsigned v = items.QList<QString>::indexOf(QInputDialog::getItem(this, "Vanity Key?", "Would you a vanity key? This could take several hours.", items, 0, false, &ok));
if (!ok) if (!ok)
return; return;
bytes bs;
if (v == StringMatch)
{
QString s = QInputDialog::getText(this, "Vanity Beginning?", "Enter some hex digits that it should begin with.\nNOTE: The more you enter, the longer generation will take.", QLineEdit::Normal, QString(), &ok);
if (!ok)
return;
bs = fromHex(s.toStdString());
}
KeyPair p; KeyPair p;
while (!beginsWith(p.address(), asBytes(s.toStdString()))) bool keepGoing = true;
p = KeyPair::create(); unsigned done = 0;
function<void()> f = [&]() {
KeyPair lp;
while (keepGoing)
{
done++;
if (done % 1000 == 0)
cnote << "Tried" << done << "keys";
lp = KeyPair::create();
auto a = lp.address();
if (v == NoVanity ||
(v == FirstTwo && a[0] == a[1]) ||
(v == FirstTwoNextTwo && a[0] == a[1] && a[2] == a[3]) ||
(v == FirstThree && a[0] == a[1] && a[1] == a[2]) ||
(v == FirstFour && a[0] == a[1] && a[1] == a[2] && a[2] == a[3]) ||
(v == StringMatch && beginsWith(lp.address(), bs))
)
break;
}
if (keepGoing)
p = lp;
keepGoing = false;
};
vector<std::thread*> ts;
for (unsigned t = 0; t < std::thread::hardware_concurrency() - 1; ++t)
ts.push_back(new std::thread(f));
f();
for (std::thread* t: ts)
{
t->join();
delete t;
}
m_myKeys.append(p); m_myKeys.append(p);
keysChanged(); keysChanged();
} }
void Main::on_killAccount_triggered()
{
if (ui->ourAccounts->currentRow() >= 0 && ui->ourAccounts->currentRow() < m_myKeys.size())
{
auto k = m_myKeys[ui->ourAccounts->currentRow()];
if (ethereum()->balanceAt(k.address()) != 0 && QMessageBox::critical(this, "Kill Account?!", "Account " + render(k.address()) + " has " + QString::fromStdString(formatBalance(ethereum()->balanceAt(k.address()))) + " in it. It, and any contract that this account can access, will be lost forever if you continue. Do NOT continue unless you know what you are doing.\nAre you sure you want to continue?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
return;
m_myKeys.erase(m_myKeys.begin() + ui->ourAccounts->currentRow());
keysChanged();
}
}
void Main::on_debugStep_triggered() void Main::on_debugStep_triggered()
{ {
if (ui->debugTimeline->value() < m_history.size()) { if (ui->debugTimeline->value() < m_history.size()) {

1
alethzero/MainWin.h

@ -108,6 +108,7 @@ private slots:
void on_mine_triggered(); void on_mine_triggered();
void on_send_clicked(); void on_send_clicked();
void on_create_triggered(); void on_create_triggered();
void on_killAccount_triggered();
void on_net_triggered(); void on_net_triggered();
void on_verbosity_valueChanged(); void on_verbosity_valueChanged();
void on_ourAccounts_doubleClicked(); void on_ourAccounts_doubleClicked();

9
libdevcrypto/Common.cpp

@ -22,6 +22,7 @@
#include <random> #include <random>
#include <chrono> #include <chrono>
#include <thread>
#include <mutex> #include <mutex>
#include <libdevcore/Guards.h> #include <libdevcore/Guards.h>
#include "SHA3.h" #include "SHA3.h"
@ -96,12 +97,16 @@ bool dev::verify(Public const& _p, Signature const& _s, h256 const& _hash)
KeyPair KeyPair::create() KeyPair KeyPair::create()
{ {
static mt19937_64 s_eng(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count()); static boost::thread_specific_ptr<mt19937_64> s_eng;
static unsigned s_id = 0;
if (!s_eng.get())
s_eng.reset(new mt19937_64(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count() + ++s_id));
uniform_int_distribution<uint16_t> d(0, 255); uniform_int_distribution<uint16_t> d(0, 255);
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i)
{ {
KeyPair ret(FixedHash<32>::random(s_eng)); KeyPair ret(FixedHash<32>::random(*s_eng.get()));
if (ret.address()) if (ret.address())
return ret; return ret;
} }

2
libethereum/BlockChain.cpp

@ -60,7 +60,7 @@ std::map<Address, Account> const& dev::eth::genesisState()
{ {
// Initialise. // Initialise.
for (auto i: vector<string>({ for (auto i: vector<string>({
"51ba59315b3a95761d0863b05ccc7a7f54703d99", "dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6",
"e6716f9544a56c530d868e4bfbacb172315bdead", "e6716f9544a56c530d868e4bfbacb172315bdead",
"b9c015918bdaba24b4ff057a92a3873d6eb201be", "b9c015918bdaba24b4ff057a92a3873d6eb201be",
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4", "1a26338f0d905e295fccb71fa9ea849ffa12aaf4",

34
libjsqrc/ethereumjs/dist/ethereum.js

@ -129,7 +129,7 @@ var formatInputReal = function (value) {
var dynamicTypeBytes = function (type, value) { var dynamicTypeBytes = function (type, value) {
// TODO: decide what to do with array of strings // TODO: decide what to do with array of strings
if (arrayType(type) || prefixedType('string')(type)) if (arrayType(type) || type == 'string') // only string itself that is dynamic; stringX is static length.
return formatInputInt(value.length); return formatInputInt(value.length);
return ""; return "";
}; };
@ -252,7 +252,7 @@ var formatOutputAddress = function (value) {
}; };
var dynamicBytesLength = function (type) { var dynamicBytesLength = function (type) {
if (arrayType(type) || prefixedType('string')(type)) if (arrayType(type) || type == 'string') // only string itself that is dynamic; stringX is static length.
return ETH_PADDING * 2; return ETH_PADDING * 2;
return 0; return 0;
}; };
@ -448,7 +448,7 @@ var abi = require('./abi');
* var myContract = web3.eth.contract('0x0123123121', abi); // creation of contract object * var myContract = web3.eth.contract('0x0123123121', abi); // creation of contract object
* *
* myContract.myMethod('this is test string param for call'); // myMethod call (implicit, default) * myContract.myMethod('this is test string param for call'); // myMethod call (implicit, default)
* myContract.myMethod('this is test string param for call').call(); // myMethod call (explicit) * myContract.call().myMethod('this is test string param for call'); // myMethod call (explicit)
* myContract.transact().myMethod('this is test string param for transact'); // myMethod transact * myContract.transact().myMethod('this is test string param for transact'); // myMethod transact
* *
* @param address - address of the contract, which should be called * @param address - address of the contract, which should be called
@ -457,6 +457,18 @@ var abi = require('./abi');
*/ */
var contract = function (address, desc) { var contract = function (address, desc) {
desc.forEach(function (method) {
// workaround for invalid assumption that method.name is the full anonymous prototype of the method.
// it's not. it's just the name. the rest of the code assumes it's actually the anonymous
// prototype, so we make it so as a workaround.
if (method.name.indexOf('(') === -1) {
var displayName = method.name;
var typeName = method.inputs.map(function(i){return i.type}).join();
method.name = displayName + '(' + typeName + ')';
}
});
var inputParser = abi.inputParser(desc); var inputParser = abi.inputParser(desc);
var outputParser = abi.outputParser(desc); var outputParser = abi.outputParser(desc);
@ -488,11 +500,12 @@ var contract = function (address, desc) {
options.to = address; options.to = address;
options.data = signature + parsed; options.data = signature + parsed;
var isTransact = result._isTransact; var isTransact = result._isTransact === true || (result._isTransact !== false && !method.constant);
var collapse = options.collapse !== false;
// reset // reset
result._options = {}; result._options = {};
result._isTransact = false; result._isTransact = null;
if (isTransact) { if (isTransact) {
// it's used byt natspec.js // it's used byt natspec.js
@ -506,7 +519,15 @@ var contract = function (address, desc) {
} }
var output = web3.eth.call(options); var output = web3.eth.call(options);
return outputParser[displayName][typeName](output); var ret = outputParser[displayName][typeName](output);
if (collapse)
{
if (ret.length == 1)
ret = ret[0];
else if (ret.length == 0)
ret = null;
}
return ret;
}; };
if (result[displayName] === undefined) { if (result[displayName] === undefined) {
@ -889,6 +910,7 @@ var ethMethods = function () {
{ name: 'transaction', call: transactionCall }, { name: 'transaction', call: transactionCall },
{ name: 'uncle', call: uncleCall }, { name: 'uncle', call: uncleCall },
{ name: 'compilers', call: 'eth_compilers' }, { name: 'compilers', call: 'eth_compilers' },
{ name: 'flush', call: 'eth_flush' },
{ name: 'lll', call: 'eth_lll' }, { name: 'lll', call: 'eth_lll' },
{ name: 'solidity', call: 'eth_solidity' }, { name: 'solidity', call: 'eth_solidity' },
{ name: 'serpent', call: 'eth_serpent' }, { name: 'serpent', call: 'eth_serpent' },

8
libjsqrc/ethereumjs/dist/ethereum.js.map

File diff suppressed because one or more lines are too long

2
libjsqrc/ethereumjs/dist/ethereum.min.js

File diff suppressed because one or more lines are too long

4
libjsqrc/ethereumjs/lib/abi.js

@ -128,7 +128,7 @@ var formatInputReal = function (value) {
var dynamicTypeBytes = function (type, value) { var dynamicTypeBytes = function (type, value) {
// TODO: decide what to do with array of strings // TODO: decide what to do with array of strings
if (arrayType(type) || prefixedType('string')(type)) if (arrayType(type) || type == 'string') // only string itself that is dynamic; stringX is static length.
return formatInputInt(value.length); return formatInputInt(value.length);
return ""; return "";
}; };
@ -251,7 +251,7 @@ var formatOutputAddress = function (value) {
}; };
var dynamicBytesLength = function (type) { var dynamicBytesLength = function (type) {
if (arrayType(type) || prefixedType('string')(type)) if (arrayType(type) || type == 'string') // only string itself that is dynamic; stringX is static length.
return ETH_PADDING * 2; return ETH_PADDING * 2;
return 0; return 0;
}; };

29
libjsqrc/ethereumjs/lib/contract.js

@ -37,7 +37,7 @@ var abi = require('./abi');
* var myContract = web3.eth.contract('0x0123123121', abi); // creation of contract object * var myContract = web3.eth.contract('0x0123123121', abi); // creation of contract object
* *
* myContract.myMethod('this is test string param for call'); // myMethod call (implicit, default) * myContract.myMethod('this is test string param for call'); // myMethod call (implicit, default)
* myContract.myMethod('this is test string param for call').call(); // myMethod call (explicit) * myContract.call().myMethod('this is test string param for call'); // myMethod call (explicit)
* myContract.transact().myMethod('this is test string param for transact'); // myMethod transact * myContract.transact().myMethod('this is test string param for transact'); // myMethod transact
* *
* @param address - address of the contract, which should be called * @param address - address of the contract, which should be called
@ -46,6 +46,18 @@ var abi = require('./abi');
*/ */
var contract = function (address, desc) { var contract = function (address, desc) {
desc.forEach(function (method) {
// workaround for invalid assumption that method.name is the full anonymous prototype of the method.
// it's not. it's just the name. the rest of the code assumes it's actually the anonymous
// prototype, so we make it so as a workaround.
if (method.name.indexOf('(') === -1) {
var displayName = method.name;
var typeName = method.inputs.map(function(i){return i.type}).join();
method.name = displayName + '(' + typeName + ')';
}
});
var inputParser = abi.inputParser(desc); var inputParser = abi.inputParser(desc);
var outputParser = abi.outputParser(desc); var outputParser = abi.outputParser(desc);
@ -77,11 +89,12 @@ var contract = function (address, desc) {
options.to = address; options.to = address;
options.data = signature + parsed; options.data = signature + parsed;
var isTransact = result._isTransact; var isTransact = result._isTransact === true || (result._isTransact !== false && !method.constant);
var collapse = options.collapse !== false;
// reset // reset
result._options = {}; result._options = {};
result._isTransact = false; result._isTransact = null;
if (isTransact) { if (isTransact) {
// it's used byt natspec.js // it's used byt natspec.js
@ -95,7 +108,15 @@ var contract = function (address, desc) {
} }
var output = web3.eth.call(options); var output = web3.eth.call(options);
return outputParser[displayName][typeName](output); var ret = outputParser[displayName][typeName](output);
if (collapse)
{
if (ret.length == 1)
ret = ret[0];
else if (ret.length == 0)
ret = null;
}
return ret;
}; };
if (result[displayName] === undefined) { if (result[displayName] === undefined) {

1
libjsqrc/ethereumjs/lib/web3.js

@ -82,6 +82,7 @@ var ethMethods = function () {
{ name: 'transaction', call: transactionCall }, { name: 'transaction', call: transactionCall },
{ name: 'uncle', call: uncleCall }, { name: 'uncle', call: uncleCall },
{ name: 'compilers', call: 'eth_compilers' }, { name: 'compilers', call: 'eth_compilers' },
{ name: 'flush', call: 'eth_flush' },
{ name: 'lll', call: 'eth_lll' }, { name: 'lll', call: 'eth_lll' },
{ name: 'solidity', call: 'eth_solidity' }, { name: 'solidity', call: 'eth_solidity' },
{ name: 'serpent', call: 'eth_serpent' }, { name: 'serpent', call: 'eth_serpent' },

33
libsolidity/CompilerStack.cpp

@ -44,14 +44,14 @@ bool CompilerStack::addSource(string const& _name, string const& _content)
{ {
bool existed = m_sources.count(_name) != 0; bool existed = m_sources.count(_name) != 0;
reset(true); reset(true);
m_sources[_name].scanner = make_shared<Scanner>(CharStream(_content), _name); m_sources[_name].scanner = make_shared<Scanner>(CharStream(expanded(_content)), _name);
return existed; return existed;
} }
void CompilerStack::setSource(string const& _sourceCode) void CompilerStack::setSource(string const& _sourceCode)
{ {
reset(); reset();
addSource("", _sourceCode); addSource("", expanded(_sourceCode));
} }
void CompilerStack::parse() void CompilerStack::parse()
@ -91,6 +91,7 @@ void CompilerStack::parse()
void CompilerStack::parse(string const& _sourceCode) void CompilerStack::parse(string const& _sourceCode)
{ {
setSource(_sourceCode); setSource(_sourceCode);
addSources(StandardSources);
parse(); parse();
} }
@ -124,17 +125,29 @@ void CompilerStack::compile(bool _optimize)
} }
} }
const map<string, string> StandardSources = map<string, string>{
/* { "Config", "contract Config{function lookup(uint256 service)constant returns(address a){}function kill(){}function unregister(uint256 id){}function register(uint256 id,address service){}}" },
{ "owned", "contract owned{function owned(){owner = msg.sender;}address owner;}" },
{ "mortal", "import \"owned\";\ncontract mortal is owned {function kill() { if (msg.sender == owner) suicide(owner); }}" },
{ "NameReg", "contract NameReg{function register(string32 name){}function addressOf(string32 name)constant returns(address addr){}function unregister(){}function nameOf(address addr)constant returns(string32 name){}}" },
{ "named", "import \"Config\";\nimport \"NameReg\";\ncontract named is mortal, owned {function named(string32 name) {NameReg(Config().lookup(1)).register(name);}}" },
{ "std", "import \"owned\";\nimport \"mortal\";\nimport \"Config\";\nimport \"NameReg\";\nimport \"named\";\n" },
*/};
////// BEGIN: TEMPORARY ONLY
/// remove once import works properly and we have genesis contracts
string CompilerStack::expanded(string const& _sourceCode) string CompilerStack::expanded(string const& _sourceCode)
{ {
// TODO: populate some nicer way. const map<string, string> c_standardSources = map<string, string>{
static const map<string, string> c_requires = {
{ "Config", "contract Config{function lookup(uint256 service)constant returns(address a){}function kill(){}function unregister(uint256 id){}function register(uint256 id,address service){}}" }, { "Config", "contract Config{function lookup(uint256 service)constant returns(address a){}function kill(){}function unregister(uint256 id){}function register(uint256 id,address service){}}" },
{ "owned", "contract owned{function owned(){owner = msg.sender;}address owner;}" }, { "owned", "contract owned{function owned(){owner = msg.sender;}address owner;}" },
{ "mortal", "#require owned\ncontract mortal is owned {function kill() { if (msg.sender == owner) suicide(owner); }}" }, { "mortal", "#require owned\ncontract mortal is owned {function kill() { if (msg.sender == owner) suicide(owner); }}" },
{ "NameReg", "contract NameReg{function register(string32 name){}function addressOf(string32 name)constant returns(address addr){}function unregister(){}function nameOf(address addr)constant returns(string32 name){}}" }, { "NameReg", "contract NameReg{function register(string32 name){}function addressOf(string32 name)constant returns(address addr){}function unregister(){}function nameOf(address addr)constant returns(string32 name){}}" },
{ "named", "#require Config NameReg\ncontract named is mortal, owned {function named(string32 name) {NameReg(Config().lookup(1)).register(name);}" }, { "named", "#require Config NameReg\ncontract named is mortal, owned {function named(string32 name) {NameReg(Config().lookup(1)).register(name);}}" },
{ "std", "#require owned mortal Config NameReg named" }, { "std", "#require owned mortal Config NameReg named" },
}; };
string sub; string sub;
set<string> got; set<string> got;
function<string(string const&)> localExpanded; function<string(string const&)> localExpanded;
@ -151,22 +164,24 @@ string CompilerStack::expanded(string const& _sourceCode)
for (auto const& r: rs) for (auto const& r: rs)
if (!got.count(r)) if (!got.count(r))
{ {
if (c_requires.count(r)) if (c_standardSources.count(r))
sub.append("\n" + localExpanded(c_requires.at(r)) + "\n"); sub.append("\n" + localExpanded(c_standardSources.at(r)) + "\n");
got.insert(r); got.insert(r);
} }
} }
// TODO: remove once we have genesis contracts. // TODO: remove once we have genesis contracts.
else if ((p = ret.find("Config()")) != string::npos) else if ((p = ret.find("Config()")) != string::npos)
ret.replace(p, 8, "Config(0x661005d2720d855f1d9976f88bb10c1a3398c77f)"); ret.replace(p, 8, "Config(0xc6d9d2cd449a754c494264e1809c50e34d64562b)");
return ret; return ret;
}; };
return sub + localExpanded(_sourceCode); return sub + localExpanded(_sourceCode);
} }
////// END: TEMPORARY ONLY
bytes const& CompilerStack::compile(string const& _sourceCode, bool _optimize) bytes const& CompilerStack::compile(string const& _sourceCode, bool _optimize)
{ {
parse(expanded(_sourceCode)); parse(_sourceCode);
compile(_optimize); compile(_optimize);
return getBytecode(); return getBytecode();
} }

3
libsolidity/CompilerStack.h

@ -49,6 +49,8 @@ enum class DocumentationType: uint8_t
ABI_SOLIDITY_INTERFACE ABI_SOLIDITY_INTERFACE
}; };
extern const std::map<std::string, std::string> StandardSources;
/** /**
* Easy to use and self-contained Solidity compiler with as few header dependencies as possible. * Easy to use and self-contained Solidity compiler with as few header dependencies as possible.
* It holds state and can be used to either step through the compilation stages (and abort e.g. * It holds state and can be used to either step through the compilation stages (and abort e.g.
@ -61,6 +63,7 @@ public:
/// Adds a source object (e.g. file) to the parser. After this, parse has to be called again. /// Adds a source object (e.g. file) to the parser. After this, parse has to be called again.
/// @returns true if a source object by the name already existed and was replaced. /// @returns true if a source object by the name already existed and was replaced.
void addSources(std::map<std::string, std::string> const& _nameContents) { for (auto const& i: _nameContents) addSource(i.first, i.second); }
bool addSource(std::string const& _name, std::string const& _content); bool addSource(std::string const& _name, std::string const& _content);
void setSource(std::string const& _sourceCode); void setSource(std::string const& _sourceCode);
/// Parses all source units that were added /// Parses all source units that were added

43
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -216,8 +216,11 @@ WebThreeStubServerBase::WebThreeStubServerBase(jsonrpc::AbstractServerConnector&
void WebThreeStubServerBase::setAccounts(std::vector<dev::KeyPair> const& _accounts) void WebThreeStubServerBase::setAccounts(std::vector<dev::KeyPair> const& _accounts)
{ {
m_accounts.clear(); m_accounts.clear();
for (auto i: _accounts) for (auto const& i: _accounts)
m_accounts[i.address()] = i.secret(); {
m_accounts.push_back(i.address());
m_accountsLookup[i.address()] = i;
}
} }
void WebThreeStubServerBase::setIdentities(std::vector<dev::KeyPair> const& _ids) void WebThreeStubServerBase::setIdentities(std::vector<dev::KeyPair> const& _ids)
@ -235,8 +238,8 @@ std::string WebThreeStubServerBase::web3_sha3(std::string const& _param1)
Json::Value WebThreeStubServerBase::eth_accounts() Json::Value WebThreeStubServerBase::eth_accounts()
{ {
Json::Value ret(Json::arrayValue); Json::Value ret(Json::arrayValue);
for (auto i: m_accounts) for (auto const& i: m_accounts)
ret.append(toJS(i.first)); ret.append(toJS(i));
return ret; return ret;
} }
@ -307,25 +310,31 @@ static TransactionSkeleton toTransaction(Json::Value const& _json)
return ret; return ret;
} }
bool WebThreeStubServerBase::eth_flush()
{
client()->flushTransactions();
return true;
}
std::string WebThreeStubServerBase::eth_call(Json::Value const& _json) std::string WebThreeStubServerBase::eth_call(Json::Value const& _json)
{ {
std::string ret; std::string ret;
TransactionSkeleton t = toTransaction(_json); TransactionSkeleton t = toTransaction(_json);
if (!t.from && m_accounts.size()) if (!t.from && m_accounts.size())
{ {
auto b = m_accounts.begin()->first; auto b = m_accounts.front();
for (auto a: m_accounts) for (auto const& a: m_accounts)
if (client()->balanceAt(a.first) > client()->balanceAt(b)) if (client()->balanceAt(a) > client()->balanceAt(b))
b = a.first; b = a;
t.from = b; t.from = b;
} }
if (!m_accounts.count(t.from)) if (!m_accountsLookup.count(t.from))
return ret; return ret;
if (!t.gasPrice) if (!t.gasPrice)
t.gasPrice = 10 * dev::eth::szabo; t.gasPrice = 10 * dev::eth::szabo;
if (!t.gas) if (!t.gas)
t.gas = min<u256>(client()->gasLimitRemaining(), client()->balanceAt(t.from) / t.gasPrice); t.gas = min<u256>(client()->gasLimitRemaining(), client()->balanceAt(t.from) / t.gasPrice);
ret = toJS(client()->call(m_accounts[t.from].secret(), t.value, t.to, t.data, t.gas, t.gasPrice)); ret = toJS(client()->call(m_accountsLookup[t.from].secret(), t.value, t.to, t.data, t.gas, t.gasPrice));
return ret; return ret;
} }
@ -607,13 +616,13 @@ std::string WebThreeStubServerBase::eth_transact(Json::Value const& _json)
TransactionSkeleton t = toTransaction(_json); TransactionSkeleton t = toTransaction(_json);
if (!t.from && m_accounts.size()) if (!t.from && m_accounts.size())
{ {
auto b = m_accounts.begin()->first; auto b = m_accounts.front();
for (auto a: m_accounts) for (auto const& a: m_accounts)
if (client()->balanceAt(a.first) > client()->balanceAt(b)) if (client()->balanceAt(a) > client()->balanceAt(b))
b = a.first; b = a;
t.from = b; t.from = b;
} }
if (!m_accounts.count(t.from)) if (!m_accountsLookup.count(t.from))
return ret; return ret;
if (!t.gasPrice) if (!t.gasPrice)
t.gasPrice = 10 * dev::eth::szabo; t.gasPrice = 10 * dev::eth::szabo;
@ -623,9 +632,9 @@ std::string WebThreeStubServerBase::eth_transact(Json::Value const& _json)
{ {
if (t.to) if (t.to)
// TODO: from qethereum, insert validification hook here. // TODO: from qethereum, insert validification hook here.
client()->transact(m_accounts[t.from].secret(), t.value, t.to, t.data, t.gas, t.gasPrice); client()->transact(m_accountsLookup[t.from].secret(), t.value, t.to, t.data, t.gas, t.gasPrice);
else else
ret = toJS(client()->transact(m_accounts[t.from].secret(), t.value, t.data, t.gas, t.gasPrice)); ret = toJS(client()->transact(m_accountsLookup[t.from].secret(), t.value, t.data, t.gas, t.gasPrice));
client()->flushTransactions(); client()->flushTransactions();
} }
return ret; return ret;

4
libweb3jsonrpc/WebThreeStubServerBase.h

@ -79,6 +79,7 @@ public:
virtual int eth_defaultBlock(); virtual int eth_defaultBlock();
virtual std::string eth_gasPrice(); virtual std::string eth_gasPrice();
virtual Json::Value eth_filterLogs(int const& _id); virtual Json::Value eth_filterLogs(int const& _id);
virtual bool eth_flush();
virtual Json::Value eth_logs(Json::Value const& _json); virtual Json::Value eth_logs(Json::Value const& _json);
virtual bool eth_listening(); virtual bool eth_listening();
virtual bool eth_mining(); virtual bool eth_mining();
@ -129,7 +130,8 @@ protected:
virtual dev::WebThreeNetworkFace* network() = 0; virtual dev::WebThreeNetworkFace* network() = 0;
virtual dev::WebThreeStubDatabaseFace* db() = 0; virtual dev::WebThreeStubDatabaseFace* db() = 0;
std::map<dev::Address, dev::KeyPair> m_accounts; std::map<dev::Address, dev::KeyPair> m_accountsLookup;
std::vector<dev::Address> m_accounts;
std::map<dev::Public, dev::Secret> m_ids; std::map<dev::Public, dev::Secret> m_ids;
std::map<unsigned, dev::Public> m_shhWatches; std::map<unsigned, dev::Public> m_shhWatches;

6
libweb3jsonrpc/abstractwebthreestubserver.h

@ -32,6 +32,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
this->bindAndAddMethod(new jsonrpc::Procedure("eth_codeAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_codeAtI); this->bindAndAddMethod(new jsonrpc::Procedure("eth_codeAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_codeAtI);
this->bindAndAddMethod(new jsonrpc::Procedure("eth_transact", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_transactI); this->bindAndAddMethod(new jsonrpc::Procedure("eth_transact", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_transactI);
this->bindAndAddMethod(new jsonrpc::Procedure("eth_call", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_callI); this->bindAndAddMethod(new jsonrpc::Procedure("eth_call", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_callI);
this->bindAndAddMethod(new jsonrpc::Procedure("eth_flush", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_flushI);
this->bindAndAddMethod(new jsonrpc::Procedure("eth_blockByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_blockByHashI); this->bindAndAddMethod(new jsonrpc::Procedure("eth_blockByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_blockByHashI);
this->bindAndAddMethod(new jsonrpc::Procedure("eth_blockByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_blockByNumberI); this->bindAndAddMethod(new jsonrpc::Procedure("eth_blockByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_blockByNumberI);
this->bindAndAddMethod(new jsonrpc::Procedure("eth_transactionByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_transactionByHashI); this->bindAndAddMethod(new jsonrpc::Procedure("eth_transactionByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_transactionByHashI);
@ -142,6 +143,10 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
{ {
response = this->eth_call(request[0u]); response = this->eth_call(request[0u]);
} }
inline virtual void eth_flushI(const Json::Value &request, Json::Value &response)
{
response = this->eth_flush();
}
inline virtual void eth_blockByHashI(const Json::Value &request, Json::Value &response) inline virtual void eth_blockByHashI(const Json::Value &request, Json::Value &response)
{ {
response = this->eth_blockByHash(request[0u].asString()); response = this->eth_blockByHash(request[0u].asString());
@ -274,6 +279,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
virtual std::string eth_codeAt(const std::string& param1) = 0; virtual std::string eth_codeAt(const std::string& param1) = 0;
virtual std::string eth_transact(const Json::Value& param1) = 0; virtual std::string eth_transact(const Json::Value& param1) = 0;
virtual std::string eth_call(const Json::Value& param1) = 0; virtual std::string eth_call(const Json::Value& param1) = 0;
virtual bool eth_flush() = 0;
virtual Json::Value eth_blockByHash(const std::string& param1) = 0; virtual Json::Value eth_blockByHash(const std::string& param1) = 0;
virtual Json::Value eth_blockByNumber(const int& param1) = 0; virtual Json::Value eth_blockByNumber(const int& param1) = 0;
virtual Json::Value eth_transactionByHash(const std::string& param1, const int& param2) = 0; virtual Json::Value eth_transactionByHash(const std::string& param1, const int& param2) = 0;

1
libweb3jsonrpc/spec.json

@ -22,6 +22,7 @@
{ "name": "eth_transact", "params": [{}], "order": [], "returns": ""}, { "name": "eth_transact", "params": [{}], "order": [], "returns": ""},
{ "name": "eth_call", "params": [{}], "order": [], "returns": ""}, { "name": "eth_call", "params": [{}], "order": [], "returns": ""},
{ "name": "eth_flush", "params": [], "order": [], "returns" : true},
{ "name": "eth_blockByHash", "params": [""],"order": [], "returns": {}}, { "name": "eth_blockByHash", "params": [""],"order": [], "returns": {}},
{ "name": "eth_blockByNumber", "params": [0],"order": [], "returns": {}}, { "name": "eth_blockByNumber", "params": [0],"order": [], "returns": {}},

41
standard.js

@ -1,4 +1,27 @@
var compile = function(name) { return web3.eth.solidity(env.contents("../../dapp-bin/" + name + "/" + name + ".sol")); }; ///TODO
var compile = function(name) { return web3.eth.solidity(env.contents("/home/gav/Eth/dapp-bin/" + name + "/" + name + ".sol")); web3.eth.flush(); };
var create = function(code) { return web3.eth.transact({ 'code': code }); web3.eth.flush(); };
var createVal = function(code, val) { return web3.eth.transact(val ? { 'code': code, 'value': val } : { 'code': code }); web3.eth.flush(); };
var send = function(from, val, to) { web3.eth.transact({ 'from': from, 'value': val, 'to': to }); web3.eth.flush(); };
var initService = function(name) { return create(compile(name)); };
var initServiceVal = function(name, val) { createVal(compile(name), val); };
var addrConfig = create(compile("config"));
var addrNameReg = initService("namereg", addrConfig);
var addrGavsino = initServiceVal("gavmble", addrNameReg, "1000000000000000000");
var abiNameReg = [{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"getName","outputs":[{"name":"o_name","type":"string32"}]},{"constant":false,"inputs":[{"name":"name","type":"string32"}],"name":"register","outputs":[]},{"constant":true,"inputs":[{"name":"name","type":"string32"}],"name":"addressOf","outputs":[{"name":"addr","type":"address"}]},{"constant":true,"inputs":[{"name":"_name","type":"string32"}],"name":"getAddress","outputs":[{"name":"o_owner","type":"address"}]},{"constant":false,"inputs":[],"name":"unregister","outputs":[]},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"nameOf","outputs":[{"name":"name","type":"string32"}]}];
var regName = function(account, name) { return web3.eth.contract(addrNameReg, abiNameReg).transact({'from': account, 'gas': 10000}).register(name); };
send(web3.eth.accounts[0], '100000000000000000000', web3.eth.accounts[1]);
regName(web3.eth.accounts[0], 'Gav');
regName(web3.eth.accounts[1], 'Gav Would');
/*
// ASYNC API
var compile = function(name) { return web3.eth.solidity(env.contents("/home/gav/Eth/dapp-bin/" + name + "/" + name + ".sol")); };
var create = function(code) { return web3.eth.transact({ 'code': code }); }; var create = function(code) { return web3.eth.transact({ 'code': code }); };
var createVal = function(code, val) { return web3.eth.transact(val ? { 'code': code, 'value': val } : { 'code': code }); }; var createVal = function(code, val) { return web3.eth.transact(val ? { 'code': code, 'value': val } : { 'code': code }); };
var send = function(from, val, to) { return web3.eth.transact({ 'from': from, 'value': val, 'to': to }); }; var send = function(from, val, to) { return web3.eth.transact({ 'from': from, 'value': val, 'to': to }); };
@ -11,13 +34,13 @@ var addrGavsino = initServiceVal("gavmble", addrNameReg, "1000000000000000000");
var abiNameReg = [{"constant":true,"inputs":[{"name":"name","type":"string32"}],"name":"addressOf","outputs":[{"name":"addr","type":"address"}]},{"constant":false,"inputs":[],"name":"kill","outputs":[]},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"nameOf","outputs":[{"name":"name","type":"string32"}]},{"constant":false,"inputs":[{"name":"name","type":"string32"}],"name":"register","outputs":[]},{"constant":false,"inputs":[],"name":"unregister","outputs":[]}]; var abiNameReg = [{"constant":true,"inputs":[{"name":"name","type":"string32"}],"name":"addressOf","outputs":[{"name":"addr","type":"address"}]},{"constant":false,"inputs":[],"name":"kill","outputs":[]},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"nameOf","outputs":[{"name":"name","type":"string32"}]},{"constant":false,"inputs":[{"name":"name","type":"string32"}],"name":"register","outputs":[]},{"constant":false,"inputs":[],"name":"unregister","outputs":[]}];
var regName = function(account, name) { return web3.contract(addrNameReg, abiNameReg).register(name).transact({'from': account, 'gas': 10000}); }; var regName = function(account, name) { return web3.contract(addrNameReg, abiNameReg).register(name).transact({'from': account, 'gas': 10000}); };
/*
var coins = initService("coins", 1, nameReg); //var coins = initService("coins", 1, nameReg);
var coin = initService("coin", 2, coins); //var coin = initService("coin", 2, coins);
var approve = function(account, approvedAddress) { web3.eth.transact({ 'from': account, 'to': coin, 'gas': '10000', 'data': [ web3.fromAscii('approve'), approvedAddress ] }); }; //var approve = function(account, approvedAddress) { web3.eth.transact({ 'from': account, 'to': coin, 'gas': '10000', 'data': [ web3.fromAscii('approve'), approvedAddress ] }); };
var exchange = initService("exchange", 3, coin); //var exchange = initService("exchange", 3, coin);
var offer = function(account, haveCoin, haveVal, wantCoin, wantVal) { web3.eth.transact({ 'from': account, 'to': exchange, 'gas': '10000', 'data': [web3.fromAscii('new'), haveCoin, haveVal, wantCoin, wantVal] }); }; //var offer = function(account, haveCoin, haveVal, wantCoin, wantVal) { web3.eth.transact({ 'from': account, 'to': exchange, 'gas': '10000', 'data': [web3.fromAscii('new'), haveCoin, haveVal, wantCoin, wantVal] }); };
*/
addrConfig.then(function() { addrConfig.then(function() {
env.note("config ready"); env.note("config ready");
web3.eth.accounts.then(function(accounts) web3.eth.accounts.then(function(accounts)
@ -39,7 +62,7 @@ addrConfig.then(function() {
// eth.transact({ 'to': dnsReg, 'data': [web3.fromAscii('register'), web3.fromAscii('gav'), web3.fromAscii('opensecrecy.com')] }); // eth.transact({ 'to': dnsReg, 'data': [web3.fromAscii('register'), web3.fromAscii('gav'), web3.fromAscii('opensecrecy.com')] });
}); });
}); });
*/
// TODO // TODO
/* /*
var nameRegJeff; var nameRegJeff;

Loading…
Cancel
Save