I am new to Solidity and tried to write a contract. Now for better developing reasons I made myself a setup with truffle. Previously I used to work with remix only. My Project contains multiple contracts. In remix I used to deploy the first contract and then insert it's address into the other contracts. There I used for each Contract abstractions. Now I tried to integrate one contract and it's avstract zo my truffle environment. But it doesn't seem to work as expected. Disregarding the quality of the code itself, truffle won't deploy my contract (see the output below).
I looked around different posts like (https://www.toshblocks.com/solidity/abstract-contracts-solidity/ or Deploying abstract contracts and interfaces). But it seems like I can't find the solution to this problem/misunderstanding myself.
See the following files
The Abstraction (.abstracts/organAbstract.sol):
pragma solidity 0.4.24;
// Contract declaration
contract organA {
// Structs
struct organ { address originOwner; address currentOwner; string organType; string organState; }
// Signatures for all functions within the organ contract
function addOrgan(address _originOwner, string _type, string _state) external returns(bytes32 organHash);
function changeOrganState(bytes32 _organId, string _state) public;
function getOrganListLength() public view returns(uint ListLenght);
function getOrganList(uint indexNumber) public view returns(bytes32 OrganId);
function getOrgan(bytes32 _organHash) public view returns(address OriginOwner, address CurrentOwner, string OrganType, string OrganState);
function existsOrgan(bytes32 _organHash) external view returns(bool Existence);
function organOriginOwner(bytes32 _organHash) external view returns(address OriginOwner);
}
The Contract (./contracts/organ.sol):
pragma solidity 0.4.24;
// Import Abstracts
import "../abstracts/organAbstract.sol";
contract organContract is organA {
// --- Global variables --- //
address contractOwner;
uint256 organCount;
// Constructor for contract entity_organs
constructor() public {
contractOwner = msg.sender; // Declare first sender as owner
emit stateOwner(msg.sender); // Trigger event
organCount = 0; // Set the counter to 0
}
// Mapping for Organs
mapping (bytes32 => organ) private organsList;
mapping (uint256 => bytes32) private organIndex;
// Organs Array
bytes32[] private organsListByHash;
// --- Modifiers --- //
// Modifier to allow contract owner only
modifier contractOwnerOnly () {
// Require the given address to be the same
require(msg.sender == contractOwner, "You are not allowed to interact!");
_;
}
// Check if the organ exists
modifier checkOrganExistence(bytes32 _organHash) {
require(bytes(organsList[_organHash].organState).length != 0, "Organ with given id doesn't exist!");
_;
}
// Require atleast one organ on count
modifier organCountMin() {
require(organCount != 0, "No organs found to return!");
_;
}
// --- Events --- //
// Event when first transaction gets owner
event stateOwner (
address ownerAddress
);
// Event when a new organ gets added
event newOrganAdded (
address organOwner,
bytes32 organId
);
// Event when organ state has changed
event organStateChanged (
bytes32 organId,
string state
);
// -- Organ Functions -- //
// Function to add a new organ to an owner
// This function will be called over the entityContract
function addOrgan(address _originOwner, string _type, string _state) external returns(bytes32 organHash) {
// Somehow unique (There is no raqndom generator available)
bytes32 uniqueOrgan = keccak256(_type, _originOwner);
// Pass the values
organsList[uniqueOrgan].originOwner = _originOwner; // insert the owner
organsList[uniqueOrgan].currentOwner = _originOwner; // insert the owner
organsList[uniqueOrgan].organType = _type; // insert the organ type
organsList[uniqueOrgan].organState = _state; // Insert the organ state
// Update the index
organIndex[organCount] = uniqueOrgan; // Enter the hash for the integer key
organCount++; // Update the global counter
organsListByHash.push(uniqueOrgan); // Push to Array
emit newOrganAdded(_originOwner, uniqueOrgan); // Trigger event
// Return Organ for
return uniqueOrgan;
}
// Change organ state (in prototype only type)
function changeOrganState(bytes32 _organId, string _state) checkOrganExistence(_organId) public {
// Blacklist certain states if donator still alive
// DATE COMPARISON https://github.com/pipermerriam/ethereum-datetime
organsList[_organId].organState = _state; // Change organ state
emit organStateChanged(_organId, _state);
return;
}
// Function to view to length of organs
// Returns the value as integer of the array length
function getOrganListLength() organCountMin() public view returns(uint ListLenght) {
return organCount;
}
// Function to return the entire list for organs
function getOrganList(uint indexNumber) organCountMin() public view returns(bytes32 OrganId) {
return organIndex[indexNumber]; // Return the array
}
// Function to show organ with properties
// With the given id to web3js foreach organ can be viewd it's properties by id
function getOrgan(bytes32 _organHash) checkOrganExistence(_organHash) public view returns(address OriginOwner, address CurrentOwner, string OrganType, string OrganState) {
// Return the value
return (
organsList[_organHash].originOwner,
organsList[_organHash].currentOwner,
organsList[_organHash].organType,
organsList[_organHash].organState
);
}
// Function to return organs existence (for external contracts)
function existsOrgan(bytes32 _organHash) external view returns(bool Existence) {
if (bytes(organsList[_organHash].organState).length != 0) { return true; } else { return false; }
}
// Function to return origin owner of an organ
function organOriginOwner(bytes32 _organHash) organCountMin() checkOrganExistence(_organHash) external view returns(address OriginOwner) {
return organsList[_organHash].originOwner;
}
}
This is the Deployment definition:
var organC = artifacts.require("./organ.sol");
module.exports = function(deployer) {
deployer.deploy(organC, {overwrite: true})
};
After running the following command:
sudo truffle deploy --reset
I get this output:
2_deploy_contracts.js
=====================
Error: *** Deployment Failed ***
"organ" is an abstract contract or an interface and cannot be deployed.
* Import abstractions into the '.sol' file that uses them instead of deploying them separately.
* Contracts that inherit an abstraction must implement all its method signatures exactly.
* A contract that only implements part of an inherited abstraction is also considered abstract.
at Deployer._preFlightCheck (/usr/lib/node_modules/truffle/build/webpack:/packages/truffle-deployer/src/deployment.js:178:1)
Truffle v5.0.3 (core: 5.0.3)
Node v11.15.0
I don't really understand, why the contract "organ" is treated as abstract. The same message is occurring , when i try to deploy the contract without the include Statement. So something must be wrong with the contract itself, right? Or have i misunderstood the concept of abstractions completely?
Thanks in regard for help. If further information needed I will extend the post.