GithubHelp home page GithubHelp logo

ethereum / solc-js Goto Github PK

View Code? Open in Web Editor NEW
1.4K 43.0 449.0 689 KB

Javascript bindings for the Solidity compiler

Home Page: https://soliditylang.org

License: MIT License

JavaScript 10.50% Solidity 1.14% TypeScript 88.35%
solidity ethereum compiler hacktoberfest

solc-js's Introduction

CircleCI Coverage Status

solc-js

JavaScript bindings for the Solidity compiler.

Uses the Emscripten compiled Solidity found in the solc-bin repository.

Node.js Usage

To use the latest stable version of the Solidity compiler via Node.js you can install it via npm:

npm install solc

Usage on the Command-Line

If this package is installed globally (npm install -g solc), a command-line tool called solcjs will be available.

To see all the supported features, execute:

solcjs --help

To compile a contract that imports other contracts via relative paths:

solcjs --bin --include-path node_modules/ --base-path . MainContract.sol

Use the --base-path and --include-path options to describe the layout of your project. --base-path represents the root of your own source tree while --include-path allows you to specify extra locations containing external code (e.g. libraries installed with a package manager).

Note: ensure that all the files you specify on the command line are located inside the base path or one of the include paths. The compiler refers to files from outside of these directories using absolute paths. Having absolute paths in contract metadata will result in your bytecode being reproducible only when it's placed in these exact absolute locations.

Note: this commandline interface is not compatible with solc provided by the Solidity compiler package and thus cannot be used in combination with an Ethereum client via the eth.compile.solidity() RPC method. Please refer to the Solidity compiler documentation for instructions to install solc. Furthermore, the commandline interface to solc-js provides fewer features than the binary release.

Usage in Projects

There are two ways to use solc:

  1. Through a high-level API giving a uniform interface to all compiler versions
  2. Through a low-level API giving access to all the compiler interfaces, which depend on the version of the compiler

High-level API

The high-level API consists of a single method, compile, which expects the Compiler Standard Input and Output JSON.

It also accepts an optional set of callback functions, which include the import and the smtSolver callbacks. Starting 0.6.0 it only accepts an object in place of the callback to supply the callbacks.

The import callback function is used to resolve unmet dependencies. This callback receives a path and must synchronously return either an error or the content of the dependency as a string. It cannot be used together with callback-based, asynchronous, filesystem access. A workaround is to collect the names of dependencies, return an error, and keep re-running the compiler until all of them are resolved.

Example usage without the import callback

Example:

var solc = require('solc');

var input = {
  language: 'Solidity',
  sources: {
    'test.sol': {
      content: 'contract C { function f() public { } }'
    }
  },
  settings: {
    outputSelection: {
      '*': {
        '*': ['*']
      }
    }
  }
};

var output = JSON.parse(solc.compile(JSON.stringify(input)));

// `output` here contains the JSON output as specified in the documentation
for (var contractName in output.contracts['test.sol']) {
  console.log(
    contractName +
      ': ' +
      output.contracts['test.sol'][contractName].evm.bytecode.object
  );
}

Example usage with import callback

var solc = require('solc');

var input = {
  language: 'Solidity',
  sources: {
    'test.sol': {
      content: 'import "lib.sol"; contract C { function f() public { L.f(); } }'
    }
  },
  settings: {
    outputSelection: {
      '*': {
        '*': ['*']
      }
    }
  }
};

function findImports(path) {
  if (path === 'lib.sol')
    return {
      contents:
        'library L { function f() internal returns (uint) { return 7; } }'
    };
  else return { error: 'File not found' };
}

// New syntax (supported from 0.5.12, mandatory from 0.6.0)
var output = JSON.parse(
  solc.compile(JSON.stringify(input), { import: findImports })
);

// `output` here contains the JSON output as specified in the documentation
for (var contractName in output.contracts['test.sol']) {
  console.log(
    contractName +
      ': ' +
      output.contracts['test.sol'][contractName].evm.bytecode.object
  );
}

Since version 0.5.1, the smtSolver callback function is used to solve SMT queries generated by Solidity's SMTChecker. If you have an SMT solver installed locally, it can be used to solve the given queries, where the callback must synchronously return either an error or the result from the solver. A default smtSolver callback is included in this package via the module smtchecker.js which exports the smtCallback function that takes 1) a function that takes queries and returns the solving result, and 2) a solver configuration object. The module smtsolver.js has a few predefined solver configurations, and relies on Z3, Eldarica or CVC4 being installed locally. It exports the list of locally found solvers and a function that invokes a given solver.

The API of the SMT callback is experimental and can change at any time. The last change was in version 0.8.11.

Example usage with smtSolver callback

var solc = require('solc');
const smtchecker = require('solc/smtchecker');
const smtsolver = require('solc/smtsolver');
// Note that this example only works via node and not in the browser.

