Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat next release 0916 #73

Merged
merged 8 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Substrate.NetApi.Test/Keys/Ed25519Tests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using NUnit.Framework;
using Substrate.NetApi.Model.Types;
using Substrate.NetApi.Model.Types.Base;
Expand Down Expand Up @@ -133,7 +134,7 @@ public void Ed25519SignatureTestComparePolkadotJs(string polkadotJsSignature)

[Test]
[TestCase("0xd2baabb61bcd0026e797136cb0938d55e3c3ea8825c163eb3d1738b3c79af8e8f4953ba4767dc5477202756d3fba97bc50fc3ac8355ff5acfba88a36311f2f0f")]
public void AccountEd25519SignatureTestComparePolkadotJs(string polkadotJsSignature)
public async Task AccountEd25519SignatureTestComparePolkadotJsAsync(string polkadotJsSignature)
{
var rawSeed = "0x70f93a75dbc6ad5b0c051210704a00a9937732d0c360792b0fea24efb8ea8465";

Expand All @@ -146,7 +147,7 @@ public void AccountEd25519SignatureTestComparePolkadotJs(string polkadotJsSignat
// According to https://github.com/polkadot-js/apps/blob/master/packages/page-signing/src/Sign.tsx#L93
var messageBytes = WrapMessage.Wrap(message);

var signature = account.Sign(messageBytes);
var signature = await account.SignRawAsync(messageBytes);
var singatureHexString = Utils.Bytes2HexString(signature);

// SIGn C#: 0x679FA7BC8B2A7C40B5ECD50CA041E961DB8971D2B454DB7DE64E543B3C1892A6D3F223DDA01C66B9878C149CFCC8B86ECF2B20F11F7610596F51479405776907
Expand Down
5 changes: 3 additions & 2 deletions Substrate.NetApi.Test/Keys/Sr25519Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using NUnit.Framework;
using Schnorrkel.Keys;
using Substrate.NetApi.Model.Types;
using System.Threading.Tasks;

namespace Substrate.NetApi.Test.Keys
{
Expand Down Expand Up @@ -88,7 +89,7 @@ public void Sr25519SignatureTestComparePolkadotJs(string polkadotJsSignature)

[Test]
[TestCase("0x5c42ac4e2d55b8e59d9b255af370de03fe177f5545eecbbd784531cb2eb1f2553e0e2b91656f99fae930eb6ff8ac1a3eca4e19d307ecb39832a479a478a8608a")]
public void AccountSr25519SignatureTestComparePolkadotJs(string polkadotJsSignature)
public async Task AccountSr25519SignatureTestComparePolkadotJsAsync(string polkadotJsSignature)
{
var miniSecretAlice = new MiniSecret(Utils.HexToByteArray("0xe5be9a5092b81bca64be81d212e7f2f9eba183bb7a90954f7b76361f6edb5c0a"), ExpandMode.Ed25519);

Expand All @@ -97,7 +98,7 @@ public void AccountSr25519SignatureTestComparePolkadotJs(string polkadotJsSignat
var message = "I test this signature!";
var messageBytes = WrapMessage.Wrap(message);

var simpleSign = account.Sign(messageBytes);
var simpleSign = await account.SignRawAsync(messageBytes);
var singatureHexString = Utils.Bytes2HexString(simpleSign);
// SIGn C#: 0x2A6346A8707A9929B65167C448F719FE977F2EE04D2CB250685C98C79CCBF2458901F9B386D08422D9102FBD8BF7CFECDF7605F4CDC5FA8D121E2E9730F9098C

Expand Down
5 changes: 3 additions & 2 deletions Substrate.NetApi/Model/Extrinsics/Extrinsic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,15 @@ public Extrinsic(string str, ChargeType chargeType) : this(Utils.HexToByteArray(
/// <summary>
/// Initializes a new instance of the <see cref="Extrinsic"/> class.
/// </summary>
/// <param name="memory">The memory.</param>
/// <param name="memory"></param>
/// <param name="chargeType"></param>
internal Extrinsic(Memory<byte> memory, ChargeType chargeType)
{
int p = 0;
int m;

// length
var length = CompactInteger.Decode(memory.ToArray(), ref p);
_ = CompactInteger.Decode(memory.ToArray(), ref p);

// signature version
m = 1;
Expand Down
25 changes: 17 additions & 8 deletions Substrate.NetApi/Model/Extrinsics/Payload.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
using System.Linq;
using Substrate.NetApi.Model.Types;
using System.Linq;

namespace Substrate.NetApi.Model.Extrinsics
{
/// <summary>
/// Payload
/// </summary>
public class Payload
public class Payload : IEncodable
{
private readonly Method _call;
public readonly Method Call;

private readonly SignedExtensions _signedExtension;
public readonly SignedExtensions SignedExtension;

/// <summary>
/// Initializes a new instance of the <see cref="Payload"/> class.
Expand All @@ -18,17 +19,25 @@ public class Payload
/// <param name="signedExtensions">The signed extensions.</param>
public Payload(Method call, SignedExtensions signedExtensions)
{
_call = call;
_signedExtension = signedExtensions;
Call = call;
SignedExtension = signedExtensions;
}

/// <summary>
/// Encodes this instance.
/// Encodes this instance, returns the encoded bytes. Additionally, if
/// the encoded bytes are longer than 256 bytes, they are hashed using `blake2_256`.
/// </summary>
/// <returns></returns>
public byte[] Encode()
{
byte[] bytes = _call.Encode().Concat(_signedExtension.Encode()).ToArray();
byte[] bytes = Call.Encode().Concat(SignedExtension.Encode()).ToArray();

// Payloads longer than 256 bytes are going to be `blake2_256`-hashed.
if (bytes.Length > 256)
{
bytes = HashExtension.Blake2(bytes, 256);
}

return bytes;
}
}
Expand Down
42 changes: 21 additions & 21 deletions Substrate.NetApi/Model/Extrinsics/SignedExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ namespace Substrate.NetApi.Model.Extrinsics
/// </summary>
public class SignedExtensions
{
private readonly uint _specVersion;
public readonly uint SpecVersion;

private readonly uint _txVersion;
public readonly uint TxVersion;

private readonly Hash _genesis;
public readonly Hash Genesis;

private readonly Hash _startEra;
public readonly Hash StartEra;

private readonly Era _mortality;
public readonly Era Mortality;

private readonly CompactInteger _nonce;
public readonly CompactInteger Nonce;

private readonly ChargeType _charge;
public readonly ChargeType Charge;

/// <summary>
/// Initializes a new instance of the <see cref="SignedExtensions"/> class.
Expand All @@ -34,13 +34,13 @@ public class SignedExtensions
/// <param name="chargeTransactionPayment">The charge transaction payment.</param>
public SignedExtensions(uint specVersion, uint txVersion, Hash genesis, Hash startEra, Era mortality, CompactInteger nonce, ChargeType charge)
{
_specVersion = specVersion;
_txVersion = txVersion;
_genesis = genesis;
_startEra = startEra;
_mortality = mortality;
_nonce = nonce;
_charge = charge;
SpecVersion = specVersion;
TxVersion = txVersion;
Genesis = genesis;
StartEra = startEra;
Mortality = mortality;
Nonce = nonce;
Charge = charge;
}

/// <summary>
Expand All @@ -52,13 +52,13 @@ public byte[] GetExtra()
var bytes = new List<byte>();

// CheckMortality
bytes.AddRange(_mortality.Encode());
bytes.AddRange(Mortality.Encode());

// CheckNonce
bytes.AddRange(_nonce.Encode());
bytes.AddRange(Nonce.Encode());

// ChargeType
bytes.AddRange(_charge.Encode());
bytes.AddRange(Charge.Encode());

return bytes.ToArray();
}
Expand All @@ -72,16 +72,16 @@ public byte[] GetAdditionalSigned()
var bytes = new List<byte>();

// CheckSpecVersion
bytes.AddRange(Utils.Value2Bytes(_specVersion));
bytes.AddRange(Utils.Value2Bytes(SpecVersion));

// CheckTxVersion
bytes.AddRange(Utils.Value2Bytes(_txVersion));
bytes.AddRange(Utils.Value2Bytes(TxVersion));

// CheckGenesis
bytes.AddRange(_genesis.Bytes);
bytes.AddRange(Genesis.Bytes);

// CheckMortality, Additional Blockhash check. Immortal = genesis_hash, Mortal = logic
bytes.AddRange(_startEra.Bytes);
bytes.AddRange(StartEra.Bytes);

return bytes.ToArray();
}
Expand Down
50 changes: 41 additions & 9 deletions Substrate.NetApi/Model/Types/Account.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
using Chaos.NaCl;
using Newtonsoft.Json;
using Schnorrkel;
using Substrate.NetApi.Model.Extrinsics;
using Substrate.NetApi.Model.Types.Base;
using System;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;

namespace Substrate.NetApi.Model.Types
{
/// <summary>
/// Represents a key type.
/// Enum KeyType represents the type of cryptographic keys used in digital signatures.
/// </summary>
public enum KeyType
{
/// <summary>
/// Ed25519
/// Ed25519: Elliptic Curve Digital Signature Algorithm using SHA-512 and Curve25519.
/// Preferred for its balance of security and performance, suitable for scenarios
/// requiring fast signature verification. Commonly used in secure communication,
/// authentication, and blockchain applications.
/// </summary>
Ed25519,

/// <summary>
/// Sr25519
/// Sr25519: Schnorr signature scheme using SHA-512 and Curve25519, implemented in Schnorrkel.
/// Offers advantages in complex cryptographic constructions and potentially better performance.
/// Frequently used in decentralized systems and advanced cryptographic protocols.
/// </summary>
Sr25519
}
Expand All @@ -31,9 +38,16 @@ public interface IAccount
/// <summary>
/// Sign the specified message.
/// </summary>
/// <param name="message"></param>
/// <param name="message">The message bytes.</param>
/// <returns></returns>
Task<byte[]> SignRawAsync(byte[] message);

/// <summary>
/// Sign the specified payload.
/// </summary>
/// <param name="payload">The payload.</param>
/// <returns></returns>
byte[] Sign(byte[] message);
Task<byte[]> SignPayloadAsync(Payload payload);

/// <summary>
/// Verifies a signature from this account.
Expand Down Expand Up @@ -106,6 +120,12 @@ public void Create(KeyType keyType, byte[] publicKey)
Create(keyType, null, publicKey);
}

/// <inheritdoc/>
public override void CreateFromJson(string str)
{
throw new NotSupportedException("CreateFromJson is not supported for Account.");
}

/// <summary>
/// Builds the specified key type.
/// </summary>
Expand All @@ -121,26 +141,37 @@ public static Account Build(KeyType keyType, byte[] privateKey, byte[] publicKey
}

/// <summary>
/// Signs the specified message.
/// Asynchronously signs the specified message.
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
/// <exception cref="NotSupportedException"></exception>
public byte[] Sign(byte[] message)
public virtual async Task<byte[]> SignRawAsync(byte[] message)
{
switch (KeyType)
{
case KeyType.Ed25519:
return Ed25519.Sign(message, PrivateKey);
return await Task.Run(() => Ed25519.Sign(message, PrivateKey));

case KeyType.Sr25519:
return Sr25519v091.SignSimple(Bytes, PrivateKey, message);
return await Task.Run(() => Sr25519v091.SignSimple(Bytes, PrivateKey, message));

default:
throw new NotSupportedException($"Unknown key type found '{KeyType}'.");
}
}

/// <summary>
/// Asynchronously signs the specified payload.
/// </summary>
/// <param name="payload"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public virtual async Task<byte[]> SignPayloadAsync(Payload payload)
{
return await SignRawAsync(payload.Encode());
}

/// <summary>
/// Verifies a signature from this account.
/// </summary>
Expand Down Expand Up @@ -174,5 +205,6 @@ public bool Verify(byte[] signature, byte[] publicKey, byte[] message)
throw new NotSupportedException($"Unknown key type found '{KeyType}'.");
}
}

}
}
4 changes: 2 additions & 2 deletions Substrate.NetApi/Model/Types/Base/BaseType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ public virtual void Create(byte[] byteArray)
}

/// <summary>
/// Create from a json string
/// Create from JSON is used to deserialize in GenericTypeConverters, to automatically convert scale encoded JSON Rust types to C# types.
/// </summary>
/// <param name="str"></param>
public virtual void CreateFromJson(string str) => Create(Utils.HexToByteArray(str));

/// <summary>
/// New
/// Create a new instance of the type, this uses the default constructor.
/// </summary>
/// <returns></returns>
public IType New() => this;
Expand Down
Loading
Loading