0

When does a compiler fail to generate bytecode for solidity? The code compiles entirely but both remix and solc js give proper abi but empty bytecode. The contract imports ERC721.

Solidity contract:

pragma solidity ^0.5.12;  
import "./ERC721.sol";  
contract abcToken is ERC721 { 

    struct Item{
        uint id;
        bytes name; // Name of the Item
        uint creationTime; // Item Level
        uint tokenType;  // 0 = transaction, 1 = reputation, 2 = attention
        uint expiryduration;
    }

    Item[] public items; // First Item has Index 0

    struct User {
        uint[][] tokenId;
    }

    mapping (address => User) usersByAddr;
    address[] users;
    address public owner;
    address[] public owners;
    uint[] public tokenCount;
    uint[] public tokenCountInSupply;
    bytes transactionSymbol = "MTXN";
    bytes reputationSymbol = "MREP";
    bytes attentionSymbol = "MATT";

    event tokenCreated(address _to, uint _tokenType, uint _amount, uint timeCreated, uint[] _tokenId);
    event tokenDestroyed(address _from, uint _tokenType, uint _amount, uint timeDestroyed, uint[] _tokenId, bool penalty);
    event tokenTransfer(address _from, address _to, uint _tokenType, uint _amount, uint transferTime, uint[] _tokenId);
    event ownerAdded(address _primaryOwner, address _secondaryOwner);
    event ownerRemoved(address _primaryOwner, address _secondaryOwner);

    constructor() public {
        owner == msg.sender; //First owner used for token transfers
        owners.push(msg.sender); // The Sender is the Owner; Ethereum Address of the Owner
        for(uint i = 0; i < 3; i++) {
            tokenCount[i] = 0;
            tokenCountInSupply[i] = 0;
        }
    }
    /**
     * @return true if `msg.sender` is the owner of the contract.
     */
    function isOwner() public view returns (bool) {
        for (uint i = 0; i < owners.length; i++) {
            if (owners[i] == msg.sender) {
                return true;
            }
        }
        return false;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner());
        _;
    }

    function createItem(address _to, uint _tokenType, uint _expiryduration, uint quantity) public onlyOwner() {
        // Only the Owner can create Items
        //add loop for quantity
        bytes memory tokenSymbol;
        if(_tokenType == 0) tokenSymbol = transactionSymbol;
        if(_tokenType == 1) tokenSymbol = reputationSymbol;
        if(_tokenType == 2) tokenSymbol = attentionSymbol;
        bytes memory _name = tokenSymbol; 
        uint[] memory _tokenIds;
        uint _creationTime = block.timestamp;
        bool firstTimeUser = true;
        for(uint j = 0; j < users.length; j++) {
            if (users[j] == _to) {
                firstTimeUser = false;
                break;
            }
        }
        for (uint i = 0; i < quantity; i++) {
            uint id = items.length; // Item ID = Length of the Array Items
            items.push(Item(id,_name, _creationTime, _tokenType, _expiryduration));
            _tokenIds[i] = id;
            if(!firstTimeUser) {
                uint usertokenlength = usersByAddr[_to].tokenId[_tokenType].length;
                usersByAddr[_to].tokenId[_tokenType][usertokenlength] = id;
            }
            if (firstTimeUser) {
                uint[][] memory usersTokens;
                usersTokens[_tokenType][0] = id;
                User memory newuser = User(usersTokens);
                usersByAddr[_to] = newuser;
                users.push(_to);
                firstTimeUser = false;
            }
            _mint(_to,id); // Assigns the Token to the Ethereum Address that is specified
            tokenCount[_tokenType] += 1;
            tokenCountInSupply[_tokenType] += 1;
        }
        emit tokenCreated(_to, _tokenType, quantity, _creationTime, _tokenIds);
    }

    function getUsers() public view returns (address[] memory _users) {
        return users;
    }

    function tokenDetails(uint _tokenId) public view returns (uint _id, bytes memory _tokenName, uint _creationTime, uint _tokenType, uint _expiryduration) { //return individual elements
        for(uint i = 0; i < items.length; i++) {
            if(items[i].id == _tokenId) {
                _id = items[i].id;
                _tokenName = items[i].name;
                _creationTime = items[i].creationTime;
                _tokenType = items[i].tokenType;
                _expiryduration = items[i].expiryduration;
            }
        }
        return (_id, _tokenName, _creationTime, _tokenType, _expiryduration);
    }

    function getUserTokens(address _userAddress, uint _tokenType) public returns (uint[] memory _tokens) { //check 2d array push syntax
        burnToken(_userAddress);
        return usersByAddr[_userAddress].tokenId[_tokenType];
    }

    function getUserBalance(address _userAddress) public view returns(uint txnBlanace, uint repBalance, uint attBalance) {
        txnBlanace = usersByAddr[_userAddress].tokenId[0].length;
        repBalance = usersByAddr[_userAddress].tokenId[1].length;
        attBalance = usersByAddr[_userAddress].tokenId[2].length;
        return (txnBlanace, repBalance, attBalance);
    }

    function burnTokenPenalty(address _userAddress, uint _tokenType, uint quantity) public onlyOwner() returns (uint _tokenBurntQuantity) {
        uint[] memory tokensDeletedPosition;
        uint[] memory _tokenIds;
        for(uint j = 0; j < usersByAddr[_userAddress].tokenId[_tokenType].length; j++) {
            if(_tokenIds.length < quantity && items[usersByAddr[_userAddress].tokenId[_tokenType][j]].creationTime + items[usersByAddr[_userAddress].tokenId[_tokenType][j]].expiryduration >= block.timestamp) {
                _burn(_userAddress, items[usersByAddr[_userAddress].tokenId[_tokenType][j]].id);
                _tokenIds[j] = items[usersByAddr[_userAddress].tokenId[_tokenType][j]].id;
                delete usersByAddr[_userAddress].tokenId[_tokenType][j];
                tokensDeletedPosition[tokensDeletedPosition.length] = j;
            }
        }
        shiftUserTokens(_userAddress, _tokenType,tokensDeletedPosition);
        emit tokenDestroyed(_userAddress, _tokenType, tokensDeletedPosition.length, block.timestamp, _tokenIds, true);
        return _tokenIds.length;
    }

    //shift after burn
    function burnToken(address _userAddress) public onlyOwner() {
        for(uint i = 0; i < 3; i++) {
            uint[] memory tokensDeletedPosition;
            uint[] memory _tokenIds;
            for(uint j = 0; j < usersByAddr[_userAddress].tokenId[i].length; j++) {
                if(items[usersByAddr[_userAddress].tokenId[i][j]].creationTime + items[usersByAddr[_userAddress].tokenId[i][j]].expiryduration <= block.timestamp) {
                    _burn(_userAddress, items[usersByAddr[_userAddress].tokenId[i][j]].id);
                    _tokenIds[j] = items[usersByAddr[_userAddress].tokenId[i][j]].id;
                    delete usersByAddr[_userAddress].tokenId[i][j];
                    tokensDeletedPosition[tokensDeletedPosition.length] = j;
                }
            }
            shiftUserTokens(_userAddress,i,tokensDeletedPosition);
            emit tokenDestroyed(_userAddress, i, tokensDeletedPosition.length, block.timestamp, _tokenIds, false);
        }
    }

    function shiftUserTokens(address _userAddress, uint _tokenType, uint[] memory deletedPositions) public onlyOwner() {
        uint tokenListLength = usersByAddr[_userAddress].tokenId[_tokenType].length;
        for (uint i = 0; i < deletedPositions.length; i++) {
            if (deletedPositions[i] < tokenListLength-1 ) {
                usersByAddr[_userAddress].tokenId[_tokenType][deletedPositions[i]] = usersByAddr[_userAddress].tokenId[_tokenType][tokenListLength -1];
                delete usersByAddr[_userAddress].tokenId[_tokenType][tokenListLength -1];
                tokenListLength = usersByAddr[_userAddress].tokenId[_tokenType].length;
                tokenCountInSupply[_tokenType] -= 1;
            }
        }
    }

    function transferToken(address _from, address _to, uint _tokenType, uint _amount, uint _expiryTime, bytes memory _reason) public returns (uint[] memory tokens, uint[] memory tokenPositions) {
        require(msg.sender == owner || msg.sender == _from);
        uint validTokensCount = 0;
        uint[] memory validTokens;
        uint[] memory validTokenPositions;
        for (uint i = 0; i < usersByAddr[_from].tokenId[_tokenType].length; i++) {
            uint itemNo = usersByAddr[_from].tokenId[_tokenType][i];
            if (items[itemNo].creationTime + items[itemNo].expiryduration >= _expiryTime ) {
                validTokens[validTokensCount] = usersByAddr[_from].tokenId[_tokenType][i];
                validTokenPositions[validTokensCount] = i;
                validTokensCount += 1;
            }
        }
        if (validTokensCount >= _amount) {
            uint _toTokenLength = usersByAddr[_to].tokenId[_tokenType].length ;
            for (uint i = 0; i < validTokens.length; i++) {
                safeTransferFrom(_from, _to, validTokens[i], _reason);
                delete usersByAddr[_from].tokenId[_tokenType][validTokenPositions[i]];
                usersByAddr[_to].tokenId[_tokenType][_toTokenLength] = validTokens[i];
                _toTokenLength += 1;
            }
            emit tokenTransfer(_from, _to, _tokenType, _amount, block.timestamp, validTokens);
            return (validTokens, validTokenPositions);
        } else {
            delete validTokens;
            delete validTokenPositions;
            return (validTokens, validTokenPositions);
        }

    }

    function addOwner(address _secondaryOwner) public onlyOwner() {
        owners.push(_secondaryOwner);
        emit ownerAdded(msg.sender, _secondaryOwner);
    }

    function removeOwner(address _secondaryOwner) public onlyOwner() {
        bool ownerRemovedflag = false;
        uint removedPosition;
        for( uint i = 0; i < owners.length; i++) {
            if(owners[i] == _secondaryOwner) {
                delete owners[i];
                ownerRemovedflag = true;
                removedPosition = i;
                emit ownerRemoved(msg.sender, _secondaryOwner);
            }
        }
        if(ownerRemovedflag) {
            if(removedPosition < owners.length-1) {
                owners[removedPosition] = owners[owners.length-1];
                delete owners[owners.length-1];
            }
        }
    }
}

Compiler script:

   const path = require("path"); 

   const solc = require("solc"); 
   const fs = require("fs-extra");

   const contracts = [];
   fs.readdirSync("contracts").forEach(file => {   contracts.push(file); });

    sources = {};   contracts.forEach(contract => {  
        sources[contract] = {  
          content: fs.readFileSync(  
            path.resolve(__dirname, "contracts", contract),  
            "utf8"
          )  
        }; });


    compilingPreparations = () => {
     const buildPath = path.resolve(__dirname, "build");     
          fs.removeSync(buildPath);
     return buildPath;   };

/** * Returns and Object describing what to compile and what need to be returned. */

createConfiguration = () => {  
  return {  
    language: "Solidity",  
    sources: sources,  
    settings: {  
      outputSelection: {  
        "*": {  
          "*": ["abi", "evm.bytecode"]  
        }  
      }
    }
  } 
};  

/** * Compiles the sources, defined in the config object with solc-js. * @param config - Configuration object. * @returns {any} - Object with compiled sources and errors object. */

compileSources = config => {  
  try { 
 fs.writeFileSync('./oldsolabi.txt',solc.compile(JSON.stringify(config)));  
    return JSON.parse(solc.compile(JSON.stringify(config)));  
  } catch (e) {
    console.log(e);
  }
};

