From c80fe4728988f66ef0bdaadbdf4d51ce8aec235f Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 16 Nov 2014 21:07:47 +0100 Subject: [PATCH] Fix std services except DNS Reg whose contract needs rewriting. --- alethzero/MainWin.cpp | 7 +- alethzero/MainWin.h | 1 + libdevcore/CommonJS.cpp | 31 +-- libdevcore/CommonJS.h | 11 +- libdevcore/Exceptions.h | 4 +- libethereum/Executive.cpp | 6 +- libevm/VM.h | 2 +- libqethereum/QEthereum.h | 1 + libweb3jsonrpc/WebThreeStubServer.cpp | 4 +- stdserv.js | 324 +++----------------------- 10 files changed, 62 insertions(+), 329 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index e10d01efc..dc5b326bc 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -353,6 +353,11 @@ void Main::on_enableOptimizer_triggered() on_data_textChanged(); } +QString Main::contents(QString _s) +{ + return QString::fromStdString(dev::asString(dev::contents(_s.toStdString()))); +} + void Main::load(QString _s) { QString contents = QString::fromStdString(dev::asString(dev::contents(_s.toStdString()))); @@ -682,7 +687,7 @@ void Main::on_importKeyFile_triggered() try { js::mValue val; - json_spirit::read_string(asString(contents(s.toStdString())), val); + json_spirit::read_string(asString(dev::contents(s.toStdString())), val); auto obj = val.get_obj(); if (obj["encseed"].type() == js::str_type) { diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 9f7ad97de..14877f610 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -85,6 +85,7 @@ public slots: void note(QString _entry); void debug(QString _entry); void warn(QString _entry); + QString contents(QString _file); void onKeysChanged(); diff --git a/libdevcore/CommonJS.cpp b/libdevcore/CommonJS.cpp index 96f4b1896..c09a5b565 100644 --- a/libdevcore/CommonJS.cpp +++ b/libdevcore/CommonJS.cpp @@ -38,31 +38,20 @@ bytes jsToBytes(std::string const& _s) return bytes(); } -std::string jsPadded(std::string const& _s, unsigned _l, unsigned _r) +bytes padded(bytes _b, unsigned _l) { - bytes b = jsToBytes(_s); - while (b.size() < _l) - b.insert(b.begin(), 0); - while (b.size() < _r) - b.push_back(0); - return asString(b).substr(b.size() - std::max(_l, _r)); + while (_b.size() < _l) + _b.insert(_b.begin(), 0); + while (_b.size() < _l) + _b.push_back(0); + return asBytes(asString(_b).substr(_b.size() - std::max(_l, _l))); } -std::string jsPadded(std::string const& _s, unsigned _l) +bytes unpadded(bytes _b) { - if (_s.substr(0, 2) == "0x" || _s.find_first_not_of("0123456789") == std::string::npos) - // Numeric: pad to right - return jsPadded(_s, _l, _l); - else - // Text: pad to the left - return jsPadded(_s, 0, _l); -} - -std::string jsUnpadded(std::string _s) -{ - auto p = _s.find_last_not_of((char)0); - _s.resize(p == std::string::npos ? 0 : (p + 1)); - return _s; + auto p = asString(_b).find_last_not_of((char)0); + _b.resize(p == std::string::npos ? 0 : (p + 1)); + return _b; } } diff --git a/libdevcore/CommonJS.h b/libdevcore/CommonJS.h index be98c2372..80e1a9ca1 100644 --- a/libdevcore/CommonJS.h +++ b/libdevcore/CommonJS.h @@ -47,9 +47,8 @@ inline std::string toJS(dev::bytes const& _n) } bytes jsToBytes(std::string const& _s); -std::string jsPadded(std::string const& _s, unsigned _l, unsigned _r); -std::string jsPadded(std::string const& _s, unsigned _l); -std::string jsUnpadded(std::string _s); +bytes padded(bytes _b, unsigned _l); +bytes unpadded(bytes _s); template FixedHash jsToFixed(std::string const& _s) { @@ -61,7 +60,7 @@ template FixedHash jsToFixed(std::string const& _s) return (typename FixedHash::Arith)(_s); else // Binary - return FixedHash(asBytes(jsPadded(_s, N))); + return FixedHash(); // FAIL } inline std::string jsToFixed(double _s) @@ -79,7 +78,7 @@ template boost::multiprecision::number>(_s); else // Binary - return fromBigEndian>>(asBytes(jsPadded(_s, N))); + return 0; // FAIL } inline Address jsToAddress(std::string const& _s) { return jsToFixed(_s); } @@ -89,7 +88,7 @@ inline u256 jsToU256(std::string const& _s) { return jsToInt<32>(_s); } inline std::string jsToBinary(std::string const& _s) { - return jsUnpadded(dev::toString(jsToBytes(_s))); + return dev::toString(unpadded(jsToBytes(_s))); } inline std::string jsToDecimal(std::string const& _s) diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h index bbc928da4..5d03c195f 100644 --- a/libdevcore/Exceptions.h +++ b/libdevcore/Exceptions.h @@ -45,7 +45,7 @@ struct FileError: virtual Exception {}; typedef boost::error_info errinfo_invalidSymbol; typedef boost::error_info errinfo_wrongAddress; typedef boost::error_info errinfo_comment; -typedef boost::error_info errinfo_required; -typedef boost::error_info errinfo_got; +typedef boost::error_info errinfo_required; +typedef boost::error_info errinfo_got; typedef boost::tuple RequirementError; } diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index f8c526ac7..c3a8b2a80 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -71,7 +71,7 @@ bool Executive::setup(bytesConstRef _rlp) if (m_t.gas() < gasCost) { clog(StateDetail) << "Not enough gas to pay for the transaction: Require >" << gasCost << " Got" << m_t.gas(); - BOOST_THROW_EXCEPTION(OutOfGas()); + BOOST_THROW_EXCEPTION(OutOfGas() << RequirementError((bigint)gasCost, (bigint)m_t.gas())); } u256 cost = m_t.value() + m_t.gas() * m_t.gasPrice(); @@ -80,14 +80,14 @@ bool Executive::setup(bytesConstRef _rlp) if (m_s.balance(m_sender) < cost) { clog(StateDetail) << "Not enough cash: Require >" << cost << " Got" << m_s.balance(m_sender); - BOOST_THROW_EXCEPTION(NotEnoughCash() << RequirementError((int)cost, (int)m_s.balance(m_sender))); + BOOST_THROW_EXCEPTION(NotEnoughCash() << RequirementError((bigint)cost, (bigint)m_s.balance(m_sender))); } u256 startGasUsed = m_s.gasUsed(); if (startGasUsed + m_t.gas() > m_s.m_currentBlock.gasLimit) { clog(StateDetail) << "Too much gas used in this block: Require <" << (m_s.m_currentBlock.gasLimit - startGasUsed) << " Got" << m_t.gas(); - BOOST_THROW_EXCEPTION(BlockGasLimitReached() << RequirementError((int)(m_s.m_currentBlock.gasLimit - startGasUsed), (int)m_t.gas())); + BOOST_THROW_EXCEPTION(BlockGasLimitReached() << RequirementError((bigint)(m_s.m_currentBlock.gasLimit - startGasUsed), (bigint)m_t.gas())); } // Increment associated nonce for sender. diff --git a/libevm/VM.h b/libevm/VM.h index 52149a9a1..487c8cd1a 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -71,7 +71,7 @@ public: template bytesConstRef go(Ext& _ext, OnOpFunc const& _onOp = OnOpFunc(), uint64_t _steps = (uint64_t)-1); - void require(u256 _n) { if (m_stack.size() < _n) BOOST_THROW_EXCEPTION(StackTooSmall() << RequirementError(int(_n), m_stack.size())); } + void require(u256 _n) { if (m_stack.size() < _n) BOOST_THROW_EXCEPTION(StackTooSmall() << RequirementError((bigint)_n, (bigint)m_stack.size())); } void requireMem(unsigned _n) { if (m_temp.size() < _n) { m_temp.resize(_n); } } u256 gas() const { return m_gas; } u256 curPC() const { return m_curPC; } diff --git a/libqethereum/QEthereum.h b/libqethereum/QEthereum.h index 4f276b7e1..0824b0139 100644 --- a/libqethereum/QEthereum.h +++ b/libqethereum/QEthereum.h @@ -83,6 +83,7 @@ private: { \ _frame->disconnect(); \ _frame->addToJavaScriptWindowObject("_web3", qweb, QWebFrame::ScriptOwnership); \ + _frame->addToJavaScriptWindowObject("env", _env, QWebFrame::QtOwnership); \ _frame->evaluateJavaScript(contentsOfQResource(":/js/es6-promise-2.0.0.js")); \ _frame->evaluateJavaScript(contentsOfQResource(":/js/main.js")); \ _frame->evaluateJavaScript(contentsOfQResource(":/js/qt.js")); \ diff --git a/libweb3jsonrpc/WebThreeStubServer.cpp b/libweb3jsonrpc/WebThreeStubServer.cpp index 73c938ce2..03c2a37ac 100644 --- a/libweb3jsonrpc/WebThreeStubServer.cpp +++ b/libweb3jsonrpc/WebThreeStubServer.cpp @@ -370,10 +370,10 @@ static TransactionSkeleton toTransaction(Json::Value const& _json) ret.data = jsToBytes(_json["code"].asString()); else if (_json["data"].isArray()) for (auto i: _json["data"]) - dev::operator +=(ret.data, jsToBytes(jsPadded(i.asString(), 32))); + dev::operator +=(ret.data, padded(jsToBytes(i.asString()), 32)); else if (_json["code"].isArray()) for (auto i: _json["code"]) - dev::operator +=(ret.data, jsToBytes(jsPadded(i.asString(), 32))); + dev::operator +=(ret.data, padded(jsToBytes(i.asString()), 32)); else if (_json["dataclose"].isArray()) for (auto i: _json["dataclose"]) dev::operator +=(ret.data, jsToBytes(i.asString())); diff --git a/stdserv.js b/stdserv.js index 375a8379f..fe681414e 100644 --- a/stdserv.js +++ b/stdserv.js @@ -1,69 +1,41 @@ -eth = web3.eth; -env = web3.env; - -var configSource = -"{"+ -" [[69]] (caller)"+ -" (returnlll {"+ -" (when (&& (= (calldatasize) 64) (= (caller) @@69))"+ -" (for {} (< @i (calldatasize)) [i](+ @i 64)"+ -" [[ (calldataload @i) ]] (calldataload (+ @i 32))"+ -" )"+ -" )"+ -" (return @@ $0)"+ -" })"+ -"}"; - -console.log('Creating Config...') -var config = eth.lll(configSource); -config = config.then(function (configCode) { console.log('Config code: ' + configCode); return eth.transact({ 'code': configCode }); }); -config.then(function(configAddress) { console.log('Config at address ' + configAddress); config = configAddress; return configAddress; }); - -// marek: TODO +var compile = function(name) { return web3.eth.lll(env.contents("../../dapp-bin/" + name + "/" + name + ".lll")); }; +var create = function(code) { return web3.eth.transact({ 'code': code }); }; +var send = function(from, val, to) { return web3.eth.transact({ 'from': from, 'value': val, 'to': to }); }; +var initService = function(name, index, dep) { return dep.then(function(){ var ret = compile(name).then(create); register(ret, index); return ret; }); }; + +var config = compile("config").then(create); +var register = function(address, index) { return web3.eth.transact({ 'to': config, 'gas': '10000', 'data': [index + '', address] }); }; +var nameReg = initService("namereg", 0, config); +var regName = function(account, name) { return web3.eth.transact({ 'from': account, 'to': nameReg, 'gas': '10000', 'data': [ web3.fromAscii('register'), web3.fromAscii(name) ] }); }; +var coins = initService("coins", 1, nameReg); +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 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] }); }; + +config.then(function() { + web3.eth.accounts.then(function(accounts) + { + var funded = send(accounts[0], '100000000000000000000', accounts[1]); + funded.then(function(){ env.note("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); regName(accounts[1], 'Gav Would'); env.note("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); approve(accounts[1], exchange); }); + regName(accounts[0], 'Gav'); + approve(accounts[0], exchange).then(function(){ offer(accounts[0], coin, '5000', '0', '5000000000000000000'); }); + + // TODO: once we have a new implementation of DNSReg. + // env.note('Register gav.eth...') + // eth.transact({ 'to': dnsReg, 'data': [web3.fromAscii('register'), web3.fromAscii('gav'), web3.fromAscii('opensecrecy.com')] }); + }); +}); + +// TODO /* - -var nameRegCode = eth.lll(" -{ - [[(address)]] 'NameReg - [['NameReg]] (address) - [[config]] 'Config - [['Config]] config - [[69]] (caller) - (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) - -var nameReg; - -env.note('Create NameReg...') -eth.transact({ 'code': nameRegCode }, function(a) { nameReg = a; }); - -env.note('Register NameReg...') -eth.transact({ 'to': config, 'data': ['0', nameReg] }); - var nameRegJeff; env.note('Create NameRegJeff...') eth.transact({ 'code': nameRegCode }, function(a) { nameRegJeff = a; }); env.note('Register NameRegJeff...') -eth.transact({ 'to': config, 'data': ['4', nameReg] }); +eth.transact({ 'to': config, 'data': ['4', nameRegJeff] }); var dnsRegCode = '0x60006000546000600053602001546000600053604001546020604060206020600073661005d2720d855f1d9976f88bb10c1a3398c77f6103e8f17f7265676973746572000000000000000000000000000000000000000000000000600053606001600060200201547f446e735265670000000000000000000000000000000000000000000000000000600053606001600160200201546000600060006000604060606000600053604001536103e8f1327f6f776e65720000000000000000000000000000000000000000000000000000005761011663000000e46000396101166000f20060006000547f72656769737465720000000000000000000000000000000000000000000000006000602002350e0f630000006d596000600160200235560e0f630000006c59600032560e0f0f6300000057596000325657600260200235600160200235576001602002353257007f64657265676973746572000000000000000000000000000000000000000000006000602002350e0f63000000b95960016020023532560e0f63000000b959600032576000600160200235577f6b696c6c000000000000000000000000000000000000000000000000000000006000602002350e0f630000011559327f6f776e6572000000000000000000000000000000000000000000000000000000560e0f63000001155932ff00'; @@ -75,240 +47,6 @@ env.note('DnsReg at address ' + dnsReg) env.note('Register DnsReg...') eth.transact({ 'to': config, 'data': ['4', dnsReg] }); - -var coinRegCode = eth.lll(" -{ -(regname 'CoinReg) -(returnlll { - (def 'name $0) - (def 'denom $32) - (def 'address (caller)) - (when (|| (& 0xffffffffffffffffffffffffff name) @@name) (stop)) - (set 'n (+ @@0 1)) - [[0]] @n - [[@n]] name - [[name]] address - [[(sha3 name)]] denom -}) -} -"); - -var coinReg; -env.note('Create CoinReg...') -eth.transact({ 'code': coinRegCode }, function(a) { coinReg = a; }); - -env.note('Register CoinReg...') -eth.transact({ 'to': config, 'data': ['1', coinReg] }); - -var gavCoinCode = eth.lll(" -{ -[[ (caller) ]] 0x1000000 -[[ 0x69 ]] (caller) -[[ 0x42 ]] (number) - -(regname 'GavCoin) -(regcoin 'GAV 1000) - -(returnlll { - (when (&& (= $0 'kill) (= (caller) @@0x69)) (suicide (caller))) - (when (= $0 'balance) (return @@$32)) - (when (= $0 'approved) (return @@ (sha3pair (if (= (calldatasize) 64) (caller) $64) $32)) ) - - (when (= $0 'approve) { - [[(sha3pair (caller) $32)]] $32 - (stop) - }) - - (when (= $0 'send) { - (set 'fromVar (if (= (calldatasize) 96) - (caller) - { - (when (! @@ (sha3pair (origin) (caller))) (return 0)) - (origin) - } - )) - (def 'to $32) - (def 'value $64) - (def 'from (get 'fromVar)) - (set 'fromBal @@from) - (when (< @fromBal value) (return 0)) - [[ from ]]: (- @fromBal value) - [[ to ]]: (+ @@to value) - (return 1) - }) - - (set 'n @@0x42) - (when (&& (|| (= $0 'mine) (! (calldatasize))) (> (number) @n)) { - (set 'b (- (number) @n)) - [[(coinbase)]] (+ @@(coinbase) (* 1000 @b)) - [[(caller)]] (+ @@(caller) (* 1000 @b)) - [[0x42]] (number) - (return @b) - }) - - (return @@ $0) -}) -} -"); - -var gavCoin; -env.note('Create GavCoin...') -eth.transact({ 'code': gavCoinCode }, function(a) { gavCoin = a; }); - -env.note('Register GavCoin...') -eth.transact({ 'to': config, 'data': ['2', gavCoin] }); - - -var exchangeCode = eth.lll(" -{ -(regname 'Exchange) - -(def 'min (a b) (if (< a b) a b)) - -(def 'head (_list) @@ _list) -(def 'next (_item) @@ _item) -(def 'inc (itemref) [itemref]: (next @itemref)) -(def 'rateof (_item) @@ (+ _item 1)) -(def 'idof (_item) @@ (+ _item 2)) -(def 'wantof (_item) @@ (+ _item 3)) -(def 'newitem (rate who want list) { - (set 'pos (sha3trip rate who list)) - [[ (+ @pos 1) ]] rate - [[ (+ @pos 2) ]] who - [[ (+ @pos 3) ]] want - @pos -}) -(def 'stitchitem (parent pos) { - [[ pos ]] @@ parent - [[ parent ]] pos -}) -(def 'addwant (_item amount) [[ (+ _item 3) ]] (+ @@ (+ _item 3) amount)) -(def 'deductwant (_item amount) [[ (+ _item 3) ]] (- @@ (+ _item 3) amount)) - -(def 'xfer (contract to amount) - (if contract { - [0] 'send - [32] to - [64] amount - (msg allgas contract 0 0 96) - } - (send to amount) - ) -) - -(def 'fpdiv (a b) (/ (+ (/ b 2) (* a (exp 2 128))) b)) -(def 'fpmul (a b) (/ (* a b) (exp 2 128)) ) - -(returnlll { - (when (= $0 'new) { - (set 'offer $32) - (set 'xoffer (if @offer $64 (callvalue))) - (set 'want $96) - (set 'xwant $128) - (set 'rate (fpdiv @xoffer @xwant)) - (set 'irate (fpdiv @xwant @xoffer)) - - (unless (&& @rate @irate @xoffer @xwant) (stop)) - - (when @offer { - (set 'arg1 'send) - (set 'arg2 (address)) - (set 'arg3 @xoffer) - (set 'arg4 (caller)) - (unless (msg allgas @offer 0 arg1 128) (stop)) - }) - (set 'list (sha3pair @offer @want)) - (set 'ilist (sha3pair @want @offer)) - - (set 'last @ilist) - (set 'item @@ @last) - - (for {} (&& @item (>= (rateof @item) @irate)) {} { - (set 'offerA (min @xoffer (wantof @item))) - (set 'wantA (fpmul @offerA (rateof @item))) - - (set 'xoffer (- @xoffer @offerA)) - (set 'xwant (- @xwant @wantA)) - - (deductwant @item @offerA) - - (xfer @offer (idof @item) @offerA) - (xfer @want (caller) @wantA) - - (unless @xoffer (stop)) - - (set 'item @@ @item) - [[ @last ]] @item - }) - - (set 'last @list) - (set 'item @@ @last) - - (set 'newpos (newitem @rate (caller) @xwant @list)) - - (for {} (&& @item (!= @item @newpos) (>= (rateof @item) @rate)) { (set 'last @item) (inc item) } {}) - (if (= @item @newpos) - (addwant @item @wantx) - (stitchitem @last @newpos) - ) - (stop) - }) - (when (= $0 'delete) { - (set 'offer $32) - (set 'want $64) - (set 'rate $96) - (set 'list (sha3pair @offer @want)) - (set 'last @list) - (set 'item @@ @last) - (for {} (&& @item (!= (idof @item) (caller)) (!= (rateof @item) @rate)) { (set 'last @item) (inc item) } {}) - (when @item { - (set 'xoffer (fpmul (wantof @item) (rateof @item))) - [[ @last ]] @@ @item - (xfer @offer (caller) @xoffer) - }) - (stop) - }) - (when (= $0 'price) { - (set 'offer $32) - (set 'want $96) - (set 'item (head (sha3pair @offer @want))) - (return (if @item (rateof @list) 0)) - }) -}) -} -"); - -var exchange; -env.note('Create Exchange...') -eth.transact({ 'code': exchangeCode }, function(a) { exchange = a; }); - -env.note('Register Exchange...') -eth.transact({ 'to': config, 'data': ['3', exchange] }); - - - - -env.note('Register my name...') -eth.transact({ 'to': nameReg, 'data': [ web3.fromAscii('register'), web3.fromAscii('Gav') ] }); - -env.note('Dole out ETH to other address...') -eth.transact({ 'value': '100000000000000000000', 'to': eth.accounts[1] }); - -env.note('Register my other name...') -eth.transact({ 'from': eth.keys[1], 'to': nameReg, 'data': [ web3.fromAscii('register'), web3.fromAscii("Gav Would") ] }); - -env.note('Approve Exchange...') -eth.transact({ 'to': gavCoin, 'data': [ web3.fromAscii('approve'), exchange ] }); - -env.note('Approve Exchange on other address...') -eth.transact({ 'from': eth.keys[1], 'to': gavCoin, 'data': [ web3.fromAscii('approve'), exchange ] }); - -env.note('Make offer 5000GAV/5ETH...') -eth.transact({ 'to': exchange, 'data': [web3.fromAscii('new'), gavCoin, '5000', '0', '5000000000000000000'] }); - -env.note('Register gav.eth...') -eth.transact({ 'to': dnsReg, 'data': [web3.fromAscii('register'), web3.fromAscii('gav'), web3.fromAscii('opensecrecy.com')] }); */ -env.note('All done.') // env.load('/home/gav/Eth/cpp-ethereum/stdserv.js')