var input = {
  language: 'Solidity',
  sources: {
    'test.sol': {
      content: 'contract C { function f(uint x) public { assert(x > 0); } }'
    }
  },
  settings: {
    modelChecker: {
      engine: "chc",
      solvers: [ "smtlib2" ]
    }
  }
};

var output = JSON.parse(
  solc.compile(
    JSON.stringify(input),
    { smtSolver: smtchecker.smtCallback(smtsolver.smtSolver, smtsolver.availableSolvers[0]) }
  )
);

The assertion is clearly false, and an assertion failure warning should be returned, together with a counterexample.

Low-level API

The low-level API is as follows:

  • solc.lowlevel.compileSingle: the original entry point, supports only a single file
  • solc.lowlevel.compileMulti: this supports multiple files, introduced in 0.1.6
  • solc.lowlevel.compileCallback: this supports callbacks, introduced in 0.2.1
  • solc.lowlevel.compileStandard: this works just like compile above, but is only present in compilers after (and including) 0.4.11

For examples how to use them, please refer to the README of the above mentioned solc-js releases.

Note: These low-level functions remain available for compatibility reasons. However, they were superseded by the compile() function and are no longer required. Starting from version 0.5.0+commit.1d4f565a, the functions compileSingle, compileMulti, and compileCallback are always null when using newer solc binary versions. It is recommended to use the latest release of solc-js, but it should also handle all the older solc binaries down to 0.1.x.

Using with Electron

Note: If you are using Electron, nodeIntegration is on for BrowserWindow by default. If it is on, Electron will provide a require method which will not behave as expected and this may cause calls, such as require('solc'), to fail.

To turn off nodeIntegration, use the following:

new BrowserWindow({
  webPreferences: {
    nodeIntegration: false
  }
});

Using a Legacy Version

In order to compile contracts using a specific version of Solidity, the solc.loadRemoteVersion(version, callback) method is available. This returns a new solc object that uses a version of the compiler specified.

You can also load the "binary" manually and use setupMethods to create the familiar wrapper functions described above: var solc = solc.setupMethods(require("/my/local/soljson.js")).

Using the Latest Development Snapshot

By default, the npm version is only created for releases. This prevents people from deploying contracts with non-release versions because they are less stable and harder to verify. If you would like to use the latest development snapshot (at your own risk!), you may use the following example code.

var solc = require('solc');

// getting the development snapshot
solc.loadRemoteVersion('latest', function(err, solcSnapshot) {
  if (err) {
    // An error was encountered, display and quit
  } else {
    // NOTE: Use `solcSnapshot` here with the same interface `solc` has
    // For example:
    const output = solcSnapshot.compile(/* ... */)
  }
});

The version must be in the long format. Thus, if you would like to use version v0.8.17 you need to include the commit hash of the release. You can extract the long version string for each version from the publicly available release list.

solc.loadRemoteVersion('v0.8.17+commit.8df45f5f', function(err, solcSnapshot) { /* ... */ });

Linking Bytecode

When using libraries, the resulting bytecode will contain placeholders for the real addresses of the referenced libraries. These have to be updated, via a process called linking, before deploying the contract.

The linker module (require('solc/linker')) offers helpers to accomplish this.

The linkBytecode method provides a simple helper for linking:

var linker = require('solc/linker');

bytecode = linker.linkBytecode(bytecode, { MyLibrary: '0x123456...' });

As of Solidity 0.4.11 the compiler supports standard JSON input and output which outputs a link references map. This gives a map of library names to offsets in the bytecode to replace the addresses at. It also doesn't have the limitation on library file and contract name lengths.

There is a method available in the linker module called findLinkReferences which can find such link references in bytecode produced by an older compiler:

var linker = require('solc/linker');

var linkReferences = linker.findLinkReferences(bytecode);

Updating the ABI

The ABI generated by Solidity versions can differ slightly, due to new features introduced. There is a tool included which aims to translate the ABI generated by an older Solidity version to conform to the latest standard.

It can be used as:

var abi = require('solc/abi');

var inputABI = [
  {
    constant: false,
    inputs: [],
    name: 'hello',
    outputs: [{ name: '', type: 'string' }],
    payable: false,
    type: 'function'
  }
];
var outputABI = abi.update('0.3.6', inputABI);
// Output contains: [{"constant":false,"inputs":[],"name":"hello","outputs":[{"name":"","type":"string"}],"payable":true,"type":"function"},{"type":"fallback","payable":true}]

Formatting old JSON assembly output

There is a helper available to format old JSON assembly output into a text familiar to earlier users of Remix IDE.

var translate = require('solc/translate')

// assemblyJSON refers to the JSON of the given assembly and sourceCode is the source of which the assembly was generated from
var output = translate.prettyPrintLegacyAssemblyJSON(assemblyJSON, sourceCode)

Browser Usage

