Как условно отправить эфиры на другую учетную запись после хард-форка, чтобы защитить себя от повторных атак

Контракт DAO подвергся атаке 17 июня 2016 года, когда злоумышленник похитил эфиры на сумму около 50 миллионов долларов США , используя уязвимость рекурсивного вызова в коде контракта DAO.

Злоумышленник слил украденные эфиры в несколько дочерних DAO, а группа Робин Гуда слила оставшиеся средства в другие дочерние DAO.

Блокчейн Ethereum был подвергнут хард- форку в блоке 1 920 000 20 июля 2016 года для передачи эфиров из контракта DAO и его дочерних DAO в контракт WithdrawDAO .

В то время как большинство клиентов узлов Ethereum используют блокчейн с хардфорком (ETH), меньшинство клиентов узлов Ethereum использует классический блокчейн без хардфорка (ETC).

Клиенты узлов Ethereum могут быть настроены на использование блокчейна с хард-форком или блокчейна без хард-форка. Некоторые узлы были настроены для ретрансляции транзакций из разветвленной цепочки блоков в неразветвленную цепочку блоков и наоборот. Транзакции, выполненные в блокчейне ETH, с высокой вероятностью будут воспроизведены в блокчейне ETC, а транзакции в блокчейне ETC с высокой вероятностью будут воспроизведены в блокчейне ETH.

Несколько сплит-контрактов были развернуты по одному и тому же адресу контракта как в блокчейнах с хард-форком, так и в блокчейнах без хард-форка.

Как вы используете эти сплит-контракты для условной отправки эфиров на другие учетные записи либо в цепочке ETH с хард-форком, либо в цепочке ETC Classic без хард-форка?



Возврат средств DAO

Не вижу разницы в этих двух темах.
Я не эксперт по солидности, но как атрибут стал методом?
@XavierCombelle: общедоступная переменная состояния, такая как forked, получает автоматически сгенерированный метод доступа в Solidity.
@eth Я понимаю, это выглядит как плохой дизайн солидности, если он пытается быть вдохновленным python: он явно нарушает явный девиз лучше, чем неявный
@XavierCombelle Я не думаю, что Solidity пытается быть похожей на Python (девиз нарушается в других местах, таких как msgи txпеременные). Не стесняйтесь задавать вопросы и добро пожаловать на сайт!

Ответы (2)

Обновление от 02 июня 2017 г.

Из ПРЕДУПРЕЖДЕНИЯ: НЕ используйте SafeConditionalHFTransfer! Или используйте его правильно :

SafeConditionalHFTransfer сэкономил много эфиров, неправильно перемещенных по неправильной цепочке после хардфорка DAO . На данный момент через SafeConditionalHFTransfer по адресу 0x1e143b2588705dfea63a17f2032ca123df995ce0 прошло 20549 txns + 16022 internalTxns . Автор связался со мной сегодня утром по поводу 67 317,257581981046981598 ETH ~ 14 892 596,89 долларов США (@ $ 221,23 / ETH), отправленных неправильно в контракт.

При использовании этого контракта вы должны вызывать функции classicTransfer(...)или transfer(...)для направления вашего ETH или ETC в предполагаемую цепочку. Если вы отправляете ETH (или ETC) НАПРЯМУЮ на адрес контракта, ваш ETH (или ETC) не будет перенаправлен на адрес назначения в цепочке назначения, а вместо этого останется в этом контракте НАВСЕГДА.

Поскольку последние клиенты в цепочках ETH и ETC имеют встроенную защиту от воспроизведения EIP155 , вам НЕ нужно больше ее использовать SafeConditionalHFTransfer. Просто убедитесь, что вы используете последний клиент с EIP155!

Вот основные клиенты и версии, реализующие EIP155:

Это предупреждение также было размещено в верхней части ответа на вопрос « Как условно отправить эфиры на другую учетную запись после хард-форка, чтобы защитить себя от повторных атак» .



Обновление от 26 ноября 2016 г. — см. ответ @eth на вопрос выше, так как в версии geth1.5.3 реализована защита от повторных атак.



Резюме

  • Используйте метод 1 ниже, если вы хотите использовать gethдля передачи эфиров в классическую сеть с хард-форком ИЛИ без хард-форка через SafeConditionalHFTransferконтракт.
  • Используйте метод 2 ниже, если вы хотите использовать gethдля передачи эфиров в классическую сеть с хард-форком и без хард-форка через ReplaySafeSplitV2контракт.
  • Используйте метод 3 ниже, если вы хотите использовать кошелек Ethereum для перевода эфиров в цепочку Classic с хард-форком ИЛИ без хард-форка через SafeConditionalHFTransferконтракт.
  • Используйте метод 4 ниже, если вы хотите использовать кошелек Ethereum для перевода эфиров в классическую сеть с хард-форком и без хард-форка через ReplaySafeSplitV2контракт. Любая учетная запись может быть вашей исходной учетной записью, чтобы средства отправлялись обратно на вашу учетную запись в одной из цепочек.
  • Приведенные выше методы основаны на том, что некоторые узлы Ethereum передают транзакции из цепочки с хард-форком в цепочку без хард-форка или наоборот. Если транзакции перестанут ретранслироваться в другую сеть, транзакция будет выполняться только в цепочке, по которой передает ваш узел Ethereum.
  • ПРЕДУПРЕЖДЕНИЯ
    • Сначала переведите небольшую тестовую сумму
    • Если вы хотите, чтобы ваши транзакции выполнялись в обеих цепочках, переводите только суммы, которые не превышают баланс вашего счета до хард-форка.
  • ВОПРОСЫ

    • Если вы переведете сумму эфира, которая превышает баланс вашего счета в одной из цепочек, транзакция будет отклонена в этой цепочке, но выполнена в другой цепочке. Это приведет к тому, что ваша транзакция не будет синхронизирована в обеих цепочках, и вы не сможете автоматически выполнять транзакции в обеих цепочках. См. Проблема после вывода не хардфорка Эфириума .
    • Если ваши транзакции не выполняются в обеих цепочках, ваш одноразовый номер транзакции может быть не синхронизирован в обеих цепочках. Если вы все еще хотите выполнять транзакции в ДРУГОЙ цепочке, вам нужно будет синхронизировать клиент вашего узла Ethereum с этой ДРУГОЙ цепочкой.
  • Если вы хотите отправить предварительно хардфорк ETC на учетную запись Exchange ETC

    1. Для этого вы можете использовать свой support-hard-forkили oppose-hard-forkклиент узла Ethereum.
    2. На сайте биржи получите адрес депозита ETC.
    3. Используйте classicTransferметод gethили « Перевод только в классической цепочке без жесткого форка» в кошельке Ethereum .
    4. Сначала переведите небольшую тестовую сумму. Проверьте свою учетную запись ETH в обозревателе блокчейнов (например , http://etherscan.io/ ), и вы заметите, что с вашей учетной записи списана лишь небольшая сумма в счет стоимости газа по SafeConditionalHFTransferконтракту, возвращающему ваш ETH.
    5. Вам придется немного подождать, прежде чем транзакция ETC появится на вашем биржевом депозитном адресе ETC, поскольку ретрансляция добавляет небольшую задержку к транзакции, появляющейся в цепочке ETC.



Обновление от 25 августа 2016 г.

Ethereum Wallet и Mist Beta 0.8.2 теперь имеют функцию предотвращения повторного воспроизведения:

Предотвращение повторного воспроизведения

Мы добавили расширенную функцию для предотвращения повторного воспроизведения ваших транзакций в других цепочках, таких как ethereum classic. Это позволяет вам либо вообще предотвратить этот перевод на Classic, либо использовать эту транзакцию для отправки той же суммы на другой контракт, например, на вновь созданную учетную запись или на биржу. Если вы хотите полностью разделить все свои транзакции, мы рекомендуем вам создать две новые учетные записи, одну для собственно Ethereum, а другую для Classic, а затем перевести на них все свои средства (помните, что для перемещения токенов вам нужен эфир), убедившись, что каждая аккаунт имеет 0 эфиров в другой цепочке — если сделать это один раз, любая будущая транзакция не будет воспроизведена. Чтобы использовать это, используйте кнопку «Дополнительные параметры» на странице отправки.

Эта функция также поддерживает разделение токенов, но она очень экспериментальная и работает не со всеми токенами. Поскольку все это делается с помощью контракта, сначала вам нужно разрешить этому контракту перемещать токены от вашего имени, нажав «Подтвердить передачу токена».

Как всегда, эти функции являются экспериментальными и должны быть сначала протестированы на небольших количествах . Хотя большинство транзакций воспроизводятся в обеих цепочках, некоторые могут не воспроизводиться по нескольким причинам. Кроме того, на некоторых биржах возникают проблемы с получением эфира с адреса контракта — если это ваш случай, свяжитесь с биржей.

Мы также удалили весь код форка из приложения Mist, поэтому, если вы хотите использовать его, Ether Classic вам придется либо загрузить Classic Mist непосредственно из их репозитория, либо использовать свой собственный узел в качестве серверной части для вашего кошелька (как Ethereum Wallet, так и Ethereum Wallet). и Mist может подключиться к любому узлу), как и в случае с частной сетью.

