• 以太坊:Solidity-合约的元数据


    合约的元数据

    Solidity编译器自动生成JSON文件,即合约的元数据,其中包含了当前合约的相关信息。 它可以用于查询编译器版本,所使用的源代码,应用二进制接口Application Binary Interface(ABI) 和 以太坊标准说明格式Ethereum Nature Specification Format(natspec) 文档,以便更安全地与合约进行交互并验证其源代码。

    编译器会将元数据文件的 Swarm 哈希值附加到每个合约的字节码末尾(详情请参阅下文), 以便你可以以认证的方式获取该文件,而不必求助于中心化的数据提供者。

    当然,你必须将元数据文件发布到 Swarm (或其他服务),以便其他人可以访问它。 该文件可以通过使用 solc --metadata 来生成,并被命名为 ContractName_meta.json 。 它将包含源代码的在 Swarm 上的引用,因此你必须上传所有源文件和元数据文件。

    元数据文件具有以下格式。 下面的例子将以人类可读的方式呈现。 正确格式化的元数据应正确使用引号,将空白减少到最小,并对所有对象的键值进行排序以得到唯一的格式。 代码注释当然也是不允许的,这里仅用于解释目的。

    {
      // 必选:元数据格式的版本
      version: "1",
      // 必选:源代码的编程语言,一般会选择规范的“子版本”
      language: "Solidity",
      // 必选:编译器的细节,内容视语言而定。
      compiler: {
        // 对 Solidity 来说是必须的:编译器的版本
        version: "0.4.6+commit.2dabbdf0.Emscripten.clang",
        // 可选: 生成此输出的编译器二进制文件的哈希值
        keccak256: "0x123..."
      },
      // 必选:编译的源文件/源单位,键值为文件名
      sources:
      {
        "myFile.sol": {
          // 必选:源文件的 keccak256 哈希值
          "keccak256": "0x123...",
          // 必选(除非定义了“content”,详见下文):
          // 已排序的源文件的URL,URL的协议可以是任意的,但建议使用 Swarm 的URL
          "urls": [ "bzzr://56ab..." ]
        },
        "mortal": {
          // 必选:源文件的 keccak256 哈希值
          "keccak256": "0x234...",
          // 必选(除非定义了“urls”): 源文件的字面内容
          "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"
        }
      },
      // 必选:编译器的设置
      settings:
      {
        // 对 Solidity 来说是必须的: 已排序的重定向列表
        remappings: [ ":g/dir" ],
        // 可选: 优化器的设置( enabled 默认设为 false )
        optimizer: {
          enabled: true,
          runs: 500
        },
        // 对 Solidity 来说是必须的:用以生成该元数据的文件名和合约名或库名
        compilationTarget: {
          "myFile.sol": "MyContract"
        },
        // 对 Solidity 来说是必须的:所使用的库的地址
        libraries: {
          "MyLib": "0x123123..."
        }
      },
      // 必选:合约的生成信息
      output:
      {
        // 必选:合约的 ABI 定义
        abi: [ ... ],
        // 必选:合约的 NatSpec 用户文档
        userdoc: [ ... ],
        // 必选:合约的 NatSpec 开发者文档
        devdoc: [ ... ],
      }
    }
    

    注解

    需注意,上面的 ABI 没有固定的顺序,随编译器的版本而不同。

    注解

    由于生成的合约的字节码包含元数据的哈希值,因此对元数据的任何更改都会导致字节码的更改。 此外,由于元数据包含所有使用的源代码的哈希值,所以任何源代码中的, 哪怕是一个空格的变化都将导致不同的元数据,并随后产生不同的字节代码。

    元数据哈希字节码的编码

    由于在将来我们可能会支持其他方式来获取元数据文件, 类似 {"bzzr0":<Swarm hash>} 的键值对,将会以 CBOR 编码来存储。 由于这种编码的起始位不容易找到,因此添加两个字节来表述其长度,以大端方式编码。 所以,当前版本的Solidity编译器,将以下内容添加到部署的字节码的末尾:

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

    因此,为了获取数据,可以检查部署的字节码的末尾以匹配该模式,并使用 Swarm 哈希来获取元数据文件。

    自动化接口生成和 以太坊标准说明格式Ethereum Nature Specification Format(natspec) 的使用方法

    元数据以下列方式被使用:想要与合约交互的组件(例如,Mist)读取合约的字节码, 从中获取元数据文件的 Swarm 哈希,然后从 Swarm 获取该文件。该文件被解码为上面的 JSON 结构。

    然后该组件可以使用ABI自动生成合约的基本用户接口。

    此外,Mist可以使用 userdoc 在用户与合约进行交互时向用户显示确认消息。

    有关 以太坊标准说明格式Ethereum Nature Specification Format(natspec) 的其他信息可以在 这里 找到。

    源代码验证的使用方法

    为了验证编译,可以通过元数据文件中的链接从 Swarm 中获取源代码。 获取到的源码,会根据元数据中指定的设置,被正确版本的编译器(应该为“官方”编译器之一)所处理。 处理得到的字节码会与创建交易的数据或者 CREATE 操作码使用的数据进行比较。 这会自动验证元数据,因为它的哈希值是字节码的一部分。 而额外的数据,则是与基于接口进行编码并展示给用户的构造输入数据相符的。

  • 相关阅读:
    SpringCloud Zipkin快速开始
    Spring-Cloud-Gateway Predicate谓词(断言)使用与自定义
    Gateway Redis令牌桶请求限流过滤器
    SpringBoot集成logback日志组件
    Java使用Aspose-Words实现Word转换Pdf
    JAVA通过Map拼接SQL语句(Insert Update语句)
    使用Java反射机制将Bean对象转换成Map(驼峰命名方式 — 下划线命名方式)
    mybatis执行原生sql
    windows环境下elasticsearch安装教程(超详细)
    购物车的原理及Java实现(仿京东实现原理)
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13313116.html
Copyright © 2020-2023  润新知