今天科技圈最大的新聞莫過于百度李彥宏被“澆水”一事了,微博、微信、今日頭條可謂是炸開了鍋,但想想要是10年前,討論最火的地方可能不是這些app,無疑是百度貼吧了,但可能卻面臨刪帖的危險...
這時,區塊鏈的不可篡改行就幫上了大忙!
今天營長就使用DApp開發框架Embark,手把手教你構建一個去中心化的社交新聞網站,從主要分以下三個部分:
明確DApp需求,部署智能合約;
使用DApp開發框架Embark的JavaScript程序庫EmbarkJS測試智能合約;
使用JavaScript用戶界面框架React構建DApp的前端。
明確DApp需求,部署智能合約。
百度貼吧是一個功能非常復雜的平臺,因此我們無法做到把它全部推倒重建,我們只會構建出百度貼吧的一些核心功能,并在構建中詳細介紹如何使用Embark框架構建DApp。
我們的構想非常簡單:首先我們給DApp取名為DReddit(去中心化的百度貼吧),它允許用戶在其中發布帖子,而其他用戶可以憑興趣以及帖子的質量對帖子進行好評和差評的投票。為了簡化開發,DReddit直接使用以太坊錢包賬戶作為用戶帳戶,也就是說每個以太坊錢包賬戶都是該應用程序的有效帳戶,用戶可以使用基于瀏覽器的以太坊輕錢包Metamask等擴展程序進行身份認證。
我們將創建一個智能合約來實現發布帖子以及對帖子投票的功能。同時為了簡化用戶的交互過程,我們還會使用React框架構建一個用戶界面。
1、應用程序設置
首先,安裝Embark框架,命令如下:
npminstall-gembark
使用new命令來創建并設置應用程序:
embarknewdredditcddreddit
使用cd命令進入文件夾之后,我們可以看到應用程序的文件結構,在其中最重要的文件夾是用來存放智能合約的contracts,以及用來存放前端程序的app。
民調:84%的選民希望美國總統候選人支持比特幣的權利:金色財經報道,隨著2024年美國總統大選的臨近,由于數字資產預計將在競選議程中占據突出位置,選民在投票前可能會對他們所喜歡的總統候選人對比特幣的立場產生疑問。Michael Saylor在5月27日在推特上發起“你是否會要求任何總統候選人在贏得你的投票前支持你的比特幣權利”調查。
截至5月28日,近3萬名推特用戶進行了投票,其中84%的人選擇了是,16%的受訪者投了反對票。[2023/5/29 9:47:40]
2、創建智能合約
使用Solidity語言編寫智能合約,在其中加入創建帖子功能和投票功能。
在contracts文件夾下創建智能合約文件DReddit
上述結構體只能用來存儲單個帖子,在多個帖子場景中,我們需要添加一個數組來存儲多個帖子結構體,代碼如下:
Postpublicposts;
a)新建帖子
創建函數createPost,其中參數_description是用來表示帖子內容的字節型數據。
functioncreatePost(bytes_description)public{uintpostId=posts
在函數中,我們為存儲的帖子創建一個序號id,然后使用剛剛定義的帖子結構體Post創建一個新的實例。
b)發布帖子
創建一個新的事件類型NewPost,代碼如下:
eventNewPost(uintindexedpostId,addressowner,bytesdescription)
定義完成后,在新建帖子函數createPost中使用所需的數據執行NewPost:
functioncreatePost(bytes_description)public{..
c)好評/差評
Ledger將推遲發布Ledger Recover功能:5月23日消息,Ledger宣布將推遲發布Ledger Recover(密鑰恢復)功能,在發布代碼之前不會引入該項新功能。
據悉,Ledger Recover服務將私鑰恢復短語拆分為三個加密分片,并將它們分發給三個托管方:Ledger、加密托管公司Coincover和代碼托管公司EscrowTech。如果有人丟失了他們的恢復短語,則可以合并三個分片中的兩個(等待ID檢查)以重新獲得對鎖定資金的訪問權限。該功能引發了部分用戶對隱私和安全的擔憂。[2023/5/24 15:21:44]
DReddit允許用戶對帖子進行好評差評投票。為實現這一功能,我們需要使用投票計數器來擴展之前定義的帖子結構體Post,并引入一個代表投票類型的枚舉結構。為了方便前端應用程序調用,我們需要添加一個新建投票事件NewVote。完成后,我們還需要添加一個用來執行投票的方法。
首先,定義一個表示投票種類的枚舉類型Ballot,其中可選的投票類型包括好評UPVOTE、差評DOWNVOTE、不投票NONE:
enumBallot{NONE,UPVOTE,DOWNVOTE}
為存儲每個帖子中的投票紀錄,我們需要在帖子結構體Post中相應地加入“好評”投票計數器和“差評”投票計數器。為確保用戶不會重復投票,我們還需要添加一個用來存儲所有已投票用戶以及投票的映射:
structPost{..
現在的新建投票事件NewVote應該如下所示:
eventNewVote(uintindexedpostId,addressowner,uint8vote);
由于帖子結構體Post中加入了投票計數器,需要用新的結構體更新createPost():
functioncreatePost(bytes_description)public{..
現在萬事俱備,只欠投票函數vote()了!!!
加密資產公司Hashdex計劃推出比特幣現貨ETF:金色財經報道,隨著比特幣期貨ETF在紐約證券交易所上市六個月,加密資產管理公司Hashdex開始逐步推出現貨產品。該公司的首席執行官兼聯合創始人Marcelo Sampaio表示:“現貨比特幣ETF是不可避免的,我們只是不知道什么時候,在什么情況下。”雖然很難確定一個時間表,但他相信現貨ETF將獲得美國SEC主席的授權。(The Block)[2023/3/17 13:08:57]
函數的參數_vote就是我們剛剛定義的投票枚舉類型Ballot,它的取值為0、1、2這三個無符號整數,分別對應三種類型的投票。
使用Solidity的require()語句確保用戶只能對實際存在的帖子進行投票及用戶不能對同一個帖子多次投票。
在函數中,我們用當前的投票類型更新“好評”投票計數器或“差評”投票計數器,存儲已投票用戶的信息并發出新建投票事件NewVote:
functionvote(uint_postId,uint8_vote)public{Poststoragepost=posts;require(post
else{post
post
d)判斷用戶是否可以投票
在前端中,我們希望向用戶展示自己是否已經對帖子進行了投票。為此,定義一個可以判斷用戶能否對帖子投票的API將大大簡化這個過程。判斷用戶是否可以投票的過程非常簡單,只需要判斷該帖子中是否存在該用戶的投票,判斷代碼如下:
functioncanVote(uint_postId)publicviewreturns(bool){if(_postId>posts
e)獲取投票信息
如果你想瀏覽自己過去的投票信息怎么辦?很簡單,一個簡單的函數getVote()就可以實現,代碼如下:
functiongetVote(uint_postId)publicviewreturns(uint8){Poststoragepost=posts;returnuint8(post
三箭聯創:FTX、Alameda“串通”擊垮三箭,SBF予以否認:11月17日消息,三箭資本聯合創始人Kyle Davies周三對CNBC表示,FTX、Alameda互相“串通”擊垮了三箭,FTX、Alameda串通進行獵殺止損(Stop Hunting),作為他們最大的客戶,3AC遭到“獵殺”,我們的頭寸被清算。CNBC表示,它收到了FTX創始人Sam Bankman-Fried的一份聲明,他回應說:我很震驚。100%不同意……他們的指控不屬實。
此前11月13日,三箭資本聯合創始人KyleDavies在其個人社交媒體平臺發文稱,今年5月時,LUNA暴雷后的一系列事件讓其極為震驚。如今他了解到,是FTX/Alameda在該事件中對三箭資本頭寸進行了獵殺,最終導致其損失自身和LP/債權人的全部資金。[2022/11/17 13:15:27]
到這里,部署智能合約大功告成!
使用EmbarkJS測試智能合約
前面已經部署了DReddit智能合約,并在智能合約中實現了發布帖子和給帖子投票的功能,接下來就需要使用Embark框架為智能合約編寫一些測試。
1、編寫第一個測試
先從最簡單的功能開始測試。
首先,我們需要在測試文件夾test中創建一個測試文件DReddit_spec
);});
運行測試命令embarktest,輸出如下:
所有測試都成功通過,接下來測試一些實際的功能!
2、測試帖子的創建過程
測試創建帖子:首先以某種方式在JavaScript中導入DReddit智能合約的實例,然后調用智能合約中的各個方法測試它們能否正常工作,同時我們還需要配置測試環境來正確創建智能合約的實例。
a)導入智能合約實例
在運行測試時,Embark框架會在全局范圍加入一些必要的自定義函數和對象。其中一個就是自定義獲取函數require(),它可以幫助我們從特定的Embark路徑中導入智能合約實例。
FatMan:Hodlnaut添加UST是為了利用散戶作為退出流動性來脫手其UST頭寸:6月29日消息,Terra研究員FatMan發推文稱,加密借貸公司Hodlnaut內部人員向其發布了一些信息,看到了來自Hodlnaut CEO朱俊濤發布的有關于他們在4月份添加UST真相的內部消息,朱俊濤承認Hodlnaut添加了UST是為了利用散戶作為退出流動性來脫手該公司的UST頭寸。
即Hodlnaut通過默默地將客戶的USDC和USDT兌換成UST以產生收益,積累了巨大的UST頭寸。他們可能希望降低風險,但他們的Anchor和UST 3Crv頭寸巨大,冒著脫錨的風險是不明智的。他們沒有傾銷它,而是開始募集客戶資金。然后,每當客戶存入UST時,朱俊濤就可以在后臺清算公司負債,并將他們自己的UST轉換為USDC,而無需公開平倉他們的鯨魚賬戶頭寸(因有鏈上監控),從而將頭寸拋售給散戶。該計劃沒有奏效,盡管據稱他們確實從客戶的UST存款中獲得了大約2000萬UST,但這不足以拋售他們所有的敞口,最終脫錨還是發生了。[2022/6/29 1:38:43]
就比如說,為了在測試中導入DReddit智能合約的實例,我們需要在spec文件中添加如下的命令:
constDReddit=require('Embark/contracts/DReddit');
DReddit現在被指定為一個EmbarkJS的智能合約實例,我們需要使用設置函數config()讓Embark框架知道,我們需要的智能合約都有哪些。設置函數config(),以便Embark框架知道我們需要哪些智能合約:
config({contracts:{DReddit:{}}});
這個操作與配置智能合約的操作非常相似,實際上它就相當于在測試環境中配置智能合約。我們將所需的智能合約作為參數,通過配置對象將它傳遞給設置函數config()。在我們這個應用程序中,需要設置的參數只有DReddit,這是因為我們的智能合約并不需要構造函數。
b)測試創建帖子函數createPost()
導入好智能合約實例之后,我們就可以測試智能合約的創建帖子函數createPost()了。不過在定義createPost函數時,我們指定了帖子的描述為字節形式,如何測試呢?
首先我們需要說明的是為什么要用字節形式的數據。我們都知道,帖子的長短不好控制,有些帖子很長,有些帖子很短,所以最好的方案就是將帖子的描述(內容)存儲在一個并不在意數據大小的地方,而在智能合約之中存儲的只是帖子描述的哈希值。通過使用哈希值我們可以保證數據的索引與數據一一對應,同時智能合約中存儲的數據索引始終具有相同的長度,所以我們將帖子真正的描述存儲在IPFS中,而創建帖子函數createPost中的帖子描述實際上是帖子描述的IPFS哈希值。
在得到帖子描述的哈希值后(代碼中選用之前準備好的哈希值),我們可以使用Web3程序庫的fromAscii()工具函數將該哈希值轉換為字節,然后使用智能合約的創建帖子函數createPost將它發送出去。在測試時,我們可以檢索剛才發出的事件,并檢查它的返回值,這些操作的代碼如下所示:
..
);});
運行測試命令embarktest,兩條測試都測試通過!
3、測試數據的正確性
需要測試的另外一個功能是,存儲的數據(帖子的描述,所有者)是否能解析回正確的數據。這就要用到先前定義的全局可見的帖子序號postId。我們還需要執行與先前測試類似的檢查,如果要測試帖子的所有者數據是否正確,我們首先需要訪問創建帖子的帳戶。
Embark框架的設置函數config可以讓我們輕松地訪問錢包帳戶,我們所要做的就是將一個解析處理程序加入到設置函數config中并存儲傳遞的值:
..
);
完成了操作后,測試代碼如下:
it('postshouldhavecorrectdata',async()=>{constpost=awaitDReddit
);
注意到,代碼中引用了帳戶accounts,但僅僅通過查看代碼,我們無法確定賬戶account是否是我們指定的那個賬戶。而Embark框架可以幫助我們解決這個問題,在設置完帳戶后,Embark框架會自動將錢包的第一個帳戶(accounts)設置為用于發起交易的默認帳戶。這種特性讓我們可以確定,賬戶accounts會是帖子的所有者。
另一種方法是將所有帳戶發送給智能合約的send()函數,在這種情況下,我們可以決定使用哪個賬戶發起交易。
4、測試能否投票函數canVote()
接下來我們來測試能否投票函數canVote()是否按預期的方式工作。很簡單,用戶不能給不存在的帖子投票,因此測試只需要用能否投票函數判斷不存在的帖子序號postId。測試代碼如下:
it('shouldnotbeabletovoteinanunexistingpost',async()=>{constuserCanVote=awaitDReddit
);
不過,當用戶確實可以給某個帖子投票時,我們要確保能否投票函數canVote()的返回值是能true,我們需要用該函數來判斷之前存儲的帖子序號postId:
it('shouldbeabletovoteinapostifaccounthasnotvotedbefore',async()=>{constuserCanVote=awaitDReddit
);
很棒,我們現在完成了5個測試!
5、測試投票函數vote()
投票功能可謂是我們應用程序的核心功能,因而對它的測試是重中之重。我們有許多種不同的方法驗證投票函數vote()的功能是否符合預期,但在本教程中,我們只檢查新建投票事件NewVote發出投票的所有者帳戶是否與真正執行投票的帳戶相同,在代碼實現中我們可以借鑒先前的測試:
it("shouldbeabletovoteinapost",async()=>{constreceipt=awaitDReddit
);
5、測試每個用戶每個帖子只能投一票
在智能合約定義中,我們設置了每個用戶對每個帖子只能投一票,因而最后一個也是最必要的一個測試就是檢查智能合約是否允許用戶在同一帖子上多次投票。這個測試中我們又用到了async/await異步操作的方法,同時還用到了try/catch來更好地進行測試。當用戶對一個已經投過票的帖子再次進行投票時,投票函數vote()將執行失敗,這個操作我們可以使用斷言(assert)方法來實現:
it('shouldnotbeabletovotetwice',async()=>{try{constreceipt=awaitDReddit
catch(error){assert(error
});
代碼看起來可能會讓你有些困惑,但實際上它的邏輯非常直接。如果投票函數vote()執行失敗,我們不應該調用函數assert.fail(),而應該立即進入catch()部分。如果結果不是這樣,那么就說明測試發現了問題,這種測試方法其實就是大名鼎鼎的負向(Negative)測試。
到這里,也就是我們最后一次運行embarktest進行測試了,如果一切正常的話,測試的輸出應該如下所示,也就是說,我們已經完全覆蓋了所有的測試!快為自己點個贊!
?embarktestCompilingcontractsDReddit?shouldwork(0ms)-?shouldbeabletocreateapostandreceiveitviacontractevent(60ms)-?postshouldhavecorrectdata(18ms)-?shouldnotbeabletovoteinanunexistingpost(14ms)-?shouldbeabletovoteinapostifaccounthasn'tvotedbefore(12ms)-?shouldbeabletovoteinapost(42ms)-?shouldn'tbeabletovotetwice(37ms)-7passing(5s)->Alltestspassed
由于下一部分篇幅過長,我們將在下一篇文章中介紹如何使用React框架作為客戶端前端JavaScript庫來構建DReddit前端界面。主要包括以下5部分:
渲染組件
構建創建帖子組件CreatePost
構建帖子組件Post
構建帖子列表組件List
添加投票功能
老鐵們,敬請期待
7月4日,央行深圳市中心支行黨委書記、行長邢毓靜表示,央行貿易金融區塊鏈平臺已接入深圳市28家銀行、483家網點業務上鏈運行,對外付匯業務量已超300億元.
1900/1/1 0:00:00昨日BTC再度拉升,目前的幣價已經回到12000美元附近,今天朋友圈很多人都在發新浪財經上線數字貨幣行情走勢,這算是加密貨幣全行業的利好.
1900/1/1 0:00:00互鏈脈搏按:互鏈脈搏專欄“賽迪區塊鏈生態聯盟”,新近又發表了一篇“賽迪區塊鏈研究院”的報告,值得注意的是,賽迪區塊鏈研究院隸屬于中國電子信息產業發展研究院,是工信部直屬機構.
1900/1/1 0:00:00根據金融服務公司Jefferies對600名美國社交媒體用戶的調查顯示,五分之四的受訪者稱,他們“不太可能”或“完全不可能”購買Facebook的加密貨幣Libra.
1900/1/1 0:00:00近期行情回暖,朋友圈一下子又欣欣向榮起來。項目活躍了,合作搞起來了,很久沒有聲音的社區又冒泡了。只是對于呂凱,確是有點苦澀起來.
1900/1/1 0:00:00親愛的用戶: bitget.com幣得全球站已上線EOS/USDT永續合約交易對。 杠桿倍數:0-50倍.
1900/1/1 0:00:00