10

Optimistic Rollup 就這樣用(2)

 3 years ago
source link: https://medium.com/taipei-ethereum-meetup/optimistic-rollup-example-erc721-5e78e2c548b9
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Optimistic Rollup 就這樣用(2)

ERC721 的儲值、轉移與提領

TL;DR

  • Node.js
  • Docker
  • Docker-compose

筆者沒有碰到環境相容問題,但是建議都升到最新版本, Node.js 使用 v16.1.0 或以上版本

Optimism 服務啟動

有關 Optimisim 的所有服務,都包裝在 Optimism 這個超大專案當中了,直接使用原始碼進行組建:

$ git clone [email protected]:ethereum-optimism/optimism.git
$ cd optimism
$ yarn
$ yarn build

組建完成後,就可以在本機啟動服務了:

$ cd ops
$ docker-compose build
$ docker-compose up

這個指令會啟動數個服務,包括:

  • L1 Ethereum Node (EVM)
  • L2 Ethereum Node (OVM)
  • Batch Submitter
  • Data Transport Layer
  • Deployer
  • Relayer
  • Verifier

Deployer 服務中的一個參數要特別注意: FRAUD_PROOF_WINDOW_SECONDS,這個就是 OPtimistic Rollup 的挑戰期,代表使用者出金(Withdraw)需等候的時長。在本篇演示中預設為 0 秒。

如果有需要重啟,記得把整個 Docker Volume 也清乾淨,例如: docker-compose down -v

Optimism 整合測試

在繼續接下來的演示之前,我們需要先確認 Optimism 是否有順利啟動,特別是 Relayer 是否運作正常,因此我們需要先進行整合測試:

$ cd optimism/integration-tests
$ yarn build:integration
$ yarn test:integration

確保 L1 <--> L2 Communication 相關測試通過後再繼續執行接下來的演示內容。

啟動服務及部署合約需要花費一些時間,運行一段時間(約 120 秒)之後再執行測試,如果測試結果全部皆為 Fail,可能是 Optimism 尚未啟動完成,再等待一段時間即可。

ERC721 合約部署

Optimism 啟動成功並且完成整合測試後,接下來進行 ERC721 合約的部署。筆者已將合約及部署腳本放在 optimistic-rollup-example-erc721 這個專案中:

$ git clone [email protected]:ethereum-optimism/optimistic-rollup-example-erc721.git
$ cd optimistic-rollup-example-erc721
$ yarn install
$ yarn compile

接下來我們需要部署以下合約:

  • ERC721,部署於 L1
  • L2DepositedEERC721,部署於 L2
  • OVM_L1ERC721Gateway,部署於 L1

OVM_L1ERC721Gateway 只部署在 L1 上,顧名思義它就是 L1 <=> L2 的「門戶」,提供 Deposit / Withdraw 兩個基本功能,使用者必須透過這個合約來進出 L2。

雖然 OVM_L1ERC20Gateway 是 Optimistic Rollup 官方提供的合約。但是開發者也可以依需求自行設計自己的「門戶」。

OVM_L1ERC20Gateway 目前沒有 Optimism 的官方實作,本演示所使用的 ERC721 Gateway 合約來自這個提案,目前尚未成為官方標準。

接下來,我們直接用腳本進行部署:

$ node ./deploy.js
Deploying L1 ERC721...
L1 ERC2721 Contract Address: 0xFD471836031dc5108809D173A067e8486B9047A3
Deploying L2 ERC721...
L2 ERC721 Contract Address: 0x09635F643e140090A9A8Dcd712eD6285858ceBef
Deploying L1 ERC721 Gateway...
L1 ERC721 Gateway Contract Address: 0xcbEAF3BDe82155F56486Fb5a1072cb8baAf547cc
Initializing L2 ERC721...

ERC721 鑄造、儲值、轉移與提領

鑄造(L1)

初始狀態如下,所有帳戶皆尚未持有任何代幣:

0*rms2twzBQI4Gb-0h.png?q=20
optimistic-rollup-example-erc721-5e78e2c548b9

接下來,我們將鑄造 2 個代幣以進行接下來的演示。首先,進入 ETH(L1) 的 Console:

$ npx hardhat console --network eth
Welcome to Node.js v16.1.0.
Type ".help" for more information.
>

取得 Deployer / User 帳戶:

// In Hardhat ETH Console> let accounts = await ethers.getSigners()> let deployer = accounts[0]> let user = accounts[1]

取得 ERC721OVM_L1ERC721Gateway 合約物件,合約地址可以從部署訊息中取得:

// In Hardhat ETH Console> let ERC721_abi = await artifacts.readArtifact("ExampleToken").then(c => c.abi)> let ERC721 = new ethers.Contract("0xFD471836031dc5108809D173A067e8486B9047A3", ERC721_abi)> let Gateway_abi = await artifacts.readArtifact("OVM_L1ERC721Gateway").then(c => c.abi)> let Gateway = new ethers.Contract("0xcbEAF3BDe82155F56486Fb5a1072cb8baAf547cc", Gateway_abi)

鑄造兩個 ERC721 代幣:

