Skip to content

Commit

Permalink
update RpcClient (neo-project#296)
Browse files Browse the repository at this point in the history
* update RpcClient

* fix sln

* fix format

* fix format

Co-authored-by: Owen Zhang <[email protected]>
  • Loading branch information
2 people authored and 陈志同 committed Oct 13, 2020
1 parent d213136 commit 974b5b8
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 108 deletions.
7 changes: 4 additions & 3 deletions src/RpcClient/ContractClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ public Transaction CreateDeployContractTx(byte[] contractScript, ContractManifes
sb.EmitSysCall(ApplicationEngine.System_Contract_Create, contractScript, manifest.ToString());
script = sb.ToArray();
}

UInt160 sender = Contract.CreateSignatureRedeemScript(key.PublicKey).ToScriptHash();
Transaction tx = new TransactionManager(rpcClient, sender)
.MakeTransaction(script, null)
Signer[] signers = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = sender } };

Transaction tx = new TransactionManager(rpcClient)
.MakeTransaction(script, signers)
.AddSignature(key)
.Sign()
.Tx;
Expand Down
12 changes: 6 additions & 6 deletions src/RpcClient/Nep5API.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,11 @@ public RpcNep5TokenInfo GetTokenInfo(UInt160 scriptHash)
public Transaction CreateTransferTx(UInt160 scriptHash, KeyPair fromKey, UInt160 to, BigInteger amount)
{
var sender = Contract.CreateSignatureRedeemScript(fromKey.PublicKey).ToScriptHash();
Cosigner[] cosigners = new[] { new Cosigner { Scopes = WitnessScope.CalledByEntry, Account = sender } };
Signer[] signers = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = sender } };

byte[] script = scriptHash.MakeScript("transfer", sender, to, amount);
Transaction tx = new TransactionManager(rpcClient, sender)
.MakeTransaction(script, cosigners)
Transaction tx = new TransactionManager(rpcClient)
.MakeTransaction(script, signers)
.AddSignature(fromKey)
.Sign()
.Tx;
Expand All @@ -135,11 +135,11 @@ public Transaction CreateTransferTx(UInt160 scriptHash, int m, ECPoint[] pubKeys
if (m > fromKeys.Length)
throw new ArgumentException($"Need at least {m} KeyPairs for signing!");
var sender = Contract.CreateMultiSigContract(m, pubKeys).ScriptHash;
Cosigner[] cosigners = new[] { new Cosigner { Scopes = WitnessScope.CalledByEntry, Account = sender } };
Signer[] signers = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = sender } };

