State of the Layer: All Hands – Dec 20 2016

  • Craig
    1. Updates for Omni port
    2. Omniwallet fixes for null recipient
    3. DEx volume and automation
    4. DEx tutorial
    5. UIT protocol enhancements
    6. Core.ID discussion / protocol needs
  • Adam
    1. Omniwallet
      1. Continuing to handle support and feedback from launch
      2. Working on fixes for dex 1.0 interface
  • Patrick
    1. Evaluating HTML 5 app design for making multisig easy
    2. Editing on multisig article
    3. Spec draft for futures and options WIP
    4. Business development Re: US stocks transferable between brokerage accounts and blockchain tokens
  • Marv
    1. Omniwallet
      1. User support
  • Zathras
      1. Fixed several API issues preventing successful completion of automated testing (thanks @Sean)
      2. Investigating OE outage caused by Omni Core crash on failed page allocation
    2. Omni Core
      1. Initial works on Omni Core port
      2. Performing further review & tests on fee system
  • Sean
    1. Jenkins CI
      1. Found and helped resolve Omniwallet issue with send-to-self
      2. Updated to use (new URL and API) in tests
      3. Configured to build both stable and integration branches of Omni Core
        1. master branch is built by omnicore-stable job
        2. develop branch is built by omnicore-integration job
        3. Consensus Tests and RegTest Integration Tests run against both builds.
    2. OmniJ
      1. OmniChest classes now use OmniExplorer URL/APIs (may be renamed in future)
      2. Improvements to error handling in Omniwallet client
      3. Still working on multi-address query API update
  • Judith
    • Ongoing Communication with projects

State of the Layer: All Hands – Dec 13 2016

State of the Layer: All Hands – Dec 20 2016

State of the Layer: All Hands – Dec 13 2016

State of the Layer: All Hands – Dec 06 2016

State of the Layer: All Hands – Dec 13 2016

Multisignature Addresses and Omni


The recommended way to do a managed smart property issuance is through a multisignature address. Also, long-term storage of assets held on an institutional level, and institutional operations such as payroll management, may also benefit from using multisignature addresses. Most importantly, exchanges integrating the Omni Layer protocol can manage risk with one central multisignature address, or preferably, a series of rolled multisignature addresses.

The protocol does not currently support sending to multiple addresses in a single transaction, this is a feature we’d like to develop. Creating transactions that fulfill customer withdrawals as secondary outputs is not yet possible, so a combination strategy of hot wallets and multisignature repository wallets is recommended for doing a large number of send transactions, for now. For example, an exchange could keep 10% of the assets in a hot wallet that the server controls for fast withdrawals and then re-fill it on a daily basis.

It’s also possible to create applications that make the below illustrated process much easier, and even facilitate exciting uses like market places for real goods, with paid arbitrators available to settle disputes with a 3rd key.

First, one must safely generate and store private keys and their corresponding public keys. The best way to do this is install Linux on a formatted USB, drop a download of Omnicore on the same USB, wipe a hard drive, and boot from the USB. Load up Omnicore (or Bitcoin Core, for this purpose, it’s the same) and go to Help -> Debug -> Console. Then type:


Copy the address and paste it in front of the following command:

validateaddress <address>

The pubkey will be displayed, write it down, it’s in Hex (base 16) so your hand might get a cramp. Pasting it into an email and having a copy in the cloud is acceptable since pubkeys are not a security vulnerability, and are actually meant to be shared. The other board members or team members, or your accountant, or your spouse, or whomever is going to follow these steps on their own to generate their own private key, will have to share their pubkeys with you in order to generate the multisig address.

Now the very important part:

dumpprivkey <address>

Like it says on the tin, this will dump the private key for that address (though it only works if you’ve generated the address locally and it’s saved in that local client).

It’s very important that the privkey is written down on paper, make sure your hand-writing isn’t too bad, that characters that might be confused for another are marked.

Now it’s time to generate the multisignature address, let’s say you want to create a 2-of-3 address, you’ll do this by specifying the number of signatures needed (2) and listing an array of pubkeys:

 omnicore-cli createmultisigaddress 2 '["0232b7c756b51c8ad37fa63929d119b118af54598c8a0f1ab8f1966704e4cbff96",

