Creating and signing a multi-signature transaction (Offline)
This guide describes different methods of creating and signing a multi-signature transaction offline. A user can create an offline multi-signature transaction using the CLI, or via Klayr Elements. The steps apply to all the blockchain clients developed with the Klayr SDK, including Klayr Core.
On this page, you’ll learn:
-
How to create a multi-signature transaction in an entirely offline environment.
-
How to sign a multi-signature transaction in an entirely offline environment.
Prerequisites
To use this guide, ensure the following criteria below have been fulfilled:
-
A multi-signature account with sufficient balance exists. To learn more about creating a multi-signature account, see the guide on How to create multi-signature accounts and transactions.
As the name suggests, a multi-signature transaction requires multiple signatures on a transaction for it to be accepted and processed successfully.
For the sake of this guide, we are using a multi-signature account which requires two signatures from a set of three optionalKeys
and no mandatoryKeys
.
In case you have a different setup for the multi-signature account, where the account requires a different number of mandatory and optional keys, adjust the following process accordingly. The basic steps will remain the same regardless of the number of mandatory and optional keys.
Option 1: Using the node CLI
Creating a transaction offline
The CLI of a node can be used to create a transaction, even if the node is currently offline.
The flag The The Without signatures, a transaction should be created by mentioning the sender’s public key after its flag: The Although, it isn’t mandatory, however, to also see the decoded transaction object on creation, add the To acquire a readable response add the |
A multi-signature transaction requires individual signatures from the owners of the multi-signature account, hence while creating such a transaction, the aforementioned flags should be used.
Create a transaction via the CLI like this:
./bin/run transaction:create token transfer 1000000 --offline --chain-id 00000001 --nonce 3 --json --pretty --no-signature --sender-public-key e98e8a6325730be6bf2644af83d5a0b004bb31c15858fedbd0ac2c1f89e2eece --json --pretty
Define the transaction params:
? Please enter: tokenID: 0000000100000000
? Please enter: amount: 20000000
? Please enter: recipientAddress: klygmmkgyc67n5jrpf2trgtxtc4yjg7bpu992chba
? Please enter: data:
After all relevant information about the transaction is given, the transaction is created and returned in hex format:
{
"transaction": "0a05746f6b656e12087472616e73666572180320c0843d2a20e98e8a6325730be6bf2644af83d5a0b004bb31c15858fedbd0ac2c1f89e2eece32270a0800000001000000001080dac4091a14f94b4fc46a71d7c913d89cbf30cc698f3ee3120d2200"
}
{
"transaction": {
"module": "token",
"command": "transfer",
"fee": "1000000",
"nonce": "3",
"senderPublicKey": "e98e8a6325730be6bf2644af83d5a0b004bb31c15858fedbd0ac2c1f89e2eece",
"signatures": [],
"params": {
"tokenID": "0000000100000000",
"amount": "20000000",
"recipientAddress": "klygmmkgyc67n5jrpf2trgtxtc4yjg7bpu992chba",
"data": ""
}
}
}
Signing a transaction offline
Once a transaction is created in the aforementioned manner, the transaction is ready to be signed by the required number of signatories. Since the multi-signature account considered in this guide requires two signatures from a set of three optional keys, we will sign the transaction hash received above with the first optional key.
To sign a transaction, use the transaction:sign
command.
Pass the above-mentioned transaction hash, all the mandatory (in case your multi-signature account requires mandatory keys as well) and optional keys with their respective flags: --mandatory-keys
and --optional-keys
.
Also, mention the --chain-id
and --offline
flag.
You can also add the --json
and --pretty
flags to retrieve a more readable signed transaction, however, that is optional.
./bin/run transaction:sign 0a05746f6b656e12087472616e73666572180320c0843d2a20e98e8a6325730be6bf2644af83d5a0b004bb31c15858fedbd0ac2c1f89e2eece32270a0800000001000000001080dac4091a14f94b4fc46a71d7c913d89cbf30cc698f3ee3120d2200 --optional-keys c61cd862a8b7f73857b248a4358a7b35c29ca273d76ba3819e8c54b62801f16e e98e8a6325730be6bf2644af83d5a0b004bb31c15858fedbd0ac2c1f89e2eece --chain-id 00000001 --offline --pretty --json
The signatory will enter their passphrase:
? Please enter passphrase: [hidden]
The node will respond with an updated transaction hash string and the same transaction in JSON format as well.
Notice the signatures
array in the JSON formatted transaction, it contains placeholders for two signatures.
The aforementioned sign
transaction adds a single signature as per the lexicographical order of the public keys.
{
"transaction": "0a05746f6b656e12087472616e73666572180120c0843d2a20e98e8a6325730be6bf2644af83d5a0b004bb31c15858fedbd0ac2c1f89e2eece32270a0800000001000000001080dac4091a14f94b4fc46a71d7c913d89cbf30cc698f3ee3120d22003a003a405470fa9d437fe8e8e2936ed527d269e91f256ca0b5d2a62f863276c2329d02ad69309f3f6b29648a627577ebc8234cd61fb6e4fae757c98dcd2928ea7eec5f053a00"
}
{
"transaction": {
"module": "token",
"command": "transfer",
"nonce": "1",
"fee": "1000000",
"senderPublicKey": "e98e8a6325730be6bf2644af83d5a0b004bb31c15858fedbd0ac2c1f89e2eece",
"params": {
"tokenID": "0000000100000000",
"amount": "20000000",
"recipientAddress": "klygmmkgyc67n5jrpf2trgtxtc4yjg7bpu992chba",
"data": ""
},
"signatures": [
"",
"5470fa9d437fe8e8e2936ed527d269e91f256ca0b5d2a62f863276c2329d02ad69309f3f6b29648a627577ebc8234cd61fb6e4fae757c98dcd2928ea7eec5f05"
],
"id": "2d90fe6566f551a63f11861f7a70d3e0b6ee473f4d4c04364783fb3193bdbd2a"
}
}
Take the transaction hash above and send it to the second signatory. The second signatory should repeat the same process with a single change; update the transaction hash with the recently signed transaction hash, like this:
./bin/run transaction:sign 0a05746f6b656e12087472616e73666572180120c0843d2a20e98e8a6325730be6bf2644af83d5a0b004bb31c15858fedbd0ac2c1f89e2eece32270a0800000001000000001080dac4091a14f94b4fc46a71d7c913d89cbf30cc698f3ee3120d22003a003a405470fa9d437fe8e8e2936ed527d269e91f256ca0b5d2a62f863276c2329d02ad69309f3f6b29648a627577ebc8234cd61fb6e4fae757c98dcd2928ea7eec5f053a00 --optional-keys c61cd862a8b7f73857b248a4358a7b35c29ca273d76ba3819e8c54b62801f16e e98e8a6325730be6bf2644af83d5a0b004bb31c15858fedbd0ac2c1f89e2eece --chain-id 00000001 --json --offline --pretty
Enter the account’s passphrase:
? Please enter passphrase: [hidden]
{
"transaction": "0a05746f6b656e12087472616e73666572180120c0843d2a20e98e8a6325730be6bf2644af83d5a0b004bb31c15858fedbd0ac2c1f89e2eece32270a0800000001000000001080dac4091a14f94b4fc46a71d7c913d89cbf30cc698f3ee3120d22003a40422c376f6d1542e14c1f6fb993af1d6b1dd56506ce5da16835bf1194922d1aeaaa9424ae4fe39f2683a9f4eba297337b083e76d96293b1191ca4ee956f6f23033a405470fa9d437fe8e8e2936ed527d269e91f256ca0b5d2a62f863276c2329d02ad69309f3f6b29648a627577ebc8234cd61fb6e4fae757c98dcd2928ea7eec5f053a00"
}
{
"transaction": {
"module": "token",
"command": "transfer",
"nonce": "1",
"fee": "1000000",
"senderPublicKey": "e98e8a6325730be6bf2644af83d5a0b004bb31c15858fedbd0ac2c1f89e2eece",
"params": {
"tokenID": "0000000100000000",
"amount": "20000000",
"recipientAddress": "klygmmkgyc67n5jrpf2trgtxtc4yjg7bpu992chba",
"data": ""
},
"signatures": [
"422c376f6d1542e14c1f6fb993af1d6b1dd56506ce5da16835bf1194922d1aeaaa9424ae4fe39f2683a9f4eba297337b083e76d96293b1191ca4ee956f6f2303",
"5470fa9d437fe8e8e2936ed527d269e91f256ca0b5d2a62f863276c2329d02ad69309f3f6b29648a627577ebc8234cd61fb6e4fae757c98dcd2928ea7eec5f05"
],
"id": "9ce9fc9c1bd8ba72f611ad7e8282586e18f495a760add24097187f4e405b532e"
}
}
The transaction has the required number of signatures and is ready to be dry-run or to be sent to the node, which can only happen when the node is online. Once online, you can post the transaction to the node by either using the transaction:send command or txpool_postTransaction endpoint.
Once the transaction is executed, check the account balance of the sender (the multi-signature account) and the receiver. The balance of both accounts should have changed.
Option 2: Creating transactions offline with Klayr SDK
The create-multiSig-transaction.js script can be found in the multiSigtx-creation-signing folder. |
The process of creating and signing a transaction with Klayr SDK has already been explained in the following guides.
Beware that, whilst you can create and sign a transaction using Klayr SDK, it is not possible to dry-run or post a transaction without an up-and-running node. |