// In Hardhat ETH Console> await ERC721.connect(deployer).mintToken(deployer.address, "foo"){
hash: "...",
...
}> await ERC721.connect(deployer).mintToken(deployer.address, "bar"){
hash: "...",
...
}

只有合約的 Owner(deployer) 可以進行鑄造的操作。

確認 Deployer 餘額:

> await ERC721.connect(deployer).balanceOf(deployer.address)BigNumber { _hex: '0x02', _isBigNumber: true } // 2

確認代幣的 TokenID 與 Owner:

> await ERC721.connect(deployer).ownerOf(1)'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' // deployer> await ERC721.connect(deployer).ownerOf(2)'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' // deployer

儲值(L1 => L2)

完成以上步驟後,目前的狀態如下:

0*7I1h03CfDXaPZOHq.png?q=20
optimistic-rollup-example-erc721-5e78e2c548b9

接下來,授權 OVM_L1ERC721Gateway使用 TokenID 為 2 的代幣:

// In Hardhat ETH Console> await ERC721.connect(deployer).approve("0xcbEAF3BDe82155F56486Fb5a1072cb8baAf547cc", 2){
hash: "...",
...
}

OVM_L1ERC721Gateway 合約呼叫 Deposit,儲值 TokenID 為 2 的代幣:

// In Hardhat ETH Console> await Gateway.connect(deployer).deposit(2){
hash: "...",
...
}

我們可以到 Optimism (L2) 的 Console 確認入金是否成功:

$ npx hardhat console --network optimism
Welcome to Node.js v16.1.0.
Type ".help" for more information.
>

取得 Deployer / User 帳戶:

// In Hardhat Optimism Console> let accounts = await ethers.getSigners()> let deployer = accounts[0]> let user = accounts[1]

取得 L2DepositedERC721 合約物件,合約地址可以從部署訊息中取得:

// In Hardhat Optimism Console> let L2ERC721_abi = await artifacts.readArtifact("OVM_L2DepositedERC721").then(c => c.abi)> let L2DepositedERC721 = new ethers.Contract("0x09635F643e140090A9A8Dcd712eD6285858ceBef", L2ERC721_abi)

確認入金是否成功:

// In Hardhat Optimism Console> await L2DepositedERC721.connect(deployer).balanceOf(deployer.address)BigNumber { _hex: '0x01', _isBigNumber: true } // 1> await L2DepositedERC721.connect(deployer).ownerOf(2)'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' // deployer

ERC721 轉移(L2 <=> L2)

完成以上步驟後,目前的狀態如下:

0*Zt2fM5uytKnnRAlE.png?q=20
optimistic-rollup-example-erc721-5e78e2c548b9

接下來,我們在 L2 從 Deployer 轉移代幣給 User:

// In Hardhat Optimism Console> await L2DepositedERC721.connect(user).balanceOf(user.address)BigNumber { _hex: '0x00', _isBigNumber: true } // 0> await L2DepositedERC721.connect(deployer).transferFrom(depoyer.address, user.address, 2){
hash: "..."
...
}> await L2DepositedERC721.connect(user).balanceOf(user.address)BigNumber { _hex: '0x01', _isBigNumber: true } // 1> await L2DepositedERC721.connect(user).ownerOf(2)'0x70997970C51812dc3A010C7d01b50e0d17dc79C8' // user

ERC721 提領(L2 => L1)

完成以上步驟後,目前的狀態如下:

0*PV0q8IUHrGgUXTee.png?q=20
optimistic-rollup-example-erc721-5e78e2c548b9

接下來,我們用 User 帳戶提領資金,在 L2DepositedERC721 合約呼叫 Withdraw

// In Hardhat Optimism Console> await L2DepositedERC721.connect(user).withdraw(2){
hash: "..."
...
}> await L2DepositedERC721.connect(user).balanceOf(user.address)BigNumber { _hex: '0x00', _isBigNumber: true }

最後,檢查在 L1 是否提領成功:

// In Hardhat ETH Console> await ERC721.connect(user).balanceOf(user.address)BigNumber { _hex: '0x01', _isBigNumber: true } // 1> await ERC721.connect(deployer).balanceOf(deployer.address)BigNumber { _hex: '0x01', _isBigNumber: true } // 1> await ERC721.connect(user).ownerOf(2)'0x70997970C51812dc3A010C7d01b50e0d17dc79C8' // user

由於挑戰期為 0 秒,因此提領幾乎無需等待時間,頂多只需數秒鐘

做完上述所有操作,最終狀態應該如下:

0*KnS23hhDGiF7WD55.png?q=20
optimistic-rollup-example-erc721-5e78e2c548b9

本文演示了:

  • Optimistic Rollup 相關服務的本機部署
  • ERC721 L1 => L2 的儲值(Deposit)
  • ERC721 L2 帳戶之間轉移(Transfer)
  • ERC721 L2 => L1 的提領(Withdraw)

筆者未來將繼續擴充此系列的教學內容,例如支援其他標準的合約如 ERC1155,以及如何運行 Optimistic Rollup 生態系中最重要的驗證者(Verifier),敬請期待。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK