Solidity – Getting Address of New Contract from Contract Factory: Step-by-Step Guide

contract-developmentsolidityweb3-providersweb3js

i need to deploy a rental contract at runtime whenever user want's to start the contract. for this purpose i have acontract factory. here is the actual code for facotry

pragma solidity ^0.4.8;
import './RentalContract.sol';


contract contractFactory {
  address[] public contracts;


  function getContractCount() public returns(uint) {
    return contracts.length;
  }

  function newContract(uint _rent, uint _security_deposit, string _house, address _owner, address _tenant)
  public payable returns(address)  {
    Rental c = new Rental(_rent, _security_deposit, _house, _owner, _tenant);
    contracts.push(c);
    return c;
  }
}

this function newContract is suposed to return the address of new rental contract. Here is the my angular service which calls this function to get the address of new contract.

   import { Injectable } from '@angular/core';
    import * as Web3 from 'web3';
    import {Observable} from 'rxjs/Observable';
    import { fromPromise } from 'rxjs/observable/fromPromise';
    import {observable} from "rxjs/symbol/observable";
    import {reject} from "q";

    const FactoryArtifacts = require('/home/work/angularplustruffle/angular4-truffle-starter-dapp/build/contracts/contractFactory.json');
    const contract = require('truffle-contract');
    const RentalArtifacts = require('/home/work/angularplustruffle/angular4-truffle-starter-dapp/build/contracts/Rental.json');

    declare let require: any;
    declare let window: any;

    @Injectable()
    export class ContractsService {
      ContractFactory = contract(FactoryArtifacts);
      Rental = contract(RentalArtifacts);
      private web3: any;
      public acc_no: any = 5;

      constructor() {
        if (typeof window.web3 !== 'undefined') {
          // Use Mist/MetaMask's provider
          this.web3 = new Web3(window.web3.currentProvider);
          this.ContractFactory.setProvider(window.web3.currentProvider);
          this.Rental.setProvider(window.web3.currentProvider);

          /* if (this.web3.version.network !== '4') {
            alert('Please connect to the Rinkeby network');
          } */
        } else {
          console.warn(
            'Please use a dapp browser like mist or MetaMask plugin for chrome'
          );
        }
      }

 public deployRentalContract(rent, security_deposit, house, owner, tenant): Observable<any> {
    let meta;
      return Observable.create( observer => {
        this.ContractFactory
          .deployed()
          .then( instance => {
              meta = instance;
              console.log('data to send:' + "rent " + rent, " security " + security_deposit + " house" + house + " owner" + owner + " tenant" + tenant);
              return meta.newContract(rent, security_deposit, house, owner, tenant, {from: this.web3.eth.accounts[0],
                gas:1000000, value: this.web3.toWei(0.01, "ether")});
          })
          .then(value => {
            console.log("value is");
            console.log(value);
            observer.next(value);
            observer.complete();
          })
          .catch(e => {
            console.log(e);
            observer.error(e);
          });
      });
  }
}

but instead of getting an address i am getting following response
enter image description here

how can i get actual address instead?

Best Answer

The response you are getting is the receipt of the transaction. Return values from functions which create transactions, to my knowledge, can only be true or false.

However, you should be able to emit an event containing the address of the contract after it is created in the factory.

event ContractCreated(address newAddress);

Then, within your newContract() function, after you create a new contract, you can do:

ContractCreated(c);

This will create an event which you can then search for to find your address. I believe this event will also appear in the receipt object from web3, so you may be able to obtain the address from there as well.

Related Topic