Skip to content

Commit

Permalink
C# SDK Add Transaction Manager and Smart Contract APIs (neo-project#1026
Browse files Browse the repository at this point in the history
)

* Add NEO SDK based on RPC client

* add rpc interface methods for neo3

* update unit test

* add unit test

* Update TransactionHelper.cs

Changed for neo 3.0, not final yet.

* implement sdk rpc client methods

* backup files

* change class name

* remove uncompleted modules for pull request

* change json deserialize method with Neo JObject

* modified JSON implementation, added FromJson()

* more RPC change

* PR correction

* RPC module fix, remove newton.json

* fix

* fix getblock issue

* PR correction

* PR Correction

* PR Correction: rename RPC models

* PR Correction

* resolve conflicts

* Clean code

* Clean code

* Clean code

* Clean code

* Update RpcValidateAddressResult.cs

* Clean code

* PR correction

* Move test file to the right place

* Added SDK Transaction module.

* Add SDK SmartContract module

* height = count - 1

* Add sign function for TxManager

* Add Deploy Contract

* Add unit tests

* Add Network Fee calculate for TxManager,
add unit tests

* adjust cosigners change

* PR Correction

* Remove empty line

* Rename TxManager to TransactionManager

* PR correction

* PR correction

* change namespace

* Reorder methods

* Remove TransactionContext

* fix unit test

* Remove `virtual`

* Remove virtuals

* Remove ScriptHash from KeyPair

* Add comments

* Add comments

* Adjust to Neo_Contract_Create parameter

* use default mainfest

* fix unit test

* Fix typo

* use manifest as parameter

* add cosigner for nep5 transfer

* code clean

* Update neo.UnitTests/Network/RPC/UT_RpcClient.cs

Co-Authored-By: Shargon <shargon@gmail.com>

* move MakeScript to VM.Helper

* Add unit test for InteropInterface

* PR Correction

* Add unit test
  • Loading branch information
chenquanyu authored and Tommo-L committed Jun 22, 2020
1 parent f76c037 commit 9c05432
Show file tree
Hide file tree
Showing 16 changed files with 1,112 additions and 58 deletions.
68 changes: 68 additions & 0 deletions neo.UnitTests/Network/RPC/UT_ContractClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Neo.Network.RPC;
using Neo.SmartContract;
using Neo.SmartContract.Manifest;
using Neo.SmartContract.Native;
using Neo.VM;
using Neo.Wallets;

namespace Neo.UnitTests.Network.RPC
{
[TestClass]
public class UT_ContractClient
{
Mock<RpcClient> rpcClientMock;
KeyPair keyPair1;
UInt160 sender;

[TestInitialize]
public void TestSetup()
{
keyPair1 = new KeyPair(Wallet.GetPrivateKeyFromWIF("KyXwTh1hB76RRMquSvnxZrJzQx7h9nQP2PCRL38v6VDb5ip3nf1p"));
sender = Contract.CreateSignatureRedeemScript(keyPair1.PublicKey).ToScriptHash();
rpcClientMock = UT_TransactionManager.MockRpcClient(sender, new byte[0]);
}

[TestMethod]
public void TestMakeScript()
{
byte[] testScript = NativeContract.GAS.Hash.MakeScript("balanceOf", UInt160.Zero);

Assert.AreEqual("14000000000000000000000000000000000000000051c10962616c616e63654f66142582d1b275e86c8f0e93a9b2facd5fdb760976a168627d5b52",
testScript.ToHexString());
}

[TestMethod]
public void TestInvoke()
{
byte[] testScript = NativeContract.GAS.Hash.MakeScript("balanceOf", UInt160.Zero);
UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.ByteArray, Value = "00e057eb481b".HexToBytes() });

ContractClient contractClient = new ContractClient(rpcClientMock.Object);
var result = contractClient.TestInvoke(NativeContract.GAS.Hash, "balanceOf", UInt160.Zero);

Assert.AreEqual(30000000000000L, (long)result.Stack[0].ToStackItem().GetBigInteger());
}