Compilation is generally a long-running and resource intensive task that cannot reasonably be performed in the main thread of the browser. Some browsers even disallow synchronous compilation on the main thread if the module is larger than 4KB. Thus, the only supported way to use solc in a web browser is through a web worker.

Loading solc with web workers

Web Workers allow you to run javascript in the background in the browser, letting the browser's main thread free to do whatever it needs to do. Please, see the minimal example of how to use solc with web workers below or check out this repository for a full demo.

  • index.html
<!DOCTYPE html>
<html>

<head>
	<meta charset="utf-8" />
</head>

<body>
	<script>
		var worker = new Worker('./dist/bundle.js');
		worker.addEventListener('message', function (e) {
			console.log(e.data.version)
		}, false);

		worker.postMessage({})
	</script>
</body>

</html>
  • worker.js:
importScripts('https://binaries.soliditylang.org/bin/soljson-v0.8.19+commit.7dd6d404.js')
import wrapper from 'solc/wrapper';

self.addEventListener('message', () => {
	const compiler = wrapper(self.Module)
	self.postMessage({
		version: compiler.version()
	})
}, false)

solc-js's People

Contributors

0mkara avatar 0x-r4bbit avatar adi611 avatar arthcp avatar axic avatar bakaoh avatar cameel avatar captdaylight avatar chaoweichiu avatar chevdor avatar chriseth avatar denton-l avatar ekpyron avatar erak avatar hrkrshnn avatar leon-do avatar leonardoalt avatar matheusaaguiar avatar micahzoltu avatar nikola-matic avatar nitro888 avatar pgrimaud avatar r0qs avatar ripper234 avatar rorye avatar stephensli avatar theoport avatar watilde avatar xiaoxianboy avatar yann300 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

solc-js's Issues

Unable to require('solc')

I am trying to run Ethereum smart contracts on vm.
VM tech: vagrant
host OS: mac osx
vm os: ubuntu trusty
solc version:

vagrant@vagrant-ubuntu-trusty-64:~/repo/sol-00$ solc --version
solc, the solidity compiler commandline interface
Version: 0.3.4-0/RelWithDebInfo-Linux/g++/Interpreter

solc-js version: [email protected]

I have created small script called c1.js with just one line

var solc = require('solc');

When I run it using node c1.js I get one line result "Killed".

Can you help please?

`solc` breaks mocha test runner.

Repro case here: https://github.com/MicahZoltu/mocha-test/

Run either with docker build -t mocha-test . && docker run --rm mocha-test or with npm install && node_modules/.bin/mocha. Notice that the test runner crashes.

Comment out the line here https://github.com/MicahZoltu/mocha-test/blob/master/test/example.js#L2-L3 and then notice that the test runner does not crash.

Prime suspect is https://github.com/ethereum/solc-js/blob/master/solcjs#L8, though replacing the require("solc") line with that does not cause the problem to persist. I have been unable to narrow down the problem past solc, though the test runner crash output suggests that solc is to blame.

"Must provide a file" issue

Hello!

Issue I'm experiencing with:

$ ./geth attach ipc:/home/resurtm/.ethereum/testnet/geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/v1.4.18-stable-c72f5459/linux/go1.7.1
coinbase: 0x1eded942353420c4ac3f3766ea858dff1f4afdca
at block: 1819615 (Mon, 31 Oct 2016 16:53:09 +06)
 datadir: /home/resurtm/.ethereum/testnet
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> var contract = eth.compile.solidity("contract test { function multiply(uint a) returns(uint d) { return a * 7; } }")
solc: exit status 1
Must provide a file

Specify --help for available options

    at web3.js:3119:20
    at web3.js:6023:15
    at web3.js:4995:36
    at <anonymous>:1:16

> 

Here's my system & software details:

$ ./geth version
Geth
Version: 1.4.18-stable-c72f5459
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.7.1
OS: linux
GOPATH=
GOROOT=/usr/lib/go-1.7
$ screenfetch
         _,met$$$$$gg.           resurtm@resurtm-desktop
      ,g$$$$$$$$$$$$$$$P.        OS: Debian testing stretch
    ,g$$P""       """Y$$.".      Kernel: x86_64 Linux 4.7.0-1-amd64
   ,$$P'              `$$$.      Uptime: 4h 58m
  ',$$P       ,ggs.     `$$b:    Packages: 2565
  `d$$'     ,$P"'   .    $$$     Shell: bash 4.4.0
   $$P      d$'     ,    $$P     Resolution: 1920x1200
   $$:      $$.   -    ,d$$'     DE: XFCE
   $$\;      Y$b._   _,d$P'      WM: Xfwm4
   Y$$.    `.`"Y$$$$P"'          WM Theme: Next
   `$$b      "-.__               GTK Theme: Xfce-basic [GTK2]
    `Y$$                         Icon Theme: Tango
     `Y$$.                       Font: Sans 10
       `$$b.                     CPU: Intel Core i3 CPU 540 @ 3.067GHz
         `Y$$b.                  GPU: GeForce 9500 GT/PCIe/SSE2
            `"Y$b._              RAM: 4598MiB / 5961MiB
                `""""           
