pragma solidity 0.4.15;
/**
* @title ERC20Basic
* @dev Simpler version of ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/179
*/
contract ERC20Basic {
uint256 public totalSupply;
function balanceOf(address who) constant returns (uint256);
function transfer(address to, uint256 value) returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
}
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
function mul(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal constant returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
function sub(uint256 a, uint256 b) internal constant returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
/**
* @title Basic token
* @dev Basic version of StandardToken, with no allowances.
*/
contract BasicToken is ERC20Basic {
using SafeMath for uint256;
mapping(address => uint256) balances;
/**
* @dev transfer token for a specified address
* @param _to The address to transfer to.
* @param _value The amount to be transferred.
*/
function transfer(address _to, uint256 _value) returns (bool) {
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
Transfer(msg.sender, _to, _value);
return true;
}
/**
* @dev Gets the balance of the specified address.
* @param _owner The address to query the the balance of.
* @return An uint256 representing the amount owned by the passed address.
*/
function balanceOf(address _owner) constant returns (uint256 balance) {
return balances[_owner];
}
}
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
*/
contract ERC20 is ERC20Basic {
function allowance(address owner, address spender) constant returns (uint256);
function transferFrom(address from, address to, uint256 value) returns (bool);
function approve(address spender, uint256 value) returns (bool);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
/**
* @title Standard ERC20 token
*
* @dev Implementation of the basic standard token.
* @dev https://github.com/ethereum/EIPs/issues/20
* @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*/
contract StandardToken is ERC20, BasicToken {
mapping (address => mapping (address => uint256)) allowed;
/**
* @dev Transfer tokens from one address to another
* @param _from address The address which you want to send tokens from
* @param _to address The address which you want to transfer to
* @param _value uint256 the amout of tokens to be transfered
*/
function transferFrom(address _from, address _to, uint256 _value) returns (bool) {
var _allowance = allowed[_from][msg.sender];
// Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
// require (_value <= _allowance);
balances[_to] = balances[_to].add(_value);
balances[_from] = balances[_from].sub(_value);
allowed[_from][msg.sender] = _allowance.sub(_value);
Transfer(_from, _to, _value);
return true;
}
/**
* @dev Aprove the passed address to spend the specified amount of tokens on behalf of msg.sender.
* @param _spender The address which will spend the funds.
* @param _value The amount of tokens to be spent.
*/
function approve(address _spender, uint256 _value) returns (bool) {
// To change the approve amount you first have to reduce the addresses`
// allowance to zero by calling `approve(_spender, 0)` if it is not
// already 0 to mitigate the race condition described here:
// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
require((_value == 0) || (allowed[msg.sender][_spender] == 0));
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
return true;
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param _owner address The address which owns the funds.
* @param _spender address The address which will spend the funds.
* @return A uint256 specifing the amount of tokens still avaible for the spender.
*/
function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
return allowed[_owner][_spender];
}
}
/// @title StandardToken which circulation can be delayed and started by another contract.
/// @dev To be used as a mixin contract.
/// The contract is created in disabled state: circulation is disabled.
contract CirculatingToken is StandardToken {
event CirculationEnabled();
modifier requiresCirculation {
require(m_isCirculating);
_;
}
// PUBLIC interface
function transfer(address _to, uint256 _value) requiresCirculation returns (bool) {
return super.transfer(_to, _value);
}
function transferFrom(address _from, address _to, uint256 _value) requiresCirculation returns (bool) {
return super.transferFrom(_from, _to, _value);
}
function approve(address _spender, uint256 _value) requiresCirculation returns (bool) {
return super.approve(_spender, _value);
}
// INTERNAL functions
function enableCirculation() internal returns (bool) {
if (m_isCirculating)
return false;
m_isCirculating = true;
CirculationEnabled();
return true;
}
// FIELDS
/// @notice are the circulation started?
bool public m_isCirculating;
}
/// note: during any ownership changes all pending operations (waiting for more signatures) are cancelled
// TODO acceptOwnership
contract multiowned {
// TYPES
// struct for the status of a pending operation.
struct MultiOwnedOperationPendingState {
// count of confirmations needed
uint yetNeeded;
// bitmap of confirmations where owner #ownerIndex's decision corresponds to 2**ownerIndex bit
uint ownersDone;
// position of this operation key in m_multiOwnedPendingIndex
uint index;
}
// EVENTS
event Confirmation(address owner, bytes32 operation);
event Revoke(address owner, bytes32 operation);
event FinalConfirmation(address owner, bytes32 operation);
// some others are in the case of an owner changing.
event OwnerChanged(address oldOwner, address newOwner);
event OwnerAdded(address newOwner);
event OwnerRemoved(address oldOwner);
// the last one is emitted if the required signatures change
event RequirementChanged(uint newRequirement);
// MODIFIERS
// simple single-sig function modifier.
modifier onlyowner {
require(isOwner(msg.sender));
_;
}
// multi-sig function modifier: the operation must have an intrinsic hash in order
// that later attempts can be realised as the same underlying operation and
// thus count as confirmations.
modifier onlymanyowners(bytes32 _operation) {
if (confirmAndCheck(_operation)) {
_;
}
// Even if required number of confirmations has't been collected yet,
// we can't throw here - because changes to the state have to be preserved.
// But, confirmAndCheck itself will throw in case sender is not an owner.
}
modifier validNumOwners(uint _numOwners) {
require(_numOwners > 0 && _numOwners <= c_maxOwners);
_;
}
modifier multiOwnedValidRequirement(uint _required, uint _numOwners) {
require(_required > 0 && _required <= _numOwners);
_;
}
modifier ownerExists(address _address) {
require(isOwner(_address));
_;
}
modifier ownerDoesNotExist(address _address) {
require(!isOwner(_address));
_;
}
modifier multiOwnedOperationIsActive(bytes32 _operation) {
require(isOperationActive(_operation));
_;
}
// METHODS
// constructor is given number of sigs required to do protected "onlymanyowners" transactions
// as well as the selection of addresses capable of confirming them (msg.sender is not added to the owners!).
function multiowned(address[] _owners, uint _required)
validNumOwners(_owners.length)
multiOwnedValidRequirement(_required, _owners.length)
{
assert(c_maxOwners <= 255);
m_numOwners = _owners.length;
m_multiOwnedRequired = _required;
for (uint i = 0; i < _owners.length; ++i)
{
address owner = _owners[i];
// invalid and duplicate addresses are not allowed
require(0 != owner && !isOwner(owner) /* not isOwner yet! */);
uint currentOwnerIndex = checkOwnerIndex(i + 1 /* first slot is unused */);
m_owners[currentOwnerIndex] = owner;
m_ownerIndex[owner] = currentOwnerIndex;
}
assertOwnersAreConsistent();
}
/// @notice replaces an owner `_from` with another `_to`.
/// @param _from address of owner to replace
/// @param _to address of new owner
// All pending operations will be canceled!
function changeOwner(address _from, address _to)
external
ownerExists(_from)
ownerDoesNotExist(_to)
onlymanyowners(sha3(msg.data))
{
assertOwnersAreConsistent();
clearPending();
uint ownerIndex = checkOwnerIndex(m_ownerIndex[_from]);
m_owners[ownerIndex] = _to;
m_ownerIndex[_from] = 0;
m_ownerIndex[_to] = ownerIndex;
assertOwnersAreConsistent();
OwnerChanged(_from, _to);
}
/// @notice adds an owner
/// @param _owner address of new owner
// All pending operations will be canceled!
function addOwner(address _owner)
external
ownerDoesNotExist(_owner)
validNumOwners(m_numOwners + 1)
onlymanyowners(sha3(msg.data))
{
assertOwnersAreConsistent();
clearPending();
m_numOwners++;
m_owners[m_numOwners] = _owner;
m_ownerIndex[_owner] = checkOwnerIndex(m_numOwners);
assertOwnersAreConsistent();
OwnerAdded(_owner);
}
/// @notice removes an owner
/// @param _owner address of owner to remove
// All pending operations will be canceled!
function removeOwner(address _owner)
external
ownerExists(_owner)
validNumOwners(m_numOwners - 1)
multiOwnedValidRequirement(m_multiOwnedRequired, m_numOwners - 1)
onlymanyowners(sha3(msg.data))
{
assertOwnersAreConsistent();
clearPending();
uint ownerIndex = checkOwnerIndex(m_ownerIndex[_owner]);
m_owners[ownerIndex] = 0;
m_ownerIndex[_owner] = 0;
//make sure m_numOwners is equal to the number of owners and always points to the last owner
reorganizeOwners();
assertOwnersAreConsistent();
OwnerRemoved(_owner);
}
/// @notice changes the required number of owner signatures
/// @param _newRequired new number of signatures required
// All pending operations will be canceled!
function changeRequirement(uint _newRequired)
external
multiOwnedValidRequirement(_newRequired, m_numOwners)
onlymanyowners(sha3(msg.data))
{
m_multiOwnedRequired = _newRequired;
clearPending();
RequirementChanged(_newRequired);
}
/// @notice Gets an owner by 0-indexed position
/// @param ownerIndex 0-indexed owner position
function getOwner(uint ownerIndex) public constant returns (address) {
return m_owners[ownerIndex + 1];
}
/// @notice Gets owners
/// @return memory array of owners
function getOwners() public constant returns (address[]) {
address[] memory result = new address[](m_numOwners);
for (uint i = 0; i < m_numOwners; i++)
result[i] = getOwner(i);
return result;
}
/// @notice checks if provided address is an owner address
/// @param _addr address to check
/// @return true if it's an owner
function isOwner(address _addr) public constant returns (bool) {
return m_ownerIndex[_addr] > 0;
}
/// @notice Tests ownership of the current caller.
/// @return true if it's an owner
// It's advisable to call it by new owner to make sure that the same erroneous address is not copy-pasted to
// addOwner/changeOwner and to isOwner.
function amIOwner() external constant onlyowner returns (bool) {
return true;
}
/// @notice Revokes a prior confirmation of the given operation
/// @param _operation operation value, typically sha3(msg.data)
function revoke(bytes32 _operation)
external
multiOwnedOperationIsActive(_operation)
onlyowner
{
uint ownerIndexBit = makeOwnerBitmapBit(msg.sender);
var pending = m_multiOwnedPending[_operation];
require(pending.ownersDone & ownerIndexBit > 0);
assertOperationIsConsistent(_operation);
pending.yetNeeded++;
pending.ownersDone -= ownerIndexBit;
assertOperationIsConsistent(_operation);
Revoke(msg.sender, _operation);
}
/// @notice Checks if owner confirmed given operation
/// @param _operation operation value, typically sha3(msg.data)
/// @param _owner an owner address
function hasConfirmed(bytes32 _operation, address _owner)
external
constant
multiOwnedOperationIsActive(_operation)
ownerExists(_owner)
returns (bool)
{
return !(m_multiOwnedPending[_operation].ownersDone & makeOwnerBitmapBit(_owner) == 0);
}
// INTERNAL METHODS
function confirmAndCheck(bytes32 _operation)
private
onlyowner
returns (bool)
{
if (512 == m_multiOwnedPendingIndex.length)
// In case m_multiOwnedPendingIndex grows too much we have to shrink it: otherwise at some point
// we won't be able to do it because of block gas limit.
// Yes, pending confirmations will be lost. Dont see any security or stability implications.
// TODO use more graceful approach like compact or removal of clearPending completely
clearPending();
var pending = m_multiOwnedPending[_operation];
// if we're not yet working on this operation, switch over and reset the confirmation status.
if (! isOperationActive(_operation)) {
// reset count of confirmations needed.
pending.yetNeeded = m_multiOwnedRequired;
// reset which owners have confirmed (none) - set our bitmap to 0.
pending.ownersDone = 0;
pending.index = m_multiOwnedPendingIndex.length++;
m_multiOwnedPendingIndex[pending.index] = _operation;
assertOperationIsConsistent(_operation);
}
// determine the bit to set for this owner.
uint ownerIndexBit = makeOwnerBitmapBit(msg.sender);
// make sure we (the message sender) haven't confirmed this operation previously.
if (pending.ownersDone & ownerIndexBit == 0) {
// ok - check if count is enough to go ahead.
assert(pending.yetNeeded > 0);
if (pending.yetNeeded == 1) {
// enough confirmations: reset and run interior.
delete m_multiOwnedPendingIndex[m_multiOwnedPending[_operation].index];
delete m_multiOwnedPending[_operation];
FinalConfirmation(msg.sender, _operation);
return true;
}
else
{
// not enough: record that this owner in particular confirmed.
pending.yetNeeded--;
pending.ownersDone |= ownerIndexBit;
assertOperationIsConsistent(_operation);
Confirmation(msg.sender, _operation);
}
}
}
// Reclaims free slots between valid owners in m_owners.
// TODO given that its called after each removal, it could be simplified.
function reorganizeOwners() private {
uint free = 1;
while (free < m_numOwners)
{
// iterating to the first free slot from the beginning
while (free < m_numOwners && m_owners[free] != 0) free++;
// iterating to the first occupied slot from the end
while (m_numOwners > 1 && m_owners[m_numOwners] == 0) m_numOwners--;
// swap, if possible, so free slot is located at the end after the swap
if (free < m_numOwners && m_owners[m_numOwners] != 0 && m_owners[free] == 0)
{
// owners between swapped slots should't be renumbered - that saves a lot of gas
m_owners[free] = m_owners[m_numOwners];
m_ownerIndex[m_owners[free]] = free;
m_owners[m_numOwners] = 0;
}
}
}
function clearPending() private onlyowner {
uint length = m_multiOwnedPendingIndex.length;
for (uint i = 0; i < length; ++i) {
if (m_multiOwnedPendingIndex[i] != 0)
delete m_multiOwnedPending[m_multiOwnedPendingIndex[i]];
}
delete m_multiOwnedPendingIndex;
}
function checkOwnerIndex(uint ownerIndex) private constant returns (uint) {
assert(0 != ownerIndex && ownerIndex <= c_maxOwners);
return ownerIndex;
}
function makeOwnerBitmapBit(address owner) private constant returns (uint) {
uint ownerIndex = checkOwnerIndex(m_ownerIndex[owner]);
return 2 ** ownerIndex;
}
function isOperationActive(bytes32 _operation) private constant returns (bool) {
return 0 != m_multiOwnedPending[_operation].yetNeeded;
}
function assertOwnersAreConsistent() private constant {
assert(m_numOwners > 0);
assert(m_numOwners <= c_maxOwners);
assert(m_owners[0] == 0);
assert(0 != m_multiOwnedRequired && m_multiOwnedRequired <= m_numOwners);
}
function assertOperationIsConsistent(bytes32 _operation) private constant {
var pending = m_multiOwnedPending[_operation];
assert(0 != pending.yetNeeded);
assert(m_multiOwnedPendingIndex[pending.index] == _operation);
assert(pending.yetNeeded <= m_multiOwnedRequired);
}
// FIELDS
uint constant c_maxOwners = 250;
// the number of owners that must confirm the same operation before it is run.
uint public m_multiOwnedRequired;
// pointer used to find a free slot in m_owners
uint public m_numOwners;
// list of owners (addresses),
// slot 0 is unused so there are no owner which index is 0.
// TODO could we save space at the end of the array for the common case of <10 owners? and should we?
address[256] internal m_owners;
// index on the list of owners to allow reverse lookup: owner address => index in m_owners
mapping(address => uint) internal m_ownerIndex;
// the ongoing operations.
mapping(bytes32 => MultiOwnedOperationPendingState) internal m_multiOwnedPending;
bytes32[] internal m_multiOwnedPendingIndex;
}
/**
* @title Contract which is owned by owners and operated by controller.
*
* @notice Provides a way to set up an entity (typically other contract) entitled to control actions of this contract.
* Controller is set up by owners or during construction.
*
* @dev controller check is performed by onlyController modifier.
*/
contract MultiownedControlled is multiowned {
event ControllerSet(address controller);
event ControllerRetired(address was);
modifier onlyController {
require(msg.sender == m_controller);
_;
}
// PUBLIC interface
function MultiownedControlled(address[] _owners, uint _signaturesRequired, address _controller)
multiowned(_owners, _signaturesRequired)
{
m_controller = _controller;
ControllerSet(m_controller);
}
/// @dev sets the controller
function setController(address _controller) external onlymanyowners(sha3(msg.data)) {
m_controller = _controller;
ControllerSet(m_controller);
}
/// @dev ability for controller to step down
function detachController() external onlyController {
address was = m_controller;
m_controller = address(0);
ControllerRetired(was);
}
// FIELDS
/// @notice address of entity entitled to mint new tokens
address public m_controller;
}
/// @title StandardToken which can be minted by another contract.
contract MintableMultiownedToken is MultiownedControlled, StandardToken {
/// @dev parameters of an extra token emission
struct EmissionInfo {
// tokens created
uint256 created;
// totalSupply at the moment of emission (excluding created tokens)
uint256 totalSupplyWas;
}
event Mint(address indexed to, uint256 amount);
event Emission(uint256 tokensCreated, uint256 totalSupplyWas, uint256 time);
event Dividend(address indexed to, uint256 amount);
// PUBLIC interface
function MintableMultiownedToken(address[] _owners, uint _signaturesRequired, address _minter)
MultiownedControlled(_owners, _signaturesRequired, _minter)
{
dividendsPool = this; // or any other special unforgeable value, actually
// emission #0 is a dummy: because of default value 0 in m_lastAccountEmission
m_emissions.push(EmissionInfo({created: 0, totalSupplyWas: 0}));
}
/// @notice Request dividends for current account.
function requestDividends() external {
payDividendsTo(msg.sender);
}
/// @notice hook on standard ERC20#transfer to pay dividends
function transfer(address _to, uint256 _value) returns (bool) {
payDividendsTo(msg.sender);
payDividendsTo(_to);
return super.transfer(_to, _value);
}
/// @notice hook on standard ERC20#transferFrom to pay dividends
function transferFrom(address _from, address _to, uint256 _value) returns (bool) {
payDividendsTo(_from);
payDividendsTo(_to);
return super.transferFrom(_from, _to, _value);
}
// Disabled: this could be undesirable because sum of (balanceOf() for each token owner) != totalSupply
// (but: sum of (balances[owner] for each token owner) == totalSupply!).
//
// @notice hook on standard ERC20#balanceOf to take dividends into consideration
// function balanceOf(address _owner) constant returns (uint256) {
// var (hasNewDividends, dividends) = calculateDividendsFor(_owner);
// return hasNewDividends ? super.balanceOf(_owner).add(dividends) : super.balanceOf(_owner);
// }
/// @dev mints new tokens
function mint(address _to, uint256 _amount) external onlyController {
require(m_externalMintingEnabled);
payDividendsTo(_to);
mintInternal(_to, _amount);
}
/// @dev disables mint(), irreversible!
function disableMinting() external onlyController {
require(m_externalMintingEnabled);
m_externalMintingEnabled = false;
}
// INTERNAL functions
/**
* @notice Starts new token emission
* @param _tokensCreated Amount of tokens to create
* @dev Dividends are not distributed immediately as it could require billions of gas,
* instead they are `pulled` by a holder from dividends pool account before any update to the holder account occurs.
*/
function emissionInternal(uint256 _tokensCreated) internal {
require(0 != _tokensCreated);
require(_tokensCreated < totalSupply / 2); // otherwise it looks like an error
uint256 totalSupplyWas = totalSupply;
m_emissions.push(EmissionInfo({created: _tokensCreated, totalSupplyWas: totalSupplyWas}));
mintInternal(dividendsPool, _tokensCreated);
Emission(_tokensCreated, totalSupplyWas, now);
}
function mintInternal(address _to, uint256 _amount) internal {
totalSupply = totalSupply.add(_amount);
balances[_to] = balances[_to].add(_amount);
Transfer(this, _to, _amount);
Mint(_to, _amount);
}
/// @dev adds dividends to the account _to
function payDividendsTo(address _to) internal {
var (hasNewDividends, dividends) = calculateDividendsFor(_to);
if (!hasNewDividends)
return;
if (0 != dividends) {
balances[dividendsPool] = balances[dividendsPool].sub(dividends);
balances[_to] = balances[_to].add(dividends);
Transfer(dividendsPool, _to, dividends);
}
m_lastAccountEmission[_to] = getLastEmissionNum();
}
/// @dev calculates dividends for the account _for
/// @return (true if state has to be updated, dividend amount (could be 0!))
function calculateDividendsFor(address _for) constant internal returns (bool hasNewDividends, uint dividends) {
assert(_for != dividendsPool); // no dividends for the pool!
uint256 lastEmissionNum = getLastEmissionNum();
uint256 lastAccountEmissionNum = m_lastAccountEmission[_for];
assert(lastAccountEmissionNum <= lastEmissionNum);
if (lastAccountEmissionNum == lastEmissionNum)
return (false, 0);
uint256 initialBalance = balances[_for]; // beware of recursion!
if (0 == initialBalance)
return (true, 0);
uint256 balance = initialBalance;
for (uint256 emissionToProcess = lastAccountEmissionNum + 1; emissionToProcess <= lastEmissionNum; emissionToProcess++) {
EmissionInfo storage emission = m_emissions[emissionToProcess];
assert(0 != emission.created && 0 != emission.totalSupplyWas);
uint256 dividend = balance.mul(emission.created).div(emission.totalSupplyWas);
Dividend(_for, dividend);
balance = balance.add(dividend);
}
return (true, balance.sub(initialBalance));
}
function getLastEmissionNum() private constant returns (uint256) {
return m_emissions.length - 1;
}
// FIELDS
/// @notice if this true then token is still externally mintable (but this flag does't affect emissions!)
bool public m_externalMintingEnabled = true;
/// @dev internal address of dividends in balances mapping.
address dividendsPool;
/// @notice record of issued dividend emissions
EmissionInfo[] public m_emissions;
/// @dev for each token holder: last emission (index in m_emissions) which was processed for this holder
mapping(address => uint256) m_lastAccountEmission;
}
/// @title Storiqa coin contract
contract STQToken is CirculatingToken, MintableMultiownedToken {
// PUBLIC interface
function STQToken(address[] _owners)
MintableMultiownedToken(_owners, 2, /* minter: */ address(0))
{
require(3 == _owners.length);
}
/// @dev Allows token transfers
function startCirculation() external onlyController {
assert(enableCirculation()); // must be called once
}
/// @notice Starts new token emission
/// @param _tokensCreatedInSTQ Amount of STQ (not STQ-wei!) to create, like 30 000 or so
function emission(uint256 _tokensCreatedInSTQ) external onlymanyowners(sha3(msg.data)) {
emissionInternal(_tokensCreatedInSTQ.mul(uint256(10) ** uint256(decimals)));
}
// FIELDS
string public constant name = 'Storiqa Token';
string public constant symbol = 'STQ';
uint8 public constant decimals = 18;
}
{
"compilationTarget": {
"STQToken.sol": "STQToken"
},
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"removeOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"startCirculation","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_addr","type":"address"}],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_numOwners","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_externalMintingEnabled","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"amIOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"detachController","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_tokensCreatedInSTQ","type":"uint256"}],"name":"emission","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"addOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_multiOwnedRequired","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"disableMinting","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_controller","type":"address"}],"name":"setController","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getOwners","outputs":[{"name":"","type":"address[]"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"m_emissions","outputs":[{"name":"created","type":"uint256"},{"name":"totalSupplyWas","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_operation","type":"bytes32"}],"name":"revoke","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_newRequired","type":"uint256"}],"name":"changeRequirement","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_operation","type":"bytes32"},{"name":"_owner","type":"address"}],"name":"hasConfirmed","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"ownerIndex","type":"uint256"}],"name":"getOwner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"requestDividends","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_controller","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_isCirculating","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"}],"name":"changeOwner","outputs":[],"payable":false,"type":"function"},{"inputs":[{"name":"_owners","type":"address[]"}],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"tokensCreated","type":"uint256"},{"indexed":false,"name":"totalSupplyWas","type":"uint256"},{"indexed":false,"name":"time","type":"uint256"}],"name":"Emission","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Dividend","type":"event"},{"anonymous":false,"inputs":[],"name":"CirculationEnabled","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"},{"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":false,"name":"controller","type":"address"}],"name":"ControllerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"was","type":"address"}],"name":"ControllerRetired","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"}],"name":"Confirmation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"}],"name":"Revoke","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"}],"name":"FinalConfirmation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"oldOwner","type":"address"},{"indexed":false,"name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newOwner","type":"address"}],"name":"OwnerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"oldOwner","type":"address"}],"name":"OwnerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newRequirement","type":"uint256"}],"name":"RequirementChanged","type":"event"}]