From a4b03cdffde107068c270cb3c4b99937e9d89544 Mon Sep 17 00:00:00 2001 From: Erikos Alkalai Date: Fri, 15 Jan 2016 16:21:17 +0100 Subject: [PATCH 1/6] Introduce Asset of a Tx Vout In the initial library it was defined as an object --- MultiChainLib/Model/AssetVout.cs | 27 ++++++++++++++++++++++++++ MultiChainLib/Model/TransactionVout.cs | 4 ++-- MultiChainLib/MultiChainLib.csproj | 1 + 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 MultiChainLib/Model/AssetVout.cs diff --git a/MultiChainLib/Model/AssetVout.cs b/MultiChainLib/Model/AssetVout.cs new file mode 100644 index 0000000..91a4b34 --- /dev/null +++ b/MultiChainLib/Model/AssetVout.cs @@ -0,0 +1,27 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MultiChainLib +{ + public class AssetVout + { + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("issuetxid")] + public string IssueTxId { get; set; } + + [JsonProperty("assetref")] + public string AssetRef { get; set; } + + [JsonProperty("qty")] + public decimal Qty { get; set; } + + [JsonProperty("raw")] + public long Raw { get; set; } + } +} diff --git a/MultiChainLib/Model/TransactionVout.cs b/MultiChainLib/Model/TransactionVout.cs index f4a0487..4ba8bab 100644 --- a/MultiChainLib/Model/TransactionVout.cs +++ b/MultiChainLib/Model/TransactionVout.cs @@ -19,14 +19,14 @@ public class TransactionVout public ScriptPubKeyResponse ScriptPubKey { get; set; } [JsonProperty("assets")] - public List Assets { get; set; } + public List Assets { get; set; } [JsonProperty("permissions")] public List Permissions { get; set; } public TransactionVout() { - this.Assets = new List(); + this.Assets = new List(); this.Permissions = new List(); } } diff --git a/MultiChainLib/MultiChainLib.csproj b/MultiChainLib/MultiChainLib.csproj index e081a27..3893693 100644 --- a/MultiChainLib/MultiChainLib.csproj +++ b/MultiChainLib/MultiChainLib.csproj @@ -54,6 +54,7 @@ + From 1a05b19a985f16340c426f79a4164055f2a68032 Mon Sep 17 00:00:00 2001 From: Erikos Alkalai Date: Tue, 2 Feb 2016 17:00:29 +0100 Subject: [PATCH 2/6] upgrade listunspent to include addresses --- MultiChainLib/Client/MultiChainClient.cs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/MultiChainLib/Client/MultiChainClient.cs b/MultiChainLib/Client/MultiChainClient.cs index e4301d8..2794290 100644 --- a/MultiChainLib/Client/MultiChainClient.cs +++ b/MultiChainLib/Client/MultiChainClient.cs @@ -62,6 +62,7 @@ public Task> SendToAddressAsync(string address, string a var theAmount = new Dictionary(); theAmount[assetName] = amount; return this.ExecuteAsync("sendtoaddress", 0, address, theAmount, comment ?? string.Empty, + return this.ExecuteAsync("sendtoaddress", 0, address, theAmount, comment ?? string.Empty, commentTo ?? string.Empty); } @@ -72,7 +73,7 @@ public Task> SendWithMetadataFromAsync(string fromAddres return this.ExecuteAsync("sendwithmetadatafrom", 0, fromAddress, toAddress, theAmount, FormatHex(dataHex)); } - public Task> SendAssetToAddressAsync(string address, string assetName, decimal quantity, + public Task> SendAssetToAddressAsync(string address, string assetName, decimal quantity, int nativeAmount = 0, string comment = null, string commentTo = null) { return this.ExecuteAsync("sendassettoaddress", 0, address, assetName, quantity, nativeAmount, @@ -176,7 +177,7 @@ public Task>> ListPermissions(Bloc return this.ExecuteAsync>("listpermissions", 0, permissionsAsString); } - public Task> IssueAsync(string issueAddress, string assetName, int quantity, decimal units, + public Task> IssueAsync(string issueAddress, string assetName, int quantity, decimal units, decimal nativeAmount = 0, string comment = null, string commentTo = null, int startBlock = 0, int endBlock = 0) { return this.ExecuteAsync("issue", 0, issueAddress, assetName, quantity, units); /*, nativeAmount, comment, @@ -517,7 +518,20 @@ public Task> ListSinceBlockAsync(str public Task>> ListUnspentAsync(int minConf = 1, int maxConf = 999999, IEnumerable addresses = null) { - return this.ExecuteAsync>("listunspent", 0, minConf, maxConf); + //multichain - cli testbc listunspent 1 999999[\"4Qk5zZJbJNRTjwVETGzyBbgCW5ePVt7j4vuXTc\"] + + StringBuilder builder = new StringBuilder(); + + foreach (var address in addresses) + { + if (builder.Length > 0) + builder.Append(","); + builder.Append(address); + } + builder.Insert(0, "["); + builder.Append("]"); + //return this.ExecuteAsync>("listunspent", 0, minConf, maxConf,addresses!=null?builder.ToString():string.Empty); + return this.ExecuteAsync>("listunspent", 0, minConf, maxConf, addresses ??null); } public Task>> ListLockUnspentAsync() From 204867c32a7055af5848f98e5092925a8ac08d7a Mon Sep 17 00:00:00 2001 From: Erikos Alkalai Date: Tue, 2 Feb 2016 17:01:47 +0100 Subject: [PATCH 3/6] Create raw transaction Dynamically create objects with addresses and amounts --- MultiChainLib/Client/MultiChainClient.cs | 19 ++++++--- .../Model/CreateRawTransactionAmount.cs | 42 +++++++++++++++++++ .../Model/CreateRawTransactionTxIn.cs | 25 +++++++++++ MultiChainLib/MultiChainLib.csproj | 2 + 4 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 MultiChainLib/Model/CreateRawTransactionAmount.cs create mode 100644 MultiChainLib/Model/CreateRawTransactionTxIn.cs diff --git a/MultiChainLib/Client/MultiChainClient.cs b/MultiChainLib/Client/MultiChainClient.cs index 2794290..61467d7 100644 --- a/MultiChainLib/Client/MultiChainClient.cs +++ b/MultiChainLib/Client/MultiChainClient.cs @@ -61,7 +61,6 @@ public Task> SendToAddressAsync(string address, string a { var theAmount = new Dictionary(); theAmount[assetName] = amount; - return this.ExecuteAsync("sendtoaddress", 0, address, theAmount, comment ?? string.Empty, return this.ExecuteAsync("sendtoaddress", 0, address, theAmount, comment ?? string.Empty, commentTo ?? string.Empty); } @@ -214,7 +213,7 @@ public Task> RevokeAsync(IEnumerable addresses, commentTo ?? string.Empty, startBlock, endBlock);*/ } - public Task> GrantFromAsync(string fromAddress, IEnumerable toAddresses, BlockchainPermissions permissions, decimal nativeAmount = 0M, + public Task> GrantFromAsync(string fromAddress, IEnumerable toAddresses, BlockchainPermissions permissions, decimal nativeAmount = 0M, string comment = null, string commentTo = null, int startBlock = 0, int endBlock = 0) { var stringifiedAddresses = this.StringifyValues(toAddresses); @@ -383,10 +382,20 @@ public Task> VerifyChainAsync(CheckBlockType type = CheckB return this.ExecuteAsync("verifychain", 0, (int)type, numBlocks); } - // not implemented -- contact us with specific implementation requirements and we'll implement this... - public Task> CreateRawTransactionAync() + public Task> CreateRawTransactionAync(IEnumerable txids = null, IEnumerable assets = null) { - throw new NotImplementedException("This operation has not been implemented."); + string amountstr = string.Empty; + dynamic flexible; + flexible = new System.Dynamic.ExpandoObject(); + var dictionary = (IDictionary)flexible; + if (assets != null) + { + foreach (var asset in assets) + { + dictionary.Add(asset.Address, asset.StringifyAmount()); + } + } + return this.ExecuteAsync("createrawtransaction", 0, txids, dictionary); } // not implemented -- contact us with specific implementation requirements and we'll implement this... diff --git a/MultiChainLib/Model/CreateRawTransactionAmount.cs b/MultiChainLib/Model/CreateRawTransactionAmount.cs new file mode 100644 index 0000000..7ba0612 --- /dev/null +++ b/MultiChainLib/Model/CreateRawTransactionAmount.cs @@ -0,0 +1,42 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MultiChainLib +{ + public class CreateRawTransactionAmount + { + public string Address { get; set; } + public Decimal Qty { get; set; } + + public CreateRawTransactionAmount() + { + } + + //"1DK3fuhpAqHWAvNtbWHqsyHYxUsK38N878t3nZ":qty, + public virtual object StringifyAmount() + { + return Qty; + } + } + + public class CreateRawTransactionAsset: CreateRawTransactionAmount + { + public string Name { get; set; } + public CreateRawTransactionAsset() { } + + //"1DK3fuhpAqHWAvNtbWHqsyHYxUsK38N878t3nZ":{"asset":qty}, + public override object StringifyAmount() + { + dynamic flexible; + flexible = new System.Dynamic.ExpandoObject(); + var dictionary = (IDictionary)flexible; + dictionary.Add(Name, Qty); + + return dictionary; + } + } +} diff --git a/MultiChainLib/Model/CreateRawTransactionTxIn.cs b/MultiChainLib/Model/CreateRawTransactionTxIn.cs new file mode 100644 index 0000000..8e582ef --- /dev/null +++ b/MultiChainLib/Model/CreateRawTransactionTxIn.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MultiChainLib +{ + public class CreateRawTransactionTxIn + { + [JsonProperty("txid")] + public string TxId { get; set; } + + [JsonProperty("vout")] + public int Vout { get; set; } + + + public CreateRawTransactionTxIn() + { + } + + + } +} diff --git a/MultiChainLib/MultiChainLib.csproj b/MultiChainLib/MultiChainLib.csproj index 3893693..17a3e9c 100644 --- a/MultiChainLib/MultiChainLib.csproj +++ b/MultiChainLib/MultiChainLib.csproj @@ -59,6 +59,8 @@ + + From ee80166f120df23709594ba5971068cb71a8c009 Mon Sep 17 00:00:00 2001 From: Erikos Alkalai Date: Tue, 2 Feb 2016 17:07:29 +0100 Subject: [PATCH 4/6] Sign raw transaction implementation --- MultiChainLib/Client/MultiChainClient.cs | 14 +++++------ .../Model/SignRawTransactionResponse.cs | 23 +++++++++++++++++++ MultiChainLib/MultiChainLib.csproj | 1 + 3 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 MultiChainLib/Model/SignRawTransactionResponse.cs diff --git a/MultiChainLib/Client/MultiChainClient.cs b/MultiChainLib/Client/MultiChainClient.cs index 61467d7..3ae49d1 100644 --- a/MultiChainLib/Client/MultiChainClient.cs +++ b/MultiChainLib/Client/MultiChainClient.cs @@ -389,13 +389,13 @@ public Task> CreateRawTransactionAync(IEnumerable)flexible; if (assets != null) - { + { foreach (var asset in assets) - { + { dictionary.Add(asset.Address, asset.StringifyAmount()); - } + } } - return this.ExecuteAsync("createrawtransaction", 0, txids, dictionary); + return this.ExecuteAsync("createrawtransaction", 0, txids, dictionary); } // not implemented -- contact us with specific implementation requirements and we'll implement this... @@ -404,10 +404,10 @@ public Task> SendRawTransactionAsync() throw new NotImplementedException("This operation has not been implemented."); } - // not implemented -- contact us with specific implementation requirements and we'll implement this... - public Task> SignRawTransactionAsync() + + public Task> SignRawTransactionAsync(string hex) { - throw new NotImplementedException("This operation has not been implemented."); + return this.ExecuteAsync("signrawtransaction", 0, hex); } public Task> PrioritiseTransactionAsync(string txId, decimal priority, int feeSatoshis) diff --git a/MultiChainLib/Model/SignRawTransactionResponse.cs b/MultiChainLib/Model/SignRawTransactionResponse.cs new file mode 100644 index 0000000..f3c844b --- /dev/null +++ b/MultiChainLib/Model/SignRawTransactionResponse.cs @@ -0,0 +1,23 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MultiChainLib +{ + public class SignRawTransactionResponse + { + [JsonProperty("hex")] + public string Hex { get; set; } + + [JsonProperty("complete")] + public bool Complete { get; set; } + + + public SignRawTransactionResponse() + { + } + } +} diff --git a/MultiChainLib/MultiChainLib.csproj b/MultiChainLib/MultiChainLib.csproj index 17a3e9c..b05654b 100644 --- a/MultiChainLib/MultiChainLib.csproj +++ b/MultiChainLib/MultiChainLib.csproj @@ -78,6 +78,7 @@ + From 20f3ac04706316ab20decf49c8aae79381a5c0be Mon Sep 17 00:00:00 2001 From: Erikos Alkalai Date: Tue, 2 Feb 2016 17:10:38 +0100 Subject: [PATCH 5/6] send raw transaction implementation --- MultiChainLib/Client/MultiChainClient.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MultiChainLib/Client/MultiChainClient.cs b/MultiChainLib/Client/MultiChainClient.cs index 3ae49d1..4494312 100644 --- a/MultiChainLib/Client/MultiChainClient.cs +++ b/MultiChainLib/Client/MultiChainClient.cs @@ -398,10 +398,10 @@ public Task> CreateRawTransactionAync(IEnumerable("createrawtransaction", 0, txids, dictionary); } - // not implemented -- contact us with specific implementation requirements and we'll implement this... - public Task> SendRawTransactionAsync() + + public Task> SendRawTransactionAsync(string hex) { - throw new NotImplementedException("This operation has not been implemented."); + return this.ExecuteAsync("sendrawtransaction", 0, hex); } From 6f157728b3810c09818ea2f74ad44b76525c92a2 Mon Sep 17 00:00:00 2001 From: Erikos Alkalai Date: Thu, 25 Feb 2016 18:09:19 +0100 Subject: [PATCH 6/6] Adding methods and fixings PrepareLockUnspent fixing listlockUnspent --- MultiChainLib/Client/MultiChainClient.cs | 68 ++++++++++++++++--- .../Model/PrepareLockUnspentAmount.cs | 28 ++++++++ MultiChainLib/MultiChainLib.csproj | 6 ++ 3 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 MultiChainLib/Model/PrepareLockUnspentAmount.cs diff --git a/MultiChainLib/Client/MultiChainClient.cs b/MultiChainLib/Client/MultiChainClient.cs index 4494312..c7652ee 100644 --- a/MultiChainLib/Client/MultiChainClient.cs +++ b/MultiChainLib/Client/MultiChainClient.cs @@ -389,22 +389,22 @@ public Task> CreateRawTransactionAync(IEnumerable)flexible; if (assets != null) - { + { foreach (var asset in assets) - { + { dictionary.Add(asset.Address, asset.StringifyAmount()); - } + } } - return this.ExecuteAsync("createrawtransaction", 0, txids, dictionary); + return this.ExecuteAsync("createrawtransaction", 0, txids, dictionary); } - + public Task> SendRawTransactionAsync(string hex) { return this.ExecuteAsync("sendrawtransaction", 0, hex); } - + public Task> SignRawTransactionAsync(string hex) { return this.ExecuteAsync("signrawtransaction", 0, hex); @@ -525,12 +525,60 @@ public Task> ListSinceBlockAsync(str return this.ExecuteAsync("listsinceblock", 0, hash, confirmations, watchOnly); } + public Task> PrepareLockUnspent(string address = null, IEnumerable amounts = null, bool _lock = true) + { + //multichain - cli testbc preparelockunspent '{"asset1":100,"asset2":20}' + + string amountstr = string.Empty; + dynamic flexible; + flexible = new System.Dynamic.ExpandoObject(); + var dictionary = (IDictionary)flexible; + if (amounts != null) + { + foreach (var amount in amounts) + { + dictionary.Add(amount.Name, amount.Qty); + } + } + if (address == null) + return this.ExecuteAsync("preparelockunspent", 0, dictionary, _lock); + + return this.ExecuteAsync("preparelockunspentfrom", 0, address, dictionary, _lock); + } + + + public Task> PrepareLockUnspent(IEnumerable amounts = null, bool _lock = true) + { + //multichain - cli testbc preparelockunspent '{"asset1":100,"asset2":20}' + + string amountstr = string.Empty; + dynamic flexible; + flexible = new System.Dynamic.ExpandoObject(); + var dictionary = (IDictionary)flexible; + if (amounts != null) + { + foreach (var amount in amounts) + { + dictionary.Add(amount.Name, amount.Qty); + } + } + + return this.ExecuteAsync("preparelockunspent", 0, dictionary, _lock); + } + + public Task> LockUnspent(bool unlock, IEnumerable unspentTxs = null) + { + + + return this.ExecuteAsync("lockunspent", 0, unlock, unspentTxs); + } + public Task>> ListUnspentAsync(int minConf = 1, int maxConf = 999999, IEnumerable addresses = null) { //multichain - cli testbc listunspent 1 999999[\"4Qk5zZJbJNRTjwVETGzyBbgCW5ePVt7j4vuXTc\"] StringBuilder builder = new StringBuilder(); - + foreach (var address in addresses) { if (builder.Length > 0) @@ -540,12 +588,12 @@ public Task>> ListUnspentAsync(int minConf builder.Insert(0, "["); builder.Append("]"); //return this.ExecuteAsync>("listunspent", 0, minConf, maxConf,addresses!=null?builder.ToString():string.Empty); - return this.ExecuteAsync>("listunspent", 0, minConf, maxConf, addresses ??null); + return this.ExecuteAsync>("listunspent", 0, minConf, maxConf, addresses ?? null); } - public Task>> ListLockUnspentAsync() + public Task>> ListLockUnspentAsync() { - return this.ExecuteAsync>("listlockunspent", 0); + return this.ExecuteAsync>("listlockunspent", 0); } public Task>> GetAddressesAsync() diff --git a/MultiChainLib/Model/PrepareLockUnspentAmount.cs b/MultiChainLib/Model/PrepareLockUnspentAmount.cs new file mode 100644 index 0000000..a7bf8b3 --- /dev/null +++ b/MultiChainLib/Model/PrepareLockUnspentAmount.cs @@ -0,0 +1,28 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MultiChainLib +{ + public class PrepareLockUnspentAmount + { + public string Name { get; set; } + public Decimal Qty { get; set; } + + public PrepareLockUnspentAmount() { } + public PrepareLockUnspentAmount(string name, decimal qty) { Name = name; Qty = qty; } + + public object StringifyAmount() + { + dynamic flexible; + flexible = new System.Dynamic.ExpandoObject(); + var dictionary = (IDictionary)flexible; + dictionary.Add(Name, Qty); + + return dictionary; + } + } +} diff --git a/MultiChainLib/MultiChainLib.csproj b/MultiChainLib/MultiChainLib.csproj index b05654b..ca8f8e5 100644 --- a/MultiChainLib/MultiChainLib.csproj +++ b/MultiChainLib/MultiChainLib.csproj @@ -11,6 +11,10 @@ MultiChainLib v4.5.2 512 + SAK + SAK + SAK + SAK true @@ -59,6 +63,7 @@ + @@ -93,6 +98,7 @@ +