$ uname -a
Linux resurtm-desktop 4.7.0-1-amd64 #1 SMP Debian 4.7.8-1 (2016-10-19) x86_64 GNU/Linux

$ cat /proc/version 
Linux version 4.7.0-1-amd64 ([email protected]) (gcc version 5.4.1 20160904 (Debian 5.4.1-2) ) #1 SMP Debian 4.7.8-1 (2016-10-19)

$ cat /etc/debian_version 
stretch/sid
$ node --version
v6.9.1

$ npm --version
3.10.8

$ solcjs --version
0.4.3+commit.2353da71.Emscripten.clang

$ solc --version
0.4.3+commit.2353da71.Emscripten.clang

$ ls -la /usr/bin/solc*
lrwxrwxrwx 1 root root  6 Oct 31 16:47 /usr/bin/solc -> solcjs
lrwxrwxrwx 1 root root 31 Oct 31 16:32 /usr/bin/solcjs -> ../lib/node_modules/solc/solcjs

Also reported here: ethereum/go-ethereum#2944 (comment)

Making compileJSONCallback work

Intro for anyone trying to understand the context:

Basically compileJSONCallback uses the same interface as compileJSONMulti (which supports multiple input files defined in a JSON) with the addition of a readFileCallback parameter.

This callback is executed when a missing import statement is encountered. It receives the import path and should return the destination file contents. To be more precise it expects an array with two fields: contents and error.

Internally this is wrapped to match the readFileCallback(path, contents, error) method (see in C). It has an Emscripten-wrapping, therefore all parameters are pointers to the Emscripten heap. (relevant Emscripten doc)

