pragma solidity ^0.5.0;
I get invalid opcode error when trying to estimate gas needed for my transaction from react-native using the following line of code:
const gasAmount = await contract.methods
.Track(RecordOwner, account, meidcalRecordHash)
.estimateGas({from: account});
After some searching, I found this answer, which states that invalid opcode
can be the result
of either
one of the following runtime operations
:
(1)assert
of an expression which evaluates to false
(2)array[i]
where i >= array.length
However, I do not see any of these two possible runtime operation in my solidity "Track" function
function Track(
address _patientID,
address _doctorID,
string memory _recordHash
) public {
// Get the record hash index
uint256 i;
uint256 recordHashIndex;
string[] memory patient_recordHashes = getPatientRecordHashes(
_patientID
);
for (i = 0; i < patient_recordHashes.length; i++) {
// CHANGED count to patient_recordHashes.length
string memory patient_recordHash = patient_recordHashes[i];
if (
keccak256(abi.encodePacked(patient_recordHash)) ==
keccak256(abi.encodePacked(_recordHash))
) {
recordHashIndex = i;
}
}
// Get the doctor address index
uint256 doctorIndex;
address[] memory patient_listOfDoctors = getPatientRecordListOfDoctors(
_patientID,
recordHashIndex
);
for (i = 0; i < patient_listOfDoctors.length; i++) {
if (patient_listOfDoctors[i] == _doctorID) {
doctorIndex = i;
}
}
// Set the bool value corresponding to the "recordHashIndex" & "doctorIndex" to true
IsRecordSeen[_patientID][recordHashIndex][doctorIndex] = true;
// Destroy/remove the medical record from the dcotor view screen
delete patientToDoctorRecordNames[_patientID][_doctorID][recordHashIndex];
delete patientToDoctorRecordHashes[_patientID][_doctorID][recordHashIndex];
delete patientToDoctorEncKeyHashes[_patientID][_doctorID][recordHashIndex];
} // end of the Track function
//Some of the function used inside the Track function:
// Get all the record hashes of a patient
function getPatientRecordHashes(address _patientID)
public
view
userExists(_patientID)
returns (string[] memory)
{
return patientRecordHashes[_patientID];
}
// Get the list of doctors with access to a specific medical record of a patient
function getPatientRecordListOfDoctors(address _patientID, uint256 index)
public
view
userExists(_patientID)
returns (address[] memory)
{
return patientRecordListOfDoctors[_patientID][index];
}
Is there something wrong inside the Track function that cause invalid opcode ? Any hint would be highly appreciated
Update1: I have just tested the "Track" function on remix. It is working fine. Also, the estimate gas sometimes works, but not all the time. any hint on why this is happening, please?
const gasAmount = await contract.methods
.Track(RecordOwner, account, meidcalRecordHash)
.estimateGas({from: account});
some data structures used :
mapping(address => mapping(address => string[]))
public patientToDoctorRecordHashes;
mapping(address => mapping(uint256 => address[]))
public patientRecordListOfDoctors;
mapping(address => string[]) public patientRecordHashes;
mapping(address => mapping(uint256 => bool[])) public IsRecordSeen;
Update2: Please note there is also an "Add" function
that is usually called before the "Track" function. This "Add" function has multiple "push" operations inside. some of these push operations
are:
patientRecordHashes[_patientID].push(_recordHash);
doctorListOfPatients[doctorAddress].push(_patientID);
patientToDoctorRecordHashes[_patientID][doctorAddress].push( _recordHash);
IsRecordSeen[_patientID][count].push(false);
enum
parameter as input, and passing it a value larger than that enum's max value. This is a rather poor decision of the Solidity compiler development team, but it is nevertheless the current behavior.patientRecordHashes
andpatientRecordListOfDoctors
are missing in your code. We have no idea what they are (arrays or mappings) and how they are initialized. Obviously, your question cannot be answered without this information!However, I do not see any of these two possible runtime operation
- I could not find a single occurrence ofpush
in your code (and in this entire webpage to be honest, except for the one that i just mentioned). So obviously every storage array in your code is of length 0. Thus, obviously any attempt to access any of the arrays in your contract would result with an invalid opcode, exactly as stated in the 2nd bullet in the answer that you've quoted!solc --asm
. The output should have comments that denote entry point of your function.