Browse Source

Merge pull request #1520 from arkpar/az_load_rlp

Enable loading DApps by content uri in AZ
cl-refactor
Gav Wood 10 years ago
parent
commit
8d20e33321
  1. 24
      alethzero/DappLoader.cpp
  2. 2
      alethzero/MainWin.cpp
  3. 2
      mix/CMakeLists.txt
  4. 6
      mix/ClientModel.cpp
  5. 3
      mix/ClientModel.h
  6. 5
      mix/ContractCallDataEncoder.cpp
  7. 8
      mix/ContractCallDataEncoder.h
  8. 1
      mix/FileIo.cpp
  9. 5
      mix/MixApplication.cpp
  10. 84
      mix/Web3Server.cpp
  11. 2
      mix/Web3Server.h
  12. 23
      mix/qml/DeploymentDialog.qml
  13. 4
      mix/qml/LogsPane.qml
  14. 2
      mix/qml/ProjectModel.qml
  15. 6
      mix/qml/StatusPane.qml
  16. 1
      mix/qml/WebPreview.qml
  17. 42
      mix/qml/js/ProjectModel.js
  18. 16
      mix/qml/js/QEtherHelper.js

24
alethzero/DappLoader.cpp

@ -193,10 +193,26 @@ Manifest DappLoader::loadManifest(std::string const& _manifest)
void DappLoader::loadDapp(QString const& _uri)
{
DappLocation location = resolveAppUri(_uri);
QUrl uri(location.contentUri);
QNetworkRequest request(uri);
m_uriHashes[uri] = location.contentHash;
QUrl uri(_uri);
QUrl contentUri;
h256 hash;
if (uri.path().endsWith(".dapp") && uri.query().startsWith("hash="))
{
contentUri = uri;
QString query = uri.query();
query.remove("hash=");
if (!query.startsWith("0x"))
query.insert(0, "0x");
hash = jsToFixed<32>(query.toStdString());
}
else
{
DappLocation location = resolveAppUri(_uri);
contentUri = location.contentUri;
hash = location.contentHash;
}
QNetworkRequest request(contentUri);
m_uriHashes[uri] = hash;
m_net.get(request);
}

2
alethzero/MainWin.cpp

