Browse Source

Compiler fixes. Updates for coins.

cl-refactor
Gav Wood 11 years ago
parent
commit
44525c5f06
  1. 41
      alethzero/MainWin.cpp
  2. 4
      libethereum/Client.cpp
  3. 2
      liblll/Assembly.cpp
  4. 3
      liblll/CodeFragment.cpp
  5. 16
      liblll/CompilerState.cpp
  6. 2
      liblll/CompilerState.h
  7. 13
      liblll/Parser.cpp
  8. 147
      stdserv.js

41
alethzero/MainWin.cpp

@ -274,6 +274,18 @@ void Main::eval(QString const& _js)
ui->jsConsole->setHtml(s);
}
QString fromRaw(eth::h256 _n)
{
if (_n)
{
std::string s((char const*)_n.data(), 32);
if (s.find_first_of('\0') != string::npos)
s.resize(s.find_first_of('\0'));
return QString::fromStdString(s);
}
return QString();
}
QString Main::pretty(eth::Address _a) const
{
h256 n;
@ -284,14 +296,7 @@ QString Main::pretty(eth::Address _a) const
if (!n)
n = state().storage(m_nameReg, (u160)(_a));
if (n)
{
std::string s((char const*)n.data(), 32);
if (s.find_first_of('\0') != string::npos)
s.resize(s.find_first_of('\0'));
return QString::fromStdString(s);
}
return QString();
return fromRaw(n);
}
QString Main::render(eth::Address _a) const
@ -494,7 +499,7 @@ void Main::updateBlockCount()
{
auto d = m_client->blockChain().details();
auto diff = BlockInfo(m_client->blockChain().block()).difficulty;
ui->blockCount->setText(QString("#%1 @%3 T%2").arg(d.number).arg(toLog2(d.totalDifficulty)).arg(toLog2(diff)));
ui->blockCount->setText(QString("#%1 @%3 T%2 N%4").arg(d.number).arg(toLog2(d.totalDifficulty)).arg(toLog2(diff)).arg(eth::c_protocolVersion));
}
void Main::on_blockChainFilter_textChanged()
@ -659,8 +664,11 @@ void Main::refresh(bool _override)
m_keysChanged = false;
ui->ourAccounts->clear();
u256 totalBalance = 0;
u256 totalGavCoinBalance = 0;
Address gavCoin = fromString("GavCoin");
map<Address, pair<QString, u256>> altCoins;
Address coinsAddr = right160(st.storage(c_config, 1));
for (unsigned i = 0; i < st.storage(coinsAddr, 0); ++i)
altCoins[right160(st.storage(coinsAddr, st.storage(coinsAddr, i + 1)))] = make_pair(fromRaw(st.storage(coinsAddr, i + 1)), 0);
// u256 totalGavCoinBalance = 0;
for (auto i: m_myKeys)
{
u256 b = st.balance(i.address());
@ -668,10 +676,15 @@ void Main::refresh(bool _override)
->setData(Qt::UserRole, QByteArray((char const*)i.address().data(), Address::size));
totalBalance += b;
totalGavCoinBalance += st.storage(gavCoin, (u160)i.address());
for (auto& c: altCoins)
c.second.second += (u256)st.storage(c.first, (u160)i.address());
}
ui->balance->setText(QString::fromStdString(toString(totalGavCoinBalance) + " GAV | " + formatBalance(totalBalance)));
QString b;
for (auto const& c: altCoins)
if (c.second.second)
b += QString::fromStdString(toString(c.second.second)) + " " + c.second.first.toUpper() + " | ";
ui->balance->setText(b + QString::fromStdString(formatBalance(totalBalance)));
}
}
@ -1019,7 +1032,7 @@ void Main::on_data_textChanged()
QString s = ui->data->toPlainText();
while (s.size())
{
QRegExp r("(@|\\$)?\"(.*)\"(.*)");
QRegExp r("(@|\\$)?\"([^\"]*)\"(.*)");
QRegExp h("(@|\\$)?(0x)?(([a-fA-F0-9])+)(.*)");
if (r.exactMatch(s))
{

4
libethereum/Client.cpp

@ -371,7 +371,7 @@ PastTransactions Client::transactions(TransactionFilter const& _f) const
// Handle pending transactions differently as they're not on the block chain.
if (_f.latest() == 0)
{
for (unsigned i = m_postMine.pending().size(); i--;)
for (unsigned i = m_postMine.pending().size(); i-- && ret.size() != m;)
if (_f.matches(m_postMine, i))
{
if (s)
@ -391,7 +391,7 @@ PastTransactions Client::transactions(TransactionFilter const& _f) const
try
{
State st(m_stateDB, m_bc, h);
for (unsigned i = st.pending().size(); i--;)
for (unsigned i = st.pending().size(); i-- && ret.size() != m;)
if (_f.matches(st, i))
{
if (s)

2
liblll/Assembly.cpp

@ -74,12 +74,14 @@ unsigned Assembly::bytesRequired() const
void Assembly::append(Assembly const& _a)
{
auto newDeposit = m_deposit + _a.deposit();
for (AssemblyItem i: _a.m_items)
{
if (i.type() == Tag || i.type() == PushTag)
i.m_data += m_usedTags;
append(i);
}
m_deposit = newDeposit;
m_usedTags += _a.m_usedTags;
for (auto const& i: _a.m_data)
m_data.insert(i);

3
liblll/CodeFragment.cpp

@ -151,6 +151,9 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
case 5:
us = "SEQ";
break;
case 6:
us = "CALLDATALOAD";
break;
default:;
}

16
liblll/CompilerState.cpp

@ -45,18 +45,20 @@ void CompilerState::populateStandard()
{
static const string s = "{"
"(def 'gav 0x51ba59315b3a95761d0863b05ccc7a7f54703d99)"
"(def 'namereg 0x2d0aceee7e5ab874e22ccf8d1a649f59106d74e8)"
"(def 'config 0xccdeac59d35627b7de09332e819d5159e7bb7250)"
"(def 'config 0x661005d2720d855f1d9976f88bb10c1a3398c77f)"
"(def 'namereg 0x50441127ea5b9dfd835a9aba4e1dc9c1257b58ca)"
"(def 'gavcoin 0x5620133321fcac7f15a5c570016f6cb6dc263f9d)"
"(def 'sendgavcoin (to value) { [0]:to [32]:value (call (- (gas) 21) gavcoin 0 0 64 0 0) })"
"(def 'regname (name) { [0]:name (call (- (gas) 21) namereg 0 0 32 0 0) })"
"(def 'send (to value) (call (- (gas) 21) to value 0 0 0 0))"
"(def 'allgas (- (gas) 21))"
"(def 'sendgavcoin (to value) { [0]'send [32]:to [64]:value (call allgas gavcoin 0 0 96 0 0) })"
"(def 'regname (name) { [0]'register [32]name (call allgas namereg 0 0 64 0 0) })"
"(def 'regcoins (name) { [0]'register [32]name (call allgas namereg 0 0 64 0 0) })"
"(def 'send (to value) (call allgas to value 0 0 0 0))"
"(def 'send (gaslimit to value) (call gaslimit to value 0 0 0 0))"
"(def 'msg (gaslimit to value data datasize outsize) { (set x outsize) (set y (alloc @32)) (call gaslimit to value data datasize @0 @32) @0 })"
"(def 'msg (gaslimit to value data datasize) { (call gaslimit to value data datasize 0 32) @0 })"
"(def 'msg (gaslimit to value data) { [0]:data (msg gaslimit to value 0 32) })"
"(def 'msg (to value data) { [0]:data (msg (- gas 21) to value 0 32) })"
"(def 'msg (to data) { [0]:data (msg (- gas 21) to 0 0 32) })"
"(def 'msg (to value data) { [0]:data (msg allgas to value 0 32) })"
"(def 'msg (to data) { [0]:data (msg allgas to 0 0 32) })"
"(def 'create (value code) { [0]:(msize) (create value @0 (lll code @0)) })"
"(def 'create (code) { [0]:(msize) (create 0 @0 (lll code @0)) })"
"(def 'sha3 (val) { [0]:val (sha3 0 32) })"

2
liblll/CompilerState.h

@ -41,7 +41,7 @@ struct CompilerState
CodeFragment const& getDef(std::string const& _s);
void populateStandard();
unsigned stackSize = 64;
unsigned stackSize = 128;
std::map<std::string, std::pair<unsigned, unsigned>> vars; ///< maps name to stack offset & size.
std::map<std::string, CodeFragment> defs;
std::map<std::string, CodeFragment> args;

13
liblll/Parser.cpp

@ -56,6 +56,7 @@ void eth::debugOutAST(ostream& _out, sp::utree const& _this)
case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break;
case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break;
case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break;
case 6: _out << "$ "; debugOutAST(_out, _this.front()); break;
default:;
}
@ -80,8 +81,8 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
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()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;$@()[]{}:\n\t") + '\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];
@ -92,10 +93,11 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
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::list_type()> calldataload = qi::lit("$") > element;
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> list = '(' > *element > ')';
auto x = [](int a) { return [=](sp::utree& n, typename qi::rule<it, qi::ascii::space_type, sp::utree()>::context_type& c) { (boost::fusion::at_c<0>(c.attributes) = n).tag(a); }; };
qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[x(2)] | mload[x(1)] | sstore[x(4)] | mstore[x(3)] | seq[x(5)];
qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[x(2)] | mload[x(1)] | sstore[x(4)] | mstore[x(3)] | seq[x(5)] | calldataload[x(6)];
element = atom | list | extra;
string s;
@ -120,7 +122,8 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
}
auto ret = s.cbegin();
qi::phrase_parse(ret, s.cend(), element, space, qi::skip_flag::dont_postskip, o_out);
if (ret != s.cend())
throw std::exception();
for (auto i = ret; i != s.cend(); ++i)
if (!isspace(*i))
throw std::exception();
}

147
stdserv.js

@ -1,44 +1,48 @@
env.note('Creating Config...')
var configCode = eth.lll("{
var configCode = eth.lll("
{
[[69]] (caller)
(returnlll
(when (= (caller) @@69)
(returnlll {
(when (&& (= (calldatasize) 64) (= (caller) @@69))
(for {} (< @i (calldatasize)) [i](+ @i 64)
[[ (calldataload @i) ]] (calldataload (+ @i 32))
)
)
)
}")
(return @@ $0)
})
}
")
env.note('Config code: ' + configCode.unbin())
var config = "0x9ef0f0d81e040012600b0c1abdef7c48f720f88a";
eth.create(eth.key, '0', configCode, 10000, eth.gasPrice, function(a) { config = a; })
env.note('Config at address ' + config)
var nameRegCode = eth.lll("{
var nameRegCode = eth.lll("
{
[[(address)]] 'NameReg
[['NameReg]] (address)
[[" + config + "]] 'Config
[['Config]] " + config + "
[[69]] (caller)
(returnlll
(if (calldatasize)
{
(when @@(calldataload 0) (stop))
(when @@(caller) [[@@(caller)]] 0)
[[(calldataload 0)]] (caller)
[[(caller)]] (calldataload 0)
}
{
(when (= (caller) @@69) (suicide (caller)))
(when @@(caller) {
[[@@(caller)]] 0
[[(caller)]] 0
})
}
)
)
}");
(returnlll {
(when (= $0 'register) {
(when @@ $32 (stop))
(when @@(caller) [[@@(caller)]] 0)
[[$32]] (caller)
[[(caller)]] $32
(stop)
})
(when (&& (= $0 'unregister) @@(caller)) {
[[@@(caller)]] 0
[[(caller)]] 0
(stop)
})
(when (&& (= $0 'kill) (= (caller) @@69)) (suicide (caller)))
(return @@ $0)
})
}
");
env.note('NameReg code: ' + nameRegCode.unbin())
var nameReg = "0x3face8f2b3ef580265f0f67a57ce0fb78b135613";
@ -50,22 +54,89 @@ env.note('NameReg at address ' + nameReg)
env.note('Register NameReg...')
eth.transact(eth.key, '0', config, "0".pad(32) + nameReg.pad(32), 10000, eth.gasPrice);
var gavCoinCode = eth.lll("{
[[ (caller) ]]: 0x1000000
(call (- (gas) 100) " + nameReg + " 0 0 (lit 0 'GavCoin) 0 0)
(returnlll {
(when (!= (calldatasize) 64) (stop))
[fromBal] @@(caller)
[toBal]: @@(calldataload 0)
[value]: (calldataload 32)
(when (< @fromBal @value) (stop))
[[ (caller) ]]: (- @fromBal @value)
[[ (calldataload 0) ]]: (+ @toBal @value)
})
}");
var coinsCode = eth.lll("
{
[0]'register [32]'Coins
(msg allgas " + nameReg + " 0 0 64)
(returnlll {
(def 'name $0)
(def 'address (caller))
(when (|| (& 0xffffffffffffffffffffffffff name) @@name) (stop))
(set 'n (+ @@0 1))
[[0]] @n
[[@n]] name
[[name]] address
})
}
");
var coins;
env.note('Create Coins...')
eth.create(eth.key, '0', coinsCode, 10000, eth.gasPrice, function(a) { coins = a; })
env.note('Coins at address ' + coins)
env.note('Register Coins...')
eth.transact(eth.key, '0', config, "1".pad(32) + coins.pad(32), 10000, eth.gasPrice);
var gavCoinCode = eth.lll("
{
[[ (caller) ]] 0x1000000
[[ 0x69 ]] (caller)
[[ 0x42 ]] (number)
[0]'register [32]'GavCoin
(msg allgas " + nameReg + " 0 0 64)
(msg " + coins + " 'GAV)
(returnlll {
(when (&& (= $0 'kill) (= (caller) @@0x69)) (suicide (caller)))
(when (= $0 'balance) (return @@$32))
(when (= $0 'approved) (return @@ @(sha3 (^ (if (= (calldatasize) 64) (caller) $64) $32))) )
(when (= $0 'approve) {
[[@(sha3 (^ (caller) $32))]] $32
(stop)
})
(when (= $0 'send) {
(set 'fromVar (if (= (calldatasize) 96)
(caller)
{
(when (! @@ @(sha3 (^ $96 $32)) ) (stop))
$96
}
))
(def 'to $32)
(def 'value $64)
(def 'from (get 'fromVar))
(set 'fromBal @@from)
(when (< @fromBal value) (stop))
[[ from ]]: (- @fromBal value)
[[ to ]]: (+ @@to value)
(stop)
})
(set 'n @@0x42)
(when (&& (|| (= $0 'mine) (! (calldatasize))) (> (number) @n)) {
[[(coinbase)]] (+ @@(coinbase) 1024)
[[0x42]] (+ @n 1)
})
(return @@ $0)
})
}
");
var gavCoin;
env.note('Create GavCoin...')
eth.create(eth.key, '0', gavCoinCode, 10000, eth.gasPrice);
eth.create(eth.key, '0', gavCoinCode, 10000, eth.gasPrice, function(a) { gavCoin = a; });
env.note('Register GavCoin...')
eth.transact(eth.key, '0', config, "2".pad(32) + gavCoin.pad(32), 10000, eth.gasPrice);
env.note('Register my name...')
eth.transact(eth.key, '0', nameReg, "register".pad(32) + "Gav".pad(32), 10000, eth.gasPrice);
env.note('All done.')

Loading…
Cancel
Save