開源專案欣賞:Private Lossless Prediction Market (ETHGlobal Hackathon)

Paul (Tzu Chun) Yu
SWF Lab
Published in
6 min readAug 11, 2022

有鑒於想參加九月有一場黑客松,我想每幾天讀一個過去區塊鏈黑客松得獎作品的源碼累積一點實力。形式會以我的自問自答為主,會延伸解答我自己好奇的問題,不會一行一行解讀源碼。

專案是Compound Grants Supply Pool, Chainlink Pool Prize得獎作品。

Table of Content

  1. 專案主題
  2. 為什麼此專案需要Chainlink?
    2.5. Chainlink 還有什麼額外功能可以使用?
  3. 為什麼需要 OpenZeppelin?
    3.5. OpenZeppelin還可以怎麼使用?
  4. Event跟Return差別是什麼?
  5. interface沒有其他implementation嗎?
  6. 其他學習

專案主題及架構

兩人投錢入一池並做價格賭注,賭贏者可連同本金及輸家利息一同拿走。

架構圖

為什麼此專案需要 Chainlink ?

這裡需要的原因很簡單就是資產價格的取得,並且要是去中心化的。在這裡面使用主要是取得eth價格,然後可以透過addUint("until", block.timestamp + _timer)來設定delay

Chainlink 還有什麼額外功能可以使用?

  1. 可取得 Randomness 但要收費。可取得多個或一定範圍內隨機值。
  2. Any API,有其他 data 提供者可以提供鏈下資料 e.g.天氣、書評、運動資料。
  3. Keepers,自動依照情況執行 contract
  4. Doc 有提供 hackathon starter kits (Borwnie, Truffle, Hardhat)
  5. Doc 也有提供 77 種 Chainlink use cases 及過去得獎作品

為什麼需要 OpenZeppelin?

OpenZeppelin 要達到幾個目標(依照官網上寫)是:

  1. modular, reusable
  2. Upgradeable
  3. secure

這提供一個框架讓我們去減少很多坑,舉本專案例子使用到ownable來說,ownable 這個 contract 修飾詞在 OpenZeppelin 源碼裡面有一段是

function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}

上述程式碼減少一個確認環節,也就是確認Market contract的使用者是不是一開始擁有這個 contract 的人(也就是這個賭場的老闆)。

OpenZeppelin 還可以怎麼使用?

以下介紹的功能,我都寫成「官方文件裡面的類別: 具體功能」這個形式,以利讀者查找

  1. Utility: 跟cryptography有關的如 check signature, Merkle Proofs
    什麼時候可以派上用場?舉例,用戶用加密後資訊呼叫一函式 withdraw,這是meta transaction的概念,可以在此討論串看到更多資訊。
  2. Utility: safeMath 避免overflow/underflow
  3. Utility: split payment
  4. Utility: collection有關的如 EnumerableSet, EnumerableMap
  5. Utility: Multicall, multiple calls bundled in a single external call
  6. Access Control: ownable
  7. Crosschain: 跨鏈支援
  8. Governance: 鏈上治理
    Compound有GovernorAlpha, GovernorBravo contract,但有些小缺陷,OpenZeppelin的Governor contract對其做了改善。
  9. Token: 如 ERC20/721/1155/1363/1400

還有其他production stage比較需要考慮的:

  1. 寫自動測試
  2. contract升級

EventReturn 差別是什麼?

event NewDeal(uint dealId, address initiator, uint256 val, uint upOrDown, uint timer);

源碼中 newDeal 是一個 event,最終被 emit 到客戶端。我好奇 event 跟 return 差別是什麼,如果同樣都是讓客戶端取得一個物件。
此文中提到 event 是無法被其他 contract 監聽的; 另外一方面,一個 transaction 的回傳值是不會傳出solidity的,如此文所述

總結來說,event 是提供給例如 Javascript VM 或者是前端 listener 知道的,而 return 是提供給 contract 或區塊鏈知道的。event 有點像是 console.log 的感覺,可以用來 debug,例如我們在 remix 開發的時候在 log 就看不見 return 只能看見 emit event 的結果。

interface 沒有 implementation 嗎?

interface CEth {
function mint() external payable;
function exchangeRateCurrent() external returns (uint256);
function supplyRatePerBlock() external returns (uint256);
function redeem(uint) external returns (uint);
function redeemUnderlying(uint) external returns(uint);
function balanceOf(address) external view returns(uint256);
function balanceOfUnderlying(address) external returns(uint);

}

這篇文章有提到 interface 在 solidity 有個特別用法是initialized with contract address。因此supplyEthToCoumpound這函式內可以看到CEth cToken = CEth(_cEtherContract);
這個 contract address 可以從 Compound 官方教學取得。

其他學習

  1. 在每個function前都標注的很詳細
/*
@param
@dev
@returns
*/

2. 之後要試試看 OpenZeppelin 的框架來進行開發熟悉一下有哪些工具

Reference

https://showcase.ethglobal.com/ethonline2021/private-lossless-prediction-market

--

--

Paul (Tzu Chun) Yu
SWF Lab
Writer for

NTU CSIE, ECON; learning crypto and zero knowledge proof; I envision a hyperstructure; https://github.com/NOOMA-42