Calling Contracts
Contract API basically comes in three pieces.
Firstly, there’s state-changing transaction like tranferring tokens to a counter-party.
Secondly, there’s event reception and reporting that happen when such a state change occurs.
Finally, there is inspection of the contract state through calling
constant
function.
Our first contract
The first contract we will deal with is the global(name) registry. If you are not yet familiar, this is a registry that exists on all sensible blockchain which records fields of information for any desired name.
The registry records onwership information so that names can be registered and their information changed at a later date.
The registry contract has a fairly simple API for inspecting. We only need to worry about two functions:
getOwner(bytes32) -> address
, given the Keccak hash of name, this returns the address of its owner, if it has been reserved.getData(bytes32, bytes32) -> bytes32
, given the Keccak hash of a name and a second field key, this returns the associated data.
There are subordinate functions to the latter such as getAddress
and getUint
which coerce the data into some other type. It is important to note that amongst the standardised field keys are:
A
theaddress
primarily associated with the name; if you’re wanting to send funds to the name, this is where to send them(assuming it’s not null)CONTENT
thebytes32
which equals the Keccak hash of any content associated with this name. e.g. If the name represents a dapp, then this would be the hash of the dapp’s content.IMG
thebytes32
which equals the Keccak hash of an associated image; this might be a person’s avatar or the dapp icon, depending on what is being named.
Let’s begin by displaying the address associated with the name gavofyork
. To do this we will need to create a special Bond
-API contract object. The function to do this is bonds.makeContract
; It takes the address and the ABI of the contract and returns an object with Bond
– returning functions for each of the contract’s functions.
The address is easy enough to find; this can be determined via the parity.api.parity.registry
call. The ABI spec is rather long and can be derived from the contract code available at the ethcode/contracts repository. Since there is only a single canonical registry, Parity, conveniently constructs this for you and provides it at the bonds.registry
object.
To figure out the primary associated address of the gavofyork
name, we can use the getAddress
call, together with the parity.api.util.sha3
call to take the Keccak hash of our name. The full expression would be:
1 | bonds.registry.getAddress(parity.api.util.sha3('gavofyork')) |
Typing parity.api.util.sha3(...)
every time you want to look up a name in the registry gets tedious fast. Happily, Parity provides a number of derivative helper functions as part of the bonds'registry
object: lookupDate
, lookupAddress
, lookupUint
and lookupOwner
. They are all just like the get-
prefixed brethren, but do the hashing for you. Our expression therefore can become:
1 | bonds.registry.lookupAddress('gavofyork', 'A') |
Let’s get this in to our dapp, Change the render()
ed HTML to:
1 | <div> |
Dynamic lookups
1 | export class App extends React.Component { |
Derivative contracts
Typically the registry is used to lookup the address of a second contract that you would actucally like to use.
Let’s suppose that second contract is the GithubHint contract; if you’re not already familiar, the GithubHint contract allows you to suggest which URLs might serve content for a particular hash.It’s a semi-centralized, hacky alternative to content-addressable-delivery systems like BitTorrent/Kademlia, Swarm and IPFS. We use it widely in Parity as a means of content dissemination.
Since is a ‘standard’ contract in Parity, the ABI for it is available in oo7-parity
as GitHubHintABI
. The address changes per chain, but can be discovered via the registry under the name ‘githubhint’. The expression would therefore be bonds.registry.lookupAddress('githubhint', 'A')
.
Though we mustn’t forget to import GitHubHint
1 | import { GitHubHintABI } form 'oo7-parity' |
The GithubHint contract has only a single inspection method: entries
. This takes a bytes32
and returns three items(via an array). There are three kinds of entry: Github repository entries, whereby the first and second items form the addresss of a particular commit of a particular repository; general URLs, where the first item is a URL and the second is the null hash; and empty entries where both items are null. The third item is always the owner (if any) of the entry and the only account capable of changing the hint information.
In this small demo, we’ll assume that we are looking up only URLs and so are only interested in the first item. We therefore want an expression like:
1 | GitHubHint.entries(hash)[0] |
Where hash
is some content hash and GitHubHint
is the contract object.
Putting this all together we can change our dapp to:
1 | export class App extends React.Component { |
Note that we are using HashBond
from oo7-react
rather than InputBond
. This just ensures that we enter only valid 32-byte hashes. Ensure that the import line is changed to:
1 | import { InputBond, HashBond } from 'parity-reactive-ui' |