web3.js how to search all the contracts ever created by and address

in #ethereum7 years ago (edited)

For those who are looking for a way, as Adam said in his post, there is no direct way to find contracts created by wallet address. Hence, we have to implement registry pattern as shown below to keep track of things and just ask that contract in web3.js, also shown below....

This is how my contract look like

contract ContractA {
  bool public is_approved;
  address public visa_details;
  uint public artifact_count;

  // constructors
  function ContractA() public {
    owner = msg.sender;
  }
}

Here is the registry pattern contract

contract ContractARegistry {
  mapping(address => address[]) user_contracts;

  function registerContract(address contractA) public {
    user_applications[msg.sender].push(contractA) - 1; // -1 is very important
  }

  function findContract(address user) view public returns (address[]){
    return user_contracts[user];
  }
}

In web3.js you may search like this (I am using Angular4)

import * as ContractA from '../../../../build/contracts/ContractA.json';
import * as UserContracts from '../../../../build/contracts/UserContracts.json';
import * as TruffleContract from 'truffle-contract';
import {Observable} from "rxjs/Observable";

declare var window: any;

@Injectable()
export class AppWeb3ContractAService {
  CONTRACT_A = TruffleContract(ContractA);
  USER_CONTRACTS = TruffleContract(UserContracts);

  constructor(private appWeb3Svc: AppWeb3Service) {
    console.log("Injecting the provider");
    this.CONTRACT_A.setProvider(this.appWeb3Svc.currentProvider());
    this.USER_CONTRACTS.setProvider(this.appWeb3Svc.currentProvider());
  }

  create(ethAddress): Observable<any> {
    return Observable.create(observer => {
      this.CONTRACT_A
        .new({
          from: ethAddress
        })
        .then(application => {
          this.USER_CONTRACTS
            .deployed()
            .then(registry => {
              registry.registerContractA(application.address, {from: ethAddress})
                .then(result => observer.next(application))
                .catch(error => observer.error(error));
            })
            .catch(error => observer.error(error));
        })
        .catch(error => observer.error(error));
    });
  }


  findAll(ethAddress: string):
    Observable<any[]> {
    return Observable.create(observer => {
      this.USER_CONTRACTS
        .deployed()
        .then(registry => {
          registry.findUserContracts(ethAddress, {from: ethAddress})
            .then(addresses => {
              addresses.forEach(address => observer.next(this.CONTRACT_A.at(address)));
            })
            .catch(error => observer.error(error));
        })
        .catch(error => observer.error(error));
    });
  }
}

This is how my appWeb3Svc looks like

import {Injectable} from '@angular/core';
import {environment} from '../../../environments/environment';
import * as Web3 from 'web3';

declare var window: any;

@Injectable()
export class AppWeb3Service {
  public web3: Web3;

  checkAndInstantiateWeb3 = () => {
    // Checking if Web3 has been injected by the browser (Mist/MetaMask)
    if (typeof window.web3 !== 'undefined') {
      console.warn(
        'Using web3 detected from external source. If you find that your accounts don\'t appear or you have 0 MetaCoin, ensure you\'ve configured that source properly. If using MetaMask, see the following link. Feel free to delete this warning. :) http://truffleframework.com/tutorials/truffle-and-metamask'
      );
      // Use Mist/MetaMask's provider
      this.web3 = new Web3(window.web3.currentProvider);
    } else {
      console.warn(
        'No web3 detected. Falling back to ${environment.HttpProvider}. You should remove this fallback when you deploy live, as it\'s inherently insecure. Consider switching to Metamask for development. More info here: http://truffleframework.com/tutorials/truffle-and-metamask'
      );
      // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
      this.web3 = new Web3(
        new Web3.providers.HttpProvider(environment.HttpProvider)
      );
    }
  };

  constructor() {
    this.checkAndInstantiateWeb3();
  }

  currentProvider() {
    return this.web3.currentProvider;
  }

  eth() {
    return this.web3.eth;
  }

  isAddress(ethAddress: string): boolean {
    if (this.web3) {
      return this.web3.isAddress(ethAddress);
    }
    return false
  }
}

Hope this helps!

Sort:  

Congratulations @dagrawal! You have received a personal award!

1 Year on Steemit
Click on the badge to view your Board of Honor.

Do not miss the last post from @steemitboard:

SteemitBoard notifications improved

Support SteemitBoard's project! Vote for its witness and get one more award!

Congratulations @dagrawal! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 2 years!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Do not miss the last post from @steemitboard:

SteemFest⁴ commemorative badge refactored
Vote for @Steemitboard as a witness to get one more award and increased upvotes!