Merge pull request #1509 from 0xProject/fix/dev-tools-pages/finalTouches

Dev Tools Pages - Final Touches
This commit is contained in:
Fabio B
2019-01-17 16:56:01 +01:00
committed by GitHub
32 changed files with 325 additions and 165 deletions

View File

@@ -1,3 +1 @@
public
assets/fonts/*.woff
assets/fonts/*.woff2
public

View File

@@ -1,20 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<ul>
<li><a href="/compiler">Compiler</a></li>
<li><a href="/cov">Cov</a></li>
<li><a href="/profiler">Profiler</a></li>
<li><a href="/trace">Trace</a></li>
</ul>
</body>
</html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Test</title>
</head>
<body>
<ul>
<li><a href="/compiler">Compiler</a></li>
<li><a href="/coverage">Coverage</a></li>
<li><a href="/profiler">Profiler</a></li>
<li><a href="/trace">Trace</a></li>
</ul>
</body>
</html>

View File

@@ -12,7 +12,17 @@
"build:dev": "../../node_modules/.bin/webpack --mode development",
"clean": "shx rm -f public/bundle*",
"lint": "tslint --format stylish --project . 'ts/**/*.ts' 'ts/**/*.tsx'",
"dev": "webpack-dev-server --mode development --content-base public"
"dev": "webpack-dev-server --mode development --content-base public",
"deploy:all": "npm run build; npm run deploy:compiler; npm run deploy:compiler:index; npm run deploy:coverage; npm run deploy:coverage:index; npm run deploy:profiler; npm run deploy:profiler:index; npm run deploy:trace; npm run deploy:trace:index;",
"deploy:compiler": "DIR_NAME=./public/. BUCKET=s3://sol-compiler.com yarn s3:sync --exclude 'bundle-cov*' --exclude 'bundle-trace*' --exclude 'bundle-profiler*'",
"deploy:coverage": "DIR_NAME=./public/. BUCKET=s3://sol-coverage.com yarn s3:sync --exclude 'bundle-compiler*' --exclude 'bundle-trace*' --exclude 'bundle-profiler*'",
"deploy:profiler": "DIR_NAME=./public/. BUCKET=s3://sol-profiler.com yarn s3:sync --exclude 'bundle-cov*' --exclude 'bundle-trace*' --exclude 'bundle-compiler*'",
"deploy:trace": "DIR_NAME=./public/. BUCKET=s3://sol-trace.com yarn s3:sync --exclude 'bundle-cov*' --exclude 'bundle-compiler*' --exclude 'bundle-profiler*'",
"deploy:compiler:index": "DIR_NAME=./public/compiler/. BUCKET=s3://sol-compiler.com yarn s3:sync",
"deploy:coverage:index": "DIR_NAME=./public/coverage/. BUCKET=s3://sol-coverage.com yarn s3:sync",
"deploy:profiler:index": "DIR_NAME=./public/profiler/. BUCKET=s3://sol-profiler.com yarn s3:sync",
"deploy:trace:index": "DIR_NAME=./public/trace/. BUCKET=s3://sol-trace.com yarn s3:sync",
"s3:sync": "aws s3 sync $DIR_NAME $BUCKET --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --exclude *.map.js --exclude 'profiler/*' --exclude 'trace/*' --exclude 'coverage/*' --exclude 'compiler/*'"
},
"license": "Apache-2.0",
"dependencies": {

View File

@@ -17,15 +17,15 @@ const pages = [
},
},
{
title: 'sol-cov',
filename: 'cov/index.html',
title: 'sol-coverage',
filename: 'coverage/index.html',
template: 'assets/index.html',
chunks: ['cov'],
chunks: ['coverage'],
favicon: 'assets/favicons/cov.ico',
minify: true,
meta: {
description: 'Solidity code coverage',
'og-title': { property: 'og:title', content: 'sol-cov' },
'og-title': { property: 'og:title', content: 'sol-coverage' },
'og-description': { property: 'og:description', content: 'Solidity code coverage' },
'og-type': { property: 'og:type', content: 'website' },
'og-image': { property: 'og:image', content: '/images/og-cov' },

View File

@@ -0,0 +1,40 @@
import * as React from 'react';
import styled from 'styled-components';
import { ContextInterface, ThemeContext } from 'ts/context';
import { Button } from './button';
const CallToAction: React.StatelessComponent<ContextInterface> = ({ children }) => (
<ThemeContext.Consumer>
{({ docLink }: ContextInterface) => (
<StyledCallToAction>
<CallToActionContainer>
<Button as="a" href={docLink} target="_blank" large={true}>
Read the Docs
</Button>
</CallToActionContainer>
{navigator.userAgent !== 'ReactSnap' ? children : null}
</StyledCallToAction>
)}
</ThemeContext.Consumer>
);
const StyledCallToAction = styled.section`
text-align: center;
padding-top: 0;
padding-bottom: 1rem;
padding-left: 2.5rem;
padding-right: 2.5rem;
min-height: min-content;
max-height: 37.5rem;
height: 20vh;
position: relative;
`;
const CallToActionContainer = styled.div`
margin: 0 auto;
max-width: 590px;
`;
export { CallToAction };

View File

@@ -139,7 +139,6 @@ class Code extends React.Component<CodeProps, CodeState> {
public render(): React.ReactNode {
const { language, isLight, isDiff, children, gutterLength, canCopy } = this.props;
const { hlCode } = this.state;
return (
<Container>
<Base language={language} isDiff={isDiff} isLight={isLight}>

View File

@@ -45,7 +45,7 @@ const Dd = styled.dd`
const cards = [
{
title: 'A Project-centric',
title: 'Project-centric',
body: (
<React.Fragment>
Compiles an entire project instead of only individual <InlineCode isAlt={true}>.sol</InlineCode> files.
@@ -54,7 +54,7 @@ const cards = [
},
{
title: 'Incremental builds',
body: 'Recompiles your smart contracts after they have changed',
body: 'Only recompiles smart contracts that have been modified.',
},
{
title: 'Customizable artifacts',
@@ -63,12 +63,16 @@ const cards = [
},
{
title: 'Seamless',
body: 'Fetches and caches the required compiler binaries.',
body: 'Fetches and caches the required compiler binaries for the Solidity versions you use.',
},
{
title: 'Versioning',
body:
'Compiles each contract with the version specified at the top of its file (sol-compiler even supports version ranges!).',
'Compiles each contract with the Solidity version specified at the top of its file (it even supports version ranges!).',
},
{
title: 'Watch mode',
body: 'Have your contracts instantly recompile on file save.',
},
];

View File

@@ -3,7 +3,7 @@ import * as React from 'react';
import styled from 'styled-components';
import { context as compiler } from 'ts/context/compiler';
import { context as cov } from 'ts/context/cov';
import { context as coverage } from 'ts/context/coverage';
import { context as profiler } from 'ts/context/profiler';
import { context as trace } from 'ts/context/trace';
import MainIcon from 'ts/icons/logos/0x.svg';
@@ -12,7 +12,7 @@ import { media } from 'ts/variables';
import { Container } from './container';
import { Alpha, Beta } from './typography';
const tools = [trace, cov, compiler, profiler];
const tools = [trace, coverage, compiler, profiler];
const Footer: React.StatelessComponent<{}> = () => (
<StyledFooter>
@@ -20,9 +20,9 @@ const Footer: React.StatelessComponent<{}> = () => (
<Top>
<Alpha>Other tools by 0x</Alpha>
<List>
{_.map(tools, ({ title, subtitle, icon }) => (
{_.map(tools, ({ title, subtitle, icon, name }) => (
<ListItem key={title}>
<ListLink href="#">
<ListLink href={`http://sol-${name}.com`}>
<Icon as={icon as 'svg'} />
<div>
<Beta>{title}</Beta>

View File

@@ -17,7 +17,7 @@ const Header: React.StatelessComponent<{}> = () => (
<Title>{title}</Title>
</LogoMark>
<Link as="a" href="https://0xproject.com/">
<Link as="a" href="https://0x.org/" target="_blank">
Built by 0x
</Link>
</Container>

View File

@@ -9,12 +9,12 @@ import { Beta } from './typography';
const Hero: React.StatelessComponent<ContextInterface> = ({ children }) => (
<ThemeContext.Consumer>
{({ subtitle, tagline }: ContextInterface) => (
{({ subtitle, tagline, docLink }: ContextInterface) => (
<StyledHero>
<HeroContainer>
<Subtitle>{subtitle}</Subtitle>
<Tagline as="p">{tagline}</Tagline>
<Button as="a" href="#" large={true}>
<Button as="a" href={docLink} target="_blank" large={true}>
Read the Docs
</Button>
</HeroContainer>

View File

@@ -25,7 +25,7 @@ const Trace: React.StatelessComponent<{}> = () => (
troublemaking line of code. The only hint you'll get is a generic error.
</MainCopy>
<Breakout>
<Code isLight={true}>Error: VM Exception while processing transaction: rever</Code>
<Code isLight={true}>Error: VM Exception while processing transaction: revert</Code>
</Breakout>
<List>
@@ -44,8 +44,8 @@ const Trace: React.StatelessComponent<{}> = () => (
<Copy dark={true}>
<Gamma as="h3">Time-consuming</Gamma>
<p>
Working with a large code-base that contains hundreds of smart contracts,
finding the failing line of code quickly becomes a daunting task.
Working within a large code-base that contains many smart contracts, finding the
failing line of code quickly becomes a daunting task.
</p>
</Copy>
<Icon as={TimeConsuming} />
@@ -78,8 +78,8 @@ const Trace: React.StatelessComponent<{}> = () => (
<Copy>
<Gamma as="h3">Exact location</Gamma>
<p>
It shows you the exact location of the specific code linen and where it was
called from.
It shows you the exact location of the offending line and where it was called
from.
</p>
</Copy>
<Icon as={ExactLocation} />
@@ -90,8 +90,7 @@ const Trace: React.StatelessComponent<{}> = () => (
<Gamma as="h3">Time-saving</Gamma>
<p>
Turning "Your code failed somewhere, good luck debugging it" into "Your code
failed on line X of contract Y", it drastically improves the developer
experience.
failed on line X of contract Y", drastically improves the developer experience.
</p>
</Copy>
<Icon as={TimeSaving} />

View File

@@ -5,6 +5,7 @@ import { ContextInterface } from './index';
export const context: ContextInterface = {
title: 'sol-compiler',
name: 'compiler',
docLink: 'https://0x.org/docs/sol-compiler',
subtitle: 'Solidity compilation that just works',
tagline: 'Seamlessly compile an entire solidity project and generate customisable artifacts',
icon: Icon,

View File

@@ -3,9 +3,10 @@ import Icon from 'ts/icons/logos/cov.svg';
import { ContextInterface } from './index';
export const context: ContextInterface = {
title: 'sol-cov',
name: 'cov',
title: 'sol-coverage',
name: 'coverage',
subtitle: 'Solidity code coverage',
docLink: 'https://0x.org/docs/sol-coverage',
tagline: 'Measure Solidity code coverage',
icon: Icon,
colors: {

View File

@@ -3,6 +3,7 @@ import { createContext } from 'react';
interface ContextInterface {
title?: string;
name?: string;
docLink?: string;
subtitle?: string;
tagline?: string;
icon?: React.ReactNode;

View File

@@ -5,6 +5,7 @@ import { ContextInterface } from './index';
export const context: ContextInterface = {
title: 'sol-profiler',
name: 'profiler',
docLink: 'https://0x.org/docs/sol-profiler',
subtitle: 'Gas profiling for Solidity',
tagline: "Implement data-guided optimizations by profiling your contract's gas usage",
icon: Icon,

View File

@@ -6,6 +6,7 @@ export const context: ContextInterface = {
title: 'sol-trace',
name: 'trace',
subtitle: 'Human-readable stack traces',
docLink: 'https://0x.org/docs/sol-trace',
tagline: 'Immediately locate Solidity errors and rapidly debug failed transactions',
icon: Icon,
colors: {

View File

@@ -6,6 +6,7 @@ import { context } from 'ts/context/compiler';
import { Base } from 'ts/components/base';
import { Breakout } from 'ts/components/breakout';
import { CallToAction } from 'ts/components/call_to_action';
import { Code } from 'ts/components/code';
import { Compiler as CompilerComponent } from 'ts/components/compiler';
import { Content } from 'ts/components/content';
@@ -24,6 +25,9 @@ const Animation = Loadable({
},
});
const SOLIDITY_INPUT_FORMAT_DOCS =
'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#compiler-input-and-output-json-description';
const Compiler: React.StatelessComponent<{}> = () => (
<Base context={context}>
<Hero>
@@ -40,7 +44,7 @@ const Compiler: React.StatelessComponent<{}> = () => (
<ContentBlock title="Run">
<Breakout>
<Code>cd /your_project_dir && sol-compiler</Code>
<Code canCopy={true}>cd /your_project_dir && sol-compiler</Code>
</Breakout>
</ContentBlock>
@@ -49,11 +53,11 @@ const Compiler: React.StatelessComponent<{}> = () => (
Configure via a <InlineCode>compiler.json</InlineCode> file.
</p>
<Breakout>
<Code>mkdir compiler.json</Code>
<Code canCopy={true}>mkdir compiler.json</Code>
</Breakout>
<p>Example of settings:</p>
<Breakout>
<Code language="json">
<Code language="json" canCopy={true}>
{`{
"contractsDir": "contracts",
"artifactsDir": "artifacts",
@@ -74,15 +78,19 @@ const Compiler: React.StatelessComponent<{}> = () => (
<Content dark={true}>
<ContentBlock main={true} title="Artifacts">
<Lead>
Sol compiler uses solidity standard JSON output format for the artifacts. This way, you can define
which parts of the artifact you need.
Sol compiler uses{' '}
<a href={SOLIDITY_INPUT_FORMAT_DOCS} target="_blank">
Solidity standard JSON input format
</a>{' '}
to specify what to include in the generated artifacts. This way, you have complete flexibility on
what is included.
</Lead>
</ContentBlock>
<ContentBlock title="Production">
<p>
Sol compiler uses solidity standard JSON output format for the artifacts. This way, you can define
which parts of the artifact you need.
In production, you want to optimize for a small bundle size, so your compiler.json config would
instruct sol-compiler to only output the contract ABI.
</p>
<Breakout>
<Code isLight={true} language="json" isEtc={true}>
@@ -109,8 +117,9 @@ const Compiler: React.StatelessComponent<{}> = () => (
</ContentBlock>
<ContentBlock title="Development">
<p>
Sometimes you need to use some debuggers or other dev tools and youll need more info in the
artifact.
In development, you need to use profiler and other dev tools that require more information from the
artifact. To do this, you can specify that the artifact also contain the bytecode, deployed bytecode
and source maps.
</p>
<Breakout>
<Code isLight={true} language="json" isEtc={true}>
@@ -158,6 +167,9 @@ const Compiler: React.StatelessComponent<{}> = () => (
</Breakout>
</ContentBlock>
</Content>
<div style={{ paddingTop: '5rem' }}>
<CallToAction />
</div>
</Base>
);

View File

@@ -2,10 +2,11 @@ import * as React from 'react';
import { hydrate, render } from 'react-dom';
import * as Loadable from 'react-loadable';
import { context } from 'ts/context/cov';
import { context } from 'ts/context/coverage';
import { Base } from 'ts/components/base';
import { Breakout } from 'ts/components/breakout';
import { CallToAction } from 'ts/components/call_to_action';
import { Code } from 'ts/components/code';
import { Content } from 'ts/components/content';
import { ContentBlock } from 'ts/components/content-block';
@@ -25,7 +26,7 @@ const Animation = Loadable({
},
});
const Cov: React.StatelessComponent<{}> = () => (
const Coverage: React.StatelessComponent<{}> = () => (
<Base context={context}>
<Hero>
<Animation />
@@ -33,9 +34,9 @@ const Cov: React.StatelessComponent<{}> = () => (
<Intro>
<IntroLead title="Measure your tests">
<p>
When it comes to writing smart contracts, testing is one of the most important steps of the process.
In order to quantify the robustness of your Solidity testing suite, you need to measure its code
coverage.
When it comes to writing secure smart contracts, testing is one of the most important steps in the
process. In order to quantify the robustness of your Solidity testing suite, you need to measure its
code coverage.
</p>
</IntroLead>
<IntroAside>
@@ -69,29 +70,57 @@ const Cov: React.StatelessComponent<{}> = () => (
<ContentBlock title="Prerequisites">
<List>
<ListItem>
Use <a href="#">ganache-cli</a> as a backing node.
Use{' '}
<a href="https://github.com/ethereum/go-ethereum" target="_blank">
Geth
</a>{' '}
as a backing node. We recommend using our{' '}
<a href="https://hub.docker.com/r/0xorg/devnet" target="_blank">
Devnet Docker container
</a>{' '}
which sets up a Geth node for testing purposes.{' '}
<a href="https://github.com/0xProject/0x-monorepo/issues/1520" target="_blank">
Ganache support is a work in progress.
</a>
</ListItem>
<ListItem>
Understand and use <a href="#">web3-provider-engine</a>.
Understand and use{' '}
<a href="https://github.com/MetaMask/provider-engine" target="_blank">
web3-provider-engine
</a>
.
</ListItem>
</List>
</ContentBlock>
<ContentBlock title="Installation">
<Breakout>
<Code>npm install @0x/sol-coverage --save</Code>
<Code canCopy={true}>npm install @0x/sol-coverage --save</Code>
</Breakout>
<p>
Sol-cov is a subprovider that needs to be prepended to your <a href="#">provider engine</a>.
Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-cov ships with
the <InlineCode>SolCompilerArtifactAdapter</InlineCode> for use with <a href="#">Sol-compiler</a>{' '}
Sol-coverage is a subprovider that needs to be prepended to your{' '}
<a href="https://github.com/MetaMask/provider-engine" target="_blank">
provider engine
</a>
. Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-coverage
ships with the <InlineCode>SolCompilerArtifactAdapter</InlineCode> for use with{' '}
<a href="http://sol-compiler.com" target="_blank">
Sol-compiler
</a>{' '}
and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
<a href="#">Truffle framework</a>. You can also write your own and support any artifact format.
<a href="https://truffleframework.com/truffle" target="_blank">
Truffle framework
</a>{' '}
(Also see our{' '}
<a href="https://github.com/0xProject/dev-tools-truffle-example" target="_blank">
Truffle example project
</a>{' '}
for a complete walk-through). You can also write your own and support any artifact format.
</p>
<Tabs>
<TabBlock title="Sol-compiler">
<Code language="javascript">
<Code language="javascript" canCopy={true}>
{`import { SolCompilerArtifactAdapter } from '@0x/sol-trace';
// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
@@ -99,16 +128,16 @@ const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDi
</Code>
</TabBlock>
<TabBlock title="Truffle">
<Code language="javascript">
<Code language="javascript" canCopy={true}>
{`import { TruffleArtifactAdapter } from '@0x/sol-trace';
const projectRoot = '.';
const solcVersion = '0.4.24';
const solcVersion = '0.5.0';
const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);`}
</Code>
</TabBlock>
<TabBlock title="Custom">
<Code language="javascript">
<Code language="javascript" canCopy={true}>
{`import { AbstractArtifactAdapter } from '@0x/sol-trace';
class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...};
@@ -118,32 +147,33 @@ const artifactAdapter = new YourCustomArtifactsAdapter(...);`}
</Tabs>
<p>
Now that we have an <InlineCode>artifactAdapter</InlineCode>, we can create a{' '}
<InlineCode>RevertTraceSubprovider</InlineCode> and append it to our provider engine.
<InlineCode>CoverageSubprovider</InlineCode> and append it to our provider engine.
</p>
<Breakout>
<Code language="javascript">
<Code language="javascript" canCopy={true}>
{`import { ProviderEngine, RpcSubprovider } from 'web3-provider-engine';
import { RevertTraceSubprovider } from '@0x/sol-coverage';
import { CoverageSubprovider } from '@0x/sol-coverage';
const defaultFromAddress = "..."; // Some ethereum address with test funds
const revertTraceSubprovider = new RevertTraceSubprovider(artifactAdapter, defaultFromAddress);
const coverageSubprovider = new CoverageSubprovider(artifactAdapter, defaultFromAddress);
const providerEngine = new ProviderEngine();
providerEngine.addProvider(revertTraceSubprovider);
providerEngine.addProvider(coverageSubprovider);
providerEngine.addProvider(new RpcSubprovider({rpcUrl: 'http://localhost:8545'}));
providerEngine.start();`}
</Code>
</Breakout>
</ContentBlock>
</Content>
<CallToAction />
</Base>
);
const root = document.getElementById('app');
if (root.hasChildNodes()) {
hydrate(<Cov />, root);
hydrate(<Coverage />, root);
} else {
render(<Cov />, root);
render(<Coverage />, root);
}

View File

@@ -6,6 +6,7 @@ import { context } from 'ts/context/profiler';
import { Base } from 'ts/components/base';
import { Breakout } from 'ts/components/breakout';
import { CallToAction } from 'ts/components/call_to_action';
import { Code } from 'ts/components/code';
import { Content } from 'ts/components/content';
import { ContentBlock } from 'ts/components/content-block';
@@ -66,29 +67,57 @@ const Profiler: React.StatelessComponent<{}> = () => (
<ContentBlock title="Prerequisites">
<List>
<ListItem>
Use <a href="#">ganache-cli</a> as a backing node.
Use{' '}
<a href="https://github.com/ethereum/go-ethereum" target="_blank">
Geth
</a>{' '}
as a backing node. We recommend using our{' '}
<a href="https://hub.docker.com/r/0xorg/devnet" target="_blank">
Devnet Docker container
</a>{' '}
which sets up a Geth node for testing purposes.{' '}
<a href="https://github.com/0xProject/0x-monorepo/issues/1520" target="_blank">
Ganache support is a work in progress.
</a>
</ListItem>
<ListItem>
Understand and use <a href="#">web3-provider-engine</a>.
Understand and use{' '}
<a href="https://github.com/MetaMask/provider-engine" target="_blank">
web3-provider-engine
</a>
.
</ListItem>
</List>
</ContentBlock>
<ContentBlock title="Installation">
<Breakout>
<Code>npm install @0x/sol-trace --save</Code>
<Code canCopy={true}>npm install @0x/sol-trace --save</Code>
</Breakout>
<p>
Sol-trace is a subprovider that needs to be prepended to your <a href="#">provider engine</a>.
Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships
Sol-trace is a subprovider that needs to be prepended to your{' '}
<a href="https://github.com/MetaMask/provider-engine" target="_blank">
provider engine
</a>
. Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships
with the <InlineCode>SolCompilerArtifactAdapter</InlineCode> for use with{' '}
<a href="#">Sol-compiler</a> and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
<a href="#">Truffle framework</a>. You can also write your own and support any artifact format.
<a href="http://sol-compiler.com" target="_blank">
Sol-compiler
</a>{' '}
and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
<a href="https://truffleframework.com/truffle" target="_blank">
Truffle framework
</a>{' '}
(Also see our{' '}
<a href="https://github.com/0xProject/dev-tools-truffle-example" target="_blank">
Truffle example project
</a>{' '}
for a complete walk-through). You can also write your own and support any artifact format.
</p>
<Tabs>
<TabBlock title="Sol-compiler">
<Code language="javascript">
<Code language="javascript" canCopy={true}>
{`import { SolCompilerArtifactAdapter } from '@0x/sol-trace';
// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
@@ -96,16 +125,16 @@ const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDi
</Code>
</TabBlock>
<TabBlock title="Truffle">
<Code language="javascript">
<Code language="javascript" canCopy={true}>
{`import { TruffleArtifactAdapter } from '@0x/sol-trace';
const projectRoot = '.';
const solcVersion = '0.4.24';
const solcVersion = '0.5.0';
const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);`}
</Code>
</TabBlock>
<TabBlock title="Custom">
<Code language="javascript">
<Code language="javascript" canCopy={true}>
{`import { AbstractArtifactAdapter } from '@0x/sol-trace';
class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...};
@@ -115,25 +144,26 @@ const artifactAdapter = new YourCustomArtifactsAdapter(...);`}
</Tabs>
<p>
Now that we have an <InlineCode>artifactAdapter</InlineCode>, we can create a{' '}
<InlineCode>RevertTraceSubprovider</InlineCode> and append it to our provider engine.
<InlineCode>ProfilerSubprovider</InlineCode> and append it to our provider engine.
</p>
<Breakout>
<Code language="javascript">
<Code language="javascript" canCopy={true}>
{`import { ProviderEngine, RpcSubprovider } from 'web3-provider-engine';
import { RevertTraceSubprovider } from '@0x/sol-coverage';
import { ProfilerSubprovider } from '@0x/sol-profiler';
const defaultFromAddress = "..."; // Some ethereum address with test funds
const revertTraceSubprovider = new RevertTraceSubprovider(artifactAdapter, defaultFromAddress);
const profilerSubprovider = new ProfilerSubprovider(artifactAdapter, defaultFromAddress);
const providerEngine = new ProviderEngine();
providerEngine.addProvider(revertTraceSubprovider);
providerEngine.addProvider(profilerSubprovider);
providerEngine.addProvider(new RpcSubprovider({rpcUrl: 'http://localhost:8545'}));
providerEngine.start();`}
</Code>
</Breakout>
</ContentBlock>
</Content>
<CallToAction />
</Base>
);

View File

@@ -6,6 +6,7 @@ import { context } from 'ts/context/trace';
import { Base } from 'ts/components/base';
import { Breakout } from 'ts/components/breakout';
import { CallToAction } from 'ts/components/call_to_action';
import { Code } from 'ts/components/code';
import { Content } from 'ts/components/content';
import { ContentBlock } from 'ts/components/content-block';
@@ -36,29 +37,57 @@ const Trace: React.StatelessComponent<{}> = () => (
<ContentBlock title="Prerequisites">
<List>
<ListItem>
Use <a href="#">ganache-cli</a> as a backing node.
Use{' '}
<a href="https://github.com/ethereum/go-ethereum" target="_blank">
Geth
</a>{' '}
as a backing node. We recommend using our{' '}
<a href="https://hub.docker.com/r/0xorg/devnet" target="_blank">
Devnet Docker container
</a>{' '}
which sets up a Geth node for testing purposes.{' '}
<a href="https://github.com/0xProject/0x-monorepo/issues/1520" target="_blank">
Ganache support is a work in progress.
</a>
</ListItem>
<ListItem>
Understand and use <a href="#">web3-provider-engine</a>.
Understand and use{' '}
<a href="https://github.com/MetaMask/provider-engine" target="_blank">
web3-provider-engine
</a>
.
</ListItem>
</List>
</ContentBlock>
<ContentBlock title="Installation">
<Breakout>
<Code>npm install @0x/sol-trace --save</Code>
<Code canCopy={true}>npm install @0x/sol-trace --save</Code>
</Breakout>
<p>
Sol-trace is a subprovider that needs to be prepended to your <a href="#">provider engine</a>.
Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships
Sol-trace is a subprovider that needs to be prepended to your{' '}
<a href="https://github.com/MetaMask/provider-engine" target="_blank">
provider engine
</a>
. Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships
with the <InlineCode>SolCompilerArtifactAdapter</InlineCode> for use with{' '}
<a href="#">Sol-compiler</a> and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
<a href="#">Truffle framework</a>. You can also write your own and support any artifact format.
<a href="http://sol-compiler.com" target="_blank">
Sol-compiler
</a>{' '}
and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
<a href="https://truffleframework.com/truffle" target="_blank">
Truffle framework
</a>{' '}
(Also see our{' '}
<a href="https://github.com/0xProject/dev-tools-truffle-example" target="_blank">
Truffle example project
</a>{' '}
for a complete walk-through). You can also write your own and support any artifact format.
</p>
<Tabs>
<TabBlock title="Sol-compiler">
<Code language="javascript">
<Code language="javascript" canCopy={true}>
{`import { SolCompilerArtifactAdapter } from '@0x/sol-trace';
// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
@@ -66,16 +95,16 @@ const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDi
</Code>
</TabBlock>
<TabBlock title="Truffle">
<Code language="javascript">
<Code language="javascript" canCopy={true}>
{`import { TruffleArtifactAdapter } from '@0x/sol-trace';
const projectRoot = '.';
const solcVersion = '0.4.24';
const solcVersion = '0.5.0';
const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);`}
</Code>
</TabBlock>
<TabBlock title="Custom">
<Code language="javascript">
<Code language="javascript" canCopy={true}>
{`import { AbstractArtifactAdapter } from '@0x/sol-trace';
class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...};
@@ -85,13 +114,13 @@ const artifactAdapter = new YourCustomArtifactsAdapter(...);`}
</Tabs>
<p>
Now that we have an <InlineCode>artifactAdapter</InlineCode>, we can create a{' '}
<InlineCode>RevertTraceSubprovider</InlineCode> and append it to our provider engine.
<InlineCode>revertTraceSubprovider</InlineCode> and append it to our provider engine.
</p>
<Breakout>
<Code language="javascript">
<Code language="javascript" canCopy={true}>
{`import { ProviderEngine, RpcSubprovider } from 'web3-provider-engine';
import { RevertTraceSubprovider } from '@0x/sol-coverage';
import { RevertTraceSubprovider } from '@0x/sol-trace';
const defaultFromAddress = "..."; // Some ethereum address with test funds
const revertTraceSubprovider = new RevertTraceSubprovider(artifactAdapter, defaultFromAddress);
@@ -102,8 +131,10 @@ providerEngine.addProvider(new RpcSubprovider({rpcUrl: 'http://localhost:8545'})
providerEngine.start();`}
</Code>
</Breakout>
<p>Stack traces will now be printed whenever your contracts revert!</p>
</ContentBlock>
</Content>
<CallToAction />
</Base>
);

View File

@@ -3,7 +3,6 @@ const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const HtmlWebpackPlugin = require('html-webpack-plugin');
const childProcess = require('child_process');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
@@ -12,7 +11,7 @@ const pages = require('./pages');
const config = {
entry: {
compiler: './ts/pages/compiler.tsx',
cov: './ts/pages/cov.tsx',
coverage: './ts/pages/coverage.tsx',
profiler: './ts/pages/profiler.tsx',
trace: './ts/pages/trace.tsx',
},

View File

@@ -1,7 +1,7 @@
**Install**
```bash
yarn add @0x/sol-coverage
yarn add -D @0x/sol-coverage
```
**Import**

View File

@@ -1 +1 @@
Welcome to the [sol-coverage](https://github.com/0xProject/0x-monorepo/tree/development/packages/sol-coverage) documentation! Sol-coverage is a Solidity coverage tool for your smart contract tests.
Welcome to the [sol-coverage](https://github.com/0xProject/0x-monorepo/tree/development/packages/sol-coverage) documentation! Sol-coverage is a Solidity coverage tool.

View File

@@ -1,4 +1,4 @@
Sol-coverage uses transaction traces in order to figure out which lines of Solidity source code have been covered by your tests. In order for it to gather these traces, you must add the `CoverageSubprovider` to the [ProviderEngine](https://github.com/MetaMask/provider-engine) instance you use when running your Solidity tests. If you're unfamiliar with ProviderEngine, please read the [Web3 Provider explained](https://0x.org/wiki#Web3-Provider-Explained) wiki article.
Sol-coverage uses transaction traces in order to figure out which lines of Solidity source code have been covered by your tests. In order for it to gather these traces, you must add the `CoverageSubprovider` to the [ProviderEngine](https://github.com/MetaMask/provider-engine) instance you use when running your Solidity tests. If you're unfamiliar with `ProviderEngine`, please read the [Web3 Provider explained](https://0x.org/wiki#Web3-Provider-Explained) wiki article.
The CoverageSubprovider eavesdrops on the `eth_sendTransaction` and `eth_call` RPC calls and collects traces after each call using `debug_traceTransaction`. `eth_call`'s' don't generate traces - so we take a snapshot, re-submit it as a transaction, get the trace and then revert the snapshot.
@@ -12,9 +12,8 @@ If you are generating your artifacts with [@0x/sol-compiler](https://0x.org/docs
```typescript
import { SolCompilerArtifactsAdapter } from '@0x/sol-coverage';
const artifactsPath = 'src/artifacts';
const contractsPath = 'src/contracts';
const artifactsAdapter = new SolCompilerArtifactsAdapter(artifactsPath, contractsPath);
// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir);
```
### Truffle
@@ -23,8 +22,9 @@ If your project is using [Truffle](https://truffleframework.com/), we've written
```typescript
import { TruffleArtifactAdapter } from '@0x/sol-coverage';
const contractsPath = 'src/contracts';
const artifactAdapter = new TruffleArtifactAdapter(contractsDir);
const projectRoot = '.';
const solcVersion = '0.5.0';
const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);
```
Because truffle artifacts don't have all the data we need - we actually will recompile your contracts under the hood. That's why you don't need to pass an `artifactsPath`.
@@ -32,7 +32,13 @@ Because truffle artifacts don't have all the data we need - we actually will rec
### Other framework/toolset
You'll need to write your own artifacts adapter. It should extend `AbstractArtifactsAdapter`.
Look at the code of the two adapters above for examples.
```typescript
import { AbstractArtifactAdapter } from '@0x/sol-trace';
class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...};
const artifactAdapter = new YourCustomArtifactsAdapter(...);
```
### Usage
@@ -41,16 +47,14 @@ import { CoverageSubprovider } from '@0x/sol-coverage';
import ProviderEngine = require('web3-provider-engine');
const provider = new ProviderEngine();
const artifactsPath = 'src/artifacts';
const contractsPath = 'src/contracts';
const networkId = 50;
// Some calls might not have `from` address specified. Nevertheless - transactions need to be submitted from an address with at least some funds. defaultFromAddress is the address that will be used to submit those calls as transactions from.
const defaultFromAddress = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
const isVerbose = true;
const coverageSubprovider = new CoverageSubprovider(artifactsAdapter, defaultFromAddress, isVerbose);
provider.addProvider(coverageSubprovider);
// Add all your other providers
provider.start();
```
After your test suite is complete (e.g in the Mocha global `after` hook), you'll need to call:

View File

@@ -1,7 +1,7 @@
**Install**
```bash
yarn add @0x/sol-profiler
yarn add -D @0x/sol-profiler
```
**Import**

View File

@@ -1,4 +1,4 @@
Sol-profiler uses transaction traces in order to figure out which lines of Solidity source code have been covered by your tests. In order for it to gather these traces, you must add the `ProfilerSubprovider` to the [ProviderEngine](https://github.com/MetaMask/provider-engine) instance you use when running your Solidity tests. If you're unfamiliar with ProviderEngine, please read the [Web3 Provider explained](https://0x.org/wiki#Web3-Provider-Explained) wiki article.
Sol-profiler uses transaction traces in order to figure out which lines of Solidity source code have been covered by your tests. In order for it to gather these traces, you must add the `ProfilerSubprovider` to the [ProviderEngine](https://github.com/MetaMask/provider-engine) instance you use when running your Solidity tests. If you're unfamiliar with `ProviderEngine`, please read the [Web3 Provider explained](https://0x.org/wiki#Web3-Provider-Explained) wiki article.
The ProfilerSubprovider eavesdrops on the `eth_sendTransaction` and `eth_call` RPC calls and collects traces after each call using `debug_traceTransaction`. `eth_call`'s' don't generate traces - so we take a snapshot, re-submit it as a transaction, get the trace and then revert the snapshot.
@@ -12,9 +12,8 @@ If you are generating your artifacts with [@0x/sol-compiler](https://0x.org/docs
```typescript
import { SolCompilerArtifactsAdapter } from '@0x/sol-profiler';
const artifactsPath = 'src/artifacts';
const contractsPath = 'src/contracts';
const artifactsAdapter = new SolCompilerArtifactsAdapter(artifactsPath, contractsPath);
// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir);
```
### Truffle
@@ -23,8 +22,9 @@ If your project is using [Truffle](https://truffleframework.com/), we've written
```typescript
import { TruffleArtifactAdapter } from '@0x/sol-profiler';
const contractsPath = 'src/contracts';
const artifactAdapter = new TruffleArtifactAdapter(contractsDir);
const projectRoot = '.';
const solcVersion = '0.5.0';
const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);
```
Because truffle artifacts don't have all the data we need - we actually will recompile your contracts under the hood. That's why you don't need to pass an `artifactsPath`.
@@ -32,7 +32,13 @@ Because truffle artifacts don't have all the data we need - we actually will rec
### Other framework/toolset
You'll need to write your own artifacts adapter. It should extend `AbstractArtifactsAdapter`.
Look at the code of the two adapters above for examples.
```typescript
import { AbstractArtifactAdapter } from '@0x/sol-trace';
class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...};
const artifactAdapter = new YourCustomArtifactsAdapter(...);
```
### Usage
@@ -41,22 +47,20 @@ import { ProfilerSubprovider } from '@0x/sol-profiler';
import ProviderEngine = require('web3-provider-engine');
const provider = new ProviderEngine();
const artifactsPath = 'src/artifacts';
const contractsPath = 'src/contracts';
const networkId = 50;
// Some calls might not have `from` address specified. Nevertheless - transactions need to be submitted from an address with at least some funds. defaultFromAddress is the address that will be used to submit those calls as transactions from.
const defaultFromAddress = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
const isVerbose = true;
const profilerSubprovider = new ProfilerSubprovider(artifactsAdapter, defaultFromAddress, isVerbose);
provider.addProvider(profilerSubprovider);
// Add all your other providers
provider.start();
```
After your test suite is complete (e.g in the Mocha global `after` hook), you'll need to call:
```typescript
await profilerSubprovider.writeProfilerAsync();
await profilerSubprovider.writeProfilerOutputAsync();
```
This will create a `profiler.json` file in a `profiler` directory. This file has an [Istanbul format](https://github.com/gotwarlost/istanbul/blob/master/profiler.json.md) - so you can use it with any of the existing Istanbul reporters.
This will create a `coverage.json` file in a `coverage` directory. This file has an [Istanbul format](https://github.com/gotwarlost/istanbul/blob/master/profiler.json.md) - so you can use it with any of the existing Istanbul reporters.

View File

@@ -1,17 +1,17 @@
**Install**
```bash
yarn add @0x/sol-trace
yarn add -D @0x/sol-trace
```
**Import**
```javascript
import { TraceSubprovider } from '@0x/sol-trace';
import { RevertTraceSubprovider } from '@0x/sol-trace';
```
or
```javascript
var TraceSubprovider = require('@0x/sol-trace').TraceSubprovider;
var RevertTraceSubprovider = require('@0x/sol-trace').RevertTraceSubprovider;
```

View File

@@ -1 +1 @@
Welcome to the [sol-trace](https://github.com/0xProject/0x-monorepo/tree/development/packages/sol-trace) documentation! Sol-trace is a Solidity trace tool for your smart contract tests.
Welcome to the [sol-trace](https://github.com/0xProject/0x-monorepo/tree/development/packages/sol-trace) documentation! Sol-trace gives you a human-readable error stack trace when a revert happens in your Solidity code.

View File

@@ -1,10 +1,10 @@
Sol-trace uses transaction traces in order to figure out which lines of Solidity source code have been covered by your tests. In order for it to gather these traces, you must add the `TraceSubprovider` to the [ProviderEngine](https://github.com/MetaMask/provider-engine) instance you use when running your Solidity tests. If you're unfamiliar with ProviderEngine, please read the [Web3 Provider explained](https://0x.org/wiki#Web3-Provider-Explained) wiki article.
Sol-trace uses transaction traces to reconstruct the stack trace when reverts happen in Solidity. In order for it to gather these traces, you must add the `RevertTraceSubprovider` to the [ProviderEngine](https://github.com/MetaMask/provider-engine) instance you use when running your Solidity tests. If you're unfamiliar with `ProviderEngine`, please read the [Web3 Provider explained](https://0x.org/wiki#Web3-Provider-Explained) wiki article.
The TraceSubprovider eavesdrops on the `eth_sendTransaction` and `eth_call` RPC calls and collects traces after each call using `debug_traceTransaction`. `eth_call`'s' don't generate traces - so we take a snapshot, re-submit it as a transaction, get the trace and then revert the snapshot.
The `RevertTraceSubprovider` eavesdrops on the `eth_sendTransaction` and `eth_call` RPC calls and collects traces after each call using `debug_traceTransaction`. `eth_call`'s' don't generate traces - so we take a snapshot, re-submit it as a transaction, get the trace and then revert the snapshot.
Trace subprovider needs some info about your contracts (`srcMap`, `bytecode`). It gets that info from your project's artifacts. Some frameworks have their own artifact format. Some artifact formats don't actually contain all the neccessary data.
In order to use `TraceSubprovider` with your favorite framework you need to pass an `artifactsAdapter` to it.
In order to use `RevertTraceSubprovider` with your favorite framework you need to pass an `artifactsAdapter` to it.
### Sol-compiler
@@ -12,9 +12,8 @@ If you are generating your artifacts with [@0x/sol-compiler](https://0x.org/docs
```typescript
import { SolCompilerArtifactsAdapter } from '@0x/sol-trace';
const artifactsPath = 'src/artifacts';
const contractsPath = 'src/contracts';
const artifactsAdapter = new SolCompilerArtifactsAdapter(artifactsPath, contractsPath);
// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir);
```
### Truffle
@@ -23,8 +22,9 @@ If your project is using [Truffle](https://truffleframework.com/), we've written
```typescript
import { TruffleArtifactAdapter } from '@0x/sol-trace';
const contractsPath = 'src/contracts';
const artifactAdapter = new TruffleArtifactAdapter(contractsDir);
const projectRoot = '.';
const solcVersion = '0.5.0';
const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);
```
Because truffle artifacts don't have all the data we need - we actually will recompile your contracts under the hood. That's why you don't need to pass an `artifactsPath`.
@@ -32,31 +32,29 @@ Because truffle artifacts don't have all the data we need - we actually will rec
### Other framework/toolset
You'll need to write your own artifacts adapter. It should extend `AbstractArtifactsAdapter`.
Look at the code of the two adapters above for examples.
```typescript
import { AbstractArtifactAdapter } from '@0x/sol-trace';
class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...};
const artifactAdapter = new YourCustomArtifactsAdapter(...);
```
### Usage
```typescript
import { TraceSubprovider } from '@0x/sol-trace';
import { RevertTraceSubprovider } from '@0x/sol-trace';
import ProviderEngine = require('web3-provider-engine');
const provider = new ProviderEngine();
const artifactsPath = 'src/artifacts';
const contractsPath = 'src/contracts';
const networkId = 50;
// Some calls might not have `from` address specified. Nevertheless - transactions need to be submitted from an address with at least some funds. defaultFromAddress is the address that will be used to submit those calls as transactions from.
const defaultFromAddress = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
const isVerbose = true;
const traceSubprovider = new TraceSubprovider(artifactsAdapter, defaultFromAddress, isVerbose);
const revertTraceSubprovider = new RevertTraceSubprovider(artifactsAdapter, defaultFromAddress, isVerbose);
provider.addProvider(traceSubprovider);
provider.addProvider(revertTraceSubprovider);
// Add all your other providers
provider.start();
```
After your test suite is complete (e.g in the Mocha global `after` hook), you'll need to call:
```typescript
await traceSubprovider.writeTraceAsync();
```
This will create a `trace.json` file in a `trace` directory. This file has an [Istanbul format](https://github.com/gotwarlost/istanbul/blob/master/trace.json.md) - so you can use it with any of the existing Istanbul reporters.
Now when you run your tests, it should print out stack traces when encountering an error.