# Bitcoin Scripts and Script Language

Bitcoin Script is a powerful and unique scripting language at the heart of the Bitcoin blockchain, defining the rules governing transaction execution. Designed by Satoshi Nakamoto, it enables users to create complex, programmable transactions, unlocking a realm of possibilities beyond simple peer-to-peer transfers. Let’s look at the basics of how it works…

Successful Basic Script and Assembly equivalent:

*Reference : *

https://siminchen.github.io/bitcoinIDE/build/editor.html#

https://learn.saylor.org/mod/book/view.php?id=36364&chapterid=18952

`02 07 OP_ADD 03 OP_SUB 01 OP_ADD 07 OP_EQUAL`

`0102010793010394010193010787`

You can just as easily paste in this “Assembly”and execute it as you can the Script.

Obviously the script is easier for a human to create.

## Transaction Scripts

If the unlocking script is executed without errors (e.g., it has no “dangling” pointers left over), the main stack is copied and the locking script is executed

CS120: Bitcoin for Developers

See : https://learn.saylor.org/mod/book/view.php?id=36364&chapterid=18952

OP_CHECKSIG is perhaps the most interesting part of the process:

The **OP_CHECKSIG** operation checks if the digital signature matches the public key provided in the transaction. If they match, it means the person spending the Bitcoin(s) is the rightful owner of the associated private key. Have a play around using https://ide.scriptwiz.app/

When we say a signature is “valid,” it means that the *signature* was indeed created by the *private key* corresponding to the *public key* in the transaction. In other words, the signature can be successfully verified using the public key, confirming that the person initiating the transaction is indeed the owner of the private key associated with that public key.

So, as long as you have the digital signature and the corresponding public key, you can verify the authenticity of the signature and confirm ownership of the private key.

Verify the owner

```
from ecdsa import SigningKey, SECP256k1
# Generate a private key
private_key = SigningKey.generate(curve=SECP256k1)
# Get the corresponding public key
public_key = private_key.get_verifying_key()
# Create a message to sign
message = b"Hello, World!"
# Sign the message
signature = private_key.sign(message)
signature_string = signature.hex()
print(f"Signature: \n{signature_string}\n")
# Assuming 'public_key' is the bytes object
public_key_string = public_key.to_string().hex()
print(f"Public key: \n{public_key_string}")
# Verify the signature - ensure you pass the message that was signed!
if public_key.verify(signature, message):
print("\nSignature is valid.")
else:
print("Signature is not valid.")
```

```
Signature:
0ec65fae53ed23988e19331c7873b2dc738c0b364588be1519cd2435c2eb5a32f2e863993daf256188b5930fac59b10c82f16055c206f98d68dc12a39a026d0e
Public key:
0ec65fae53ed23988e19331c7873b2dc738c0b364588be1519cd2435c2eb5a32f2e863993daf256188b5930fac59b10c82f16055c206f98d68dc12a39a026d0e
Signature is valid.
```

The raw public key and signature are **not directly compared** in Bitcoin scripts. Instead, the public key is hashed, and the hash is compared against a pre-determined hash. If they match, the script proceeds to the signature verification.

Modern Bitcoin addresses and transactions use compressed public keys for efficiency and smaller transaction sizes. This is done to save space on the blockchain and reduce transaction fees.

https://bitcoin.stackexchange.com/a/90417/139723

```
use secp256k1::{Message, PublicKey, Secp256k1, SecretKey};
fn main() {
let secp = Secp256k1::new();
let secret_key = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order");
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
let message = Message::from_digest_slice(&[0xab; 32]).expect("32 bytes");
let sig = secp.sign_ecdsa(&message, &secret_key);
assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());
}
```

This **Rust** code demonstrates how to use the `secp256k1`

crate to perform Elliptic Curve Digital Signature Algorithm (ECDSA) operations. **ECDSA** is commonly used in blockchain and cryptography for creating and verifying digital signatures.

Here’s a breakdown of the code:

- Import the necessary items from the
`secp256k1`

crate:`use secp256k1::{Message, PublicKey, Secp256k1, SecretKey};`

This brings into scope the types and methods needed for working with the secp256k1 elliptic curve. - Define the
`main`

function:`fn main() { // ... }`

This is the entry point of the Rust program. - Create a new instance of the
`Secp256k1`

struct:`let secp = Secp256k1::new();`

This initializes a new secp256k1 context, which is necessary for other cryptographic operations. - Generate a secret key:
`let secret_key = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order");`

A 32-byte secret key is created here. The key is generated from a slice containing the byte`0xcd`

repeated 32 times. The`expect`

method is used to handle any errors that might occur during the key generation. - Derive the corresponding public key from the secret key:
`let public_key = PublicKey::from_secret_key(&secp, &secret_key);`

This computes the corresponding public key using the secp256k1 elliptic curve parameters. - Create a message:
`let message = Message::from_digest_slice(&[0xab; 32]).expect("32 bytes");`

A 32-byte message is created using the`Message::from_digest_slice`

method. The message content is generated from a slice containing the byte`0xab`

repeated 32 times. - Sign the message using the secret key:
`let sig = secp.sign_ecdsa(&message, &secret_key);`

The`sign_ecdsa`

method is used to generate a digital signature for the given message using the provided secret key. - Verify the signature:
`assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());`

The`verify_ecdsa`

method is used to verify the signature against the original message and public key. If the verification is successful, the result will be`Ok`

, and the`assert!`

macro will succeed, indicating that the signature is valid.

In summary, this code demonstrates the basic process of generating a secp256k1 key pair, signing a message with the private key, and then verifying the signature using the corresponding public key and original message.

Note: In a real-world scenario, you would typically use a secure method to generate a random secret key rather than using a constant value as shown in the example. The use of a constant value is for demonstration purposes only.

https://docs.rs/secp256k1/latest/secp256k1/

In a real-world scenario, when signing a Bitcoin transaction, you don’t typically sign an arbitrary message like “hello.” Instead, you sign the transaction itself. The transaction includes information such as the transaction inputs, outputs, and other necessary details. This ensures that the signature is specific to that particular transaction, preventing it from being reused for a different purpose.