www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 物聯(lián)網(wǎng) > 區(qū)塊鏈
[導(dǎo)讀] 本次教程主要展示在編寫智能合約時(shí)通常應(yīng)遵循的安全模式。 方案建議 以下建議適用于以太坊上任何智能合約系統(tǒng)的開(kāi)發(fā)。 外部調(diào)用 使用外部調(diào)用時(shí)需要格外注意 調(diào)

本次教程主要展示在編寫智能合約時(shí)通常應(yīng)遵循的安全模式。

方案建議

以下建議適用于以太坊上任何智能合約系統(tǒng)的開(kāi)發(fā)。

外部調(diào)用

使用外部調(diào)用時(shí)需要格外注意

調(diào)用不受信任的智能合約可能會(huì)帶來(lái)一些意外的風(fēng)險(xiǎn)或Bug。外部調(diào)用可能在該合約或它依賴的任何其他合約中執(zhí)行惡意代碼。因此,每個(gè)外部調(diào)用都應(yīng)視為潛在的安全風(fēng)險(xiǎn)。 如果無(wú)法或不希望刪除外部調(diào)用,請(qǐng)使用本節(jié)教程的建議將危險(xiǎn)降至最低。

標(biāo)記不受信任的合約

當(dāng)與外部合約進(jìn)行交互時(shí),請(qǐng)以清楚表明與它們進(jìn)行交互不安全的方式命名變量,方法和合約接口,適用于您自己的調(diào)用外部合約的函數(shù)。

// bad

Bank.withdraw(100); // Unclear whether trusted or untrusted

function makeWithdrawal(uint amount) { // Isn‘t clear that this funcTIon is potenTIally unsafe

Bank.withdraw(amount);

}

// good

UntrustedBank.withdraw(100); // untrusted external call

TrustedBank.withdraw(100); // external but trusted bank contract maintained by XYZ Corp

funcTIon makeUntrustedWithdrawal(uint amount) {

UntrustedBank.withdraw(amount);

}

避免外部調(diào)用后的狀態(tài)更改

無(wú)論使用原始調(diào)用(形式為someAddress.call())還是合約調(diào)用(形式為ExternalContract.someMethod()),都可能存在執(zhí)行惡意代碼的風(fēng)險(xiǎn)。 即使ExternalContract不是惡意的,惡意代碼也可以通過(guò)其調(diào)用的任何合約執(zhí)行。

一種特別的危險(xiǎn)是惡意代碼可能會(huì)劫持控制流,從而導(dǎo)致由于可重入而產(chǎn)生的漏洞。

如果要調(diào)用不受信任的外部合約,請(qǐng)避免在調(diào)用后更改狀態(tài)。這種模式有時(shí)也被稱為檢查效果交互模式。

避免使用transfer()和send()

.transfer()和.send()都會(huì)將2300gas轉(zhuǎn)發(fā)給收件人。這一硬編碼gas津貼的目的是防止重入漏洞,但這只有在gas成本不變的假設(shè)下才有意義。最近的EIP 1283(在最后一刻退出了君士坦丁堡硬叉)和EIP 1884(預(yù)計(jì)將在伊斯坦布爾硬叉中到達(dá))表明此假設(shè)無(wú)效。

為了避免將來(lái)gas成本發(fā)生變化時(shí)會(huì)產(chǎn)生問(wèn)題,最好改用.call.value(amount)(“”)。請(qǐng)注意,這無(wú)助于減輕重入攻擊,因此必須采取其他預(yù)防措施。

處理外部調(diào)用中的Bug

Solidity提供了適用于原始地址的低級(jí)調(diào)用方法:address.call(),address.callcode(),address.delegatecall()和address.send()。 這些低級(jí)方法從不拋出異常,但是如果調(diào)用遇到異常,則將返回false。 另一方面,合同調(diào)用(例如,ExternalContract.doSomething())將自動(dòng)傳播一個(gè)引發(fā)(例如,如果doSomething()引發(fā),則ExternalContract.doSomething()也將引發(fā))。

如果選擇使用低級(jí)調(diào)用方法,請(qǐng)確保通過(guò)檢查返回值來(lái)處理調(diào)用失敗的可能性。

// bad

