Integration guide

The Ocean platform is based on Bitcoin, and has a superset of functionality, both in the protocol and the RPC interface. This guide describes methods and instructions for the integration of an Ocean sidechain into services, products and exchanges. For detailed instructions on installing and configuring an Ocean sidechain node, please read the ‘Ocean Node Setup’ section of the documentation.

Address Types

Ocean platform sidechains support a superset of the Bitcoin scripting language, and all redeem scripts and scriptPubKey script valid on Bitcoin are also valid on Ocean platform sidechains. Ocean sidechains therefore support the standard address formats, including P2PKH, P2SH and Segwit P2SH-P2WPKH. The Base58check address and private key (WIF compressed) prefixes used by oceand and wallets can be customised for specific asset backed sidechains, however the following defaults are used:

chain=ocean_main (mainnet)

Type Pre-fix Example
P2PKH 0x00 1EN1hdE4wVdgn6fWJQDmyUUwXNQ1RXbmGx
P2SH 0x05 3F42dAiWVPx4sGMwRVtNQ6qsftgj24aJdh
WIF 0x80 Kyp3hfVDandgQtABnT79yt9g3AAbwL9xsAN4ixULqVPauhdWneG2

chain=ocean_test (testnet)

Type Pre-fix Example
P2PKH 0xEB 2dnnm69GmntXaxxRs3zVfvwSpRuwgTBVsyT
P2SH 0x4B XQiFYmagC2PQ7c818sCgLstwjCikhBvygH
WIF 0xEF cQB3AaV51rKwaKdTArvHMCejfPU1bnFewCWXqNvrLc3bASgWmnGU

chain=gold_main (DGLD)

Type Pre-fix Example
P2PKH 0x26 GXCw7kZ1vMEyrZxoELstQEpqSYBrQchASF
P2SH 0x61 gG9XDA91ozag79Bug6Xh1dtFaJPWPkA6FY
WIF 0xB4 TfxqS4DzgnGq5nr8YPdbNw4zykcXM6FmL8kqpaVGNNabYutFx9ur

New addresses from the oceand can be generated using the getnewaddress RPC. P2SH-P2WPKH addresses can be generated by then supplying a wallet address to the addwitnessaddress. A P2SH multisig address can be generated using the createmultisig RPC with a supplied array of public keys.

Client wallet

The oceand client has an RPC wallet that is an extension of the bitcoind wallet. This is a BIP32 HD wallet that is generated on first use, with the wallet.dat file stored in the datadir/chain directory. The only significant difference is that the oceand wallet has functionality to handle multiple token types. For example, the wallet status accessed via the getwalletinfo RPC, which for example returns:

{
  "walletversion": 130000,
  "balance": {
    "21c5b781892bfa1ac72674181915be0b5eb13d4c917fbd72decbc9d18b2d6270": 32.0,
    "7e679401d07144ee6b3ee19f0cb02884ca10a4040726430c51f9b8534c89f898": 144.3454
  },
  "unconfirmed_balance": {
  },
  "immature_balance": {
  },
  "txcount": 0,
  "keypoololdest": 1571756105,
  "keypoolsize": 100,
  "paytxfee": 0.00000000,
  "hdmasterkeyid": "2572ce4d00d2fa5ebca9c371c9a846ab20889ba4"
}

Where this wallet holds two token types (or asset IDs): 21c5b781892bfa1ac72674181915be0b5eb13d4c917fbd72decbc9d18b2d6270 and 7e679401d07144ee6b3ee19f0cb02884ca10a4040726430c51f9b8534c89f898.

Sending one of these token types to an address can be performed using the sendtoaddress RPC as with bitcoind, but with the chosen asset ID as an additional argument. For example:

./oceand -datadir=path sendtoaddress GXCw7kZ1vMEyrZxoELstQEpqSYBrQchASF 16.0 '' '' false 21c5b781892bfa1ac72674181915be0b5eb13d4c917fbd72decbc9d18b2d6270

