Skip to content

Commit 4c7ec3a

Browse files
committed
L1 to L2 msg
1 parent f81a0ab commit 4c7ec3a

File tree

9 files changed

+376
-13
lines changed

9 files changed

+376
-13
lines changed

basic/26-quadratic-vote&gitcoin/hardhat.config.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,25 @@ module.exports = {
3434
*/
3535
},
3636
rinkeby: {
37-
url: "https://rinkeby.infura.io/v3/0aae8358bfe04803b8e75bb4755eaf07", //<---- YOUR INFURA ID! (or it won't work)
37+
url: `https://rinkeby.infura.io/v3/${process.env.INFURA_ID}`, //<---- YOUR INFURA ID! (or it won't work)
3838
accounts: [
3939
mnemonic()
4040
],
4141
},
4242
kovan: {
43-
url: "https://kovan.infura.io/v3/0aae8358bfe04803b8e75bb4755eaf07", //<---- YOUR INFURA ID! (or it won't work)
43+
url: `https://kovan.infura.io/v3/${process.env.INFURA_ID}`, //<---- YOUR INFURA ID! (or it won't work)
4444
accounts: [
4545
mnemonic()
4646
],
4747
},
4848
mainnet: {
49-
url: "https://mainnet.infura.io/v3/0aae8358bfe04803b8e75bb4755eaf07", //<---- YOUR INFURA ID! (or it won't work)
49+
url: `https://mainnet.infura.io/v3/${process.env.INFURA_ID}`, //<---- YOUR INFURA ID! (or it won't work)
5050
accounts: [
5151
mnemonic()
5252
],
5353
},
5454
ropsten: {
55-
url: "https://ropsten.infura.io/v3/0aae8358bfe04803b8e75bb4755eaf07", //<---- YOUR INFURA ID! (or it won't work)
55+
url: `https://ropsten.infura.io/v3/${process.env.INFURA_ID}`, //<---- YOUR INFURA ID! (or it won't work)
5656
accounts: [
5757
mnemonic()
5858
],

basic/27-Arbitrum-layer2/README.md

+28-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Arbitrum
22

3-
Arbitrum bridge:<https://bridge.arbitrum.io/>
4-
53
与 optimism 差别在于: 交互式证明挑战
64

75
Optimism 的争议解决比 Arbitrum 更依赖于以太坊虚拟机 (EVM)。当有人提交关于 Optimism 的挑战时,**整个有问题的交易都通过 EVM 运行**。相比之下,**Arbitrum 使用链下争议解决流程将争议减少到一笔交易中的一个步骤**。然后,协议将这个一步断言(而不是整个交易)发送到 EVM 进行最终验证。因此,从概念上讲,Optimism 的争议解决过程比 Arbitrum 简单得多。
@@ -26,11 +24,13 @@ Optimism 的争议解决过程比 Arbitrum 更简单、更快捷,因为它只
2624
AVM 与 EVM 的不同:
2725
AVM 既支持执行交易,又支持证明(L1 合约相信某个断言是真的)
2826

29-
## 开发
27+
## L1 to L2 messaging
28+
29+
### Ethereum to Arbitrum: Retryable Tickets
3030

31-
### L1 to L2 messaging
31+
Retryable tickets are the Arbitrum protocol’s canonical method for passing generalized messages from Ethereum to Arbitrum. A retryable ticket is an L2 message encoded and delivered by L1; if gas is provided, it will be executed immediately. If no gas is provided or the execution reverts, it will be placed in the L2 retry buffer, where any user can re-execute for some fixed period (roughly one week).
3232

33-
<https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/greeter>
33+
- <https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/greeter>
3434

3535
### L2 to L1 messaging
3636

@@ -47,6 +47,8 @@ https://developer.offchainlabs.com/docs/useful_addresses
4747

4848
## Quick Start
4949

50+
### depoly SimpleToken
51+
5052
- 安装依赖
5153

5254
```bash
@@ -77,6 +79,27 @@ https://developer.offchainlabs.com/docs/useful_addresses
7779
Token address: 0x...
7880
```
7981

82+
### L1 to L2
83+
84+
```sh
85+
node ./scripts/L1toL2.js
86+
```
87+
88+
output:
89+
90+
```sh
91+
Arbitrum Demo: Cross-chain Greeter
92+
Lets
93+
Go ➡️
94+
...🚀
95+
96+
Deploying L1 Greeter 👋
97+
deployed to 0x24b11e81B6477129f298e546c568C20e73b6DD5b
98+
Deploying L2 Greeter 👋👋
99+
deployed to 0x4998e921AC9Cd7ba3B2921aDA9dCedbDC1341465
100+
...
101+
```
102+
80103
## 参考链接
81104

82105
- <https://developer.offchainlabs.com/docs/inside_arbitrum>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
pragma solidity >=0.6.11;
3+
4+
contract Greeter {
5+
string greeting;
6+
7+
constructor(string memory _greeting) public {
8+
greeting = _greeting;
9+
}
10+
11+
function greet() public view returns (string memory) {
12+
return greeting;
13+
}
14+
15+
function setGreeting(string memory _greeting) public virtual {
16+
greeting = _greeting;
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
pragma solidity >=0.6.11;
3+
4+
import "arb-bridge-eth/contracts/bridge/Inbox.sol";
5+
import "arb-bridge-eth/contracts/bridge/Outbox.sol";
6+
import "./Greeter.sol";
7+
8+
contract GreeterL1 is Greeter {
9+
address public l2Target;
10+
IInbox public inbox;
11+
12+
event RetryableTicketCreated(uint256 indexed ticketId);
13+
14+
constructor(
15+
string memory _greeting,
16+
address _l2Target,
17+
address _inbox
18+
) public Greeter(_greeting) {
19+
l2Target = _l2Target;
20+
inbox = IInbox(_inbox);
21+
}
22+
23+
function updateL2Target(address _l2Target) public {
24+
l2Target = _l2Target;
25+
}
26+
27+
function setGreetingInL2(
28+
string memory _greeting,
29+
uint256 maxSubmissionCost,
30+
uint256 maxGas,
31+
uint256 gasPriceBid
32+
) public payable returns (uint256) {
33+
bytes memory data = abi.encodeWithSelector(Greeter.setGreeting.selector, _greeting);
34+
uint256 ticketID = inbox.createRetryableTicket{ value: msg.value }(
35+
l2Target,
36+
0,
37+
maxSubmissionCost,
38+
msg.sender,
39+
msg.sender,
40+
maxGas,
41+
gasPriceBid,
42+
data
43+
);
44+
45+
emit RetryableTicketCreated(ticketID);
46+
return ticketID;
47+
}
48+
49+
/// @notice only l2Target can update greeting
50+
function setGreeting(string memory _greeting) public override {
51+
IBridge bridge = inbox.bridge();
52+
// this prevents reentrancies on L2 to L1 txs
53+
require(msg.sender == address(bridge), "NOT_BRIDGE");
54+
IOutbox outbox = IOutbox(bridge.activeOutbox());
55+
address l2Sender = outbox.l2ToL1Sender();
56+
require(l2Sender == l2Target, "Greeting only updateable by L2");
57+
58+
Greeter.setGreeting(_greeting);
59+
}
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
pragma solidity >=0.6.11;
3+
4+
import "arbos-precompiles/arbos/builtin/ArbSys.sol";
5+
import "arb-bridge-eth/contracts/libraries/AddressAliasHelper.sol";
6+
import "./Greeter.sol";
7+
8+
contract GreeterL2 is Greeter {
9+
ArbSys constant arbsys = ArbSys(100);
10+
address public l1Target;
11+
12+
event L2ToL1TxCreated(uint256 indexed withdrawalId);
13+
14+
constructor(string memory _greeting, address _l1Target) public Greeter(_greeting) {
15+
l1Target = _l1Target;
16+
}
17+
18+
function updateL1Target(address _l1Target) public {
19+
l1Target = _l1Target;
20+
}
21+
22+
function setGreetingInL1(string memory _greeting) public returns (uint256) {
23+
bytes memory data = abi.encodeWithSelector(Greeter.setGreeting.selector, _greeting);
24+
25+
uint256 withdrawalId = arbsys.sendTxToL1(l1Target, data);
26+
27+
emit L2ToL1TxCreated(withdrawalId);
28+
return withdrawalId;
29+
}
30+
31+
/// @notice only l1Target can update greeting
32+
function setGreeting(string memory _greeting) public override {
33+
// To check that message came from L1, we check that the sender is the L1 contract's L2 alias.
34+
require(
35+
msg.sender == AddressAliasHelper.applyL1ToL2Alias(l1Target),
36+
"Greeting only updateable by L1"
37+
);
38+
Greeter.setGreeting(_greeting);
39+
}
40+
}

basic/27-Arbitrum-layer2/contracts/SimpleToken.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity ^0.8.0;
33

4-
import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol";
4+
import "@openzeppelin/contracts-0.8/token/ERC20/presets/ERC20PresetMinterPauser.sol";
55

66
contract SimpleToken is ERC20PresetMinterPauser {
77
/**

basic/27-Arbitrum-layer2/hardhat.config.js

+28-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,28 @@ function mnemonic() {
2323
* @type import('hardhat/config').HardhatUserConfig
2424
*/
2525
module.exports = {
26-
solidity: "0.8.7",
26+
solidity: {
27+
"compilers": [
28+
{
29+
"version": "0.6.11",
30+
"settings": {
31+
"optimizer": {
32+
"enabled": true,
33+
"runs": 100
34+
}
35+
}
36+
},
37+
{
38+
"version": "0.8.7",
39+
"settings": {
40+
"optimizer": {
41+
"enabled": true,
42+
"runs": 100
43+
}
44+
}
45+
}
46+
]
47+
},
2748
networks: {
2849
localhost: {
2950
url: "http://localhost:8545",
@@ -33,6 +54,12 @@ module.exports = {
3354
(you can put in a mnemonic here to set the deployer locally)
3455
*/
3556
},
57+
rinkeby: {
58+
url: `https://rinkeby.infura.io/v3/${process.env.INFURA_ID}`, //<---- YOUR INFURA ID! (or it won't work)
59+
accounts: [
60+
mnemonic()
61+
],
62+
},
3663
arbitrum: {
3764
url: 'https://arb1.arbitrum.io/rpc',
3865
accounts: [

basic/27-Arbitrum-layer2/package.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "27-Arbitrum-layer2",
33
"version": "1.0.0",
4-
"description": "Arbitrum bridge: https://bridge.arbitrum.io/",
4+
"description": "",
55
"main": "index.js",
66
"scripts": {
77
"test": "npx hardhat test"
@@ -14,9 +14,12 @@
1414
"hardhat": "^2.6.5"
1515
},
1616
"devDependencies": {
17+
"@arbitrum/sdk": "^1.1.4",
1718
"@nomiclabs/hardhat-ethers": "^2.0.0",
1819
"@nomiclabs/hardhat-waffle": "^2.0.0",
19-
"@openzeppelin/contracts": "^4.6.0",
20+
"arb-bridge-eth": "^0.7.7",
21+
"arb-shared-dependencies": "^1.0.0",
22+
"arbos-precompiles": "^1.0.2",
2023
"chai": "^4.2.0",
2124
"ethereum-waffle": "^3.0.0",
2225
"ethers": "^5.0.0"

0 commit comments

Comments
 (0)