diff --git a/src/neo/BigDecimal.cs b/src/neo/BigDecimal.cs
index ad1948f6bc..45e2ae770c 100644
--- a/src/neo/BigDecimal.cs
+++ b/src/neo/BigDecimal.cs
@@ -12,16 +12,39 @@ public struct BigDecimal
public byte Decimals => decimals;
public int Sign => value.Sign;
+ ///
+ /// Create BigDecimal from BigInteger
+ ///
+ /// Value
+ /// Decimals
public BigDecimal(BigInteger value, byte decimals)
{
this.value = value;
this.decimals = decimals;
}
- public BigDecimal(decimal value)
+ ///
+ /// Create BigDecimal from decimal
+ ///
+ /// Value
+ public unsafe BigDecimal(decimal value)
{
- this.decimals = BitConverter.GetBytes(decimal.GetBits(value)[3])[2];
- this.value = new BigInteger(decimal.Multiply((Decimal)Math.Pow(10, this.decimals), value));
+ ReadOnlySpan buffer = new ReadOnlySpan(&value, sizeof(decimal));
+ this.decimals = buffer[14];
+ this.value = new BigInteger(decimal.Multiply((decimal)Math.Pow(10, decimals), value));
+ }
+
+ ///
+ /// Create BigDecimal from decimal
+ ///
+ /// Value
+ /// Decimals
+ public unsafe BigDecimal(decimal value, byte decimals)
+ {
+ ReadOnlySpan buffer = new ReadOnlySpan(&value, sizeof(decimal));
+ if (buffer[14] > decimals) throw new ArgumentException(null, nameof(value));
+ this.value = new BigInteger(decimal.Multiply((decimal)Math.Pow(10, decimals), value));
+ this.decimals = decimals;
}
public BigDecimal ChangeDecimals(byte decimals)
diff --git a/src/neo/Wallets/Wallet.cs b/src/neo/Wallets/Wallet.cs
index d5c9ef0a13..a0dc5c4945 100644
--- a/src/neo/Wallets/Wallet.cs
+++ b/src/neo/Wallets/Wallet.cs
@@ -146,7 +146,7 @@ public BigDecimal GetBalance(UInt160 asset_id, params UInt160[] accounts)
}
using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 20000000L * accounts.Length);
if (engine.State.HasFlag(VMState.FAULT))
- return new BigDecimal(0, 0);
+ return new BigDecimal(BigInteger.Zero, 0);
byte decimals = (byte)engine.ResultStack.Pop().GetInteger();
BigInteger amount = engine.ResultStack.Pop().GetInteger();
return new BigDecimal(amount, decimals);
diff --git a/tests/neo.UnitTests/Ledger/UT_Blockchain.cs b/tests/neo.UnitTests/Ledger/UT_Blockchain.cs
index c2051f40d4..40ba38c868 100644
--- a/tests/neo.UnitTests/Ledger/UT_Blockchain.cs
+++ b/tests/neo.UnitTests/Ledger/UT_Blockchain.cs
@@ -11,6 +11,7 @@
using Neo.Wallets.NEP6;
using System;
using System.Linq;
+using System.Numerics;
using System.Reflection;
namespace Neo.UnitTests.Ledger
@@ -119,7 +120,7 @@ private Transaction CreateValidTx(NEP6Wallet wallet, UInt160 account, uint nonce
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = account,
- Value = new BigDecimal(1,8)
+ Value = new BigDecimal(BigInteger.One,8)
}
},
account);
diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs
index bd949063d3..77d4d5f750 100644
--- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs
+++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs
@@ -139,7 +139,7 @@ public void FeeIsMultiSigContract()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = acc.ScriptHash,
- Value = new BigDecimal(1,8)
+ Value = new BigDecimal(BigInteger.One,8)
}
}, acc.ScriptHash);
@@ -210,7 +210,7 @@ public void FeeIsSignatureContractDetailed()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = acc.ScriptHash,
- Value = new BigDecimal(1,8)
+ Value = new BigDecimal(BigInteger.One,8)
}
}, acc.ScriptHash);
@@ -318,7 +318,7 @@ public void FeeIsSignatureContract_TestScope_Global()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
- BigInteger value = (new BigDecimal(1, 8)).Value;
+ BigInteger value = (new BigDecimal(BigInteger.One, 8)).Value;
sb.EmitDynamicCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value, null);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
@@ -404,7 +404,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
- BigInteger value = (new BigDecimal(1, 8)).Value;
+ BigInteger value = (new BigDecimal(BigInteger.One, 8)).Value;
sb.EmitDynamicCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value, null);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
@@ -491,7 +491,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
- System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value;
+ System.Numerics.BigInteger value = (new BigDecimal(BigInteger.One, 8)).Value;
sb.EmitDynamicCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value, null);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
@@ -579,7 +579,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_FAULT()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
- System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value;
+ System.Numerics.BigInteger value = (new BigDecimal(BigInteger.One, 8)).Value;
sb.EmitDynamicCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
@@ -631,7 +631,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
- BigInteger value = (new BigDecimal(1, 8)).Value;
+ BigInteger value = (new BigDecimal(BigInteger.One, 8)).Value;
sb.EmitDynamicCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value, null);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
@@ -721,7 +721,7 @@ public void FeeIsSignatureContract_TestScope_NoScopeFAULT()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
- BigInteger value = (new BigDecimal(1, 8)).Value;
+ BigInteger value = (new BigDecimal(BigInteger.One, 8)).Value;
sb.EmitDynamicCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
@@ -984,7 +984,7 @@ public void FeeIsSignatureContract_TestScope_FeeOnly_Default()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
- BigInteger value = (new BigDecimal(1, 8)).Value;
+ BigInteger value = (new BigDecimal(BigInteger.One, 8)).Value;
sb.EmitDynamicCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value, null);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
@@ -1128,7 +1128,7 @@ public void Test_VerifyStateIndependent()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = acc.ScriptHash,
- Value = new BigDecimal(1,8)
+ Value = new BigDecimal(BigInteger.One,8)
}
}, acc.ScriptHash);
@@ -1201,7 +1201,7 @@ public void Test_VerifyStateDependent()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = acc.ScriptHash,
- Value = new BigDecimal(1,8)
+ Value = new BigDecimal(BigInteger.One,8)
}
}, acc.ScriptHash);
@@ -1271,7 +1271,7 @@ public void Test_Verify()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = acc.ScriptHash,
- Value = new BigDecimal(1,8)
+ Value = new BigDecimal(BigInteger.One,8)
}
}, acc.ScriptHash);
diff --git a/tests/neo.UnitTests/UT_BigDecimal.cs b/tests/neo.UnitTests/UT_BigDecimal.cs
index ccd147427a..8ea5f05054 100644
--- a/tests/neo.UnitTests/UT_BigDecimal.cs
+++ b/tests/neo.UnitTests/UT_BigDecimal.cs
@@ -39,23 +39,23 @@ public void TestBigDecimalConstructor()
value.Value.Should().Be(new BigInteger(-10));
value.Decimals.Should().Be(0);
- value = new BigDecimal(123.456789M);
+ value = new BigDecimal(123.456789M, 6);
value.Value.Should().Be(new BigInteger(123456789));
value.Decimals.Should().Be(6);
- value = new BigDecimal(-123.45M);
- value.Value.Should().Be(new BigInteger(-12345));
- value.Decimals.Should().Be(2);
+ value = new BigDecimal(-123.45M, 3);
+ value.Value.Should().Be(new BigInteger(-123450));
+ value.Decimals.Should().Be(3);
- value = new BigDecimal(123.45M);
+ value = new BigDecimal(123.45M, 2);
value.Value.Should().Be(new BigInteger(12345));
value.Decimals.Should().Be(2);
- value = new BigDecimal(123M);
+ value = new BigDecimal(123M, 0);
value.Value.Should().Be(new BigInteger(123));
value.Decimals.Should().Be(0);
- value = new BigDecimal(0M);
+ value = new BigDecimal(0M, 0);
value.Value.Should().Be(new BigInteger(0));
value.Decimals.Should().Be(0);
}
diff --git a/tests/neo.UnitTests/Wallets/UT_Wallet.cs b/tests/neo.UnitTests/Wallets/UT_Wallet.cs
index 219bd62d25..75d38c25a1 100644
--- a/tests/neo.UnitTests/Wallets/UT_Wallet.cs
+++ b/tests/neo.UnitTests/Wallets/UT_Wallet.cs
@@ -9,6 +9,7 @@
using Neo.Wallets;
using System;
using System.Collections.Generic;
+using System.Numerics;
namespace Neo.UnitTests.Wallets
{
@@ -206,7 +207,7 @@ public void TestGetAvailable()
entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor;
snapshot.Commit();
- wallet.GetAvailable(NativeContract.GAS.Hash).Should().Be(new BigDecimal(1000000000000, 8));
+ wallet.GetAvailable(NativeContract.GAS.Hash).Should().Be(new BigDecimal(new BigInteger(1000000000000M), 8));
entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState()));
entry.GetInteroperable().Balance = 0;
@@ -228,8 +229,8 @@ public void TestGetBalance()
entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor;
snapshot.Commit();
- wallet.GetBalance(UInt160.Zero, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(0, 0));
- wallet.GetBalance(NativeContract.GAS.Hash, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(1000000000000, 8));
+ wallet.GetBalance(UInt160.Zero, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(BigInteger.Zero, 0));
+ wallet.GetBalance(NativeContract.GAS.Hash, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(new BigInteger(1000000000000M), 8));
entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState()));
entry.GetInteroperable().Balance = 0;
@@ -294,7 +295,7 @@ public void TestMakeTransaction1()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = account.ScriptHash,
- Value = new BigDecimal(1,8),
+ Value = new BigDecimal(BigInteger.One,8),
Data = "Dec 12th"
}
}, UInt160.Zero);
@@ -306,7 +307,7 @@ public void TestMakeTransaction1()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = account.ScriptHash,
- Value = new BigDecimal(1,8),
+ Value = new BigDecimal(BigInteger.One,8),
Data = "Dec 12th"
}
}, account.ScriptHash);
@@ -318,7 +319,7 @@ public void TestMakeTransaction1()
{
AssetId = UInt160.Zero,
ScriptHash = account.ScriptHash,
- Value = new BigDecimal(1,8),
+ Value = new BigDecimal(BigInteger.One,8),
Data = "Dec 12th"
}
}, account.ScriptHash);
@@ -342,7 +343,7 @@ public void TestMakeTransaction1()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = account.ScriptHash,
- Value = new BigDecimal(1,8)
+ Value = new BigDecimal(BigInteger.One,8)
}
});
tx.Should().NotBeNull();
@@ -353,7 +354,7 @@ public void TestMakeTransaction1()
{
AssetId = NativeContract.NEO.Hash,
ScriptHash = account.ScriptHash,
- Value = new BigDecimal(1,8),
+ Value = new BigDecimal(BigInteger.One,8),
Data = "Dec 12th"
}
});