Overview of Blockchain Technologies

This spreadsheet is a work in progress, comments are welcome here, which describes the features of multiple blockchain and sidechain technologies. Views about blockchain technologies range from hype to skepticism. A blockchain is a distributed database and consensus network that can be used to validate cryptocurrency transactions. Blockchains do not replace conventional databases, instead they create consensus protocols between untrusted parties on what information needs to be appended to a shared database. This obviates or reduces the need for trusted third parties in financial agreements.

Below we describe the different types of blockchain players and their features:

Type of player

  • Cryptocurrencies (e.g. Bitcoin, the first cryptocurrency in history)
  • Blockchain platforms (e.g. Ethereum, a platform that has its own cryptocurrency)
  • Sidechains (e.g. Rootstock, a sidechain which provides smart contracts for Bitcoin)
  • Distributed ledgers/private blockchains (e.g. R3 develops blockchains for the financial industry)

Market capitalization

Market capitalization is a meaningful indicator of the importance and power of a blockchain player. Bitcoin is the biggest player with a market capitalization of approximately 10 billion dollars, followed by Ethereum with around 1 billion dollars (as of July 2016). This can change quickly, because it’s a young and therefore unpredictable market.

Liquidity

A meaningful indicator for the usability and value of a cryptocurrency is liquidity. Liquidity defines how easily and quickly cryptocurrencies can be purchased or sold without significant loss.

License

Most players have licensed their software as open source. For example Bitcoin is licensed under the MIT free software license.

Asset names, currency symbols and three letter currency codes

Cryptocurrencies and sidechains use unique asset names, currency symbols and three letter currency codes to identify themselves. For example Bitcoin, which is also the asset name, uses ฿ as its currency symbol and BTC as its official three letter currency code.

Public and private

Public blockchains are available to the general public, while private blockchains are restricted to clients and internals of banks or other institutions.

Identity

Identity protection and privacy may be important to users and traders to safeguard their business strategies, while identifying users may be important to criminal and tax institutions. There are different levels of protection:

  • anonymous (traders or users cannot be identified by anyone)
  • pseudonymous (traders or users can be identified only by blockchain intelligence and network traffic analysis)
  • private (traders or users identities are only known to the organization running the blockchain or platform)
  • transparent (traders and users identities are known to everyone)

Consensus methods

Consensus methods like Proof of Work or Proof of Stake determine how transactions are validated.

  • In validation by Poof of Work (PoW) the result of an expensive cryptographic calculation is required as proof of the right to vote on consensus.
  • In validation by Proof of Stake (PoS) the amount of voting power for consensus is directly proportional to the shares held. For example, holding 10% shares bestows 10% voting power.

Scripting language, Turing completeness and smart contracts

Many cryptocurrencies have their own scripting languages which can be embedded into transactions. Some languages are Turing complete (e.g. Solidity in Ethereum) and can run any algorithm. This is necessary to run smart contracts which are programs to conduct consensus-enforced contracts between users. Insurance companies could use smart contracts to compensate automatically for crop loss due to hail, for instance. A supply service could use a smart contract to charge on delivery. A more complex example of the use of smart contracts is a DAO (Decentralized Autonomous Organization), a company run by smart contracts rather than by managers. Smart contracts can be used for financial products, property registration, prediction markets, crowdfunding, and other purposes.

Governance, Stakeholders and Conflict of Interests

Governance refers to who decides what happens with a blockchain in terms of software updates: Miners, nodes, users, the core development team, and other stakeholders. Ideological, technical, financial and privacy interests can influence the direction of a cryptocurrency. This can lead to conflicts of interests among the governance and may even cause a cryptocurrency to split and form an Altcoin.

Transaction speed, fees and micropayments

Cryptocurrency transactions should be fast and cheap and even micropayments should be allowed. The proof of stake consensus method allows faster and cheaper transactions, although these are less secure than those which use proof of work. New off-chain methods offer secure, instant micropayments. This is useful when charging for small amounts, like in pay-per-minute video streaming, or pay-per-megabyte data transmission.

Processing power

Processing power costs (CPUs, GPUs, ASICs) are proportional to energy costs. Proof of work tends to require a lot of energy and substantial computer equipment. proof of stake is less expensive.

