Get Started
Create Smart Contract
To create a contract, follow these steps to send a transaction with block type 1:
- Call
contract_createContractToAddress
to generate a new contract address. - If the contract constructor has input parameters, encode the arguments according to ABI.
- Compose block data. The data consists of a prefix of 14 bytes (10-byte consensus group id + 1-byte contract type + 1-byte response latency + 1-byte random degree + 1-byte quota multiplier), the contract's compiled code, and encoded arguments.
- Create an account block and set all necessary fields. Note that
toAddress
is the contract address generated in step 1. SetblockType
to 1 andfee
to 10 VITE. Also, setamount
andtokenId
if you want to transfer some tokens to the contract (the constructor must be payable). - Call
ledger_sendRawTransaction
to send the transaction.
See here for more information.
Call Contract
To call a contract, follow these steps to send a transaction to the smart contract with the encoded method name and arguments:
- Encode the function call according to ABI.
- Create an account block and set all necessary fields. Note that
toAddress
is the contract address anddata
is the output from step 1. SetblockType
to 2. Also, setamount
andtokenId
if you want to transfer some tokens (the calling function must be payable). - Call
ledger_sendRawTransaction
to send the transaction.
Read Contract States
A contract's public states can be accessed off-chain through the API contract_query
(or contract_callOffChainMethod
in Solidity++ 0.4) with the following steps:
- Encode the view function call (or off-chain method in Solidity++ 0.4) according to ABI.
- Call
contract_query
orcontract_callOffChainMethod
to read contract states.
Call Built-in Contract
Calling a built-in contract is exactly the same as calling an ordinary contract.
Vite has three built-in contracts: Built-in Quota Contract, Built-in Asset Contract, and Built-in Consensus Contract, which will be covered in the next chapters.
Note
ViteX is also implemented as built-in contracts.
Built-in Contract Callbacks
Some built-in contracts have declared callbacks. The callbacks are used to receive async calling results and should be implemented by the contract that calls the built-in contract.
For example, the following ABI declares a function StakeForQuotaWithCallback
with a callback of the same name.
Let's assume a contract A calls the function to acquire quota for beneficiary B. To receive the staking result, A implements the callback so the built-in Quota contract can send the result back.
Tip
In Vite's VM, callbacks are implemented as external functions by adding a trailing "Callback" to the original name.
[
{"type":"function","name":"StakeForQuotaWithCallback", "inputs":[{"name":"beneficiary","type":"address"},{"name":"stakeHeight","type":"uint64"}]},
{"type":"callback","name":"StakeForQuotaWithCallback", "inputs":[{"name":"id","type":"bytes32"},{"name":"success","type":"bool"}]}
]
Example
// SPDX-License-Identifier: GPL-3.0
pragma soliditypp >=0.8.0;
interface IQuotaBuiltIn {
function StakeForQuotaWithCallback(address beneficiary, uint64 stakeHeight) payable external;
}
contract A {
IQuotaBuiltIn constant Contract = IQuotaBuiltIn("vite_0000000000000000000000000000000000000003f6af7459b9");
event StakeSuccess(bytes32 indexed id);
function requestForQuota(address beneficiary) external payable {
Contract.StakeForQuotaWithCallback{value: 134 vite}(beneficiary, 259200);
}
// Will be called back by quota contract
function StakeForQuotaWithCallbackCallback(bytes32 id, bool success) external {
require(msg.sender == address("vite_0000000000000000000000000000000000000003f6af7459b9"));
if (success) {
emit StakeSuccess(id);
}
}
}
In this example, StakeForQuotaWithCallbackCallback
is the callback for the function StakeForQuotaWithCallback
.