mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2025-11-28 15:45:50 +00:00
WIP revised tutorials IA
This commit is contained in:
@@ -1,707 +0,0 @@
|
||||
---
|
||||
html: assign-a-regular-key-pair.html
|
||||
parent: manage-account-settings.html
|
||||
seo:
|
||||
description: Authorize a second key pair to sign transactions from your account. This key pair can be changed or removed later.
|
||||
labels:
|
||||
- Security
|
||||
- Accounts
|
||||
---
|
||||
# Assign a Regular Key Pair
|
||||
|
||||
The XRP Ledger allows an account to authorize a secondary key pair, called a _[regular key pair](../../../concepts/accounts/cryptographic-keys.md)_, to sign future transactions. If the private key of a regular key pair is compromised, you can remove or replace it without changing the rest of your [account](../../../concepts/accounts/index.md) and re-establishing its relationships to other accounts. You can also rotate a regular key pair proactively. (Neither of those things is possible for the master key pair of an account, which is intrinsically linked to the account's address.)
|
||||
|
||||
For more information about master and regular key pairs, see [Cryptographic Keys](../../../concepts/accounts/cryptographic-keys.md).
|
||||
|
||||
This tutorial walks through the steps required to assign a regular key pair to your account:
|
||||
|
||||
1. [Generate a key pair](#1-generate-a-key-pair)
|
||||
2. [Assign the key pair to your account as a regular key pair](#2-assign-the-key-pair-to-your-account-as-a-regular-key-pair)
|
||||
3. [Verify the regular key pair](#3-verify-the-regular-key-pair)
|
||||
4. [Explore next steps](#see-also)
|
||||
|
||||
|
||||
## 1. Generate a Key Pair
|
||||
|
||||
Generate a key pair that you'll assign to your account as a regular key pair.
|
||||
|
||||
This key pair is the same data type as a master key pair, so you can generate it the same way: you can use the client library of your choice or use the [wallet_propose method][] of a server you run. This might look as follows:
|
||||
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
// Request:
|
||||
|
||||
{
|
||||
"command": "wallet_propose"
|
||||
}
|
||||
|
||||
// Response:
|
||||
|
||||
{
|
||||
"result": {
|
||||
"account_id": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
|
||||
"key_type": "secp256k1",
|
||||
"master_key": "KNEW BENT LYNN LED GAD BEN KENT SHAM HOBO RINK WALT ALLY",
|
||||
"master_seed": "sh8i92YRnEjJy3fpFkL8txQSCVo79",
|
||||
"master_seed_hex": "966C0F68643EFBA50D58D191D4CA8AA7",
|
||||
"public_key": "aBRNH5wUurfhZcoyR6nRwDSa95gMBkovBJ8V4cp1C1pM28H7EPL1",
|
||||
"public_key_hex": "03AEEFE1E8ED4BBC009DE996AC03A8C6B5713B1554794056C66E5B8D1753C7DD0E"
|
||||
},
|
||||
"status": "success",
|
||||
"type": "response"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
// Request:
|
||||
|
||||
{
|
||||
"method": "wallet_propose"
|
||||
}
|
||||
|
||||
// Response:
|
||||
|
||||
{
|
||||
"result": {
|
||||
"account_id": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
|
||||
"key_type": "secp256k1",
|
||||
"master_key": "KNEW BENT LYNN LED GAD BEN KENT SHAM HOBO RINK WALT ALLY",
|
||||
"master_seed": "sh8i92YRnEjJy3fpFkL8txQSCVo79",
|
||||
"master_seed_hex": "966C0F68643EFBA50D58D191D4CA8AA7",
|
||||
"public_key": "aBRNH5wUurfhZcoyR6nRwDSa95gMBkovBJ8V4cp1C1pM28H7EPL1",
|
||||
"public_key_hex": "03AEEFE1E8ED4BBC009DE996AC03A8C6B5713B1554794056C66E5B8D1753C7DD0E",
|
||||
"status": "success"
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```sh
|
||||
$ rippled wallet_propose
|
||||
|
||||
{
|
||||
"result" : {
|
||||
"account_id" : "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
|
||||
"key_type" : "secp256k1",
|
||||
"master_key" : "KNEW BENT LYNN LED GAD BEN KENT SHAM HOBO RINK WALT ALLY",
|
||||
"master_seed" : "sh8i92YRnEjJy3fpFkL8txQSCVo79",
|
||||
"master_seed_hex" : "966C0F68643EFBA50D58D191D4CA8AA7",
|
||||
"public_key" : "aBRNH5wUurfhZcoyR6nRwDSa95gMBkovBJ8V4cp1C1pM28H7EPL1",
|
||||
"public_key_hex" : "03AEEFE1E8ED4BBC009DE996AC03A8C6B5713B1554794056C66E5B8D1753C7DD0E",
|
||||
"status" : "success"
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Python" %}
|
||||
```py
|
||||
keypair = xrpl.wallet.Wallet.create()
|
||||
print("seed:", keypair.seed)
|
||||
print("classic address:", keypair.address)
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
```js
|
||||
const keypair = new xrpl.Wallet()
|
||||
console.log("seed:", keypair.seed)
|
||||
console.log("classic address:", keypair.classicAddress)
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Java" %}
|
||||
```java
|
||||
WalletFactory walletFactory = DefaultWalletFactory.getInstance();
|
||||
Wallet keypair = walletFactory.randomWallet(true).wallet();
|
||||
System.out.println(keypair);
|
||||
System.out.println(keypair.privateKey().get());
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
In the next step, you'll use the address from this response (`account_id` in the API response) to assign the key pair as a regular key pair to your account. Also, save the seed value from this key pair (`master_seed` in the API response) somewhere securely; you'll use that key to sign transactions later. (Everything else, you can forget about.)
|
||||
|
||||
|
||||
## 2. Assign the Key Pair to Your Account as a Regular Key Pair
|
||||
|
||||
Use a [SetRegularKey transaction][] to assign the key pair you generated in step 1 to your account as a regular key pair.
|
||||
|
||||
When assigning a regular key pair to your account for the first time, the SetRegularKey transaction requires signing with your account's master private key (secret). There are [several ways of securely signing transactions](../../../concepts/transactions/secure-signing.md), but this tutorial uses a local `rippled` server.
|
||||
|
||||
When you send later SetRegularKey transactions, you can sign using the existing regular private key to replace or [remove itself](change-or-remove-a-regular-key-pair.md). Note that you should still not submit your regular private key across the network.
|
||||
|
||||
|
||||
### Sign Your Transaction
|
||||
|
||||
{% partial file="/docs/_snippets/tutorial-sign-step.md" /%}
|
||||
|
||||
|
||||
Populate the request fields with the following values:
|
||||
|
||||
| Request Field | Value |
|
||||
|:--------------|:-------------------------------------------------------------|
|
||||
| `Account` | The address of your account. |
|
||||
| `RegularKey` | `account_id` generated in step 1. |
|
||||
| `secret` | `master_key`, `master_seed`, or `master_seed_hex` (master private key) for your account. |
|
||||
|
||||
|
||||
#### Request Format
|
||||
|
||||
An example of the request format:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"command": "sign",
|
||||
"tx_json": {
|
||||
"TransactionType": "SetRegularKey",
|
||||
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
|
||||
"RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7"
|
||||
},
|
||||
"secret": "ssCATR7CBvn4GLd1UuU2bqqQffHki"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"method": "sign",
|
||||
"params": [
|
||||
{
|
||||
"tx_json": {
|
||||
"TransactionType": "SetRegularKey",
|
||||
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
|
||||
"RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7"
|
||||
},
|
||||
"secret": "ssCATR7CBvn4GLd1UuU2bqqQffHki"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```sh
|
||||
#Syntax: sign secret tx_json
|
||||
rippled sign ssCATR7CBvn4GLd1UuU2bqqQffHki '{"TransactionType": "SetRegularKey", "Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93", "RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7"}'
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
|
||||
#### Response Format
|
||||
|
||||
An example of a successful response:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"tx_blob": "1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
|
||||
"tx_json": {
|
||||
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
|
||||
"Sequence": 4,
|
||||
"SigningPubKey": "0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
|
||||
"TransactionType": "SetRegularKey",
|
||||
"TxnSignature": "304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C26",
|
||||
"hash": "AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
|
||||
}
|
||||
},
|
||||
"status": "success",
|
||||
"type": "response"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"status": "success",
|
||||
"tx_blob": "1200052280000000240000000768400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402201453CA3D4D17F0EE3828B9E3D6ACF65327F5D4FC2BA30953CACF6CBCB4145E3502202F2154BED1D7462CAC1E3DBB31864E48C3BA0B3133ACA5E37EC54F0D0C339E2D8114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
|
||||
"tx_json": {
|
||||
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
|
||||
"Sequence": 4,
|
||||
"SigningPubKey": "0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
|
||||
"TransactionType": "SetRegularKey",
|
||||
"TxnSignature": "304402201453CA3D4D17F0EE3828B9E3D6ACF65327F5D4FC2BA30953CACF6CBCB4145E3502202F2154BED1D7462CAC1E3DBB31864E48C3BA0B3133ACA5E37EC54F0D0C339E2D",
|
||||
"hash": "AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```json
|
||||
{
|
||||
"result" : {
|
||||
"status" : "success",
|
||||
"tx_blob" : "1200052280000000240000000768400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402201453CA3D4D17F0EE3828B9E3D6ACF65327F5D4FC2BA30953CACF6CBCB4145E3502202F2154BED1D7462CAC1E3DBB31864E48C3BA0B3133ACA5E37EC54F0D0C339E2D8114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
|
||||
"tx_json" : {
|
||||
"Account" : "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
|
||||
"Fee" : "10",
|
||||
"Flags" : 2147483648,
|
||||
"RegularKey" : "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
|
||||
"Sequence" : 4,
|
||||
"SigningPubKey" : "0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
|
||||
"TransactionType" : "SetRegularKey",
|
||||
"TxnSignature" : "304402201453CA3D4D17F0EE3828B9E3D6ACF65327F5D4FC2BA30953CACF6CBCB4145E3502202F2154BED1D7462CAC1E3DBB31864E48C3BA0B3133ACA5E37EC54F0D0C339E2D",
|
||||
"hash" : "AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
The `sign` command response contains a `tx_blob` value, as shown above. The offline signing response contains a `signedTransaction` value. Both are signed binary representations (blobs) of the transaction.
|
||||
|
||||
Next, use the `submit` command to send the transaction blob (`tx_blob` or `signedTransaction`) to the network.
|
||||
|
||||
|
||||
### Submit Your Transaction
|
||||
|
||||
Take the `signedTransaction` value from the offline signing response or the `tx_blob` value from the `sign` command response and submit it as the `tx_blob` value using the [submit method][].
|
||||
|
||||
#### Request Format
|
||||
|
||||
An example of the request format:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"command": "submit",
|
||||
"tx_blob": "1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"method":"submit",
|
||||
"params": [
|
||||
{
|
||||
"tx_blob": "1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```sh
|
||||
#Syntax: submit tx_blob
|
||||
rippled submit 1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
|
||||
#### Response Format
|
||||
|
||||
An example of a successful response:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"engine_result": "tesSUCCESS",
|
||||
"engine_result_code": 0,
|
||||
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
|
||||
"tx_blob": "1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
|
||||
"tx_json": {
|
||||
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
|
||||
"Sequence": 4,
|
||||
"SigningPubKey": "0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
|
||||
"TransactionType": "SetRegularKey",
|
||||
"TxnSignature": "304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C26",
|
||||
"hash": "AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
|
||||
}
|
||||
},
|
||||
"status": "success",
|
||||
"type": "response"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"engine_result": "tesSUCCESS",
|
||||
"engine_result_code": 0,
|
||||
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
|
||||
"status": "success",
|
||||
"tx_blob": "1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
|
||||
"tx_json": {
|
||||
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
|
||||
"Sequence": 4,
|
||||
"SigningPubKey": "0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
|
||||
"TransactionType": "SetRegularKey",
|
||||
"TxnSignature": "304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C26",
|
||||
"hash": "AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```json
|
||||
{
|
||||
"result" : {
|
||||
"engine_result" : "tesSUCCESS",
|
||||
"engine_result_code" : 0,
|
||||
"engine_result_message" : "The transaction was applied. Only final in a validated ledger.",
|
||||
"status" : "success",
|
||||
"tx_blob" : "1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
|
||||
"tx_json" : {
|
||||
"Account" : "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
|
||||
"Fee" : "10",
|
||||
"Flags" : 2147483648,
|
||||
"RegularKey" : "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
|
||||
"Sequence" : 4,
|
||||
"SigningPubKey" : "0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
|
||||
"TransactionType" : "SetRegularKey",
|
||||
"TxnSignature" : "304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C26",
|
||||
"hash" : "AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
|
||||
Note that the response contains a `hash` of the transaction, which you can use to [look up the transaction's final outcome](../../../references/http-websocket-apis/public-api-methods/transaction-methods/tx.md).
|
||||
|
||||
|
||||
## 3. Verify the Regular Key Pair
|
||||
|
||||
At this point, the regular key pair is assigned to your account and you should be able to send transactions using the regular key pair. **To avoid losing control of your account,** it is important that you test your regular key before you take any additional steps such as [disabling the master key pair](disable-master-key-pair.md). If you make a mistake and lose access to your account, no one can restore it for you.
|
||||
|
||||
To verify that your account has the regular key pair set correctly, submit an [AccountSet transaction][] from your account, signing it with the regular private key you assigned to your account in step 2. As in step 1, this tutorial uses a local `rippled` server as a [way of securely signing transactions](../../../concepts/transactions/secure-signing.md).
|
||||
|
||||
|
||||
### Sign Your Transaction
|
||||
|
||||
{% partial file="/docs/_snippets/tutorial-sign-step.md" /%}
|
||||
|
||||
|
||||
Populate the request fields with the following values:
|
||||
|
||||
| Request Field | Value |
|
||||
|:--------------|:-------------------------------------------------------------|
|
||||
| `Account` | The address of your account. |
|
||||
| `secret` | `master_key`, `master_seed`, or `master_seed_hex` (regular private key) generated in step 1 and assigned to your account in step 2. |
|
||||
|
||||
|
||||
#### Request Format
|
||||
|
||||
Here's an example of the request format. Note that the request does not include any `AccountSet` options. This means that a successful transaction has no effect other than to confirm that the regular key pair is set correctly for your account (and to destroy the transaction cost).
|
||||
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"command": "sign",
|
||||
"tx_json": {
|
||||
"TransactionType": "AccountSet",
|
||||
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93"
|
||||
},
|
||||
"secret": "sh8i92YRnEjJy3fpFkL8txQSCVo79"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"method": "sign",
|
||||
"params": [
|
||||
{
|
||||
"tx_json": {
|
||||
"TransactionType": "AccountSet",
|
||||
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93"
|
||||
},
|
||||
"secret": "sh8i92YRnEjJy3fpFkL8txQSCVo79"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```sh
|
||||
#Syntax: sign secret tx_json
|
||||
rippled sign sh8i92YRnEjJy3fpFkL8txQSCVo79 '{"TransactionType": "AccountSet", "Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93"}'
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
|
||||
#### Response Format
|
||||
|
||||
An example of a successful response:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"tx_blob": "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
|
||||
"tx_json": {
|
||||
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 4,
|
||||
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||
"TransactionType": "AccountSet",
|
||||
"TxnSignature": "3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
|
||||
"hash": "D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
|
||||
}
|
||||
},
|
||||
"status": "success",
|
||||
"type": "response"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"status": "success",
|
||||
"tx_blob": "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
|
||||
"tx_json": {
|
||||
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 4,
|
||||
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||
"TransactionType": "AccountSet",
|
||||
"TxnSignature": "3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
|
||||
"hash": "D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```json
|
||||
{
|
||||
"result" : {
|
||||
"status" : "success",
|
||||
"tx_blob" : "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
|
||||
"tx_json" : {
|
||||
"Account" : "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
|
||||
"Fee" : "10",
|
||||
"Flags" : 2147483648,
|
||||
"Sequence" : 4,
|
||||
"SigningPubKey" : "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||
"TransactionType" : "AccountSet",
|
||||
"TxnSignature" : "3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
|
||||
"hash" : "D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
The `sign` command response contains a `tx_blob` value, as shown above. The offline signing response contains a `signedTransaction` value. Both are signed binary representations (blobs) of the transaction.
|
||||
|
||||
Next, use the `submit` command to send the transaction blob (`tx_blob` or `signedTransaction`) to the network.
|
||||
|
||||
|
||||
### Submit Your Transaction
|
||||
|
||||
Take the `signedTransaction` value from the offline signing response or the `tx_blob` value from the `sign` command response and submit it as the `tx_blob` value using the [submit method][].
|
||||
|
||||
#### Request Format
|
||||
|
||||
An example of the request format:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"command": "submit",
|
||||
"tx_blob": "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"method":"submit",
|
||||
"params": [
|
||||
{
|
||||
"tx_blob": "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```sh
|
||||
#Syntax: submit tx_blob
|
||||
rippled submit 1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
|
||||
#### Response Format
|
||||
|
||||
An example of a successful response:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"engine_result": "tesSUCCESS",
|
||||
"engine_result_code": 0,
|
||||
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
|
||||
"tx_blob": "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
|
||||
"tx_json": {
|
||||
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 4,
|
||||
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||
"TransactionType": "AccountSet",
|
||||
"TxnSignature": "3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
|
||||
"hash": "D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
|
||||
}
|
||||
},
|
||||
"status": "success",
|
||||
"type": "response"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"engine_result": "tesSUCCESS",
|
||||
"engine_result_code": 0,
|
||||
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
|
||||
"status": "success",
|
||||
"tx_blob": "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
|
||||
"tx_json": {
|
||||
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 4,
|
||||
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||
"TransactionType": "AccountSet",
|
||||
"TxnSignature": "3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
|
||||
"hash": "D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```json
|
||||
{
|
||||
"result" : {
|
||||
"engine_result" : "tesSUCCESS",
|
||||
"engine_result_code" : 0,
|
||||
"engine_result_message" : "The transaction was applied. Only final in a validated ledger.",
|
||||
"status" : "success",
|
||||
"tx_blob" : "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
|
||||
"tx_json" : {
|
||||
"Account" : "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
|
||||
"Fee" : "10",
|
||||
"Flags" : 2147483648,
|
||||
"Sequence" : 4,
|
||||
"SigningPubKey" : "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||
"TransactionType" : "AccountSet",
|
||||
"TxnSignature" : "3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
|
||||
"hash" : "D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
If the transaction fails with the following [result codes](../../../references/protocol/transactions/transaction-results/index.md), here are some things to check:
|
||||
|
||||
- **`tefBAD_AUTH`**: The regular key you signed your test transaction with doesn't match the regular key you set in the previous step. Check that the secret and address for your regular key pair match and double-check which values you used in each step.
|
||||
- **`tefBAD_AUTH_MASTER`** or **`temBAD_AUTH_MASTER`**: Your account doesn't have a regular key assigned. Check that the SetRegularKey transaction executed successfully. You can also use the [account_info method][] to confirm that your regular key is set in the `RegularKey` field as expected.
|
||||
|
||||
For possible causes of other result codes, see [Transaction Results](../../../references/protocol/transactions/transaction-results/index.md).
|
||||
|
||||
|
||||
## See Also
|
||||
|
||||
Now that you're familiar with the benefits of assigning a regular key pair to an account, consider taking a look at these related topics and tutorials:
|
||||
|
||||
- **Concepts:**
|
||||
- [Cryptographic Keys](../../../concepts/accounts/cryptographic-keys.md)
|
||||
- [Multi-Signing](../../../concepts/accounts/multi-signing.md)
|
||||
- [Issuing and Operational Addresses](../../../concepts/accounts/account-types.md)
|
||||
- **Tutorials:**
|
||||
- [Change or Remove a Regular Key Pair](change-or-remove-a-regular-key-pair.md)
|
||||
- [Set Up Multi-Signing](set-up-multi-signing.md)
|
||||
- [List XRP as an Exchange](../../../use-cases/defi/list-xrp-as-an-exchange.md)
|
||||
- **References:**
|
||||
- [wallet_propose method][]
|
||||
- [sign method][]
|
||||
- [SetRegularKey transaction][]
|
||||
- [AccountRoot object](../../../references/protocol/ledger-data/ledger-entry-types/accountroot.md) where the regular key is stored in the field `RegularKey`
|
||||
|
||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
||||
@@ -1,382 +0,0 @@
|
||||
---
|
||||
html: change-or-remove-a-regular-key-pair.html
|
||||
parent: manage-account-settings.html
|
||||
seo:
|
||||
description: Remove or update a regular key pair already authorized by your account.
|
||||
labels:
|
||||
- Security
|
||||
- Accounts
|
||||
---
|
||||
# Change or Remove a Regular Key Pair
|
||||
|
||||
The XRP Ledger allows an account to authorize a secondary key pair, called a _[regular key pair](../../../concepts/accounts/cryptographic-keys.md)_, to sign future transactions. If your [account](../../../concepts/accounts/index.md)'s regular key pair is compromised, or if you want to periodically change the regular key pair as a security measure, use a [SetRegularKey transaction][] to remove or change the regular key pair for your account.
|
||||
|
||||
For more information about master and regular key pairs, see [Cryptographic Keys](../../../concepts/accounts/cryptographic-keys.md).
|
||||
|
||||
|
||||
## Changing a Regular Key Pair
|
||||
|
||||
The steps to change your existing regular key pair are almost the same as the steps to [assign a regular key](assign-a-regular-key-pair.md) for the first time. You generate the key pair and assign it to your account as a regular key pair, overwriting the existing regular key pair. However, the main difference is that when changing the existing regular key pair, you can use the existing regular private key to replace itself; but when assigning a regular key pair to an account for the first time, you have to use the account's master private key to do it.
|
||||
|
||||
For more information about master and regular key pairs, see [Cryptographic Keys](../../../concepts/accounts/cryptographic-keys.md).
|
||||
|
||||
|
||||
## Removing a Regular Key Pair
|
||||
|
||||
If you want to remove a compromised regular key pair from your account, you don't need to generate a key pair first. Use a [SetRegularKey transaction][], omitting the `RegularKey` field. Note that the transaction fails if you don't have another way of signing for your account currently enabled (either the master key pair or a [signer list](../../../concepts/accounts/multi-signing.md)).
|
||||
|
||||
|
||||
When removing a regular key pair to your account, the `SetRegularKey` transaction requires signing by your account's master private key (secret) or existing regular key pair. Sending your master or regular private key anywhere is dangerous, so we keep transaction signing separate from transaction submission to the network.
|
||||
|
||||
### Sign Your Transaction
|
||||
|
||||
{% partial file="/docs/_snippets/tutorial-sign-step.md" /%}
|
||||
|
||||
|
||||
Populate the request fields with the following values:
|
||||
|
||||
| Request Field | Value |
|
||||
|:--------------|:-------------------------------------------------------------|
|
||||
| `Account` | The address of your account. |
|
||||
| `secret` | `master_key`, `master_seed`, or `master_seed_hex` (master or regular private key) for your account. |
|
||||
|
||||
|
||||
#### Request Format
|
||||
|
||||
An example of the request format:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"command": "sign",
|
||||
"tx_json": {
|
||||
"TransactionType": "SetRegularKey",
|
||||
"Account": "r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8"
|
||||
},
|
||||
"secret": "snoPBrXtMeMyMHUVTgbuqAfg1SUTb"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"method": "sign",
|
||||
"params": [
|
||||
{
|
||||
"secret" : "snoPBrXtMeMyMHUVTgbuqAfg1SUTb",
|
||||
"tx_json" : {
|
||||
"TransactionType" : "SetRegularKey",
|
||||
"Account" : "r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```sh
|
||||
#Syntax: sign secret tx_json
|
||||
rippled sign snoPBrXtMeMyMHUVTgbuqAfg1SUTb '{"TransactionType": "SetRegularKey", "Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93"}'
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
|
||||
#### Response Format
|
||||
|
||||
An example of a successful response:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"tx_blob": "1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
|
||||
"tx_json": {
|
||||
"Account": "r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 2,
|
||||
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||
"TransactionType": "SetRegularKey",
|
||||
"TxnSignature": "3045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E83",
|
||||
"hash": "59BCAB8E5B9D4597D6A7BFF22F6C555D0F41420599A2E126035B6AF19261AD97"
|
||||
}
|
||||
},
|
||||
"status": "success",
|
||||
"type": "response"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"status": "success",
|
||||
"tx_blob": "1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
|
||||
"tx_json": {
|
||||
"Account": "r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 2,
|
||||
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||
"TransactionType": "SetRegularKey",
|
||||
"TxnSignature": "3045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E83",
|
||||
"hash": "59BCAB8E5B9D4597D6A7BFF22F6C555D0F41420599A2E126035B6AF19261AD97"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```json
|
||||
{
|
||||
"result" : {
|
||||
"status" : "success",
|
||||
"tx_blob" : "1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
|
||||
"tx_json" : {
|
||||
"Account" : "r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
|
||||
"Fee" : "10",
|
||||
"Flags" : 2147483648,
|
||||
"Sequence" : 2,
|
||||
"SigningPubKey" : "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||
"TransactionType" : "SetRegularKey",
|
||||
"TxnSignature" : "3045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E83",
|
||||
"hash" : "59BCAB8E5B9D4597D6A7BFF22F6C555D0F41420599A2E126035B6AF19261AD97"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
The `sign` command response contains a `tx_blob` value, as shown above. The offline signing response contains a `signedTransaction` value. Both are signed binary representations (blobs) of the transaction.
|
||||
|
||||
Next, use the `submit` command to send the transaction blob (`tx_blob` or `signedTransaction`) to the network.
|
||||
|
||||
|
||||
### Submit Your Transaction
|
||||
|
||||
Take the `signedTransaction` value from the offline signing response or the `tx_blob` value from the `sign` command response and submit it as the `tx_blob` value using the [submit method][].
|
||||
|
||||
#### Request Format
|
||||
|
||||
An example of the request format:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"command": "submit",
|
||||
"tx_blob": "1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"method":"submit",
|
||||
"params":[
|
||||
{
|
||||
"tx_blob":"1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```sh
|
||||
#Syntax: submit tx_blob
|
||||
rippled submit 1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
|
||||
#### Response Format
|
||||
|
||||
An example of a successful response:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"engine_result": "tesSUCCESS",
|
||||
"engine_result_code": 0,
|
||||
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
|
||||
"tx_blob": "1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
|
||||
"tx_json": {
|
||||
"Account": "r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 2,
|
||||
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||
"TransactionType": "SetRegularKey",
|
||||
"TxnSignature": "3045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E83",
|
||||
"hash": "59BCAB8E5B9D4597D6A7BFF22F6C555D0F41420599A2E126035B6AF19261AD97"
|
||||
}
|
||||
},
|
||||
"status": "success",
|
||||
"type": "response"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"engine_result": "tesSUCCESS",
|
||||
"engine_result_code": 0,
|
||||
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
|
||||
"status": "success",
|
||||
"tx_blob": "1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
|
||||
"tx_json": {
|
||||
"Account": "r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 2,
|
||||
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||
"TransactionType": "SetRegularKey",
|
||||
"TxnSignature": "3045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E83",
|
||||
"hash": "59BCAB8E5B9D4597D6A7BFF22F6C555D0F41420599A2E126035B6AF19261AD97"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```json
|
||||
{
|
||||
"result" : {
|
||||
"engine_result" : "tesSUCCESS",
|
||||
"engine_result_code" : 0,
|
||||
"engine_result_message" : "The transaction was applied. Only final in a validated ledger.",
|
||||
"status" : "success",
|
||||
"tx_blob" : "1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
|
||||
"tx_json" : {
|
||||
"Account" : "r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
|
||||
"Fee" : "10",
|
||||
"Flags" : 2147483648,
|
||||
"Sequence" : 2,
|
||||
"SigningPubKey" : "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||
"TransactionType" : "SetRegularKey",
|
||||
"TxnSignature" : "3045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E83",
|
||||
"hash" : "59BCAB8E5B9D4597D6A7BFF22F6C555D0F41420599A2E126035B6AF19261AD97"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
The way to verify that regular key pair removal succeeded is to confirm that you can't send a transaction using the removed regular private key.
|
||||
|
||||
Here's an example error response for an [AccountSet transaction][] signed using the regular private key removed by the `SetRegularKey` transaction above.
|
||||
|
||||
|
||||
### Response Format
|
||||
|
||||
An example of a successful response:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"error": "badSecret",
|
||||
"error_code": 41,
|
||||
"error_message": "Secret does not match account.",
|
||||
"request": {
|
||||
"command": "submit",
|
||||
"secret": "snoPBrXtMeMyMHUVTgbuqAfg1SUTb",
|
||||
"tx_json": {
|
||||
"Account": "r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
|
||||
"TransactionType": "AccountSet"
|
||||
}
|
||||
},
|
||||
"status": "error",
|
||||
"type": "response"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"error": "badSecret",
|
||||
"error_code": 41,
|
||||
"error_message": "Secret does not match account.",
|
||||
"request": {
|
||||
"command": "submit",
|
||||
"secret": "snoPBrXtMeMyMHUVTgbuqAfg1SUTb",
|
||||
"tx_json": {
|
||||
"Account": "r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
|
||||
"TransactionType": "AccountSet"
|
||||
}
|
||||
},
|
||||
"status": "error"
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```json
|
||||
{
|
||||
"result" : {
|
||||
"error" : "badSecret",
|
||||
"error_code" : 41,
|
||||
"error_message" : "Secret does not match account.",
|
||||
"request" : {
|
||||
"command" : "submit",
|
||||
"secret" : "snoPBrXtMeMyMHUVTgbuqAfg1SUTb",
|
||||
"tx_json" : {
|
||||
"Account" : "r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
|
||||
"TransactionType" : "AccountSet"
|
||||
}
|
||||
},
|
||||
"status" : "error"
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
In some cases, you can even use the `SetRegularKey` transaction to send a [key reset transaction](../../../concepts/transactions/transaction-cost.md#key-reset-transaction) without paying the [transaction cost](../../../concepts/transactions/transaction-cost.md). The XRP Ledger's [transaction queue](../../../concepts/transactions/transaction-queue.md) prioritizes key reset transactions above other transactions even though the nominal transaction cost of a key reset transaction is zero.
|
||||
|
||||
|
||||
- **Concepts:**
|
||||
- [Cryptographic Keys](../../../concepts/accounts/cryptographic-keys.md)
|
||||
- [Multi-Signing](../../../concepts/accounts/multi-signing.md)
|
||||
- [Transaction Cost](../../../concepts/transactions/transaction-cost.md)
|
||||
- **Tutorials:**
|
||||
- [Change or Remove a Regular Key Pair](change-or-remove-a-regular-key-pair.md)
|
||||
- [Set Up Multi-Signing](set-up-multi-signing.md)
|
||||
- [List XRP as an Exchange](../../../use-cases/defi/list-xrp-as-an-exchange.md)
|
||||
- **References:**
|
||||
- [wallet_propose method][]
|
||||
- [sign method][]
|
||||
- [SetRegularKey transaction][]
|
||||
- [AccountRoot object](../../../references/protocol/ledger-data/ledger-entry-types/accountroot.md) where the regular key is stored in the field `RegularKey`
|
||||
|
||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
||||
@@ -1,502 +0,0 @@
|
||||
---
|
||||
html: disable-master-key-pair.html
|
||||
parent: manage-account-settings.html
|
||||
seo:
|
||||
description: Disable the master key that is mathematically associated with an address.
|
||||
labels:
|
||||
- Security
|
||||
- Accounts
|
||||
---
|
||||
# Disable Master Key Pair
|
||||
|
||||
This page describes how to disable the [master key pair](../../../concepts/accounts/cryptographic-keys.md) that is mathematically associated with an [account](../../../concepts/accounts/index.md)'s address. You should do this if your account's master key pair may have been compromised, or if you want to make [multi-signing](../../../concepts/accounts/multi-signing.md) the _only_ way to submit transactions from your account.
|
||||
|
||||
{% admonition type="danger" name="Warning" %}Disabling the master key pair removes one method of [authorizing transactions](../../../concepts/transactions/index.md#authorizing-transactions). You should be sure you can use one of the other ways of authorizing transactions, such as with a regular key or by multi-signing, before you disable the master key pair. (For example, if you [assigned a regular key pair](assign-a-regular-key-pair.md), make sure that you can successfully submit transactions with that regular key.) Due to the decentralized nature of the XRP Ledger, no one can restore access to your account if you cannot use the remaining ways of authorizing transactions.{% /admonition %}
|
||||
|
||||
**To disable the master key pair, you must use the master key pair.** However, you can _re-enable_ the master key pair using any other method of authorizing transactions.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
To disable the master key pair for an account, you must meet the following prerequisites:
|
||||
|
||||
- You must have an XRP Ledger [account](../../../concepts/accounts/index.md) and you must be able to sign and submit transactions from that account using the master key pair. See also: [Set Up Secure Signing](../../../concepts/transactions/secure-signing.md). Two common ways this can work are:
|
||||
- You know the account's master seed value. A seed value is commonly represented as a [base58][] value starting with "s", such as `sn3nxiW7v8KXzPzAqzyHXbSSKNuN9`.
|
||||
- Or, you use a [dedicated signing device](../../../concepts/transactions/secure-signing.md#use-a-dedicated-signing-device) that stores the seed value securely, so you don't need to know it.
|
||||
- Your account must have at least one method of authorizing transactions other than the master key pair. In other words, you must do one or both of the following:
|
||||
- [Assign a Regular Key Pair](assign-a-regular-key-pair.md).
|
||||
- [Set Up Multi-Signing](set-up-multi-signing.md).
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Construct Transaction JSON
|
||||
|
||||
Prepare an [AccountSet transaction][] from your account with the field `"SetValue": 4`. This is the value for the AccountSet flag "Disable Master" (`asfDisableMaster`). The only other required fields for this transaction are the required [common fields](../../../references/protocol/transactions/common-fields.md). For example, if you leave off the [auto-fillable fields](../../../references/protocol/transactions/common-fields.md#auto-fillable-fields), the following transaction instructions are enough:
|
||||
|
||||
```json
|
||||
{
|
||||
"TransactionType": "AccountSet",
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"SetFlag": 4
|
||||
}
|
||||
```
|
||||
|
||||
{% admonition type="success" name="Tip" %}It is strongly recommended to also provide the `LastLedgerSequence` field so that you can [reliably get the outcome of the transaction in a predictable amount of time](../../../concepts/transactions/reliable-transaction-submission.md).{% /admonition %}
|
||||
|
||||
### 2. Sign Transaction
|
||||
|
||||
You must use the **master key pair** to sign the transaction.
|
||||
|
||||
{% admonition type="danger" name="Warning" %}Do not submit your secret to a server you don't control, and do not send it over the network unencrypted. These examples assume you are using a [local `rippled` server](../../../concepts/transactions/secure-signing.md#run-rippled-locally). You should adapt these instructions if you are using another [secure signing configuration](../../../concepts/transactions/secure-signing.md).{% /admonition %}
|
||||
|
||||
#### Example Request
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"command": "sign",
|
||||
"tx_json": {
|
||||
"TransactionType": "AccountSet",
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"SetFlag": 4
|
||||
},
|
||||
"secret": "s████████████████████████████"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"method": "sign",
|
||||
"params": [
|
||||
{
|
||||
"tx_json": {
|
||||
"TransactionType": "AccountSet",
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"SetFlag": 4
|
||||
},
|
||||
"secret": "s████████████████████████████"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```sh
|
||||
$ rippled sign s████████████████████████████ '{"TransactionType":"AccountSet",
|
||||
"Account":"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", "SetFlag":4}'
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
#### Example Response
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"deprecated": "This command has been deprecated and will be removed in a future version of the server. Please migrate to a standalone signing tool.",
|
||||
"tx_blob": "1200032280000000240000017C20210000000468400000000000000A732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7446304402204457A890BC06F48061F8D61042975702B57EBEF3EA2C7C484DFE38CFD42EA11102202505A7C62FF41E68FDE10271BADD75BD66D54B2F96A326BE487A2728A352442D81144B4E9C06F24296074F7BC48F92A97916C6DC5EA9",
|
||||
"tx_json": {
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 380,
|
||||
"SetFlag": 4,
|
||||
"SigningPubKey": "03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB",
|
||||
"TransactionType": "AccountSet",
|
||||
"TxnSignature": "304402204457A890BC06F48061F8D61042975702B57EBEF3EA2C7C484DFE38CFD42EA11102202505A7C62FF41E68FDE10271BADD75BD66D54B2F96A326BE487A2728A352442D",
|
||||
"hash": "327FD263132A4D08170E1B01FE1BB2E21D0126CE58165C97A9173CA9551BCD70"
|
||||
}
|
||||
},
|
||||
"status": "success",
|
||||
"type": "response"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"deprecated": "This command has been deprecated and will be removed in a future version of the server. Please migrate to a standalone signing tool.",
|
||||
"status": "success",
|
||||
"tx_blob": "1200032280000000240000017C20210000000468400000000000000A732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7446304402204457A890BC06F48061F8D61042975702B57EBEF3EA2C7C484DFE38CFD42EA11102202505A7C62FF41E68FDE10271BADD75BD66D54B2F96A326BE487A2728A352442D81144B4E9C06F24296074F7BC48F92A97916C6DC5EA9",
|
||||
"tx_json": {
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 380,
|
||||
"SetFlag": 4,
|
||||
"SigningPubKey": "03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB",
|
||||
"TransactionType": "AccountSet",
|
||||
"TxnSignature": "304402204457A890BC06F48061F8D61042975702B57EBEF3EA2C7C484DFE38CFD42EA11102202505A7C62FF41E68FDE10271BADD75BD66D54B2F96A326BE487A2728A352442D",
|
||||
"hash": "327FD263132A4D08170E1B01FE1BB2E21D0126CE58165C97A9173CA9551BCD70"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```sh
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
2020-Feb-13 00:13:24.783570867 HTTPClient:NFO Connecting to 127.0.0.1:5005
|
||||
|
||||
{
|
||||
"result" : {
|
||||
"deprecated" : "This command has been deprecated and will be removed in a future version of the server. Please migrate to a standalone signing tool.",
|
||||
"status" : "success",
|
||||
"tx_blob" : "1200032280000000240000017C20210000000468400000000000000A732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7446304402204457A890BC06F48061F8D61042975702B57EBEF3EA2C7C484DFE38CFD42EA11102202505A7C62FF41E68FDE10271BADD75BD66D54B2F96A326BE487A2728A352442D81144B4E9C06F24296074F7BC48F92A97916C6DC5EA9",
|
||||
"tx_json" : {
|
||||
"Account" : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Fee" : "10",
|
||||
"Flags" : 2147483648,
|
||||
"Sequence" : 380,
|
||||
"SetFlag" : 4,
|
||||
"SigningPubKey" : "03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB",
|
||||
"TransactionType" : "AccountSet",
|
||||
"TxnSignature" : "304402204457A890BC06F48061F8D61042975702B57EBEF3EA2C7C484DFE38CFD42EA11102202505A7C62FF41E68FDE10271BADD75BD66D54B2F96A326BE487A2728A352442D",
|
||||
"hash" : "327FD263132A4D08170E1B01FE1BB2E21D0126CE58165C97A9173CA9551BCD70"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
Look for `"status": "success"` to indicate that the server successfully signed the transaction. If you get `"status": "error"` instead, check the `error` and `error_message` fields for more information. Some common possibilities include:
|
||||
|
||||
- `"error": "badSecret"` usually means you made a typo in the `secret` of the request.
|
||||
- `"error": "masterDisabled"` means this address's master key pair is _already_ disabled.
|
||||
|
||||
Take note of the `tx_blob` value from the response. This is a signed transaction binary you can submit to the network.
|
||||
|
||||
### 3. Submit Transaction
|
||||
|
||||
Submit the signed transaction blob from the previous step to the XRP Ledger.
|
||||
|
||||
#### Example Request
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"command": "submit",
|
||||
"tx_blob": "1200032280000000240000017C20210000000468400000000000000A732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7446304402204457A890BC06F48061F8D61042975702B57EBEF3EA2C7C484DFE38CFD42EA11102202505A7C62FF41E68FDE10271BADD75BD66D54B2F96A326BE487A2728A352442D81144B4E9C06F24296074F7BC48F92A97916C6DC5EA9"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"method":"submit",
|
||||
"params": [
|
||||
{
|
||||
"tx_blob": "1200032280000000240000017C20210000000468400000000000000A732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7446304402204457A890BC06F48061F8D61042975702B57EBEF3EA2C7C484DFE38CFD42EA11102202505A7C62FF41E68FDE10271BADD75BD66D54B2F96A326BE487A2728A352442D81144B4E9C06F24296074F7BC48F92A97916C6DC5EA9"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```
|
||||
$ rippled submit 1200032280000000240000017C20210000000468400000000000000A732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7446304402204457A890BC06F48061F8D61042975702B57EBEF3EA2C7C484DFE38CFD42EA11102202505A7C62FF41E68FDE10271BADD75BD66D54B2F96A326BE487A2728A352442D81144B4E9C06F24296074F7BC48F92A97916C6DC5EA9
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
#### Example Response
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"engine_result" : "tesSUCCESS",
|
||||
"engine_result_code" : 0,
|
||||
"engine_result_message" : "The transaction was applied. Only final in a validated ledger.",
|
||||
"tx_blob" : "1200032280000000240000017C20210000000468400000000000000A732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7446304402204457A890BC06F48061F8D61042975702B57EBEF3EA2C7C484DFE38CFD42EA11102202505A7C62FF41E68FDE10271BADD75BD66D54B2F96A326BE487A2728A352442D81144B4E9C06F24296074F7BC48F92A97916C6DC5EA9",
|
||||
"tx_json" : {
|
||||
"Account" : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Fee" : "10",
|
||||
"Flags" : 2147483648,
|
||||
"Sequence" : 380,
|
||||
"SetFlag" : 4,
|
||||
"SigningPubKey" : "03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB",
|
||||
"TransactionType" : "AccountSet",
|
||||
"TxnSignature" : "304402204457A890BC06F48061F8D61042975702B57EBEF3EA2C7C484DFE38CFD42EA11102202505A7C62FF41E68FDE10271BADD75BD66D54B2F96A326BE487A2728A352442D",
|
||||
"hash" : "327FD263132A4D08170E1B01FE1BB2E21D0126CE58165C97A9173CA9551BCD70"
|
||||
}
|
||||
},
|
||||
"status": "success",
|
||||
"type": "response"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"result" : {
|
||||
"engine_result" : "tesSUCCESS",
|
||||
"engine_result_code" : 0,
|
||||
"engine_result_message" : "The transaction was applied. Only final in a validated ledger.",
|
||||
"status" : "success",
|
||||
"tx_blob" : "1200032280000000240000017C20210000000468400000000000000A732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7446304402204457A890BC06F48061F8D61042975702B57EBEF3EA2C7C484DFE38CFD42EA11102202505A7C62FF41E68FDE10271BADD75BD66D54B2F96A326BE487A2728A352442D81144B4E9C06F24296074F7BC48F92A97916C6DC5EA9",
|
||||
"tx_json" : {
|
||||
"Account" : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Fee" : "10",
|
||||
"Flags" : 2147483648,
|
||||
"Sequence" : 380,
|
||||
"SetFlag" : 4,
|
||||
"SigningPubKey" : "03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB",
|
||||
"TransactionType" : "AccountSet",
|
||||
"TxnSignature" : "304402204457A890BC06F48061F8D61042975702B57EBEF3EA2C7C484DFE38CFD42EA11102202505A7C62FF41E68FDE10271BADD75BD66D54B2F96A326BE487A2728A352442D",
|
||||
"hash" : "327FD263132A4D08170E1B01FE1BB2E21D0126CE58165C97A9173CA9551BCD70"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```sh
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
2020-Feb-13 00:25:49.361743460 HTTPClient:NFO Connecting to 127.0.0.1:5005
|
||||
|
||||
{
|
||||
"result" : {
|
||||
"engine_result" : "tesSUCCESS",
|
||||
"engine_result_code" : 0,
|
||||
"engine_result_message" : "The transaction was applied. Only final in a validated ledger.",
|
||||
"status" : "success",
|
||||
"tx_blob" : "1200032280000000240000017C20210000000468400000000000000A732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7446304402204457A890BC06F48061F8D61042975702B57EBEF3EA2C7C484DFE38CFD42EA11102202505A7C62FF41E68FDE10271BADD75BD66D54B2F96A326BE487A2728A352442D81144B4E9C06F24296074F7BC48F92A97916C6DC5EA9",
|
||||
"tx_json" : {
|
||||
"Account" : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Fee" : "10",
|
||||
"Flags" : 2147483648,
|
||||
"Sequence" : 380,
|
||||
"SetFlag" : 4,
|
||||
"SigningPubKey" : "03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB",
|
||||
"TransactionType" : "AccountSet",
|
||||
"TxnSignature" : "304402204457A890BC06F48061F8D61042975702B57EBEF3EA2C7C484DFE38CFD42EA11102202505A7C62FF41E68FDE10271BADD75BD66D54B2F96A326BE487A2728A352442D",
|
||||
"hash" : "327FD263132A4D08170E1B01FE1BB2E21D0126CE58165C97A9173CA9551BCD70"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
If the transaction fails with the result `tecNO_ALTERNATIVE_KEY`, your account does not have another method of authorizing transactions currently enabled. You must [assign a regular key pair](assign-a-regular-key-pair.md) or [set up multi-signing](set-up-multi-signing.md), then try again to disable the master key pair.
|
||||
|
||||
|
||||
### 4. Wait for validation
|
||||
|
||||
{% raw-partial file="/docs/_snippets/wait-for-validation.md" /%}
|
||||
|
||||
### 5. Confirm Account Flags
|
||||
|
||||
Confirm that your account's master key is disabled using the [account_info method][]. Be sure to specify the following parameters:
|
||||
|
||||
| Field | Value |
|
||||
|:---------------|:------------------------------------------------------------|
|
||||
| `account` | The address of your account. |
|
||||
| `ledger_index` | `"validated"` to get results from the latest validated ledger version. |
|
||||
|
||||
#### Example Request
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"command": "account_info",
|
||||
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"ledger_index": "validated"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"method": "account_info",
|
||||
"params": [{
|
||||
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"ledger_index": "validated"
|
||||
}]
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```sh
|
||||
rippled account_info rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn validated
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
|
||||
#### Example Response
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="WebSocket" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"account_data": {
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"AccountTxnID": "327FD263132A4D08170E1B01FE1BB2E21D0126CE58165C97A9173CA9551BCD70",
|
||||
"Balance": "423013688",
|
||||
"Domain": "6D64756F31332E636F6D",
|
||||
"EmailHash": "98B4375E1D753E5B91627516F6D70977",
|
||||
"Flags": 9633792,
|
||||
"LedgerEntryType": "AccountRoot",
|
||||
"MessageKey": "0000000000000000000000070000000300",
|
||||
"OwnerCount": 9,
|
||||
"PreviousTxnID": "327FD263132A4D08170E1B01FE1BB2E21D0126CE58165C97A9173CA9551BCD70",
|
||||
"PreviousTxnLgrSeq": 53391321,
|
||||
"RegularKey": "rD9iJmieYHn8jTtPjwwkW2Wm9sVDvPXLoJ",
|
||||
"Sequence": 381,
|
||||
"TransferRate": 4294967295,
|
||||
"index": "13F1A95D7AAB7108D5CE7EEAF504B2894B8C674E6D68499076441C4837282BF8",
|
||||
"urlgravatar": "http://www.gravatar.com/avatar/98b4375e1d753e5b91627516f6d70977"
|
||||
},
|
||||
"ledger_hash": "A90CEBD4AEDA24470AAC5CD307B6D26267ACE79C03669A0A0B8C41ACAEDAA6F0",
|
||||
"ledger_index": 53391576,
|
||||
"validated": true
|
||||
},
|
||||
"status": "success",
|
||||
"type": "response"
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="JSON-RPC" %}
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"account_data": {
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"AccountTxnID": "327FD263132A4D08170E1B01FE1BB2E21D0126CE58165C97A9173CA9551BCD70",
|
||||
"Balance": "423013688",
|
||||
"Domain": "6D64756F31332E636F6D",
|
||||
"EmailHash": "98B4375E1D753E5B91627516F6D70977",
|
||||
"Flags": 9633792,
|
||||
"LedgerEntryType": "AccountRoot",
|
||||
"MessageKey": "0000000000000000000000070000000300",
|
||||
"OwnerCount": 9,
|
||||
"PreviousTxnID": "327FD263132A4D08170E1B01FE1BB2E21D0126CE58165C97A9173CA9551BCD70",
|
||||
"PreviousTxnLgrSeq": 53391321,
|
||||
"RegularKey": "rD9iJmieYHn8jTtPjwwkW2Wm9sVDvPXLoJ",
|
||||
"Sequence": 381,
|
||||
"TransferRate": 4294967295,
|
||||
"index": "13F1A95D7AAB7108D5CE7EEAF504B2894B8C674E6D68499076441C4837282BF8",
|
||||
"urlgravatar": "http://www.gravatar.com/avatar/98b4375e1d753e5b91627516f6d70977"
|
||||
},
|
||||
"ledger_hash": "4C4AC95149B13B539369998675FE6860C52695E83658366F18872181C9F1AEBF",
|
||||
"ledger_index": 53391589,
|
||||
"status": "success",
|
||||
"validated": true
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```sh
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
2020-Feb-13 00:41:38.642710734 HTTPClient:NFO Connecting to 127.0.0.1:5005
|
||||
|
||||
{
|
||||
"result" : {
|
||||
"account_data" : {
|
||||
"Account" : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"AccountTxnID" : "327FD263132A4D08170E1B01FE1BB2E21D0126CE58165C97A9173CA9551BCD70",
|
||||
"Balance" : "423013688",
|
||||
"Domain" : "6D64756F31332E636F6D",
|
||||
"EmailHash" : "98B4375E1D753E5B91627516F6D70977",
|
||||
"Flags" : 9633792,
|
||||
"LedgerEntryType" : "AccountRoot",
|
||||
"MessageKey" : "0000000000000000000000070000000300",
|
||||
"OwnerCount" : 9,
|
||||
"PreviousTxnID" : "327FD263132A4D08170E1B01FE1BB2E21D0126CE58165C97A9173CA9551BCD70",
|
||||
"PreviousTxnLgrSeq" : 53391321,
|
||||
"RegularKey" : "rD9iJmieYHn8jTtPjwwkW2Wm9sVDvPXLoJ",
|
||||
"Sequence" : 381,
|
||||
"TransferRate" : 4294967295,
|
||||
"index" : "13F1A95D7AAB7108D5CE7EEAF504B2894B8C674E6D68499076441C4837282BF8",
|
||||
"urlgravatar" : "http://www.gravatar.com/avatar/98b4375e1d753e5b91627516f6d70977"
|
||||
},
|
||||
"ledger_hash" : "BBA4034FB5D5D89987E0987A9491E7B62B16708EECFF04CDB0367BD4D28EB1B5",
|
||||
"ledger_index" : 53391568,
|
||||
"status" : "success",
|
||||
"validated" : true
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
|
||||
In the response's `account_data` object, compare the `Flags` field with the `lsfDisableMaster` flag value (`0x00100000` in hex, or `1048576` in decimal) using bitwise-AND (the `&` operator in most common programming languages).
|
||||
|
||||
Example code:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
```js
|
||||
// Assuming the JSON-RPC response above is saved as account_info_response
|
||||
const lsfDisableMaster = 0x00100000;
|
||||
let acct_flags = account_info_response.result.account_data.Flags;
|
||||
if ((lsfDisableMaster & acct_flags) === lsfDisableMaster) {
|
||||
console.log("Master key pair is DISABLED");
|
||||
} else {
|
||||
console.log("Master key pair is available for use");
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Python" %}
|
||||
```python
|
||||
# Assuming the JSON-RPC response above is parsed from JSON
|
||||
# and saved as the variable account_info_response
|
||||
lsfDisableMaster = 0x00100000
|
||||
acct_flags = account_info_response["result"]["account_data"]["Flags"]
|
||||
if lsfDisableMaster & acct_flags == lsfDisableMaster:
|
||||
print("Master key pair is DISABLED")
|
||||
else:
|
||||
print("Master key pair is available for use")
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
This operation has only two possible outcomes:
|
||||
|
||||
- A nonzero result, equal to the `lsfDisableMaster` value, indicates **the master key has been successfully disabled**.
|
||||
- A zero result indicates the account's master key is not disabled.
|
||||
|
||||
If the result does not match your expectations, check whether the transaction you sent in the previous steps has executed successfully. It should be the most recent entry in the account's transaction history ([account_tx method][]) and it should have the result code `tesSUCCESS`. If you see any other [result code](../../../references/protocol/transactions/transaction-results/index.md), the transaction was not executed successfully. Depending on the cause of the error, you may want to restart these steps from the beginning.
|
||||
|
||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
||||
@@ -1,345 +0,0 @@
|
||||
---
|
||||
html: offline-account-setup.html
|
||||
parent: manage-account-settings.html
|
||||
seo:
|
||||
description: Set up an XRP Ledger account using an air-gapped, offline machine to store its cryptographic keys.
|
||||
labels:
|
||||
- Accounts
|
||||
- Security
|
||||
---
|
||||
# Offline Account Setup Tutorial
|
||||
|
||||
A highly secure [signing configuration](../../../concepts/transactions/secure-signing.md) involves keeping an XRP Ledger [account](../../../concepts/accounts/index.md)'s [cryptographic keys](../../../concepts/accounts/cryptographic-keys.md) securely on an offline, air-gapped machine. After setting up this configuration, you can sign a variety of transactions, transfer only the signed transactions to an online computer, and submit them to the XRP Ledger network without ever exposing your secret key to malicious actors online.
|
||||
|
||||
{% admonition type="warning" name="Caution" %}Proper operational security is necessary to protect your offline machine. For example, the offline machine must be physically located where untrusted people cannot get access to it, and trusted operators must be careful not to transfer compromised software onto the machine. (For example, do not use a USB drive that was previously attached to a network-connected computer.){% /admonition %}
|
||||
|
||||
## Prerequisites
|
||||
|
||||
To use offline signing, you must meet the following prerequisites:
|
||||
|
||||
- You must have one computer to use as an offline machine. This machine must be set up with a [supported operating system](../../../infrastructure/installation/system-requirements.md). See your operating system's support for offline setup instructions. (For example, [Red Hat Enterprise Linux DVD ISO installation instructions](https://access.redhat.com/solutions/7227).) Be sure that the software and physical media you use are not infected with malware.
|
||||
- You must have a separate computer to use as an online machine. This machine does not need to run `rippled` but it must be able to connect to the XRP Ledger network and receive information about the state of the shared ledger. For example, you can use a [WebSocket connection to a public server](../../http-websocket-apis/build-apps/get-started.md).
|
||||
- You must have a secure way to transfer signed transaction binary data from the offline machine to the online machine.
|
||||
- One way to do this is with a QR code generator on the offline machine, and a QR code scanner on the online machine. (In this case, your "online machine" could be a handheld device such as a smartphone.)
|
||||
- Another way is to copy files from the offline machine to an online machine using physical media. If you use this method, be sure not to use physical media that could infect your offline machine with malicious software. (For example, do not reuse the same USB drive on both online and offline machines.)
|
||||
- You _could_ manually type the data onto the online machine, but doing so would be tedious and error-prone.
|
||||
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Set up offline machine
|
||||
|
||||
The offline machine needs secure persistent storage (for example, an encrypted disk drive) and a way to [sign transactions](../../../concepts/transactions/secure-signing.md). For an offline machine, you typically use physical media to transfer any necessary software after downloading it from an online machine. You must be sure that the online machine, the physical media, and the software itself are not infected with malware.
|
||||
|
||||
Software options for signing on the XRP Ledger include:
|
||||
|
||||
- [Install `rippled`](../../../infrastructure/installation/index.md) from a package (`.deb` or `.rpm` depending on which Linux distribution you use) file, then [run it in stand-alone mode](../../../concepts/networks-and-servers/rippled-server-modes.md).
|
||||
- Install [xrpl.js](https://github.com/XRPLF/xrpl.js/) (or another [client library](../../../references/client-libraries.md)) and its dependencies offline. The Yarn package manager, for example, has [recommended instructions for offline usage](https://yarnpkg.com/blog/2016/11/24/offline-mirror/).
|
||||
- See also: [Set Up Secure Signing](../../../concepts/transactions/secure-signing.md)
|
||||
|
||||
You may want to set up custom software to help construct transaction instructions on the offline machine. For example, your software may track what [sequence number][] to use next, or contain preset templates for certain types of transactions you expect to send.
|
||||
|
||||
|
||||
### 2. Generate cryptographic keys
|
||||
|
||||
On the **offline machine**, generate a pair of [cryptographic keys](../../../concepts/accounts/cryptographic-keys.md) to be used with your account. Be sure to generate the keys with a securely random procedure, not from a short passphrase or some other source that does not have enough entropy. For example, you can use the [wallet_propose method][] of `rippled`:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="rippled Commandline" %}
|
||||
```sh
|
||||
$ ./rippled wallet_propose
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
2019-Dec-09 22:58:24.110862955 HTTPClient:NFO Connecting to 127.0.0.1:5005
|
||||
|
||||
{
|
||||
"result" : {
|
||||
"account_id" : "r4MRc4BArFPXmiDjmLdrufyFManSYhfKE6",
|
||||
"key_type" : "secp256k1",
|
||||
"master_key" : "JANE GIBE LIST TEND NU RUDE JIG PA FLOG DEFT SAME NASH",
|
||||
"master_seed" : "shYHSiJod8CLPTj1SNJ2PdUFj4pFk",
|
||||
"master_seed_hex" : "8465FDB80B2E2620A7D58274C26291A0",
|
||||
"public_key" : "aBQLW8imt7VChRJU1NMVCB7fE3jSL3VNEgLDKf88ygAhnfuZh3oo",
|
||||
"public_key_hex" : "03396074ED4B8155ACF9A8DC3665EFA53B5CFA0A1E91C3879303D37721EB222644",
|
||||
"status" : "success"
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
Take note of the following values:
|
||||
|
||||
- **`account_id`**. This is the address associated with the key pair, which becomes your **[account](../../../concepts/accounts/index.md) address** in the XRP Ledger after you fund it with XRP (later in this process). It is safe to share your `account_id` publicly.
|
||||
- **`master_seed`**. This is the secret seed value for the key pair, which you'll use to sign transactions from the account. For best security, encrypt this value before writing it to disk on the offline machine. As an encryption key, use a secure passphrase that human operators can memorize or write down somewhere physically secure, such as a [diceware passphrase](https://theworld.com/~reinhold/diceware.html) created with properly weighted dice. You may also want to use a physical security key as a second factor. The extent of the precautions to take at this stage is up to you.
|
||||
- **`key_type`**. This is the cryptographic algorithm used for this key pair. You need to know what type of key pair you have. The default in `rippled` is `secp256k1`, but some client libraries use `Ed25519` by default.
|
||||
|
||||
**Do not** share the `master_key`, `master_seed`, or `master_seed_hex` values anywhere. Any of these can be used to reconstruct the private key associated with this address.
|
||||
|
||||
<!-- SPELLING_IGNORE: diceware -->
|
||||
|
||||
|
||||
|
||||
### 3. Fund the new address
|
||||
|
||||
From an online machine, send enough XRP to the **account address** you noted in step 1. For more information, see [Creating Accounts](../../../concepts/accounts/index.md#creating-accounts).
|
||||
|
||||
{% admonition type="success" name="Tip" %}For testing purposes, you can use the [Testnet Faucet](/resources/dev-tools/xrp-faucets) to get a new account with Test XRP, then use that account to fund the address you generated offline.{% /admonition %}
|
||||
|
||||
|
||||
|
||||
### 4. Confirm account details
|
||||
|
||||
When the transaction from the previous step is validated by consensus, your account has been created. From the online machine, you can confirm the status of the account with the [account_info method][]. Make sure the response contains `"validated": true` to confirm that this result is final.
|
||||
|
||||
Take note of the sequence number of the account, in the `Sequence` field of the result's `account_data`. You need to know the sequence number to sign transactions from the account in future steps.
|
||||
|
||||
The `Sequence` number of a newly-funded account matches the [ledger index][] when it was funded. Before the [DeletableAccounts amendment](/resources/known-amendments.md#deletableaccounts), a newly funded account's `Sequence` number was always 1.
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="rippled Commandline" %}
|
||||
```sh
|
||||
$ ./rippled account_info rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn
|
||||
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
2019-Dec-11 01:06:21.728637950 HTTPClient:NFO Connecting to 127.0.0.1:5005
|
||||
{
|
||||
"result" : {
|
||||
"account_data" : {
|
||||
"Account" : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Balance" : "5000000000000",
|
||||
"Flags" : 0,
|
||||
"LedgerEntryType" : "AccountRoot",
|
||||
"OwnerCount" : 0,
|
||||
"PreviousTxnID" : "00C5B713B11DA775C6F932D38CE162C16FA88B7269BAFC6FDF4C6ADB74419670",
|
||||
"PreviousTxnLgrSeq" : 3,
|
||||
"Sequence" : 1,
|
||||
"index" : "13F1A95D7AAB7108D5CE7EEAF504B2894B8C674E6D68499076441C4837282BF8"
|
||||
},
|
||||
"ledger_current_index" : 4,
|
||||
"status" : "success",
|
||||
"validated" : false
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
### 5. Enter the sequence number on the offline machine.
|
||||
|
||||
Save the account's starting sequence number on the offline machine. Whenever you prepare a transaction using the offline machine, use the saved sequence number, then increase the sequence number by 1 and save the new value.
|
||||
|
||||
You can prepare several transactions in advance this way, then transfer the signed transactions to the online machine all at once and submit them. As long as each transaction is validly formed and pays a high enough [transaction cost](../../../concepts/transactions/transaction-cost.md), the XRP Ledger network should eventually include those transactions in validated ledgers, keeping the account's sequence number in the shared XRP Ledger in sync with the "current" sequence number you are tracking on the offline machine. (Most transactions get a final, validated result within 15 seconds or less after being submitted to the network.)
|
||||
|
||||
Optionally, save the current ledger index to the offline machine. You can use this value to choose an appropriate `LastLedgerSequence` value for upcoming transactions.
|
||||
|
||||
|
||||
|
||||
### 6. Sign initial setup transactions, if any.
|
||||
|
||||
On the offline machine, prepare and sign transactions for configuring your account. The details depend on how you intend to use your account. Some examples of things you might want to do include:
|
||||
|
||||
- [Assign a regular key pair](assign-a-regular-key-pair.md) that you can rotate regularly.
|
||||
- [Require destination tags](require-destination-tags.md) so that users can't send you payments without tagging the reason they sent it or the customer it's intended for.
|
||||
- [Set Up Multi-Signing](set-up-multi-signing.md) for a higher bar of account security.
|
||||
- [Enable DepositAuth](../../../concepts/accounts/depositauth.md) so you can only receive payments you've explicitly accepted or from parties you've pre-approved.
|
||||
- [Require Auth](../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md#enabling-require-auth) so that users can't open [trust lines](../../../concepts/tokens/fungible-tokens/index.md) to you without your permission. If you don't plan to use the XRP Ledger's decentralized exchange or [token](../../../concepts/tokens/index.md) features, you may want to do this as a precaution.
|
||||
- [Token Issuers](../../../use-cases/tokenization/stablecoin-issuer.md) may have additional setup, such as:
|
||||
- Set a Transfer Fee for users transferring your tokens.
|
||||
- Disallow XRP payments if you plan to use this address for tokens only.
|
||||
|
||||
At this stage, you are only signing the transactions, not submitting them. For each transaction, you must provide all fields, including fields that are normally auto-fillable such as the `Fee` ([transaction cost](../../../concepts/transactions/transaction-cost.md)) and `Sequence` ([sequence number][]). If you prepare multiple transactions at the same time, you must use sequentially increasing `Sequence` numbers in the order you want the transactions to execute.
|
||||
|
||||
Example (enable Require Auth):
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="rippled Commandline" %}
|
||||
```sh
|
||||
$ rippled sign sn3nxiW7v8KXzPzAqzyHXbSSKNuN9 '{"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", "Fee": "12", "Sequence": 1, "TransactionType": "AccountSet", "SetFlag": 2}' offline
|
||||
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
2019-Dec-11 00:18:31.865955978 HTTPClient:NFO Connecting to 127.0.0.1:5005
|
||||
{
|
||||
"result" : {
|
||||
"deprecated" : "This command has been deprecated and will be removed in a future version of the server. Please migrate to a standalone signing tool.",
|
||||
"status" : "success",
|
||||
"tx_blob" : "1200032280000000240000000120210000000268400000000000000C7321039543A0D3004CDA0904A09FB3710251C652D69EA338589279BC849D47A7B019A174473045022100D5C92D7705036CD7EBB601C8DFCD90927FA591A62AF832C489E9C898EC8E2FA0022052F1819340EB73E9749B8930A6935727362B8E141D1B2E246B49F912223FFD4381144B4E9C06F24296074F7BC48F92A97916C6DC5EA9",
|
||||
"tx_json" : {
|
||||
"Account" : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Fee" : "12",
|
||||
"Flags" : 2147483648,
|
||||
"Sequence" : 1,
|
||||
"SetFlag" : 2,
|
||||
"SigningPubKey" : "039543A0D3004CDA0904A09FB3710251C652D69EA338589279BC849D47A7B019A1",
|
||||
"TransactionType" : "AccountSet",
|
||||
"TxnSignature" : "3045022100D5C92D7705036CD7EBB601C8DFCD90927FA591A62AF832C489E9C898EC8E2FA0022052F1819340EB73E9749B8930A6935727362B8E141D1B2E246B49F912223FFD43",
|
||||
"hash" : "F81C34E7F05423DC1C973CB5008CA41AE984DE142EAA3975A749FABF0D08FA63"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
To ensure _all_ transactions have a final outcome within a limited amount of time, provide a [`LastLedgerSequence`](../../../concepts/transactions/reliable-transaction-submission.md#lastledgersequence) field. This value should be based on the current ledger index (which you must look up from an online machine) and the amount of time you want the transaction to remain valid. Be sure to set a large enough `LastLedgerSequence` value to allow for time spent switching from the online machine to the offline machine and back. For example, a value 256 higher than the current ledger index means that the transaction is valid for about 15 minutes. For more information, see [Finality of Results](../../../concepts/transactions/finality-of-results/index.md) and [Reliable Transaction Submission](../../../concepts/transactions/reliable-transaction-submission.md).
|
||||
|
||||
|
||||
### 7. Copy transactions to online machine.
|
||||
|
||||
After you have signed the transactions, the next step is to get the signed transaction data to your online machine. See [Prerequisites](#prerequisites) for some examples of how to do this.
|
||||
|
||||
|
||||
|
||||
### 8. Submit setup transactions.
|
||||
|
||||
The next step is to submit the transactions. Most transactions should have a final outcome in the next validated ledger after submission (about 4 seconds later), or possibly the ledger after that if they get queued (less than 10 seconds). For detailed steps to track the final outcome of a transaction, see [Reliable Transaction Submission](../../../concepts/transactions/reliable-transaction-submission.md).
|
||||
|
||||
Example of transaction submission:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="rippled Commandline" %}
|
||||
```sh
|
||||
$ rippled submit 1200032280000000240000000120210000000268400000000000000C7321039543A0D3004CDA0904A09FB3710251C652D69EA338589279BC849D47A7B019A174473045022100D5C92D7705036CD7EBB601C8DFCD90927FA591A62AF832C489E9C898EC8E2FA0022052F1819340EB73E9749B8930A6935727362B8E141D1B2E246B49F912223FFD4381144B4E9C06F24296074F7BC48F92A97916C6DC5EA9
|
||||
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
2019-Dec-11 01:14:25.988839227 HTTPClient:NFO Connecting to 127.0.0.1:5005
|
||||
|
||||
{
|
||||
"result" : {
|
||||
"deprecated" : "Signing support in the 'submit' command has been deprecated and will be removed in a future version of the server. Please migrate to a standalone signing tool.",
|
||||
"engine_result" : "tesSUCCESS",
|
||||
"engine_result_code" : 0,
|
||||
"engine_result_message" : "The transaction was applied. Only final in a validated ledger.",
|
||||
"status" : "success",
|
||||
"tx_blob" : "1200032280000000240000000120210000000268400000000000000C7321039543A0D3004CDA0904A09FB3710251C652D69EA338589279BC849D47A7B019A174473045022100D5C92D7705036CD7EBB601C8DFCD90927FA591A62AF832C489E9C898EC8E2FA0022052F1819340EB73E9749B8930A6935727362B8E141D1B2E246B49F912223FFD4381144B4E9C06F24296074F7BC48F92A97916C6DC5EA9",
|
||||
"tx_json" : {
|
||||
"Account" : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Fee" : "12",
|
||||
"Flags" : 2147483648,
|
||||
"Sequence" : 1,
|
||||
"SetFlag" : 2,
|
||||
"SigningPubKey" : "039543A0D3004CDA0904A09FB3710251C652D69EA338589279BC849D47A7B019A1",
|
||||
"TransactionType" : "AccountSet",
|
||||
"TxnSignature" : "3045022100D5C92D7705036CD7EBB601C8DFCD90927FA591A62AF832C489E9C898EC8E2FA0022052F1819340EB73E9749B8930A6935727362B8E141D1B2E246B49F912223FFD43",
|
||||
"hash" : "F81C34E7F05423DC1C973CB5008CA41AE984DE142EAA3975A749FABF0D08FA63"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% admonition type="success" name="Tip" %}If you are submitting more than 10 transactions at a time, you may have more success if you submit them in groups of 10 or less at a time, because the [transaction queue](../../../concepts/transactions/transaction-queue.md) is limited to 10 transactions from the same sender at a time. After each group of 10 transactions, wait for all the transactions to leave the queue before submitting the next group.{% /admonition %}
|
||||
|
||||
Retry submitting any transactions that failed with a [non-final outcome](../../../concepts/transactions/finality-of-results/index.md). There is no chance of the same transaction being processed more than once.
|
||||
|
||||
### 9. Confirm the final status of the transactions.
|
||||
|
||||
For each transaction you submitted, note the transaction's [final outcome](../../../concepts/transactions/finality-of-results/index.md), for example using the [tx method][]. For example:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="rippled Commandline" %}
|
||||
```sh
|
||||
$ ./rippled tx F81C34E7F05423DC1C973CB5008CA41AE984DE142EAA3975A749FABF0D08FA63
|
||||
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
2019-Dec-11 01:38:30.124771464 HTTPClient:NFO Connecting to 127.0.0.1:5005
|
||||
{
|
||||
"result" : {
|
||||
"Account" : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Fee" : "12",
|
||||
"Flags" : 2147483648,
|
||||
"Sequence" : 1,
|
||||
"SetFlag" : 2,
|
||||
"SigningPubKey" : "039543A0D3004CDA0904A09FB3710251C652D69EA338589279BC849D47A7B019A1",
|
||||
"TransactionType" : "AccountSet",
|
||||
"TxnSignature" : "3045022100D5C92D7705036CD7EBB601C8DFCD90927FA591A62AF832C489E9C898EC8E2FA0022052F1819340EB73E9749B8930A6935727362B8E141D1B2E246B49F912223FFD43",
|
||||
"date" : 629343510,
|
||||
"hash" : "F81C34E7F05423DC1C973CB5008CA41AE984DE142EAA3975A749FABF0D08FA63",
|
||||
"inLedger" : 4,
|
||||
"ledger_index" : 4,
|
||||
"meta" : {
|
||||
"AffectedNodes" : [
|
||||
{
|
||||
"ModifiedNode" : {
|
||||
"FinalFields" : {
|
||||
"Account" : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Balance" : "4999999999988",
|
||||
"Flags" : 262144,
|
||||
"OwnerCount" : 0,
|
||||
"Sequence" : 2
|
||||
},
|
||||
"LedgerEntryType" : "AccountRoot",
|
||||
"LedgerIndex" : "13F1A95D7AAB7108D5CE7EEAF504B2894B8C674E6D68499076441C4837282BF8",
|
||||
"PreviousFields" : {
|
||||
"Balance" : "5000000000000",
|
||||
"Flags" : 0,
|
||||
"Sequence" : 1
|
||||
},
|
||||
"PreviousTxnID" : "00C5B713B11DA775C6F932D38CE162C16FA88B7269BAFC6FDF4C6ADB74419670",
|
||||
"PreviousTxnLgrSeq" : 3
|
||||
}
|
||||
}
|
||||
],
|
||||
"TransactionIndex" : 0,
|
||||
"TransactionResult" : "tesSUCCESS"
|
||||
},
|
||||
"status" : "success",
|
||||
"validated" : true
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
You may also find it useful to check the [account_info][account_info method] of the sending account after all transactions have processed. Note the account's current sequence number (`Sequence` field) and, optionally, XRP balance.
|
||||
|
||||
For any transactions that failed, you should decide what to do:
|
||||
|
||||
- If the transaction failed with a `tefMAX_LEDGER` code, you may need to specify a higher [transaction cost](../../../concepts/transactions/transaction-cost.md) to get the transaction processed. (This likely indicates that the XRP Ledger network is under load.) You may decide to replace the transaction with a new version that pays a higher cost and has a higher `LastLedgerSequence` parameter (if any).
|
||||
- If the transaction failed with any [`tem`-class code](../../../references/protocol/transactions/transaction-results/tem-codes.md), you probably made a typo or another error in constructing the transaction. Double-check the transaction so that you can replace it with a validly-formed one.
|
||||
- If the transaction failed with a [`tec`-class code](../../../references/protocol/transactions/transaction-results/tec-codes.md), you should address it on a case-by-case basis depending on the exact reason it failed.
|
||||
|
||||
For any transactions you decide to adjust or replace, note the details for when you return to the offline machine.
|
||||
|
||||
|
||||
|
||||
### 10. Reconcile offline machine status.
|
||||
|
||||
Return to the offline machine and apply any necessary changes to your custom server's saved settings, such as:
|
||||
|
||||
- Updating the account's current `Sequence` number. If all transactions were included in validated ledgers (successfully or with `tec` codes), then the offline machine's saved sequence number should already be correct. Otherwise, you may need to change the saved sequence number to match the `Sequence` value you noted in the previous step.
|
||||
- Updating the current ledger index so that you can use appropriate `LastLedgerSequence` values in any new transactions. (You should always do this shortly before constructing any new transactions.)
|
||||
- _(Optional)_ Updating your actual amount of XRP available, if you are tracking it in the offline machine.
|
||||
|
||||
Then adjust and sign any replacement transactions for transactions that failed in the previous step. Repeat the previous steps for constructing transactions on the offline machine, transferring them, and submitting them from the online machine.
|
||||
|
||||
|
||||
|
||||
## See Also
|
||||
|
||||
- **Concepts:**
|
||||
- [Accounts](../../../concepts/accounts/index.md)
|
||||
- [Cryptographic Keys](../../../concepts/accounts/cryptographic-keys.md)
|
||||
- **Tutorials:**
|
||||
- [Set Up Secure Signing](../../../concepts/transactions/secure-signing.md)
|
||||
- [Assign a Regular Key Pair](assign-a-regular-key-pair.md)
|
||||
- [Set Up Multi-Signing](set-up-multi-signing.md)
|
||||
- **References:**
|
||||
- [Basic Data Types: Account Sequence](../../../references/protocol/data-types/basic-data-types.md#account-sequence)
|
||||
- [account_info method][]
|
||||
- [sign method][]
|
||||
- [submit method][]
|
||||
- [tx method][]
|
||||
- [AccountSet transaction][]
|
||||
|
||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
||||
@@ -1,442 +0,0 @@
|
||||
---
|
||||
html: send-a-multi-signed-transaction.html
|
||||
parent: manage-account-settings.html
|
||||
seo:
|
||||
description: Send a transaction authorized with multiple signatures.
|
||||
labels:
|
||||
- Security
|
||||
---
|
||||
# Send a Multi-Signed Transaction
|
||||
|
||||
The following procedure demonstrates how to create, sign, and submit a multi-signed transaction.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- You must have already [set up multi-signing](set-up-multi-signing.md) for your address.
|
||||
|
||||
- Multi-signing must be available. Multi-signing has been enabled by an [**Amendment**](../../../concepts/networks-and-servers/amendments.md) to the XRP Ledger Consensus Protocol since 2016-06-27.
|
||||
|
||||
|
||||
## 1. Create the transaction
|
||||
|
||||
Create a JSON object that represents the transaction you want to submit. You have to specify _everything_ about this transaction, including `Fee` and `Sequence`. Also include the field `SigningPubKey` as an empty string, to indicate that the transaction is multi-signed.
|
||||
|
||||
Keep in mind that the `Fee` for multi-signed transactions is significantly higher than for regularly-signed transactions. It should be at least (N+1) times the normal [transaction cost](../../../concepts/transactions/transaction-cost.md), where N is the number of signatures you plan to provide. Since it sometimes takes a while to collect signatures from multiple sources, you may want to specify more than the current minimum, in case the [transaction cost](../../../concepts/transactions/transaction-cost.md) increases in that time.
|
||||
|
||||
Here's an example transaction ready to be multi-signed:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JSON" %}
|
||||
```json
|
||||
{
|
||||
"TransactionType": "TrustSet",
|
||||
"Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
|
||||
"Flags": 262144,
|
||||
"LimitAmount": {
|
||||
"currency": "USD",
|
||||
"issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"value": "100"
|
||||
},
|
||||
"Sequence": 2,
|
||||
"SigningPubKey": "",
|
||||
"Fee": "30000"
|
||||
}
|
||||
```
|
||||
|
||||
(This transaction creates an accounting relationship from `rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC` to `rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh` with a maximum balance of 100 USD.)
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Javascript" %}
|
||||
{% code-snippet file="/_code-samples/multisigning/js/multisigning.ts" language="js" from="const accountSet: AccountSet = {" before="const { tx_blob" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Python" %}
|
||||
{% code-snippet file="/_code-samples/multisigning/py/multisigning.py" language="py" from="account_set_tx = AccountSet" before="# Since" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
## 2. Get one signature
|
||||
|
||||
Use the [sign_for method][] with the secret key and address of one of the members of your SignerList to get a signature for that member.
|
||||
|
||||
{% partial file="/docs/_snippets/secret-key-warning.md" /%}
|
||||
|
||||
|
||||
```
|
||||
$ rippled sign_for rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW <rsA2L..'s secret> '{
|
||||
> "TransactionType": "TrustSet",
|
||||
> "Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
|
||||
> "Flags": 262144,
|
||||
> "LimitAmount": {
|
||||
> "currency": "USD",
|
||||
> "issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
> "value": "100"
|
||||
> },
|
||||
> "Sequence": 2,
|
||||
> "SigningPubKey": "",
|
||||
> "Fee": "30000"
|
||||
> }'
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
Connecting to 127.0.0.1:5005
|
||||
{
|
||||
"result" : {
|
||||
"status" : "success",
|
||||
"tx_blob" : "1200142200040000240000000263D5038D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E868400000000000753073008114A3780F5CB5A44D366520FC44055E8ED44D9A2270F3E010732102B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF744730450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E58114204288D2E47F8EF6C99BCC457966320D12409711E1F1",
|
||||
"tx_json" : {
|
||||
"Account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
|
||||
"Fee" : "30000",
|
||||
"Flags" : 262144,
|
||||
"LimitAmount" : {
|
||||
"currency" : "USD",
|
||||
"issuer" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"value" : "100"
|
||||
},
|
||||
"Sequence" : 2,
|
||||
"Signers" : [
|
||||
{
|
||||
"Signer" : {
|
||||
"Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
"SigningPubKey" : "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
|
||||
"TxnSignature" : "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
|
||||
}
|
||||
}
|
||||
],
|
||||
"SigningPubKey" : "",
|
||||
"TransactionType" : "TrustSet",
|
||||
"hash" : "A94A6417D1A7AAB059822B894E13D322ED3712F7212CE9257801F96DE6C3F6AE"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Save the `tx_json` field of the response: it has the new signature in the `Signers` field. You can discard the value of the `tx_blob` field.
|
||||
|
||||
If you have a problem in stand-alone mode or a non-production network, check that [multi-sign is enabled](../../../infrastructure/testing-and-auditing/start-a-new-genesis-ledger-in-stand-alone-mode.md#settings-in-new-genesis-ledgers).
|
||||
|
||||
## 3. Get additional signatures
|
||||
|
||||
You can collect additional signatures in parallel or in serial:
|
||||
|
||||
* In parallel: Use the `sign_for` command with the original JSON for the transaction. Each response has a single signature in the `Signers` array.
|
||||
* In serial: Use the `sign_for` command with the `tx_json` value from the previous `sign_for` response. Each response adds a new signature to the existing `Signers` array.
|
||||
|
||||
{% partial file="/docs/_snippets/secret-key-warning.md" /%}
|
||||
|
||||
|
||||
```
|
||||
$ rippled sign_for rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v <rUpy..'s secret> '{
|
||||
> "Account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
|
||||
> "Fee" : "30000",
|
||||
> "Flags" : 262144,
|
||||
> "LimitAmount" : {
|
||||
> "currency" : "USD",
|
||||
> "issuer" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
> "value" : "100"
|
||||
> },
|
||||
> "Sequence" : 2,
|
||||
> "Signers" : [
|
||||
> {
|
||||
> "Signer" : {
|
||||
> "Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
> "SigningPubKey" : "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
|
||||
> "TxnSignature" : "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
|
||||
> }
|
||||
> }
|
||||
> ],
|
||||
> "SigningPubKey" : "",
|
||||
> "TransactionType" : "TrustSet",
|
||||
> "hash" : "A94A6417D1A7AAB059822B894E13D322ED3712F7212CE9257801F96DE6C3F6AE"
|
||||
> }'
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
Connecting to 127.0.0.1:5005
|
||||
{
|
||||
"result" : {
|
||||
"status" : "success",
|
||||
"tx_blob" : "1200142200040000240000000263D5038D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E868400000000000753073008114A3780F5CB5A44D366520FC44055E8ED44D9A2270F3E010732102B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF744730450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E58114204288D2E47F8EF6C99BCC457966320D12409711E1E0107321028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B744630440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC181147908A7F0EDD48EA896C3580A399F0EE78611C8E3E1F1",
|
||||
"tx_json" : {
|
||||
"Account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
|
||||
"Fee" : "30000",
|
||||
"Flags" : 262144,
|
||||
"LimitAmount" : {
|
||||
"currency" : "USD",
|
||||
"issuer" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"value" : "100"
|
||||
},
|
||||
"Sequence" : 2,
|
||||
"Signers" : [
|
||||
{
|
||||
"Signer" : {
|
||||
"Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
"SigningPubKey" : "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
|
||||
"TxnSignature" : "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Signer" : {
|
||||
"Account" : "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
|
||||
"SigningPubKey" : "028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B",
|
||||
"TxnSignature" : "30440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC1"
|
||||
}
|
||||
}
|
||||
],
|
||||
"SigningPubKey" : "",
|
||||
"TransactionType" : "TrustSet",
|
||||
"hash" : "BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Depending on the SignerList you configured, you may need to repeat this step several times to get signatures from all the necessary parties.
|
||||
|
||||
|
||||
## 4. Combine signatures and submit
|
||||
|
||||
If you collected the signatures in serial, the `tx_json` from the last `sign_for` response has all the signatures assembled, so you can use that as the argument to the [submit_multisigned method][].
|
||||
|
||||
If you collected the signatures in parallel, you must manually construct a `tx_json` object with all the signatures included. Take the `Signers` arrays from all the `sign_for` responses, and combine their contents into a single `Signers` array that has each signature. Add the combined `Signers` array to the original transaction JSON value, and use that as the argument to the [submit_multisigned method][].
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```
|
||||
$ rippled submit_multisigned '{
|
||||
> "Account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
|
||||
> "Fee" : "30000",
|
||||
> "Flags" : 262144,
|
||||
> "LimitAmount" : {
|
||||
> "currency" : "USD",
|
||||
> "issuer" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
> "value" : "100"
|
||||
> },
|
||||
> "Sequence" : 2,
|
||||
> "Signers" : [
|
||||
> {
|
||||
> "Signer" : {
|
||||
> "Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
> "SigningPubKey" : "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
|
||||
> "TxnSignature" : "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
|
||||
> }
|
||||
> },
|
||||
> {
|
||||
> "Signer" : {
|
||||
> "Account" : "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
|
||||
> "SigningPubKey" : "028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B",
|
||||
> "TxnSignature" : "30440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC1"
|
||||
> }
|
||||
> }
|
||||
> ],
|
||||
> "SigningPubKey" : "",
|
||||
> "TransactionType" : "TrustSet",
|
||||
> "hash" : "BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6"
|
||||
> }'
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
Connecting to 127.0.0.1:5005
|
||||
{
|
||||
"result": {
|
||||
"engine_result": "tesSUCCESS",
|
||||
"engine_result_code": 0,
|
||||
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
|
||||
"status": "success",
|
||||
"tx_blob": "1200142200040000240000000263D5038D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E868400000000000753073008114A3780F5CB5A44D366520FC44055E8ED44D9A2270F3E010732102B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF744730450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E58114204288D2E47F8EF6C99BCC457966320D12409711E1E0107321028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B744630440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC181147908A7F0EDD48EA896C3580A399F0EE78611C8E3E1F1",
|
||||
"tx_json": {
|
||||
"Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
|
||||
"Fee": "30000",
|
||||
"Flags": 262144,
|
||||
"LimitAmount": {
|
||||
"currency": "USD",
|
||||
"issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"value": "100"
|
||||
},
|
||||
"Sequence": 2,
|
||||
"Signers": [{
|
||||
"Signer": {
|
||||
"Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
"SigningPubKey": "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
|
||||
"TxnSignature": "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
|
||||
}
|
||||
}, {
|
||||
"Signer": {
|
||||
"Account": "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
|
||||
"SigningPubKey": "028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B",
|
||||
"TxnSignature": "30440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC1"
|
||||
}
|
||||
}],
|
||||
"SigningPubKey": "",
|
||||
"TransactionType": "TrustSet",
|
||||
"hash": "BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Take note of the `hash` value from the response so you can check the results of the transaction later. (In this case, the hash is `BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6`.)
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Javascript" %}
|
||||
{% code-snippet file="/_code-samples/multisigning/js/multisigning.ts" language="js" from="const { tx_blob" before="if (submitResponse" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Python" %}
|
||||
{% code-snippet file="/_code-samples/multisigning/py/multisigning.py" language="py" from="tx_1 =" before="if multisigned_tx_response" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
## 5. Close the ledger
|
||||
|
||||
If you are using the live network, you can wait 4-7 seconds for the ledger to close automatically.
|
||||
|
||||
If you're running `rippled` in stand-alone mode, use the [ledger_accept method][] to manually close the ledger:
|
||||
|
||||
```
|
||||
$ rippled ledger_accept
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
Connecting to 127.0.0.1:5005
|
||||
{
|
||||
"result" : {
|
||||
"ledger_current_index" : 7,
|
||||
"status" : "success"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 6. Confirm transaction results
|
||||
|
||||
Use the hash value from the response to the `submit_multisigned` command to look up the transaction using the [tx method][]. In particular, check that the `TransactionResult` is the string `tesSUCCESS`.
|
||||
|
||||
On the live network, you must also confirm that the `validated` field is set to the boolean `true`. If the field is not `true`, you might need to wait longer for the consensus process to finish; or your transaction may be unable to be included in a ledger for some reason.
|
||||
|
||||
In stand-alone mode, the server automatically considers a ledger to be `validated` if it has been manually closed.
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```
|
||||
$ rippled tx BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
Connecting to 127.0.0.1:5005
|
||||
{
|
||||
"result": {
|
||||
"Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
|
||||
"Fee": "30000",
|
||||
"Flags": 262144,
|
||||
"LimitAmount": {
|
||||
"currency": "USD",
|
||||
"issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"value": "100"
|
||||
},
|
||||
"Sequence": 2,
|
||||
"Signers": [{
|
||||
"Signer": {
|
||||
"Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
"SigningPubKey": "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
|
||||
"TxnSignature": "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
|
||||
}
|
||||
}, {
|
||||
"Signer": {
|
||||
"Account": "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
|
||||
"SigningPubKey": "028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B",
|
||||
"TxnSignature": "30440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC1"
|
||||
}
|
||||
}],
|
||||
"SigningPubKey": "",
|
||||
"TransactionType": "TrustSet",
|
||||
"date": 512172510,
|
||||
"hash": "BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6",
|
||||
"inLedger": 6,
|
||||
"ledger_index": 6,
|
||||
"meta": {
|
||||
"AffectedNodes": [{
|
||||
"ModifiedNode": {
|
||||
"LedgerEntryType": "AccountRoot",
|
||||
"LedgerIndex": "2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8",
|
||||
"PreviousTxnID": "B7E1D33DB7DEA3BB65BFAB2C80E02125F47FCCF6C957A7FDECD915B3EBE0C1DD",
|
||||
"PreviousTxnLgrSeq": 4
|
||||
}
|
||||
}, {
|
||||
"CreatedNode": {
|
||||
"LedgerEntryType": "RippleState",
|
||||
"LedgerIndex": "93E317B32022977C77810A2C558FBB28E30E744C68E73720622B797F957EC5FA",
|
||||
"NewFields": {
|
||||
"Balance": {
|
||||
"currency": "USD",
|
||||
"issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji",
|
||||
"value": "0"
|
||||
},
|
||||
"Flags": 2162688,
|
||||
"HighLimit": {
|
||||
"currency": "USD",
|
||||
"issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"value": "0"
|
||||
},
|
||||
"LowLimit": {
|
||||
"currency": "USD",
|
||||
"issuer": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
|
||||
"value": "100"
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"ModifiedNode": {
|
||||
"FinalFields": {
|
||||
"Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
|
||||
"Balance": "999960000",
|
||||
"Flags": 0,
|
||||
"OwnerCount": 6,
|
||||
"Sequence": 3
|
||||
},
|
||||
"LedgerEntryType": "AccountRoot",
|
||||
"LedgerIndex": "A6B1BA6F2D70813100908EA84ABB7783695050312735E2C3665259F388804EA0",
|
||||
"PreviousFields": {
|
||||
"Balance": "999990000",
|
||||
"OwnerCount": 5,
|
||||
"Sequence": 2
|
||||
},
|
||||
"PreviousTxnID": "8FDC18960455C196A8C4DE0D24799209A21F4A17E32102B5162BD79466B90222",
|
||||
"PreviousTxnLgrSeq": 5
|
||||
}
|
||||
}, {
|
||||
"ModifiedNode": {
|
||||
"FinalFields": {
|
||||
"Flags": 0,
|
||||
"Owner": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
|
||||
"RootIndex": "C2728175908D82FB1DE6676F203D8D3C056995A9FA9B369EF326523F1C65A1DE"
|
||||
},
|
||||
"LedgerEntryType": "DirectoryNode",
|
||||
"LedgerIndex": "C2728175908D82FB1DE6676F203D8D3C056995A9FA9B369EF326523F1C65A1DE"
|
||||
}
|
||||
}, {
|
||||
"CreatedNode": {
|
||||
"LedgerEntryType": "DirectoryNode",
|
||||
"LedgerIndex": "D8120FC732737A2CF2E9968FDF3797A43B457F2A81AA06D2653171A1EA635204",
|
||||
"NewFields": {
|
||||
"Owner": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"RootIndex": "D8120FC732737A2CF2E9968FDF3797A43B457F2A81AA06D2653171A1EA635204"
|
||||
}
|
||||
}
|
||||
}],
|
||||
"TransactionIndex": 0,
|
||||
"TransactionResult": "tesSUCCESS"
|
||||
},
|
||||
"status": "success",
|
||||
"validated": true
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Javascript" %}
|
||||
{% code-snippet file="/_code-samples/multisigning/js/multisigning.ts" language="js" from="if (submitResponse" before="await client.disconnect" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Python" %}
|
||||
{% code-snippet file="/_code-samples/multisigning/py/multisigning.py" language="py" from="if multisigned_tx_response" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
|
||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
||||
@@ -1,246 +0,0 @@
|
||||
---
|
||||
html: set-up-multi-signing.html
|
||||
parent: manage-account-settings.html
|
||||
seo:
|
||||
description: Add a signer list to your account to enable multi-signing.
|
||||
labels:
|
||||
- Security
|
||||
---
|
||||
# Set Up Multi-Signing
|
||||
|
||||
[Multi-signing](../../../concepts/accounts/multi-signing.md) is one of three ways to authorize [transactions](../../../concepts/transactions/index.md) for the XRP Ledger, alongside signing with [regular keys and master keys](../../../concepts/accounts/cryptographic-keys.md). You can configure your [address](../../../concepts/accounts/index.md) to allow any combination of the three methods to authorize transactions.
|
||||
|
||||
This tutorial demonstrates how to enable multi-signing for an address.
|
||||
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- You must have a funded XRP Ledger [address](../../../concepts/accounts/index.md) with enough spare XRP to send transactions and meet the [reserve requirement](../../../concepts/accounts/reserves.md) of a new signer list.
|
||||
|
||||
- With the [MultiSignReserve amendment][] enabled, multi-signing requires {% $env.PUBLIC_OWNER_RESERVE %} for the account reserve, regardless of the number of signers and signatures you use. (The MultiSignReserve amendment has been enabled in the production XRP Ledger since **2019-04-07**.)
|
||||
|
||||
- If you are on a test network that does not have the [MultiSignReserve amendment][] enabled, multi-signing requires more than the usual amount of XRP for the [account reserve](../../../concepts/accounts/reserves.md), increasing with the number of signers in the list.
|
||||
|
||||
- You must have access to a tool that can generate key pairs in the XRP Ledger format. If you are using a `rippled` server for this, you must have admin access because the [wallet_propose method][] is admin-only.
|
||||
|
||||
- Alternatively, if you are authorizing others who already have XRP Ledger addresses to be signers for your address, you only need to know the account addresses of those people or entities.
|
||||
|
||||
- Multi-signing must be available. (The MultiSign amendment has been enabled in the production XRP Ledger since **2016-06-27**.)
|
||||
|
||||
## 1. Design Your Configuration
|
||||
|
||||
Decide how many signers you want to include (up to 32). Choose a quorum number for your signer list and weights for your signers based on how many signatures you want to require for a given transaction. For a straightforward "M-of-N" signing setup, assign each signer weight **`1`** and set your list's quorum to be "M", the number of signatures to require.
|
||||
|
||||
|
||||
## 2. Prepare member keys
|
||||
|
||||
You need one or more validly-formed XRP Ledger addresses to include as members of your signer list. You or your chosen signers must know the secret keys associated with these addresses. The addresses can be funded accounts that exist in the ledger, but they do not need to be.
|
||||
|
||||
You can generate new addresses using the [wallet_propose method][]. For example:
|
||||
|
||||
```
|
||||
$ rippled wallet_propose
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
Connecting to 127.0.0.1:5005
|
||||
{
|
||||
"result" : {
|
||||
"account_id" : "rnRJ4dpSBKDR2M1itf4Ah6tZZm5xuNZFPH",
|
||||
"key_type" : "secp256k1",
|
||||
"master_key" : "FLOG SEND GOES CUFF GAGE FAT ANTI DEL GUM TIRE ISLE BEAR",
|
||||
"master_seed" : "snheH5UUjU4CWqiNVLny2k21TyKPC",
|
||||
"master_seed_hex" : "A9F859765EB8614D26809836382AFB82",
|
||||
"public_key" : "aBR4hxFXcDNHnGYvTiqb2KU8TTTV1cYV9wXTAuz2DjBm7S8TYEBU",
|
||||
"public_key_hex" : "03C09A5D112B393D531E4F092E3A5769A5752129F0A9C55C61B3A226BB9B567B9B",
|
||||
"status" : "success"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Take note of the `account_id` (XRP Ledger Address) and `master_seed` (secret key) for each one you generate.
|
||||
|
||||
|
||||
## 3. Send SignerListSet transaction
|
||||
|
||||
[Sign and submit](../../../concepts/transactions/index.md#signing-and-submitting-transactions) a [SignerListSet transaction][] in the normal (single-signature) way. This associates a signer list with your XRP Ledger address, so that a combination of signatures from the members of that signer list can multi-sign later transactions on your behalf.
|
||||
|
||||
In this example, the signer list has 3 members, with the weights and quorum set up such that multi-signed transactions need a signature from `rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW` plus at least one signature from the other two members of the list.
|
||||
|
||||
{% partial file="/docs/_snippets/secret-key-warning.md" /%}
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```
|
||||
$ rippled submit shqZZy2Rzs9ZqWTCQAdqc3bKgxnYq '{
|
||||
> "Flags": 0,
|
||||
> "TransactionType": "SignerListSet",
|
||||
> "Account": "rnBFvgZphmN39GWzUJeUitaP22Fr9be75H",
|
||||
> "Fee": "10000",
|
||||
> "SignerQuorum": 3,
|
||||
> "SignerEntries": [
|
||||
> {
|
||||
> "SignerEntry": {
|
||||
> "Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
> "SignerWeight": 2
|
||||
> }
|
||||
> },
|
||||
> {
|
||||
> "SignerEntry": {
|
||||
> "Account": "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
|
||||
> "SignerWeight": 1
|
||||
> }
|
||||
> },
|
||||
> {
|
||||
> "SignerEntry": {
|
||||
> "Account": "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n",
|
||||
> "SignerWeight": 1
|
||||
> }
|
||||
> }
|
||||
> ]
|
||||
> }'
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
Connecting to 127.0.0.1:5005
|
||||
{
|
||||
"result" : {
|
||||
"engine_result" : "tesSUCCESS",
|
||||
"engine_result_code" : 0,
|
||||
"engine_result_message" : "The transaction was applied. Only final in a validated ledger.",
|
||||
"status" : "success",
|
||||
"tx_blob" : "12000C2200000000240000000120230000000368400000000000271073210303E20EC6B4A39A629815AE02C0A1393B9225E3B890CAE45B59F42FA29BE9668D74473045022100BEDFA12502C66DDCB64521972E5356F4DB965F553853D53D4C69B4897F11B4780220595202D1E080345B65BAF8EBD6CA161C227F1B62C7E72EA5CA282B9434A6F04281142DECAB42CA805119A9BA2FF305C9AFA12F0B86A1F4EB1300028114204288D2E47F8EF6C99BCC457966320D12409711E1EB13000181147908A7F0EDD48EA896C3580A399F0EE78611C8E3E1EB13000181143A4C02EA95AD6AC3BED92FA036E0BBFB712C030CE1F1",
|
||||
"tx_json" : {
|
||||
"Account" : "rnBFvgZphmN39GWzUJeUitaP22Fr9be75H",
|
||||
"Fee" : "10000",
|
||||
"Flags" : 0,
|
||||
"Sequence" : 1,
|
||||
"SignerEntries" : [
|
||||
{
|
||||
"SignerEntry" : {
|
||||
"Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
"SignerWeight" : 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"SignerEntry" : {
|
||||
"Account" : "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
|
||||
"SignerWeight" : 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"SignerEntry" : {
|
||||
"Account" : "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n",
|
||||
"SignerWeight" : 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"SignerQuorum" : 3,
|
||||
"SigningPubKey" : "0303E20EC6B4A39A629815AE02C0A1393B9225E3B890CAE45B59F42FA29BE9668D",
|
||||
"TransactionType" : "SignerListSet",
|
||||
"TxnSignature" : "3045022100BEDFA12502C66DDCB64521972E5356F4DB965F553853D53D4C69B4897F11B4780220595202D1E080345B65BAF8EBD6CA161C227F1B62C7E72EA5CA282B9434A6F042",
|
||||
"hash" : "3950D98AD20DA52EBB1F3937EF32F382D74092A4C8DF9A0B1A06ED25200B5756"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Javascript" %}
|
||||
{% code-snippet file="/_code-samples/multisigning/js/multisigning.ts" language="js" from=" const { wallet: wallet1" before="const accountSet:" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Python" %}
|
||||
{% code-snippet file="/_code-samples/multisigning/py/multisigning.py" language="py" from="master_wallet =" before="# Now that" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
Make sure that the [Transaction Result](../../../references/protocol/transactions/transaction-results/index.md) is [**`tesSUCCESS`**](../../../references/protocol/transactions/transaction-results/tes-success.md). Otherwise, the transaction failed. If you have a problem in stand-alone mode or a non-production network, check that [multi-sign is enabled](../../../infrastructure/testing-and-auditing/start-a-new-genesis-ledger-in-stand-alone-mode.md#settings-in-new-genesis-ledgers).
|
||||
|
||||
{% admonition type="info" name="Note" %}Without the [MultiSignReserve amendment][], the more members in the signer list, the more XRP your address must have for purposes of the [owner reserve](../../../concepts/accounts/reserves.md#owner-reserves). If your address does not have enough XRP, the transaction fails with [`tecINSUFFICIENT_RESERVE`](../../../references/protocol/transactions/transaction-results/tec-codes.md). With the [MultiSignReserve amendment][] enabled, the XRP your address must have for purposes of the [owner reserve](../../../concepts/accounts/reserves.md#owner-reserves) is 5 XRP, regardless of the number of members in the signer list. See also: [Signer Lists and Reserves](../../../references/protocol/ledger-data/ledger-entry-types/signerlist.md#signer-lists-and-reserves).{% /admonition %}
|
||||
|
||||
|
||||
## 4. Wait for validation
|
||||
|
||||
{% raw-partial file="/docs/_snippets/wait-for-validation.md" /%}
|
||||
|
||||
|
||||
## 5. Confirm the new signer list
|
||||
|
||||
Use the [account_objects method][] to confirm that the signer list is associated with the address in the latest validated ledger.
|
||||
|
||||
Normally, an account can own many objects of different types (such as trust lines and offers). If you funded a new address for this tutorial, the signer list is the only object in the response.
|
||||
|
||||
```
|
||||
$ rippled account_objects rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC validated
|
||||
Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
Connecting to 127.0.0.1:5005
|
||||
{
|
||||
"result" : {
|
||||
"account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
|
||||
"account_objects" : [
|
||||
{
|
||||
"Flags" : 0,
|
||||
"LedgerEntryType" : "SignerList",
|
||||
"OwnerNode" : "0000000000000000",
|
||||
"PreviousTxnID" : "8FDC18960455C196A8C4DE0D24799209A21F4A17E32102B5162BD79466B90222",
|
||||
"PreviousTxnLgrSeq" : 5,
|
||||
"SignerEntries" : [
|
||||
{
|
||||
"SignerEntry" : {
|
||||
"Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
"SignerWeight" : 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"SignerEntry" : {
|
||||
"Account" : "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n",
|
||||
"SignerWeight" : 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"SignerEntry" : {
|
||||
"Account" : "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
|
||||
"SignerWeight" : 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"SignerListID" : 0,
|
||||
"SignerQuorum" : 3,
|
||||
"index" : "79FD203E4DDDF2EA78B798C963487120C048C78652A28682425E47C96D016F92"
|
||||
}
|
||||
],
|
||||
"ledger_hash" : "56E81069F06492FB410A70218C08169BE3AB3CFD5AEA20E999662D81DC361D9F",
|
||||
"ledger_index" : 5,
|
||||
"status" : "success",
|
||||
"validated" : true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If the signer list is present with the expected contents, then your address is ready to multi-sign.
|
||||
|
||||
## 6. Further steps
|
||||
|
||||
At this point, your address is ready to [send a multi-signed transaction](send-a-multi-signed-transaction.md). You may also want to:
|
||||
|
||||
* [Disable the address's master key pair](disable-master-key-pair.md).
|
||||
* [Remove the address's regular key pair](change-or-remove-a-regular-key-pair.md) (if you previously set one) by sending a [SetRegularKey transaction][].
|
||||
|
||||
## See Also
|
||||
|
||||
- **Concepts:**
|
||||
- [Cryptographic Keys](../../../concepts/accounts/cryptographic-keys.md)
|
||||
- [Multi-Signing](../../../concepts/accounts/multi-signing.md)
|
||||
- **Tutorials:**
|
||||
- [Install rippled](../../../infrastructure/installation/index.md)
|
||||
- [Assign a Regular Key Pair](assign-a-regular-key-pair.md)
|
||||
- [Reliable Transaction Submission](../../../concepts/transactions/reliable-transaction-submission.md)
|
||||
- [Enable Public Signing](../../../infrastructure/configuration/enable-public-signing.md)
|
||||
- **References:**
|
||||
- [wallet_propose method][]
|
||||
- [account_objects method][]
|
||||
- [sign_for method][]
|
||||
- [submit_multisigned method][]
|
||||
- [SignerListSet transaction][]
|
||||
- [SignerList object](../../../references/protocol/ledger-data/ledger-entry-types/signerlist.md)
|
||||
|
||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
||||
Reference in New Issue
Block a user