是否曾因為想買某個幣安未上架的 ERC-20 代幣,必須去註冊其他交易所帳戶而覺得麻煩?註冊後還需要先把錢儲值到交易所帳戶內,會不會擔心不安全?而且,成功買到幣之後可能還需要通過 KYC 才能提幣!這些問題,透過 0x Instant 就能解決,還能用來購買 ERC-721 的 NFTs!
這篇文章會有以下幾個重點:
- 介紹 0x Instant
- 實作
- 深入瞭解 0x 在背後做了哪些事
- 販售自己的 Token
- 瀏覽幾項進階參數
介紹
0x 團隊在 2018 年底發行了 0x Instant(以下簡稱 Instant ),其目的在於降低開發 代幣購買 功能的門檻與時間,開發者只需要撰寫極少量的程式碼,就能將這項功能加入自己的 app 或網站中。
Instant 除了解決複雜的交易串接之外,還提供了簡易的 UI 給開發者使用。
Instant 提供的簡易UI / 圖片來源
然而,Instant 目前只允許使用 ETH 購買 ERC-20 和 ERC-721,無法用 Token 換回 ETH ,也暫不支援以 ERC-20 買 ERC-20 。
實作
在實作自己的 Instant 前,你可能會希望能先使用別人已經寫好的 Instant App 來玩玩看。因此,我在 Kovan 測試鏈上發行了 RobinToken(ROB),放進 Instant 販售(大家不用擔心,在 Kovan 上可以領免費 ETH,不需要花真錢),有興趣的人請連結到 Buy RobinToken Demo。
為了方便教學與實作,我們將使用線上開發工具 CodePen 來編輯程式碼,並且能立即查看執行結果。下方嵌入在文章中的 CodePen 僅能展示成果,若覺得視窗太小,或是想自己動手做做看,可以點擊此 CodePen連結 以完整視窗檢視和編輯(或點擊 Run Pen 後,再點擊右上角的 Edit On CodePen 即可)。
此次的 CodePen,我們只需要看 JS 的部分就好。
在這個簡易的 app 中,其實只需要提供 orderSource
這個參數,就已經能提供最基本的功能了。
orderSource
參數的意思是:能被購買的交易來源。也就是使用者在點擊購買後, Instant 會自動幫你尋找賣單搓合的地方。範例裡傳入的值是一個去中心化交易所的 API ,然而這個交易所API 必須實作 0x protocol 的 order 格式,才能讓 Instant 讀到 orderbook 資料並且最終進行搓合。
除了傳入交易所API,使用交易所上架的幣和賣單,開發者也能自行提供賣單(signedOrder)給 Instant ,這些自行提供的賣單就可以包含自己發行的 ERC-20 或 ERC-721 Token!但這部分較為複雜,將留到 “販售自己的 Token” 再來介紹。
而為了進行測試,我們不會希望要在主網上花真的 ETH 來購買,因此還會加上另一個參數: networkId
,用來告訴 Instant 我們要連結的是主網或是其他測試鏈。幾個較常使用的值為 1 = 主網
、 3 = Ropsten
、4 = Rinkeby
、42 = Kovan
,其餘有興趣可以連到 這篇回覆 看。
還要注意的一點是,有些 交易所API 會依照連結到的網路的不同(主網、測試鏈),而作些微的調整,以方便區分。因此,修改了 networkId
,也可能會需要修改 orderSource
才能正常運作。下面列出幾個 pair 給大家,有些交易所在測試鏈上可能沒有持續維護或更新 orderbook,練習時若發現想買的幣數量不足,可以切換其他幣種或是交易所再試試(更多資訊請參考這裡):
//####################################################
// {Radar Relay交易所} // 主網 orderSource: 'https://api.radarrelay.com/0x/v2/', networkId: 1
// Kovan測試鏈 orderSource: 'https://api.kovan.radarrelay.com/0x/v2/', networkId: 42
//####################################################
// {OpenRelay交易所} // 主網 orderSource: 'https://api.openrelay.xyz/v2/', networkId: 1
// Ropsten測試鏈 orderSource: 'https://api.openrelay.xyz/v2/', networkId: 3
// Kovan測試鏈 orderSource: 'https://api.openrelay.xyz/v2/', networkId: 42
//####################################################
在 JS 區塊改完這兩個參數後,點擊上方的 Run 按鈕,Result 區塊就能看到 Instant 幫你做出來的購買頁面了!
若你的 Metamask 連結到的網路,與 Instant 連結的不同,Result 頁面上方會提示你:
? Wrong network detected. Try switching to XXX.
此時只要將 Metamask 和 Instant 的設定調成一致就行,不論是切換 Metamask 的網路,或是更改 Instant 的參數都可以。
接下來,就可以用我們的 app 來實際購買 Token 了!
- 點擊 Select Token ,在彈出列表中選擇你想購買的 Token(這個列表上能選擇的 Token 就是
orderSource
所能提供的 Token 種類,給orderSource
傳入不同的值可能會有不同的結果) - 填入數量並按下 Buy XXX
- 這時候 Metamask 會彈出視窗請你確認交易,點擊 Confirm , Instant 就會幫你搓合並執行交易
- 等待交易的區塊確認
- 若交易成功, Instant 的頁面右上方會顯示 勾勾 表示交易成功,我們可以點擊 View Transaction 在 Etherscan 上查看此次交易的詳細資訊
到此為止,恭喜你已經成功做出自己的第一個 Instant App 並完成交易了!
Behind the scenes…
交易完成後,點擊 View Transaction 會連結到 Etherscan,可以查看交易的詳細資訊。現在,我們來看的更深一點, 0x 到底在背後幫我們做了什麼事?
- 從使用者錢包轉出 ETH
- ETH 轉進 0x-Forwarder合約(0x-Forwarder 是用來幫使用者處理 ETH 和 WETH 之間的轉換,以購買 Token。因為要使用 0x protocol 必須遵守其規範,也就是必須使用 ERC-20 或 ERC-721 的 Token(未來可能會支援更多標準),但 ETH 是以太坊的原生代幣,並不符合 ERC-20,因此必須先轉換成 WETH 才能使用,而 WETH 其實也就只是 ERC-20 版的 ETH ,兌換比率恆定 1:1 )
- 0x-Forwarder合約 將 ETH 換成 WETH
- 0x-Forwarder合約 向賣家(賣單)索取 Token
- 並支付 WETH 給賣家(賣單)(因此賣家最終收到的是 WETH ,在 Etherscan 會顯示在 Token 欄位,須自行去 0x Portal 或 Radar Relay 才能兌換回 ETH )
- 0x-Forwarder合約 將 Token 轉交給使用者
這筆交易只用了最基本的功能,若我們在 Instant App 中實作了抽佣的功能,抑或是
orderSource
的交易所有抽成,交易中的 Token 轉移將更複雜!至於要如何加入抽佣的功能,將在後面的進階參數提到。
販售自己的 Token
在介紹進階參數前,先進一步介紹前面提到的必填參數 orderSource
,除了可以傳入交易所API,開發者也能自行傳入賣單(signedOrder),以販售自己擁有的 Token(包括自己發行的 Token)。
開發者發行了自己的 Token 之後,只要使用 0x 產生 signedOrder 並放進 Instant ,即可提供使用者購買。
我認為這是 Instant 最重要的功能,有以下幾個原因:
- 不用等待交易所審核上架
- 使用者不需要註冊交易所帳號
- 使用者不需要自行輸入合約地址
- 支援 ERC-721
- 提供了簡易 UI ,並且可以自行客製化
- 可以嵌入至自己的網站中
而 signedOrder 顧名思義就是 被簽名的訂單,在這邊是由 maker 送出 Token 賣單的交易,並用 private key 簽名以證明交易的真實性。signedOrder 的 Interface 如下:
{ exchangeAddress: string, //0x的exchange合約地址 expirationTimeSeconds: BigNumber, //order過期時間(UNIX時間) feeRecipientAddress: string, //手續費接收的錢包地址 makerAddress: string, makerAssetAmount: BigNumber, makerAssetData: string, //賣單Token的assetData(後面會介紹) makerFee: BigNumber, salt: BigNumber, //隨機數,用以確保orderHash的唯一性 senderAddress: string, signature: string, takerAddress: string, takerAssetAmount: BigNumber, takerAssetData: string, //買單Token的assetData(後面會介紹) takerFee: BigNumber, }
至於如何填入 Token 資訊並產生 signedOrder ,可以參考新手範例程式碼中的幾個 scenario ,或是官方的 Create, Validate, Fill Order 完整教學。因篇幅因素,在此就不贅述了。
進階參數
provider
:連結到 Ethereum 的方式。如果沒有提供值給此參數, Instant 會嘗試尋找執行環境中是否已經有被嵌入的 provider ,若還是沒有,則會要求使用者安裝 Metamask 才能使用。defaultSelectedAssetData
:預設選取的 Token 種類。defaultAssetBuyAmount
:預設填入的購買數量。availableAssetDatas
:指定透過 Instant 所能購買的 Token 種類,預設是orderSource
提供的所有 Token。參數接收一個陣列,陣列內的值是符合 0x 定義的一段 unique 識別碼(assetData)。如果你要使用的 Token 是 Instant 原本就支援的,可以直接抓列表上的值。 assetData 是由 代幣的 Transfer Proxy Id + 合約地址 + Token Id(ERC-721才需要提供)所組成。以 ERC-20 的合約為例,ERC-20 的Transfer Proxy Id = 0xf47261b0
,合約地址address = 0x1dc4c1cefef38a777b15aa20260a54e584b16c48
,產生出的結果則為assetData = 0xf47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48
。為了方便, Instant 目前有提供一個 method 來取得 ERC-20 的 assetData 值,透過呼叫zeroExInstant.assetDataForERC20TokenAddress('contractAddress')
即可。additionalAssetMetaDataMap
:額外新增其他種類的 Token,因為你的 Token 可能不在 Instant 預設支援的名單中。需要傳入的參數包括 Token 的 assetData、使用的 Transfer Proxy Id、代幣名稱和縮寫等等。詳細資訊可以參考 Instant FAQs 內的 “What is assetMetaData?” 章節。affiliateInfo
:抽佣的比例以及佣金存入的錢包地址。每個實作 Instant 的 App 都可以自行決定是否要抽佣,最高可以抽到 5%!部署後的每筆交易, Instant 會自動從使用者支付的 ETH 中抽取對應比例,並直接存入指定的錢包地址。
由 Instant 的推出,可以看到 0x 團隊對於推動去中心化交易的努力,在熊市中仍然不遺餘力的開發,不斷幫助使用者降低開發門檻,使用其產品也不要求一定要支付手續費,這樣的方式更能吸引到開發者。2019,就讓我們看看 0x 還會以哪些方式繼續改變世界!