本文將詳細介紹Web3DApp開發的架構、技術,以及使用哪些工具,并給出完整示例。我們先介紹Web3用到的技術:區塊鏈,以以太坊為主流,也包括Solana、Aptos等其他非EVM鏈。區塊鏈本身是軟件,需要運行在一系列節點上,這些節點組成P2P網絡或者半中心化網絡。節點不僅負責接收新的輸入并生成新的區塊,還需要存儲區塊鏈運行時產生的所有數據,并負責同步、對外提供查詢等RPC服務。錢包:幫助用戶管理自己在區塊鏈上資產的軟件,加密存儲用戶的私鑰。當用戶需要和區塊鏈交互時,就需要用到私鑰簽名;智能合約:運行在區塊鏈上的一段托管程序,主要用來和外部賬戶交互;UI:這里特指前端頁面,因為直接通過RPC調用合約僅限個別高級用戶,普通用戶仍需要一個前端頁面,并通過JavaScript腳本配合錢包簽名與合約交互。因為區塊鏈上所有數據全透明,要查詢任意區塊的數據,可以通過EtherScan這個網站查。其他公鏈,無論是與Ethereum兼容的BSC、Polygon,還是不兼容的Solana、Aptos等,也提供類似XxxScan這樣的查詢網站。這些Scan能提供基本的讀寫合約的能力,有助于開發階段的測試。區塊鏈本身以及錢包、EtherScan等屬于基礎設施,如何基礎設施不在本文討論范圍之內。本文僅限定如何開發DApp。一個完整的DApp需要開發以下部分:智能合約:將邏輯寫入合約,并部署在鏈上;UI:為用戶提供一個交互式UI,配合錢包完成特定功能。此外,對后端開發有經驗的同學應該知道,通常來說,App數據會存儲在數據庫中,前端與后端交互,離不開后端對數據的查詢和修改。在DApp中,同樣需要一個查詢的“后端”,但這個后端通常不是數據庫。有的同學會認為,既然節點本身提供了查詢鏈上全部數據的PRC接口,那么,前端直接查詢節點是否可行?答案是不行。因為節點提供的數據,是用戶產生的原始日志。舉個例子,假設有個NFT合約,允許用戶創建NFT,那么,一段時間內,節點產生的日志如下:用戶A創建了NFT-1;用戶B創建了NFT-2;用戶B把NFT-2轉移給了用戶X;用戶C創建了NFT-3;...這些未經聚合處理的數據沒法生成一個不斷更新的數據庫表:OwnerNFTID用戶A1用戶X2用戶C3所以,一個DApp除了前端外,還需要一個后端服務,它主要功能是不斷聚合鏈上產生的數據,并根據DApp的業務需求設計表結構以方便查詢。一個直觀的想法是用Java或者Go語言等編寫一個后端服務,再配上一個數據庫,就可以為前端提供RESTAPI來實現查詢。只不過自己維護后端服務比較麻煩,還需要租用云端服務器、數據庫等資源,費時費力。我們推薦另一種后端服務:TheGraph。它本身也可看作是一個基礎設置。TheGraph可以讓我們部署一個Graph查詢服務,如何定義表結構以及如何更新則由我們提供一個預編譯的WASM。整個配置、WASM代碼以及查詢服務都托管在TheGraph中,無需自己搭建服務器,非常方便。因此,一個完整的DApp架構如下:┌───────┐┌───────────│DApp│───────────┐│└───────┘││read/writequery││contractdata│▼▼┌───────┐┌───────┐│Wallet││Graph│└───────┘└───────┘│▲│signindex││broadcastdata││││┌─────────────││┌────┐┌────┐┌────┐││└──┼?│Node││Node│...│Node│───┘└────┘└────┘└────┘││Ethereum─────────────┘我們看看開發各個組件所需的技能樹需求。由于本文僅討論ETH以及ETH兼容鏈的DApp開發,所以,以下技能樹僅適用于ETH系:合約開發:使用Solidity語言;合約部署工具:可以選擇Hardhat、Truffle或Foundry,建議使用Hardhat;數據聚合服務:選擇TheGraph提供的托管服務;數據聚合開發:TheGraph給出的模板代碼是TypeScript,因此這里使用TypeScript;前端頁面:HTML+JavaScript/TypeScript,也可配合任意前端框架如Vue、React等;合約交互框架:雖然理論上使用JSONRPC就可以讀寫合約,但使用Ethers.js可以大大簡化開發;錢包支持:如果僅支持MetaMask,則使用Ethers.js已足夠,如果要支持多種錢包,尤其是需要連接手機錢包,則需要使用Web3Modal。綜上所述,我們可以總結一個基本的Web3全棧開發技術需求:Solidity語言;JavaScript語言;TypeScript語言;HTML/CSS等前端技能。以及用到的服務:將所有源碼托管在GitHub;使用TheGraph提供的HostedService;使用GitHubPage實現靜態頁托管;可選:綁定一個域名。下面我們以一個具體的項目來演示Web3全棧開發的完整流程。該項目允許用戶在Polygon上創建屬于自己的NFT卡片,并可在頁面查看鏈上鑄造的所有NFT卡片:圖片Polygon是兼容以太坊的PoS鏈,特點是Gas便宜,速度快,領測試幣方便。編寫合約創建Web3DApp的第一步是編寫合約。我們使用Hardhat工具,它是Node.js開發的,確保本機安裝了Node.js和NPM,先安裝Solidity編譯器:$npminstall-gsolc$solc--versionsolc,thesoliditycompilercommandlineinterfaceVersion:0.8.17然后創建目錄web3stack并安裝Hardhat:$mkdirweb3stack$cdweb3stack$npminstall--save-devhardhat然后輸入命令npxhardhat開始創建一個新的合約項目:$npxhardhatHardhat提示選擇項目類型:?Whatdoyouwanttodo?…?CreateaJavaScriptprojectCreateaTypeScriptprojectCreateanemptyhardhat.config.jsQuit這里選擇JavaScript項目。后續接著提示項目根目錄、是否添加.gitignore、是否安裝相關依賴等:?Whatdoyouwanttodo?·CreateaJavaScriptproject?Hardhatprojectroot:·/path/to/web3stack?Doyouwanttoadda.gitignore?(Y/n)·y?Doyouwanttoinstallthissampleproject'sdependencieswithnpm(@nomicfoundation/hardhat-toolbox)?(Y/n)·y全部按默認值來。完成后查看package.json應該有兩個dev依賴:{"devDependencies":{"@nomicfoundation/hardhat-toolbox":"^2.0.1","hardhat":"^2.12.7"}}Hardhat默認創建了一個Lock合約,以及相關配置。我們可以自己再寫一個Card合約://SPDX-License-Identifier:GPL-v3pragmasolidity=0.8.17;import"@openzeppelin/contracts/token/ERC721/ERC721.sol";contractCardisERC721{...}直接編譯:$npxhardhatcompileErrorHH411:Thelibrary@openzeppelin/contracts,importedfromcontracts/Card.sol,isnotinstalled.Tryinstallingitusingnpm.編譯提示找不到library報錯,因為我們引用了OpenZeppelin的庫,所以要先用NPM安裝一下:npminstall--save@openzeppelin/contracts這條命令會在package.json中添加一個新的依賴:{..."dependencies":{"@openzeppelin/contracts":"^4.8.1"}}再次編譯:npxhardhatcompile生成的合約存放在artifacts/contracts/Card.sol/Card.json,它包括了ABI接口、字節碼等所有信息。部署合約就是把字節碼部署到鏈上。Hardhat提供了一個示例代碼script/deploy.js用于部署Lock合約,我們可以仿照這個腳本,復制一份script/deploy-card.js來部署Card合約:consthre=require("hardhat");asyncfunctionmain(){//合約工廠:constCard=awaithre.ethers.getContractFactory("Card");//部署:constcard=awaitCard.deploy();awaitcard.deployed();//打印部署的地址:console.log(`Carddeployedto${card.address}`);}main().catch((error)=>{console.error(error);process.exitCode=1;});部署時,直接運行腳本:$npxhardhatrunscripts/deploy-card.js但是,我們并沒有在本地配置任何關于鏈的信息,也沒有配置私鑰等賬戶信息,這個合約是不可能部署到鏈上的,那它部署到哪了?實際上合約默認部署到Hardhat提供的“虛擬JavaScript環境”,它可以在本地用Node執行合約代碼,主要用于測試。要部署到真實的鏈上,我們首先要在hardhat.config.js中加一點關于鏈的配置:module.exports={...//定義所有的鏈:networks:{//定義名為testnet的鏈:testnet:{//配置私鑰:accounts:,//配置為PolygonTestnet節點的PRC:url:"https://matic-mumbai.chainstacklabs.com"}},...}這里為了方便我們把私鑰直接寫進配置里,實際開發可從環境變量讀取。在部署前,確保私鑰對應的地址有一點MATIC測試幣。可以從這里領測試幣。然后用帶--network參數的命令部署:$npxhardhatrunscripts/deploy-card.js--networktestnet如果部署成功,則顯示Card合約被部署的地址:Carddeployedto0x8131aa1B766966f9F8ec3E1132D9d29D92311AB0在PolygonScan上就能查看該合約。順便可以將合約源碼在PolygonScan上驗證,驗證后即可在PolygonScan對合約進行基本的讀寫操作。開發DAppUIDAppUI就是前端頁面,既可以手寫HTML+JavaScript,也可以使用React、Vue等任何前端框架與Webpack等前端工具。為了簡化開發流程,這里我們直接手寫一個index.html頁,讓用戶能在頁面創建一個NFT。頁面引入的第三方庫包括jQuery、BootstrapCSS、Vue,以及用于合約交互的Ethers.js:<scriptsrc="https://cdn.jsdelivr.net/npm/ethers@5.0.32/dist/ethers.umd.min.js"></script>安裝了MetaMask插件后,頁面會獲得一個注入的window.ethereum全局變量,通過此變量與錢包進行交互,例如,連接錢包:awaitwindow.ethereum.request({method:'eth_requestAccounts',});調用合約方法則使用Ethers.js。下面的代碼創建了Card合約并調用mint()方法創建NFT:asyncfunction(){//創建合約:letcontract=newethers.Contract(//合約地址:'0x8131aa1b766966f9f8ec3e1132d9d29d92311ab0',//合約的ABI接口'',//錢包簽名對象:newethers.providers.Web3Provider(window.ethereum,"any").getSigner());//調用mint()方法:lettx=awaitcontract.mint();//等待1個確認:awaittx.wait(1);//TODO:解析tx的日志并拿到TokenID}異步調用mint()方法時,會拉起MetaMask,提示用戶對交易進行簽名。簽名后返回tx對象代表已發送的交易。等待1個確認后,如果要獲取交易信息,則需要解析tx的日志以便拿到TokenID等信息。最后注意到合約的ABI接口包含了合約完整的讀寫方法以及輸入輸出,它是一個JSON對象,這里以字符串形式傳入。Card合約的ABI可以在Card.json中找到并復制出來,不過我們可以使用Hardhat的一個插件直接輸出ABI文件。我們先用NPM安裝插件:$npminstall--save-devhardhat-abi-exporter然后在hardhat.config.js中添加插件配置://用require引入插件:require('hardhat-abi-exporter');...module.exports={...//使用ABIExporter插件:abiExporter:{//輸出到abi目錄:path:"./abi",clear:false,flat:true,pretty:false,//編譯時輸出:runOnCompile:true,}};再運行一次編譯,我們就可在abi目錄下看到若干.json文件。找到Card.json,整理下格式,變成一個字符串粘貼至HTML:...window.NFT_ABI=',"stateMutability":"nonpayable","type":"constructor"}...';...這樣,通過前端頁面,就可以調用合約方法。通過mint()方法寫入后,NFT已經生成,在PolygonScan查找對應的tx可查看詳細信息。通過PolygonScan的ReadContract頁面調用getImage()可獲得NFT圖片信息:圖片把返回的data:image/svg...復制到瀏覽器的地址欄,可查看圖片:圖片也可在OpenSea等第三方NFT市場看到該NFT的圖片。不過我們還有最后一個問題,就是如何在我們自己的頁面上展示用戶創建的NFT。有的同學會想到在頁面調用Card合約的讀方法,依次讀出每個NFT的信息,這種方式會非常慢,因為需要反復多次調用讀方法,且無法實現條件查詢,比如根據地址查詢該地址擁有的NFT,或者創建于一個月內的NFT。因此,我們還需要用到TheGraph提供的數據聚合服務。創建Graph查詢為了創建Graph查詢,我們需要使用TheGraph提供的托管服務。先注冊TheGraph,然后安裝全局命令行工具,只需運行一次:npminstall-g@graphprotocol/graph-cli安裝后可使用命令graph,例如查看版本:$graph--version0.38.0第二步是在TheGraph的HostedService-MyDashboard-AddSubgraph創建一個項目,創建成功后TheGraph顯示狀態為未部署。為了把Subgraph部署上去,我們在本地項目根目錄創建一個subgraph目錄,然后在此目錄下執行命令:$graphinit--producthosted-servicemichaelliao/web3stack注意將登錄名替換為你的GitHub用戶名,將項目名替換為TheGraph上創建的項目名。接下來依次輸入信息:選擇協議的類型:選ethereum;填寫subgraph名稱:用默認的名稱;填寫目錄名:用默認目錄名;選擇鏈:選mumbai;填寫合約地址:填入部署的地址0x8131...1ab0;嘗試自動獲取ABI,一般都能成功;填寫從指定的塊開始:查看合約部署的TX所在塊填入區塊高度;填寫合約名字:與合約代碼保持一致,此處必須為Card;是否索引事件:默認是。接下來會安裝一系列依賴。如果填寫的信息有問題,或者NPM運行出錯,刪掉subgraph目錄再來一遍即可。然后按照提示,先運行graphauth輸入TheGraph給的一個AccessToken,然后進入subgraph/web3stack目錄,運行:npmrundeploy幾秒鐘后,就可以在TheGraph提供的Playground輸入查詢并查看結果:圖片為什么我們可以直接查詢transfers?首先,我們查看schema.graphql,默認有3個Entity,把Entity看作是數據庫表,這3個Entity是TheGraph根據合約定義的Event自動生成的:typeApproval@entity(immutable:true){...}typeApprovalForAll@entity(immutable:true){...}typeTransfer@entity(immutable:true){...}但并不是我們的業務需要的。我們需要的是Card類型,包括owner、image等信息。因此,刪掉自動生成的代碼,換成我們自定義的Card:typeCard@entity(immutable:false){id:String!owner:Bytes!blockNumber:BigInt!blockTimestamp:BigInt!transactionHash:Bytes!image:String!}其中,id是唯一主鍵,這里用NFT的TokenID即可,但類型是String而不是BigInt。接下來,在subgraph.yaml中定義了如何處理事件,需要修改的有兩處,一是entities,刪除原有的3個Entity,換成我們定義的Card:dataSources:-kind:ethereum...mapping:...entities:-Card二是在eventHandlers中刪除我們不關心的Approval和ApprovalForAll事件,僅保留Transfer:dataSources:-kind:ethereum...mapping:...eventHandlers:-event:Transfer(indexedaddress,indexedaddress,indexeduint256)handler:handleTransfer當TheGraph的節點掃描到我們部署的合約產生了Transfer事件后,它將調用handleTransfer處理,這個函數定義在src/card.ts中,自動生成的代碼如下:exportfunctionhandleTransfer(event:TransferEvent):void{letentity=newTransfer(event.transaction.hash.concatI32(event.logIndex.toI32()))entity.from=event.params.fromentity.to=event.params.toentity.tokenId=event.params.tokenIdentity.blockNumber=event.block.numberentity.blockTimestamp=event.block.timestampentity.transactionHash=event.transaction.hashentity.save(。因此,每捕獲到一個Transfer事件,會保存一個Transfer的Entity,這就是我們前面在TheGraph的Playground中能查詢transfers的原因。現在我們不需要Transfer這個Entity,改成Card,先定義Card這個Entity:exportclassCardextendsEntity{...}再修改handleTransfer()的代碼:exportfunctionhandleTransfer(event:TransferEvent):void{lettokenId=event.params.tokenId;letcontract=CardContract.bind(event.address);if(event.params.from.equals(Address.zero())){//如果from=0,表示創建了新的NFT:letnft=newCard(tokenId.toString());nft.owner=event.params.to;nft.image=contract.getImage(tokenId);nft.blockNumber=event.block.number;nft.blockTimestamp=event.block.timestamp;nft.transactionHash=event.transaction.hash;nft.save();}else{//from!=0,表示NFT發生了轉移,需要更新owner和image:letnft=Card.load(tokenId.toString());if(nft===null){log.error('failedloadNFTbytoken:{}',);}else{nft.owner=event.params.to;nft.image=contract.getImage(tokenId);nft.save();}}}再次運行npmrundeploy,我們可以在TheGraph的Playground中查詢到cards:圖片這樣,支持頁面顯示的后端查詢服務就準備就緒。下一步,我們在頁面中添加一點查詢代碼:asyncfunctionquery(){letquery={"query"://輸入為Graph查詢字符串:`{cards(first:20,orderBy:blockTimestamp,orderDirection:desc){idownerimage}}`};//調用jQuery發送POST請求并獲得JSON結果:letopt={type:'POST',dataType:'json',contentType:'application/json',//與Graph服務接口保持一致:url:'https://api.thegraph.com/subgraphs/name/michaelliao/web3stack',data:JSON.stringify(query。;letresult=await$.ajax(opt);letcards=result.data.cards;}拿到查詢結果,我們就能直接在頁面展示:圖片最后一步就是把頁面發布到GitHubPages,然后綁一個域名,就可以讓用戶訪問了:https://web3stack.itranswarp.com至此,一個完整的DApp就開發完畢。FAQQ:可以不用TheGraph,自己寫后端服務嗎?A:可以,很多需求,例如用戶實名認證、發送Email是TheGraph服務無法支持的,必須自己編寫后端服務,配合數據庫實現。Q:可以同時支持多鏈嗎?A:可以,用戶在錢包切換鏈時,DApp可以通過chainChanged事件拿到鏈ID,提前配置好鏈ID與不同鏈的合約地址,就可以正常在不同鏈調用不同合約。Q:可以支持多種錢包嗎?A:可以,需要使用Web3Modal這個庫,能簡化連接多個錢包的代碼。小結從本文給出的完整示例來看,Web3全棧開發,最適合前端開發人員。當年國外有個前端開發叫Hayden,在17年失業了,他決定自學Solidity并花了幾個月的時間為以太坊開發了一個DeFi應用,后來這個應用火爆了,它叫Uniswap。
Polygon Labs將與韓國電信巨頭SK Telecom合作開發Web3生態系統:8月17日消息,Polygon Labs與韓國電信巨頭SK Telecom簽署合作協議,將共同開發Web3生態系統,同時尋求值得孵化的Web3初創公司,SK Telecom的NFT市場Top Port也將開始支持Polygon。[2023/8/17 18:04:52]
Web3初創公司Magic獲5200萬美元融資:金色財經報道,Web3初創公司Magic在PayPalVentures領投的一輪融資中籌集了5200萬美元,該公司開發了幫助企業與Web3客戶互動的軟件。Magic是一個多平臺提供商軟件,該初創公司開發的解決方案旨在促進數字資產在非托管錢包中的存儲。可以使用電子郵件地址、短信或社交媒體帳戶配置進行訪問。[2023/6/11 21:29:35]
Web3日活用戶數排名:BNB Chain第一約110萬,Polygon第二約39萬:金色財經報道,數據網站Token Terminal推特發文稱,各主流公鏈和應用的Web3日活躍用戶數排名顯示如下:
1、BNB Chain:110萬;
2、Polygon:39萬;
3、Ethereum:34萬;
4、Solana:12萬;
5、Fantom:5.82萬;
6、Arbitrum:5.8萬;
7、OpenSea:5.4萬;
8、Optimism:4.9萬;
9、Uniswap:4.4萬;
10、Avalanche:3萬。
有從業者分析稱,這些數據存在水分,需要清洗掉“機器用戶”。這意味著,Web3的真實用戶數可能要低于該數據。考慮到一個真實用戶可能存在多個地址,Web3用戶數或許要遠小于該數據。[2022/12/19 21:52:50]
數據:11月份全球Web3領域融資總額為10.34億美元,環比增長21.65%:金色財經報道,據財聯社創投通統計,11月份全球Web3.0領域融資總數量為71筆,融資總額為10.34億美元,環比增長21.65%。
從細分賽道來看,13個區塊鏈基礎設施項目獲得4.56億美元,成為融資總額最多的領域。德國3個項目獲得2.11億美元融資;中國10個項目獲得2.04億美元融資,成為融資額增長最多的地區,環比增長超過4倍。從輪次來看,11月份的融資主要集中在種子輪和戰略輪,占比分別43.67%和12.68%。
根據此前財聯社的統計,10月全球Web3市場共融資8.5億美元。[2022/12/8 21:31:10]
三位高管離職后,Web3游戲Mythical Games裁員近10%:金色財經報道,作為業務重組的一部分,Web3游戲Mythical Games裁減了大約10%的員工,理由是經濟環境充滿挑戰,這家初創公司目前擁有大約321名員工。
此外,裁員的前一天,三位高管(聯合創始人Rudy Koch、首席運營官兼游戲工作室和發行負責人Matt Nutt、戰略和投資高級副總裁Chris Ko)宣布他們將離開這家初創公司。Mythical Games發言人Nate Nesbitt表示,“像所有公司一樣,我們受到了經濟衰退的影響,不得不相應地重新評估和重組我們的某些業務領域。”
去年11月,Mythical Games完成了1.5億美元C輪融資,a16z領投,使其估值達到12.5億美元。(The Block)[2022/11/5 12:19:18]
特斯拉又出事了! 4月19日上午消息,2021年上海國際車展媒體日首日,特斯拉的展臺上出現一位穿著“剎車失靈”和特斯拉標識T恤的女士進行維權.
1900/1/1 0:00:00作者丨萊道君 來源丨萊道區塊鏈 據上次USDT因兌付危機短時遭遇大幅貶值已有半年,4月26日USDT再次引發信用危機.
1900/1/1 0:00:00世界協調時3月3日上午12點,加密市場急劇下滑。比特幣的價格(比特幣)下跌超過5%,從23418美元左右跌至22163美元.
1900/1/1 0:00:00做一個有責任、有態度、有價值的幣市觀察者。距離BTC減半還剩47天,距離BCHABC減半還剩18天,距離BSV減半還剩17天.
1900/1/1 0:00:00Compound——協議概述Compound是以太坊區塊鏈上的協議,允許用戶借用和借出加密代幣。其利率是根據每種資產的供求通過算法設置的.
1900/1/1 0:00:00AI技術至今仍是2023年最熱門的話題之一。盡管在過去三個月中處于高度波動的階段,但與這種人工智能技術相關的加密貨幣卻取得了可觀的收益,反映出它們越來越受歡迎.
1900/1/1 0:00:00