someAddress.send(55);

someAddress.call.value(55)(“”); // this is doubly dangerous, as it will forward all remaining gas and doesn’t check for result

someAddress.call.value(100)(bytes4(sha3(“deposit()”))); // if deposit throws an excepTIon, the raw call() will only return false and transaction will NOT be reverted

// good

(bool success, ) = someAddress.call.value(55)(“”);

if(!success) {

// handle failure code

}

ExternalContract(someAddress).deposit.value(100)();

支持外部調(diào)用push

外部調(diào)用可能發(fā)生意外或者惡意BUG。為了最大限度地減少此類故障造成的損害,通常最好將每個(gè)外部調(diào)用隔離到自己的事務(wù)中,該事務(wù)可以由調(diào)用的接收者發(fā)起。這與支付尤其相關(guān),在支付中,最好讓用戶提取資金,而不是自動(dòng)向他們推送資金。(這也降低了GAS限制出現(xiàn)問(wèn)題的可能性)避免在一個(gè)事務(wù)中合并多個(gè)以太坊轉(zhuǎn)移。

// bad

contract auction {

address highestBidder;

uint highestBid;

function bid() payable {

require(msg.value 》= highestBid);

if (highestBidder != address(0)) {

(bool success, ) = highestBidder.call.value(highestBid)(“”);

require(success); // if this call consistently fails, no one else can bid

}

highestBidder = msg.sender;

highestBid = msg.value;

}

}

// good

contract auction {

address highestBidder;

uint highestBid;

mapping(address =》 uint) refunds;

function bid() payable external {

require(msg.value 》= highestBid);

if (highestBidder != address(0)) {

refunds[highestBidder] += highestBid; // record the refund that this user can claim

}

highestBidder = msg.sender;

highestBid = msg.value;

}

function withdrawRefund() external {

uint refund = refunds[msg.sender];

refunds[msg.sender] = 0;

(bool success, ) = msg.sender.call.value(refund)(“”);

require(success);

}

}

不要將調(diào)用委托給不受信任的代碼

delegateCall函數(shù)用于從其他合約調(diào)用函數(shù),就好像它們屬于調(diào)用方合約一樣。因此調(diào)用方可以改變調(diào)用地址的狀態(tài),這是存在風(fēng)險(xiǎn)。下面的示例演示了使用delegatecall如何導(dǎo)致合約的破壞和資金損失。

contract Destructor

{

function doWork() external

{

selfdestruct(0);

}

}

contract Worker

{

function doWork(address _internalWorker) public

{

// unsafe

_internalWorker.delegatecall(bytes4(keccak256(“doWork()”)));

}

}

如果使用已部署的Destructor合約的地址作為參數(shù)調(diào)用Worker.doWork(),則Worker合約將自毀。 僅將執(zhí)行委托給受信任的合約,而不委托給用戶提供的地址。

不要假設(shè)合約是用零余額創(chuàng)建的,攻擊者可以在創(chuàng)建合約之前將以太坊發(fā)送到該合約的地址。

請(qǐng)記住,可以強(qiáng)制將以太坊發(fā)送到一個(gè)帳戶

小心編寫嚴(yán)格檢查智能合約的余額的不變量。

攻擊者可以強(qiáng)行將以太坊發(fā)送到任何帳戶,并且這是無(wú)法避免的(即使使用執(zhí)行revert()的回退函數(shù)也無(wú)法阻止)。

攻擊者可以通過(guò)創(chuàng)建合約,用1 wei資助該合約并調(diào)用selfdestruct(victimAddress)來(lái)實(shí)現(xiàn)此目的。在victimaddress中沒(méi)有調(diào)用任何代碼,因此無(wú)法阻止它。發(fā)送到礦工的地址的區(qū)塊獎(jiǎng)勵(lì)也是如此,該地址可以是任意地址。

此外,由于可以預(yù)先計(jì)算合約地址,因此可以在部署合約之前將以太坊發(fā)送到某個(gè)地址。

請(qǐng)記住,鏈上數(shù)據(jù)是公開(kāi)的

