合约元数据¶

The Solidity compiler automatically generates a JSON file, thecontract metadata, that contains information about the current contract.It can be used to query the compiler version, the sources used, the ABIand NatSpec documentation in order to more safely interact with the contractand to verify its source code.

The compiler appends a Swarm hash of the metadata file to the end of thebytecode (for details, see below) of each contract, so that you can retrievethe file in an authenticated way without having to resort to a centralizeddata provider.

Of course, you have to publish the metadata file to Swarm (or some other service)so that others can access it. The file can be output by using solc —metadataand the file will be called ContractName_meta.json.It will contain Swarm references to the source code, so you have to uploadall source files and the metadata file.

The metadata file has the following format. The example below is presented in ahuman-readable way. Properly formatted metadata should use quotes correctly,reduce whitespace to a minimum and sort the keys of all objects to arrive at aunique formatting.Comments are of course also not permitted and used here only for explanatory purposes.

  1. {
  2. // Required: The version of the metadata format
  3. version: "1",
  4. // Required: Source code language, basically selects a "sub-version"
  5. // of the specification
  6. language: "Solidity",
  7. // Required: Details about the compiler, contents are specific
  8. // to the language.
  9. compiler: {
  10. // Required for Solidity: Version of the compiler
  11. version: "0.4.6+commit.2dabbdf0.Emscripten.clang",
  12. // Optional: Hash of the compiler binary which produced this output
  13. keccak256: "0x123..."
  14. },
  15. // Required: Compilation source files/source units, keys are file names
  16. sources:
  17. {
  18. "myFile.sol": {
  19. // Required: keccak256 hash of the source file
  20. "keccak256": "0x123...",
  21. // Required (unless "content" is used, see below): Sorted URL(s)
  22. // to the source file, protocol is more or less arbitrary, but a
  23. // Swarm URL is recommended
  24. "urls": [ "bzzr://56ab..." ]
  25. },
  26. "mortal": {
  27. // Required: keccak256 hash of the source file
  28. "keccak256": "0x234...",
  29. // Required (unless "url" is used): literal contents of the source file
  30. "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"
  31. }
  32. },
  33. // Required: Compiler settings
  34. settings:
  35. {
  36. // Required for Solidity: Sorted list of remappings
  37. remappings: [ ":g/dir" ],
  38. // Optional: Optimizer settings (enabled defaults to false)
  39. optimizer: {
  40. enabled: true,
  41. runs: 500
  42. },
  43. // Required for Solidity: File and name of the contract or library this
  44. // metadata is created for.
  45. compilationTarget: {
  46. "myFile.sol": "MyContract"
  47. },
  48. // Required for Solidity: Addresses for libraries used
  49. libraries: {
  50. "MyLib": "0x123123..."
  51. }
  52. },
  53. // Required: Generated information about the contract.
  54. output:
  55. {
  56. // Required: ABI definition of the contract
  57. abi: [ ... ],
  58. // Required: NatSpec user documentation of the contract
  59. userdoc: [ ... ],
  60. // Required: NatSpec developer documentation of the contract
  61. devdoc: [ ... ],
  62. }
  63. }

Note

Note the ABI definition above has no fixed order. It can change with compiler versions.

Note

Since the bytecode of the resulting contract contains the metadata hash, any change tothe metadata will result in a change of the bytecode. Furthermore, since the metadataincludes a hash of all the sources used, a single whitespace change in any of the sourcecodes will result in a different metadata, and subsequently a different bytecode.

Encoding of the Metadata Hash in the Bytecode¶

Because we might support other ways to retrieve the metadata file in the future,the mapping {"bzzr0": <Swarm hash>} is storedCBOR-encoded. Since the beginning of thatencoding is not easy to find, its length is added in a two-byte big-endianencoding. The current version of the Solidity compiler thus adds the followingto the end of the deployed bytecode:

  1. 0xa1 0x65 'b' 'z' 'z' 'r' '0' 0x58 0x20 <32 bytes swarm hash> 0x00 0x29

So in order to retrieve the data, the end of the deployed bytecode can be checkedto match that pattern and use the Swarm hash to retrieve the file.

Usage for Automatic Interface Generation and NatSpec¶

The metadata is used in the following way: A component that wants to interactwith a contract (e.g. Mist) retrieves the code of the contract, from thatthe Swarm hash of a file which is then retrieved.That file is JSON-decoded into a structure like above.

The component can then use the ABI to automatically generate a rudimentaryuser interface for the contract.

Furthermore, Mist can use the userdoc to display a confirmation message to the userwhenever they interact with the contract.

Additional information about Ethereum Natural Specification (NatSpec) can be found here.

Usage for Source Code Verification¶

In order to verify the compilation, sources can be retrieved from Swarmvia the link in the metadata file.The compiler of the correct version (which is checked to be part of the “official” compilers)is invoked on that input with the specified settings. The resultingbytecode is compared to the data of the creation transaction or CREATE opcode data.This automatically verifies the metadata since its hash is part of the bytecode.Excess data corresponds to the constructor input data, which should be decodedaccording to the interface and presented to the user.

原文: http://solidity.apachecn.org/cn/doc/v0.4.21/metadata.html