Last modified: Mon Nov 04 2019 16:15:12 GMT+0000 (Coordinated Universal Time)

ORG.ID Tutorial

What is ORG.ID?

ORG.ID (short for Organization Identity) is a global decentralized business registry. Because it is decentralized, you can obtain your own unique identifier that you will be able to use with other ORG.ID participants without talking to anyone.

An ORG.ID consists of two parts: 0xORG and ORG.JSON. The former is any smart contract that follows the specified interface, and the latter is a JSON file conforming to a specification that contains the actual organization record.

1. Create an ORG.JSON

ORG.JSON is a specification that prescribes what information you must disclose to other market participants to be discoverable by them, as well as additional data fields you may want to fill out in order to build your organization's trust on the platform.

Apart from the meta-fields (dataFormatVersion and updatedAt), you must always present a legalEntity and if you are participating in a Segment Directory, the corresponding section (hotel, airline, ota which we have so far) should also be present.

2. Publish ORG.JSON

After you have prepared and validated your ORG.JSON, you have to publish it somewhere it can be easily accessible.

Storing a lot of data on the blockchain can be expensive, but you can store your ORG.JSON off-chain (on your own server, on AWS, on GitHub Gist, Pastebin, Swarm or IPFS, it's entirely up to you). Just make sure that you use a service with proper access control.

In the examples above we used GitHub Gist, so for the sake of this tutorial, go ahead and paste your own JSON there and click save. Right click the Raw button in the upper right corner and select a Copy link address option. This is the orgJsonUri of the ORG.JSON file. Note it down, we will need it later.

Saved gist, click the Raw button for getting a link to it

While we are working with ORG.JSON file, we will also create an orgJsonHash - a hash of the data which we will publish alongside the orgJsonUri. The orgJsonHash is a keccak256 equivalent hash, commonly named soliditySha3 in various Ethereum libraries. Or we can just use a tool like this (always check for empty lines in the beginning or end of the contents).

You should always keep the hash and the data in sync, so if you update your ORG.JSON data, make sure that you update the orgJsonHash as well.

Warning

Hashing is very content-sensitive. While you are producing a hash, be sure to always use the source data as-is available to the world without any interpretation such as deserialization.

If we take the example data we are going to use, the hash will look like this. The 0x prefix is a commonly used thing in the Ethereum world and only denotes that the hash is in a hexadecimal format. Some of the libraries refuse to work without the prefix, so let's keep it there. Note the resulting hash down, we will need it later.

0xea937104edca4af1f37e47808a5667173e83cc6033e0cf6e6a3c9f7c102b8beb

Info

The upcoming steps will require you to interact with the Ethereum blockchain. If you choose to interact with mainnet, you will be spending real ether.

3. Connect to the network

You have a few options here: to spin up your own testnet or mainnet node, or cheat a bit and connect to it through an intermediary, in this case we'll be using Infura (a service that Metamask and many other companies use).

3.1. Get an Ethereum Account

Warning

Educating you about safety and security of working with Ethereum is not a part of this guide. Here we assume that when you will be working with Winding Tree in production, you will apply adequate security measures to everything you do. For example working directly with a mnemonic in a hosted software is probably not the greatest idea.

For the purpose of this guide, let's generate a new mnemonic sentence using this generator. Just click on the link and then click "GENERATE". You should see a list of 15 words in the "BIP39 Mnemonic" box, like so: grocery medal idea ....

3.2. Create an Infura Account

No rocket science here; just create an account, and then create a new project. Later on we will need just one piece of information associated with your new Infura project: the PROJECT ID.

3.3. Install Truffle Console

Info

If you are not comfortable with truffle console, you might try our web based smart contract caller.

Working with Truffle can be a bit clunky, if you are new to it, so we created a helper repository for you. The following commands will install truffle in the orgid-tutorial directory, create a configuration file for it to connect to the network, and import Winding Tree smart contracts for you to be able to work with them from truffle console.

Comment

In order for the commands below to work, you will need Node 10 and Git. You can use nvm for managing multiple node versions.

> git clone https://github.com/windingtree/orgid-tutorial.git && cd orgid-tutorial # Get the code
> nvm use # Activate Node 10 from nvm. Skip if you're not using nvm
> npm install # Install dependencies

3.4. Truffle Console Configuration

At this point, truffle needs two more things to successfully connect to Ethereum network, we'll put both those things into a keys.json file inside our orgid-tutorial directory. So, fire up your favorite editor and put the following info there:

{
  "mnemonic": "grocery medal idea ...",
  "infura_projectid": "dd31f5a7..."
}

3.5 Run Truffle Console

Now this should work:

> npm run truffle-ropsten
# or
> npm run truffle-mainnet

You should see an output like this (the 0x.. part will be different and you will see either ropsten or mainnet):

Running truffle with default account 0xd054c6df3314a1b49f2b7ec0bf1011405a5efdff
truffle(ropsten)>

Now you know your account address (it starts with 0x...), and you can add some ETH to it to be able to interact with smart contracts.

3.6. Get Some ETH

We have a guide for that, but if you're working on a Ropsten testnet, just pop your account address in one of the following websites:

Wait until the transaction is confirmed and verify that you have some ETH available for your account on http://ropsten.etherscan.io/.

Warning

If you are working on mainnet, you are using real ETH that you will have to buy from someone or on an exchange. You won't need more than a few dollars worth of it. You must know how Ethereum private keys and mnemonic phrases work before you do anything on mainnet. Above everything else: 1) you must never ever disclose your private key or mnemonic phrase to anyone else, by doing so you are giving full control of your account to another (perhaps, malicious) person, and 2) losing your private key or mnemonic phrase is equal to losing control of your account and associated funds without any possibility of recovery.

4. Deploy 0xORG smart contract

To deploy a new 0xORG you can either:

  1. Use our Organization Factory smart contract, or
  2. Deploy a custom 0xORG implementation (you may extend the canonical 0xORG as you like) - we will not cover this option here.

Info

While we are using ropsten network in all of our code snippets, the code will be the same for mainnet. The addresses will be different, though.

4.1. Connecting to Entrypoint

Entrypoint smart contract is, well, the entry point to the Winding Tree world. It contains references to other smart contracts, such as Organization Factory and Segment Directories.

In your truffle console, type:

truffle(ropsten)> entrypoint = await WindingTreeEntrypoint.at('0xa268937c2573e2AB274BF6d96e88FfE0827F0D4D')
undefined

Comment

The undefined is an expected outcome of instantiation commands like this. Don't panic.

If you are getting an error such as Error: Cannot create instance of WindingTreeEntrypoint; no code at address 0xa268937c2573e2AB274BF6d96e88FfE0827F0D4D, please check that you are using an Entrypoint address that matches the used network.

4.2. Calling Organization Factory

We already know the address of the Organization Factory smart contract (it's in the beginning of this guide), but let's see how we can get it from the Entrypoint.

truffle(ropsten)> entrypoint.getOrganizationFactory()
'0x8E6463ea056d812094Ed514455Ab3C88fc23D59C'

Let's make it easy to call this smart contract's methods from the console:

truffle(ropsten)> factory = await OrganizationFactory.at('0x8E6463ea056d812094Ed514455Ab3C88fc23D59C')
undefined

4.3. Create and Deploy an ORG.ID

The Organization Factory smart contract will automagically do both for you, the only things you need to provide are the ORG.JSON URI and its hash from Step 2.

truffle(ropsten)> factory.create('https://gist.githubusercontent.com/JirkaChadima/9c86f9ed1cfd157f71a172ee9379f35f/raw/0287be953438ba04a9fb98b625589b2b28c64b8b/legal-entity-hotel-api.json', '0xea937104edca4af1f37e47808a5667173e83cc6033e0cf6e6a3c9f7c102b8beb')
{ tx:
   '0xbdf20ac934b921761a3739172f674660ab4eff2beee0b3fb84245e63189f98d3',
   ...
}

The result of calling the create method is a complex JSON called a transaction receipt. For now we will just find this transaction on Etherscan: 0xbdf20ac934b921761a3739172f674660ab4eff2beee0b3fb84245e63189f98d3. It seems like the transaction went through. If you switch to the Internal Transactions tab, you will see that a create call was executed. The "recipient" of that method's call is your new 0xORG smart contract. Click on it to reveal its full address. This address (0xf3ad504caed347cadb6e31806ce7088ef0f09742 but yours will be different) is the ORG.ID of your company.

Newly created 0xORG address

Success

Congratulations! You have obtained an ORG.ID for your company!

5. Getting ORG.ID Data

Now that you have your own brand new ORG.ID you can send it to another organization that is capable of working with this standard. How do they obtain the actual record of your company? Very easy:

truffle(ropsten)> orgid = await Organization.at('0xF3Ad504cAeD347cAdb6e31806CE7088EF0F09742')
undefined
truffle(ropsten)> orgid.getOrgJsonUri()
'https://gist.githubusercontent.com/JirkaChadima/9c86f9ed1cfd157f71a172ee9379f35f/raw/0287be953438ba04a9fb98b625589b2b28c64b8b/legal-entity-hotel-api.json'

They should also be responsible and check that nobody has tampered with your data by creating a hash by themselves and comparing it to the hash presented in your 0xORG smart contract.

truffle(ropsten)> orgid.getOrgJsonHash()
'0xea937104edca4af1f37e47808a5667173e83cc6033e0cf6e6a3c9f7c102b8beb'