Security

A variety of attack vectors challenge the security and reliability of a blockchain. Here are some examples: A 51% Attack is when a stakeholder of a Proof of Stake cryptocurrency owns 51% of all shares and abuses his or her majority power to bias consensus to agree on double spending. A Sybil attack is when one node fakes various node identities and gains a voting advantage to bias consensus.

Note: Bitcoin’s security threshold is not 51%, but about 33% due to selfish mining. Ethereum’s security is theoretically 12.5% due to uncle mining. The only PoW blockchain that has 51% security is RSK.

Some Comments on the Security of ECIES with secp256k1

The challenge of modern cryptography is to find efficient but secure encryption schemes. The Elliptic Curve Integrated Encryption Scheme (ECIES) is a widely used encryption scheme which is specified in many standards. It is used for example in Ethereum’s Whisper. While Bitcoin Core does not implement ECIES, it can be employed to send secure messages using Bitcoin keys. Together with the Decentral Jaxx project we contributed with the OpenPGP.js project that follows this approach.

Most encryption schemes rely on the intractability of some variants of the Diffie-Hellman problem. ECIES security assumes, amongst other things, that the hashed decisional Diffie-Hellman problem over the specified elliptic curve is of exponential complexity. Although this problem is easy for a specific class of elliptic curves, the rest can currently only be solved via discrete logarithms. This is in general a harder task which is believed to be of exponential complexity for carefully chosen elliptic curves.

In our paper here we summarize the ECIES scheme and its security when paired with the secp256k1 curve of the SEC Group which is currently used in Ethereum.  (For more information about the complexity of the discrete logarithm problem on elliptic curves please see our previous article: ECDSA Security in Bitcoin and Ethereum: a Research Survey)

Interdependent Transactions in Bitcoin, RSK and Ethereum

A recent paper titled The Blockchain Anomaly presents the difficulties the authors encountered when trying to make two transactions interdependent such that the second transaction cannot be executed without the first being confirmed. Although the paper may be useful as a guide, the title is misleading since Bitcoin does not guarantee the order of transactions (no dependencies between inputs and outputs).

Also, “The Blockchain Anomaly” states that Bitcoin requires six block confirmations to finalize a transaction, but the original Bitcoin paper does not actually stipulate a specific number. In addition, each Bitcoin wallet application can choose which algorithm inform the user that a transaction has been confirmed. In fact, for stronger security, the number of block confirmations should not be constant, but should depend on several factors:

  • Transaction amount (large transactions require more confirmations to prevent double-spending)
  • The properties of other transactions included in competing blocks (such as the presence of bribe fees) during the confirmation interval
  • The properties of other transactions included in the confirmation chain (to detect if these other transactions could be targeted by double-spend attacks which reorganize the blockchain)
  • The state of the network’s hashing power (to detect sudden drops which might indicate the preparation of a parallel secret branch by an attacker)
  • The state of trusted peers (to detect Sybil attacks)

The same happens in Ethereum, users are not obliged to wait exactly 12 block confirmations. . First, let’s try to define the problem more clearly. One formulation might be: “Alice wants to pay to Carol only if Bob pays to Alice first”. As Nakamoto consensus only assures probabilistic settlement, this problem can be easily solved by picking a long enough confirmation time for the Bob/Alice transaction (e.g. 7 days of confirmation blocks). Then if the payment is reverted, the whole platform would be halted as insecure and the Alice/Carol payment will never be confirmed either, so this problem is not very interesting. A more interesting problem would be “Alice wants to pay to Carol as soon as Bob pays Alice”. This problem arises in a number of contexts such as in a crypto asset exchange, spending money right after an investment has been secured, or in fast betting applications, such as SatoshiDice.

Solutions

For Bitcoin, one solution is to create a single transaction that contains both payments, but this requires off-chain coordination that is beyond of the scope of the problem. In addition, this solution will not work if the second payment is governed by a third condition, such as winning the SatoshiDice game. A simpler and more elegant solution is to use the unspent output of the Bob/Alice payment as an input of the Alice/Carol payment. This makes the second payment consensus-dependent on the first, establishing a static dependency. The cost of this solution is near zero: in the worst case it is the transaction fees related to the overhead of the space consumed by one input.

