Storage half of the Elcoin ledger, holding balances behind an owner and a single authorised caller contract.
Historical Significance
Splitting a token into a storage contract and a replaceable logic contract is the upgrade pattern that later became routine, appearing here in 2015 before proxies and delegatecall based upgrades were established. The owner and caller split is the whole mechanism: one key owns the data, one contract is allowed to change it, and swapping the second is an upgrade.
Key Facts
Description
The contract separates data from logic. It holds a balances mapping and an owner, plus one caller address that is the only contract permitted to move balances. The owner can rotate that caller, which is how the logic contract in front of it could be replaced without migrating the ledger.
Both guards are written as modifiers that return quietly rather than throwing when the check fails, the common pattern before require existed. Transfers emit a Transaction event carrying an indexed hash, the two parties, a timestamp and the amount.
Source Verified
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Frontier Era
The initial release of Ethereum. A bare-bones implementation for technical users.
Bytecode Overview
Verified Source Available
Source verified on Etherscan.
View Verification ProofShow source code (Solidity)
contract ElcoinDb {
address owner;
address caller;
event Transaction(bytes32 indexed hash, address indexed from, address indexed to, uint time, uint amount);
modifier checkOwner() { if(msg.sender == owner) { _ } else { return; } }
modifier checkCaller() { if(msg.sender == caller) { _ } else { return; } }
mapping (address => uint) public balances;
function ElcoinDb(address pCaller) {
owner = msg.sender;
caller = pCaller;
}
function getOwner() constant returns (address rv) {
return owner;
}
function getCaller() constant returns (address rv) {
return caller;
}
function setCaller(address pCaller) checkOwner() returns (bool _success) {
caller = pCaller;
return true;
}
function setOwner(address pOwner) checkOwner() returns (bool _success) {
owner = pOwner;
return true;
}
function getBalance(address addr) constant returns(uint balance) {
return balances[addr];
}
function deposit(address addr, uint amount, bytes32 hash, uint time) checkCaller() returns (bool res) {
balances[addr] += amount;
Transaction(hash,0 , addr, time, amount);
return true;
}
function withdraw(address addr, uint amount, bytes32 hash, uint time) checkCaller() returns (bool res) {
uint oldBalance = balances[addr];
if(oldBalance >= amount) {
msg.sender.send(amount);
balances[addr] = oldBalance - amount;
Transaction(hash, addr, 0, time, amount);
return true;
}
return false;
}
}External Links
Related contracts
elcoin
Same deployerJan 2016 ELC token using the Ambisafe Ambi v1 multi-authority framework with on-chain PoS rewards.
0xa04bf4...d121aaJanuary 27, 2016HonestDice
Same eraOne of the earliest provably-fair dice gambling contracts on Ethereum, deployed August 12, 2015 (day 13 of Frontier). Commit-reveal dice game with 2% house edge
0xc4c51d...1ae9fcAugust 12, 2015WalletProxy
Same era45-byte factory-generated wallet proxy forwarding via CALLCODE to a shared EF multi-sig Wallet (0x4efc6389). Variant without the success-check. Deployed by Fabian Vogelsteller.
0xf6ed6e...f510cfAugust 20, 2015Wallet
Same eraGav Wood's multi-sig, daily-limited wallet: the shared implementation that 111 Frontier-era 49-byte forwarders CALLCODE into.
0x273930...2220a2August 20, 2015WalletProxy
Same era49-byte factory-generated wallet proxy. Forwards all calls via CALLCODE to the shared Ethereum Foundation multi-sig Wallet at 0x273930d2. One of a series deployed by Fabian Vogelsteller.
0x816c42...41ff55August 20, 2015Wallet
Same eraA 49-byte CALLCODE forwarder for an early Ethereum multi-sig wallet, delegating every call to Gav Wood's shared wallet library.
0xf5d2ae...8d9533August 20, 2015