4

I'm using a function in my NodeJS app to deploy contracts. The user inputs the contract he wishes to deploy and the app deploys it. The structure of the app is

.
├── app
│   ├── models
│   │   └── user.js
│   └── routes.js
├── cert.pem
├── config
│   ├── auth.js
│   ├── database.js
│   └── passport.js
├── contracts
│   ├── Registry.sol
│   ├── TrustEntity.sol
│   └── User.sol
├── key.pem
├── modules
│   ├── contracts.js
│   └── helpers.js

TrustEntity.sol is

pragma solidity ^0.4.11;
import "./User.sol";

contract TrustEntity {
    address owner;
    address registry;
    address[] pendingRequests;

    function pushPending(address requester) {
        pendingRequests.push(requester);
    }
}

and User.sol is

pragma solidity ^0.4.11;
import "./TrustEntity.sol";

contract User {
    // State variables
    TrustEntity trustEntity;
    address owner = msg.sender;
    bool verified = false;
    uint creationTime = now;
    uint level = 0;
    address[] public pendingRequests;

    // Set trustEntity's deployed contract address
    function User(address _trustEntity) {
        trustEntity = TrustEntity(_trustEntity);
    }

    function requestValidation() {
        trustEntity.pushPending(owner);
    }
}

Finally, the relevant part of the deploy function is

function deploy(contractName, publicAddress, _gas) {
    // Get the contract code from contracts
    const input = fs.readFileSync('contracts/' + contractName + '.sol').toString();
    const output = solc.compile(input);
    // The trailing ':' is needed otherwise it crashes
    const bytecode = output.contracts[':' + contractName].bytecode;
    const abi = JSON.parse(output.contracts[':' + contractName].interface);
    console.log(abi[0].inputs[0]);
    const contract = web3.eth.contract(abi);
    console.log("Contract:" + contract);
    const contractInstance = contract.new({
    .
    .
    .
}

When I try it, the following error is returned

{ contracts: {},
  errors: [ ':2:1: ParserError: Source "User.sol" not found: File not supplied initially.\nimport "./User.sol";\n^------------------^\n' ],
  sourceList: [ '' ],
  sources: {} }
TypeError: Cannot read property 'bytecode' of undefined

even though the docs say (as expected) that . refers to the current directory. Specifically, they say: "To import a file x from the same directory as the current file, use import "./x" as x;". Also, it was working fine in Remix so I'm not sure where the error is.

  • Can you remove the dot and try like import "TrustEntity.sol"; ? – Rangesh Aug 4 '17 at 17:11
  • Tried that too but it didn't work either. – mcansado Aug 4 '17 at 17:15
0

You need to import each contract as a string and then pass them all to solidity https://github.com/ethereum/solc-js#from-version-016

0

This works for me:

    fs.readFile(fullFileName, 'utf8', (err, data) => {

    const compiled = solc.compile(data);

    const bytecode = compiled.contracts[':' + name].bytecode
    const abi = JSON.parse(compiled.contracts[':' + name].interface)

    ...

    const contractData = '0x' + bytecode

    const rawTx = {
        nonce: nonceHex,
        gasPrice: gasPriceHex,
        gasLimit: gasLimitHex,
        data: contractData,
        from: mainAccount
    };


    const tx = new EthTx(rawTx)
    tx.sign(new Buffer(pKey, 'hex'))
    const txHex = tx.serialize().toString('hex')

    web3.eth.sendSignedTransaction(`0x${txHex}`).on('receipt', (receipt) => {

        ...

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.