Will send 16.0 of asset 21c5b781892bfa1ac72674181915be0b5eb13d4c917fbd72decbc9d18b2d6270 to address GXCw7kZ1vMEyrZxoELstQEpqSYBrQchASF.

If you don’t care about the specific asset ID being sent (i.e. if the different tokens are considered fungible) then the sendanytoaddress RPC can be used. e.g.

./oceand -datadir=path sendanytoaddress GXCw7kZ1vMEyrZxoELstQEpqSYBrQchASF 60.0

Will select any assets summing to the value of 60.0 to the specified address, with the coin selection optimized for keeping assets together.

Fees

The oceand wallet will add transaction fees based on the parameters (minrelaytxfee) specified in the ocean.conf configuration file and the transaction size. If fixedfee is set, then a fixed transaction fee is used, independent of the transaction size - this option can be used for sidechains that employ whitelisting.

The transaction fee in Ocean transactions is specified explicitly, by paying an amount to an output with an empty scriptPubKey. This means that in Ocean transactions, the inputs amounts of each asset must equal exactly the output amounts of each asset (i.e. all assets are conserved). This is in contrast to Bitcoin where the difference between the input and output amounts is taken as the transaction fee.

By default, the transaction fee can be paid in any token type (but only one, and with a single output).

Transactions

Ocean transactions have a similar serialization format to Bitcoin transactions but with some additional flags and 32-byte asset ID labels for each output. All cryptographic algorithms (i.e. SHA256, secp256k1), signature formats (DER encoding), scriptSig and scriptPubKey formats and SigHash types and flags are identical to Bitcoin.

Raw transactions can be created using the RPCs createrawtransaction (if each asset ID is sent to a separate address) or createrawtxoutputs (if the specification of individual outputs is required). These raw transactions can then be signed using signrawtransaction with either wallet or WIF keys supplied as arguments, and then broadcast with sendrawtransaction as with bitcoind.

For a given transaction ID, the deserialized transaction can be retrieved with the following RPC:

./oceand -datadir=path getrawtransaction 1c606ab1490c4111bc0cc79af559b3566eb104f0f81f783d63911087d789ffae true

This will return the JSON encoded deserialized transaction. e.g.

