0

Base

pragma solidity ^0.4.18;

contract ZombieFactory {

    event NewZombie(uint zombieId, string name, uint dna);

    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;

    struct Zombie {
        string name;
        uint dna;
    }

    Zombie[] public zombies;

    mapping (uint => address) public zombieToOwner;
    mapping (address => uint) ownerZombieCount;

    function _createZombie(string _name, uint _dna) internal {
        uint id = zombies.push(Zombie(_name, _dna)) - 1;
        zombieToOwner[id] = msg.sender;
        ownerZombieCount[msg.sender]++;
        NewZombie(id, _name, _dna);
    }

    function _generateRandomDna(string _str) private view returns (uint) {
        uint rand = uint(keccak256(_str));
        return rand % dnaModulus;
    }

    function createRandomZombie(string _name) public {
        require(ownerZombieCount[msg.sender] == 0);
        uint randDna = _generateRandomDna(_name);
        randDna = randDna - randDna % 100;
        _createZombie(_name, randDna);
    }

    function getZombieDnaById(uint _id) public view returns (uint) {
        return zombies[_id].dna;
    }

    function getZombieCount() public pure returns (uint) {
        //return ownerZombieCount[msg.sender];
        return 6789;
    }

}

Derived

pragma solidity ^0.4.18;

import "./ZombieFactory.sol";

contract KittyInterface {
  function getKitty(uint256 _id) external view returns (
    bool isGestating,
    bool isReady,
    uint256 cooldownIndex,
    uint256 nextActionAt,
    uint256 siringWithId,
    uint256 birthTime,
    uint256 matronId,
    uint256 sireId,
    uint256 generation,
    uint256 genes
  );
}

contract ZombieFeeding is ZombieFactory {

  address ckAddress = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d;
  KittyInterface kittyContract = KittyInterface(ckAddress);

  // Modify function definition here:
  function feedAndMultiply(uint _zombieId, uint _targetDna) public {
    require(msg.sender == zombieToOwner[_zombieId]);
    Zombie storage myZombie = zombies[_zombieId];
    _targetDna = _targetDna % dnaModulus;
    uint newDna = (myZombie.dna + _targetDna) / 2;
    // Add an if statement here
    _createZombie("NoName", newDna);
  }

  function feedOnKitty(uint _zombieId, uint _kittyId) public {
    uint kittyDna;
    (,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId);
    // And modify function call here:
    feedAndMultiply(_zombieId, kittyDna);
  }
}

2_deploy_contracts.js

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

module.exports = function(deployer) {
  deployer.deploy(ZombieFeeding);
};

app.js

CryptoZombiesFeeding.deployed().then(function(contractInstance){

  console.log(contractInstance);

  // call getZombieCount() of Base contract ZombieFactory.sol
  contractInstance.getZombieCount.call().then(function(zombieCount){
    console.log("address " + account + " has " + zombieCount + " zombies");
  });      

});

Commands

truffle migrate --reset

Everything builds ok, the contract ZombieFeeding is migrated successfully, and the contents of the contract instance in the client application contains both the parent and derived function references.

enter image description here

The problem is that when I call the getZombieCount function it returns 0, and it should be 6789. If I deploy the ZombieFactory contract alongside the ZombieFeeding contract it works. This shows me that when I use inheritance, the parent contracts functions can't be called.

1

Solution

When calling the contract add a from:address parameter to create a transaction. Transactions require gas and are needed to store data or run computations on contracts.

Example

app.js

// call Base contract function with transaction
CryptoZombiesFeeding.deployed().then(function(contractInstance){
  contractInstance.createRandomZombie(username, {from: address}).then(function(response){
    console.log("random zombie created with dna " + response);
  });
});

EDIT: The address is your Ether wallet address that is available through the web3 library.

-1

Try adding this to the migration file:

var ZombieFactory= artifacts.require("./ZombieFactory.sol");
var KittyInterface = artifacts.require("./KittyInterface.sol");
var ZombieFeeding = artifacts.require("./ZombieFeeding.sol");

module.exports = function(deployer) {
deployer.deploy(KittyInterface );
deployer.deploy(ZombieFactory);
deployer.link(ZombieFactory,ZombieFeeding);
deployer.deploy(ZombieFeeding);
};
  • So yes this works as mentioned in the question if I deploy both the Parent and Derived contracts, but you should only need to deploy the derived contract, the compilation stage concatenates the parent and derived before deploying. – David Jan 9 '18 at 19:41
  • Inheritance in the docs solidity.readthedocs.io/en/develop/contracts.html#inheritance When a contract inherits from multiple contracts, only a single contract is created on the blockchain, and the code from all the base contracts is copied into the created contract. – David Jan 9 '18 at 20:07
  • You do not have to deploy base classes ZombieFactory nor the interface contract KittyInterface. – Ismael Jan 11 '18 at 3:53

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.