Skip to content

Instantly share code, notes, and snippets.

@spentak
Last active October 2, 2018 17:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spentak/c6f95aec1aef6ddb1de5322318ea2e50 to your computer and use it in GitHub Desktop.
Save spentak/c6f95aec1aef6ddb1de5322318ea2e50 to your computer and use it in GitHub Desktop.
Code for creating a SimpleWallet on the NEM blockchain in C#
/// 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