Как я могу убедиться, что мой баланс токенов The DAO правильный, когда Goodies обеспечивают возврат ETC в цепочке Ethereum Classic?

Из сообщения в блоге The White Hats and DAO Wars: Behind the Scenes Goodies намереваются:

разработать смарт-контракты, которые будут использоваться для распределения ETC по адресам, содержащим токены DAO в блоке 1 919 999.


Обновление 00:57 20 августа 2016 UTC

Контракт DAOBalanceSnapShot по адресу 0x180826b05452ce96e157f0708c43381fee64a6b8 будет использоваться для определения баланса держателя токена DAO (DTH) в блоке 1 919 999 до хард-форка .

  • Каталог Daobalance, содержащий контракт dao_balance_snapshot.sol и скрипт, генерирующий данные. Он заполняется из цепочки ETH, но развертывается в цепочке ETC и содержит баланс держателей токенов DAO во время хардфорка. Этот контракт уже развернут и заполнен данными в цепочке ETC по адресу 0x180826b05452ce96e157f0708c43381fee64a6b8. Вы можете протестировать его вживую, используя следующий интерфейс в geth:

    var daobalancesnapshot_abi = [{"константа":истина,"входы":[],"имя":"общее предложение","выходы":[{"имя":"","тип":"uint256"}]," тип":"функция"},{"константа":ложь,"входы":[],"имя":"печать","выходы":[],"тип":"функция"},{"константа" :true,"входы":[],"имя":"totalAccounts","выходы":[{"имя":"","тип":"uint256"}],"тип":"функция"}, {"константа":истина,"входы":[{"имя":"","тип":"адрес"}],"имя":"баланс","выходы":[{"имя":"" ,"тип":"uint256"}],"тип":"функция"},{"константа":ложь,"входы":[{"имя":"данные","тип":"uint256[]"}],"имя" :"заполнение","выходы":[],"тип":"функция"},{"константа":true,"входы":[],"имя":"владелец","выходы":[{" имя":"","тип":"адрес"}],"тип":"функция"},{"константа":истина,"входы":[],"имя":"запечатанный","выходы" :[{"имя":"","тип":"bool"}],"тип":"функция"},{"входы":[],"тип":"конструктор"}];[{"имя":"данные","тип":"uint256[]"}],"имя":"заполнить","выходы":[],"тип":"функция"},{"константа" :true,"входы":[],"имя":"владелец","выходы":[{"имя":"","тип":"адрес"}],"тип":"функция"}, {"константа":true,"входы":[],"имя":"запечатанный","выходы":[{"имя":"","тип":"bool"}],"тип":" функция"},{"входы":[],"тип":"конструктор"}];[{"имя":"данные","тип":"uint256[]"}],"имя":"заполнить","выходы":[],"тип":"функция"},{"константа" :true,"входы":[],"имя":"владелец","выходы":[{"имя":"","тип":"адрес"}],"тип":"функция"}, {"константа":true,"входы":[],"имя":"запечатанный","выходы":[{"имя":"","тип":"bool"}],"тип":" функция"},{"входы":[],"тип":"конструктор"}];true,"входы":[],"имя":"владелец","выходы":[{"имя":"","тип":"адрес"}],"тип":"функция"},{ «константа»: истина, «входы»: [], «имя»: «запечатанный», «выходы»: [{«имя»: «», «тип»: «логическое значение»}], «тип»: «функция "},{"входы":[],"тип":"конструктор"}];true,"входы":[],"имя":"владелец","выходы":[{"имя":"","тип":"адрес"}],"тип":"функция"},{ «константа»: истина, «входы»: [], «имя»: «запечатанный», «выходы»: [{«имя»: «», «тип»: «логическое значение»}], «тип»: «функция "},{"входы":[],"тип":"конструктор"}];функция"},{"входы":[],"тип":"конструктор"}];функция"},{"входы":[],"тип":"конструктор"}];

    var daobalancesnapshot = web3.eth.contract(daobalancesnapshot_abi).at("0x180826b05452ce96e157f0708c43381fee64a6b8");

    daobalancesnapshot.balanceOf (ВАШ АККАУНТ ЗДЕСЬ);