In Ethereum and RSK we cannot link two transactions unless they are created by the same account and contract. When two transactions are created by the same account, the second payment cannot be confirmed without the first because each transaction has an increasing nonce value, and nonce values cannot be skipped. If the payments are created by different accounts, then we can link them with a conditional payment contract. This contract must be created and funded on creation, before the first payment, and it automatically self-destructs afterwards. Here it is:

This contract solves the problem when the conditions of the payment to C (e.g. amount, additional transaction data) are known before the payment to the conditionalPayment1 is executed. If the conditions for payment to C must be decided by Alice after Bob’s payment, then a contract like the following conditionalPayment2 contract is required.

Both conditionalPayment1 and conditionalPayment2 are hard-wired for particular source and destination addresses, but a generic contract can also be created to handle third party conditional payments in a trustless manner. Generic contracts require:

  • An initial transaction to set up the conditional contract.
  • A secure method to send the address of the contract, since he may not know Alice’s address.
  • Two transactions If the payment from Alice to Carol is greater than the payment from Bob to Alice. Alice must fund the contract with additional coins (using fund() or when creating the contract), or split her payment to Carol into two different transactions, one coming from the conditional contract and the other from Alice’s own account.
  • Almost 100 times more gas than two standard transactions. This means that a generic contract is 100 times more expensive.

Both RSK and Ethereum platforms have a special opcode BLOCKHASH that allows a contract to retrieve the hash of one of the previous 256 blocks counting from the block being processed. This opcode is a better way to create dependencies. The underlying idea is that after Bob’s  transaction to Alice has been confirmed, Alice creates a transaction to Carol as an on-the-fly contract that checks the blockchain to make sure Bob’s transaction is there. If it is not, then the contract returns the funds to Alice, and only some minimal gas is consumed.

On-the-fly contracts can also be used to reduce storage costs. When a new contract is created, some setup code given by the creator is called. When programming in Solidity, this setup code is the smart contract constructor (whose name is the same as the contract name). The constructor can perform any operation and self-destruct afterwards , which prevents the smart contract from persisting, and refunds the cost of contract code storage to the creator. This makes Alice’s transaction far cheaper.

The following is an example of a Solidity smart contract based on BLOCKHASH. In Solidity, the BLOCKHASH opcode can be accessed using the block.blockhash() method. Alice must set the blockIndex and blockHash as soon as Bob’s contract has been observed in the blockchain. The blockIndex is the blockchain height of the block that contains Bob’s transaction and blockHash is the block ID or hash.

The cost of executing this contract is only five times the cost of a single transaction.  Re-writing this small contract in RVM/EVM assembler would probably cut that cost in half.

RSK Labs is creating an Ethereum-compatible platform that tries to cover the most common use cases at the lowest possible cost. RSK is working on new opcodes and native contracts to allow transaction dependencies with lower overhead. The RSK virtual machine release 2.0 has a new native contract, IS_TRANSACTION_MEMBER, which receives a block number, a transaction hash and an SPV proof for the transaction trie as arguments and returns “true” if the transaction is included in that block, and “false” otherwise. A similar native contract, IS_LOG_MEMBER, can be used to detect whether a certain log entry has been recorded in the receipt trie. With these native contracts you can, for example, create a contract that pays Carol if Bob pays Alice, but allows the payment from Bot to Alice to be fully independent from the contract. For example, suppose that X is a contract where users vote to elect one of the members as president. When a president is elected, a message stating the elected user account is logged or, some coins are sent to the elected user account. Then, a contract Y can be created that rewards the elected user by sending him coins from contract Y. Contract Y can be called by any user, sending the “proof of winning election” as an SPV proof using IS_LOG_MEMBER/IS_TRANSACTION_MEMBER.

Conclusion

Programmers of smart contracts should pay special attention to transaction dependencies when fast responses are required or when a break in the dependency causes significant monetary loss. Input/output dependencies can be used to easily create guaranteed transaction dependencies in Bitcoin , but special smart contracts are required in RSK and Ethereum. The naïve RSK/Ethereum smart contract which receives a first payment and only afterwards performs a second payment is very expensive in terms of consumed gas. BLOCKHASH can do the same thing at 1/20 of the cost. RSK is working on additional opcodes and native contracts to provide this functionality without the need to specify a new destination address for a new contract for the first payment.

