Bitcoin Script
The SVScript() class allows you to parse existing Bitcoin Script program fragments. The developer will use this class primarily in either retrieving data fields from existing Transactions, or as a utility for building new types of Scripts.
Parsing an ASM-formatted script
When working with a local bitcoin node instance during testing, you might observe bitcoin script written as a series of plain-text OP_CODES. This is called ASM (assembly) format.
import org.twostack.bitcoin4j.script.Script
//the locking script of a Pay-to-Pubkey-Hash (P2PKH) transaction
val asm = "OP_DUP OP_HASH160 f4c03610e60ad15100929cc23da2f3a799af1725 OP_EQUALVERIFY OP_CHECKSIG";
val script: Script = Script.fromAsmString(asm);
//extract the pubkey hash from the parsed script
val pubKeyHash: String = HEX.encode(script.chunks[2].data);
Parsing a hexadecimal-formatted script
When interacting with third-party service providers or if receiving serialized transactions over the internet, one often encounters Script instructions in their hexadecimal representations.
import org.twostack.bitcoin4j.script.Script
val script = Script.fromByteArray(HEX.decode("76a914f4c03610e60ad15100929cc23da2f3a799af172588ac"));
//convert to ASM representation
val asmString = script.toAsmString()
Custom Script Templates
One of the primary benefits of using the BitcoinSV blockchain is that the notion of “standard transactions” no longer exist. This means that one can construct arbitrary locking and unlocking scripts when creating transactions.
In order to make the Bitcoin4J library as extensible as possible, we have constructed a means for developers to define custom implementations for locking and unlocking script templates. These custom implementations can be implemented very simply, and will still be able to offload the heavy lifting of things like transaction building and verification to the Bitcoin4J library.
LockingScriptBuilder and UnlockingScriptBuilder implementations are used together with */TransactionBuilder*/ when one creates and signs custom spending or locking behaviours for transactions.
The primary interfaces (abstract classes) that allow for this behaviour are:
abstract class | description |
---|---|
LockingScriptBuilder | Implement this interface to enable custom scriptPubKey (locking script) behaviour |
UnlockingScriptBuilder | Implement this interface to enable custom scriptSig (unlocking script) behaviour |
Locking Script Builder
The LockingScriptBuilder interface forms the basis of the defined behaviour for locking scripts.
The following code snippet shows the simplest implementation of a LockingScriptBuilder implementation. Notice that the only method that needs to be implemented is getLockingScript(). When using your LockingScriptBuilder implementation with the TransactionBuilder, the getLockingScript() will be invoked by the TransactionBuilder to compose the Transaction Outputs for your transaction.
/*
* A default locking script builder implementation that delegates the actual
* construction of the locking script to the developer. I.e.
* this LockingScriptBuilder does not impose any template or format on what
* may be contained in the locking script (scriptPubKey)
*/
public class DefaultLockBuilder extends LockingScriptBuilder{
public DefaultLockBuilder(Script script){
super(script);
}
public DefaultLockBuilder(){
super();
}
@Override
public Script getLockingScript() {
return script;
}
}
Unlocking Script Builder
The UnlockingScriptBuilder interface forms the basis of the defined behaviour for unlocking scripts.
The following code snippet shows the simplest implementation of a UnlockingScriptBuilder implementation. Notice that the only method that needs to be implemented is getUnlockingScript(). When using your UnlockingScriptBuilder implementation with the TransactionBuilder, the getUnlockingScript() method will be invoked by the TransactionBuilder to create the Transaction Inputs for your transaction.
In the event that your LockingScriptBuilder needs to participate in the Transaction Signature generation, you will have access to the list of signatures in the abstract base. Please have a look at the implementation of the library’s P2PKHUnlockBuilder to understand how to work with signatures.
/*
* A default unlocking script builder implementation that delegates the actual
* construction of the unlocking script to the developer. I.e.
* this UnlockingScriptBuilder does not impose any template or format on what
* may be contained in the unlocking script (scriptSig)
*/
public class DefaultUnlockBuilder extends UnlockingScriptBuilder {
List<TransactionSignature> signatures = new ArrayList<>();
public DefaultUnlockBuilder(){
super();
}
public DefaultUnlockBuilder(Script script){
super(script);
}
@Override
public Script getUnlockingScript() {
return script;
}
}