0
# Meta-Transactions
1
2
ERC-2771 meta-transaction support enabling gasless transactions through trusted forwarders and context-aware message handling.
3
4
## Capabilities
5
6
### ERC-2771 Context
7
8
Context-aware contract that can handle meta-transactions from trusted forwarders.
9
10
```solidity { .api }
11
/**
12
* @dev Context variant with ERC-2771 support
13
*/
14
abstract contract ERC2771ContextUpgradeable {
15
function __ERC2771Context_init(address trustedForwarder) internal onlyInitializing;
16
17
/**
18
* @dev Returns whether forwarder is a trusted forwarder
19
*/
20
function isTrustedForwarder(address forwarder) external view returns (bool);
21
22
/**
23
* @dev Returns the original sender of the transaction
24
*/
25
function _msgSender() internal view override returns (address);
26
27
/**
28
* @dev Returns the original call data
29
*/
30
function _msgData() internal view override returns (bytes calldata);
31
32
/**
33
* @dev Returns the length of the context suffix
34
*/
35
function _contextSuffixLength() internal view override returns (uint256);
36
}
37
```
38
39
### ERC-2771 Forwarder
40
41
Forwarder contract that executes meta-transactions on behalf of users.
42
43
```solidity { .api }
44
/**
45
* @dev Simple forwarder to be used together with an ERC-2771 compatible contract
46
*/
47
contract ERC2771ForwarderUpgradeable {
48
function __ERC2771Forwarder_init(string memory name) internal onlyInitializing;
49
50
/**
51
* @dev Structure of a forwarding request
52
*/
53
struct ForwardRequestData {
54
address from;
55
address to;
56
uint256 value;
57
uint256 gas;
58
uint48 deadline;
59
bytes data;
60
bytes signature;
61
}
62
63
/**
64
* @dev Returns the current nonce for a signer
65
*/
66
function nonces(address owner) external view returns (uint256);
67
68
/**
69
* @dev Verify the validity of a forward request
70
*/
71
function verify(ForwardRequestData calldata request) external view returns (bool);
72
73
/**
74
* @dev Execute a forward request
75
*/
76
function execute(ForwardRequestData calldata request) external payable returns (bool success, bytes memory returndata);
77
78
/**
79
* @dev Batch execute multiple forward requests
80
*/
81
function executeBatch(
82
ForwardRequestData[] calldata requests,
83
address payable refundReceiver
84
) external payable returns (bool[] memory successes, bytes[] memory returndatas);
85
}
86
```
87
88
## Usage Examples
89
90
### Meta-Transaction Enabled Token
91
92
```solidity
93
import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
94
import {ERC2771ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/metatx/ERC2771ContextUpgradeable.sol";
95
96
contract MetaToken is ERC20Upgradeable, ERC2771ContextUpgradeable {
97
function initialize(
98
string memory name,
99
string memory symbol,
100
address trustedForwarder
101
) initializer public {
102
__ERC20_init(name, symbol);
103
__ERC2771Context_init(trustedForwarder);
104
}
105
106
// Override _msgSender and _msgData to use ERC2771 context
107
function _msgSender() internal view override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (address) {
108
return ERC2771ContextUpgradeable._msgSender();
109
}
110
111
function _msgData() internal view override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (bytes calldata) {
112
return ERC2771ContextUpgradeable._msgData();
113
}
114
115
function _contextSuffixLength() internal view override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (uint256) {
116
return ERC2771ContextUpgradeable._contextSuffixLength();
117
}
118
}
119
```
120
121
### Forwarder Deployment
122
123
```solidity
124
import {ERC2771ForwarderUpgradeable} from "@openzeppelin/contracts-upgradeable/metatx/ERC2771ForwarderUpgradeable.sol";
125
126
contract MyForwarder is ERC2771ForwarderUpgradeable {
127
function initialize() initializer public {
128
__ERC2771Forwarder_init("MyForwarder");
129
}
130
}
131
```