签名消息与签名结构化数据

签名消息与签名结构化数据

点击顶部栏中的 🚀 -> Binder 可在线运行此示例!

在 Ethereum 中,建议遵循 EIP-712 对数据进行签名和验证签名,而在 Conflux 中,我们遵循 CIP-23 对数据进行签名和验证。

对数据进行签名和验证的方式与 eth-account 一致,这里是示例。

Sign Message

from cfx_account import Account
from cfx_account.messages import encode_defunct

message = "Hello World"

acct = Account.create()

# 消息在签名前需要进行预处理
signable_message = encode_defunct(text=message)
# 签名
signed = acct.sign_message(signable_message)

# 验签
assert acct.address == Account.recover_message(signable_message, signature=signed.signature)

签名结构化数据

如下所示, typed_data 是由 CIP-23 定义的数据结构。其与 EIP-712 定义的结构体的主要区别在于 EIP712Domain 被替换为了 CIP23Domain,且domain字段的chainId字段必须要填写。

from cfx_account.messages import encode_structured_data

typed_data = {
    "types": {
        "CIP23Domain": [
            {
                "name": "name",
                "type": "string"
            },
            {
                "name": "version",
                "type": "string"
            },
            {
                "name": "chainId",
                "type": "uint256"
            },
            {
                "name": "verifyingContract",
                "type": "address"
            }
        ],
        "Person": [
            {
                "name": "name",
                "type": "string"
            },
            {
                "name": "wallet",
                "type": "address"
            }
        ],
        "Mail": [
            {
                "name": "from",
                "type": "Person"
            },
            {
                "name": "to",
                "type": "Person"
            },
            {
                "name": "contents",
                "type": "string"
            }
        ]
    },
    "primaryType": "Mail",
    "domain": {
        "name": "Ether Mail",
        "version": "1",
        "chainId": 1,
        "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
    },
    "message": {
        "from": {
            "name": "Cow",
            "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
        },
        "to": {
            "name": "Bob",
            "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
        },
        "contents": "Hello, Bob!"
    }
}

# 预处理数据
signable_message = encode_structured_data(primitive=typed_data)
# 签名
signed = acct.sign_message(signable_message)

# 验签
assert acct.address == Account.recover_message(signable_message, signature=signed.signature)