Security News
RubyGems.org Adds New Maintainer Role
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
The solc npm package is a JavaScript binding for the Solidity compiler. It allows developers to compile Solidity code from within a JavaScript environment, making it easier to integrate smart contract compilation into web applications, development tools, and automated scripts.
Compile Solidity Source Code
This feature allows you to compile Solidity source code. The code sample demonstrates how to compile a simple Solidity contract using the solc package.
const solc = require('solc');
const source = 'contract SimpleStorage { uint storedData; function set(uint x) public { storedData = x; } function get() public view returns (uint) { return storedData; } }';
const input = {
language: 'Solidity',
sources: {
'SimpleStorage.sol': {
content: source
}
},
settings: {
outputSelection: {
'*': {
'*': ['*']
}
}
}
};
const output = JSON.parse(solc.compile(JSON.stringify(input)));
console.log(output);
Get Compiler Version
This feature allows you to retrieve the version of the Solidity compiler being used. The code sample demonstrates how to get the compiler version using the solc package.
const solc = require('solc');
console.log(solc.version());
Compile with Specific Compiler Version
This feature allows you to compile Solidity code using a specific version of the Solidity compiler. The code sample demonstrates how to compile a contract using a specific compiler version.
const solc = require('solc');
const solcVersion = 'v0.8.6+commit.11564f7e';
const solcjs = require(`solc/soljson-${solcVersion}.js`);
const input = {
language: 'Solidity',
sources: {
'SimpleStorage.sol': {
content: 'contract SimpleStorage { uint storedData; function set(uint x) public { storedData = x; } function get() public view returns (uint) { return storedData; } }'
}
},
settings: {
outputSelection: {
'*': {
'*': ['*']
}
}
}
};
const output = JSON.parse(solcjs.compile(JSON.stringify(input)));
console.log(output);
Truffle is a development environment, testing framework, and asset pipeline for Ethereum. It provides a suite of tools for developing smart contracts, including compilation, linking, deployment, and binary management. Unlike solc, which focuses solely on compilation, Truffle offers a more comprehensive suite of tools for the entire smart contract development lifecycle.
Hardhat is a development environment for Ethereum that helps developers manage and automate the recurring tasks inherent to building smart contracts and DApps. It includes a built-in Solidity compiler, but also offers additional features like task runners, testing, and debugging. Hardhat provides a more integrated development experience compared to solc, which is focused on compilation.
Embark is a framework for developing and deploying decentralized applications (DApps) that integrates with Ethereum blockchains. It includes a Solidity compiler, but also offers features for managing smart contract deployment, testing, and communication with decentralized storage and messaging systems. Embark provides a broader range of functionalities compared to solc, which is specialized in compilation.
JavaScript bindings for the Solidity compiler.
Uses the Emscripten compiled Solidity found in the solc-bin repository.
To use the latest stable version of the Solidity compiler via Node.js you can install it via npm:
npm install solc
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 --base-path . ./MainContract.sol
The option --base-path
enables automatic loading of imports from the filesystem and
takes a path as argument that contains the source files.
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.
There are two ways to use solc
:
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:
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
);
}
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
);
}
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 distributed by solc-js
, which relies on either
Z3 or CVC4 being installed locally.
var solc = require('solc');
var smt = require('smtsolver');
// Note that this example only works via node and not in the browser.
var input = {
language: 'Solidity',
sources: {
'test.sol': {
content: 'pragma experimental SMTChecker; contract C { function f(uint x) public { assert(x > 0); } }'
}
}
};
var output = JSON.parse(
solc.compile(JSON.stringify(input), { smtSolver: smt.smtSolver })
);
The assertion is clearly false, and an assertion failure
warning
should be returned.
The low-level API is as follows:
solc.lowlevel.compileSingle
: the original entry point, supports only a single filesolc.lowlevel.compileMulti
: this supports multiple files, introduced in 0.1.6solc.lowlevel.compileCallback
: this supports callbacks, introduced in 0.2.1solc.lowlevel.compileStandard
: this works just like compile
above, but is only present in compilers after (and including) 0.4.11For examples how to use them, please refer to the README of the above mentioned solc-js releases.
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
}
});
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"))
.
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
}
});
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);
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}]
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)
Add the version of solc
you want to use into index.html
:
<script
type="text/javascript"
src="https://solc-bin.ethereum.org/bin/{{ SOLC VERSION }}.js"
></script>
(Alternatively use https://solc-bin.ethereum.org/bin/soljson-latest.js
to get the latests version.)
This will load solc
into the global variable window.Module
. Then use this inside Javascript as:
var wrapper = require('solc/wrapper');
var solc = wrapper(window.Module);
Or in ES6 syntax:
import * as wrapper from 'solc/wrapper';
const solc = wrapper(window.Module);
Alternatively, to iterate the releases, one can load list.js
from solc-bin
:
<script
type="text/javascript"
src="https://solc-bin.ethereum.org/bin/list.js"
></script>
This will result in two global variables, window.soljsonReleases
listing all releases and window.soljsonSources
listing all nightly builds and releases.
FAQs
Solidity compiler
The npm package solc receives a total of 160,640 weekly downloads. As such, solc popularity was classified as popular.
We found that solc demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 7 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.
Security News
Research
Socket's threat research team has detected five malicious npm packages targeting Roblox developers, deploying malware to steal credentials and personal data.