Skip to content

Commit

Permalink
update signers and add sender for rpc api (neo-project#309)
Browse files Browse the repository at this point in the history
  • Loading branch information
ProDog authored and 陈志同 committed Oct 13, 2020
1 parent ca00c69 commit bd689b4
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 25 deletions.
18 changes: 10 additions & 8 deletions src/RpcServer/RpcServer.SmartContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void SerializeUnsigned(BinaryWriter writer)
}
}

private JObject GetInvokeResult(byte[] script, Signers signers = null)
private JObject GetInvokeResult(byte[] script, UInt160 sender = null, Signers signers = null)
{
using ApplicationEngine engine = ApplicationEngine.Run(script, container: signers, gas: settings.MaxGasInvoke);
JObject json = new JObject();
Expand All @@ -76,15 +76,15 @@ private JObject GetInvokeResult(byte[] script, Signers signers = null)
{
json["stack"] = "error: recursive reference";
}
ProcessInvokeWithWallet(json, signers);
ProcessInvokeWithWallet(json, sender, signers);
return json;
}

private static Signers SignersFromJson(JArray _params)
{
var ret = new Signers(_params.Select(u => new Signer()
{
Account = UInt160.Parse(u["account"].AsString()),
Account = AddressToScriptHash(u["account"].AsString()),
Scopes = (WitnessScope)Enum.Parse(typeof(WitnessScope), u["scopes"]?.AsString()),
AllowedContracts = ((JArray)u["allowedcontracts"])?.Select(p => UInt160.Parse(p.AsString())).ToArray(),
AllowedGroups = ((JArray)u["allowedgroups"])?.Select(p => ECPoint.Parse(p.AsString(), ECCurve.Secp256r1)).ToArray()
Expand All @@ -103,21 +103,23 @@ 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];
Signers signers = _params.Count >= 4 ? SignersFromJson((JArray)_params[3]) : null;
UInt160 sender = _params.Count >= 4 ? AddressToScriptHash(_params[3].AsString()) : null;
Signers signers = _params.Count >= 5 ? SignersFromJson((JArray)_params[4]) : null;
byte[] script;
using (ScriptBuilder sb = new ScriptBuilder())
{
script = sb.EmitAppCall(script_hash, operation, args).ToArray();
}
return GetInvokeResult(script, signers);
return GetInvokeResult(script, sender, signers);
}

[RpcMethod]
private JObject InvokeScript(JArray _params)
{
byte[] script = _params[0].AsString().HexToBytes();
Signers signers = _params.Count >= 2 ? SignersFromJson((JArray)_params[1]) : null;
return GetInvokeResult(script, signers);
UInt160 sender = _params.Count >= 2 ? AddressToScriptHash(_params[1].AsString()) : null;
Signers signers = _params.Count >= 3 ? SignersFromJson((JArray)_params[2]) : null;
return GetInvokeResult(script, sender, signers);
}

[RpcMethod]
Expand All @@ -128,7 +130,7 @@ private JObject GetUnclaimedGas(JArray _params)
UInt160 script_hash;
try
{
script_hash = address.ToScriptHash();
script_hash = AddressToScriptHash(address);
}
catch
{
Expand Down
4 changes: 2 additions & 2 deletions src/RpcServer/RpcServer.Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ partial class RpcServer
[RpcMethod]
private JObject ListPlugins(JArray _params)
{
return new JArray(Neo.Plugins.Plugin.Plugins
return new JArray(Plugin.Plugins
.OrderBy(u => u.Name)
.Select(u => new JObject
{
Expand All @@ -33,7 +33,7 @@ private JObject ValidateAddress(JArray _params)
UInt160 scriptHash;
try
{
scriptHash = address.ToScriptHash();
scriptHash = AddressToScriptHash(address);
}
catch
{
Expand Down
50 changes: 36 additions & 14 deletions src/RpcServer/RpcServer.Wallet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private JObject CloseWallet(JArray _params)
private JObject DumpPrivKey(JArray _params)
{
CheckWallet();
UInt160 scriptHash = _params[0].AsString().ToScriptHash();
UInt160 scriptHash = AddressToScriptHash(_params[0].AsString());
WalletAccount account = wallet.GetAccount(scriptHash);
return account.GetKey().Export();
}
Expand Down Expand Up @@ -138,16 +138,24 @@ private JObject OpenWallet(JArray _params)
return true;
}

private void ProcessInvokeWithWallet(JObject result, Signers signers = null)
private void ProcessInvokeWithWallet(JObject result, UInt160 sender = null, Signers signers = null)
{
Transaction tx = null;
if (wallet != null && signers != null)
{
UInt160[] accounts = wallet.GetAccounts().Where(p => !p.Lock && !p.WatchOnly).Select(p => p.ScriptHash).ToArray();
Signer[] witnessCosigners = signers.GetSigners().Where(p => accounts.Contains(p.Account)).ToArray();
if (witnessCosigners.Count() > 0)
Signer[] witnessSigners = signers.GetSigners().ToArray();
UInt160[] signersAccounts = signers.GetScriptHashesForVerifying(null);
if (sender != null)
{
tx = wallet.MakeTransaction(result["script"].AsString().HexToBytes(), null, witnessCosigners);
if (!signersAccounts.Contains(sender))
witnessSigners = witnessSigners.Prepend(new Signer() { Account = sender, Scopes = WitnessScope.CalledByEntry }).ToArray();
else if (signersAccounts[0] != sender)
throw new RpcException(-32602, "The sender must be the first element of signers.");
}

if (witnessSigners.Count() > 0)
{
tx = wallet.MakeTransaction(result["script"].AsString().HexToBytes(), sender, witnessSigners);
ContractParametersContext context = new ContractParametersContext(tx);
wallet.Sign(context);
if (context.Completed)
Expand All @@ -164,12 +172,14 @@ private JObject SendFrom(JArray _params)
{
CheckWallet();
UInt160 assetId = UInt160.Parse(_params[0].AsString());
UInt160 from = _params[1].AsString().ToScriptHash();
UInt160 to = _params[2].AsString().ToScriptHash();
UInt160 from = AddressToScriptHash(_params[1].AsString());
UInt160 to = AddressToScriptHash(_params[2].AsString());
AssetDescriptor descriptor = new AssetDescriptor(assetId);
BigDecimal amount = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals);
if (amount.Sign <= 0)
throw new RpcException(-32602, "Invalid params");
Signer[] signers = _params.Count >= 5 ? ((JArray)_params[4]).Select(p => new Signer() { Account = AddressToScriptHash(p.AsString()), Scopes = WitnessScope.CalledByEntry }).ToArray() : null;

Transaction tx = wallet.MakeTransaction(new[]
{
new TransferOutput
Expand All @@ -178,7 +188,7 @@ private JObject SendFrom(JArray _params)
Value = amount,
ScriptHash = to
}
}, from);
}, from, signers);
if (tx == null)
throw new RpcException(-300, "Insufficient funds");

Expand Down Expand Up @@ -206,12 +216,14 @@ private JObject SendMany(JArray _params)
UInt160 from = null;
if (_params[0] is JString)
{
from = _params[0].AsString().ToScriptHash();
from = AddressToScriptHash(_params[0].AsString());
to_start = 1;
}
JArray to = (JArray)_params[to_start];
if (to.Count == 0)
throw new RpcException(-32602, "Invalid params");
Signer[] signers = _params.Count >= to_start + 2 ? ((JArray)_params[to_start + 1]).Select(p => new Signer() { Account = AddressToScriptHash(p.AsString()), Scopes = WitnessScope.CalledByEntry }).ToArray() : null;

TransferOutput[] outputs = new TransferOutput[to.Count];
for (int i = 0; i < to.Count; i++)
{
Expand All @@ -221,12 +233,12 @@ private JObject SendMany(JArray _params)
{
AssetId = asset_id,
Value = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals),
ScriptHash = to[i]["address"].AsString().ToScriptHash()
ScriptHash = AddressToScriptHash(to[i]["address"].AsString())
};
if (outputs[i].Value.Sign <= 0)
throw new RpcException(-32602, "Invalid params");
}
Transaction tx = wallet.MakeTransaction(outputs, from);
Transaction tx = wallet.MakeTransaction(outputs, from, signers);
if (tx == null)
throw new RpcException(-300, "Insufficient funds");

Expand All @@ -251,7 +263,7 @@ private JObject SendToAddress(JArray _params)
{
CheckWallet();
UInt160 assetId = UInt160.Parse(_params[0].AsString());
UInt160 scriptHash = _params[1].AsString().ToScriptHash();
UInt160 to = AddressToScriptHash(_params[1].AsString());
AssetDescriptor descriptor = new AssetDescriptor(assetId);
BigDecimal amount = BigDecimal.Parse(_params[2].AsString(), descriptor.Decimals);
if (amount.Sign <= 0)
Expand All @@ -262,7 +274,7 @@ private JObject SendToAddress(JArray _params)
{
AssetId = assetId,
Value = amount,
ScriptHash = scriptHash
ScriptHash = to
}
});
if (tx == null)
Expand Down Expand Up @@ -299,5 +311,15 @@ private JObject SignAndRelay(Transaction tx)
return context.ToJson();
}
}

internal static UInt160 AddressToScriptHash(string address)
{
if (UInt160.TryParse(address, out var scriptHash))
{
return scriptHash;
}

return address.ToScriptHash();
}
}
}
2 changes: 1 addition & 1 deletion src/RpcServer/RpcServer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" Version="2.2.0" />
<PackageReference Include="Neo" Version="3.0.0-preview3-00" />
<PackageReference Include="Neo" Version="3.0.0-CI00986" />
</ItemGroup>

</Project>

0 comments on commit bd689b4

Please sign in to comment.