Commit 7286c9a3 authored by chriseth's avatar chriseth Committed by GitHub

Merge pull request #380 from ethereum/publish-button

Introduce (metadata) publish button
parents 199a2be9 bd0a6eac
...@@ -173,12 +173,18 @@ ...@@ -173,12 +173,18 @@
.udapp input, .udapp input,
.udapp button { .udapp button {
width: 33%; width: 20%;
display: block; display: block;
float: left; float: left;
padding: 0.25em; padding: 0.25em;
} }
.udapp button:disabled {
cursor: not-allowed;
background-color: white;
border-color: lightgray;
}
.udapp .atAddress { .udapp .atAddress {
background-color: #B1EAC5; background-color: #B1EAC5;
border-color: #B1EAC5; border-color: #B1EAC5;
...@@ -186,6 +192,13 @@ ...@@ -186,6 +192,13 @@
border-radius: 3px; border-radius: 3px;
} }
.udapp .publishContract {
background-color: #EC96EC;
border-color: #EC96EC;
margin-right: 1em;
border-radius: 3px;
}
.udapp input { .udapp input {
border-left: 0 none; border-left: 0 none;
} }
...@@ -312,6 +325,10 @@ ...@@ -312,6 +325,10 @@
width: 1em; width: 1em;
} }
.udapp .legend .publish:before {
background-color: #EC96EC;
}
.udapp .legend .attach:before { .udapp .legend .attach:before {
background-color: #B1EAC5; background-color: #B1EAC5;
} }
......
/* global alert, confirm, prompt, FileReader, Option, Worker, chrome */ /* global alert, confirm, prompt, FileReader, Option, Worker, chrome */
'use strict' 'use strict'
var async = require('async')
var $ = require('jquery') var $ = require('jquery')
var base64 = require('js-base64').Base64 var base64 = require('js-base64').Base64
var swarmgw = require('swarmgw') var swarmgw = require('swarmgw')
...@@ -646,6 +647,69 @@ var run = function () { ...@@ -646,6 +647,69 @@ var run = function () {
startdebugging(txResult.transactionHash) startdebugging(txResult.transactionHash)
}) })
function swarmVerifiedPublish (content, expectedHash, cb) {
swarmgw.put(content, function (err, ret) {
if (err) {
cb(err)
} else if (ret !== expectedHash) {
cb('Hash mismatch')
} else {
cb()
}
})
}
function publishOnSwarm (contract, cb) {
// gather list of files to publish
var sources = []
sources.push({
content: contract.metadata,
hash: contract.metadataHash
})
var metadata
try {
metadata = JSON.parse(contract.metadata)
} catch (e) {
return cb(e)
}
if (metadata === undefined) {
return cb('No metadata')
}
Object.keys(metadata.sources).forEach(function (fileName) {
// find hash
var hash
try {
hash = metadata.sources[fileName].urls[0].match('bzzr://(.+)')[1]
} catch (e) {
return cb('Metadata inconsistency')
}
sources.push({
content: files.get(fileName),
hash: hash
})
})
// publish the list of sources in order, fail if any failed
async.eachSeries(sources, function (item, cb) {
swarmVerifiedPublish(item.content, item.hash, cb)
}, cb)
}
udapp.event.register('publishContract', this, function (contract) {
publishOnSwarm(contract, function (err) {
if (err) {
alert('Failed to publish metadata: ' + err)
} else {
alert('Metadata published successfully')
}
})
})
// ----------------- Renderer ----------------- // ----------------- Renderer -----------------
var transactionContextAPI = { var transactionContextAPI = {
getAddress: (cb) => { getAddress: (cb) => {
......
...@@ -72,23 +72,25 @@ Renderer.prototype.error = function (message, container, options) { ...@@ -72,23 +72,25 @@ Renderer.prototype.error = function (message, container, options) {
} }
Renderer.prototype.contracts = function (data, source) { Renderer.prototype.contracts = function (data, source) {
var retrieveMetadataHash = function (bytecode) {
var match = /a165627a7a72305820([0-9a-f]{64})0029$/.exec(bytecode)
if (match) {
return match[1]
}
}
var udappContracts = [] var udappContracts = []
for (var contractName in data.contracts) { for (var contractName in data.contracts) {
var contract = data.contracts[contractName] var contract = data.contracts[contractName]
udappContracts.push({ udappContracts.push({
name: contractName, name: contractName,
interface: contract['interface'], interface: contract['interface'],
bytecode: contract.bytecode bytecode: contract.bytecode,
metadata: contract.metadata,
metadataHash: contract.bytecode && retrieveMetadataHash(contract.bytecode)
}) })
} }
var retrieveMetadataHash = function (bytecode) {
var match = /a165627a7a72305820([0-9a-f]{64})0029$/.exec(bytecode)
if (match) {
return match[1]
}
}
var tableRowItems = function (first, second, cls) { var tableRowItems = function (first, second, cls) {
return $('<div class="crow"/>') return $('<div class="crow"/>')
.addClass(cls) .addClass(cls)
......
...@@ -146,6 +146,7 @@ UniversalDApp.prototype.render = function () { ...@@ -146,6 +146,7 @@ UniversalDApp.prototype.render = function () {
} }
var $legend = $('<div class="legend" />') var $legend = $('<div class="legend" />')
.append($('<div class="publish"/>').text('Publish'))
.append($('<div class="attach"/>').text('Attach')) .append($('<div class="attach"/>').text('Attach'))
.append($('<div class="transact"/>').text('Transact')) .append($('<div class="transact"/>').text('Transact'))
.append($('<div class="payable"/>').text('Transact (Payable)')) .append($('<div class="payable"/>').text('Transact (Payable)'))
...@@ -189,6 +190,10 @@ UniversalDApp.prototype.getCreateInterface = function ($container, contract) { ...@@ -189,6 +190,10 @@ UniversalDApp.prototype.getCreateInterface = function ($container, contract) {
$close.click(function () { self.$el.remove() }) $close.click(function () { self.$el.remove() })
$createInterface.append($close) $createInterface.append($close)
} }
var $publishButton = $('<button class="publishContract"/>').text('Publish').click(function () { self.event.trigger('publishContract', [contract]) })
$createInterface.append($publishButton)
var $atButton = $('<button class="atAddress"/>').text('At Address').click(function () { self.clickContractAt(self, $container.find('.createContract'), contract) }) var $atButton = $('<button class="atAddress"/>').text('At Address').click(function () { self.clickContractAt(self, $container.find('.createContract'), contract) })
$createInterface.append($atButton) $createInterface.append($atButton)
...@@ -211,6 +216,11 @@ UniversalDApp.prototype.getCreateInterface = function ($container, contract) { ...@@ -211,6 +216,11 @@ UniversalDApp.prototype.getCreateInterface = function ($container, contract) {
$createButton.attr('title', 'This contract does not implement all functions and thus cannot be created.') $createButton.attr('title', 'This contract does not implement all functions and thus cannot be created.')
} }
if (contract.metadata.length === 0) {
$publishButton.attr('disabled', 'disabled')
$publishButton.attr('title', 'This contract does not implement all functions and thus cannot be published.')
}
return $createInterface return $createInterface
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment