Contract info (metadata)

In the previous sections we explained how you create a contract on the blockchain. Now we deal with the rest of the compiler output, the contract metadata or contract info. The idea is that

  • contract info is uploaded somewhere identifiable by a url which is publicly accessible
  • anyone can find out what the url is only knowing the contracts address

These requirements are achieved very simply by using a 2 step blockchain registry. The first step registers the contract code (hash) with a content hash in a contract called HashReg. The second step registers a url with the content hash in the UrlHint contract. These simple registry contracts will be part of the frontier proposition.

By using this scheme, it is sufficient to know a contract's address to look up the url and fetch the actual contract metadata info bundle. Read on to learn why this is good.

So if you are a conscientious contract creator, the steps are the following:

  1. Deploy the contract itself to the blockchain
  2. Get the contract info json file.
  3. Deploy contract info json file to any url of your choice
  4. Register codehash ->content hash -> url

The JS API makes this process very easy by providing helpers. Call admin.register to extract info from the contract, write out its json serialisation in the given file, calculates the content hash of the file and finally registers this content hash to the contract's code hash. Once you deployed that file to any url, you can use admin.registerUrl to register the url with your content hash on the blockchain as well. (Note that in case a fixed content addressed model is used as document store, the url-hint is no longer necessary.)

source = "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"
// compile with solc
contract = eth.compile.solidity(source).test
// create contract object
var MyContract = eth.contract(contract.info.abiDefinition)
// extracts info from contract, save the json serialisation in the given file, 
contenthash = admin.saveInfo(contract.info, "~/dapps/shared/contracts/test/info.json")
// send off the contract to the blockchain
MyContract.new({from: primaryAccount, data: contract.code}, function(error, contract){
  if(!error && contract.address) {
    // calculates the content hash and registers it with the code hash in `HashReg`
    // it uses address to send the transaction. 
    // returns the content hash that we use to register a url
    admin.register(primaryAccount, contract.address, contenthash)
    // here you deploy ~/dapps/shared/contracts/test/info.json to a url
    admin.registerUrl(primaryAccount, hash, url)
  }
});