Skip to content

Instantly share code, notes, and snippets.

Created December 21, 2017 22:59
Show Gist options
  • Save anonymous/16068a1a0fe4158e04699a21d6d1f332 to your computer and use it in GitHub Desktop.
Save anonymous/16068a1a0fe4158e04699a21d6d1f332 to your computer and use it in GitHub Desktop.
Created using browser-solidity: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://ethereum.github.io/browser-solidity/#version=soljson-v0.4.16+commit.d7661dd9.js&optimize=true&gist=
pragma solidity ^0.4.16;
/**
* @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 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 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;
}
}
interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData); }
contract MyToken {
// Public variables of the token
string public name;
string public symbol;
uint8 public decimals;
uint256 public totalSupply;
// This creates an array with all balances
mapping (address => uint256) public balanceOf;
mapping (address => mapping (address => uint256)) public allowance;
// This generates a public event on the blockchain that will notify clients
event Transfer(address indexed from, address indexed to, uint256 value);
// This notifies clients about the amount burnt
event Burn(address indexed from, uint256 value);
/**
* Constrctor function
*
* Initializes contract with initial supply tokens to the creator of the contract
*/
function MyToken(
uint256 initialSupply,
string tokenName,
uint8 decimalUnits,
string tokenSymbol
) {
balanceOf[msg.sender] = initialSupply; // Give the creator all initial tokens
totalSupply = initialSupply; // Update total supply
name = tokenName; // Set the name for display purposes
symbol = tokenSymbol; // Set the symbol for display purposes
decimals = decimalUnits; // Amount of decimals for display purposes
}
/**
* Internal transfer, only can be called by this contract
*/
function _transfer(address _from, address _to, uint _value) internal {
require(_to != 0x0); // Prevent transfer to 0x0 address. Use burn() instead
require(balanceOf[_from] >= _value); // Check if the sender has enough
require(balanceOf[_to] + _value > balanceOf[_to]); // Check for overflows
balanceOf[_from] -= _value; // Subtract from the sender
balanceOf[_to] += _value; // Add the same to the recipient
Transfer(_from, _to, _value);
}
/**
* Transfer tokens
*
* Send `_value` tokens to `_to` from your account
*
* @param _to The address of the recipient
* @param _value the amount to send
*/
function transfer(address _to, uint256 _value) {
_transfer(msg.sender, _to, _value);
}
/**
* Transfer tokens from other address
*
* Send `_value` tokens to `_to` in behalf of `_from`
*
* @param _from The address of the sender
* @param _to The address of the recipient
* @param _value the amount to send
*/
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
require(_value <= allowance[_from][msg.sender]); // Check allowance
allowance[_from][msg.sender] -= _value;
_transfer(_from, _to, _value);
return true;
}
/**
* Set allowance for other address
*
* Allows `_spender` to spend no more than `_value` tokens in your behalf
*
* @param _spender The address authorized to spend
* @param _value the max amount they can spend
*/
function approve(address _spender, uint256 _value)
returns (bool success) {
allowance[msg.sender][_spender] = _value;
return true;
}
/**
* Set allowance for other address and notify
*
* Allows `_spender` to spend no more than `_value` tokens in your behalf, and then ping the contract about it
*
* @param _spender The address authorized to spend
* @param _value the max amount they can spend
* @param _extraData some extra information to send to the approved contract
*/
function approveAndCall(address _spender, uint256 _value, bytes _extraData)
returns (bool success) {
tokenRecipient spender = tokenRecipient(_spender);
if (approve(_spender, _value)) {
spender.receiveApproval(msg.sender, _value, this, _extraData);
return true;
}
}
/**
* Destroy tokens
*
* Remove `_value` tokens from the system irreversibly
*
* @param _value the amount of money to burn
*/
function burn(uint256 _value) returns (bool success) {
require(balanceOf[msg.sender] >= _value); // Check if the sender has enough
balanceOf[msg.sender] -= _value; // Subtract from the sender
totalSupply -= _value; // Updates totalSupply
Burn(msg.sender, _value);
return true;
}
/**
* Destroy tokens from other ccount
*
* Remove `_value` tokens from the system irreversibly on behalf of `_from`.
*
* @param _from the address of the sender
* @param _value the amount of money to burn
*/
function burnFrom(address _from, uint256 _value) returns (bool success) {
require(balanceOf[_from] >= _value); // Check if the targeted balance is enough
require(_value <= allowance[_from][msg.sender]); // Check allowance
balanceOf[_from] -= _value; // Subtract from the targeted balance
allowance[_from][msg.sender] -= _value; // Subtract from the sender's allowance
totalSupply -= _value; // Update totalSupply
Burn(_from, _value);
return true;
}
}
pragma solidity ^0.4.16;
/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.
/// @author Stefan George - <stefan.george@consensys.net>
contract MultiSigWallet {
event Confirmation(address sender, bytes32 transactionHash);
event Revocation(address sender, bytes32 transactionHash);
event Submission(bytes32 transactionHash);
event Execution(bytes32 transactionHash);
event Deposit(address sender, uint value);
event OwnerAddition(address owner);
event OwnerRemoval(address owner);
event RequiredUpdate(uint required);
mapping (bytes32 => Transaction) public transactions;
mapping (bytes32 => mapping (address => bool)) public confirmations;
mapping (address => bool) public isOwner;
address[] owners;
bytes32[] transactionList;
uint public required;
struct Transaction {
address destination;
uint value;
bytes data;
uint nonce;
bool executed;
}
modifier onlyWallet() {
if (msg.sender != address(this))
throw;
_;
}
modifier signaturesFromOwners(bytes32 transactionHash, uint8[] v, bytes32[] rs) {
for (uint i=0; i<v.length; i++)
if (!isOwner[ecrecover(transactionHash, v[i], rs[i], rs[v.length + i])])
throw;
_;
}
modifier ownerDoesNotExist(address owner) {
if (isOwner[owner])
throw;
_;
}
modifier ownerExists(address owner) {
if (!isOwner[owner])
throw;
_;
}
modifier confirmed(bytes32 transactionHash, address owner) {
if (!confirmations[transactionHash][owner])
throw;
_;
}
modifier notConfirmed(bytes32 transactionHash, address owner) {
if (confirmations[transactionHash][owner])
throw;
_;
}
modifier notExecuted(bytes32 transactionHash) {
if (transactions[transactionHash].executed)
throw;
_;
}
modifier notNull(address destination) {
if (destination == 0)
throw;
_;
}
modifier validRequired(uint _ownerCount, uint _required) {
if ( _required > _ownerCount
|| _required == 0
|| _ownerCount == 0)
throw;
_;
}
function addOwner(address owner)
external
onlyWallet
ownerDoesNotExist(owner)
{
isOwner[owner] = true;
owners.push(owner);
OwnerAddition(owner);
}
function removeOwner(address owner)
external
onlyWallet
ownerExists(owner)
{
isOwner[owner] = false;
for (uint i=0; i<owners.length - 1; i++)
if (owners[i] == owner) {
owners[i] = owners[owners.length - 1];
break;
}
owners.length -= 1;
if (required > owners.length)
updateRequired(owners.length);
OwnerRemoval(owner);
}
function updateRequired(uint _required)
public
onlyWallet
validRequired(owners.length, _required)
{
required = _required;
RequiredUpdate(_required);
}
function addTransaction(address destination, uint value, bytes data, uint nonce)
private
notNull(destination)
returns (bytes32 transactionHash)
{
transactionHash = sha3(destination, value, data, nonce);
if (transactions[transactionHash].destination == 0) {
transactions[transactionHash] = Transaction({
destination: destination,
value: value,
data: data,
nonce: nonce,
executed: false
});
transactionList.push(transactionHash);
Submission(transactionHash);
}
}
function submitTransaction(address destination, uint value, bytes data, uint nonce)
external
returns (bytes32 transactionHash)
{
transactionHash = addTransaction(destination, value, data, nonce);
confirmTransaction(transactionHash);
}
function submitTransactionWithSignatures(address destination, uint value, bytes data, uint nonce, uint8[] v, bytes32[] rs)
external
returns (bytes32 transactionHash)
{
transactionHash = addTransaction(destination, value, data, nonce);
confirmTransactionWithSignatures(transactionHash, v, rs);
}
function addConfirmation(bytes32 transactionHash, address owner)
private
notConfirmed(transactionHash, owner)
{
confirmations[transactionHash][owner] = true;
Confirmation(owner, transactionHash);
}
function confirmTransaction(bytes32 transactionHash)
public
ownerExists(msg.sender)
{
addConfirmation(transactionHash, msg.sender);
executeTransaction(transactionHash);
}
function confirmTransactionWithSignatures(bytes32 transactionHash, uint8[] v, bytes32[] rs)
public
signaturesFromOwners(transactionHash, v, rs)
{
for (uint i=0; i<v.length; i++)
addConfirmation(transactionHash, ecrecover(transactionHash, v[i], rs[i], rs[i + v.length]));
executeTransaction(transactionHash);
}
function executeTransaction(bytes32 transactionHash)
public
notExecuted(transactionHash)
{
if (isConfirmed(transactionHash)) {
Transaction tx = transactions[transactionHash];
tx.executed = true;
if (!tx.destination.call.value(tx.value)(tx.data))
throw;
Execution(transactionHash);
}
}
function revokeConfirmation(bytes32 transactionHash)
external
ownerExists(msg.sender)
confirmed(transactionHash, msg.sender)
notExecuted(transactionHash)
{
confirmations[transactionHash][msg.sender] = false;
Revocation(msg.sender, transactionHash);
}
function MultiSigWallet(address[] _owners, uint _required)
validRequired(_owners.length, _required)
{
for (uint i=0; i<_owners.length; i++)
isOwner[_owners[i]] = true;
owners = _owners;
required = _required;
}
function()
payable
{
if (msg.value > 0)
Deposit(msg.sender, msg.value);
}
function isConfirmed(bytes32 transactionHash)
public
constant
returns (bool)
{
uint count = 0;
for (uint i=0; i<owners.length; i++)
if (confirmations[transactionHash][owners[i]])
count += 1;
if (count == required)
return true;
}
function confirmationCount(bytes32 transactionHash)
external
constant
returns (uint count)
{
for (uint i=0; i<owners.length; i++)
if (confirmations[transactionHash][owners[i]])
count += 1;
}
function filterTransactions(bool isPending)
private
returns (bytes32[] _transactionList)
{
bytes32[] memory _transactionListTemp = new bytes32[](transactionList.length);
uint count = 0;
for (uint i=0; i<transactionList.length; i++)
if ( isPending && !transactions[transactionList[i]].executed
|| !isPending && transactions[transactionList[i]].executed)
{
_transactionListTemp[count] = transactionList[i];
count += 1;
}
_transactionList = new bytes32[](count);
for (i=0; i<count; i++)
if (_transactionListTemp[i] > 0)
_transactionList[i] = _transactionListTemp[i];
}
function getPendingTransactions()
external
constant
returns (bytes32[] _transactionList)
{
return filterTransactions(true);
}
function getExecutedTransactions()
external
constant
returns (bytes32[] _transactionList)
{
return filterTransactions(false);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment