跳转到主要内容

Python的EIP-712结构化接口。

项目描述

EIP-712 结构体

PyPI version Python versions

Python的EIP-712结构化接口。

注意:这是一个eip712-structs模块的直接替代品,该模块自2019年起已停止使用。

它带来了与前一个版本相同的对象,附带一些糖分

  • 代码是完全类型化的
  • 清理了依赖项
  • 支持Python 3.8及更高版本
  • 代码现代化,包括Sourcery清理
  • 99%测试覆盖率
  • 简化测试(不再需要docker)

警告:移除任何旧版 eip712-structs 模块的安装,以防止导入冲突: python -m pip uninstall -y eip712-structs

在此模块中,“结构”是指标准中定义的有序数据。它不同于Python标准库中的struct

支持的Python版本

Python 3.8及更高版本。

安装

python -m pip install -U eip712-structs-ng

用法

请参阅API.md以获取可用方法的简要总结。

以下为示例及详细说明。

快速入门

假设我们想要表示以下结构体,将其转换为消息并签名

struct MyStruct {
    string some_string;
    uint256 some_number;
}

使用此模块,它看起来是这样的

from eip712_structs import make_domain, EIP712Struct, String, Uint


# Make a domain separator
domain = make_domain(name='Some name', version='1.0.0')

# Define your struct type
class MyStruct(EIP712Struct):
    some_string = String()
    some_number = Uint(256)

# Create an instance with some data
mine = MyStruct(some_string="hello world", some_number=1234)

# Values can be get/set dictionary-style:
mine["some_number"] = 4567
assert mine["some_string"] == "hello world"
assert mine["some_number"] == 4567

# Into a message dict - domain required
my_msg = mine.to_message(domain)

# Into message JSON - domain required.
# This method converts bytes types for you, which the default JSON encoder won't handle.
my_msg_json = mine.to_message_json(domain)

# Into signable bytes - domain required
my_bytes = mine.signable_bytes(domain)

有关支持的类型更多信息,请参阅成员类型

动态构建

也可以动态地添加属性。如果您想使用保留关键字,如from,这可能很有必要。

from eip712_structs import EIP712Struct, Address


class Message(EIP712Struct):
    pass

Message.to = Address()
setattr(Message, "from", Address())

# At this point, `Message` is equivalent to `struct Message { address to; address from; }`

域分隔符

EIP-712指定了一个域结构体,以区分可能不相关的相同结构体。为此存在一个辅助方法。所有传递给make_domain()函数的值都是可选的——但至少必须定义一个。如果省略,则生成的域结构体定义将完全省略该参数。

完整的签名

make_domain(name: string, version: string, chainId: uint256, verifyingContract: address, salt: bytes32)

设置默认域

始终提供相同的域可能很麻烦。您可以设置一个默认值,然后忘记它。它将被.to_message().signable_bytes()自动使用。

import eip712_structs


foo = SomeStruct()

my_domain = eip712_structs.make_domain(name="hello world")
eip712_structs.default_domain = my_domain

assert foo.to_message() == foo.to_message(my_domain)
assert foo.signable_bytes() == foo.signable_bytes(my_domain)

成员类型

基本类型

EIP712的基本类型直接映射到Solidity类型

from eip712_structs import Address, Boolean, Bytes, Int, String, Uint


Address()  # Solidity's 'address'
Boolean()  # 'bool'
Bytes()    # 'bytes'
Bytes(N)   # 'bytesN' - N must be an int from 1 through 32
Int(N)     # 'intN' - N must be a multiple of 8, from 8 to 256
String()   # 'string'
Uint(N)    # 'uintN' - N must be a multiple of 8, from 8 to 256

用法如下

from eip712_structs import EIP712Struct, Address, Bytes


class Foo(EIP712Struct):
    member_name_0 = Address()
    member_name_1 = Bytes(5)
    # etc.

结构引用

除了包含基本类型外,EIP-712结构体还可以包含其他结构体!用法几乎相同——区别在于您不需要“实例化”类。

示例

from eip712_structs import EIP712Struct, String


class Dog(EIP712Struct):
    name = String()
    breed = String()

class Person(EIP712Struct):
    name = String()
    dog = Dog  # Take note - no parentheses!

# Dog "stands alone"
Dog.encode_type()  # Dog(string name,string breed)

# But Person knows how to include Dog
Person.encode_type()  # Person(string name,Dog dog)Dog(string name,string breed)

使用嵌套值实例化结构体可以有多种方式

# Method one: set it to a struct
dog = Dog(name="Mochi", breed="Corgi")
person = Person(name="E.M.", dog=dog)

# Method two: set it to a dict - the underlying struct is built for you
person = Person(
    name="E.M.",
    dog={
        "name": "Mochi",
        "breed": "Corgi",
    }
)

数组

标准也支持数组

array_member = Array(<item_type>[, <optional_length>])
  • <item_type> - 将存在于数组中的基本类型或结构体
  • <optional_length> - 如果指定,数组将设置为该长度。

例如

dynamic_array = Array(String())      # String[] dynamic_array
static_array  = Array(String(), 10)  # String[10] static_array
struct_array  = Array(MyStruct, 10)  # MyStruct[10] - again, don't instantiate structs like the basic types

开发

贡献始终欢迎。

设置开发环境

python -m venv venv
. venv/bin/activate

安装依赖项

python -m pip install -U pip
python -m pip install -e '.[tests]'

运行测试

python -m pytest

在提交PR之前运行linters

./checks.sh

Solidity合约

当更改Solidity测试合约的代码时,您将不得不重新生成其Python数据代码

cd src/tests/integration/contract_sources && ./compile.sh

就这样!不要忘记提交这些更改。

部署新版本

  • __init__.py中增加版本号,将其提交到main分支。
  • 在GitHub的main分支上创建一个发布标签。
  • CI将处理PyPi发布。

不要脸的广告

最初由ConsenSys为全世界编写!由BoboTiG继续! :heart

项目详情


下载文件

下载适合您平台的应用程序。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分发

eip712_structs_ng-2.0.1.tar.gz (23.6 kB 查看散列)

上传时间

构建分发

eip712_structs_ng-2.0.1-py3-none-any.whl (13.7 kB 查看散列)

上传时间 Python 3

由以下支持