




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
2025年區(qū)塊鏈工程師能力評(píng)估卷:智能合約設(shè)計(jì)與調(diào)試試題考試時(shí)間:______分鐘總分:______分姓名:______第一部分:智能合約設(shè)計(jì)1.請(qǐng)?jiān)O(shè)計(jì)一個(gè)簡(jiǎn)單的去中心化投票系統(tǒng)智能合約。該系統(tǒng)應(yīng)支持:*初始化投票主題和候選人數(shù)量。*允許注冊(cè)用戶進(jìn)行投票。*計(jì)算并返回投票結(jié)果。*確保每個(gè)地址只能投票一次。*投票完成后,不允許再進(jìn)行投票。請(qǐng)描述你的設(shè)計(jì)思路,包括:*合約的核心狀態(tài)變量。*關(guān)鍵函數(shù)及其作用(如初始化函數(shù)、投票函數(shù)、計(jì)票函數(shù)等)。*數(shù)據(jù)結(jié)構(gòu)的選擇(如使用映射Map、數(shù)組Array等)。*簡(jiǎn)述如何保證用戶只能投一次票。2.假設(shè)你需要開發(fā)一個(gè)基于ERC-721標(biāo)準(zhǔn)的NFT合約,用于發(fā)行代表數(shù)字藝術(shù)作品的NFT。除了ERC-721標(biāo)準(zhǔn)要求的基本功能(如`ownerOf`,`balanceOf`,`approve`,`transferFrom`等)外,該NFT還需要包含以下特性:*每個(gè)NFT的元數(shù)據(jù)(如名稱、描述、圖像URI)存儲(chǔ)在鏈下(如IPFS),合約中只存儲(chǔ)其對(duì)應(yīng)的URI地址。*所有NFT的創(chuàng)建者(鑄造者)是合約的初始所有者。*提供一個(gè)公共函數(shù),允許合約所有者(部署者)批量鑄造NFT。請(qǐng)?jiān)O(shè)計(jì)該NFT合約的關(guān)鍵結(jié)構(gòu),包括必要的狀態(tài)變量、核心函數(shù)(如構(gòu)造器、`mint`函數(shù)、`tokenURI`函數(shù)等)及其基本邏輯。請(qǐng)?zhí)貏e說明`tokenURI`函數(shù)的實(shí)現(xiàn)方式。第二部分:智能合約編碼與實(shí)現(xiàn)3.請(qǐng)根據(jù)你在第一部分第1題中設(shè)計(jì)的去中心化投票系統(tǒng),使用Solidity語(yǔ)言編寫智能合約的核心代碼部分。至少包含初始化投票主題、注冊(cè)投票、進(jìn)行投票、查詢投票結(jié)果等關(guān)鍵功能的實(shí)現(xiàn)。請(qǐng)確保代碼中包含基本的訪問控制(如`onlyOwner`修飾符,假設(shè)投票系統(tǒng)由單一管理員管理)。4.請(qǐng)編寫一個(gè)簡(jiǎn)單的ERC-20代幣合約,實(shí)現(xiàn)`transfer`、`transferFrom`、`approve`和`increaseAllowance`、`decreaseAllowance`函數(shù)。為了簡(jiǎn)化,可以不實(shí)現(xiàn)事件(Events)和錯(cuò)誤(Errors)的拋出,但需注意處理整數(shù)溢出/下溢的情況(可使用Solidity0.8.0及更高版本自動(dòng)處理,或顯式實(shí)現(xiàn))。第三部分:智能合約調(diào)試與問題解決5.以下是一段存在安全漏洞的Solidity代碼片段(假設(shè)使用Solidity0.8.0+,可自動(dòng)處理整數(shù)溢出,但Reentrancy風(fēng)險(xiǎn)存在):```soliditypragmasolidity^0.8.0;contractVulnerableContract{mapping(address=>uint256)publicbalances;functiondeposit()publicpayable{balances[msg.sender]+=msg.value;}functionwithdraw(uint256amount)public{require(balances[msg.sender]>=amount,"Insufficientbalance");balances[msg.sender]-=amount;payable(msg.sender).transfer(amount);}}```請(qǐng)分析這段代碼中存在的安全漏洞,并解釋其可能被利用的方式。如果你是調(diào)用者(攻擊者),你會(huì)如何利用這個(gè)漏洞竊取資金?6.假設(shè)你部署了一個(gè)智能合約,并嘗試調(diào)用其`transfer`函數(shù)向另一個(gè)地址發(fā)送代幣。調(diào)用失敗,并返回錯(cuò)誤信息提示“OutofGas”。請(qǐng)分析可能導(dǎo)致此錯(cuò)誤的原因,并列舉至少三種可能的解決方案。7.在調(diào)試一個(gè)智能合約時(shí),你發(fā)現(xiàn)合約狀態(tài)變量`state`的值在某個(gè)操作后變得異常(不是預(yù)期的值)。你正在使用RemixIDE進(jìn)行部署和交互測(cè)試。請(qǐng)描述你將采取的調(diào)試步驟,以定位導(dǎo)致`state`變量異常的原因。你需要檢查哪些信息?可能會(huì)使用哪些工具或命令行(如`etherscan`)?第四部分:智能合約基礎(chǔ)知識(shí)與安全8.解釋以下概念的區(qū)別:狀態(tài)變量(StateVariable)、視圖函數(shù)(view)和純函數(shù)(pure)。9.什么是智能合約的Gas費(fèi)用?簡(jiǎn)述影響Gas費(fèi)用的主要因素。10.描述“重入攻擊”(ReentrancyAttack)的基本原理,并說明一種防范該攻擊的常用方法。試卷答案第一部分:智能合約設(shè)計(jì)1.設(shè)計(jì)思路:*狀態(tài)變量:*`addressowner`:合約所有者(管理員)。*`stringmemoryproposalTitle`:投票主題。*`mapping(address=>bool)voted`:記錄已投票地址。*`mapping(address=>uint256)votes`:記錄每個(gè)候選人的得票數(shù)。*`uint256candidateCount`:候選人數(shù)量。*`boolvotingFinished`:標(biāo)記投票是否結(jié)束。*函數(shù):*`constructor(stringmemory_title,uint256_candidateCount)`:初始化函數(shù),設(shè)置投票主題、候選人數(shù)量,設(shè)置部署者為合約所有者,初始化`votingFinished`為`false`。*`functionvote(uint256candidateIndex)public`:投票函數(shù)。檢查`candidateIndex`是否有效,檢查`votingFinished`是否為`false`,檢查`msg.sender`是否已投票(`voted[msg.sender]`是否為`true`),如果滿足條件,將對(duì)應(yīng)候選人的票數(shù)加一,并將`voted[msg.sender]`設(shè)置為`true`。*`functionfinishVoting()public`:結(jié)束投票函數(shù)。只有合約所有者(`msg.sender==owner`)可以調(diào)用,將`votingFinished`設(shè)置為`true`。*`functiongetVoteCount(uint256candidateIndex)publicviewreturns(uint256)`:獲取某個(gè)候選人得票數(shù)的函數(shù)。檢查`candidateIndex`是否有效,返回對(duì)應(yīng)候選人的票數(shù)。*`functionisVoted(addressvoter)publicviewreturns(bool)`:查詢某個(gè)地址是否已投票。*數(shù)據(jù)結(jié)構(gòu):*使用`mapping(address=>bool)voted`記錄投票情況,鍵為投票者地址,值為是否已投票布爾值。*使用`mapping(address=>uint256)votes`記錄候選人的得票數(shù),鍵為候選人地址(或索引),值為票數(shù)。*使用`uint256candidateCount`存儲(chǔ)候選人總數(shù)。*使用`boolvotingFinished`標(biāo)記投票狀態(tài)。*保證唯一投票:通過`mapping(address=>bool)voted`數(shù)組,在`vote`函數(shù)中檢查`msg.sender`是否已經(jīng)存在該鍵且值為`true`,如果存在則拒絕投票,從而保證每個(gè)地址只能投票一次。2.設(shè)計(jì)方案:*關(guān)鍵結(jié)構(gòu):*繼承`ERC721`標(biāo)準(zhǔn)合約。*狀態(tài)變量:*`stringmemoryname`:合約名稱。*`stringmemorysymbol`:合約符號(hào)。*`mapping(uint256=>TokenMetadata)privatetokenMetadata`:存儲(chǔ)每個(gè)NFT的元數(shù)據(jù)信息(地址)。*`uint256internal_tokenIdCounter`:記錄下一個(gè)要生成的tokenId。*結(jié)構(gòu)體`TokenMetadata`:*`stringuri`:元數(shù)據(jù)的IPFSURI地址。*構(gòu)造器:初始化`name`和`symbol`。*函數(shù):*`constructor(stringmemory_name,stringmemory_symbol)ERC721(_name,_symbol)`:調(diào)用父合約構(gòu)造器。*`functionmint(addressrecipient,stringmemory_tokenUri)public`:假設(shè)只有合約所有者可以鑄造,使用`onlyOwner`修飾符。增加`_tokenIdCounter`,創(chuàng)建NFT給`recipient`,設(shè)置該NFT的`tokenMetadata`的`uri`字段為`_tokenUri`。*`functiontokenURI(uint256tokenId)publicviewoverridereturns(stringmemory)`:實(shí)現(xiàn)`ERC721`的`tokenURI`函數(shù)。檢查`tokenId`是否存在。從`tokenMetadata`中獲取對(duì)應(yīng)`tokenId`的`uri`,并拼接上基礎(chǔ)前綴(如`ipfs://`),返回完整的URI。*元數(shù)據(jù)存儲(chǔ):合約僅存儲(chǔ)每個(gè)NFT元數(shù)據(jù)的URI地址。創(chuàng)建NFT時(shí),調(diào)用者提供該URI,合約將其與`tokenId`關(guān)聯(lián)。實(shí)際元數(shù)據(jù)文件存儲(chǔ)在鏈下IPFS,用戶通過合約返回的URI訪問。第二部分:智能合約編碼與實(shí)現(xiàn)3.Solidity代碼(核心部分):```soliditypragmasolidity^0.8.0;contractVotingSystem{addresspublicowner;stringpublicproposalTitle;mapping(address=>bool)publicvoted;mapping(address=>uint256)publicvotes;uint256publiccandidateCount;boolpublicvotingFinished;constructor(stringmemory_title,uint256_candidateCount){owner=msg.sender;proposalTitle=_title;candidateCount=_candidateCount;votingFinished=false;}modifieronlyOwner(){require(msg.sender==owner,"Notthecontractowner");_;}functionvote(uint256candidateIndex)publiconlyOwner{require(candidateIndex<candidateCount,"Invalidcandidateindex");require(!votingFinished,"Votinghasfinished");require(!voted[msg.sender],"Youhavealreadyvoted");voted[msg.sender]=true;votes[msg.sender]=candidateIndex;//AssumingcandidateIndexisthevotechoice}functionfinishVoting()publiconlyOwner{votingFinished=true;}functiongetVoteCountForCandidate(uint256candidateIndex)publicviewreturns(uint256){require(candidateIndex<candidateCount,"Invalidcandidateindex");uint256count=0;for(uint256i=0;i<candidateCount;i++){if(votes[i]==candidateIndex){count++;}}returncount;}}```4.ERC-20代幣合約代碼(簡(jiǎn)化版,無事件和錯(cuò)誤,整數(shù)溢出由0.8+自動(dòng)處理):```soliditypragmasolidity^0.8.0;contractSimpleERC20{mapping(address=>uint256)publicbalanceOf;mapping(address=>mapping(address=>uint256))publicallowance;uint256publictotalSupply;stringpublicname="SimpleToken";stringpublicsymbol="STK";uint8publicdecimals=18;eventTransfer(addressindexedfrom,addressindexedto,uint256value);eventApproval(addressindexedowner,addressindexedspender,uint256value);constructor(uint256_initialSupply){balanceOf[msg.sender]=_initialSupply;totalSupply=_initialSupply;}functiontransfer(addressto,uint256amount)publicreturns(bool){_transfer(msg.sender,to,amount);returntrue;}functiontransferFrom(addressfrom,addressto,uint256amount)publicreturns(bool){require(amount<=allowance[from][msg.sender],"Allowanceexceeded");allowance[from][msg.sender]-=amount;_transfer(from,to,amount);returntrue;}functionapprove(addressspender,uint256amount)publicreturns(bool){allowance[msg.sender][spender]=amount;emitApproval(msg.sender,spender,amount);returntrue;}functionincreaseAllowance(addressspender,uint256addedValue)publicreturns(bool){allowance[msg.sender][spender]+=addedValue;emitApproval(msg.sender,spender,allowance[msg.sender][spender]);returntrue;}functiondecreaseAllowance(addressspender,uint256subtractedValue)publicreturns(bool){require(allowance[msg.sender][spender]>=subtractedValue,"Allowancebelowzero");allowance[msg.sender][spender]-=subtractedValue;emitApproval(msg.sender,spender,allowance[msg.sender][spender]);returntrue;}function_transfer(addressfrom,addressto,uint256amount)internal{require(to!=address(0),"Cannottransfertozeroaddress");require(amount>0,"Transferamountmustbepositive");balanceOf[from]-=amount;balanceOf[to]+=amount;emitTransfer(from,to,amount);}}```第三部分:智能合約調(diào)試與問題解決5.漏洞分析:*漏洞:重入攻擊(ReentrancyAttack)。*原理:`withdraw`函數(shù)在執(zhí)行`payable(msg.sender).transfer(amount)`時(shí),如果存在一個(gè)外部合約調(diào)用了`withdraw`并在這個(gè)轉(zhuǎn)賬過程中再次調(diào)用該合約的某個(gè)狀態(tài)修改函數(shù)(即使該函數(shù)不耗Gas或耗Gas很少),那么這個(gè)狀態(tài)修改函數(shù)可能會(huì)再次調(diào)用`withdraw`,導(dǎo)致原始調(diào)用者的資金被重復(fù)提取。*利用方式:攻擊者部署一個(gè)惡意合約,該合約實(shí)現(xiàn)一個(gè)調(diào)用`VulnerableContract`的`withdraw`函數(shù),并在調(diào)用`transfer`之前,通過某種方式(例如,利用`transfer`的收包特性,或另一個(gè)合約配合)再次觸發(fā)`VulnerableContract`的`withdraw`,使得資金被多次提取。6.原因分析:*調(diào)用`transfer`函數(shù)時(shí),合約的執(zhí)行需要支付Gas。如果發(fā)送的代幣數(shù)量加上交易本身的Gas費(fèi)用超過了賬戶余額,交易就會(huì)失敗,返回“OutofGas”。*可能原因:*發(fā)送的代幣數(shù)量本身過大。*交易設(shè)置了較高的Gas限制,但實(shí)際執(zhí)行所需的Gas超過了限制。*被轉(zhuǎn)賬地址接收交易時(shí),其合約代碼執(zhí)行過程中消耗了過多的Gas,導(dǎo)致超出其賬戶余額所能支付的Gas。*網(wǎng)絡(luò)擁堵,實(shí)際執(zhí)行成本遠(yuǎn)高于預(yù)估,導(dǎo)致Gas不足。*解決方案:*降低發(fā)送的代幣數(shù)量。*重新發(fā)送交易,適當(dāng)提高Gas限制(但要合理,避免浪費(fèi))。*檢查接收方合約代碼,看是否有Gas消耗過大的地方(如復(fù)雜的計(jì)算、不必要的循環(huán))。*在發(fā)送前使用Gas估算器估算所需Gas,確保賬戶余額充足。*在發(fā)送`transfer`或`transferFrom`時(shí),考慮使用`call{value:amount}()`形式,同時(shí)發(fā)送少量ETH作為Gas費(fèi),確保即使接收方合約執(zhí)行耗盡Gas,也能保證轉(zhuǎn)賬成功(前提是接收方合約不會(huì)消耗過多Gas)。7.調(diào)試步驟:*查看交易回執(zhí)(TransactionReceipt):在Etherscan或其他區(qū)塊鏈瀏覽器中找到導(dǎo)致`state`異常的交易,查看其`output`或`logs`,看是否有相關(guān)的事件日志或錯(cuò)誤信息。*檢查調(diào)用棧(CallStack):如果使用IDE(如Remix),查看合約調(diào)試器中的調(diào)用棧信息,看是哪個(gè)函數(shù)的執(zhí)行導(dǎo)致了`state`變化,以及調(diào)用該函數(shù)的上下文。*單步調(diào)試:在IDE中設(shè)置斷點(diǎn),逐步執(zhí)行代碼,觀察`state`變量在關(guān)鍵操作點(diǎn)(如函數(shù)入口、重要賦值語(yǔ)句前后)的值的變化。*檢查輸入?yún)?shù):確認(rèn)調(diào)用函數(shù)時(shí)傳入的參數(shù)是否正確,參數(shù)錯(cuò)誤可能導(dǎo)致邏輯異常。*檢查狀態(tài)變量初始化:確認(rèn)合約部署時(shí)狀態(tài)變量是否正確初始化。*查看事件日志:如果合約中定義了事件,檢查相關(guān)事件是否被正確觸發(fā),事件日志可以提供函數(shù)調(diào)用順序和參數(shù)信息。*分析代碼邏輯:仔細(xì)閱讀相關(guān)函數(shù)的代碼邏輯,特別是涉及`state`變量更新的部分,檢查是否存在并發(fā)問題、邊界條件處理不當(dāng)、條件判斷錯(cuò)誤等。*使用`etherscan`:查詢與該合約相關(guān)的交易,查看交易詳情和日志,確認(rèn)合約狀態(tài)變化的時(shí)間點(diǎn)和原因。第四部分:智能合約基礎(chǔ)知識(shí)與安全8.區(qū)別:*狀態(tài)變量(StateVariable):存儲(chǔ)在區(qū)塊鏈的狀態(tài)信息,占用Gas,每個(gè)區(qū)塊的最終狀態(tài)會(huì)被永久記錄。如`uint256balance;`。其值可以被合約內(nèi)的其他函數(shù)讀取和修改。*視圖函數(shù)(view):一種特殊函數(shù),通過`view`關(guān)鍵字聲明。它不會(huì)修改合約的任何狀態(tài),因此執(zhí)行時(shí)不需要消耗調(diào)用者的Gas(除了基本的讀取開銷)。主要用于讀取狀態(tài)變量或計(jì)算值,返回結(jié)果。調(diào)用者無需擔(dān)心其執(zhí)行會(huì)改變合約狀態(tài)。*純函數(shù)(pure):另一種特殊函數(shù),通過`pure`關(guān)鍵字聲明。它既不修改合約狀態(tài),也不讀取任何狀態(tài)變量。它的輸出完全取決于其輸入?yún)?shù),并且其執(zhí)行結(jié)果會(huì)被緩存,相同輸入多次調(diào)用返回相同結(jié)果,執(zhí)行時(shí)不需要消耗調(diào)用者的Gas。純函數(shù)通常用于計(jì)算,結(jié)果不寫入鏈上。9.
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025春季內(nèi)蒙古包頭市九原區(qū)機(jī)關(guān)事業(yè)單位引進(jìn)高層次和緊缺急需人才27人考前自測(cè)高頻考點(diǎn)模擬試題有完整答案詳解
- 2025國(guó)家三門峽黃河明珠(集團(tuán))有限公司招聘高校畢業(yè)生8人考前自測(cè)高頻考點(diǎn)模擬試題附答案詳解(典型題)
- 2025湖北恩施州恩施市福牛物業(yè)有限公司招聘恩施市金滿園農(nóng)業(yè)發(fā)展有限公司工作人員人員模擬試卷及答案詳解(各地真題)
- 2025年哈爾濱道里區(qū)工程社區(qū)衛(wèi)生服務(wù)中心招聘若干名考前自測(cè)高頻考點(diǎn)模擬試題及答案詳解(各地真題)
- 2025貴州省人民醫(yī)院第十三屆貴州人博會(huì)引進(jìn)人才10人模擬試卷及完整答案詳解一套
- 2025年福建省泉州市晉江市反邪教協(xié)會(huì)招聘1人模擬試卷及答案詳解(名師系列)
- 2025年濰坊諸城市恒益燃?xì)庥邢薰竟_招聘工作人員模擬試卷附答案詳解(完整版)
- 2025江西贛州市會(huì)昌縣正源建設(shè)有限責(zé)任公司招聘勞務(wù)派遣人員1人考前自測(cè)高頻考點(diǎn)模擬試題及答案詳解(歷年真題)
- 2025廣東廣州航海學(xué)院廣州交通大學(xué)(籌)招聘高層次人才(學(xué)科領(lǐng)軍人才)15人考前自測(cè)高頻考點(diǎn)模擬試題(含答案詳解)
- 2025年保險(xiǎn)銷售與理賠案例試卷及答案
- 2024-2025學(xué)年九年級(jí)化學(xué)人教版上冊(cè)檢測(cè)試卷(1-4單元)
- DB11 2076-2022 民用建筑節(jié)水設(shè)計(jì)標(biāo)準(zhǔn)
- 輔警考試題《公安基礎(chǔ)知識(shí)》綜合能力測(cè)試題(附答案)
- 高中數(shù)學(xué)重要函數(shù)圖像(共62個(gè)高考?jí)狠S題必考)
- 抖音來客商家門店經(jīng)營(yíng)
- 機(jī)動(dòng)車維修服務(wù)質(zhì)量統(tǒng)計(jì)信息報(bào)送制度
- 公司治理、內(nèi)部控制與非效率投資理論分析與經(jīng)驗(yàn)證據(jù)
- 現(xiàn)代低壓電器技術(shù) 課件 2. 常見低壓電器
- 高中新外研版單詞總表(必修123+選修1234)
- 催化重整(石油加工生產(chǎn)技術(shù)課件)
- (完整版)袱子的書寫格式和稱呼
評(píng)論
0/150
提交評(píng)論