Swap tech notes, part 1: smart contracts integration
The intro
For the passed year I have been working on my personal project Swap
which is goods and services exchange platform powered by blockchain
technology. Started with a backend (NodeJs, JS, MySql) and a mobile
client (Android, Kotlin, Java, Espresso), it starts utilise ethereum
smart contracts (Solidity, Hardhat, Jest) and automatization (Git
Actions, private chain, shell scripts).
It has passed a few product pivots and become mature enough to start
share tech details of its implementation which might be interesting
for my clients and readers with the technical (software engineering)
background.
This is a 1st part of seria of publications on this topic which will
cover ethereum smart contracts integration.
The initial idea
The idea behind this project is to give people an option to exchange
products and services without money (barter).
I am belong to the group of people who are quite concerned regarding
plans and attempts from some groups in the power to limit peoples
freedoms and rights. I am not talking about people in the government,
but rather talking about people who stays behind people in governments.
When two years Kazan's government issued a policy to limit access to
the public transport to some groups of people, I quickly did a
proof-of-concept (PoC) of the platform
which should help to find transport within or between cities. When I
discovered rising risks in similar way limit access to banks and a
job market, I started to work on this product.
Where is blockchain could help
Different blockchain-like technologies promise two valuable things: decentralized work (p2p, similar to torrents trackers) and data records which are very difficult, close to unrealistic to reverse or tamper.That's why blockchain usage for this project becomes very interesting.
However, after several months of work in integration ethereum into the project, not all what has been promised can be launched in the real project.
It is unlikely to run all your app's logic on the chain because of its gas costs. It means we still ends up with client-server application. However to have data records with minimal, close to unrealistic chance to be reversible or tampered is still true.
Interesting points
ERC721 is the current standard for non-fungible tokens (NFT) which is
the best fit for project requirements, but it is important to keep a
hand on discussions on new proposals.
Engineers from openzeppelin
do a good job to implement variety of confirmed ethereum standards
which can be integrated to your own contracts to speed up the development.
Defensive programming
Defensive programming I have not been using for a while, but ethereum
smart contracts actively use it. There is also such things like
'modifiers' which could be applied to the functions.
modifier bothHaveValidTokens(Match memory subj) { require(_swapValueContract.offer(subj._valueOfFirstUser)._isConsumed != true && _swapValueContract.offer(subj._valueOfSecondUser)._isConsumed != true, "Tokens should not be already consumed."); require(block.timestamp < _swapValueContract.offer(subj._valueOfFirstUser)._availabilityEnd && block.timestamp < _swapValueContract.offer(subj._valueOfSecondUser)._availabilityEnd, "One or both tokens has been expired."); _; }
which are later used like this:
function _approveSwap(address msgSender, Match memory subj) private callerIsRegisteredUser(msgSender, subj._userFirst, subj._userSecond) userExists(subj._userFirst, subj._userSecond) bothHaveValidTokens(subj) { // the main code block ... }
Who is a sender
Solidity supports such thing like `msg.sender` which allows to get
an address of the caller.
By using ether.js you could call contract.connect(
However when inside your contract this contract calls another contract
msg.sender would be an address of the contract caller – not an address
which was defined during the initial call, e.g.
`contract.connect(
It might be important during ERC721 token approve call: we could
approve one address, but eventually authorized ERC721 token function
would be called by deployed contract which would end up with revered
tx as this address has not been approved.
Data structures, memory and gas usage
Solidity from the out-of-the box doesn't support many data structures
which become common in others high level languages. I haven’t found
any reference on Sets or HashMaps, but here is a
collection of structures
implemented by the community via smart contracts.
Compared with java memory management there is no such thing like a
garbage collector, all allocated memory is never reclaimed back at
least at this point of development.
(Official docs).
There is no such thing like dynamic resizable arrays and at the same
time the compiler allows potentially dangerous operations with array
definition and usage.
(ethereum.stackexchange.com discussion)
All operations on chain require gas. First iteration of the project
shown, with growth of the dataset supported by the smart contract
running business logic which involves non-optimized iteration over
a dataset start costs thousands and millions of dollars by current
Ether\USD exchange rate. Optimization might give some gains, but in
the long term this problem will remain. It was a reason to pivot a
project on another direction,
Security concerns
I was looking for some kind enumerable interface for a data and there
is one, but there is also a security issue with it.
ERC721 standard allows to have Enumerable interface which gives access
to token ids. Although, there is well known security attack on its
concept and implementation by overusing balanceOf() call (or may be
something different).
It was just one of examples which affected my personal scope of work,
but it brings security concerns to the top of ethereum powered
projects due the development even for things which is assumed standard
like API.
Gas overhead and project pivot
Minting a token might cost a huge amount of money (~40 USD at Jan 2021)
which might put a cross on the whole idea of using blockchain for
securing exchanges. More info is
here
Some dev instruments like Hardhat support compiler time contract gas
cost evaluation which should give quite precise estimates on how much
gas - and money! - it would cost to deploy a contract, emission of
new tokens and contract operations.
In case of the first iteration of Swap smart contracts, the PoC shown
the total cost of contract deployment & operation on the production
chain brings financial overhead which makes project non-profitable.
Integration with the mobile client
The Ethereum dev community ported web3 on several platforms. In
Java&Kotlin&Android platform it was done under the web3j project.
I had to provide a byte code of the smart contract and implement
a Java wrapper where Java hooks trigger methods of the smart
contract.
Web3j allows to autogenerate such wrappers, but it doesn't work
stably. I was able to manage it work for some case and for some
cases I wasn't.
What is next
There are many others interesting things I have discovered when have
been working with smart contracts, the rest you can find in the
tech doc
of the swap project.
Next publications in this seria will cover test coverage of a smart
contract, backend & frontend and their test coverage, setting up a
private nodes network and project deployment automatization.