Solidity

送出/揭示如何解決搶先交易?

  • February 21, 2021

我試圖確保我理解正確,所以我會提出解決方案的問題。

問題:

假設commit已被呼叫。在此之後,我們呼叫reveal. 攻擊者監聽commit交易,並稱其commit為自己的前鋒。然後,攻擊者監聽reveal交易。攻擊者現在所做的是,一旦他發現reveal池中有一筆新交易,他就會抓取參數(這些是雜湊是如何派生的參數),對它們進行雜湊處理,如果它與已經儲存在他自己地址上的匹配當他呼叫 時commit,攻擊者也會搶先reveal交易。

解決方案:

我認為上述問題的唯一解決方案是我們msg.sender在獲取承諾雜湊時包含。這樣,即使攻擊者偵聽reveal交易並預先執行它,也不夠,因為msg.sender攻擊者會有所不同,並且不會產生與承諾相同的雜湊。

問題1:你怎麼看?我對上面的解決方案是正確的嗎?

問題 2:我看到了一些msg.sender在派生承諾散列時未包含的實現。這意味著front-run仍然存在,這意味著攻擊者front-runs commit,然後front-runs reveal。如果有很多交易發生,當然,這種預先執行對攻擊者沒有任何意義,但如果我們將其用於使用者送出解決方案並獲得的智能合約,我認為commit-reveal方案無法解決預先執行quiz獎勵,因為攻擊者可以再次收聽commit並且很可能無論誰送出,很可能是贏家,因此攻擊者還將等待reveal來自同一使用者commit的再次呼叫並搶先執行。你怎麼看待這件事 ?對我來說,對於測驗系統,commit/reveal似乎不是解決搶先交易的好方法。你能舉一些真正有用的例子嗎?**注意:**我知道這commit/reveal是一個很好的方案,但我需要一些例子來解決前端執行問題並且也不會msg.sender在散列中使用。

問題1:你怎麼看?我對上面的解決方案是正確的嗎?

同意。為了防止搶先,請使用msg.sender雜湊函式中的一個因子,這樣搶先者可以知道秘密,但仍然無法使用該知識。

例如,考慮一個存錢罐,其中包含一個可以釋放錢的秘密單詞。如果提款功能使用(偽)hash(secret),那麼領跑者可以學習密語並嘗試先提款。如果函式使用hash(msg.sender, secret),則防止搶先執行 - 必須從某個地址發送秘密 - 兩個因素而不是一個因素。

您還應該考慮契約如何執行獎勵的授予。考慮 msg.sender.transfer()rightPerson.transfer(). 您要確保效果是只有正確的帳戶才能真正獲勝。

對於某些應用程序,您可能希望任何人都可以支付 gas 費用以將資金推送給合適的人。假設 Alice 沒有理由想留下她的資金,而 Bob 想成為英雄並支付她的燃料費。只要契約確定資金的去向,這種方法就可以奏效。

mapping(bytes32 => unit) public pendingPayments;

function beAHero(address receiver, bytes32 secret) public {
 bytes32 key = keccak256(abi.encodePacked(receiver, secret));
 uint amount = pendingPayments[key];
 if(amount > 0) {
   pendingPayments[key] = 0;
   receiver.transfer(amount);
   // emit ...
 }
}

愛麗絲可以把她的秘密告訴鮑勃,而鮑勃所能做的就是支付汽油費,如果他願意的話。無論如何,愛麗絲都能拿到錢。如果receiver.transfer()是,msg.sender.transfer()那麼任何知道秘密的人都可以拿走 Alice 的錢,包括監聽未決交易的領跑者。

(只是一個塗鴉,所以請原諒我的錯別字)。

希望能幫助到你。

引用自:https://ethereum.stackexchange.com/questions/93727