{
  "hex": "0200000000013b60b9276d9e1d6fbeb9d580057f40a63a3d1209b663960e28c96a2898f601ca010000006b483045022100a3b1a25644a671c4cd6248f83fb3ca896778f7e68cade4539816090ba67c0c1802200735eab82b2a12c3093a12f7a1c857112ff933158f5c3194e4ba7d2b340cc685012102faf9a07437dada1a60651ef194031ffa01bba65082a593d672895949a4c90451feffffff0301230f4f5d4b7c6fa845806ee4f67713459e1b69e8e60fcee2e4940c7a0d5de1b201000009184e72855c001976a914668f07ad957d44271fc563c60fddda292bab9c4088ac01230f4f5d4b7c6fa845806ee4f67713459e1b69e8e60fcee2e4940c7a0d5de1b20100001b48eb57e000001976a9145b92412ad76ea5344f22d0a4ff8742a9b212aeef88ac01230f4f5d4b7c6fa845806ee4f67713459e1b69e8e60fcee2e4940c7a0d5de1b2010000000000001aa400006f000000",
  "txid": "1c606ab1490c4111bc0cc79af559b3566eb104f0f81f783d63911087d789ffae",
  "hash": "1c606ab1490c4111bc0cc79af559b3566eb104f0f81f783d63911087d789ffae",
  "withash": "ab3393f4fb64685a4de07ac89c6903d6a0ba107c87fff33c9a981a7590bae48e",
  "size": 341,
  "vsize": 341,
  "version": 2,
  "locktime": 111,
  "vin": [
    {
      "txid": "ca01f698286ac9280e9663b609123d3aa6407f0580d5b9be6f1d9e6d27b9603b",
      "vout": 1,
      "scriptSig": {
        "asm": "3045022100a3b1a25644a671c4cd6248f83fb3ca896778f7e68cade4539816090ba67c0c1802200735eab82b2a12c3093a12f7a1c857112ff933158f5c3194e4ba7d2b340cc685[ALL] 02faf9a07437dada1a60651ef194031ffa01bba65082a593d672895949a4c90451",
        "hex": "483045022100a3b1a25644a671c4cd6248f83fb3ca896778f7e68cade4539816090ba67c0c1802200735eab82b2a12c3093a12f7a1c857112ff933158f5c3194e4ba7d2b340cc685012102faf9a07437dada1a60651ef194031ffa01bba65082a593d672895949a4c90451"
      },
      "is_pegin": false,
      "sequence": 4294967294
    }
  ],
  "vout": [
    {
      "value": 99999.99993180,
      "asset": "b2e15d0d7a0c94e4e2ce0fe6e8691b9e451377f6e46e8045a86f7c4b5d4f0f23",
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 668f07ad957d44271fc563c60fddda292bab9c40 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a914668f07ad957d44271fc563c60fddda292bab9c4088ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "2din2ez1HuAQ2bSGuiGRyhvMrTCnwweMxR3"
        ]
      }
    },
    {
      "value": 300000.00000000,
      "asset": "b2e15d0d7a0c94e4e2ce0fe6e8691b9e451377f6e46e8045a86f7c4b5d4f0f23",
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 5b92412ad76ea5344f22d0a4ff8742a9b212aeef OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a9145b92412ad76ea5344f22d0a4ff8742a9b212aeef88ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "2dhmw5vLW7VqiUhE4UpbAKERcJhZnMLUZJZ"
        ]
      }
    },
    {
      "value": 0.00006820,
      "asset": "b2e15d0d7a0c94e4e2ce0fe6e8691b9e451377f6e46e8045a86f7c4b5d4f0f23",
      "n": 2,
      "scriptPubKey": {
        "asm": "",
        "hex": "",
        "type": "fee"
      }
    }
  ]
}

This is similar to a deserialized Bitcoin transaction, except that each output also has an asset field for the asset ID.

Serialization

CommerceBlock maintains several libraries for wallet tools that include transaction building, serialization and signing for different platforms.

These include:

  • oceanjs A Javascript library for node.js and browsers.
  • oceanj A Java library for APK.

The above raw transaction (hex) serialization is broken down with the following labeling:

02000000  # version
00   #flag
01   # number of vins
3b60b9276d9e1d6fbeb9d580057f40a63a3d1209b663960e28c96a2898f601ca   #vin[0] txid
01000000   #vin[0] previous index (vout)
6b 483045022100a3b1a25644a671c4cd6248f83fb3ca896778f7e68cade4539816090ba67c0c1802200735eab82b2a12c3093a12f7a1c857112ff933158f5c3194e4ba7d2b340cc685012102faf9a07437dada1a60651ef194031ffa01bba65082a593d672895949a4c90451   # scriptSig
feffffff   # sequence
03   # number of outputs
01 230f4f5d4b7c6fa845806ee4f67713459e1b69e8e60fcee2e4940c7a0d5de1b2   #output[0] asset ID
01   # value flag
000009184e72855c   #output[0] value
00   # nonce
19 76a914668f07ad957d44271fc563c60fddda292bab9c4088ac   #scriptPubKey
01 230f4f5d4b7c6fa845806ee4f67713459e1b69e8e60fcee2e4940c7a0d5de1b2   #output[1] asset ID
01   # value flag
00001b48eb57e000   #output[1] value
00   # nonce
19 76a9145b92412ad76ea5344f22d0a4ff8742a9b212aeef88ac   #scriptPubKey
01 230f4f5d4b7c6fa845806ee4f67713459e1b69e8e60fcee2e4940c7a0d5de1b2   #output[2] asset ID
01
0000000000001aa4   #output[2] value (tx fee)
00   # nonce
00   #scriptPubKey (empty for tx fee output)
6f000000    #locktime