The createmultisigaddress call will return the new address and the redeem script, which like the pubkey, is very long, annoying to physically write down, and not a security risk to share, but necessary to complete transactions. It can be copied to a digital back-up and shared in emails.

It’s essential that you fund the new address you just created with some bitcoin, it can be a very small amount, but no less than .005 is recommended. Check your transaction hash when you send, you’ll need it later.

Now the most technically complex part: preparing a transaction to be signed. There are a series of RPC calls that begin with “omni_createpayload_”and then are followed by the name of an existing transaction, for example “omni_createpayload_simplesend”, “omni_createpayload_trade”, and “omni_createpayload_issuancemanaged” – the full list can be found here.

Issuance of a managed smart property is one of the more parameter-intensive transaction types, here is a list:


Name Type Presence Description
ecosystem number required the ecosystem to create the tokens in (1 for main ecosystem, 2 for test ecosystem)
type number required the type of the tokens to create: (1 for indivisible tokens, 2 for divisible tokens)
previousid number required an identifier of a predecessor token (use 0 for new tokens)
category string required a category for the new tokens (can be “”)
subcategory string required a subcategory for the new tokens (can be “”)
name string required the name of the new tokens to create
url string required an URL for further information about the new tokens (can be “”)
data string required a description for the new tokens (can be “”)

omnicore-cli omni_createpayload_issuancemanaged 1 2 0 “” “” “myTokens” “” “Experimental multisig tokens.”

Very important note, OP_Return only allows 80 bytes of data, 4 of which are consumed by the omni market, so your hex payload must be less than 152 characters long (76 bytes), the categories parameters are not worth the text, just name your asset, include the URL and come up with a very succinct 3-5 word description. Longer strings will fail to modify the transaction.

The resulting hex is what would go into the OP_Return of a Bitcoin protocol transaction that would effectively make it an Omni Layer transaction.

We must also create the components of a bitcoin transaction as if we weren’t creating an Omni transaction, with an added bonus of inserting the payload you just create as an OP_Return, and after that we’ll have a proper transaction hex to sign.

The steps:

omni_createrawtx_input, then add the payload via
omni_createrawtx_opreturn, then add the reference  address via
omni_createrawtx_reference, and finally add the change address with

Now step by step with parameters:

omnicore-cli “omni_createrawtx_input” “<raw tx hex to modify, we’re creating a new one, but it’s necessary to put in the quotes and leave it blank>” “<the transaction id of the bitcoin you sent to fund the address earlier>” <the vout position of the output that this input transaction is providing to fund mining fees – an integer, usually 0 or 1, you can tell what integer by looking at the transaction on, the 0 position output is listed fist, then the 1 output, then the 2 output and so on>

Now copy the hex that was just emitted, as well as the Omni Layer transaction payload you created two steps ago, as parameters for the next step:

omnicore-cli “omni_createrawtx_opreturn” “<modified transaction you just got from the createrawtx_input>” “<hash that is the payload of the Omni transaction you want to put into the OP_return>”

You’ll get another modified hex representing the new data, now copy that and your multisig address as parameters:

omnicore-cli “omni_createrawtx_reference” “<the most recent transaction hex you want to build-up>” “<address to send to>”

Note that your reference address is only the address you’re sending from if you’re doing an issuance, usually this is the address you want to send tokens to. If you’re doing a grant or issuance, this step can be omitted.

Now finally, we’ll take the resulting transaction hex and add a change address (change as in “spare some change?” not as in “we want change”), which will also be the address you’re transacting from, so any bitcoin not used in the fee will end up on the same address.

