Search code examples
blockchainethereumsoliditycontract

Create a global Addressbook for deployed Smart Contracts


I want to create a smart contract (called Deal) which, after it gets deployed, It calls another smart contract (called AddressBook) to register his address on the global AddressBook smart contract. The code I am using works, but unfortunately my newly deployed smart contract is not using the address from the AddressBook smart contract, but instead it uses his own address to call the addAddress function. The red marking shows the output if I am calling addressbook.getAddresses(addresses) inside the Deal contract. The blue marking shows the output if I am calling the getAddresses function within the AddressBook contract. So what I want is the blue output within the Deal contract

Image of the Output

Can anybody tell me how I can add the addesses of my deployed contract to a global AddressBook contract?

This his how my AddressBook smart contract looks like. I would like to add all deployed smart contracts at this contact.

contract AddressBook {
    mapping(address => address[]) private _addresses;
    mapping(address => mapping(address => string)) private _aliases;

    function getAddresses() public view  returns (address[]) {
        return _addresses[msg.sender];
    }    
    function addAddress(address addr, string _alias) public payable {
        _addresses[msg.sender].push(addr);
        _aliases[msg.sender][addr] = _alias;
    }

    function removeAddress(address addr) public payable {
        uint length = _addresses[msg.sender].length;
        for(uint i = 0; i < length; i++) {
            if (addr == _addresses[msg.sender][i]) {
                if (1 < _addresses[msg.sender].length && i < length-1) {
                    _addresses[msg.sender][i] = _addresses[msg.sender][length-1];
                }
                delete _addresses[msg.sender][length-1];
                _addresses[msg.sender].length--;
                delete _aliases[msg.sender][addr];
                break;
            }
        }
    }

    function getAlias(address addr) public view returns (string) {
        return _aliases[msg.sender][addr];
    }
}

This is the smart contract I want to deploy and register at the global

AddressBook smart contract:


    contract Deal {
      AddressBook addressBook;
      address public owner;
      address public buyerAddr;  
      address private addr;
      string private metaData;
      uint private duration;
      uint private price;
      string private typeOfData;
      string private gateKeeper;


      event SafepaySent(address buyer, uint value, uint now);

      /// The smart contract's constructor
      function Deal(address _addressBook) public payable {

        /// The seller is the contract's owner
        owner = msg.sender;
        AddressBook a = AddressBook(_addressBook);
        a.addAddress(owner,"test");
      }
    }
      function getAddresses(address _addressBook) public view returns (address[]) {
        return  AddressBook(_addressBook).getAddresses();
        }
    }

    contract AddressBook {

        function getAddresses() public view returns (address[]);

        function addAddress(address addr, string _alias) public payable ;

        function removeAddress(address addr) public payable;

        function getAlias(address addr) public view returns (string);
    }

Now I want to call the AddressBook.getAddresses() function within the AddressBook smart contract and I want to receive the addresses of all deployed Deal contracts. However, I am not receiving any address within the AddressBook smart contract. If I am calling the function Deal.getAddresses("address of the global Addressbook") I get the address of the newly deployed smart contract. But this is not what I want.


Solution

  • First if you want to use AddressBook as a global smart contract to track and load all the Deal contracts. You should already deploy the AddressBook contract and save it's address. Then you can load the AddressBook contract inside the constructor of the Deal contract and add the address of current Deal contract which is going to deploy, inside the already deployed global AddressBook contract. I did some working on the given contracts. I am using an array of addresses inside the AddressBook contract to track the address of all the Deal contracts. The following example code can give you good idea.

    //Address Book Contract
        pragma solidity ^0.5.1;
    
    contract AddressBook {
        //mapping(address => address[]) private _addresses;
        address[] private _addresses;
        mapping(address => mapping(address => string)) private _aliases;
    
        function getAddresses() public view  returns (address [] memory) {
            return _addresses;
        }
        function addAddress(address addr, string memory _alias) public payable {
            _addresses.push(addr);
            _aliases[msg.sender][addr] = _alias;
        }
    }
    

    I just focused on _address here. Following is the deal contract:

    pragma solidity ^0.5.1;
    import "./AddressBook.sol";
    
    contract Deal {
          AddressBook addressBook;
          address public owner;
          address public buyerAddr;  
          address private addr;
          string private metaData;
          uint private duration;
          uint private price;
          string private typeOfData;
          string private gateKeeper;
    
    
          event SafepaySent(address buyer, uint value, uint now);
    
          /// The smart contract's constructor
         constructor(address _addressBook) public payable {
    
            /// The seller is the contract's owner
            owner = msg.sender;
            addressBook  = AddressBook(_addressBook);
            addressBook.addAddress(address(this),"test");
          }
          function getAddresses() public view returns (address[] memory) {
            return  addressBook.getAddresses();
            }
        }
    

    You can also test and run this in remix. Hope it works.