Last active
October 2, 2018 17:01
-
-
Save spentak/c6f95aec1aef6ddb1de5322318ea2e50 to your computer and use it in GitHub Desktop.
Code for creating a SimpleWallet on the NEM blockchain in C#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Created by Jacob Luetzow | |
/// Copyright Blockstart 2018 | |
using System; | |
using System.Text; | |
using System.Security.Cryptography; | |
using Org.BouncyCastle.Crypto.Digests; | |
using io.blockstart.sdk.Core.Crypto; | |
using io.blockstart.sdk.Core.Crypto.Chaso.NaCl; | |
using io.blockstart.sdk.Model.Blockchain; | |
using io.blockstart.sdk.Model.Accounts; | |
using Newtonsoft.Json; | |
using Newtonsoft.Json.Linq; | |
namespace io.blockstart.sdk.Model.Wallet { | |
public class SimpleWallet : Wallet { | |
/// <summary> | |
/// Gets the EncryptedPrivateKey | |
/// </summary> | |
public EncryptedPrivateKey EncryptedPrivateKey { get; } | |
/// <summary> | |
/// Initailizes a new instance of SimpleWallet | |
/// </summary> | |
/// <param name="name"></param> | |
/// <param name="network"></param> | |
/// <param name="address"></param> | |
/// <param name="creationDate"></param> | |
/// <param name="encryptedPrivateKey"></param> | |
private SimpleWallet(string name, NetworkType.Types network, Address address, DateTime creationDate, EncryptedPrivateKey encryptedPrivateKey): | |
base(name, network, address, creationDate, "simple_v1") | |
{ | |
EncryptedPrivateKey = encryptedPrivateKey; | |
} | |
/// <summary> | |
/// Create a new Simple Wallet | |
/// </summary> | |
/// <param name="name"></param> | |
/// <param name="password"></param> | |
/// <param name="network"></param> | |
/// <returns>SimpleWallet</returns> | |
public static SimpleWallet Create(string name, string password, NetworkType.Types network) | |
{ | |
using (var ng = RandomNumberGenerator.Create()) { | |
// Create random bytes | |
byte[] bytes = new byte[2048]; | |
ng.GetNonZeroBytes(bytes); | |
// Hash random bytes with entropy seed | |
// Finalize and keep only 32 bytes | |
var digestSha3 = new Sha3Digest(256); | |
var stepOne = new byte[32]; | |
digestSha3.BlockUpdate(bytes, 0, 32); | |
digestSha3.DoFinal(stepOne, 0); | |
// Create KeyPair from hash key | |
var keyPair = KeyPair.CreateFromPrivateKey(stepOne.ToHexLower()); | |
// Create address from public key | |
var address = Address.CreateFromPublicKey(keyPair.PublicKeyString, network); | |
// Encrypt private key using password | |
var encryptedPrivateKey = CryptoUtils.EncodePrivateKey(new Password(password).value, keyPair.PrivateKeyString); | |
return new SimpleWallet(name, network, address, DateTime.Now, encryptedPrivateKey); | |
} | |
} | |
/// <summary> | |
/// Create a Simple Wallet from private key | |
/// </summary> | |
/// <param name="name"></param> | |
/// <param name="password"></param> | |
/// <param name="privateKey"></param> | |
/// <param name="network"></param> | |
/// <returns>SimpleWallet</returns> | |
public static SimpleWallet CreateFromPrivateKey(string name, string password, string privateKey, NetworkType.Types network) | |
{ | |
var keyPair = KeyPair.CreateFromPrivateKey(privateKey); | |
var address = Address.CreateFromPublicKey(keyPair.PublicKeyString, network); | |
var encryptedPrivateKey = CryptoUtils.EncodePrivateKey(new Password(password).value, privateKey); | |
return new SimpleWallet(name, network, address, DateTime.Now, encryptedPrivateKey); | |
} | |
/// <summary> | |
/// Convert SimpleWallet Object to String | |
/// </summary> | |
/// <param name="simpleWallet"></param> | |
/// <returns>String</returns> | |
public static string writeWLTFile(SimpleWallet simpleWallet) | |
{ | |
var wlt = JsonConvert.SerializeObject(simpleWallet); | |
return Convert.ToBase64String(Encoding.UTF8.GetBytes(wlt)); | |
} | |
/// <summary> | |
/// Convert WLT String to SimpleWallet | |
/// </summary> | |
/// <param name="wlt"></param> | |
/// <returns>SimpleWallet</returns> | |
public static SimpleWallet readFromWLT(string wlt) | |
{ | |
var joObject = JObject.Parse(ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(wlt))); | |
var address = new Address(joObject["Address"]["Plain"].ToString(), NetworkType.GetRawValue(Int32.Parse(joObject["Address"]["NetworkByte"].ToString()))); | |
var encryptedPrivateKey = new EncryptedPrivateKey(joObject["EncryptedPrivateKey"]["EncryptedKey"].ToString(), joObject["EncryptedPrivateKey"]["IV"].ToString()); | |
return new SimpleWallet(joObject["Name"].ToString(), | |
NetworkType.GetRawValue(Int32.Parse(joObject["Network"].ToString())), | |
address, | |
DateTime.Parse(joObject["CreationDate"].ToString()), | |
encryptedPrivateKey); | |
} | |
public Account Open(string password) { | |
return Account.CreateFromPrivateKey(CryptoUtils.PasswordToPrivateKey(password, this), Network); | |
} | |
} | |
} | |
namespace io.blockstart.sdk.Model.Mosaics | |
{ | |
public class MosaicView | |
{ | |
/// <summary> | |
/// Gets the MosaicInfo | |
/// </summary> | |
public MosaicInfo MosaicInfo { get; } | |
/// <summary> | |
/// Gets the NamespaceName | |
/// </summary> | |
public string NamespaceName { get; } | |
/// <summary> | |
/// Gets the MosaicName | |
/// </summary> | |
public string MosaicName { get; } | |
/// <summary> | |
/// Initializes a new instance of MosaicView | |
/// </summary> | |
/// <param name="mosaicInfo"></param> | |
/// <param name="namespaceName"></param> | |
/// <param name="mosaicName"></param> | |
public MosaicView(MosaicInfo mosaicInfo, string namespaceName, string mosaicName) | |
{ | |
MosaicInfo = mosaicInfo; | |
NamespaceName = namespaceName; | |
MosaicName = mosaicName; | |
} | |
/// <summary> | |
/// Namespace and Mosaic name | |
/// </summary> | |
/// <returns>FullName</returns> | |
public string FullName() | |
{ | |
return NamespaceName + ":" + MosaicName; | |
} | |
} | |
} | |
namespace io.blockstart.sdk.Model.Mosaics | |
{ | |
public class MosaicAmountView | |
{ | |
/// <summary> | |
/// Gets the MosaicInfo | |
/// </summary> | |
public MosaicInfo MosaicInfo { get; } | |
/// <summary> | |
/// Gets the NamespaceName | |
/// </summary> | |
public string NamespaceName { get; } | |
/// <summary> | |
/// Gets the MosaicName | |
/// </summary> | |
public string MosaicName { get; } | |
/// <summary> | |
/// Gets the Amount | |
/// </summary> | |
public UInt64 Amount { get; } | |
/// <summary> | |
/// Initializes a new instance of MosaicAmountView | |
/// </summary> | |
/// <param name="mosaicInfo"></param> | |
/// <param name="namespaceName"></param> | |
/// <param name="mosaicName"></param> | |
/// <param name="amount"></param> | |
public MosaicAmountView(MosaicInfo mosaicInfo, string namespaceName, string mosaicName, UInt64 amount) | |
{ | |
MosaicInfo = mosaicInfo; | |
NamespaceName = namespaceName; | |
MosaicName = mosaicName; | |
Amount = amount; | |
} | |
/// <summary> | |
/// Relative amount deviding amount by the divisbility | |
/// </summary> | |
/// <returns>RelativeAmount</returns> | |
public double RelativeAmount() | |
{ | |
if (MosaicInfo.Divisibility == 0) { return Amount; } | |
return Amount / Math.Pow(10, MosaicInfo.Divisibility); | |
} | |
/// <summary> | |
/// Namespace and Mosaic name | |
/// </summary> | |
/// <returns>FullName</returns> | |
public string FullName() | |
{ | |
return NamespaceName + ":" + MosaicName; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment