Skip to content
This repository has been archived by the owner on Jan 26, 2023. It is now read-only.

Commit

Permalink
Added MultiSig test and versioned TransferTransaction
Browse files Browse the repository at this point in the history
  • Loading branch information
alexkof committed Jun 17, 2018
1 parent 59b11d8 commit ce94810
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 43 deletions.
63 changes: 35 additions & 28 deletions WavesCS/Node.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class Node
public const string TestNetHost = "https://testnode1.wavesnodes.com";
public const string MainNetHost = "https://nodes.wavesnodes.com";

private readonly string _host;
private readonly string _host;

public Node(string nodeHost = TestNetHost)
{
Expand All @@ -21,25 +21,25 @@ public Node(string nodeHost = TestNetHost)
_host = nodeHost;
}


public Dictionary<string, object> GetObject(string url, params object[] args)
{
{
return Http.GetObject($"{_host}/{url}", args);
}

public IEnumerable<Dictionary<string, object>> GetObjects(string url, params object[] args)
{
return Http.GetObjects($"{_host}/{url}", args);
}
}

public int GetHeight()
{
return GetObject("blocks/height").GetInt("height");
}

public decimal GetBalance(string address)
{
return GetObject($"addresses/balance/{address}").GetDecimal("balance", Assets.WAVES);
return GetObject($"addresses/balance/{address}").GetDecimal("balance", Assets.WAVES);
}

public decimal GetBalance(string address, int confirmations)
Expand All @@ -49,16 +49,16 @@ public decimal GetBalance(string address, int confirmations)

public decimal GetBalance(string address, Asset asset)
{
return GetObject($"assets/balance/{address}/{asset.Id}").GetDecimal("balance", asset);
return GetObject($"assets/balance/{address}/{asset.Id}").GetDecimal("balance", asset);
}

public int GetUnconfirmedPoolSize()
{
return GetObject("transactions/unconfirmed/size").GetInt("size");
}
return GetObject("transactions/unconfirmed/size").GetInt("size");
}