omnicore-cli “omni_createrawtx_change” “<latest version of the hex for this transaction you’re building>” “[{\’txid\’: \'<id of input transaction that funded the address>\’,\’vout\’:<0 if the input you’re spending is first among inputs, 1 if second, ect. – an integer>,\’scriptPubKey\’:\'<3039a5ee506a381271c1a8974eda16457838f249 – should look like this, click the “Scripts and Coinbase” link under “Inputs and Output”in the tx view of and scroll down to the hex ouput corresponding to the output you’ve chosen to spend>\’,\’value\’:<BTC spent in output, an 8 decimal place floating point number, must equal the whole output chosen by vout from the input tx>\’},<other JSON objects representing other input transactions used, where applicable>]” “<your address to receive the change, same as in the previous action>” 0.00035

The last parameter is an integer for the miner fee paid.

One tricky thing about this step the JSON has to have “\” in front of every ” or ‘ used in the JSON part, but other JSON sections in, for example, the signrawtransaction call, don’t require this. Just a quirk of the design of the RPCs. If you don’t use the \’s you’ll get an “Error parsing JSON:” response.

Here’s a really clear example:

 ./omnicore-cli omni_createrawtx_change “0100000001cde12afc42d31cf0dc70ffdda31f11d470d45407790fc487e478223a249228fa0000000000ffffffff031ef579120000000017a314a6eb127dfb988196197f8e2aa1353974b66a2s648700000000000000001b6a14ef7d6e69000000000000007600000006c7c12e10aa0a0000000000001976a0b3e8cab9b8383e121f2dbf77be8fc79″[{\”txid\”: \”b13e92243a22783485c407780724d170d313cfa3ddff70dcf01cd342fc2ae1c\”,\”vout\”:0,\”scriptPubKey\”: \”b264a9ed243dfb686126127e8d1cb1356281d26a278487\”,\”value \”:0.749}]” “3QSYoxGXw5sfHLzMMSsDUgdW45G2W7M8sM2” 0.00025

There are extra spaces separating : and \ so the blog doesn’t show a :\ emoticon, remove those in practice.

And now we have a valid transaction to broadcast. Share the hex with your co-signers. They can copy it in along with their private keys using this command:

$ omnicore-cli signrawtransaction "0100000001e006a9...f16c9f4af17f8700000000" 

These parameters are: the transaction hex, a JSON including similar information as the change address call above, but including the redeem script shown when you generated the multisig (which can be saved digitally, as its compromise can’t really be used to compromise the address, but which is necessary to sign transactions on a multisig address). And finally, the private key. Note that the \’ required above is not required for the JSON here, just one of those things. Finally, use the pubkey prefixed with OP_HASH160 bytes and suffixed with OP_EQUAL byte.  This is the script to redeem that output and is what you use in the transaction. You can get it by decoding the transaction:

 ./omnicore-cli decoderawtransaction "0100000001cde12afc42d31cf0dc70ffdda31f11d470d45407790fc487e478223a249228fa0000000000ffffffff031ef558160000000017a914a9eb247dfb988196197f8e2aa1353974b66a2784870000000000000000166a146f6d6e69000000000000007600000006c7c12e10aa0a0000000000001976a914e8fab7b8383e121f2dbf77be8fc79effec252e7688ac00000000"
 "txid" : "5bef1c94f072317bc14201273eaf1f17a60ca4c97d5586b35333dc7b327b05c6",
 "version" : 1,
 "locktime" : 0,
 "vin" : [
 "txid" : "b13e92243a22783485c407780724d170d313cfa3ddff70dcf01cd342fc2ae1cd",
 "vout" : 0,
 "scriptSig" : {
 "asm" : "",
 "hex" : ""
 "sequence" : 4294967295
 "vout" : [
 "value" : 0.749,
 "n" : 0,
 "scriptPubKey" : {
 "asm" : "OP_HASH160 a9eb247dfb988196197f8e2aa1353974b66a2784 OP_EQUAL",
---> "hex" : "b264a9ed243dfb686126127e8d1cb1356281d26a278487",
 "reqSigs" : 1,
 "type" : "scripthash",
 "addresses" : [
 "value" : 0.00000000,
 "n" : 1,
 "scriptPubKey" : {
 "asm" : "OP_RETURN 6f6d6e69000000000000007600000006c7c12e10",
 "hex" : "6a146f6d6e69000000000000007600000006c7c12e10",
 "type" : "nulldata"
 "value" : 0.00002730,
 "n" : 2,
 "scriptPubKey" : {
 "asm" : "OP_DUP OP_HASH160 e8fab7b8383e121f2dbf77be8fc79effec252e76 OP_EQUALVERIFY OP_CHECKSIG",
 "hex" : "62b63ee8fab7b8383e121f2dbf77be8fe19effec252e7688ac",
 "reqSigs" : 1,
 "type" : "pubkeyhash",
 "addresses" : [

That arrow in the middle of the above block quote shows you where to find the hex you need to properly sign. The one at the bottom is what you’d need to use to sign a successor transaction that takes the output you’re about to produce as an input.

The result will be transaction you can copy and email to your other co-signers to continue signing. You’ll get a message suggesting an error and see “complete: false” but don’t let this fool, you, that means you did it right. Once the transaction has enough signatures, it will show an output where “complete:true”.

But before you sign that last transaction, make sure it’s something you’d want to sign with a special version of the decode call:

./omnicore-cli omni_decodetransaction “0100000001cde12afc42d31cf0dc70ffdda31f11d470d45407790fc487e478223a249228fa0000000000ffffffff031ef579120000000017a314a6eb127dfb988196197f8e2aa1353974b66a2s648700000000000000001b6a14ef7d6e69000000000000007600000006c7c12e10aa0a0000000000001976a0b3e8cab9b8383e121f2dbf77be8fc79effec252e7688ac00000000”

“txid” : “8cda8e91f973717b317426292d8c1637360c12c97d5586b35333dc7b327b05c6”,
“fee” : “0.00025000”,
“sendingaddress” : “3QSYoxGXw5sfHLzMMSsDUgdW45G2W7M8sM2”,
“referenceaddress” : “1J2P7J6yAkPOpVsanJSHx4RrhZqd1fc8dn”,
“ismine” : false,
“version” : 0,
“type_int” : 0,
“type” : “Simple Send”,
“propertyid” : 118,
“divisible” : true,
“amount” : “291.21130000”,
“confirmations” : 0

Once you’re sure you’re good on signing, follow the steps linked above and when complete:true is the result, you can take the resulting hex and do this:

omnicore-cli sendrawtransaction  “<completed, signed transaction hex>”

If you get an “insufficient priority” error, this is because your miner’s fee is not large enough.

Also note, the Bitcoin Core RPC “createrawtransaction” will make your fee the different between the input and the output, it doesn’t have all the steps involved here so by default just that call won’t include a change address, so if you try to send 1 bitcoin from an address containing 10, you’ll pay a miner’s fee of 9 BTC and have a bad time.


The output from sending the raw transaction, assuming no errors occur due to lack of sufficient signatures or fee, will be a transaction id that you’re used to seeing, copy it into a and or and you’ll see the transaction out in the wild, pending confirmation.

For periodic business operations, weekly or monthly, this is a somewhat tedious process, but once you get the hang of it and have the commands in your SSH history, it’ll be easy. Except, for security reasons you must scrub your bash history after using a private key in the signing transaction, more on that here. It’s considered good security practice to create a new multisignature address prior to using your private keys on the old one, and periodically port funds and control of a smart property to it, limiting the possibility of a compromise over time for a highly re-used set of private keys.

Just to spell it all out, here’s that transaction:


Change the issuer on record of the given tokens.


Name Type Presence Description
fromaddress string required the address associated with the tokens
toaddress string required the address to transfer administrative control to
propertyid number required the identifier of the tokens


"hash"  // (string) the hex-encoded transaction hash


$ omnicore-cli "omni_sendchangeissuer" \
    "1ARjWDkZ7kT9fwjPrjcQyvbXDkEySzKHwu" "3HTHRxu3aSDV4deakjC7VmsiUp7c6dfbvs" 3

It’s possible for co-signers to write down a private key (and it’s important that they do it well, without ambiguity of upper or lower case in their long-hand, maybe a typewriter would be useful) and rarely use it, and for the administrator to use those pubkeys over and over while generating a new key and address each operations cycle.

It’s worth it to take more time generating keys in an air-gap and signing transactions in the same environment, reduces the risk profile to a physical compromise only. Every layer involved is a potential attack vector, which is why the best way to sign a transaction is in an unsync’ed Omnicore QT instance (Help->Debug->Console) on a Linux device that is clean-booted from a recently formatted USB stick and never used to access the internet.

People talk about air-gaping like it’s hard, but the hardest part is simply allocating a device for it, which should be a trivial line item for a serious operation. Different organizations will find different balances of compromise. Probably the best trade-off would be having a script that takes one private key as a parameter, pasted in fresh before the script runs, to prepare and partially-sign the relevant transactions and output a JSON object listing them along with their decoded parameters, and have it auto-email the CFO or accountant, who then saves it to a .txt file, carries it to the air-gap device on a USB stick, and then copies the long transaction hexes in while signing them manually. Maybe manually decode them again before signing to check for possible man-in-the-middle attacks. Then take a .txt file of those signed transactions, or maybe a .json file, bring it over to the internet-connected computer on the USB stick, and either email it back or submit it to a server to run another script that tries a sendrawtransaction call for each transaction. Hacking your operation should be as challenging as the famous sequence in the first Mission:Impossible film.

No exchange that requires multiple manual signatures to move assets has yet been hacked.

If you’re new to server management, see this tutorial.

Multisignature Addresses and Omni

Setting Up Omni Core on a Server

I’ve had to set up different versions of Omni Core on servers over the last year, here’s a short-cut reference for those trying to get started with algorithmic trading over the DEx, or trying to do managed smart properties and apps.

Open your bash shell and copy this into the command line:

wget -O omnicore-

Then unpack the tarball:

tar -zxvf omnicore-

Then go to the directory you just installed to:

cd omnicore-

Almost there, before we fire up omnicored, it’s essential to create a configuration file for bitcoin at root/.bitcoin/bitcoin.conf and set the following parameters:


Note: if you don’t intuitively know your way around a server, try a program like BitVise to shell in, it comes with an FTP client that loads up after logging into the bash shell terminal, and makes navigation and manipulation of files as easy as doing so in your local operating system.

txindex is essential to running Omni Core at all, when you try this process using the QT downloadable client a restart with txindex=1 is prompted, here we are doing it ourselves.

logtimestamps gets the logfile that should be included in the same folder as bitcoin.conf to track all transactions, you can omit this if you prefer.

server = 1 means you can skip including the -server flag that runs omnicored to listen for remote-procedure calls.

rpcuser = <enter your on user name here>

rpcpass = <enter your own password here>

allowip = <enter the ip of the server you’ll be using to run remote procedure calls on this node>

allowip gives some security to your operation by limiting mis-use of your node and any privatekey saved in it to a breach of the server ip specified, be sure to use pubkey encryption on your server.

Note: if you are going to run your code that does RPCs with Omnicore on the same sever, you can enter for localhost.

Now we can run omnicored, if we hadn’t added the config entries, we’d want to add the -daemon and -server tags so it runs in the background and listens for RPCs:

./omnicored -daemon -server

Now wait patiently for a few days while the client proceeds to sync the Bitcoin blockchain. On a virtual private server or cloud-based instance, the incoming connections should be open by default and thus, the process shouldn’t take more than 2-3 days. If things take too long check your omnicore.log file in the .bitcoin folder to see time-stamps on each block coming in and get an idea of the progress, and if it’s going more slowly than 1 recent block per 10-20 seconds, make sure your server ports are open for incoming traffic.

Once your node has caught up with the blockchain, you can start working it from the command line or using RPCs via software packages like OmniTrade.js

For those who are new to server-based scripts, Cloud 9 is a free development environment that runs from your browser.

Finally, hosting a blockchain node requires a huge data foot-print, and most VPS providers simply don’t design their packages around hard drive space. However there is one that allows you to rent a 160 GB VPS that can host the blockchain for at least the next year, for an annual payment of <72 EUR. Now you may be wondering, is it secure to have a lot of funds on addresses controlled by a private key generated and saved inside a server?

The answer is no. Which is why the next tutorial is on multi-signature address management.



Setting Up Omni Core on a Server

State of the Layer: All Hands – Dec 06 2016

  • Craig
    1. Automated DEx trading
    2. Next releases
  • Adam
    1. Omniwallet
      1. OmniDex Interface launched
      2. Continuing to handle support and feedback from launch
  • Patrick
    1. Trying to test btc spend and fail-safing of Dex trading system
    2. Finishing email automation tool for fulfilling orders of a product through a website (vending machine w/ some KYC)
    3. Final Omniwallet testing last week
    4. Futures contract interviews
    5. Feedback on making Dex phase one open to non-OMNI pairs
    6. Design to automate Dex phase one trading in Omniwallet
  • Marv
    1. Omniwallet
      1. OmniDex launch
      2. Monitoring support
    2. OmniExplorer
      1. Reporting bugs & feature requests
  • dexx
    1. Fixed Travis CI configuration for 0.13 port
    2. Hosted Mac OS X SDK for Travis CI on AWS S3
    3. Fixed restoring of default minRelayTxFee in unit tests, so random test order also works
    4. Bumped version of 0.13 port version to 0.1.99, and updated related tests
  • Zathras
    1. Omni Explorer:
      1. Fixed a crash in MetaDEx market page when the total amount of available tokens overflows an unsigned 32-bit integer (thanks for report Marv!)
      2. Fixed an issue where cancelled trades with no matches would show as 100% sold (thanks for report Marv!)
      3. Working on engine logic problem that results in matched trades being recorded in multiple iterations (causing duplicates) (thanks for report Marv!)
    2. Omni Core:
      1. Working on optimizations, achieved target of sub-10 minute parsing!  Improvements include:
        1. For Class B, only prepare an equivalent number of SHA256 hashes to the packet count (rather than MAX_SHA256_OBFUSCATION_TIMES each transaction)
        2. No longer recalculate fee distribution thresholds every block, only when smart property token counts change (eg grant or issuance)
        3. Skip iterating the vector of checkpoints unless we’re actually in a block that is %10000.
        4. Fix the MAX_SEED_BLOCK const that was causing seed blocks >390K to be ignored
        5. Skip actually fetching a property from the SP database when we need to check if it exists (property ID’s are sequential so existence can be inferred from peeking next available property ID)
        6. Wallet cache improvements
        7. Migrate the tally map from std::map to std::unordered_map (this is actually slower at the beginning when we only have a small number of elements, but by about block 300,000 the hashtable lookup of unordered_map starts to see substantial improvements over std::map).
        8. Don’t bother iterating over the outputs again in HandleExodusPurchase if we’re past the Exodus crowdsale & on mainnet
        9. Added model to drop non-Omni transactions faster by comparing bytes in scriptPubKey looking for marker bytes and only examining interesting transactions more closely
  • Sean
    1. OmniPortfolio 0.1.2 coming this week
      1. Update to OmniJ 0.5.0
      2. Use Omniwallet address array balance query (using Omniwallet staging server)
  • Judith
    • Ongoing Communication with projects

State of the Layer: All Hands – Nov 22 2016

State of the Layer: All Hands – Dec 06 2016

Omniwallet Updates, OmniDex Trading Interface Launched


Just in time for the Holidays Omniwallet is pleased to present several updates, overhauls and the OmniDex. The OmniDex interface ties in with the recently activated functionality on the Omni Protocol and now allows a completely decentralized interface for users to Trade Any Omni Issued Asset for any other Omni Issued Asset.

User Offers are automatically matched against any existing open offer at the corresponding rate. Additionally, if you don’t see an offer for a pair you want to sell/buy you can open the new market just as easily by placing the first offer for that pair.

Getting started is as simple as navigating to the ‘Exchange’->’OmniDex’ tab in the interface: 1-overview

From there you’ll be presented with the option to choose your preferred ‘Market Currency’ and then the existing Markets with open offers will be displayed. A full Getting Started Guide has been added to the knowledge base/wiki.

Additional updates and changes include fee estimation, simplified fee configuration, updated and improved websocket library/feeds, auto websocket reconnection and resubscription (No more stale data when something restarts), improved balance feeds, and misc some bug fixes.

So get out there and start placing your Offers!

Omniwallet Updates, OmniDex Trading Interface Launched