Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gas requirement of function high: infinite

Below is my smart contract. When I put it in remix, I get warnings on each of the following functions.

Gas requirement of function MedicalRecord.addNote(bytes32,bytes32) high: infinite.

Gas requirement of function MedicalRecord.getDoctorsNames() high: infinite.

Gas requirement of function MedicalRecord.getNotes() high: infinite.

Gas requirement of function MedicalRecord.giveDoctorAccess(address,bytes32) high: infinite.

pragma solidity ^0.4.17;


contract MedicalRecord {
struct Doctor {
    bytes32 name;
    uint id;
}

struct Note {
    bytes32 title;
    bytes32 note;
}

address public patient;
uint private doctorId;
bytes32[] public doctorsNames;
Note[] notes;
mapping (address => Doctor) private doctors;

modifier onlypatient {
    require(msg.sender == patient);
    _;
}

modifier isCurrentDoctor {
    require(!(doctors[msg.sender].id < doctorId));
    _;
}

function MedicalRecord() public {
    patient = msg.sender;
    doctorId = 0;
}

function giveDoctorAccess(address drAddress, bytes32 name)
public
onlypatient
returns (bytes32)
{
    doctors[drAddress] = Doctor (name, doctorId);
    doctorId++;
    doctorsNames.push(name);
    return (name);
}

function getNotes()
    view
    public
    isCurrentDoctor
    returns (bytes32[], bytes32[])
{
    bytes32[] memory titles = new bytes32[](notes.length);
    bytes32[] memory noteTexts = new bytes32[](notes.length);
    
    for (uint i = 0; i < notes.length; i++) {
        Note storage snote = notes[i];
        titles[i] = snote.title;
        noteTexts[i] = snote.note;
    }
    
    return (titles, noteTexts);
}

function getDoctorsNames() view public returns (bytes32[]) {
    return doctorsNames;
}

function addNote(bytes32 title, bytes32 note) public isCurrentDoctor 
{
    notes.push(Note({title: title, note:note}));
}
}

Can anyone tell me how I can improve this?

like image 865
bak Avatar asked Mar 10 '18 03:03

bak


1 Answers

Any reference to a dynamic array will result in an infinite gas warning. It doesn't necessarily mean you're doing something wrong.

From an optimization size, there are a couple minor things you could do, but most will not drastically change your gas consumption. For example, I don't see a need to store a separate array of doctorNames since you already hold those in your Doctor struct. Also, generally speaking it's not a good idea to iterate through a potentially unbounded array of items as you are doing in getNotes(). Usually, it's better to have a function that returns the array length and then call a separate function to get the note passing in the index (in other words, do the loop in your client). But even here, it doesn't seem like your use case will result in a very large array of notes.

Your biggest cost is going to be your contract being bound to a single patient. Contract deployments are very expensive. Here, you will be deploying a contract for every patient in your system (maybe multiple contracts per patient since it's a medical record?). I would be looking to push everything down into structs and have 1 contract for all patients/medical records. MAYBE one contract per patient, depending on the overall business case (even considering this, I think I would explore having one contract per doctor first). But, certainly not a contract per medical record.

like image 173
Adam Kipnis Avatar answered Nov 02 '22 23:11

Adam Kipnis