4

From the blog post The White Hats and DAO Wars: Behind the Scenes, the Goodies intend to:

develop the smart contracts that will be used to distribute ETC to the addresses holding DAO Tokens at block 1,919,999.


Update 00:57 Aug 20 2016 UTC

From ETC withdraw contract to be reviewed, the DAOBalanceSnapShot contract at 0x180826b05452ce96e157f0708c43381fee64a6b8 will be used to determine The DAO Token Holder's (DTH) balances at pre-hard-fork block 1,919,999.

  • Daobalance directory, containing the dao_balance_snapshot.sol contract and the script that generates the data. This is populated from the ETH chain but is deployed in the ETC chain and contains the DAO Token Holder balances at the time of the hard fork. This contract is already deployed and filled with data in the ETC chain at 0x180826b05452ce96e157f0708c43381fee64a6b8. You can test it live using the following interface in geth:

    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"}];

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

    daobalancesnapshot.balanceOf(YOURACCOUNTHERE);


How can I verify that my The DAO token balance is correct when the Goodies provide an ETC refund on the Ethereum Classic chain?

1 Answer 1

6

Updated 00:57 Aug 20 2016 UTC - using BigNumber to accurately compute the totalSupply figures.

Checking Your The DAO Token Balance

From ETC withdraw contract to be reviewed you can check your The DAO token balance at pre-hard-fork block 1,919,999 using geth synced to the Ethereum Classic chain using the following commands:

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 


Alternatively, you can verify your The DAO token balances at block 1,919,999 in theDAOTokenBalance_20160819_155742UTC_balance.xlsx. You may have to right mouse click -> Save Link As to download the spreadsheet to your computer.



Checking All DAO Token Balances

The script getTheDAOTokenBalance finds all addresses involved in the CreatedToken and Transfer The DAO events and queries each of these addresses against The DAO's balanceOf(...) function, AT block 1,919,999.

The script additionally reconciles this results against the DAOBalanceSnapShot contract at 0x180826b05452ce96e157f0708c43381fee64a6b8 (with ABI here) that the Goodies intend to use to determine the number of The DAO tokens each address owns at block 1,919,999.

The results are that my script calculate the same number of The DAO tokens for each address compared to the Goodies' DAOBalanceSnapShot contract and the totals are the same.

There is a summary at github.com/bokkypoobah/TheDAOETCTokenBalance. You can find all the CreatedToken events in theDAOTokenBalance_20160819_155742UTC_creation.txt, all the Transfer events 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.

My script finds a total of 22,092 non-zero accounts with a total of 1,153,816,598.7024671407837618 DAOs. My script queries the Goodies' DAOBalanceSnapShot contract and finds the same DAO total. The DAOBalanceSnapShot contract has a totalSupply attribute that returns the value 11538165987024671407837618 or 1,153,816,598.7024671407837618 DAOs.The Goodies' DAOBalanceSnapShot contract accurately represent the balances of DTH's accounts at the pre-hard-fork block 1,919,999.

And checking theDAO's totalSupply() at pre-hard-fork block 1,919,999 using geth confirms the total supply figure.

> 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" 



The Script

To use the following script, you will have to download the Classic blockchain using geth --oppose-dao-fork console. Note that you cannot use the --fast parameter as this will exclude the intermediate results required for the debug.traceTransaction(...) API query required to determine the correct addresses involved in the token creation. The script will take over half a day to execute, depending on the speed of your processor and disk.

The script getTheDAOTokenBalance follows:

#!/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 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.