Using ONT ID

Integrating ONT ID to centralized and decentralized systems

ONT ID can be integrated to centralized and decentralized systems alike to implement a decentralized identity and account mechanism with a rich variety of other functions. The Ontology framework is flexible in terms of the languages that are supported. There are several public SDKs that are available for the community to work and experiment with.

ONT ID

Developers can glance over ONT ID specifications to get a better understanding of the technical architecture.

The ONT ID protocol has been implemented on the Ontology chain using native smart contracts. API methods can be invoked to carry out ONT ID related actions such as registration, cancellation, attribute modification, etc. Follow the link below to navigate to the ONT ID contract API reference.

ONT ID Contract API

Integrating the ONT ID framework is a simple enough process. The major steps have been illustrated below.

Use OWallet tool to create a new wallet

OWallet is a wallet tool that can be used to work with Ontology wallets and carry out staking on the Ontology network. You can download the latest version of OWallet by following this link.

Download and install OWallet, and then in the main 'wallets' window click on the '+' icon. Follow the prompts to create a new Ontology wallet. You'll need this perform any interactions with the Ontology chain.

You'll be able to see your wallet address on the top after successfully creating your wallet and exporting the .dat wallet file.

We encourage and value any contributions that are made by community developers to the SDKs for other languages. Support for ONT ID 2.0 allows the developer community to integrate this safe and decentralized identity management protocol to the new applications swiftly and conveniently.

Fetch testnet ONG

Performing on-chain actions consumes ONG in the form of gas/transaction costs. Follow this link to apply for testnet ONG that will come in handy when developing on and working within the Ontology ecosystem. Use your wallet address to apply for testnet ONG tokens on the portal.

Set up SDK environment

Currently, the Java, Golang, and Typescript SDKs support the updated ONT ID 2.0 specifications. For the rest of the SDKs that for now support ONT ID 1.0 can be accessed using the link below.

SDKs

After obtaining testnet ONG, you're all set to start working with the Ontology framework. The SDKs illustrated below can be used to implement ONT ID related functions. But first, we must set up the environment to use the SDK libraries in your project. Execute the commands specified to set up the SDK.

Golang SDK

Please ensure that you have the latest version of Go set up and running on your local machine.

1. Clone the SDK library

git clone https://github.com/ontio/ontology-go-sdk.git

2. Install dependencies

Run the following command to enable Go modules in your environment in case they aren't already enabled.

export GO111MODULE="on"

For Windows OS, configure the environment variables in system settings to enable Go modules.

And then run the following command to install the necessary dependencies.

go mod vendor

Java SDK

Please confirm that you have the latest version of Java and Maven set up and running on your system.

1. Clone the SDK library

git clone https://github.com/ontio/ontology-java-sdk.git

2. Install dependencies

mvn clean install

TypeScript SDK

Please ensure that you have a NodeJS and TypeScript environment set up and running on your local system (we'll be using npm)

1. Clone the SDK library

git clone https://github.com/ontio/ontology-ts-sdk.git

2. Install the necessary dependencies

npm install

Initialize and invoke SDK

Once the environment is set up, next up would be initializing the respective SDK. The process has been briefly described individually for each SDK using the testing package that contains several useful demos for reference. Roughly speaking the sequence is as follows:

  1. Instantiate and initialize the SDK

  2. Create a wallet object that will be used when executing methods and making API calls

  3. Create a new ONT ID linked to the account

  4. Register the action on chain by storing the DID document into the contract

  5. Add attributes if necessary

  6. Fetch ONT ID and respective attribute related details

All the sample code used below is used for the purpose of illustration and has been taken from test or demo files that come with the SDK. The name of the file has also been specified with each code snippet.

Move the newly created wallet to the SDK main directory before proceeding to initialize the SDK

Go SDK

One way to initialize an SDK instance would be:

/* ontology-go-sdk/ont_sdk_test.go */

func Init() {
    testOntSdk = NewOntologySdk()
    testOntSdk.NewRpcClient().SetAddress("http://polaris1.ont.io") // Set RPC client address to testnet node address
    var err error
    var wallet *Wallet
    if !common.FileExisted("./wallet.dat") {// Checks if a wallet exists in the main directory
        fmt.Println("Wallet not found")
        }
    } else { 
        testWallet, err = testOntSdk.OpenWallet("./wallet.dat") // Imports and uses wallet for the SDK instance
        if err != nil {
            fmt.Println("[OpenWallet] error:", err)
            return
        }
    }
}

