visit
Current situation
An organisation (A) applies for a subsidy from the government (B). This is currently paid in one amount for a period of 1 year. The receiving party must meet certain conditions during this period. If the recipient has not fulfilled the conditions at the end of the year, the grant must be fully or partially repaid.Why should it work differently?
In the situation whereby party A has not complied with the conditions and the subsidy has to be repaid in whole or in part, you run into the problem that in most cases the entire amount has already been spent. This ensures that the subsidy provider (party B), is not assured of the amount to be recovered and that party A may run into financial problems.How does the recurring payment work?
Party A draws up the contract with the terms of payment, including how often, when and the amount. Party B fills the safe with tokens to meet the contract conditions. Any period whereby party A is entitled to tokens from the contract, party A can execute a transaction to receive the tokens for that period.If party B wants to terminate the contract prematurely, the preset fee must be paid to party A, and party B will receive the remaining tokens from the safe. This can be compared to the premature termination of a contract.“In the future you are able to create a contract between yourself and your neighbour who happens to be a guitar teacher. You set up a contract for 1 year, whereby you pay him an agreed amount every month. You then deposit one months payment in advance, and if either party terminates the contract, the last month will be provided to the teacher. Once established the contract is immutable and it creates a transparent readable agreement between the two parties.”
A flexible service infrastructure
Today the tool uses only a . With these six custom transactions we have the potential to build a powerful blockchain application that creates a flexible contracting solution between two parties. It gives you the possibility to create the following:Components of the PoC
Custom Transactions
“Transactions are an essential part of blockchain applications that are created using the Lisk SDK, as they define the set of actions that can be performed by users in the network. Each transaction belongs to a specific transaction type that is registered in the network.” .
This proof of concept uses six different custom transactions. can interact with contract wallets as listed below:Note: transactions will work with units of minutes in this proof of concept to simulate contracts faster.
See the for a list with all registered Lisk transaction types. Everyone can make a pull request to add new or update existing registrations, and also reuse the registered custom transactions in order to quickly set up your own blockchain app.Contract
A contract is made with different rules that must be adhered to as shown below:SDK 4.0
This PoC uses the Lisk SDK 4.0. This provides Dynamic Fees and Chain State. The chain state store is used to determine the time of the transaction and can determine from the contract state how many tokens are unlockable. In this version of the SDK the timestamp is removed from the base transaction and a nonce is introduced.Due to the incremental nature of the nonce, the front-end retrieves the account nonce from the blockchain every time, just before a transaction is signed.// slotTypes = [minutes, hours, days, months] in seconds
export const getPastSlots = (
start,
now,
type,
length,
unit
) => {
const slot = slotTypes[type] * length;
return Math.floor((now - start) / slot) - unit;
}
const unitsAvailable = getPastSlots(
contract.asset.start,
store.chain.lastBlockHeader.timestamp,
contract.asset.unit.type,
contract.asset.unit.typeAmount,
contract.asset.payments
);
Dynamic Fees solution
Dynamic fees work like a charm. Due to missing documentation (as we started using v4 too early), it took some time to work out how to calculate them. We solved it in the following manner described below:const tx = new FundContractTransaction({
nonce: nonce.toString(),
senderPublicKey: publicKey,
asset: {
...data
}
});
tx.fee = (tx.minFee + BigInt(65000)).toString();
tx.sign(config.networkIdentifier, passphrase);
BigInt
For the front-end we had a problem with BigInt (), because BigInt uses a Buffer library for js in the browser which has not yet completed the integration of
`buffer.readBigUint64BE()`
. This function is used in the Lisk SDK and is needed for signing transactions.The pull request for this function is in the pipeline but has not yet been accepted at the time of writing. We fixed it by forking the buffer repository and merging it with the pull request to make it work for now.HTTP API
The default Lisk has been extended with an extra API module to make it possible to search for partial usernames, contract specific asset fields and transaction specific assets fields.For example, every contract has transactions belonging to itself but the account is never the sender of any transactions.To collect all transactions belonging to a contract, the API will receive the transactions from the transaction entity by adding a
`asset_contains`
filter to the Transaction entity. This makes it possible to search on `.asset.contractPublicKey`
=== `contract.publicKey`
. Front-end
The creation of custom transactions in the back-end is relatively easy when you start getting the hang of it. The most time consuming element is the front-end, depending on the UI requirements, and connecting the two together. Gathering data from the blockchain can be optimised further, however it is outside the scope of this proof of concept.The undoAsset() method
In addition, the
UndoAsset()
method in a custom transaction can be difficult to create with static nominal data. We are looking forward to the new solution to create custom transactions without the UndoAsset() method, which has already been planned in a later version of the SDK. Solving this will ensure the review transaction sends a lot less data, and hence uses less network resources, which in turn results in lower dynamic fees.