Browse Source

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

cl-refactor
arkpar 10 years ago
parent
commit
5552d212d6
  1. 86
      abi/main.cpp
  2. 3
      libdevcore/vector_ref.h
  3. 6
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  4. 1
      mix/CodeModel.cpp
  5. 36
      mix/ContractCallDataEncoder.cpp
  6. 1
      mix/ContractCallDataEncoder.h
  7. 7
      mix/qml/TransactionDialog.qml

86
abi/main.cpp

@ -264,12 +264,12 @@ struct ABIType
{ {
bytes ret = _b; bytes ret = _b;
while (ret.size() < _length) while (ret.size() < _length)
if (_f == Format::Binary) if (base == Base::Bytes || (base == Base::Unknown && _f == Format::Binary))
ret.push_back(0); ret.push_back(0);
else else
ret.insert(ret.begin(), 0); ret.insert(ret.begin(), 0);
while (ret.size() > _length) while (ret.size() > _length)
if (_f == Format::Binary) if (base == Base::Bytes || (base == Base::Unknown && _f == Format::Binary))
ret.pop_back(); ret.pop_back();
else else
ret.erase(ret.begin()); ret.erase(ret.begin());
@ -303,7 +303,7 @@ tuple<bytes, ABIType, Format> fromUser(std::string const& _arg, Tristate _prefix
type.noteDecimalInput(); type.noteDecimalInput();
return make_tuple(toCompactBigEndian(bigint(val.substr(1))), type, Format::Decimal); return make_tuple(toCompactBigEndian(bigint(val.substr(1))), type, Format::Decimal);
} }
if (val.substr(0, 1) == "@") if (val.substr(0, 1) == "'")
{ {
type.noteBinaryInput(); type.noteBinaryInput();
return make_tuple(asBytes(val.substr(1)), type, Format::Binary); return make_tuple(asBytes(val.substr(1)), type, Format::Binary);
@ -335,6 +335,7 @@ tuple<bytes, ABIType, Format> fromUser(std::string const& _arg, Tristate _prefix
throw InvalidUserString(); throw InvalidUserString();
} }
struct ExpectedAdditionalParameter: public Exception {};
struct ExpectedOpen: public Exception {}; struct ExpectedOpen: public Exception {};
struct ExpectedClose: public Exception {}; struct ExpectedClose: public Exception {};
@ -394,10 +395,10 @@ struct ABIMethod
ss << "constant "; ss << "constant ";
if (!outs.empty()) if (!outs.empty())
{ {
ss << "returns ("; ss << "returns(";
f = 0; f = 0;
for (ABIType const& i: outs) for (ABIType const& i: outs)
ss << (f ? ", " : "") << i.canon() << " " << i.name; ss << (f++ ? ", " : "") << i.canon() << " " << i.name;
ss << ")"; ss << ")";
} }
return ss.str(); return ss.str();
@ -417,11 +418,15 @@ struct ABIMethod
for (ABIType const& a: ins) for (ABIType const& a: ins)
{ {
if (pi >= _params.size())
throw ExpectedAdditionalParameter();
auto put = [&]() { auto put = [&]() {
if (a.isBytes()) if (a.isBytes())
ret += h256(u256(_params[pi].first.size())).asBytes(); ret += h256(u256(_params[pi].first.size())).asBytes();
suffix += a.unrender(_params[pi].first, _params[pi].second); suffix += a.unrender(_params[pi].first, _params[pi].second);
pi++; pi++;
if (pi >= _params.size())
throw ExpectedAdditionalParameter();
}; };
function<void(vector<int>, unsigned)> putDim = [&](vector<int> addr, unsigned q) { function<void(vector<int>, unsigned)> putDim = [&](vector<int> addr, unsigned q) {
if (addr.size() == a.dims.size()) if (addr.size() == a.dims.size())
@ -430,13 +435,14 @@ struct ABIMethod
{ {
if (_params[pi].second != Format::Open) if (_params[pi].second != Format::Open)
throw ExpectedOpen(); throw ExpectedOpen();
++pi;
int l = a.dims[addr.size()]; int l = a.dims[addr.size()];
if (l == -1) if (l == -1)
{ {
// read ahead in params and discover the arity. // read ahead in params and discover the arity.
unsigned depth = 0; unsigned depth = 0;
l = 0; l = 0;
for (unsigned pi2 = pi + 1; depth || _params[pi2].second != Format::Close;) for (unsigned pi2 = pi; depth || _params[pi2].second != Format::Close;)
{ {
if (_params[pi2].second == Format::Open) if (_params[pi2].second == Format::Open)
++depth; ++depth;
@ -454,6 +460,7 @@ struct ABIMethod
putDim(addr, q); putDim(addr, q);
if (_params[pi].second != Format::Close) if (_params[pi].second != Format::Close)
throw ExpectedClose(); throw ExpectedClose();
++pi;
} }
}; };
putDim(vector<int>(), 1); putDim(vector<int>(), 1);
@ -463,8 +470,6 @@ struct ABIMethod
string decode(bytes const& _data, int _index, EncodingPrefs _ep) string decode(bytes const& _data, int _index, EncodingPrefs _ep)
{ {
stringstream out; stringstream out;
if (_index == -1)
out << "[";
unsigned di = 0; unsigned di = 0;
vector<unsigned> catDims; vector<unsigned> catDims;
for (ABIType const& a: outs) for (ABIType const& a: outs)
@ -481,7 +486,6 @@ struct ABIMethod
put(); put();
else else
{ {
out << "[";
int l = a.dims[addr.size()]; int l = a.dims[addr.size()];
if (l == -1) if (l == -1)
{ {
@ -492,7 +496,6 @@ struct ABIMethod
q *= l; q *= l;
for (addr.push_back(0); addr.back() < l; ++addr.back()) for (addr.push_back(0); addr.back() < l; ++addr.back())
putDim(addr, q); putDim(addr, q);
out << "]";
} }
}; };
putDim(vector<int>(), 1); putDim(vector<int>(), 1);
@ -500,12 +503,20 @@ struct ABIMethod
unsigned d = 0; unsigned d = 0;
for (ABIType const& a: outs) for (ABIType const& a: outs)
{ {
if (_index == -1 && out.tellp() > 0)
out << ", ";
auto put = [&]() { auto put = [&]() {
unsigned l = 32;
if (a.isBytes()) if (a.isBytes())
l = (catDims[d++] + 31 / 32) * 32; {
out << a.render(bytesConstRef(&_data).cropped(di, l).toBytes(), _ep) << ", "; out << a.render(bytesConstRef(&_data).cropped(di, catDims[d]).toBytes(), _ep);
di += l; di += ((catDims[d] + 31) / 32) * 32;
d++;
}
else
{
out << a.render(bytesConstRef(&_data).cropped(di, 32).toBytes(), _ep);
di += 32;
}
}; };
function<void(vector<int>)> putDim = [&](vector<int> addr) { function<void(vector<int>)> putDim = [&](vector<int> addr) {
if (addr.size() == a.dims.size()) if (addr.size() == a.dims.size())
@ -527,22 +538,22 @@ struct ABIMethod
} }
}; };
putDim(vector<int>()); putDim(vector<int>());
if (_index == -1)
out << ", ";
} }
(void)_data;
if (_index == -1)
out << "]";
return out.str(); return out.str();
} }
}; };
string canonSig(string const& _name, vector<ABIType> const& _args) string canonSig(string const& _name, vector<ABIType> const& _args)
{ {
try {
string methodArgs; string methodArgs;
for (auto const& arg: _args) for (auto const& arg: _args)
methodArgs += (methodArgs.empty() ? "" : ",") + arg.canon(); methodArgs += (methodArgs.empty() ? "" : ",") + arg.canon();
return _name + "(" + methodArgs + ")"; return _name + "(" + methodArgs + ")";
}
catch (...) {
return string();
}
} }
struct UnknownMethod: public Exception {}; struct UnknownMethod: public Exception {};
@ -632,6 +643,7 @@ int main(int argc, char** argv)
int outputIndex = -1; int outputIndex = -1;
vector<pair<bytes, Format>> params; vector<pair<bytes, Format>> params;
vector<ABIType> args; vector<ABIType> args;
string incoming;
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
{ {
@ -656,8 +668,6 @@ int main(int argc, char** argv)
typePrefix = Tristate::True; typePrefix = Tristate::True;
else if (arg == "-T" || arg == "--no-typing") else if (arg == "-T" || arg == "--no-typing")
typePrefix = Tristate::False; typePrefix = Tristate::False;
else if (arg == "-v" || arg == "--verbose")
verbose = true;
else if (arg == "-x" || arg == "--hex") else if (arg == "-x" || arg == "--hex")
prefs.e = Encoding::Hex; prefs.e = Encoding::Hex;
else if (arg == "-d" || arg == "--decimal" || arg == "--dec") else if (arg == "-d" || arg == "--decimal" || arg == "--dec")
@ -665,21 +675,23 @@ int main(int argc, char** argv)
else if (arg == "-b" || arg == "--binary" || arg == "--bin") else if (arg == "-b" || arg == "--binary" || arg == "--bin")
prefs.e = Encoding::Binary; prefs.e = Encoding::Binary;
else if (arg == "-v" || arg == "--verbose") else if (arg == "-v" || arg == "--verbose")
version(); verbose = true;
else if (arg == "-V" || arg == "--version") else if (arg == "-V" || arg == "--version")
version(); version();
else if (method.empty()) else if (method.empty())
method = arg; method = arg;
else else if (mode == Mode::Encode)
{ {
auto u = fromUser(arg, formatPrefix, typePrefix); auto u = fromUser(arg, formatPrefix, typePrefix);
args.push_back(get<1>(u)); args.push_back(get<1>(u));
params.push_back(make_pair(get<0>(u), get<2>(u))); params.push_back(make_pair(get<0>(u), get<2>(u)));
} }
else if (mode == Mode::Decode)
incoming += arg;
} }
string abiData; string abiData;
if (abiFile.empty()) if (!abiFile.empty())
abiData = contentsString(abiFile); abiData = contentsString(abiFile);
if (mode == Mode::Encode) if (mode == Mode::Encode)
@ -695,14 +707,31 @@ int main(int argc, char** argv)
try { try {
m = abi.method(method, args); m = abi.method(method, args);
} }
catch(...) catch (...)
{ {
cerr << "Unknown method in ABI." << endl; cerr << "Unknown method in ABI." << endl;
exit(-1); exit(-1);
} }
} }
try {
userOutput(cout, m.encode(params), encoding); userOutput(cout, m.encode(params), encoding);
} }
catch (ExpectedAdditionalParameter const&)
{
cerr << "Expected additional parameter in input." << endl;
exit(-1);
}
catch (ExpectedOpen const&)
{
cerr << "Expected open-bracket '[' in input." << endl;
exit(-1);
}
catch (ExpectedClose const&)
{
cerr << "Expected close-bracket ']' in input." << endl;
exit(-1);
}
}
else if (mode == Mode::Decode) else if (mode == Mode::Decode)
{ {
if (abiData.empty()) if (abiData.empty())
@ -725,9 +754,14 @@ int main(int argc, char** argv)
exit(-1); exit(-1);
} }
string encoded; string encoded;
if (incoming == "--" || incoming.empty())
for (int i = cin.get(); i != -1; i = cin.get()) for (int i = cin.get(); i != -1; i = cin.get())
encoded.push_back((char)i); encoded.push_back((char)i);
cout << m.decode(fromHex(encoded), outputIndex, prefs); else
{
encoded = contentsString(incoming);
}
cout << m.decode(fromHex(boost::trim_copy(encoded)), outputIndex, prefs) << endl;
} }
} }

3
libdevcore/vector_ref.h

@ -39,7 +39,8 @@ public:
size_t size() const { return m_count; } size_t size() const { return m_count; }
bool empty() const { return !m_count; } bool empty() const { return !m_count; }
vector_ref<_T> next() const { return vector_ref<_T>(m_data + m_count, m_count); } vector_ref<_T> next() const { return vector_ref<_T>(m_data + m_count, m_count); }
vector_ref<_T> cropped(size_t _begin, size_t _count = ~size_t(0)) const { if (m_data && _begin + std::max(size_t(0), _count) <= m_count) return vector_ref<_T>(m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count); else return vector_ref<_T>(); } vector_ref<_T> cropped(size_t _begin, size_t _count) const { if (m_data && _begin + _count <= m_count) return vector_ref<_T>(m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count); else return vector_ref<_T>(); }
vector_ref<_T> cropped(size_t _begin) const { if (m_data && _begin <= m_count) return vector_ref<_T>(m_data + _begin, m_count - _begin); else return vector_ref<_T>(); }
void retarget(_T* _d, size_t _s) { m_data = _d; m_count = _s; } void retarget(_T* _d, size_t _s) { m_data = _d; m_count = _s; }
void retarget(std::vector<_T> const& _t) { m_data = _t.data(); m_count = _t.size(); } void retarget(std::vector<_T> const& _t) { m_data = _t.data(); m_count = _t.size(); }
void copyTo(vector_ref<typename std::remove_const<_T>::type> _t) const { memcpy(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); } void copyTo(vector_ref<typename std::remove_const<_T>::type> _t) const { memcpy(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); }

6
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -79,7 +79,7 @@ static Json::Value toJson(dev::eth::Transaction const& _t)
Json::Value res; Json::Value res;
res["hash"] = toJS(_t.sha3()); res["hash"] = toJS(_t.sha3());
res["input"] = toJS(_t.data()); res["input"] = toJS(_t.data());
res["to"] = toJS(_t.receiveAddress()); res["to"] = _t.isCreation() ? Json::Value() : toJS(_t.receiveAddress());
res["from"] = toJS(_t.safeSender()); res["from"] = toJS(_t.safeSender());
res["gas"] = toJS(_t.gas()); res["gas"] = toJS(_t.gas());
res["gasPrice"] = toJS(_t.gasPrice()); res["gasPrice"] = toJS(_t.gasPrice());
@ -115,7 +115,7 @@ static Json::Value toJson(dev::eth::BlockInfo const& _bi, UncleHashes const& _us
static Json::Value toJson(dev::eth::TransactionSkeleton const& _t) static Json::Value toJson(dev::eth::TransactionSkeleton const& _t)
{ {
Json::Value res; Json::Value res;
res["to"] = toJS(_t.to); res["to"] = _t.creation ? Json::Value() : toJS(_t.to);
res["from"] = toJS(_t.from); res["from"] = toJS(_t.from);
res["gas"] = toJS(_t.gas); res["gas"] = toJS(_t.gas);
res["gasPrice"] = toJS(_t.gasPrice); res["gasPrice"] = toJS(_t.gasPrice);
@ -418,7 +418,7 @@ static TransactionSkeleton toTransaction(Json::Value const& _json)
if (!_json["from"].empty()) if (!_json["from"].empty())
ret.from = jsToAddress(_json["from"].asString()); ret.from = jsToAddress(_json["from"].asString());
if (!_json["to"].empty()) if (!_json["to"].empty() && _json["to"].asString() != "0x")
ret.to = jsToAddress(_json["to"].asString()); ret.to = jsToAddress(_json["to"].asString());
else else
ret.creation = true; ret.creation = true;

1
mix/CodeModel.cpp

@ -342,6 +342,7 @@ SolidityType CodeModel::nodeType(dev::solidity::Type const* _type)
r.type = SolidityType::Type::Bytes; r.type = SolidityType::Type::Bytes;
r.size = static_cast<unsigned>(b->getNumBytes()); r.size = static_cast<unsigned>(b->getNumBytes());
} }
break;
case Type::Category::Contract: case Type::Category::Contract:
r.type = SolidityType::Type::Address; r.type = SolidityType::Type::Address;
break; break;

36
mix/ContractCallDataEncoder.cpp

@ -80,28 +80,32 @@ unsigned ContractCallDataEncoder::encodeSingleItem(QVariant const& _data, Solidi
if ((src.startsWith("\"") && src.endsWith("\"")) || (src.startsWith("\'") && src.endsWith("\'"))) if ((src.startsWith("\"") && src.endsWith("\"")) || (src.startsWith("\'") && src.endsWith("\'")))
src = src.remove(src.length() - 1, 1).remove(0, 1); src = src.remove(src.length() - 1, 1).remove(0, 1);
QRegExp rx("[a-z]+");
if (src.startsWith("0x")) if (src.startsWith("0x"))
{ {
result = fromHex(src.toStdString().substr(2)); result = fromHex(src.toStdString().substr(2));
if (_type.type != SolidityType::Type::Bytes) if (_type.type != SolidityType::Type::Bytes)
result = padded(result, alignSize); result = padded(result, alignSize);
} }
else if (rx.indexIn(src.toLower(), 0) != -1)
{
QByteArray bytesAr = src.toLocal8Bit();
result = bytes(bytesAr.begin(), bytesAr.end());
}
else else
{
try
{ {
bigint i(src.toStdString()); bigint i(src.toStdString());
result = bytes(alignSize); result = bytes(alignSize);
toBigEndian((u256)i, result); toBigEndian((u256)i, result);
} }
catch (std::exception const& ex)
{
// manage input as a string.
QByteArray bytesAr = src.toLocal8Bit();
result = bytes(bytesAr.begin(), bytesAr.end());
result = paddedRight(result, alignSize);
}
}
unsigned dataSize = _type.dynamicSize ? result.size() : alignSize; unsigned dataSize = _type.dynamicSize ? result.size() : alignSize;
_dest.insert(_dest.end(), result.begin(), result.end()); _dest.insert(_dest.end(), result.begin(), result.end());
if (_dest.size() % alignSize != 0) if ((_dest.size() - 4) % alignSize != 0)
_dest.resize((_dest.size() & ~(alignSize - 1)) + alignSize); _dest.resize((_dest.size() & ~(alignSize - 1)) + alignSize);
return dataSize; return dataSize;
} }
@ -158,6 +162,10 @@ dev::bytes ContractCallDataEncoder::decodeBytes(dev::bytes const& _rawValue)
QString ContractCallDataEncoder::toString(dev::bytes const& _b) QString ContractCallDataEncoder::toString(dev::bytes const& _b)
{ {
QString str;
if (asString(_b, str))
return "\"" + str + "\" " + QString::fromStdString(dev::toJS(_b));
else
return QString::fromStdString(dev::toJS(_b)); return QString::fromStdString(dev::toJS(_b));
} }
@ -196,3 +204,17 @@ QStringList ContractCallDataEncoder::decode(QList<QVariableDeclaration*> const&
} }
return r; return r;
} }
bool ContractCallDataEncoder::asString(dev::bytes const& _b, QString& _str)
{
dev::bytes bunPad = unpadded(_b);
for (unsigned i = 0; i < bunPad.size(); i++)
{
if (bunPad.at(i) < 9 || bunPad.at(i) > 127)
return false;
else
_str += QString::fromStdString(dev::toJS(bunPad.at(i))).replace("0x", "");
}
return true;
}

