Apr 2, 2016 MyToken-tutorial fork — owner mint/freeze, allowances, and a built-in buy/sell with prices left at zero at deploy.
Historical Significance
African Gold Dinar preserves a transitional pre-ERC-20 design: allowances are tracked with a separate spentAllowance mapping (rather than mutating the original allowance map on each spend), administrative minting and freezing are baked directly into the token, and exchange functions live in the same contract rather than in a separate market layer. It belongs to the broader cluster of April 2016 tutorial-derived tokens that experimented with these patterns just weeks before the ERC-20 standard converged around approve / transferFrom.
Context
Deployed on April 2, 2016 at block 1,261,284 by 0x28ba0b04488b9fb1f50f9b9ef782a9899855a5d6 (deploy tx 0x417de6c36d1b9047c931af008b6da60ba00d54ba88677857d6f2bb678e104532, nonce 6). The deployer is the same address passed as the centralMinter constructor argument, so the constructor sets owner = msg.sender and credits the deployer with the full 200,000.000 D initial supply.
The contract is part of the broader MyToken tutorial lineage that dominated early Frontier and Homestead-era token experiments — owned + tokenRecipient + MyToken with public state getters, a fallback that throws to reject plain ETH transfers, and the owner-administered mint / freeze / setPrices interface. African Gold Dinar's prices were never configured on-chain, so the buy/sell paths were inert from launch.
Token Information
Key Facts
Description
African Gold Dinar (symbol D, 3 decimals) is an April 2, 2016 token built from the early MyToken Ethereum-tutorial family. It exposes the standard balance / allowance / freeze / mint / buy / sell surface and is intended to hold its own tokens for the built-in exchange path. The constructor sets decimals = 3 and credits the deployer with 200,000,000 base units (= 200,000.000 D), but neither sellPrice nor buyPrice is initialized — both stay at zero until the owner calls setPrices(), so the buy() path divides by zero and reverts and sell() returns nothing to senders until prices are configured.
The reconstructed source compiles with soljson v0.2.1+commit.91a6b35f and the optimizer enabled to bytecode that matches the on-chain creation AND runtime byte-for-byte. EthereumHistory's first verification recorded native solc v0.1.5; that was wrong — v0.1.5 emits the pre-nightly identity-precompile gas formula (words*3 + 15) in the public-string getter helper, while the on-chain code uses the swapped formula (words*15 + 3) that solc adopted in v0.1.7-nightly.2015.11.19+commit.58110b27 and kept through v0.3.2.
Source Verified
Exact creation and runtime bytecode match. Runtime: 2,346 bytes (SHA-256 5bcf41862ed3c02bf976b5dd34cb623ab6ef40775dbd9c54cefd2b29b29069b1). Creation: 3,121 bytes = 2,833 code + 288 constructor args (SHA-256 4fe71400eb256a617b27e443861f159421b45120770a91caad98eab7d6f89422). Compiler: soljson v0.2.1+commit.91a6b35f, optimizer ON. Verified on Sourcify (creationMatch + runtimeMatch = match) and Etherscan (Pass - Verified). Initial EH verification recorded native solc v0.1.5; corrected based on the identity-precompile gas-formula signature (words*15 + 3) which only appears in v0.1.7-nightly.2015.11.19 and later.
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Homestead Era
The first planned hard fork. Removed the canary contract, adjusted gas costs.
Bytecode Overview
Verified Source Available
Source verified through compiler archaeology and exact bytecode matching.
View Verification ProofShow source code (Solidity)
// Submitted by EthereumHistory (ethereumhistory.com)
contract owned {
address public owner;
function owned() {
owner = msg.sender;
}
modifier onlyOwner {
if (msg.sender != owner) throw;
_
}
function transferOwnership(address newOwner) onlyOwner {
owner = newOwner;
}
}
contract tokenRecipient {
function receiveApproval(address _from, uint256 _value, address _token);
}
contract MyToken is owned {
string public name;
string public symbol;
uint8 public decimals;
uint256 public sellPrice;
uint256 public buyPrice;
uint256 public totalSupply;
mapping (address => uint256) public balanceOf;
mapping (address => bool) public frozenAccount;
mapping (address => mapping (address => uint256)) public allowance;
mapping (address => mapping (address => uint256)) public spentAllowance;
event Transfer(address indexed from, address indexed to, uint256 value);
event FrozenFunds(address target, bool frozen);
function MyToken(uint256 initialSupply, string tokenName, uint8 decimalUnits, string tokenSymbol, address centralMinter) {
if (centralMinter != 0) owner = msg.sender;
balanceOf[msg.sender] = initialSupply;
name = tokenName;
symbol = tokenSymbol;
decimals = decimalUnits;
totalSupply = initialSupply;
}
function transfer(address _to, uint256 _value) {
if (balanceOf[msg.sender] < _value) throw;
if (balanceOf[_to] + _value < balanceOf[_to]) throw;
if (frozenAccount[msg.sender]) throw;
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
Transfer(msg.sender, _to, _value);
}
function approveAndCall(address _spender, uint256 _value) returns (bool success) {
allowance[msg.sender][_spender] = _value;
tokenRecipient spender = tokenRecipient(_spender);
spender.receiveApproval(msg.sender, _value, this);
return true;
}
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
if (balanceOf[_from] < _value) throw;
if (balanceOf[_to] + _value < balanceOf[_to]) throw;
if (spentAllowance[_from][msg.sender] + _value > allowance[_from][msg.sender]) throw;
balanceOf[_from] -= _value;
balanceOf[_to] += _value;
spentAllowance[_from][msg.sender] += _value;
Transfer(_from, _to, _value);
return true;
}
function () {
throw;
}
function mintToken(address target, uint256 mintedAmount) onlyOwner {
balanceOf[target] += mintedAmount;
totalSupply += mintedAmount;
Transfer(0, owner, mintedAmount);
Transfer(owner, target, mintedAmount);
}
function freezeAccount(address target, bool freeze) onlyOwner {
frozenAccount[target] = freeze;
FrozenFunds(target, freeze);
}
function setPrices(uint256 newSellPrice, uint256 newBuyPrice) onlyOwner {
sellPrice = newSellPrice;
buyPrice = newBuyPrice;
}
function buy() {
uint amount = msg.value / buyPrice;
if (balanceOf[this] < amount) throw;
balanceOf[msg.sender] += amount;
balanceOf[this] -= amount;
Transfer(this, msg.sender, amount);
}
function sell(uint256 amount) {
if (balanceOf[msg.sender] < amount) throw;
balanceOf[this] += amount;
balanceOf[msg.sender] -= amount;
msg.sender.send(amount * sellPrice);
Transfer(msg.sender, this, amount);
}
}