Swagger Specification for Coinbase API v2

Coinbase has official client libraries for Python, Ruby, PHP, Node.js and Java, but what about other languages? Enter Swagger. Swagger is an open-source project which includes an specification for describing APIs in JSON or YAML and tools for generating ready-to-go client libraries in several languages.

Here at CoinFabrik, we have been writing a first draft swagger specification for Coinbase API v2. We’ve got the basics covered for now: Users, Accounts, Addresses and Transactions. If you would like to help expand the scope, make a pull request on the github repository.

Generating a Client Library

The easiest way to generate a client library for your language of choice is to load the swagger.json file into the Swagger Editor and then download it from the “Generate Client” tab. The libraries come with full documentation on how to use them, complete with examples.

This is the full list of languages and frameworks that can be generated right from the Swagger Editor:

Akka ScalaAndroidAsync ScalaClojureC#
C# .NET 2.0DartDynamic HTMLFlashGo
HTMLJavaJavaScriptJavaScript Closure AngularJmeter
Objective-CPerlPHPPythonQT 5 C++
RubyScalaSwiftTizenTypescript Angular
Typescript Node

ECDSA Security in Bitcoin and Ethereum: a Research Survey

Elliptic curve cryptography is becoming more and more popular. One of its main supporters is the cryptocurrency system Bitcoin which uses an elliptic curve scheme for their digital signatures. Smaller key size, a more efficient implementation than the RSA system, and a similar level of security make elliptic curve cryptography an interesting alternative to RSA.

Signatures based on elliptic curves are, mathematically speaking, currently very safe. There are, however, well-known attack strategies available, most prominently Pollard’s rho method, which one should take into account when choosing an elliptic curve. The SEC Group’s curve secp256k1, which is currently used in Bitcoin and Ethereum, has no known mathematical vulnerabilities, although it is more vulnerable to small design flaws than others. A private key has already been successfully extracted with a side-channeling attack and an invalid-curve attack might also be possible.

Those who want a deeper exploration of the security level of the signature scheme used in Bitcoin and Ethereum can read our full survey, complete with references to other articles here.

How to Run Multiple Geth Instances on a Private Ethereum Blockchain

A private ethereum blockchain with multiple geth instances can be run over a network or on the same computer. We will explain how to do both, and also how to solve some common issues.

Configuring genesis.json

We need to create a JSON file, which will represent the genesis block of our private blockchain. This file which we will name “genesis.json” will be used by all of our nodes, and is in fact what determines which chain that we are on.

The gasLimit allows us to execute contracts, and by setting the mining difficulty extra low we can easily create our own ethers. If you have several computers on a network, copy this file so all of them have the same genesis.json.

Launching Geth

Each geth instance should be run with the following parameters:

geth –genesis <path to genesis.json> –networkid 321 –nodiscover –datadir <path to empty folder> –port 30304 console

What all the instances will have in common is the genesis path and the network identification. The nodes will only attempt to connect to other nodes with the same network identification, but we are also adding a –nodiscover flag to avoid accidentally connecting to nodes outside our network.

Each node will have a different data directory where the blocks data is stored and, if running on the same computer, also a different port. So if you plan on launching several instances on the same computer, you will need an empty folder to be used for each of the nodes.

Windows

If you are running multiple geth instances on a Windows computer, add the flag –ipcdisable, to avoid “Error String IPC: Access is denied”. If you do not want to disable IPC, pick a different IPC path for each node with the flag –ipcpath <path> . The default path is “\\.\pipe\geth.ipc”, so name the second node something else (e.g. “\\.\pipe\geth2.ipc”).

Connecting Geth Nodes to Each Other

In order to explicitly connect one geth node to another, we need its URL. To get it, type the following into a running geth console:

admin.nodeInfo.NodeUrl admin.nodeInfo.enode

It will return something like:

“enode://702de1918184581815e1a00e63d849524cb4126b9b5886090eabd4d4b5dc6f24c4198249775df30f835b1bfbc9a9733c014b27a99008043f3274c22e49db6fca@[::]:30304?discport=0”

The node URL includes a public key, an IP, and a port.

If you are on Windows, you may need to replace the IP part of the enode URL (after the @), with your IP. If both instances are running on the same computer, the IP would be 127.0.0.1, and the URL would be:

“enode://702de1918184581815e1a00e63d849524cb4126b9b5886090eabd4d4b5dc6f24c4198249775df30f835b1bfbc9a9733c014b27a99008043f3274c22e49db6fca@127.0.0.1:30304?discport=0”

Now, on a different geth instance console, type:

admin.addPeer(<enode of first geth>)

To check that indeed the nodes are connected to each other, type web3.net.peerCount in either of them. You
should get “1” as a result.

You can connect as many nodes as you want. Happy testing!

Extra Resources

Check out the the chapter Testing contracts and transactions, about creating accounts and mining in the book Ethereum Frontier Guide, and check Adrian Duke’s guide for pre-seeding accounts using allocation.

Independently Generating Your Private Key for Coinkite

In How to Use Coinkite’s Multi-Signature Wallets with Bitcore we explained how to create a multisignature wallet on Coinkite and cosign it with Bitcore. We used Coinkite’s offline tool to generate a key pair. Although it is easier to use Coinkite to generate the private key, it is a good security practice to generate it independently. Below, we explain how to do this with Bitcore.

In the following dialog choose “Import Key” and you will see the “Import Extended Pubkey” dialog:

multi-signature-key-creation

import-extended-pubkey

Separately, we will have to generate the key and signature with Bitcore and its add-on library Bitcore Message:

This is a sample output:
xprivkey: tprv8ZgxMBicQKsPdhaer1ZSHH2ZU6CbPforhVuVAn6qUgxfdMNLLGRTGM33N5CaSEoLmoB5kZF9w5dXBz12j3WXyTvBMgqap1xwM28gJyooATU
xpubkey: tpubD6NzVbkrYhZ4XAcSjfE2gggg37iXYzzmGoWGTJ98txm4Tqd6xfF3SqeuYCkMNsAKy9hnyJimaMo8FoHkg4DmTpUF4B85nnLfKAWzgq11TJB
Signature for message "Coinkite": H2uhiyw4+FQWRx4mniYVAvPZ+pl7Wmur/IvYOOjAARuFUy9HTXoy6s3J9k7M9QKbCh9GQbPupuNTzjK43ZJZh6U=

With this, you can submit the xpubkey and signature to Coinkite, and store the xprivkey safely on your end.

How to Use Coinkite’s Multi-Signature Wallets with Bitcore (Beginner Friendly Article)

The Bitcoin community has been talking about multi-signature wallets for years. However, it is still very difficult for end users to use these wallets. Multi-signature wallets should allow copayers to communicate, but there is no standard protocol for seamless communication between copayers. The Bitcoin community should standardize the communication process.

We’re going to learn to use a 2-of-3 multisignature wallet with Coinkite’s API and Bitcore. One cosigner will use a Coinkite account, and the other will use the Bitcore library in NodeJS.

Setting Up Your Coinkite Multi-Signature Wallet

First we need to create a multi-signature wallet on Coinkite. Select “Multisig vault” on the Coinkite wallet page.

create-multi-signature-wallet-on-coinkite

Enter an account name and select “Bitcoin Testnet” as currency.

new-shared-account

Choose 2-of-3 (the default value).

setup-account

Now it’s time to configure each cosigner. For the first cosigner, select “Simple”. This cosigner will be controlled by Coinkite, so we name it “Coinkite”.

key-generation

For the second cosigner, select “Generate Key”. Go through the process until you see the screen below. Securely store the “HD Wallet” part. Next, click “Upload to Coinkite”.

private-key

Rename the second cosigner “Bitcore”.

Each of the three cosigners in a 2-of-3 wallet has a private key, however, since two cosigners are sufficient, we will use the third cosigner’s key as a backup. Choose “Passphrase” or “Generate key” and name the third cosigner “Backup”.

copayer-status

Click “Create Shared Account”, accept the warning, and your multisig wallet should be ready.

shared-account-information

The above window shows your balance, your receiving address, and the public keys for each cosigner. Save this page to your bookmarks as it might come in handy later.

API keys

