Solidity
從合約呼叫合約不起作用
下面是一個契約呼叫另一個契約的非常簡單的設置,我不知何故無法讓它工作。
契約C1
pragma solidity ^0.5.0; contract C1 { int public x = 1; function setX(int _x) public { x = _x; } function getX() public view returns (int y) { return x; } }
契約C2
pragma solidity ^0.5.0; import { C1 } from './C1.sol'; contract C2 { C1 c1; constructor(address _c1) public { c1 = C1(_c1); } function setX(int _x) public { c1.setX(_x); } function getX() public view returns (int) { c1.getX(); } }
在 C1 上呼叫 setX 和 getX 效果很好。但是 C2 方法不起作用。在https://remix.ethereum.org/上 試過 用solidity 編譯器0.5.0 和EVM 版本constantinople 試過。我想我做錯了什麼,但無法弄清楚是什麼。
編輯:添加 JS 程式碼:
'use strict'; const web3 = require("web3"); const solc = require("solc"); const fs = require("fs"); const w3 = new web3(new web3.providers.WebsocketProvider("ws://***.***.***.***:8545")) // compile contract const contracts = { 'C1.sol': { content: fs.readFileSync(__dirname + "/C1.sol", "utf-8") }, 'C2.sol': { content: fs.readFileSync(__dirname + "/C2.sol", "utf-8") } } const input = { language: 'Solidity', sources: contracts, settings: { optimizer: { enabled: false }, outputSelection: { '*': { '*': ["abi", "evm.bytecode"] } } } } const parsedOutput = JSON.parse(solc.compile(JSON.stringify(input))); const compiled = {}; for (let contract in contracts) { const name = contract.split(".")[0]; const output = {}; output.abi = parsedOutput.contracts[contract][name].abi; output.bin = parsedOutput.contracts[contract][name].evm.bytecode.object; compiled[name] = output; } // console.log(compiled); // deploy contract const init = async () => { const addresses = await w3.eth.getAccounts(); console.log(addresses); const sendObj = { from: addresses[0], gas: 450000000 }; const callObj = { from: addresses[0] } // deploy C1 const ct1 = new w3.eth.Contract(compiled["C1"].abi); ct1.options.data = "0x" + compiled["C1"].bin; const ct1Deployed = await ct1.deploy().send(sendObj); console.log(ct1Deployed.options.address); const newCt1 = new w3.eth.Contract(compiled["C1"].abi, ct1Deployed.options.address); console.log(await newCt1.methods.getX().call(callObj)); await newCt1.methods.setX(123).send(sendObj); console.log(await newCt1.methods.getX().call(callObj)); // deploy C2 const ct2 = new w3.eth.Contract(compiled["C2"].abi); ct2.options.data = "0x" + compiled["C2"].bin; const ct2Deployed = await ct2.deploy({ arguments: [ct1Deployed.options.address] }).send(sendObj); console.log(ct2Deployed.options.address); const newCt2 = new w3.eth.Contract(compiled["C2"].abi, ct2Deployed.options.address); console.log(await newCt2.methods.getX(ct1Deployed.options.address).call(callObj)); // await newCt2.methods.setX(123).send(sendObj); // console.log(await newCt2.methods.getX().call(callObj)); } init();
您錯過了 中的
return
關鍵字C2
。function getX() public view returns (int) { return c1.getX(); }
此外,在 C1 的 getter 中看到一個變數令人困惑
y
,這似乎是錯誤的。最好將其刪除,如下所示:function getX() public view returns (int) { return x; }