📜 [專欄新文章] Optimistic Rollup 就這樣用(2)
✍️ Juin Chiu
📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使用心得 #教學文 #medium
ERC721 的儲值、轉移與提領
TL;DR
本文會跳過 Optimistic Rollup 的介紹而直接實際演示,關於 Optimistic Rollup 的概念與設計原理筆者將在日後另撰文說明,有興趣的讀者可以先參考下列三篇文章(由淺入深):1. OVM Deep Dive 2. (Almost) Everything you need to know about Optimistic Rollup 3. How does Optimism’s Rollup really work?
本文將演示一個 Optimism Rollup 的 ERC721 範例,程式碼在這裡。
本演示大量參考了以下範例:Optimistic Rollup Example: ERC20。
本演示所使用的 ERC721 Gateway 合約來自這個提案,目前尚未成為官方標準。
環境設置
Git
Node.js
Yarn
Docker
Docker-compose
筆者沒有碰到環境相容問題,但是建議都升到最新版本, Node.js 使用 v16.1.0 或以上版本
Optimism 服務啟動
有關 Optimisim 的所有服務,都包裝在 Optimism 這個超大專案當中了,直接使用原始碼進行組建:
$ git clone git@github.com: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 git@github.com: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.jsDeploying L1 ERC721...L1 ERC2721 Contract Address: 0xFD471836031dc5108809D173A067e8486B9047A3Deploying L2 ERC721...L2 ERC721 Contract Address: 0x09635F643e140090A9A8Dcd712eD6285858ceBefDeploying L1 ERC721 Gateway...L1 ERC721 Gateway Contract Address: 0xcbEAF3BDe82155F56486Fb5a1072cb8baAf547ccInitializing L2 ERC721...
ERC721 鑄造、儲值、轉移與提領
鑄造(L1)
初始狀態如下,所有帳戶皆尚未持有任何代幣:
接下來,我們將鑄造 2 個代幣以進行接下來的演示。首先,進入 ETH(L1) 的 Console:
$ npx hardhat console --network ethWelcome 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]
取得 ERC721 及 OVM_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)
完成以上步驟後,目前的狀態如下:
接下來,授權 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 optimismWelcome 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)
完成以上步驟後,目前的狀態如下:
接下來,我們在 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)
完成以上步驟後,目前的狀態如下:
接下來,我們用 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 秒,因此提領幾乎無需等待時間,頂多只需數秒鐘
做完上述所有操作,最終狀態應該如下:
總結
本文演示了:
Optimistic Rollup 相關服務的本機部署
ERC721 L1 => L2 的儲值(Deposit)
ERC721 L2 帳戶之間轉移(Transfer)
ERC721 L2 => L1 的提領(Withdraw)
筆者未來將繼續擴充此系列的教學內容,例如支援其他標準的合約如 ERC1155,以及如何運行 Optimistic Rollup 生態系中最重要的驗證者(Verifier),敬請期待。
參考資料
OVM Deep Dive
(Almost) Everything you need to know about Optimistic Rollup
How does Optimism’s Rollup really work?
Optimistic Rollup Official Documentation
Ethers Documentation (v5)
Optimistic Rollup Example: ERC20(Github)
Optimism (Github)
optimism-tutorial (Github)
l1-l2-deposit-withdrawal (Github)
Proof-of-concept ERC721 Bridge Implementation (Github)
Optimistic Rollup 就這樣用(2) was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.
👏 歡迎轉載分享鼓掌
同時也有25部Youtube影片,追蹤數超過1萬的網紅translation,也在其Youtube影片中提到,#'90年にコンパイルが開発、ナムコが発売した、msx2版縦STG作品('88年)からのPCE移植版。 アーケードモードはオリジナルゼビウスを移植したものだが、ブラグスパリオに当たり判定が無い、アンドアジェネシスがコアからも弾を撃つ、ゾルバクを破壊する事で空中敵のレベル調整が可能等の変更点がある。フ...
compile c 在 BorntoDev Facebook 的最佳解答
🖥️ เมื่อเราเรียนเกี่ยวกับการเขียนโปรแกรมภาษา C นั้น สิ่งหนึ่งเลยที่ทุกคนจะถูกสอนกันมาว่า ใน main() นั้นเราต้องทำการ return 0 ทุกครั้งเหมือนกับว่าเป็น “กฎเหล็กของภาษา C” เลยก็ว่าได้ แล้วทุกคนสงสัยมั้ยว่า ทำไมต้องใส่ return 0 ทุกครั้ง ในวันนี้เรามีคำตอบมาแบ่งปันกัน มาดูกันเลย
.
👉 การ return 0 นั้น เป็นกฎที่เพิ่มเข้ามาในมาตรฐานภาษา C ในปี 1999 หรือ C99 นั่นเอง โดยระบุไว้ว่า ต้องทำการ return กลับเป็นตัวเลขเสมอ เนื่องจากก่อนที่จะเป็น C99 นั้น จะใช้รูปแบบ void main() (ปัจจุบันคือ int main()) ซึ่งเจ้า main() จะทำการส่งกลับค่า void กลับนั่นเอง
.
🤼♂️ แล้วในทีนี้มีการกำหนดมาตรฐานขึ้นมาใหม่ (C99) ให้ return int แทน ดั้งนั้นเพื่อเป็นหลักสากลว่า โปรแกรมนั้นทำงานได้ถูกต้องและเสร็จสิ้นโดยสมบูรณ์แล้วโดยไม่มี error จะให้ทำการ return 0 นั่นเอง และอีกอย่างหนึ่งคือเพื่อป้องกันไม่ให้ IDE compile มีปัญหา (ส่วนมากจะถูกสอนให้ใส่ return 0 ก็เพราะปัญหานี้เลย เพราะบาง IDE จะ compile ไม่ผ่านถ้าไม่ใส่ return 0)
.
🌈 ถ้าเราเคยสังเกตุเห็นตอนเราเขียนโปรแกรมแล้วมี error หรือปัญหาอะไรสักอย่าง ในหน้าต่าง Terminal จะมีการ return ด้วยเลขอื่น ๆ ด้วยที่ไม่ใช่เลข 0 (เช่น return 2542347)
.
📍 สรุปเลยก็คือ การที่เราใส่ return 0 นั้นเพื่อเป็นสัญลักษณ์ว่า โปรแกรมที่เราเขียนนั้นทำงานได้ถูกต้อง และไม่มี error ซึ่งเจ้าโปรแกรมจะ return ค่าออกมาหลังจากเรารันโปรแกรมของเรานั่นเอง
.
borntoDev - 🦖 สร้างการเรียนรู้ที่ดีสำหรับสายไอทีในทุกวัน
compile c 在 BorntoDev Facebook 的精選貼文
☕ CoffeeScript เป็นภาษาขนาดเล็กที่ Compile เป็น JavaScript สร้างขึ้นเมื่อปี 2009 เพื่อลบจุดด้อยของ JavaScript มี Syntax ที่ง่ายต่อการเรียนรู้มากกว่า JavaScript ช่วยให้เราเขียน JavaScript สั้นลง ดูแลได้ง่ายนั่นเอง !!
.
👨💻 การใช้งานเบื้องต้น
ก่อนอื่นจำเป็นต้องมี Node.js และ NPM ก่อนนะ และเริ่มต้นเขียนคำสั่งตามด้านล่างเลยจ้า
.
คำสั่ง
# Install locally for a project:
npm install --save-dev coffeescript
.
# Install globally to execute .coffee files anywhere:
npm install --global coffeescript
.
จากนั้นทำการเปิดใช้งาน CoffeeScript Library
coffee -c filename.coffee
.
ทดลองพิมพ์คำสั่ง
.
console.log "Hello world"
.
จะเห็นได้ว่า CoffeeScript มันไม่ต้องใส่วงเล็บ ก็สามารถรันโค้ดได้
.
🔎 มาดูข้อดีของ CoffeeScript กันดีกว่า
.
⭐ เข้าใจง่าย - เพราะ Syntax ของเจ้า CoffeeScript จะเน้นเขียนง่าย ทำให้จัดเรียงโค้ดได้สะอาดตา และทำให้เราเข้าใจได้ง่าย
.
⭐ ไม่ต้องใช้ var - ไม่ต้องประกาศ var ก่อนตัวแปร มันจะช่วยหลีกเลี่ยงปัญหาขอบเขตของตัวแปรได้
.
⭐ หมดปัญหาเรื่องลืม Symbol - เพราะ CoffeeScript ไม่ต้องใส่ Symbol เช่น () หรือ ; ต่อท้ายเลย ซึ่งเราจะใช้การเว้นวรรคแบ่งการทำงานของแต่ละฟังก์ชันแทน คล้ายๆ กับใน Python นั่นแหละ
.
⭐ Less Code - บรรทัดของโค้ดจะลดน้อยลง ซึ่งมันจะช่วยลดความซับซ้อนของโปรแกรมนั่นเอง
.
⭐ ดูแลง่าย - การที่มันเขียนง่าย เข้าใจง่าย มันจึงทำให้เราสามารถแก้ไขโค้ดได้ง่ายนั่นเอง
.
🌈 ทำไมถึงได้รับความนิยมน้อยลง ??
.
ด้วยการเกิดของ ES6 ในปี 2015 ซึ่งทำให้ลบจุดด้อยของ JavaScript ไปได้เยอะ และยังเพิ่มประสิทธิภาพของ JavaScript ไปได้อีกด้วย แถมยังมี Community ที่ใหญ่มากขึ้นด้วย อีกทั้ง TypeScript ก็ถูกพัฒนาเป็นภาษามาตรฐาน และมีประสิทธิภาพด้วยเช่นกัน ทำให้เจ้าใหญ่ๆ เช่น Angular ใช้ TypeScript ในการพัฒนาเป็นหลัก จนทำให้ทุกวันนี้ CoffeeScript ลดความนิยมไปอย่างมากนั่นเอง
.
borntoDev - 🦖 สร้างการเรียนรู้ที่ดีสำหรับสายไอทีในทุกวัน
compile c 在 translation Youtube 的最佳貼文
#'90年にコンパイルが開発、ナムコが発売した、msx2版縦STG作品('88年)からのPCE移植版。
アーケードモードはオリジナルゼビウスを移植したものだが、ブラグスパリオに当たり判定が無い、アンドアジェネシスがコアからも弾を撃つ、ゾルバクを破壊する事で空中敵のレベル調整が可能等の変更点がある。ファードラウトモードは遠藤氏著のファードラウトサーガに基づく作りで4つの時代のステージ構成だがオリジナルのmsx2番とは内容が異なる。
BGMはコンパイルスタッフが作・編曲、オリジナルBGMを中心に多くの追加曲が加えられた。
サウンドディレクター:宮本昌知氏
効果音:塚本雅信氏、迫田敏明氏
ドライバ作成:広野隆行氏
作・編曲・宮本昌知氏,塚本雅信氏,迫田敏明氏
Manufacturer: 1990.06.29 namco / compile
computer: PC Engine / TurboGrafx-16
Hardware: HuC6280
Sound effect: Masanobu Tsukamoto,Toshiaki Sakoda
Music driver programmer: Takayuki Hirono
Sound director: Masatomo Miyamoto
Composer&Arranger: Masatomo Miyamoto,Masanobu Tsukamoto,Toshiaki Sakoda
----------------------------------------------------------------------------------------
00:00 01.Game Start [Arcade Mode] (ゲームスタート *「Start」ゼビウス (AC)/アーケードモード)
00:09 02.main [Arcade Mode] (メインBGM *「main bgm」ゼビウス (AC)/アーケードモード)
00:32 03.BGM 1 [Arcade Mode] (BGM 1/アーケードモード)
01:54 04.BGM 2 [Arcade Mode] (BGM 2/アーケードモード)
02:37 05.BGM 3 [Arcade Mode] (BGM 3/アーケードモード)
04:01 06.BGM 4 [Arcade Mode] (BGM 4/アーケードモード)
04:56 07.BGM 5 [Arcade Mode] (BGM 5/アーケードモード)
06:27 08.Extended [Arcade Mode] (1UP *「extend」ザナック(msx)/アーケードモード)
06:31 09.Game Over [Arcade Mode] (ゲームオーバー *「game over」ドルアーガの塔(AC)/アーケードモード)
06:38 10.Name Entry [Arcade Mode] (1st). (ネームエントリー1位 *「name entry 1st」ゼビウス(AC)/アーケードモード)
08:01 11.Name Entry [Arcade Mode] (2nd to 5th) (ネームエントリー2位~5位 *「name entry 2nd to 5th」ゼビウス(AC)/アーケードモード)
09:28 12.Game Start [Fardraut Mode] (ゲームスタート *「Start」ゼビウス (AC)/ファードラウトモード)
09:37 13.BGM 1 [Version A] [Fardraut Mode] (BGM 1 [Version A]/ファードラウトモード)
10:20 14.BGM 1 [Version B] [Fardraut Mode] (BGM 1 [Version B]/ファードラウトモード)
13:56 15.BGM 1 [Version C] [Fardraut Mode] (BGM 1 [Version C]/ファードラウトモード)
14:50 16.BGM 1 [Fardraut Mode] (BGM 1/ファードラウトモード)
16:33 17.BGM 2 [Fardraut Mode] (BGM 2/ファードラウトモード)
17:16 18.BGM 3 [Fardraut Mode] (BGM 3/ファードラウトモード)
18:09 19.BGM 4 [Fardraut Mode] (BGM 4/ファードラウトモード)
19:04 20.BGM 5 [Fardraut Mode] (BGM 5/ファードラウトモード)
19:52 21.Extended [Fardraut Mode] (1UP *「extend」ザナック(msx)/ファードラウトモード)
19:57 22.Game Over [Fardraut Mode] (ゲームオーバー *「game over」ドルアーガの塔(AC)/ファードラウトモード)
20:03 23.Name Entry (1st) [Fardraut Mode] (ネームエントリー1位/ *「name entry 1st」ゼビウス(AC)/ファードラウトモード)
20:45 24.Name Entry (2nd to 5th) [Fardraut Mode] (ネームエントリー2位~5位 *「name entry 2nd to 5th」ゼビウス(AC)/ファードラウトモード)
21:30 25.Ending [Fardraut Mode] (エンディング/ファードラウトモード)
---------------------------------------------------------------------------------------
compile c 在 真電玩宅速配 Youtube 的最讚貼文
《極限凸記 萌萌編年史》是款3D迷宮角色扮演遊戲,遊戲中以人類和怪物女孩共存的奇幻世界為背景,玩家所扮演的主角將與怪物女孩展開冒險,且找出為何與人類為敵的原因,遊戲中更強調帶給玩家臉紅心跳的遊玩體驗。
這次的Switch版《極限凸記 萌萌編年史 H》,一樣要與擬人化的魔物美少女們一起冒險,遊戲更繼承了前作的「摩擦」系統,透過Switch所對應的HD震動,讓玩家在觸碰時會更有臨場感。
除此之外遊戲也將完全的以HD高畫質重現,不僅這樣的雙重H加持,遊戲中還加入了能更快速養成魔物娘的道具和「自動導航」模式,讓玩家在迷宮中探險時不會迷路。
獨家於亞洲發行的繁體中文版實體片,預定於2019年春季發行,有興趣和魔物美少女同樂的玩家可以預購一波囉。
(C)IDEA FACTORY / COMPILE HEART
「電玩宅速配」粉絲團:https://www.facebook.com/tvgamexpress
「美女愛玩Game」節目:http://bit.ly/1Qwt7S3
休閒平台:http://myfun.gamedb.com.tw
遊戲庫粉絲團:http://www.facebook.com/Gamedbfans
compile c 在 電撃オンライン Youtube 的最讚貼文
コンパイルハートが贈るネプテューヌ最新作『勇者ネプテューヌ 世界よ宇宙よ括目せよ!! アルティメットRPG宣言!!』が2018年12月20日に発売。
その注目作にさまざまなグッズを付けた電撃スペシャルパックが発売されます。この動画は、そのなかの特典の1つ「勇者ネプテューヌ カードゲーム ~女神のシェアを取り戻せ!~」のゲームのルールをわかりやすく解説した動画で、このゲームの作者であるカナイセイジさんが自ら説明しています。
(C)2018 IDEA FACTORY / COMPILE HEART / Artisan Studios
compile c 在 逐步解說:在命令列編譯C 程式 - Microsoft Docs 的相關結果
C :\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise>cl Microsoft (R) C/C++ Optimizing Compiler Version 19.10.25017 for x86 Copyright ... ... <看更多>
compile c 在 Online C Compiler - online editor 的相關結果
OnlineGDB is online IDE with c compiler. Quick and easy way to compile c program online. It supports gcc compiler for c. ... <看更多>
compile c 在 使用gcc 編譯程式 的相關結果
在C:\test 資料夾底下新增一個文字檔hello.c,並且輸入以下程式碼: ... 如果要MSYS2 的Shell 內要切換到C槽,在MSYS2內的對應目錄為 /c. 所以切換到 C:\test 底下則 ... ... <看更多>