1
mix/ContractCallDataEncoder.h

@ -66,6 +66,7 @@ private:
dev::bytes encodeBytes(QString const& _str); dev::bytes encodeBytes(QString const& _str);
dev::bytes decodeBytes(dev::bytes const& _rawValue); dev::bytes decodeBytes(dev::bytes const& _rawValue);
QString toString(dev::bytes const& _b); QString toString(dev::bytes const& _b);
bool asString(dev::bytes const& _b, QString& _str);
private: private:
bytes m_encodedData; bytes m_encodedData;

7
mix/qml/TransactionDialog.qml

@ -81,6 +81,7 @@ Window {
loadParameter(params[p]); loadParameter(params[p]);
} }
} }
initTypeLoader();
modalTransactionDialog.setX((Screen.width - width) / 2); modalTransactionDialog.setX((Screen.width - width) / 2);
modalTransactionDialog.setY((Screen.height - height) / 2); modalTransactionDialog.setY((Screen.height - height) / 2);
@ -126,11 +127,15 @@ Window {
} }
} }
} }
initTypeLoader();
}
function initTypeLoader()
{
typeLoader.value = {} typeLoader.value = {}
typeLoader.members = [] typeLoader.members = []
typeLoader.value = paramValues; typeLoader.value = paramValues;
typeLoader.members = paramsModel; typeLoader.members = paramsModel;
} }
function close() function close()

Loading…
Cancel
Save