[TestMethod]
public void TestDeployContract()
{
byte[] script;
var manifest = ContractManifest.CreateDefault(new byte[1].ToScriptHash());
manifest.Features = ContractFeatures.HasStorage | ContractFeatures.Payable;
using (ScriptBuilder sb = new ScriptBuilder())
{
sb.EmitSysCall(InteropService.Neo_Contract_Create, new byte[1], manifest.ToString());
script = sb.ToArray();
}

UT_TransactionManager.MockInvokeScript(rpcClientMock, script, new ContractParameter());

ContractClient contractClient = new ContractClient(rpcClientMock.Object);
var result = contractClient.DeployContract(new byte[1], manifest, keyPair1);

Assert.IsNotNull(result);
}
}
}
89 changes: 89 additions & 0 deletions neo.UnitTests/Network/RPC/UT_Nep5API.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Neo.Network.RPC;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.VM;
using Neo.Wallets;
using System.Numerics;

namespace Neo.UnitTests.Network.RPC
{
[TestClass]
public class UT_Nep5API
{
Mock<RpcClient> rpcClientMock;
KeyPair keyPair1;
UInt160 sender;
Nep5API nep5API;

[TestInitialize]
public void TestSetup()
{
keyPair1 = new KeyPair(Wallet.GetPrivateKeyFromWIF("KyXwTh1hB76RRMquSvnxZrJzQx7h9nQP2PCRL38v6VDb5ip3nf1p"));
sender = Contract.CreateSignatureRedeemScript(keyPair1.PublicKey).ToScriptHash();
rpcClientMock = UT_TransactionManager.MockRpcClient(sender, new byte[0]);
nep5API = new Nep5API(rpcClientMock.Object);
}

[TestMethod]
public void TestBalanceOf()
{
byte[] testScript = NativeContract.GAS.Hash.MakeScript("balanceOf", UInt160.Zero);
UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(10000) });

var balance = nep5API.BalanceOf(NativeContract.GAS.Hash, UInt160.Zero);
Assert.AreEqual(10000, (int)balance);
}

[TestMethod]
public void TestGetName()
{
byte[] testScript = NativeContract.GAS.Hash.MakeScript("name");
UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.GAS.Name });

var result = nep5API.Name(NativeContract.GAS.Hash);
Assert.AreEqual(NativeContract.GAS.Name, result);
}

[TestMethod]
public void TestGetSymbol()
{
byte[] testScript = NativeContract.GAS.Hash.MakeScript("symbol");
UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.GAS.Symbol });

var result = nep5API.Symbol(NativeContract.GAS.Hash);
Assert.AreEqual(NativeContract.GAS.Symbol, result);
}

[TestMethod]
public void TestGetDecimals()
{
byte[] testScript = NativeContract.GAS.Hash.MakeScript("decimals");
UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(NativeContract.GAS.Decimals) });

var result = nep5API.Decimals(NativeContract.GAS.Hash);
Assert.AreEqual(NativeContract.GAS.Decimals, (byte)result);
}

[TestMethod]
public void TestGetTotalSupply()
{
byte[] testScript = NativeContract.GAS.Hash.MakeScript("totalSupply");
UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_00000000) });

var result = nep5API.TotalSupply(NativeContract.GAS.Hash);
Assert.AreEqual(1_00000000, (int)result);
}

[TestMethod]
public void TestTransfer()
{
byte[] testScript = NativeContract.GAS.Hash.MakeScript("transfer", sender, UInt160.Zero, new BigInteger(1_00000000));
UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter());

var result = nep5API.Transfer(NativeContract.GAS.Hash, keyPair1, UInt160.Zero, new BigInteger(1_00000000));
Assert.IsNotNull(result);
}
}
}
69 changes: 69 additions & 0 deletions neo.UnitTests/Network/RPC/UT_PolicyAPI.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Neo.Network.RPC;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.VM;
using Neo.Wallets;
using System.Numerics;

