0

Recent code:

pragma solidity ^0.5.11; 
pragma experimental ABIEncoderV2; 

contract Master {

    address Pi_C_Owner;
    address payable public NewAuctionPayable;   //Hilfsvariable um Auktionsadresse besser zu übertragen (sonst: in 'createAuction' deklarieren)
    address public NewTracking;                 //Hilfsvariable um Trackingaddresse besser zu übertragen (sonst: in 'createTracking' deklarieren)

    constructor() public {
        Pi_C_Owner = msg.sender;
    }

    function checkBalance() public view returns(uint) { 
        require(msg.sender == Pi_C_Owner,"Insufficient permission");
        return(address(this).balance);
    }

    function increaseBalance() public payable {
        require(msg.sender == Pi_C_Owner,"Insufficient permission");
    }

    function createAuction(address _Destination, uint _WTP, uint _BiddingTime) public returns(address) {    //Departure aus 'Tracking'?
        require(_WTP > 0,"Willingness to pay has to exceed 0.");
        address NewAuction = address (new Auction(_Destination, _WTP, _BiddingTime, address(this)));
        NewAuctionPayable = address(uint160(NewAuction));
        NewAuctionPayable.transfer(_WTP);
        return(NewAuctionPayable);
    } 

    function createTracking() public returns(address) {
        NewTracking = address (new Tracking(Pi_C_Owner));
        return(NewTracking);
    }

    //function ProofOfDelivery() public view returns(address) {
      //  return(auction.Destination());
    //}

    function() external payable {
    }
}

contract Tracking {

    uint RecordId;
    uint public RecordCount;

    struct Record{
        uint id;
        address adr;            
        string pifunction;
        string coordinates;
        uint time;
    }    

    mapping(uint => Record) records;

    constructor(address _Departure) public {
        records[RecordId] = Record(RecordId, _Departure, "PI-Shipper", "N.49.27.30.555/O.11.5.38.326", now);
        RecordId++;
        RecordCount = RecordId;
    }

    function a_addRecord(string memory PI_Function, string memory Coordinates) public {
        records[RecordId] = Record(RecordId, msg.sender, PI_Function, Coordinates, now);
        RecordId++;
        RecordCount = RecordId;
    }

    function b_getRecord(uint RecordID) public view returns(Record memory) {
        return records[RecordID];
    }

    function c_getAddresses() public view returns(address[] memory) {
        address[] memory adr = new address[](RecordId);
        for(uint i = 0; i < RecordId; i++) {
            Record storage record = records[i];
            adr[i] = record.adr;
        }
        return(adr);
    }

    function d_getPI_Functions() public view returns(string[] memory) {
        string[] memory pifunction = new string[](RecordId);
        for(uint i = 0; i < RecordId; i++) {
            Record storage record = records[i];
            pifunction[i] = record.pifunction;
        }
        return(pifunction);
    }

    function e_getCoordinates() public view returns(string[] memory) {
        string[] memory coordinates = new string[](RecordId);
        for(uint i = 0; i < RecordId; i++) {
            Record storage record = records[i];
            coordinates[i] = record.coordinates;
        }
        return(coordinates);
    }

    //function f_getTimestamps() public view returns(uint[] memory) {
    //    uint[] memory time = new uint[](RecordId);
    //    for(uint i = 0; i < RecordId; i++) {
    //        Record storage record = records[i];
    //        time[i] = record.time;
    //    }
    //    return(time);
    //}

    function g_getRecords() public view returns(Record[] memory) {                       
        Record[] memory id = new Record[](RecordId);
        for(uint i = 0; i < RecordId; i++) {
            Record storage record = records[i];
            id[i] = record;
        }
        return(id);
    }
}