Next we can generate an ONT ID and start working with it. The sample code illustrates how to execute certain basic operations.

/* ontology-go-sdk/native_contract_test.go */

func TestOntId(t *testing.T) {
    Init() // Initializing the SDK

    /* Generating a new ONT ID */

    testIdentity, err := testWallet.NewDefaultSettingIdentity(testPasswd) // Generating a new ONT ID with the default settings
    if err != nil {
        t.Errorf("TestOntId NewDefaultSettingIdentity error:%s", err)
        return
    }
    _, err = testOntSdk.Native.OntId.RegIDWithPublicKey(testGasPrice, testGasLimit, testDefAcc, testIdentity.ID, testDefAcc) // Sends transaction to register ONT ID with the wallet account
    if err != nil {
        t.Errorf("TestOntId RegIDWithPublicKey error:%s", err)
        return
    }
    testOntSdk.WaitForGenerateBlock(30 * time.Second) // Timeout till next block

    /* Add attributes for the ONT ID */

    attributes := []*DDOAttribute{ // Define DDO attributes for the ONT ID
        &DDOAttribute{
            Key:       []byte("1"),
            Value:     []byte("2"),
            ValueType: []byte("3"),
        },
    }

    /* Add attributes to the DDO document in the ONT ID contract on chain */

    _, err = testOntSdk.Native.OntId.AddAttributesByIndex(testGasPrice, testGasLimit, testDefAcc, testIdentity.ID, attributes, 1, testDefAcc) // Sending the transaction
    if err != nil {
        t.Errorf("TestOntId AddAttributesByIndex error:%s", err)
        return
    }
    testOntSdk.WaitForGenerateBlock(30 * time.Second) // Timeout till next block

    /* Fetch details for particular attribute */

    attribute, err := testOntSdk.Native.OntId.GetAttributeByKey(testIdentity.ID, "1") // Method call to pass the attribute key
    if err != nil {
        t.Errorf("TestOntId GetAttributeByKey error:%s", err)
        return
    }
    fmt.Printf("TestOntId GetAttributeByKey:%+v\n", attribute)

    /* Fetch DDO for particular ONT ID */

    document, err := testOntSdk.Native.OntId.GetDocumentJson(testIdentity.ID) // Method call to pass the ONT ID
    if err != nil {
        t.Errorf("TestOntId GetDocumentJson error:%s", err)
        return
    }
    fmt.Printf("TestOntId GetDocumentJson:%+v\n", string(document))
    return
}

The addresses for the currently active Polaris testnet nodes can be found here.

For a more detailed and practical test case, you can refer to cred_test.go.

Follow this link to find the Go SDK reference on Github.

Java SDK

To instantiate and initialize an SDK object:

/* src/test/java/com/github/ontio/smartcontract/nativevm/NativeOntIdTxTest.java */

public void setUp() throws Exception {
        ontSdk = OntSdk.getInstance();
        // Set testnet node URL
        ontSdk.setRestful(OntSdkTest.URL);
        ontSdk.setDefaultConnect(ontSdk.getRestful());
        // Open wallet with SDK object
        ontSdk.openWalletFile(walletFile);
//      ontSdk.setSignatureScheme(SignatureScheme.SHA256WITHECDSA);
        payer = new Account(SignatureScheme.SHA256WITHECDSA);
        payerAcct = payer;
        // Generate ONT ID
        identity = ontSdk.getWalletMgr().createIdentity(password);
        account = new com.github.ontio.account.Account(SignatureScheme.SHA256WITHECDSA);
        // Record action on chain
//      ontSdk.nativevm().ontId().sendRegister(identity,password,payerAcct,ontSdk.DEFAULT_GAS_LIMIT,0);
        Thread.sleep(6000);

    }

The above method is defined in the NativeOntIdTest class. You can refer to the source file and run the test respective test cases.

Sample code that illustrates basic operations:

/* src/test/java/com/github/ontio/smartcontract/nativevmNativeOntIdTxTest.java */