namespace Neo.UnitTests.Network.RPC
{
[TestClass]
public class UT_PolicyAPI
{
Mock<RpcClient> rpcClientMock;
KeyPair keyPair1;
UInt160 sender;
PolicyAPI policyAPI;

[TestInitialize]
public void TestSetup()
{
keyPair1 = new KeyPair(Wallet.GetPrivateKeyFromWIF("KyXwTh1hB76RRMquSvnxZrJzQx7h9nQP2PCRL38v6VDb5ip3nf1p"));
sender = Contract.CreateSignatureRedeemScript(keyPair1.PublicKey).ToScriptHash();
rpcClientMock = UT_TransactionManager.MockRpcClient(sender, new byte[0]);
policyAPI = new PolicyAPI(rpcClientMock.Object);
}

[TestMethod]
public void TestGetMaxTransactionsPerBlock()
{
byte[] testScript = NativeContract.Policy.Hash.MakeScript("getMaxTransactionsPerBlock");
UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(512) });

var result = policyAPI.GetMaxTransactionsPerBlock();
Assert.AreEqual(512u, result);
}

[TestMethod]
public void TestGetMaxBlockSize()
{
byte[] testScript = NativeContract.Policy.Hash.MakeScript("getMaxBlockSize");
UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1024u * 256u) });

var result = policyAPI.GetMaxBlockSize();
Assert.AreEqual(1024u * 256u, result);
}

[TestMethod]
public void TestGetFeePerByte()
{
byte[] testScript = NativeContract.Policy.Hash.MakeScript("getFeePerByte");
UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1000) });

var result = policyAPI.GetFeePerByte();
Assert.AreEqual(1000L, result);
}

[TestMethod]
public void TestGetBlockedAccounts()
{
byte[] testScript = NativeContract.Policy.Hash.MakeScript("getBlockedAccounts");
UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Array, Value = new[] { new ContractParameter { Type = ContractParameterType.Hash160, Value = UInt160.Zero } } });

