Solidity
當我使用另一個契約創建契約時,我如何在 web3js 中訪問他的方法?
嘿,我在這個文件中有文件’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 institution
為indexed
,以便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();