We need Coinkite’s API keys. Go to https://coinkite.com/merchant/api and click “Create New Key”. On the next screen, check the following permissions: read, recv, send, send2, and cosign. Click “Save Changes”.

permissions

You’ll be given an API key and an API secret. Write down the API secret as it’s only shown for a limited time.

Enter NodeJS

So, we’re all set up on Coinkite’s side. We’ll create an empty node project (you need to have NodeJS installed). We need three packages: bitcore, coinkite-javascript and request. In an empty folder, run the command:

npm install bitcore coinkite-javascript request

This will install both of them: request is a widely used package that’s for, you guessed it, making http requests. We will use it to communicate with Coinkite’s API. coinkite-javascript is written by the Coinkite team, and will help us to set the correct headers when making those requests.

The First API Call

To make your first API call, create the file “app.js” containing the code below in your project folder. Don’t forget to enter your own API keys.

Here we’re using the request package to call https://api.coinkite.com/v1/my/self , which is a Coinkite API endpoint, to get general information about your account (view documentation).

We’re using Coinkite’s helper to place the correct authentication headers. When the json option is set to true, the response body is automatically parsed for us.

If you run this node app.js you should get the following response:

My user name is <your username>

The following helper code will allow us to call any Coinkite endpoint and automatically set the correct header. Create a file in the same project folder called “coinkite-helper.js”.

The request function can now be used for any Coinkite endpoint, any HTTP method, and parameters.

Now let’s replace the contents of app.js so it uses this helper function:

If you run the app again, you should get the same result as before.

Cosigning Process

The Coinkite API endpoints we will be using are /v1/new/send and /v1/co-sign (link to this cosigning related ones).

The process of performing a transaction with a 2-of-3 multi-signature wallet on Coinkite is as follows:

  1. Make a send request (using /new/send). You will get tha “CK_refnum” to identify the send request. You can use the detail endpoint with any CK_refnum to see all the information about that object, which could be anything (requests, accounts, cosigners…).
  2. Get the signing requirements for the cosigner we have named bitcore by using /co-sign/<request_refnum>/<cosigner_refnum>.
  3. Ask Coinkite to sign the transaction.
  4. Sign for the “bitcore” user and send the signature via /co-sign/<request_refnum>/<cosigner_refnum>/sign.

Now we will guide you through the code for each of these three steps.

To begin, we need the cosigners refnums. To get them, modify app.js as follows:

Run the script and you should get something like this:

[{“user”:”coinkite”,”refnum”:”1EC3A1CFFE-2DAE34″,”xpubkey”:”tpub⋯ rumgqaM9″},

{“user”:”bitcore”,”refnum”:”1B590633FF-3B60BC”,”xpubkey”:”tpub⋯ ANz6KXnh”}]

Assign this, and list the HD private key we generated at the beginning of app.js to use later:

The “bitcore” user’s xpubkey and xprivkey should be the ones we generated earlier.

Issuing Send Requests

The API endpoint for creating send requests is /v1/new/send. The Coinkite API requires that we use the PUT method and the parameters account, amount, and destination:

In order to try this, your wallet must contain bitcoins. Here’s a faucet that you can use to obtain free testnet bitcoins.

If you try this more than once you might get the error  “No fund sources to draw from (no balance)”. This is because the rest of the funds are being sent to the change address. If this happens, go to the “Pending and Recent Transactions” section at the bottom of https://coinkite.com/accounts/balances to cancel pending requests. The API can also be used to cancel Coinkite requests:

To resume a previous transaction, use the endpoint /v1/list/unauth_sends.

Signatures

Now for the fun part (signing stuff is fun, right?). We will sign the transaction with the Coinkite API and then add another signature with Bitcore.

The first part is pretty straightforward. We can ask Coinkite to sign using the co-sign endpoint. Here we’re using the “cosigners” variable that we defined earlier, which has all the cosigners’ refnums:

You should get the message “Signature added, but further signatures are required.”, along with data related to the transaction at hand.

We will use the “Bitcore” cosigner’s CK_refnum for the other signature. Fetch the signing requirements, sign them, and send the signatures back to Coinkite.

First we request the signing requirements for the “Bitcore” cosigner, then we send the corresponding signatures.

getSignatures

This is the getSignatures function we used above:

