Share your account’s importance securely with a node.
Delegated harvesting enables accounts to receive rewards from creating new blocks without running a node. The following guide will show you how to delegate your account importance without compromising the account’s funds.
In this process, you will delegate your main account (M) importance to a proxy public key (R). Then,you will request a node to add your remote account (R) as a delegated harvester with the announcer account (A).
Before you can activate delegated harvesting, you need to have three accounts:
10,000
harvesting mosaic units.symbol.xym
units to announce a transaction.// replace with network type
const networkType = NetworkType.TEST_NET;
// replace with private key
const mainAccountPrivateKey = '0000000000000000000000000000000000000000000000000000000000000000';
const mainAccount = Account.createFromPrivateKey(mainAccountPrivateKey, networkType);
const remoteAccount = Account.generateNewAccount(networkType);
// replace with private key
const announcerAccountPrivateKey = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
const announcerAccount = Account.createFromPrivateKey(announcerAccountPrivateKey, networkType);
// replace with network type
const networkType = symbol_sdk_1.NetworkType.TEST_NET;
// replace with private key
const mainAccountPrivateKey = '0000000000000000000000000000000000000000000000000000000000000000';
const mainAccount = symbol_sdk_1.Account.createFromPrivateKey(mainAccountPrivateKey, networkType);
const remoteAccount = symbol_sdk_1.Account.generateNewAccount(networkType);
// replace with private key
const announcerAccountPrivateKey = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
const announcerAccount = symbol_sdk_1.Account.createFromPrivateKey(announcerAccountPrivateKey, networkType);
const accountLinkTransaction = AccountKeyLinkTransaction.create(
Deadline.create(),
remoteAccount.publicKey,
LinkAction.Link,
networkType,
UInt64.fromUint(2000000));
const accountLinkTransaction = symbol_sdk_1.AccountKeyLinkTransaction.create(symbol_sdk_1.Deadline.create(), remoteAccount.publicKey, symbol_sdk_1.LinkAction.Link, networkType, symbol_sdk_1.UInt64.fromUint(2000000));
// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.096x.symboldev.network:3000';
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash = '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
const signedTransaction = mainAccount.sign(accountLinkTransaction, networkGenerationHash);
transactionHttp
.announce(signedTransaction)
.subscribe((x) => console.log(x), (err) => console.error(err));
// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.096x.symboldev.network:3000';
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash = '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const repositoryFactory = new symbol_sdk_1.RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
const signedTransaction = mainAccount.sign(accountLinkTransaction, networkGenerationHash);
transactionHttp
.announce(signedTransaction)
.subscribe((x) => console.log(x), (err) => console.error(err));
Once the transaction is confirmed, the next step is to share R’s private key with the node you wish to connect for delegated harvesting.
4. Create a PersistentDelegationRequestTransaction. Add the node’s public key as the transaction recipient and share the R’s private key by creating a special encrypted message as follows:
Note
Get the node’s public key by querying http://<node-url>:3000/node/info
.
// replace with node publicKey (nodeUrl + '/node/info')
const nodePublicKey = '3A537D5A1AF51158C42F80A199BB58351DBF3253C4A6A1B7BD1014682FB595EA';
const nodePublicAccount = PublicAccount.createFromPublicKey(nodePublicKey, networkType);
const persistentDelegationRequestTransaction = PersistentDelegationRequestTransaction
.createPersistentDelegationRequestTransaction(
Deadline.create(),
remoteAccount.privateKey,
nodePublicAccount.publicKey,
networkType,
UInt64.fromUint(2000000));
// replace with node publicKey (nodeUrl + '/node/info')
const nodePublicKey = '3A537D5A1AF51158C42F80A199BB58351DBF3253C4A6A1B7BD1014682FB595EA';
const nodePublicAccount = symbol_sdk_1.PublicAccount.createFromPublicKey(nodePublicKey, networkType);
const persistentDelegationRequestTransaction = symbol_sdk_1.PersistentDelegationRequestTransaction
.createPersistentDelegationRequestTransaction(symbol_sdk_1.Deadline.create(), remoteAccount.privateKey, nodePublicAccount.publicKey, networkType, symbol_sdk_1.UInt64.fromUint(2000000));
The special encrypted message ensures that R’s proxy private key is securely shared, only readable by the node owner. Moreover, the remote account does not possess any mosaics. The valuable assets remain safely in the main account which the node owner remains without access.
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash = '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = announcerAccount.sign(persistentDelegationRequestTransaction, networkGenerationHash);
// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.096x.symboldev.network:3000';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
transactionHttp
.announce(signedTransaction)
.subscribe((x) => console.log(x), (err) => console.error(err));
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash = '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = announcerAccount.sign(persistentDelegationRequestTransaction, networkGenerationHash);
// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.096x.symboldev.network:3000';
const repositoryFactory = new symbol_sdk_1.RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
transactionHttp
.announce(signedTransaction)
.subscribe((x) => console.log(x), (err) => console.error(err));
Note
You could announce the transaction with M, but it is recommended to use a third account to keep the information about transfer of importance confidential.
If everything is successful, the node will receive an encrypted message using WebSockets. Once the node decrypts the private key of the potential delegated harvester, the node owner may add R as a delegated harvester if the following requirements are met:
Note
Announcing a valid PersistentDelegationRequestTransaction does not guarantee being added as a delegated harvester. Currently, the only way to verify that an account has successfully activated delegated harvesting is to become the signer of a new block.
10.000
symbol.xym
— as a CLI profile.symbol-cli profile import --private-key 0000000000000000000000000000000000000000000000000000000000000000 --network TEST_NET --url http://api-01.us-east-1.096x.symboldev.network:3000 --profile main
symbol-cli account generate --network-type TEST_NET
symbol-cli transaction accountlink --public-key 98DB319D390F8B52E29A5FB2B4109FD709218CA505BB38D4BC54F51E1102FCDA --action Link --profile main
symbol.xym
to be able to announce the transaction to the network.symbol-cli profile import --private-key FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF --network TEST_NET --url http://api-01.us-east-1.096x.symboldev.network:3000 --profile announcer
<recipient-public-key>
with the node’s public key and <remote-private-key>
with R’s private key.Note
Get the node’s public key by querying http://<node-url>:3000/node/info
.
symbol-cli transaction persistentharvestdelegation --recipient-public-key <recipientPublicKey> --remote-private-key <remotePrivateKey> --profile announcer
Once the node decrypts the private key of the potential delegated harvester, the node owner may add you as a delegated harvester.
Did you find what you were looking for? Give us your feedback.