-
Notifications
You must be signed in to change notification settings - Fork 28
/
Token.sol
143 lines (118 loc) · 4.73 KB
/
Token.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
pragma solidity ^0.4.9;
/* https://github.com/LykkeCity/EthereumApiDotNetCore/blob/master/src/ContractBuilder/contracts/token/SafeMath.sol */
contract SafeMath {
uint256 constant public MAX_UINT256 =
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
function safeAdd(uint256 x, uint256 y) constant internal returns (uint256 z) {
if (x > MAX_UINT256 - y) throw;
return x + y;
}
function safeSub(uint256 x, uint256 y) constant internal returns (uint256 z) {
if (x < y) throw;
return x - y;
}
function safeMul(uint256 x, uint256 y) constant internal returns (uint256 z) {
if (y == 0) return 0;
if (x > MAX_UINT256 / y) throw;
return x * y;
}
}
contract ContractReceiver {
function tokenFallback(address _from, uint _value, bytes _data);
}
contract ERC223Token is SafeMath {
event Transfer(address indexed _from, address indexed _to, uint256 _value, bytes _data);
mapping(address => uint) balances;
string public name = "Token";
string public symbol = "TKN";
uint8 public decimals = 18;
uint256 public totalSupply;
function ERC223Token()
{
//Supply of 100 tokens with 18 decimals. (100 + 18 times zero)
balances[0xdc8fE10C5e872e25Ac24dE310e60D88E4b7a22a1] = 100 * 10**uint(decimals);
totalSupply = balances[0xdc8fE10C5e872e25Ac24dE310e60D88E4b7a22a1];
}
// Function to access name of token .
function name() constant returns (string _name) {
return name;
}
// Function to access symbol of token .
function symbol() constant returns (string _symbol) {
return symbol;
}
// Function to access decimals of token .
function decimals() constant returns (uint8 _decimals) {
return decimals;
}
// Function to access total supply of tokens .
function totalSupply() constant returns (uint256 _totalSupply) {
return totalSupply;
}
// Function that is called when a user or another contract wants to transfer funds .
function transfer(address _to, uint _value, bytes _data, string _custom_fallback) returns (bool success) {
if(isContract(_to)) {
if (balanceOf(msg.sender) < _value) throw;
balances[msg.sender] = safeSub(balanceOf(msg.sender), _value);
balances[_to] = safeAdd(balanceOf(_to), _value);
assert(_to.call.value(0)(bytes4(sha3(_custom_fallback)), msg.sender, _value, _data));
Transfer(msg.sender, _to, _value, _data);
return true;
}
else {
return transferToAddress(_to, _value, _data);
}
}
// Function that is called when a user or another contract wants to transfer funds .
function transfer(address _to, uint _value, bytes _data) returns (bool success) {
if(isContract(_to)) {
return transferToContract(_to, _value, _data);
}
else {
return transferToAddress(_to, _value, _data);
}
}
// Standard function transfer similar to ERC20 transfer with no _data .
// Added due to backwards compatibility reasons .
function transfer(address _to, uint _value) returns (bool success) {
//standard function transfer similar to ERC20 transfer with no _data
//added due to backwards compatibility reasons
bytes memory empty;
if(isContract(_to)) {
return transferToContract(_to, _value, empty);
}
else {
return transferToAddress(_to, _value, empty);
}
}
//assemble the given address bytecode. If bytecode exists then the _addr is a contract.
function isContract(address _addr) private returns (bool is_contract) {
uint length;
assembly {
//retrieve the size of the code on target address, this needs assembly
length := extcodesize(_addr)
}
return (length>0);
}
//function that is called when transaction target is an address
function transferToAddress(address _to, uint _value, bytes _data) private returns (bool success) {
if (balanceOf(msg.sender) < _value) throw;
balances[msg.sender] = safeSub(balanceOf(msg.sender), _value);
balances[_to] = safeAdd(balanceOf(_to), _value);
Transfer(msg.sender, _to, _value, _data);
return true;
}
//function that is called when transaction target is a contract
function transferToContract(address _to, uint _value, bytes _data) private returns (bool success) {
if (balanceOf(msg.sender) < _value) throw;
balances[msg.sender] = safeSub(balanceOf(msg.sender), _value);
balances[_to] = safeAdd(balanceOf(_to), _value);
ContractReceiver receiver = ContractReceiver(_to);
receiver.tokenFallback(msg.sender, _value, _data);
Transfer(msg.sender, _to, _value, _data);
return true;
}
function balanceOf(address _owner) constant returns (uint balance) {
return balances[_owner];
}
}