/** * Shows when there were errors during compilation. * @param compiledSources */

errorHandling = compiledSources => {  
  if (!compiledSources) {  
    console.error("ERRORS\n","NO OUTPUT");  
} else if (compiledSources.errors) {
    // something went wrong.
    console.error("ERRORS <<<<<<<<<<<<<<<<<<<<<<<<\n");
    compiledSources.errors.map(error => console.log(error.formattedMessage));
  }
};

/** * Writes the contracts from the compiled sources into JSON files, which you will later be able to * use in combination with web3. * @param compiled - Object containing the compiled contracts. * @param buildPath - Path of the build folder. */

writeOutput = (compiled, buildPath) => {  
  fs.ensureDirSync(buildPath);  

  for (let contractFileName in compiled.contracts) {  
    const contractName = contractFileName.replace(".sol", "");  
    console.log("Writing: ", contractName + ".json");  
    fs.outputJsonSync(path.resolve(buildPath, contractName + ".json"),  
      compiled.contracts[contractFileName][contractName]  
    );
  }
};

const buildPath = compilingPreparations();  
const config = createConfiguration();  
const compiled = compileSources(config);  
errorHandling(compiled);  
writeOutput(compiled, buildPath); 
  • 2
    Please share your compilation command-line or whatever it is you do in order to compile your code, including any other piece of information necessary for referring to your question (for example, your code, your compiler version, etc). – goodvibration Oct 13 '19 at 14:22
  • Sorry for the terrible indentation. Have added the codes above. – learningOneErrorAtATime Oct 14 '19 at 5:12
  • a bit hard to tell from the formatting and everything else, but are you sure you're not accidentally looking at the output for the ERC721 interface (which doesnt compile bytecode) rather than your contract? – AnAllergyToAnalogy Oct 14 '19 at 5:46
  • Yes, I checked it each time. I ensure that I selected abcToken.sol and then check the compilation details (Because I can see the abi clearly there, but no bytecode). – learningOneErrorAtATime Oct 14 '19 at 7:20
  • I tried in remix. Bytecode generates just fine. – Iftifar Taz Oct 15 '19 at 10:33
0

I ran into this same issue and wasn't able to find a good answer anywhere, so I thought I'd share what fixed it for me.

I was extending a base contract but not calling it's constructor. It looks like you may be doing the same thing with the ERC721 contract.

Here's some solidity documentation about how to properly call base contract constructors:

pragma solidity >=0.4.22 <0.6.0;

contract Base {
    uint x;
    constructor(uint _x) public { x = _x; }
}

// Either directly specify in the inheritance list...
contract Derived1 is Base(7) {
    constructor() public {}
}

// or through a "modifier" of the derived constructor.
contract Derived2 is Base {
    constructor(uint _y) Base(_y * _y) public {}
}

Hope this helps!

| 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.