I am using web3 and truffle to create a frontend to interact with this contract.

On the frontend, when I call sendCert with all the values, it seems to add them to the map but NOT to the array. I tried adding to the array the way shown above and with the .push() method and when I call the two functions to check the certArray length and the addressIdx array length, it ALWAYS returns 0.

The method sendCert, which is supposed to add the certifications to the array and the mapping also returns 0 for that certId no matter how many times I add certifications.

Am I doing something wrong here? In the frontend, I have a call back which logs "success" when the certification is sent successfully and executed by this method successfully.

Lastly, is there any way I can send the contents of the two arrays to the frontend to work on them in javascript instead of solidity?

1 Answer
1

There's a lot more going here. The big picture item is you're storing the certificate structure twice - once in the mapping and once in an array. This is not ideal. Also, I think the use of an address for the unique identifier of each certificate causes limitations and confusion. Why is a certificate known by the id of someone who earned it? What if a student earns more than one certificate? It's probably better to reference each certificate with an arbitrary Id:

mapping(bytes32 => CertificateStruct) public certificateStructs;

and then you can maintain an iterable list of them:

bytes32[] public certificateList;

You might also want a list of certificates for each student address, which could lead to something like:

mapping(address => bytes32[]) studentCertificates;

Your read-only functions like function getAddressIdxLength() returns(uint) are not marked with the constant modifier, so you're not getting the expected uint. It's costing gas to send a transaction and you don't get to see the response owing to mining delays. When you add constant, you'll see the expected 1 and things will start to make sense again.

It's a little on the data-heavy side for a platform with expensive storage cost and you might find that a mapping from an address to a certificate Id, in concert with off-chain storage adequately solves the problem of proving a given student was awarded a given certificate at a given time. The key is to economize.

The loopy search function is an anti-pattern because at some (uncalculated) number of iterations, it will exceed the block gas limit and cease to work at all. Generally, design everything to complete with a consistent gas cost at any scale. Either you won't really need to put that in the contract because ancillary storage is expected to contain the extra details, or create internal mappings to solve for searches in one operation.

I noticed pragma solidity ^0.4.2; which is quite old. If the constant suggestion gives you trouble, it's probably because you're actually using a newer compiler, in which case try view.