本系列文將分享如何使用 Python 的 Brownie 框架開發 ERC-721,也就是 NFT。並且 deploy contract 到 Ethereum 的測試網路 Rinkeby,圖檔和 Metadata 則上傳到 IPFS,再透過測試版本的 Opensea 來看看成果!
在上一篇 自己寫 NFT 吧!- 準備 Metadata – 以 Python Brownie 開發 我們已經準備好 Metadata,接下來要實際 deploy smart contract 到 testnet,並透過測試版本的 Opensea 來檢查是否有問題。
取得測試用的 Ether
我們選用 Ethereum 的 testnet Rinkeby 來做測試,先乞討幾個 ether 來用用,這邊列出幾個可以要 ether 的 faucet
他乞討法比較麻煩
1. 必須將你的錢包位置用 twitter 或 FB 發文,權限設置公開
2. 將該篇貼文的網址貼到 Faucet 輸入匡中
3. 選擇你想要乞討的數量,數量越多,下次能再乞討的時間間隔就越長
4. 等待 transaction 一段時間,就會發現錢包 eth 數量上升
優點:可以一次要很多 eth,在 testnet 成富人
缺點:服務好像不太穩定,最近常常 offline
另一個是使用 Chainlink 提供的 Faucet
Chainlink Request testnet LINK
他的方法很簡單
1. 連結你的錢包
2. 驗證不是機器人後,直接點要 eth 即可
優點:要 eth 非常簡單迅速,還可以順便要 LINK token
缺點:一次只能要 0.1 eth
將私鑰匯入 Brownie
要在 Rinkeby testnet 上 deploy smart contract,必須先將 account 的私鑰匯入 Brownie,才能正確簽署 transaction。
為了安全,極度不建議把私鑰寫在 brownie-config.yaml 或者是用環境變數儲存。除非該 account 只用在 testnet 上,沒有真實資產。一旦私鑰被盜走,等同把 account 交到駭客手中,所有資產都受人擺佈囉!
在 console 輸入以下指令,id 替換成你為這個 account 取的代稱
$ brownie accounts new <id>
enter 後 Brownie 會請你輸入 account 的私鑰
Brownie v1.17.2 - Python development framework for Ethereum
Enter the private key you wish to add:
接下來一定要設定密碼保護
Enter the password to encrypt this account with:
如此 accounts 就順利匯入了
申請 Infura 帳號並開通 api
我們需要透過節點與區塊鏈溝通,在 local 時使用 Ganache 架設開發用的節點,到 testnet 除了可以自己跑 Ethereum 節點,也可以直接使用第三方暴露的節點 api ,省去自架節點的麻煩。
透過指令 brownie networks list
可以看到 Brownie 已經幫開發者預設很多 用 Infura 做節點的 network,我們只需要申請帳號,取得 Project ID 並設定就能直接使用囉!
前往 Infura 申請帳號,點選 Create Project,Product 選擇 Ethereum,填入 Project Name 後點擊 create
複製畫面中的 Project ID
在專案根目錄下的 .env
檔增加一個變數 WEB3_INFURA_PROJECT_ID
,並設定剛剛複製的 Project ID 即可完成
WEB3_INFURA_PROJECT_ID=<your_project_id>
Deploy ECR-721 Contract 囉!
deploy 的方法我們在 自己寫 NFT 吧!- Deploy 到 Ganache – 以 Python Brownie 開發 有做過介紹,但這次要 deploy 到 testnet,不像 local 一樣有 10 個預設 accounts,我們需要使用剛剛匯入的 account,因此要做一些修改。
假設我們剛剛匯入的 account id 為 my-account
,在 brownie-config.yml
中新增 rinkeby network,並在下面加上 account: my-account
dotenv: .env
networks:
default: development
rinkeby:
account: my-account
開一個 utils.py
,新增一個 get_account
函數:
- 從
network.show_active()
中取得目前 network 的 name (如 rinkeby) - 如果 name 是 “`
development
,表是為 local 測試用的鏈,回傳第一個 account - 反之為 testnet 或 main-net,從 config 中取得對應 network 的 account 名稱(如 my-account)
from brownie import network, config, accounts
def get_account():
network_name = network.show_active()
if network_name == "development":
return accounts[0]
else:
return accounts.load(config["networks"][network_name]["account"])
回頭修改 deploy.py
中取用 account 的部分
from scripts.utils import get_account
def main():
# owner = accounts[0]
owner = get_account() # 改成使用 util function
kong_long = KongLongNFT.deploy({"from": owner})
...
一樣到 console 下 deploy,指定 network 為 rinkeby
$ brownie run script/deploy.py --network rinkeby
此時 Brownie 會提示你需要密碼,輸入剛剛匯入 account 所設定的
Running 'scripts/kong_long_nft.py::main'...
Enter password for "my-account":
enter 後,brownie 就會送出 transaction。因為是在非 local 的區塊鏈上操作,需要等待一段時間才能有結果,長短依照當時網路擁塞而定。
Mint NFT 囉!
接下來要 mint,稍微修改一下 mint.py
def main():
# owner = accounts[0]
owner = get_account() # 改成使用 util function
# receiver = accounts[1]
receiver = get_account() # receiver 位置改成自己方便測試
# nft = KongLongNFT.at('0x684f51E9A4Ec41DDaC067A9E03eECad3274F4FDd')
nft = KongLongNFT[-1] # 改成使用最後 deploy 的 contract,不 hard code contract address
# uri 記得改成你自己的 CID
nft.mintToken(receiver, "ipfs://QmXfFYmRnEGnWbnUfRsVMZz4pF9gY9wyJfkGUMsfnpndUH", {"from": owner})
...
到 console 下 mint
$ brownie run script/mint.py --network rinkeby
立馬到 testnet 版的 OpenSea 瞧瞧自己的 collection。如果還沒出現是正常的,實測 mint 後需要一段時間 OpenSea 才會抓到新的 NFT
如果像下面這樣,一直抓不到 NFT 的圖片和標題描述,可能是 Metadata 的格式或者 URI 出問題,參考 如何以 Python Brownie 開發 DeFi 應用?- 發個 NFT 吧!準備 Metadata 檢查一下吧!
到這整個 ERC-721 從環境準備、撰寫 smart contract、準備 metadata、發布到 testnet Rinkeby 的流程我們都一起走過一遍,相信大家對 blockchain development 也有初步的認識。想要發布到 main-net 上玩玩?其實方法一樣,但是 Ehtereum 太貴了!下次我們來看看如何使用側鏈 Polygon 來發布,節省你的 gas 費!
延伸閱讀:
如何以 Python Brownie 開發 DeFi 應用?- 環境準備
自己寫 NFT 吧!- 實現 ERC-721 – 以 Python Brownie 開發
自己寫 NFT 吧!- Deploy 到 Ganache – 以 Python Brownie 開發
自己寫 NFT 吧!- 準備 Metadata – 以 Python Brownie 開發