# Smart Contract

# Introduction

Miyabi allows users to use smart contracts for handling complex operations towards tables. When using a smart contract, the user needs to specify the name of the smart contract, functions, and parameters. All the direct operations to tables can be defined in the smart contract. A smart contract is a C# class inherited from ContractBase in Miyabi. ContractBase provides World State read and write abstraction. A smart contract owned Binary table is also created when a smart contract instance is created, the developers can use this for storing various data (general metadata and bookkeeping etc.). The smart contracts can use allowed assemblies and members to accomplish various operations. The World State can be accessed and modified through a smart contract if necessary credentials are included in the transaction that invokes the smart contract instance.

The process begins with compiling and analyzing the source code and its dependencies using a Roslyn Analyzer, which applies various checks. After the code successfully passes the analysis, it can be deployed to Miyabi. The user needs to instantiate the smart contract and specify an instance owner. Following this, the user can interact with the contract by invoking its methods using transactions or querying its read-only methods. If an exception is thrown, the transaction will be marked as failed and the changes will be discarded. Also, the instance owner can delete the instance record so no one can invoke/query this instance.

This document shall provide CLI examples with the following sample smart contract: SampleContract.cs (opens new window)

# Create a Smart Contract

A simple smart contract, written in C#, looks like the following:

public class SampleContract:ContractBase
{
    public override bool Instantiate(string[] args)
    {
        // instantiate code
    }
    public void InvokeMethod(string[] args)
    {
        // Method invokes through transactions
    }
    public string QueryMethod(string[] args)
    {
        // Method queried through API
    }
}

All the smart contracts in Miyabi inherit from the ContractBase class, either directly or indirectly. To update the World State in the invoked method, the user can use the StateWriter member defined in ContractBase.

Miyabi also provides two templates derived from the ContractBase:

  • TransformableSmartContractdefines a SaveState function.
    Developers can override it with logic that the user wants to execute after every invocation.
  • UpgradableContractBase provides some tool functions to hand over table ownership.
    Developers can use the preserved GrantTables method to implement the logic that needs to be done when upgrading one instance to a different instance and call it from the new instances.

# Get Assembly Id

The Assembly Id is the hash of the Miyabi smart contract source code. getassemblyid is an offline command that calculates the Assembly Id of the smart contract without compiling the source code. Miyabi uses the hash value of source code Assembly Id to distinguish different smart contracts. Since the same source code will have the same Assembly Id, developers cannot deploy the same smart contract twice.

# Example

$ ./miyabi-cli.exe getassemblyid -f SampleContract.cs
8819851eae0bca115266bd329527c595f6320a19a2975de9773c4c8d352c0ff6

# Deploy Smart Contract

The first step to use a smart contract is to deploy it to Miyabi. The deployment step ensures that the smart contract is using valid code (no disallowed assemblies and members) and also that the source code is compilable. The assembly of the smart contract is then stored by Miyabi nodes.

To deploy a smart contract, the transaction should be signed by an address with contract Deploy permission. Once a smart contract is deployed, the compiled source code will be stored in the World State, and registered to a predefined table for managing smart contracts.

The deploycontract command has the following parameters:

Item Type Description
Contract Admin Private Keys PrivateKey[] Private key(s) of the signer with 'Deploy' contract permission (optional)
Source Files string[] File path to the smart contract source code
LanguageVersion string C# Language version to compile
Instantiators Address[] Address(es) which can administer the creation of the contract instances
Dependencies string[] Assembly name of third party dependencies (optional)
Debug bool Flag to indicate if the smart contract can be debugged

# Example

$ ./miyabi-cli.exe sendtransaction deploycontract -lv CSharp10 -p 14e3a2d16c8a43a4eb1b088b32bca2abaf274e3f185afc9c15b33491c8deb9a6 -i 026beca06739461a20249fd4b24cf27542013624d18710bc418e8de10d6ef68568 -f SampleContract.cs
8afa45fd1497c69c92a9dc11b8c4db1ef1b04b5095433f6106d0ad27fdd7dcac

# Instantiate Smart Contract

The deployed smart contract exists as a compiled assembly in Miyabi. To use the deployed smart contract, the user needs to create an instance of the smart contract. The contract instantiation will create an instance record and an internal table to store metadata of this instance. Instantiating a smart contract needs the assembly Id, class name, and an instance name for that instance. In Miyabi, the hash of the aforementioned three parameters constitutes the InstanceId for strictly distinguishing different instances.

The transaction needs to be signed by at least one Instantiator address, and other addresses according to the required permissions. The instantiatecontract command has the following parameters:

Item Type Description
Assembly Id ByteString Assembly Id of the deployed smart contract
Instance Name string Instance name for the new instance of the deployed smart contract
Contract Name string The class inherited ContractBase and whose instantiate function will be called
Instance Owners Address[] Address(es) of instance owner.
Private Keys PrivateKey[] Private key of user or valid signer as defined in contract (optional)
Arguments string[] An array containing all the parameters needed for the instantiate function (optional)