contract Auction {

    bool Ended;
    uint WTP;
    uint public AuctionEndTime;
    uint public SafetyDeposit;
    uint public LowestBid;
    address public Destination;
    address payable MasterPayable;
    address payable LowestBidder;
    address payable Payee;

    struct Participant {
        bool biddingright;
        uint amount;
    }

    mapping(address => Participant) participants;
    address payable[] depositor;

    constructor(address _Destination, uint _WTP, uint _BiddingTime, address payable _Master) public {
        Destination = _Destination;
        WTP = _WTP;
        SafetyDeposit = _WTP/2;
        LowestBid = _WTP;
        AuctionEndTime = now + _BiddingTime;
        MasterPayable = _Master;
        Ended = false;
    }

    function getRights() public payable { 
        require(now <= AuctionEndTime,"Auction already ended.");
        require(msg.value >= SafetyDeposit);
        require(participants[msg.sender].biddingright == false,"Safety deposit already payed.");
        participants[msg.sender].biddingright = true;
        participants[msg.sender].amount = msg.value;
        depositor.push(msg.sender);
    }

    function placeBid(uint Bid) public {                                         
        require(now <= AuctionEndTime,"Auction already ended.");
        require(Bid < LowestBid,"There already is a lower bid.");
        require(participants[msg.sender].biddingright == true,"Please note safety deposit.");
        LowestBidder = msg.sender;
        LowestBid = Bid;
    }

    function AuctionEnd() public {
        require(now >= AuctionEndTime,"Auction not yet ended.");
        require(Ended == false,"Auction end has already been called.");
        Ended = true;
        MasterPayable.transfer(WTP-LowestBid);                          //Zahlung and LowestBidder wird einbehalten bis PoD
        for(uint i=0; i<depositor.length; i++) {
            Payee = depositor[i];
            if(Payee != LowestBidder) {
                Payee.transfer(participants[Payee].amount);             //Deposit of LowestBidder wird einbehalten bis PoD
            }
        }
    }

    function checkBalance() public view returns(uint) {                 //Testfunktion!!!
        return(address(this).balance);
    }

    function() external payable {
    }
}

At the moment I would like to check the Destination-variable of my Auction-contract in my Master-contract. Is there a way in which a Factory-contract can access information/functions/variables in the child-contracts he generated?

Help would be much appreciated, thanks.

1

Yes, you do need to change function Contract (... to constructor(... because this is the new way to indicate the constructor.

There is nothing else you need to do in the Factory to invoke the constructor. The constructor always runs one time on deployment, regardless of how the contract is deployed. It cannot be prevented/avoided even if you want to.

In summary, the constructor defines what you want to happen on deployment.

UPDATE

You could use a contract type instead of address that would possibly be more safe. Using addresses, make a dynamic array to hold the created contracts.

address[] public createdAuctions;

Around here:

address NewAuction = address (new Auction(_Destination, _WTP, _BiddingTime, address(this))); // NewAuction should be camelCase.

createdAuctions.push(newAuction); // now you have a list of them.

You have to work out the address of the contract you want to inspect/interact with. Then you just:

Auction auction = Auction(contractAddress);
// now carry on
action.doSomething();

In case that isn't clear, auction is cast as a contract (left side) and the compiler gets the ABI from contract Auction elsewhere in the code. The value assigned (right side) is and instance that lives at contractAddress so you just need to figure out the address you are interested in.

List keeping (working it out) is a common concern. This might be useful: https://medium.com/robhitchens/solidity-crud-part-1-824ffa69509a

A updated implementation: https://github.com/rob-Hitchens/UnorderedKeySet/blob/master/contracts/HitchensUnorderedAddressSet.sol

Hope it helps.

| improve this answer | |
  • Thanks for your answer. But it is still not working. I changed the 'function' to 'constructor' but now I get an error in line 7 of my code. Error message: "TypeError: Type contract Contract is not implicitly convertible to expected type address. address. newContract = new Contract(name)" – Siewi Oct 10 '19 at 15:19
  • I gather you're really after issues related to refactoring for solidity 0.5.x and not the factory pattern itself. Contracts are convertible to addresses but in 0.5.x such conversions need to be explicit. address newContract = address(new Contract(name)); – Rob Hitchens Oct 10 '19 at 15:52
  • Thank you very much for your help so far. I hope you can help me with my next problem as well. First of all, in my Remix IDE this factory contract is just generating a contract-address. After I got the address I have to manually deploy the newContract on this address. Is there a way the factory contract can automatically deploy the newContract? The second this is that I would like to transfer 1 ether from my factory contract to my childContract. Is there a way I could do this in my createContract-function? (PS: I updated my code) – Siewi Oct 13 '19 at 6:13
  • Q1. No, that's not right. the Factory does deploy a Contract and it records its address. Given the ABI for the new Contract, which you have, and the address for the new Contract, which you have, any client can interact with it - deploy to the same address is neither desirable nor possible. Since it wasn't deployed with Remix's process, it is not magically aware of what to do. A client wouldn't be either. In any case, you configure to get started with Contract "At". It's not deploying. It's the contract that is actually there. Any client would follow a similar process. – Rob Hitchens Oct 13 '19 at 20:23
  • Actualy, there is a further error in the Factory. It can't be view because that is, by definition, a read-only invocation. Remove view so it is a write function. The "write" is the deployment operation and you want it to be persistent. – Rob Hitchens Oct 13 '19 at 20:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.