Contract factory
When interacting with smart contracts in Unity, the contract factory is responsible for
creating the contract proxy class with the given
contract interface type T
.
Contract factory types
Impromptu contract factory
The impromptu contract factory uses the Impromptu
library to return a new instance of Contract
that behaves likes the given interface type T
.
Since the contract is a dynamic object, all method invocations to the returned object of type T
are automatically routed to the Contract
class.
The impromptu contract factory is only supported on Mono or in a runtime that has the CLR. The IL2CPP runtime does not support this factory. Use the backed type contract factory if you need a more concrete type.
Backed type contract factory
The backed type contract factory uses a concrete class
type that inherits the Contract
class and
the given interface type T
.
To use this factory, the given interface must declare the class attribute BackedType
that specifies which concrete class
type must be used when creating a new Contract
instance.
The declared class
must inherit from the given interface type T
.
[BackedType(typeof(ERC20Backing))]
public interface ERC20 : IContract
{
[EvmMethodInfo(Name = "decimals", View = true)]
[return: EvmParameterInfo(Type = "uint8")]
Task<BigInteger> Decimals();
// Define other interface methods.
}
Inside the backed class
, you must override all interface methods and either invoke custom logic or
use the Contract
class to automatically perform the correct logic based on the method data.
You can use var method = System.Reflection.MethodBase.GetCurrentMethod();
to get the current
method being invoked, and then you can use base.InvokeMethod(MethodInfo method, object[] args)
to
invoke the correct logic for the given method
and args
.
public class ERC20Backing : Contract, ERC20
{
public string Address
{
get => base.Address;
}
[EvmMethodInfo(Name = "decimals", View = true)]
[return: EvmParameterInfo(Type = "uint8")]
public Task<BigInteger> Decimals()
{
var method = System.Reflection.MethodBase.GetCurrentMethod();
return (Task<BigInteger>) InvokeMethod(method, new object[] { });
}
// Define other interface methods.
}
The contract code generator automatically generates a backing
class
for each contract interface generated.
This contract factory is useful for when you need more concrete definitions of the contract
interface type T
.
This can be useful in runtimes where dynamic
or DynamicObject
are not available (IL2CPP).
Set the contract factory
To set the current contract factory, you can use Contract.ContractFactory
:
Contract.ContractFactory = new BackedTypeContractFactory();
You don't need to do this, unless you create a custom contract factory. We recommend just using the default contract factories for each runtime:
- Mono runtime - Impromptu contract factory
- IL2CPP runtime - Backed typed contract factory