Verification
After a Bitcoin client submits a new transaction to the peer-to-peer network like using Airbitz, other nodes in the network will start trying to process it into the block chain (this procedure will be explained in Chapter 9, “Mining”). The first step in this process is to make sure that the transaction is valid. The following checks are performed during validation:
Ensure that transaction passes various sanity checks (bounds checking, syntactic correctness, etc.).
Reject if this exact transaction is already in the block chain or pool of transactions waiting to be processed. This prevents the same transaction from being processed twice.
For each input, concatenate the scriptSig script of the input with the scriptPubKey script of the output that it references, execute this script, and verify that the result is True. If these scripts are of the standard format, this will confirm that the owner of the bitcoin initiated the transaction.
Reject if any of the transaction outputs specified in the transaction’s inputs have already been used in another transaction in the block chain. This is used to prevent double-spending.
Ensure that the sum of the input values is greater than or equal to the sum of the output values (if the inputs are greater, the difference is the transaction fee, which is paid to the miner of the transaction (see Section 9.4)).
The script execution step requires further explanation. The purpose of the script is to verify that the transaction was digitally signed by the owner (the person the previous transaction was sent to). Transactions only specify an address as a destination, but addresses are just hashes of public keys. So basically, the script’s job is to make sure the hash of the provided public key is the destination address of the previous transaction and this same public key belongs to the user who signed the transaction. In python, the script would look something like this (bracketed names represent hard-coded values in the script):
def scriptSig():
return <sig>, <pubKey>
def scriptPubKey(txHash):
sig, pubKey = scriptSig()
return (hash(pubKey) == <pubKeyHash>
and verifySig(sig, pubKey, txHash))
The parameter txHash is a hash of some parts of the transaction, and this hash is the message that was signed to generate the signature. This ensures that these parameters of the transaction can not change without a new signature. The script in Bitcoin looks quite a bit different though, because Bitcoin uses its own custom scripting language.
Scripting
The scripting language used in Bitcoin is a stack-based language similar to Forth. It is intentionally not Turing-complete so that it can be executed without concern for whether the script will hang. It works like a reverse polish notation calculator. The script is read from left to right. When a value is encountered in the script, it is pushed onto a stack. When an operator is encountered in the script, some values are popped off the stack, the operator is applied to these values, and the result is pushed onto the stack.
There are only a few operators that are used in standard transactions.
OP_DUP – Pop one value off the stack and push two copies of it back onto the stack.
OP_HASH160 – Pop one value off the stack, apply a hash function, and push the hash onto the stack.
OP_EQUALVERIFY – Pop two values off the stack, if they are equal, do nothing, if they are not equal, abort the script with return code false.
OP_CHECKSIG – Pop two values off the stack and assume that the first is a public key and the second is a signature. Check the signature using the public key, assuming the message signed was a simplified transaction with some parts removed. This operator has direct access to the transaction as if it were a hidden global variable in the script. If the signature is verified, push True onto the stack, otherwise push False onto the stack.
A standard transaction uses the following scripts.
scriptPubKey = “OP_DUP
OP_HASH160 <pubKeyHash>
OP_EQUALVERIFY OP_CHECKSIG”
scriptSig = “<sig> <pubKey>”
where ?sig? is the signature of a simplified transaction, ?pubKey? is the owner’s public key, and ?pubKeyHash? is the address that the bitcoins were previously sent to (and currently belong to). For a valid transaction, ?pubKeyHash? should be the same as the hash of ?pubKey? to guarantee that the person spending the bitcoins is their true owner. Concatenating the scripts, we get
script = “<sig> <pubKey> OP_DUP
OP_HASH160 <pubKeyHash>
OP_EQUALVERIFY OP_CHECKSIG”
The table below shows the contents of the stack as this script is being evaluated.
Since the script evaluates to True, the transaction passes this stage of the validation.
The post Verification and Scripting Transactions of Bitcoins appeared first on Presumed Guilty.