@ -900,7 +900,7 @@ void Main::on_urlEdit_returnPressed()
{
QString s = ui->urlEdit->text();
QUrl url(s);
if (url.scheme().isEmpty() || url.scheme() == "eth")
if (url.scheme().isEmpty() || url.scheme() == "eth" || url.path().endsWith(".dapp"))
{
try
{

2
mix/CMakeLists.txt

@ -29,7 +29,7 @@ else()
qt5_add_resources(UI_RESOURCES noweb.qrc)
endif()
if (CMAKE_BUILD_TYPE EQUAL "DEBUG")
if (CMAKE_BUILD_TYPE MATCHES Debug)
add_definitions(-DQT_QML_DEBUG)
endif()

6
mix/ClientModel.cpp

@ -139,6 +139,12 @@ QString ClientModel::newAddress()
return QString::fromStdString(toHex(a.secret().ref()));
}
QString ClientModel::encodeAbiString(QString _string)
{
ContractCallDataEncoder encoder;
return QString::fromStdString(toHex(encoder.encodeBytes(_string)));
}
QVariantMap ClientModel::contractAddresses() const
{
QVariantMap res;

3
mix/ClientModel.h

@ -155,7 +155,10 @@ public slots:
Q_INVOKABLE void debugRecord(unsigned _index);
/// Show the debugger for an empty record
Q_INVOKABLE void emptyRecord();
/// Generate new adress
Q_INVOKABLE QString newAddress();
/// Encode a string to ABI parameter. Returns a hex string
Q_INVOKABLE QString encodeAbiString(QString _string);
private slots:
/// Update UI with machine states result. Display a modal dialog.

5
mix/ContractCallDataEncoder.cpp

@ -110,11 +110,6 @@ unsigned ContractCallDataEncoder::encodeSingleItem(QVariant const& _data, Solidi
return dataSize;
}
void ContractCallDataEncoder::push(bytes const& _b)
{
m_encodedData.insert(m_encodedData.end(), _b.begin(), _b.end());
}
bigint ContractCallDataEncoder::decodeInt(dev::bytes const& _rawValue)
{
dev::u256 un = dev::fromBigEndian<dev::u256>(_rawValue);

8
mix/ContractCallDataEncoder.h

@ -52,8 +52,10 @@ public:
QVariant decode(SolidityType const& _type, bytes const& _value);
/// Get all encoded data encoded by encode function.
bytes encodedData();
/// Push the given @a _b to the current param context.
void push(bytes const& _b);
/// Encode a string to ABI bytes
dev::bytes encodeBytes(QString const& _str);
/// Decode bytes from ABI
dev::bytes decodeBytes(dev::bytes const& _rawValue);
private:
unsigned encodeSingleItem(QVariant const& _data, SolidityType const& _type, bytes& _dest);
@ -63,8 +65,6 @@ private:
dev::bytes encodeBool(QString const& _str);
bool decodeBool(dev::bytes const& _rawValue);
QString toString(bool _b);
dev::bytes encodeBytes(QString const& _str);
dev::bytes decodeBytes(dev::bytes const& _rawValue);
QString toString(dev::bytes const& _b);
bool asString(dev::bytes const& _b, QString& _str);

1
mix/FileIo.cpp

@ -196,6 +196,7 @@ QStringList FileIo::makePackage(QString const& _deploymentFolder)
QStringList ret;
ret.append(QString::fromStdString(toHex(dappHash.ref())));
ret.append(qFileBytes.toBase64());
ret.append(url.toString());
return ret;
}

5
mix/MixApplication.cpp

@ -36,6 +36,7 @@
#include "Clipboard.h"
#include "HttpServer.h"
extern int qInitResources_js();
using namespace dev::mix;
ApplicationService::ApplicationService()
@ -59,7 +60,6 @@ MixApplication::MixApplication(int& _argc, char* _argv[]):
}
}
void MixApplication::initialize()
{
#if __linux
@ -72,6 +72,9 @@ void MixApplication::initialize()
if (!getenv("OPENSSL_CONF"))
putenv((char*)"OPENSSL_CONF=c:\\");
#endif
#ifdef ETH_HAVE_WEBENGINE
qInitResources_js();
#endif
setOrganizationName(tr("Ethereum"));
setOrganizationDomain(tr("ethereum.org"));

84
mix/Web3Server.cpp

@ -23,13 +23,93 @@
#include <libdevcore/Exceptions.h>
#include <libdevcore/Log.h>
#include <libethereum/Interface.h>
#include <libwebthree/WebThree.h>
#include "Web3Server.h"
using namespace dev::mix;
using namespace dev;
namespace
{
class EmptyNetwork : public dev::WebThreeNetworkFace
{
std::vector<p2p::PeerSessionInfo> peers() override
{
return std::vector<p2p::PeerSessionInfo>();
}
size_t peerCount() const override
{
return 0;
}
void addNode(p2p::NodeId const& _node, bi::tcp::endpoint const& _hostEndpoint) override
{
(void)_node;
(void)_hostEndpoint;
}
void requirePeer(p2p::NodeId const& _node, bi::tcp::endpoint const& _endpoint) override
{
(void)_node;
(void)_endpoint;
}
dev::bytes saveNetwork() override
{
return dev::bytes();
}
void setIdealPeerCount(size_t _n) override
{
(void)_n;
}
bool haveNetwork() const override
{
return false;
}
void setNetworkPreferences(p2p::NetworkPreferences const& _n, bool _dropPeers) override
{
(void)_n;
(void)_dropPeers;
}
p2p::NodeId id() const override
{
return p2p::NodeId();
}
p2p::Peers nodes() const override
{
return p2p::Peers();
}
void startNetwork() override
{
}
void stopNetwork() override
{
}
bool isNetworkStarted() const override
{
return false;
}
};
}
Web3Server::Web3Server(jsonrpc::AbstractServerConnector& _conn, std::vector<dev::KeyPair> const& _accounts, dev::eth::Interface* _client):
WebThreeStubServerBase(_conn, _accounts),
m_client(_client)
m_client(_client),
m_network(new EmptyNetwork())
{
}
Web3Server::~Web3Server()
{
}
@ -40,7 +120,7 @@ std::shared_ptr<dev::shh::Interface> Web3Server::face()
dev::WebThreeNetworkFace* Web3Server::network()
{
BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::WebThreeNetworkFace"));
return m_network.get();
}
std::string Web3Server::get(std::string const& _name, std::string const& _key)

2
mix/Web3Server.h

@ -39,6 +39,7 @@ class Web3Server: public QObject, public dev::WebThreeStubServerBase, public dev
public:
Web3Server(jsonrpc::AbstractServerConnector& _conn, std::vector<dev::KeyPair> const& _accounts, dev::eth::Interface* _client);
virtual ~Web3Server();
signals:
void newTransaction();
@ -60,6 +61,7 @@ private:
private:
dev::eth::Interface* m_client;
std::map<std::string, std::string> m_db;
std::unique_ptr<dev::WebThreeNetworkFace> m_network;
};
}

