0

I set up a contract with three files referring to Token Factory. I make a test on remix online tool, they can be successfully compiled.

when I'm tring to compile them by solc module in a .js file, got an error saying "TypeError: Cannot read property 'TestToken.sol' of undefined"

> for (var contractName in output.contracts['TestToken.sol']) {
...     TokenJson.abi = output.contracts['TestToken.sol']["TestToken"].abi;
...     TokenJson.bytecode = output.contracts['TestToken.sol']["TestToken"].bytecode;
... }
TypeError: Cannot read property 'TestToken.sol' of undefined

please help how to fix the problem, many thanks.

The solc compiler .js file is as below:

var fs = require('fs');
var solc =  require('solc');
let contractSource = fs.readFileSync('/root/TestToken/TestToken.sol', 'utf-8');
let jsonContractSource = JSON.stringify({
    language: 'Solidity',
    sources: {
        'TestToken.sol': {
            content: contractSource
        }
    },
    settings: {
        outputSelection: {
            '*': {
                '*': [ '*' ]
            }
        }
    }
});
let output = JSON.parse(solc.compile(jsonContractSource));
TokenJson = {
    'abi': {},
    'bytecode': ''
};
    TokenJson.abi = output.contracts['TestToken.sol']["TestToken"].abi;
    TokenJson.bytecode = output.contracts['TestToken.sol']["TestToken"].evm.bytecode.object;

fs.writeFile('/root/TestToken/TestToken.json', JSON.stringify(TokenJson), function(err){
    if(err)
        console.error(err);
})

contract files:

TestToken.sol

pragma solidity ^0.5.9;
import "/root/TestToken/StandardToken.sol";
contract TestToken is StandardToken {
/* Public variables */
string public name;
uint8 public decimals;
string public symbol;
string public version = '0.1';

constructor(
    uint256 _initialAmount,
    string memory _tokenName,
    uint8 _decimalUnits,
    string memory _tokenSymbol
    ) public {
    balances[msg.sender] = _initialAmount;
    totalTokenSupply = _initialAmount;
    name = _tokenName;
    decimals = _decimalUnits;
    symbol = _tokenSymbol;
}

function approveAndCall(address _spender, uint256 _value) public returns (bool success) {
    allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);
    return true;
} }

StandardToken.sol

pragma solidity ^0.5.9;
import "/root/TestToken/Token.sol";
contract StandardToken is Token {
    function transfer(address _to, uint256 _value) public returns (bool success) {
        //if (balances[msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
        if (balances[msg.sender] >= _value && _value > 0) {
            balances[msg.sender] -= _value;
            balances[_to] += _value;
            emit Transfer(msg.sender, _to, _value);
            return true;
        } else { return false; }
    }
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        //if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
        if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0) {
            balances[_to] += _value;
            balances[_from] -= _value;
            allowed[_from][msg.sender] -= _value;
            emit Transfer(_from, _to, _value);
            return true;
        } else { return false; }
    }
    function balanceOf(address _owner) public view returns (uint256 balance) {
        return balances[_owner];
    }
    function approve(address _spender, uint256 _value) public returns (bool success) {
        allowed[msg.sender][_spender] = _value;
        emit Approval(msg.sender, _spender, _value);
        return true;
    }
    function allowance(address _owner, address _spender) public view returns (uint256 remaining) {
      return allowed[_owner][_spender];
    }
    mapping (address => uint256) balances;
    mapping (address => mapping (address => uint256)) allowed;
    uint256 totalTokenSupply;
}

Token.sol

pragma solidity ^0.5.9;
contract Token {
    function totalSupply() public view returns (uint256 supply) {}
    function balanceOf(address _owner) public view returns (uint256 balance) {}
    function transfer(address _to, uint256 _value) public returns (bool success) {}
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {}
    function approve(address _spender, uint256 _value) public returns (bool success) {}
    function allowance(address _owner, address _spender) public view returns (uint256 remaining) {}
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
  • Clearly from the error, variable output has no field named contracts. Why don't you start by investigating that? – goodvibration Jun 1 '19 at 9:44
  • I used the same way to compile another contract made of only one single source file, it worked. This case has three files. I don't know whether it's the difference why it not works.Thanks.:) – Ntydrm Jun 1 '19 at 10:21
  • It's really the problem, please see the message in output 'Source "/root/TestToken/StandardToken.sol" not found: File import callback not supported', I use absolute path to include StansardToken.sol file, it still can node find it.Perhaps need some improvement. – Ntydrm Jun 1 '19 at 10:39
0

Check the version of SOLC and the solidity version of your sol files. 'Source file requires different compiler version'

Your sol file version is pragma solidity ^0.5.9; what is your SOLC version...?

| improve this answer | |
0
let contractSource = fs.readFileSync('/root/TestToken/TestToken.sol', 'utf-8')

I believe you get the error here. this directory is valid in posix systems. If you are using non-posix os this will not work. better using node.js built in "path" module.

const path=require("path")
const TestTokenPath = path.resolve(__dirname, "TestToken", "TestToken.sol");
const source = fs.readFileSync(TestTokenPath, "utf8");

Also, you defined this JSON object:

TokenJson = {
    'abi': {},
    'bytecode': ''
};

but you cannot access to its properties like regular objects:

    TokenJson.abi // this is invalid
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.