From 18ad5a4916d78760fc8e7411c8b97961b390f4c2 Mon Sep 17 00:00:00 2001 From: quantumagi Date: Tue, 6 Apr 2021 18:46:29 +1000 Subject: [PATCH 1/7] Enable passing signatures to SC method calls --- .../BuildCallContractTransactionRequest.cs | 8 ++++ .../BuildCreateContractTransactionRequest.cs | 9 ++++ .../Wallet/SmartContractWalletController.cs | 44 +++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCallContractTransactionRequest.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCallContractTransactionRequest.cs index b3fa86da0a..37225b4561 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCallContractTransactionRequest.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCallContractTransactionRequest.cs @@ -104,6 +104,14 @@ public BuildCallContractTransactionRequest() /// public string[] Parameters { get; set; } + /// + /// An array of base 64 encoded strings containing the signatures to add if a "system contract" method "create" transaction is being created. + /// + /// + /// The strings passed here are typically obtained by signatories via the "signmessage" API by signing the "challenge" string returned by a method. + /// + public string[] Signatures { get; set; } + public override string ToString() { var builder = new StringBuilder(); diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCreateContractTransactionRequest.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCreateContractTransactionRequest.cs index b92c9e9703..73bfcf3cbe 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCreateContractTransactionRequest.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCreateContractTransactionRequest.cs @@ -96,6 +96,15 @@ public BuildCreateContractTransactionRequest() /// public string[] Parameters { get; set; } + /// + /// An array of base 64 encoded strings containing the signatures to add if a "system contract" method "create" transaction is being created. + /// + /// + /// The strings passed here are typically obtained by signatories via the "signmessage" API by signing the "challenge" string returned by a method. + /// + + public string[] Signatures { get; set; } + public override string ToString() { var builder = new StringBuilder(); diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletController.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletController.cs index cf48bd5ad3..27fe453861 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletController.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletController.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using NBitcoin; +using NBitcoin.DataEncoders; using Stratis.Bitcoin.Connection; using Stratis.Bitcoin.Features.SmartContracts.Models; using Stratis.Bitcoin.Features.Wallet; @@ -270,6 +271,39 @@ public IActionResult GetHistory(GetHistoryRequest request) } } + private string[] ReplaceSignatures(string[] parameters, string[] signatures, out IActionResult errorResult) + { + // If signatures have been included then they replace the SIG# parameter. + string encodedSigs = null; + for (int i = 0; i < parameters.Length; i++) + { + if (parameters[i] == "SIG#") + { + if (encodedSigs == null) + { + var sigs = signatures.Select(s => Convert.FromBase64String(s)).ToArray(); + if (sigs.Any(s => s.Length != 65 || s[0] < 27 || s[0] > 34)) + { + errorResult = ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, "Invalid signature.", "Input Exception"); + return parameters; + } + + var sigbuf = new byte[signatures.Length * 65]; + for (int j = 0; j < sigs.Length; j++) + Array.Copy(sigs[j], 0, sigbuf, j * 65, 65); + + encodedSigs = $"10#{Encoders.Hex.EncodeData(sigbuf)}"; + } + + parameters[i] = encodedSigs; + } + } + + errorResult = null; + + return parameters; + } + /// /// Builds a transaction to create a smart contract and then broadcasts the transaction to the network. /// If the deployment is successful, methods on the smart contract can be subsequently called. @@ -290,6 +324,11 @@ public IActionResult Create([FromBody] BuildCreateContractTransactionRequest req if (!this.ModelState.IsValid) return ModelStateErrors.BuildErrorResponse(this.ModelState); + // If signatures have been included then they replace the SIG# parameter. + request.Parameters = ReplaceSignatures(request.Parameters, request.Signatures, out IActionResult errorResult); + if (errorResult != null) + return errorResult; + BuildCreateContractTransactionResponse response = this.smartContractTransactionService.BuildCreateTx(request); if (!response.Success) @@ -332,6 +371,11 @@ public IActionResult Call([FromBody] BuildCallContractTransactionRequest request if (!this.ModelState.IsValid) return ModelStateErrors.BuildErrorResponse(this.ModelState); + // If signatures have been included then they replace the SIG# parameter. + request.Parameters = ReplaceSignatures(request.Parameters, request.Signatures, out IActionResult errorResult); + if (errorResult != null) + return errorResult; + BuildCallContractTransactionResponse response = this.smartContractTransactionService.BuildCallTx(request); if (!response.Success) From 22acf41ebb7dcc99194a0c671628acc84cae68aa Mon Sep 17 00:00:00 2001 From: quantumagi Date: Wed, 7 Apr 2021 13:32:25 +1000 Subject: [PATCH 2/7] Refactor --- .../Wallet/SmartContractTransactionService.cs | 35 +++++++++++++++ .../Wallet/SmartContractWalletController.cs | 43 ------------------- 2 files changed, 35 insertions(+), 43 deletions(-) diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs index 81b008a0c4..7d830d4180 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs @@ -3,6 +3,7 @@ using System.Linq; using CSharpFunctionalExtensions; using NBitcoin; +using NBitcoin.DataEncoders; using Stratis.Bitcoin.Features.SmartContracts.Models; using Stratis.Bitcoin.Features.Wallet; using Stratis.Bitcoin.Features.Wallet.Interfaces; @@ -198,6 +199,34 @@ public BuildContractTransactionResult BuildTx(BuildContractTransactionRequest re return BuildContractTransactionResult.Success(model); } + private string[] ReplaceSignatures(string[] parameters, string[] signatures) + { + // If signatures have been included then they replace the SIG# parameter. + string encodedSigs = null; + for (int i = 0; i < parameters.Length; i++) + { + if (parameters[i] == "SIG#") + { + if (encodedSigs == null) + { + var sigs = signatures.Select(s => Convert.FromBase64String(s)).ToArray(); + if (sigs.Any(s => s.Length != 65 || s[0] < 27 || s[0] > 34)) + throw new Exception("Invalid signature(s)."); + + var sigbuf = new byte[signatures.Length * 65]; + for (int j = 0; j < sigs.Length; j++) + Array.Copy(sigs[j], 0, sigbuf, j * 65, 65); + + encodedSigs = $"10#{Encoders.Hex.EncodeData(sigbuf)}"; + } + + parameters[i] = encodedSigs; + } + } + + return parameters; + } + public BuildCallContractTransactionResponse BuildCallTx(BuildCallContractTransactionRequest request) { if (!this.CheckBalance(request.Sender)) @@ -214,6 +243,9 @@ public BuildCallContractTransactionResponse BuildCallTx(BuildCallContractTransac { try { + // If signatures have been included then they replace the SIG# parameter. + request.Parameters = ReplaceSignatures(request.Parameters, request.Signatures); + object[] methodParameters = this.methodParameterStringSerializer.Deserialize(request.Parameters); txData = new ContractTxData(ReflectionVirtualMachine.VmVersion, (Stratis.SmartContracts.RuntimeObserver.Gas)request.GasPrice, (Stratis.SmartContracts.RuntimeObserver.Gas)request.GasLimit, addressNumeric, request.MethodName, methodParameters); } @@ -275,6 +307,9 @@ public BuildCreateContractTransactionResponse BuildCreateTx(BuildCreateContractT { try { + // If signatures have been included then they replace the SIG# parameter. + request.Parameters = ReplaceSignatures(request.Parameters, request.Signatures); + object[] methodParameters = this.methodParameterStringSerializer.Deserialize(request.Parameters); txData = new ContractTxData(ReflectionVirtualMachine.VmVersion, (Stratis.SmartContracts.RuntimeObserver.Gas)request.GasPrice, (Stratis.SmartContracts.RuntimeObserver.Gas)request.GasLimit, request.ContractCode.HexToByteArray(), methodParameters); } diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletController.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletController.cs index 27fe453861..bcab46eff9 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletController.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletController.cs @@ -271,39 +271,6 @@ public IActionResult GetHistory(GetHistoryRequest request) } } - private string[] ReplaceSignatures(string[] parameters, string[] signatures, out IActionResult errorResult) - { - // If signatures have been included then they replace the SIG# parameter. - string encodedSigs = null; - for (int i = 0; i < parameters.Length; i++) - { - if (parameters[i] == "SIG#") - { - if (encodedSigs == null) - { - var sigs = signatures.Select(s => Convert.FromBase64String(s)).ToArray(); - if (sigs.Any(s => s.Length != 65 || s[0] < 27 || s[0] > 34)) - { - errorResult = ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, "Invalid signature.", "Input Exception"); - return parameters; - } - - var sigbuf = new byte[signatures.Length * 65]; - for (int j = 0; j < sigs.Length; j++) - Array.Copy(sigs[j], 0, sigbuf, j * 65, 65); - - encodedSigs = $"10#{Encoders.Hex.EncodeData(sigbuf)}"; - } - - parameters[i] = encodedSigs; - } - } - - errorResult = null; - - return parameters; - } - /// /// Builds a transaction to create a smart contract and then broadcasts the transaction to the network. /// If the deployment is successful, methods on the smart contract can be subsequently called. @@ -324,11 +291,6 @@ public IActionResult Create([FromBody] BuildCreateContractTransactionRequest req if (!this.ModelState.IsValid) return ModelStateErrors.BuildErrorResponse(this.ModelState); - // If signatures have been included then they replace the SIG# parameter. - request.Parameters = ReplaceSignatures(request.Parameters, request.Signatures, out IActionResult errorResult); - if (errorResult != null) - return errorResult; - BuildCreateContractTransactionResponse response = this.smartContractTransactionService.BuildCreateTx(request); if (!response.Success) @@ -371,11 +333,6 @@ public IActionResult Call([FromBody] BuildCallContractTransactionRequest request if (!this.ModelState.IsValid) return ModelStateErrors.BuildErrorResponse(this.ModelState); - // If signatures have been included then they replace the SIG# parameter. - request.Parameters = ReplaceSignatures(request.Parameters, request.Signatures, out IActionResult errorResult); - if (errorResult != null) - return errorResult; - BuildCallContractTransactionResponse response = this.smartContractTransactionService.BuildCallTx(request); if (!response.Success) From e621ee9e0988dbb4951043359f3d0cf7d9e740b3 Mon Sep 17 00:00:00 2001 From: quantumagi Date: Wed, 7 Apr 2021 14:02:37 +1000 Subject: [PATCH 3/7] Add test case --- .../SmartContractTransactionServiceTests.cs | 105 +++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs index d1828ae954..9804c0c16f 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs @@ -1,10 +1,12 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Globalization; using System.Linq; using CSharpFunctionalExtensions; using Microsoft.Extensions.Logging; using Moq; using NBitcoin; +using NBitcoin.DataEncoders; using Stratis.Bitcoin.Configuration.Logging; using Stratis.Bitcoin.Features.SmartContracts.Models; using Stratis.Bitcoin.Features.SmartContracts.Wallet; @@ -974,5 +976,106 @@ public void BuildFeeEstimationContext_Recipient_Is_Not_P2PKH() ))); } */ + + [Fact] + public void CanPassSignatures() + { + const int utxoIndex = 0; + uint256 utxoId = uint256.Zero; + uint256 utxoIdUnused = uint256.One; + string senderAddress = uint160.Zero.ToBase58Address(this.network); + string contractAddress = uint160.One.ToBase58Address(this.network); + + var key1 = new Key(); + var key2 = new Key(); + var msg = "This is a test challenge"; + var sig1 = key1.SignMessage(msg); + var sig2 = key2.SignMessage(msg); + + var request = new BuildCallContractTransactionRequest + { + Amount = "0", + AccountName = "account 0", + ContractAddress = contractAddress, + FeeAmount = "0.01", + GasLimit = 100_000, + GasPrice = 100, + MethodName = "TestMethod", + WalletName = "wallet", + Password = "password", + Sender = senderAddress, + Outpoints = new List + { + new OutpointRequest + { + Index = utxoIndex, + TransactionId = utxoId.ToString() + }, + }, + Parameters = new[] { "SIG#" }, + Signatures = new[] { sig1, sig2 } + }; + + this.walletManager.Setup(x => x.GetAddressBalance(request.Sender)) + .Returns(new AddressBalance + { + Address = senderAddress, + AmountConfirmed = new Money(100, MoneyUnit.BTC) + }); + + this.walletManager.Setup(x => x.GetSpendableTransactionsInWallet(It.IsAny(), 0)) + .Returns(new List + { + new UnspentOutputReference + { + Address = new HdAddress + { + Address = senderAddress + }, + Transaction = new TransactionData + { + Id = utxoId, + Index = utxoIndex, + } + }, new UnspentOutputReference + { + Address = new HdAddress + { + Address = senderAddress + }, + Transaction = new TransactionData + { + Id = utxoIdUnused, + Index = utxoIndex, + } + } + }); + + var wallet = new Features.Wallet.Wallet(); + wallet.AccountsRoot.Add(new AccountRoot(wallet)); + var account0 = new HdAccount(wallet.AccountsRoot.First().Accounts) { Name = request.AccountName }; + account0.ExternalAddresses.Add(new HdAddress() { Address = senderAddress }); + + this.walletManager.Setup(x => x.GetWallet(request.WalletName)) + .Returns(wallet); + + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); + + var service = new SmartContractTransactionService( + this.network, + this.walletManager.Object, + this.walletTransactionHandler.Object, + this.stringSerializer.Object, + this.callDataSerializer.Object, + this.addressGenerator.Object, + this.stateRepository.Object, + reserveUtxoService); + + BuildCallContractTransactionResponse result = service.BuildCallTx(request); + + string expected = $"10#{Encoders.Hex.EncodeData(Convert.FromBase64String(sig1).Concat(Convert.FromBase64String(sig2)).ToArray())}"; + + this.stringSerializer.Verify(x => x.Deserialize(It.Is(x => x[0] == expected))); + } } } From 17b476ea3cc4eabaa484df86320394b9dff1e777 Mon Sep 17 00:00:00 2001 From: quantumagi Date: Wed, 7 Apr 2021 14:58:22 +1000 Subject: [PATCH 4/7] Check nulls --- .../Wallet/SmartContractTransactionService.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs index 7d830d4180..666525aa08 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs @@ -201,7 +201,10 @@ public BuildContractTransactionResult BuildTx(BuildContractTransactionRequest re private string[] ReplaceSignatures(string[] parameters, string[] signatures) { - // If signatures have been included then they replace the SIG# parameter. + if (parameters == null) + return null; + + // Replace SIG# with any included signatures. string encodedSigs = null; for (int i = 0; i < parameters.Length; i++) { @@ -209,11 +212,11 @@ private string[] ReplaceSignatures(string[] parameters, string[] signatures) { if (encodedSigs == null) { - var sigs = signatures.Select(s => Convert.FromBase64String(s)).ToArray(); + var sigs = (signatures ?? new string[0]).Select(s => Convert.FromBase64String(s)).ToArray(); if (sigs.Any(s => s.Length != 65 || s[0] < 27 || s[0] > 34)) throw new Exception("Invalid signature(s)."); - var sigbuf = new byte[signatures.Length * 65]; + var sigbuf = new byte[sigs.Length * 65]; for (int j = 0; j < sigs.Length; j++) Array.Copy(sigs[j], 0, sigbuf, j * 65, 65); From f10097b8c4012b9dc9decb229ec39c2f40b716d4 Mon Sep 17 00:00:00 2001 From: quantumagi Date: Wed, 7 Apr 2021 15:01:46 +1000 Subject: [PATCH 5/7] Add ToUpper --- .../Wallet/SmartContractTransactionService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs index 666525aa08..7fb445ae82 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs @@ -208,7 +208,7 @@ private string[] ReplaceSignatures(string[] parameters, string[] signatures) string encodedSigs = null; for (int i = 0; i < parameters.Length; i++) { - if (parameters[i] == "SIG#") + if (parameters[i].ToUpper() == "SIG#") { if (encodedSigs == null) { From 9ed78493bb9c0aed045817e6f9002e89c55ab18e Mon Sep 17 00:00:00 2001 From: quantumagi Date: Thu, 8 Apr 2021 15:54:19 +1000 Subject: [PATCH 6/7] Changes based on feedback --- .../Models/BuildCallContractTransactionRequest.cs | 2 +- .../Models/BuildCreateContractTransactionRequest.cs | 2 +- .../Wallet/SmartContractTransactionService.cs | 10 +++++++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCallContractTransactionRequest.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCallContractTransactionRequest.cs index 37225b4561..a70661ccfa 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCallContractTransactionRequest.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCallContractTransactionRequest.cs @@ -105,7 +105,7 @@ public BuildCallContractTransactionRequest() public string[] Parameters { get; set; } /// - /// An array of base 64 encoded strings containing the signatures to add if a "system contract" method "create" transaction is being created. + /// An array of base 64 encoded strings containing the signatures to add. /// /// /// The strings passed here are typically obtained by signatories via the "signmessage" API by signing the "challenge" string returned by a method. diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCreateContractTransactionRequest.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCreateContractTransactionRequest.cs index 73bfcf3cbe..8914a5f15a 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCreateContractTransactionRequest.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Models/BuildCreateContractTransactionRequest.cs @@ -97,7 +97,7 @@ public BuildCreateContractTransactionRequest() public string[] Parameters { get; set; } /// - /// An array of base 64 encoded strings containing the signatures to add if a "system contract" method "create" transaction is being created. + /// An array of base 64 encoded strings containing the signatures to add. /// /// /// The strings passed here are typically obtained by signatories via the "signmessage" API by signing the "challenge" string returned by a method. diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs index 7fb445ae82..3a0e07bf86 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs @@ -201,6 +201,10 @@ public BuildContractTransactionResult BuildTx(BuildContractTransactionRequest re private string[] ReplaceSignatures(string[] parameters, string[] signatures) { + const int signatureLength = 65; + const int minHeaderByte = 27; + const int maxHeaderByte = 34; + if (parameters == null) return null; @@ -213,12 +217,12 @@ private string[] ReplaceSignatures(string[] parameters, string[] signatures) if (encodedSigs == null) { var sigs = (signatures ?? new string[0]).Select(s => Convert.FromBase64String(s)).ToArray(); - if (sigs.Any(s => s.Length != 65 || s[0] < 27 || s[0] > 34)) + if (sigs.Any(s => s.Length != signatureLength || s[0] < minHeaderByte || s[0] > maxHeaderByte)) throw new Exception("Invalid signature(s)."); - var sigbuf = new byte[sigs.Length * 65]; + var sigbuf = new byte[sigs.Length * signatureLength]; for (int j = 0; j < sigs.Length; j++) - Array.Copy(sigs[j], 0, sigbuf, j * 65, 65); + Array.Copy(sigs[j], 0, sigbuf, j * signatureLength, signatureLength); encodedSigs = $"10#{Encoders.Hex.EncodeData(sigbuf)}"; } From 659e631e2d86e8a5534e655b0038dd83e509209e Mon Sep 17 00:00:00 2001 From: quantumagi Date: Thu, 8 Apr 2021 16:02:07 +1000 Subject: [PATCH 7/7] Changes based on feedback --- .../SmartContractTransactionServiceTests.cs | 3 ++- .../Wallet/SmartContractTransactionService.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs index 9804c0c16f..8a1d1c813d 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs @@ -1073,7 +1073,8 @@ public void CanPassSignatures() BuildCallContractTransactionResponse result = service.BuildCallTx(request); - string expected = $"10#{Encoders.Hex.EncodeData(Convert.FromBase64String(sig1).Concat(Convert.FromBase64String(sig2)).ToArray())}"; + byte[] buffer = Convert.FromBase64String(sig1).Concat(Convert.FromBase64String(sig2)).ToArray(); + string expected = $"{(int)MethodParameterDataType.ByteArray}#{Encoders.Hex.EncodeData(buffer)}"; this.stringSerializer.Verify(x => x.Deserialize(It.Is(x => x[0] == expected))); } diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs index 3a0e07bf86..c655cbb564 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs @@ -224,7 +224,7 @@ private string[] ReplaceSignatures(string[] parameters, string[] signatures) for (int j = 0; j < sigs.Length; j++) Array.Copy(sigs[j], 0, sigbuf, j * signatureLength, signatureLength); - encodedSigs = $"10#{Encoders.Hex.EncodeData(sigbuf)}"; + encodedSigs = $"{(int)MethodParameterDataType.ByteArray}#{Encoders.Hex.EncodeData(sigbuf)}"; } parameters[i] = encodedSigs;