public void sendRegister() throws Exception {

        // Record ONT ID allocation action on chain 
        Transaction tx = ontSdk.nativevm().ontId().makeRegister(identity.ontid, account.serializePublicKey(), payer.getAddressU160().toBase58(), ontSdk.DEFAULT_GAS_LIMIT, 0);
        ontSdk.addSign(tx, account);
        ontSdk.addSign(tx, payerAcct);
        ontSdk.getConnect().sendRawTransaction(tx);

        Identity identity2 = ontSdk.getWalletMgr().createIdentity(password);

        ontSdk.nativevm().ontId().sendRegister(identity2.ontid, account, payerAcct, ontSdk.DEFAULT_GAS_LIMIT, 0);

        //Adding attributes to an ONT ID
        Identity identity3 = ontSdk.getWalletMgr().createIdentity(password);
        Attribute[] attributes = new Attribute[1];
        attributes[0] = new Attribute("key2".getBytes(), "value2".getBytes(), "type2".getBytes());
        ontSdk.nativevm().ontId().sendRegisterWithAttrs(identity3.ontid, attributes, account, payerAcct, ontSdk.DEFAULT_GAS_LIMIT, 0);

        Thread.sleep(6000);

        //Fetch DDO object from contract
        String ddo = ontSdk.nativevm().ontId().sendGetDDO(identity.ontid);
        Assert.assertTrue(ddo.contains(identity.ontid));

        String dd02 = ontSdk.nativevm().ontId().sendGetDDO(identity3.ontid);
        Assert.assertTrue(dd02.contains("key2"));

        String keystate = ontSdk.nativevm().ontId().sendGetKeyState(identity.ontid, 1);
        Assert.assertNotNull(keystate);

        //merkleproof
        Object merkleproof = ontSdk.nativevm().ontId().getMerkleProof(tx.hash().toHexString());
        boolean b = ontSdk.nativevm().ontId().verifyMerkleProof(JSONObject.toJSONString(merkleproof));
        Assert.assertTrue(b);

        //claim
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("Issuer", identity.ontid);
        map.put("Subject", identity2.ontid);

        Map clmRevMap = new HashMap();
        clmRevMap.put("typ", "AttestContract");
        clmRevMap.put("addr", identity.ontid.replace(Common.didont, ""));

        String claim = ontSdk.nativevm().ontId().createOntIdClaim(identity.ontid, account, "claim:context", map, map, clmRevMap, System.currentTimeMillis() / 1000 + 100000);
        boolean b2 = ontSdk.nativevm().ontId().verifyOntIdClaim(claim);
        Assert.assertTrue(b2);
    }

You can refer to the NativeOntIdTxTest.java in the test directory of the SDK to find and experiment with the test class methods.

Follow this link to find the Java SDK reference on Github.

TypeScript SDK

/* test/newOntidContractTxBuilder.test.ts */

    // Generate ONT ID and send a transaction to record action on chain
    test('buildRegIDWithPublicKeyTx', async () => {
        const tx = NewOntidTxBuilder.buildRegIDWithPublicKeyTx(did1, pk1, gasPrice, gasLimit, address1);
        signTransaction(tx, privateKey1);
        const res = await socketClient.sendRawTransaction(tx.serialize(), false, true);
        console.log(res);
        expect(res.Error).toEqual(0);
    }, 100000);

    // Add attributes to an ONT ID document
    test('buildAddAttributeTx', async () => {
        const attr = new DDOAttribute();
        attr.key = 'hello2';
        attr.type = 'string',
        attr.value = 'world2';
        const tx = NewOntidTxBuilder.buildAddAttributeTx(did4, [attr], pk4, gasPrice, gasLimit, address4);
        signTransaction(tx, pri4);
        const res = await socketClient.sendRawTransaction(tx.serialize(), false, true);
        console.log(res);
        expect(res.Error).toEqual(0);
    }, 100000);

    // Fetch attribute information
    test('buildGetAttributesTx', async () => {
        const tx = NewOntidTxBuilder.buildGetAttributesTx(did4);
        const res = await socketClient.sendRawTransaction(tx.serialize(), true);
        console.log(res);
        expect(res.Error).toEqual(0);
    }, 100000);

    // Fetch document information
    test('buildGetDocumentTx', async () => {
        const ontid = 'did:ont:AN3iwgee5JKzZV99gknpdmQf5XUJJbQ7xQ';
        const doc = await NewOntidTxBuilder.getDocumentJson(ontid, 'http://polaris1.ont.io:20334');
        console.log(doc);
    }, 100000);

Follow this link to find the TypeScript SDK reference on Github.

A wide variety of functions operations can be performed with ONT ID by calling the public API exposed from the native contract deployed on the Ontology chain. The API reference for the contract and the chain itself is available here.

Last updated