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 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 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 at 10:39

Your Answer

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

Browse other questions tagged or ask your own question.