web3.js 如何搜索所有曾经创建的合约并查看地址

dag*_*gra 4 blockchain ethereum solidity web3js

我是 web3.js 和 Solidity 的新手。我的问题与我们在区块链上搜索的方式有关。如果我们知道合约地址,就很容易搜索特定合约。然而,我们如何使用最初用于创建合约的地址来查找和识别特定类型的合约。

例如。我有一个合同 ContractA,它是由“发件人”地址 AddressA 使用 web3.js 创建的。现在我想找到由AddressA创建的ContractA的所有实例。

我尝试使用 web3.eth.filter API 进行搜索,但注意到没有返回。请帮忙。

我还阅读了有关使用注册表模式来存储所有合同并询问注册表的信息,但找不到任何有用的示例。

dag*_*gra 5

对于那些正在寻找方法的人来说,正如 Adam 在他的帖子中所说,没有直接的方法可以找到由钱包地址创建的合约。因此,我们必须实现如下所示的注册表模式来跟踪事物,并且只需在 web3.js 中询问该合同,也如下所示......

这就是我的合同的样子

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

  // constructors
  function ContractA() public {
    owner = msg.sender;
  }
}
Run Code Online (Sandbox Code Playgroud)

这是注册表模式合约

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];
  }
}
Run Code Online (Sandbox Code Playgroud)

在 web3.js 中你可以这样搜索(我使用的是 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));
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

这就是我的 appWeb3Svc 的样子

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
  }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!