13

I am making a student registration form and need a unique identifier for them. Are there any methods in Solidity that will give a unique number for every student that registers?

10

There is no built-in unique id generator in Solidity.

2 ideas:

  • use a counter, uint, and make sure to only increment it
  • use keccak256 hash function on unique data about the student, such as their username or email address
  • I can u please expand on the uint part? I tried that way but everytime the contract is called the value get set to default. – Rajat Mar 17 '17 at 7:09
  • @Rajat Like function getID() returns(uint) { return ++counter; } Contract has a state variable named counter. – eth Mar 31 '17 at 10:05
8

Check out the create() and createWithNonce() methods in this contract:

https://github.com/link-blockchain/blobstore/blob/master/blobstore.sol

create() takes the blockhash of the previous block with the sender address and hashes (with keccak256) to create a unique identifier:

/**
     * @dev Creates a new blob. It is guaranteed that different users will never receive the same blobId, even before consensus has been reached. This prevents blobId sniping. Consider createWithNonce() if not calling from another contract.
     * @param flags Packed blob settings.
     * @param contents Contents of the blob to be stored.
     * @return blobId Id of the blob.
     */
    function create(bytes4 flags, bytes contents) external returns (bytes20 blobId) {
        // Generate the blobId.
        blobId = bytes20(keccak256(msg.sender, block.blockhash(block.number - 1)));
        // Make sure this blobId has not been used before (could be in the same block).
        while (blobInfo[blobId].blockNumber != 0) {
            blobId = bytes20(keccak256(blobId));
        }
        // Store blob info in state.
        blobInfo[blobId] = BlobInfo({
            flags: flags,
            revisionCount: 1,
            blockNumber: uint32(block.number),
            owner: (flags & ANONYMOUS != 0) ? 0 : msg.sender,
        });
        // Store the first revision in a log in the current block.
        Store(blobId, 0, contents);
}

createWithNonce:

/**
     * @dev Creates a new blob using provided nonce. It is guaranteed that different users will never receive the same blobId, even before consensus has been reached. This prevents blobId sniping. This method is cheaper than create(), especially if multiple blobs from the same account end up in the same block. However, it is not suitable for calling from other contracts because it will throw if a unique nonce is not provided.
     * @param flagsNonce First 4 bytes: Packed blob settings. The parameter as a whole must never have been passed to this function from the same account, or it will throw.
     * @param contents Contents of the blob to be stored.
     * @return blobId Id of the blob.
     */
    function createWithNonce(bytes32 flagsNonce, bytes contents) external returns (bytes20 blobId) {
        // Generate the blobId.
        blobId = bytes20(keccak256(msg.sender, flagsNonce));
        // Make sure this blobId has not been used before.
        if (blobInfo[blobId].blockNumber != 0) {
            throw;
        }
        // Store blob info in state.
        blobInfo[blobId] = BlobInfo({
            flags: bytes4(flagsNonce),
            revisionCount: 1,
            blockNumber: uint32(block.number),
            owner: (bytes4(flagsNonce) & ANONYMOUS != 0) ? 0 : msg.sender,
        });
        // Store the first revision in a log in the current block.
        Store(blobId, 0, contents);
}
  • Welcome to the site! I'll upvote but a code snippet or two could also improve this answer. – eth Nov 14 '16 at 11:18
  • I have created a Student registration form and taking input as firstName, lastName and studentRegId. – Rahul Sharma Nov 15 '16 at 5:07
  • Isn't the "while (blobInfo[blobId].blockNumber != 0)" is prone to GAS burning loop? In case the blobId already used (where 2+ txs happened closely) this will loop until a new block is mined. @jonathan-brown – Eli Livshitz Aug 8 '18 at 6:41
1

You can fiddle in this site https://ethfiddle.com/mn8VfzWoN9

contract Student {
  uint public studentId;

  function getStudentId() public returns (uint) {
    return studentId++;
  }
}

Every time you invoke getStudentId function, the studentId will increase 1.

Maybe you have to replace public to internal with some validation statement.

  • Please make it to sentences, otherwise, the quality of the post look bad and people would start downvoting. – Rajesh Mar 19 '18 at 9:09
  • Sorry, i will fix this answer. – Xat_MassacrE Mar 19 '18 at 14:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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