許多應(yīng)用程序要求提交的數(shù)據(jù)在某個(gè)時(shí)間點(diǎn)之前都是隱匿的。游戲(如鏈上剪刀石頭布)和拍賣機(jī)制(如競(jìng)價(jià)拍賣)兩大類例子。如果您在構(gòu)建隱私問(wèn)題的應(yīng)用程序,請(qǐng)確保避免用戶過(guò)早公布信息。最好的策略是使用具有不同階段的承諾方案:首先使用值的哈希值進(jìn)行提交,然后在后續(xù)階段中顯示值。

例子:

在剪刀石頭布上,要求兩個(gè)玩家先提交其預(yù)期動(dòng)作的哈希值,然后要求兩個(gè)玩家均提交其動(dòng)作;如果提交的動(dòng)作與散列不匹配,則將其丟棄。

在拍賣中,要求玩家在初始階段提交其出價(jià)值的哈希值(以及大于其出價(jià)值的保證金),然后在第二階段提交其拍賣出價(jià)。

開(kāi)發(fā)依賴于隨機(jī)數(shù)生成器的應(yīng)用程序時(shí),順序應(yīng)始終為(1)玩家提交動(dòng)作,(2)生成隨機(jī)數(shù),(3)玩家支付。產(chǎn)生隨機(jī)數(shù)的方法本身就是積極研究的領(lǐng)域。當(dāng)前同類最佳的解決方案包括比特幣區(qū)塊頭(通過(guò)http://btcrelay.org驗(yàn)證),哈希提交顯示方案(即,一方生成數(shù)字,發(fā)布其哈希值以“提交”給該值,以及然后顯示價(jià)值)和RANDAO。由于以太坊是確定性協(xié)議,因此協(xié)議中的任何變量都不能用作不可預(yù)測(cè)的隨機(jī)數(shù)。還應(yīng)注意,礦工在某種程度上控制著block.blockhash()值*。

注意某些參與者可能“下線”而不上線的可能性

不要依賴于由特定方執(zhí)行特定操作的退款或索賠程序,而沒(méi)有其他方法將資金取出。例如在石頭剪刀布游戲中,一個(gè)常見(jiàn)的錯(cuò)誤是在兩個(gè)玩家都提交動(dòng)作之前不進(jìn)行支付。 但是惡意的玩者可以通過(guò)根本不提交自己的舉動(dòng)來(lái)“困擾”對(duì)方-實(shí)際上,如果一個(gè)玩者看到了對(duì)方顯示的舉動(dòng)并確定自己輸了,則根本沒(méi)有理由提出自己的舉動(dòng)。

(1)提供一種規(guī)避未參與參與者的方法,可能會(huì)在一定時(shí)限內(nèi)進(jìn)行;

(2)考慮為參與者在其所處的所有情況下提交信息提供額外的經(jīng)濟(jì)激勵(lì)。

注意負(fù)整數(shù)取反

solidity提供了幾種處理有符號(hào)整數(shù)的類型。與大多數(shù)編程語(yǔ)言一樣,在solidity中,帶n位的有符號(hào)整數(shù)可以表示從-2^(n-1)到2^(n-1)-1的值。這意味著MIN_INT沒(méi)有正等價(jià)物。求反是通過(guò)找到一個(gè)數(shù)字的兩個(gè)補(bǔ)數(shù)實(shí)現(xiàn)的,因此,最負(fù)數(shù)的求反將得出相同的值。

contract Negation {

function negate8(int8 _i) public pure returns(int8) {

return -_i;

}

function negate16(int16 _i) public pure returns(int16) {

return -_i;

}

int8 public a = negate8(-128); // -128

int16 public b = negate16(-128); // 128

int16 public c = negate16(-32768); // -32768

}

處理此問(wèn)題的一種方法是,在求反之前檢查變量的值,如果該值等于最小整數(shù),則拋出。另一種選擇是確保使用容量更大的類型(例如int32而不是int16)永遠(yuǎn)不會(huì)達(dá)到最大負(fù)數(shù)。

當(dāng)min_int乘以或除以-1時(shí),int類型也會(huì)出現(xiàn)類似的問(wèn)題。
來(lái)源: 區(qū)塊鏈研究實(shí)驗(yàn)室?

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見(jiàn),不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開(kāi)關(guān)電源具有效率高的特性,而且開(kāi)關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開(kāi)關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