In this guide, we will go through an example of multi-sig transaction using native script. The example will demonstrate the
steps required to create a multi-sig script and claim fund from the script address.
Let’s go through some theory first. Click here to directly jump to the example section.
A native script is a set of rules that defines how you can spend a UTxO. Native scripts are used
to make script addresses where the authorisation condition for a transaction to use that address is that the transaction has
signatures from multiple cryptographic keys. Examples include M of N schemes, where a transaction can be authorized if at
least M distinct keys, from a set of N keys, sign the transaction.
Some key points about native scripts in Cardano
A native script can be encoded as a json text file
It uses a simple language for expressing witness requirements for spending an output, minting or burning transaction
Keys are identified in the script by hash of public key
It also provides support for time-locking, so the script is valid for a specific time range
There are six supported constructors in a multi-sig script. The following section briefly explains about each constructor and
corresponding type in json file.
RequireSignature: has the hash of a verification key.
This expression evaluates to true if the transaction is signed by a particular key, identified by its verification key hash.
Type: “sig”
RequireAllOf: has a list of multisig sub-expressions.
This expression evaluates to true if (and only if) all the sub-expressions evaluate to true.
Type: “all”
RequireAnyOf: has a list of multisig sub-expressions.
This expression evaluates to true if (and only if) any the sub-expressions evaluate to true.
Type: “any”
RequireMOf: has a number M and a list of multisig sub-expressions.
This expression evaluates to true if (and only if) at least M of the sub-expressions evaluate to true.
Type: “atLeast”
RequireTimeBefore: has a slot number X.
This condition guarantees that the actual slot number in which the transaction is included is (strictly) less than slot number X.
Type: “before”
RequireTimeAfter: has a slot number X.
This condition guarantees that the actual slot number in which the transaction is included is greater than or equal to slot number X.
Type: “after”
Cardano Client Lib provides apis and helpers to create and manage native scripts in Java.
In this example we are going to simulate a joint account use case using a multi-sig script. So a muti-sig account between three parties
which specifies that at least any two members need to sign to spend fund from the account.
In next few sections, we are going to
Create a multi-sig script with three key hashes (2 regular accounts, 1 payment key pair(skey & vkey))
Create script address for the multi-sig script
Top up multi-sig address with some fund
Claim fund from the multi-sig address and distribute to two regular accounts
We are going to create a multi-sig script with “RequireMOf” constructor or “atLeast” type.
For our example, we first need to create verification keys for account1 and account2 using their public key. These verification
keys, including the one from payment key pair, are then used to create corresponding ScriptPubKey (sig type native script) instances.
Finally, all three ScriptPubKey instances can be composed to build a ScriptAtLeast instance.
Create VerificationKey instances using public keys of account1 and account2. Use verification keys to create ScriptPubKey instances.
Based on your selected network (preprod / preview), get some test Ada from the below faucet. You need to provide scriptAddress
generated in the previous section to get some test Ada.
Use the Tx class to define the transaction. Specify the outputs, attach the native script, and set the
script address as the sender.
With QuickTx, you don’t need to manually add the script to the witness set or specify the number of signers
for fee calculation — attachNativeScript handles the witness and QuickTx handles balancing automatically.
Alternatively, you can sign with account1 and account2, or with all three keys.
completeAndWait waits up to 60 seconds by default. result.getTxStatus() is CONFIRMED once the transaction is on-chain. It can also be PENDING or TIMEOUT, in which case the transaction may still land, so check the status. result.getTxHash() holds the transaction hash.
To check the details on a public network, look the hash up in an explorer for Preview or Preprod.
Stringaccount2Mnemonic="report crowd trophy rough twin column access include evolve awkward world random bounce pave select rocket vote junk farm group main boat tissue mad";