# Day2. 使用 javascript 建構 DAO **Published by:** [Samumu.eth](https://paragraph.com/@samumu/) **Published on:** 2022-02-26 **URL:** https://paragraph.com/@samumu/day2-javascript-dao ## Content 經過上一篇教程,我們現在可以連接到使用者的錢包,這意味著我們現在可以驗證該用戶是否在我們的DAO中。為了加入我們的DAO,使用者將需要一個會員資格NFT,如果他們沒有會員資格NFT,我們會提示他們是否鑄造會員NFT並加入我們的DAO(你也可以自己設計一個比較好的機制,比如常見的白單限制) 要完成以上的需求,我們需要編寫+部署我們自己的NFT智能合約,在這邊我們使用ThirdWeb給我們提供的是一套工具,可以在不編寫任何Solidity的情況下創建我們所有的智能合約(不過使用這種方式會有諸多局限性,如果你對於Solidity很熟悉,之後也可以嘗試自己編寫並部署) 不過我們這系列的都不會使用到Solidity編碼,ThirdWeb提供了一組安全的合同標準,並且在部署之後你也可以使用其用戶端 SDK 輕鬆地從前端與這些合約進行交互 介紹完我們接下來要使用的強力工具,我們可以開嚕了創建 ThirdWeb 專案到此網站創建專案連接含有 Rinkeby ETH 的 Metamask address(部署合約時會需要耗費gas fee)連接到 Rinkeby 網路點擊右上 Create Project(這將為我們將在鏈上部署的合約創建容器,thirdweb不會有中心化資料庫,你的所有數據都存儲在鏈上) 獲取 Alchemy API到Alchemy官網申請帳號,並點擊 +CREATE APP 來創建,NETWORK部分一定要選擇到Rinkeby,創建完成後,點擊 VIEW KEY 可以看到你的 API KEY , HTTP , WEBSOCKETS.ENV存儲私鑰現在,我們需要實際編寫一些腳本,讓我們使用thirdweb創建/部署我們的合約到Rinkeby。首先,我們要做的第一件事是在專案的根目錄中創建一個.env 檔PRIVATE_KEY=YOUR_PRIVATE_KEY_HERE WALLET_ADDRESS=YOUR_WALLET_ADDRESS ALCHEMY_API_URL=YOUR_ALCHEMY_API_URL thirdweb需要所有這些東西來代表你部署合同,它們不存儲任何內容,所有內容都保留在本地的檔中。謹記不要將 .env 檔提交到 Github,你的錢包會被搶劫的,小心!!!從Metamask獲取所需資訊點擊【Account details】,再點擊【Export Private Key】,輸入密碼後便可取得 PRIVATE_KEY 點擊Account下方 0x... 後方的複製icon即可取得 WALLET_ADDRESS從Alchemy獲取 ALCHEMY_API_URL初始化軟體開發工具組 前往 .scripts/1-initialize-sdk.jsimport { ThirdwebSDK } from "@3rdweb/sdk"; import ethers from "ethers"; import dotenv from "dotenv"; dotenv.config(); if (!process.env.PRIVATE_KEY || process.env.PRIVATE_KEY == "") { console.log("🛑 Private key not found.") } if (!process.env.ALCHEMY_API_URL || process.env.ALCHEMY_API_URL == "") { console.log("🛑 Alchemy API URL not found.") } if (!process.env.WALLET_ADDRESS || process.env.WALLET_ADDRESS == "") { console.log("🛑 Wallet Address not found.") } const sdk = new ThirdwebSDK( new ethers.Wallet( process.env.PRIVATE_KEY, ethers.getDefaultProvider(process.env.ALCHEMY_API_URL), ), ); (async () => { try { const apps = await sdk.getApps(); console.log("Your app address is:", apps[0].address); } catch (err) { console.error("Failed to get apps from the sdk", err); process.exit(1); } })() export default sdk; 我們這邊所做的是初始化thirdweb,然後添加一個third web SDK,因為我們將在其他腳本中重用初始化的sdk。在初始化的過程中我們必須提供 PRIVATE_KEY以及使用 ALCHEMY_API_URL 創建的 prvider 在執行該腳本之前,請確保您安裝了Node 16 +,您可以使用以下命令檢查您的版本:node -v 如果您有舊版本的 Node,可以在此處進行更新。(下載 LTS 版本) 接下來,讓我們來執行這個腳本,移至終端並貼下以下命令:node scripts/1-initialize-sdk.js 以下是運行完腳本時獲得的內容buildspace-dao-starter % node scripts/1-initialize-sdk.js 👋 Your app address is: 0xa002D595189bF9D50D5897C64b6e07BE5bdEe9b8 💡 *注意:您可能還會看到一些隨機警告,例如*`ExperimentalWarning`,只需確保您的應用程式位址已列印出來即可! 接著將這段地址加入 .env 檔,你目前的 .env 檔內應該如下:PRIVATE_KEY=<YOUR_PRIVATE_KEY_HERE> ALCHEMY_API_URL=<YOUR_ALCHEMY_API_URL> WALLET_ADDRESS=<YOUR_WALLET_ADDRESS> APP_MODULE_ADDRESS=0xa002D595189bF9D50D5897C64b6e07BE5bdEe9b8 創建 ERC1155 集合我們現在要做的是創建+部署ERC1155合約到Rinkeby,這是我們創建NFT所需的基本模組。這邊我們要先為NFT設置元數據**。**這是諸如集合的名稱(例如CryptoPunks)以及與集合關聯的圖像之類的東西,該圖像在OpenSea上顯示為標題。 💡 您可能知道ERC-721,其中每個NFT都是唯一的,即使它們具有相同的圖像,名稱和屬性。使用ERC-1155,多個人可以成為同一NFT的持有者。在這種情況下,我們的"會員NFT"對每個人都是一樣的,因此,與其每次都製作一個新的NFT,我們可以簡單地將相同的NFT分配給所有會員。 移至並新增以下代碼:scripts/2-deploy-drop.jsimport { ethers } from "ethers"; import sdk from "./1-initialize-sdk.js"; import { readFileSync } from "fs"; import dotenv from "dotenv"; dotenv.config(); const app = sdk.getAppModule(process.env.APP_MODULE_ADDRESS); (async () => { try { const bundleDropModule = await app.deployBundleDropModule({ name: "DevDAO", description: "A DAO for devloper", image: readFileSync("scripts/assets/dev.png"), primarySaleRecipientAddress: ethers.constants.AddressZero, }); console.log( "✅ Successfully deployed bundleDrop module, address:", bundleDropModule.address, ); console.log( "✅ bundleDrop metadata:", await bundleDropModule.getMetadata(), ); } catch (error) { console.log("failed to deploy bundleDrop module", error); } })() 我們給集合一個name、description、 primarySaleRecipientAddress 和 imagename: DAO 的名稱,請自己隨意命名description: 簡單描述這個 DAOimage: 我們會從本地檔載入,因此請確保將該圖像包含在下scripts/assets ,並確保圖片格式是PNG,JPG或GIFprimarySaleRecipientAddress: 傳入一個地址,這個地址是用來接收NFT賣出的$,這邊我們將其設定為 ‘0x0’ 也就是 ethers.constants.AddressZero 是為了不向使用者收費,你也可以將地址改為自己的地址來收費運行此腳本後會看到如下輸出:node scripts/2-deploy-drop.js buildspace-dao-starter % node scripts/2-deploy-drop.js 👋 Your app address is: 0xa002D595189bF9D50D5897C64b6e07BE5bdEe9b8 ✅ Successfully deployed bundleDrop module, address: 0x31c70F45060AE0870624Dd9D79A1d8dafC095A5d ✅ bundleDrop metadata: { metadata: { name: 'NarutoDAO Membership', description: 'A DAO for fans of Naruto.', image: 'https://cloudflare-ipfs.com/ipfs/bafybeicuuhilocc2tskhnvbwjqarsc5k7flfqdr4ifvwxct32vzjmb3sam', primary_sale_recipient_address: '0x0000000000000000000000000000000000000000', uri: 'ipfs://bafkreieti3mpdd3pytt3v6vxbc3rki2ja6qpbblfznmup2tnw5mghrihnu' }, address: '0x31c70F45060AE0870624Dd9D79A1d8dafC095A5d', type: 11 } 首先,我們剛剛向Rinkeby部署了ERC-1155合同,如果你到etherscan並查詢 bundleDrop 的地址(第一行的地址),會發現你成功剛剛部署了一個智能合約! 把這串地址添加到 .env 檔PRIVATE_KEY=<YOUR_PRIVATE_KEY_HERE> ALCHEMY_API_URL=<YOUR_ALCHEMY_API_URL> WALLET_ADDRESS=<YOUR_WALLET_ADDRESS> APP_MODULE_ADDRESS=0xa002D595189bF9D50D5897C64b6e07BE5bdEe9b8 BUNDLEDROP_MODULE_ADDRESS=0xa002D595189bF9D50D5897C64b6e07BE5bdEe9b8 可以在此處查看thirdweb使用的實際智慧合約代碼 另外,我們可以通過CloudFlare從IPFS檢索NFT的圖像 您甚至可以使用URI直接點擊IPFS(注意 - 由於您需要運行IPFS節點,因此在Chrome上不起作用,但可以在Brave上工作,它可以為您做到這一點 💡 IPFS基本上是一個分散的存儲系統,[請在此處閱讀更多內容](https://docs.ipfs.io/concepts/what-is-ipfs/)! 如果您之前在Solidity中開發了一個自定義智慧合約,也了解其開發過程,相對來說,使用thirdWeb 讓整個流程變得更簡單,目前,我們已經有一個合約部署到IPFS上託管的Rinkeby +數據,恭喜你 接下來,我們需要實際創建我們的NFT Day3. 使用 javascript 建構 DAO ## Publication Information - [Samumu.eth](https://paragraph.com/@samumu/): Publication homepage - [All Posts](https://paragraph.com/@samumu/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@samumu): Subscribe to updates - [Twitter](https://twitter.com/SamumuClan): Follow on Twitter