智能合约开发实战——元交易(Metatransaction),元交易合约的实现
引言
前一篇文章(可以看我主页哦)中提到,普通的 ETH 交易并不能够做到让用户无需 gas 费,需要交易中嵌套一个交易,即元交易,来实现免 gas 费。
本文将分析开源库 OpenZeppelin/openzeppelin-contracts 中的元交易合约的实现,让你能够快速入门元交易实现细节,从而能够自己对后续更多的相关技术深入探索。
前置知识概述
元交易会涉及到 ECDSA 与 EIP712 等知识,如果你是熟手,可以跳过此节内容,直接浏览具体实现分析部分。
Hash
也称哈希、散列、数字摘要。通过哈希函数,可以将长短不一的信息转化为一段长度任意但可预测的(确定性的)结果。这是一类神奇的函数,可以将一大堆信息转变成一串短的,可作为摘要的数据 “指纹”。对于一个给定的输入而言,生成的 “指纹” 始终一致。如果你的原始数据中有任何细微的改动,生成的哈希值将大不相同。以太坊中采用的是 Keccak-256 算法。
ECDSA
在密码学中,ECDSA(Elliptic Curve Digital Signature Algorithm,椭圆曲线数字签名算法)是使用椭圆曲线密码学的数字签名算法(DSA)的一个变种。
主要用于对数据(比如一个文件)创建数字签名,以便于你在不破坏它的安全性的前提下对它的真实性进行验证。可以将它想象成一个实际的签名,你可以识别部分人的签名,但是你无法在别人不知道的情况下伪造它。
你不应该将ECDSA与用来对数据进行加密的AES(高级加密标准)相混淆。ECDSA不会对数据进行加密、或阻止别人看到或访问你的数据,它可以防止的是确保数据没有被篡改。
如图所示,在以太坊中,ECDSA 用于对原始数据的 hash 值进行签名及恢复。
将原始数据通过 hash 函数得到它的 hash 值后,用户 A 用自己的私钥对该 hash 值进行签名,得到 Signature(签名)。有了该签名与 hash 值,任何人都能够从中恢复出签名人的钱包地址,在这里用户 B 则恢复得到了用户 A 的钱包地址。
EIP712
Ethereum Improvement Proposals (EIPs),你可以在这里查看所有的 EIPs。EIP712 (Ethereum typed structured data hashing and signing)以太坊类型的结构化数据哈希与签名。
如果我们只关心字节字符串的话,签名数据是一个已经解决了的问题。但不幸的是,在现实世界中,我们关心的是复杂而有意义的信息,对结构化数据进行哈希是非常重要的,错误会导致系统安全属性的丢失。
此 EIP 旨在提高链上使用的链下消息签名的可用性。我们看到越来越多的人采用链下消息签名,因为它节省了 gas 费,减少了区块链上的交易数量。当前签名消息是一个不透明的十六进制字符串,显示给用户,关于组成消息的项目的上下文很少。
EIP712 概述了一个编码数据及其结构的方案,该方案允许在签名时将数据显示给用户进行验证。下面是一个用户在签署 EIP712 消息时显示的示例。
ECDSA 是 openzeppelin 实现的一个 solidity 库,它实现了从 hash 值中恢复钱包地址的方法,将它应用在 bytes32 上,就可以直接在 bytes32 上调用 recover 方法。recover 函数签名:function recover(bytes32 hash, bytes memory signature) internal pure returns (address) 。
ForwardRequest 结构体定义了一个交易中用于签名的基本组成成分。与以太坊交易不同的是没有 gasPrice,因为智能合约的执行只关心 gas 的消耗。ForwardRequest 中 的 nonce 概念与以太坊类似,都是为了避免双花攻击,但这里的 nonce 仅由智能合约维护,跟普通的以太坊交易中的 nonce 无关。
构造函数中直接使用 EIP712 的构造函数进行初始化,EIP712 的构造函数签名为:constructor(string memory name, string memory version) ,其中 name 是合约名称,version 是合约版本,这将作为 EIP712 签名验证的一部分,它在部署时,将自动获取合约的地址、chainId 等信息。意味着,即便有相同的 ForwardRequest 结构体数据,但合约地址或区块链网络不同,也会导致签名无效。
mapping(address => uint256) private _nonces; function getNonce(address from) public view returns (uint256) { return _nonces[from]; }
简单理解为避免中继器(代为执行元交易的人)恶意地或无意地使用足够低的 gas 使得交易执行成功,而元交易执行失败。详情可以在 ethereum gas dangers 中学习。
猜你喜欢
-
大型物联网平台如何来保障亿级设备安全连接上云?
推荐原创摘要:华为云IoT设备接入云服务(后续章节简称为“IoTDA”)提供海量设备的接入和管理能力,可以将IoT设备联接到华为云,支撑设备数据采集上云和云端下发命令给设备进行远程控制,配合华为云其他产品,帮助快速构筑物联网解决方案。
-
【Kafka系列教程】088:Kafka Streams之概念——状态
某些流处理应用程序不需要状态,这意味着消息的处理独立于所有其他消息的处理。然而,能够维护状态为复杂的流处理应用程序打开了许多可能性:您可以加入输入流,或分组和聚合数据记录。许多这样的有状态运算符是由Kafka Streams DSL.Kafka Streams提供了所谓的状态存储,流处理应用程序可以
-
边缘计算:盘点100个知识点
推荐第三代、第四代和第五代蜂窝技术。简单来说,3G 代表智能手机及其移动网络浏览器的引入;4G 是当前一代的蜂窝技术,为移动设备提供真正的宽带互联网接入;5G 蜂窝技术将为蜂窝系统提供巨大的带宽并减少延迟,支持从智能手机到自动驾驶汽车和大规模物联网的一系列设备。边缘计算被认为是 5G 的关键组成部分。
-
在 WebAssembly 中使用 Rust 编写 eBPF 程序并发布 OCI 镜像
推荐原创eBPF(extended Berkeley Packet Filter)是一种高性能的内核虚拟机,可以运行在内核空间中,以收集系统和网络信息。随着计算机技术的不断发展,eBPF 的功能日益强大,并且已经成为各种效率高效的在线诊断和跟踪系统,以及构建安全的网络、服务网格的重要组成部分。
-
配置应用签名信息
推荐原创准备签名文件 文件名称 作用 0密钥文件(.p12文件) 用于打包项目时进行签名、获取签名证书指纹。 证书请求文件(.csr) 用于向华为申请调试证书、发布证书。 表1 需准备的签名文件清单 搭建完开发环境后,您需要使用DevEco Studio
-
爬虫时IP代理不能用?考虑以下几点原因
推荐代理服务商提供的IP大多数资源都是及时的。如果客户不能使用代理,IP正常访问网络,可以先检查代理IP是否有效IP生命周期不固定,受到影响IP类型,IP受质量等因素影响,有的生存时间短,几秒钟或几分钟,有的时间长,十几个小时或几天。通过测试或直接更改其他代理IP判断其不能使用的原因是比较直接快捷的方法。