0

I initially had my libraries in separate contracts, but I had trouble deploying my contracts. I am trying to debug the issue so I moved all of my contracts into one file, ERC20God.sol:

pragma solidity ^0.4.24;

library Safemath {
  function add(uint _a, uint _b) public pure returns (uint){
    uint sum = _a + _b;
    require(sum >= _a && sum >= _b);
    return sum;
  }

  function subtract(uint _a, uint _b) public pure returns (uint){
    require( _a >= _b );
    return _a - _b;
  }

  function multiply(uint _a, uint _b) public pure returns (uint){
    uint product = _a * _b;
    require(product/_a == _b);

    return product;
  }

  function divide(uint _a, uint _b) public pure returns (uint){
    require( _b != 0 );
    return _a / _b;
  }
}

library ERC20Transfer {
  using Safemath for uint;

  struct UserBalance{
    mapping(address => uint256) balance;
  }

  function transferTokens(UserBalance storage self, address _from, address _to, uint _amount) public returns(bool) {
    require(self.balance[_from] >= _amount);

    self.balance[_from] -= _amount;
    self.balance[_to] += _amount;
    // self.balance[_from] = self.balance[_from].subtract(_amount);
    // self.balance[_to]   = self.balance[_to].add(_amount);

    return true;
  }
}

// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
contract ERC20God {
  using Safemath for uint;

  ERC20Transfer.UserBalance userBalance;

  string public name;
  string public symbol;
  uint8 public decimals;
  uint256 public totalSupply;

  address public owner;

  event Transfer(address indexed _from, address indexed _to, uint256 amount);

  constructor(string _name, string _symbol, uint8 _decimals, uint256 _totalSupply) public {
    owner       = msg.sender;
    name        = _name;
    symbol      = _symbol;
    decimals    = _decimals;
    totalSupply = _totalSupply.multiply(10**uint(decimals));
    userBalance.balance[owner] = totalSupply;
  }

  modifier onlyOwner {
    require(msg.sender == owner);
    _;
  }

  modifier notOwner {
    require(msg.sender != owner);
    _;
  }

  function withdrawalEth() public onlyOwner returns(bool) {
    owner.transfer(address(this).balance);
    return true;
  }

  function tokenSale() public payable notOwner returns(bool) {
    require(msg.value > 0);

    // 1eth = 1000coin
    uint256 tokenAmount = ((msg.value / 1 ether).multiply(1000)).multiply(10**uint(decimals));

    ERC20Transfer.transferTokens(userBalance, owner, msg.sender, tokenAmount);
    emit Transfer(owner, msg.sender, tokenAmount);

    return true;
  }

  function transfer(address _to, uint256 _amount) public returns(bool) {
    uint adjustedAmount = _amount.multiply(10**uint(decimals));

    ERC20Transfer.transferTokens(userBalance, msg.sender, _to, adjustedAmount);
    emit Transfer(msg.sender, _to, adjustedAmount);

    return true;
  }

  function balanceOf(address _owner) public view returns(uint256) {
    return userBalance.balance[_owner];
  }
}

My second migration file, 2_migrate_contracts.js looks like this:

var ERC20God = artifacts.require("./ERC20God.sol");

module.exports = async function(deployer) {
  await deployer.deploy(ERC20God);
};

I am getting the following error:

Error: ERC20God contains unresolved libraries. You must deploy and link the following libraries before you can deploy a new version of ERC20God: ERC20Transfer, Safemath

From some of the answers I've seen, people have issues linking separate files (i.e. deployer.link(ERC20God, [Safemath, ERC20Transfer]). However, all of my libraries are in a single file. If I don't use Safemath, then everything works.

What am I doing incorrectly here?

Edit: I have also tried moving the libraries into separate files and linking them. Still getting no errors and running migrations will deploy Safemath to an address, but abruptly stop when it tries to deploy ERC20Transfer (no address was returned).

Running migration: 2_migrate_smartcontract.js 
Deploying Safemath... ... 0xc7c236b6015a40a6225054e19ed5e36444c54f7f53df284e29b0e2bff2feaac5 

Safemath: 0xdc1ecf296aa2e2810f8080b89402486d81384ccb 

Saving successful migration to network... 
Linking Safemath to ERC20 ... 0x2d10c5cc6ae1fcf168358f3b864745dd43cc8d7c9b3ba66a1623b1b429c62fa6 

Deploying ERC20Transfer... ... 0xe69beb4c6b797cf86aca15a9e958ce405bb428e8d939aac7a9dee1f44a254848 
Saving artifacts
  • What is your aim in declaring a struct mapping inside a library? – Rick Park Nov 6 '18 at 20:52
  • @RickPark I had to declare the struct mapping inside the library because I coudlnt pass a mapping to a library function if it's in another file. The only reason why I moved it into one file was because remix only deployed one library and I wanted to see if it was an issue with how I was declaring my external libraries. – Huy Nov 6 '18 at 21:40
2

I think it is not possible with truffle, you need to separate it back.

Migration script should looks like:

UPDATED

var Safemath = artifacts.require("./Safemath.sol");
var ERC20Transfer = artifacts.require("./ERC20Transfer.sol");
var ERC20 = artifacts.require("./ERC20.sol");

module.exports = function (deployer) {
    deployer.deploy(Safemath);
    deployer.link(Safemath, [ERC20Transfer, ERC20]);

    deployer.deploy(ERC20Transfer);
    deployer.link(ERC20Transfer, ERC20);

    deployer.deploy(ERC20, "NAME", "SML", 0, 1000);
};
  • That doesnt work either. Only safemath gets deployed. If i try to run ERC20Transfer.deployed in truffle console, I get: ERC20Transfer has not been deployed to detected network (network/artifact mismatch) – Huy Nov 6 '18 at 21:43
  • delete build directory and run migration again – Aquila Nov 6 '18 at 21:47
  • Running migration: 2_migrate_smartcontract.js Deploying Safemath... ... 0xc7c236b6015a40a6225054e19ed5e36444c54f7f53df284e29b0e2bff2feaac5 Safemath: 0xdc1ecf296aa2e2810f8080b89402486d81384ccb Saving successful migration to network... Linking Safemath to ERC20 ... 0x2d10c5cc6ae1fcf168358f3b864745dd43cc8d7c9b3ba66a1623b1b429c62fa6 Deploying ERC20Transfer... ... 0xe69beb4c6b797cf86aca15a9e958ce405bb428e8d939aac7a9dee1f44a254848 Saving artifacts... – Huy Nov 6 '18 at 21:52
  • For some reason, it stops at ERC20Transfer and does not deploy it. It just saves Saving artifacts but does not return the address that ERC20Transfer is deployed to – Huy Nov 6 '18 at 21:53
  • do you use ganache or truffle develop? what is in log? – Aquila Nov 6 '18 at 22:02

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.