A factory library that deploys mintable and burnable tokens, and hands back their ABI
Historical Significance
Contract creation offered as a service by a library, with the created contract's ABI published on chain beside it. The embedded version string names the exact source release, which is how this one was found.
Context
Deployed in the Homestead era, when a dapp that wanted to create a contract had to ship a compiler or a hardcoded blob.
Key Facts
Description
CreatorTokenEmission is one of the factory libraries in Airalab's DAO toolkit. Its create function deploys a TokenEmission contract, a token whose owner can mint more supply and whose holders can burn their own, taking the name, symbol, decimals and starting supply as arguments. Two further functions make it self describing on chain: version returns the toolkit release it was built from, and interface returns the full ABI of the token it creates as a JSON string, so a dapp can call the new token without being told its shape out of band. Deployed on 18 August 2016 by 0x4af013afbadb22d8a88c92d68fc96b033b9ebb8a and recovered from airalab/core.
DAO Fork Era
The controversial fork to recover funds from The DAO hack.
Bytecode Overview
Verified Source Available
This contract has verified source code on Etherscan.
Show source code (Solidity)
// Submitted by EthereumHistory (ethereumhistory.com)
/**
* @title The root contract
* @dev This contract is used as base of all contracts,
* e.g. it change default behaviour of fallback function
*/
contract Object {
/**
* @dev Default fallback behaviour will throw sended ethers
*/
function() { throw; }
}
/**
* @title Contract for object that have an owner
*/
contract Owned is Object {
/**
* Contract owner address
*/
address public owner;
/**
* @dev Store owner on creation
*/
function Owned() { owner = msg.sender; }
/**
* @dev Delegate contract to another person
* @param _owner is another person address
*/
function delegate(address _owner) onlyOwner
{ owner = _owner; }
/**
* @dev Owner check modifier
*/
modifier onlyOwner { if (msg.sender != owner) throw; _ }
}
/**
* @title Token contract represents any asset in digital economy
*/
contract Token is Owned {
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
/* Short description of token */
string public name;
string public symbol;
/* Total count of tokens exist */
uint public totalSupply;
/* Fixed point position */
uint8 public decimals;
/* Token approvement system */
mapping(address => uint) public balanceOf;
mapping(address => mapping(address => uint)) public allowance;
/**
* @return available balance of `sender` account (self balance)
*/
function getBalance() constant returns (uint)
{ return balanceOf[msg.sender]; }
/**
* @dev This method returns non zero result when sender is approved by
* argument address and target address have non zero self balance
* @param _address target address
* @return available for `sender` balance of given address
*/
function getBalance(address _address) constant returns (uint) {
return allowance[_address][msg.sender]
> balanceOf[_address] ? balanceOf[_address]
: allowance[_address][msg.sender];
}
/* Token constructor */
function Token(string _name, string _symbol, uint8 _decimals, uint _count) {
name = _name;
symbol = _symbol;
decimals = _decimals;
totalSupply = _count;
balanceOf[msg.sender] = _count;
}
/**
* @dev Transfer self tokens to given address
* @param _to destination address
* @param _value amount of token values to send
* @notice `_value` tokens will be sended to `_to`
* @return `true` when transfer done
*/
function transfer(address _to, uint _value) returns (bool) {
if (balanceOf[msg.sender] >= _value) {
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
Transfer(msg.sender, _to, _value);
return true;
}
return false;
}
/**
* @dev Transfer with approvement mechainsm
* @param _from source address, `_value` tokens shold be approved for `sender`
* @param _to destination address
* @param _value amount of token values to send
* @notice from `_from` will be sended `_value` tokens to `_to`
* @return `true` when transfer is done
*/
function transferFrom(address _from, address _to, uint _value) returns (bool) {
var avail = allowance[_from][msg.sender]
> balanceOf[_from] ? balanceOf[_from]
: allowance[_from][msg.sender];
if (avail >= _value) {
allowance[_from][msg.sender] -= _value;
balanceOf[_from] -= _value;
balanceOf[_to] += _value;
Transfer(_from, _to, _value);
return true;
}
return false;
}
/**
* @dev Give to target address ability for self token manipulation without sending
* @param _address target address
* @param _value amount of token values for approving
*/
function approve(address _address, uint _value) {
allowance[msg.sender][_address] += _value;
Approval(msg.sender, _address, _value);
}
/**
* @dev Reset count of tokens approved for given address
* @param _address target address
*/
function unapprove(address _address)
{ allowance[msg.sender][_address] = 0; }
}
contract TokenEmission is Token {
function TokenEmission(string _name, string _symbol, uint8 _decimals,
uint _start_count)
Token(_name, _symbol, _decimals, _start_count)
{}
/**
* @dev Token emission
* @param _value amount of token values to emit
* @notice owner balance will be increased by `_value`
*/
function emission(uint _value) onlyOwner {
// Overflow check
if (_value + totalSupply < totalSupply) throw;
totalSupply += _value;
balanceOf[owner] += _value;
}
/**
* @dev Burn the token values from sender balance and from total
* @param _value amount of token values for burn
* @notice sender balance will be decreased by `_value`
*/
function burn(uint _value) {
if (balanceOf[msg.sender] >= _value) {
balanceOf[msg.sender] -= _value;
totalSupply -= _value;
}
}
}
library CreatorTokenEmission {
function create(string _name, string _symbol, uint8 _decimals, uint256 _start_count) returns (TokenEmission)
{ return new TokenEmission(_name, _symbol, _decimals, _start_count); }
function version() constant returns (string)
{ return "v0.4.9 (47c069a9)"; }
function interface() constant returns (string)
{ return '[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"burn","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"emission","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"delegate","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"_address","type":"address"}],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"unapprove","outputs":[],"type":"function"},{"inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_decimals","type":"uint8"},{"name":"_start_count","type":"uint256"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"}]'; }
}
/**
* @dev Double linked list with address items
*/
library AddressList {
struct Data {
address head;
address tail;
mapping(address => bool) isContain;
mapping(address => address) nextOf;
mapping(address => address) prevOf;
}
function first(Data storage _data) constant returns (address)
{ return _data.head; }
function last(Data storage _data) constant returns (address)
{ return _data.tail; }
/**
* @dev Chec list for element
* @param _data is list storage ref
* @param _item is an element
* @return `true` when element in list
*/
function contains(Data storage _data, address _item) constant returns (bool)
{ return _data.isContain[_item]; }
/**
* @dev Next element of list
* @param _data is list storage ref
* @param _item is current element of list
* @return next elemen of list
*/
function next(Data storage _data, address _item) constant returns (address)
{ return _data.nextOf[_item]; }
/**
* @dev Previous element of list
* @param _data is list storage ref
* @param _item is current element of list
* @return previous element of list
*/
function prev(Data storage _data, address _item) constant returns (address)
{ return _data.prevOf[_item]; }
/**
* @dev Append element to end of list
* @param _data is list storage ref
* @param _item is a new list element
*/
function append(Data storage _data, address _item)
{ append(_data, _item, _data.tail); }
/**
* @dev Append element to end of element
* @param _data is list storage ref
* @param _item is a new list element
* @param _to is a item element before new
* @notice gas usage < 100000
*/
function append(Data storage _data, address _item, address _to) {
// Unable to contain double element
if (_data.isContain[_item]) throw;
// Empty list
if (_data.head == 0) {
_data.head = _data.tail = _item;
} else {
if (!_data.isContain[_to]) throw;
var nextTo = _data.nextOf[_to];
if (nextTo != 0) {
_data.prevOf[nextTo] = _item;
} else {
_data.tail = _item;
}
_data.nextOf[_to] = _item;
_data.prevOf[_item] = _to;
_data.nextOf[_item] = nextTo;
}
_data.isContain[_item] = true;
}
/**
* @dev Prepend element to begin of list
* @param _data is list storage ref
* @param _item is a new list element
*/
function prepend(Data storage _data, address _item)
{ prepend(_data, _item, _data.head); }
/**
* @dev Prepend element to element of list
* @param _data is list storage ref
* @param _item is a new list element
* @param _to is a item element before new
*/
function prepend(Data storage _data, address _item, address _to) {
// Unable to contain double element
if (_data.isContain[_item]) throw;
// Empty list
if (_data.head == 0) {
_data.head = _data.tail = _item;
} else {
if (!_data.isContain[_to]) throw;
var prevTo = _data.prevOf[_to];
if (prevTo != 0) {
_data.nextOf[prevTo] = _item;
} else {
_data.head = _item;
}
_data.prevOf[_item] = prevTo;
_data.nextOf[_item] = _to;
_data.prevOf[_to] = _item;
}
_data.isContain[_item] = true;
}
/**
* @dev Remove element from list
* @param _data is list storage ref
* @param _item is a removed list element
*/
function remove(Data storage _data, address _item) {
if (!_data.isContain[_item]) throw;
var elemPrev = _data.prevOf[_item];
var elemNext = _data.nextOf[_item];
if (elemPrev != 0) {
_data.nextOf[elemPrev] = elemNext;
} else {
_data.head = elemNext;
}
if (elemNext != 0) {
_data.prevOf[elemNext] = elemPrev;
} else {
_data.tail = elemPrev;
}
_data.isContain[_item] = false;
}
/**
* @dev Replace element on list
* @param _data is list storage ref
* @param _from is old element
* @param _to is a new element
*/
function replace(Data storage _data, address _from, address _to) {
if (!_data.isContain[_from]) throw;
var elemPrev = _data.prevOf[_from];
var elemNext = _data.nextOf[_from];
if (elemPrev != 0) {
_data.nextOf[elemPrev] = _to;
} else {
_data.head = _to;
}
if (elemNext != 0) {
_data.prevOf[elemNext] = _to;
} else {
_data.tail = _to;
}
_data.prevOf[_to] = elemPrev;
_data.nextOf[_to] = elemNext;
_data.isContain[_from] = false;
}
/**
* @dev Swap two elements of list
* @param _data is list storage ref
* @param _a is a first element
* @param _b is a second element
*/
function swap(Data storage _data, address _a, address _b) {
if (!_data.isContain[_a] || !_data.isContain[_b]) throw;
var prevA = _data.prevOf[_a];
remove(_data, _a);
replace(_data, _b, _a);
if (prevA == 0) {
prepend(_data, _b);
} else {
append(_data, _b, prevA);
}
}
}
/**
* @dev Iterable by index (string => address) mapping structure
* with reverse resolve and fast element remove
*/
library AddressMap {
struct Data {
mapping(bytes32 => address) valueOf;
mapping(address => string) keyOf;
AddressList.Data items;
}
using AddressList for AddressList.Data;
/**
* @dev Get element by name
* @param _data is an map storage ref
* @param _key is a item key
* @return item value
*/
function get(Data storage _data, string _key) constant returns (address)
{ return _data.valueOf[sha3(_key)]; }
/** Get key of element
* @param _data is an map storage ref
* @param _item is a item
* @return item key
*/
function getKey(Data storage _data, address _item) constant returns (string)
{ return _data.keyOf[_item]; }
/**
* @dev Set element value for given key
* @param _data is an map storage ref
* @param _key is a item key
* @param _value is a item value
* @notice by design you can't set different keys with same value
*/
function set(Data storage _data, string _key, address _value) {
var replaced = get(_data, _key);
if (replaced != 0)
_data.items.replace(replaced, _value);
else
_data.items.append(_value);
_data.valueOf[sha3(_key)] = _value;
_data.keyOf[_value] = _key;
}
/**
* @dev Remove item from map by key
* @param _data is an map storage ref
* @param _key is and item key
*/
function remove(Data storage _data, string _key) {
var value = get(_data, _key);
_data.items.remove(value);
_data.valueOf[sha3(_key)] = 0;
_data.keyOf[value] = "";
}
}
/**
* @title Contract for objects that can be morder
*/
contract Mortal is Owned {
/**
* @dev Destroy contract and scrub a data
* @notice Only owner can kill me
*/
function kill() onlyOwner
{ suicide(owner); }
}
/**
* @title The DAO core contract basicaly describe the organisation and contain:
* agent storage,
* infrastructure nodes,
* contract templates
*/
contract Core is Mortal {
/* Short description */
string public name;
string public description;
address public founder;
/* Modules map */
AddressMap.Data modules;
/* Module constant mapping */
mapping(bytes32 => bool) is_constant;
/**
* @dev Interface storage
* the contract interface contains source URI
*/
mapping(address => string) public interfaceOf;
/* Using libraries */
using AddressList for AddressList.Data;
using AddressMap for AddressMap.Data;
/**
* @dev DAO constructor
* @param _name is a DAO name
* @param _description is a short DAO description
*/
function Core(string _name, string _description) {
name = _name;
description = _description;
founder = msg.sender;
}
/**
* @dev Fast module exist check
* @param _module is a module address
* @return `true` wnen core contains module
*/
function contains(address _module) constant returns (bool)
{ return modules.items.contains(_module); }
/**
* @dev Check for module have permanent name
* @param _name is a module name
* @return `true` when module have permanent name
*/
function isConstant(string _name) constant returns (bool)
{ return is_constant[sha3(_name)]; }
/**
* @dev Get module by name
* @param _name is module name
* @return module address
*/
function getModule(string _name) constant returns (address)
{ return modules.get(_name); }
/**
* @dev Get module name by address
* @param _module is a module address
* @return module name
*/
function getModuleName(address _module) constant returns (string)
{ return modules.keyOf[_module]; }
/**
* @dev Get first module
* @return first address
*/
function firstModule() constant returns (address)
{ return modules.items.head; }
/**
* @dev Get next module
* @param _current is an current address
* @return next address
*/
function nextModule(address _current) constant returns (address)
{ return modules.items.next(_current); }
/**
* @dev Set new module for given name
* @param _name infrastructure node name
* @param _module infrastructure node address
* @param _interface node interface URI
* @param _constant have a `true` value when you create permanent name of module
*/
function setModule(string _name, address _module, string _interface, bool _constant) onlyOwner {
if (isConstant(_name)) throw;
// Set module in the map
modules.set(_name, _module);
// Register node interface
interfaceOf[_module] = _interface;
// Register constant module
is_constant[sha3(_name)] = _constant;
}
/**
* @dev Remove module by name
* @param _name module name
*/
function removeModule(string _name) onlyOwner {
if (isConstant(_name)) throw;
// Remove module
modules.remove(_name);
}
}
library CreatorCore {
function create(string _name, string _description) returns (Core)
{ return new Core(_name, _description); }
function version() constant returns (string)
{ return "v0.4.9 (47c069a9)"; }
function interface() constant returns (string)
{ return '[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"getModule","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_module","type":"address"}],"name":"getModuleName","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"interfaceOf","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":true,"inputs":[],"name":"founder","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"removeModule","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"delegate","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_module","type":"address"}],"name":"contains","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"firstModule","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"description","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"isConstant","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_module","type":"address"},{"name":"_interface","type":"string"},{"name":"_constant","type":"bool"}],"name":"setModule","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_current","type":"address"}],"name":"nextModule","outputs":[{"name":"","type":"address"}],"type":"function"},{"inputs":[{"name":"_name","type":"string"},{"name":"_description","type":"string"}],"type":"constructor"}]'; }
}
contract Proposal is Owned {
// Constructor
function Proposal(address _destination, uint _targetValue, string _description) {
destination = _destination;
description = _description;
targetValue = _targetValue;
}
// Proposal destination address
address public destination;
// Proposal description
string public description;
// Proposal value in credits
uint public targetValue;
// Proposal close time
uint public closed = 0;
function close() onlyOwner
{ closed = now; }
// Current summary shares given
uint public summaryShares = 0;
function setSummaryShares(uint _summary) onlyOwner
{ summaryShares = _summary; }
// Current given shares by funder address
mapping(address => uint) public sharesOf;
function setSharesOf(address _funder, uint _shares) onlyOwner
{ sharesOf[_funder] = _shares; }
// Amount of credits returned
uint public backValue = 0;
function setBackValue(uint _backValue) onlyOwner
{ backValue = _backValue; }
// Current released shares
mapping(address => uint) public refundSharesOf;
function setRefunSharesOf(address _funder, uint _shares) onlyOwner
{ refundSharesOf[_funder] = _shares; }
// List of proposal funders
address[] public funders;
function appendFunder(address _funder) onlyOwner
{ funders.push(_funder); }
uint public sharePrice = 0;
function setSharePrice(uint _sharePrice) onlyOwner
{ sharePrice = _sharePrice; }
}
contract CashFlow is Owned {
Token public credits;
Token public shares;
// Proposal list
Proposal[] public proposals;
// Events
event Created(address indexed proposal);
event Updated(address indexed proposal);
event Closed(address indexed proposal);
// Constructor
function CashFlow(address _credits, address _shares) {
credits = Token(_credits);
shares = Token(_shares);
}
/**
* @dev Nominal price of one share in credits
* @return amount of credits in one share
*/
function nominalSharePrice() constant returns (uint)
{ return credits.getBalance() / shares.totalSupply(); }
/**
* @dev Initial new proposal
* @param _target is a destination address
* @param _total is a credits goal
* @param _description is a short description of new proposal
* @return proposal address
*/
function proposal(address _target, uint _total, string _description) returns (Proposal) {
var proposal = new Proposal(_target, _total, _description);
proposals.push(proposal);
Created(proposal);
return proposal;
}
/**
* @dev Vote for the proposal
* @param _proposal is an proposal instance
* @param _value is a count of given shares
*/
function fund(Proposal _proposal, uint _value) {
if (_proposal.closed() > 0 ||
shares.getBalance(msg.sender) < _value) throw;
var share_price = nominalSharePrice();
var summary = _proposal.summaryShares() + _value;
bool overload = summary * share_price > _proposal.targetValue();
if (overload) {
var correction = summary * share_price - _proposal.targetValue();
_value -= correction / share_price;
}
// Transfer shares
shares.transferFrom(msg.sender, this, _value);
// Append new funder
_proposal.appendFunder(msg.sender);
_proposal.setSharesOf(msg.sender, _proposal.sharesOf(msg.sender) + _value);
_proposal.setSummaryShares(_proposal.summaryShares() + _value);
// Is proposal done?
if (_proposal.summaryShares() * share_price >= _proposal.targetValue()) {
// Transfer credits
if (!credits.transfer(_proposal.destination(),
_proposal.targetValue())) throw;
// Close proposal
_proposal.close();
_proposal.setSharePrice(share_price);
Closed(_proposal);
} else {
Updated(_proposal);
}
}
/**
* @dev Refund shares from proposal
* @param _proposal is a proposal instance
* @param _value is how amount shares will be refunded
* @notice target proposal should be open
*/
function refund(Proposal _proposal, uint _value) {
uint sender_balance = _proposal.sharesOf(msg.sender);
uint refund_shares = 0;
if (_proposal.closed() > 0) {
// CLOSED proposal
var free_shares = sender_balance
* _proposal.backValue()
/ _proposal.targetValue();
refund_shares = free_shares > sender_balance
? sender_balance : free_shares;
refund_shares = refund_shares > _value
? _value : refund_shares;
_proposal.setRefunSharesOf(msg.sender, refund_shares);
} else {
// OPEN proposal
refund_shares = sender_balance > _value ? _value : sender_balance;
_proposal.setSharesOf(msg.sender, sender_balance - refund_shares);
_proposal.setSummaryShares(_proposal.summaryShares() - refund_shares);
}
if (!shares.transfer(msg.sender, refund_shares)) throw;
Updated(_proposal);
}
/**
* @dev Request for release shares by sending
* @param _proposal is a proposal instance
* @param _value is a value of returned credits
*/
function fundback(Proposal _proposal, uint _value) {
// Try to take a credits
if (!credits.transferFrom(msg.sender, this, _value)) throw;
// Update back value
_proposal.setBackValue(_proposal.backValue() + _value);
Updated(_proposal);
}
}
/**
* @title Ethereum crypto currency extention for Token contract
*/
contract TokenEther is Token {
function TokenEther(string _name, string _symbol)
Token(_name, _symbol, 18, 0)
{}
/**
* @dev This is the way to withdraw money from token
* @param _value how many tokens withdraw from balance
*/
function withdraw(uint _value) {
if (balanceOf[msg.sender] >= _value) {
balanceOf[msg.sender] -= _value;
totalSupply -= _value;
if(!msg.sender.send(_value)) throw;
}
}
/**
* @dev This is the way to refill your token balance by ethers
*/
function refill() {
balanceOf[msg.sender] += msg.value;
totalSupply += msg.value;
}
/**
* @dev This method is called when money sended to contract address,
* a synonym for refill()
*/
function () {
balanceOf[msg.sender] += msg.value;
totalSupply += msg.value;
}
}
/**
* @title Builder based contract
*/
contract BuilderBase is Mortal {
/* Addresses builded contracts at sender */
mapping(address => address[]) public getContractsOf;
/**
* @dev this event emitted for every builded contract
*/
event Builded(address indexed sender, address indexed instance);
/**
* @dev Get last address
* @return last address contract
*/
function getLastContract() constant returns (address) {
var sender_contracts = getContractsOf[msg.sender];
return sender_contracts[sender_contracts.length - 1];
}
}
/**
* @title Builder based contract
*/
contract Builder is BuilderBase {
/* Building beneficiary */
address public beneficiary;
/**
* @dev Set beneficiary
* @param _beneficiary is address of beneficiary
*/
function setBeneficiary(address _beneficiary) onlyOwner
{ beneficiary = _beneficiary; }
/* Building cost */
uint public buildingCostWei;
/**
* @dev Set building cost
* @param _buildingCostWei is cost
*/
function setCost(uint _buildingCostWei) onlyOwner
{ buildingCostWei = _buildingCostWei; }
/* Security check report */
string public securityCheckURI;
/**
* @dev Set security check report URI
* @param _uri is an URI to report
*/
function setSecurityCheck(string _uri) onlyOwner
{ securityCheckURI = _uri; }
/**
* @dev Payment for builded contract and a request for release of shares
* @param _contract is address contract
* @notice Called after builded contract
*/
function deal(address _contract) internal {
Builded(msg.sender, _contract);
getContractsOf[msg.sender].push(_contract);
if (buildingCostWei > 0 && beneficiary != 0) {
if ( msg.value < buildingCostWei
|| !msg.sender.send(msg.value - buildingCostWei)
|| !beneficiary.send(buildingCostWei)
) throw;
}
}
}
//
// AIRA Builder for basic DAO contracts
//
// Ethereum address:
// - Testnet:
//
contract BuilderDAO is Builder {
function create(string _dao_name, string _dao_description,
string _shares_name, string _shares_symbol, uint _shares_count) {
// DAO core
var dao = CreatorCore.create(_dao_name, _dao_description);
var shares = CreatorTokenEmission.create(_shares_name, _shares_symbol, 0, _shares_count);
shares.transfer(msg.sender, _shares_count);
shares.delegate(msg.sender);
// Append shares module
dao.setModule(_shares_name, shares,
"github://airalab/core/token/TokenEmission.sol", true);
// Delegate DAO to sender
dao.delegate(msg.sender);
// Notify
deal(dao);
}
}
External Links
Related contracts
AddressList
Same deployerA doubly linked list of addresses, deployed as a shared library
0xb0af78...dff94bAugust 18, 2016Contract 0x7e62ca...86e943
Same deployerAn address to address map with iteration, deployed as a shared library
0x7e62ca...86e943August 18, 2016CreatorTokenEther
Same deployerA factory library that deploys tokens backed one for one by ether held in the token
0x01f568...7b8312August 18, 2016AddressList
Same deployerA doubly linked list of addresses, deployed as a shared library
0xb51afd...224574August 25, 2016Contract 0xed6216...c0bce9
Same deployerAn address to address map with iteration, deployed as a shared library
0xed6216...c0bce9August 25, 2016CreatorVoting51
Same deployerA factory library that deploys simple majority voting contracts
0x6e98df...86df55August 25, 2016