Transaction Hash:
Block:
4630604 at Nov-27-2017 08:14:20 AM +UTC
Transaction Fee:
0.00159906 ETH
$3.23
Gas Used:
79,953 Gas / 20 Gwei
Emitted Events:
| 28 |
0xfa39126efcb257b4ef8459ea9e6372926640c501.0x8a95e3fbb777c23aeda3e2d69b9b9859e67501dfa72116a1c4e7749d29b0a7cb( 0x8a95e3fbb777c23aeda3e2d69b9b9859e67501dfa72116a1c4e7749d29b0a7cb, 0x0000000000000000000000009e791174b496c91c9de6821dad1e778daecca1e7, 0x0000000000000000000000005f9ae7af6f5ecdc61ba2ee330afcbbdc8440575d, 0x58453835435054435259505237364b394837564d000000000000000000000000, 0000000000000000000000000000000000000000000000000dd8e5d03ce28000, 0000000000000000000000000000000000000000000000000000000000000060, 0000000000000000000000000000000000000000000000000000000000000001, 0000000000000000000000000000000000000000000000000000000000000000 )
|
Account State Difference:
| Address | Before | After | State Difference | ||
|---|---|---|---|---|---|
| 0x5f9ae7Af...c8440575d | 3,472.11301455868065326 Eth | 3,473.11081455868065326 Eth | 0.9978 | ||
| 0x9e791174...daEcCA1e7 |
1 Eth
Nonce: 0
|
0.00060094 Eth
Nonce: 1
| 0.99939906 | ||
|
0xEA674fdD...16B898ec8
Miner
| (Ethermine) | 392.53887688237822652 Eth | 392.54047594237822652 Eth | 0.00159906 |
Execution Trace
ETH 0.9978
0xb4d9b203d8d16f41916a62deab83389cf2b7eecb.733480b7( )
RegistryICAP.parse( _icap=58453835435054435259505237364B394837564D000000000000000000000000 ) => ( 0x5f9ae7Af6F5eCDC61bA2eE330aFcbBDc8440575d, 4350540000000000000000000000000000000000000000000000000000000000, True )
-
Null: 0x000...004.CALL( )
-
Null: 0x000...004.CALL( )
-
Null: 0x000...004.CALL( )
-
- ETH 0.9978
0x5f9ae7af6f5ecdc61ba2ee330afcbbdc8440575d.CALL( ) 0xfa39126efcb257b4ef8459ea9e6372926640c501.eacbc236( )EToken2Emitter.emitTransferToICAP( _from=0x9e791174b496C91c9DE6821dad1e778daEcCA1e7, _to=0x5f9ae7Af6F5eCDC61bA2eE330aFcbBDc8440575d, _icap=58453835435054435259505237364B394837564D000000000000000000000000, _value=997800000000000000, _reference= )-
0xfa39126efcb257b4ef8459ea9e6372926640c501.488725a0( )
-
File 1 of 2: RegistryICAP
File 2 of 2: EToken2Emitter
// This software is a subject to Ambisafe License Agreement.
// No use or distribution is allowed without written permission from Ambisafe.
// https://ambisafe.com/terms.pdf
contract Ambi {
function getNodeAddress(bytes32 _nodeName) constant returns(address);
function hasRelation(bytes32 _nodeName, bytes32 _relation, address _to) constant returns(bool);
function addNode(bytes32 _nodeName, address _nodeAddress) constant returns(bool);
}
contract AmbiEnabled {
Ambi public ambiC;
bool public isImmortal;
bytes32 public name;
modifier checkAccess(bytes32 _role) {
if(address(ambiC) != 0x0 && ambiC.hasRelation(name, _role, msg.sender)){
_
}
}
function getAddress(bytes32 _name) constant returns (address) {
return ambiC.getNodeAddress(_name);
}
function setAmbiAddress(address _ambi, bytes32 _name) returns (bool){
if(address(ambiC) != 0x0){
return false;
}
Ambi ambiContract = Ambi(_ambi);
if(ambiContract.getNodeAddress(_name)!=address(this)) {
if (!ambiContract.addNode(_name, address(this))){
return false;
}
}
name = _name;
ambiC = ambiContract;
return true;
}
function immortality() checkAccess("owner") returns(bool) {
isImmortal = true;
return true;
}
function remove() checkAccess("owner") returns(bool) {
if (isImmortal) {
return false;
}
selfdestruct(msg.sender);
return true;
}
}
library StackDepthLib {
// This will probably work with a value of 390 but no need to cut it
// that close in the case that the optimizer changes slightly or
// something causing that number to rise slightly.
uint constant GAS_PER_DEPTH = 400;
function checkDepth(address self, uint n) constant returns(bool) {
if (n == 0) return true;
return self.call.gas(GAS_PER_DEPTH * n)(0x21835af6, n - 1);
}
function __dig(uint n) constant {
if (n == 0) return;
if (!address(this).delegatecall(0x21835af6, n - 1)) throw;
}
}
contract Safe {
// Should always be placed as first modifier!
modifier noValue {
if (msg.value > 0) {
// Internal Out Of Gas/Throw: revert this transaction too;
// Call Stack Depth Limit reached: revert this transaction too;
// Recursive Call: safe, no any changes applied yet, we are inside of modifier.
_safeSend(msg.sender, msg.value);
}
_
}
modifier onlyHuman {
if (_isHuman()) {
_
}
}
modifier noCallback {
if (!isCall) {
_
}
}
modifier immutable(address _address) {
if (_address == 0) {
_
}
}
address stackDepthLib;
function setupStackDepthLib(address _stackDepthLib) immutable(address(stackDepthLib)) returns(bool) {
stackDepthLib = _stackDepthLib;
return true;
}
modifier requireStackDepth(uint16 _depth) {
if (stackDepthLib == 0x0) {
throw;
}
if (_depth > 1023) {
throw;
}
if (!stackDepthLib.delegatecall(0x32921690, stackDepthLib, _depth)) {
throw;
}
_
}
// Must not be used inside the functions that have noValue() modifier!
function _safeFalse() internal noValue() returns(bool) {
return false;
}
function _safeSend(address _to, uint _value) internal {
if (!_unsafeSend(_to, _value)) {
throw;
}
}
function _unsafeSend(address _to, uint _value) internal returns(bool) {
return _to.call.value(_value)();
}
function _isContract() constant internal returns(bool) {
return msg.sender != tx.origin;
}
function _isHuman() constant internal returns(bool) {
return !_isContract();
}
bool private isCall = false;
function _setupNoCallback() internal {
isCall = true;
}
function _finishNoCallback() internal {
isCall = false;
}
}
contract RegistryICAP is AmbiEnabled, Safe {
function decodeIndirect(bytes _bban) constant returns(string, string, string) {
bytes memory asset = new bytes(3);
bytes memory institution = new bytes(4);
bytes memory client = new bytes(9);
uint8 k = 0;
for (uint8 i = 0; i < asset.length; i++) {
asset[i] = _bban[k++];
}
for (i = 0; i < institution.length; i++) {
institution[i] = _bban[k++];
}
for (i = 0; i < client.length; i++) {
client[i] = _bban[k++];
}
return (string(asset), string(institution), string(client));
}
function parse(bytes32 _icap) constant returns(address, bytes32, bool) {
// Should start with XE.
if (_icap[0] != 88 || _icap[1] != 69) {
return (0, 0, false);
}
// Should have 12 zero bytes at the end.
for (uint8 j = 20; j < 32; j++) {
if (_icap[j] != 0) {
return (0, 0, false);
}
}
bytes memory bban = new bytes(18);
for (uint8 i = 0; i < 16; i++) {
bban[i] = _icap[i + 4];
}
var (asset, institution, _) = decodeIndirect(bban);
bytes32 assetInstitutionHash = sha3(asset, institution);
uint8 parseChecksum = (uint8(_icap[2]) - 48) * 10 + (uint8(_icap[3]) - 48);
uint8 calcChecksum = 98 - mod9710(prepare(bban));
if (parseChecksum != calcChecksum) {
return (institutions[assetInstitutionHash], assets[sha3(asset)], false);
}
return (institutions[assetInstitutionHash], assets[sha3(asset)], registered[assetInstitutionHash]);
}
function prepare(bytes _bban) constant returns(bytes) {
for (uint8 i = 0; i < 16; i++) {
uint8 charCode = uint8(_bban[i]);
if (charCode >= 65 && charCode <= 90) {
_bban[i] = byte(charCode - 65 + 10);
}
}
_bban[16] = 33; // X
_bban[17] = 14; // E
//_bban[18] = 48; // 0
//_bban[19] = 48; // 0
return _bban;
}
function mod9710(bytes _prepared) constant returns(uint8) {
uint m = 0;
for (uint8 i = 0; i < 18; i++) {
uint8 charCode = uint8(_prepared[i]);
if (charCode >= 48) {
m *= 10;
m += charCode - 48; // number
m %= 97;
} else {
m *= 10;
m += charCode / 10; // part1
m %= 97;
m *= 10;
m += charCode % 10; // part2
m %= 97;
}
}
m *= 10;
//m += uint8(_prepared[18]) - 48;
m %= 97;
m *= 10;
//m += uint8(_prepared[19]) - 48;
m %= 97;
return uint8(m);
}
mapping(bytes32 => bool) public registered;
mapping(bytes32 => address) public institutions;
mapping(bytes32 => address) public institutionOwners;
mapping(bytes32 => bytes32) public assets;
modifier onlyInstitutionOwner(string _institution) {
if (msg.sender == institutionOwners[sha3(_institution)]) {
_
}
}
function changeInstitutionOwner(string _institution, address _address) noValue() onlyInstitutionOwner(_institution) returns(bool) {
institutionOwners[sha3(_institution)] = _address;
return true;
}
// web3js sendIBANTransaction interface
function addr(bytes32 _institution) constant returns(address) {
return institutions[sha3("ETH", _institution[0], _institution[1], _institution[2], _institution[3])];
}
function registerInstitution(string _institution, address _address) noValue() checkAccess("admin") returns(bool) {
if (bytes(_institution).length != 4) {
return false;
}
if (institutionOwners[sha3(_institution)] != 0) {
return false;
}
institutionOwners[sha3(_institution)] = _address;
return true;
}
function registerInstitutionAsset(string _asset, string _institution, address _address) noValue() onlyInstitutionOwner(_institution) returns(bool) {
if (!registered[sha3(_asset)]) {
return false;
}
bytes32 assetInstitutionHash = sha3(_asset, _institution);
if (registered[assetInstitutionHash]) {
return false;
}
registered[assetInstitutionHash] = true;
institutions[assetInstitutionHash] = _address;
return true;
}
function updateInstitutionAsset(string _asset, string _institution, address _address) noValue() onlyInstitutionOwner(_institution) returns(bool) {
bytes32 assetInstitutionHash = sha3(_asset, _institution);
if (!registered[assetInstitutionHash]) {
return false;
}
institutions[assetInstitutionHash] = _address;
return true;
}
function removeInstitutionAsset(string _asset, string _institution) noValue() onlyInstitutionOwner(_institution) returns(bool) {
bytes32 assetInstitutionHash = sha3(_asset, _institution);
if (!registered[assetInstitutionHash]) {
return false;
}
delete registered[assetInstitutionHash];
delete institutions[assetInstitutionHash];
return true;
}
function registerAsset(string _asset, bytes32 _symbol) noValue() checkAccess("admin") returns(bool) {
if (bytes(_asset).length != 3) {
return false;
}
bytes32 asset = sha3(_asset);
if (registered[asset]) {
return false;
}
registered[asset] = true;
assets[asset] = _symbol;
return true;
}
}File 2 of 2: EToken2Emitter
// This software is a subject to Ambisafe License Agreement.
// No use or distribution is allowed without written permission from Ambisafe.
// https://www.ambisafe.co/terms-of-use/
// 0.4.8+commit.60cc1668, enabled optimization, 200 runs.
pragma solidity 0.4.8;
contract EventsHistory {
function versions(address) constant returns(uint);
}
/**
* @title EToken2 Emitter.
*
* Contains all the original event emitting function definitions and events.
* In case of new events needed later, additional emitters can be developed.
* All the functions is meant to be called using delegatecall.
*/
library EToken2Emitter {
event Transfer(address indexed from, address indexed to, bytes32 indexed symbol, uint value, string reference, uint version);
event TransferToICAP(address indexed from, address indexed to, bytes32 indexed icap, uint value, string reference, uint version);
event Issue(bytes32 indexed symbol, uint value, address by, uint version);
event Revoke(bytes32 indexed symbol, uint value, address by, uint version);
event OwnershipChange(address indexed from, address indexed to, bytes32 indexed symbol, uint version);
event Approve(address indexed from, address indexed spender, bytes32 indexed symbol, uint value, uint version);
event Recovery(address indexed from, address indexed to, address by, uint version);
event Error(bytes32 message, uint version);
event Change(bytes32 indexed symbol, uint version);
function emitTransfer(address _from, address _to, bytes32 _symbol, uint _value, string _reference) {
Transfer(_from, _to, _symbol, _value, _reference, _getVersion());
}
function emitTransferToICAP(address _from, address _to, bytes32 _icap, uint _value, string _reference) {
TransferToICAP(_from, _to, _icap, _value, _reference, _getVersion());
}
function emitIssue(bytes32 _symbol, uint _value, address _by) {
Issue(_symbol, _value, _by, _getVersion());
}
function emitRevoke(bytes32 _symbol, uint _value, address _by) {
Revoke(_symbol, _value, _by, _getVersion());
}
function emitOwnershipChange(address _from, address _to, bytes32 _symbol) {
OwnershipChange(_from, _to, _symbol, _getVersion());
}
function emitApprove(address _from, address _spender, bytes32 _symbol, uint _value) {
Approve(_from, _spender, _symbol, _value, _getVersion());
}
function emitRecovery(address _from, address _to, address _by) {
Recovery(_from, _to, _by, _getVersion());
}
function emitError(bytes32 _message) {
Error(_message, _getVersion());
}
function emitChange(bytes32 _symbol) {
Change(_symbol, _getVersion());
}
/**
* Get version number of the caller.
*
* Assuming that the call is made by EventsHistory using delegate call,
* context was not changed, so the caller is the address that called
* EventsHistory.
*
* @return current context caller version number.
*/
function _getVersion() constant internal returns(uint) {
return EventsHistory(address(this)).versions(msg.sender);
}
}