var result = policyAPI.GetBlockedAccounts();
Assert.AreEqual(UInt160.Zero, result[0]);
}
}
}
24 changes: 14 additions & 10 deletions neo.UnitTests/Network/RPC/UT_RpcClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public void TestGetBlock()
{
// create block
var block = new Block();
TestUtils.SetupBlockWithValues(block, UInt256.Zero, out UInt256 merkRootVal, out UInt160 val160, out ulong timestampVal, out uint indexVal, out Witness scriptVal, out Transaction[] transactionsVal, 0);
TestUtils.SetupBlockWithValues(block, UInt256.Zero, out _, out UInt160 _, out ulong _, out uint _, out Witness _, out Transaction[] _, 0);

block.Transactions = new[]
{
Expand Down Expand Up @@ -158,7 +158,7 @@ public void TestGetBlockCount()
MockResponse(response.ToString());

var result = rpc.GetBlockCount();
Assert.AreEqual(100, result);
Assert.AreEqual(100u, result);
}

[TestMethod]
Expand Down Expand Up @@ -187,7 +187,7 @@ public void TestGetBlockHeaderHex()
public void TestGetBlockHeader()
{
Header header = new Header();
TestUtils.SetupHeaderWithValues(header, UInt256.Zero, out UInt256 merkRootVal, out UInt160 val160, out ulong timestampVal, out uint indexVal, out Witness scriptVal);
TestUtils.SetupHeaderWithValues(header, UInt256.Zero, out UInt256 _, out UInt160 _, out ulong _, out uint _, out Witness _);

JObject json = header.ToJson();
JObject response = CreateResponse(1);
Expand Down Expand Up @@ -231,12 +231,16 @@ public void TestGetConnectionCount()
[TestMethod]
public void TestGetContractState()
{
var sb = new ScriptBuilder();
sb.EmitSysCall(InteropService.System_Runtime_GetInvocationCounter);
byte[] script;
using (var sb = new ScriptBuilder())
{
sb.EmitSysCall(InteropService.System_Runtime_GetInvocationCounter);
script = sb.ToArray();
}

ContractState state = new ContractState
{
Script = new byte[] { (byte)OpCode.DROP, (byte)OpCode.DROP }.Concat(sb.ToArray()).ToArray(),
Script = new byte[] { (byte)OpCode.DROP, (byte)OpCode.DROP }.Concat(script).ToArray(),
Manifest = ContractManifest.CreateDefault(UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01"))
};

Expand Down Expand Up @@ -316,7 +320,7 @@ public void TestGetRawMempoolBoth()
MockResponse(response.ToString());

var result = rpc.GetRawMempoolBoth();
Assert.AreEqual((uint)65535, result.Height);
Assert.AreEqual(65535u, result.Height);
Assert.AreEqual("0x9786cce0dddb524c40ddbdd5e31a41ed1f6b5c8a683c122f627ca4a007a7cf4e", result.Verified[0]);
Assert.AreEqual("0xf86f6f2c08fbf766ebe59dc84bc3b8829f1053f0a01deb26bf7960d99fa86cd6", result.UnVerified[1]);
}
Expand Down Expand Up @@ -476,7 +480,7 @@ public void TestInvokeScript()
response["result"] = json;
MockResponse(response.ToString());

var result = rpc.InvokeScript("00046e616d656724058e5e1b6008847cd662728549088a9ee82191");
var result = rpc.InvokeScript("00046e616d656724058e5e1b6008847cd662728549088a9ee82191".HexToBytes());
Assert.AreEqual(json.ToString(), result.ToJson().ToString());
}

Expand Down Expand Up @@ -507,7 +511,7 @@ public void TestSendRawTransaction()
response["result"] = json;
MockResponse(response.ToString());

var result = rpc.SendRawTransaction("80000001195876cb34364dc38b730077156c6bc3a7fc570044a66fbfeeea56f71327e8ab0000029b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500c65eaf440000000f9a23e06f74cf86b8827a9108ec2e0f89ad956c9b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc50092e14b5e00000030aab52ad93f6ce17ca07fa88fc191828c58cb71014140915467ecd359684b2dc358024ca750609591aa731a0b309c7fb3cab5cd0836ad3992aa0a24da431f43b68883ea5651d548feb6bd3c8e16376e6e426f91f84c58232103322f35c7819267e721335948d385fae5be66e7ba8c748ac15467dcca0693692dac");
var result = rpc.SendRawTransaction("80000001195876cb34364dc38b730077156c6bc3a7fc570044a66fbfeeea56f71327e8ab0000029b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500c65eaf440000000f9a23e06f74cf86b8827a9108ec2e0f89ad956c9b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc50092e14b5e00000030aab52ad93f6ce17ca07fa88fc191828c58cb71014140915467ecd359684b2dc358024ca750609591aa731a0b309c7fb3cab5cd0836ad3992aa0a24da431f43b68883ea5651d548feb6bd3c8e16376e6e426f91f84c58232103322f35c7819267e721335948d385fae5be66e7ba8c748ac15467dcca0693692dac".HexToBytes());
Assert.AreEqual(json.ToString(), ((JObject)result).ToString());
}

Expand All @@ -519,7 +523,7 @@ public void TestSubmitBlock()
response["result"] = json;
MockResponse(response.ToString());

var result = rpc.SubmitBlock("03febccf81ac85e3d795bc5cbd4e84e907812aa3");
var result = rpc.SubmitBlock("03febccf81ac85e3d795bc5cbd4e84e907812aa3".HexToBytes());
Assert.AreEqual(json.ToString(), ((JObject)result).ToString());
}

Expand Down
Loading

0 comments on commit 9c05432

Please sign in to comment.