¿Cómo puedo verificar que mi saldo de tokens de The DAO sea correcto cuando los Goodies proporcionan un reembolso de ETC en la cadena Ethereum Classic?

De la publicación del blog The White Hats and DAO Wars: Behind the Scenes , los Goodies tienen la intención de:

desarrollar los contratos inteligentes que se utilizarán para distribuir ETC a las direcciones que tienen tokens DAO en el bloque 1,919,999.


Actualización 00:57 20 de agosto de 2016 UTC

Del contrato de retiro de ETC para ser revisado , el contrato DAOBalanceSnapShot en 0x180826b05452ce96e157f0708c43381fee64a6b8 se usará para determinar los saldos del titular del token DAO (DTH) en el bloque anterior a la bifurcación dura 1,919,999.

  • Directorio Daobalance, que contiene el contrato dao_balance_snapshot.sol y el script que genera los datos. Esto se completa a partir de la cadena ETH, pero se implementa en la cadena ETC y contiene los saldos del titular del token DAO en el momento de la bifurcación dura. Este contrato ya está implementado y lleno de datos en la cadena ETC en 0x180826b05452ce96e157f0708c43381fee64a6b8. Puedes probarlo en vivo usando la siguiente interfaz en geth:

    var daobalancesnapshot_abi = [{"constante":verdadero,"entradas":[],"nombre":"suministrototal","salidas":[{"nombre":"","tipo":"uint256"}]," tipo":"función"},{"constante":falso,"entradas":[],"nombre":"sello","salidas":[],"tipo":"función"},{"constante" :verdadero,"entradas":[],"nombre":"cuentastotales","salidas":[{"nombre":"","tipo":"uint256"}],"tipo":"función"}, {"constante":verdadero,"entradas":[{"nombre":"","tipo":"dirección"}],"nombre":"balanceOf","salidas":[{"nombre":"" ,"escribe":"uint256"}],"tipo":"función"},{"constante":falso,"entradas":[{"nombre":"datos","tipo":"uint256[]"}],"nombre" :"rellenar","salidas":[],"tipo":"función"},{"constante":verdadero,"entradas":[],"nombre":"propietario","salidas":[{" nombre":"","tipo":"dirección"}],"tipo":"función"},{"constante":verdadero,"entradas":[],"nombre":"sellado","salidas" :[{"nombre":"","tipo":"bool"}],"tipo":"función"},{"entradas":[],"tipo":"constructor"}];[{"nombre":"datos","tipo":"uint256[]"}],"nombre":"relleno","salidas":[],"tipo":"función"},{"constante" :verdadero,"entradas":[],"nombre":"propietario","salidas":[{"nombre":"","tipo":"dirección"}],"tipo":"función"}, {"constante":verdadero,"entradas":[],"nombre":"sellado","salidas":[{"nombre":"","tipo":"bool"}],"tipo":" función"},{"entradas":[],"tipo":"constructor"}];[{"nombre":"datos","tipo":"uint256[]"}],"nombre":"relleno","salidas":[],"tipo":"función"},{"constante" :verdadero,"entradas":[],"nombre":"propietario","salidas":[{"nombre":"","tipo":"dirección"}],"tipo":"función"}, {"constante":verdadero,"entradas":[],"nombre":"sellado","salidas":[{"nombre":"","tipo":"bool"}],"tipo":" función"},{"entradas":[],"tipo":"constructor"}];true,"entradas":[],"nombre":"propietario","salidas":[{"nombre":"","tipo":"dirección"}],"tipo":"función"},{ "constante":verdadero,"entradas":[],"nombre":"sellado","salidas":[{"nombre":"","tipo":"bool"}],"tipo":"función "},{"entradas":[],"tipo":"constructor"}];true,"entradas":[],"nombre":"propietario","salidas":[{"nombre":"","tipo":"dirección"}],"tipo":"función"},{ "constante":verdadero,"entradas":[],"nombre":"sellado","salidas":[{"nombre":"","tipo":"bool"}],"tipo":"función "},{"entradas":[],"tipo":"constructor"}];función"},{"entradas":[],"tipo":"constructor"}];función"},{"entradas":[],"tipo":"constructor"}];

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

    daobalancesnapshot.balanceOf(SUCUENTAAQUÍ);


¿Cómo puedo verificar que mi saldo de tokens de The DAO sea correcto cuando los Goodies proporcionan un reembolso de ETC en la cadena Ethereum Classic?

Respuestas (1)

Actualizado el 20 de agosto de 2016 a las 00:57 UTC : se utiliza BigNumberpara calcular con precisión las totalSupplycifras.

Comprobación del saldo de su token DAO

Desde ETC retire el contrato para ser revisado , puede verificar su saldo de tokens de The DAO en el bloque anterior a la bifurcación 1,919,999 usando gethsincronizado con la cadena Ethereum Classic usando los siguientes comandos:

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


Alternativamente, puede verificar sus saldos de tokens de The DAO en el bloque 1,919,999 en theDAOTokenBalance_20160819_155742UTC_balance.xlsx . Es posible que deba hacer clic con el botón derecho del mouse -> Guardar enlace como para descargar la hoja de cálculo a su computadora.



Comprobación de todos los saldos de tokens DAO

El script getTheDAOTokenBalance encuentra todas las direcciones involucradas en los eventos CreatedTokeny TransferThe DAO y consulta cada una de estas direcciones con la balanceOf(...)función de The DAO, bloque AT 1,919,999.

El script también concilia estos resultados con el DAOBalanceSnapShotcontrato en 0x180826b05452ce96e157f0708c43381fee64a6b8 (con ABI aquí ) que los Goodies pretenden usar para determinar la cantidad de tokens DAO que posee cada dirección en el bloque 1,919,999.

Los resultados son que mi secuencia de comandos calcula la misma cantidad de tokens de The DAO para cada dirección en comparación con el DAOBalanceSnapShotcontrato de Goodies y los totales son los mismos.

Hay un resumen en 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 .

Mi script encuentra un total de 22,092 cuentas distintas de cero con un total de 1,153,816,598.7024671407837618 DAO. Mi script consulta el DAOBalanceSnapShotcontrato de Goodies y encuentra el mismo total de DAO. El DAOBalanceSnapShotcontrato tiene un totalSupplyatributo que devuelve el valor 11538165987024671407837618 o 1,153,816,598.7024671407837618 DAO. El DAOBalanceSnapShotcontrato de Goodies representa con precisión los saldos de las cuentas de DTH en el bloque anterior a la bifurcación 1,919,999.

Y al verificar los DAO totalSupply()en el bloque 1,919,999 anterior a la bifurcación dura, se gethconfirma la cifra de suministro total.

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



La secuencia de comandos

Para usar el siguiente script, deberá descargar la cadena de bloques clásica usando geth --oppose-dao-fork console. Tenga en cuenta que no puede usar el --fastparámetro ya que esto excluirá los resultados intermedios requeridos para la debug.traceTransaction(...)consulta de API requerida para determinar las direcciones correctas involucradas en la creación del token. La secuencia de comandos tardará más de medio día en ejecutarse, dependiendo de la velocidad de su procesador y disco.

El script getTheDAOTokenBalance sigue:

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