@ledgerwatch in thedao.slack.com/messages/extrabal_community/ has deployed the ExtraBalToken contract at 0x5c40ef6f527f4fba68368774e6130ce6515123f2 in block #2,197,120 with transaction 0x6f5ea6f387722f2899789947a37703f211983b74215b0b15f5bb4b3835b63bc6.
See also How do I get a refund for the amount I paid in excess of 1 ether to 100 The DAO tokens and The latest on the childDAO and extraBalance refunds
Reconciliation Of ExtraBalToken Contract Values
I’ve written a script to reconcile the balance in this contract. The documentation can be found at Extra Balance Reconcilation, and the source code for the reconciliation script can be found at github.com/bokkypoobah/TheDAOData/reconcileExtraBalTokenValues.
ExtraBalToken Contract Source Code
Following is the source code for the ExtraBalToken contract. It is an ERC20 standard token contract with a fill(...)
function and a seal()
function to preload the token balance by addresses.
The only very minor improvement that I could find over the implementation below is to use modifier noEther() {if (msg.value > 0) throw; _}
to prevent users accidentally sending ethers to the functions transfer(...)
, approve(...)
and transferFrom(...)
. And there is no way to retrieve any ethers accidentally sent to this contract, but the chance of this is has been minimised by overriding the default ()
function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
contract ExtraBalToken { uint256 public totalSupply; /* This creates an array with all balances */ mapping (address => uint256) public balanceOf; mapping (address => mapping (address => uint256)) public allowance; /* This generates a public event on the blockchain that will notify clients */ event Transfer(address indexed from, address indexed to, uint256 value); /* Send coins */ function transfer(address _to, uint256 _value) { if (balanceOf[msg.sender] < _value) throw; // Check if the sender has enough if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows balanceOf[msg.sender] -= _value; // Subtract from the sender balanceOf[_to] += _value; // Add the same to the recipient Transfer(msg.sender, _to, _value); // Notify anyone listening that this transfer took place } /* Allow another contract to spend some tokens in your behalf */ function approve(address _spender, uint256 _value) returns (bool success) { allowance[msg.sender][_spender] = _value; return true; } /* A contract attempts to get the coins */ function transferFrom(address _from, address _to, uint256 _value) returns (bool success) { if (balanceOf[_from] < _value) throw; // Check if the sender has enough if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows if (_value > allowance[_from][msg.sender]) throw; // Check allowance balanceOf[_from] -= _value; // Subtract from the sender balanceOf[_to] += _value; // Add the same to the recipient allowance[_from][msg.sender] -= _value; Transfer(_from, _to, _value); return true; } /* This unnamed function is called whenever someone tries to send ether to it */ function () { throw; // Prevents accidental sending of ether } uint constant D160 = 0x10000000000000000000000000000000000000000; address public owner; function ExtraBalToken() { owner = msg.sender; } bool public sealed; // The 160 LSB is the address of the balance // The 96 MSB is the balance of that address. function fill(uint[] data) { if ((msg.sender != owner)||(sealed)) throw; for (uint i=0; i<data.length; i++) { address a = address( data[i] & (D160-1) ); uint amount = data[i] / D160; if (balanceOf[a] == 0) { // In case it's filled two times, it only increments once balanceOf[a] = amount; totalSupply += amount; } } } function seal() { if ((msg.sender != owner)||(sealed)) throw; sealed= true; } } |