Я использую функцию в своем приложении NodeJS для развертывания контрактов. Пользователь вводит контракт, который он хочет развернуть, и приложение развертывает его. Структура приложения

.
├── 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 это

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

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

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

И User.sol

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);
    }
}

Наконец, важная часть функции развертывания:

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({
    .
    .
    .
}

Когда я пытаюсь это сделать, возвращается следующая ошибка

{ 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

Хотя документы скажем (как и ожидалось), что . относится к текущему каталогу. В частности, они говорят: «Чтобы импортировать файл x из того же каталога, что и текущий файл, используйте import "./x" as x;». Кроме того, он отлично работал в Remix, поэтому я не уверен, где ошибка.

4
mcansado 4 Авг 2017 в 20:05
Можете ли вы удалить точку и попробовать импортировать «TrustEntity.sol»; ?
 – 
Rangesh
4 Авг 2017 в 20:11
Тоже пробовал, но тоже не получилось.
 – 
mcansado
4 Авг 2017 в 20:15

2 ответа

Это работает для меня:

    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) => {

        ...
0
Renaud 10 Апр 2018 в 20:48

Вам нужно импортировать каждый контракт в виде строки, а затем передать их все в Solidity. https://github.com/ethereum/solc-js#from-version- 016

0
user34322 9 Мар 2018 в 20:31