Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix add signature in invokefunction and invokescript #280

Merged
merged 11 commits into from
Jul 9, 2020
29 changes: 17 additions & 12 deletions src/RpcServer/RpcServer.SmartContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ namespace Neo.Plugins
{
partial class RpcServer
{
private class CheckWitnessHashes : IVerifiable
private class Cosigners : IVerifiable
{
private readonly UInt160[] _scriptHashesForVerifying;
private readonly Cosigner[] _cosigners;
public Witness[] Witnesses { get; set; }
public int Size { get; }

public CheckWitnessHashes(UInt160[] scriptHashesForVerifying)
public Cosigners(Cosigner[] cosigners)
{
_scriptHashesForVerifying = scriptHashesForVerifying;
_cosigners = cosigners;
}

public void Serialize(BinaryWriter writer)
Expand All @@ -45,7 +45,12 @@ public void DeserializeUnsigned(BinaryReader reader)

public UInt160[] GetScriptHashesForVerifying(StoreView snapshot)
{
return _scriptHashesForVerifying;
return _cosigners.Select(p => p.Account).ToArray();
}

public Cosigner[] GetCosigners()
{
return _cosigners;
}

public void SerializeUnsigned(BinaryWriter writer)
Expand All @@ -54,9 +59,9 @@ public void SerializeUnsigned(BinaryWriter writer)
}
}

private JObject GetInvokeResult(byte[] script, IVerifiable checkWitnessHashes = null)
private JObject GetInvokeResult(byte[] script, Cosigners cosigners = null)
{
using ApplicationEngine engine = ApplicationEngine.Run(script, checkWitnessHashes, extraGAS: settings.MaxGasInvoke);
using ApplicationEngine engine = ApplicationEngine.Run(script, cosigners, extraGAS: settings.MaxGasInvoke);
JObject json = new JObject();
json["script"] = script.ToHexString();
json["state"] = engine.State;
Expand All @@ -69,7 +74,7 @@ private JObject GetInvokeResult(byte[] script, IVerifiable checkWitnessHashes =
{
json["stack"] = "error: recursive reference";
}
ProcessInvokeWithWallet(json);
ProcessInvokeWithWallet(json, cosigners);
return json;
}

Expand All @@ -79,21 +84,21 @@ private JObject InvokeFunction(JArray _params)
UInt160 script_hash = UInt160.Parse(_params[0].AsString());
string operation = _params[1].AsString();
ContractParameter[] args = _params.Count >= 3 ? ((JArray)_params[2]).Select(p => ContractParameter.FromJson(p)).ToArray() : new ContractParameter[0];
CheckWitnessHashes checkWitnessHashes = _params.Count >= 4 ? new CheckWitnessHashes(((JArray)_params[3]).Select(u => UInt160.Parse(u.AsString())).ToArray()) : null;
Cosigners cosigners = _params.Count >= 4 ? new Cosigners(((JArray)_params[3]).Select(u => new Cosigner() { Account = UInt160.Parse(u["account"].AsString()), Scopes = (WitnessScope)Enum.Parse(typeof(WitnessScope), u["scopes"].AsString()) }).ToArray()) : null;
byte[] script;
using (ScriptBuilder sb = new ScriptBuilder())
{
script = sb.EmitAppCall(script_hash, operation, args).ToArray();
}
return GetInvokeResult(script, checkWitnessHashes);
return GetInvokeResult(script, cosigners);
}

[RpcMethod]
private JObject InvokeScript(JArray _params)
{
byte[] script = _params[0].AsString().HexToBytes();
CheckWitnessHashes checkWitnessHashes = _params.Count >= 2 ? new CheckWitnessHashes(((JArray)_params[1]).Select(u => UInt160.Parse(u.AsString())).ToArray()) : null;
return GetInvokeResult(script, checkWitnessHashes);
Cosigners cosigners = _params.Count >= 2 ? new Cosigners(((JArray)_params[1]).Select(u => new Cosigner() { Account = UInt160.Parse(u["account"].AsString()), Scopes = (WitnessScope)Enum.Parse(typeof(WitnessScope), u["scopes"].AsString()) }).ToArray()) : null;
return GetInvokeResult(script, cosigners);
}

[RpcMethod]
Expand Down
26 changes: 16 additions & 10 deletions src/RpcServer/RpcServer.Wallet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,19 +138,25 @@ private JObject OpenWallet(JArray _params)
return true;
}

private void ProcessInvokeWithWallet(JObject result)
private void ProcessInvokeWithWallet(JObject result, Cosigners cosigners = null)
{
if (wallet != null)
Transaction tx = null;
if (wallet != null && cosigners != null)
shargon marked this conversation as resolved.
Show resolved Hide resolved
{
Transaction tx = wallet.MakeTransaction(result["script"].AsString().HexToBytes());
ContractParametersContext context = new ContractParametersContext(tx);
wallet.Sign(context);
if (context.Completed)
tx.Witnesses = context.GetWitnesses();
else
tx = null;
result["tx"] = tx?.ToArray().ToHexString();
UInt160[] accounts = wallet.GetAccounts().Where(p => !p.Lock && !p.WatchOnly).Select(p => p.ScriptHash).ToArray();
Cosigner[] witnessCosigners = cosigners.GetCosigners().Where(p => accounts.Contains(p.Account)).ToArray();
if (witnessCosigners.Count() > 0)
{
tx = wallet.MakeTransaction(result["script"].AsString().HexToBytes(), null, witnessCosigners);
ContractParametersContext context = new ContractParametersContext(tx);
wallet.Sign(context);
if (context.Completed)
tx.Witnesses = context.GetWitnesses();
else
tx = null;
}
}
result["tx"] = tx?.ToArray().ToHexString();
}

[RpcMethod]
Expand Down