I am new to solidity and am following a tutorial that uses solidity compiler version 0.4.25. In the tutorial, solc.compile is used in a compile.js file followed by extract abi and bytecode and generating json files by using the following codes:
const output = solc.compile(contractSource, 1);
for (let contract in output.contracts){
fileSystem.outputJSONSync(
path.resolve(exportPath,"Interface.json"),
output.contracts[contract].interface
);
fileSystem.outputJSONSync(
path.resolve(exportPath,"ByteCode.json"),
output.contracts[contract].bytecode
);
}
I am trying to compile a contract using solidity compiler version 0.5.3 instead and am able to get the output from the compiler by changing the codes to:
var input = {
language: 'Solidity',
sources: {
'Voting.sol': {
content: votingSource
}
},
settings: {
outputSelection: {
'*': {
'*': [ '*' ]
}
}
}
}
const output = JSON.parse(solc.compile(JSON.stringify(input)),1);
However, I am unable to find the abi and bytecode using:
output.contracts[contract].interface
output.contracts[contract].bytecode
I think it is because the output structure is different from the output compiled using version 0.4.25 and that there isn't interface in the structure compiled using version 0.5.3. I would like to know what do I use instead to get the same json file outputs using the newer compiler version as well as how to get pass the error I encountered which I will show below.
I run compile.js in terminal and get the following error
TypeError: Cannot read property 'replace' of undefined at stringify (...\node_modules\fs-extra\node_modules\jsonfile\index.js:88:14) at Object.writeFileSync (...\node_modules\fs-extra\node_modules\jsonfile\index.js:115:13) at Object.outputJsonSync (...\node_modules\fs-extra\lib\json\output-json-sync.js:15:12) at Object. (...\smartContract\compile.js:35:20) at Module._compile (internal/modules/cjs/loader.js:722:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:733:10) at Module.load (internal/modules/cjs/loader.js:620:32) at tryModuleLoad (internal/modules/cjs/loader.js:560:12) at Function.Module._load (internal/modules/cjs/loader.js:552:3) at Function.Module.runMain (internal/modules/cjs/loader.js:775:12)
Here's my codes. Voting.sol
pragma solidity ^0.5.3;
contract Voting {
address chairPersonAddress;
struct Candidate {
address candidateAddress;
uint votes;
}
struct Vote{
uint votedCandidateIndex;
bool alreadyVoted;
}
modifier onlyChairPerson(){
require(msg.sender == chairPersonAddress);
_;
}
mapping(address => Vote) public voterAddressToTheirVote;
Candidate[] public candidates;
constructor(address _chairPersonAddress) public {
chairPersonAddress = _chairPersonAddress;
}
function nominateCandidate(address _candidateAddress) onlyChairPerson public {
Candidate memory newCandidate = Candidate({
candidateAddress: _candidateAddress,
votes: 0
});
candidates.push(newCandidate);
}
function vote(uint _candidateIndex) public {
Vote memory existingVote = voterAddressToTheirVote[msg.sender];
//If voter vote for the first candidate in the list - the index is always 0
if(_candidateIndex == 0){
require(existingVote.alreadyVoted == false, "You already voted for the first candidate");
_addNewVote(_candidateIndex);
}
else{
require(existingVote.votedCandidateIndex != _candidateIndex && existingVote.alreadyVoted == false, "You already voted for this candidate");
_addNewVote(_candidateIndex);
}
}
function _addNewVote(uint _candidateIndex) private {
Vote memory newVote = Vote({
votedCandidateIndex: _candidateIndex,
alreadyVoted: true
});
voterAddressToTheirVote[msg.sender] = newVote;
candidates[_candidateIndex].votes++;
}
function numberOfCandidates() public view returns(uint){
return candidates.length;
}
}
compile.js
const path = require("path");
const solc = require("solc");
const fileSystem = require("fs-extra");
//Preparing for bin folder
const exportPath = path.resolve(__dirname, "bin");
fileSystem.removeSync(exportPath);
//Get contract path
const votingContract = path.resolve(__dirname, "contracts", "Voting.sol");
//Read the contract from voting path
const votingSource = fileSystem.readFileSync(votingContract, "utf8");
var input = {
language: 'Solidity',
sources: {
'Voting.sol': {
content: votingSource
}
},
settings: {
outputSelection: {
'*': {
'*': [ '*' ]
}
}
}
}
try{
const output = JSON.parse(solc.compile(JSON.stringify(input)),1);
for (let contract in output.contracts){
fileSystem.outputJSONSync(
path.resolve(exportPath,"VotingABI.json"),
output.contracts[contract].interface
);
fileSystem.outputJSONSync(
path.resolve(exportPath,"VotingBytecode.json"),
output.contracts[contract].bytecode
);
}
}catch(error){
console.log(error);
}