Now in C world we have a condition to display an error if both contents and error are null (i.e. JS didn't touched them). Otherwise they are copied around appropriately.

Problem:

The wrapped callback is executed as evidenced by a console.log within, but no matter what is done, upon returning from this callback nothing happens.

If the callback doesn't touches the contents/error, they should remain null and the error as mentioned above should be displayed.

Sample code to test:

var cb = soljson.Runtime.addFunction(function() { console.log('We should trigger the error') });
var output = compileInternal(input, optimize, cb);
console.log(output);
bash-3.2$ node test.js 
We should trigger the error
bash-3.2$ 

The only way I can get a different result is by setting the pointer to a wrong location: soljson.setValue(ptr, ptr, '*'):

/Users/alex/Projects/solc/solc-js/soljson.js:1
(function (exports, require, module, __filename, __dirname) { var Module;if(!Module)Module=(typeof Module!=="undefined"?Module:null)||{};var moduleOverrides={};for(var key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;if(Module["ENVIRONMENT"]){if(Module["ENVIRONMENT"]==="WEB"){ENVIRONMENT_IS_WEB=true}else if(Module["ENVIRONMENT"]==="WORKER"){ENVIRONMENT_IS_WORKER=true}else if(Module["ENVIRONMENT"]==="NODE"){ENVIRONMENT_IS_NODE=true}else if(Module["ENVIRONMENT"]==="SHELL"){ENVIRONMENT_IS_SHELL=true}else{throw new Error("The provided Module['ENVIRONMENT'] value is not valid. It must be one of: WEB|WORKER|NODE|SHELL.")}}else{ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_W
abort() at Error
    at jsStackTrace (/Users/alex/Projects/solc/solc-js/soljson.js:1:15961)
    at stackTrace (/Users/alex/Projects/solc/solc-js/soljson.js:1:16144)
    at Object.abort (/Users/alex/Projects/solc/solc-js/soljson.js:19:14981)
    at _abort (/Users/alex/Projects/solc/solc-js/soljson.js:1:1240434)
    at cXa (/Users/alex/Projects/solc/solc-js/soljson.js:5:332247)
    at Array.zi (/Users/alex/Projects/solc/solc-js/soljson.js:6:74167)
    at Object.UJb [as dynCall_viii] (/Users/alex/Projects/solc/solc-js/soljson.js:12:322458)
    at invoke_viii (/Users/alex/Projects/solc/solc-js/soljson.js:1:1272342)
    at Array.Xsa (/Users/alex/Projects/solc/solc-js/soljson.js:7:455012)
    at Object.wLb [as dynCall_viiii] (/Users/alex/Projects/solc/solc-js/soljson.js:12:328625)
If this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.

Contract Source Files as inputs for compilations

I am a newbee on ethereum and trying to evaluate this package for automated-deployment , My idea is to provide source 'files' (not just strings) to the solc-js and then somehow use this as a deployment services. Its hard to put string directly in the definitions where the actual contract code lies in different files.

Question: Is the generated ABI in written order?

If I have contract:

contract MyContract {

    function A() {}

    funciton B() {}
}

In the contract outputs, will method A always be in front of method B in the ABI array?

ABI:

[{name: "A" ...}, {name: "B" ...} ...]

Or is there no guarantee or requirement for this by a Ethereum contract compiler?

Warnings returned as error

Result of the compiling for the following contract:

contract SimpleContract{
    address addr;
}

with compilers version 0.4.x:
"errors":["test/Simple/simple.sol:1:1: Warning: Source file does not specify required compiler version!

It would be nice to report warnings as such and not as errors.

Make solcjs have better output

Currently, solcjs has almost no output. Even if a build errors out, it will just silently exit and simply not make any files.

A desired behaviour would be to have solcjs print out all of the error messages that caused the build to fail and then return a non-zero exit code, instead.

Latest 4 solc versions are missed.

When listing the remote versions the loop misses the last 4 versions in the list.

for (var i = sources.length - 1; i >= 0; i--) {
    // FIXME: use build as well
    var version = sources[i].match(/^soljson-v([0-9.]*)-.*.js$/);

    // Skip invalid lines
    if (!version) {
      continue;
    }

    if (version[1] === wanted) {
      downloadBinary(sources[i].match(/^soljson-(.*).js$/)[1]);
      return;
    }
  }

Expose AST w/o import processing

I'd like to use solc's abstract syntax tree to evaluate imports and to eventually extend the import functionality using custom imports (i.e., import "Foo"; would pull Foo's source from a package manager). Unfortunately, when creating the abstract syntax tree solc evaluates imports which, of course, can't be resolved in this case. In response I've created my own solidity-parser project, but there's no use maintaining two sets of code and I'd very much like to use the canonical AST. Can you expose a function that creates an abstract syntax tree without the need to resolve imports? Thanks!

Errors for demo use case

Using "solc": "^0.3.6", in a project and trying to compile the demo:

var solc = require('solc');
var input = {
    'lib.sol': 'library L { function f() returns (uint) { return 7; } }',
    'cont.sol': 'import "lib.sol"; contract x { function g() { L.f(); } }'
};
var output = solc.compile({sources: input}, 1);
output.formal.errors.forEach((err)=>{

    console.log(err)
})

Output:

lib.sol:1:1: Error: Libraries not supported.
library L { function f() returns (uint) { return 7; } }
^-----------------------------------------------------^

lib.sol:1:35: Error: Unnamed return variables not yet supported.
library L { function f() returns (uint) { return 7; } }

Edit:

After looking into it more, I assume this is only error for formal verification and should not affect the compilation of contracts? If so feel free to close this issue :)

invalid soljson.js file after upgrade to v0.4.0

Can not require solc after upgrading to version 0.4.0. Error message: SyntaxError: Unexpected token <

I can see the soljson.js file contains HTML with an error message
`

404


File not found

  <p>
    The site configured at this address does not
    contain the requested file.
  </p>`

the soljson.js file is not in the repo so this must be dynamically generated but I don't know how.

Steps to reproduce:

  1. Update dependency in package.json to "solc":"^0.4.0",
  2. Run npm install solc
  3. compile project that uses the solc module. eg https://github.com/juanfranblanco/vscode-solidity

Support Natspec Flags

One difference between the solc-js and solc native binary is that the additional flags for natspec flags don't seem to be supported with the JS version.

These include:

  --combined-json abi,asm,ast,bin,bin-runtime,clone-bin,devdoc,interface,opcodes,srcmap,srcmap-runtime,userdoc
  --ast                AST of all source files.
  --ast-json           AST of all source files in JSON format.
  --asm                EVM assembly of the contracts.
  --asm-json           EVM assembly of the contracts in JSON format.
  --opcodes            Opcodes of the contracts.
  --bin                Binary of the contracts in hex.
  --bin-runtime        Binary of the runtime part of the contracts in hex.
  --clone-bin          Binary of the clone contracts in hex.
  --abi                ABI specification of the contracts.
  --hashes             Function signature hashes of the contracts.
  --userdoc            Natspec user documentation of all contracts.
  --devdoc             Natspec developer documentation of all contracts.
  --formal             Translated source suitable for formal analysis.

Why doesn't this package include a cli?

I was expecting I could npm install -g solc and have solc in my path. That was the impression I got from https://solidity.readthedocs.io/en/latest/installing-solidity.html:

NPM / node.js

This is probably the most portable and most convenient way to install Solidity locally.

A platform-independent JavaScript library is provided by compiling the C++ source into JavaScript using > Emscripten for browser-solidity and there is also an NPM package available.

To install it, simply use

npm install solc

I guess I just install the binaries instead?

Versioning

Currently the versioning of solc is not 100% semver (and thus npm) compatible.

e.g. 0.3.1-1 translates to prerelease version of 1.

For reference, the C solc has a version of v0.3.2-2016-04-22-dd4300d, which includes a lot of build metadata. The right way to include that is by using the plus sign: 0.3.1+1 or 0.3.1+2016-04-22-dd4300d.

@chriseth also raised that mirroring the version in JS causes the issue that interface changes in JS cannot be properly signaled using semver as it is tied to the C version.

Insignificant newline changes output of solc.compile

A newline (\n) at the end of a contract's source code causes the output bytecode to be different to the same contract without the newline. So, for example, if you copy and paste a contract into a string to be compiled, the result may be different to reading the source code into a string from file.

Feature Request: allow for input of pre-compiled bytecode

Right now the solc compiler can only intake the sources of solidity files/source maps. But when I'm compiling more than say, 15 contracts (which I do often, as many of us use the EVM/solc as a testing environment). The compile time takes forever, sometimes up to 10+ minutes depending on the source. Many of the contracts I'm compiling have already been compiled (and have not changed). Often times, I may only be changing one or two at most. So I'd like to request a bytecode input feature (if something like this is possible and doable).

Usage:

var solc = require('solc');
var input = {
    'lib.sol': 'library L { function f() returns (uint) { return 7; } }',
    'cont.sol': 'import "lib.sol"; contract x { function g() { L.f(); } }',
};
var bytecode = {
    'cont.sol': '0x00..',
};
var output = solc.compile({ sources: input, bytecode: bytecode }, 1);

This way, if the bytecode is presented for a specific contract, then it won't recompile the source, instead it will just use the source provided.

Optimizations like this allow us to have a faster environment to develop large Solidity applications. This way, the build environment can optimize compile time by presenting bytecode that often times does not change.

Thoughts?

One con/Fix:

  • what if the bytecode is old and the contract has actually changed, but the build environment improperly handled the change, and did not recompile code properly.
    Potential Fix: instead of the bytecode map being "contract_name": "bytecode", it could be: "keccak256(contract_code)": "bytecode". This way, the map will only map to that contracts bytecode and nothing else. This would avoid a situation where bytecode is presented for an old contract code.

UNMET PEER DEPENDENCY solc@^0.3.5

hello!
I recently in buliding the ethereum development environment.Everything goes well with the early,include truffle and testrpc.
But when I install solc.I met a big trouble.

sudo npm install -g solc solc-cli --save-dev
├── UNMET PEER DEPENDENCY solc@^0.3.5
└── [email protected]
npm WARN [email protected] requires a peer of solc@^0.3.5 but none was installed.

I try install solc first,but the solc virsion is

└─┬ [email protected]
├── [email protected]
├── [email protected]
└─┬ [email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ └── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├─┬ [email protected]
│ └─┬ [email protected]
│ └── [email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ └── [email protected]
│ └── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ └── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└─┬ [email protected]
└── [email protected]

The solc-cli need solc@^0.3.5.

thanks for the help!

Export linker

The library linking option is not available in Javascript. Would be very useful to have it in the form of:

solc.linkBytecode(bytecode, <class name / address pairs>)
solc.link(<output JSON from compile>, <class name to link>, <class name / address pairs>)

This could also obsolete the linking code in browser-solidity (and perhaps in truffle).

It could be
a) implemented in Javascript in solc-js or
b) solidity/solc/jsonCompiler.cpp could be extended to export link() too (as it is present internally).

solc-js throws an error with just a number; trouble compiling strings.js

When you try to compile solidity stringutils's strings.sol, solc-js will throw an error with only a number as its error message. I've created a github project showing how you can reproduce the error, link below. This error was originally posted on Truffle's issue tracker here.

https://github.com/tcoulter/solc-result-bug

$ ./index.js

/Users/tim/Documents/workspace/Consensys/solcbug/node_modules/solc/soljson.js:1 (function (exports, require, module, __filename, __dirname) { var Module;if(!Module)Module=(typeof Module!=="undefined"?Module:null)||{};var moduleOverrides={};for(var key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var ENVIRONMENT_IS_WEB=typeof window==="object";var ENVIRONMENT_IS_WORKER=typeof importScripts==="function";var ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;var ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE){if(!Module["print"])Module["print"]=function print(x){process["stdout"].write(x+"\n")};if(!Module["printErr"])Module["printErr"]=function printErr(x){process["stderr"].write(x+"\n")};var nodeFS=require("fs");var nodePath=require("path");Module["read"]=function read(filename,binary){filename=nodePath"normalize";var ret=nodeFS["readFil
6042264

$

Change compile() so that it always works with JSON input

I think going forward, compile() should always work JSON input and the readFile callback and should always return a JSON.

compile() then should do the wrapping to work with older versions of soljson, which lack compileJSONCallback and/or compileJSONMulti.

Error: Cannot find module 'ws' from '/home/nick/github/wafr/node_modules/solc' while browserify

Error: Cannot find module 'ws' from '/home/nick/github/wafr/node_modules/solc'
    at /home/nick/github/wafr/node_modules/resolve/lib/async.js:46:17
    at process (/home/nick/github/wafr/node_modules/resolve/lib/async.js:173:43)
    at ondir (/home/nick/github/wafr/node_modules/resolve/lib/async.js:188:17)
    at load (/home/nick/github/wafr/node_modules/resolve/lib/async.js:69:43)
    at onex (/home/nick/github/wafr/node_modules/resolve/lib/async.js:92:31)
    at /home/nick/github/wafr/node_modules/resolve/lib/async.js:22:47
    at FSReqWrap.oncomplete (fs.js:123:15)

I should be able to browserify a module that depends on and requires solc. But I keep getting this error, where the ws package is not required.

Should we install this as a dependency and include it in the package.json? How should I proceed?

coherent output between solc and solcjs

Is there a reason why which are output by the native solc compiler differ from the solcjs output?
It would be great to receive the same output from both.

e.g.
bytecode vs. bin
runtimeBytecode vs. bin-runtime
interface vs. abi

browserify -- provide instructions and best practices

Please provide the browserify instructions and best practices. Many people will use this module in the browser. We should have a solid known way to browserify everything properly.

i.e. something like this:

browserify -s 'solc' -e . -o ./dist/solc-bundle.js

Document 'errors'

By trial and error I found out that in case the compilation fails compile() returns an object with a errors attribute, which is a list of all compiler errors. This is really useful! Maybe it could be documented somewhere. I'm not sure here is the best place, because that already comes from the compiler I assume, but here was where I was looking for it.

":" added in front of contract name

It seems your last version adds a ":" in front of the contract name. Using the following code:

var solc = require('solc');
var input = 'contract x { function g() {} }';
var output = solc.compile(input, 1); // 1 activates the optimiser
for (var contractName in output.contracts) {
    console.log(contractName + ': ' + output.contracts[contractName].bytecode);
    console.log(contractName + '; ' + JSON.parse(output.contracts[contractName].interface));
}

Version 0.4.9 output:

$ node test.js
:x: 60606040523415600b57fe5b5b605e8060196000396000f300606060405263ffffffff60e060020a600035041663e2179b8e81146020575bfe5b3415602757fe5b602d602f565b005b5b5600a165627a7a72305820e8b0c70626050e1e6a4bebdbdf05a2fad07018a377ee47c825a7c4431095b55b0029
:x; [object Object]

Version 0.4.8 output:

$ node test.js
x: 6060604052346000575b605d8060166000396000f300606060405263ffffffff60e060020a600035041663e2179b8e81146022575b6000565b34600057602c602e565b005b5b5600a165627a7a72305820686ccb19afb1089a94c403bbef1c50117601224abebee233f6feebb22877b2ce0029
x; [object Object]

rgds
Jn_r

solcjs not compatible with console

Hi, I'm having an issue with solcjs when I try to compile something from the console :

> admin.setSolc("/usr/local/bin/solcjs")
"0.4.2+commit.af6afb04.mod.Emscripten.clang\n\npath: /usr/local/bin/solcjs"
> eth.compile.solidity('contract C{}')
solc: exit status 1
Must provide a file

Specify --help for available options

    at web3.js:3119:20
    at web3.js:6023:15
    at web3.js:4995:36
    at <anonymous>:1:1

I did not understand until I setSolc to a debugging python program :

import sys
print(sys.stdin.read(), file=sys.stderr)
print(sys.argv, file=sys.stderr)
sys.exit(1)

(when you use setSolc, you have to return an exit code of 0, but you can modify the program again before you compile)

The issue seems to be that solcjs has no input_file parameter, and is passed the program via stdin.
Is it possible to modify it to accept input from stdin ?

trying to compile getting exit status 1

Hi i really need some help.. i have been trying to use solc to compile for the last 2 days, from console and from atom and i keep getting the error " exit status 1 must provide file"
i have no idea what is going wrong, in the atom i built a contract and in the console i either gave a path to a contract or wrote one in eth.compile.solidity("---contract---") and it just wont work..

any help would be greatly appericiated.

i am runing solc 0..3.6 btw

thanks for the help!

Extra colon in contract names

contract MyGoodContract {
  function doThing(){}
}

The output name has a colon (:myGoodContract instead of myGoodContract)

{ contracts: 
   { ':MyGoodContract': 
      { assembly: [Object],
        bytecode: '60606040523415600b57fe5b5b60788061001a6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063fa62770c14603a575bfe5b3415604157fe5b60476049565b005b5b5600a165627a7a72305820695b304d793049b81cd9e7655797bd5edfd679b8c71858363c5b8b7313310e930029',
        functionHashes: [Object],
        gasEstimates: [Object],
        interface: '[{"constant":false,"inputs":[],"name":"doThing","outputs":[],"payable":false,"type":"function"}]',
        metadata: '{"compiler":{"version":"0.4.9+commit.364da425"},"language":"Solidity","output":{"abi":[{"constant":false,"inputs":[],"name":"doThing","outputs":[],"payable":false,"type":"function"}],"devdoc":{"methods":{}},"userdoc":{"methods":{}}},"settings":{"compilationTarget":{"":"MyGoodContract"},"libraries":{},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"":{"keccak256":"0x654418339d51814dacd735e57934e06fa925dbeaf415c8534cea9bd93633e3f9","urls":["bzzr://8256fcd2faa122281a2175578b24e95a3230331483503c10c09d070b2300dfda"]}},"version":1}',
        opcodes: 'PUSH1 0x60 PUSH1 0x40 MSTORE CALLVALUE ISZERO PUSH1 0xB JUMPI INVALID JUMPDEST JUMPDEST PUSH1 0x78 DUP1 PUSH2 0x1A PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x60 PUSH1 0x40 MSTORE PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH4 0xFFFFFFFF AND DUP1 PUSH4 0xFA62770C EQ PUSH1 0x3A JUMPI JUMPDEST INVALID JUMPDEST CALLVALUE ISZERO PUSH1 0x41 JUMPI INVALID JUMPDEST PUSH1 0x47 PUSH1 0x49 JUMP JUMPDEST STOP JUMPDEST JUMPDEST JUMP STOP LOG1 PUSH6 0x627A7A723058 SHA3 PUSH10 0x5B304D793049B81CD9E7 PUSH6 0x5797BD5EDFD6 PUSH26 0xB8C71858363C5B8B7313310E9300290000000000000000000000 ',
        runtimeBytecode: '60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063fa62770c14603a575bfe5b3415604157fe5b60476049565b005b5b5600a165627a7a72305820695b304d793049b81cd9e7655797bd5edfd679b8c71858363c5b8b7313310e930029',
        srcmap: '0:48:0:-;;;;;;;;;;;;;;;;',
        srcmapRuntime: '0:48:0:-;;;;;;;;;;;;;;;;;27:20;;;;;;;;;;;;;;:::o' } },
  errors: [ ':1:1: Warning: Source file does not specify required compiler version!Consider adding "pragma solidity ^0.4.9\ncontract MyGoodContract {  function doThing(){}}\n^----------------------------------------------^\n' ],
  formal: { why3: '\n\nmodule UInt256\n\tuse import mach.int.Unsigned\n\ttype uint256\n\tconstant max_uint256: int = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\tclone export mach.int.Unsigned with\n\t\ttype t = uint256,\n\t\tconstant max = max_uint256\nend\n\nmodule Address\n\tuse import mach.int.Unsigned\n\ttype address\n\tconstant max_address: int = 0xffffffffffffffffffffffffffffffffffffffff (* 160 bit = 40 f\'s *)\n\tclone export mach.int.Unsigned with\n\t\ttype t = address,\n\t\tconstant max = max_address\nend\n   \nmodule Contract_MyGoodContract\n\tuse import int.Int\n\tuse import ref.Ref\n\tuse import map.Map\n\tuse import array.Array\n\tuse import int.ComputerDivision\n\tuse import mach.int.Unsigned\n\tuse import UInt256\n\texception Revert\n\texception Return\n\ttype state = ()\n\ttype account = {\n\t\tmutable balance: uint256;\n\t\tstorage: state\n\t}\n\tval external_call (this: account): bool\n\t\tensures { result = false -> this = (old this) }\n\t\twrites { this }\n\tlet rec _doThing (this: account):\n\t\t\t()\n\t\twrites { this }\n\t\t=\n\t\tlet prestate = {balance = this.balance; storage = ()} in \n\t\ttry\n\t\tbegin\n\t\tend;\n\t\traise Return\n\t\twith Return -> () |\n\t\t     Revert -> this.balance <- prestate.balance; ()\n\tend\nend\n\n' },
  sourceList: [ '' ],
  sources: { '': { AST: [Object] } } }

Please raise compiler memory limit.. large "var (tuples)" during inter-contract calls now overflow :-(

In version solc 3.7> I use to be able to have large var tuple instantiation without causing a memory overflow.

Such as:

BoardRoom board = BoardRoom(msg.sender);
var (name, destination, proxy, value, hash, executed, debatePeriod, created) = board.proposals(_proposalID);

Now things like this are causing massive memory overflow. I remember we can just raise the memory limit somewhere in the compiler. Can we raise this again, I had asked before and during v3 and we raised it. Looks like we set it back again.

Otherwise I have to add a crap ton of getters to my contract... not looking forward to it =(

Thanks yall.

Create output dir if it does not exist

Currently:

 solcjs -o **IdontExist** --bin contract.sol

fails because IdontExist well... does not exist.

Using fs-extra makes it an easy fix:

var fs = require('fs-extra);
fs.ensureDirSync (outputDir);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.