Как я могу убедиться, что мой баланс токенов The DAO правильный, когда Goodies обеспечивают возврат ETC в цепочке Ethereum Classic?

Ответы (1)

Обновлено 00:57, 20 августа 2016 г. UTC — используется BigNumberдля точного вычисления totalSupplyцифр.

Проверка баланса токена DAO

Из контракта на вывод средств ETC, который будет рассмотрен , вы можете проверить баланс своего токена DAO в блоке 1 919 999 до хард-форка, используя gethсинхронизацию с цепочкой Ethereum Classic, используя следующие команды:

geth --fast --oppose-dao-fork console
// Allow the chain to sync
> var daobalancesnapshot_abi = [{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[],"name":"seal","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"totalAccounts","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"data","type":"uint256[]"}],"name":"fill","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"sealed","outputs":[{"name":"","type":"bool"}],"type":"function"},{"inputs":[],"type":"constructor"}];
undefined
> var daobalancesnapshot = web3.eth.contract(daobalancesnapshot_abi).at("0x180826b05452ce96e157f0708c43381fee64a6b8"); 
undefined
> daobalancesnapshot.balanceOf(YOURACCOUNTHERE);
123456


Кроме того, вы можете проверить баланс своих токенов DAO в блоке 1 919 999 в файле DAOTokenBalance_20160819_155742UTC_balance.xlsx . Возможно, вам придется щелкнуть правой кнопкой мыши -> Сохранить ссылку как, чтобы загрузить электронную таблицу на свой компьютер.



Проверка баланса всех токенов DAO

Сценарий getTheDAOTokenBalance находит все адреса, участвующие в событиях DAO CreatedTokenи TransferDAO, и запрашивает каждый из этих адресов в соответствии с функцией The DAO balanceOf(...), блоком AT 1 919 999.

Сценарий дополнительно сверяет эти результаты с DAOBalanceSnapShotконтрактом по адресу 0x180826b05452ce96e157f0708c43381fee64a6b8 (с ABI здесь ), который Goodies намереваются использовать для определения количества токенов DAO, которыми владеет каждый адрес, в блоке 1 919 999.

В результате мой скрипт вычисляет одинаковое количество токенов DAO для каждого адреса по сравнению с DAOBalanceSnapShotконтрактом Goodies, и итоговые значения совпадают.

Резюме есть на github.com/bokkypoobah/TheDAOETCTokenBalance . You can find all the CreatedTokenevents in theDAOTokenBalance_20160819_155742UTC_creation.txt , all the Transferevents in theDAOTokenBalance_20160819_155742UTC_transfer.txt and all balances at block 1,919,999 in theDAOTokenBalance_20160819_155742UTC_balance.txt and theDAOTokenBalance_20160819_155742UTC_balance.xlsx .

Мой скрипт находит в общей сложности 22 092 ненулевых учетных записи с 1 153 816 598,7024671407837618 DAO. Мой скрипт запрашивает DAOBalanceSnapShotконтракт Goodies и находит ту же сумму DAO. Контракт DAOBalanceSnapShotимеет totalSupplyатрибут, который возвращает значение 11538165987024671407837618 или 1 153 816 598,7024671407837618 DAO. Контракт Goodies DAOBalanceSnapShotточно представляет остатки на счетах DTH в блоке 1 919 999 до хард-форка.

И проверка DAO totalSupply()в блоке 1 919 999 до хардфорка gethподтверждает общую цифру предложения.

> var theDAOABIFragment = [{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"type":"function"}];
undefined
> var theDAOAddress = "0xbb9bc244d798123fde783fcc1c72d3bb8c189413"
undefined
> var theDAO = web3.eth.contract(theDAOABIFragment).at(theDAOAddress);
undefined
> theDAO.totalSupply(1919999).toString(10);
"11538165987024671407837618"



Сценарий