byte[] script = scriptHash.MakeScript("transfer", sender, to, amount);
Transaction tx = new TransactionManager(rpcClient, sender)
.MakeTransaction(script, cosigners)
Transaction tx = new TransactionManager(rpcClient)
.MakeTransaction(script, signers)
.AddMultiSig(fromKeys, m, pubKeys)
.Sign()
.Tx;
Expand Down
12 changes: 6 additions & 6 deletions src/RpcClient/RpcClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -316,12 +316,12 @@ public UInt256 SubmitBlock(byte[] block)
/// Returns the result after calling a smart contract at scripthash with the given operation and parameters.
/// This RPC call does not affect the blockchain in any way.
/// </summary>
public RpcInvokeResult InvokeFunction(string scriptHash, string operation, RpcStack[] stacks, params UInt160[] scriptHashesForVerifying)
public RpcInvokeResult InvokeFunction(string scriptHash, string operation, RpcStack[] stacks, params Signer[] signer)
{
List<JObject> parameters = new List<JObject> { scriptHash, operation, stacks.Select(p => p.ToJson()).ToArray() };
if (scriptHashesForVerifying.Length > 0)
if (signer.Length > 0)
{
parameters.Add(scriptHashesForVerifying.Select(p => (JObject)p.ToString()).ToArray());
parameters.Add(signer.Select(p => (JObject)p.ToJson()).ToArray());
}
return RpcInvokeResult.FromJson(RpcSend("invokefunction", parameters.ToArray()));
}
Expand All @@ -330,12 +330,12 @@ public RpcInvokeResult InvokeFunction(string scriptHash, string operation, RpcSt
/// Returns the result after passing a script through the VM.
/// This RPC call does not affect the blockchain in any way.
/// </summary>
public RpcInvokeResult InvokeScript(byte[] script, params UInt160[] scriptHashesForVerifying)
public RpcInvokeResult InvokeScript(byte[] script, params Signer[] signers)
{
List<JObject> parameters = new List<JObject> { script.ToHexString() };
if (scriptHashesForVerifying.Length > 0)
if (signers.Length > 0)
{
parameters.Add(scriptHashesForVerifying.Select(p => (JObject)p.ToString()).ToArray());
parameters.Add(signers.Select(p => p.ToJson()).ToArray());
}
return RpcInvokeResult.FromJson(RpcSend("invokescript", parameters.ToArray()));
}
Expand Down
2 changes: 1 addition & 1 deletion src/RpcClient/RpcClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Neo" Version="3.0.0-CI00966" />
<PackageReference Include="Neo" Version="3.0.0-CI00972" />
</ItemGroup>

</Project>
19 changes: 7 additions & 12 deletions src/RpcClient/TransactionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ public class TransactionManager
private readonly RpcClient rpcClient;
private readonly PolicyAPI policyAPI;
private readonly Nep5API nep5API;
private readonly UInt160 sender;

private class SignItem { public Contract Contract; public HashSet<KeyPair> KeyPairs; }

Expand All @@ -43,12 +42,11 @@ private class SignItem { public Contract Contract; public HashSet<KeyPair> KeyPa
/// </summary>
/// <param name="rpc">the RPC client to call NEO RPC API</param>
/// <param name="sender">the account script hash of sender</param>
public TransactionManager(RpcClient rpc, UInt160 sender)
public TransactionManager(RpcClient rpc)
{
rpcClient = rpc;
policyAPI = new PolicyAPI(rpc);
nep5API = new Nep5API(rpc);
this.sender = sender;
}

/// <summary>
Expand All @@ -57,7 +55,7 @@ public TransactionManager(RpcClient rpc, UInt160 sender)
/// <param name="script">Transaction Script</param>
/// <param name="attributes">Transaction Attributes</param>
/// <returns></returns>
public TransactionManager MakeTransaction(byte[] script, TransactionAttribute[] attributes = null)
public TransactionManager MakeTransaction(byte[] script, Signer[] signers = null, TransactionAttribute[] attributes = null)
{
var random = new Random();
uint height = rpcClient.GetBlockCount() - 1;
Expand All @@ -66,15 +64,12 @@ public TransactionManager MakeTransaction(byte[] script, TransactionAttribute[]
Version = 0,
Nonce = (uint)random.Next(),
Script = script,
Sender = sender,
Signers = signers,
ValidUntilBlock = height + Transaction.MaxValidUntilBlockIncrement,
Attributes = attributes ?? Array.Empty<TransactionAttribute>(),
Witnesses = Array.Empty<Witness>()
};

// Add witness hashes parameter to pass CheckWitness
UInt160[] hashes = Tx.GetScriptHashesForVerifying(null);
RpcInvokeResult result = rpcClient.InvokeScript(script, hashes);
RpcInvokeResult result = rpcClient.InvokeScript(script, signers);
Tx.SystemFee = long.Parse(result.GasConsumed);
context = new ContractParametersContext(Tx);
signStore = new List<SignItem>();
Expand All @@ -90,7 +85,7 @@ private long CalculateNetworkFee()
{
long networkFee = 0;
UInt160[] hashes = Tx.GetScriptHashesForVerifying(null);
int size = Transaction.HeaderSize + Tx.Attributes.GetVarSize() + Tx.Script.GetVarSize() + IO.Helper.GetVarSize(hashes.Length);
int size = Transaction.HeaderSize + Tx.Signers.GetVarSize() + Tx.Attributes.GetVarSize() + Tx.Script.GetVarSize() + IO.Helper.GetVarSize(hashes.Length);
foreach (UInt160 hash in hashes)
{
byte[] witness_script = null;
Expand Down Expand Up @@ -203,9 +198,9 @@ public TransactionManager Sign()
{
// Calculate NetworkFee
Tx.NetworkFee = CalculateNetworkFee();
var gasBalance = nep5API.BalanceOf(NativeContract.GAS.Hash, sender);
var gasBalance = nep5API.BalanceOf(NativeContract.GAS.Hash, Tx.Sender);
if (gasBalance < Tx.SystemFee + Tx.NetworkFee)
throw new InvalidOperationException($"Insufficient GAS in address: {sender.ToAddress()}");
throw new InvalidOperationException($"Insufficient GAS in address: {Tx.Sender.ToAddress()}");

// Sign with signStore
foreach (var item in signStore)
Expand Down
7 changes: 3 additions & 4 deletions src/RpcClient/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public static Transaction TransactionFromJson(JObject json)
Transaction tx = new Transaction();
tx.Version = byte.Parse(json["version"].AsString());
tx.Nonce = uint.Parse(json["nonce"].AsString());
tx.Sender = json["sender"].AsString().ToScriptHash();
tx.Signers = ((JArray)json["signers"]).Select(p => SignerFromJson(p)).ToArray();
tx.SystemFee = long.Parse(json["sysfee"].AsString());
tx.NetworkFee = long.Parse(json["netfee"].AsString());
tx.ValidUntilBlock = uint.Parse(json["validuntilblock"].AsString());
Expand All @@ -137,9 +137,9 @@ public static Header HeaderFromJson(JObject json)
return header;
}

public static Cosigner CosignerFromJson(JObject json)
public static Signer SignerFromJson(JObject json)
{
return new Cosigner
return new Signer
{
Account = UInt160.Parse(json["account"].AsString()),
Scopes = (WitnessScope)Enum.Parse(typeof(WitnessScope), json["scopes"].AsString()),
Expand All @@ -162,7 +162,6 @@ public static TransactionAttribute TransactionAttributeFromJson(JObject json)

switch (usage)
{
case TransactionAttributeType.Cosigner: return CosignerFromJson(json);
default: throw new FormatException();
}
}
Expand Down
Loading

0 comments on commit 974b5b8

Please sign in to comment.