23
mix/qml/DeploymentDialog.qml

@ -24,7 +24,8 @@ Window {
visible: false
property alias applicationUrlEth: applicationUrlEth.text
property alias applicationUrlHttp: applicationUrlHttp.text
property string urlHintContract: urlHintAddr.text
property alias urlHintContract: urlHintAddr.text
property alias localPackageUrl: localPackageUrl.text
property string packageHash
property string packageBase64
property string eth: registrarAddr.text
@ -131,8 +132,8 @@ Window {
var jsonRpcRequestId = 0;
requests.push({
jsonrpc: "2.0",
method: "eth_countAt",
params: [ currentAccount ],
method: "eth_getTransactionCount",
params: [ currentAccount, "pending" ],
id: jsonRpcRequestId++
});
TransactionHelper.rpcCall(requests, function (httpRequest, response){
@ -299,7 +300,7 @@ Window {
DefaultTextField
{
text: "20000"
text: "1000000"
Layout.preferredWidth: 350
id: gasToUseInput
}
@ -416,6 +417,20 @@ Window {
columns: 2
Layout.fillWidth: true
DefaultLabel
{
Layout.preferredWidth: 355
text: qsTr("Local package URL")
}
DefaultTextField
{
Layout.preferredWidth: 350
id: localPackageUrl
readOnly: true
enabled: rowRegister.isOkToRegister()
}
DefaultLabel
{
Layout.preferredWidth: 355

4
mix/qml/LogsPane.qml

@ -27,10 +27,6 @@ Rectangle
}
}
LogsPaneStyle {
id: logStyle
}
anchors.fill: parent
radius: 10
color: "transparent"

2
mix/qml/ProjectModel.qml

@ -160,7 +160,7 @@ Item {
}
MessageDialog {
id: deployRessourcesDialog
id: deployResourcesDialog
title: qsTr("Project")
standardButtons: StandardButton.Ok
}

6
mix/qml/StatusPane.qml

@ -231,7 +231,11 @@ Rectangle {
top = top.parent
var coordinates = logsContainer.mapToItem(top, 0, 0);
logsContainer.parent = top;
logsContainer.x = status.x + statusContainer.x - LogsPaneStyle.generic.layout.dateWidth - LogsPaneStyle.generic.layout.typeWidth + 70
logsContainer.x = status.x + statusContainer.x - logStyle.generic.layout.dateWidth - logStyle.generic.layout.typeWidth + 70
}
LogsPaneStyle {
id: logStyle
}
LogsPane

1
mix/qml/WebPreview.qml

@ -304,6 +304,7 @@ Item {
id: webView
experimental.settings.localContentCanAccessRemoteUrls: true
onJavaScriptConsoleMessage: {
console.log(sourceID + ":" + lineNumber + ": " + message);
webPreview.javaScriptMessage(level, sourceID, lineNumber, message);
}
onLoadingChanged: {

42
mix/qml/js/ProjectModel.js

@ -367,23 +367,8 @@ function startDeployProject(erasePrevious)
var ctrNames = Object.keys(codeModel.contracts);
var ctrAddresses = {};
setDefaultBlock(0, function() {
deployContracts(0, ctrAddresses, ctrNames, function (){
finalizeDeployment(deploymentId, ctrAddresses);
});
});
}
function setDefaultBlock(val, callBack)
{
var requests = [{
jsonrpc: "2.0",
method: "eth_setDefaultBlock",
params: [val],
id: 0
}];
rpcCall(requests, function (httpCall, response){
callBack();
deployContracts(0, ctrAddresses, ctrNames, function (){
finalizeDeployment(deploymentId, ctrAddresses);
});
}
@ -392,7 +377,7 @@ function deployContracts(ctrIndex, ctrAddresses, ctrNames, callBack)
var code = codeModel.contracts[ctrNames[ctrIndex]].codeHex;
var requests = [{
jsonrpc: "2.0",
method: "eth_transact",
method: "eth_sendTransaction",
params: [ { "from": deploymentDialog.currentAccount, "gas": deploymentDialog.gasToUse, "code": code } ],
id: 0
}];
@ -452,7 +437,8 @@ function finalizeDeployment(deploymentId, addresses) {
"\tinterface: " + codeModel.contracts[c].contractInterface + ",\n" +
"\taddress: \"" + addresses[c] + "\"\n" +
"};\n" +
contractAccessor + ".contract = web3.eth.contract(" + contractAccessor + ".address, " + contractAccessor + ".interface);\n";
contractAccessor + ".contractClass = web3.eth.contract(" + contractAccessor + ".interface);\n" +
contractAccessor + ".contract = new " + contractAccessor + ".contractClass(" + contractAccessor + ".address);\n";
}
fileIo.writeFile(deploymentDir + "deployment.js", deploymentJs);
deploymentAddresses = addresses;
@ -461,6 +447,7 @@ function finalizeDeployment(deploymentId, addresses) {
var packageRet = fileIo.makePackage(deploymentDir);
deploymentDialog.packageHash = packageRet[0];
deploymentDialog.packageBase64 = packageRet[1];
deploymentDialog.localPackageUrl = packageRet[2] + "?hash=" + packageRet[0];
var applicationUrlEth = deploymentDialog.applicationUrlEth;
@ -468,9 +455,8 @@ function finalizeDeployment(deploymentId, addresses) {
deploymentStepChanged(qsTr("Registering application on the Ethereum network ..."));
checkEthPath(applicationUrlEth, function () {
deploymentComplete();
deployRessourcesDialog.text = qsTr("Register Web Application to finalize deployment.");
deployRessourcesDialog.open();
setDefaultBlock(-1, function() {});
deployResourcesDialog.text = qsTr("Register Web Application to finalize deployment.");
deployResourcesDialog.open();
});
}
@ -567,7 +553,7 @@ function checkRegistration(dappUrl, addr, callBack)
requests.push({
jsonrpc: "2.0",
method: "eth_transact",
method: "eth_sendTransaction",
params: [ { "from": deploymentDialog.currentAccount, "gas": 20000, "code": "0x60056013565b61059e8061001d6000396000f35b33600081905550560060003560e060020a90048063019848921461009a578063449c2090146100af5780635d574e32146100cd5780635fd4b08a146100e1578063618242da146100f65780636be16bed1461010b5780636c4489b414610129578063893d20e8146101585780639607730714610173578063c284bc2a14610187578063e50f599a14610198578063e5811b35146101af578063ec7b9200146101cd57005b6100a560043561031b565b8060005260206000f35b6100ba6004356103a0565b80600160a060020a031660005260206000f35b6100db600435602435610537565b60006000f35b6100ec600435610529565b8060005260206000f35b6101016004356103dd565b8060005260206000f35b6101166004356103bd565b80600160a060020a031660005260206000f35b61013460043561034b565b82600160a060020a031660005281600160a060020a03166020528060405260606000f35b610160610341565b80600160a060020a031660005260206000f35b6101816004356024356102b4565b60006000f35b6101926004356103fd565b60006000f35b6101a96004356024356044356101f2565b60006000f35b6101ba6004356101eb565b80600160a060020a031660005260206000f35b6101d8600435610530565b80600160a060020a031660005260206000f35b6000919050565b600054600160a060020a031633600160a060020a031614610212576102af565b8160026000858152602001908152602001600020819055508061023457610287565b81600160a060020a0316837f680ad70765443c2967675ab0fb91a46350c01c6df59bf9a41ff8a8dd097464ec60006000a3826001600084600160a060020a03168152602001908152602001600020819055505b827f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b505050565b600054600160a060020a031633600160a060020a0316146102d457610317565b806002600084815260200190815260200160002060010181905550817f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b5050565b60006001600083600160a060020a03168152602001908152602001600020549050919050565b6000600054905090565b6000600060006002600085815260200190815260200160002054925060026000858152602001908152602001600020600101549150600260008581526020019081526020016000206002015490509193909250565b600060026000838152602001908152602001600020549050919050565b600060026000838152602001908152602001600020600101549050919050565b600060026000838152602001908152602001600020600201549050919050565b600054600160a060020a031633600160a060020a03161461041d57610526565b80600160006002600085815260200190815260200160002054600160a060020a031681526020019081526020016000205414610458576104d2565b6002600082815260200190815260200160002054600160a060020a0316817f680ad70765443c2967675ab0fb91a46350c01c6df59bf9a41ff8a8dd097464ec60006000a36000600160006002600085815260200190815260200160002054600160a060020a03168152602001908152602001600020819055505b6002600082815260200190815260200160002060008101600090556001810160009055600281016000905550807f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b50565b6000919050565b6000919050565b600054600160a060020a031633600160a060020a0316146105575761059a565b806002600084815260200190815260200160002060020181905550817f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b505056" } ],
id: jsonRpcRequestId++
});
@ -588,7 +574,7 @@ function checkRegistration(dappUrl, addr, callBack)
requests.push({
//setRegister()
jsonrpc: "2.0",
method: "eth_transact",
method: "eth_sendTransaction",
params: [ { "from": deploymentDialog.currentAccount, "gas": 30000, "to": '0x' + addr, "data": "0x96077307" + crLevel + deploymentDialog.pad(newCtrAddress) } ],
id: jsonRpcRequestId++
});
@ -617,12 +603,12 @@ function registerContentHash(registrar, callBack)
deploymentStepChanged(txt);
console.log(txt);
var requests = [];
var paramTitle = createString(projectModel.projectTitle);
var paramTitle = clientModel.encodeAbiString(projectModel.projectTitle);
requests.push({
//setContent()
jsonrpc: "2.0",
method: "eth_transact",
params: [ { "from": deploymentDialog.currentAccount, "gas": 30000, "gasPrice": "10", "to": '0x' + registrar, "data": "0x5d574e32" + paramTitle.encodeValueAsString() + deploymentDialog.packageHash } ],
method: "eth_sendTransaction",
params: [ { "from": deploymentDialog.currentAccount, "gas": 30000, "gasPrice": "10", "to": '0x' + registrar, "data": "0x5d574e32" + paramTitle + deploymentDialog.packageHash } ],
id: jsonRpcRequestId++
});
rpcCall(requests, function (httpRequest, response) {
@ -638,7 +624,7 @@ function registerToUrlHint()
requests.push({
//urlHint => suggestUrl
jsonrpc: "2.0",
method: "eth_transact",
method: "eth_sendTransaction",
params: [ { "to": '0x' + deploymentDialog.urlHintContract, "gas": 30000, "data": "0x4983e19c" + deploymentDialog.packageHash + paramUrlHttp.encodeValueAsString() } ],
id: jsonRpcRequestId++
});

16
mix/qml/js/QEtherHelper.js

@ -15,19 +15,3 @@ function createBigInt(_value)
return bigint;
}
function createString(_value)
{
var stringComponent = Qt.createComponent("qrc:/qml/QStringType.qml");
var stringC = stringComponent.createObject();
stringC.setValue(_value);
return stringC;
}
function createHash(_value)
{
var hComponent = Qt.createComponent("qrc:/qml/QHashType.qml");
var hC = hComponent.createObject();
hC.setValue(_value);
return hC;
}

Loading…
Cancel
Save