diff --git a/lib/components/Web3Utilities/index.js b/lib/components/Web3Utilities/index.js
new file mode 100644
index 0000000..f2c6427
--- /dev/null
+++ b/lib/components/Web3Utilities/index.js
@@ -0,0 +1,209 @@
+'use babel'
+// Copyright 2018 Etheratom Authors
+// This file is part of Etheratom.
+
+// Etheratom is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Etheratom is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Etheratom. If not, see
.
+import React from 'react'
+import { connect } from 'react-redux'
+import { Collapse } from 'react-collapse'
+import ReactJson from 'react-json-view'
+import VirtualList from 'react-tiny-virtual-list'
+
+class Web3Utilities extends React.Component {
+ constructor(props) {
+ super(props);
+ this.helpers = props.helpers;
+ this.state = {
+ input: null,
+ output: null
+ };
+ this._hexToUtf8 = this._hexToUtf8.bind(this);
+ this._handleInputChange = this._handleInputChange.bind(this);
+ this._toHex = this._toHex.bind(this);
+ this._toChecksumAddress = this._toChecksumAddress.bind(this);
+ this._hexToBytes = this._hexToBytes.bind(this);
+ this._hexToNumber = this._hexToNumber.bind(this);
+ this._bytesToHex = this._bytesToHex.bind(this);
+ this._padLeft32 = this._padLeft32.bind(this);
+ this._padRight32 = this._padRight32.bind(this);
+ this._padLeft64 = this._padLeft64.bind(this);
+ this._padRight64 = this._padRight64.bind(this);
+ this._hexToAscii = this._hexToAscii.bind(this);
+ }
+ _handleInputChange(event) {
+ this.setState({ input: event.target.value });
+ }
+ async _hexToUtf8() {
+ try {
+ const { input } = this.state;
+ const decoded = await this.helpers.hexToUtf8(input);
+ this.setState({ output: decoded });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ async _hexToAscii() {
+ try {
+ const { input } = this.state;
+ const ascii = await this.helpers.hexToAscii(input);
+ this.setState({ output: ascii });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ async _toHex() {
+ try {
+ const { input } = this.state;
+ const encoded = await this.helpers.toHex(input);
+ this.setState({ output: encoded });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ async _toChecksumAddress() {
+ try {
+ const { input } = this.state;
+ const chkSmAddr = await this.helpers.toChecksumAddress(input);
+ this.setState({ output: chkSmAddr });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ async _hexToNumber() {
+ try {
+ const { input } = this.state;
+ const number = await this.helpers.hexToNumber(input);
+ this.setState({ output: number });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ async _hexToBytes() {
+ try {
+ const { input } = this.state;
+ const bytes = await this.helpers.hexToBytes(input);
+ this.setState({ output: bytes });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ async _bytesToHex() {
+ try {
+ const { input } = this.state;
+ const hex = await this.helpers.bytesToHex(input);
+ this.setState({ output: hex });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ async _padLeft32() {
+ try {
+ const { input } = this.state;
+ const leftPadded = await this.helpers.padLeft(input, 32);
+ this.setState({ output: leftPadded });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ async _padRight32() {
+ try {
+ const { input } = this.state;
+ const rightPadded = await this.helpers.padRight(input, 32);
+ this.setState({ output: rightPadded });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ async _padLeft64() {
+ try {
+ const { input } = this.state;
+ const leftPadded = await this.helpers.padLeft(input, 64);
+ this.setState({ output: leftPadded });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ async _padRight64() {
+ try {
+ const { input } = this.state;
+ const rightPadded = await this.helpers.padRight(input, 64);
+ this.setState({ output: rightPadded });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ render() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ this.state.output &&
+
+ }
+
+ );
+ }
+}
+const mapStateToProps = () => {
+ return { };
+}
+
+export default connect(mapStateToProps, {})(Web3Utilities);
diff --git a/lib/web3/methods.js b/lib/web3/methods.js
index b55988e..c0a7700 100644
--- a/lib/web3/methods.js
+++ b/lib/web3/methods.js
@@ -18,8 +18,6 @@
// methods.js are collection of various functions used to execute calls on web3
import Solc from 'solc'
import Web3 from 'web3'
-import ethJSABI from 'ethereumjs-abi'
-import EthJSTX from 'ethereumjs-tx'
import EventEmitter from 'events'
import { MessagePanelView, PlainMessageView, LineMessageView } from 'atom-message-panel'
@@ -163,14 +161,13 @@ export default class Web3Helpers {
async call({...arguments}) {
console.log("%c Web3 calling functions... ", 'background: rgba(36, 194, 203, 0.3); color: #EF525B');
console.log(arguments);
+ const that = this;
const coinbase = arguments.coinbase;
const password = arguments.password;
const contract = arguments.contract;
const abiItem = arguments.abiItem;
var params = arguments.params || [];
- //this.web3.eth.defaultAccount = coinbase;
- console.log(coinbase);
try {
// Prepare params for call
params = params.map(param => {
@@ -185,6 +182,7 @@ export default class Web3Helpers {
// Handle fallback
if(abiItem.type === 'fallback') {
+ console.log("%c Calling fallback function... ", 'background: rgba(36, 194, 203, 0.3); color: #EF525B');
if(password) {
await this.web3.eth.personal.unlockAccount(coinbase, password);
}
@@ -193,25 +191,31 @@ export default class Web3Helpers {
to: contract.options.address,
value: abiItem.payableValue || 0
})
+ console.log(result);
return result;
}
-
- if(abiItem.constant === false || abiItem.payable === true) {
- if(password) {
- await this.web3.eth.personal.unlockAccount(coinbase, password);
- }
- if(params.length > 0) {
- const result = await contract.methods[abiItem.name](...params).send({ from: coinbase, value: abiItem.payableValue });
- return result;
- }
- const result = await contract.methods[abiItem.name]().send({ from: coinbase, value: abiItem.payableValue });
- return result;
- }
- if(params.length > 0) {
+ // Handle constant calls
+ if(abiItem.constant === true) {
+ console.log("%c Calling constant function default... ", 'background: rgba(36, 194, 203, 0.3); color: #EF525B');
const result = await contract.methods[abiItem.name](...params).call({ from: coinbase });
+ console.log(result);
return result;
}
- const result = await contract.methods[abiItem.name]().call({ from: coinbase });
+ // handle default payable non-constant methods
+ if(password) {
+ await this.web3.eth.personal.unlockAccount(coinbase, password);
+ }
+ console.log("%c Calling payable function... ", 'background: rgba(36, 194, 203, 0.3); color: #EF525B');
+ const result = await contract.methods[abiItem.name](...params).send({ from: coinbase, value: abiItem.payableValue })
+ .on('transactionHash', (hash) => {
+ // show method tx hash & pending loader
+ console.log(hash);
+ that.showPanelTx(hash);
+ })
+ .on('receipt', (receipt) => {
+ return receipt;
+ })
+ console.log(result);
return result;
}
catch(e) {
@@ -240,17 +244,33 @@ export default class Web3Helpers {
messages.attach();
messages.add(new PlainMessageView({ message: err_message, className: 'red-message' }));
}
+ showPanelTx(txHash) {
+ const messages = new MessagePanelView({ title: 'Etheratom transaction' });
+ messages.attach();
+ messages.add(new PlainMessageView({ message: 'New transaction: ' + txHash, className: 'green-message' }));
+ return;
+ }
showOutput({...arguments}) {
const address = arguments.address;
const data = arguments.data;
+ const block = arguments.block;
+
const messages = new MessagePanelView({ title: 'Etheratom output' });
messages.attach();
messages.add(new PlainMessageView({
message: 'Contract address: ' + address,
className: 'green-message'
}));
+ if(block) {
+ const rawMessage = `
Block:
${JSON.stringify(block, null, 4)}`;
+ messages.add(new PlainMessageView({
+ message: rawMessage,
+ raw: true,
+ className: 'green-message'
+ }));
+ }
if(data instanceof Object) {
- const rawMessage = `
Contract output:
${JSON.stringify(data, null, 4)}`
+ const rawMessage = `
Contract output:
${JSON.stringify(data, null, 4)}`;
messages.add(new PlainMessageView({
message: rawMessage,
raw: true,
@@ -286,21 +306,91 @@ export default class Web3Helpers {
async getAccounts() {
try {
return await this.web3.eth.getAccounts();
- } catch (e) {
+ } catch(e) {
throw e;
}
}
async getMining() {
try {
return await this.web3.eth.isMining();
- } catch (e) {
+ } catch(e) {
throw e;
}
}
async getHashrate() {
try {
return await this.web3.eth.getHashrate();
- } catch (e) {
+ } catch(e) {
+ throw e;
+ }
+ }
+ async getBlock(blockNumber) {
+ try {
+ return await this.web3.eth.getBlock(blockNumber);
+ } catch(e) {
+ throw e;
+ }
+ }
+ async hexToUtf8(input) {
+ try {
+ return await this.web3.utils.hexToUtf8(input);
+ } catch(e) {
+ throw e;
+ }
+ }
+ async hexToAscii(input) {
+ try {
+ return await this.web3.utils.hexToAscii(input);
+ } catch(e) {
+ throw e;
+ }
+ }
+ async toHex(input) {
+ try {
+ return await this.web3.utils.toHex(input);
+ } catch(e) {
+ throw e;
+ }
+ }
+ async toChecksumAddress(input) {
+ try {
+ return await this.web3.utils.toChecksumAddress(input);
+ } catch(e) {
+ throw e;
+ }
+ }
+ async hexToNumber(input) {
+ try {
+ return await this.web3.utils.hexToNumber(input);
+ } catch(e) {
+ throw e;
+ }
+ }
+ async hexToBytes(input) {
+ try {
+ return await this.web3.utils.hexToBytes(input);
+ } catch(e) {
+ throw e;
+ }
+ }
+ async bytesToHex(input) {
+ try {
+ return await this.web3.utils.bytesToHex(input);
+ } catch(e) {
+ throw e;
+ }
+ }
+ async padLeft(input, padding) {
+ try {
+ return await this.web3.utils.padLeft(input, padding);
+ } catch(e) {
+ throw e;
+ }
+ }
+ async padRight(input, padding) {
+ try {
+ return await this.web3.utils.padRight(input, padding);
+ } catch(e) {
throw e;
}
}
From 68a3054bcefedbb0a1d990bdfc72bb4019f1a2bf Mon Sep 17 00:00:00 2001
From: 0mkar <0mkar@protonmail.com>
Date: Mon, 7 May 2018 20:38:12 +0530
Subject: [PATCH 3/9] Add share box
---
lib/components/ShareBox/index.js | 109 +++++++++++++++++++++++++++++++
lib/ethereum-interface-view.js | 7 ++
lib/web3/methods.js | 48 +++++++++++++-
lib/web3/view.js | 2 +
lib/web3/web3.js | 8 +--
styles/atom-solidity.less | 4 ++
6 files changed, 173 insertions(+), 5 deletions(-)
create mode 100644 lib/components/ShareBox/index.js
diff --git a/lib/components/ShareBox/index.js b/lib/components/ShareBox/index.js
new file mode 100644
index 0000000..8057336
--- /dev/null
+++ b/lib/components/ShareBox/index.js
@@ -0,0 +1,109 @@
+'use babel'
+// Copyright 2018 Etheratom Authors
+// This file is part of Etheratom.
+
+// Etheratom is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Etheratom is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Etheratom. If not, see
.
+import React from 'react'
+import { connect } from 'react-redux'
+
+class ShareBox extends React.Component {
+ constructor(props) {
+ super(props);
+ this.helpers = props.helpers;
+ this.state = {
+ shared: false,
+ shareLink: null,
+ gas: 500000
+ }
+ this._handleShare = this._handleShare.bind(this);
+ this._handleLoad = this._handleLoad.bind(this);
+ this._handleCopy = this._handleCopy.bind(this);
+ this._handleChange = this._handleChange.bind(this);
+ this._handleGasChange = this._handleGasChange.bind(this);
+ }
+ async _handleShare() {
+ const that = this;
+ const { coinbase, password } = this.props;
+ const { gas } = this.state;
+ let code = null;
+ atom.workspace.observeTextEditors(async (editor) => {
+ code = editor.getText();
+ return;
+ });
+ // Will upload code to smart contract
+ const shared = await that.helpers.shareCode(coinbase, password, code, gas);
+ console.log(shared);
+ //const shared = 'abcd';
+ that.setState({ shared: true, shareLink: shared });
+ return;
+ }
+ async _handleLoad() {
+ // Will load code from smart contract
+ }
+ async _handleCopy() {
+ const { shareLink } = this.state;
+ atom.clipboard.write(shareLink);
+ }
+ async _handleChange(event) {
+ this.setState({ shared: false, shareLink: event.target.value });
+ }
+ async _handleGasChange(event) {
+ this.setState({ gas: event.target.value });
+ }
+ render() {
+ const { shareLink, shared, gas } = this.state;
+ return (
+
+
+ {
+ !shared &&
+
+ }
+
+ {
+ shared &&
+
+ }
+
+
+ );
+ }
+}
+
+const mapStateToProps = ({ account }) => {
+ const { coinbase, password } = account;
+ return { coinbase, password };
+}
+
+export default connect(mapStateToProps, {})(ShareBox);
diff --git a/lib/ethereum-interface-view.js b/lib/ethereum-interface-view.js
index 8d9d637..6d15abf 100644
--- a/lib/ethereum-interface-view.js
+++ b/lib/ethereum-interface-view.js
@@ -104,6 +104,13 @@ export default AtomSolidityView = (() => {
buttonNode.appendChild(compileButton);
mainNode.appendChild(buttonNode);
+ shareNode = document.createElement('div');
+ att = document.createAttribute('id');
+ att.value = 'share-box';
+ shareNode.setAttributeNode(att);
+ shareNode.classList.add('block');
+ mainNode.appendChild(shareNode);
+
tabNode = document.createElement('div');
att = document.createAttribute('id');
att.value = 'tab_view';
diff --git a/lib/web3/methods.js b/lib/web3/methods.js
index c0a7700..ea47798 100644
--- a/lib/web3/methods.js
+++ b/lib/web3/methods.js
@@ -105,7 +105,7 @@ export default class Web3Helpers {
try {
const gasPrice = await this.web3.eth.getGasPrice();
const contract = await new this.web3.eth.Contract(abi, {
- from: this.web3.eth.defaultAccount,
+ from: coinbase,
data: '0x' + code,
gas: this.web3.utils.toHex(gasSupply),
gasPrice: this.web3.utils.toHex(gasPrice)
@@ -394,4 +394,50 @@ export default class Web3Helpers {
throw e;
}
}
+ // Code sharing
+ async shareCode(coinbase, password, code, gas) {
+ const that = this;
+ const bytecode = '608060405234801561001057600080fd5b50610507806100206000396000f30060806040526004361061006c5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166327b53401811461007157806341c0e1b5146100fe57806348c5e7bc146101155780637f630b4c1461012d578063f1eae25c14610186575b600080fd5b34801561007d57600080fd5b5061008960043561019b565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100c35781810151838201526020016100ab565b50505050905090810190601f1680156100f05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561010a57600080fd5b50610113610235565b005b34801561012157600080fd5b50610089600435610276565b34801561013957600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101139436949293602493928401919081908401838280828437509497506103199650505050505050565b34801561019257600080fd5b50610113610409565b60016020818152600092835260409283902080548451600294821615610100026000190190911693909304601f810183900483028401830190945283835291929083018282801561022d5780601f106102025761010080835404028352916020019161022d565b820191906000526020600020905b81548152906001019060200180831161021057829003601f168201915b505050505081565b6000543373ffffffffffffffffffffffffffffffffffffffff908116911614156102745760005473ffffffffffffffffffffffffffffffffffffffff16ff5b565b60008181526001602081815260409283902080548451600260001995831615610100029590950190911693909304601f8101839004830284018301909452838352606093909183018282801561030d5780601f106102e25761010080835404028352916020019161030d565b820191906000526020600020905b8154815290600101906020018083116102f057829003601f168201915b50505050509050919050565b60003382604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140182805190602001908083835b6020831061038d5780518252601f19909201916020918201910161036e565b51815160209384036101000a600019018019909216911617905260408051929094018290039091206000818152600183529390932088519397506103d996509450870192506104409050565b5060405181907f0f66da887a9c57b75a06c56ae415879ac0fa76f7e5fcb12af540c94fe85c2e5d90600090a25050565b6000805473ffffffffffffffffffffffffffffffffffffffff19163373ffffffffffffffffffffffffffffffffffffffff16179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061048157805160ff19168380011785556104ae565b828001600101855582156104ae579182015b828111156104ae578251825591602001919060010190610493565b506104ba9291506104be565b5090565b6104d891905b808211156104ba57600081556001016104c4565b905600a165627a7a723058207d63bc55d7869b380b4dc0893827f66269543a40ff3b44414c2368d40e7c81000029';
+ const abi = [{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"fiddle_data","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"bytes32"}],"name":"get_fiddle","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_code","type":"string"}],"name":"share","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"mortal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_id","type":"bytes32"}],"name":"NewFiddle","type":"event"}];
+
+ return new Promise(async (resolve, reject) => {
+ if(!coinbase) {
+ const error = new Error('No coinbase selected!');
+ reject(error);
+ }
+ try {
+ if(password) {
+ const unlocked = await that.web3.eth.personal.unlockAccount(coinbase, password);
+ }
+ const maxGas = await that.getGasLimit();
+ const minGas = await that.getGasEstimate(coinbase, bytecode);
+ const gasPrice = await that.web3.eth.getGasPrice();
+ const contract = await new that.web3.eth.Contract(abi, '0xc17744c2F1B77907574b7D49A00319Aa47e828B8', {
+ from: coinbase,
+ data: '0x' + bytecode,
+ gas: that.web3.utils.toHex(gas),
+ gasPrice: that.web3.utils.toHex(gasPrice)
+ });
+ console.log(contract);
+ contract.events.NewFiddle()
+ .on('data', data => {
+ console.log("Got new fiddle...");
+ const fiddleId = data.returnValues._id;
+ console.log(fiddleId);
+ resolve(fiddleId);
+ })
+ contract.methods.share(code).send({ from: coinbase })
+ .on('transactionHash', txHash => {
+ console.log('transactionHash:');
+ console.log(txHash);
+ })
+ .on('error', e => {
+ reject(e);
+ })
+ } catch (e) {
+ console.log(e);
+ reject(e);
+ }
+ });
+ }
}
diff --git a/lib/web3/view.js b/lib/web3/view.js
index cb3d77b..d9a9c75 100644
--- a/lib/web3/view.js
+++ b/lib/web3/view.js
@@ -24,6 +24,7 @@ import ClientSelector from '../components/ClientSelector'
import TabView from '../components/TabView'
import CoinbaseView from '../components/CoinbaseView'
import CompileBtn from '../components/CompileBtn'
+import ShareBox from '../components/ShareBox'
import ErrorView from '../components/ErrorView'
import { SET_ACCOUNTS, SET_COINBASE } from '../actions/types'
@@ -52,6 +53,7 @@ export default class View {
}
createButtonsView() {
ReactDOM.render(
, document.getElementById('compile_btn'));
+ ReactDOM.render(
, document.getElementById('share-box'));
}
createTabView() {
ReactDOM.render(
, document.getElementById('tab_view'));
diff --git a/lib/web3/web3.js b/lib/web3/web3.js
index 5971947..65bab1b 100644
--- a/lib/web3/web3.js
+++ b/lib/web3/web3.js
@@ -142,8 +142,8 @@ export default class Web3Env {
// newBlockHeaders subscriber
this.web3.eth.subscribe('newBlockHeaders')
.on("data", (blocks) => {
- console.log("%c newBlockHeaders:data ", 'background: rgba(36, 194, 203, 0.3); color: #EF525B');
- console.log(blocks);
+ //console.log("%c newBlockHeaders:data ", 'background: rgba(36, 194, 203, 0.3); color: #EF525B');
+ //console.log(blocks);
})
.on('error', (e) => {
console.log("%c newBlockHeaders:error ", 'background: rgba(36, 194, 203, 0.3); color: #EF525B');
@@ -152,8 +152,8 @@ export default class Web3Env {
// pendingTransactions subscriber
this.web3.eth.subscribe('pendingTransactions')
.on("data", (transaction) => {
- console.log("%c pendingTransactions:data ", 'background: rgba(36, 194, 203, 0.3); color: #EF525B');
- console.log(transaction);
+ //console.log("%c pendingTransactions:data ", 'background: rgba(36, 194, 203, 0.3); color: #EF525B');
+ //console.log(transaction);
this.store.dispatch({ type: ADD_PENDING_TRANSACTION, payload: transaction });
})
.on('error', (e) => {
diff --git a/styles/atom-solidity.less b/styles/atom-solidity.less
index a08dea7..b576778 100644
--- a/styles/atom-solidity.less
+++ b/styles/atom-solidity.less
@@ -312,3 +312,7 @@
.no-header {
text-align: center;
}
+
+.gas-supply {
+ width: 25%;
+}
From 038f9ca0624c700e970bf77bbf87148a48d4c710 Mon Sep 17 00:00:00 2001
From: 0mkar <0mkar@protonmail.com>
Date: Tue, 8 May 2018 08:34:40 +0530
Subject: [PATCH 4/9] Show snippet code
---
lib/components/ShareBox/index.js | 100 +++++++++++++++++++------------
lib/components/TabView/index.js | 7 +++
lib/ethereum-interface-view.js | 4 +-
lib/web3/methods.js | 29 +++++++--
lib/web3/view.js | 2 -
5 files changed, 96 insertions(+), 46 deletions(-)
diff --git a/lib/components/ShareBox/index.js b/lib/components/ShareBox/index.js
index 8057336..e4588cb 100644
--- a/lib/components/ShareBox/index.js
+++ b/lib/components/ShareBox/index.js
@@ -24,7 +24,8 @@ class ShareBox extends React.Component {
this.state = {
shared: false,
shareLink: null,
- gas: 500000
+ gas: 394504, // contract creation gas
+ snippet: null
}
this._handleShare = this._handleShare.bind(this);
this._handleLoad = this._handleLoad.bind(this);
@@ -32,6 +33,13 @@ class ShareBox extends React.Component {
this._handleChange = this._handleChange.bind(this);
this._handleGasChange = this._handleGasChange.bind(this);
}
+ async componentWillReceiveProps(nextProps) {
+ const { accounts } = nextProps;
+ if(accounts.length > 0) {
+ const gasEstm = await this.helpers.getShareGasEstm(accounts[0]);
+ this.setState({ gas: gasEstm });
+ }
+ }
async _handleShare() {
const that = this;
const { coinbase, password } = this.props;
@@ -41,15 +49,16 @@ class ShareBox extends React.Component {
code = editor.getText();
return;
});
- // Will upload code to smart contract
const shared = await that.helpers.shareCode(coinbase, password, code, gas);
- console.log(shared);
- //const shared = 'abcd';
that.setState({ shared: true, shareLink: shared });
return;
}
async _handleLoad() {
// Will load code from smart contract
+ const { shareLink } = this.state;
+ const { coinbase } = this.props;
+ const code = await this.helpers.getSnippet(coinbase, shareLink);
+ this.setState({ snippet: code });
}
async _handleCopy() {
const { shareLink } = this.state;
@@ -62,48 +71,65 @@ class ShareBox extends React.Component {
this.setState({ gas: event.target.value });
}
render() {
- const { shareLink, shared, gas } = this.state;
+ const { shareLink, shared, gas, snippet } = this.state;
return (
-
-
- {
- !shared &&
-
- }
-
+
+
+
+ {
+ !shared &&
+
+ }
+ {
+ shared &&
+
+ }
+
+
+
+
+
+
+
+ This is contract creation gas. Update it according to your needs!
+
+
{
- shared &&
-
+ snippet &&
+
}
-
);
}
}
const mapStateToProps = ({ account }) => {
- const { coinbase, password } = account;
- return { coinbase, password };
+ const { coinbase, password, accounts } = account;
+ return { coinbase, password, accounts };
}
export default connect(mapStateToProps, {})(ShareBox);
diff --git a/lib/components/TabView/index.js b/lib/components/TabView/index.js
index 553fec9..7813ae7 100644
--- a/lib/components/TabView/index.js
+++ b/lib/components/TabView/index.js
@@ -22,6 +22,7 @@ import TxAnalyzer from '../TxAnalyzer'
import Events from '../Events'
import NodeControl from '../NodeControl'
import Web3Utilities from '../Web3Utilities'
+import ShareBox from '../ShareBox'
class TabView extends React.Component {
constructor(props) {
@@ -83,6 +84,9 @@ class TabView extends React.Component {
Web3 Utilities
+
+ Share
+
Node
@@ -104,6 +108,9 @@ class TabView extends React.Component {
+
+
+
diff --git a/lib/ethereum-interface-view.js b/lib/ethereum-interface-view.js
index 6d15abf..e45f90a 100644
--- a/lib/ethereum-interface-view.js
+++ b/lib/ethereum-interface-view.js
@@ -104,12 +104,12 @@ export default AtomSolidityView = (() => {
buttonNode.appendChild(compileButton);
mainNode.appendChild(buttonNode);
- shareNode = document.createElement('div');
+ /*shareNode = document.createElement('div');
att = document.createAttribute('id');
att.value = 'share-box';
shareNode.setAttributeNode(att);
shareNode.classList.add('block');
- mainNode.appendChild(shareNode);
+ mainNode.appendChild(shareNode);*/
tabNode = document.createElement('div');
att = document.createAttribute('id');
diff --git a/lib/web3/methods.js b/lib/web3/methods.js
index ea47798..145fc0a 100644
--- a/lib/web3/methods.js
+++ b/lib/web3/methods.js
@@ -24,6 +24,8 @@ import { MessagePanelView, PlainMessageView, LineMessageView } from 'atom-messag
export default class Web3Helpers {
constructor(web3) {
this.web3 = web3;
+ this.bytecode = '608060405234801561001057600080fd5b50610507806100206000396000f30060806040526004361061006c5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166327b53401811461007157806341c0e1b5146100fe57806348c5e7bc146101155780637f630b4c1461012d578063f1eae25c14610186575b600080fd5b34801561007d57600080fd5b5061008960043561019b565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100c35781810151838201526020016100ab565b50505050905090810190601f1680156100f05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561010a57600080fd5b50610113610235565b005b34801561012157600080fd5b50610089600435610276565b34801561013957600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101139436949293602493928401919081908401838280828437509497506103199650505050505050565b34801561019257600080fd5b50610113610409565b60016020818152600092835260409283902080548451600294821615610100026000190190911693909304601f810183900483028401830190945283835291929083018282801561022d5780601f106102025761010080835404028352916020019161022d565b820191906000526020600020905b81548152906001019060200180831161021057829003601f168201915b505050505081565b6000543373ffffffffffffffffffffffffffffffffffffffff908116911614156102745760005473ffffffffffffffffffffffffffffffffffffffff16ff5b565b60008181526001602081815260409283902080548451600260001995831615610100029590950190911693909304601f8101839004830284018301909452838352606093909183018282801561030d5780601f106102e25761010080835404028352916020019161030d565b820191906000526020600020905b8154815290600101906020018083116102f057829003601f168201915b50505050509050919050565b60003382604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140182805190602001908083835b6020831061038d5780518252601f19909201916020918201910161036e565b51815160209384036101000a600019018019909216911617905260408051929094018290039091206000818152600183529390932088519397506103d996509450870192506104409050565b5060405181907f0f66da887a9c57b75a06c56ae415879ac0fa76f7e5fcb12af540c94fe85c2e5d90600090a25050565b6000805473ffffffffffffffffffffffffffffffffffffffff19163373ffffffffffffffffffffffffffffffffffffffff16179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061048157805160ff19168380011785556104ae565b828001600101855582156104ae579182015b828111156104ae578251825591602001919060010190610493565b506104ba9291506104be565b5090565b6104d891905b808211156104ba57600081556001016104c4565b905600a165627a7a723058207d63bc55d7869b380b4dc0893827f66269543a40ff3b44414c2368d40e7c81000029';
+ this.abi = [{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"fiddle_data","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"bytes32"}],"name":"get_fiddle","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_code","type":"string"}],"name":"share","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"mortal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_id","type":"bytes32"}],"name":"NewFiddle","type":"event"}];
}
async compileWeb3(sources) {
// compile solidity using solcjs
@@ -395,10 +397,13 @@ export default class Web3Helpers {
}
}
// Code sharing
+ async getShareGasEstm(coinbase) {
+ const { bytecode } = this;
+ return await this.getGasEstimate(coinbase, bytecode);
+ }
async shareCode(coinbase, password, code, gas) {
const that = this;
- const bytecode = '608060405234801561001057600080fd5b50610507806100206000396000f30060806040526004361061006c5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166327b53401811461007157806341c0e1b5146100fe57806348c5e7bc146101155780637f630b4c1461012d578063f1eae25c14610186575b600080fd5b34801561007d57600080fd5b5061008960043561019b565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100c35781810151838201526020016100ab565b50505050905090810190601f1680156100f05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561010a57600080fd5b50610113610235565b005b34801561012157600080fd5b50610089600435610276565b34801561013957600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101139436949293602493928401919081908401838280828437509497506103199650505050505050565b34801561019257600080fd5b50610113610409565b60016020818152600092835260409283902080548451600294821615610100026000190190911693909304601f810183900483028401830190945283835291929083018282801561022d5780601f106102025761010080835404028352916020019161022d565b820191906000526020600020905b81548152906001019060200180831161021057829003601f168201915b505050505081565b6000543373ffffffffffffffffffffffffffffffffffffffff908116911614156102745760005473ffffffffffffffffffffffffffffffffffffffff16ff5b565b60008181526001602081815260409283902080548451600260001995831615610100029590950190911693909304601f8101839004830284018301909452838352606093909183018282801561030d5780601f106102e25761010080835404028352916020019161030d565b820191906000526020600020905b8154815290600101906020018083116102f057829003601f168201915b50505050509050919050565b60003382604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140182805190602001908083835b6020831061038d5780518252601f19909201916020918201910161036e565b51815160209384036101000a600019018019909216911617905260408051929094018290039091206000818152600183529390932088519397506103d996509450870192506104409050565b5060405181907f0f66da887a9c57b75a06c56ae415879ac0fa76f7e5fcb12af540c94fe85c2e5d90600090a25050565b6000805473ffffffffffffffffffffffffffffffffffffffff19163373ffffffffffffffffffffffffffffffffffffffff16179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061048157805160ff19168380011785556104ae565b828001600101855582156104ae579182015b828111156104ae578251825591602001919060010190610493565b506104ba9291506104be565b5090565b6104d891905b808211156104ba57600081556001016104c4565b905600a165627a7a723058207d63bc55d7869b380b4dc0893827f66269543a40ff3b44414c2368d40e7c81000029';
- const abi = [{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"fiddle_data","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"bytes32"}],"name":"get_fiddle","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_code","type":"string"}],"name":"share","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"mortal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_id","type":"bytes32"}],"name":"NewFiddle","type":"event"}];
+ const { bytecode, abi } = this;
return new Promise(async (resolve, reject) => {
if(!coinbase) {
@@ -409,8 +414,6 @@ export default class Web3Helpers {
if(password) {
const unlocked = await that.web3.eth.personal.unlockAccount(coinbase, password);
}
- const maxGas = await that.getGasLimit();
- const minGas = await that.getGasEstimate(coinbase, bytecode);
const gasPrice = await that.web3.eth.getGasPrice();
const contract = await new that.web3.eth.Contract(abi, '0xc17744c2F1B77907574b7D49A00319Aa47e828B8', {
from: coinbase,
@@ -418,7 +421,6 @@ export default class Web3Helpers {
gas: that.web3.utils.toHex(gas),
gasPrice: that.web3.utils.toHex(gasPrice)
});
- console.log(contract);
contract.events.NewFiddle()
.on('data', data => {
console.log("Got new fiddle...");
@@ -440,4 +442,21 @@ export default class Web3Helpers {
}
});
}
+ async getSnippet(coinbase, id) {
+ const { bytecode, abi } = this;
+ try {
+ const gas = await this.getGasEstimate(coinbase, bytecode);
+ const gasPrice = await this.web3.eth.getGasPrice();
+ const contract = await new this.web3.eth.Contract(abi, '0xc17744c2F1B77907574b7D49A00319Aa47e828B8', {
+ from: coinbase,
+ data: '0x' + bytecode,
+ gas: this.web3.utils.toHex(gas),
+ gasPrice: this.web3.utils.toHex(gasPrice)
+ });
+ const fiddle = contract.methods.get_fiddle(id).call({ from: coinbase });
+ return fiddle;
+ } catch(e) {
+ throw e;
+ }
+ }
}
diff --git a/lib/web3/view.js b/lib/web3/view.js
index d9a9c75..cb3d77b 100644
--- a/lib/web3/view.js
+++ b/lib/web3/view.js
@@ -24,7 +24,6 @@ import ClientSelector from '../components/ClientSelector'
import TabView from '../components/TabView'
import CoinbaseView from '../components/CoinbaseView'
import CompileBtn from '../components/CompileBtn'
-import ShareBox from '../components/ShareBox'
import ErrorView from '../components/ErrorView'
import { SET_ACCOUNTS, SET_COINBASE } from '../actions/types'
@@ -53,7 +52,6 @@ export default class View {
}
createButtonsView() {
ReactDOM.render(
, document.getElementById('compile_btn'));
- ReactDOM.render(
, document.getElementById('share-box'));
}
createTabView() {
ReactDOM.render(
, document.getElementById('tab_view'));
From 6ba7be4902e9632c936deb15fe0a1f600fa0aa97 Mon Sep 17 00:00:00 2001
From: 0mkar <0mkar@protonmail.com>
Date: Tue, 8 May 2018 09:27:05 +0530
Subject: [PATCH 5/9] Update readme with telegram group link
---
README.md | 1 +
lib/components/ShareBox/index.js | 13 ++++++++-----
lib/web3/methods.js | 13 ++++---------
3 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/README.md b/README.md
index bf404c7..582710f 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,7 @@
[](https://greenkeeper.io/)
[](https://travis-ci.org/0mkara/etheratom)
+[](https://t.me/etheratom)
Etheratom is a package for hackable Atom editor. It uses web3js to interact with Ethereum node.
diff --git a/lib/components/ShareBox/index.js b/lib/components/ShareBox/index.js
index e4588cb..1f17d1b 100644
--- a/lib/components/ShareBox/index.js
+++ b/lib/components/ShareBox/index.js
@@ -54,11 +54,14 @@ class ShareBox extends React.Component {
return;
}
async _handleLoad() {
- // Will load code from smart contract
- const { shareLink } = this.state;
- const { coinbase } = this.props;
- const code = await this.helpers.getSnippet(coinbase, shareLink);
- this.setState({ snippet: code });
+ try {
+ const { shareLink } = this.state;
+ const { coinbase } = this.props;
+ const code = await this.helpers.getSnippet(coinbase, shareLink);
+ this.setState({ snippet: code });
+ } catch(e) {
+ throw e;
+ }
}
async _handleCopy() {
const { shareLink } = this.state;
diff --git a/lib/web3/methods.js b/lib/web3/methods.js
index 145fc0a..8eb3fe9 100644
--- a/lib/web3/methods.js
+++ b/lib/web3/methods.js
@@ -24,6 +24,7 @@ import { MessagePanelView, PlainMessageView, LineMessageView } from 'atom-messag
export default class Web3Helpers {
constructor(web3) {
this.web3 = web3;
+ // Etheratom contract bytecode & abi
this.bytecode = '608060405234801561001057600080fd5b50610507806100206000396000f30060806040526004361061006c5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166327b53401811461007157806341c0e1b5146100fe57806348c5e7bc146101155780637f630b4c1461012d578063f1eae25c14610186575b600080fd5b34801561007d57600080fd5b5061008960043561019b565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100c35781810151838201526020016100ab565b50505050905090810190601f1680156100f05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561010a57600080fd5b50610113610235565b005b34801561012157600080fd5b50610089600435610276565b34801561013957600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101139436949293602493928401919081908401838280828437509497506103199650505050505050565b34801561019257600080fd5b50610113610409565b60016020818152600092835260409283902080548451600294821615610100026000190190911693909304601f810183900483028401830190945283835291929083018282801561022d5780601f106102025761010080835404028352916020019161022d565b820191906000526020600020905b81548152906001019060200180831161021057829003601f168201915b505050505081565b6000543373ffffffffffffffffffffffffffffffffffffffff908116911614156102745760005473ffffffffffffffffffffffffffffffffffffffff16ff5b565b60008181526001602081815260409283902080548451600260001995831615610100029590950190911693909304601f8101839004830284018301909452838352606093909183018282801561030d5780601f106102e25761010080835404028352916020019161030d565b820191906000526020600020905b8154815290600101906020018083116102f057829003601f168201915b50505050509050919050565b60003382604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140182805190602001908083835b6020831061038d5780518252601f19909201916020918201910161036e565b51815160209384036101000a600019018019909216911617905260408051929094018290039091206000818152600183529390932088519397506103d996509450870192506104409050565b5060405181907f0f66da887a9c57b75a06c56ae415879ac0fa76f7e5fcb12af540c94fe85c2e5d90600090a25050565b6000805473ffffffffffffffffffffffffffffffffffffffff19163373ffffffffffffffffffffffffffffffffffffffff16179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061048157805160ff19168380011785556104ae565b828001600101855582156104ae579182015b828111156104ae578251825591602001919060010190610493565b506104ba9291506104be565b5090565b6104d891905b808211156104ba57600081556001016104c4565b905600a165627a7a723058207d63bc55d7869b380b4dc0893827f66269543a40ff3b44414c2368d40e7c81000029';
this.abi = [{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"fiddle_data","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"bytes32"}],"name":"get_fiddle","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_code","type":"string"}],"name":"share","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"mortal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_id","type":"bytes32"}],"name":"NewFiddle","type":"event"}];
}
@@ -443,18 +444,12 @@ export default class Web3Helpers {
});
}
async getSnippet(coinbase, id) {
- const { bytecode, abi } = this;
+ const { abi } = this;
try {
- const gas = await this.getGasEstimate(coinbase, bytecode);
- const gasPrice = await this.web3.eth.getGasPrice();
const contract = await new this.web3.eth.Contract(abi, '0xc17744c2F1B77907574b7D49A00319Aa47e828B8', {
- from: coinbase,
- data: '0x' + bytecode,
- gas: this.web3.utils.toHex(gas),
- gasPrice: this.web3.utils.toHex(gasPrice)
+ from: coinbase
});
- const fiddle = contract.methods.get_fiddle(id).call({ from: coinbase });
- return fiddle;
+ return await contract.methods.get_fiddle(id).call({ from: coinbase });
} catch(e) {
throw e;
}
From de37bac604ce346a9757af41e5dcf6e895045da5 Mon Sep 17 00:00:00 2001
From: 0mkar <0mkar@protonmail.com>
Date: Wed, 9 May 2018 02:15:07 +0530
Subject: [PATCH 6/9] watch events with filter
---
contracts/main.sol | 4 +-
lib/components/ShareBox/index.js | 103 ++++++++++++++++++++++++-------
lib/web3/methods.js | 53 ++++++++--------
lib/web3/web3.js | 2 +-
styles/atom-solidity.less | 11 ++++
5 files changed, 122 insertions(+), 51 deletions(-)
diff --git a/contracts/main.sol b/contracts/main.sol
index 8b040c8..97f76f7 100644
--- a/contracts/main.sol
+++ b/contracts/main.sol
@@ -3,13 +3,13 @@ import '../contracts/mortal.sol';
contract Main is Mortal {
mapping (bytes32 => string) public fiddle_data;
- event NewFiddle(bytes32 indexed _id);
+ event NewFiddle(address indexed _user, bytes32 indexed _id);
// share some given input
function share(string _code) public {
bytes32 _id = keccak256(msg.sender, _code);
fiddle_data[_id] = _code;
- emit NewFiddle(_id);
+ emit NewFiddle(msg.sender, _id);
}
// get code for given bytes32 id
function get_fiddle(bytes32 _id) view public returns (string) {
diff --git a/lib/components/ShareBox/index.js b/lib/components/ShareBox/index.js
index 1f17d1b..b49022c 100644
--- a/lib/components/ShareBox/index.js
+++ b/lib/components/ShareBox/index.js
@@ -16,6 +16,7 @@
// along with Etheratom. If not, see .
import React from 'react'
import { connect } from 'react-redux'
+import { Collapse } from 'react-collapse'
class ShareBox extends React.Component {
constructor(props) {
@@ -24,34 +25,60 @@ class ShareBox extends React.Component {
this.state = {
shared: false,
shareLink: null,
- gas: 394504, // contract creation gas
- snippet: null
+ gas: 0,
+ snippet: null,
+ txHash: null,
+ code: null,
+ isOpened: false,
+ toggleBtnStyle: 'btn icon icon-unfold inline-block-tight',
+ togglePreviewTxt: 'Preview Snippet'
}
this._handleShare = this._handleShare.bind(this);
this._handleLoad = this._handleLoad.bind(this);
this._handleCopy = this._handleCopy.bind(this);
this._handleChange = this._handleChange.bind(this);
this._handleGasChange = this._handleGasChange.bind(this);
+ this._togglePreview = this._togglePreview.bind(this);
+ this.watchSyncEvents();
}
- async componentWillReceiveProps(nextProps) {
- const { accounts } = nextProps;
- if(accounts.length > 0) {
- const gasEstm = await this.helpers.getShareGasEstm(accounts[0]);
- this.setState({ gas: gasEstm });
- }
- }
- async _handleShare() {
+ async watchSyncEvents() {
const that = this;
- const { coinbase, password } = this.props;
- const { gas } = this.state;
- let code = null;
- atom.workspace.observeTextEditors(async (editor) => {
+ const { coinbase } = this.props;
+ that.helpers.snptEvents.NewFiddle({ filter: { _user: coinbase } })
+ .on('data', data => {
+ console.log(data);
+ const fiddleId = data.returnValues._id;
+ that.setState({ shared: true, shareLink: fiddleId });
+ })
+ .on('error', e => {
+ throw e;
+ })
+ }
+ async componentDidMount() {
+ const { coinbase } = this.props;
+ const gasEstm = await this.helpers.getShareGasEstm(coinbase);
+ this.setState({ gas: gasEstm });
+ atom.workspace.observeActiveTextEditor(async (editor) => {
+ if(!editor || !editor.getBuffer()) {
+ return
+ }
code = editor.getText();
+ this.setState({ code });
return;
});
- const shared = await that.helpers.shareCode(coinbase, password, code, gas);
- that.setState({ shared: true, shareLink: shared });
- return;
+ }
+ async _handleShare() {
+ const that = this;
+ const { coinbase, password } = this.props;
+ const { gas, code } = this.state;
+ this.setState({ txHash: null, shareLink: null, snippet: null });
+ that.helpers.shareCode(coinbase, password, code, gas)
+ .then(txHash => {
+ this.setState({ txHash: txHash });
+ })
+ .catch(e => {
+ throw e;
+ });
}
async _handleLoad() {
try {
@@ -73,8 +100,23 @@ class ShareBox extends React.Component {
async _handleGasChange(event) {
this.setState({ gas: event.target.value });
}
+ _togglePreview() {
+ const { isOpened } = this.state;
+ this.setState({ isOpened: !isOpened });
+ if(!isOpened) {
+ this.setState({
+ toggleBtnStyle: 'btn btn-success icon icon-fold inline-block-tight',
+ togglePreviewTxt: 'Hide Snippet'
+ });
+ } else {
+ this.setState({
+ toggleBtnStyle: 'btn icon icon-unfold inline-block-tight',
+ togglePreviewTxt: 'Preview Snippet'
+ });
+ }
+ }
render() {
- const { shareLink, shared, gas, snippet } = this.state;
+ const { shareLink, shared, gas, snippet, txHash, code, toggleBtnStyle, togglePreviewTxt, isOpened } = this.state;
return (
@@ -113,10 +155,29 @@ class ShareBox extends React.Component {
Share
-
+
This is contract creation gas. Update it according to your needs!
+
+ {
+ txHash &&
+
+ Transaction: { txHash }
+
+ }
+
+ {
+ code &&
+
+ }
+
{
snippet &&
@@ -131,8 +192,8 @@ class ShareBox extends React.Component {
}
const mapStateToProps = ({ account }) => {
- const { coinbase, password, accounts } = account;
- return { coinbase, password, accounts };
+ const { coinbase, password } = account;
+ return { coinbase, password };
}
export default connect(mapStateToProps, {})(ShareBox);
diff --git a/lib/web3/methods.js b/lib/web3/methods.js
index 8eb3fe9..f375d98 100644
--- a/lib/web3/methods.js
+++ b/lib/web3/methods.js
@@ -24,9 +24,22 @@ import { MessagePanelView, PlainMessageView, LineMessageView } from 'atom-messag
export default class Web3Helpers {
constructor(web3) {
this.web3 = web3;
- // Etheratom contract bytecode & abi
- this.bytecode = '608060405234801561001057600080fd5b50610507806100206000396000f30060806040526004361061006c5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166327b53401811461007157806341c0e1b5146100fe57806348c5e7bc146101155780637f630b4c1461012d578063f1eae25c14610186575b600080fd5b34801561007d57600080fd5b5061008960043561019b565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100c35781810151838201526020016100ab565b50505050905090810190601f1680156100f05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561010a57600080fd5b50610113610235565b005b34801561012157600080fd5b50610089600435610276565b34801561013957600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101139436949293602493928401919081908401838280828437509497506103199650505050505050565b34801561019257600080fd5b50610113610409565b60016020818152600092835260409283902080548451600294821615610100026000190190911693909304601f810183900483028401830190945283835291929083018282801561022d5780601f106102025761010080835404028352916020019161022d565b820191906000526020600020905b81548152906001019060200180831161021057829003601f168201915b505050505081565b6000543373ffffffffffffffffffffffffffffffffffffffff908116911614156102745760005473ffffffffffffffffffffffffffffffffffffffff16ff5b565b60008181526001602081815260409283902080548451600260001995831615610100029590950190911693909304601f8101839004830284018301909452838352606093909183018282801561030d5780601f106102e25761010080835404028352916020019161030d565b820191906000526020600020905b8154815290600101906020018083116102f057829003601f168201915b50505050509050919050565b60003382604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140182805190602001908083835b6020831061038d5780518252601f19909201916020918201910161036e565b51815160209384036101000a600019018019909216911617905260408051929094018290039091206000818152600183529390932088519397506103d996509450870192506104409050565b5060405181907f0f66da887a9c57b75a06c56ae415879ac0fa76f7e5fcb12af540c94fe85c2e5d90600090a25050565b6000805473ffffffffffffffffffffffffffffffffffffffff19163373ffffffffffffffffffffffffffffffffffffffff16179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061048157805160ff19168380011785556104ae565b828001600101855582156104ae579182015b828111156104ae578251825591602001919060010190610493565b506104ba9291506104be565b5090565b6104d891905b808211156104ba57600081556001016104c4565b905600a165627a7a723058207d63bc55d7869b380b4dc0893827f66269543a40ff3b44414c2368d40e7c81000029';
- this.abi = [{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"fiddle_data","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"bytes32"}],"name":"get_fiddle","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_code","type":"string"}],"name":"share","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"mortal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_id","type":"bytes32"}],"name":"NewFiddle","type":"event"}];
+
+ // Etheratom contract, bytecode & abi
+ this.bytecode = '608060405234801561001057600080fd5b5061051f806100206000396000f30060806040526004361061006c5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166327b53401811461007157806341c0e1b5146100fe57806348c5e7bc146101155780637f630b4c1461012d578063f1eae25c14610186575b600080fd5b34801561007d57600080fd5b5061008960043561019b565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100c35781810151838201526020016100ab565b50505050905090810190601f1680156100f05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561010a57600080fd5b50610113610235565b005b34801561012157600080fd5b50610089600435610276565b34801561013957600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101139436949293602493928401919081908401838280828437509497506103199650505050505050565b34801561019257600080fd5b50610113610421565b60016020818152600092835260409283902080548451600294821615610100026000190190911693909304601f810183900483028401830190945283835291929083018282801561022d5780601f106102025761010080835404028352916020019161022d565b820191906000526020600020905b81548152906001019060200180831161021057829003601f168201915b505050505081565b6000543373ffffffffffffffffffffffffffffffffffffffff908116911614156102745760005473ffffffffffffffffffffffffffffffffffffffff16ff5b565b60008181526001602081815260409283902080548451600260001995831615610100029590950190911693909304601f8101839004830284018301909452838352606093909183018282801561030d5780601f106102e25761010080835404028352916020019161030d565b820191906000526020600020905b8154815290600101906020018083116102f057829003601f168201915b50505050509050919050565b60003382604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140182805190602001908083835b6020831061038d5780518252601f19909201916020918201910161036e565b51815160209384036101000a600019018019909216911617905260408051929094018290039091206000818152600183529390932088519397506103d996509450870192506104589050565b50604051819073ffffffffffffffffffffffffffffffffffffffff3316907f6eb913f8381f04b5834f6f06c6b4b88df26f76a9ca6796ccd1c423a8281c851c90600090a35050565b6000805473ffffffffffffffffffffffffffffffffffffffff19163373ffffffffffffffffffffffffffffffffffffffff16179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061049957805160ff19168380011785556104c6565b828001600101855582156104c6579182015b828111156104c65782518255916020019190600101906104ab565b506104d29291506104d6565b5090565b6104f091905b808211156104d257600081556001016104dc565b905600a165627a7a72305820069778fb50b89b88f77ce5e177c54524efd1ecec6ef957ce6f7b164d392706d60029';
+ this.createSnptContract();
+ }
+ async createSnptContract() {
+ const abi = [{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"fiddle_data","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"bytes32"}],"name":"get_fiddle","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_code","type":"string"}],"name":"share","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"mortal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_user","type":"address"},{"indexed":true,"name":"_id","type":"bytes32"}],"name":"NewFiddle","type":"event"}];
+ const SnippetServiceAddr = "0xBb114b958D1A3a0Ca6Ec260e11dc66Ba14a845bA";
+ const gasPrice = await this.web3.eth.getGasPrice();
+ this.snptContract = await new this.web3.eth.Contract(abi, SnippetServiceAddr, {
+ data: '0x' + this.bytecode,
+ gasPrice: this.web3.utils.toHex(gasPrice)
+ });
+ }
+ get snptEvents() {
+ return this.snptContract.events;
}
async compileWeb3(sources) {
// compile solidity using solcjs
@@ -404,7 +417,8 @@ export default class Web3Helpers {
}
async shareCode(coinbase, password, code, gas) {
const that = this;
- const { bytecode, abi } = this;
+ const { bytecode, abi, SnippetServiceAddr } = this;
+ const { snptContract } = this;
return new Promise(async (resolve, reject) => {
if(!coinbase) {
@@ -415,28 +429,16 @@ export default class Web3Helpers {
if(password) {
const unlocked = await that.web3.eth.personal.unlockAccount(coinbase, password);
}
- const gasPrice = await that.web3.eth.getGasPrice();
- const contract = await new that.web3.eth.Contract(abi, '0xc17744c2F1B77907574b7D49A00319Aa47e828B8', {
- from: coinbase,
- data: '0x' + bytecode,
- gas: that.web3.utils.toHex(gas),
- gasPrice: that.web3.utils.toHex(gasPrice)
- });
- contract.events.NewFiddle()
- .on('data', data => {
- console.log("Got new fiddle...");
- const fiddleId = data.returnValues._id;
- console.log(fiddleId);
- resolve(fiddleId);
- })
- contract.methods.share(code).send({ from: coinbase })
+ snptContract.options.from = coinbase;
+ snptContract.options.gas = that.web3.utils.toHex(gas);
+
+ snptContract.methods.share(code).send({ from: coinbase })
.on('transactionHash', txHash => {
- console.log('transactionHash:');
- console.log(txHash);
+ resolve(txHash);
})
.on('error', e => {
reject(e);
- })
+ });
} catch (e) {
console.log(e);
reject(e);
@@ -444,12 +446,9 @@ export default class Web3Helpers {
});
}
async getSnippet(coinbase, id) {
- const { abi } = this;
+ const { snptContract } = this;
try {
- const contract = await new this.web3.eth.Contract(abi, '0xc17744c2F1B77907574b7D49A00319Aa47e828B8', {
- from: coinbase
- });
- return await contract.methods.get_fiddle(id).call({ from: coinbase });
+ return await snptContract.methods.get_fiddle(id).call({ from: coinbase });
} catch(e) {
throw e;
}
diff --git a/lib/web3/web3.js b/lib/web3/web3.js
index 65bab1b..330d7a2 100644
--- a/lib/web3/web3.js
+++ b/lib/web3/web3.js
@@ -241,7 +241,7 @@ export default class Web3Env {
if(!this.web3Subscriptions) {
return
}
- this.compileSubscriptions.add(atom.workspace.observeTextEditors((editor) => {
+ this.compileSubscriptions.add(atom.workspace.observeActiveTextEditor((editor) => {
if(!editor || !editor.getBuffer()) {
return
}
diff --git a/styles/atom-solidity.less b/styles/atom-solidity.less
index b576778..547bc91 100644
--- a/styles/atom-solidity.less
+++ b/styles/atom-solidity.less
@@ -45,6 +45,17 @@
width: 100%;
margin-top: 10px;
padding: 0px 8px;
+
+ .padded {
+ padding: 5px;
+ }
+ }
+
+ .row-thin {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;
}
.icon {
From 53499da59c1df52453a95346858047ec7d3a8f45 Mon Sep 17 00:00:00 2001
From: 0mkar <0mkar@protonmail.com>
Date: Wed, 9 May 2018 02:27:34 +0530
Subject: [PATCH 7/9] add telegram link to help
---
lib/components/TabView/index.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/components/TabView/index.js b/lib/components/TabView/index.js
index 7813ae7..288fd72 100644
--- a/lib/components/TabView/index.js
+++ b/lib/components/TabView/index.js
@@ -120,6 +120,9 @@ class TabView extends React.Component {
Etheratom news #Etheratom
+
+ Etheratom telegram t.me/etheratom
+
Contact: 0mkar@protonmail.com
From 4b138d529cc6ad47123b7ba226dab09adf86fe84 Mon Sep 17 00:00:00 2001
From: 0mkar <0mkar@protonmail.com>
Date: Wed, 9 May 2018 03:08:25 +0530
Subject: [PATCH 8/9] proper gas estimate with code
---
lib/components/ShareBox/index.js | 20 ++++++++++++++------
lib/web3/methods.js | 6 +++---
styles/atom-solidity.less | 2 +-
3 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/lib/components/ShareBox/index.js b/lib/components/ShareBox/index.js
index b49022c..b25ed29 100644
--- a/lib/components/ShareBox/index.js
+++ b/lib/components/ShareBox/index.js
@@ -26,6 +26,7 @@ class ShareBox extends React.Component {
shared: false,
shareLink: null,
gas: 0,
+ gasLimit: 0,
snippet: null,
txHash: null,
code: null,
@@ -56,14 +57,20 @@ class ShareBox extends React.Component {
}
async componentDidMount() {
const { coinbase } = this.props;
- const gasEstm = await this.helpers.getShareGasEstm(coinbase);
- this.setState({ gas: gasEstm });
atom.workspace.observeActiveTextEditor(async (editor) => {
if(!editor || !editor.getBuffer()) {
return
}
- code = editor.getText();
- this.setState({ code });
+ const code = editor.getText();
+ const maxGas = await this.helpers.getGasLimit();
+ this.setState({ code, gasLimit: maxGas });
+ try {
+ const gasEstm = await this.helpers.getShareGasEstm(coinbase, code);
+ this.setState({ gas: gasEstm });
+ } catch(e) {
+ this.setState({ gas: 0 });
+ throw e;
+ }
return;
});
}
@@ -116,7 +123,7 @@ class ShareBox extends React.Component {
}
}
render() {
- const { shareLink, shared, gas, snippet, txHash, code, toggleBtnStyle, togglePreviewTxt, isOpened } = this.state;
+ const { shareLink, shared, gas, snippet, txHash, code, toggleBtnStyle, togglePreviewTxt, isOpened, gasLimit } = this.state;
return (
@@ -156,7 +163,8 @@ class ShareBox extends React.Component {
-
This is contract creation gas. Update it according to your needs!
+
Adjust gas estimate.
+
Max: { gasLimit }
diff --git a/lib/web3/methods.js b/lib/web3/methods.js
index f375d98..8d52931 100644
--- a/lib/web3/methods.js
+++ b/lib/web3/methods.js
@@ -411,9 +411,9 @@ export default class Web3Helpers {
}
}
// Code sharing
- async getShareGasEstm(coinbase) {
- const { bytecode } = this;
- return await this.getGasEstimate(coinbase, bytecode);
+ async getShareGasEstm(coinbase, code) {
+ const maxGas = await this.getGasLimit();
+ return await this.snptContract.methods.share(code).estimateGas({ gas: maxGas, from: coinbase });
}
async shareCode(coinbase, password, code, gas) {
const that = this;
diff --git a/styles/atom-solidity.less b/styles/atom-solidity.less
index 547bc91..b6c248a 100644
--- a/styles/atom-solidity.less
+++ b/styles/atom-solidity.less
@@ -54,7 +54,7 @@
.row-thin {
display: flex;
flex-direction: row;
- justify-content: center;
+ justify-content: space-between;
align-items: center;
}
From 477dd7c2f50a4dbcffe22a9c56b8b2826a70cf94 Mon Sep 17 00:00:00 2001
From: 0mkar <0mkar@protonmail.com>
Date: Fri, 18 May 2018 20:53:08 +0530
Subject: [PATCH 9/9] more encoders
---
lib/components/Web3Utilities/index.js | 83 ++++++++++++++++++++++++++-
lib/web3/methods.js | 19 ++++++
2 files changed, 101 insertions(+), 1 deletion(-)
diff --git a/lib/components/Web3Utilities/index.js b/lib/components/Web3Utilities/index.js
index f2c6427..33420d8 100644
--- a/lib/components/Web3Utilities/index.js
+++ b/lib/components/Web3Utilities/index.js
@@ -40,6 +40,13 @@ class Web3Utilities extends React.Component {
this._padLeft64 = this._padLeft64.bind(this);
this._padRight64 = this._padRight64.bind(this);
this._hexToAscii = this._hexToAscii.bind(this);
+ // abi encoders & decoders
+ this._encFuncSig = this._encFuncSig.bind(this);
+ this._encEvntSig = this._encEvntSig.bind(this);
+ this._encFuncCall = this._encFuncCall.bind(this);
+ this._encParams = this._encParams.bind(this);
+ this._decParams = this._decParams.bind(this);
+ this._decLog = this._decLog.bind(this);
}
_handleInputChange(event) {
this.setState({ input: event.target.value });
@@ -143,6 +150,60 @@ class Web3Utilities extends React.Component {
this.helpers.showPanelError(e);
}
}
+ async _encFuncSig() {
+ try {
+ const { input } = this.state;
+ const encodedFn = await this.helpers.encFuncSig(input);
+ this.setState({ output: encodedFn });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ async _encEvntSig() {
+ try {
+ const { input } = this.state;
+ const encodedEvnt = await this.helpers.encEvntSig(input);
+ this.setState({ output: encodedEvnt });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ async _encFuncCall() {
+ try {
+ const { input } = this.state;
+ const encodedFnCl = await this.helpers.encFuncCall(input);
+ this.setState({ output: encodedFnCl });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ async _encParams() {
+ try {
+ const { input } = this.state;
+ const encodedParams = await this.helpers.encParams(input);
+ this.setState({ output: encodedParams });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ async _decParams() {
+ try {
+ const { input } = this.state;
+ const decodedParams = await this.helpers.decParams(input);
+ this.setState({ output: decodedParams });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
+ async _decLog() {
+ try {
+ const { input } = this.state;
+ const decodedLog = await this.helpers.decLog(input);
+ this.setState({ output: decodedLog });
+ } catch(e) {
+ this.helpers.showPanelError(e);
+ }
+ }
render() {
return (
@@ -153,7 +214,7 @@ class Web3Utilities extends React.Component {
name="utilsInput"
value={this.state.input}
onChange={this._handleInputChange}
- placeholder="Enter web3 supported cryptographically encoded string"
+ placeholder="Enter value to encoded/decode"
class="input-text" />
@@ -191,6 +252,26 @@ class Web3Utilities extends React.Component {
Pad right 64
+
+
+
+
+
+
+
+
{
this.state.output &&
diff --git a/lib/web3/methods.js b/lib/web3/methods.js
index 8d52931..65665ca 100644
--- a/lib/web3/methods.js
+++ b/lib/web3/methods.js
@@ -453,4 +453,23 @@ export default class Web3Helpers {
throw e;
}
}
+ // abi encoders & decoders
+ async encFuncSig(input) {
+ return await this.web3.eth.abi.encodeFunctionSignature(input);
+ }
+ async encEvntSig(input) {
+ return await this.web3.eth.abi.encodeEventSignature(input);
+ }
+ async encFuncCall(input) {
+ return await this.web3.eth.abi.encodeFunctionCall(input);
+ }
+ async encParams(input) {
+ return await this.web3.eth.abi.encodeParameters(input);
+ }
+ async decParams(input) {
+ return await this.web3.eth.abi.decodeParameters(input);
+ }
+ async decLog(input) {
+ return await this.web3.eth.abi.decodeLog(input);
+ }
}