Renewed Pay to Script Hash

Joonmo Yang
CodeChain
Published in
4 min readMay 26, 2018

--

Giving permission to use a certain property is a difficult problem. Traditionally we delegated this authority to certified third party, like Visa, MasterCard, or even the government. But since the advent of blockchain, it became possible to transfer and verify each others’ assets without risk of being cheated. All the transactions are recorded in a distributed ledger, and everyone can reliably rip malicious trials off from it. Every invalid transfer requests will be automatically blocked, with the magic of transaction verifiers residing in the blockchain client software.

Then how can we prove that I really own a certain asset? In the context of Bitcoin, it is done by working with the lock script included in the UTXO. Every output from transactions contain predefined “scripts” written in Bitcoin Script language. To spend this output, one should provide an “unlock script” that can create successful result when concatenated with the lock script. So far so good, but as always, there are some tradeoffs with this scheme.

Typically, the lock script is saved in UTXO as plain data. But the problem is that UTXO is visible to everyone in the network, so the unlock condition is also publicly known to all users. Although this feature is desirable for blockchains as a distributed ledger, some might hesitate in favor of privacy. Of course, a person other than the owner of the asset won’t be able to satisfy the unlocking condition with high possibility. But if we could embed the script in encrypted form, the system would gain more security than before. This is where Pay to script hash(P2SH) comes in.

Actually, security concern is not a main reason why P2SH was invented. It was first created as a method to allow users to utilize arbitrary kind of lock scripts while maintaining so-called standard script rules. Whatever the reason was, it brought numerous kind of benefits to users, and enhanced anonymity is one of them. In P2SH, only the hash of original lock script is stored. To unlock an asset, one should provide the unlock script along with the original lock script which hashes to script hash saved in the output. This means only those who know what the original lock script looks like can unlock the UTXO, which results in a more powerful security metric.

However, during the initial stages of development, the transaction format of Bitcoin was not designed while taking P2SH into account. Bitcoin transactions did not have any field to represent the script hash of P2SH. So they implemented this functionality by creating a special script template, and decided that all scripts represented by this will have special treatment in the software. It was a reasonable decision at that time since Bitcoin should consider a huge amount of backward compatible features. However, this is not a very neat solution either. There must’ve been a better solution for this if we could implement it from scratch, without any concerns about compatibility issues.

In CodeChain, we decided to use P2SH in every asset-related transactions in the network. Every transaction output contains a hash of lock script instead of the full script itself. Just like P2SH in Bitcoin, a stranger won’t be able to learn the unlock condition without knowing the original lock script. One of the problem of the scheme was that the script hash changes for every receiver we want to send things to, so it becomes really difficult to determine if this asset really belongs to my account. We solved this by excluding predefined part of script in hashing process, so that every script with similar structure hashes to same value. The user would only have to scan for UTXO with the wanted script hash, and check ownership with the unhashed part of the script.

Another feature we get by embedding the script hash in UTXO is reduced space usage. Pay to public key hash, which is the most commonly used form of transaction in Bitcoin, requires at least 107 bytes of space in the transaction. By taking only hash of the lock script, we can save more than 40 bytes of storage for each asset. It is true that it only applies to unspent transactions, since we have to provide and store lock script when spending it. However, the total number of UTXO is currently over 56,000,000, so we expect to save at least 2GiB of blockchain size with this structure. It’s over 1% of the total storage consumption!

Using P2SH as default has a lot more other fascinating advantages. Some state-of-art features on Bitcoin like MAST and MimbleWimble relies on P2SH. With native support for P2SH, it will become easier and more natural to adopt fresh new results from the academic world. We are always preparing room for advanced technologies, and looking for the best structure to adopt them as fast as possible.

Check out the source code at our github repo. If you would like to chat with the CodeChain developers community, join our gitter.

--

--