Alert Source Discuss
⚠️ Draft Standards Track: ERC

ERC-7654: 请求方法类型

使用一组请求方法来指示要在合约上执行的操作类型。

Authors Rickey (@HelloRickey)
Created 2024-03-13
Discussion Link https://ethereum-magicians.org/t/erc-7654-request-method-types/19183

摘要

本提案标准化了客户端和智能合约之间的一组请求和响应通信标准,使用 POST、GET 和 PUT 请求来创建、读取和更新智能合约的状态。您可以自定义不同的请求方法名称、请求参数和响应值,并且每个请求方法都将映射到特定的操作。

动机

由于每个合约都有不同的功能,因此客户端无法使用标准来调用不同合约的不同功能。合约请求方法重新定义了合约的请求方法,以便可以使用一组一致的规则和协议来调用多个不同合约的不同功能。

通过将功能类型划分为 POST、GET 和 PUT,可以对合约执行不同的操作。这种清晰的操作类型不仅可以帮助各方限制对合约数据的访问和操作,还可以有效地简化客户端和合约之间的交互,使各方更容易理解合约的功能和层次结构。此标准的每个功能的请求和响应参数数据类型可以表达合约的预期操作,并具有描述其自身结构的能力,这有利于各方和合约创建统一且可预测的数据交换方式。

规范

本文档中的关键词“必须 (MUST)”,“不得 (MUST NOT)”,“必需 (REQUIRED)”,“应 (SHALL)”,“不应 (SHALL NOT)”,“应该 (SHOULD)”,“不应该 (SHOULD NOT)”,“推荐 (RECOMMENDED)”,“不推荐 (NOT RECOMMENDED)”,“可以 (MAY)”和“可选 (OPTIONAL)”应按照 RFC 2119 和 RFC 8174 中的描述进行解释。

它由四种请求方法类型组成:

GET: 请求合约检索记录。

POST: 请求合约创建新记录。

PUT: 请求合约更新记录。

OPTIONS: 支持的请求方法类型。

工作流程:

  1. 调用 options 以获取支持的请求方法类型。
  2. 调用 getMethods 以获取请求方法名称。
  3. 调用 getMethodReqAndRes 以获取请求参数数据类型和响应值数据类型。
  4. 编码请求参数并调用 getpostput
  5. 解码响应值。

接口

IRequestMethodTypes.sol

// SPDX-License-Identifier: CC0-1.0
pragma solidity >=0.8.0;
import "./Types.sol";
interface IRequestMethodTypes{

    /**
     * Requested method type.
     * GET, POST, PUT, OPTIONS
     */
    enum MethodTypes{
        GET,
        POST,
        PUT,
        OPTIONS
    }

    /**
     * Response data event.
     * @param _response is the response value of the post request or put request.
     */
    event Response(bytes _response);

    /**
     * Get method names based on request method type.
     * @param _methodTypes is the request method type.
     * @return Method names.
     */
    function getMethods(MethodTypes _methodTypes)external view returns (string[] memory);

    /**
     * Get the data types of request parameters and responses based on the requested method name.
     * @param _methodName is the method name.
     * @return Data types of request parameters and responses.
     */
    function getMethodReqAndRes(string memory _methodName) external view returns(Types.Type[] memory ,Types.Type[] memory );

    /**
     * Request the contract to retrieve records.
     * @param _methodName is the method name.
     * @param _methodReq is the method type.
     * @return The response to the get request.
     */
    function get(string memory _methodName,bytes memory _methodReq)external view returns(bytes memory);

    /**
     * Request the contract to create a new record.
     * @param _methodName is the method name.
     * @param _methodReq is the method type.
     * @return The response to the post request.
     */
    function post(string memory _methodName,bytes memory _methodReq)external payable returns(bytes memory);

    /**
     * Request the contract to update a record.
     * @param _methodName is the method name.
     * @param _methodReq is the method type.
     * @return The response to the put request.
     */
    function put(string memory _methodName,bytes memory _methodReq)external payable returns(bytes memory);

    /**
     * Supported request method types.
     * @return Method types.
     */
    function options()external returns(MethodTypes[] memory);
}

Types.sol 包含上述接口中使用的 Solidity 类型的枚举。

原理

请求方法类型

为了使客户端能够以标准化且可预测的方式操作合约,设置了三种请求方法类型 GETPOSTPUT。每种方法的功能都需要在这三种类型中定义,以方便合约调用者理解和处理请求所需的信息。但是,没有 DELETE 操作类型,因为删除合约中的数据是一种低效的操作。开发人员可以自行添加 PUT 请求方法,以将数据设置为有效和无效,并且只在 GET 方法中返回有效数据。

请求方法参数类型

每种请求方法类型中都定义了一些函数。它们都包括请求参数数据类型和响应参数数据类型,这些数据类型需要在 constructor 中设置,然后通过 getMethodReqAndRes 根据方法名称获取。 参数的数据类型由数据类型的枚举定义。 处理请求参数时,abi.decode 用于根据请求参数类型和请求值进行解码。 返回响应时,abi.encode 用于根据响应值和响应参数类型进行编码。

参考实现

参见 请求方法类型示例

安全注意事项

合约请求方法分为安全方法和不安全方法。 如果方法请求是只读操作,不会改变合约的状态,那么该方法是安全的。

安全方法: GET、OPTIONS 不安全方法: POST、PUT

版权

版权及相关权利已通过 CC0 放弃。

Citation

Please cite this document as:

Rickey (@HelloRickey), "ERC-7654: 请求方法类型 [DRAFT]," Ethereum Improvement Proposals, no. 7654, March 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7654.