Skip to content

Commit 0e22d68

Browse files
committed
fix: add native meta transaction question to meta transactions section
1 parent 8823a07 commit 0e22d68

File tree

1 file changed

+126
-1
lines changed

1 file changed

+126
-1
lines changed

solidity/junior-3/solidity/README.md

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,136 @@
3636
- Для чего необходимо реализовать контракт ```Paymaster```?
3737
- Можно ли использовать [контракты из библиотеки OpenZeppelin](https://docs.openzeppelin.com/contracts/4.x/api/metatx) для организации метатранзакций?
3838
- Какие еще есть сервисы, которые можно использовать для организации метатранзакций?
39-
5. Творческий вопрос. Как ты считаешь, на сколько важны метатранзакции? Есть ли у них будущее? Нарушают ли они какие-нибудь законы децентрализации?
39+
5. Можно ли реализовать метатранзакции нативно?
40+
- Как работает следующий пример кода?
41+
```solidity
42+
// SPDX-License-Identifier: UNLICENSED
43+
pragma solidity ^0.8.19;
44+
45+
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
46+
47+
contract Token is ERC20 {
48+
bytes32 public constant META_TRANSACTION_TYPEHASH =
49+
keccak256("MetaTransaction(uint256 nonce,address signer,bytes functionSignature)");
50+
51+
mapping(address signer => uint256 nonce) private _nonces;
52+
53+
struct MetaTransaction {
54+
uint256 nonce;
55+
address signer;
56+
bytes functionSignature;
57+
}
58+
59+
event MetaTransactionExecuted(
60+
address signer,
61+
address relayer,
62+
bytes functionSignature
63+
);
64+
65+
error ZeroAddress();
66+
error InvalidSignature();
67+
error InvalidCall();
68+
69+
constructor() ERC20("Token", "MTT") {}
70+
71+
function DOMAIN_SEPARATOR() public view returns (bytes32) {
72+
return keccak256(
73+
abi.encode(
74+
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
75+
keccak256("EIP712"),
76+
keccak256("1"),
77+
block.chainid,
78+
address(this)
79+
)
80+
);
81+
}
82+
83+
function executeMetaTransaction(
84+
address signer,
85+
bytes memory functionSignature,
86+
uint8 v,
87+
bytes32 r,
88+
bytes32 s
89+
) external payable returns (bytes memory result) {
90+
MetaTransaction memory _tx = MetaTransaction({
91+
nonce: _nonces[signer],
92+
signer: signer,
93+
functionSignature: functionSignature
94+
});
95+
96+
bool isVerify = _verify(signer, _tx, v, r, s);
97+
if (!isVerify) {
98+
revert InvalidSignature();
99+
}
100+
101+
_nonces[signer] += 1;
102+
103+
(bool success, bytes memory data) = address(this).call(
104+
abi.encodePacked(functionSignature, signer)
105+
);
106+
107+
if (!success) {
108+
revert InvalidCall();
109+
}
110+
111+
emit MetaTransactionExecuted(signer, msg.sender, functionSignature);
112+
113+
return data;
114+
}
115+
116+
function getNonce(address account) external view returns (uint256) {
117+
return _nonces[account];
118+
}
119+
120+
function _msgSender() internal view override returns (address sender) {
121+
if (msg.sender == address(this)) {
122+
assembly {
123+
sender := shr(96, calldataload(sub(calldatasize(), 20)))
124+
}
125+
}
126+
else {
127+
return super._msgSender();
128+
}
129+
}
130+
131+
function _verify(
132+
address signer,
133+
MetaTransaction memory _tx,
134+
uint8 v,
135+
bytes32 r,
136+
bytes32 s
137+
) private view returns (bool) {
138+
if (signer == address(0)) {
139+
revert ZeroAddress();
140+
}
141+
142+
return signer == ecrecover(_getDigest(_tx), v, r, s);
143+
}
144+
145+
function _getDigest(MetaTransaction memory _tx) private view returns (bytes32) {
146+
return keccak256(
147+
abi.encodePacked(
148+
"\x19\x01",
149+
DOMAIN_SEPARATOR(),
150+
keccak256(
151+
abi.encode(
152+
META_TRANSACTION_TYPEHASH,
153+
_tx.nonce,
154+
_tx.signer,
155+
keccak256(_tx.functionSignature)
156+
)
157+
)
158+
)
159+
);
160+
}
161+
}
162+
```
163+
6. Творческий вопрос. Как ты считаешь, на сколько важны метатранзакции? Есть ли у них будущее? Нарушают ли они какие-нибудь законы децентрализации?
40164
41165
- [Gas-free transactions: Meta Transactions explained](https://medium.com/coinmonks/gas-free-transactions-meta-transactions-explained-f829509a462d)
42166
- [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771)
43167
- [Gas Station Network](https://docs.opengsn.org/)
168+
- [Native Meta Transactions](https://medium.com/gitcoin/native-meta-transactions-e509d91a8482)
44169
45170
## Oracles
46171

0 commit comments

Comments
 (0)