如何在硬分叉後使用提款合 約將我的 The DAO 代幣轉換為乙太幣?
DAO 合約於 2016 年 6 月 17 日遭到攻擊,攻擊者利用DAO 合約程式碼中的遞歸呼叫漏洞耗盡了價值約5000 萬美元的乙太幣。
攻擊者將被盜的乙太幣轉移到幾個子 DAO 中,而羅賓漢集團將剩餘的資金轉移到其他子 DAO 中。
硬分叉計劃在#1,920,000 區塊(大約 24 小時內,約 20/07/2016 澳大利亞東部標準時間 23:26)將乙太幣從 The DAO 合約及其子 DAO 轉移到提款合約中。
一旦硬分叉通過,我如何將我的 The DAO 代幣轉換為乙太幣?
DAO 退款
- $$ THIS $$ 如何在硬分叉後使用提款合約將我的 The DAO 代幣轉換為乙太幣?
- 我如何獲得超過 1 乙太幣到 100 The DAO 代幣的退款
- 我的 The DAO 代幣被拆分為子 DAO,如何獲得退款?
- 如何將我的 The DAO 代幣轉換為 Ethereum Classic 鏈上的乙太幣?
- 如何在硬分叉後有條件地將乙太幣發送到另一個帳戶以保護自己免受重放攻擊
更新時間 2016 年 7 月 20 日 13:31 UTC
取款合約的餘額為 11,597,664.781027947 乙太幣(145,318,739.71 美元)。
一次成功的硬分叉。祝大家硬分叉快樂!開發人員和其他相關人員做得很好。
更新時間 2016 年 7 月 20 日 22:31 UTC
取款合約現在的餘額為 6,369,298.685677664 乙太幣(79,807,312.53 美元)。現在大約 45% 的 DAO 已轉換為 ETH,超過 1,506 筆交易。
更新時間 2016 年 7 月 23 日 18:04 UTC
取款合約現在的餘額為 4,595,418.245476871 乙太幣(65,944,251.82 美元)。現在大約 60% 的 DAO 已轉換為 ETH,超過 3,887 筆交易。
這是來自https://slacknation.github.io/medium/11/11.html的圖表:
更新時間 2016 年 8 月 1 日 23:18 UTC
更新時間 2016 年 9 月 6 日 14:58 UTC
剩餘 13.55% 的餘額。
2017 年 3 月 29 日更新
最新說明可在The DAO Refunds中找到。
筆記
- 此提款合約僅允許以 100 個 DAO = 1 ETH 的比率將 The DAO 代幣 (DAO) 轉換為乙太幣 (ETH)。
- 提款合約的編碼方式意味著您必須批准您賬戶中所有 DAO 的轉移,因為提款合約只會一次性轉移您的所有 DAO。如果你不批准你所有的 DAO 被轉移,該
withdraw()
函式將拋出一個錯誤,消耗交易指定的所有氣體。- 在 DAO 眾籌階段的最後兩週購買 DAO 的任何人每 100 個 DAO 支付超過 1 ETH。每 100 個 DAO 超過 1 ETH 的金額儲存在 The DAO 的extraBalance 帳戶中。extraBalance 賬戶的餘額現已轉入管理員的多重簽名錢包。
對於每 100 個 DAO 支付超過 1 ETH 的購買者,有一個單獨的流程可以退還已支付的額外金額(超過每 100 個 DAO 1 ETH)。此答案未涵蓋此過程,但請放心,開發人員正在盡最大努力將多餘的資金公平地分配給原始 DAO 購買者。
請參閱如何獲得我支付的超過 1 乙太幣到 100 DAO 代幣的退款,這將在進一步詳細資訊公佈時更新。
- 如果您從 The DAO 執行了合法拆分,您的 DAO 餘額已移至子 DAO,並且您在 The DAO 中的 DAO 餘額為零。由於您在 The DAO 中的 DAO 餘額為零,因此您將無法使用本問答中的程序將您的 DAO 轉換為 ETH。
請參閱如何獲得拆分為子 DAO 的 The DAO 代幣的退款?因為您需要聯繫 TheDAOCurator 以便他們安排您的退款。
- 在硬分叉之後等待一段時間,然後再嘗試將您的 DAO 轉換為 ETH。提款沒有最後期限。最安全的做法是等待。
更新 2016 年 10 月 26 日 06:33一些 DAO -> ETH 交易由於舍入錯誤而失敗。請參閱為什麼我的 DAO 到 ETH 退款失敗?.
提款方式一 - MyEtherWallet
- 訪問http://www.myetherwallet.com/#the-dao
- 上傳/粘貼您的 Keystore 文件/私鑰以訪問您的錢包。
- 按大紅色按鈕。
- 確認您確定要退出。
- 等待幾秒鐘,將出現 2 個交易連結。再等大約 30 秒,然後在 Etherscan 上檢查您的帳戶餘額。你應該有更多的 ETH 和 0 DAO。我(@tayvano)使用 MyEtherWallet 捐贈帳戶確認它在太平洋夏令時間上午 6:43 有效:http: //etherscan.io/address/0x7cb57b5a97eabe94205c07890be4c1ad31e486a8
提現方式二——乙太坊錢包
Griff Green的(循環引用的)文章How to use the Withdraw Contract with Mist提供了類似於以下說明的分步絲網印刷指南。
確保您已下載Ethereum Wallet 0.8.1或更高版本。
第一次啟動乙太坊錢包 0.8.1 時,對問題“你想啟動與漏洞相關的資金恢復到可以由 The DAO 代幣持有者提取的契約的鏈嗎?”選擇“是”。 . 您現在已經選擇使用硬分叉的乙太坊鏈。
如果 Ethereum Wallet 凍結,請參閱2016 年 7 月 23 日更新,如何從 Ethereum Wallet (Mist) 監視列表中刪除 DAO 合約,因為它正在凍結?.
如果您尚未在 The DAO 合約上添加監視,請參閱The DAO - 如何添加和監視 DAO 合約。此步驟將允許您批准將 DAO 轉移到提款合約。
如果找不到下面需要的Approve函式,請使用上面的步驟重新載入 The DAO 合約的 JSON 介面。如果您在使用乙太坊錢包時遇到凍結顯示的問題,請嘗試從乙太坊錢包中移除 The DAO 合約(如何從乙太坊錢包 (Mist) 關注列表中移除 The DAO 合約,因為它正在凍結?),然後再次觀看 The DAO 合約.
在 The DAO 提款合約上添加手錶。使用與上面連結中相同的過程,但設置:
- 契約名稱:
The DAO Withdrawal
- 合約地址:
0xbf4ed7b27f1d666546e30d74d50d173d20bca754
- JSON介面:
[{"constant":false,"inputs":[],"name":"trusteeWithdraw","outputs":[],"type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"mainDAO","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"trustee","outputs":[{"name":"","type":"address"}],"type":"function"}]
23:47 20/07/2016 AEST - 我已確認以下使用乙太坊錢包的過程有效
批准將您的 DAO 轉移到提款合約
- 獲取您想要將 DAO 轉換為 ETH 的賬戶地址
- 在 Wallet 菜單下,選擇要將 DAO 轉換為 ETH 的賬戶。
- 點兩下帳戶地址,然後使用 Linux 或 Windows 中的 Control-C 或 MacBook 上的 Command-C 將地址複製到剪貼板。
- 獲取您想要將 DAO 轉換為 ETH 的賬戶餘額
- 在合約菜單中,選擇 The DAO 合約。
- 向下滾動到左側“從合約讀取”列下的“餘額”功能。
- 將剪貼板中的地址粘貼到所有者地址欄位中。
- 點兩下顯示的餘額,然後在 Linux 或 Windows 中使用 Control-C 或在 MacBook 上使用 Command-C 將餘額複製到剪貼板。
- 批准將您賬戶的 DAO 餘額轉移到提款合約地址
- 在合約菜單中,選擇 The DAO 合約。
- 在右側的 Write To Contract 列下,選擇Approve功能。
- 使用 Linux 或 Windows 中的 Control-V 或 MacBook 上的 Command-V將剪貼板中的餘額粘貼到數量 256 位無符號整數欄位中。
0xbf4ed7b27f1d666546e30d74d50d173d20bca754
在支出者地址欄位中輸入提款合約地址。- 在Execute from欄位下,選擇要將 DAO 轉換為 ETH 的賬戶。
- 將發送 ETHER欄位保留為 0。
- 點擊執行並輸入您的帳戶密碼。
- 您應該會收到一條交易確認消息。
執行提現合約功能
- 從提款合約中提取 ETH
- 在合約菜單中,選擇 The DAO 提款合約
- 在右側的 Write To Contract 列下,選擇Withdraw功能。
- 在Execute from欄位下,選擇要將 DAO 轉換為 ETH 的賬戶。
- 點擊執行並輸入您的帳戶密碼。
- 您應該會收到一條交易確認消息。
- 稍等片刻,您的乙太幣餘額應該會更新。如果沒有,請重啟乙太坊錢包。
提款方式3 -
geth
確保您執行的是
geth
1.4.10或更高版本。並使用該選項執行您的geth
命令,--support-dao-fork
以便您位於硬分叉區塊鏈上。例如:geth --support-dao-fork console
該
--support-dao-fork
設置在 的單獨執行之間保持不變geth
,因此您只需指定一次此參數。使用確認您的
geth
版本user@Kumquat:~$ geth version Geth Version: 1.4.10-stable Protocol Versions: [63 62] Network Id: 1 Go Version: go1.5.1 OS: linux
這是
geth
用於將您的 DAO 轉換為您帳戶的 ETH的過程{x}
。00:14 21/07/2016 AEST - 我已確認以下使用過程
geth
有效geth --support-dao-fork --unlock {your account} console ... Unlocking account {your account} Passhrase: {enter your passphrase} // Allow your blockchain to sync > var account = "{your account}"; undefined > var theDAOAddress = "0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413"; undefined > var theDAOWithdrawalAddress = "0xbf4ed7b27f1d666546e30d74d50d173d20bca754"; undefined > var theDAOABIFragment = [{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_amount","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"type":"function"}, {"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"type":"function"}]; undefined > var theDAO = web3.eth.contract(theDAOABIFragment).at(theDAOAddress); undefined > var approve = theDAO.approve(theDAOWithdrawalAddress, theDAO.balanceOf(account), {from: account}); undefined > eth.getTransaction(approve); // Repeat the command above until you see that blockNumber is not null // Wait a few blocks (~ 15 seconds each) for your approve transaction to get mined > var theDAOWithdrawalABIFragment = [{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"type":"function"}]; undefined > var theDAOWithdrawal = web3.eth.contract(theDAOWithdrawalABIFragment).at(theDAOWithdrawalAddress); undefined > var withdrawal = theDAOWithdrawal.withdraw({from: account}); undefined > eth.getTransaction(withdrawal); // Repeat the command above until you see that blockNumber is not null // Wait a few blocks (~15 second each) and check your new account balance web3.fromWei(eth.getBalance(account), "ether") 11.023456789012345678
提現方式四——Mist 瀏覽器模式下的乙太坊錢包
確保您已下載Ethereum Wallet 0.8.1或更高版本。
第一次啟動乙太坊錢包 0.8.1 時,對問題“你想啟動與漏洞相關的資金恢復到可以由 The DAO 代幣持有者提取的契約的鏈嗎?”選擇“是”。 . 您現在已經選擇使用硬分叉的乙太坊鏈。退出乙太坊錢包。
現在在 Mist 瀏覽器模式下執行乙太坊錢包,使用您安裝軟體的子目錄中的以下命令:
- 在 Linux 和 MacBook 中
./Ethereum-Wallet --mode mist &
- 在 Windows 中
Ethereum-Wallet --mode mist
(或者,您可以直接下載Mist 瀏覽器- 請參閱
@johnmardlin
下面的答案)。然後:
- 確保您只選擇了用於購買“The DAO”代幣的帳戶。
- 在 Mist 中瀏覽到https://slacknation.github.io/medium/12/12.html
- 點擊“批准”,等待一個塊
- 點擊“退款”,等待一個塊
(根據@slacknation 在https://www.reddit.com/r/ethereum/comments/4tx13d/how_do_i_withdraw_dao_tokens_eth_after_hf_update/中的要求添加了方法 4 )
提現流程說明
將您的 DAO 轉換為 ETH 有兩個步驟。
a) 批准將 DAO 從 DAO 轉移到提款合約
第一步是批准將 DAO 從 The DAO 轉移到提款合約中。這是通過呼叫 DAO 的
approve(...)
函式來完成的,如下所示:來自 The DAO 的原始碼,這裡是 TokenInterface.approve() 函式定義:
/// @notice `msg.sender` approves `_spender` to spend `_amount` tokens on /// its behalf /// @param _spender The address of the account able to transfer the tokens /// @param _amount The amount of tokens to be approved for transfer /// @return Whether the approval was successful or not function approve(address _spender, uint256 _amount) returns (bool success);
這是實現上面定義的函式的 Token.approve(…) 函式:
function approve(address _spender, uint256 _amount) returns (bool success) { allowed[msg.sender][_spender] = _amount; Approval(msg.sender, _spender, _amount); return true; }
一旦你呼叫了 The DAO 的approve(…) 函式,你就為取款合約創建了一個批准,以將你的 DAO 轉移到取款合約中。
b) 使用提款合約將您的 DAO 轉換為 ETH
第二步是呼叫Withdrawal合約的
withdraw()
函式將DAOs從The DAO轉移到Withdrawal合約中,並讓Withdrawal合約向您的賬戶發送等值的ETH。以下是該
withdraw()
函式的原始碼:function withdraw(){ uint balance = mainDAO.balanceOf(msg.sender); if (!mainDAO.transferFrom(msg.sender, this, balance) || !msg.sender.send(balance)) throw; }
資訊來源
thedao.slack.com 的使用者@lefteris表示,DAO 提現合約可以在0xbf4ed7b27f1d666546e30d74d50d173d20bca754找到,將 DAO 轉換為 ETH 的過程如下:
a) call dao.approve("0xbf4ed7b27f1d666546e30d74d50d173d20bca754", dao.balanceOf(youraccount)) b) call withdrawContract.withdraw()
提現合約源碼及地址
提款合約的原始碼可以在0xbf4ed7b27f1d666546e30d74d50d173d20bca754找到,如下:
contract DAO { function balanceOf(address addr) returns (uint); function transferFrom(address from, address to, uint balance) returns (bool); uint public totalSupply; } contract WithdrawDAO { DAO constant public mainDAO = DAO(0xbb9bc244d798123fde783fcc1c72d3bb8c189413); address public trustee = 0xda4a4626d3e16e094de3225a751aab7128e96526; function withdraw(){ uint balance = mainDAO.balanceOf(msg.sender); if (!mainDAO.transferFrom(msg.sender, this, balance) || !msg.sender.send(balance)) throw; } function trusteeWithdraw() { trustee.send((this.balance + mainDAO.balanceOf(this)) - mainDAO.totalSupply()); } }
來自 The DAO 的原始碼(上面引用過),這裡是
Token.transferFrom(...)
函式:function transferFrom( address _from, address _to, uint256 _amount ) noEther returns (bool success) { if (balances[_from] >= _amount && allowed[_from][msg.sender] >= _amount && _amount > 0) { balances[_to] += _amount; balances[_from] -= _amount; allowed[_from][msg.sender] -= _amount; Transfer(_from, _to, _amount); return true; } else { return false; } }
一些進一步的參考資料