Signature
使用 ECDSA 驗證智能合約內部的簽名
遵循使用 ECDSA 驗證乙太坊簽名的技術。
我想知道這裡是否有人可以在 Solidity 上看到這種方法的任何安全問題:
mapping(uint256 => bool) usedIDS; function claimTokens(uint256 amount, uint256 id, bytes memory sig) public { require(!usedIDS[id]); usedIDS[id] = true; bytes32 message = keccak256(abi.encodePacked(amount, id)); require(recoverSigner(message, sig) == expectedAddressWhichCreateSig); _mint(msg.sender, amount); }
更新後的版本:
function claimTokens(uint256 amount, uint256 nonce, bytes memory sig) public { require(!usedNonces[nonce]); usedNonces[nonce] = true; bytes32 message = keccak256(abi.encodePacked(msg.sender, amount, nonce, this)); require(recoverSigner(message, sig) == expectedAddressWhichCreateSig); _mint(msg.sender, amount); }
我找到了這個!這可能是 ECDSA 的一個潛在問題,但是,它可能被認為是整個區塊鏈以及其他使用 ECDSA 的技術的問題,對嗎?
ECDSA:如果 nonce 已知,則顯示私鑰 (NIST256p)
非常感謝您的寶貴時間!
一般來說,使用 ecrecover 沒有問題,最重要的部分是如何創建您簽名的雜湊(例如,將合約地址和鏈 id 包含到雜湊中以防止重放攻擊)
大多數錢包不允許您簽署可能是原始交易的數據。因此,您有幾個簽名標準。
要根據這些標準生成簽名,您可以使用現有的 rpc 方法(例如
eth_signTypedData
和eth_sign
)並在您的契約上驗證這些。
該功能存在明顯的前沿問題
claimTokens
。假設使用者 A 發送
claimTokens
帶有簽名消息作為sig
參數的交易。使用者 B(邪惡)在記憶體池中看到交易。要獲得屬於 A 的代幣,B 所要做的就是複制 A 的交易參數,包括,然後以比 A 更高的 gas 價格
sig
發送自己的交易。claimTokens
B 交易將首先被探勘,
msg.sender
在這種情況下,代幣將被鑄造到 - B。交易將因為以下原因而恢復require(!usedIDS[id])
我不同意另一個答案,並說在實際情況下,ECDSA 充滿了潛在的安全問題,並且是契約中最難解決的問題之一。我第一眼就看到了這個前沿問題,但我不會對這個實現中潛伏著其他安全問題或您可能想出的任何其他問題感到驚訝。使用 ECDSA 需要您自己(和您的使用者)承擔風險。