There’s a lot going on here so let’s break it down. We need a signature for each input we are sending money from. Coinkite provides all the information we need to generate these signatures except the extended private keys we already have. The full signingInfo structure, available here, provides the following information:

  • sighash: This is what we sign.
  • pathIndex: This is the x value in Coinkite’s m/x derivation path. We use the pathIndex to derive a regular private key from an HD key.
  • address: The input address.We can use the input address to ensure that we generated the correct private key.

We will also need to generate a private key (privKey) for each input. We use Bitcore, our xprivKey and the derivation path provided by Coinkite to do this.

With this private key in hand, we sign the sighash using the bitcore.crypto.ECDSA.sign function. We then assemble a triplet for each input with the corresponding signature, sighash and path index and send it to Coinkite.

Tying It All Together

See our sample code for an example of how to link all of these functions together to perform a transaction from start to finish.

Bonus: How to Generate Addresses for HD Multi-Signature Wallets

Hierarchical Deterministic (HD) wallets generate a new address for each transaction. The only difference in this case is that each of those addresses is multi-signature. A 2-of-3 wallet is associated with three public keys.

To generate each multisig address Coinkite derives regular public keys from the cosigner extended public keys and creates a new multisig address for them:

Multiplexing Online Web Wallets with Bitcore Wallet Service

In Web Wallets Using Copay and Scalable Multi-Signature Web Wallets With Copay we explained how to multiplex Copay connections to form a single BitPay Insight server connection so you could easily scale an online web wallet service based on BitPay open source software. Copay has since been modified to use interesting new components: Bitcore Wallet Service (BWS) and Bitcore Wallet Client. The Bitcore Wallet Client makes it easy to manage multi-signature wallets. However, the client only handles one wallet at a time. If you want to use more than one wallet at a time you must instantiate different clients, each of which uses a different network connection. To get around this new issue and multiplex the connections we have modified BWS and Bitcore Wallet Client.

First, we decoupled the client API class from the physical network socket in the Bitcore Wallet Client. This is transparent to the user of the library. Then we modified the way messages are routed between sockets in the Bitcore Wallet Service to allow more than one wallet per connection. We have submitted two pull requests to integrate these modifications into the BWS and Bitcore Wallet Client:

  1. https://github.com/bitpay/bitcore-wallet-client/pull/89
  2. https://github.com/bitpay/bitcore-wallet-service/pull/272

Resources

Scalable Multi-Signature Web Wallets With Copay

As we saw in Web Wallets Using Copay the main drawback to using BitPay’s Copay as an online web wallet like Coinbase is its lack of scalability. Every Copay wallet establishes two connections to the Insight server. Our previous article includes code which eliminates one of the connections used to send and receive single-signature wallet updates to and from the blockchain. Here we offer code which consolidates all multi-signature wallet copayer updates.

First, a quick explanation of how Copay works. Let’s refer to an instance of Copay running in a web browser as a client, and to the instance of Insight the various clients connect to as server. When a wallet connects to a server it is assigned a channel according to the wallet’s public key. A channel in this context functions similarly to a chatroom; when a message is sent to a channel, it is received by all clients subscribed to that channel. All the users of a specific multi-signature wallet will be assigned the same channel and so receive each other’s messages. Because of the way clients are coded in Copay each socket is subscribed to only one channel but the number of channels a socket may be subscribed to is actually unlimited. Additionally, Copay takes advantage of an Insight plugin called “mailbox” that allows messages between clients to be distributed asynchronously. A client may broadcast a message regardless of whether the other clients are connected at that time. This is used for transaction confirmations and other types of notifications.

What our modification does is separate a wallet from its socket, so several wallets may share the same socket. This single socket will subscribe to the corresponding channel of each wallet. Messages are sent normally, but receiving messages requires a simple bit of routing so the message gets to the right wallet. Note that, because of the way socket channels work, if a socket receives a message, there is a wallet using that socket that should receive that message. Our modification doesn’t increase network traffic.

Bitcoin lacks specifications for joining wallets and receiving new addresses generated by other copayers. Fortunately, Copay has addressed these issues for their users, but the solution should ideally be a standard part of Bitcoin.

(Sebastian Wain contributed with the writing of this article)