Skip to content

Instantly share code, notes, and snippets.

@kyriediculous
Forked from anonymous/ERC20.sol
Last active December 24, 2017 22:31
Show Gist options
  • Save kyriediculous/33dfc96c1d3bffdd54bb41b9f3c6666e to your computer and use it in GitHub Desktop.
Save kyriediculous/33dfc96c1d3bffdd54bb41b9f3c6666e to your computer and use it in GitHub Desktop.
ERC223 with ERC20 backwards compatibility
pragma solidity ^0.4.10;
import 'browser/SafeMath.sol';
contract ERC20 {
uint256 public totalSupply;
function name() constant returns (string _name);
function symbol() constant returns (string _symbol);
function decimals() constant returns (uint8 _decimals);
function totalSupply() constant returns (uint256 _totalSupply);
function balanceOf(address who) public view returns (uint256);
function allowance(address owner, address spender) public view returns (uint256);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
pragma solidity ^0.4.10;
import 'browser/StandardToken.sol';
contract ERC223 is StandardToken {
function transfer(address to, uint value, bytes data);
event Transfer(address indexed from, address indexed to, uint value, bytes indexed data);
}
pragma solidity ^0.4.10;
/**
* @title Contract that will work with ERC223 tokens.
*/
contract ERC223ReceivingContract {
/**
* @dev Standard ERC223 function that will handle incoming token transfers.
*
* @param _from Token sender address.
* @param _value Amount of tokens.
* @param _data Transaction metadata.
*/
function tokenFallback(address _from, uint _value, bytes _data);
}
pragma solidity ^0.4.10;
import 'browser/ERC223.sol';
import 'browser/ERC223ReceivingContract.sol';
contract ERC223Token is ERC223 {
function transfer(address _to, uint _value) {
uint codeLength;
bytes memory empty;
assembly {
// Retrieve the size of the code on target address, this needs assembly .
codeLength := extcodesize(_to)
}
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
if(codeLength>0) {
ERC223ReceivingContract receiver = ERC223ReceivingContract(_to);
receiver.tokenFallback(msg.sender, _value, empty);
}
Transfer(msg.sender, _to, _value, empty);
}
function transfer(address _to, uint _value, bytes _data) {
// Standard function transfer similar to ERC20 transfer with no _data .
// Added due to backwards compatibility reasons .
uint codeLength;
assembly {
// Retrieve the size of the code on target address, this needs assembly .
codeLength := extcodesize(_to)
}
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
if(codeLength>0) {
ERC223ReceivingContract receiver = ERC223ReceivingContract(_to);
receiver.tokenFallback(msg.sender, _value, _data);
}
Transfer(msg.sender, _to, _value, _data);
}
}
pragma solidity ^0.4.10;
import 'browser/ERC223Token.sol';
contract MyToken is StandardToken {
string public name = "MyToken";
string public symbol = "MYT";
uint8 public decimals = 8;
uint256 public totalSupply = 10000;
function MyToken() {
balances[msg.sender] = totalSupply;
}
function name() constant returns (string _name) {
return name;
}
function symbol() constant returns (string _symbol) {
return symbol;
}
function decimals() constant returns (uint8 _decimals) {
return decimals;
}
function totalSupply() constant returns (uint256) {
return totalSupply;
}
}
pragma solidity ^0.4.10;
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
assert(c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure 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 pure returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
pragma solidity ^0.4.10;
import 'browser/ERC20.sol';
contract StandardToken is ERC20 {
using SafeMath for uint256;
mapping(address => uint256) balances;
mapping (address => mapping (address => uint256)) internal allowed;
/**
* @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) public view returns (uint256 balance) {
return balances[_owner];
}
/**
* @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 amount of tokens to be transferred
*/
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]);
balances[_from] = SafeMath.sub(balances[_from], _value);
balances[_to] = SafeMath.add(balances[_to], _value);
allowed[_from][msg.sender] = SafeMath.sub(allowed[_from][msg.sender], _value);
Transfer(_from, _to, _value);
return true;
}
function approve(address _spender, uint256 _value) public returns (bool) {
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
return true;
}
function allowance(address _owner, address _spender) public view returns (uint256) {
return allowed[_owner][_spender];
}
function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
allowed[msg.sender][_spender] = SafeMath.add(allowed[msg.sender][_spender], _addedValue);
Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
uint oldValue = allowed[msg.sender][_spender];
if (_subtractedValue > oldValue) {
allowed[msg.sender][_spender] = 0;
} else {
allowed[msg.sender][_spender] = SafeMath.sub(oldValue, _subtractedValue);
}
Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment