The public counter that sells DAO container deployments for a fee
Historical Significance
Part of a 2016 attempt to sell working organisations as deployable parts: a governance contract, a token or a payment splitter bought from a counter for a fee, with the created contract's shape published on chain beside it.
Context
Deployed in the Homestead era, when deploying a contract meant compiling one yourself.
Key Facts
Description
BuilderCore is the public facing half of Airalab's DAO toolkit. A caller pays the building fee and gets back a freshly deployed Core, the container a DAO is built around, recorded against their address and announced in a Builded event. The owner sets the fee, the beneficiary and a URI pointing at a security review of the contract being sold. Deployed on 15 November 2016 by 0x4af013afbadb22d8a88c92d68fc96b033b9ebb8a and recovered from airalab/core. Etherscan cannot verify it: solc writes its link placeholder as the library name in lowercase at this vintage and Etherscan will not resolve that, so this record is the published form.
Source Verified
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Tangerine Whistle Era
Emergency fork to address DoS attacks. Repriced IO-heavy opcodes.
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)
pragma solidity ^0.4.4;
/**
* @dev Double linked list with address items
*/
library AddressList {
struct Data {
address head;
address tail;
uint length;
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;
++_data.length;
}
/**
* @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;
++_data.length;
}
/**
* @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;
--_data.length;
}
/**
* @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);
}
}
}
pragma solidity ^0.4.4;
/**
* @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 size of map
* @return count of elements
*/
function size(Data storage _data) constant returns (uint)
{ return _data.items.length; }
/**
* @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] = "";
}
}
pragma solidity ^0.4.4;
/**
* @title Contract for object that have an owner
*/
contract Owned {
/**
* 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; _; }
}
pragma solidity ^0.4.4;
/**
* @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); }
}
pragma solidity ^0.4.4;
/**
* @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;
/* Module manipulation events */
event ModuleAdded(address indexed module);
event ModuleRemoved(address indexed module);
event ModuleReplaced(address indexed from, address indexed to);
/* Modules map */
AddressMap.Data modules;
/* Module constant mapping */
mapping(bytes32 => bool) is_constant;
/**
* @dev Contract ABI storage
* the contract interface contains source URI
*/
mapping(address => string) public abiOf;
/* 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 Modules counter
* @return count of modules in core
*/
function size() constant returns (uint)
{ return modules.size(); }
/**
* @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 get(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 getName(address _module) constant returns (string)
{ return modules.keyOf[_module]; }
/**
* @dev Get first module
* @return first address
*/
function first() constant returns (address)
{ return modules.items.head; }
/**
* @dev Get next module
* @param _current is an current address
* @return next address
*/
function next(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 _abi node interface URI
* @param _constant have a `true` value when you create permanent name of module
*/
function set(string _name, address _module, string _abi, bool _constant) onlyOwner {
if (isConstant(_name)) throw;
// Notify
if (modules.get(_name) != 0)
ModuleReplaced(modules.get(_name), _module);
else
ModuleAdded(_module);
// Set module in the map
modules.set(_name, _module);
// Register module abi
abiOf[_module] = _abi;
// Register constant flag
is_constant[sha3(_name)] = _constant;
}
/**
* @dev Remove module by name
* @param _name module name
*/
function remove(string _name) onlyOwner {
if (isConstant(_name)) throw;
// Notify
ModuleRemoved(modules.get(_name));
// Remove module
modules.remove(_name);
}
}
pragma solidity ^0.4.2;
library CreatorCore {
function create(string _name, string _description) returns (Core)
{ return new Core(_name, _description); }
function version() constant returns (string)
{ return "v0.5.0 (041be4cf)"; }
function abi() constant returns (string)
{ return '[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"first","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"abiOf","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"founder","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"delegate","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_module","type":"address"}],"name":"contains","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_module","type":"address"}],"name":"getName","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"get","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"description","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"remove","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"isConstant","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"size","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_current","type":"address"}],"name":"next","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_module","type":"address"},{"name":"_abi","type":"string"},{"name":"_constant","type":"bool"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"inputs":[{"name":"_name","type":"string"},{"name":"_description","type":"string"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"module","type":"address"}],"name":"ModuleAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"module","type":"address"}],"name":"ModuleRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"}],"name":"ModuleReplaced","type":"event"}]'; }
}
pragma solidity ^0.4.4;
/**
* @title Builder based contract
*/
contract Builder is Mortal {
/**
* @dev this event emitted for every builded contract
*/
event Builded(address indexed client, address indexed instance);
/* Addresses builded contracts at sender */
mapping(address => address[]) public getContractsOf;
/**
* @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];
}
/* 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; }
}
//
// AIRA Builder for Core contract
//
// Ethereum address:
// - Mainnet:
// - Testnet:
//
pragma solidity ^0.4.4;
/**
* @title BuilderCore contract
*/
contract BuilderCore is Builder {
/**
* @dev Run script creation contract
* @param _name is DAO name
* @param _description is DAO description
* @param _client is a contract destination address (zero for sender)
* @return address new contract
*/
function create(string _name, string _description, address _client) payable returns (address) {
if (buildingCostWei > 0 && beneficiary != 0) {
// Too low value
if (msg.value < buildingCostWei) throw;
// Beneficiary send
if (!beneficiary.send(buildingCostWei)) throw;
// Refund
if (msg.value > buildingCostWei) {
if (!msg.sender.send(msg.value - buildingCostWei)) throw;
}
} else {
// Refund all
if (msg.value > 0) {
if (!msg.sender.send(msg.value)) throw;
}
}
if (_client == 0)
_client = msg.sender;
var inst = CreatorCore.create(_name, _description);
getContractsOf[_client].push(inst);
Builded(_client, inst);
inst.delegate(_client);
return inst;
}
}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, 2016CreatorTokenEmission
Same deployerA factory library that deploys mintable and burnable tokens, and hands back their ABI
0x63bfd6...63231eAugust 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, 2016