Skip to content

Commit 5ad34b9

Browse files
CS address in script reader (#237)
* [CS] - Get cold stake address from script and added CS to Address Indexer v2.0 * Check all addresses if null in indexer. * Fix namespaces Co-authored-by: Dennis <41244965+DennisAMenace@users.noreply.github.com>
1 parent 25dfd87 commit 5ad34b9

8 files changed

Lines changed: 112 additions & 25 deletions

File tree

src/Blockcore/Consensus/ScriptAddressReader.cs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,36 @@ namespace Blockcore.Consensus
99
public class ScriptAddressReader : IScriptAddressReader
1010
{
1111
/// <inheritdoc cref="IScriptAddressReader.GetAddressFromScriptPubKey"/>
12-
public string GetAddressFromScriptPubKey(Network network, Script script)
12+
public ScriptAddressResult GetAddressFromScriptPubKey(Network network, Script script)
1313
{
1414
ScriptTemplate scriptTemplate = network.StandardScriptsRegistry.GetTemplateFromScriptPubKey(script);
1515

16-
string destinationAddress = null;
16+
var destinationAddress = new ScriptAddressResult();
1717

1818
switch (scriptTemplate?.Type)
1919
{
2020
// Pay to PubKey can be found in outputs of staking transactions.
2121
case TxOutType.TX_PUBKEY:
2222
PubKey pubKey = PayToPubkeyTemplate.Instance.ExtractScriptPubKeyParameters(script);
23-
destinationAddress = pubKey.GetAddress(network).ToString();
23+
destinationAddress.Address = pubKey.GetAddress(network).ToString();
2424
break;
2525
// Pay to PubKey hash is the regular, most common type of output.
2626
case TxOutType.TX_PUBKEYHASH:
27-
destinationAddress = script.GetDestinationAddress(network).ToString();
27+
destinationAddress.Address = script.GetDestinationAddress(network).ToString();
2828
break;
29+
2930
case TxOutType.TX_SCRIPTHASH:
30-
destinationAddress = script.GetDestinationAddress(network).ToString();
31+
destinationAddress.Address = script.GetDestinationAddress(network).ToString();
32+
break;
33+
34+
case TxOutType.TX_COLDSTAKE:
35+
destinationAddress = this.GetColdStakeAddresses(network, script);
3136
break;
37+
3238
case TxOutType.TX_SEGWIT:
33-
destinationAddress = script.GetDestinationAddress(network).ToString();
39+
destinationAddress.Address = script.GetDestinationAddress(network).ToString();
3440
break;
41+
3542
case TxOutType.TX_NONSTANDARD:
3643
case TxOutType.TX_MULTISIG:
3744
case TxOutType.TX_NULL_DATA:
@@ -40,5 +47,15 @@ public string GetAddressFromScriptPubKey(Network network, Script script)
4047

4148
return destinationAddress;
4249
}
50+
51+
public ScriptAddressResult GetColdStakeAddresses(Network network, Script script)
52+
{
53+
var destinationAddressResult = script.GetColdStakeDestinationAddress(network);
54+
return new ScriptAddressResult()
55+
{
56+
HotAddress = destinationAddressResult.hotAddress.ToString(),
57+
ColdAddress = destinationAddressResult.coldAddress.ToString()
58+
};
59+
}
4360
}
44-
}
61+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
namespace Blockcore.Consensus
2+
{
3+
/// <summary>
4+
/// The script result address.
5+
/// </summary>
6+
public class ScriptAddressResult
7+
{
8+
/// <summary>
9+
/// Will return the script public address if exists, Otherwise returns <see cref="string.Empty"/>
10+
/// </summary>
11+
public static implicit operator string(ScriptAddressResult scriptAddressResult)
12+
{
13+
return scriptAddressResult.Address.ToString();
14+
}
15+
16+
/// <summary>
17+
/// If Address, Hot and Cold addresses are all empty, it will return true, otherwise false.
18+
/// </summary>
19+
public bool IsNullOrEmpty()
20+
{
21+
return string.IsNullOrEmpty(this.Address) &&
22+
string.IsNullOrEmpty(this.HotAddress) &&
23+
string.IsNullOrEmpty(this.ColdAddress);
24+
}
25+
26+
/// <summary>
27+
/// Will return the script public address if exists, Otherwise returns <see cref="string.Empty"/>
28+
/// </summary>
29+
public string Address { get; set; } = string.Empty;
30+
31+
/// <summary>
32+
/// Will return the script hot public address if exists, Otherwise returns <see cref="string.Empty"/>
33+
/// </summary>
34+
public string HotAddress { get; set; } = string.Empty;
35+
36+
/// <summary>
37+
/// Will return the script cold public address if exists, Otherwise returns <see cref="string.Empty"/>
38+
/// </summary>
39+
public string ColdAddress { get; set; } = string.Empty;
40+
41+
}
42+
}

src/Features/Blockcore.Features.ColdStaking/ColdStakingScriptSigParameters.cs renamed to src/Blockcore/Consensus/ScriptInfo/ColdStakingScriptSigParameters.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
using Blockcore.Consensus.ScriptInfo;
2-
using Blockcore.Consensus.TransactionInfo;
1+
using Blockcore.Consensus.TransactionInfo;
32
using NBitcoin;
43

5-
namespace Blockcore.Features.ColdStaking
4+
namespace Blockcore.Consensus.ScriptInfo
65
{
76
/// <summary>
87
/// The scriptSig parameters used for cold staking script.

src/Features/Blockcore.Features.ColdStaking/ColdStakingScriptTemplate.cs renamed to src/Blockcore/Consensus/ScriptInfo/ColdStakingScriptTemplate.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
using System;
22
using System.Linq;
3-
using Blockcore.Consensus;
43
using Blockcore.Consensus.BlockInfo;
5-
using Blockcore.Consensus.ScriptInfo;
64
using Blockcore.Consensus.TransactionInfo;
75
using Blockcore.Networks;
86
using Blockcore.Utilities;
97
using NBitcoin;
108
using static Blockcore.Consensus.ScriptInfo.OpcodeType;
119

12-
namespace Blockcore.Features.ColdStaking
10+
namespace Blockcore.Consensus.ScriptInfo
1311
{
1412
/// <summary>
1513
/// Script template for the cold staking script.

src/Blockcore/Consensus/ScriptInfo/Script.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,24 @@ public BitcoinAddress GetDestinationAddress(Network network)
10111011
return dest == null ? null : dest.GetAddress(network);
10121012
}
10131013

1014+
/// <summary>
1015+
/// Extract ColdStakingScript addresses from scriptPubKey
1016+
/// </summary>
1017+
/// <param name="network"></param>
1018+
/// <returns>Both hot and cold <c>BitcoinAddress</c> addresses</returns>
1019+
public (BitcoinAddress hotAddress, BitcoinAddress coldAddress) GetColdStakeDestinationAddress(Network network)
1020+
{
1021+
bool hasAddresses = ColdStakingScriptTemplate.Instance.ExtractScriptPubKeyParameters(this, out KeyId hotKeyId, out KeyId coldKeyId);
1022+
if (hasAddresses)
1023+
{
1024+
return (hotKeyId.GetAddress(network), coldKeyId.GetAddress(network));
1025+
}
1026+
else
1027+
{
1028+
return (null, null);
1029+
}
1030+
}
1031+
10141032
/// <summary>
10151033
/// Extract P2SH/P2PH/P2WSH/P2WPKH id from scriptPubKey
10161034
/// </summary>
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Blockcore.Consensus.ScriptInfo;
1+
using Blockcore.Consensus;
2+
using Blockcore.Consensus.ScriptInfo;
23
using Blockcore.Networks;
34
using NBitcoin;
45

@@ -12,9 +13,6 @@ public interface IScriptAddressReader
1213
/// <summary>
1314
/// Extracts an address from a given Script, if available. Otherwise returns <see cref="string.Empty"/>
1415
/// </summary>
15-
/// <param name="network"></param>
16-
/// <param name="script"></param>
17-
/// <returns></returns>
18-
string GetAddressFromScriptPubKey(Network network, Script script);
16+
ScriptAddressResult GetAddressFromScriptPubKey(Network network, Script script);
1917
}
20-
}
18+
}

