/**
*Submitted for verification at Etherscan.io on 2019-06-04
*/
/**
* Source Code first verified at https://etherscan.io on Friday, July 20, 2018
(UTC) */
pragma solidity ^0.4.26;
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
constructor() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
/**
* @title Helps contracts guard agains reentrancy attacks.
* @author Remco Bloemen <remco@2π.com>
* @notice If you mark a function `nonReentrant`, you should also
* mark it `external`.
*/
contract ReentrancyGuard {
/**
* @dev We use a single lock for the whole contract.
*/
bool private reentrancy_lock = false;
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* @notice If you mark a function `nonReentrant`, you should also
* mark it `external`. Calling one nonReentrant function from
* another is not supported. Instead, you can implement a
* `private` function doing the actual work, and a `external`
* wrapper marked as `nonReentrant`.
*/
modifier nonReentrant() {
require(!reentrancy_lock);
reentrancy_lock = true;
_;
reentrancy_lock = false;
}
}
/**
* @title Eliptic curve signature operations
*
* @dev Based on https://gist.github.com/axic/5b33912c6f61ae6fd96d6c4a47afde6d
*/
library ECRecovery {
/**
* @dev Recover signer address from a message by using his signature
* @param hash bytes32 message, the hash is the signed message. What is recovered is the signer address.
* @param sig bytes signature, the signature is generated using web3.eth.sign()
*/
function recover(bytes32 hash, bytes sig) public pure returns (address) {
bytes32 r;
bytes32 s;
uint8 v;
//Check the signature length
if (sig.length != 65) {
return (address(0));
}
// Divide the signature in r, s and v variables
assembly {
r := mload(add(sig, 32))
s := mload(add(sig, 64))
v := byte(0, mload(add(sig, 96)))
}
// Version of signature should be 27 or 28, but 0 and 1 are also possible versions
if (v < 27) {
v += 27;
}
// If the version is correct return the signer address
if (v != 27 && v != 28) {
return (address(0));
} else {
return ecrecover(hash, v, r, s);
}
}
}
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, "SafeMath: division by zero");
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0, "SafeMath: modulo by zero");
return a % b;
}
}
contract STMPackage is Ownable, ReentrancyGuard {
using ECRecovery for bytes32;
//mapping(bytes32 => Deal) public streamityTransfers;
//constructor(address streamityContract) public {
// require(streamityContract != 0x0);
//}
//struct Deal {
// uint256 value;
//}
event MultiTransfer(
address _to,
uint _amount
);
event BuyPackage(bytes32 _tradeId);
function pay(bytes32 _tradeID, uint256 _value, bytes _sign)
external
payable
{
require(msg.value > 0);
require(msg.value == _value);
bytes32 _hashDeal = keccak256(_tradeID, msg.value);
verifyDeal(_hashDeal, _sign);
emit BuyPackage(_tradeID);
}
function verifyDeal(bytes32 _hashDeal, bytes _sign) private view {
require(_hashDeal.recover(_sign) == owner);
}
function withdrawToAddress(address _to, uint256 _amount) external onlyOwner {
_to.transfer(_amount);
}
function multiTransfer(address[] _addresses, uint[] _amounts)
external onlyOwner
returns(bool)
{
for (uint i = 0; i < _addresses.length; i++) {
_safeTransfer(_addresses[i], _amounts[i]);
emit MultiTransfer(_addresses[i], _amounts[i]);
}
return true;
}
function _safeTransfer(address _to, uint _amount) internal {
require(_to != 0);
_to.transfer(_amount);
}
}
{
"compilationTarget": {
"STMPackage.sol": "STMPackage"
},
"evmVersion": "byzantium",
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"constant":false,"inputs":[{"name":"_addresses","type":"address[]"},{"name":"_amounts","type":"uint256[]"}],"name":"multiTransfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"withdrawToAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tradeID","type":"bytes32"},{"name":"_value","type":"uint256"},{"name":"_sign","type":"bytes"}],"name":"pay","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_to","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"MultiTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_tradeId","type":"bytes32"}],"name":"BuyPackage","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]