fix abi and bytecode copy and presentation

pull/4182/head
Joseph Izang 1 year ago
parent ae91d82a78
commit 218b69709d
  1. 8
      apps/vyper/src/app/app.tsx
  2. 28
      apps/vyper/src/app/components/CompilerButton.tsx
  3. 27
      apps/vyper/src/app/components/VyperResult.tsx
  4. 4
      apps/vyper/src/app/utils/compiler.tsx
  5. 8
      apps/vyper/src/app/utils/remix-client.tsx

@ -1,6 +1,6 @@
import React, {useState, useEffect} from 'react'
import {VyperCompilationOutput, remixClient, toStandardOutput} from './utils'
import {VyperCompilationOutput, normalizeContractPath, remixClient, toStandardOutput} from './utils'
import {CompilationResult} from '@remixproject/plugin-api'
// Components
@ -13,7 +13,6 @@ import ToggleButton from 'react-bootstrap/ToggleButton'
import Button from 'react-bootstrap/Button'
import './app.css'
import { VyperCompilationResultType } from './utils/types'
interface AppState {
status: 'idle' | 'inProgress'
@ -34,7 +33,7 @@ const App: React.FC = () => {
environment: 'local',
localUrl: 'http://localhost:8000/'
})
const [compilerResponse, setCompilerResponse] = useState<any>({})
useEffect(() => {
async function start() {
@ -100,8 +99,9 @@ const App: React.FC = () => {
setOutput={(name, update) => setOutput({...output, [name]: update})}
/>
</div>
<article id="result" className="px-2">
<VyperResult output={contract ? output[contract] : undefined} />
{Object.keys(output).length > 0 ? <VyperResult output={ output} themeColor={remixClient.checkActiveTheme()} /> : null}
</article>
</section>
</main>

@ -1,11 +1,13 @@
import React from 'react'
import {isVyper, compile, toStandardOutput, VyperCompilationOutput, isCompilationError, remixClient} from '../utils'
import {isVyper, compile, toStandardOutput, VyperCompilationOutput, isCompilationError, remixClient, normalizeContractPath} from '../utils'
import Button from 'react-bootstrap/Button'
import _ from 'lodash'
import { runtime } from 'webpack'
interface Props {
compilerUrl: string
contract?: string
setOutput: (name: string, output: VyperCompilationOutput) => void
setOutput: (name: string, output: any) => void
}
function CompilerButton({contract, setOutput, compilerUrl}: Props) {
@ -40,8 +42,26 @@ function CompilerButton({contract, setOutput, compilerUrl}: Props) {
setOutput(_contract.name, {status: 'failed', message: e.message})
return
}
setOutput(_contract.name, output)
// setCompilerResponse(output)
const compileReturnType = () => {
const t: any = toStandardOutput(contract, output)
const temp = _.merge(t['contracts'][contract])
const normal = normalizeContractPath(contract)[2]
console.log(normal)
const abi = temp[normal]['abi']
const evm = _.merge(temp[normal]['evm'])
const dpb = evm.deployedBytecode
const runtimeBytecode = evm.bytecode
const result = {
contractName: normal,
abi: abi,
bytecode: dpb,
runtimeBytecode: runtimeBytecode,
ir: ''
}
return result
}
setOutput(_contract.name, compileReturnType())
// ERROR
if (isCompilationError(output)) {

@ -3,13 +3,14 @@ import {VyperCompilationOutput, isCompilationError} from '../utils'
import Tabs from 'react-bootstrap/Tabs'
import Tab from 'react-bootstrap/Tab'
import Button from 'react-bootstrap/Button'
import JSONTree from 'react-json-view'
import JSONTree, { ThemeKeys } from 'react-json-view'
import ReactJson from 'react-json-view'
import {CopyToClipboard} from '@remix-ui/clipboard'
import { VyperCompilationResult } from '../utils/types'
interface VyperResultProps {
output?: VyperCompilationOutput
output?: any
themeColor?: string
}
export type ExampleContract = {
@ -17,7 +18,7 @@ export type ExampleContract = {
address: string
}
function VyperResult({ output }: VyperResultProps) {
function VyperResult({ output, themeColor }: VyperResultProps) {
const [active, setActive] = useState<keyof VyperCompilationResult>('abi')
if (!output)
@ -49,36 +50,36 @@ function VyperResult({ output }: VyperResultProps) {
return (
<Tabs id="result" activeKey={active} onSelect={(key: any) => setActive(key)}>
<Tab eventKey="abi" title="ABI">
<CopyToClipboard getContent={() => JSON.stringify(output.abi)}>
<CopyToClipboard getContent={() => JSON.stringify(Object.values(output)[0]['abi'])}>
<Button variant="info" className="copy" data-id="copy-abi">
Copy ABI
</Button>
</CopyToClipboard>
<JSONTree src={output.abi} />
<JSONTree src={Object.values(output)[0]['abi']} theme={themeColor as any}/>
</Tab>
<Tab eventKey="bytecode" title="Bytecode">
<CopyToClipboard getContent={() => output.bytecode}>
<CopyToClipboard getContent={() => JSON.stringify(Object.values(output)[0]['bytecode'].object.toString())}>
<Button variant="info" className="copy">
Copy Bytecode
</Button>
</CopyToClipboard>
<textarea defaultValue={output.bytecode}></textarea>
<textarea defaultValue={Object.values(output)[0]['bytecode'].object.toString()}></textarea>
</Tab>
<Tab eventKey="bytecode_runtime" title="Runtime Bytecode">
<CopyToClipboard getContent={() => output.bytecode_runtime}>
<CopyToClipboard getContent={() => JSON.stringify(Object.values(output)[0]['runtimeBytecode'].object.toString())}>
<Button variant="info" className="copy">
Copy Runtime Bytecode
</Button>
</CopyToClipboard>
<textarea defaultValue={output.bytecode_runtime}></textarea>
<textarea defaultValue={Object.values(output)[0]['runtimeBytecode'].object.toString()}></textarea>
</Tab>
<Tab eventKey="ir" title="LLL">
<CopyToClipboard getContent={() => output.ir}>
<Button variant="info" className="copy">
Copy LLL Code
<CopyToClipboard getContent={() => JSON.stringify(Object.values(output)[0]['ir'])}>
<Button disabled={Object.values(output)[0]['ir'].length <= 1} variant="info" className="copy">
{Object.values(output)[0]['ir'].length > 1 ? 'Copy LLL Code' : 'Nothing to copy yet'}
</Button>
</CopyToClipboard>
<textarea defaultValue={output.ir}></textarea>
<textarea defaultValue={Object.values(output)[0]['ir'].toString()}></textarea>
</Tab>
</Tabs>
)

@ -10,6 +10,7 @@ export interface Contract {
export interface VyperCompilationResult {
status: 'success'
bytecode: string
contractName?: string
bytecode_runtime: string
abi: ABIDescription[]
ir: string
@ -102,7 +103,7 @@ export async function compile(url: string, contract: Contract): Promise<VyperCom
* @param compilationResult Result returned by the compiler
*/
export function toStandardOutput(fileName: string, compilationResult: VyperCompilationResultType): CompilationResult {
const contractName = fileName.split('/').slice(-1)[0].split('.')[0]
const contractName = normalizeContractPath(fileName)[2]
const compiledAbi = compilationResult['contractTypes'][contractName].abi
const deployedBytecode = compilationResult['contractTypes'][contractName].deploymentBytecode.bytecode.replace('0x', '')
const bytecode = compilationResult['contractTypes'][contractName].runtimeBytecode.bytecode.replace('0x', '')
@ -123,6 +124,7 @@ export function toStandardOutput(fileName: string, compilationResult: VyperCompi
// The Ethereum Contract ABI. If empty, it is represented as an empty array.
// See https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
abi: compiledAbi,
contractName: contractName,
evm: {
bytecode: {
linkReferences: {},

@ -4,6 +4,7 @@ import {createClient} from '@remixproject/plugin-webview'
import {PluginClient} from '@remixproject/plugin'
import {Contract} from './compiler'
import {ExampleContract} from '../components/VyperResult'
import { ThemeKeys } from 'react-json-view'
export class RemixClient extends PluginClient {
private client = createClient<Api, Readonly<RemixApi>>(this)
@ -66,6 +67,13 @@ export class RemixClient extends PluginClient {
this.client.emit('statusChanged', status)
}
checkActiveTheme() {
const active = this.client.call('theme', 'currentTheme')
if (active === 'dark') {
return 'monokai' as any
}
}
/** Highlight a part of the editor */
async highlight(lineColumnPos: HighlightPosition, name: string, message: string) {
await this.client.call('editor', 'highlight', lineColumnPos, name)

Loading…
Cancel
Save