
11月8日に、
Parityは、マルチシグウォレットの操作を担当するコードに重大なエラーを
発表しました。これは、一般にアクセス可能な
スマートコントラクトに基づいています。 これは2番目のケースです。
最初のケースは
2017年7
月19日に発生し、スマートコントラクトの脆弱性が見つかったため、150,000 ETHが撤回されました(
詳細はHabré )。
問題が何であり、約3億ドルがアクセスできなくなった理由を説明してみましょう。
マルチシグウォレットとはマルチシグ(自然)ウォレットは、プライベートキーの保護を強化する問題を解決するために作成されました。トランザクションには1つ以上のプライベートキーが必要なためです(一般的な形式ではNキーのうちM)。 3つのキーのうち2つがキーの場合の例:1つのキーはローカルに保存され、1つはクラウドに保存され、もう1つのバックアップは(人里離れた場所に)保存されます。 トランザクションを完了するには、2つのキーが必要です。
ここでもう少し読むことができ
ます。 GitHubユーザー
devops199は、スマートコントラクト
kill
メソッド(パリティウォレットライブラリ)と呼ばれる、公開されているスマートコントラクトのパブリックメソッドを実験しています。 GitHubの問題
#6995 。
この結果、合計約100万ETH(現在の為替レートで3億ドル)の584個のウォレットが「凍結」されました。つまり、それらからお金を転送する機会が失われました。
技術的には、彼は最初にinitWalletコントラクト初期化メソッドを呼び出しました
function initWallet(address[] _owners, uint _required, uint _daylimit) only_uninitialized { initDaylimit(_daylimit); initMultiowned(_owners, _required); }
only_uninitialized
修飾子
only_uninitialized
次のように説明されます
// throw unless the contract is not yet initialized. modifier only_uninitialized { if (m_numOwners > 0) throw; _; }
ただし、コントラクトを配置するとき、所有者のリストは初期化されず、
m_numOwners
変数は0
m_numOwners
た。
m_numOwners
のすべての操作の履歴は、
ここで表示でき
ますその結果、
devops199
を呼び出すと、
initWallet
が契約の所有者になることができ
devops199
た(ライブラリのスマートコントラクトアドレスで
msg.sender
と、所有者
msg.sender
、つまり
devops199
を持つ通常のウォレットになりました)。
次に、
kill
を実行して削除するだけで済みます。
// kills the contract sending everything to `_to`. function kill(address _to) onlymanyowners(sha3(msg.data)) external { suicide(_to); }
EVMの
suicide
操作は、契約を破棄し、残りの残高全体を指定された住所に転送するために使用されます。 同時に、
suicide
send
操作よりも効果的であり、ブロックチェーンの契約データからスペースを解放するため、負のガス値があります。
マルチシグウォレットのロジック全体は契約に依存していたため、2017年7月20日以降にウォレットを作成したすべての所有者(および7月20日以前に別の脆弱性があったため、これは実際にはすべてのユーザーです)が資金を転送する機能へのアクセスを失いましたパリティウォレットウォレット。 次のEthereumの分岐でのみエラーを修正できますが、もちろんこれは
起こりません 。
ライブラリのスマートコントラクトを公開するときにパリティが
kill
機能を削除すれば、この問題は簡単に回避できたと思います。 テスト時にのみ有用ですが、ターゲットシステムでは有用ではありません。
このようにして、Parity Walletウォレットと3億ドルの歴史は終わりました。
本番環境に渡す前に、テスト用のコードを削除することを忘れないでください!