public Dictionary<string, object> GetAddressData(string address)
{
{
return GetObjects("addresses/data/{0}", address)
.ToDictionary(o => o.GetString("key"), o =>
{
Expand All @@ -80,40 +80,42 @@ public Asset GetAsset(string assetId)
throw new ArgumentException("Wrong asset id (transaction type)");
return new Asset(assetId, tx.GetString("name"), tx.GetByte("decimals"));
}

public string Transfer(PrivateKeyAccount sender, string recipient, Asset asset, decimal amount, string message = "")

public string Transfer(PrivateKeyAccount sender, string recipient, Asset asset, decimal amount,
string message = "")
{
var tx = new TransferTransaction(sender.PublicKey, recipient, asset, amount, message);
tx.Sign(sender);
tx.Sign(sender);
return Broadcast(tx);
}

public string MassTransfer(PrivateKeyAccount sender, Asset asset, IEnumerable<MassTransferItem> transfers, string message = "")

public string MassTransfer(PrivateKeyAccount sender, Asset asset, IEnumerable<MassTransferItem> transfers,
string message = "")
{
var tx = new MassTransferTransaction(sender.PublicKey, asset, transfers, message);
tx.Sign(sender);
tx.Sign(sender);
return Broadcast(tx);
}

public string Lease(PrivateKeyAccount sender, string recipient, decimal amount)
{
var tx = new LeaseTransaction(sender.PublicKey, recipient, amount);
tx.Sign(sender);
tx.Sign(sender);
return Broadcast(tx);
}

public string CancelLease(PrivateKeyAccount account, string transactionId)
{
var tx = new CancelLeasingTransaction(account.PublicKey, transactionId);
tx.Sign(account);
tx.Sign(account);
return Broadcast(tx);
}

public Asset IssueAsset(PrivateKeyAccount account,
string name, string description, decimal quantity, byte decimals, bool reissuable)
{
string name, string description, decimal quantity, byte decimals, bool reissuable)
{
var tx = new IssueTransaction(account.PublicKey, name, description, quantity, decimals, reissuable);
tx.Sign(account);
tx.Sign(account);
var response = Broadcast(tx);
var assetId = response.ParseJsonObject().GetString("id");
return new Asset(assetId, name, decimals);
Expand All @@ -122,7 +124,7 @@ public Asset IssueAsset(PrivateKeyAccount account,
public string ReissueAsset(PrivateKeyAccount account, Asset asset, decimal quantity, bool reissuable)
{
var tx = new ReissueTransaction(account.PublicKey, asset, quantity, reissuable);
tx.Sign(account);
tx.Sign(account);
return Broadcast(tx);
}

Expand All @@ -139,14 +141,19 @@ public string CreateAlias(PrivateKeyAccount account, string alias, char scheme,
tx.Sign(account);
return Broadcast(tx);
}

public string PutData(PrivateKeyAccount account, DictionaryObject entries)
{
var tx = new DataTransaction(account.PublicKey, entries);
tx.Sign(account);
tx.Sign(account);
return Broadcast(tx);
}

public byte[] CompileScript(string script)
{
return Post("/utils/script/compile", script).ParseJsonObject().Get<string>("script").FromBase64();
}

public string Post(string url, string data)
{
return Http.Post(_host + url, data);
Expand Down
2 changes: 1 addition & 1 deletion WavesCS/PrivateKeyAccount.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ private static byte[] GetPublicKeyFromPrivateKey(byte[] privateKey)
var publicKey = new byte[privateKey.Length];
Curve_sigs.curve25519_keygen(publicKey, privateKey);
return publicKey;
}
}

public static string GenerateSeed()
{
Expand Down
2 changes: 1 addition & 1 deletion WavesCS/Transactions/DataTransaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public override Dictionary<string, object> GetJson()
{
{"key", pair.Key},
{"type", pair.Value is long ? "integer" : (pair.Value is bool ? "boolean" : (pair.Value is string ? "string" : "binary"))},
{"value", pair.Value is byte[] bytes ? "base64:" + bytes.ToBase64() : pair.Value }
{"value", pair.Value is byte[] bytes ? bytes.ToBase64() : pair.Value }
})},
{"fee", Assets.WAVES.AmountToLong(Fee)},
{"timestamp", Timestamp.ToLong()},
Expand Down
2 changes: 1 addition & 1 deletion WavesCS/Transactions/SetScriptTransaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public override Dictionary<string, object> GetJson()
{"type", TransactionType.SetScript},
{"version", Version},
{"senderPublicKey", SenderPublicKey.ToBase58()},
{"script", Script == null ? null : "base64:" + Script.ToBase64()},
{"script", Script == null ? null : Script.ToBase64()},
{"fee", Assets.WAVES.AmountToLong(Fee)},
{"timestamp", Timestamp.ToLong()}
};
Expand Down
2 changes: 1 addition & 1 deletion WavesCS/Transactions/Transaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public DictionaryObject GetJsonWithSignature()
if (proofs.Length == 0)
throw new InvalidOperationException("Transaction is not signed");
if (proofs.Length > 1)
throw new InvalidOperationException("Transaction type and version doesn't support multipl proofs");
throw new InvalidOperationException("Transaction type and version doesn't support multiple proofs");
json.Add("signature", proofs.Single());
}
return json;
Expand Down
21 changes: 14 additions & 7 deletions WavesCS/Transactions/TransferTransaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@ public class TransferTransaction : Transaction
public Asset FeeAsset { get; }
public byte[] Attachment { get; }

public static byte Version = 1;

public TransferTransaction(byte[] senderPublicKey, string recipient,
Asset asset, decimal amount, string attachment) :
this(senderPublicKey, recipient, asset, amount, Encoding.UTF8.GetBytes(attachment))
this(senderPublicKey, recipient, asset, amount, 0.001m, Encoding.UTF8.GetBytes(attachment))
{
}

public TransferTransaction(byte[] senderPublicKey, string recipient,
Asset asset, decimal amount, byte[] attachment = null) :
this(senderPublicKey, recipient, asset, amount, 0.001m, Assets.WAVES, attachment)
Asset asset, decimal amount, decimal fee = 0.001m, byte[] attachment = null) :
this(senderPublicKey, recipient, asset, amount, fee, Assets.WAVES, attachment)
{
}