Контракт защиты от воспроизведения можно найти по адресу 0x1ca4a86bba124426507d1ef67ad271cc5a02820a .



Метод 1 — использование gethи SafeConditionalHFTransferконтракт

Убедитесь, что вы используете версию geth 1.4.10 или более позднюю. И запустите свои команды geth с параметром --support-dao-fork, чтобы вы находились на хард-форке блокчейна. Для передачи с помощью функций transfer(...)или :classicTransfer(...)

user@Kumquat:~$ geth console
// Allow chain to sync
var fromAccount = "{from account}";
var toAccount = "{to account}";
var amount = web3.toWei(1.123, "ether");
personal.unlockAccount(fromAccount, "{password}")

var safeConditionalHFTransferAddress = "0x1e143b2588705dfea63a17f2032ca123df995ce0";
var safeConditionalHFTransferABI = [{"constant":false,"inputs":[{"name":"to","type":"address"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"}],"name":"classicTransfer","outputs":[],"type":"function"},{"inputs":[],"type":"constructor"}];
var safeConditionalHFTransfer = eth.contract(safeConditionalHFTransferABI).at(safeConditionalHFTransferAddress);    

// WARNING - Run the next statement to transfer ETH on the hard-forked chain
// This will only cost some gas on the non-hard-forked ETC Classic chain
// Test with a small amount first
var transfer = safeConditionalHFTransfer.transfer(toAccount, {from: fromAccount, value: amount});
console.log(transfer);

// WARNING - Run the next statement to transfer ETC on the non-hard-forked Classic chain
// This will only cost some gas on the hard-forked ETH chain
// Test with a small amount first
var classicTransfer = safeConditionalHFTransfer.classicTransfer(toAccount, {from: fromAccount, value: amount});
console.log(classicTransfer);



Способ 2 — использование gethи ReplaySafeSplitV2контракт

Убедитесь, что вы используете версию geth 1.4.10 или более позднюю. И запустите свои команды geth с параметром --support-dao-fork, чтобы вы находились на хард-форке блокчейна. Для передачи с помощью split(...)функции:

user@Kumquat:~$ geth console
// Allow chain to sync
var fromAccount = "{from account}";
var toAccountFork = "{to account on forked chain}";
var toAccountNoFork = "{to account on non-forked chain}";
var amount = web3.toWei(1.123, "ether");
personal.unlockAccount(fromAccount, "{password}")

var replaySafeSplitV2Address = "0xaBbb6bEbFA05aA13e908EaA492Bd7a8343760477";
var replaySafeSplitV2ABI = [{"constant":false,"inputs":[{"name":"targetFork","type":"address"},{"name":"targetNoFork","type":"address"}],"name":"split","outputs":[{"name":"","type":"bool"}],"type":"function"}];
var replaySafeSplitV2 = eth.contract(replaySafeSplitV2ABI).at(replaySafeSplitV2Address);    

var transfer = replaySafeSplitV2.split(toAccountFork, toAccountNoFork, {from: fromAccount, value: amount});
console.log(transfer);



Способ 3 — Использование кошелька Ethereum и SafeConditionalHFTransferконтракта

Обратите внимание, что приведенный ReplaySafeSplitV2ниже контракт имеет больше встроенных функций безопасности.

Убедитесь, что вы загрузили Ethereum Wallet 0.8.1 или более позднюю версию.

При первом запуске Ethereum Wallet 0.8.1 выберите «Да» на вопрос «Хотите ли вы активировать цепочку, в которой средства, связанные с эксплойтом, восстанавливаются в контракт, где они могут быть сняты держателями токенов The DAO?» . Теперь вы сделали выбор в пользу использования хард-форка Ethereum.

В Ethereum Wallet выберите страницу КОНТРАКТЫ в верхнем меню. Нажмите ПОСМОТРЕТЬ КОНТРАКТ.

  • Введите НАЗВАНИЕ КОНТРАКТАSafeConditionalHFTransfer
  • Введите ДОГОВОРНЫЙ АДРЕС0x1e143b2588705dfea63a17f2032ca123df995ce0
  • Введите в JSON INTERFACE следующий текст[{"constant":false,"inputs":[{"name":"to","type":"address"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"}],"name":"classicTransfer","outputs":[],"type":"function"},{"inputs":[],"type":"constructor"}]
  • Нажмите «ОК». Ваш Watch Contract должен выглядеть так:

введите описание изображения здесь


Для передачи только по цепочке с жестким форком

Это переведет ваш ETH на целевой счет в сети с жестким форком и будет стоить вам только газа в классической цепочке без жесткого форка.

Выберите страницу КОНТРАКТЫ в верхнем меню. Нажмите на БЕЗОПАСНЫЙ HFTRANSFER. В правой части страницы в разделе ЗАПИСАТЬ КОНТРАКТ выберите функцию Transfer . Введите адрес назначения в цепочке хард-форка в поле « Кому — адрес » . В разделе «Выполнить из » выберите свою учетную запись. Введите количество ETH в поле « Отправить ETHER » . Нажмите кнопку ВЫПОЛНИТЬ, введите свой пароль и подтвердите. Вот изображение экрана:

введите описание изображения здесь


Для передачи только в классической цепочке без жесткого форка

Это переведет ваш ETH на целевой счет в классической цепочке без хард-форка и будет стоить вам только газа в цепочке с хард-форком.

Выберите страницу КОНТРАКТЫ в верхнем меню. Нажмите на БЕЗОПАСНЫЙ HFTRANSFER. В правой части страницы в разделе ЗАПИСАТЬ КОНТРАКТ выберите функцию Classic Transfer . Введите адрес назначения в цепочке без хард-форка в поле Кому - адрес . В разделе «Выполнить из » выберите свою учетную запись. Введите количество ETH (ETC) в поле « Отправить ETHER» . Нажмите кнопку ВЫПОЛНИТЬ, введите свой пароль и подтвердите. Вот изображение экрана:

введите описание изображения здесь



Способ 4 — Использование кошелька Ethereum и ReplaySafeSplitV2контракта

ОБНОВЛЕНИЕ 22:27, 4 сентября 2016 г. Это новая более безопасная версия, ReplaySafeSplitкак обсуждалось @chevdor на thedao.slack.com/messages/general в более безопасной версии смарт-контракта ReplaySafeSplit . Эта новая версия проверяет, что указанные вами адреса не являются 0x0000...0000 перед отправкой ваших эфиров на адреса. Этот раздел был обновлен новыми деталями контракта.

Убедитесь, что вы загрузили Ethereum Wallet 0.8.1 или более позднюю версию.

При первом запуске Ethereum Wallet 0.8.1 выберите «Да» на вопрос «Хотите ли вы активировать цепочку, в которой средства, связанные с эксплойтом, восстанавливаются в контракт, где они могут быть сняты держателями токенов The DAO?» . Теперь вы сделали выбор в пользу использования хард-форка Ethereum.

В Ethereum Wallet выберите страницу КОНТРАКТЫ в верхнем меню. Нажмите ПОСМОТРЕТЬ КОНТРАКТ.

  • Введите НАЗВАНИЕ КОНТРАКТАReplaySafeSplitV2
  • Введите АДРЕС КОНТРАКТА0x8201... (этот старый адрес был только в цепочке ETH. Если вы использовали этот контракт, удалите свой Контракт на просмотр и заново создайте Контракт на просмотр с новым адресом ниже. )
  • Введите ДОГОВОРНЫЙ АДРЕС0xaBbb6bEbFA05aA13e908EaA492Bd7a8343760477
  • Введите в JSON INTERFACE следующий текст[{"constant":false,"inputs":[{"name":"targetFork","type":"address"},{"name":"targetNoFork","type":"address"}],"name":"split","outputs":[{"name":"","type":"bool"}],"type":"function"}]
  • Нажмите «ОК». Ваш Watch Contract должен выглядеть так:

введите описание изображения здесь


Перевести

Это переведет ваш ETH на две учетные записи, первая будет учетной записью назначения в цепочке с хард-форком, а вторая — учетной записью назначения в классической цепочке без хард-форка.

Выберите страницу КОНТРАКТЫ в верхнем меню. Нажмите REPLAYSAFESPLITV2. В правой части страницы в разделе ЗАПИСАТЬ КОНТРАКТ выберите функцию Split . Введите адрес назначения в цепочке хард-форка в поле « Целевой форк — адрес » . Введите адрес назначения в сети Classic без хард-форка в поле « Цель без форка — адрес ». В разделе «Выполнить из » выберите свою учетную запись. Введите количество эфиров в поле « Отправить ETHER » . Нажмите кнопку ВЫПОЛНИТЬ, введите свой пароль и подтвердите.

Вот изображение экрана:

введите описание изображения здесь



SafeConditionalHFTransferДоговор

Обратите внимание, что приведенный ReplaySafeSplitV2ниже контракт имеет больше встроенных функций безопасности.

Ниже приведен исходный код контракта SafeConditionalHFTransfer (предложен 26 июля 2016 г. @shoraibit). Этот контракт не зависит от контракта WithdrawDAO, имеющего баланс более 1 000 000 эфиров в будущем.

contract ClassicCheck {
    function isClassic() constant returns (bool isClassic);
}

contract SafeConditionalHFTransfer {        
    bool classic;

    function SafeConditionalHFTransfer() {
        classic = ClassicCheck(0x882fb4240f9a11e197923d0507de9a983ed69239).isClassic();
    }

    function classicTransfer(address to) {
        if (!classic) 
            msg.sender.send(msg.value);
        else
            to.send(msg.value);
    }

    function transfer(address to) {
        if (classic)
            msg.sender.send(msg.value);
        else
            to.send(msg.value);
    }            
}

Этот контракт зависит от контракта ClassicCheck :

contract ClassicCheck {   
    bool public classic;

    function ClassicCheck() {
        if (address(0xbf4ed7b27f1d666546e30d74d50d173d20bca754).balance > 1000000 ether)
            classic = false;
        else
            classic = true;
    }   

    function isClassic() constant returns (bool isClassic) {
        return classic;
    }
}

Когда SafeConditionalHFTransferконтракт был развернут, он использовал ClassicCheckконтракт, чтобы определить, был ли код развернут в хард-форк или не хард-форк. И эта проверка была сделана, когда баланс WithdrawDAO превышал 1 000 000 . SafeConditionalHFTransfer всегда должен работать , так как ему больше не нужно проверять баланс баланса WithdrawDAO.



ReplaySafeSplitV2Договор

ОБНОВЛЕНИЕ 22:27, 4 сентября 2016 г. Это новая более безопасная версия, ReplaySafeSplitкак обсуждалось @chevdor на thedao.slack.com/messages/general в более безопасной версии смарт-контракта ReplaySafeSplit . В этой новой версии есть проверки того, что адреса, которые вы указываете, не 0x0000...0000перед отправкой ваших эфиров на адреса.

Ниже приведен исходный код контракта ReplaySafeSplitV2 :

contract RequiringFunds {
   modifier NeedEth () {
       if (msg.value <= 0 ) throw;
       _
   }
}

contract AmIOnTheFork {
   function forked() constant returns(bool);
}

contract ReplaySafeSplit is RequiringFunds {
   // address private constant oracleAddress = 0x8128B12cABc6043d94BD3C4d9B9455077Eb18807;    // testnet
   address private constant oracleAddress = 0x2bd2326c993dfaef84f696526064ff22eba5b362;   // mainnet

   // Fork oracle to use
   AmIOnTheFork amIOnTheFork = AmIOnTheFork(oracleAddress);

   // Splits the funds into 2 addresses
   function split(address targetFork, address targetNoFork) NeedEth returns(bool) {
       // The 2 checks are to ensure that users provide BOTH addresses
       // and prevent funds to be sent to 0x0 on one fork or the other.
       if (targetFork == 0) throw;
       if (targetNoFork == 0) throw;

       if (amIOnTheFork.forked()                   // if we are on the fork
           && targetFork.send(msg.value)) {        // send the ETH to the targetFork address
           return true;
       } else if (!amIOnTheFork.forked()           // if we are NOT on the fork
           && targetNoFork.send(msg.value)) {      // send the ETH to the targetNoFork address
           return true;
       }

       throw;                                      // don't accept value transfer, otherwise it would be trapped.
   }

   // Reject value transfers.
   function() {
       throw;
   }
}

Ниже приведен код виртуальной машины из классического блокчейна без жесткого форка, который соответствует проверенному коду виртуальной машины + исходному коду в цепочке с жестким форком.

user@PussyWillow:~$ geth -exec 'eth.getCode("0xaBbb6bEbFA05aA13e908EaA492Bd7a8343760477")' attach
"0x6060604052361561001f5760e060020a60003504630f2c93298114610028575b6100005b610002565b6100406004356024356000348190116100e157610002565b60408051918252519081900360200190f35b80547f16c72721000000000000000000000000000000000000000000000000000000006060908152600160a060020a0391909116906316c727219060649060209060048187876161da5a03f11561000257505060405151905080156100d25750604051600160a060020a038416908290349082818181858883f193505050505b1561010f575060015b92915050565b82600160a060020a0316600014156100f857610002565b81600160a060020a03166000141561005257610002565b600060009054906101000a9004600160a060020a0316600160a060020a03166316c727216040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151159050801561018c5750604051600160a060020a038316908290349082818181858883f193505050505b15610023575060016100db56"

Этот контракт зависит от контракта AmIOnTheFork :

contract AmIOnTheFork {
    bool public forked = false;
    address constant darkDAO = 0x304a554a310c7e546dfe434669c62820b7d83490;
    // Check the fork condition during creation of the contract.
    // This function should be called between block 1920000 and 1921200.
    // Approximately between 2016-07-20 12:00:00 UTC and 2016-07-20 17:00:00 UTC.
    // After that the status will be locked in.
    function update() {
        if (block.number >= 1920000 && block.number <= 1921200) {
            forked = darkDAO.balance < 3600000 ether;
        }
    }
    function() {
        throw;
    }
}
Мне удалось создать вторую учетную запись Windows и скопировать данные цепочки в другую папку. Затем geth начал указывать на папку Classic с флагом --datadir, а также с флагом --oppose-dao-fork. Таким образом, одна учетная запись пользователя Windows находится в Classic, а другая в основной сети. Я смог использовать вышеуказанный контракт HFConditionalTranfer для отправки эфира (первоначально всего с 1) на новую учетную запись в классической цепочке. Сначала я проверил это на gastracker.io и etherscan.io , ожидая полной синхронизации моей цепочки Classic. Затем я разместил ETC на Poloniex. Все идет нормально.
Я пробовал это с --oppose-dao-forkЭто работает!
Пробовали трассировку через live.ether.camp? Или, если вас это устраивает, не могли бы вы опубликовать свой хэш TX?
Моя ошибка, похоже, что etherscan не обнаружил внутреннюю передачу, и я не дождался обновления баланса достаточно долго. Все хорошо. Оно работает.
Не мог ли кто-нибудь создать контракт на 0xb671c3883307cf05bb3dff77a9754e87b4347195 на форке Ethereum Classic и каким-то образом объединить 10 миллионов и т. д., чтобы проверка прошла успешно и повторная атака снова активировалась?
@Fernando Да, поэтому разумно переместить ваш эфир в обеих цепочках на разные адреса. Этот метод позволяет вам предотвратить повторные атаки в течение следующих нескольких дней или недель, чтобы вы могли сделать это без каких-либо проблем... но обязательно избавьтесь от своих адресов до хардфорка, если вы заботитесь о том, чтобы повторные атаки были возможны, когда адрес возврата DAO находится под миллионов в Главной сети.
В вашем коде метода 1 var classicTransfer = hfConditionalTransferошибочно, потому что он все еще использует, hfConditionalTransferа не безопасную версию.
Спасибо @ThomasKahle. Сейчас я обновил код. Не могли бы вы проверить / протестировать.
Когда я проверил контракт, он сработал (отправка и т. д. на poloniex, по одному за раз, просто для проверки дважды), затем я попробовал общую сумму, и она не отображается в gastracker. Если этого не произошло, я получаю подтверждения в Тумане.
Что касается метода 3, не могли бы вы объяснить, как ReplaySafeSplitвыполняются действия в двух блокчейнах? Я не понимаю эту часть. Я ожидал, что вам придется запускать что-то дважды, по одному разу из кошелька, указывающего на один из двух блокчейнов.
@mowliv, транзакции из сети HF в настоящее время ретранслируются в сеть без HF, и наоборот. Я обновил ответ выше.

Если вы используете новый клиент, такой как Geth 1.5.3, он реализует защиту от атак повторного воспроизведения EIP 155 , чтобы ваши транзакции ETH были защищены от повторной атаки на ETC.

Используя Geth 1.5.3 (или более позднюю версию), вы должны создать другую учетную запись и переместить все свои ETH на новый адрес. Не забудьте сделать резервную копию этой новой учетной записи (и не удаляйте старую учетную запись, поскольку в ней есть ваш ETC).


Дополнительный шаг тем временем, так как Geth 1.5.3 очень новый: после вышеизложенного в цепочке ETC переместите все ETC на другой адрес. Это поможет убедиться, что вы действительно защищены от повторных атак.