3

satoshi created bitcoin script which is the language that the bitcoin client uses to handle most of the operations such as sending or verifying transactions.

was it necessary to have another language for these operations? isn't it possible to write the whole runtime in one language?

4 Answers 4

8

was it necessary to have another language for these operations? isn't it possible to write the whole runtime in one language?

To be clear: the goal of the scripting language isn't for defining the runtime logic of blockchain validation. No part of Bitcoin Core itself is written in the Bitcoin Script language, just in C++. The goal of the Bitcoin Script language is for customizing the conditions under which transaction outputs can be spent. These scripts are intended to be written by "users" of the system, not by (authors of) the system itself. Of course, in practice they are written and designed by the authors of the wallet software these users use, but it permits a flexibility that wouldn't otherwise exist: wallet authors can develop and experiment with new scripts permitted by the language, without needing to wait for the entire Bitcoin ecosystem to adopt changes to specifically enable their use case.

Would it be possible to not have such a language: certainly. There are several cryptocurrencies that don't have such a concept at all. But this alternative doesn't need to mean that the Script language is replaced by C++ (or whatever other language the validation logic is written in) - it can simply mean there is no customizability of spending conditions at all, and every output is just e.g. a public key, and every input is just a signature, and nothing else is possible.

Having this language at all just introduces features that wouldn't be achievable through other means. The simplest example is having coins that can only be spent when multiple people sign off on it(*), or only after a certain amount of time, or after some secret gets revealed. Together these are the basis for example for trustless escrows (where the escrow can't steal the coins), or for systems built on top like payment channels.

Perhaps your question is: why is this customizability of spending conditions not done using the language as the one the validation logic is written in? There are several reasons for this:

  • It is essential that the outcome of evaluation of Bitcoin Script (or whatever alternative you're envisioning) only depends on data committed to by the transaction itself, or possibly in the blockchain it ends up in. Anything else is inviting risk of forks. For example, Scripts can (perhaps surprisingly) not observe the current time in any way. The (local) time at which validation is performed by various validators differs, so including the current time in Script could lead to a script that some validators accept and others reject, just by virtue of performing validation at different points in time. Bitcoin Script can however (indirectly) observe the timestamp of blocks in the blockchain, because this value is guaranteed to be identical for all validators. Imposing such strong restrictions on an existing language intended for general purpose programming is hard, and having a separate language for it makes it much easier to enforce this.
  • Size matters. As a global consensus system, capacity is limited. Bandwidth and latency constraints of the slowest and least-well connected devices the system wishes to let participate set a bound on how much data can be included in the chain. One aspect of that size is how much data it takes to express typical conditions in the Script language (or whatever its replacement is). As we envision many transactions whose conditions for spending at least involve some form of signature check, it stands to reason that it should be very cheap to express these. In Bitcoin Script, the logic "require a signature on the current transaction with public key X" can be expressed in 2 bytes + the size of the public key. This would be much harder to accomplish using a general-purpose language.
  • Computation cost, and predictability for that, matters. As the scripts included in transactions submitted to the network will be run and re-run by every validator (possibly ever), we care about the computational cost that validation entails for those validators, and specifically want an upper-bound on that cost. This means there needs to be some mechanism for stopping execution if it takes too long, or being able to determine ahead of time how long it's going to take.
  • Not every piece of software that interacts with the blockchain or transactions is written in the same language. In Bitcoin, the currently most-used validation software is Bitcoin Core, which is written in C++, but it is far from the only wallet software, and these other wallets are written in a variety of languages. Using C++ for the scripting language would pretty much require all these implementations to have a C++ dependency. Given that C++ is a compiled language, it would additionally require access to a C++ compiler just to run the scripts received in blocks and transactions from the network. C++ isn't designed for such on-the-fly code updating, and using an abstraction to e.g. run it in a virtual machine or interpreter would negate whatever advantages existed to use the same language in the first place. The situation may be different for other languages of course, but the point remains that the goals for a language to write a validation engine is, and the goals for the language to write spendability conditions are wildly different, so there is little reason to want to cover both by a single language.

(*) There are techniques in modern cryptography to actually make a single public key that can only be spent when multiple people cooperate to spend it.

4

It is theoretically possible that Satoshi could have taken the entire C++ language (Bitcoin Core is written in C++) and then severely restricted what C++ functionality was available for Bitcoin scripting. Ethereum did something similar by making modifications to Javascript and calling it Solidity. An alternative approach that other altcoins took (e.g. Mimblewimble based altcoins such as Grin, Beam) was not to have a scripting language at all and only allow single signature spends (no multisignature, no timelocks etc).

As RedGrittyBrick says for various reasons it made sense to start from a much more limited language (Forth) than C++ as even Forth was too expressive for Bitcoin Script; various Forth opcodes had to be disabled for Satoshi to be comfortable it wasn't exposing Bitcoin to uncertain verification costs. (There are also new opcodes that Bitcoin Script would like that aren't in Forth.)

Taking an existing language (C++, Javascript, Forth etc) and then removing and adding functionality so it can be used for Bitcoin scripting is an imperfect approach. Simplicity is an effort to build a scripting language for Bitcoin from the ground up. It is still a work in progress and would need a soft fork to be added to Bitcoin but designing specifically for the Bitcoin scripting use case and providing guarantees that aren't available in adjusted existing languages seems to be a much more promising approach.

2

Consider a script that says

 While (true) {
   // some pointless but slow calculation
 }

in order to discover if the transaction containing it is valid, every node on the network has to run this until it returns a value.

The halting problem means that it is impossible to know whether a script will ever complete.


These scripts are created by the transaction creators and could contain any script that a malicious person can dream up.

One way to combat malicious scripts is to have nodes know of a small number of standard scripts and not relay non standard scripts.

You could ask, if we only have a few standard transaction types, we don't need a scripting language at all, the evaluations could be hard coded in C++ and no scripts would be in the transaction itself. This would not be Bitcoin. Having a scripting language arguably provides for future flexibility.

We need the scripting language to be judiciously limited, so that we can be sure any script can be executed in finite time. we also need to be certain that no matter what malicious data is presented to the script by bad actors, it will terminate in finite time. having the scripting language be a carefully designed minimalistic language with limited capabilities arguably provides the best assurance of this.


As Crypto News said

the limitations in Bitcoin Script prevents a “logic bomb,” or an infinite loop from being included in any single transaction. This restriction eliminates the possibility of a denial-of-service (DoS) attack on the network.


See also

2
  • there is only one global script that is executing on every machine, if someone sends something that doesn't conform to the rules of the script, it would simply be return an error.
    – ezio
    Jun 11 at 7:37
  • i think you missunderstood my point, if i have the whole runtime of my blockchain as print('"hello world") then every node would execute only that and wouldn't recognise anything else and i could write that line only in one language .
    – ezio
    Jun 11 at 8:01
0

was it necessary to have another language for these operations? isn't it possible to write the whole runtime in one language?

It is possible to have one language for bitcoin implementation and use the same language for writing bitcoin scripts.

Examples: Sapio uses Rust and Solana1 programs can be written in Rust or C++

1 Solana programs are smart contracts that dont hold user data like Ethereum, they talk to accounts that hold data and are upgradeable

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.