Expand All @@ -39,9 +41,11 @@ public TransferTransaction(byte[] senderPublicKey, string recipient,
public override byte[] GetBody()
{
using(var stream = new MemoryStream())
using (var writer = new BinaryWriter(stream))
using(var writer = new BinaryWriter(stream))
{
writer.Write(TransactionType.Transfer);
if (Version == 2)
writer.Write(Version);
writer.Write(SenderPublicKey);
writer.WriteAsset(Asset.Id);
writer.WriteAsset(FeeAsset.Id);
Expand All @@ -57,9 +61,9 @@ public override byte[] GetBody()

public override Dictionary<string, object> GetJson()
{
return new Dictionary<string, object>
var result = new Dictionary<string, object>
{
{"type", TransactionType.Transfer},
{"type", TransactionType.Transfer},
{"senderPublicKey", SenderPublicKey.ToBase58()},
{"recipient", Recipient},
{"amount", Asset.AmountToLong(Amount)},
Expand All @@ -69,11 +73,14 @@ public override Dictionary<string, object> GetJson()
{"timestamp", Timestamp.ToLong()},
{"attachment", Attachment.ToBase58()}
};
if (Version > 1)
result.Add("version", Version);
return result;
}

protected override bool SupportsProofs()
{
return false;
return Version == 2;
}
}
}
2 changes: 1 addition & 1 deletion WavesCS/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static long ToLong(this DateTime date)

public static string ToBase64(this byte[] data)
{
return Convert.ToBase64String(data);
return "base64:" + Convert.ToBase64String(data);
}

public static byte[] FromBase64(this string data)
Expand Down
50 changes: 47 additions & 3 deletions WavesCSTests/SetScriptTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json.Serialization;
using WavesCS;

namespace WavesCSTests
Expand All @@ -20,19 +22,19 @@ public void TestSetScript()
var node = new Node();

var script = "true";
var compiledScript = node.Post("/utils/script/compile", script).ParseJsonObject().Get<string>("script");
var compiledScript = node.CompileScript(script);

Console.WriteLine("Compiled script: {0}", compiledScript);

var setScriptTx = new SetScriptTransaction(Accounts.Carol.PublicKey, compiledScript.FromBase64(), 'T');
var setScriptTx = new SetScriptTransaction(Accounts.Carol.PublicKey, compiledScript, 'T');
setScriptTx.Sign(Accounts.Carol);
node.Broadcast(setScriptTx.GetJsonWithSignature());

Thread.Sleep(10000);

var scriptInfo = node.GetObject("addresses/scriptInfo/{0}", Accounts.Carol.Address);
Assert.AreEqual("TRUE", scriptInfo["scriptText"]);
Assert.AreEqual(compiledScript, scriptInfo["script"]);
Assert.AreEqual(compiledScript.ToBase64(), scriptInfo["script"]);
Assert.IsTrue(scriptInfo.GetInt("complexity") > 0);
Assert.IsTrue(scriptInfo.GetInt("extraFee") > 0);

Expand All @@ -48,5 +50,47 @@ public void TestSetScript()
Assert.AreEqual(0, scriptInfo.GetInt("extraFee"));
}


[TestMethod]
public void MultisigTest()
{
// This test works with tranfer transactions of version 2 only
TransferTransaction.Version = 2;
var node = new Node();

var script = $@"
let aliceSigned = sigVerify(tx.bodyBytes, tx.proofs[0], base58'{Accounts.Alice.PublicKey.ToBase58()}')
let bobSigned = sigVerify(tx.bodyBytes, tx.proofs[1], base58'{Accounts.Bob.PublicKey.ToBase58()}')
aliceSigned && bobSigned";

Console.WriteLine($"Scrit: {script}");

var compiledScript = node.CompileScript(script);

var multiAccount = PrivateKeyAccount.CreateFromSeed(PrivateKeyAccount.GenerateSeed(), AddressEncoding.TestNet);
Console.WriteLine("Account generated: {0}", multiAccount.Address);
node.Transfer(Accounts.Alice, multiAccount.Address, Assets.WAVES, 0.1m);

Thread.Sleep(10000);

Assert.IsTrue(node.GetBalance(multiAccount.Address) == 0.1m);

var setScriptTx = new SetScriptTransaction(multiAccount.PublicKey, compiledScript, 'T');
setScriptTx.Sign(multiAccount);
node.Broadcast(setScriptTx.GetJsonWithSignature());

Thread.Sleep(10000);

var tx = new TransferTransaction(multiAccount.PublicKey, Accounts.Alice.Address, Assets.WAVES, 0.09m, 0.005m);
tx.Sign(Accounts.Alice, 0);
tx.Sign(Accounts.Bob, 1);

node.Broadcast(tx);

Thread.Sleep(10000);

Assert.IsTrue(node.GetBalance(multiAccount.Address) < 0.02m);
}

}
}

0 comments on commit ce94810

Please sign in to comment.