Invoking Smart Contracts
The smart contract invoking described in this section refers to invoking a smart contract that has been deployed as a class library.
Static Call
To invoke another contract from one contract, you need to first add a statement in C# using Appcall and the script hash of the contract to invoke, and then you can invoke it in the code.
[Appcall("XXXXXXXXXX")]//ScriptHash
public static extern int AnotherContract(string arg);
public static void Main()
{
AnotherContract("Hello");
}
Dynamic Call
In some cases the contract script hash you want to invoke is uncertain and needs to be passed in as a variable, you can invoke the contract dynamically.
Dynamic call code
The following is an example of dynamic call contract:
using Neo.SmartContract.Framework;
using Neo.SmartContract.Framework.Services.Neo;
using Helper = Neo.SmartContract.Framework.Helper;
using System;
using System.Numerics;
namespace DynCall
{
public class DynCallDemo : SmartContract
{
delegate object Dyncall(string method, object[] args);
public static object Main(string operation, object[] args)
{
if (operation == "DynCall")
{
if (args.Length != 2)
{
return false;
}
byte[] target = Storage.Get(Storage.CurrentContext, "BaseAddress");
Dyncall dyncall = (Dyncall)target.ToDelegate();
object[] newarg = new object[1];
string method = (string)args[0];
newarg[0] = args[1];
return dyncall(method, newarg);
}
else if (operation == "SetTarget")
{
Storage.Put(Storage.CurrentContext, "BaseAddress", (byte[])args[0]);
return true;
}
else if (operation == "ShowTarget")
{
byte[] target = Storage.Get(Storage.CurrentContext, "BaseAddress");
if (target.Length != 0)
{
return target;
}
else
{
return 0;
}
}
else
{
return false;
}
}
}
}
where three methods are defined:
-
DynCall: invoke contracts based on the specified script hash.
-
SetTarget: set the contract script hash (little endian) you want to invoke by inputting parameters.
-
ShowTarget: return the contract script hash to invoke.
Dynamic call demonstration
In Visual Studio 2017 compile the preceding dynamic call code into d.avm. Next we are going to do a dynamic call to invoke an ordinary contract a.avm using Neo-GUI.
Deploying the smart contract
Follow these steps to deploy two contracts, a.avm and d.avm, respectively.
-
From NEO-GUI, open any wallet and click
Advanced
->Deploy Contract
. -
In the Deploy Contract dialog,Click
Load
and select the desired smart contract file.Copy the contract script hash displayed under the code box for use in a later step.
-
Enter the information and metadata fields. You need to fill in each fields to enable the
Deploy
button.For metadata related parameters, refer to Parameters and Return Values .
Check the
Need Storage
option. For d.avm, checkNeed dynamic call
as well. -
Click
Deploy
. -
Click
Test
in the dialog that appears. If no issue, clickInvoke
.Deploying a smart contract costs 100 ~1000 GAS. For more information, refer to Fees .
Converting script hash to little endian
Convert the a.avm script hash from big endian to little endian using DataTransformationTool . Copy the string for later use.
Invoking the contract
Now we use the contract d.avm to invoke the contract a.avm.
-
Click
Advance
->Invoke contract
->Function call
。 -
Paste d.avm scripthash copied in the early step to
ScriptHash
and press search button. Relevant contract information is displayed automatically. -
Click
...
besidearguments
to enter the edit interface. -
Invoke the method SetTarget:
-
Click [0] and enter the value “SetTarget”
-
Click [1] and enter the little endian script hash of a.avm
-
Click
Update
-
-
Invoke the method ShowTarget to check if the specified contract script hash can be returned:
-
Invoke the method DynCall to invoke a.avm. Suppose we invoke the Height method in the contract and its parameter is Simple, set as shown below: