diff --git a/contracts/common/Controlled.sol b/contracts/common/Controlled.sol index d2773f3..7b615b6 100644 --- a/contracts/common/Controlled.sol +++ b/contracts/common/Controlled.sol @@ -10,7 +10,7 @@ contract Controlled { address public controller; - constructor() public { + constructor() internal { controller = msg.sender; } diff --git a/contracts/common/MessageSigned.sol b/contracts/common/MessageSigned.sol new file mode 100644 index 0000000..5a5a262 --- /dev/null +++ b/contracts/common/MessageSigned.sol @@ -0,0 +1,77 @@ +pragma solidity ^0.4.21; + +/** + * @notice Uses ethereum signed messages + */ +contract MessageSigned { + + constructor() internal { + + } + + /** + * @notice recovers address who signed the message + * @param _signHash operation ethereum signed message hash + * @param _messageSignature message `_signHash` signature + */ + function recoverAddress( + bytes32 _signHash, + bytes _messageSignature + ) + pure + internal + returns(address) + { + uint8 v; + bytes32 r; + bytes32 s; + (v,r,s) = signatureSplit(_messageSignature); + return ecrecover( + _signHash, + v, + r, + s + ); + } + + /** + * @notice Hash a hash with `"\x19Ethereum Signed Message:\n32"` + * @param _hash Sign to hash. + * @return signHash Hash to be signed. + */ + function getSignHash( + bytes32 _hash + ) + pure + internal + returns (bytes32 signHash) + { + signHash = keccak256("\x19Ethereum Signed Message:\n32", _hash); + } + + /** + * @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s` + */ + function signatureSplit(bytes _signature) + pure + internal + returns (uint8 v, bytes32 r, bytes32 s) + { + // The signature format is a compact form of: + // {bytes32 r}{bytes32 s}{uint8 v} + // Compact means, uint8 is not padded to 32 bytes. + assembly { + r := mload(add(_signature, 32)) + s := mload(add(_signature, 64)) + // Here we are loading the last 32 bytes, including 31 bytes + // of 's'. There is no 'mload8' to do this. + // + // 'byte' is not working due to the Solidity parser, so lets + // use the second best option, 'and' + v := and(mload(add(_signature, 65)), 0xff) + } + + require(v == 27 || v == 28); + } + +} \ No newline at end of file diff --git a/contracts/common/Owned.sol b/contracts/common/Owned.sol index 177bf0f..18f03e7 100644 --- a/contracts/common/Owned.sol +++ b/contracts/common/Owned.sol @@ -14,7 +14,7 @@ contract Owned { address public owner; /// @notice The Constructor assigns the message sender to be `owner` - constructor() public { + constructor() internal { owner = msg.sender; } diff --git a/contracts/token/ERC20Token.sol b/contracts/token/ERC20Token.sol index c210342..ff8de15 100644 --- a/contracts/token/ERC20Token.sol +++ b/contracts/token/ERC20Token.sol @@ -1,48 +1,52 @@ -pragma solidity ^0.4.17; +pragma solidity ^0.4.23; // Abstract contract for the full ERC 20 Token standard // https://github.com/ethereum/EIPs/issues/20 -contract ERC20Token { - /* This is a slight change to the ERC20 base standard. - function totalSupply() constant returns (uint256 supply); - is replaced with: - uint256 public totalSupply; - This automatically creates a getter function for the totalSupply. - This is moved to the base contract since public getter functions are not - currently recognised as an implementation of the matching abstract - function by the compiler. - */ - /// total amount of tokens - uint256 public totalSupply; +interface ERC20Token { - /// @notice send `_value` token to `_to` from `msg.sender` - /// @param _to The address of the recipient - /// @param _value The amount of token to be transferred - /// @return Whether the transfer was successful or not - function transfer(address _to, uint256 _value) public returns (bool success); + /** + * @notice send `_value` token to `_to` from `msg.sender` + * @param _to The address of the recipient + * @param _value The amount of token to be transferred + * @return Whether the transfer was successful or not + */ + function transfer(address _to, uint256 _value) external returns (bool success); - /// @notice `msg.sender` approves `_spender` to spend `_value` tokens - /// @param _spender The address of the account able to transfer the tokens - /// @param _value The amount of tokens to be approved for transfer - /// @return Whether the approval was successful or not - function approve(address _spender, uint256 _value) public returns (bool success); + /** + * @notice `msg.sender` approves `_spender` to spend `_value` tokens + * @param _spender The address of the account able to transfer the tokens + * @param _value The amount of tokens to be approved for transfer + * @return Whether the approval was successful or not + */ + function approve(address _spender, uint256 _value) external returns (bool success); - /// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from` - /// @param _from The address of the sender - /// @param _to The address of the recipient - /// @param _value The amount of token to be transferred - /// @return Whether the transfer was successful or not - function transferFrom(address _from, address _to, uint256 _value) public returns (bool success); + /** + * @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from` + * @param _from The address of the sender + * @param _to The address of the recipient + * @param _value The amount of token to be transferred + * @return Whether the transfer was successful or not + */ + function transferFrom(address _from, address _to, uint256 _value) external returns (bool success); - /// @param _owner The address from which the balance will be retrieved - /// @return The balance - function balanceOf(address _owner) public view returns (uint256 balance); + /** + * @param _owner The address from which the balance will be retrieved + * @return The balance + */ + function balanceOf(address _owner) external view returns (uint256 balance); - /// @param _owner The address of the account owning tokens - /// @param _spender The address of the account able to transfer the tokens - /// @return Amount of remaining tokens allowed to spent - function allowance(address _owner, address _spender) public view returns (uint256 remaining); + /** + * @param _owner The address of the account owning tokens + * @param _spender The address of the account able to transfer the tokens + * @return Amount of remaining tokens allowed to spent + */ + function allowance(address _owner, address _spender) external view returns (uint256 remaining); + + /** + * @notice return total supply of tokens + */ + function totalSupply() external view returns (uint256 supply); event Transfer(address indexed _from, address indexed _to, uint256 _value); event Approval(address indexed _owner, address indexed _spender, uint256 _value); diff --git a/contracts/token/StandardToken.sol b/contracts/token/StandardToken.sol index 10ca74a..d42852c 100644 --- a/contracts/token/StandardToken.sol +++ b/contracts/token/StandardToken.sol @@ -4,23 +4,24 @@ import "./ERC20Token.sol"; contract StandardToken is ERC20Token { + uint256 private supply; mapping (address => uint256) balances; mapping (address => mapping (address => uint256)) allowed; constructor() internal { } - + function transfer( address _to, uint256 _value ) - public + external returns (bool success) { return transfer(msg.sender, _to, _value); } function approve(address _spender, uint256 _value) - public + external returns (bool success) { allowed[msg.sender][_spender] = _value; @@ -33,7 +34,7 @@ contract StandardToken is ERC20Token { address _to, uint256 _value ) - public + external returns (bool success) { if (balances[_from] >= _value && @@ -47,7 +48,7 @@ contract StandardToken is ERC20Token { } function allowance(address _owner, address _spender) - public + external view returns (uint256 remaining) { @@ -55,12 +56,31 @@ contract StandardToken is ERC20Token { } function balanceOf(address _owner) - public + external view returns (uint256 balance) { return balances[_owner]; } + + function totalSupply() + external + view + returns(uint256 supply) + { + return supply; + } + + function mint( + address _to, + uint256 _amount + ) + internal + { + balances[_to] += _amount; + supply += _amount; + emit Transfer(0x0, _to, _amount); + } function transfer( address _from, diff --git a/contracts/token/TestToken.sol b/contracts/token/TestToken.sol new file mode 100644 index 0000000..2afff21 --- /dev/null +++ b/contracts/token/TestToken.sol @@ -0,0 +1,19 @@ +pragma solidity ^0.4.23; + +import "./StandardToken.sol"; + +/** + * @notice ERC20Token for test scripts, can be minted by anyone. + */ +contract TestToken is StandardToken { + + constructor() public { } + + /** + * @notice any caller can mint any `_amount` + * @param _amount how much to be minted + */ + function mint(uint256 _amount) public { + mint(msg.sender, _amount); + } +}