-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathL1L2Example.sol
96 lines (80 loc) · 2.61 KB
/
L1L2Example.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;
interface IStarknetCore {
/**
Sends a message to an L2 contract.
Returns the hash of the message.
*/
function sendMessageToL2(
uint256 toAddress,
uint256 selector,
uint256[] calldata payload
) external payable returns (bytes32);
/**
Consumes a message that was sent from an L2 contract.
Returns the hash of the message.
*/
function consumeMessageFromL2(
uint256 fromAddress,
uint256[] calldata payload
) external returns (bytes32);
}
/**
Demo contract for L1 <-> L2 interaction between an L2 StarkNet contract and this L1 solidity
contract.
*/
contract L1L2Example {
// The StarkNet core contract.
IStarknetCore starknetCore;
mapping(uint256 => uint256) public userBalances;
uint256 constant MESSAGE_WITHDRAW = 0;
// The selector of the "deposit" l1_handler.
uint256 constant DEPOSIT_SELECTOR =
352040181584456735608515580760888541466059565068553383579463728554843487745;
/**
Initializes the contract state.
*/
constructor(IStarknetCore starknetCore_) public {
starknetCore = starknetCore_;
}
function withdraw(
uint256 l2ContractAddress,
uint256 user,
uint256 amount
) external {
// Construct the withdrawal message's payload.
uint256[] memory payload = new uint256[](3);
payload[0] = MESSAGE_WITHDRAW;
payload[1] = user;
payload[2] = amount;
// Consume the message from the StarkNet core contract.
// This will revert the (Ethereum) transaction if the message does not exist.
starknetCore.consumeMessageFromL2(l2ContractAddress, payload);
// Update the L1 balance.
userBalances[user] += amount;
}
function deposit(
uint256 l2ContractAddress,
uint256 user,
uint256 amount
) external payable {
require(amount < 2**64, "Invalid amount.");
require(
amount <= userBalances[user],
"The user's balance is not large enough."
);
// Update the L1 balance.
userBalances[user] -= amount;
// Construct the deposit message's payload.
uint256[] memory payload = new uint256[](2);
payload[0] = user;
payload[1] = amount;
// Send the message to the StarkNet core contract, passing any value that was
// passed to us as message fee.
starknetCore.sendMessageToL2{value: msg.value}(
l2ContractAddress,
DEPOSIT_SELECTOR,
payload
);
}
}