@ -20,6 +20,7 @@
* Ethereum IDE client .
* /
Qt . include ( "QEtherHelper.js" )
Qt . include ( "TransactionHelper.js" )
var htmlTemplate = "<html>\n<head>\n<script>\n</script>\n</head>\n<body>\n<script>\n</script>\n</body>\n</html>" ;
var contractTemplate = "contract Contract {\n}\n" ;
@ -50,7 +51,8 @@ function saveProject() {
applicationUrlEth : deploymentDialog . applicationUrlEth ,
applicationUrlHttp : deploymentDialog . applicationUrlHttp ,
packageHash : deploymentDialog . packageHash ,
packageBase64 : deploymentDialog . packageBase64
packageBase64 : deploymentDialog . packageBase64 ,
deploymentDir : projectModel . deploymentDir
} ;
for ( var i = 0 ; i < projectListModel . count ; i ++ )
projectData . files . push ( projectListModel . get ( i ) . fileName )
@ -68,6 +70,8 @@ function loadProject(path) {
var projectFile = path + projectFileName ;
var json = fileIo . readFile ( projectFile ) ;
var projectData = JSON . parse ( json ) ;
if ( projectData . deploymentDir )
projectModel . deploymentDir = projectData . deploymentDir
if ( projectData . packageHash )
deploymentDialog . packageHash = projectData . packageHash
if ( projectData . packageBase64 )
@ -289,6 +293,7 @@ function deployProject(force) {
deploymentDialog . open ( ) ;
}
var codeTest = "" ;
function startDeployProject ( erasePrevious )
{
var date = new Date ( ) ;
@ -309,12 +314,13 @@ function startDeployProject(erasePrevious)
for ( var c in codeModel . contracts ) { //TODO: order based on dependencies
var code = codeModel . contracts [ c ] . codeHex ;
requests . push ( {
jsonrpc : "2.0" ,
method : "eth_transact" ,
params : [ { "code" : code } ] ,
id : jsonRpcRequestId ++
} ) ;
jsonrpc : "2.0" ,
method : "eth_transact" ,
params : [ { "from" : deploymentDialog . currentAccount , "gas" : 20000 , " code" : code /* "0x60056013565b61059e8061001d6000396000f35b33600081905550560060003560e060020a90048063019848921461009a578063449c2090146100af5780635d574e32146100cd5780635fd4b08a146100e1578063618242da146100f65780636be16bed1461010b5780636c4489b414610129578063893d20e8146101585780639607730714610173578063c284bc2a14610187578063e50f599a14610198578063e5811b35146101af578063ec7b9200146101cd57005b6100a560043561031b565b8060005260206000f35b6100ba6004356103a0565b80600160a060020a031660005260206000f35b6100db600435602435610537565b60006000f35b6100ec600435610529565b8060005260206000f35b6101016004356103dd565b8060005260206000f35b6101166004356103bd565b80600160a060020a031660005260206000f35b61013460043561034b565b82600160a060020a031660005281600160a060020a03166020528060405260606000f35b610160610341565b80600160a060020a031660005260206000f35b6101816004356024356102b4565b60006000f35b6101926004356103fd565b60006000f35b6101a96004356024356044356101f2565b60006000f35b6101ba6004356101eb565b80600160a060020a031660005260206000f35b6101d8600435610530565b80600160a060020a031660005260206000f35b6000919050565b600054600160a060020a031633600160a060020a031614610212576102af565b8160026000858152602001908152602001600020819055508061023457610287565b81600160a060020a0316837f680ad70765443c2967675ab0fb91a46350c01c6df59bf9a41ff8a8dd097464ec60006000a3826001600084600160a060020a03168152602001908152602001600020819055505b827f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b505050565b600054600160a060020a031633600160a060020a0316146102d457610317565b806002600084815260200190815260200160002060010181905550817f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b5050565b60006001600083600160a060020a03168152602001908152602001600020549050919050565b6000600054905090565b6000600060006002600085815260200190815260200160002054925060026000858152602001908152602001600020600101549150600260008581526020019081526020016000206002015490509193909250565b600060026000838152602001908152602001600020549050919050565b600060026000838152602001908152602001600020600101549050919050565b600060026000838152602001908152602001600020600201549050919050565b600054600160a060020a031633600160a060020a03161461041d57610526565b80600160006002600085815260200190815260200160002054600160a060020a031681526020019081526020016000205414610458576104d2565b6002600082815260200190815260200160002054600160a060020a0316817f680ad70765443c2967675ab0fb91a46350c01c6df59bf9a41ff8a8dd097464ec60006000a36000600160006002600085815260200190815260200160002054600160a060020a03168152602001908152602001600020819055505b6002600082815260200190815260200160002060008101600090556001810160009055600281016000905550807f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b50565b6000919050565b6000919050565b600054600160a060020a031633600160a060020a0316146105575761059a565b806002600084815260200190815260200160002060020181905550817f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b505056" */ } ] ,
id : jsonRpcRequestId ++
} ) ;
requestNames . push ( c ) ;
codeTest = code ;
}
var rpcRequest = JSON . stringify ( requests ) ;
@ -327,11 +333,18 @@ function startDeployProject(erasePrevious)
if ( httpRequest . readyState === XMLHttpRequest . DONE ) {
if ( httpRequest . status === 200 ) {
var rpcResponse = JSON . parse ( httpRequest . responseText ) ;
console . log ( "crea" + httpRequest . responseText ) ;
if ( rpcResponse . length === requestNames . length ) {
var contractAddresses = { } ;
for ( var r = 0 ; r < rpcResponse . length ; r ++ )
contractAddresses [ requestNames [ r ] ] = rpcResponse [ r ] . result ;
finalizeDeployment ( deploymentId , contractAddresses ) ;
var txt = qsTr ( "Please wait while the contract is published ..." )
deploymentStepChanged ( txt ) ;
console . log ( txt ) ;
deploymentDialog . waitForTrCountToIncrement ( function ( ) {
finalizeDeployment ( deploymentId , contractAddresses ) ;
} ) ;
}
} else {
var errorText = qsTr ( "Deployment error: RPC server HTTP status " ) + httpRequest . status ;
@ -346,6 +359,7 @@ function startDeployProject(erasePrevious)
function finalizeDeployment ( deploymentId , addresses ) {
deploymentStepChanged ( qsTr ( "Packaging application ..." ) ) ;
var deploymentDir = projectPath + deploymentId + "/" ;
projectModel . deploymentDir = deploymentDir ;
fileIo . makeDir ( deploymentDir ) ;
for ( var i = 0 ; i < projectListModel . count ; i ++ ) {
var doc = projectListModel . get ( i ) ;
@ -372,16 +386,16 @@ function finalizeDeployment(deploymentId, addresses) {
}
//write deployment js
var deploymentJs =
"// Autogenerated by Mix\n" +
"web3 = require(\"web3\");\n" +
"contracts = {};\n" ;
"// Autogenerated by Mix\n" +
"web3 = require(\"web3\");\n" +
"contracts = {};\n" ;
for ( var c in codeModel . contracts ) {
var contractAccessor = "contracts[\"" + codeModel . contracts [ c ] . contract . name + "\"]" ;
deploymentJs += contractAccessor + " = {\n" +
"\tinterface: " + codeModel . contracts [ c ] . contractInterface + ",\n" +
"\taddress: \"" + addresses [ c ] + "\"\n" +
"};\n" +
contractAccessor + ".contract = web3.eth.contract(" + contractAccessor + ".address, " + contractAccessor + ".interface);\n" ;
"\tinterface: " + codeModel . contracts [ c ] . contractInterface + ",\n" +
"\taddress: \"" + addresses [ c ] + "\"\n" +
"};\n" +
contractAccessor + ".contract = web3.eth.contract(" + contractAccessor + ".address, " + contractAccessor + ".interface);\n" ;
}
fileIo . writeFile ( deploymentDir + "deployment.js" , deploymentJs ) ;
//copy scripts
@ -398,135 +412,181 @@ function finalizeDeployment(deploymentId, addresses) {
applicationUrlEth = formatAppUrl ( applicationUrlEth ) ;
deploymentStepChanged ( qsTr ( "Registering application on the Ethereum network ..." ) ) ;
checkRegistration ( applicationUrlEth , deploymentDialog . eth , function ( ) {
applicationUrlEth . splice ( 0 , 1 ) ; //Remove eth (already exists).
applicationUrlEth . push ( projectModel . projectTitle ) ;
checkEthPath ( applicationUrlEth , function ( ) {
deploymentComplete ( ) ;
deployRessourcesDialog . text = qsTr ( "Register Web Application to finalize deployment." ) ;
deployRessourcesDialog . open ( ) ;
} ) ;
}
function rpcCall ( requests , callBack )
function checkEthPath ( dappUrl , callBack )
{
var jsonRpcUrl = "http://localhost:8080" ;
var rpcRequest = JSON . stringify ( requests ) ;
var httpRequest = new XMLHttpRequest ( ) ;
httpRequest . open ( "POST" , jsonRpcUrl , true ) ;
httpRequest . setRequestHeader ( "Content-type" , "application/json" ) ;
httpRequest . setRequestHeader ( "Content-length" , rpcRequest . length ) ;
httpRequest . setRequestHeader ( "Connection" , "close" ) ;
httpRequest . onreadystatechange = function ( ) {
if ( httpRequest . readyState === XMLHttpRequest . DONE ) {
if ( httpRequest . status !== 200 )
{
var errorText = qsTr ( "Deployment error: Error while registering Dapp " ) + httpRequest . status ;
console . log ( errorText ) ;
deploymentError ( errorText ) ;
return ;
}
callBack ( httpRequest . status , httpRequest . responseText )
var str = createString ( dappUrl [ 0 ] ) ;
var requests = [ ] ;
console . log ( " ggg " + deploymentDialog . currentAccount ) ;
console . log ( " ggg " + deploymentDialog . eth ) ;
requests . push ( {
//register()
jsonrpc : "2.0" ,
method : "eth_call" ,
params : [ { "from" : deploymentDialog . currentAccount , "to" : '0x' + deploymentDialog . eth , "data" : "0x6be16bed" + str . encodeValueAsString ( ) } ] ,
id : jsonRpcRequestId ++
} ) ;
rpcCall ( requests , function ( httpRequest , response ) {
console . log ( "checking in path eth: found " + response ) ;
var res = JSON . parse ( response ) ;
var addr = normalizeAddress ( res [ 0 ] . result ) ;
if ( addr === "" )
{
var errorTxt = qsTr ( "Path does not exists " + JSON . stringify ( dappUrl ) + ". Please register using Registration Dapp. Aborting." ) ;
deploymentError ( errorTxt ) ;
console . log ( errorTxt ) ;
}
}
httpRequest . send ( rpcRequest ) ;
else
{
dappUrl . splice ( 0 , 1 ) ;
checkRegistration ( dappUrl , addr , callBack ) ;
}
} ) ;
}
function checkRegistration ( dappUrl , addr , callBack )
{
var txt = qsTr ( "Checking " + JSON . stringify ( dappUrl ) + " ... in registrar " + addr ) ;
deploymentStepChanged ( txt ) ;
console . log ( txt ) ;
var requests = [ ] ;
var data = "" ;
if ( dappUrl . length > 0 )
{
//checking path (register).
var str = createString ( dappUrl [ 0 ] ) ;
data = "0x6be16bed" + str . encodeValueAsString ( ) ;
console . log ( "checking if path exists (register) => " + JSON . stringify ( dappUrl ) ) ;
requests . push ( {
jsonrpc : "2.0" ,
method : "eth_call" ,
params : [ { "to" : '0x' + addr , "data" : data } ] ,
id : jsonRpcRequestId ++
} ) ;
rpcCall ( requests , function ( httpRequest , response ) {
var address = JSON . parse ( response ) [ 0 ] . result . replace ( '0x' , '' ) ;
if ( address === "" )
{
var errorTxt = qsTr ( "Path does not exists " + JSON . stringify ( dappUrl ) + " cannot continue" ) ;
deploymentError ( errorTxt ) ;
console . log ( errorTxt ) ;
return ;
}
dappUrl . splice ( 0 , 1 ) ;
checkRegistration ( dappUrl , address , callBack ) ;
} ) ;
}
else
{
var paramTitle = createString ( projectModel . projectTitle ) ;
requests . push ( {
//owner()
jsonrpc : "2.0" ,
method : "eth_call" ,
params : [ { "to" : '0x' + addr , "data" : "0xec7b9200" + paramTitle . encodeValueAsString ( ) } ] ,
id : jsonRpcRequestId ++
} ) ;
var registrar = { }
var str = createString ( dappUrl [ 0 ] ) ;
requests . push ( {
//getOwner()
jsonrpc : "2.0" ,
method : "eth_call" ,
params : [ { "from" : deploymentDialog . currentAccount , "to" : '0x' + addr , "data" : "0x893d20e8" } ] ,
id : jsonRpcRequestId ++
} ) ;
requests . push ( {
//accounts
jsonrpc : "2.0" ,
method : "eth_accounts " ,
params : null ,
id : jsonRpcRequestId ++
} ) ;
requests . push ( {
//register()
jsonrpc : "2.0" ,
method : "eth_call" ,
params : [ { "from" : deploymentDialog . currentAccount , "to" : '0x' + addr , "data" : "0x6be16bed" + str . encodeValueAsString ( ) } ] ,
id : jsonRpcRequestId ++
} ) ;
rpcCall ( requests , function ( httpRequest , response ) {
rpcCall ( requests , function ( httpRequest , response ) {
console . log ( " >> " + response ) ;
var res = JSON . parse ( response ) ;
var nextAddr = normalizeAddress ( res [ 1 ] . result ) ;
var errorTxt ;
if ( res [ 1 ] . result === "0x" )
{
errorTxt = qsTr ( "Error when creating new owned path. Please use the regsitration Dapp. Aborting" ) ;
deploymentError ( errorTxt ) ;
console . log ( errorTxt ) ;
}
else if ( normalizeAddress ( deploymentDialog . currentAccount ) !== normalizeAddress ( res [ 0 ] . result ) )
{
errorTxt = qsTr ( "You are not the owner of " + dappUrl [ 0 ] + ". Aborting" ) ;
deploymentError ( errorTxt ) ;
console . log ( errorTxt ) ;
}
else if ( nextAddr !== "" )
{
dappUrl . splice ( 0 , 1 ) ;
if ( dappUrl . length > 0 )
checkRegistration ( dappUrl , nextAddr , callBack ) ;
else
registerContentHash ( addr , callBack ) ;
}
else
{
var txt = qsTr ( "Creating sub domain " + dappUrl [ 0 ] + " ..." ) ;
console . log ( txt ) ;
deploymentStepChanged ( txt ) ;
//current registrar is owned => ownedregistrar creation and continue.
requests = [ ] ;
var res = JSON . parse ( response ) ;
var currentOwner = res [ 0 ] . result ;
var noOwner = currentOwner . replace ( '0x' , '' ) . replace ( /0/g , '' ) === '' ;
if ( noOwner )
{
requests . push ( {
//reserve()
requests . push ( {
jsonrpc : "2.0" ,
method : "eth_transact" ,
params : [ { "to" : '0x' + addr , "data" : "0x1c83171b" + paramTitle . encodeValueAsString ( ) } ] ,
params : [ { "from" : deploymentDialog . currentAccount , "gas" : 20000 , "code" : "0x60056013565b61059e8061001d6000396000f35b33600081905550560060003560e060020a90048063019848921461009a578063449c2090146100af5780635d574e32146100cd5780635fd4b08a146100e1578063618242da146100f65780636be16bed1461010b5780636c4489b414610129578063893d20e8146101585780639607730714610173578063c284bc2a14610187578063e50f599a14610198578063e5811b35146101af578063ec7b9200146101cd57005b6100a560043561031b565b8060005260206000f35b6100ba6004356103a0565b80600160a060020a031660005260206000f35b6100db600435602435610537565b60006000f35b6100ec600435610529565b8060005260206000f35b6101016004356103dd565b8060005260206000f35b6101166004356103bd565b80600160a060020a031660005260206000f35b61013460043561034b565b82600160a060020a031660005281600160a060020a03166020528060405260606000f35b610160610341565b80600160a060020a031660005260206000f35b6101816004356024356102b4565b60006000f35b6101926004356103fd565b60006000f35b6101a96004356024356044356101f2565b60006000f35b6101ba6004356101eb565b80600160a060020a031660005260206000f35b6101d8600435610530565b80600160a060020a031660005260206000f35b6000919050565b600054600160a060020a031633600160a060020a031614610212576102af565b8160026000858152602001908152602001600020819055508061023457610287565b81600160a060020a0316837f680ad70765443c2967675ab0fb91a46350c01c6df59bf9a41ff8a8dd097464ec60006000a3826001600084600160a060020a03168152602001908152602001600020819055505b827f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b505050565b600054600160a060020a031633600160a060020a0316146102d457610317565b806002600084815260200190815260200160002060010181905550817f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b5050565b60006001600083600160a060020a03168152602001908152602001600020549050919050565b6000600054905090565b6000600060006002600085815260200190815260200160002054925060026000858152602001908152602001600020600101549150600260008581526020019081526020016000206002015490509193909250565b600060026000838152602001908152602001600020549050919050565b600060026000838152602001908152602001600020600101549050919050565b600060026000838152602001908152602001600020600201549050919050565b600054600160a060020a031633600160a060020a03161461041d57610526565b80600160006002600085815260200190815260200160002054600160a060020a031681526020019081526020016000205414610458576104d2565b6002600082815260200190815260200160002054600160a060020a0316817f680ad70765443c2967675ab0fb91a46350c01c6df59bf9a41ff8a8dd097464ec60006000a36000600160006002600085815260200190815260200160002054600160a060020a03168152602001908152602001600020819055505b6002600082815260200190815260200160002060008101600090556001810160009055600281016000905550807f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b50565b6000919050565b6000919050565b600054600160a060020a031633600160a060020a0316146105575761059a565b806002600084815260200190815260200160002060020181905550817f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b505056" } ] ,
id : jsonRpcRequestId ++
} ) ;
}
else
{
var bOwner = false ;
currentOwner = normalizeAddress ( currentOwner ) ;
for ( var u in res [ 1 ] . result )
{
if ( normalizeAddress ( res [ 1 ] . result [ u ] ) === currentOwner )
bOwner = true ;
}
if ( ! bOwner )
{
var errorTxt = qsTr ( "Current user is not the owner of this path. Cannot continue" )
deploymentError ( errorTxt ) ;
console . log ( errorTxt ) ;
return ;
}
}
console . log ( "setContentHash" ) ;
requests . push ( {
//setContent()
jsonrpc : "2.0" ,
method : "eth_transact" ,
params : [ { "to" : '0x' + addr , "data" : "0x5d574e32" + paramTitle . encodeValueAsString ( ) + deploymentDialog . packageHash } ] ,
id : jsonRpcRequestId ++
} ) ;
rpcCall ( requests , function ( httpRequest , response ) {
callBack ( ) ;
rpcCall ( requests , function ( httpRequest , response ) {
console . log ( "crea2" + response ) ;
var newCtrAddress = normalizeAddress ( JSON . parse ( response ) [ 0 ] . result ) ;
requests = [ ] ;
console . log ( 'new created addr ' + newCtrAddress ) ;
var txt = qsTr ( "Please wait while " + dappUrl [ 0 ] + " is creating ..." ) ;
deploymentStepChanged ( txt ) ;
console . log ( txt ) ;
deploymentDialog . waitForTrCountToIncrement ( function ( ) {
var crLevel = createString ( dappUrl [ 0 ] ) . encodeValueAsString ( ) ;
console . log ( "registering " + dappUrl [ 0 ] ) ;
requests . push ( {
//setRegister()
jsonrpc : "2.0" ,
method : "eth_transact" ,
params : [ { "from" : deploymentDialog . currentAccount , "gas" : 2000 , "to" : '0x' + addr , "data" : "0x96077307" + crLevel + deploymentDialog . pad ( newCtrAddress ) } ] ,
id : jsonRpcRequestId ++
} ) ;
rpcCall ( requests , function ( ) {
dappUrl . splice ( 0 , 1 ) ;
if ( dappUrl . length > 0 )
checkRegistration ( dappUrl , newCtrAddress , callBack ) ;
else
registerContentHash ( addr , callBack ) ;
} ) ;
} ) ;
} ) ;
} ) ;
}
}
} ) ;
}
var filterId ;
function createFilter ( callBack )
{
var requests = [ ] ;
var jsonRpcRequestId = 0 ;
requests . push ( {
jsonrpc : "2.0" ,
method : "eth_newFilterString" ,
params : [ "pending" ] ,
id : jsonRpcRequestId ++
} ) ;
rpcCall ( requests , function ( httpRequest , response ) {
console . log ( response ) ;
filterId = JSON . parse ( response ) [ 0 ] . result ;
callBack ( filterId ) ;
} )
}
function registerContentHash ( registrar , callBack )
{
var txt = qsTr ( "Finalizing Dapp registration ..." ) ;
deploymentStepChanged ( txt ) ;
console . log ( txt ) ;
var requests = [ ] ;
var paramTitle = createString ( projectModel . projectTitle ) ;
requests . push ( {
//setContent()
jsonrpc : "2.0" ,
method : "eth_transact" ,
params : [ { "from" : deploymentDialog . currentAccount , "gas" : "2000" , "gasPrice" : "10" , "to" : '0x' + registrar , "data" : "0x5d574e32" + paramTitle . encodeValueAsString ( ) + deploymentDialog . packageHash } ] ,
id : jsonRpcRequestId ++
} ) ;
rpcCall ( requests , function ( httpRequest , response ) {
callBack ( ) ;
} ) ;
}
function registerToUrlHint ( )
@ -535,12 +595,12 @@ function registerToUrlHint()
var requests = [ ] ;
var paramUrlHttp = createString ( deploymentDialog . applicationUrlHttp ) ;
requests . push ( {
//urlHint => suggestUrl
jsonrpc : "2.0" ,
method : "eth_transact" ,
params : [ { "to" : '0x' + deploymentDialog . urlHintContract , "data" : "0x4983e19c" + deploymentDialog . packageHash + paramUrlHttp . encodeValueAsString ( ) } ] ,
id : jsonRpcRequestId ++
} ) ;
//urlHint => suggestUrl
jsonrpc : "2.0" ,
method : "eth_transact" ,
params : [ { "to" : '0x' + deploymentDialog . urlHintContract , "data" : "0x4983e19c" + deploymentDialog . packageHash + paramUrlHttp . encodeValueAsString ( ) } ] ,
id : jsonRpcRequestId ++
} ) ;
rpcCall ( requests , function ( httpRequest , response ) {
deploymentComplete ( ) ;
@ -556,7 +616,7 @@ function normalizeAddress(addr)
if ( addr [ k ] !== "0" )
break ;
else
i ++ ;
i ++ ;
}
return addr . substring ( i ) ;
}
@ -586,4 +646,3 @@ function formatAppUrl(url)
return ret ;
}
}