Transaction Hash:
Block:
5864039 at Jun-27-2018 03:44:17 PM +UTC
Transaction Fee:
0.000222912 ETH
$0.42
Gas Used:
55,728 Gas / 4 Gwei
Emitted Events:
147 |
WeToken.Transfer( from=[Sender] 0xe2186aeb756d6f8bc3acd2a22578a5e1c1eb8c72, to=0x2E6325159a587E8Ce03FFBD9FFF4B8F536dBca8F, value=2852760000000000000000, data=0x )
|
148 |
WeToken.Transfer( from=[Sender] 0xe2186aeb756d6f8bc3acd2a22578a5e1c1eb8c72, to=0x2E6325159a587E8Ce03FFBD9FFF4B8F536dBca8F, value=2852760000000000000000 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x829BD824...93333A830
Miner
| (F2Pool Old) | 5,060.857609057916443696 Eth | 5,060.857831969916443696 Eth | 0.000222912 | |
0xAAE81c01...e11a242CE | |||||
0xe2186aEb...1c1eb8c72 | (WorldWifi: Deployer) |
0.816298319972583896 Eth
Nonce: 40056
|
0.816075407972583896 Eth
Nonce: 40057
| 0.000222912 |
Execution Trace
WeToken.transfer( _to=0x2E6325159a587E8Ce03FFBD9FFF4B8F536dBca8F, _value=2852760000000000000000 ) => ( success=True )
transfer[ERC20 (ln:16)]
pragma solidity ^0.4.13; contract Receiver { function tokenFallback(address from, uint value, bytes data); } /* * ERC20 interface * see https://github.com/ethereum/EIPs/issues/20 */ contract ERC20 { uint public totalSupply; function balanceOf(address who) public constant returns (uint); function allowance(address owner, address spender) public constant returns (uint); function transfer(address to, uint value) public returns (bool ok); function transferFrom(address from, address to, uint value) public returns (bool ok); function approve(address spender, uint value) public returns (bool ok); event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); } /** * Math operations with safety checks */ contract SafeMath { function safeMul(uint a, uint b) internal returns (uint) { uint c = a * b; assert(a == 0 || c / a == b); return c; } function safeDiv(uint a, uint b) internal returns (uint) { assert(b > 0); uint c = a / b; assert(a == b * c + a % b); return c; } function safeSub(uint a, uint b) internal returns (uint) { assert(b <= a); return a - b; } function safeAdd(uint a, uint b) internal returns (uint) { uint c = a + b; assert(c>=a && c>=b); return c; } function max64(uint64 a, uint64 b) internal constant returns (uint64) { return a >= b ? a : b; } function min64(uint64 a, uint64 b) internal constant returns (uint64) { return a < b ? a : b; } function max256(uint256 a, uint256 b) internal constant returns (uint256) { return a >= b ? a : b; } function min256(uint256 a, uint256 b) internal constant returns (uint256) { return a < b ? a : b; } function assert(bool assertion) internal { if (!assertion) { revert(); } } } /** * Standard ERC20 token with Short Hand Attack and approve() race condition mitigation. * * Based on code by FirstBlood: * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol */ contract StandardToken is ERC20, SafeMath { event Transfer(address indexed from, address indexed to, uint indexed value, bytes data); /* Token supply got increased and a new owner received these tokens */ event Minted(address receiver, uint amount); /* Actual balances of token holders */ mapping(address => uint) balances; /* approve() allowances */ mapping (address => mapping (address => uint)) allowed; /** * * Fix for the ERC20 short address attack * * http://vessenes.com/the-erc20-short-address-attack-explained/ */ modifier onlyPayloadSize(uint size) { if(msg.data.length != size + 4) { revert(); } _; } function transfer(address _to, uint _value) onlyPayloadSize(2 * 32) public returns (bool success) { bytes memory _empty; return transfer(_to, _value, _empty); } function transfer(address _to, uint _value, bytes _data) public returns (bool success) { balances[msg.sender] = safeSub(balances[msg.sender], _value); balances[_to] = safeAdd(balances[_to], _value); Transfer(msg.sender, _to, _value, _data); Transfer(msg.sender, _to, _value); if (isContract(_to)) { Receiver(_to).tokenFallback(msg.sender, _value, _data); } return true; } // ERC223 fetch contract size (must be nonzero to be a contract) function isContract( address _addr ) private returns (bool) { uint length; _addr = _addr; assembly { length := extcodesize(_addr) } return (length > 0); } function transferFrom(address _from, address _to, uint _value) public returns (bool success) { uint _allowance = allowed[_from][msg.sender]; // Check is not needed because safeSub(_allowance, _value) will already throw if this condition is not met // if (_value > _allowance) revert(); balances[_to] = safeAdd(balances[_to], _value); balances[_from] = safeSub(balances[_from], _value); allowed[_from][msg.sender] = safeSub(_allowance, _value); Transfer(_from, _to, _value); return true; } function balanceOf(address _owner) public constant returns (uint balance) { return balances[_owner]; } function approve(address _spender, uint _value) public returns (bool success) { // To change the approve amount you first have to reduce the addresses` // allowance to zero by calling `approve(_spender, 0)` if it is not // already 0 to mitigate the race condition described here: // https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 if ((_value != 0) && (allowed[msg.sender][_spender] != 0)) revert(); allowed[msg.sender][_spender] = _value; Approval(msg.sender, _spender, _value); return true; } function allowance(address _owner, address _spender) public constant returns (uint remaining) { return allowed[_owner][_spender]; } /** * Atomic increment of approved spending * * Works around https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * */ function addApproval(address _spender, uint _addedValue) public onlyPayloadSize(2 * 32) returns (bool success) { uint oldValue = allowed[msg.sender][_spender]; allowed[msg.sender][_spender] = safeAdd(oldValue, _addedValue); Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; } /** * Atomic decrement of approved spending. * * Works around https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 */ function subApproval(address _spender, uint _subtractedValue) public onlyPayloadSize(2 * 32) returns (bool success) { uint oldVal = allowed[msg.sender][_spender]; if (_subtractedValue > oldVal) { allowed[msg.sender][_spender] = 0; } else { allowed[msg.sender][_spender] = safeSub(oldVal, _subtractedValue); } Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; } } contract BurnableToken is StandardToken { address public constant BURN_ADDRESS = 0; /** How many tokens we burned */ event Burned(address burner, uint burnedAmount); /** * Burn extra tokens from a balance. * */ function burn(uint burnAmount) public { address burner = msg.sender; balances[burner] = safeSub(balances[burner], burnAmount); totalSupply = safeSub(totalSupply, burnAmount); Burned(burner, burnAmount); } } /** * Upgrade agent interface inspired by Lunyr. * * Upgrade agent transfers tokens to a new contract. * Upgrade agent itself can be the token contract, or just a middle man contract doing the heavy lifting. */ contract UpgradeAgent { uint public originalSupply; /** Interface marker */ function isUpgradeAgent() public constant returns (bool) { return true; } function upgradeFrom(address _from, uint256 _value) public; } /** * A token upgrade mechanism where users can opt-in amount of tokens to the next smart contract revision. * * First envisioned by Golem and Lunyr projects. */ contract UpgradeableToken is StandardToken { /** Contract / person who can set the upgrade path. This can be the same as team multisig wallet, as what it is with its default value. */ address public upgradeMaster; /** The next contract where the tokens will be migrated. */ UpgradeAgent public upgradeAgent; /** How many tokens we have upgraded by now. */ uint256 public totalUpgraded; /** * Upgrade states. * * - NotAllowed: The child contract has not reached a condition where the upgrade can bgun * - WaitingForAgent: Token allows upgrade, but we don't have a new agent yet * - ReadyToUpgrade: The agent is set, but not a single token has been upgraded yet * - Upgrading: Upgrade agent is set and the balance holders can upgrade their tokens * */ enum UpgradeState {Unknown, NotAllowed, WaitingForAgent, ReadyToUpgrade, Upgrading} /** * Somebody has upgraded some of his tokens. */ event Upgrade(address indexed _from, address indexed _to, uint256 _value); /** * New upgrade agent available. */ event UpgradeAgentSet(address agent); /** * Do not allow construction without upgrade master set. */ function UpgradeableToken(address _upgradeMaster) public { upgradeMaster = _upgradeMaster; } /** * Allow the token holder to upgrade some of their tokens to a new contract. */ function upgrade(uint256 value) public { UpgradeState state = getUpgradeState(); if(!(state == UpgradeState.ReadyToUpgrade || state == UpgradeState.Upgrading)) { // Called in a bad state revert(); } // Validate input value. if (value == 0) revert(); balances[msg.sender] = safeSub(balances[msg.sender], value); // Take tokens out from circulation totalSupply = safeSub(totalSupply, value); totalUpgraded = safeAdd(totalUpgraded, value); // Upgrade agent reissues the tokens upgradeAgent.upgradeFrom(msg.sender, value); Upgrade(msg.sender, upgradeAgent, value); } /** * Set an upgrade agent that handles */ function setUpgradeAgent(address agent) external { if(!canUpgrade()) { // The token is not yet in a state that we could think upgrading revert(); } if (agent == 0x0) revert(); // Only a master can designate the next agent if (msg.sender != upgradeMaster) revert(); // Upgrade has already begun for an agent if (getUpgradeState() == UpgradeState.Upgrading) revert(); upgradeAgent = UpgradeAgent(agent); // Bad interface if(!upgradeAgent.isUpgradeAgent()) revert(); // Make sure that token supplies match in source and target if (upgradeAgent.originalSupply() != totalSupply) revert(); UpgradeAgentSet(upgradeAgent); } /** * Get the state of the token upgrade. */ function getUpgradeState() public constant returns(UpgradeState) { if(!canUpgrade()) return UpgradeState.NotAllowed; else if(address(upgradeAgent) == 0x00) return UpgradeState.WaitingForAgent; else if(totalUpgraded == 0) return UpgradeState.ReadyToUpgrade; else return UpgradeState.Upgrading; } /** * Change the upgrade master. * * This allows us to set a new owner for the upgrade mechanism. */ function setUpgradeMaster(address master) public { if (master == 0x0) revert(); if (msg.sender != upgradeMaster) revert(); upgradeMaster = master; } /** * Child contract can enable to provide the condition when the upgrade can begun. */ function canUpgrade() public constant returns(bool) { return true; } } contract WeToken is BurnableToken, UpgradeableToken { string public name; string public symbol; uint public decimals; address public owner; bool public mintingFinished = false; mapping(address => uint) public previligedBalances; /** List of agents that are allowed to create new tokens */ mapping(address => bool) public mintAgents; event MintingAgentChanged(address addr, bool state); modifier onlyOwner() { if(msg.sender != owner) revert(); _; } modifier onlyMintAgent() { // Only crowdsale contracts are allowed to mint new tokens if(!mintAgents[msg.sender]) revert(); _; } /** Make sure we are not done yet. */ modifier canMint() { if(mintingFinished) revert(); _; } modifier onlyNotSame(address _from, address _to) { if(_from == _to) revert(); _; } function transferOwnership(address newOwner) public onlyOwner { if (newOwner != address(0)) { owner = newOwner; } } function WeToken(address _owner, string _name, string _symbol, uint _totalSupply, uint _decimals) public UpgradeableToken(_owner) { name = _name; symbol = _symbol; decimals = _decimals; totalSupply = _totalSupply * 10 ** uint(decimals); // Allocate initial balance to the owner balances[_owner] = totalSupply; // save the owner owner = _owner; } function mintingFinish() public onlyOwner { mintingFinished = true; } // privileged transfer function transferPrivileged(address _to, uint _value) public onlyOwner returns (bool success) { balances[msg.sender] = safeSub(balances[msg.sender], _value); balances[_to] = safeAdd(balances[_to], _value); previligedBalances[_to] = safeAdd(previligedBalances[_to], _value); Transfer(msg.sender, _to, _value); return true; } // get priveleged balance function getPrivilegedBalance(address _owner) public constant returns (uint balance) { return previligedBalances[_owner]; } // admin only can transfer from the privileged accounts function transferFromPrivileged(address _from, address _to, uint _value) public onlyOwner onlyNotSame(_from, _to) returns (bool success) { uint availablePrevilegedBalance = previligedBalances[_from]; balances[_from] = safeSub(balances[_from], _value); balances[_to] = safeAdd(balances[_to], _value); previligedBalances[_from] = safeSub(availablePrevilegedBalance, _value); Transfer(_from, _to, _value); return true; } /** * Create new tokens and allocate them to an address.. * * Only callably by a crowdsale contract (mint agent). */ function mint(address receiver, uint amount) onlyMintAgent canMint public { amount *= 10 ** uint(decimals); totalSupply = safeAdd(totalSupply, amount); balances[receiver] = safeAdd(balances[receiver], amount); // This will make the mint transaction apper in EtherScan.io // We can remove this after there is a standardized minting event Transfer(0, receiver, amount); } /** * Owner can allow a crowdsale contract to mint new tokens. */ function setMintAgent(address addr, bool state) onlyOwner canMint public { mintAgents[addr] = state; MintingAgentChanged(addr, state); } }