mirror of
https://github.com/embarklabs/embark.git
synced 2025-02-16 23:57:11 +00:00
feature: decode raw transactions in tx decoder
This commit is contained in:
parent
5e4a80edec
commit
b15467f64a
@ -103,6 +103,13 @@ export const transaction = {
|
||||
failure: (error) => action(TRANSACTION[FAILURE], {error})
|
||||
};
|
||||
|
||||
export const DECODED_TRANSACTION = createRequestTypes('DECODED_TRANSACTION');
|
||||
export const decodedTransaction = {
|
||||
request: (hash) => action(DECODED_TRANSACTION[REQUEST], {hash}),
|
||||
success: (transaction) => action(DECODED_TRANSACTION[SUCCESS], {transaction}),
|
||||
failure: (error) => action(DECODED_TRANSACTION[FAILURE], {error})
|
||||
};
|
||||
|
||||
export const PROCESSES = createRequestTypes('PROCESSES');
|
||||
export const processes = {
|
||||
request: () => action(PROCESSES[REQUEST]),
|
||||
|
@ -6,8 +6,8 @@ import {withRouter} from 'react-router-dom';
|
||||
import TransactionDecoder from '../components/TransactionDecoder';
|
||||
import PageHead from '../components/PageHead';
|
||||
import { Row, Col } from 'reactstrap';
|
||||
import { transaction as transactionAction } from '../actions';
|
||||
import {getTransaction} from "../reducers/selectors";
|
||||
import { decodedTransaction as decodedTransactionAction } from '../actions';
|
||||
import {getDecodedTransaction} from "../reducers/selectors";
|
||||
|
||||
const getQueryParams = (props) => {
|
||||
return qs.parse(props.location.search, {
|
||||
@ -19,7 +19,7 @@ class TransactionDecoderContainer extends Component {
|
||||
componentDidMount() {
|
||||
const { hash } = getQueryParams(this.props);
|
||||
if (hash) {
|
||||
this.props.fetchTransaction(hash);
|
||||
this.props.fetchDecodedTransaction(hash);
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ class TransactionDecoderContainer extends Component {
|
||||
const prevHash = getQueryParams(prevProps).hash;
|
||||
|
||||
if (hash && hash !== prevHash) {
|
||||
this.props.fetchTransaction(hash);
|
||||
this.props.fetchDecodedTransaction(hash);
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,13 +48,13 @@ class TransactionDecoderContainer extends Component {
|
||||
}
|
||||
|
||||
TransactionDecoderContainer.propTypes = {
|
||||
fetchTransaction: PropTypes.func,
|
||||
fetchDecodedTransaction: PropTypes.func,
|
||||
transaction: PropTypes.object
|
||||
};
|
||||
|
||||
function mapStateToProps(state, props) {
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
transaction: getTransaction(state, getQueryParams(props).hash),
|
||||
transaction: getDecodedTransaction(state),
|
||||
error: state.errorMessage,
|
||||
loading: state.loading
|
||||
};
|
||||
@ -62,6 +62,6 @@ function mapStateToProps(state, props) {
|
||||
export default withRouter(connect(
|
||||
mapStateToProps,
|
||||
{
|
||||
fetchTransaction: transactionAction.request
|
||||
fetchDecodedTransaction: decodedTransactionAction.request
|
||||
}
|
||||
)(TransactionDecoderContainer));
|
||||
|
@ -3,7 +3,7 @@ import {REQUEST, SUCCESS, FAILURE, CONTRACT_COMPILE, FILES, LOGOUT, AUTHENTICATE
|
||||
FETCH_CREDENTIALS, UPDATE_BASE_ETHER, CHANGE_THEME, FETCH_THEME, EXPLORER_SEARCH, DEBUGGER_INFO,
|
||||
SIGN_MESSAGE, VERIFY_MESSAGE, TOGGLE_BREAKPOINT, UPDATE_PREVIEW_URL,
|
||||
UPDATE_DEPLOYMENT_PIPELINE, WEB3_CONNECT, WEB3_DEPLOY, WEB3_ESTIMAGE_GAS, FETCH_EDITOR_TABS,
|
||||
SAVE_FILE, SAVE_FOLDER, REMOVE_FILE} from "../actions";
|
||||
SAVE_FILE, SAVE_FOLDER, REMOVE_FILE, DECODED_TRANSACTION} from "../actions";
|
||||
import {EMBARK_PROCESS_NAME, DARK_THEME, DEPLOYMENT_PIPELINES, DEFAULT_HOST, ELEMENTS_LIMIT} from '../constants';
|
||||
|
||||
const BN_FACTOR = 10000;
|
||||
@ -376,6 +376,16 @@ function editorTabs(state = [], action) {
|
||||
return state;
|
||||
}
|
||||
|
||||
function decodedTransaction(state = {}, action) {
|
||||
if (action.type === DECODED_TRANSACTION[SUCCESS] && action.transaction) {
|
||||
return action.transaction;
|
||||
}
|
||||
if (action.type === DECODED_TRANSACTION[FAILURE]) {
|
||||
return action.error;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
function previewUrl(state= `${window.location.protocol}//${window.location.host}/`, action) {
|
||||
if (action.type === UPDATE_PREVIEW_URL) {
|
||||
return action.payload;
|
||||
@ -419,7 +429,8 @@ const rootReducer = combineReducers({
|
||||
theme,
|
||||
editorTabs,
|
||||
previewUrl,
|
||||
editorOperationStatus
|
||||
editorOperationStatus,
|
||||
decodedTransaction
|
||||
});
|
||||
|
||||
export default rootReducer;
|
||||
|
@ -28,6 +28,10 @@ export function getTransaction(state, hash) {
|
||||
return state.entities.transactions.find((transaction) => transaction.hash === hash);
|
||||
}
|
||||
|
||||
export function getDecodedTransaction(state) {
|
||||
return state.decodedTransaction;
|
||||
}
|
||||
|
||||
export function getTransactionsByAccount(state, address) {
|
||||
return state.entities.transactions.filter((transaction) => transaction.from === address);
|
||||
}
|
||||
|
@ -81,6 +81,7 @@ export const toggleBreakpoint = doRequest.bind(null, actions.toggleBreakpoint, a
|
||||
export const authenticate = doRequest.bind(null, actions.authenticate, api.authenticate);
|
||||
export const initRegularTxs = doRequest.bind(null, actions.initRegularTxs, api.regularTxs);
|
||||
export const stopRegularTxs = doRequest.bind(null, actions.stopRegularTxs, api.regularTxs);
|
||||
export const decodeTransaction = doRequest.bind(null, actions.decodedTransaction, api.fetchTransaction);
|
||||
|
||||
export const fetchCredentials = doRequest.bind(null, actions.fetchCredentials, storage.fetchCredentials);
|
||||
export const saveCredentials = doRequest.bind(null, actions.saveCredentials, storage.saveCredentials);
|
||||
@ -103,6 +104,10 @@ export function *watchFetchTransaction() {
|
||||
yield takeEvery(actions.TRANSACTION[actions.REQUEST], fetchTransaction);
|
||||
}
|
||||
|
||||
export function *watchDecodeTransaction() {
|
||||
yield takeEvery(actions.DECODED_TRANSACTION[actions.REQUEST], decodeTransaction);
|
||||
}
|
||||
|
||||
export function *watchFetchTransactions() {
|
||||
yield takeEvery(actions.TRANSACTIONS[actions.REQUEST], fetchTransactions);
|
||||
}
|
||||
@ -557,6 +562,7 @@ export default function *root() {
|
||||
fork(watchListenToContractEvents),
|
||||
fork(watchFetchBlock),
|
||||
fork(watchFetchTransactions),
|
||||
fork(watchDecodeTransaction),
|
||||
fork(watchPostCommand),
|
||||
fork(watchPostCommandSuggestions),
|
||||
fork(watchFetchVersions),
|
||||
|
@ -1,11 +1,12 @@
|
||||
const Web3 = require('web3');
|
||||
const async = require('async');
|
||||
const Provider = require('./provider.js');
|
||||
const Transaction = require('ethereumjs-tx');
|
||||
const ethUtil = require('ethereumjs-util');
|
||||
const utils = require('../../utils/utils');
|
||||
const constants = require('../../constants');
|
||||
const embarkJsUtils = require('embarkjs').Utils;
|
||||
const {bigNumberify} = require('ethers/utils/bignumber');
|
||||
const RLP = require('ethers/utils/rlp');
|
||||
|
||||
const WEB3_READY = 'blockchain:ready';
|
||||
|
||||
@ -420,10 +421,12 @@ class BlockchainConnector {
|
||||
'/embark-api/blockchain/transactions/:hash',
|
||||
(req, res) => {
|
||||
self.getTransactionByHash(req.params.hash, (err, transaction) => {
|
||||
if (err) {
|
||||
self.logger.error(err);
|
||||
}
|
||||
res.send(transaction);
|
||||
if (!err) return res.send(transaction);
|
||||
|
||||
self.getTransactionByRawTransactionHash(req.params.hash, (err, transaction) => {
|
||||
if(err) return res.send({ error: "Could not find or decode transaction hash" });
|
||||
res.send(transaction);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
@ -645,20 +648,39 @@ class BlockchainConnector {
|
||||
}
|
||||
|
||||
getTransactionByRawTransactionHash(hash, cb) {
|
||||
const rawData = Buffer.from(ethUtil.stripHexPrefix(hash), 'hex');
|
||||
const tx = new Transaction(rawData, 'hex');
|
||||
let rawData, decoded;
|
||||
|
||||
try {
|
||||
rawData = Buffer.from(ethUtil.stripHexPrefix(hash), 'hex');
|
||||
decoded = RLP.decode(rawData);
|
||||
} catch(e) {
|
||||
return cb("could not decode transaction");
|
||||
}
|
||||
|
||||
const [
|
||||
nonce,
|
||||
gasPrice,
|
||||
gasLimit,
|
||||
to,
|
||||
value,
|
||||
data,
|
||||
v,
|
||||
r,
|
||||
s
|
||||
] = decoded;
|
||||
|
||||
const transaction = {
|
||||
from: `0x${tx.getSenderAddress().toString('hex').toLowerCase()}`,
|
||||
gasPrice: tx.gasPrice.toString('utf8'),
|
||||
input: `0x${tx.input.toString('hex').toLowerCase()}`,
|
||||
nonce: tx.nonce.toString('utf8'),
|
||||
v: `0x${tx.v.toString('hex').toLowerCase()}`,
|
||||
r: `0x${tx.r.toString('hex').toLowerCase()}`,
|
||||
s: `0x${tx.s.toString('hex').toLowerCase()}`,
|
||||
value: tx.value.toString('utf8'),
|
||||
to: `0x${tx.to.toString('hex').toLowerCase()}`,
|
||||
hash
|
||||
nonce: bigNumberify(nonce).toNumber(),
|
||||
gasPrice: bigNumberify(gasPrice).toNumber(),
|
||||
gasLimit: bigNumberify(gasLimit).toNumber(),
|
||||
data: data,
|
||||
v: `0x${v.toString('hex').toLowerCase()}`,
|
||||
r: `0x${r.toString('hex').toLowerCase()}`,
|
||||
s: `0x${s.toString('hex').toLowerCase()}`,
|
||||
value: value.toString('utf8'),
|
||||
to: `0x${to.toString('hex').toLowerCase()}`
|
||||
};
|
||||
|
||||
cb(null, transaction);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user