I have read that blockchains aren't good at storing large files. But you can create a hash of a file and somehow store that in the blockchain, they say. How do I do that? What API or service should I be looking at? Can I do it on bitcoin.org, or does it need to be some special "parameterized" blockchain service of some sort?
In the blogs I've seen touting how cool it is where you can store your data in mysql but store the hash in the blockchain, they don't show how you actually nitty-gritty get the hash into the blockchain, or even what services are recommended to do this. Where is the API? What field do I pass to the hash into?
This is what I think the frontend would look like:
hashedData = web3.utils.sha3(JSON.stringify(certificate));
contracts.mycontract.deployed().then(function(result) {
return result.createCertificate(public_addresskey,hashedData,{ from: account }); //get logged in public key from metamask
}).then(function(result) {
//send post request to backend to create db entry
}).catch(function(err) {
console.error(err);
// show error to the user.
});
The contract might look something like the sketch below.
There is a struct to contain everything but the id. A mapping from hash => Cert for random access (using the hash as id) and a certList to enumerate the certificates in case the hash isn't known. That should not happen because it emits events for each important state change. You would probably want to protect the newCert() function with onlyOwner, a whiteList or role-based access control.
To "confirm" a cert, the recipient confirms by signing a transaction. The existence of a true in this field shows that the user mentioned did indeed sign because there is no other way for this to occur.
pragma solidity 0.5.1;
contract Certificates {
struct Cert {
address recipient;
bool confirmed;
}
mapping(bytes32 => Cert) public certs;
bytes32[] public certList;
event LogNewCert(address sender, bytes32 cert, address recipient);
event LogConfirmed(address sender, bytes32 cert);
function isCert(bytes32 cert) public view returns(bool isIndeed) {
if(cert == 0) return false;
return certs[cert].recipient != address(0);
}
function createCert(bytes32 cert, address recipient) public {
require(recipient != address(0));
require(!isCert(cert));
Cert storage c = certs[cert];
c.recipient = recipient;
certList.push(cert);
emit LogNewCert(msg.sender, cert, recipient);
}
function confirmCert(bytes32 cert) public {
require(certs[cert].recipient == msg.sender);
require(certs[cert].confirmed == false);
certs[cert].confirmed = true;
emit LogConfirmed(msg.sender, cert);
}
function isUserCert(bytes32 cert, address user) public view returns(bool) {
if(!isCert(cert)) return false;
if(certs[cert].recipient != user) return false;
return certs[cert].confirmed;
}
}
The short answer is: "Use Ethereum smart contract with events and don't store hash values in the contract."
On Etherscan your may find a complete contract for the storage of hash values in Ethereum: HashValueManager. As you will see in this code example - things are a bit more complex. You have to manage access rights and here the cost was not important (this contract has been designed for a syndicated blockchain)
Actually it is very expensive to store hash data in a blockchain. When you use an Ethereum contract to store the hash data, you have to pay about 0.03 Euro (depending on the ETH and Gas prize) for each transaction.
It would be a better option not to store the hash value in the contract. A much more cheaper alternative is to emit indexed events in a smart contract and query the events (this is very fast). Information about the events are stored in a bloom filter of the mined block and will be readable forever. The only disadvantage is that an event can't be read from within the contract (but this is not your business logic)
You may read more details here about events and how to fetch them in an application : "ETHEREUM EVENT EXPLORER FOR SMART CONTRACTS" (disclaimer: this article is my blog). Also the complete source code is available on GitHub.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With