solidity编写的以太坊智能合约可经过命令行编译工具solc来进行编译,成为以太坊虚拟机中的代码。solc编译后最终部署到链上造成咱们所见到的各类智能合约。html
做为一个solidity命令行编译工具,咱们来看看官网都怎么说solc。git
solc的安装很简单:github
npm install -g solc
//或者
npm install -g solc-cli
//或者
sudo apt-get install solc
复制代码
安装完成后咱们来看,solc --help
,solc --help命令显示全部的solc命令选项。编译器能够生成各类输出,好比最终的二进制合约文件、语法树的汇编或者须要预计的要花费的gas等。solc --bin sourceFile.sol
,能够编译后输出一个名为sourceFile.sol的智能合约文件。若是你想从solc
得到更丰富的一些输出变量,你可使用solc -o outputDirectory --bin --ast --asm sourceFile.sol
。express
你在部署以太坊智能合约以前能够用solc --optimize --bin sourceFile.sol
优化一下。默认状况下solc编译器会帮你优化200次。你也能够设置 --runs=1
,这样就按照最小化的方式进行编译,若是你但愿屡次交易不太在意成本,那你能够设置成你想要的次数:)。npm
命令行编译器会自动读取须要导入的文件,也能够经过使用prefix = path
来指定路径,例如:json
solc github.com/ethereum/dapp-bin/=/usr/local/lib/dapp-bin/ =/usr/local/lib/fallback file.sol
安全
这样编译器就会从指定目录github.com/ethereum/dapp-bin/
下的/usr/local/lib/dapp-bin/
目录开始搜索,若是没有找到文件,它将查看/usr/local/lib/fallback
。solc将只读取你指定的这两个路径的,所以像import "/etc/passwd";
必需要经过/=
从新映射才起做用。若是有多个匹配,则选择具备最长公共前缀的进行匹配。bash
出于安全上的考虑,编译器限制了它能够访问的一些目录。在命令行中指定的源文件的路径(及其子目录)和命令行指定的路径外其余全部内容都会被拒绝。--allow-paths /sample/path,/another/sample/path
来切换。app
若是智能合约使用了libraries,你会注意到字节码包含了__LibraryName______
的子字符串。您可使用solc做为连接器,这意味着它将在这些点为您插入库地址。less
能够经过添加库--libraries "Math:0x12345678901234567890 Heap:0xabcdef0123456"
到您的命令,以提供每一个库的地址,或者使用文件中的说明字符串(每行一个库),并使用--libraries fileName
运行solc。
若是用选项--link
调用Solc,则全部输入文件都被解释为未连接的二进制文件(HEX编码),在上面给出的__LibraryName____
格式中,将其连接到适当地址(若是从stdin读取输入,则将其写入stdout)。在这种状况下,除了库外,全部选项都被忽略(包括-o
)。
若是用--standard-json
调用SOLC,它就将标准的JSON输入(以下所述),并返回JSON输出。
#solc编译器输入输出JSON描述
这些JSON格式经过编译器API使用,能够经过SOLC得到。内容都是能够修改的,一些对象是可选的(如前所述),其目的是向后兼容。
编译器的API须要一个JSON格式的输入,而后以JSON格式输出编译结果。
注意不容许注释。下面示例中的注释,是官网为了学习者更好的理解标注的。
{
// Required: Source code language, such as "Solidity", "serpent", "lll", "assembly", etc.
language: "Solidity",
// Required
sources:
{
// The keys here are the "global" names of the source files,
// imports can use other files via remappings (see below).
"myFile.sol":
{
// Optional: keccak256 hash of the source file
// It is used to verify the retrieved content if imported via URLs.
"keccak256": "0x123...",
// Required (unless "content" is used, see below): URL(s) to the source file.
// URL(s) should be imported in this order and the result checked against the
// keccak256 hash (if available). If the hash doesn't match or none of the // URL(s) result in success, an error should be raised. "urls": [ "bzzr://56ab...", "ipfs://Qma...", "file:///tmp/path/to/file.sol" ] }, "mortal": { // Optional: keccak256 hash of the source file "keccak256": "0x234...", // Required (unless "urls" is used): literal contents of the source file "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }" } }, // Optional settings: { // Optional: Sorted list of remappings remappings: [ ":g/dir" ], // Optional: Optimizer settings optimizer: { // disabled by default enabled: true, // Optimize for how many times you intend to run the code. // Lower values will optimize more for initial deployment cost, higher values will optimize more for high-frequency usage. runs: 200 }, evmVersion: "byzantium", // Version of the EVM to compile for. Affects type checking and code generation. Can be homestead, tangerineWhistle, spuriousDragon, byzantium or constantinople // Metadata settings (optional) metadata: { // Use only literal content and not URLs (false by default) useLiteralContent: true }, // Addresses of the libraries. If not all libraries are given here, it can result in unlinked objects whose output data is different. libraries: { // The top level key is the the name of the source file where the library is used. // If remappings are used, this source file should match the global path after remappings were applied. // If this key is an empty string, that refers to a global level. "myFile.sol": { "MyLib": "0x123123..." } } // The following can be used to select desired outputs. // If this field is omitted, then the compiler loads and does type checking, but will not generate any outputs apart from errors. // The first level key is the file name and the second is the contract name, where empty contract name refers to the file itself, // while the star refers to all of the contracts. // // The available output types are as follows: // abi - ABI // ast - AST of all source files // legacyAST - legacy AST of all source files // devdoc - Developer documentation (natspec) // userdoc - User documentation (natspec) // metadata - Metadata // ir - New assembly format before desugaring // evm.assembly - New assembly format after desugaring // evm.legacyAssembly - Old-style assembly format in JSON // evm.bytecode.object - Bytecode object // evm.bytecode.opcodes - Opcodes list // evm.bytecode.sourceMap - Source mapping (useful for debugging) // evm.bytecode.linkReferences - Link references (if unlinked object) // evm.deployedBytecode* - Deployed bytecode (has the same options as evm.bytecode) // evm.methodIdentifiers - The list of function hashes // evm.gasEstimates - Function gas estimates // ewasm.wast - eWASM S-expressions format (not supported atm) // ewasm.wasm - eWASM binary format (not supported atm) // // Note that using a using `evm`, `evm.bytecode`, `ewasm`, etc. will select every // target part of that output. Additionally, `*` can be used as a wildcard to request everything. // outputSelection: { // Enable the metadata and bytecode outputs of every single contract. "*": { "*": [ "metadata", "evm.bytecode" ] }, // Enable the abi and opcodes output of MyContract defined in file def. "def": { "MyContract": [ "abi", "evm.bytecode.opcodes" ] }, // Enable the source map output of every single contract. "*": { "*": [ "evm.bytecode.sourceMap" ] }, // Enable the legacy AST output of every single file. "*": { "": [ "legacyAST" ] } } } } 复制代码
{
// Optional: not present if no errors/warnings were encountered
errors: [
{
// Optional: Location within the source file.
sourceLocation: {
file: "sourceFile.sol",
start: 0,
end: 100
],
// Mandatory: Error type, such as "TypeError", "InternalCompilerError", "Exception", etc.
// See below for complete list of types.
type: "TypeError",
// Mandatory: Component where the error originated, such as "general", "ewasm", etc.
component: "general",
// Mandatory ("error" or "warning")
severity: "error",
// Mandatory
message: "Invalid keyword"
// Optional: the message formatted with source location
formattedMessage: "sourceFile.sol:100: Invalid keyword"
}
],
// This contains the file-level outputs. In can be limited/filtered by the outputSelection settings.
sources: {
"sourceFile.sol": {
// Identifier (used in source maps)
id: 1,
// The AST object
ast: {},
// The legacy AST object
legacyAST: {}
}
},
// This contains the contract-level outputs. It can be limited/filtered by the outputSelection settings.
contracts: {
"sourceFile.sol": {
// If the language used has no contract names, this field should equal to an empty string.
"ContractName": {
// The Ethereum Contract ABI. If empty, it is represented as an empty array.
// See https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
abi: [],
// See the Metadata Output documentation (serialised JSON string)
metadata: "{...}",
// User documentation (natspec)
userdoc: {},
// Developer documentation (natspec)
devdoc: {},
// Intermediate representation (string)
ir: "",
// EVM-related outputs
evm: {
// Assembly (string)
assembly: "",
// Old-style assembly (object)
legacyAssembly: {},
// Bytecode and related details.
bytecode: {
// The bytecode as a hex string.
object: "00fe",
// Opcodes list (string)
opcodes: "",
// The source mapping as a string. See the source mapping definition.
sourceMap: "",
// If given, this is an unlinked object.
linkReferences: {
"libraryFile.sol": {
// Byte offsets into the bytecode. Linking replaces the 20 bytes located there.
"Library1": [
{ start: 0, length: 20 },
{ start: 200, length: 20 }
]
}
}
},
// The same layout as above.
deployedBytecode: { },
// The list of function hashes
methodIdentifiers: {
"delegate(address)": "5c19a95c"
},
// Function gas estimates
gasEstimates: {
creation: {
codeDepositCost: "420000",
executionCost: "infinite",
totalCost: "infinite"
},
external: {
"delegate(address)": "25000"
},
internal: {
"heavyLifting()": "infinite"
}
}
},
// eWASM related outputs
ewasm: {
// S-expressions format
wast: "",
// Binary format (hex string)
wasm: ""
}
}
}
}
}
复制代码
continue
在for
循环以外使用。原文请访问:solc