public virtual string SignTransaction(string aTxData, ICurrencyTransaction aValidationInfo) { if (aValidationInfo.Outputs.Length > 2) { throw new ArgumentException("Invalid output."); } var lTxOutput = aValidationInfo.Outputs.First(); var lFromAddress = aValidationInfo.Inputs[0].Address.ToLower(); var lToAddress = lTxOutput.Address; var lKeyIndex = FAddresses[lFromAddress]; var lAmount = lTxOutput.Amount; var lTokenData = !string.IsNullOrEmpty(lTxOutput.Script) ? lTxOutput.Script : null; //var lNonceStr = Encoding.Default.GetString(HexStringToByteArray(aTxData)); //I removed this line because biginteger already accepts hex string lCleanHexNonce = string.Concat("0", aTxData.Replace("0x", string.Empty)); var lNonce = BigInteger.Parse(lCleanHexNonce, System.Globalization.NumberStyles.HexNumber); var lGasLimit = lTokenData == null ? 21000 : 60000; // number of gass units you can use BigInteger lGasPrice = aValidationInfo.TxFee / lGasLimit; var lChainID = aValidationInfo.CurrencyId == 10196 ? 3 : 1; //10196 is ropsten but this may be changed to a boolean into currency item var lResult = (new TransactionSigner()).SignTransaction(GetBinaryPrivateKey((int)lKeyIndex), lChainID, lToAddress, lAmount, lNonce, lGasPrice, lGasLimit, lTokenData); return(lResult); }
public virtual string SignTransaction(string aTxData, ICurrencyTransaction aValidationInfo) { if (!CustomTransaction.GetCustomTransaction(Id, out Transaction tx, aTxData, Network)) { tx = new Transaction(aTxData, Network); } // check how much is being spent and insure all is spent. BigInteger lTotalSent = 0; foreach (ITransactionUnit linput in aValidationInfo.Inputs) { lTotalSent += linput.Amount; } BigInteger lTotalSpending = aValidationInfo.TxFee; foreach (ITransactionUnit lOutput in aValidationInfo.Outputs) { lTotalSpending += lOutput.Amount; } if (lTotalSent != lTotalSpending) { throw new Exception("The total of the inputs does not equal the total outputs."); } // Check output amounts in the transaction to sign. int lValidCount = 0; foreach (TxOut lOutput in tx.Outputs) { string lAddress = lOutput.GetAddress(Network); foreach (ITransactionUnit lValOut in aValidationInfo.Outputs) { if (lAddress == lValOut.Address) { if (lOutput.Value.Satoshi == lValOut.Amount) { lValidCount++; } } } } if (lValidCount != aValidationInfo.Outputs.Length) { throw new Exception("Transaction to sign is not correct."); } List <CCKey> lKeys = new List <CCKey>(); List <ICoin> lCoins = new List <ICoin>(); for (int i = 0; i < tx.Inputs.Count; i++) { if (!FAddressLookup.TryGetValue(aValidationInfo.Inputs[i].Address, out long lIndex)) { throw new Exception(string.Format("Address {0} does not exist.", aValidationInfo.Inputs[i].Address)); } lKeys.Add(GetCCKey(lIndex)); ITransactionUnit lPrevOut = aValidationInfo.Inputs .Where(lInput => lInput.TxID == tx.Inputs[i].PrevOut.Hash.ToString() && lInput.Index == tx.Inputs[i].PrevOut.N) .FirstOrDefault(); if (lPrevOut == null) { throw new Exception("Failed to found previous tx out information"); } lCoins.Add(new Coin(tx.Inputs[i].PrevOut, new TxOut() { ScriptPubKey = tx.Inputs[i].ScriptSig, Value = new Money((long)lPrevOut.Amount) })); tx.Inputs[i].ScriptSig = Script.Empty; } var lHexTest = tx.ToHex(); tx.Sign(lKeys.ToArray(), lCoins.ToArray()); return(tx.ToHex()); }