Чтобы использовать следующий скрипт, вам нужно будет загрузить классический блокчейн, используя файлы geth --oppose-dao-fork console. Обратите внимание, что вы не можете использовать этот --fastпараметр, так как это исключит промежуточные результаты, необходимые для debug.traceTransaction(...)запроса API, необходимого для определения правильных адресов, участвующих в создании токена. Сценарий будет выполняться полдня, в зависимости от скорости вашего процессора и диска.

Скрипт getTheDAOTokenBalance выглядит следующим образом:

#!/bin/sh
# ------------------------------------------------------------------------------
# Retrieve The DAO Creation and Transfer events, collecting addresses. Then 
# retrieve the pre-hard-fork balances and the current balances for these 
# addresses.
#
# v2 improvements
# * Summing totals as BigNumbers instead of floats
# * Only including non-zero balances at block 1919999 in counter
#
# Usage:
#   1. Download this script to getTheDAOTokenBalance .
#   2. `chmod 700 getTheDAOTokenBalance`
#   3. Run `geth console` in a window.
#   4. Then run this script `./getTheDAOTokenBalance` in a separate window.
#
# Enjoy. (c) BokkyPooBah 2016. The MIT licence.
# ------------------------------------------------------------------------------

DATE=`date -u +%Y%m%d_%H%M%S`
OUTPUT=theDAOTokenBalance_${DATE}UTC_all.txt
CREATION=theDAOTokenBalance_${DATE}UTC_creation.txt
TRANSFER=theDAOTokenBalance_${DATE}UTC_transfer.txt
BALANCE=theDAOTokenBalance_${DATE}UTC_balance.txt

geth attach << EOF | egrep "^Header|^Data|^Stats|^Footer" > $OUTPUT
var theDAOABIFragment = [{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"type":"function"}, {"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"CreatedToken","type":"event"}, {"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"Transfer","type":"event"}];
var theDAOAddress = "0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413";
var theDAO = web3.eth.contract(theDAOABIFragment).at(theDAOAddress);

var theDAOTokenBalancePreHardForkABI = [{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[],"name":"seal","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"totalAccounts","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"data","type":"uint256[]"}],"name":"fill","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"sealed","outputs":[{"name":"","type":"bool"}],"type":"function"},{"inputs":[],"type":"constructor"}];
var theDAOTokenBalancePreHardForkAddress = "0x180826b05452ce96e157f0708c43381fee64a6b8";
var theDAOTokenBalancePreHardForkContract = web3.eth.contract(theDAOTokenBalancePreHardForkABI).at(theDAOTokenBalancePreHardForkAddress);

// The DAO created in block 1428757 Apr-30-2016 01:42:58 AM +UTC
var creationStartBlock = 1428757;
// First The DAO creation event with non-zero extraBalance in block 1520861 May-15-2016 09:00:16 AM +UTC
var creationWithExtraBalanceStartBlock = 1520861;
// Last The DAO creation event in block 1599205 May-28-2016 08:59:47 AM +UTC
var creationEndBlock = 1599205;
// First The DAO transfer event in block 1599207 May-28-2016 09:00:07 AM +UTC, but use block above
var transferStartBlock = creationEndBlock + 1;
// Last The DAO transfer
var transferEndBlock = eth.blockNumber;
// Pre hard-fork block
var preHardForkBlock = 1919999;
// Hard-fork block
var hardForkBlock = 1920000;

// Collect addresses
var addresses = {};

// --- Get creation events ---
var startBlock = creationStartBlock;
var endBlock = creationEndBlock;

// Testing
// startBlock = creationWithExtraBalanceStartBlock - 5;
// endBlock = creationWithExtraBalanceStartBlock + 5;

var theDAOCreatedTokenEvent = theDAO.CreatedToken({}, {fromBlock: startBlock, toBlock: endBlock});
console.log("HeaderCreation\tTokenOwner");
var i = 0;
theDAOCreatedTokenEvent.watch(function(error, result) {
  addresses[result.args.to] = 1;
  i = i + 1;
  console.log("DataCreation\t" + i + "\t" + result.args.to);
});