# Example

$ ./miyabi-cli.exe sendtransaction instantiatecontract -p 6591bfae609236291e2d22609aeb1ce74550dcbbc628f91b6eef3c6f350a79da -p 10425b7e6ebf5e0d5918717f77ce8a66aaf92bc64b65996f885ff12bd94ef529 -a 8819851eae0bca115266bd329527c595f6320a19a2975de9773c4c8d352c0ff6 -c "SmartContractSample.ContractFiles.SampleContract" -i "test_SampleContract_instance" -o 0249a37736e3290729ea5cd12abe5575cc4153f76dbb540b9b94d929e63d1b6077
4816c26ee6e4d6efcb72006e24fcd25f2940720c9a7ae8236ede162987aa3826

# Invoke Smart Contract

Users can invoke methods of a smart contract instance to do various operations. A smart contract method can potentially:

  1. Make changes to the World State
  2. Make changes to the data of the smart contract instance
  3. Communicate with other smart contracts
  4. Perform some idempotent operations

Users can only invoke the method with a void return type and check the result by transaction result code. Contract invocation can be done using a ContractInvoke transaction entry, in which, the user can input the method name and the respective arguments of the method to be invoked.

The invokecontract command has the following parameters:

Item Type Description
Assembly Id ByteString Assembly Id of the deployed smart contract
Instance Name string Instance name provided by user to distinguish different instance
Contract Name string The class inherited ContractBase and whose instantiate function will be called
Method Name string The method invoked in the smart contract. Must return void
Arguments string[] An array provide all the arguments needed for the method being invoked (optional)
Private keys PrivateKey[] Private key of user or valid signer as defined in contract (optional)

The method arguments can be of following types:

  1. ByteString
  2. PublicKey
  3. Address
  4. Primitive types
  5. Miyabi types serialized as JSON string

The following objects cannot be treated as input parameters: Object, Empty (Null reference), DateTime, DBNull. The user needs to serialize all the parameters into a JSON format string, and the executor will deserialize them according to the definition of methods in the smart contract.

# Example

$ ./miyabi-cli.exe  sendtransaction invokecontract -a 8819851eae0bca115266bd329527c595f6320a19a2975de9773c4c8d352c0ff6 -c "SmartContractSample.ContractFiles.SampleContract" -i "test_SampleContract_instance" -m "RegisterAccount" --argument 032fc2558d4df2e251a79be12926abf9f5fa0932311d6e19a63fb0ab46c39e35be
9303d672fd1dc9a9a26b159fbf12f46ad23b7b080fb1bcbac6ab05106530bc02

# Contract Event

Users can also store their customized data into the event through smart contracts. Users need to define their event data derived from ContractEventBase and use IContractExecutionContext.TriggerEvent(event) to trigger the event builder. The event data can be serialized to ByteString and stored in the filter FilterData, used in the bloom filter of the block event for quick searching in a block.

# Query Smart Contract

Users can use the API to query the smart contract. The contract query request is a read request to the World State and can't make any changes to it. In return, the query methods have a non-void return type as the HTTP response.

The querycontract command has the following parameters:

Item Type Description
Assembly Id ByteString Assembly Id of the deployed smart contract
Instance Name string Instance name provided by user to distinguish different instance
Contract Name string The class inherited ContractBase and whose instantiate function will be called
Method Name string Name of the smart contract method
Parameters string[] An array containing all the parameters needed for the query method being invoked (optional)

# Example

$ ./miyabi-cli.exe querycontract -a 8819851eae0bca115266bd329527c595f6320a19a2975de9773c4c8d352c0ff6 -c "SmartContractSample.ContractFiles.SampleContract" -i "test_SampleContract_instance" -m "IsAccountRegistered" -p 032fc2558d4df2e251a79be12926abf9f5fa0932311d6e19a63fb0ab46c39e35be
true

# Delete Smart Contract Instance

In Miyabi, smart contract users can delete the instance of a deployed contract with the help of instance owner's signatures.

The deletecontractinstance command has the following parameters.

Item Type Description
Assembly Id ByteString Assembly Id of the deployed smart contract
Instance Name string Instance name of the smart contract to be deleted
Contract Name string The class inherited ContractBase and whose instantiate function will be called
Private keys Privatekey[] Private key(s) of the smart contract instance owners (optional)

# Example

$ ./miyabi-cli.exe sendtransaction deletecontractinstance -p 6591bfae609236291e2d22609aeb1ce74550dcbbc628f91b6eef3c6f350a79da -p 6591bfae609236291e2d22609aeb1ce74550dcbbc628f91b6eef3c6f350a79dc -a 8819851eae0bca115266bd329527c595f6320a19a2975de9773c4c8d352c0ff6 -c "SmartContractSample.ContractFiles.SampleContract" -i test_SampleContract_instance
1b80556428619de86557acb761c19368a52826cc75e8ddfcbd39841f3f385502