0

I am trying to connect two different Smart Contracts using interfaces. Here is my contract CRUD.sol:

// SPDX-License-Identifier: MIT pragma solidity ^0.8.4;

contract CRUD {

struct Data {
    uint id;
    bytes32 contentHash;
    string description;
}

// Variables de estado 
Data[] data;

uint nextId;

// Operaciones CRUD: CREATE, READ, UPDATE y DELETE:

// Operación CREATE
function createData(string memory _description) public{
    bytes32 contentHash = createHash(_description);
    data.push(Data(nextId, contentHash, _description));
    nextId++;
}



// Operación READ por búsqueda del id
function readData(uint _id) public view returns (uint, bytes32,string memory) {
    uint index = findIndex(_id);
    return (data[index].id, data[index].contentHash, data[index].description);
}

// Operación READ por búsqueda del hash de la entrada de datos
function readDataByHash(bytes32 _hash) public view returns (uint, bytes32,string memory) {
    uint index = findByHash(_hash);
    return (data[index].id, data[index].contentHash, data[index].description);
}

//Operacion READ todos las entradas de datos
function readAllData() external view returns (Data[] memory){
    return data;
}

function count() external view returns (uint){
    return data.length;
}

// Operación UPDATE
function updateData(uint _id, string memory _description) public returns (uint, bytes32, string memory){
    uint index =  findIndex(_id);
    bytes32 contentHash = createHash(_description);
    data[index].contentHash= contentHash;
    data[index].description = _description;
    return (data[index].id, data[index].contentHash, data[index].description);
}

// Operación DELETE
function deleteData(uint _id) public{
    uint index = findIndex(_id);
    delete data[index];
}

// Creación del hash
function createHash(string memory _description) internal pure returns (bytes32){
    return keccak256(abi.encodePacked(_description));
}

// Búsqueda del id
function findIndex(uint _id) internal view returns (uint) {
    for (uint i = 0; i < data.length; i++) {
        if (data[i].id == _id) {                
            return i;
        }
    }
    revert("Data not found");
}

// Busqueda por el hash de la entrada de datos
function findByHash(bytes32 _contentHash) internal view returns (uint) {
    for (uint i = 0; i < data.length; i++) {
        if (data[i].contentHash == _contentHash) {                
            return i;
        }
    }
    revert("Data not found");
}
}

Here is the other contract:

// SPDX-License-Identifier: MIT pragma solidity ^0.8.4;

interface ICRUD{ function readAllData() external view returns (Data[] memory); }

contract verifyData{

function read() external view returns (Data[] memory){
     Data[] data = ICRUD(0xd9145CCE52D386f254917e481eB44e9943F39138).readAllData();
     return data;
}
}

My purpose is to call readAllData function from verifyData contract but Remix just keeps returning the following error:

DeclarationError: Identifier not found or not unique.
--> verifyData.sol:5:51:
|
5 | function readAllData() external view returns (Data[] memory);
| ^^^^

Can someone help me? Thanks

1 Answer 1

1

Your issue refers that in your interface doesn't exist the implementation about Data struct. To solve it, you should move the declaration of this struct inside interface and modify your smart contracts similar to this way:

CRUD.sol:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// NOTE: I imported the smart contract where interface has declared
import "verifyData.sol";

contract CRUD is ICRUD {
    // Variables de estado 
    Data[] data;

    uint nextId;

    // Operaciones CRUD: CREATE, READ, UPDATE y DELETE:

    // Operación CREATE
    function createData(string memory _description) public{
        bytes32 contentHash = createHash(_description);
        data.push(Data(nextId, contentHash, _description));
        nextId++;
    }

    // Operación READ por búsqueda del id
    function readData(uint _id) public view returns (uint, bytes32,string memory) {
        uint index = findIndex(_id);
        return (data[index].id, data[index].contentHash, data[index].description);
    }

    // Operación READ por búsqueda del hash de la entrada de datos
    function readDataByHash(bytes32 _hash) public view returns (uint, bytes32,string memory) {
        uint index = findByHash(_hash);
        return (data[index].id, data[index].contentHash, data[index].description);
    }

    // NOTE: I override this function because I made that this smart contract implements with
    //       ICRUD interface.
    function readAllData() override external view returns (Data[] memory){
        return data;
    }

    function count() external view returns (uint){
        return data.length;
    }

    // Operación UPDATE
    function updateData(uint _id, string memory _description) public returns (uint, bytes32, string memory){
        uint index =  findIndex(_id);
        bytes32 contentHash = createHash(_description);
        data[index].contentHash= contentHash;
        data[index].description = _description;
        return (data[index].id, data[index].contentHash, data[index].description);
    }

    // Operación DELETE
    function deleteData(uint _id) public{
        uint index = findIndex(_id);
        delete data[index];
    }

    // Creación del hash
    function createHash(string memory _description) internal pure returns (bytes32){
        return keccak256(abi.encodePacked(_description));
    }

    // Búsqueda del id
    function findIndex(uint _id) internal view returns (uint) {
        for (uint i = 0; i < data.length; i++) {
            if (data[i].id == _id) {                
                return i;
            }
        }
        revert("Data not found");
    }

    // Busqueda por el hash de la entrada de datos
    function findByHash(bytes32 _contentHash) internal view returns (uint) {
        for (uint i = 0; i < data.length; i++) {
            if (data[i].contentHash == _contentHash) {                
                return i;
            }
        }
        revert("Data not found");
    }
}

verifyData.sol:

// SPDX-License-Identifier: MIT 
pragma solidity ^0.8.4;

interface ICRUD {
    // NOTE: Declare inside interface the Data struct implementation
    struct Data {
        uint id;
        bytes32 contentHash;
        string description;
    }

    function readAllData() external view returns (Data[] memory); 
}

contract verifyData is ICRUD {
    ICRUD ICrud;
    
    // NOTE: When deploy verifyData, you must pass the address of CRUD smart contract
    constructor(address _interfaceAddress) {
        ICrud = ICRUD(_interfaceAddress);
    }

    function readAllData() override external view returns (Data[] memory){
        Data[] memory data = ICrud.readAllData();
        return data;
    }
}

Inside both smart contracts I added some notes let you know every single modifies that I made.

1
  • Hi, Thanks for your replay. However, i dont understand why you made that import, is it necessary? Can you import contracts deployed in geth? I dont really understand imports
    – WakiApi
    Aug 3, 2022 at 22:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.