ETH Price: $2,320.39 (+3.77%)
Gas: 0.09 Gwei

Transaction Decoder

Block:
4964048 at Jan-24-2018 12:24:10 PM +UTC
Transaction Fee:
0.001326320000066316 ETH $3.08
Gas Used:
66,316 Gas / 20.000000001 Gwei

Emitted Events:

64 0xac2d23f67447f3e883fdc3c36cee7c606564b846.0x24d1827423a4c66732fc6c67bc0748ab490dd042bf77a735f09ccc40e26e4932( 0x24d1827423a4c66732fc6c67bc0748ab490dd042bf77a735f09ccc40e26e4932, 00000000000000000000000071d271f8b14adef568f8f28f1587ce7271ac4ca5 )
65 0xac2d23f67447f3e883fdc3c36cee7c606564b846.0x25b10c0526638e6891022dd8799ed694dbb9aaf113e89aa0c33e83af5b228cad( 0x25b10c0526638e6891022dd8799ed694dbb9aaf113e89aa0c33e83af5b228cad, 0000000000000000000000009ea2b503d73c983054ce49a497b9294115bd8b84 )
66 0x71d271f8b14adef568f8f28f1587ce7271ac4ca5.0xa9e1ee75e4263e8342f99947ca4f1085ef453a8540f800cd48c7d1e0a7621bae( 0xa9e1ee75e4263e8342f99947ca4f1085ef453a8540f800cd48c7d1e0a7621bae, 0x0000000000000000000000009ea2b503d73c983054ce49a497b9294115bd8b84, 000000000000000000000000ac2d23f67447f3e883fdc3c36cee7c606564b846 )

Account State Difference:

  Address   Before After State Difference Code
0xAc2d23F6...06564b846
0xDaf10e97...66f19Fa58
5.291967094700378196 Eth
Nonce: 95309
5.29064077470031188 Eth
Nonce: 95310
0.001326320000066316
(Ethermine)
706.113913084541437798 Eth706.115239404541504114 Eth0.001326320000066316

Execution Trace

0x71d271f8b14adef568f8f28f1587ce7271ac4ca5.57202bfd( )
  • Ambi2.hasRole( _from=0x71d271f8B14adEf568F8f28f1587ce7271AC4Ca5, _role=61737369676E0000000000000000000000000000000000000000000000000000, _to=0xDaf10e9794b83C02bc5484200E9B97b66f19Fa58 ) => ( True )
  • 0xac2d23f67447f3e883fdc3c36cee7c606564b846.cb9fa366( )
    • 0xc3b2ae46792547a96b9f84405e36d0e07edcd05c.cb9fa366( )
      // This software is a subject to Ambisafe License Agreement.
      // No use or distribution is allowed without written permission from Ambisafe.
      // https://www.ambisafe.com/terms-of-use/
      
      pragma solidity ^0.4.8;
      
      contract Ambi2 {
          bytes32 constant OWNER = "__root__";
          uint constant LIFETIME = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
          mapping(bytes32 => uint) rolesExpiration;
          mapping(address => bool) nodes;
      
          event Assign(address indexed from, bytes32 indexed role, address indexed to, uint expirationDate);
          event Unassign(address indexed from, bytes32 indexed role, address indexed to);
          event Error(bytes32 message);
      
          modifier onlyNodeOwner(address _node) {
              if (isOwner(_node, msg.sender)) {
                  _;
              } else {
                  _error("Access denied: only node owner");
              }
          }
      
          function claimFor(address _address, address _owner) returns(bool) {
              if (nodes[_address]) {
                  _error("Access denied: already owned");
                  return false;
              }
              nodes[_address] = true;
              _assignRole(_address, OWNER, _owner, LIFETIME);
              return true;
          }
      
          function claim(address _address) returns(bool) {
              return claimFor(_address, msg.sender);
          }
      
          function assignOwner(address _node, address _owner) returns(bool) {
              return assignRole(_node, OWNER, _owner);
          }
      
          function assignRole(address _from, bytes32 _role, address _to) returns(bool) {
              return assignRoleWithExpiration(_from, _role, _to, LIFETIME);
          }
      
          function assignRoleWithExpiration(address _from, bytes32 _role, address _to, uint _expirationDate) onlyNodeOwner(_from) returns(bool) {
              if (hasRole(_from, _role, _to) && rolesExpiration[_getRoleSignature(_from, _role, _to)] == _expirationDate) {
                  _error("Role already assigned");
                  return false;
              }
              if (_isPast(_expirationDate)) {
                  _error("Invalid expiration date");
                  return false;
              }
      
              _assignRole(_from, _role, _to, _expirationDate);
              return true;
          }
      
          function _assignRole(address _from, bytes32 _role, address _to, uint _expirationDate) internal {
              rolesExpiration[_getRoleSignature(_from, _role, _to)] = _expirationDate;
              Assign(_from, _role, _to, _expirationDate);
          }
      
          function unassignOwner(address _node, address _owner) returns(bool) {
              if (_owner == msg.sender) {
                  _error("Cannot remove ownership");
                  return false;
              }
      
              return unassignRole(_node, OWNER, _owner);
          }
      
          function unassignRole(address _from, bytes32 _role, address _to) onlyNodeOwner(_from) returns(bool) {
              if (!hasRole(_from, _role, _to)) {
                  _error("Role not assigned");
                  return false;
              }
      
              delete rolesExpiration[_getRoleSignature(_from, _role, _to)];
              Unassign(_from, _role, _to);
              return true;
          }
      
          function hasRole(address _from, bytes32 _role, address _to) constant returns(bool) {
              return _isFuture(rolesExpiration[_getRoleSignature(_from, _role, _to)]);
          }
      
          function isOwner(address _node, address _owner) constant returns(bool) {
              return hasRole(_node, OWNER, _owner);
          }
      
          function _error(bytes32 _message) internal {
              Error(_message);
          }
      
          function _getRoleSignature(address _from, bytes32 _role, address _to) internal constant returns(bytes32) {
              return sha3(_from, _role, _to);
          }
      
          function _isPast(uint _timestamp) internal constant returns(bool) {
              return _timestamp < now;
          }
      
          function _isFuture(uint _timestamp) internal constant returns(bool) {
              return !_isPast(_timestamp);
          }
      }