src/Features/Blockcore.Features.BlockStore/AddressIndexing/AddressIndexer.cs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -447,15 +447,22 @@ private bool ProcessBlock(Block block, ChainedHeader header)
447447
if (amountSpent == 0)
448448
continue;
449449

450-
string address = this.scriptAddressReader.GetAddressFromScriptPubKey(this.network, new Script(consumedOutputData.ScriptPubKeyBytes));
450+
var address = this.scriptAddressReader.GetAddressFromScriptPubKey(this.network, new Script(consumedOutputData.ScriptPubKeyBytes));
451451

452-
if (string.IsNullOrEmpty(address))
452+
if (address.IsNullOrEmpty())
453453
{
454454
// This condition need not be logged, as the address reader should be aware of all possible address formats already.
455455
continue;
456456
}
457457

458-
this.ProcessBalanceChangeLocked(header.Height, address, amountSpent, false);
458+
if (address.Address != string.Empty)
459+
this.ProcessBalanceChangeLocked(header.Height, address.Address, amountSpent, false);
460+
461+
if (address.HotAddress != string.Empty)
462+
this.ProcessBalanceChangeLocked(header.Height, address.HotAddress, amountSpent, false);
463+
464+
if (address.ColdAddress != string.Empty)
465+
this.ProcessBalanceChangeLocked(header.Height, address.ColdAddress, amountSpent, false);
459466
}
460467

461468
// Process outputs.
@@ -469,16 +476,23 @@ private bool ProcessBlock(Block block, ChainedHeader header)
469476
if (amountReceived == 0 || txOut.IsEmpty || txOut.ScriptPubKey.IsUnspendable)
470477
continue;
471478

472-
string address = this.scriptAddressReader.GetAddressFromScriptPubKey(this.network, txOut.ScriptPubKey);
479+
var address = this.scriptAddressReader.GetAddressFromScriptPubKey(this.network, txOut.ScriptPubKey);
473480

474-
if (string.IsNullOrEmpty(address))
481+
if (address.IsNullOrEmpty())
475482
{
476483
// This condition need not be logged, as the address reader should be aware of all
477484
// possible address formats already.
478485
continue;
479486
}
480487

481-
this.ProcessBalanceChangeLocked(header.Height, address, amountReceived, true);
488+
if (address.Address != string.Empty)
489+
this.ProcessBalanceChangeLocked(header.Height, address.Address, amountReceived, true);
490+
491+
if (address.HotAddress != string.Empty)
492+
this.ProcessBalanceChangeLocked(header.Height, address.HotAddress, amountReceived, true);
493+
494+
if (address.ColdAddress != string.Empty)
495+
this.ProcessBalanceChangeLocked(header.Height, address.ColdAddress, amountReceived, true);
482496
}
483497
}
484498

src/Features/Blockcore.Features.ColdStaking/ColdStakingFeature.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Blockcore.Configuration.Logging;
1010
using Blockcore.Connection;
1111
using Blockcore.Connection.Broadcasting;
12+
using Blockcore.Consensus.ScriptInfo;
1213
using Blockcore.Features.BlockStore;
1314
using Blockcore.Features.MemoryPool;
1415
using Blockcore.Features.RPC;

0 commit comments

Comments
 (0)