// --- Get transfer events ---
var startBlock = transferStartBlock;
var endBlock = transferEndBlock;

// Testing
// startBlock = transferStartBlock;
// endBlock = transferStartBlock + 10;

var theDAOTransferEvent = theDAO.Transfer({}, {fromBlock: startBlock, toBlock: endBlock});
console.log("HeaderTransfer\tFrom\tTo");
i = 0;
theDAOTransferEvent.watch(function(error, result) {
  addresses[result.args._from] = 1;
  addresses[result.args._to] = 1;
  i = i + 1;
  console.log("DataTransfer\t" + i + "\t" + result.args._from + "\t" + result.args._to);
});

// --- Get balances ---
var currentBlock = transferEndBlock;

console.log("HeaderBalance\tNumber\tAddress\tPreHardForkDAO\tPreHardForkDAOContract\tPreHardForkDAODiff\tCurrentDAO\tChangeDAO\tPreHardForkETH\tCurrentETH\tChangeETH");
var daosPreHardForkTotal = new BigNumber(0);
var daosPreHardForkContractTotal = new BigNumber(0);
var daosCurrentTotal = new BigNumber(0);
var nonZeroAccounts = new BigNumber(0);
i = 0;
for (var address in addresses) {
  i = i + 1;
  var checkAddress = "0xda0031fab25270778386a2dcac0bb934a288c464";
  var daosPreHardFork = theDAO.balanceOf(address, preHardForkBlock);
  var daosPreHardForkContract = theDAOTokenBalancePreHardForkContract.balanceOf(address);
  var daosPreHardForkDiff = daosPreHardFork - daosPreHardForkContract;
  var daosCurrent = theDAO.balanceOf(address, currentBlock);
  if (daosPreHardFork != 0 || daosPreHardForkContract != 0) {
    nonZeroAccounts++;
  }
  var daosChange = daosCurrent - daosPreHardFork;
  var ethsPreHardFork = eth.getBalance(address, preHardForkBlock);
  var ethsCurrent = eth.getBalance(address, currentBlock);
  var ethsChange = ethsCurrent - ethsPreHardFork;
  daosPreHardForkTotal = daosPreHardForkTotal.plus(daosPreHardFork);
  daosPreHardForkContractTotal = daosPreHardForkContractTotal.plus(daosPreHardForkContract);
  daosCurrentTotal = daosCurrentTotal.plus(daosCurrent);
  console.log("DataBalance\t" + i + "\t" + address + "\t" + 
    (daosPreHardFork/1e16).toFixed(16) + "\t" + (daosPreHardForkContract/1e16).toFixed(16) + "\t" + (daosPreHardForkDiff/1e16).toFixed(16) + "\t" + 
    (daosCurrent/1e16).toFixed(16) + "\t" + (daosChange/1e16).toFixed(16) + "\t" + 
    (ethsPreHardFork/1e18).toFixed(18) + "\t" + (ethsCurrent/1e18).toFixed(18) + "\t" + (ethsChange/1e18).toFixed(18));
}

console.log("Stats\tnonZeroAccounts\t" + nonZeroAccounts);
console.log("Stats\tdaosPreHardForkTotal\t" + daosPreHardForkTotal.toPrecision(30) + "\t" + (daosPreHardForkTotal/1e16).toFixed(16));
console.log("Stats\tdaosPreHardForkContractTotal\t" + daosPreHardForkContractTotal.toPrecision(30) + "\t" + (daosPreHardForkContractTotal/1e16).toFixed(16));
console.log("Stats\tdaosCurrentTotal\t" + daosCurrentTotal.toPrecision(30) + "\t" + (daosCurrentTotal/1e16).toFixed(16));

console.log("Footer\tReport generated at " + (new Date()).toGMTString() + " with latest block number " + transferEndBlock);

EOF

egrep "HeaderCreation|DataCreation|Footer" $OUTPUT > $CREATION
egrep "HeaderTransfer|DataTransfer|Footer" $OUTPUT > $TRANSFER
egrep "HeaderBalance|DataBalance|Footer|Stats" $OUTPUT > $BALANCE