Skip to content

Commit 361bb4c

Browse files
committed
Merge remote-tracking branch 'origin/dev-content' into sepolia-content-population
2 parents 5c60cf6 + 56982be commit 361bb4c

14 files changed

+1463
-84
lines changed
40.5 KB
Loading
11.9 KB
Loading
67.1 KB
Loading
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
---
2+
section: developers
3+
date: Last Modified
4+
title: "Bridge an ERC721 NFT through a Custom Gateway"
5+
lang: "en"
6+
permalink: "TODO"
7+
excerpt: "TODO"
8+
---
9+
10+
Whenever you want to bridge an ERC721 NFT, you may interact with the Gateway and NFT contracts on Sepolia and Scroll testnet. In this guide, we'll cover different ways of doing so.
11+
12+
## Step 1: Launch an NFT on Sepolia
13+
14+
If you already have an existing token on Sepolia, feel free to skip this step. If you don't have an NFT on L1, you can grab the following minimal example of an ERC721 and launch it on L1.
15+
16+
```solidity
17+
// SPDX-License-Identifier: MIT
18+
pragma solidity 0.8.19;
19+
20+
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
21+
22+
contract MockNFT is ERC721 {
23+
constructor() ERC721("Mock NFT", "MNFT") {}
24+
25+
function mint(address to, uint nftId) public {
26+
_mint(to, nftId);
27+
}
28+
}
29+
```
30+
31+
## Step 2: Launch the Gateway on Sepolia
32+
33+
This step is needed only if you want to launch your own Gateway. Launching your own gateway is fully permissionless and also allows you to have custom logic called every time a token is deposited. You can skip this step if you use the Scroll ERC721 bridge launched at `TODO: 0x1C441Dfc5C2eD7A2AA8636748A664E59CB029157.` More information is available [here](https://github.com/scroll-tech/token-list). This contract will allow you to send NFTs from Sepolia to Scroll testnet.
34+
35+
```solidity
36+
// SPDX-License-Identifier: MIT
37+
pragma solidity 0.8.19;
38+
39+
import "@scroll-tech/[email protected]/L1/gateways/L1ERC721Gateway.sol";
40+
41+
contract MyL1ERC721Gateway is L1ERC721Gateway {
42+
function _depositERC721(
43+
address _token,
44+
address _to,
45+
uint256 _tokenId,
46+
uint256 _gasLimit
47+
) internal override nonReentrant {
48+
super._depositERC721(_token, _to, _tokenId, _gasLimit);
49+
/*custom logic goes here*/
50+
}
51+
52+
function _batchDepositERC721(
53+
address _token,
54+
address _to,
55+
uint256[] calldata _tokenIds,
56+
uint256 _gasLimit
57+
) internal override nonReentrant {
58+
super._batchDepositERC721(_token, _to, _tokenIds, _gasLimit);
59+
/*custom logic goes here*/
60+
}
61+
}
62+
```
63+
64+
## Step 3: Launch the Gateway on Scroll Alpha
65+
66+
You can also skip this step if you use the Scroll ERC721 Gateway launched at `TODO: 0x8Fee20e0C0Ef16f2898a8073531a857D11b9C700`. This contract lets you bridge tokens from Scroll testnet back to Sepolia.
67+
68+
```solidity
69+
// SPDX-License-Identifier: MIT
70+
pragma solidity 0.8.19;
71+
72+
import "@scroll-tech/[email protected]/L2/gateways/L2ERC721Gateway.sol";
73+
74+
contract MyL2ERC721Gateway is L2ERC721Gateway {
75+
function _withdrawERC721(
76+
address _token,
77+
address _to,
78+
uint256 _tokenId,
79+
uint256 _gasLimit
80+
) internal override nonReentrant {
81+
super._withdrawERC721(_token, _to, _tokenId, _gasLimit);
82+
/*custom logic goes here*/
83+
}
84+
85+
function _batchWithdrawERC721(
86+
address _token,
87+
address _to,
88+
uint256[] calldata _tokenIds,
89+
uint256 _gasLimit
90+
) internal override nonReentrant {
91+
super._batchWithdrawERC721(_token, _to, _tokenIds, _gasLimit);
92+
/*custom logic goes here*/
93+
}
94+
}
95+
```
96+
97+
## Step 4: Launch the custom token on Scroll Alpha
98+
99+
This contract has to follow the IScrollERC721 standard interface. It has to allow the gateway to mint tokens on deposit and burn on withdrawal. The following example shows a sample implementation by passing as constructor parameters the L2 gateway (either the one you just launched or Scroll's at `TODO: 0x1C441Dfc5C2eD7A2AA8636748A664E59CB029157`) and your token address on Sepolia.
100+
101+
```solidity
102+
// SPDX-License-Identifier: MIT
103+
pragma solidity 0.8.19;
104+
105+
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
106+
import "@scroll-tech/[email protected]/libraries/token/IScrollERC721.sol";
107+
108+
contract MockNFT is ERC721, IScrollERC721 {
109+
address GATEWAY;
110+
address COUNTERPART;
111+
112+
constructor(address _gateway, address _counterpart) ERC721("Mock NFT", "MNFT") {
113+
GATEWAY = _gateway;
114+
COUNTERPART = _counterpart;
115+
}
116+
117+
/// @notice Return the address of Gateway the token belongs to.
118+
function gateway() public view returns (address) {
119+
return GATEWAY;
120+
}
121+
122+
/// @notice Return the address of counterpart token.
123+
function counterpart() public view returns (address) {
124+
return COUNTERPART;
125+
}
126+
127+
/// @notice Mint some token to recipient's account.
128+
/// @dev Gateway Utilities, only gateway contract can call
129+
/// @param _to The address of recipient.
130+
/// @param _tokenId The token id to mint.
131+
function mint(address _to, uint256 _tokenId) external {
132+
require(msg.sender == gateway(), "Only gateway can mint");
133+
_mint(_to, _tokenId);
134+
}
135+
136+
/// @notice Burn some token from account.
137+
/// @dev Gateway Utilities, only gateway contract can call
138+
/// @param _tokenId The token id to burn.
139+
function burn(uint256 _tokenId) external {
140+
require(msg.sender == gateway(), "Only gateway can mint");
141+
_burn(_tokenId);
142+
}
143+
}
144+
```
145+
146+
## Step 5: Initialize the Gateways
147+
148+
This step is only needed if you're launching your own custom Gateways. If you're using Scroll's Gateway, the Scroll team will take care of this.
149+
150+
On Sepolia, first call the `initialize` function on the Sepolia L1 Gateway by passing the following params:
151+
152+
- `counterpart` : L2 gateway you just launched on Scroll testnet.
153+
- messenger: The messenger contract on Sepolia at `TODO: 0x5260e38080BFe97e6C4925d9209eCc5f964373b6`
154+
155+
Next, you will need to call the `updateTokenMapping` to `bind the L1 and L2 tokens.`
156+
157+
- `l1 token`: Token launched on Sepolia
158+
- `l2 token`: Token launched on Scroll testnet
159+
160+
Now let's move to Scroll testnet and call the initialize function on your Scroll testnet L2 Gateway:
161+
162+
- `counterpart`: L1 gateway you just launched on Sepolia.
163+
- `messenger`: The messenger contract on Scroll testnet at `TODO: 0xb75d7e84517e1504C151B270255B087Fd746D34C`
164+
165+
Finally, let's bind the tokens on Scroll testnet by calling `updateTokenMapping` on the same contract:
166+
167+
- `l2 token` : Token launched on Scroll testnet
168+
- `l1 Token`: Token launched on Sepolia
169+
170+
## Step 6: Deposit from Sepolia to Scroll testnet
171+
172+
Deposits can be made by first approving the Gateway on L1 and then calling the `depositERC721` function by passing the following parameters. Notice that this is a payable function, so if you send 0.0001 ETH, it should be more than enough to confirm your transaction on L2: 
173+
174+
1. `token`: token address on Sepolia
175+
2. `token id`: token id that you want to deposit
176+
3. `gas limit`: 4000 should be enough
177+
178+
After confirming first on L1 and then waiting around 20mins for your confirmation on L2, you should be able to see your NFT on any block explorer.
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
---
2+
section: developers
3+
date: Last Modified
4+
title: "Bridge ERC1155 through the Custom Gateway"
5+
lang: "en"
6+
permalink: "TODO"
7+
excerpt: "TODO"
8+
---
9+
10+
Whenever you want to bridge an ERC1155 NFT, you may interact with the Gateway and NFT contracts on Sepolia and Scroll testnet. In this guide, we'll cover different approaches to doing so.
11+
12+
## Step 1: Launch an 1155 Contract on Sepolia
13+
14+
If you already have an existing token on Sepolia, feel free to skip this step. If you don't have an ERC1155 on L1, you can grab the following minimal example and launch it on L1.
15+
16+
```solidity
17+
// SPDX-License-Identifier: UNLICENSED
18+
pragma solidity 0.8.19;
19+
20+
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
21+
22+
contract MockNFT is ERC1155 {
23+
constructor() ERC1155("") {}
24+
25+
function mint(address to, uint256 id, uint256 amount) public {
26+
_mint(to, id, amount, "");
27+
}
28+
}
29+
```
30+
31+
## Step 2: Launch the Gateway on Sepolia
32+
33+
This step is needed only if you want to launch your own Gateway. Launching your own gateway is fully permissionless and also allows you to have custom logic called every time a token is deposited. You can skip this step if you use the Scroll ERC1155 bridge launched at `TODO: TODO: 0xd1bE599aaCBC21448fD6373bbc7c1b4c7806f135`. More information is available [here](https://github.com/scroll-tech/token-list). This contract will allow you to send ERC1155 tokens from Sepolia to Scroll testnet.
34+
35+
<pre class="language-solidity"><code class="lang-solidity"><strong>// SPDX-License-Identifier: MIT
36+
</strong>pragma solidity 0.8.19;
37+
38+
import "@scroll-tech/[email protected]/L1/gateways/L1ERC1155Gateway.sol";
39+
40+
contract MyL1ERC1155Gateway is L1ERC1155Gateway {
41+
function _depositERC1155(
42+
address _token,
43+
address _to,
44+
uint256 _tokenId,
45+
uint256 _amount,
46+
uint256 _gasLimit
47+
) internal override nonReentrant {
48+
super._depositERC1155(_token, _to, _tokenId, _amount, _gasLimit);
49+
/*custom logic goes here*/
50+
}
51+
52+
function _batchDepositERC1155(
53+
address _token,
54+
address _to,
55+
uint256[] calldata _tokenIds,
56+
uint256[] calldata _amounts,
57+
<strong> uint256 _gasLimit
58+
</strong> ) internal override nonReentrant {
59+
super._batchDepositERC1155(_token, _to, _tokenIds, _amounts, _gasLimit);
60+
/*custom logic goes here*/
61+
}
62+
}
63+
</code></pre>
64+
65+
## Step 3: Launch the Gateway on Scroll
66+
67+
This step is needed only if you want to launch your own Gateway. Launching your own gateway is fully permissionless and also allows you to have custom logic called every time a token is deposited. You can skip this step if you use the Scroll ERC1155 bridge launched at `TODO: 0xfe5Fc32777646bD123564C41f711FF708Dd48360`. More information is available [here](https://github.com/scroll-tech/token-list). This contract will allow you to send ERC1155 tokens from Sepolia to Scroll testnet.
68+
69+
```solidity
70+
// SPDX-License-Identifier: MIT
71+
pragma solidity 0.8.19;
72+
73+
import "@scroll-tech/[email protected]/L2/gateways/L2ERC1155Gateway.sol";
74+
75+
contract MyL2ERC1155Gateway is L2ERC1155Gateway {
76+
function _withdrawERC1155(
77+
address _token,
78+
address _to,
79+
uint256 _tokenId,
80+
uint256 _amount,
81+
uint256 _gasLimit
82+
) internal override nonReentrant {
83+
super._withdrawERC1155(_token, _to, _tokenId, _amount, _gasLimit);
84+
/*custom logic goes here*/
85+
}
86+
87+
function _batchWithdrawERC1155(
88+
address _token,
89+
address _to,
90+
uint256[] calldata _tokenIds,
91+
uint256[] calldata _amounts,
92+
uint256 _gasLimit
93+
) internal override nonReentrant {
94+
super._batchWithdrawERC1155(_token, _to, _tokenIds, _amounts, _gasLimit);
95+
/*custom logic goes here*/
96+
}
97+
}
98+
```
99+
100+
## Step 3: Launch the custom token on Scroll testnet
101+
102+
This contract has to follow the IScrollERC1155 standard interface. It has to allow the gateway to mint tokens on deposit and burn on withdrawal. The following example shows a sample implementation by passing as constructor parameters the L2 gateway (either the one you just launched or Scroll's at `TODO: 0xd1bE599aaCBC21448fD6373bbc7c1b4c7806f135`) and your token address on Sepolia.
103+
104+
```solidity
105+
// SPDX-License-Identifier: MIT
106+
pragma solidity 0.8.19;
107+
108+
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
109+
import "@scroll-tech/[email protected]/libraries/token/IScrollERC1155.sol";
110+
111+
contract MockNFT is ERC1155, IScrollERC1155 {
112+
address GATEWAY;
113+
address COUNTERPART;
114+
115+
constructor(address _gateway, address _counterpart) ERC1155("") {
116+
GATEWAY = _gateway;
117+
COUNTERPART = _counterpart;
118+
}
119+
120+
/// @notice Return the address of Gateway the token belongs to.
121+
function gateway() public view returns (address) {
122+
return GATEWAY;
123+
}
124+
125+
/// @notice Return the address of counterpart token.
126+
function counterpart() public view returns (address) {
127+
return COUNTERPART;
128+
}
129+
130+
/// @notice Mint some token to recipient's account.
131+
/// @dev Gateway Utilities, only gateway contract can call
132+
/// @param _to The address of recipient.
133+
/// @param _tokenId The token id to mint.
134+
function mint(address _to, uint256 _tokenId, uint256 _amount, bytes memory _data) external {
135+
require(msg.sender == gateway(), "Only gateway can mint");
136+
_mint(_to, _tokenId, _amount, _data);
137+
}
138+
139+
/// @notice Burn some token from account.
140+
/// @dev Gateway Utilities, only gateway contract can call
141+
/// @param _tokenId The token id to burn.
142+
function burn(address _from, uint256 _tokenId, uint256 _amount) external {
143+
require(msg.sender == gateway(), "Only gateway can mint");
144+
_burn(_from, _tokenId, _amount);
145+
}
146+
147+
function batchMint(
148+
address _to,
149+
uint256[] calldata _tokenIds,
150+
uint256[] calldata _amounts,
151+
bytes calldata _data
152+
) public {
153+
require(msg.sender == gateway(), "Only gateway can mint");
154+
_mintBatch(_to, _tokenIds, _amounts, _data);
155+
}
156+
157+
/// @notice Batch burn some token from account.
158+
/// @dev Gateway Utilities, only gateway contract can call
159+
/// @param _from The address of account to burn token.
160+
/// @param _tokenIds The list of token ids to burn.
161+
/// @param _amounts The list of corresponding amount of token to burn.
162+
function batchBurn(address _from, uint256[] calldata _tokenIds, uint256[] calldata _amounts) public {
163+
require(msg.sender == gateway(), "Only gateway can Burn");
164+
_burnBatch(_from, _tokenIds, _amounts);
165+
}
166+
}
167+
```
168+
169+
## Step 4: Initialize the Gateways
170+
171+
This step is only needed if you're launching your own custom Gateways. If you're using Scroll's Gateway, the Scroll team will take care of this.
172+
173+
On Sepolia, first call the `initialize` function on the Sepolia L1 Gateway by passing the following params:
174+
175+
- `counterpart` : L2 gateway you just launched on Scroll testnet.
176+
- messenger: The messenger contract on Sepolia at `TODO: 0x5260e38080BFe97e6C4925d9209eCc5f964373b6`
177+
178+
Next, you will need to call the `updateTokenMapping` to `bind the L1 and L2 tokens.`
179+
180+
- `l1 token`: Token launched on Sepolia
181+
- `l2 token`: Token launched on Scroll testnet
182+
183+
Now let's move to Scroll testnet and call the initialize function on your Scroll testnet L2 Gateway:
184+
185+
- `counterpart`: L1 gateway you just launched on Sepolia.
186+
- `messenger`: The messenger contract on Scroll testnet at `TODO: 0xb75d7e84517e1504C151B270255B087Fd746D34C`
187+
188+
Finally, let's bind the tokens on Scroll testnet by calling `updateTokenMapping` on the same contract:
189+
190+
- `l2 token` : Token launched on Scroll testnet
191+
- `l1 Token`: Token launched on Sepolia
192+
193+
## Step 5: Deposit from Sepolia to Scroll testnet
194+
195+
Deposits can be made by first approving the Gateway on L1 and then calling the `depositERC1155` function by passing the following parameters. Notice that this is a payable function, so if you send 0.0001 ETH, it should be more than enough to confirm your transaction on L2:
196+
197+
1. `token`: token address on Sepolia
198+
2. `token id`: token id that you want to deposit
199+
3. `amount`: amount of tokens you want to deposit
200+
4. `gas limit`: 4000 should be enough

0 commit comments

Comments
 (0)