Solidity

當我使用另一個契約創建契約時,我如何在 web3js 中訪問他的方法?

  • April 30, 2019

嘿,我在這個文件中有文件’contractFactory.sol'

contract contractFactory{

   event contractCreated(string name, address institution, address parent);

   function createContract(
       string _name,
       address head,
       address creator,
       address[] _Members)
   public returns(address){

       Contracts  ContractAddress = new Contracts(_name , head , creator , _Members);
       emit contractCreated(_name,address(ContractAddress), creator);
       return address(ContractAddress);
   }
}

contract Contracts{

   function  dosomthing(){}
}

現在在前端 web3js 中,我使用 ‘contractsFactory’ 創建了 ‘Contracts’ 契約。有人知道我如何在 web3js 中訪問 dosomting() 方法嗎?

這是一個依賴於 web3.js v1.0.0-beta.34 的工作範例。

請注意,我必須修復契約中的各種編譯錯誤,因此它與您的(非工作)程式碼不完全兼容,但應該足以讓您開始。

最重要的是,請注意我還聲明address institutionindexed,以便createContract更容易地從執行函式的接收中提取此數據。

您更改的程式碼:

pragma solidity 0.4.25;

contract ContractInstance {
   string public _name;
   address public _head;
   address public _creator;

   constructor(string name, address head, address creator) public {
       _name = name;
       _head = head;
       _creator = creator;
   }

   function doSomething(string name) public {
       _name = name;
   }
}

contract ContractFactory {
   event ContractCreated(string name, address indexed institution, address parent);

   function createContract(string name, address head, address creator) public returns (address) {
       ContractInstance contractInstance = new ContractInstance(name, head, creator);
       emit ContractCreated(name, address(contractInstance), creator);
       return address(contractInstance);
   }
}

Web3.js 腳本:

const fs = require("fs");
const Web3 = require("web3");
const web3 = new Web3("http://localhost:8545");

const YOUR_PRIVATE_KEY = "0x0000000000000000000000000000000000000000000000000000000000000001";
const YOUR_ARTIFACTS_PATH = "C:/Your/Artifacts/Path/";

const ARG2 = "0x1234567812345678123456781234567812345678";
const ARG3 = "0x8765432187654321876543218765432187654321";

async function deploy(contractName, contractArgs) {
   const abi = fs.readFileSync(YOUR_ARTIFACTS_PATH + contractName + ".abi");
   const bin = fs.readFileSync(YOUR_ARTIFACTS_PATH + contractName + ".bin");
   const contract = new web3.eth.Contract(JSON.parse(abi));
   const options = {data: "0x" + bin, arguments: contractArgs};
   const transaction = contract.deploy(options);
   const handle = await send(transaction);
   const args = transaction.encodeABI().slice(options.data.length);
   return new web3.eth.Contract(JSON.parse(abi), handle.contractAddress);
}

function deployed(contractName, contractAddr) {
   const abi = fs.readFileSync(YOUR_ARTIFACTS_PATH + contractName + ".abi");
   return new web3.eth.Contract(JSON.parse(abi), contractAddr);
}

async function send(transaction) {
   const options = {
       to   : transaction._parent._address,
       data : transaction.encodeABI(),
       gas  : (await web3.eth.getBlock("latest")).gasLimit
   };
   const signedTransaction  = await web3.eth.accounts.signTransaction(options, YOUR_PRIVATE_KEY);
   const transactionReceipt = await web3.eth.sendSignedTransaction(signedTransaction.rawTransaction);
   return transactionReceipt;
}

async function run() {
   const contractFactory  = await deploy("ContractFactory", []);
   const receipt1         = await send(contractFactory.methods.createContract("MyName", ARG2, ARG3));
   const contractAddress  = "0x" + receipt1.logs[0].topics[1].slice(-40);
   const contractInstance = deployed("ContractInstance", contractAddress);
   const oldName          = await contractInstance.methods._name().call();
   const receipt2         = await send(contractInstance.methods.doSomething("YourName"));
   const newName          = await contractInstance.methods._name().call();
   console.log("oldName:", oldName);
   console.log("newName:", newName);
}

run();

引用自:https://ethereum.stackexchange.com/questions/70248