In the operation of Bitcoin, there is a crisis brewing. Bitcoin mining pools are restricted by a feedback-control loop which they defined, in the days of the inception of Bitcoin, only to be able to “mine” 1 Block every 10 minutes, which is inserted into the block-chain when that has been achieved, and which acts as a slate, onto which all Bitcoin transactions must be recorded. A block currently occupies 1MB of data, and the size of individual transactions to be recorded in it, can vary greatly, but averages 500 Bytes for the simplest types of transactions.
What this means, is that 1 Block can typically hold 2000 transactions, but will only be mined every 600 seconds, on the average, so that a global rate of available transactions of 3 /second would seem to follow. Because the world that uses Bitcoin is presently trying to conduct transactions at a faster pace – because in some parts of the world, Bitcoin is a currency – there have sometimes been escalations in the transaction fees, which are charged according to how many KB of one block the transaction consumes. Recently, the transaction fees were around 2 milliBits/kB, or 0.002 BTC/kB. That counts as extremely expensive, since 1 BTC is approximately worth CAD 2000 right now, meaning that the transaction fee could be around CAD 1.- . Many items and services people might want to buy, would not cost much more than the CAD 1.- of my country’s real currency.
Bitcoin operators recognize that a problem exists, and there exist two camps who are in conflict right now, over what to do about it:
- Bitcoin Unlimited
- Bitcoin Core
Out of these two groups, Bitcoin Core represents the status quo.
What Bitcoin Unlimited is proposing, sounds straightforward: Increase the block-size, and allow for it to be increased again, as the demand for transactions increases in the future. But there are some problems with what Bitcoin Unlimited is proposing. Changing the format of the blocks, and/or the protocol, would essentially create two types of currencies:
- The legacy currency, which might be referred to as BTC -units, and
- A new form of Bitcoins, which might be referred to as XBT -units.
If one mining pool was unilaterally to adopt a new Bitcoin block-format, this would be called a ‘Hard Fork’. In the event of a hard fork, people who held Bitcoin-amounts on the legacy block-chain, would see that that legacy block-chain has been imported into both newly-forming block-chains. Wallet-holders would therefore see, that they have a double-dipping; they’d have their present amounts both as BTC and as XBT. But, if they were to mix their Bitcoins into a new block, using a type of transaction that has more than one input, those Bitcoin-amounts would become invalid on the other, newly-differing chain.
There would be a bigger problem in the event of a hard fork, which is known as the risk of a Replay Attack. Because the legacy chain was not designed with the possibility of two future continuations in mind, after a hard fork, if a wallet-holder was to pay for a service in, say, XBT, then the payee – or somebody else – would be able to use the credentials the wallet-holder used in his own transactions, which worked for XBT, and could replay those transactions – actually signing the same inputs as before surreptitiously – but this time, pay out the amounts to another public address, as a BTC -amount. So the payer would see both his XBT and his BTC coins disappear, while only having authorized one of the two transactions himself, out of the legacy-chain.
As an alternative to a hard fork, Bitcoin Core is proposing a short-term solution named “SegWit”. This is a proposed solution, that will cause fewer bytes of data to be written to the block, per transaction, and which it is hoped, will allow the increased number of transactions to be served, that the world is asking for right this instant.
This is a video, which describes in storybook-form, what SegWit proposes. Essentially, a Bitcoin transaction possesses a list of inputs, and a list of outputs. No public address really owns the transaction, but the transaction proposes to use unspent outputs, made to the person who holds the private key, for the public key the outputs were made to – that constitute his Bitcoin balance – as an input or as inputs, and to state somebody else’s public address as the recipient of the outputs.
What Bitcoin experts know, is that the inputs-list of a transaction takes up much more space, on average, than the outputs list does. The reason for this, is the fact that in order to specify an input, Bitcoin is so restrictive, that one specific output must be identified, and not just one public address, to which the output was received. This means, that the complete Transaction ID must be stated in the inputs-list, as well as the sequence-number, the position of the output received, in the outputs-list, of the specified transaction, so that the current wallet-holder can use it as an input. This is expensive in the number of bytes used, because in addition to that, the public key of the recipient must be embedded in the inputs-list, as well as the signature with which the holder of the public address authorized the received output be unlocked.
- Transaction ID : 32 + 4 Bytes
- Sequence Number : 4 Bytes
- Public Key : 33 or 65 Bytes
- Signature : ~72 Bytes
- Additional Bytes used for script-instructions: (?)
But there is an added twist to how Bitcoin works. We might expect that this information is simply entered by software, into fields that belong to a transaction with a specific syntax. But as it stands, only the fields (1) and (2) above exist statically in a transaction. The rest is embedded as literal constants, in a very scaled-down forth-like language called “Script“.
The way script works in general, is that the piece of script in the inputs-list of the recipient, is executed before the piece of script in the outputs-list of the sender. The script of the output defines the conditions that need to be met, in order for the recipient – in another transaction than the transaction that states this script as an output – to be able to claim the amount. In order to satisfy those conditions, the script of the recipient – in his inputs-list – leaves a number of objects on a stack, which the script in the outputs-list of the sender can use as input.
According to the way Bitcoin has traditionally worked then, was that the input defined by the recipient, would place his public-key, and his signature onto the stack, in expectation that this is what the output of the sender requires. The input does this in the form of an embedded public key, and an embedded signature, in its actual script, which were placed there by software running normally on computers, and not running through script.
But the output script of the sender would then expect these data to be on the stack in a predefined order, and would verify that two conditions were met:
- When hashed, the public-key must equal the public address of the intended recipient (Those are not really the same thing), ( :1 )
- The signature must be decrypted by the same public key, to equal a hash of the transaction being claimed as input.
In order for the outputs-script to verify this, it must also receive the Transaction ID of the transaction it belongs to on the stack, but this is not the responsibility of the inputs-script of the recipient to place there.
What SegWit proposes, is that the inputs-script should neither need to state the public key of the recipient anymore, nor his actual signature, thus making the transaction shorter. Thereby, something needs to signal, that this public key should be taken ‘from the side’, from the “Extended Block”, but fed to an established output script.
While this is all very fascinating, it reveals two very serious problems of its own:
(Video posted on YouTube by ‘https://www.youtube.com/user/m1xolyd1an‘.)
- The solution is not scalable. If, in a few years time, the number of transactions requested globally has increased more, so that again there is a shortage in kB used, even though SegWit was implemented, then this trick cannot simply be repeated.
- The signature of the recipient cannot be verified independently now. As it stood, because the public key existed explicitly as part of the inputs list, as well as the signature, any independent party could inspect the block-chain and make sure that each transaction was signed for, by the wallet-holder.
Some software-developers might not think that it’s important, that the wallet-holder needs to sign for his own received funds to be unlocked, because maybe, only the hashes of the mining-pool seem important to those developers. But the wallet-holder will find it important, that his money cannot simply be claimed sight-unseen, and displayed to him next as Spent, even though he did not authorize that the amount be spent.
In order for an independent verification of a signature to be made, both the public key and the signature itself must be available – as well as the hash-code that was purportedly signed. But according to SegWit, the public key will no longer be visible in the block-chain itself.
Hence, if there was ever a dishonest service-provider – God Forbid – the execution of the script in the outputs-list of the sender could be made optional. A meaningless signature could even be specified in somebody else’s inputs-list. The fact that this signature would not be valid would not be noticeable, without the public key. And then a transaction would seem to exist, that states inputs and outputs like any other transaction would, but which was not authorized by the recipients of the outputs claimed – as inputs.
As the video above suggested, it is not an intention at this time, for SegWit to make the public keys visible, because it’s being planned as an advantage, that these public keys be kept secret, in order to prevent a future replay attack. In other words, when and if a larger-block-size is implemented – let’s say according to ‘SegWit2x’ – before that happens, the first version of ‘SegWit’ should already have been implemented. And then, an attacker would not be able to replay the credentials that unlocked what was on the legacy chain, because even though outputs were stated on the legacy chain, the inputs-list that claimed them there would not reveal any credentials.
Also, the “malleability bug” can be explained more-precisely. In order for a public-key signature to work, the signer must first hash the document to be signed, and then encrypt the hash-code with his private key. Unfortunately, as long as the encryption is asymmetric, this results in an ‘encrypted entity’, which is also longer than the original hash. Hypothetically, if the modulus was a power of two, a conservation of that original size might be possible…
But then when confirming, another person uses the public key of the signer, to decrypt this encrypted entity, supposedly to reproduce the original hash. This is also why the signature cannot be smaller in data-size, than the hash-code was. According to what I wrote above, the header of the input contained:
- Transaction ID : 32 + 4 Bytes
- Sequence Number : 4 Bytes
The Transaction ID according to my definition here, is essentially a 256-bit hash of the transaction, but has the block-index appended to it, as:
- Protection against a hash-collision,
- A way to accelerate finding the transaction in question, in the block-chain.
The Sequence Number states which output is to be signed for. I think the original problem was, that the public-key signature only used the 256-bit (32-Byte) Transaction Hash, not the added 4+4 Bytes.
So it’s being touted as a feature and not a bug, that the public keys will not be made public. And so, only the “Segregated Witness” would be in a position to make sure, that the true wallet-holder an amount was paid to, can unlock that amount.
1: ) In order for the “malleability bug” to have been exploited, there must have existed a transaction-type, earlier in the history of Bitcoin, which did not adequately test this condition. That way, the public-key signature may have been used to claim outputs of a transaction, which the intended recipient had not spent yet, but belonging to a transaction, the preceding output of which was spent-and-signed-for, by another, legitimate recipient.
2: ) I suppose the reader might also wonder, why it takes 4 bytes each, to state the block index, and the sequence-number. 32 bits happen to be a common CPU word-size, and has worked its way into several main programming languages, as the size of the smallest ‘real’ integer. Nobody is suggesting that 32 bits are in fact required, to specify which output in a list of outputs was meant. No transaction will have 4 billion of them.
Yet, there exist hundreds of thousands of blocks presently, so that an integer of size 4-bytes seems more reasonable to index those.