Transaction Hash:
Block:
7035245 at Jan-09-2019 05:35:23 AM +UTC
Transaction Fee:
0.000217896 ETH
$0.51
Gas Used:
72,632 Gas / 3 Gwei
Emitted Events:
76 |
LCDToken.Transfer( _from=[Receiver] 0x2fa03a2ecaecf47d43de77ffd56e676feaf0f59f, _to=[Sender] 0xb3ce58c1a0886b15367a11b9affbccb8d3a1ec83, _value=972343698163283793 )
|
77 |
0x2fa03a2ecaecf47d43de77ffd56e676feaf0f59f.0x5bf2177ec82333d646ddac9ef13ddd7f57260091072d459309fe1a9ee531e2ca( 0x5bf2177ec82333d646ddac9ef13ddd7f57260091072d459309fe1a9ee531e2ca, 000000000000000000000000b3ce58c1a0886b15367a11b9affbccb8d3a1ec83, 0000000000000000000000000000000000000000000000000d7e7571189cb751 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x2fa03A2E...FeAf0F59f | |||||
0x5A0b54D5...D3E029c4c
Miner
| (Spark Pool) | 13,490.153105344446900771 Eth | 13,490.153323240446900771 Eth | 0.000217896 | |
0x9a4059c1...7Fd9463b2 | |||||
0xb3ce58c1...8D3a1EC83 |
0.095836867365463495 Eth
Nonce: 204
|
0.095618971365463495 Eth
Nonce: 205
| 0.000217896 |
Execution Trace
0x2fa03a2ecaecf47d43de77ffd56e676feaf0f59f.CALL( )
-
LCDToken.transfer( _to=0xb3ce58c1a0886B15367A11b9AFFbCCb8D3a1EC83, _value=972343698163283793 ) => ( success=True )
pragma solidity ^0.4.20; pragma solidity ^0.4.15; /** * @title Safe math operations that throw error on overflow. * * Credit: Taking ideas from FirstBlood token */ library SafeMath { /** * @dev Safely add two numbers. * * @param x First operant. * @param y Second operant. * @return The result of x+y. */ function add(uint256 x, uint256 y) internal constant returns(uint256) { uint256 z = x + y; assert((z >= x) && (z >= y)); return z; } /** * @dev Safely substract two numbers. * * @param x First operant. * @param y Second operant. * @return The result of x-y. */ function sub(uint256 x, uint256 y) internal constant returns(uint256) { assert(x >= y); uint256 z = x - y; return z; } /** * @dev Safely multiply two numbers. * * @param x First operant. * @param y Second operant. * @return The result of x*y. */ function mul(uint256 x, uint256 y) internal constant returns(uint256) { uint256 z = x * y; assert((x == 0) || (z/x == y)); return z; } /** * @dev Parse a floating point number from String to uint, e.g. "250.56" to "25056" */ function parse(string s) internal constant returns (uint256) { bytes memory b = bytes(s); uint result = 0; for (uint i = 0; i < b.length; i++) { if (b[i] >= 48 && b[i] <= 57) { result = result * 10 + (uint(b[i]) - 48); } } return result; } } /** * @title The abstract ERC-20 Token Standard definition. * * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md */ contract Token { /// @dev Returns the total token supply. uint256 public totalSupply; function balanceOf(address _owner) public constant returns (uint256 balance); function transfer(address _to, uint256 _value) public returns (bool success); function transferFrom(address _from, address _to, uint256 _value) public returns (bool success); function approve(address _spender, uint256 _value) public returns (bool success); function allowance(address _owner, address _spender) public constant returns (uint256 remaining); /// @dev MUST trigger when tokens are transferred, including zero value transfers. event Transfer(address indexed _from, address indexed _to, uint256 _value); /// @dev MUST trigger on any successful call to approve(address _spender, uint256 _value). event Approval(address indexed _owner, address indexed _spender, uint256 _value); } /** * @title Default implementation of the ERC-20 Token Standard. */ contract StandardToken is Token { mapping (address => uint256) balances; mapping (address => mapping (address => uint256)) allowed; modifier onlyPayloadSize(uint numwords) { assert(msg.data.length == numwords * 32 + 4); _; } /** * @dev Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. * @dev The function SHOULD throw if the _from account balance does not have enough tokens to spend. * * @dev A token contract which creates new tokens SHOULD trigger a Transfer event with the _from address set to 0x0 when tokens are created. * * Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer event. * * @param _to The receiver of the tokens. * @param _value The amount of tokens to send. * @return True on success, false otherwise. */ function transfer(address _to, uint256 _value) public returns (bool success) { if (balances[msg.sender] >= _value && _value > 0 && balances[_to] + _value > balances[_to]) { balances[msg.sender] = SafeMath.sub(balances[msg.sender], _value); balances[_to] = SafeMath.add(balances[_to], _value); Transfer(msg.sender, _to, _value); return true; } else { return false; } } /** * @dev Transfers _value amount of tokens from address _from to address _to, and MUST fire the Transfer event. * * @dev The transferFrom method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf. * @dev This can be used for example to allow a contract to transfer tokens on your behalf and/or to charge fees in * @dev sub-currencies. The function SHOULD throw unless the _from account has deliberately authorized the sender of * @dev the message via some mechanism. * * Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer event. * * @param _from The sender of the tokens. * @param _to The receiver of the tokens. * @param _value The amount of tokens to send. * @return True on success, false otherwise. */ function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0 && balances[_to] + _value > balances[_to]) { balances[_to] = SafeMath.add(balances[_to], _value); balances[_from] = SafeMath.sub(balances[_from], _value); allowed[_from][msg.sender] = SafeMath.sub(allowed[_from][msg.sender], _value); Transfer(_from, _to, _value); return true; } else { return false; } } /** * @dev Returns the account balance of another account with address _owner. * * @param _owner The address of the account to check. * @return The account balance. */ function balanceOf(address _owner) public constant returns (uint256 balance) { return balances[_owner]; } /** * @dev Allows _spender to withdraw from your account multiple times, up to the _value amount. * @dev If this function is called again it overwrites the current allowance with _value. * * @dev NOTE: To prevent attack vectors like the one described in [1] and discussed in [2], clients * @dev SHOULD make sure to create user interfaces in such a way that they set the allowance first * @dev to 0 before setting it to another value for the same spender. THOUGH The contract itself * @dev shouldn't enforce it, to allow backwards compatilibilty with contracts deployed before. * @dev [1] https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/ * @dev [2] https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * @param _spender The address which will spend the funds. * @param _value The amount of tokens to be spent. * @return True on success, false otherwise. */ function approve(address _spender, uint256 _value) public onlyPayloadSize(2) returns (bool success) { allowed[msg.sender][_spender] = _value; Approval(msg.sender, _spender, _value); return true; } /** * @dev Returns the amount which _spender is still allowed to withdraw from _owner. * * @param _owner The address of the sender. * @param _spender The address of the receiver. * @return The allowed withdrawal amount. */ function allowance(address _owner, address _spender) public constant onlyPayloadSize(2) returns (uint256 remaining) { return allowed[_owner][_spender]; } } /** * @title The LCDToken Token contract. * * Credit: Taking ideas from BAT token and NET token */ /*is StandardToken */ contract LCDToken is StandardToken { // Token metadata string public constant name = "Lucyd"; string public constant symbol = "LCD"; uint256 public constant decimals = 18; uint256 public constant TOKEN_COMPANY_OWNED = 10 * (10**6) * 10**decimals; // 10 million LCDs uint256 public constant TOKEN_MINTING = 30 * (10**6) * 10**decimals; // 30 million LCDs uint256 public constant TOKEN_BUSINESS = 10 * (10**6) * 10**decimals; // 10 million LCDs // wallet that is allowed to distribute tokens on behalf of the app store address public APP_STORE; // Administrator for multi-sig mechanism address public admin1; address public admin2; // Accounts that are allowed to deliver tokens address public tokenVendor1; address public tokenVendor2; // Keep track of holders and icoBuyers mapping (address => bool) public isHolder; // track if a user is a known token holder to the smart contract - important for payouts later address[] public holders; // array of all known holders - important for payouts later // store the hashes of admins' msg.data mapping (address => bytes32) private multiSigHashes; // to track if management already got their tokens bool public managementTokensDelivered; // current amount of disbursed tokens uint256 public tokensSold; // Events used for logging event LogLCDTokensDelivered(address indexed _to, uint256 _value); event LogManagementTokensDelivered(address indexed distributor, uint256 _value); event Auth(string indexed authString, address indexed user); modifier onlyOwner() { // check if transaction sender is admin. require (msg.sender == admin1 || msg.sender == admin2); // if yes, store his msg.data. multiSigHashes[msg.sender] = keccak256(msg.data); // check if his stored msg.data hash equals to the one of the other admin if ((multiSigHashes[admin1]) == (multiSigHashes[admin2])) { // if yes, both admins agreed - continue. _; // Reset hashes after successful execution multiSigHashes[admin1] = 0x0; multiSigHashes[admin2] = 0x0; } else { // if not (yet), return. return; } } modifier onlyVendor() { require((msg.sender == tokenVendor1) || (msg.sender == tokenVendor2)); _; } /** * @dev Create a new LCDToken contract. * * _admin1 The first admin account that owns this contract. * _admin2 The second admin account that owns this contract. * _tokenVendor1 The first token vendor * _tokenVendor2 The second token vendor */ function LCDToken( address _admin1, address _admin2, address _tokenVendor1, address _tokenVendor2, address _appStore, address _business_development) public { // admin1 and admin2 address must be set and must be different require (_admin1 != 0x0); require (_admin2 != 0x0); require (_admin1 != _admin2); // tokenVendor1 and tokenVendor2 must be set and must be different require (_tokenVendor1 != 0x0); require (_tokenVendor2 != 0x0); require (_tokenVendor1 != _tokenVendor2); // tokenVendors must be different from admins require (_tokenVendor1 != _admin1); require (_tokenVendor1 != _admin2); require (_tokenVendor2 != _admin1); require (_tokenVendor2 != _admin2); require (_appStore != 0x0); admin1 = _admin1; admin2 = _admin2; tokenVendor1 = _tokenVendor1; tokenVendor2 = _tokenVendor2; // Init app store balance APP_STORE = _appStore; balances[_appStore] = TOKEN_MINTING; trackHolder(_appStore); // Init business development balance to admin1 balances[_admin1] = TOKEN_BUSINESS; trackHolder(_business_development); totalSupply = SafeMath.add(TOKEN_MINTING, TOKEN_BUSINESS); } // Allows to figure out the amount of known token holders function getHolderCount() public constant returns (uint256 _holderCount) { return holders.length; } // Allows for easier retrieval of holder by array index function getHolder(uint256 _index) public constant returns (address _holder) { return holders[_index]; } function trackHolder(address _to) private returns (bool success) { // Check if the recipient is a known token holder if (isHolder[_to] == false) { // if not, add him to the holders array and mark him as a known holder holders.push(_to); isHolder[_to] = true; } return true; } /// @dev Transfer LCD tokens function deliverTokens(address _buyer, uint256 _amount) // amount input will be in cents external onlyVendor returns(bool success) { // check if the function is called before May 1, 2018 require(block.timestamp <= 1525125600); // Calculate the number of tokens from the given amount in cents uint256 tokens = SafeMath.mul(_amount, 10**decimals / 100); // update state uint256 oldBalance = balances[_buyer]; balances[_buyer] = SafeMath.add(oldBalance, tokens); tokensSold = SafeMath.add(tokensSold, tokens); totalSupply = SafeMath.add(totalSupply, tokens); trackHolder(_buyer); // Log the transfer of these tokens Transfer(msg.sender, _buyer, tokens); LogLCDTokensDelivered(_buyer, tokens); return true; } // @dev Transfer tokens to management wallet function deliverManagementTokens(address _managementWallet) external onlyOwner returns (bool success) { // check if management tokens are already unlocked, if the function is called after March 31., 2019 require(block.timestamp >= 1553990400); // Deliver management tokens only once require(managementTokensDelivered == false); // update state balances[_managementWallet] = TOKEN_COMPANY_OWNED; totalSupply = SafeMath.add(totalSupply, TOKEN_COMPANY_OWNED); managementTokensDelivered = true; trackHolder(_managementWallet); // Log the transfer of these tokens Transfer(address(this), _managementWallet, TOKEN_COMPANY_OWNED); LogManagementTokensDelivered(_managementWallet, TOKEN_COMPANY_OWNED); return true; } // Using this for creating a reference between ETH wallets and accounts in the Lucyd backend function auth(string _authString) external { Auth(_authString, msg.sender); } }